diff options
| author | Ray Strode <rstrode@redhat.com> | 2008-12-19 14:28:02 -0500 |
|---|---|---|
| committer | Kristian Høgsberg <krh@redhat.com> | 2008-12-19 17:38:55 -0500 |
| commit | 966aa112e7851625f764718e3d45c46d246760fc (patch) | |
| tree | 2db6211f2e7cb3c21b7f3aa72ca20a6a880ca43a | |
| parent | 2c0e56b2d5d31f3665b6af4d6ea12fa5c66fc067 (diff) | |
| download | wayland-966aa112e7851625f764718e3d45c46d246760fc.tar.gz wayland-966aa112e7851625f764718e3d45c46d246760fc.tar.xz wayland-966aa112e7851625f764718e3d45c46d246760fc.zip | |
Ignore tty input
Previously, ctrl-c would kill wayland and input like
passwords and commands would get typed into the terminal
under the scenes.
| -rw-r--r-- | wayland-system-compositor.c | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c index d6a4411..fb44ab9 100644 --- a/wayland-system-compositor.c +++ b/wayland-system-compositor.c @@ -18,9 +18,11 @@ #include <stdio.h> #include <string.h> +#include <stdbool.h> #include <stdlib.h> #include <stdint.h> #include <stdarg.h> +#include <termios.h> #include <i915_drm.h> #include <sys/ioctl.h> #include <sys/mman.h> @@ -74,13 +76,19 @@ struct egl_compositor { EGLContext context; EGLConfig config; struct wl_display *wl_display; - int tty_fd; int width, height, stride; struct egl_surface *background; struct wl_list input_device_list; struct wl_list surface_list; + struct wl_event_source *term_signal_source; + + /* tty handling state */ + int tty_fd; + + 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; @@ -863,11 +871,72 @@ static void on_leave_vt(int signal_number, void *data) ioctl (ec->tty_fd, VT_RELDISP, 1); } +static bool open_active_tty(struct egl_compositor *ec) +{ + 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 FALSE; + } + return TRUE; +} + +static void +on_tty_input(int fd, uint32_t mask, void *data) +{ + struct egl_compositor *ec = data; + + /* Ignore input to tty. We get keyboard events from evdev + */ + tcflush(ec->tty_fd, TCIFLUSH); +} + +static void on_term_signal(int signal_number, void *data) +{ + struct egl_compositor *ec = data; + + if (tcsetattr(ec->tty_fd, TCSANOW, &ec->terminal_attributes) < 0) + fprintf(stderr, "could not restore terminal to canonical mode\n"); + + exit(0); +} + +static void ignore_tty_input(struct egl_compositor *ec, struct wl_event_loop *loop) +{ + struct termios raw_attributes; + + if (tcgetattr(ec->tty_fd, &ec->terminal_attributes) < 0) { + fprintf(stderr, "could not get terminal attributes: %m\n"); + return; + } + + /* 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->term_signal_source = wl_event_loop_add_signal(loop, SIGTERM, + on_term_signal, + ec); + + ec->tty_input_source = wl_event_loop_add_fd(loop, ec->tty_fd, + WL_EVENT_READABLE, + on_tty_input, ec); +} + static void watch_for_vt_changes(struct egl_compositor *ec, struct wl_event_loop *loop) { struct vt_mode mode = { 0 }; - ec->tty_fd = open("/dev/tty0", O_RDWR | O_NOCTTY); mode.mode = VT_PROCESS; mode.relsig = SIGUSR1; mode.acqsig = SIGUSR2; @@ -968,7 +1037,10 @@ egl_compositor_create(struct wl_display *display) wl_display_add_global(display, &shooter->base); loop = wl_display_get_event_loop(ec->wl_display); - watch_for_vt_changes (ec, loop); + if (open_active_tty (ec)) { + ignore_tty_input (ec, loop); + watch_for_vt_changes (ec, loop); + } ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec); ec->repaint_needed = 0; ec->repaint_on_timeout = 0; |
