diff options
author | Ray Strode <rstrode@redhat.com> | 2008-12-19 14:28:02 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2008-12-19 14:32:38 -0500 |
commit | bb257a5c2d447b455fb08d0d237288f33b5fceb5 (patch) | |
tree | 2af40bb92148d559d6faf8b79df44defd13f2851 | |
parent | 15d0f8b236efde6db3211182bdc45b10bdf61d2d (diff) |
Ignore tty inputignore-tty
Previously, ctrl-c would kill wayland and input like
passwords and commands would get typed into the terminal
under the scenes.
-rw-r--r-- | egl-compositor.c | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/egl-compositor.c b/egl-compositor.c index 3d607a1..a64621b 100644 --- a/egl-compositor.c +++ b/egl-compositor.c @@ -22,9 +22,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> @@ -78,7 +80,6 @@ struct egl_compositor { EGLContext context; EGLConfig config; struct wl_display *wl_display; - int tty_fd; int width, height, stride; struct egl_surface *background; struct egl_surface *overlay; @@ -87,6 +88,13 @@ struct egl_compositor { 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; @@ -1021,11 +1029,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; @@ -1130,7 +1199,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; |