home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / gnu / ispell-4.0-src.lha / ispell-4.0 / term.c < prev    next >
C/C++ Source or Header  |  1994-05-04  |  7KB  |  382 lines

  1. /* Copyright (C) 1990, 1993 Free Software Foundation, Inc.
  2.  
  3.    This file is part of GNU ISPELL.
  4.  
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <stdio.h>
  20. #include <signal.h>
  21. #include <setjmp.h>
  22.  
  23. #if defined (HAVE_TERMIO_H)
  24. #include <termio.h>
  25. #else
  26. /* Assume BSD if all else fails */
  27. #include <sgtty.h>
  28. #endif /* not HAVE_TERMIO_H */
  29.  
  30. #include <signal.h>
  31. #include "ispell.h"
  32.  
  33.  
  34. extern int reading_interactive_command;
  35. extern jmp_buf command_loop;
  36.  
  37. int erasechar, killchar;
  38.  
  39. /* termcap variables */
  40. static char *BC, *cd, *cl, *so, *se;
  41. #ifndef VENIX
  42. static char *cm, *ho, termcap[1024], termstr[1024];
  43. #endif
  44. static int li;
  45.  
  46. void
  47. gettermcap ()
  48. {
  49. #ifdef NO_TERMCAP
  50.   /* IBM pc ansi escape codes */
  51.   BC = "\b";
  52.   cl = "\033[0;0H\033[0J";
  53.   cd = "\033[0J";
  54.   so = "\033[47;30m";
  55.   se = "\033[37;40m";
  56.   li = 25;
  57. #else
  58.   char *termptr;
  59.   char *tgetstr ();
  60.  
  61.   tgetent (termcap, getenv ("TERM"));
  62.   termptr = termstr;
  63.   BC = tgetstr ("bc", &termptr);/* backspace */
  64.   if (BC == NULL)
  65.     BC = "\b";
  66.   cd = tgetstr ("cd", &termptr);/* clear to end of screen */
  67.   cl = tgetstr ("cl", &termptr);/* clear screen */
  68.   cm = tgetstr ("cm", &termptr);/* cursor motion */
  69.   ho = tgetstr ("ho", &termptr);/* home */
  70.   so = tgetstr ("so", &termptr);/* inverse video on */
  71.   se = tgetstr ("se", &termptr);/* inverse video off */
  72.   li = tgetnum ("li");        /* number of lines on screen */
  73. #endif
  74. }
  75.  
  76. #ifdef NO_TERMCAP
  77. /* ARGSUSED */
  78. void
  79. tputs (str, lines, put)
  80.      char *str;
  81.      int (*put) ();
  82. {
  83.   while (*str)
  84.     (*put) (*str++);
  85. }
  86.  
  87. #endif
  88.  
  89. void
  90. putch (c)
  91.   int c;
  92. {
  93.   putchar (c);
  94. }
  95.  
  96. void
  97. termflush ()
  98. {
  99.   (void) fflush (stdout);
  100. }
  101.  
  102. void
  103. erase ()
  104. {
  105.   if (cl)
  106.     tputs (cl, li, putch);
  107.   else
  108.     {
  109.       move (0, 0);
  110.       tputs (cd, li, putch);
  111.     }
  112. }
  113.  
  114. void
  115. move (row, col)
  116.   int row, col;
  117. {
  118. #ifdef NO_TERMCAP
  119.   (void) printf ("\033[%d;%dH", row, col);
  120. #else
  121.   char *tgoto ();
  122.   tputs (tgoto (cm, col, row), 100, putch);
  123. #endif
  124. }
  125.  
  126.  
  127. void
  128. inverse ()
  129. {
  130.   tputs (so, 10, putch);
  131. }
  132.  
  133. void
  134. normal ()
  135. {
  136.   tputs (se, 10, putch);
  137. }
  138.  
  139. void
  140. backup ()
  141. {
  142.   tputs (BC, 1, putch);
  143. }
  144.  
  145. static int termchanged = 0;
  146.  
  147. #if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H)
  148. static struct sgttyb sbuf, osbuf;
  149.  
  150. void
  151. terminit ()
  152. {
  153.   int tpgrp;
  154.   RETSIGTYPE onstop ();
  155.  
  156. retry:
  157.   sigsetmask (1 << SIGTSTP | 1 << SIGTTIN | 1 << SIGTTOU);
  158.   /* apparently tpgrp was a short on 4.1, but is now a long -
  159.      * set the high bits to zero in case the ioctl doesn't write them.
  160.      */
  161.   tpgrp = 0;
  162.   if (ioctl (0, TIOCGPGRP, &tpgrp) != 0)
  163.     {
  164.       (void) fprintf (stderr, "must run from tty in interactive mode\n");
  165.       exit (1);
  166.     }
  167.   if (tpgrp != getpgrp (0))
  168.     {                /* not in foreground */
  169.       (void) sigsetmask (1 << SIGTSTP | 1 << SIGTTIN);
  170.       (void) signal (SIGTTOU, SIG_DFL);
  171.       (void) kill (0, SIGTTOU);
  172.       /* job stops here waiting for SIGCONT */
  173.       goto retry;
  174.     }
  175.  
  176.   (void) ioctl (0, TIOCGETP, &osbuf);
  177.   termchanged = 1;
  178.  
  179.   sbuf = osbuf;
  180.   sbuf.sg_flags &= ~ECHO;
  181.   sbuf.sg_flags |= CBREAK;
  182.   ioctl (0, TIOCSETP, &sbuf);
  183.  
  184.   erasechar = sbuf.sg_erase;
  185.   killchar = sbuf.sg_kill;
  186.  
  187.   (void) signal (SIGTTIN, onstop);
  188.   (void) signal (SIGTTOU, onstop);
  189.   (void) signal (SIGTSTP, onstop);
  190.   (void) sigsetmask (0);
  191.   gettermcap ();
  192. }
  193.  
  194. void
  195. termuninit ()
  196. {
  197.   if (termchanged)
  198.     {
  199.       (void) ioctl (0, TIOCSETP, (char *) &osbuf);
  200.       termchanged = 0;
  201.     }
  202. }
  203.  
  204. void
  205. termreinit ()
  206. {
  207.   if (termchanged == 0)
  208.     {
  209.       (void) ioctl (0, TIOCSETP, (char *) &sbuf);
  210.       termchanged = 1;
  211.     }
  212. }
  213.  
  214. #endif /* !HAVE_TERMIO_H && !HAVE_TERMIOS_H */
  215.  
  216. #if defined (HAVE_TERMIO_H) || defined (HAVE_TERMIOS_H)
  217. struct termio termio, otermio;
  218.  
  219. void
  220. terminit ()
  221. {
  222.   if (ioctl (0, TCGETA, (char *) &otermio) < 0)
  223.     {
  224.       (void) fprintf (stderr, "must run from tty in interactive mode\n");
  225.       exit (1);
  226.     }
  227.  
  228.   termchanged = 1;
  229.  
  230.   termio = otermio;
  231.   termio.c_lflag &= ~(ICANON | ECHO);
  232.   termio.c_cc[VMIN] = 1;
  233.   termio.c_cc[VTIME] = 0;
  234.   erasechar = termio.c_cc[VERASE];
  235.   killchar = termio.c_cc[VKILL];
  236.  
  237.   (void) ioctl (0, TCSETA, (char *) &termio);
  238.  
  239.   gettermcap ();
  240. }
  241.  
  242.  
  243. void
  244. termuninit ()
  245. {
  246.   if (termchanged)
  247.     {
  248.       (void) ioctl (0, TCSETA, (char *) &otermio);
  249.       termchanged = 0;
  250.     }
  251. }
  252.  
  253. void
  254. termreinit ()
  255. {
  256.   if (termchanged == 0)
  257.     {
  258.       (void) ioctl (0, TCSETA, (char *) &termio);
  259.       termchanged = 1;
  260.     }
  261. }
  262.  
  263. #endif /* USG */
  264.  
  265. #ifdef MSDOS
  266. void terminit () { ; }
  267. void termuninit () { ; }
  268. void termreinit () { ; }
  269. #endif
  270.  
  271. #ifdef SIGTTIN
  272. RETSIGTYPE
  273. onstop (signo)
  274.   int signo;
  275. {
  276.   (void) signal (signo, SIG_DFL);
  277.   termuninit ();
  278.   sigsetmask (0);
  279.   (void) killpg (getpgrp (0), signo);
  280.   /* stop here */
  281.   signal (signo, onstop);
  282.   termreinit ();
  283.   if (reading_interactive_command)
  284.     longjmp (command_loop, 1);
  285. }
  286.  
  287. void
  288. stop ()
  289. {
  290.   onstop (SIGTSTP);
  291. }
  292.  
  293. #else
  294. void
  295. stop ()
  296. {
  297.   shellescape ((char *) NULL);
  298. }
  299.  
  300. #endif
  301.  
  302. static char *shellcmd, *shellsh;;
  303.  
  304. void
  305. shellfun ()
  306. {
  307.   if (shellcmd == (char *) 0)
  308.     execlp (shellsh, shellsh, (char *) 0);
  309.   else
  310.     execlp (shellsh, shellsh, "-c", shellcmd, (char *) 0);
  311. }
  312.  
  313.  
  314. void
  315. shellescape (buf)
  316.      char *buf;
  317. {
  318.   shellsh = (char *) getenv ("SHELL");
  319.   if (shellsh == NULL)
  320.     shellsh = "/bin/sh";
  321.   shellcmd = buf;
  322.   (void) dochild (shellfun);
  323.   (void) printf ("\n-- Type space to continue --");
  324.   getchar ();
  325. }
  326.  
  327. int
  328. dochild (fun)
  329.      void (*fun) (NOARGS);
  330. {
  331.   int pid, w;
  332.   int status, val = 1;
  333.   RETSIGTYPE (*oldf) (NOARGS);
  334.   termuninit ();
  335.  
  336.   oldf = (RETSIGTYPE (*)()) signal (SIGINT, SIG_IGN);
  337.   (void) signal (SIGQUIT, SIG_IGN);
  338. #ifdef SIGTTIN
  339.   (void) signal (SIGTTIN, SIG_DFL);
  340.   (void) signal (SIGTTOU, SIG_DFL);
  341.   (void) signal (SIGTSTP, SIG_DFL);
  342. #endif
  343.  
  344.   pid = fork ();
  345.   if (pid < 0)
  346.     {
  347.       perror ("fork");
  348.       goto ret;
  349.     }
  350.   if (pid == 0)
  351.     {
  352.       (void) signal (SIGINT, SIG_DFL);
  353.       (void) signal (SIGQUIT, SIG_DFL);
  354.       (*fun) ();
  355.       _exit (1);
  356.     }
  357.   while ((w = wait (&status)) >= 0)
  358.     if (w == pid)
  359.       break;
  360.  
  361.   val = (status >> 8) & 0xff;
  362. ret:
  363. #ifdef SIGTTIN
  364.   signal (SIGTTIN, onstop);
  365.   signal (SIGTTOU, onstop);
  366.   signal (SIGTSTP, onstop);
  367. #endif
  368.   signal (SIGINT, (RETSIGTYPE (*)()) oldf);
  369.   signal (SIGQUIT, SIG_DFL);
  370.  
  371.   termreinit ();
  372.  
  373.   return (val);
  374. }
  375.  
  376. void
  377. termbeep ()
  378. {
  379.   (void) putchar (7);
  380.   (void) fflush (stdout);
  381. }
  382.