From d4d16198c2924b1085258c0b6562b562c7df3c29 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Fri, 7 Sep 2012 15:14:04 +0300 Subject: geresh 0.6.3 --- terminal.cc | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 terminal.cc (limited to 'terminal.cc') diff --git a/terminal.cc b/terminal.cc new file mode 100644 index 0000000..89d606a --- /dev/null +++ b/terminal.cc @@ -0,0 +1,213 @@ +// Copyright (C) 2003 Mooffie +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +#include + +// Baruch says to put editor.h first. +#include "editor.h" // for SIGHUP's emergency_save +#include "terminal.h" +#include "dbg.h" + +#include // _POSIX_VDISABLE +#include // wait() +#include +#include +#include +#include // getenv +#include // timeval +#include // strstr +#ifdef HAVE_LANGINFO_CODESET +# include +#endif + +bool terminal::initialized = false; +bool terminal::is_utf8; +bool terminal::force_iso88598; +bool terminal::is_fixed; +bool terminal::is_color; +bool terminal::use_default_colors; +bool terminal::do_arabic_shaping; +bool terminal::graphical_boxes; + +static termios oldterm; + +void terminal::finish() +{ + endwin(); + tcsetattr(0, TCSANOW, &oldterm); + DBG(1, ("Bailing out\n")); +} + +static RETSIGTYPE sigint_hndlr(int sig) +{ +} + +static RETSIGTYPE sigterm_hndlr(int sig) +{ + terminal::finish(); + exit(0); +} + +static RETSIGTYPE sighup_hndlr(int sig) +{ + Editor::get_global_instance()->emergency_save(); + DBG(1, ("SIGHUP HANDLER\n")); + exit(0); +} + +static RETSIGTYPE sigchld_hndlr(int sig) +{ + int serrno = errno; + wait(NULL); + errno = serrno; +} + +// was_ctrl_c_pressed() - is a crude method to check if ^C was pressed +// while in a non-interactive segment, like when receiving data from +// the speller. it uses select() to see if there's any keyboard (stdin) +// input available. If so, it eats it up, and checks whether 0x03 (^C) +// was encountered. + +bool terminal::was_ctrl_c_pressed() +{ +#define HAVE_SELECT 1 +#ifdef HAVE_SELECT + fd_set rfds; + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + bool ctrl_c_pressed = false; + + while (1) { + FD_ZERO(&rfds); + FD_SET(STDIN_FILENO, &rfds); + if (select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) <= 0) + break; // no kbd input avail. + char ch; + read(STDIN_FILENO, &ch, 1); + if (ch == '\x03' || ch == '\x07') + ctrl_c_pressed = true; + } + return ctrl_c_pressed; +#else + return false; +#endif +} + +// DISABLE_SIGTSTP() is used by child processes (e.g. the speller) +// to get rid of ncurses' handler. See TODO. +void DISABLE_SIGTSTP() +{ + signal(SIGTSTP, SIG_IGN); +} + +void terminal::init() +{ + tcgetattr(0, &oldterm); + +#ifdef _POSIX_VDISABLE + termios term; + term = oldterm; + term.c_cc[VINTR] = _POSIX_VDISABLE; + term.c_cc[VQUIT] = _POSIX_VDISABLE; + term.c_cc[VSTOP] = _POSIX_VDISABLE; + term.c_cc[VSTART] = _POSIX_VDISABLE; + tcsetattr(0, TCSANOW, &term); +#else + termios term; + term = oldterm; + term.c_lflag &= ~ISIG; + term.c_iflag &= ~(IXON | IXOFF); + tcsetattr(0, TCSANOW, &term); +#endif + + signal(SIGINT, sigint_hndlr); + signal(SIGTERM, sigterm_hndlr); + signal(SIGHUP, sighup_hndlr); + signal(SIGCHLD, sigchld_hndlr); + + // it's important to ignore SIGPIPE because the editor has the ability + // to write to a pipe. + signal(SIGPIPE, SIG_IGN); + + initscr(); + keypad(stdscr, TRUE); + nonl(); + cbreak(); + noecho(); + +#ifdef HAVE_COLOR + if (has_colors()) { + is_color = true; + start_color(); +#ifdef HAVE_USE_DEFAULT_COLORS + terminal::use_default_colors = (::use_default_colors() == OK); +#else + terminal::use_default_colors = false; +#endif + } else { + is_color = false; + } +#else + is_color = false; +#endif + + terminal::do_arabic_shaping = false; + terminal::initialized = true; + + if (under_x11()) + terminal::graphical_boxes = true; + else + terminal::graphical_boxes = false; +} + +bool terminal::is_interactive() +{ + return initialized; +} + +// Are we running under X? +bool terminal::under_x11() +{ + return getenv("DISPLAY") && *getenv("DISPLAY"); +} + +// determine_locale() - find out the currently used locale. + +void terminal::determine_locale() +{ + const char *locale; + (void) (((locale = getenv("LC_ALL")) && *locale) || + ((locale = getenv("LC_CTYPE")) && *locale) || + ((locale = getenv("LANG")))); + + is_utf8 = false; + +#ifdef HAVE_LANGINFO_CODESET +# define lcl(subs) strstr(nl_langinfo(CODESET), subs) +#else +# define lcl(subs) (locale && strstr(locale, subs)) +#endif + + if (lcl("UTF-8") || lcl("utf-8") || lcl("UTF8") || lcl("utf8")) + is_utf8 = true; + + // we assume this is a non-fixed terminal if and only if we are in + // UTF-8 locale and a DISPLAY environment variable is present (the + // user can change this with command-line options). + is_fixed = !(is_utf8 && under_x11()); +} + -- cgit v1.2.3