home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / unix.c < prev    next >
Text File  |  1996-04-26  |  46KB  |  1,945 lines

  1. /*    UNIX:    Unix specific terminal driver
  2.         for MicroEMACS 4.0
  3.     (C)Copyright 1995 D. Lawrence, C. Smith
  4. */
  5.  
  6. /**
  7.     New features: (as of version 3.10)
  8.  
  9.     1. Timeouts waiting on a function key have been changed from
  10.     35000 to 500000 microseconds.
  11.  
  12.     2. Additional keymapping entries can be made from the command
  13.     language by issuing a 'set $palette xxx'.  The format of
  14.     xxx is a string as follows:
  15.         "KEYMAP keybinding escape-sequence".
  16.     To add "<ESC><[><A>" as a keybinding of FNN, issue:
  17.         "KEYMAP FNN ~e[A".
  18.     Note that the "~e" sequence represents the escape character in
  19.     the MicroEMACS command language.
  20.  
  21.     3. Colors are supported.  Under AIX the colors will be pulled
  22.     in automaticly.  For other environments, you can either add
  23.     the termcap entries, C0 to D7.  Or the colors may be defined
  24.     using the command language by issuing a 'set $palette xxx'
  25.     command.  The format of xxx is a string as follows:
  26.         "CLRMAP # escape-sequence".
  27.     The number is a number from 0 to 15, where 0 to 7 is the
  28.     foreground colors, and 8 to 15 as background colors.
  29.     To add foreground color 0 for ansi terminals, issue:
  30.         "CLRMAP 0 ~e[30m".
  31.     
  32.     'Porting notes:
  33.  
  34.     I have tried to create this file so that it should work
  35.     as well as possible without changes on your part.
  36.  
  37.     However, if something does go wrong, read the following
  38.     helpful hints:
  39.  
  40.     1. On SUN-OS4, there is a problem trying to include both
  41.     the termio.h and ioctl.h files.  I wish Sun would get their
  42.     act together.  Even though you get lots of redefined messages,
  43.     it shouldn't cause any problems with the final object.
  44.  
  45.     2. In the type-ahead detection code, the individual UNIX
  46.     system either has a FIONREAD or a FIORDCHK ioctl call.
  47.     Hopefully, your system uses one of them and this be detected
  48.     correctly without any intervention.
  49.  
  50.     3. Also lookout for directory handling.  The SCO Xenix system
  51.     is the weirdest I've seen, requiring a special load file
  52.     (see below).  Some machine call the result of a readdir() call
  53.     a "struct direct" or "struct dirent".  Includes files are
  54.     named differently depending of the O/S.  If your system doesn't
  55.     have an opendir()/closedir()/readdir() library call, then
  56.     you should use the public domain utility "ndir".
  57.  
  58.     To compile:
  59.         Compile all files normally.
  60.     To link:
  61.         Select one of the following operating systems:
  62.             SCO Xenix:
  63.                 use "-ltermcap" and "-lx";
  64.             SUN 3 and 4:
  65.                 use "-ltermcap";
  66.             IBM-RT, IBM-AIX, ATT UNIX, Altos UNIX, Interactive:
  67.                 use "-lcurses".
  68.  
  69.     - 20 feb 95    New version 4.00 features
  70.       We added new code to implient a TERMIOS driver
  71. **/
  72.  
  73. /** Include files **/
  74. #include <stdio.h>            /* Standard I/O definitions    */
  75. #include "estruct.h"            /* Emacs definitions        */
  76. #ifdef OSK
  77. extern errno;
  78. #endif
  79.  
  80. /** Do nothing routine **/
  81. int scnothing()
  82. {
  83.     return(0);
  84. }
  85.  
  86. /** Only compile for UNIX machines **/
  87. #if BSD || FREEBSD || USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX || (AVVION || TERMIOS)
  88.  
  89. /** Include files **/
  90. #include "eproto.h"            /* Function definitions        */
  91. #include "edef.h"            /* Global variable definitions    */
  92. #include "elang.h"            /* Language definitions        */
  93.  
  94. /** Kill predefined **/
  95. #undef CTRL                /* Problems with CTRL        */
  96.  
  97.  
  98. /** Overall include files **/
  99. #ifndef OSK
  100. #include <sys/types.h>            /* System type definitions    */
  101. #include <sys/stat.h>            /* File status definitions    */
  102. #include <sys/ioctl.h>            /* I/O control definitions    */
  103. #else
  104. #include <types.h>          /* System type definitions  */
  105. #include <stat.h>           /* File status definitions  */
  106. #include <modes.h>
  107. #include <sgstat.h>
  108. #define sgttyb sgbuf
  109. #define S_IFREG 0xff
  110. struct sgttyb ostate, nstate;
  111. #define        SIGTSTP 18      /* stop signal from tty */
  112. #define stty(path,buf) _ss_opt(path,buf)
  113. #define gtty(path,buf) _gs_opt(path,buf)
  114. #endif
  115.  
  116. /** Additional include files **/
  117. #if    FREEBSD
  118. #define TERMIOS 1
  119. #include <sys/time.h>
  120. #undef    BSD
  121. #include <sys/param.h>
  122. #undef BSD
  123. #define    BSD    0
  124. #endif
  125. #if (BSD && !TERMIOS)
  126. #ifndef OSK
  127. #include <sys/time.h>            /* Timer definitions        */
  128. #endif
  129. #endif /* (BSD && !TERMIOS) */
  130. #if BSD || FREEBSD || SUN || HPUX8 || HPUX9 || (AVVION || TERMIOS) || AIX
  131. #include <signal.h>            /* Signal definitions        */
  132. #endif /* BSD || FREEBSD || SUN || HPUX8 || HPUX9 || (AVVION || TERMIOS) */
  133. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX
  134. #include <termio.h>            /* Terminal I/O definitions    */
  135. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX */
  136. #if (AVVION || TERMIOS)
  137. #include <termios.h>            /* Terminal I/O definitions    */
  138. #include <unistd.h>
  139. #endif /* (AVVION || TERMIOS) */
  140. #if CURSES
  141. #include <curses.h>            /* Curses screen output        */
  142. #undef WINDOW                /* Oh no!            */
  143. #endif /* CURSES */
  144.  
  145. /** Completion include files **/
  146. /** Directory accessing: Try and figure this out... if you can! **/
  147. #if ((BSD || FREEBSD) && !TERMIOS)
  148. #ifndef OSK
  149. #include <sys/dir.h>            /* Directory entry definitions    */
  150. #else
  151. short ospeed;
  152. char PC, PC_, *BC, *UP;
  153. #include <dir.h>            /* Directory entry definitions  */
  154. #endif
  155. #define DIRENTRY    direct
  156. #endif /* (BSD && !TERMIOS) */
  157. #if XENIX || VAT
  158. #include <sys/ndir.h>            /* Directory entry definitions    */
  159. #define DIRENTRY    direct
  160. #endif /* XENIX */
  161. #if ((USG || AIX || AUX) && !VAT) || SMOS || HPUX8 || HPUX9 || SUN || (AVVION || TERMIOS)
  162. #include <dirent.h>            /* Directory entry definitions    */
  163. #define DIRENTRY    dirent
  164. #endif /* ((USG || AIX || AUX) && !VAT) || SMOS || HPUX8 || HPUX9 || SUN || (AVVION || TERMIOS) */
  165.  
  166. /** Restore predefined definitions **/
  167. #undef CTRL                /* Restore CTRL            */
  168. #define CTRL 0x0100
  169.  
  170. /** Parameters **/
  171. #define NINCHAR        64        /* Input buffer size        */
  172. #define NOUTCHAR    256        /* Output buffer size        */
  173. #if TERMCAP || TERMIOS
  174. #define NCAPBUF        1024        /* Termcap storage size        */
  175. #endif /* TERMCAP */
  176. #define MARGIN        8        /* Margin size            */
  177. #define SCRSIZ        64        /* Scroll for margin        */
  178. #define NPAUSE        10        /* # times thru update to pause */
  179.  
  180. /** CONSTANTS **/
  181. #define TIMEOUT        255        /* No character available    */
  182.  
  183. #if TERMCAP || TERMIOS
  184. struct capbind {            /* Capability binding entry    */
  185.     char * name;            /* Termcap name            */
  186.     char * store;            /* Storage variable        */
  187. };
  188. struct keybind {            /* Keybinding entry        */
  189.     char * name;            /* Termcap name            */
  190.     int value;            /* Binding value        */
  191. };
  192. char *reset = (char*) NULL;        /* reset string kjc */
  193. #endif /* TERMCAP */
  194.  
  195. /** Local variables **/
  196. #if (BSD && !TERMIOS)
  197. static struct sgttyb cursgtty;        /* Current modes        */
  198. static struct sgttyb oldsgtty;        /* Original modes        */
  199. #ifndef OSK
  200. static struct tchars oldtchars;        /* Current tchars        */
  201. static struct ltchars oldlchars;    /* Current ltchars        */
  202. #endif
  203. static char blank[6] =            /* Blank out character set    */
  204.     { -1, -1, -1, -1, -1, -1 };
  205. #endif /* (BSD && !TERMIOS) */
  206. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX
  207. static struct termio curterm;        /* Current modes        */
  208. static struct termio oldterm;        /* Original modes        */
  209. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX */
  210. #if (AVVION || TERMIOS)
  211. static struct termios curterm;        /* Current modes        */
  212. static struct termios oldterm;        /* Original modes        */
  213. #endif /* (AVVION || TERMIOS) */
  214. #if TERMCAP || TERMIOS
  215. static char tcapbuf[NCAPBUF];        /* Termcap character storage    */
  216. #define CAP_CL        0        /* Clear to end of page        */
  217. #define CAP_CM        1        /* Cursor motion        */
  218. #define CAP_CE        2        /* Clear to end of line        */
  219. #define CAP_SE        3        /* Standout ends        */
  220. #define CAP_SO        4        /* Standout (reverse video)    */
  221. #define CAP_IS        5        /* Initialize screen        */
  222. #define CAP_KS        6        /* Keypad mode starts        */
  223. #define CAP_KE        7        /* Keypad mode ends        */
  224. #define CAP_VB        8        /* Visible bell            */
  225. #if COLOR
  226. #define CAP_C0        9        /* Foreground color #0        */
  227. #define CAP_C1        10        /* Foreground color #1        */
  228. #define CAP_C2        11        /* Foreground color #2        */
  229. #define CAP_C3        12        /* Foreground color #3        */
  230. #define CAP_C4        13        /* Foreground color #4        */
  231. #define CAP_C5        14        /* Foreground color #5        */
  232. #define CAP_C6        15        /* Foreground color #6        */
  233. #define CAP_C7        16        /* Foreground color #7        */
  234. #define CAP_D0        17        /* Background color #0        */
  235. #define CAP_D1        18        /* Background color #1        */
  236. #define CAP_D2        19        /* Background color #2        */
  237. #define CAP_D3        20        /* Background color #3        */
  238. #define CAP_D4        21        /* Background color #4        */
  239. #define CAP_D5        22        /* Background color #5        */
  240. #define CAP_D6        23        /* Background color #6        */
  241. #define CAP_D7        24        /* Background color #7        */
  242. #if USG || AIX || AUX
  243. #define CAP_SF        25        /* Set foreground color        */
  244. #define CAP_SB        26        /* Set background color        */
  245. #endif /* USG || AIX || AUX */
  246. #endif /* COLOR */
  247. static struct capbind capbind[] = {    /* Capability binding list    */
  248.     { "cl" },            /* Clear to end of page        */
  249.     { "cm" },            /* Cursor motion        */
  250.     { "ce" },            /* Clear to end of line        */
  251.     { "se" },            /* Standout ends        */
  252.     { "so" },            /* Standout (reverse video)    */
  253.     { "is" },            /* Initialize screen        */
  254.     { "ks" },            /* Keypad mode starts        */
  255.     { "ke" },            /* Keypad mode ends        */
  256.     { "vb" },            /* Visible bell            */
  257. #if COLOR
  258.     { "c0" },            /* Foreground color #0        */
  259.     { "c1" },            /* Foreground color #1        */
  260.     { "c2" },            /* Foreground color #2        */
  261.     { "c3" },            /* Foreground color #3        */
  262.     { "c4" },            /* Foreground color #4        */
  263.     { "c5" },            /* Foreground color #5        */
  264.     { "c6" },            /* Foreground color #6        */
  265.     { "c7" },            /* Foreground color #7        */
  266.     { "d0" },            /* Background color #0        */
  267.     { "d1" },            /* Background color #1        */
  268.     { "d2" },            /* Background color #2        */
  269.     { "d3" },            /* Background color #3        */
  270.     { "d4" },            /* Background color #4        */
  271.     { "d5" },            /* Background color #5        */
  272.     { "d6" },            /* Background color #6        */
  273.     { "d7" },            /* Background color #7        */
  274. #if USG || AIX || AUX
  275.     { "Sf" },            /* Set foreground color        */
  276.     { "Sb" },            /* Set background color        */
  277. #endif /* USG || AIX || AUX */
  278. #endif /* COLOR */
  279. };
  280. #if COLOR
  281. static int cfcolor = -1;        /* Current forground color    */
  282. static int cbcolor = -1;        /* Current background color    */
  283. #endif /* COLOR */
  284. static struct keybind keybind[] = {    /* Keybinding list        */
  285.     { "bt", SHFT|CTRL|'i' },    /* Back-tab key            */
  286.     { "k1", SPEC|'1' },        /* F1 key            */
  287.     { "k2", SPEC|'2' },        /* F2 key            */
  288.     { "k3", SPEC|'3' },        /* F3 key            */
  289.     { "k4", SPEC|'4' },        /* F4 key            */
  290.     { "k5", SPEC|'5' },        /* F5 key            */
  291.     { "k6", SPEC|'6' },        /* F6 key            */
  292.     { "k7", SPEC|'7' },        /* F7 key            */
  293.     { "k8", SPEC|'8' },        /* F8 key            */
  294.     { "k9", SPEC|'9' },        /* F9 key            */
  295.     { "k0", SPEC|'0' },        /* F0 or F10 key        */
  296.      { "k;", SPEC|'0' },        /* F0 or F10 key    (kjc)    */
  297.     { "F1", SHFT|SPEC|'1' },    /* Shift-F1 or F11 key        */
  298.     { "F2", SHFT|SPEC|'2' },    /* Shift-F2 or F12 key        */
  299.     { "F3", SHFT|SPEC|'3' },    /* Shift-F3 or F13 key        */
  300.     { "F4", SHFT|SPEC|'4' },    /* Shift-F4 or F14 key        */
  301.     { "F5", SHFT|SPEC|'5' },    /* Shift-F5 or F15 key        */
  302.     { "F6", SHFT|SPEC|'6' },    /* Shift-F6 or F16 key        */
  303.     { "F7", SHFT|SPEC|'7' },    /* Shift-F7 or F17 key        */
  304.     { "F8", SHFT|SPEC|'8' },    /* Shift-F8 or F18 key        */
  305.     { "F9", SHFT|SPEC|'9' },    /* Shift-F9 or F19 key        */
  306.     { "FA", SHFT|SPEC|'0' },    /* Shift-F0 or F20 key        */
  307.     { "kA", CTRL|'O' },        /* Insert line key        */
  308.     { "kb", CTRL|'H' },        /* Backspace key        */
  309.     { "kC", CTRL|'L' },        /* Clear screen key        */
  310.     { "kD", SPEC|'D' },        /* Delete character key        */
  311.     { "kd", SPEC|'N' },        /* Down arrow key        */
  312.     { "kE", CTRL|'K' },        /* Clear to end of line key    */
  313.     { "kF", CTRL|'V' },        /* Scroll forward key        */
  314.     { "kH", SPEC|'>' },        /* Home down key        */
  315.      { "@7", SPEC|'>' },        /* Home down key    (kjc)    */
  316.     { "kh", SPEC|'<' },        /* Home key            */
  317.     { "kI", SPEC|'C' },        /* Insert character key        */
  318.     { "kL", CTRL|'K' },        /* Delete line key        */
  319.     { "kl", SPEC|'B' },        /* Left arrow key        */
  320.     { "kN", SPEC|'V' },        /* Next page key        */
  321.     { "kP", SPEC|'Z' },        /* Previous page key        */
  322.     { "kR", CTRL|'Z' },        /* Scroll backward key        */
  323.     { "kr", SPEC|'F' },        /* Right arrow key        */
  324.     { "ku", SPEC|'P' },        /* Up arrow key            */
  325.         { "K1", SPEC|'<' },        /* Keypad 7 -> Home        */
  326.         { "K2", SPEC|'V' },        /* Keypad 9 -> Page Up        */
  327.         { "K3", ' ' },            /* Keypad 5             */
  328.         { "K4", SPEC|'>' },        /* Keypad 1 -> End        */
  329.         { "K5", CTRL|'V' },        /* Keypad 3 -> Page Down    */
  330.      { "kw", CTRL|'E' }        /* End of line            */
  331. };
  332. #endif /* TERMCAP */
  333. static int inbuf[NINCHAR];        /* Input buffer            */
  334. static int * inbufh =            /* Head of input buffer        */
  335.     inbuf;
  336. static int * inbuft =            /* Tail of input buffer        */
  337.     inbuf;
  338. #if TERMCAP
  339. static unsigned char outbuf[NOUTCHAR];    /* Output buffer        */
  340. static unsigned char * outbuft =     /* Output buffer tail        */
  341.     outbuf;
  342. #endif /* TERMCAP */
  343.  
  344. static DIR *dirptr = NULL;        /* Current directory stream    */
  345. static char path[NFILEN];        /* Path of file to find        */
  346. static char rbuf[NFILEN];        /* Return file buffer        */
  347. static char *nameptr;            /* Ptr past end of path in rbuf    */
  348.  
  349. /** Terminal definition block **/
  350. int scopen(), scclose(), ttgetc(), ttputc(), ttflush();
  351. int scmove(), sceeol(), sceeop(), scbeep(), screv();
  352. int sckopen(), sckclose();
  353. #if COLOR
  354. int scfcol(), scbcol();
  355. #endif /* COLOR */
  356.  
  357. #if    TERMCAP && FLABEL
  358. static void dis_sfk(), dis_ufk();
  359. #endif
  360.  
  361. TERM term = {
  362.     120,                /* Maximum number of rows    */
  363.     0,                /* Current number of rows    */
  364.     132,                /* Maximum number of columns    */
  365.     0,                /* Current number of columns    */
  366.     0, 0,                /* upper left corner default screen */
  367.     MARGIN,                /* Margin for extending lines    */
  368.     SCRSIZ,                /* Scroll size for extending    */
  369.     NPAUSE,                /* # times thru update to pause    */
  370.     scopen,                /* Open terminal routine    */
  371.     scclose,            /* Close terminal routine    */
  372.     sckopen,            /* Open keyboard routine    */
  373.     sckclose,            /* Close keyboard routine    */
  374.     ttgetc,                /* Get character routine    */
  375.     ttputc,                /* Put character routine    */
  376.     ttflush,            /* Flush output routine        */
  377.     scmove,                /* Move cursor routine        */
  378.     sceeol,                /* Erase to end of line routine    */
  379.     sceeop,                /* Erase to end of page routine    */
  380.     sceeop,                /* Clear the desktop        */
  381.     scbeep,                /* Beep! routine        */
  382.     screv,                /* Set reverse video routine    */
  383.     scnothing,            /* Set resolution routine    */
  384. #if COLOR
  385.     scfcol,                /* Set forground color routine    */
  386.     scbcol,                /* Set background color routine    */
  387. #endif /* COLOR */
  388. #if    INSDEL
  389.     scinsline,             /* insert a screen line     */
  390.     scdelline,             /* delete a screen line     */
  391. #endif    /* INSDEL */
  392. };
  393.  
  394. int hpterm;                /* global flag braindead HP-terminal */
  395.  
  396. /** Open terminal device **/
  397. int ttopen()
  398. {
  399.     strcpy(os, "UNIX");
  400. #if (BSD && !TERMIOS)
  401. #ifdef OSK
  402.     gtty(0, &ostate);                       /* save old state */
  403.     gtty(0, &nstate);                       /* get base of new state */
  404.     ospeed = ostate.sg_baud;
  405.     nstate.sg_pause = 0;    /* no pause at end of page */
  406. /*  nstate.sg_backsp = 0;*/     /* nondestructive backspace */
  407. /*  nstate.sg_delete = 0;*/ /* no delete sequence */
  408.     nstate.sg_echo = 0; /* don't echo chars */
  409.     nstate.sg_dlnch = 0xff; /* ^X delete line character */
  410.     nstate.sg_rlnch = 0xff; /* ^D reprint line character */
  411.     nstate.sg_dulnch = 0xff; /* ^A duplicate line character */
  412.     nstate.sg_psch = 0xff; /* ^W pause character */
  413.     nstate.sg_eofch = 0xff; /* escape key in OS-9 */
  414.     nstate.sg_kbich = 0xff; /* ^C interrupt character */
  415.     nstate.sg_kbach = 0xff; /* ^E abort character */
  416. /* Note ^S and ^Q are disabled! */
  417.     nstate.sg_xon = 0xff;   /* ^Q XON */
  418.     nstate.sg_xoff = 0xff;  /* ^S XOFF */
  419.  
  420.     stty(0, &nstate);                       /* set mode */
  421. #else
  422.     /* Get tty modes */
  423.     if (ioctl(0, TIOCGETP, &oldsgtty) ||
  424.         ioctl(0, TIOCGETC, &oldtchars) ||
  425.         ioctl(0, TIOCGLTC, &oldlchars))
  426.         return(-1);
  427.  
  428.     /* Save to original mode variables */
  429.     cursgtty = oldsgtty;
  430.  
  431.     /* Set new modes */
  432.     cursgtty.sg_flags |= CBREAK;
  433.     cursgtty.sg_flags &= ~(ECHO|CRMOD);
  434.  
  435.     /* Set tty modes */
  436.     if (ioctl(0, TIOCSETP, &cursgtty) ||
  437.         ioctl(0, TIOCSETC, blank) ||
  438.         ioctl(0, TIOCSLTC, blank))
  439.         return(-1);
  440. #endif
  441. #endif /* (BSD && !TERMIOS) */
  442. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX
  443.  
  444. #if SMOS
  445.     /* Extended settings; 890619mhs A3 */
  446.     set_parm(0,-1,-1);
  447. #endif /* SMOS */
  448.  
  449.     /* Get modes */
  450.     if (ioctl(0, TCGETA, &oldterm)) {
  451.         perror("Cannot TCGETA");
  452.         return(-1);
  453.     }
  454.  
  455.     /* Save to original mode variable */
  456.     curterm = oldterm;
  457.  
  458.     /* Set new modes */
  459.     /* I do not believe the flow control settings of the OS should
  460.        be diddled by an application program. But if you do, change this
  461.        1 to a 0, but be warned, all sorts of terminals will get grief
  462.        with this */
  463. #if    1
  464.     curterm.c_iflag &= ~(INLCR|ICRNL|IGNCR);
  465. #else
  466.     curterm.c_iflag &= ~(INLCR|ICRNL|IGNCR|IXON|IXANY|IXOFF);
  467. #endif
  468.  
  469.     curterm.c_lflag &= ~(ICANON|ISIG|ECHO|IEXTEN);
  470.     curterm.c_cc[VMIN] = 1;
  471.     curterm.c_cc[VTIME] = 0;
  472.  
  473. #if SMOS
  474.     /****THIS IS A BIG GUESS ON MY PART... the code changed
  475.       too much between versions for me to be sure this will work - DML */
  476.  
  477.     /* Allow multiple (dual) sessions if already enabled */
  478.     curterm.c_lflag = oldterm.c_lflag & ISIG;
  479.  
  480.     /* Use old SWTCH char if necessary */
  481.     if (curterm.c_lflag != 0)
  482.         curterm.c_cc[VSWTCH] = oldterm.c_cc[VSWTCH];
  483.  
  484.     /* Copy VTI settings    */
  485.     curterm.c_cc[VTBIT] = oldterm.c_cc[VTBIT];
  486.  
  487.     /* Extended settings; 890619mhs A3 */
  488.     set_parm(0,-1,-1);
  489. #endif /* SMOS */
  490.  
  491.     /* Set tty mode */
  492.     if (ioctl(0, TCSETA, &curterm)) {
  493.         perror("Cannot TCSETA");
  494.         return(-1);
  495.     }
  496. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX */
  497. #if (AVVION || TERMIOS)
  498.     /* Get modes */
  499.     if (tcgetattr(0, &oldterm)) {
  500.         perror("Cannot tcgetattr");
  501.         return(-1);
  502.     }
  503.  
  504.     /* Save to original mode variable */
  505.     curterm = oldterm;
  506.  
  507.     /* Set new modes */
  508.         /* disable XON/XOFF. We want to use ^S/^Q */
  509.     curterm.c_iflag &= ~(INLCR|ICRNL|IGNCR|IXON|IXANY|IXOFF);
  510.     curterm.c_lflag &= ~(ICANON|ISIG|ECHO|IEXTEN);
  511.     curterm.c_cc[VMIN] = 1;
  512.     curterm.c_cc[VTIME] = 0;
  513. #ifdef    VLNEXT
  514.     curterm.c_cc[VLNEXT] = -1;
  515. #endif
  516.  
  517. #if    AVVION
  518.     /* Set line discipline for Data General */
  519.     curterm.c_line = 0;
  520. #endif
  521.  
  522.     /* Set tty mode */
  523.     if (tcsetattr(0, TCSANOW, &curterm)) {
  524.         perror("Cannot tcsetattr");
  525.         return(-1);
  526.     }
  527. #endif /* (AVVION || TERMIOS) */
  528.  
  529.     /* Success */
  530.     return(0);
  531. }
  532.  
  533. /** Close terminal device **/
  534. int ttclose()
  535. {
  536. #if ((AIX == 0) && (TERMIOS == 0)) || (FREEBSD == 1)
  537.     /* Restore original terminal modes */
  538.     if (reset != (char*)NULL)
  539.         write(1, reset, strlen(reset));
  540. #endif
  541.  
  542. #if (BSD && !TERMIOS)
  543. #ifdef OSK
  544.         stty(0, &ostate);
  545. #else
  546.     if (ioctl(0, TIOCSETP, &oldsgtty) ||
  547.         ioctl(0, TIOCSETC, &oldtchars) ||
  548.         ioctl(0, TIOCSLTC, &oldlchars))
  549. #endif
  550.         return(-1);
  551. #endif /* (BSD && !TERMIOS) */
  552.  
  553. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX
  554. #if SMOS
  555.     /* Extended settings; 890619mhs A3 */
  556.     set_parm(0,-1,-1);
  557. #endif /* SMOS */
  558.     if (ioctl(0, TCSETA, &oldterm))
  559.         return(-1);
  560. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX */
  561.  
  562. #if (AVVION || TERMIOS)
  563.     /* Set tty mode */
  564.     if (tcsetattr(0, TCSANOW, &oldterm)) {
  565.         perror("Cannot tcsetattr");
  566.         return(-1);
  567.     }
  568. #endif /* (AVVION || TERMIOS) */
  569.  
  570.     /* Success */
  571.     return(0);
  572. }
  573.  
  574. /** Flush output buffer to display **/
  575. int ttflush()
  576. {
  577. #if TERMCAP
  578.     int len;
  579.  
  580.     /* Compute length of write */
  581.     len = outbuft - outbuf;
  582.     if (len == 0)
  583.         return(0);
  584.  
  585.     /* Reset buffer position */
  586.     outbuft = outbuf;
  587.  
  588.     /* Perform write to screen */
  589.     return(write(1, outbuf, len) != len);
  590. #else /* TERMCAP */
  591. #if    CURSES
  592.     refresh();
  593. #endif /* CURSES */
  594.     return(0);
  595. #endif    /* TERMCAP */
  596. }
  597.  
  598. /** Put character onto display **/
  599. int ttputc(ch)
  600. char ch;                /* Character to display        */
  601. {
  602. #if TERMCAP
  603.     /* Check for buffer full */
  604.     if (outbuft == &outbuf[sizeof(outbuf)])
  605.         ttflush();
  606.  
  607.     /* Add to buffer */
  608.     *outbuft++ = ch;
  609. #endif /* TERMCAP */
  610.  
  611. #if CURSES
  612.     /* Put character on screen */
  613.     addch(ch);
  614. #endif /* CURSES */
  615.  
  616.     return(0);
  617. }
  618.  
  619.  
  620. /** Grab input characters, with wait **/
  621. unsigned char grabwait()
  622. {
  623. #if (BSD && !TERMIOS)
  624.     unsigned char ch;
  625.  
  626.     /* Perform read */
  627.     if (read(0, &ch, 1) != 1) {
  628.         puts("** Horrible read error occured **");
  629.         exit(1);
  630.     }
  631.     return(ch);
  632. #endif /* (BSD && !TERMIOS) */
  633. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX || (AVVION || TERMIOS)
  634.     unsigned char ch;
  635.  
  636.     /* Change mode, if necessary */
  637.     if (curterm.c_cc[VTIME]) {
  638.         curterm.c_cc[VMIN] = 1;
  639.         curterm.c_cc[VTIME] = 0;
  640. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX
  641.         ioctl(0, TCSETA, &curterm);
  642. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX */
  643. #if (AVVION || TERMIOS)
  644.         tcsetattr(0, TCSANOW, &curterm);
  645. #endif /* (AVVION || TERMIOS) */        
  646.     }
  647.  
  648.     /* Perform read */
  649. #if HANDLE_WINCH
  650.     while (read(0, &ch, 1) != 1) {
  651.         if (winch_flag)
  652.             return 0;
  653.     }
  654. #else
  655.     if (read(0, &ch, 1) != 1) {
  656.         puts("** Horrible read error occured **");
  657.         exit(1);
  658.     }
  659. #endif
  660.     /* Return new character */
  661.     return(ch);
  662. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX || (AVVION || TERMIOS) */
  663. }
  664.  
  665. /** Grab input characters, short wait **/
  666. unsigned char grabnowait()
  667. {
  668. #if (BSD && !TERMIOS)
  669.     static struct timeval timout = { 0, 500000L };
  670.     int count, r;
  671.  
  672.     /* Select input */
  673.     r = 1;
  674.     count = select(1, &r, NULL, NULL, &timout);
  675.     if (count == 0)
  676.         return(TIMEOUT);
  677.     if (count < 0) {
  678.         puts("** Horrible select error occured **");
  679.         exit(1);
  680.     }
  681.  
  682.     /* Perform read */
  683.     return(grabwait());
  684. #endif /* (BSD && !TERMIOS) */
  685. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX || (AVVION || TERMIOS)
  686.     int count;
  687.     unsigned char ch;
  688.  
  689.     /* Change mode, if necessary */
  690.     if (curterm.c_cc[VTIME] == 0) {
  691.         curterm.c_cc[VMIN] = 0;
  692.         curterm.c_cc[VTIME] = 5;
  693. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX
  694.         ioctl(0, TCSETA, &curterm);
  695. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX */
  696. #if (AVVION || TERMIOS)
  697.         tcsetattr(0, TCSANOW, &curterm);
  698. #endif /* (AVVION || TERMIOS) */        
  699.     }
  700.  
  701.     /* Perform read */
  702. #if HANDLE_WINCH
  703.     while ((count = read(0, &ch, 1)) < 0) {
  704.         if (winch_flag)
  705.             return 0;
  706.     }
  707. #else
  708.     count = read(0, &ch, 1);
  709.     if (count < 0) {
  710.         puts("** Horrible read error occured **");
  711.         exit(1);
  712.     }
  713. #endif
  714.     if (count == 0)
  715.         return(TIMEOUT);
  716.  
  717.     /* Return new character */
  718.     return(ch);
  719. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX || (AVVION || TERMIOS) */
  720. }
  721.  
  722. /*
  723.  * qin - queue in a character to the input buffer.
  724.  */
  725. #if PROTO
  726. VOID qin(int ch)
  727. #else
  728. VOID qin( ch)
  729. int ch;
  730. #endif
  731. {
  732.     /* Check for overflow */
  733.     if (inbuft == &inbuf[sizeof(inbuf)]) {
  734.         /* Annoy user */
  735.         scbeep();
  736.         return;
  737.     }
  738.     
  739.     /* Add character */
  740.     *inbuft++ = ch;
  741. }
  742.  
  743. /*
  744.  * qrep - replace a key sequence with a single character in the input buffer.
  745.  */
  746. #if PROTO
  747. VOID qrep(int ch)
  748. #else
  749. VOID qrep( ch)
  750. int ch;
  751. #endif
  752. {
  753.     inbuft = inbuf;
  754.     qin(ch);
  755. }
  756.  
  757. #if MM1
  758. /** Return cooked characters **/
  759. int ttgetc()
  760. {
  761.    int ch;
  762.  
  763.    for (;;) {
  764.       if (inbufh != inbuft) {
  765.          /* Get input from buffer, now that it is available */
  766.          ch = *inbufh++;
  767.  
  768.          /* reset us to the beginning of the buffer if there are no more
  769.           * pending characters */
  770.          if (inbufh == inbuft)
  771.             inbufh = inbuft = inbuf;
  772.  
  773.          /* Return next character */
  774.          return (ch);
  775.       }
  776.       if (typahead())
  777.          cook();
  778.  
  779.       for (;;) {
  780.          if (typahead())
  781.             break;
  782.          if (checkmouse())
  783.             break;
  784.          tsleep(2);
  785.       }
  786.    }
  787. }
  788.  
  789. #include <mouse.h>
  790.  
  791. MSRET ms;
  792. int oldbut, oldcol, oldrow;
  793. int nbuttons = 3;
  794. extern short fontszx, fontszy;
  795.  
  796. checkmouse()
  797. {
  798.    register int k;              /* current bit/button of mouse */
  799.    register int etype;          /* event type byte */
  800.    register int event;          /* encoded mouse event */
  801.    int mousecol;                /* current mouse column */
  802.    int mouserow;                /* current mouse row */
  803.    int sstate;                  /* current shift key status */
  804.    int newbut;                  /* new state of the mouse buttons */
  805.  
  806.    /* check to see if any mouse buttons are different */
  807.    _gs_mouse(1, &ms);           /* button status and mouse position */
  808.    if ( ms.pt_valid ) {
  809.       newbut = ms.pt_cbsa + 2 * ms.pt_cbsb + 4 * ms.pt_cbsc;
  810.  
  811.       mousecol = ms.pt_wrx / fontszx;
  812.       mouserow = ms.pt_wry / fontszy;
  813.  
  814.       /* only notice changes */
  815.       if ((oldbut == newbut) && (mousecol == oldcol) && (mouserow == oldrow))
  816.          return (FALSE);
  817.  
  818.       /* get the shift key status as well */
  819.       etype = MOUS >> 8;
  820.       sstate = 0;
  821. #if 0
  822.       rg.h.ah = 2;                 /* return current shift status */
  823.       int86(0x16, &rg, &rg);
  824.       sstate = rg.h.al;
  825.       if (sstate & 3)              /* shifted? */
  826.          etype |= (SHFT >> 8);
  827.       if (sstate & 4)              /* controled? */
  828.          etype |= (CTRL >> 8);
  829. #endif
  830.  
  831.       /* no buttons changes */
  832.       if (oldbut == newbut) {
  833.  
  834.          /* generate a mouse movement */
  835.          if (((mouse_move == 1) && (mmove_flag == TRUE)) || (mouse_move == 2)) {
  836.             qin(0);
  837.             qin(etype);
  838.             qin(mousecol);
  839.             qin(mouserow);
  840.             qin('m');
  841.          }
  842.          oldcol = mousecol;
  843.          oldrow = mouserow;
  844.          return (TRUE);
  845.       }
  846.       /* only on screen presses are legit! */
  847.       if (mousecol < 0)
  848.          mousecol = 0;
  849.       if (mouserow < 0)
  850.          mouserow = 0;
  851.  
  852.       for (k = 1; k != (1 << nbuttons); k = k << 1) {
  853.          /* For each button on the mouse */
  854.          if ((oldbut & k) != (newbut & k)) {
  855.             /* This button changed, generate an event */
  856.             qin(0);
  857.             qin(etype);
  858.             qin(mousecol);
  859.             qin(mouserow);
  860.  
  861.             event = ((newbut & k) ? 0 : 1);        /* up or down? */
  862.             if (k == 2)            /* center button? */
  863.                event += 4;
  864.             if (k == 4)            /* right button? */
  865.                event += 2;
  866.             event += 'a';          /* plain */
  867.             qin(event);
  868.             oldbut = newbut;
  869.             oldcol = mousecol;
  870.             oldrow = mouserow;
  871.             return (TRUE);
  872.          }
  873.       }
  874.    } else
  875.       tsleep(20);
  876.  
  877.    return (FALSE);
  878. }
  879. #else
  880.  
  881. /** Return cooked characters **/
  882. int ttgetc()
  883. {
  884.     int ch;
  885. ttflush();
  886.     /* Loop until character is in input buffer */
  887.     while (inbufh == inbuft)
  888.         cook();
  889.     
  890.     /* Get input from buffer, now that it is available */
  891.     ch = *inbufh++;
  892.  
  893.     /* reset us to the beginning of the buffer if there are no more
  894.        pending characters */
  895.     if (inbufh == inbuft)
  896.         inbufh = inbuft = inbuf;
  897.     
  898.     /* Return next character */
  899.     return(ch);
  900. }
  901. #endif /* MM1 */
  902.  
  903. #if TYPEAH
  904. int typahead()
  905. {
  906.     int count;
  907.  
  908.     /* See if internal buffer is non-empty */
  909.     if (inbufh != inbuft)
  910.         return(1);
  911. #ifdef  OSK
  912.     count = _gs_rdy(0);
  913.     return(count <= 0 ? 0 : count);
  914. #else
  915.  
  916.     /* Now check with system */
  917. #ifdef FIONREAD  /* Watch out!  This could bite you! */
  918.     /* Get number of pending characters */
  919.     if (ioctl(0, FIONREAD, &count))
  920.         return(0);
  921.     return(count);
  922. #else /* not FIONREAD */
  923. #ifdef VAT
  924.     return(0);
  925. #else /* not VAT */
  926.     /* Ask hardware for count */
  927.     count = ioctl(0, FIORDCHK, 0);
  928.     if (count < 0)
  929.         return(0);
  930.     return(count);
  931. #endif    /* VAT */
  932. #endif /* FIONREAD */
  933. #endif /* OSK */
  934. }
  935. #endif /* TYPEAH */
  936.  
  937. #if TERMCAP || TERMIOS
  938. /** Put out sequence, with padding **/
  939. void putpad(seq)
  940. char * seq;                /* Character sequence        */
  941. {
  942.     /* Check for null */
  943.     if (!seq)
  944.         return;
  945.  
  946.     /* Call on termcap to send sequence */
  947.     tputs(seq, 1, ttputc);
  948. }
  949. #endif /* TERMCAP */
  950.  
  951. /** Initialize screen package **/
  952. int scopen()
  953. {
  954. #if TERMCAP || TERMIOS
  955.     char * cp, tcbuf[1024];
  956.     int status;
  957.     struct capbind * cb;
  958.     struct keybind * kp;
  959.     char err_str[NSTRING];
  960.  
  961.     char  * tgetstr();
  962.  
  963. #ifndef VAT
  964. #define TGETSTR(a,b)    tgetstr((a), (b))
  965. #else
  966. #define TGETSTR(a,b)    tgetstr((a), *(b))
  967. #endif
  968.  
  969. #if HPUX8 || HPUX9 || VAT || AUX || (AVVION || TERMIOS) || AIX
  970.  
  971.     /* HP-UX and AUX doesn't seem to have these in the termcap library */
  972.     char PC, * UP;
  973.     short ospeed;
  974. #else /* not HPUX8 || HPUX9 || VAT || AUX */
  975.     extern char PC, * UP;
  976.     extern short ospeed;
  977. #endif /* HPUX8 || HPUX9 || VAT || AUX */
  978.  
  979.     /* Get terminal type */
  980.     cp = getenv("TERM");
  981.     if (!cp) {
  982.         puts(TEXT182);
  983. /*        "Environment variable \"TERM\" not define!" */
  984.         exit(1);
  985.     }
  986.  
  987.     /* Try to load termcap */
  988.     status = tgetent(tcbuf, cp);
  989.     if (status == -1) {
  990.         puts("Cannot open termcap file");
  991.         exit(1);
  992.     }
  993.     if (status == 0) {
  994.         sprintf(err_str, TEXT183, cp);
  995. /*        "No entry for terminal type \"%s\"\n" */
  996.         puts(err_str);
  997.         exit(1);
  998.     }
  999.  
  1000.     /* Get size from termcap */
  1001.     term.t_nrow = tgetnum("li") - 1;
  1002.     term.t_ncol = tgetnum("co");
  1003. #ifdef OSK
  1004. {   int col, row;
  1005.  
  1006. #ifdef MM1
  1007.     Palette(1, 0,   0,   0,   0);  /* black */
  1008.     Palette(1, 1, 210,   0,   0);  /* red */
  1009.     Palette(1, 2,   0, 210,   0);  /* green */
  1010.     Palette(1, 3, 230, 230,   0);  /* yellow */
  1011.     Palette(1, 4,   0,   0, 210);  /* blue */
  1012.     Palette(1, 5, 230,   0, 230);  /* magenta */
  1013.     Palette(1, 6,   0, 230, 230);  /* cyan */
  1014.     Palette(1, 7, 210, 210, 210);  /* white */
  1015.  
  1016.     if ( _gs_scsz(1, &col, &row) != -1 ) {
  1017.        term.t_ncol = col;
  1018.        term.t_nrow = row - 1;
  1019.     }
  1020. #endif
  1021. }
  1022. #endif
  1023.     if (term.t_nrow < 3 || term.t_ncol < 3) {
  1024.         puts("Screen size is too small!");
  1025.         exit(1);
  1026.     }
  1027.  
  1028.     /* initialize max number of rows and cols     */
  1029.     term.t_mrow = term.t_nrow;
  1030.     term.t_mcol = term.t_ncol;
  1031.  
  1032.     /* Start grabbing termcap commands */
  1033.     cp = tcapbuf;
  1034.  
  1035.     /* Get the reset string */
  1036.     reset = TGETSTR("is", &cp);
  1037.  
  1038.     /* Get the pad character */
  1039.     if (tgetstr("pc", &cp))
  1040.         PC = tcapbuf[0];
  1041.  
  1042.     /* Get up line capability */
  1043.     UP = TGETSTR("up", &cp);
  1044.  
  1045.     /* Get other capabilities */
  1046.     cb = capbind;
  1047.     while (cb < &capbind[sizeof(capbind)/sizeof(*capbind)]) {
  1048.         cb->store = TGETSTR(cb->name, &cp);
  1049.         cb++;
  1050.     }
  1051.  
  1052.     /* Check for minimum */
  1053.     if (!capbind[CAP_CL].store && (!capbind[CAP_CM].store || !UP)) {
  1054.         puts("This terminal doesn't have enough power to run microEmacs!");
  1055.         exit(1);
  1056.     }
  1057.  
  1058.     /* Set reverse video and erase to end of line */
  1059.     if (capbind[CAP_SO].store && capbind[CAP_SE].store)
  1060.         revexist = TRUE;
  1061.     if (!capbind[CAP_CE].store)
  1062.         eolexist = FALSE;
  1063.  
  1064.     /* Get keybindings */
  1065.     kp = keybind;
  1066.     while (kp < &keybind[sizeof(keybind)/sizeof(*keybind)]) {
  1067.         addkey(TGETSTR(kp->name, &cp), kp->value);
  1068.         kp++;
  1069.     }
  1070.  
  1071.     /* check for HP-Terminal (so we can label its function keys) */
  1072.     hpterm = tgetflag("xs");
  1073.  
  1074.     /* Open terminal device */
  1075.     if (ttopen()) {
  1076.         puts("Cannot open terminal");
  1077.         exit(1);
  1078.     }
  1079.  
  1080.     /* Set speed for padding sequences */
  1081. #if (BSD && !TERMIOS)
  1082. #ifndef OSK
  1083.     ospeed = cursgtty.sg_ospeed;
  1084. #endif
  1085. #endif /* (BSD && !TERMIOS) */
  1086. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX
  1087.     ospeed = curterm.c_cflag & CBAUD;
  1088. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX */
  1089. #if (AVVION || TERMIOS)
  1090.     ospeed = cfgetospeed(&curterm);
  1091. #endif /* (AVVION || TERMIOS) */
  1092.     
  1093.     /* Send out initialization sequences */
  1094. #if AIX == 0
  1095.     putpad(capbind[CAP_IS].store);
  1096. #endif
  1097.     putpad(capbind[CAP_KS].store);
  1098.     sckopen();
  1099. #endif /* TERMCAP */
  1100.  
  1101. #if CURSES
  1102.     /* Initialize screen */
  1103.     initscr();
  1104.  
  1105.     /* Set size of screen */
  1106.     term.t_nrow = LINES - 1;
  1107.     term.t_ncol = COLS;
  1108.  
  1109.     /* Open terminal device */
  1110.     if (ttopen()) {
  1111.         puts("Cannot open terminal");
  1112.         exit(1);
  1113.     }
  1114. #endif /* CURSES */
  1115.  
  1116.     /* Success */
  1117.     return(0);
  1118. }
  1119.  
  1120. /** Close screen package **/
  1121. int scclose()
  1122. {
  1123. #if TERMCAP
  1124.     /* Turn off keypad mode */
  1125.     putpad(capbind[CAP_KE].store);
  1126.     sckclose();
  1127.  
  1128.     /* Close terminal device */
  1129.     ttflush();
  1130.     ttclose();
  1131. #endif /* TERMCAP */
  1132.  
  1133. #if    TERMIOS
  1134.     /* Close terminal device */
  1135.     ttflush();
  1136.     ttclose();
  1137. #endif    /* TERMIOS */
  1138.  
  1139. #if CURSES
  1140.     /* Turn off curses */
  1141.     endwin();
  1142.  
  1143.     /* Close terminal device */
  1144.     ttflush();
  1145.     ttclose();
  1146. #endif /* CURSES */
  1147.  
  1148. #if MM1
  1149.     DefColr(1);
  1150.     BColor(1, 2);
  1151. #endif
  1152.  
  1153.     /* Success */
  1154.     return(0);
  1155. }
  1156.  
  1157. /* open keyboard -hm */
  1158. int sckopen()
  1159. {
  1160. #if TERMCAP
  1161.     putpad(capbind[CAP_KS].store);
  1162.     ttflush();
  1163. #if    FLABEL
  1164.     dis_ufk();
  1165. #endif
  1166. #endif
  1167. }
  1168.  
  1169. /* close keyboard -hm */
  1170. int sckclose()
  1171. {
  1172. #if TERMCAP
  1173.     putpad(capbind[CAP_KE].store);
  1174.     ttflush();
  1175. #if    FLABEL
  1176.     dis_sfk();
  1177. #endif
  1178. #endif
  1179. }
  1180.  
  1181. /** Move cursor **/
  1182. int scmove(row, col)
  1183. int row;                /* Row number            */
  1184. int col;                /* Column number        */
  1185. {
  1186.     char *tgoto();
  1187.  
  1188. #if TERMCAP || TERMIOS
  1189.     /* Call on termcap to create move sequence */
  1190.     putpad(tgoto(capbind[CAP_CM].store, col, row));
  1191. #endif /* TERMCAP */
  1192.  
  1193. #if CURSES
  1194.     move(row, col);
  1195. #endif /* CURSES */
  1196.  
  1197.     /* Success */
  1198.     return(0);
  1199. }
  1200.  
  1201. /** Erase to end of line **/
  1202. int sceeol()
  1203. {
  1204. #if TERMCAP || TERMIOS
  1205.     /* Send erase sequence */
  1206.     putpad(capbind[CAP_CE].store);
  1207. #endif /* TERMCAP */
  1208.  
  1209. #if CURSES
  1210.     clrtoeol();
  1211. #endif /* CURSES */
  1212.  
  1213.     /* Success */
  1214.     return(0);
  1215. }
  1216.  
  1217. /** Clear screen **/
  1218. int sceeop()
  1219. {
  1220. #if TERMCAP || TERMIOS
  1221. #if COLOR
  1222.     scfcol(gfcolor);
  1223.     scbcol(gbcolor);
  1224. #endif /* COLOR */
  1225.     /* Send clear sequence */
  1226.     putpad(capbind[CAP_CL].store);
  1227. #endif /* TERMCAP */
  1228.  
  1229. #if CURSES
  1230.     erase();
  1231. #endif /* CURSES */
  1232.  
  1233.  
  1234.     /* Success */
  1235.     return(0);
  1236. }
  1237.  
  1238. /** Set reverse video state **/
  1239. int screv(state)
  1240. int state;                /* New state            */
  1241. {
  1242. #if TERMCAP || TERMIOS
  1243. #if COLOR
  1244.     int ftmp, btmp;        /* temporaries for colors */
  1245. #endif /* COLOR */
  1246.  
  1247.     /* Set reverse video state */
  1248.     putpad(state ? capbind[CAP_SO].store : capbind[CAP_SE].store);
  1249.  
  1250. #if COLOR
  1251.     if (state == FALSE) {
  1252.         ftmp = cfcolor;
  1253.         btmp = cbcolor;
  1254.         cfcolor = -1;
  1255.         cbcolor = -1;
  1256.         scfcol(ftmp);
  1257.         scbcol(btmp);
  1258.     }
  1259. #endif /* COLOR */
  1260. #endif /* TERMCAP */
  1261.  
  1262. #if CURSES
  1263.     if (state)
  1264.         standout();
  1265.     else
  1266.         standend();
  1267. #endif /* CURSES */
  1268.  
  1269.     /* Success */
  1270.     return(0);
  1271. }
  1272.  
  1273. /** Beep **/
  1274. scbeep()
  1275. {
  1276. #if TERMCAP || TERMIOS
  1277. #if !NOISY
  1278.     /* Send out visible bell, if it exists */
  1279.     if (capbind[CAP_VB].store)
  1280.         putpad(capbind[CAP_VB].store);
  1281.     else
  1282. #endif /* not NOISY */
  1283.         /* The old standby method */
  1284.         ttputc('\7');
  1285. #endif /* TERMCAP */
  1286.  
  1287. #if CURSES
  1288.     addch('\7');        /* FIX THIS! beep() and flash comes up undefined */
  1289. #endif /* CURSES */
  1290.  
  1291.     /* Success */
  1292.     return(0);
  1293. }
  1294.  
  1295. #if COLOR
  1296. static char cmap[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
  1297.  
  1298. /** Set foreground color **/
  1299. int scfcol(color)
  1300. int color;        /* Color to set            */
  1301. {
  1302. #if TERMCAP || TERMIOS
  1303.     /* Skip if already the correct color */
  1304.     if (color == cfcolor)
  1305.         return(0);
  1306.  
  1307.     /* Send out color sequence */
  1308.     if (capbind[CAP_C0].store) {
  1309.         putpad(capbind[CAP_C0 + (color & 7)].store);
  1310.         cfcolor = color;
  1311.     }
  1312. #if USG || AUX
  1313.     else if (capbind[CAP_SF].store) {
  1314.         putpad(tparm(capbind[CAP_SF].store, cmap[color & 7]));
  1315.         cfcolor = color;
  1316.     }
  1317. #endif /* USG || AUX */
  1318. #endif /* TERMCAP */
  1319.  
  1320. #if CURSES
  1321.     /* ? */
  1322. #endif /* CURSES */
  1323.     return(0);
  1324. }
  1325.  
  1326. /** Set background color **/
  1327. int scbcol(color)
  1328. int color;            /* Color to set            */
  1329. {
  1330. #if TERMCAP || TERMIOS
  1331.     /* Skip if already the correct color */
  1332.     if (color == cbcolor)
  1333.         return(0);
  1334.  
  1335.     /* Send out color sequence */
  1336.     if (capbind[CAP_C0].store) {
  1337.         putpad(capbind[CAP_D0 + (color & 7)].store);
  1338.         cbcolor = color;
  1339.     }
  1340. #if USG || AUX
  1341.     else if (capbind[CAP_SB].store) {
  1342.         putpad(tparm(capbind[CAP_SB].store, cmap[color & 7]));
  1343.         cbcolor = color;
  1344.     }
  1345. #endif /* USG || AUX */
  1346. #endif /* TERMCAP */
  1347.  
  1348. #if CURSES
  1349.     /* ? */
  1350. #endif /* CURSES */
  1351.     return(0);
  1352. }
  1353. #endif /* COLOR */
  1354.  
  1355. /** Set palette **/
  1356. int spal(cmd)
  1357. char * cmd;                /* Palette command        */
  1358. {
  1359.     int code, dokeymap;
  1360.     char * cp;
  1361.  
  1362.     /* Check for keymapping command */
  1363.     if (strncmp(cmd, "KEYMAP ", 7) == 0)
  1364.         dokeymap = 1;
  1365.     else
  1366. #if TERMCAP
  1367. #if COLOR
  1368.     if (strncmp(cmd, "CLRMAP ", 7) == 0)
  1369.         dokeymap = 0;
  1370.     else
  1371. #endif /* COLOR */
  1372. #endif /* TERMCAP */
  1373.         return(0);
  1374.     cmd += 7;
  1375.  
  1376.     /* Look for space */
  1377.     for (cp = cmd; *cp != '\0'; cp++)
  1378.         if (*cp == ' ') {
  1379.             *cp++ = '\0';
  1380.             break;
  1381.         }
  1382.     if (*cp == '\0')
  1383.         return(1);
  1384.  
  1385.     /* Perform operation */
  1386.     if (dokeymap) {
  1387.  
  1388.         /* Convert to keycode */
  1389.         code = stock(cmd);
  1390.  
  1391.         /* Add to tree */
  1392.         addkey(cp, code);
  1393.     }
  1394. #if TERMCAP
  1395. #if COLOR
  1396.     else {
  1397.  
  1398.         /* Convert to color number */
  1399.         code = atoi(cmd);
  1400.         if (code < 0 || code > 15)
  1401.             return(1);
  1402.  
  1403.         /* Move color code to capability structure */
  1404.         capbind[CAP_C0 + code].store = malloc(strlen(cp) + 1);
  1405.         if (capbind[CAP_C0 + code].store)
  1406.             strcpy(capbind[CAP_C0 + code].store, cp);
  1407.     }
  1408. #endif /* COLOR */
  1409. #endif /* TERMCAP */
  1410.     return(0);
  1411. }
  1412.  
  1413. #if BSD || FREEBSD || SUN || HPUX8 || HPUX9 || (AVVION || TERMIOS)
  1414. /* Surely more than just BSD systems do this */
  1415.  
  1416. #ifndef OSK
  1417. /** Perform a stop signal **/
  1418. int bktoshell(f, n)
  1419. {
  1420.     /* Reset the terminal and go to the last line */
  1421.     vttidy();
  1422.     
  1423.     /* Okay, stop... */
  1424.     kill(getpid(), SIGTSTP);
  1425.  
  1426.     /* We should now be back here after resuming */
  1427.  
  1428.     /* Reopen the screen and redraw */
  1429.     scopen();
  1430.     curwp->w_flag = WFHARD;
  1431.     sgarbf = TRUE;
  1432.  
  1433.     /* Success */
  1434.     return(0);
  1435. }
  1436. #endif
  1437. #endif /* BSD || FREEBSD || SUN || HPUX8 || HPUX9 || (AVVION || TERMIOS) */
  1438.  
  1439. /** Get time of day **/
  1440. char * timeset()
  1441. {
  1442.     long int buf; /* Should be time_t */
  1443.     char * sp, * cp;
  1444.  
  1445. #ifndef OSK
  1446.     char * ctime();
  1447. #endif
  1448.  
  1449.     /* Get system time */
  1450.     time(&buf);
  1451.  
  1452.     /* Pass system time to converter */
  1453.     sp = ctime(&buf);
  1454.  
  1455.     /* Eat newline character */
  1456.     for (cp = sp; *cp; cp++)
  1457.         if (*cp == '\n') {
  1458.             *cp = '\0';
  1459.             break;
  1460.         }
  1461.     return(sp);
  1462. }
  1463.  
  1464. #if USG || AUX || SMOS || HPUX8 || XENIX
  1465. /** Rename a file **/
  1466. int rename(file1, file2)
  1467. char * file1;                /* Old file name        */
  1468. char * file2;                /* New file name        */
  1469. {
  1470.     struct stat buf1;
  1471.     struct stat buf2;
  1472.  
  1473.     /* No good if source file doesn't exist */
  1474.     if (stat(file1, &buf1))
  1475.         return(-1);
  1476.  
  1477.     /* Check for target */
  1478.     if (stat(file2, &buf2) == 0) {
  1479.  
  1480.         /* See if file is the same */
  1481.         if (buf1.st_dev == buf2.st_dev &&
  1482.             buf1.st_ino == buf2.st_ino)
  1483.  
  1484.             /* Not necessary to rename file */
  1485.             return(0);
  1486.     }
  1487.  
  1488.     /* Get rid of target */
  1489.     unlink(file2);
  1490.  
  1491.     /* Link two files together */
  1492.     if (link(file1, file2))
  1493.         return(-1);
  1494.  
  1495.     /* Unlink original file */
  1496.     return(unlink(file1));
  1497. }
  1498. #endif /* USG || AUX || SMOS || HPUX8 || XENIX */
  1499.  
  1500. /** Callout to system to perform command **/
  1501. int callout(cmd)
  1502. char * cmd;                /* Command to execute        */
  1503. {
  1504.     int status;
  1505.  
  1506.     /* Close down */
  1507.     scmove(term.t_nrow, 0);
  1508.     ttflush();
  1509.     sckclose();
  1510.     ttclose();
  1511.  
  1512.     /* Do command */
  1513.     status = system(cmd) == 0;
  1514.  
  1515.     /* Restart system */
  1516.         sgarbf = TRUE;
  1517.     sckopen();
  1518.     if (ttopen()) {
  1519.         puts("** Error reopening terminal device **");
  1520.         exit(1);
  1521.     }
  1522.  
  1523.     /* Success */
  1524.         return(status);
  1525. }
  1526.  
  1527. /** Create subshell **/
  1528. int spawncli(f, n)
  1529. int f;                    /* Flags            */
  1530. int n;                    /* Argument count        */
  1531. {
  1532.     char * sh;
  1533.  
  1534.     /* Don't allow this command if restricted */
  1535.     if (restflag)
  1536.         return(resterr());
  1537.  
  1538.     /* Get shell path */
  1539.     sh = getenv("SHELL");
  1540.     if (!sh)
  1541. #if BSD || FREEBSD || SUN
  1542.         sh = "/bin/csh";
  1543. #endif /* BSD || FREEBSD || SUN */
  1544. #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || XENIX || (AVVION || TERMIOS)
  1545.         sh = "/bin/sh";
  1546. #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || XENIX || (AVVION || TERMIOS) */
  1547.  
  1548.     /* Do shell */
  1549.     return(callout(sh));
  1550. }
  1551.  
  1552. /** Spawn a command **/
  1553. int spawn(f, n)
  1554. int f;                    /* Flags            */
  1555. int n;                    /* Argument count        */
  1556. {
  1557.     char line[NLINE];
  1558.     int s;
  1559.  
  1560.     /* Don't allow this command if restricted */
  1561.     if (restflag)
  1562.         return(resterr());
  1563.  
  1564.     /* Get command line */
  1565.     s = mlreply("!", line, NLINE);
  1566.     if (!s)
  1567.         return(s);
  1568.  
  1569.     /* Perform the command */
  1570.     s = callout(line);
  1571.  
  1572.     /* if we are interactive, pause here */
  1573.     if (clexec == FALSE) {
  1574.             mlwrite("[End]");
  1575.         ttflush();
  1576.         ttgetc();
  1577.         }
  1578.         return(s);
  1579. }
  1580.  
  1581. /** Execute program **/
  1582. int execprg(f, n)
  1583. int f;                    /* Flags            */
  1584. int n;                    /* Argument count        */
  1585. {
  1586.     /* Same as spawn */
  1587.     return(spawn(f, n));
  1588. }
  1589.  
  1590. /** Pipe output of program to buffer **/
  1591. int pipecmd(f, n)
  1592. int f;                    /* Flags            */
  1593. int n;                    /* Argument count        */
  1594. {
  1595.     char line[NLINE];
  1596.     int s;
  1597.     BUFFER * bp;
  1598.     EWINDOW * wp;
  1599.     static char filnam[] = "command";
  1600.  
  1601.     /* Don't allow this command if restricted */
  1602.     if (restflag)
  1603.         return(resterr());
  1604.  
  1605.     /* Get pipe-in command */
  1606.     s = mlreply("@", line, NLINE);
  1607.     if (!s)
  1608.         return(s);
  1609.  
  1610.     /* Get rid of the command output buffer if it exists */
  1611.     bp = bfind(filnam, FALSE, 0);
  1612.     if (bp) {
  1613.         /* Try to make sure we are off screen */
  1614.         wp = wheadp;
  1615.         while (wp) {
  1616.             if (wp->w_bufp == bp) {
  1617.                 onlywind(FALSE, 1);
  1618.                 break;
  1619.             }
  1620.             wp = wp->w_wndp;
  1621.         }
  1622.         if (!zotbuf(bp))
  1623.             return(0);
  1624.     }
  1625.  
  1626.     /* Add output specification */
  1627.     strcat(line, ">");
  1628.     strcat(line, filnam);
  1629.  
  1630.     /* Do command */
  1631.     s = callout(line);
  1632.     if (!s)
  1633.         return(s);
  1634.  
  1635.     /* Split the current window to make room for the command output */
  1636.     if (!splitwind(FALSE, 1))
  1637.         return(0);
  1638.  
  1639.     /* ...and read the stuff in */
  1640.     if (!getfile(filnam, FALSE))
  1641.         return(0);
  1642.  
  1643.     /* Make this window in VIEW mode, update all mode lines */
  1644.     curwp->w_bufp->b_mode |= MDVIEW;
  1645.     wp = wheadp;
  1646.     while (wp) {
  1647.         wp->w_flag |= WFMODE;
  1648.         wp = wp->w_wndp;
  1649.     }
  1650.  
  1651.     /* ...and get rid of the temporary file */
  1652.     unlink(filnam);
  1653.     return(1);
  1654. }
  1655.  
  1656. /** Filter buffer through command **/
  1657. int filter(f, n)
  1658. int f;                    /* Flags            */
  1659. int n;                    /* Argument count        */
  1660. {
  1661.     char line[NLINE], tmpnam[NFILEN];
  1662.     int s;
  1663.     BUFFER * bp;
  1664.     static char bname1[] = "fltinp";
  1665.     static char filnam1[] = "fltinp";
  1666.     static char filnam2[] = "fltout";
  1667.  
  1668.     /* Don't allow this command if restricted */
  1669.     if (restflag)
  1670.         return(resterr());
  1671.  
  1672.     /* Don't allow filtering of VIEW mode buffer */
  1673.     if (curbp->b_mode & MDVIEW)
  1674.         return(rdonly());
  1675.  
  1676.     /* Get the filter name and its args */
  1677.     s = mlreply("#", line, NLINE);
  1678.     if (!s)
  1679.         return(s);
  1680.  
  1681.     /* Setup the proper file names */
  1682.     bp = curbp;
  1683.     strcpy(tmpnam, bp->b_fname);    /* Save the original name */
  1684.     strcpy(bp->b_fname, bname1);    /* Set it to our new one */
  1685.  
  1686.     /* Write it out, checking for errors */
  1687.     if (!writeout(filnam1, "w")) {
  1688.         mlwrite("[Cannot write filter file]");
  1689.         strcpy(bp->b_fname, tmpnam);
  1690.         return(0);
  1691.     }
  1692.  
  1693.     /* Setup input and output */
  1694.     strcat(line," <fltinp >fltout");
  1695.  
  1696.     /* Perform command */
  1697.     s = callout(line);
  1698.  
  1699.     /* If successful, read in file */
  1700.     if (s) {
  1701.         s = readin(filnam2, FALSE);
  1702.         if (s)
  1703.             /* Mark buffer as changed */
  1704.             bp->b_flag |= BFCHG;
  1705.     }
  1706.             
  1707.  
  1708.     /* Reset file name */
  1709.     strcpy(bp->b_fname, tmpnam);
  1710.  
  1711.     /* and get rid of the temporary file */
  1712.     unlink(filnam1);
  1713.     unlink(filnam2);
  1714.  
  1715.     /* Show status */
  1716.     if (!s)
  1717.         mlwrite("[Execution failed]");
  1718.     return(s);
  1719. }
  1720.  
  1721. /** Get first filename from pattern **/
  1722. char *getffile(fspec)
  1723. char *fspec;                /* Filename specification    */
  1724. {
  1725.     int index, point, extflag;
  1726.  
  1727.     /* First parse the file path off the file spec */
  1728.     strcpy(path, fspec);
  1729.     index = strlen(path) - 1;
  1730.     while (index >= 0 && (path[index] != '/'))
  1731.         --index;
  1732.     path[index+1] = '\0';
  1733.  
  1734.  
  1735.     /* Check for an extension */
  1736.     point = strlen(fspec) - 1;
  1737.     extflag = FALSE;
  1738.     while (point >= 0) {
  1739.         if (fspec[point] == '.') {
  1740.             extflag = TRUE;
  1741.             break;
  1742.         }
  1743.         point--;
  1744.     }
  1745.  
  1746.     /* Open the directory pointer */
  1747.     if (dirptr) {
  1748.         closedir(dirptr);
  1749.         dirptr = NULL;
  1750.     }
  1751.  
  1752. #ifndef OSK
  1753.     dirptr = opendir((path[0] == '\0') ? "./" : path);
  1754. #else
  1755.     dirptr = opendir((path[0] == '\0') ? "." : path);
  1756. #endif
  1757.  
  1758.     if (!dirptr)
  1759.         return(NULL);
  1760.  
  1761.     strcpy(rbuf, path);
  1762.     nameptr = &rbuf[strlen(rbuf)];
  1763.  
  1764.     /* ...and call for the first file */
  1765.     return(getnfile());
  1766. }
  1767.  
  1768. /** Get next filename from pattern **/
  1769. char *getnfile()
  1770. {
  1771.     int index;
  1772.     struct DIRENTRY * dp;
  1773.     struct stat fstat;
  1774.  
  1775.     /* ...and call for the next file */
  1776.     do {
  1777.         dp = readdir(dirptr);
  1778.         if (!dp)
  1779.             return(NULL);
  1780.  
  1781.         /* Check to make sure we skip all weird entries except directories */
  1782.         strcpy(nameptr, dp->d_name);
  1783.  
  1784.     } while (stat(rbuf, &fstat) ||
  1785.         ((fstat.st_mode & S_IFMT) & (S_IFREG | S_IFDIR)) == 0);
  1786.  
  1787.     /* if this entry is a directory name, say so */
  1788.     if ((fstat.st_mode & S_IFMT) == S_IFDIR)
  1789.         strcat(rbuf, DIRSEPSTR);
  1790.  
  1791.     /* Return the next file name! */
  1792.     return(rbuf);
  1793. }
  1794.  
  1795. #if FLABEL
  1796. /*---------------------------------------------------------------------------*
  1797.  
  1798.       handle the function keys and function key labels on HP-Terminals
  1799.       -----------------------------------------------------------------
  1800.  
  1801.       Hellmuth Michaelis    e-mail: hm@hcshh.hcs.de
  1802.  
  1803.  *---------------------------------------------------------------------------*/
  1804.  
  1805. static unsigned char flabstor[8][50];        /* label & xmit backup store */
  1806. static char flabstof[8] = {0,0,0,0,0,0,0,0};    /* filled flag */
  1807.  
  1808. int fnclabel(f, n)        /* label a function key */
  1809.  
  1810. int f;        /* Default argument */
  1811. int n;        /* function key number 1...8 on hp-terminals */
  1812.  
  1813. {
  1814.     char lbl[20];    /* label string buffer */
  1815.     char xmit[5];    /* transmitted string ( ESC 'p'...'w' ) */
  1816.     char buf[80];    /* writeout buffer */
  1817.     int i;        /* general purpose index */
  1818.     int status;    /* return status */
  1819.  
  1820.     /* check if we are connected to an hp-terminal */
  1821.     if (!hpterm)
  1822.         return(FALSE);
  1823.  
  1824.     /* must be called with an argument */
  1825.     if (f == FALSE) {
  1826.         mlwrite(TEXT246);
  1827. /*            "%%Need function key number"*/
  1828.         return(FALSE);
  1829.     }
  1830.  
  1831.     /* and it must be a legal key number */
  1832.     if (n < 1 || n > 8) {
  1833.         mlwrite(TEXT247);
  1834. /*            "%%Function key number out of range"*/
  1835.         return(FALSE);
  1836.     }
  1837.  
  1838.     /* get the string to send */
  1839.     lbl[0] = '\0';    /* we don't now the label yet */
  1840.  
  1841.     if ((status = mlreply(TEXT248, lbl, 19)) != TRUE)
  1842. /*                  "Enter Label String: "*/
  1843.         return(status);
  1844.  
  1845.     lbl[16] = '\0';
  1846.      i = strlen(lbl);
  1847.  
  1848.     /* set up escape sequence to send to terminal */
  1849.     xmit[0] = 0x1b;
  1850.     xmit[1] = 'o' + n;
  1851.     xmit[2] = '\0';
  1852.  
  1853.     sprintf(flabstor[n-1], "%c&f0a%dk%dd2L%s%s", (char)0x1b, n, i,
  1854.                     lbl, xmit);
  1855.     write(1, flabstor[n-1], strlen(flabstor[n-1]));
  1856.     flabstof[n-1] = 1;
  1857.  
  1858.     sprintf(buf, "%c&jB", (char)0x1b);
  1859.     write(1, buf, strlen(buf));
  1860.  
  1861.     return(TRUE);
  1862. }
  1863.  
  1864. /* display user function key labels */
  1865. static void dis_ufk()
  1866.  
  1867. {
  1868.     int label_num;
  1869.     char buf[6];
  1870.  
  1871.     if (!hpterm)
  1872.         return;
  1873.  
  1874.     for (label_num = 0; label_num < 8; label_num++)
  1875.         if (flabstof[label_num])
  1876.             write(1, flabstor[label_num],
  1877.                 strlen(flabstor[label_num]));
  1878.     sprintf(buf, "%c&jB", (char)0x1b);
  1879.     write(1, buf, strlen(buf));
  1880. }
  1881.  
  1882. /* display system function key labels */
  1883. static void dis_sfk()
  1884.  
  1885. {
  1886.     char buf[6];
  1887.  
  1888.     if (!hpterm)
  1889.         return;
  1890.     sprintf(buf, "%c&jA", (char)0x1b);
  1891.     write(1, buf, strlen(buf));
  1892. }
  1893. #endif /* FLABEL */
  1894.  
  1895. #if XENIX && FILOCK
  1896. int mkdir(name, mode)
  1897. char *name;    /* name of directory to create */
  1898. int mode;    /* umask for creation (which we blissfully ignore...) */
  1899. {
  1900.     char buf[80];
  1901.  
  1902.     strcpy(buf, "mkdir ");
  1903.     strcat(buf, name);
  1904.     strcat(buf, " > /dev/null 2>&1");
  1905.     return(system(buf));
  1906. }
  1907.  
  1908. int rmdir(name)
  1909. char *name;    /* name of directory to delete */
  1910. {
  1911.     char buf[80];
  1912.  
  1913.     strcpy(buf,"rmdir ");
  1914.     strcat(buf, name);
  1915.     strcat(buf, " > /dev/null 2>&1");
  1916.     return(system(buf));
  1917. }
  1918. #endif /* XENIX & FILOCK */
  1919.  
  1920. #if HANDLE_WINCH
  1921. /*
  1922.  * Window size changes handled via signals.
  1923.  */
  1924. void winch_changed()
  1925. {
  1926.     signal(SIGWINCH,winch_changed);
  1927.     winch_flag = 1;
  1928. }
  1929.  
  1930. void winch_new_size()
  1931. {
  1932.     EWINDOW *wp;
  1933.     struct winsize win;
  1934.   
  1935.     winch_flag=0;
  1936.     ioctl(fileno(stdin),TIOCGWINSZ,&win);
  1937.     winch_vtresize(win.ws_row,win.ws_col);
  1938.     onlywind(0,0);
  1939.     TTmove(0,0);
  1940.     TTeeop();
  1941. }
  1942. #endif
  1943.  
  1944. #endif /* BSD || FREEBSD || USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX || (AVVION || TERMIOS) */
  1945.