home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume26 / beav / part07 < prev    next >
Encoding:
Text File  |  1991-11-21  |  53.8 KB  |  2,189 lines

  1. Newsgroups: comp.sources.misc
  2. From: pvr@wang.com (Peter Reilley)
  3. Subject:  v26i043:  beav - Binary file editor and viewer, v1.32, Part07/09
  4. Message-ID: <1991Nov21.230344.1908@sparky.imd.sterling.com>
  5. X-Md4-Signature: 9443a1e4dc2594cf2c5f9d2ef185ecfe
  6. Date: Thu, 21 Nov 1991 23:03:44 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pvr@wang.com (Peter Reilley)
  10. Posting-number: Volume 26, Issue 43
  11. Archive-name: beav/part07
  12. Environment: UNIX, AIX, MS-DOS, AMIGA
  13. Supersedes: beav: Volume 22, Issue 10-18
  14.  
  15. #! /bin/sh
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  19. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  20. # Contents:  extend.c main.c makefile.utx termio.c ttykbd.c window.c
  21. # Wrapped by kent@sparky on Thu Nov 21 16:47:02 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 7 (of 9)."'
  25. if test -f 'extend.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'extend.c'\"
  27. else
  28.   echo shar: Extracting \"'extend.c'\" \(11319 characters\)
  29.   sed "s/^X//" >'extend.c' <<'END_OF_FILE'
  30. X/*
  31. X*   Extended (M-X) commands.
  32. X*/
  33. X#include    "def.h"
  34. X
  35. Xextern    char    MSG_not_now[];
  36. Xextern    char    MSG_func[];
  37. Xextern    char    MSG_unk_func[];
  38. Xextern    char    MSG_cmd_t_ex[];
  39. Xextern    char    MSG_unk_ext[];
  40. Xextern    char    MSG_d_b[];
  41. Xextern    char    MSG_unbd[];
  42. Xextern    char    MSG_bnd_to[];
  43. Xextern    char    MSG_ins_self[];
  44. Xextern    char    MSG_bnd_file[];
  45. Xextern    char    MSG_bld_wall[];
  46. Xextern    char    MSG_wall_head[];
  47. Xextern    char    MSG_beavrc[];
  48. Xextern    char    MSG_null[];
  49. X
  50. X
  51. X#ifdef CUSTOMIZE 
  52. X
  53. Xchar *flook();
  54. X
  55. Xstatic char *bindnm =
  56. X{
  57. X    0
  58. X};                              /* file name for customized key bindings */
  59. X#endif 
  60. X
  61. X/*
  62. X* This function modifies the keyboard
  63. X* binding table, by adjusting the entries in the
  64. X* big "bindings" array. Most of the grief deals with the
  65. X* prompting for additional arguments. This code does not
  66. X* work right if there is a keyboard macro floating around.
  67. X* Should be fixed.
  68. X*/
  69. Xbool bindtokey ()
  70. X{
  71. X
  72. X    register int    s;
  73. X    register    SYMBOL * sp;
  74. X    register int    c;
  75. X    char    xname[NXNAME];
  76. X#ifdef CUSTOMIZE
  77. X    char    xname2[NXNAME];
  78. X#endif 
  79. X
  80. X    if (kbdmip != NULL || kbdmop != NULL)
  81. X    {
  82. X        writ_echo (MSG_not_now);
  83. X        return (FALSE);
  84. X    }
  85. X
  86. X    if ((s = eread (MSG_func, xname, NXNAME, EFAUTO, NULL)) != TRUE)
  87. X        return (s);
  88. X    if ((sp = symlookup (xname)) == NULL)
  89. X    {
  90. X        writ_echo (MSG_unk_func);
  91. X        return (FALSE);
  92. X    }
  93. X
  94. X#ifdef CUSTOMIZE
  95. X    strcpy (xname2, xname);
  96. X#endif 
  97. X    eputc (' ');
  98. X    eputc ('K');
  99. X    eputc ('e');
  100. X    eputc ('y');
  101. X    eputc (':');
  102. X    eputc (' ');
  103. X    ttflush ();
  104. X    c = getkey ();              /* Read key.        */
  105. X    keyname (xname, c);         /* Display keyname. */
  106. X    eputs (xname);
  107. X    ttflush ();
  108. X    if (binding[c] != NULL)     /* Unbind old, and  */
  109. X        --binding[c] -> s_nkey;
  110. X    binding[c] = sp;            /* rebind new.      */
  111. X    ++sp -> s_nkey;
  112. X    sp -> s_modify |= SBOUND;    /* flag as altered key binding */
  113. X
  114. X    return (TRUE);
  115. X}
  116. X
  117. X
  118. X/*
  119. X* Extended command. Call the message line
  120. X* routine to read in the command name and apply autocompletion
  121. X* to it. When it comes back, look the name up in the symbol table
  122. X* and run the command if it is found and has the right type.
  123. X* Print an error if there is anything wrong.
  124. X*/
  125. Xchar    extend (f, n, k)
  126. X{
  127. X
  128. X    register    SYMBOL * sp;
  129. X    register char   s;
  130. X    char    xname[NXNAME];
  131. X
  132. X    if ((s = eread (MSG_cmd_t_ex, xname, NXNAME, EFNEW | EFAUTO, NULL)) != TRUE)
  133. X        return (s);
  134. X    if ((sp = symlookup (xname)) != NULL)
  135. X        return ((*sp -> s_funcp) (f, n, KRANDOM));
  136. X    writ_echo (MSG_unk_ext);
  137. X    return (ABORT);
  138. X}
  139. X
  140. X
  141. X/*
  142. X* Read a key from the keyboard, and look it
  143. X* up in the binding table. Display the name of the function
  144. X* currently bound to the key. Say that the key is not bound
  145. X* if it is indeed not bound, or if the type is not a
  146. X* "builtin". This is a bit of overkill, because this is the
  147. X* only kind of function there is.
  148. X*/
  149. Xbool help ()
  150. X{
  151. X    register    SYMBOL * sp;
  152. X    register int    c;
  153. X    char    b[20];
  154. X    char    buf[80];
  155. X
  156. X    writ_echo (MSG_d_b);
  157. X
  158. X    c = getkey ();
  159. X    keyname (b, c);
  160. X    if ((sp = binding[c]) == NULL)
  161. X    {
  162. X        sprintf (buf, MSG_unbd, b);
  163. X        writ_echo (buf);
  164. X    }
  165. X    else
  166. X    {
  167. X        sprintf (buf, MSG_bnd_to, b, sp -> s_name);
  168. X        writ_echo (buf);
  169. X    }
  170. X    return (TRUE);
  171. X}
  172. X
  173. X/*
  174. X*   Sort the lines in the buffer.
  175. X*/
  176. Xvoid    sort_buf (b_ptr, cnt)
  177. XBUFFER  *b_ptr;
  178. Xint     cnt;
  179. X{
  180. X    LINE    *lp1, *lp2;
  181. X    bool    no_swap;
  182. X    int     loop1, loop2;
  183. X
  184. X    for (loop1 = cnt; loop1 > 0; loop1--)
  185. X    {
  186. X        no_swap = TRUE;
  187. X        lp1 = b_ptr -> b_linep -> l_fp; /* point to first line */
  188. X        lp2 = lp1 -> l_fp;      /* point to next line */
  189. X        for (loop2 = 0; loop2 <= loop1; loop2++)
  190. X        {
  191. X            /* compare strings and swap if necessary */
  192. X            if (0 < strcmp (&lp1 -> l_text[HFUNCCOL], &lp2 -> l_text[HFUNCCOL]))
  193. X            {
  194. X                lp1 -> l_bp -> l_fp = lp2;  /* get pointer to first string */
  195. X                lp2 -> l_fp -> l_bp = lp1;  /* make it point to second string */
  196. X
  197. X                lp1 -> l_fp = lp2 -> l_fp;
  198. X                lp2 -> l_bp = lp1 -> l_bp;
  199. X
  200. X                lp1 -> l_bp = lp2;
  201. X                lp2 -> l_fp = lp1;
  202. X
  203. X                lp2 -> l_file_offset = lp1 -> l_file_offset;
  204. X                lp1 -> l_file_offset = lp2 -> l_file_offset + lp2 -> l_used;
  205. X
  206. X                no_swap = FALSE;
  207. X            }
  208. X            else
  209. X            {
  210. X                /* if no swap then advance both pointers */
  211. X                lp1 = lp2;
  212. X            }
  213. X            lp2 = lp1 -> l_fp;
  214. X        }
  215. X        /* quick exit if sort is finished sooner than expected */
  216. X        if (no_swap)
  217. X        {
  218. X            return;
  219. X        }
  220. X    }
  221. X}
  222. X
  223. X/*
  224. X* This function creates a table, listing all
  225. X* of the command keys and their current bindings, and stores
  226. X* the table in the standard pop-op buffer (the one used by the
  227. X* directory list command, the buffer list command, etc.). This
  228. X* lets the editor produce it's own wall chart. The bindings to
  229. X* "ins-self" are only displayed if there is an argument.
  230. X*/
  231. Xchar    wallchart (f, n, k)
  232. X{
  233. X
  234. X    register char   s;
  235. X    register int    key, i, j;
  236. X    register    SYMBOL * sp;
  237. X    register char  *cp1;
  238. X    register char  *cp2;
  239. X    char    buf[64];
  240. X    WINDOW  *wp;
  241. X
  242. X    if ((s = bclear (blistp)) != TRUE)/* Clear it out.    */
  243. X        return (s);
  244. X    i = 0;
  245. X    (void) strcpy (blistp -> b_fname, MSG_null);
  246. X    blistp -> b_flag = BFVIEW;
  247. X    blistp -> b_type = BTHELP;
  248. X    writ_echo (MSG_bld_wall);
  249. X    sprintf (buf, MSG_wall_head);
  250. X    if (addline (buf) == FALSE)
  251. X        return(FALSE);
  252. X    for (key = 0; key < NKEYS; ++key)
  253. X    {
  254. X        /* For all keys.    */
  255. X        sp = binding[key];
  256. X        if (sp != NULL &&
  257. X            (f != FALSE || strcmp (sp -> s_name, MSG_ins_self) != 0))
  258. X        {
  259. X            cp1 = &buf[0];
  260. X            while (cp1 < &buf[HFUNCCOL])/* Goto column 3.  */
  261. X                *cp1++ = ' ';
  262. X            if ((sp -> s_modify & SBOUND) == 0)    /* comment out default binding */
  263. X                buf[0] = '#';
  264. X            cp2 = sp -> s_name; /* Add function name.   */
  265. X            while (*cp1++ = *cp2++)
  266. X                ;
  267. X            cp1--;
  268. X            while (cp1 < &buf[HKEY])/* Goto column 32.  */
  269. X                *cp1++ = ' ';
  270. X            keyname (&buf[HKEY], key);
  271. X            cp1 = &buf[strlen(buf)];
  272. X            while (cp1 < &buf[HKEYCODE])/* Goto column 50.  */
  273. X                *cp1++ = ' ';
  274. X            sprintf (&buf[HKEYCODE], "%4X", key);
  275. X            if (addline (buf) == FALSE)
  276. X                break; /* lets go with what we have */
  277. X            i++;
  278. X        }
  279. X    }
  280. X
  281. X    /* list unbound functions lest they get lost */
  282. X    for (j = 0; j < NSHASH; j++)
  283. X    {
  284. X        sp = symbol[j];
  285. X        while (sp != NULL)
  286. X        {
  287. X            if (sp -> s_nkey == 0)
  288. X            {
  289. X                cp1 = &buf[0];
  290. X                while (cp1 < &buf[HFUNCCOL])/* Goto column 3.  */
  291. X                    *cp1++ = ' ';
  292. X                buf[0] = '#';
  293. X                cp2 = sp -> s_name; /* Add function name.   */
  294. X                while (*cp1++ = *cp2++)
  295. X                    ;
  296. X                cp1--;
  297. X                while (cp1 < &buf[HENDCOL])
  298. X                    *cp1++ = ' ';
  299. X                *cp1 = 0;
  300. X                i++;
  301. X                if (addline (buf) == FALSE)
  302. X                    break; /* lets go with what we have */
  303. X            }
  304. X            sp = sp -> s_symp;
  305. X        }
  306. X    }
  307. X    sort_buf (blistp, i);      /* sort buffer lines */
  308. X    popblist ();
  309. X    writ_echo (MSG_null);
  310. X    /* make new window the current window */
  311. X    wp = wheadp;
  312. X    while (wp != NULL)
  313. X    {
  314. X        if (wp -> w_bufp == blistp)
  315. X        {
  316. X            curwp = wp;
  317. X            curbp = wp -> w_bufp;
  318. X            return (TRUE);
  319. X        }
  320. X        wp = wp -> w_wndp;
  321. X    }
  322. X    return (TRUE);
  323. X}
  324. X
  325. X/* check for BEAVFIL and read it in if found
  326. X* - also, set local file variable for bindtokey for saving new defs
  327. X* (this is some what of a hack as it only handles 'bindtokey' changes at 
  328. X* this time - also local file io !!!)
  329. X*/
  330. Xvoid check_extend (sfname)
  331. X
  332. Xchar *sfname;    /* name of startup file (null if default) */
  333. X
  334. X{
  335. X    char *fname;    /* resulting file name to execute */
  336. X    char    rc_name[NFILEN];    /* fixed up name of rc file */
  337. X    char    *term;
  338. X    char *getenv();
  339. X    register    SYMBOL * sp;
  340. X    char    funcname[NXNAME + 1];
  341. X    char    keybind[NXNAME + 1];
  342. X    int     keyval;
  343. X    FILE * bindf;
  344. X
  345. X    /* look up the startup file */
  346. X    if ((sfname != NULL) && (*sfname != 0))
  347. X        fname = flook(sfname, TRUE);
  348. X    else
  349. X    {
  350. X#ifdef UNIX
  351. X        /* hidden file under unix */
  352. X        strcpy (&rc_name[0], ".");
  353. X        strcpy (&rc_name[1], MSG_beavrc);
  354. X
  355. X        if ((term = getenv("TERM")) != 0)
  356. X        {
  357. X            strcpy (&rc_name[strlen(rc_name)], ".");
  358. X            strcpy (&rc_name[strlen(rc_name)], term);
  359. X        }
  360. X        fname = flook(rc_name, TRUE);
  361. X        /* if fixed up name is not there then check original */
  362. X        if (fname == NULL)
  363. X        {
  364. X            /* hidden file under unix */
  365. X            strcpy (&rc_name[0], ".");
  366. X            strcpy (&rc_name[1], MSG_beavrc);
  367. X            fname = flook(rc_name, TRUE);
  368. X        }
  369. X#else
  370. X        strcpy (rc_name, MSG_beavrc);
  371. X        fname = flook(rc_name, TRUE);
  372. X#ifdef AMIGA
  373. X        /* look for .beavrc in the current directory */
  374. X        if(!fname) {
  375. X            rc_name[0] = '.';
  376. X            strcpy (&rc_name[1], MSG_beavrc);
  377. X            fname = flook(rc_name, TRUE);
  378. X        }
  379. X        /* look for .beavrc in S: */
  380. X        if(!fname) {
  381. X            /* Have a look in startup directory */
  382. X            rc_name[0] = 'S';
  383. X            rc_name[1] = ':';
  384. X            rc_name[2] = '.';
  385. X            strcpy (&rc_name[3], MSG_beavrc);
  386. X            fname = flook(rc_name, TRUE);
  387. X        }
  388. X#endif /* AMIGA */
  389. X#endif
  390. X    }
  391. X    /* if it isn't around, don't sweat it */
  392. X    if (fname == NULL)
  393. X        return;
  394. X
  395. X    if (bindf = fopen(fname, "r"))
  396. X    {
  397. X        char    buffr[80];
  398. X        char    *buffp;
  399. X
  400. X        buffp = buffr;
  401. X        while (fread (buffp++, sizeof(char), 1, bindf) == 1)
  402. X        {
  403. X            /* scanf is unhappy with commas */
  404. X            if (buffp[-1] == ',')
  405. X                buffp[-1] = '-';
  406. X
  407. X            /* did we get a whole line */
  408. X            if (buffp[-1] == '\n')
  409. X            {
  410. X                *buffp = 0;    /* terminate line */
  411. X                buffp = buffr;
  412. X                sscanf (buffr, "%s %s %x", funcname, keybind, &keyval);
  413. X                if ((buffr[0] == '#') || (keyval == 0))
  414. X                    continue;
  415. X                if (sp = symlookup (funcname))
  416. X                {
  417. X                    if (binding[keyval] != NULL)/* Unbind old, and  */
  418. X                        --binding[keyval] -> s_nkey;
  419. X                    binding[keyval] = sp;/* rebind new.      */
  420. X                    ++sp -> s_nkey;
  421. X                    sp -> s_modify |= SBOUND;    /* flag as altered key binding */
  422. X                }
  423. X            }
  424. X        }
  425. X        fclose (bindf);
  426. X    }
  427. X}
  428. X
  429. X/*    Look up the existance of a file along the normal or PATH
  430. X    environment variable. Look first in the HOME directory if
  431. X    asked and possible
  432. X*/
  433. X
  434. Xchar *flook(fname, hflag)
  435. X
  436. Xchar *fname;    /* base file name to search for */
  437. Xint hflag;    /* Look in the HOME environment variable first? */
  438. X
  439. X{
  440. X    register char *home;    /* path to home directory */
  441. X    register char *path;    /* environmental PATH variable */
  442. X    register char *sp;    /* pointer into path spec */
  443. X    register int i;        /* index */
  444. X    static char fspec[NFILEN * 2];    /* full path spec to search */
  445. X    char *getenv();
  446. X    FILE * bindf;
  447. X
  448. X    if (hflag) {
  449. X        home = getenv("HOME");
  450. X        if (home != NULL) {
  451. X            /* build home dir file spec */
  452. X            strcpy(fspec, home);
  453. X            if (fspec[strlen(fspec) - 1] != '/')
  454. X                strcat(fspec, "/");
  455. X            strcat(fspec, fname);
  456. X
  457. X            /* and try it out */
  458. X            if (bindf = fopen(fspec, "r"))
  459. X            {
  460. X                fclose(bindf);
  461. X                return(fspec);
  462. X            }
  463. X        }
  464. X    }
  465. X
  466. X    /* always try the current directory first */
  467. X    if (bindf = fopen(fname, "r"))
  468. X    {
  469. X        fclose(bindf);
  470. X        return(fname);
  471. X    }
  472. X
  473. X    /* get the PATH variable */
  474. X    path = getenv("PATH");
  475. X    if (path != NULL)
  476. X        while (*path) {
  477. X
  478. X            /* build next possible file spec */
  479. X            sp = fspec;
  480. X            while (*path && (*path != PATHCHR))
  481. X                *sp++ = *path++;
  482. X
  483. X            /* add a terminating dir separator if we need it */
  484. X            if (sp[-1] != SEPCHAR)
  485. X                *sp++ = SEPCHAR;
  486. X
  487. X            *sp = 0;
  488. X            strcat(fspec, fname);
  489. X
  490. X            /* and try it out */
  491. X            if (bindf = fopen(fspec, "r"))
  492. X            {
  493. X                fclose(bindf);
  494. X                return(fspec);
  495. X            }
  496. X
  497. X            if (*path == PATHCHR)
  498. X                ++path;
  499. X        }
  500. X
  501. X    return(NULL);    /* no such luck */
  502. X}
  503. X
  504. X
  505. X/* interactive method for loading binding file
  506. X* (uses above routine, obviously)
  507. X*/
  508. Xchar    load_extend ()
  509. X{
  510. X
  511. X#ifdef CUSTOMIZE
  512. X    register char   s;
  513. X    char    fname[NFILEN];
  514. X
  515. X    if ((s = ereply (MSG_bnd_file, fname, NFILEN, NULL)) != TRUE)
  516. X        return (s);
  517. X    check_extend (fname);
  518. X    writ_echo (okmsg);
  519. X#endif
  520. X    return (TRUE);
  521. X}
  522. X
  523. Xint     find_keyval (name)
  524. Xchar   *name;
  525. X{
  526. X    SYMBOL * sp;
  527. X    int     key;
  528. X
  529. X    for (key = 0; key < NKEYS; ++key)
  530. X    {
  531. X        /* For all keys.    */
  532. X        sp = binding[key];
  533. X        if (sp != NULL && (strcmp (sp -> s_name, name) == 0))
  534. X            return (key);
  535. X    }
  536. X    return (0);
  537. X}
  538. END_OF_FILE
  539.   if test 11319 -ne `wc -c <'extend.c'`; then
  540.     echo shar: \"'extend.c'\" unpacked with wrong size!
  541.   fi
  542.   # end of 'extend.c'
  543. fi
  544. if test -f 'main.c' -a "${1}" != "-c" ; then 
  545.   echo shar: Will not clobber existing file \"'main.c'\"
  546. else
  547.   echo shar: Extracting \"'main.c'\" \(11143 characters\)
  548.   sed "s/^X//" >'main.c' <<'END_OF_FILE'
  549. X/*
  550. X*    BEAV is based on the source for emacs for display and keyboard handling 
  551. X* functions.   The binary file handling and display formats are special
  552. X* to BEAV.   There is a full manual included in this release.   There
  553. X* are makefiles for unix and MSC 5.1 under DOS.   The old Wang PC is
  554. X* supported.   This release is for unix.   The def_unix.h file is the
  555. X* header for unix and the def_dos.h file is the header for dos.   Rename 
  556. X* the appropriate .h file to def.h to convert to your os.
  557. X*     I am willing to maintain BEAV and will entertain suggestions for
  558. X* modifications and/or bug fixes.   I can be reached at;
  559. X*
  560. X*         pvr@wang.com
  561. X* 
  562. X* or at;
  563. X* 
  564. X*         Peter Reilley
  565. X*         19 Heritage Cir.
  566. X*         Hudson, N.H. 03051
  567. X*/
  568. X
  569. X/*
  570. X*    Bug fix log
  571. X*    3/04/91        1.20        pvr
  572. X*        Create new file with read/write permisions.
  573. X*        Fix polled mode system hog tty bug.
  574. X*        Add ANSI define for DOS.
  575. X*        Define short for D16 type.
  576. X*        Call ttclose on error exit.
  577. X*        Limit nrow and ncol to actual array size.
  578. X*        Added beavrc key binding functionallity.
  579. X*        Added delete current window command.
  580. X*        Support VT100 type function keys for binding.
  581. X*/
  582. X/*     
  583. X*
  584. X*     Mainline, macro commands.
  585. X*/
  586. X#include        "def.h"
  587. X
  588. Xbool    execute ();
  589. Xvoid    edinit ();
  590. Xchar    flush_all ();
  591. Xchar    quit ();
  592. Xchar    ctrlg ();
  593. Xvoid    _lowercase ();
  594. X
  595. X
  596. Xextern    char    MSG_ok[];
  597. Xextern    char    MSG_main[];
  598. Xextern    char    MSG_prog_name[];
  599. Xextern    char    MSG_no_mod[];
  600. Xextern    char    MSG_no_s_chg[];
  601. Xextern    char    MSG_auto_fl[];
  602. Xextern    char    MSG_quit[];
  603. Xextern    char    MSG_not_now[];
  604. Xextern    char    MSG_st_mac[];
  605. Xextern    char    MSG_end_mac[];
  606. Xextern    char    MSG_num_mod[];
  607. Xextern    char    MSG_null[];
  608. X
  609. Xint     thisflag;               /* Flags, this command      */
  610. Xint     lastflag;               /* Flags, last command          */
  611. Xint     curgoal;                /* Goal column                  */
  612. Xint     com_line_flags;         /* Count of cmd line switches   */
  613. XBUFFER * curbp;                 /* Current buffer               */
  614. XWINDOW * curwp;                 /* Current window               */
  615. XBUFFER * bheadp;                /* BUFFER listhead              */
  616. XWINDOW * wheadp;                /* WINDOW listhead              */
  617. XBUFFER * blistp;                /* Buffer list BUFFER           */
  618. Xshort   kbdm[NKBDM] = {
  619. X    (KCTLX | ')')};  /* Macro (fitz)  */
  620. Xshort  *kbdmip;                 /* Input  for above             */
  621. Xshort  *kbdmop;                 /* Output for above             */
  622. XSYMBOL * symbol[NSHASH];        /* Symbol table listhead.       */
  623. XSYMBOL * binding[NKEYS];        /* Key bindings.                */
  624. Xextern  ROW_FMT hex_8_fmt;
  625. Xextern  bool    ibm_pc, mem_map;
  626. X
  627. Xchar   *okmsg = {
  628. X    MSG_ok};
  629. Xint     insert_mode = {
  630. X    TRUE};
  631. Xint     extend_buf = {
  632. X    FALSE};
  633. X
  634. Xextern  bool    srch_mode;
  635. Xextern  bool    rplc_mode;
  636. Xextern  char    *getenv ();
  637. Xint     initial_load = 0;
  638. Xint     flush_count = 0;
  639. Xint     flush_num = 500;
  640. Xint     auto_update = 0;
  641. X
  642. Xvoid main (argc, argv)
  643. Xchar   *argv[];
  644. X{
  645. X
  646. X    register    int     c;
  647. X    register    int     f;
  648. X    register    int     n;
  649. X    register    int     mflag;
  650. X    char        bname[NBUFN];
  651. X
  652. X#if MSDOS
  653. X    is_wang ();                 /* Check for computer type */
  654. X
  655. X#endif
  656. X    init_fmt ();                /* initialize format arrays */
  657. X    strcpy (bname, MSG_main);     /* Get buffer name.     */
  658. X    vtinit ();                  /* Virtual terminal.    */
  659. X    keymapinit ();              /* Symbols, bindings.   */
  660. X
  661. X    if (argc == 1)
  662. X    {
  663. X        edinit (bname);
  664. X        update ();
  665. X        eerase ();
  666. X    }
  667. X
  668. X    else
  669. X    {
  670. X        com_line_flags = 0;
  671. X        initial_load = 1;
  672. X        n = (argc - 1);         /* Load  them backwards */
  673. X        if (n > com_line_flags)
  674. X        {
  675. X            /*            _lowercase (argv[n]); */
  676. X            makename (bname, argv[n]);
  677. X            edinit (bname);     /* Buffers, windows.    */
  678. X            update ();
  679. X            readin (argv[n--], 0L, MAXPOS);
  680. X            for (; n > com_line_flags; n--)
  681. X            {
  682. X                /*                _lowercase (argv[n]); */
  683. X                load_file (argv[n], 0L, MAXPOS);
  684. X            }
  685. X        }
  686. X        else
  687. X        {
  688. X            edinit (bname);
  689. X            update ();
  690. X        }
  691. X
  692. X        initial_load = 0;
  693. X    }
  694. X
  695. X    check_extend (NULL);  /* check for extended keys */
  696. X    save_buf_init();        /* initialize save buffer */
  697. X    lastflag = 0;               /* Fake last flags.     */
  698. X
  699. Xloop:
  700. X    update ();
  701. X    c = getkey ();
  702. X    if (epresf != FALSE)
  703. X    {
  704. X        eerase ();
  705. X        update ();
  706. X    }
  707. X    f = FALSE;
  708. X    n = 1;
  709. X    if (c == (KCTRL | 'U'))
  710. X    {
  711. X        /* ^U, start argument.  */
  712. X        f = TRUE;
  713. X        n = 4;
  714. X        while ((c = getkey ()) == (KCTRL | 'U'))
  715. X            n *= 4;
  716. X        if ((c >= '0' && c <= '9') || c == '-')
  717. X        {
  718. X            if (c == '-')
  719. X            {
  720. X                n = 0;
  721. X                mflag = TRUE;
  722. X            }
  723. X            else
  724. X            {
  725. X                n = c - '0';
  726. X                mflag = FALSE;
  727. X            }
  728. X            while ((c = getkey ()) >= '0' && c <= '9')
  729. X                n = 10 * n + c - '0';
  730. X            if (mflag != FALSE)
  731. X                n = -n;
  732. X        }
  733. X    }
  734. X    if (kbdmip != NULL)
  735. X    {
  736. X        /* Save macro strokes.  */
  737. X        if (c != (KCTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
  738. X        {
  739. X            ctrlg (FALSE, 0, KRANDOM);
  740. X            goto loop;
  741. X        }
  742. X        if (f != FALSE)
  743. X        {
  744. X            *kbdmip++ = (KCTRL | 'U');
  745. X            *kbdmip++ = n;
  746. X        }
  747. X        *kbdmip++ = c;
  748. X    }
  749. X    execute (c, f, n);          /* Do it.               */
  750. X    goto loop;
  751. X}
  752. X
  753. X
  754. X/*
  755. X* Command execution. Look up the binding in the the
  756. X* binding array, and do what it says. Return a very bad status
  757. X* if there is no binding, or if the symbol has a type that
  758. X* is not usable (there is no way to get this into a symbol table
  759. X* entry now). Also fiddle with the flags.
  760. X*/
  761. Xchar    execute (c, f, n)
  762. X{
  763. X
  764. X    register    SYMBOL * sp;
  765. X    register int    status;
  766. X
  767. X    if ((sp = binding[c]) != NULL)
  768. X    {
  769. X        thisflag = 0;
  770. X        if (sp -> s_modify & SMOD && (curbp -> b_flag & BFVIEW))
  771. X        {
  772. X            writ_echo (MSG_no_mod);
  773. X            return (ABORT);
  774. X        }
  775. X        if (sp -> s_modify & SSIZE && (curbp -> b_flag & BFSLOCK))
  776. X        {
  777. X            writ_echo (MSG_no_s_chg);
  778. X            return (ABORT);
  779. X        }
  780. X        if ((srch_mode  && !(sp -> s_modify & SSRCH)) ||
  781. X            (rplc_mode  && !(sp -> s_modify & SRPLC)))
  782. X        {
  783. X            ttbeep ();
  784. X            return (TRUE);
  785. X        }
  786. X
  787. X        status = (*sp -> s_funcp) (f, n, c);
  788. X        if (sp -> s_modify & SMOD)
  789. X            flush_count++;
  790. X
  791. X        if (flush_count >= flush_num && auto_update)
  792. X            if (!(kbdmip != NULL || kbdmop != NULL))/* not during macro */
  793. X            {
  794. X                ttbeep ();
  795. X                writ_echo (MSG_auto_fl);
  796. X                flush_all ();
  797. X            }
  798. X        lastflag = thisflag;
  799. X        return (status);
  800. X    }
  801. X    else
  802. X        bad_key (c);
  803. X
  804. X    lastflag = 0;
  805. X    return (ABORT);
  806. X}
  807. X
  808. X
  809. X/*
  810. X* Initialize all of the buffers
  811. X* and windows. The buffer name is passed down as
  812. X* an argument, because the main routine may have been
  813. X* told to read in a file by default, and we want the
  814. X* buffer name to be right.
  815. X*/
  816. Xvoid edinit (bname)
  817. Xchar    bname[];
  818. X{
  819. X
  820. X    register    BUFFER * bp;
  821. X    register    WINDOW * wp;
  822. X
  823. X    bp = bfind (bname, TRUE);   /* Text buffer.         */
  824. X    blistp = bcreate (MSG_null);      /* Special list buffer. */
  825. X    wp = (WINDOW *) malloc (sizeof (WINDOW));/* Initial window.      */
  826. X    if (bp == NULL || wp == NULL || blistp == NULL)
  827. X        abort ();
  828. X    curbp = bp;                 /* Current ones.        */
  829. X    wheadp = wp;
  830. X    curwp = wp;
  831. X    wp -> w_wndp = NULL;        /* Initialize window.   */
  832. X    wp -> w_bufp = bp;
  833. X    bp -> b_nwnd = 1;           /* Displayed.           */
  834. X    wp -> w_fmt_ptr = &hex_8_fmt;/* HEX 8 bit display       pvr  */
  835. X    wp -> w_linep = bp -> b_linep;
  836. X    wp -> w_dotp = bp -> b_linep;
  837. X    wp -> w_doto = 0;           /* set dot pos  pvr */
  838. X    wp -> w_markp = NULL;
  839. X    wp -> w_marko = 0;
  840. X    wp -> w_toprow = 0;
  841. X    wp -> w_ntrows = nrow - 2;  /* 2 = mode, echo.      */
  842. X    wp -> w_flag = WFMODE | WFHARD;/* Full.                */
  843. X    wp -> w_intel_mode = FALSE; /* default is no byte swap     pvr  */
  844. X    wp -> w_disp_shift = 0;     /* default to no byte shift    pvr  */
  845. X    wp -> w_loff = 0;           /* starting line offset        pvr  */
  846. X    wp -> w_unit_offset = 0;    /* dot offset from file start  pvr  */
  847. X}
  848. X
  849. X/*
  850. X* Flush all the dirty buffers that have file names
  851. X* associated with them.
  852. X*/
  853. Xchar flush_all ()
  854. X{
  855. X    register    BUFFER * bp,
  856. X    *savbp = curbp;
  857. X
  858. X    for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
  859. X        if (bp -> b_fname != NULL)
  860. X        {
  861. X            curbp = bp;         /* jam */
  862. X            filesave ();
  863. X            update ();
  864. X        }
  865. X    flush_count = 0;
  866. X    writ_echo (okmsg);
  867. X    curbp = savbp;
  868. X    if (blistp -> b_nwnd != 0)  /* update buffer display */
  869. X        listbuffers ();
  870. X    update ();
  871. X    return (TRUE);
  872. X}
  873. X
  874. X
  875. X/* call flush_all to empty the buffers
  876. X* and quit
  877. X*/
  878. Xbool flushnquit (f, n, k)
  879. X{
  880. X    flush_all ();
  881. X    quit (f, n, k);
  882. X    return (TRUE);
  883. X}
  884. X
  885. X
  886. X/*
  887. X* Quit command. If an argument, always
  888. X* quit. Otherwise confirm if a buffer has been
  889. X* changed and not written out. Normally bound
  890. X* to "C-X C-C".
  891. X*/
  892. Xchar    quit (f, n, k)
  893. X{
  894. X
  895. X    register char   s;
  896. X
  897. X    if (f != FALSE              /* Argument forces it.  */
  898. X    || anycb () == FALSE/* All buffers clean.   */
  899. X    || (s = eyesno (MSG_quit)) == TRUE)/* User says it's OK.   */
  900. X    {
  901. X
  902. X        vttidy ();
  903. X        exit (GOOD);
  904. X    }
  905. X
  906. X    return (s);
  907. X}
  908. X
  909. X
  910. X/*
  911. X* Begin a keyboard macro.
  912. X* Error if not at the top level
  913. X* in keyboard processing. Set up
  914. X* variables and return.
  915. X*/
  916. Xbool ctlxlp (f, n, k)
  917. X{
  918. X
  919. X    if (kbdmip != NULL || kbdmop != NULL)
  920. X    {
  921. X
  922. X        writ_echo (MSG_not_now);
  923. X        return (FALSE);
  924. X    }
  925. X
  926. X    writ_echo (MSG_st_mac);
  927. X    kbdmip = &kbdm[0];
  928. X    return (TRUE);
  929. X}
  930. X
  931. X
  932. X/*
  933. X* End keyboard macro. Check for
  934. X* the same limit conditions as the
  935. X* above routine. Set up the variables
  936. X* and return to the caller.
  937. X*/
  938. Xbool ctlxrp (f, n, k)
  939. X{
  940. X
  941. X    if (kbdmip == NULL)
  942. X    {
  943. X
  944. X        writ_echo (MSG_not_now);
  945. X        return (FALSE);
  946. X    }
  947. X
  948. X    writ_echo (MSG_end_mac);
  949. X    kbdmip = NULL;
  950. X    return (TRUE);
  951. X}
  952. X
  953. X
  954. X/*
  955. X* Execute a macro.
  956. X* The command argument is the
  957. X* number of times to loop. Quit as
  958. X* soon as a command gets an error.
  959. X* Return TRUE if all ok, else
  960. X* FALSE.
  961. X*/
  962. Xbool ctlxe (f, n, k)
  963. X{
  964. X
  965. X    register int    c;
  966. X    register int    af;
  967. X    register int    an;
  968. X    register int    s;
  969. X
  970. X    if (kbdmip != NULL || kbdmop != NULL)
  971. X    {
  972. X
  973. X        writ_echo (MSG_not_now);
  974. X        return (FALSE);
  975. X    }
  976. X
  977. X    if (n <= 0)
  978. X        return (TRUE);
  979. X    do
  980. X    {
  981. X
  982. X        kbdmop = &kbdm[0];
  983. X        do
  984. X        {
  985. X
  986. X            af = FALSE;
  987. X            an = 1;
  988. X            if ((c = *kbdmop++) == (KCTRL | 'U'))
  989. X            {
  990. X
  991. X                af = TRUE;
  992. X                an = *kbdmop++;
  993. X                c = *kbdmop++;
  994. X            }
  995. X
  996. X            s = TRUE;
  997. X        }        while (c != (KCTLX | ')') && (s = execute (c, af, an)) == TRUE);
  998. X        kbdmop = NULL;
  999. X    }    while (s == TRUE && --n);
  1000. X    return (s);
  1001. X}
  1002. X
  1003. X
  1004. X/*
  1005. X* Abort.
  1006. X* Beep the beeper.
  1007. X* Kill off any keyboard macro,
  1008. X* etc., that is in progress.
  1009. X* Sometimes called as a routine,
  1010. X* to do general aborting of
  1011. X* stuff.
  1012. X*/
  1013. Xchar    ctrlg (f, n, k)
  1014. X{
  1015. X    /*    ttbeep (); */
  1016. X    if (kbdmip != NULL)
  1017. X    {
  1018. X        kbdm[0] = (KCTLX | ')');
  1019. X        kbdmip = NULL;
  1020. X    }
  1021. X    return (ABORT);
  1022. X}
  1023. X
  1024. X
  1025. X/*
  1026. X* Display the version. All this does
  1027. X* is copy the text in the external "version" array into
  1028. X* the message system, and call the message reading code.
  1029. X* Don't call display if there is an argument.
  1030. X*/
  1031. Xchar    showversion (f, n, k)
  1032. X{
  1033. X    static  char    *cp;
  1034. X    char    buf[NCOL];
  1035. X
  1036. X    cp = version;
  1037. X    sprintf (buf, cp);
  1038. X    writ_echo (buf);
  1039. X    return (TRUE);
  1040. X}
  1041. X
  1042. X
  1043. X/* ughly to_lower function for
  1044. X* files read in under MSDOS setargv function
  1045. X*/
  1046. Xvoid _lowercase (s)
  1047. Xregister char  *s;
  1048. X{
  1049. X
  1050. X#ifdef MSDOS
  1051. X    for (; *s; s++)
  1052. X        if (ISUPPER (*s))
  1053. X            *s = TOLOWER (*s);
  1054. X#endif
  1055. X}
  1056. X
  1057. X
  1058. X/* autosave control
  1059. X*/
  1060. Xbool autosave ()
  1061. X{
  1062. X    register    WINDOW * wp;
  1063. X    int        n;
  1064. X    char    buf[NCOL];
  1065. X
  1066. X    if ((ereply (MSG_num_mod, buf, sizeof (buf), NULL)) == TRUE)
  1067. X    {
  1068. X
  1069. X        n = atoi (buf);
  1070. X        if (n >= 0)
  1071. X            auto_update = flush_num = n;/* not 0! */
  1072. X        else
  1073. X            auto_update = 0;
  1074. X    }
  1075. X
  1076. X    for (wp = wheadp; wp; wp = wp -> w_wndp)
  1077. X        if (wp -> w_bufp == curbp)
  1078. X            wp -> w_flag |= WFMODE;
  1079. X    return (TRUE);
  1080. X}
  1081. END_OF_FILE
  1082.   if test 11143 -ne `wc -c <'main.c'`; then
  1083.     echo shar: \"'main.c'\" unpacked with wrong size!
  1084.   fi
  1085.   # end of 'main.c'
  1086. fi
  1087. if test -f 'makefile.utx' -a "${1}" != "-c" ; then 
  1088.   echo shar: Will not clobber existing file \"'makefile.utx'\"
  1089. else
  1090.   echo shar: Extracting \"'makefile.utx'\" \(668 characters\)
  1091.   sed "s/^X//" >'makefile.utx' <<'END_OF_FILE'
  1092. X# This is the makefile for DEC ULTRIX
  1093. XCFLAGS=     -O -DUNIX -DBSD -DULTRIX
  1094. X
  1095. XOFILES=        basic.o ebcdic.o fileio.o region.o text.o wangpc.o \
  1096. X    buffer.o echo.o main.o search.o tty.o window.o \
  1097. X    cinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o \
  1098. X    display.o file.o line.o random.o symbol.o ttykbd.o format.o
  1099. X
  1100. X
  1101. XCFILES=     basic.c ebcdic.c fileio.c region.c text.c wangpc.c \
  1102. X    buffer.c echo.c format.c main.c search.c tty.c window.c \
  1103. X    cinfo.c extend.c kbd.c spawn.c ttyio.c termio.c tcap.c word.c \
  1104. X    display.c file.c line.c random.c symbol.c ttykbd.c
  1105. X
  1106. XHFILES=     def.h
  1107. X
  1108. Xbeav:     $(OFILES)
  1109. X    $(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o beav
  1110. X
  1111. X(OFILES):  $(HFILES)
  1112. END_OF_FILE
  1113.   if test 668 -ne `wc -c <'makefile.utx'`; then
  1114.     echo shar: \"'makefile.utx'\" unpacked with wrong size!
  1115.   fi
  1116.   # end of 'makefile.utx'
  1117. fi
  1118. if test -f 'termio.c' -a "${1}" != "-c" ; then 
  1119.   echo shar: Will not clobber existing file \"'termio.c'\"
  1120. else
  1121.   echo shar: Extracting \"'termio.c'\" \(4865 characters\)
  1122.   sed "s/^X//" >'termio.c' <<'END_OF_FILE'
  1123. X/*
  1124. X * The functions in this file negotiate with the operating system for
  1125. X * characters, and write characters in a barely buffered fashion on the display.
  1126. X * All operating systems.
  1127. X */
  1128. X
  1129. X#include    <sys/types.h>    /* 1.13 */
  1130. X
  1131. X#ifdef UNIX    /* System V */
  1132. X
  1133. X#include    <stdio.h>
  1134. X#include    <signal.h>
  1135. X#ifdef BSD
  1136. X#include    <sys/ioctl.h>
  1137. X#else
  1138. X#include    <termio.h>
  1139. X#endif /* BSD */
  1140. X#include    <errno.h>
  1141. X#include    <fcntl.h>
  1142. X#include    "def.h"
  1143. Xint kbdflgs;            /* saved keyboard fd flags  */
  1144. Xint kbdpoll;            /* in O_NDELAY mode         */
  1145. Xint kbdqp;          /* there is a char in kbdq  */
  1146. Xchar kbdq;          /* char we've already read  */
  1147. X
  1148. X#ifdef BSD
  1149. Xstruct    sgttyb    otermb;
  1150. Xstruct    sgttyb    ntermb;
  1151. X#else
  1152. Xstruct  termio  otermio;    /* original terminal characteristics */
  1153. Xstruct  termio  ntermio;    /* charactoristics to use inside */
  1154. X#endif /* BSD */
  1155. Xextern    errno; /* System error number -- Necessary when compiling in BSD 1.13 */
  1156. X
  1157. Xint     nrow;                   /* Terminal size, rows.         */
  1158. Xint     ncol;                   /* Terminal size, columns.      */
  1159. X
  1160. X/*
  1161. X * This function is called once to set up the terminal device streams.
  1162. X * On VMS, it translates TT until it finds the terminal, then assigns
  1163. X * a channel to it and sets it raw. On CPM it is a no-op.
  1164. X */
  1165. X
  1166. Xvoid ttopen()
  1167. X{
  1168. X#ifdef BSD
  1169. X#ifdef ULTRIX
  1170. X    struct winsize ttysize;
  1171. X#else
  1172. X    struct ttysize ttysize;
  1173. X#endif
  1174. X
  1175. X    ioctl(0, TIOCGETP, &otermb);    /* save settings    */
  1176. X    ntermb = otermb;            /* setup new settings    */
  1177. X    ntermb.sg_flags &= ~ECHO;
  1178. X    ntermb.sg_flags |= RAW;
  1179. X    ioctl(0, TIOCSETP, &ntermb);     /* and activate them    */
  1180. X    kbdpoll = FALSE;
  1181. X
  1182. X    /* on all screens we are not sure of the initial position
  1183. X       of the cursor                    */
  1184. X    ttrow = 999;
  1185. X    ttcol = 999;
  1186. X#if ULTRIX
  1187. X    if (ioctl(0, TIOCGWINSZ, &ttysize) == 0) {
  1188. X        nrow = ttysize.ws_row;
  1189. X        ncol = ttysize.ws_col;
  1190. X#else
  1191. X        if (ioctl(0, TIOCGSIZE, &ttysize) == 0) {
  1192. X            nrow = ttysize.ts_lines;
  1193. X            ncol = ttysize.ts_cols;
  1194. X#endif
  1195. X        } else {
  1196. X            nrow = NROW;
  1197. X            ncol = NCOL;
  1198. X        }
  1199. X#else
  1200. X        ioctl(0, TCGETA, &otermio); /* save old settings */
  1201. X        ntermio.c_iflag = 0;        /* setup new settings */
  1202. X        ntermio.c_oflag = 0;
  1203. X        ntermio.c_cflag = otermio.c_cflag;
  1204. X        ntermio.c_lflag = 0;
  1205. X        ntermio.c_line = otermio.c_line;
  1206. X        ntermio.c_cc[VMIN] = 1;
  1207. X        ntermio.c_cc[VTIME] = 0;
  1208. X        ioctl(0, TCSETAW, &ntermio); /* and activate them */
  1209. X        kbdflgs = fcntl( 0, F_GETFL, 0 );
  1210. X        kbdpoll = FALSE;
  1211. X        /* on all screens we are not sure of the initial position
  1212. X       of the cursor                    */
  1213. X        ttrow = 999;
  1214. X        ttcol = 999;
  1215. X        nrow = NROW;
  1216. X        ncol = NCOL;
  1217. X#endif 
  1218. X    }
  1219. X
  1220. X    /*
  1221. X * This function gets called just before we go back home to the command
  1222. X * interpreter. On VMS it puts the terminal back in a reasonable state.
  1223. X * Another no-operation on CPM.
  1224. X */
  1225. X    void  ttclose()
  1226. X        {
  1227. X#ifdef BSD
  1228. X        if (ioctl(0, TIOCSETP, &otermb) == -1) /* restore terminal settings */
  1229. X            printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
  1230. X#else
  1231. X        if (ioctl(0, TCSETAW, &otermio) == -1) /* restore terminal settings */
  1232. X            printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
  1233. X        if (fcntl(0, F_SETFL, kbdflgs) == -1)
  1234. X            printf ("closing fcntl on dev 0 failure, error = %d\n", errno);
  1235. X#endif
  1236. X
  1237. X    }
  1238. X
  1239. X    /*
  1240. X * Write a character to the display. On VMS, terminal output is buffered, and
  1241. X * we just put the characters in the big array, after checking for overflow.
  1242. X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  1243. X * MS-DOS (use the very very raw console output routine).
  1244. X */
  1245. X    void ttputc(c)
  1246. X        {
  1247. X        fputc(c, stdout);
  1248. X    }
  1249. X
  1250. X    /*
  1251. X * Flush terminal buffer. Does real work where the terminal output is buffered
  1252. X * up. A no-operation on systems where byte at a time terminal I/O is done.
  1253. X */
  1254. X    void ttflush()
  1255. X        {
  1256. X        fflush(stdout);
  1257. X    }
  1258. X
  1259. X    /*
  1260. X * Read a character from the terminal, performing no editing and doing no echo
  1261. X * at all. More complex in VMS that almost anyplace else, which figures. Very
  1262. X * simple on CPM, because the system can do exactly what you want.
  1263. X */
  1264. X    ttgetc()
  1265. X        {
  1266. X        if( kbdqp )
  1267. X            kbdqp = FALSE;
  1268. X        else
  1269. X        {
  1270. X#ifdef BSD
  1271. X            int count;
  1272. X
  1273. X            if (kbdpoll && (ioctl(0, FIONREAD, &count), count == 0))
  1274. X                return FALSE;
  1275. X            read(0, &kbdq, 1);
  1276. X#else
  1277. X            if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 )
  1278. X                return FALSE;
  1279. X            kbdpoll = FALSE;
  1280. X            while (read(0, &kbdq, 1) != 1)
  1281. X                ;
  1282. X#endif
  1283. X        }
  1284. X        return ( kbdq & 127 );
  1285. X    }
  1286. X
  1287. X    /* typahead():    Check to see if any characters are already in the
  1288. X        keyboard buffer
  1289. X*/
  1290. X    ttkeyready ()
  1291. X        {
  1292. X        if( !kbdqp )
  1293. X        {
  1294. X#ifdef BSD
  1295. X            int count;
  1296. X
  1297. X            if (!kbdpoll && (ioctl(0, FIONREAD, &count), count == 0))
  1298. X                return FALSE;
  1299. X            kbdpoll = TRUE;    /*  fix in 1.13 */
  1300. X            kbdqp = TRUE;
  1301. X#else
  1302. X            if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 )
  1303. X                return(FALSE);
  1304. X            kbdpoll = TRUE;    /*  fix in 1.13 */
  1305. X            kbdqp = (1 == read( 0, &kbdq, 1 ));
  1306. X#endif
  1307. X
  1308. X        }
  1309. X        return ( kbdqp );
  1310. X    }
  1311. X#endif
  1312. END_OF_FILE
  1313.   if test 4865 -ne `wc -c <'termio.c'`; then
  1314.     echo shar: \"'termio.c'\" unpacked with wrong size!
  1315.   fi
  1316.   # end of 'termio.c'
  1317. fi
  1318. if test -f 'ttykbd.c' -a "${1}" != "-c" ; then 
  1319.   echo shar: Will not clobber existing file \"'ttykbd.c'\"
  1320. else
  1321.   echo shar: Extracting \"'ttykbd.c'\" \(11099 characters\)
  1322.   sed "s/^X//" >'ttykbd.c' <<'END_OF_FILE'
  1323. X/*
  1324. X *      Wang PC keyboard handler
  1325. X */
  1326. X#include    "def.h"
  1327. X
  1328. Xextern    char    MSG_sp_key[];
  1329. Xextern    char    MSG_byte_shift[];
  1330. Xextern    char    MSG_back_char[];
  1331. Xextern    char    MSG_quit[];
  1332. Xextern    char    MSG_forw_del_char[];
  1333. Xextern    char    MSG_toggle_swap[];
  1334. Xextern    char    MSG_forw_char[];
  1335. Xextern    char    MSG_abort[];
  1336. Xextern    char    MSG_ins_self[];
  1337. Xextern    char    MSG_back_del_char[];
  1338. Xextern    char    MSG_refresh[];
  1339. Xextern    char    MSG_forw_line[];
  1340. Xextern    char    MSG_back_line[];
  1341. Xextern    char    MSG_quote[];
  1342. Xextern    char    MSG_recall[];
  1343. Xextern    char    MSG_twiddle[];
  1344. Xextern    char    MSG_forw_page[];
  1345. Xextern    char    MSG_kill_region[];
  1346. Xextern    char    MSG_yank[];
  1347. Xextern    char    MSG_down_window[];
  1348. Xextern    char    MSG_ins_toggle[];
  1349. Xextern    char    MSG_display_buffers[];
  1350. Xextern    char    MSG_quit[];
  1351. Xextern    char    MSG_exit_flush_all[];
  1352. Xextern    char    MSG_set_file_name[];
  1353. Xextern    char    MSG_file_insert[];
  1354. Xextern    char    MSG_buf_size_lock[];
  1355. Xextern    char    MSG_flush_all[];
  1356. Xextern    char    MSG_down_window[];
  1357. Xextern    char    MSG_up_window[];
  1358. Xextern    char    MSG_file_read[];
  1359. Xextern    char    MSG_file_save[];
  1360. Xextern    char    MSG_file_visit[];
  1361. Xextern    char    MSG_file_write[];
  1362. Xextern    char    MSG_swap_dot_and_mark[];
  1363. Xextern    char    MSG_shrink_window[];
  1364. Xextern    char    MSG_display_position[];
  1365. Xextern    char    MSG_start_macro[];
  1366. Xextern    char    MSG_end_macro[];
  1367. Xextern    char    MSG_help[];
  1368. Xextern    char    MSG_only_window[];
  1369. Xextern    char    MSG_split_window[];
  1370. Xextern    char    MSG_use_buffer[];
  1371. Xextern    char    MSG_spawn_cli[];
  1372. Xextern    char    MSG_execute_macro[];
  1373. Xextern    char    MSG_goto_line[];
  1374. Xextern    char    MSG_ins_unit[];
  1375. Xextern    char    MSG_kill_buffer[];
  1376. Xextern    char    MSG_load_bindings[];
  1377. Xextern    char    MSG_forw_window[];
  1378. Xextern    char    MSG_back_window[];
  1379. Xextern    char    MSG_view_file[];
  1380. Xextern    char    MSG_enlarge_window[];
  1381. Xextern    char    MSG_ascii_mode[];
  1382. Xextern    char    MSG_binary_mode[];
  1383. Xextern    char    MSG_buffer_name[];
  1384. Xextern    char    MSG_decimal_mode[];
  1385. Xextern    char    MSG_ebcdic_mode[];
  1386. Xextern    char    MSG_hex_mode[];
  1387. Xextern    char    MSG_back_del_unit[];
  1388. Xextern    char    MSG_octal_mode[];
  1389. Xextern    char    MSG_display_version[];
  1390. Xextern    char    MSG_unit_size1[];
  1391. Xextern    char    MSG_unit_size2[];
  1392. Xextern    char    MSG_unit_size4[];
  1393. Xextern    char    MSG_reposition_window[];
  1394. Xextern    char    MSG_set_mark[];
  1395. Xextern    char    MSG_goto_eob[];
  1396. Xextern    char    MSG_goto_bob[];
  1397. Xextern    char    MSG_next_buff[];
  1398. Xextern    char    MSG_prev_buff[];
  1399. Xextern    char    MSG_query_replace[];
  1400. Xextern    char    MSG_display_bindings[];
  1401. Xextern    char    MSG_auto_save[];
  1402. Xextern    char    MSG_back_unit[];
  1403. Xextern    char    MSG_compare[];
  1404. Xextern    char    MSG_forw_del_unit[];
  1405. Xextern    char    MSG_forw_unit[];
  1406. Xextern    char    MSG_link_windows[];
  1407. Xextern    char    MSG_print[];
  1408. Xextern    char    MSG_back_search[];
  1409. Xextern    char    MSG_forw_search[];
  1410. Xextern    char    MSG_back_page[];
  1411. Xextern    char    MSG_copy_region[];
  1412. Xextern    char    MSG_extended_command[];
  1413. Xextern    char    MSG_up_window[];
  1414. Xextern    char    MSG_search_again[];
  1415. Xextern    char    MSG_bind_to_key[];
  1416. Xextern    char    MSG_file_visit_split[];
  1417. Xextern    char    MSG_yank_buffer[];
  1418. Xextern    char    MSG_save_region[];
  1419. Xextern    char    MSG_use_buffer_split[];
  1420. Xextern    char    MSG_no_f_tb[];
  1421. X
  1422. X#define SPECIAL 0x1F            /* Special keys         */
  1423. X
  1424. Xtypedef    struct  key_name_array 
  1425. X{
  1426. X    int     key_code;
  1427. X    char    *func_name_str;
  1428. X    char    *key_name_str;
  1429. X}   KEY_NAME_ARRAY;
  1430. X#if MSDOS
  1431. Xextern  bool    wang_pc;
  1432. Xextern  bool    ibm_pc;
  1433. X#endif
  1434. X/*
  1435. X * The keyboard's special characters, those things that are prefixed with
  1436. X * a 0x1F, are placed into the keyboard tables as KCTRL || 0x80 || x, for some
  1437. X * x, i.e. they have both the control and 0x80 bits set, so they won't conflict
  1438. X * with anything else on the keyboard.
  1439. X */
  1440. X
  1441. X
  1442. X/*
  1443. X * Names for the keys with basic keycode
  1444. X * between KFIRST and KLAST (inclusive). This is used by
  1445. X * the key name routine in "kbd.c".
  1446. X */
  1447. X#if MSDOS
  1448. XKEY_NAME_ARRAY wang_keys[] =
  1449. X{
  1450. X    KCTRL | 0x80, MSG_bind_to_key, "Indent", 
  1451. X        /*  KCTRL | 0x81, NULL, "Page", */
  1452. X    KCTRL | 0x82, MSG_reposition_window, "Center",
  1453. X        /*  KCTRL | 0x83, NULL, "DecTab", */
  1454. X    /*  KCTRL | 0x84, NULL, "Format", */
  1455. X    /*  KCTRL | 0x85, NULL, "Merge", */
  1456. X    /*  KCTRL | 0x86, NULL, "Note", */
  1457. X    KCTRL | 0x87, MSG_set_mark, "Stop",
  1458. X        KCTRL | 0x88, MSG_forw_search, "Search", 
  1459. X        KCTRL | 0x89, MSG_yank, "Replace",
  1460. X        KCTRL | 0x8A, MSG_copy_region, "Copy",
  1461. X        KCTRL | 0x8B, MSG_kill_region, "Move",
  1462. X        KCTRL | 0x8C, MSG_extended_command, "Command",
  1463. X        KCTRL | 0x8D, MSG_forw_window, "UpDown",
  1464. X        /*  KCTRL | 0x8E, NULL, "BlankKey", */
  1465. X    KCTRL | 0x8F, MSG_goto_line, "GoTo",
  1466. X        /*  KCTRL | 0x90, NULL, "Sh-Indent", */
  1467. X    /*  KCTRL | 0x91, NULL, "Sh-Page", */
  1468. X    /*  KCTRL | 0x92, NULL, "Sh-Center", */
  1469. X    /*  KCTRL | 0x93, NULL, "Sh-DecTab", */
  1470. X    /*  KCTRL | 0x94, NULL, "Sh-Format", */
  1471. X    /*  KCTRL | 0x95, NULL, "Sh-Merge", */
  1472. X    /*  KCTRL | 0x96, NULL, "Sh-Note", */
  1473. X    /*  KCTRL | 0x97, NULL, "Sh-Stop", */
  1474. X    KCTRL | 0x98, MSG_search_again, "Sh-Search",
  1475. X        KCTRL | 0x99, MSG_query_replace, "Sh-Replace",
  1476. X        /*  KCTRL | 0x9A, NULL, "Sh-Copy", */
  1477. X    /*  KCTRL | 0x9B, NULL, "Sh-Move", */
  1478. X    /*  KCTRL | 0x9C, NULL, "Sh-Command", */
  1479. X    KCTRL | 0x9D, MSG_split_window, "Sh-UpDown",
  1480. X        /*  KCTRL | 0x9E, NULL, "Sh-BlankKey", */
  1481. X    /*  KCTRL | 0x9F, NULL, "Sh-GoTo", */
  1482. X    KCTRL | 0xC0, MSG_back_line, "North",
  1483. X        KCTRL | 0xC1, MSG_forw_char, "East",
  1484. X        KCTRL | 0xC2, MSG_forw_line, "South",
  1485. X        KCTRL | 0xC3, MSG_back_char, "West",
  1486. X        KCTRL | 0xC4, MSG_byte_shift, "Home",
  1487. X        /*  KCTRL | 0xC5, NULL, "Execute", */
  1488. X    KCTRL | 0xC6, MSG_ins_toggle, "Insert",
  1489. X        KCTRL | 0xC7, MSG_forw_del_char, "Delete",
  1490. X        KCTRL | 0xC8, MSG_back_page, "PrevPage",
  1491. X        KCTRL | 0xC9, MSG_forw_page, "NextPage",
  1492. X        /*  KCTRL | 0xCB, NULL, "Erase", */
  1493. X    /*  KCTRL | 0xCD, NULL, "BackTab", */
  1494. X    /*  KCTRL | 0xD0, NULL, "Sh-North", */
  1495. X    KCTRL | 0xD1, MSG_forw_unit, "Sh-East",
  1496. X        /*  KCTRL | 0xD2, NULL, "Sh-South", */
  1497. X    KCTRL | 0xD3, MSG_back_unit, "Sh-West",
  1498. X        /*  KCTRL | 0xD4, NULL, "Sh-Home", */
  1499. X    KCTRL | 0xD5, MSG_execute_macro, "Sh-Execute",
  1500. X        /*  KCTRL | 0xD6, NULL, "Sh-Insert", */
  1501. X    KCTRL | 0xD7, MSG_forw_del_unit, "Sh-Delete",
  1502. X        KCTRL | 0xD8, MSG_goto_bob, "Sh-PrevPage",
  1503. X        KCTRL | 0xD9, MSG_goto_eob, "Sh-NextPage",
  1504. X        /*  KCTRL | 0xDB, NULL, "Sh-Erase", */
  1505. X    /*  KCTRL | 0xDC, NULL, "Sh-Tab", */
  1506. X    /*  KCTRL | 0xDD, NULL, "Sh-BackTab", */
  1507. X    KCTRL | 0xE0, MSG_abort, "Cancel",
  1508. X        KMETA | KCTRL | 0xE0, MSG_abort, "Cancel",
  1509. X        KCTLX | KCTRL | 0xE0, MSG_abort, "Ctl-X Cancel",
  1510. X        KCTRL | 0xE1, MSG_display_bindings, "Help",
  1511. X        /*  KCTRL | 0xE2, NULL, "Glossary", */
  1512. X    KCTRL | 0xE3, MSG_print, "Print",
  1513. X        KCTRL | 0xF1, MSG_help, "Sh-Help",
  1514. X        /*  KCTRL | 0xF2, NULL, "Sh-Glossary", */
  1515. X    /*  KCTRL | 0xF3, NULL, "Sh-Print", */
  1516. X    0, NULL, NULL
  1517. X};
  1518. X
  1519. XKEY_NAME_ARRAY  ibm_keys[] =
  1520. X{
  1521. X    KCTLX | 0x80 | 0x3B, MSG_display_bindings, "F1",
  1522. X        KCTLX | 0x80 | 0x3C, MSG_set_mark, "F2",
  1523. X        KCTLX | 0x80 | 0x3D, MSG_forw_search, "F3",
  1524. X        KCTLX | 0x80 | 0x3E, MSG_search_again, "F4",
  1525. X        KCTLX | 0x80 | 0x3F, MSG_query_replace, "F5",
  1526. X        KCTLX | 0x80 | 0x40, MSG_yank, "F6",
  1527. X        KCTLX | 0x80 | 0x41, MSG_copy_region, "F7",
  1528. X        KCTLX | 0x80 | 0x42, MSG_kill_region, "F8",
  1529. X        KCTLX | 0x80 | 0x43, MSG_goto_line, "F9",
  1530. X        KCTLX | 0x80 | 0x44, MSG_abort, "F10",
  1531. X        KCTLX | 0x80 | 0x54, MSG_help, "Sh-F1",
  1532. X        KCTLX | 0x80 | 0x55, MSG_file_read, "Sh-F2",
  1533. X        KCTLX | 0x80 | 0x56, MSG_file_save, "Sh-F3",
  1534. X        KCTLX | 0x80 | 0x57, MSG_file_visit, "Sh-F4",
  1535. X        KCTLX | 0x80 | 0x58, MSG_file_write, "Sh-F5",
  1536. X        KCTLX | 0x80 | 0x59, MSG_flush_all, "Sh-F6",
  1537. X        KCTLX | 0x80 | 0x5A, MSG_set_file_name, "Sh-F7",
  1538. X        KCTLX | 0x80 | 0x5B, MSG_file_insert, "Sh-F8",
  1539. X        KCTLX | 0x80 | 0x5C, MSG_exit_flush_all, "Sh-F9",
  1540. X        KCTLX | 0x80 | 0x5D, MSG_quit, "Sh-F10",
  1541. X        KCTLX | 0x80 | 0x5E, MSG_display_buffers, "Ctl-F1",
  1542. X        KCTLX | 0x80 | 0x5F, MSG_use_buffer, "Ctl-F2",
  1543. X        KCTLX | 0x80 | 0x60, MSG_kill_buffer, "Ctl-F3",
  1544. X        KCTLX | 0x80 | 0x61, MSG_next_buff, "Ctl-F4",
  1545. X        KCTLX | 0x80 | 0x62, MSG_prev_buff, "Ctl-F5",
  1546. X        KCTLX | 0x80 | 0x63, MSG_yank_buffer, "Ctl-F6",
  1547. X        KCTLX | 0x80 | 0x64, MSG_set_file_name, "Ctl-F7",
  1548. X        KCTLX | 0x80 | 0x65, MSG_file_insert, "Ctl-F8",
  1549. X        KCTLX | 0x80 | 0x66, MSG_exit_flush_all, "Ctl-F9",
  1550. X        KCTLX | 0x80 | 0x67, MSG_quit, "Ctl-F10",
  1551. X        KCTLX | 0x80 | 0x48, MSG_back_line, "North",
  1552. X        KCTLX | 0x80 | 0x4D, MSG_forw_char, "East",
  1553. X        KCTLX | 0x80 | 0x74, MSG_forw_unit, "Ctl-East",
  1554. X        KCTLX | 0x80 | 0x50, MSG_forw_line, "South",
  1555. X        KCTLX | 0x80 | 0x4B, MSG_back_char, "West",
  1556. X        KCTLX | 0x80 | 0x73, MSG_back_unit, "Ctl-West",
  1557. X        KCTLX | 0x80 | 0x49, MSG_back_page, "PageDown",
  1558. X        KCTLX | 0x80 | 0x47, MSG_goto_bob, "Home",
  1559. X        KCTLX | 0x80 | 0x51, MSG_forw_page, "PageUp",
  1560. X        KCTLX | 0x80 | 0x4F, MSG_goto_eob, "End",
  1561. X        KCTLX | 0x80 | 0x52, MSG_ins_toggle, "Insert",
  1562. X        KCTLX | 0x80 | 0x53, MSG_forw_del_char, "Delete",
  1563. X        KCTLX | 0x80 | 0x76, MSG_forw_window, "Ctl-PageDown",
  1564. X        KCTLX | 0x80 | 0x84, MSG_back_window, "Ctl-PageUp",
  1565. X        KCTLX | 0x80 | 0x72, MSG_print, "Ctl-Print",
  1566. X        KCTLX | 0x80 | 0x0F, MSG_forw_unit, "Sh-Tab",
  1567. X        0, NULL, NULL
  1568. X};
  1569. X#endif
  1570. X/*
  1571. X * Read in a key, doing the low level mapping
  1572. X * of ASCII code to 11 bit code.  This level deals with
  1573. X * mapping the special keys into their spots in the C1
  1574. X * control area.  The C0 controls go right through, and
  1575. X * get remapped by "getkey".
  1576. X */
  1577. Xstatic int  unkey = KRANDOM;    /* jam - for ungetkey */
  1578. Xvoid ungetkey (k)
  1579. X{
  1580. X    unkey = k;
  1581. X}
  1582. X
  1583. Xint     getkbd ()
  1584. X{
  1585. X    register int    c;
  1586. X
  1587. X    if (unkey == KRANDOM)       /* jam */
  1588. X        c = ttgetc ();
  1589. X    else
  1590. X    {
  1591. X        c = unkey;
  1592. X        unkey = KRANDOM;
  1593. X    }
  1594. X    if (c == SPECIAL)
  1595. X    {
  1596. X        c = ttgetc ();
  1597. X        if ((c == 0xCD) || (c == 0xDD))/* Backtab is meta */
  1598. X            return (METACH);
  1599. X        return (c | KCTRL);
  1600. X    }
  1601. X    if (c == 0)
  1602. X    {
  1603. X        c = ttgetc ();
  1604. X        return (c | 0x80 | KCTLX);
  1605. X    }
  1606. X    return (c);
  1607. X}
  1608. X
  1609. X
  1610. X/*
  1611. X * Terminal specific keymap initialization.
  1612. X * Attach the special keys to the appropriate built
  1613. X * in functions.
  1614. X * As is the case of all the keymap routines, errors
  1615. X * are very fatal.
  1616. X */
  1617. Xvoid ttykeymapinit ()
  1618. X{
  1619. X#if MSDOS
  1620. X    KEY_NAME_ARRAY  *ptr;
  1621. X    int     i;
  1622. X    char    buf[NCOL];
  1623. X    if (wang_pc)
  1624. X        ptr = wang_keys;
  1625. X
  1626. X    if (ibm_pc)
  1627. X        ptr = ibm_keys;
  1628. X
  1629. X    if (!wang_pc && !ibm_pc)
  1630. X        return;
  1631. X
  1632. X    i = 0;
  1633. X    while (ptr -> key_code != 0)
  1634. X    {
  1635. X        if (ptr -> func_name_str != NULL)
  1636. X            keydup (ptr -> key_code, ptr -> func_name_str);
  1637. X        ptr++;
  1638. X        i++;
  1639. X    }
  1640. X    sprintf (buf, MSG_sp_key, i);
  1641. X    writ_echo (buf);
  1642. X#endif
  1643. X}
  1644. X/* 
  1645. X*   Search key name array for given key code.
  1646. X*   return pointer to key name.
  1647. X*/
  1648. Xchar    *keystrings (key)
  1649. Xint     key;
  1650. X{
  1651. X#if MSDOS
  1652. X    KEY_NAME_ARRAY  *ptr;
  1653. X
  1654. X    if (wang_pc)
  1655. X        ptr = wang_keys;
  1656. X
  1657. X    if (ibm_pc)
  1658. X        ptr = ibm_keys;
  1659. X
  1660. X    if (!wang_pc && !ibm_pc)
  1661. X        return(NULL);
  1662. X
  1663. X    while (ptr -> key_code != 0)
  1664. X    {
  1665. X        if (key == ptr -> key_code)
  1666. X        {
  1667. X            return (ptr -> key_name_str);
  1668. X        }
  1669. X        ptr++;
  1670. X    }
  1671. X#endif
  1672. X    return (NULL);
  1673. X}
  1674. END_OF_FILE
  1675.   if test 11099 -ne `wc -c <'ttykbd.c'`; then
  1676.     echo shar: \"'ttykbd.c'\" unpacked with wrong size!
  1677.   fi
  1678.   # end of 'ttykbd.c'
  1679. fi
  1680. if test -f 'window.c' -a "${1}" != "-c" ; then 
  1681.   echo shar: Will not clobber existing file \"'window.c'\"
  1682. else
  1683.   echo shar: Extracting \"'window.c'\" \(10328 characters\)
  1684.   sed "s/^X//" >'window.c' <<'END_OF_FILE'
  1685. X/*
  1686. X*       Window handling.
  1687. X*/
  1688. X#include    "def.h"
  1689. X
  1690. Xbool    mvupwind ();
  1691. Xbool    shrinkwind ();
  1692. X
  1693. Xextern    char    MSG_no_splt[];
  1694. Xextern    char    MSG_cnt_al_w[];
  1695. Xextern    char    MSG_one_w[];
  1696. Xextern    char    MSG_imp_chg[];
  1697. X
  1698. X/*
  1699. X* Reposition the window so as to center on the dot.
  1700. X*/
  1701. Xbool reposition ()
  1702. X{
  1703. X    long    l_val;
  1704. X
  1705. X    l_val = DOT_POS(curwp) - (curwp -> w_ntrows * R_BYTES(curwp) / 2L);
  1706. X    move_ptr (curwp, l_val, FALSE, TRUE, FALSE);
  1707. X    curwp -> w_flag |= WFHARD;
  1708. X    return (TRUE);
  1709. X}
  1710. X
  1711. X/*
  1712. X* The command make the next
  1713. X* window (next => down the screen)
  1714. X* the current window. There are no real
  1715. X* errors, although the command does
  1716. X* nothing if there is only 1 window on
  1717. X* the screen.
  1718. X*/
  1719. Xbool nextwind ()
  1720. X{
  1721. X
  1722. X    register    WINDOW * wp;
  1723. X
  1724. X    if ((wp = curwp -> w_wndp) == NULL)
  1725. X        wp = wheadp;
  1726. X    curwp = wp;
  1727. X    curbp = wp -> w_bufp;
  1728. X    return (TRUE);
  1729. X}
  1730. X
  1731. X
  1732. X/*
  1733. X* This command makes the previous
  1734. X* window (previous => up the screen) the
  1735. X* current window. There arn't any errors,
  1736. X* although the command does not do a lot
  1737. X* if there is 1 window.
  1738. X*/
  1739. Xbool prevwind ()
  1740. X{
  1741. X
  1742. X    register    WINDOW * wp1;
  1743. X    register    WINDOW * wp2;
  1744. X
  1745. X    wp1 = wheadp;
  1746. X    wp2 = curwp;
  1747. X    if (wp1 == wp2)
  1748. X        wp2 = NULL;
  1749. X    while (wp1 -> w_wndp != wp2)
  1750. X        wp1 = wp1 -> w_wndp;
  1751. X    curwp = wp1;
  1752. X    curbp = wp1 -> w_bufp;
  1753. X    return (TRUE);
  1754. X}
  1755. X
  1756. X
  1757. X/*
  1758. X* This command moves the current
  1759. X* window down by "arg" lines. Recompute
  1760. X* the top line in the window. The move up and
  1761. X* move down code is almost completely the same;
  1762. X* most of the work has to do with reframing the
  1763. X* window, and picking a new dot. We share the
  1764. X* code by having "move down" just be an interface
  1765. X* to "move up".
  1766. X*/
  1767. Xbool    mvdnwind (f, n, k)
  1768. Xregister int    n;
  1769. X{
  1770. X    return (mvupwind (f, -n, KRANDOM));
  1771. X}
  1772. X
  1773. X
  1774. X/*
  1775. X* Move the current window up by "arg"
  1776. X* lines. Recompute the new top line of the window.
  1777. X* Look to see if "." is still on the screen. If it is,
  1778. X* you win. If it isn't, then move "." to center it
  1779. X* in the new framing of the window (this command does
  1780. X* not really move "."; it moves the frame).
  1781. X*/
  1782. Xbool    mvupwind (f, n, k)
  1783. Xint    n;
  1784. X{
  1785. X    A32   l_val, l_bytes;
  1786. X
  1787. X    l_bytes = (A32)R_BYTES(curwp);     /* number of bytes in a row */
  1788. X    l_val = n * l_bytes;     /* number of bytes to move */
  1789. X    move_ptr (curwp, l_val, FALSE, TRUE, TRUE);  /* move window */
  1790. X
  1791. X    /* check that dot is in window */
  1792. X    while (DOT_POS(curwp) < WIND_POS(curwp))
  1793. X    {
  1794. X        /* dot is before the first window line */
  1795. X        move_ptr (curwp, l_bytes, TRUE, TRUE, TRUE);
  1796. X    }
  1797. X    while (DOT_POS (curwp) >=
  1798. X        ((l_bytes * curwp -> w_ntrows) + WIND_POS(curwp)))
  1799. X    {
  1800. X        /* dot is after the last window line */
  1801. X        move_ptr (curwp, -l_bytes, TRUE, TRUE, TRUE);
  1802. X    }
  1803. X    curwp -> w_flag |= WFHARD;
  1804. X    return (TRUE);
  1805. X}
  1806. X
  1807. X
  1808. X/*
  1809. X* This command makes the current
  1810. X* window the only window on the screen.
  1811. X* Try to set the framing
  1812. X* so that "." does not have to move on
  1813. X* the display. Some care has to be taken
  1814. X* to keep the values of dot and mark
  1815. X* in the buffer structures right if the
  1816. X* distruction of a window makes a buffer
  1817. X* become undisplayed.
  1818. X*/
  1819. Xbool    onlywind ()
  1820. X{
  1821. X
  1822. X    register    WINDOW * wp;
  1823. X    register    LINE * lp;
  1824. X    register int    i;
  1825. X
  1826. X    while (wheadp != curwp)
  1827. X    {
  1828. X
  1829. X        wp = wheadp;
  1830. X        wheadp = wp -> w_wndp;
  1831. X        if (--wp -> w_bufp -> b_nwnd == 0)
  1832. X        {
  1833. X
  1834. X            wp -> w_bufp -> b_dotp = wp -> w_dotp;
  1835. X            wp -> w_bufp -> b_doto = wp -> w_doto;
  1836. X            wp -> w_bufp -> b_markp = wp -> w_markp;
  1837. X            wp -> w_bufp -> b_marko = wp -> w_marko;
  1838. X        }
  1839. X
  1840. X        free ((char *) wp);
  1841. X    }
  1842. X
  1843. X    while (curwp -> w_wndp != NULL)
  1844. X    {
  1845. X
  1846. X        wp = curwp -> w_wndp;
  1847. X        curwp -> w_wndp = wp -> w_wndp;
  1848. X        if (--wp -> w_bufp -> b_nwnd == 0)
  1849. X        {
  1850. X
  1851. X            wp -> w_bufp -> b_dotp = wp -> w_dotp;
  1852. X            wp -> w_bufp -> b_doto = wp -> w_doto;
  1853. X            wp -> w_bufp -> b_markp = wp -> w_markp;
  1854. X            wp -> w_bufp -> b_marko = wp -> w_marko;
  1855. X        }
  1856. X
  1857. X        free ((char *) wp);
  1858. X    }
  1859. X
  1860. X    lp = curwp -> w_linep;
  1861. X    i = curwp -> w_toprow;
  1862. X    while (i != 0 && lback (lp) != curbp -> b_linep)
  1863. X    {
  1864. X
  1865. X        --i;
  1866. X        lp = lback (lp);
  1867. X    }
  1868. X
  1869. X    curwp -> w_toprow = 0;
  1870. X    curwp -> w_ntrows = nrow - 2;/* 2 = mode, echo.  */
  1871. X    curwp -> w_linep = lp;
  1872. X    curwp -> w_flag |= WFMODE | WFHARD;
  1873. X    return (TRUE);
  1874. X}
  1875. X
  1876. X/*
  1877. X * Delete the current window, placing its space in the window above,
  1878. X * or, if it is the top window, the window below. Bound to C-X 0.
  1879. X */
  1880. X
  1881. Xbool    delwind()
  1882. X
  1883. X{
  1884. X    register WINDOW *wp;    /* window to recieve deleted space */
  1885. X    register WINDOW *lwp;    /* ptr window before curwp */
  1886. X    register int target;    /* target line to search for */
  1887. X
  1888. X    /* if there is only one window, don't delete it */
  1889. X    if (wheadp->w_wndp == NULL) {
  1890. X        return(FALSE);
  1891. X    }
  1892. X
  1893. X    /* find window before curwp in linked list */
  1894. X    wp = wheadp;
  1895. X    lwp = NULL;
  1896. X    while (wp != NULL) {
  1897. X        if (wp == curwp)
  1898. X            break;
  1899. X        lwp = wp;
  1900. X        wp = wp->w_wndp;
  1901. X    }
  1902. X
  1903. X    /* find recieving window and give up our space */
  1904. X    wp = wheadp;
  1905. X    if (curwp->w_toprow == 0) {
  1906. X        /* find the next window down */
  1907. X        target = curwp->w_ntrows + 1;
  1908. X        while (wp != NULL) {
  1909. X            if (wp->w_toprow == target)
  1910. X                break;
  1911. X            wp = wp->w_wndp;
  1912. X        }
  1913. X        if (wp == NULL)
  1914. X            return(FALSE);
  1915. X        wp->w_toprow = 0;
  1916. X        wp->w_ntrows += target;
  1917. X    } else {
  1918. X        /* find the next window up */
  1919. X        target = curwp->w_toprow - 1;
  1920. X        while (wp != NULL) {
  1921. X            if ((wp->w_toprow + wp->w_ntrows) == target)
  1922. X                break;
  1923. X            wp = wp->w_wndp;
  1924. X        }
  1925. X        if (wp == NULL)
  1926. X            return(FALSE);
  1927. X        wp->w_ntrows += 1 + curwp->w_ntrows;
  1928. X    }
  1929. X
  1930. X    /* get rid of the current window */
  1931. X    if (--curwp->w_bufp->b_nwnd == 0) {
  1932. X        curwp->w_bufp->b_dotp = curwp->w_dotp;
  1933. X        curwp->w_bufp->b_doto = curwp->w_doto;
  1934. X        curwp->w_bufp->b_markp = curwp->w_markp;
  1935. X        curwp->w_bufp->b_marko = curwp->w_marko;
  1936. X    }
  1937. X    if (lwp == NULL)
  1938. X        wheadp = curwp->w_wndp;
  1939. X    else
  1940. X        lwp->w_wndp = curwp->w_wndp;
  1941. X    free((char *)curwp);
  1942. X    curwp = wp;
  1943. X    wp -> w_flag |= WFMODE | WFHARD;
  1944. X    curbp = wp->w_bufp;
  1945. X    return(TRUE);
  1946. X}
  1947. X
  1948. X/*
  1949. X* Split the current window. A window
  1950. X* smaller than 3 lines cannot be split.
  1951. X* The only other error that is possible is
  1952. X* a "malloc" failure allocating the structure
  1953. X* for the new window.
  1954. X*/
  1955. Xbool splitwind ()
  1956. X{
  1957. X
  1958. X    register    WINDOW * wp;
  1959. X    register int    ntru;
  1960. X    register int    ntrl;
  1961. X    register int    ntrd;
  1962. X    register    WINDOW * wp1;
  1963. X    register    WINDOW * wp2;
  1964. X    char    buf[NCOL], buf1[NCOL];
  1965. X
  1966. X    if (curwp -> w_ntrows < 3)
  1967. X    {
  1968. X        sprintf (buf1, MSG_no_splt, R_BYTE_FMT(curwp));
  1969. X        sprintf (buf, buf1, curwp -> w_ntrows);
  1970. X        writ_echo (buf);
  1971. X        return (FALSE);
  1972. X    }
  1973. X
  1974. X    if ((wp = (WINDOW *) malloc (sizeof (WINDOW))) == NULL)
  1975. X    {
  1976. X        err_echo (MSG_cnt_al_w);
  1977. X        return (FALSE);
  1978. X    }
  1979. X
  1980. X    ++curbp -> b_nwnd;          /* Displayed twice.  */
  1981. X    wp -> w_bufp = curbp;
  1982. X    wp -> w_dotp = curwp -> w_dotp;
  1983. X    wp -> w_doto = curwp -> w_doto;
  1984. X    wp -> w_unit_offset = curwp -> w_unit_offset;
  1985. X    wp -> w_markp = curwp -> w_markp;
  1986. X    wp -> w_marko = curwp -> w_marko;
  1987. X    wp -> w_flag = 0;
  1988. X    wp -> w_disp_shift = curwp -> w_disp_shift;
  1989. X    wp -> w_intel_mode = curwp -> w_intel_mode;
  1990. X    wp -> w_fmt_ptr = curwp -> w_fmt_ptr;
  1991. X    ntru = (curwp -> w_ntrows - 1) / 2;/* Upper size         */
  1992. X    ntrl = (curwp -> w_ntrows - 1) - ntru;/* Lower size      */
  1993. X
  1994. X    curwp -> w_ntrows = ntru;
  1995. X    wp -> w_wndp = curwp -> w_wndp;
  1996. X    curwp -> w_wndp = wp;
  1997. X    wp -> w_toprow = curwp -> w_toprow + ntru + 1;
  1998. X    wp -> w_ntrows = ntrl;
  1999. X
  2000. X    wind_on_dot (curwp);        /* put window on the dot */
  2001. X    wp -> w_loff = curwp -> w_loff;/* do the same for the new window */
  2002. X    wp -> w_linep = curwp -> w_linep;
  2003. X    curwp -> w_flag |= WFMODE | WFHARD;
  2004. X    wp -> w_flag |= WFMODE | WFHARD;
  2005. X    return (TRUE);
  2006. X}
  2007. X
  2008. X
  2009. X/*
  2010. X* Enlarge the current window.
  2011. X* Find the window that loses space. Make
  2012. X* sure it is big enough. If so, hack the window
  2013. X* descriptions, and ask redisplay to do all the
  2014. X* hard work. You don't just set "force reframe"
  2015. X* because dot would move.
  2016. X*/
  2017. Xbool enlargewind (f, n, k)
  2018. X{
  2019. X    register    WINDOW * adjwp;
  2020. X    register    LINE * lp;
  2021. X    register int    i;
  2022. X
  2023. X    if (n < 0)
  2024. X        return (shrinkwind (f, -n, KRANDOM));
  2025. X    if (wheadp -> w_wndp == NULL)
  2026. X    {
  2027. X
  2028. X        writ_echo (MSG_one_w);
  2029. X        return (FALSE);
  2030. X    }
  2031. X
  2032. X    if ((adjwp = curwp -> w_wndp) == NULL)
  2033. X    {
  2034. X        adjwp = wheadp;
  2035. X        while (adjwp -> w_wndp != curwp)
  2036. X            adjwp = adjwp -> w_wndp;
  2037. X    }
  2038. X
  2039. X    if (adjwp -> w_ntrows <= n)
  2040. X    {
  2041. X        writ_echo (MSG_imp_chg);
  2042. X        return (FALSE);
  2043. X    }
  2044. X
  2045. X    if (curwp -> w_wndp == adjwp)
  2046. X    {
  2047. X        /* Shrink below.     */
  2048. X        lp = adjwp -> w_linep;
  2049. X        for (i = 0; i < n && lp != adjwp -> w_bufp -> b_linep; ++i)
  2050. X            lp = lforw (lp);
  2051. X        adjwp -> w_linep = lp;
  2052. X        adjwp -> w_toprow += n;
  2053. X    }
  2054. X    else
  2055. X    {
  2056. X        /* Shrink above.     */
  2057. X        lp = curwp -> w_linep;
  2058. X        for (i = 0; i < n && lback (lp) != curbp -> b_linep; ++i)
  2059. X            lp = lback (lp);
  2060. X        curwp -> w_linep = lp;
  2061. X        curwp -> w_toprow -= n;
  2062. X    }
  2063. X
  2064. X    curwp -> w_ntrows += n;
  2065. X    adjwp -> w_ntrows -= n;
  2066. X    curwp -> w_flag |= WFMODE | WFHARD;
  2067. X    adjwp -> w_flag |= WFMODE | WFHARD;
  2068. X    return (TRUE);
  2069. X}
  2070. X
  2071. X
  2072. X/*
  2073. X* Shrink the current window.
  2074. X* Find the window that gains space. Hack at
  2075. X* the window descriptions. Ask the redisplay to
  2076. X* do all the hard work.
  2077. X*/
  2078. Xbool shrinkwind (f, n, k)
  2079. X{
  2080. X    register    WINDOW * adjwp;
  2081. X    register    LINE * lp;
  2082. X    register int    i;
  2083. X
  2084. X    if (n < 0)
  2085. X        return (enlargewind (f, -n, KRANDOM));
  2086. X    if (wheadp -> w_wndp == NULL)
  2087. X    {
  2088. X        writ_echo (MSG_one_w);
  2089. X        return (FALSE);
  2090. X    }
  2091. X
  2092. X    if ((adjwp = curwp -> w_wndp) == NULL)
  2093. X    {
  2094. X        adjwp = wheadp;
  2095. X        while (adjwp -> w_wndp != curwp)
  2096. X            adjwp = adjwp -> w_wndp;
  2097. X    }
  2098. X
  2099. X    if (curwp -> w_ntrows <= n)
  2100. X    {
  2101. X        writ_echo (MSG_imp_chg);
  2102. X        return (FALSE);
  2103. X    }
  2104. X
  2105. X    if (curwp -> w_wndp == adjwp)
  2106. X    {
  2107. X        /* Grow below.       */
  2108. X        lp = adjwp -> w_linep;
  2109. X        for (i = 0; i < n && lback (lp) != adjwp -> w_bufp -> b_linep; ++i)
  2110. X            lp = lback (lp);
  2111. X        adjwp -> w_linep = lp;
  2112. X        adjwp -> w_toprow -= n;
  2113. X    }
  2114. X    else
  2115. X    {
  2116. X        /* Grow above.       */
  2117. X        lp = curwp -> w_linep;
  2118. X        for (i = 0; i < n && lp != curbp -> b_linep; ++i)
  2119. X            lp = lforw (lp);
  2120. X        curwp -> w_linep = lp;
  2121. X        curwp -> w_toprow += n;
  2122. X    }
  2123. X
  2124. X    curwp -> w_ntrows -= n;
  2125. X    adjwp -> w_ntrows += n;
  2126. X    curwp -> w_flag |= WFMODE | WFHARD;
  2127. X    adjwp -> w_flag |= WFMODE | WFHARD;
  2128. X    return (TRUE);
  2129. X}
  2130. X
  2131. X
  2132. X/*
  2133. X* Pick a window for a pop-up.
  2134. X* Split the screen if there is only
  2135. X* one window. Pick the uppermost window that
  2136. X* isn't the current window. An LRU algorithm
  2137. X* might be better. Return a pointer, or
  2138. X* NULL on error.
  2139. X*/
  2140. XWINDOW * wpopup ()
  2141. X{
  2142. X
  2143. X    register    WINDOW * wp;
  2144. X
  2145. X    if (wheadp -> w_wndp == NULL
  2146. X        && splitwind () == FALSE)
  2147. X        return (NULL);
  2148. X    wp = wheadp;                /* Find window to use    */
  2149. X    while (wp != NULL && wp == curwp)
  2150. X        wp = wp -> w_wndp;
  2151. X    return (wp);
  2152. X}
  2153. X
  2154. X
  2155. X/*
  2156. X* Refresh the display. 
  2157. X* In the normal case the
  2158. X* call to "update" in "main.c" refreshes the screen,
  2159. X* and all of the windows need not be recomputed.
  2160. X*/
  2161. Xbool refresh ()
  2162. X{
  2163. X    sgarbf = TRUE;
  2164. X    return (TRUE);
  2165. X}
  2166. END_OF_FILE
  2167.   if test 10328 -ne `wc -c <'window.c'`; then
  2168.     echo shar: \"'window.c'\" unpacked with wrong size!
  2169.   fi
  2170.   # end of 'window.c'
  2171. fi
  2172. echo shar: End of archive 7 \(of 9\).
  2173. cp /dev/null ark7isdone
  2174. MISSING=""
  2175. for I in 1 2 3 4 5 6 7 8 9 ; do
  2176.     if test ! -f ark${I}isdone ; then
  2177.     MISSING="${MISSING} ${I}"
  2178.     fi
  2179. done
  2180. if test "${MISSING}" = "" ; then
  2181.     echo You have unpacked all 9 archives.
  2182.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2183. else
  2184.     echo You still must unpack the following archives:
  2185.     echo "        " ${MISSING}
  2186. fi
  2187. exit 0
  2188. exit 0 # Just in case...
  2189.