home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / uemacs3.7 / part11 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  42.0 KB

  1. Subject: v06i081:  MicroEmacs, Version 3.7 (uEmacs3.7), Part11/12
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence
  6. Mod.sources: Volume 6, Issue 81
  7. Archive-name: uEmacs/Part11
  8.  
  9. [  This is the latest revision of one of two programs named "MicroEmacs";
  10.    when discussing these on the net, or in contacting the authors, make
  11.    sure to mention the version number -- in this case 3.7 -- as that is
  12.    the easiest way to distinguish between them.  Daniel will be posting
  13.    uuencoded executables in net.micro.pc and net.micro.amiga; the file
  14.    'readme' contains information on how to also get these from him
  15.    directly.   --r$ ]
  16.  
  17. echo extracting - tcap.c
  18. sed 's/^X//' > tcap.c << 'FRIDAY_NIGHT'
  19. X/*    tcap:    Unix V5, V7 and BS4.2 Termcap video driver
  20. X        for MicroEMACS
  21. X*/
  22. X
  23. X#define    termdef    1            /* don't define "term" external */
  24. X
  25. X#include <stdio.h>
  26. X#include    "estruct.h"
  27. X#include        "edef.h"
  28. X
  29. X#if TERMCAP
  30. X
  31. X#define    MARGIN    8
  32. X#define    SCRSIZ    64
  33. X#define    NPAUSE    10            /* # times thru update to pause */
  34. X#define BEL     0x07
  35. X#define ESC     0x1B
  36. X
  37. Xextern int      ttopen();
  38. Xextern int      ttgetc();
  39. Xextern int      ttputc();
  40. Xextern int    tgetnum();
  41. Xextern int      ttflush();
  42. Xextern int      ttclose();
  43. Xextern int      tcapmove();
  44. Xextern int      tcapeeol();
  45. Xextern int      tcapeeop();
  46. Xextern int      tcapbeep();
  47. Xextern int    tcaprev();
  48. Xextern int      tcapopen();
  49. Xextern int      tput();
  50. Xextern char     *tgoto();
  51. X#if    COLOR
  52. Xextern    int    tcapfcol();
  53. Xextern    int    tcapbcol();
  54. X#endif
  55. X
  56. X#define TCAPSLEN 315
  57. Xchar tcapbuf[TCAPSLEN];
  58. Xchar *UP, PC, *CM, *CE, *CL, *SO, *SE;
  59. X
  60. XTERM term = {
  61. X    NULL,        /* these two values are set dynamically at open time */
  62. X    NULL,
  63. X    MARGIN,
  64. X    SCRSIZ,
  65. X    NPAUSE,
  66. X        tcapopen,
  67. X        ttclose,
  68. X        ttgetc,
  69. X        ttputc,
  70. X        ttflush,
  71. X        tcapmove,
  72. X        tcapeeol,
  73. X        tcapeeop,
  74. X        tcapbeep,
  75. X        tcaprev
  76. X#if    COLOR
  77. X    , tcapfcol,
  78. X    tcapbcol
  79. X#endif
  80. X};
  81. X
  82. Xtcapopen()
  83. X
  84. X{
  85. X        char *getenv();
  86. X        char *t, *p, *tgetstr();
  87. X        char tcbuf[1024];
  88. X        char *tv_stype;
  89. X        char err_str[72];
  90. X
  91. X        if ((tv_stype = getenv("TERM")) == NULL)
  92. X        {
  93. X                puts("Environment variable TERM not defined!");
  94. X                exit(1);
  95. X        }
  96. X
  97. X        if ((tgetent(tcbuf, tv_stype)) != 1)
  98. X        {
  99. X                sprintf(err_str, "Unknown terminal type %s!", tv_stype);
  100. X                puts(err_str);
  101. X                exit(1);
  102. X        }
  103. X
  104. X       if ((term.t_nrow=(short)tgetnum("li")-1) == -1){
  105. X               puts("termcap entry incomplete (lines)");
  106. X               exit(1);
  107. X       }
  108. X       if ((term.t_ncol=(short)tgetnum("co")) == -1){
  109. X               puts("Termcap entry incomplete (columns)");
  110. X               exit(1);
  111. X       }
  112. X
  113. X        p = tcapbuf;
  114. X        t = tgetstr("pc", &p);
  115. X        if(t)
  116. X                PC = *t;
  117. X
  118. X        CL = tgetstr("cl", &p);
  119. X        CM = tgetstr("cm", &p);
  120. X        CE = tgetstr("ce", &p);
  121. X        UP = tgetstr("up", &p);
  122. X    SE = tgetstr("se", &p);
  123. X    SO = tgetstr("so", &p);
  124. X    if (SO != NULL)
  125. X        revexist = TRUE;
  126. X
  127. X        if(CL == NULL || CM == NULL || UP == NULL)
  128. X        {
  129. X                puts("Incomplete termcap entry\n");
  130. X                exit(1);
  131. X        }
  132. X
  133. X    if (CE == NULL)        /* will we be able to use clear to EOL? */
  134. X        eolexist = FALSE;
  135. X        
  136. X        if (p >= &tcapbuf[TCAPSLEN])
  137. X        {
  138. X                puts("Terminal description too big!\n");
  139. X                exit(1);
  140. X        }
  141. X        ttopen();
  142. X}
  143. X
  144. Xtcapmove(row, col)
  145. Xregister int row, col;
  146. X{
  147. X        putpad(tgoto(CM, col, row));
  148. X}
  149. X
  150. Xtcapeeol()
  151. X{
  152. X        putpad(CE);
  153. X}
  154. X
  155. Xtcapeeop()
  156. X{
  157. X        putpad(CL);
  158. X}
  159. X
  160. Xtcaprev(state)        /* change reverse video status */
  161. X
  162. Xint state;        /* FALSE = normal video, TRUE = reverse video */
  163. X
  164. X{
  165. X    static int revstate = FALSE;
  166. X    /* mustn't send SE unless SO already sent, and vice versa */
  167. X
  168. X#if 0
  169. X    if (state) {
  170. X        if ((SO != NULL) && (revstate == FALSE))
  171. X            putpad(SO);
  172. X    } else
  173. X        if ((SE != NULL) && (revstate == TRUE))
  174. X            putpad(SE);
  175. X
  176. X    revstate = state;
  177. X#endif
  178. X    if (state) {
  179. X        if (SO != NULL)
  180. X            putpad(SO);
  181. X    } else
  182. X        if (SE != NULL)
  183. X            putpad(SE);
  184. X}
  185. X
  186. X#if    COLOR
  187. Xtcapfcol()    /* no colors here, ignore this */
  188. X{
  189. X}
  190. X
  191. Xtcapbcol()    /* no colors here, ignore this */
  192. X{
  193. X}
  194. X#endif
  195. X
  196. Xtcapbeep()
  197. X{
  198. X    ttputc(BEL);
  199. X}
  200. X
  201. Xputpad(str)
  202. Xchar    *str;
  203. X{
  204. X    tputs(str, 1, ttputc);
  205. X}
  206. X
  207. Xputnpad(str, n)
  208. Xchar    *str;
  209. X{
  210. X    tputs(str, n, ttputc);
  211. X}
  212. X
  213. X#else
  214. X
  215. Xhello()
  216. X{
  217. X}
  218. X
  219. X#endif TERMCAP
  220. FRIDAY_NIGHT
  221. echo extracting - termio.c
  222. sed 's/^X//' > termio.c << 'FRIDAY_NIGHT'
  223. X/*
  224. X * The functions in this file negotiate with the operating system for
  225. X * characters, and write characters in a barely buffered fashion on the display.
  226. X * All operating systems.
  227. X */
  228. X#include        <stdio.h>
  229. X#include    "estruct.h"
  230. X#include        "edef.h"
  231. X
  232. X#if     AMIGA
  233. X#define NEW 1006
  234. X#define AMG_MAXBUF      1024
  235. Xstatic long terminal;
  236. Xstatic char     scrn_tmp[AMG_MAXBUF+1];
  237. Xstatic int      scrn_tmp_p = 0;
  238. X#endif
  239. X
  240. X#if     VMS
  241. X#include        <stsdef.h>
  242. X#include        <ssdef.h>
  243. X#include        <descrip.h>
  244. X#include        <iodef.h>
  245. X#include        <ttdef.h>
  246. X#include    <tt2def.h>
  247. X
  248. X#define NIBUF   128                     /* Input buffer size            */
  249. X#define NOBUF   1024                    /* MM says bug buffers win!     */
  250. X#define EFN     0                       /* Event flag                   */
  251. X
  252. Xchar    obuf[NOBUF];                    /* Output buffer                */
  253. Xint     nobuf;                  /* # of bytes in above    */
  254. Xchar    ibuf[NIBUF];                    /* Input buffer          */
  255. Xint     nibuf;                  /* # of bytes in above  */
  256. Xint     ibufi;                  /* Read index                   */
  257. Xint     oldmode[3];                     /* Old TTY mode bits            */
  258. Xint     newmode[3];                     /* New TTY mode bits            */
  259. Xshort   iochan;                  /* TTY I/O channel             */
  260. X#endif
  261. X
  262. X#if     CPM
  263. X#include        <bdos.h>
  264. X#endif
  265. X
  266. X#if     MSDOS & (LATTICE | MSDOS)
  267. Xunion REGS rg;        /* cpu register for use of DOS calls */
  268. Xint nxtchar = -1;    /* character held from type ahead    */
  269. X#endif
  270. X
  271. X#if RAINBOW
  272. X#include "rainbow.h"
  273. X#endif
  274. X
  275. X#if    USG            /* System V */
  276. X#include    <signal.h>
  277. X#include    <termio.h>
  278. Xstruct    termio    otermio;    /* original terminal characteristics */
  279. Xstruct    termio    ntermio;    /* charactoristics to use inside */
  280. X#endif
  281. X
  282. X#if V7 | BSD
  283. X#undef    CTRL
  284. X#include        <sgtty.h>        /* for stty/gtty functions */
  285. X#include    <signal.h>
  286. Xstruct  sgttyb  ostate;          /* saved tty state */
  287. Xstruct  sgttyb  nstate;          /* values for editor mode */
  288. Xstruct tchars    otchars;    /* Saved terminal special character set */
  289. Xstruct tchars    ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  290. X                /* A lot of nothing */
  291. X#if BSD
  292. X#include <sys/ioctl.h>        /* to get at the typeahead */
  293. Xextern    int rtfrmshell();    /* return from suspended shell */
  294. X#define    TBUFSIZ    128
  295. Xchar tobuf[TBUFSIZ];        /* terminal output buffer */
  296. X#endif
  297. X#endif
  298. X
  299. X/*
  300. X * This function is called once to set up the terminal device streams.
  301. X * On VMS, it translates TT until it finds the terminal, then assigns
  302. X * a channel to it and sets it raw. On CPM it is a no-op.
  303. X */
  304. Xttopen()
  305. X{
  306. X    /* on all screens we are not sure of the initial position
  307. X       of the cursor                    */
  308. X    ttrow = 999;
  309. X    ttcol = 999;
  310. X
  311. X#if     AMIGA
  312. X        terminal = Open("RAW:1/1/639/199/MicroEMACS 3.7/Amiga", NEW);
  313. X#endif
  314. X#if     VMS
  315. X        struct  dsc$descriptor  idsc;
  316. X        struct  dsc$descriptor  odsc;
  317. X        char    oname[40];
  318. X        int     iosb[2];
  319. X        int     status;
  320. X
  321. X        odsc.dsc$a_pointer = "TT";
  322. X        odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  323. X        odsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  324. X        odsc.dsc$b_class        = DSC$K_CLASS_S;
  325. X        idsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  326. X        idsc.dsc$b_class        = DSC$K_CLASS_S;
  327. X        do {
  328. X                idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  329. X                idsc.dsc$w_length  = odsc.dsc$w_length;
  330. X                odsc.dsc$a_pointer = &oname[0];
  331. X                odsc.dsc$w_length  = sizeof(oname);
  332. X                status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  333. X                if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  334. X                        exit(status);
  335. X                if (oname[0] == 0x1B) {
  336. X                        odsc.dsc$a_pointer += 4;
  337. X                        odsc.dsc$w_length  -= 4;
  338. X                }
  339. X        } while (status == SS$_NORMAL);
  340. X        status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  341. X        if (status != SS$_NORMAL)
  342. X                exit(status);
  343. X        status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  344. X                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
  345. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  346. X                exit(status);
  347. X        newmode[0] = oldmode[0];
  348. X        newmode[1] = oldmode[1] | TT$M_NOECHO;
  349. X        newmode[1] &= ~(TT$M_TTSYNC|TT$M_HOSTSYNC);
  350. X        newmode[2] = oldmode[2] | TT2$M_PASTHRU;
  351. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  352. X                          newmode, sizeof(newmode), 0, 0, 0, 0);
  353. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  354. X                exit(status);
  355. X        term.t_nrow = (newmode[1]>>24) - 1;
  356. X        term.t_ncol = newmode[0]>>16;
  357. X
  358. X#endif
  359. X#if     CPM
  360. X#endif
  361. X
  362. X#if     MSDOS & (HP150 == 0) & LATTICE
  363. X    /* kill the ctrl-break interupt */
  364. X    rg.h.ah = 0x33;        /* control-break check dos call */
  365. X    rg.h.al = 1;        /* set the current state */
  366. X    rg.h.dl = 0;        /* set it OFF */
  367. X    intdos(&rg, &rg);    /* go for it! */
  368. X#endif
  369. X
  370. X#if    USG
  371. X    ioctl(o, TCGETA, &otermio);    /* save old settings */
  372. X    ntermio.c_iflag = 0;        /* setup new settings */
  373. X    ntermio.c_oflag = 0;
  374. X    ntermio.c_cflag = otermio.c_cflag;
  375. X    ntermio.c_lflag = 0;
  376. X    ntermio.c_line = otermio.c_line;
  377. X    ntermio.c_cc[VMIN] = 1;
  378. X    ntermio.c_cc[VTIME] = 0;
  379. X    ioctl(0, TCSETA, &ntermio);    /* and activate them */
  380. X#endif
  381. X
  382. X#if     V7 | BSD
  383. X        gtty(0, &ostate);                       /* save old state */
  384. X        gtty(0, &nstate);                       /* get base of new state */
  385. X        nstate.sg_flags |= RAW;
  386. X        nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
  387. X        stty(0, &nstate);                       /* set mode */
  388. X    ioctl(0, TIOCGETC, &otchars);        /* Save old characters */
  389. X    ioctl(0, TIOCSETC, &ntchars);        /* Place new character into K */
  390. X#if    BSD
  391. X    /* provide a smaller terminal output buffer so that
  392. X       the type ahead detection works better (more often) */
  393. X    setbuffer(stdout, &tobuf[0], TBUFSIZ);
  394. X    signal(SIGTSTP,SIG_DFL);    /* set signals so that we can */
  395. X    signal(SIGCONT,rtfrmshell);    /* suspend & restart emacs */
  396. X#endif
  397. X#endif
  398. X}
  399. X
  400. X/*
  401. X * This function gets called just before we go back home to the command
  402. X * interpreter. On VMS it puts the terminal back in a reasonable state.
  403. X * Another no-operation on CPM.
  404. X */
  405. Xttclose()
  406. X{
  407. X#if     AMIGA
  408. X        amg_flush();
  409. X        Close(terminal);
  410. X#endif
  411. X#if     VMS
  412. X        int     status;
  413. X        int     iosb[1];
  414. X
  415. X        ttflush();
  416. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  417. X                 oldmode, sizeof(oldmode), 0, 0, 0, 0);
  418. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  419. X                exit(status);
  420. X        status = SYS$DASSGN(iochan);
  421. X        if (status != SS$_NORMAL)
  422. X                exit(status);
  423. X#endif
  424. X#if     CPM
  425. X#endif
  426. X#if     MSDOS & (HP150 == 0) & LATTICE
  427. X    /* restore the ctrl-break interupt */
  428. X    rg.h.ah = 0x33;        /* control-break check dos call */
  429. X    rg.h.al = 1;        /* set the current state */
  430. X    rg.h.dl = 1;        /* set it ON */
  431. X    intdos(&rg, &rg);    /* go for it! */
  432. X#endif
  433. X
  434. X#if    USG
  435. X    ioctl(0, TCSETA, &otermio);    /* restore terminal settings */
  436. X#endif
  437. X
  438. X#if     V7 | BSD
  439. X        stty(0, &ostate);
  440. X    ioctl(0, TIOCSETC, &otchars);    /* Place old character into K */
  441. X#endif
  442. X}
  443. X
  444. X/*
  445. X * Write a character to the display. On VMS, terminal output is buffered, and
  446. X * we just put the characters in the big array, after checking for overflow.
  447. X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  448. X * MS-DOS (use the very very raw console output routine).
  449. X */
  450. Xttputc(c)
  451. X#if     AMIGA
  452. X        char c;
  453. X#endif
  454. X{
  455. X#if     AMIGA
  456. X        scrn_tmp[scrn_tmp_p++] = c;
  457. X        if(scrn_tmp_p>=AMG_MAXBUF)
  458. X                amg_flush();
  459. X#endif
  460. X#if     VMS
  461. X        if (nobuf >= NOBUF)
  462. X                ttflush();
  463. X        obuf[nobuf++] = c;
  464. X#endif
  465. X
  466. X#if     CPM
  467. X        bios(BCONOUT, c, 0);
  468. X#endif
  469. X
  470. X#if     MSDOS & MWC86
  471. X        dosb(CONDIO, c, 0);
  472. X#endif
  473. X
  474. X#if    MSDOS & (LATTICE | AZTEC) & ~IBMPC
  475. X    bdos(6, c, 0);
  476. X#endif
  477. X
  478. X#if RAINBOW
  479. X        Put_Char(c);                    /* fast video */
  480. X#endif
  481. X
  482. X
  483. X#if     V7 | USG | BSD
  484. X        fputc(c, stdout);
  485. X#endif
  486. X}
  487. X
  488. X#if    AMIGA
  489. Xamg_flush()
  490. X{
  491. X        if(scrn_tmp_p)
  492. X                Write(terminal,scrn_tmp,scrn_tmp_p);
  493. X        scrn_tmp_p = 0;
  494. X}
  495. X#endif
  496. X
  497. X/*
  498. X * Flush terminal buffer. Does real work where the terminal output is buffered
  499. X * up. A no-operation on systems where byte at a time terminal I/O is done.
  500. X */
  501. Xttflush()
  502. X{
  503. X#if     AMIGA
  504. X        amg_flush();
  505. X#endif
  506. X#if     VMS
  507. X        int     status;
  508. X        int     iosb[2];
  509. X
  510. X        status = SS$_NORMAL;
  511. X        if (nobuf != 0) {
  512. X                status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  513. X                         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  514. X                if (status == SS$_NORMAL)
  515. X                        status = iosb[0] & 0xFFFF;
  516. X                nobuf = 0;
  517. X        }
  518. X        return (status);
  519. X#endif
  520. X
  521. X#if     CPM
  522. X#endif
  523. X
  524. X#if     MSDOS
  525. X#endif
  526. X
  527. X#if     V7 | USG | BSD
  528. X        fflush(stdout);
  529. X#endif
  530. X}
  531. X
  532. X/*
  533. X * Read a character from the terminal, performing no editing and doing no echo
  534. X * at all. More complex in VMS that almost anyplace else, which figures. Very
  535. X * simple on CPM, because the system can do exactly what you want.
  536. X */
  537. Xttgetc()
  538. X{
  539. X#if     AMIGA
  540. X        char ch;
  541. X        amg_flush();
  542. X        Read(terminal, &ch, 1);
  543. X        return(255 & (int)ch);
  544. X#endif
  545. X#if     VMS
  546. X        int     status;
  547. X        int     iosb[2];
  548. X        int     term[2];
  549. X
  550. X        while (ibufi >= nibuf) {
  551. X                ibufi = 0;
  552. X                term[0] = 0;
  553. X                term[1] = 0;
  554. X                status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  555. X                         iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  556. X                if (status != SS$_NORMAL)
  557. X                        exit(status);
  558. X                status = iosb[0] & 0xFFFF;
  559. X                if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  560. X                        exit(status);
  561. X                nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  562. X                if (nibuf == 0) {
  563. X                        status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  564. X                                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  565. X                        if (status != SS$_NORMAL
  566. X                        || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  567. X                                exit(status);
  568. X                        nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  569. X                }
  570. X        }
  571. X        return (ibuf[ibufi++] & 0xFF);    /* Allow multinational  */
  572. X#endif
  573. X
  574. X#if     CPM
  575. X        return (biosb(BCONIN, 0, 0));
  576. X#endif
  577. X
  578. X#if RAINBOW
  579. X        int Ch;
  580. X
  581. X        while ((Ch = Read_Keyboard()) < 0);
  582. X
  583. X        if ((Ch & Function_Key) == 0)
  584. X                if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
  585. X                        Ch &= 0xFF;
  586. X
  587. X        return Ch;
  588. X#endif
  589. X
  590. X#if     MSDOS & MWC86
  591. X        return (dosb(CONRAW, 0, 0));
  592. X#endif
  593. X
  594. X#if    MSDOS & (LATTICE | MSC)
  595. X    int c;        /* character read */
  596. X
  597. X    /* if a char already is ready, return it */
  598. X    if (nxtchar >= 0) {
  599. X        c = nxtchar;
  600. X        nxtchar = -1;
  601. X        return(c);
  602. X    }
  603. X
  604. X    /* call the dos to get a char */
  605. X    rg.h.ah = 7;        /* dos Direct Console Input call */
  606. X    intdos(&rg, &rg);
  607. X    c = rg.h.al;        /* grab the char */
  608. X    return(c & 255);
  609. X#endif
  610. X
  611. X#if    MSDOS & AZTEC
  612. X    int c;        /* character read */
  613. X
  614. X    /* if a char already is ready, return it */
  615. X    if (nxtchar >= 0) {
  616. X        c = nxtchar;
  617. X        nxtchar = -1;
  618. X        return(c);
  619. X    }
  620. X
  621. X    /* call the dos to get a char */
  622. X    rg.h.ah = 7;        /* dos Direct Console I/O call */
  623. X    sysint(33, &rg, &rg);
  624. X    c = rg.h.al;        /* grab the char */
  625. X    return(c & 255);
  626. X#endif
  627. X
  628. X#if     V7 | USG | BSD
  629. X        return(127 & fgetc(stdin));
  630. X#endif
  631. X}
  632. X
  633. X#if    TYPEAH
  634. X/* typahead:    Check to see if any characters are already in the
  635. X        keyboard buffer
  636. X*/
  637. X
  638. Xtypahead()
  639. X
  640. X{
  641. X#if    MSDOS & (LATTICE | AZTEC)
  642. X    int c;        /* character read */
  643. X    int flags;    /* cpu flags from dos call */
  644. X
  645. X#if    MSC
  646. X    if (kbhit() != 0)
  647. X        return(TRUE);
  648. X    else
  649. X        return(FALSE);
  650. X#endif
  651. X
  652. X    if (nxtchar >= 0)
  653. X        return(TRUE);
  654. X
  655. X    rg.h.ah = 6;    /* Direct Console I/O call */
  656. X    rg.h.dl = 255;    /*         does console input */
  657. X#if    LATTICE
  658. X    flags = intdos(&rg, &rg);
  659. X#else
  660. X    flags = sysint(33, &rg, &rg);
  661. X#endif
  662. X    c = rg.h.al;    /* grab the character */
  663. X
  664. X    /* no character pending */
  665. X    if ((flags & 64) != 0)
  666. X        return(FALSE);
  667. X
  668. X    /* save the character and return true */
  669. X    nxtchar = c;
  670. X    return(TRUE);
  671. X#endif
  672. X
  673. X#if    BSD
  674. X    int x;    /* holds # of pending chars */
  675. X
  676. X    return((ioctl(0,FIONREAD,&x) < 0) ? 0 : x);
  677. X#endif
  678. X    return(FALSE);
  679. X}
  680. X#endif
  681. X
  682. FRIDAY_NIGHT
  683. echo extracting - vmsvt.c
  684. sed 's/^X//' > vmsvt.c << 'FRIDAY_NIGHT'
  685. X/*
  686. X *  VMS terminal handling routines
  687. X *
  688. X *  Known types are:
  689. X *    VT52, VT100, and UNKNOWN (which is defined to be an ADM3a)
  690. X *    written by Curtis Smith
  691. X */
  692. X
  693. X#include        <stdio.h>
  694. X#include        "estruct.h"
  695. X#include    "edef.h"
  696. X
  697. X#if     VMSVT
  698. X
  699. X#define    termdef    1            /* don't define "term" external */
  700. X
  701. X#include <ssdef.h>        /* Status code definitions        */
  702. X#include <descrip.h>        /* Descriptor structures        */
  703. X#include <iodef.h>        /* IO commands                */
  704. X#include <ttdef.h>        /* tty commands                */
  705. X
  706. Xextern  int     ttopen();               /* Forward references.          */
  707. Xextern  int     ttgetc();
  708. Xextern  int     ttputc();
  709. Xextern  int     ttflush();
  710. Xextern  int     ttclose();
  711. Xextern  int    vmsopen();
  712. Xextern  int    vmseeol();
  713. Xextern  int    vmseeop();
  714. Xextern  int    vmsbeep();
  715. Xextern  int    vmsmove();
  716. Xextern    int    vmsrev();
  717. Xextern  int    eolexist;
  718. X#if    COLOR
  719. Xextern    int    vmsfcol();
  720. Xextern    int    vmsbcol();
  721. X#endif
  722. X
  723. X#define    NROWS    24            /* # of screen rolls        */
  724. X#define    NCOLS    80            /* # of screen columns        */
  725. X#define    MARGIN    8            /* size of minimim margin and    */
  726. X#define    SCRSIZ    64            /* scroll size for extended lines */
  727. X#define    NPAUSE    100            /* # times thru update to pause */
  728. X
  729. X/*
  730. X * Dispatch table. All the
  731. X * hard fields just point into the
  732. X * terminal I/O code.
  733. X */
  734. XTERM    term    = {
  735. X    NROWS - 1,
  736. X    NCOLS,
  737. X    MARGIN,
  738. X    SCRSIZ,
  739. X    NPAUSE,
  740. X        &vmsopen,
  741. X        &ttclose,
  742. X        &ttgetc,
  743. X        &ttputc,
  744. X        &ttflush,
  745. X        &vmsmove,
  746. X        &vmseeol,
  747. X        &vmseeop,
  748. X        &vmsbeep,
  749. X        &vmsrev
  750. X#if    COLOR
  751. X    , &vmsfcol,
  752. X    &vmsbcol
  753. X#endif
  754. X};
  755. X
  756. Xchar * termeop;            /* Erase to end of page string        */
  757. Xint eoppad;            /* Number of pad characters after eop    */
  758. Xchar * termeol;            /* Erase to end of line string        */
  759. Xint eolpad;            /* Number of pad characters after eol    */
  760. Xchar termtype;            /* Terminal type identifier        */
  761. X
  762. X
  763. X/*******
  764. X *  ttputs - Send a string to ttputc
  765. X *******/
  766. X
  767. Xttputs(string)
  768. Xchar * string;
  769. X{
  770. X    while (*string != '\0')
  771. X        ttputc(*string++);
  772. X}
  773. X
  774. X
  775. X/*******
  776. X *  vmspad - Pad the output after an escape sequence
  777. X *******/
  778. X
  779. Xvmspad(count)
  780. Xint count;
  781. X{
  782. X    while (count-- > 0)
  783. X        ttputc('\0');
  784. X}
  785. X
  786. X
  787. X/*******
  788. X *  vmsmove - Move the cursor
  789. X *******/
  790. X
  791. Xvmsmove(row, col)
  792. X{
  793. X    switch (termtype) {
  794. X        case TT$_UNKNOWN:
  795. X            ttputc('\033');
  796. X            ttputc('=');
  797. X            ttputc(row+' ');
  798. X            ttputc(col+' ');
  799. X            break;
  800. X        case TT$_VT52:
  801. X            ttputc('\033');
  802. X            ttputc('Y');
  803. X            ttputc(row+' ');
  804. X            ttputc(col+' ');
  805. X            break;
  806. X                case TT$_VT100:         /* I'm assuming that all these  */
  807. X                case TT$_VT101:         /* are a super set of the VT100 */
  808. X                case TT$_VT102:         /* If I'm wrong, just remove    */
  809. X                case TT$_VT105:         /* those entries that aren't.   */
  810. X                case TT$_VT125:
  811. X                case TT$_VT131:
  812. X                case TT$_VT132:
  813. X                case TT$_VT200_SERIES:
  814. X            {
  815. X                char buffer[24];
  816. X
  817. X                sprintf(buffer, "\033[%d;%dH", row+1, col+1);
  818. X                ttputs(buffer);
  819. X                vmspad(50);
  820. X            }
  821. X    }
  822. X}
  823. X
  824. X/*******
  825. X *  vmsrev - set the reverse video status
  826. X *******/
  827. X
  828. Xvmsrev(status)
  829. X
  830. Xint status;    /* TRUE = reverse video, FALSE = normal video */
  831. X{
  832. X    switch (termtype) {
  833. X        case TT$_UNKNOWN:
  834. X            break;
  835. X        case TT$_VT52:
  836. X            break;
  837. X        case TT$_VT100:
  838. X            if (status) {
  839. X                ttputc('\033');
  840. X                ttputc('[');
  841. X                ttputc('7');
  842. X                ttputc('m');
  843. X            } else {
  844. X                ttputc('\033');
  845. X                ttputc('[');
  846. X                ttputc('m');
  847. X            }
  848. X            break;
  849. X    }
  850. X}
  851. X
  852. X#if    COLOR
  853. X/*******
  854. X *  vmsfcol - Set the forground color (not implimented)
  855. X *******/
  856. Xvmsfcol()
  857. X{
  858. X}
  859. X
  860. X/*******
  861. X *  vmsbcol - Set the background color (not implimented)
  862. X *******/
  863. Xvmsbcol()
  864. X{
  865. X}
  866. X#endif
  867. X
  868. X/*******
  869. X *  vmseeol - Erase to end of line
  870. X *******/
  871. X
  872. Xvmseeol()
  873. X{
  874. X    ttputs(termeol);
  875. X    vmspad(eolpad);
  876. X}
  877. X
  878. X
  879. X/*******
  880. X *  vmseeop - Erase to end of page (clear screen)
  881. X *******/
  882. X
  883. Xvmseeop()
  884. X{
  885. X    ttputs(termeop);
  886. X    vmspad(eoppad);
  887. X}
  888. X
  889. X
  890. X/*******
  891. X *  vmsbeep - Ring the bell
  892. X *******/
  893. X
  894. Xvmsbeep()
  895. X{
  896. X    ttputc('\007');
  897. X}
  898. X
  899. X
  900. X/*******
  901. X *  vmsopen - Get terminal type and open terminal
  902. X *******/
  903. X
  904. Xvmsopen()
  905. X{
  906. X    termtype = vmsgtty();
  907. X    switch (termtype) {
  908. X        case TT$_UNKNOWN:    /* Assume ADM3a    */
  909. X            eolexist = FALSE;
  910. X            termeop = "\032";
  911. X            eoppad = 0;
  912. X            break;
  913. X        case TT$_VT52:
  914. X            termeol = "\033K";
  915. X            eolpad = 0;
  916. X            termeop = "\033H\033J";
  917. X            eoppad = 0;
  918. X            break;
  919. X        case TT$_VT100:
  920. X            revexist = TRUE;
  921. X            termeol = "\033[K";
  922. X            eolpad = 3;
  923. X            termeop = "\033[;H\033[2J";
  924. X            eoppad = 50;
  925. X            break;
  926. X        default:
  927. X            puts("Terminal type not supported");
  928. X            exit (SS$_NORMAL);
  929. X    }
  930. X        ttopen();
  931. X}
  932. X
  933. X
  934. Xstruct iosb {            /* I/O status block            */
  935. X    short    i_cond;        /* Condition value            */
  936. X    short    i_xfer;        /* Transfer count            */
  937. X    long    i_info;        /* Device information            */
  938. X};
  939. X
  940. Xstruct termchar {        /* Terminal characteristics        */
  941. X    char    t_class;    /* Terminal class            */
  942. X    char    t_type;        /* Terminal type            */
  943. X    short    t_width;    /* Terminal width in characters        */
  944. X    long    t_mandl;    /* Terminal's mode and length        */
  945. X    long    t_extend;    /* Extended terminal characteristics    */
  946. X};
  947. X
  948. X/*******
  949. X *  vmsgtty - Get terminal type from system control block
  950. X *******/
  951. X
  952. Xvmsgtty()
  953. X{
  954. X    short fd;
  955. X    int status;
  956. X    struct iosb iostatus;
  957. X    struct termchar tc;
  958. X    $DESCRIPTOR(devnam, "SYS$INPUT");
  959. X
  960. X    status = sys$assign(&devnam, &fd, 0, 0);
  961. X    if (status != SS$_NORMAL)
  962. X        exit (status);
  963. X
  964. X    status = sys$qiow(        /* Queue and wait        */
  965. X        0,            /* Wait on event flag zero    */
  966. X        fd,            /* Channel to input terminal    */
  967. X        IO$_SENSEMODE,        /* Get current characteristic    */
  968. X        &iostatus,        /* Status after operation    */
  969. X        0, 0,            /* No AST service        */
  970. X        &tc,            /* Terminal characteristics buf    */
  971. X        sizeof(tc),        /* Size of the buffer        */
  972. X        0, 0, 0, 0);        /* P3-P6 unused            */
  973. X
  974. X                    /* De-assign the input device    */
  975. X    if (sys$dassgn(fd) != SS$_NORMAL)
  976. X        exit(status);
  977. X
  978. X    if (status != SS$_NORMAL)    /* Jump out if bad status    */
  979. X        exit(status);
  980. X    if (iostatus.i_cond != SS$_NORMAL)
  981. X        exit(iostatus.i_cond);
  982. X
  983. X    return tc.t_type;        /* Return terminal type        */
  984. X}
  985. X
  986. X#else
  987. X
  988. Xhellovms()
  989. X
  990. X{
  991. X}
  992. X
  993. X#endif    VMSVT
  994. FRIDAY_NIGHT
  995. echo extracting - vt52.c
  996. sed 's/^X//' > vt52.c << 'FRIDAY_NIGHT'
  997. X/*
  998. X * The routines in this file
  999. X * provide support for VT52 style terminals
  1000. X * over a serial line. The serial I/O services are
  1001. X * provided by routines in "termio.c". It compiles
  1002. X * into nothing if not a VT52 style device. The
  1003. X * bell on the VT52 is terrible, so the "beep"
  1004. X * routine is conditionalized on defining BEL.
  1005. X */
  1006. X#define    termdef    1            /* don't define "term" external */
  1007. X
  1008. X#include        <stdio.h>
  1009. X#include        "estruct.h"
  1010. X#include    "edef.h"
  1011. X
  1012. X#if     VT52
  1013. X
  1014. X#define NROW    24                      /* Screen size.                 */
  1015. X#define NCOL    80                      /* Edit if you want to.         */
  1016. X#define    MARGIN    8            /* size of minimim margin and    */
  1017. X#define    SCRSIZ    64            /* scroll size for extended lines */
  1018. X#define    NPAUSE    100            /* # times thru update to pause */
  1019. X#define BIAS    0x20                    /* Origin 0 coordinate bias.    */
  1020. X#define ESC     0x1B                    /* ESC character.               */
  1021. X#define BEL     0x07                    /* ascii bell character         */
  1022. X
  1023. Xextern  int     ttopen();               /* Forward references.          */
  1024. Xextern  int     ttgetc();
  1025. Xextern  int     ttputc();
  1026. Xextern  int     ttflush();
  1027. Xextern  int     ttclose();
  1028. Xextern  int     vt52move();
  1029. Xextern  int     vt52eeol();
  1030. Xextern  int     vt52eeop();
  1031. Xextern  int     vt52beep();
  1032. Xextern  int     vt52open();
  1033. Xextern    int    vt52rev();
  1034. X#if    COLOR
  1035. Xextern    int    vt52fcol();
  1036. Xextern    int    vt52bcol();
  1037. X#endif
  1038. X
  1039. X/*
  1040. X * Dispatch table. All the
  1041. X * hard fields just point into the
  1042. X * terminal I/O code.
  1043. X */
  1044. XTERM    term    = {
  1045. X        NROW-1,
  1046. X        NCOL,
  1047. X    MARGIN,
  1048. X    SCRSIZ,
  1049. X    NPAUSE,
  1050. X        &vt52open,
  1051. X        &ttclose,
  1052. X        &ttgetc,
  1053. X        &ttputc,
  1054. X        &ttflush,
  1055. X        &vt52move,
  1056. X        &vt52eeol,
  1057. X        &vt52eeop,
  1058. X        &vt52beep,
  1059. X        &vt52rev
  1060. X#if    COLOR
  1061. X    , &vt52fcol,
  1062. X    &vt52bcol
  1063. X#endif
  1064. X};
  1065. X
  1066. Xvt52move(row, col)
  1067. X{
  1068. X        ttputc(ESC);
  1069. X        ttputc('Y');
  1070. X        ttputc(row+BIAS);
  1071. X        ttputc(col+BIAS);
  1072. X}
  1073. X
  1074. Xvt52eeol()
  1075. X{
  1076. X        ttputc(ESC);
  1077. X        ttputc('K');
  1078. X}
  1079. X
  1080. Xvt52eeop()
  1081. X{
  1082. X        ttputc(ESC);
  1083. X        ttputc('J');
  1084. X}
  1085. X
  1086. Xvt52rev(status)    /* set the reverse video state */
  1087. X
  1088. Xint status;    /* TRUE = reverse video, FALSE = normal video */
  1089. X
  1090. X{
  1091. X    /* can't do this here, so we won't */
  1092. X}
  1093. X
  1094. X#if    COLOR
  1095. Xvt52fcol()    /* set the forground color [NOT IMPLIMENTED] */
  1096. X{
  1097. X}
  1098. X
  1099. Xvt52bcol()    /* set the background color [NOT IMPLIMENTED] */
  1100. X{
  1101. X}
  1102. X#endif
  1103. X
  1104. Xvt52beep()
  1105. X{
  1106. X#ifdef  BEL
  1107. X        ttputc(BEL);
  1108. X        ttflush();
  1109. X#endif
  1110. X}
  1111. X
  1112. X#endif
  1113. X
  1114. Xvt52open()
  1115. X{
  1116. X#if     V7 | BSD
  1117. X        register char *cp;
  1118. X        char *getenv();
  1119. X
  1120. X        if ((cp = getenv("TERM")) == NULL) {
  1121. X                puts("Shell variable TERM not defined!");
  1122. X                exit(1);
  1123. X        }
  1124. X        if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
  1125. X                puts("Terminal type not 'vt52'or 'z19' !");
  1126. X                exit(1);
  1127. X        }
  1128. X#endif
  1129. X        ttopen();
  1130. X}
  1131. FRIDAY_NIGHT
  1132. echo extracting - window.c
  1133. sed 's/^X//' > window.c << 'FRIDAY_NIGHT'
  1134. X/*
  1135. X * Window management. Some of the functions are internal, and some are
  1136. X * attached to keys that the user actually types.
  1137. X */
  1138. X
  1139. X#include        <stdio.h>
  1140. X#include        "estruct.h"
  1141. X#include    "edef.h"
  1142. X
  1143. X/*
  1144. X * Reposition dot in the current window to line "n". If the argument is
  1145. X * positive, it is that line. If it is negative it is that line from the
  1146. X * bottom. If it is 0 the window is centered (this is what the standard
  1147. X * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  1148. X */
  1149. Xreposition(f, n)
  1150. X    {
  1151. X    if (f == FALSE)    /* default to 0 to center screen */
  1152. X    n = 0;
  1153. X    curwp->w_force = n;
  1154. X    curwp->w_flag |= WFFORCE;
  1155. X    return (TRUE);
  1156. X    }
  1157. X
  1158. X/*
  1159. X * Refresh the screen. With no argument, it just does the refresh. With an
  1160. X * argument it recenters "." in the current window. Bound to "C-L".
  1161. X */
  1162. Xrefresh(f, n)
  1163. X    {
  1164. X    if (f == FALSE)
  1165. X        sgarbf = TRUE;
  1166. X    else
  1167. X        {
  1168. X        curwp->w_force = 0;             /* Center dot. */
  1169. X        curwp->w_flag |= WFFORCE;
  1170. X        }
  1171. X
  1172. X    return (TRUE);
  1173. X    }
  1174. X
  1175. X/*
  1176. X * The command make the next window (next => down the screen) the current
  1177. X * window. There are no real errors, although the command does nothing if
  1178. X * there is only 1 window on the screen. Bound to "C-X C-N".
  1179. X *
  1180. X * with an argument this command finds the <n>th window from the top
  1181. X *
  1182. X */
  1183. Xnextwind(f, n)
  1184. X
  1185. Xint f, n;    /* default flag and numeric argument */
  1186. X
  1187. X{
  1188. X    register WINDOW *wp;
  1189. X    register int nwindows;        /* total number of windows */
  1190. X
  1191. X    if (f) {
  1192. X
  1193. X        /* first count the # of windows */
  1194. X        wp = wheadp;
  1195. X        nwindows = 1;
  1196. X        while (wp->w_wndp != NULL) {
  1197. X            nwindows++;
  1198. X            wp = wp->w_wndp;
  1199. X        }
  1200. X
  1201. X        /* if the argument is negative, it is the nth window
  1202. X           from the bottom of the screen            */
  1203. X        if (n < 0)
  1204. X            n = nwindows + n + 1;
  1205. X
  1206. X        /* if an argument, give them that window from the top */
  1207. X        if (n > 0 && n <= nwindows) {
  1208. X            wp = wheadp;
  1209. X            while (--n)
  1210. X                wp = wp->w_wndp;
  1211. X        } else {
  1212. X            mlwrite("Window number out of range");
  1213. X            return(FALSE);
  1214. X        }
  1215. X    } else
  1216. X        if ((wp = curwp->w_wndp) == NULL)
  1217. X            wp = wheadp;
  1218. X    curwp = wp;
  1219. X    curbp = wp->w_bufp;
  1220. X    upmode();
  1221. X    return (TRUE);
  1222. X}
  1223. X
  1224. X/*
  1225. X * This command makes the previous window (previous => up the screen) the
  1226. X * current window. There arn't any errors, although the command does not do a
  1227. X * lot if there is 1 window.
  1228. X */
  1229. Xprevwind(f, n)
  1230. X{
  1231. X    register WINDOW *wp1;
  1232. X    register WINDOW *wp2;
  1233. X    register int nwindows;    /* total # of windows */
  1234. X
  1235. X    /* if we have an argument, we mean the nth window from the bottom */
  1236. X    if (f)
  1237. X        return(nextwind(f, -n));
  1238. X
  1239. X    wp1 = wheadp;
  1240. X    wp2 = curwp;
  1241. X
  1242. X    if (wp1 == wp2)
  1243. X        wp2 = NULL;
  1244. X
  1245. X    while (wp1->w_wndp != wp2)
  1246. X        wp1 = wp1->w_wndp;
  1247. X
  1248. X    curwp = wp1;
  1249. X    curbp = wp1->w_bufp;
  1250. X    upmode();
  1251. X    return (TRUE);
  1252. X}
  1253. X
  1254. X/*
  1255. X * This command moves the current window down by "arg" lines. Recompute the
  1256. X * top line in the window. The move up and move down code is almost completely
  1257. X * the same; most of the work has to do with reframing the window, and picking
  1258. X * a new dot. We share the code by having "move down" just be an interface to
  1259. X * "move up". Magic. Bound to "C-X C-N".
  1260. X */
  1261. Xmvdnwind(f, n)
  1262. X    int n;
  1263. X    {
  1264. X    return (mvupwind(f, -n));
  1265. X    }
  1266. X
  1267. X/*
  1268. X * Move the current window up by "arg" lines. Recompute the new top line of
  1269. X * the window. Look to see if "." is still on the screen. If it is, you win.
  1270. X * If it isn't, then move "." to center it in the new framing of the window
  1271. X * (this command does not really move "."; it moves the frame). Bound to
  1272. X * "C-X C-P".
  1273. X */
  1274. Xmvupwind(f, n)
  1275. X    int n;
  1276. X    {
  1277. X    register LINE *lp;
  1278. X    register int i;
  1279. X
  1280. X    lp = curwp->w_linep;
  1281. X
  1282. X    if (n < 0)
  1283. X        {
  1284. X        while (n++ && lp!=curbp->b_linep)
  1285. X            lp = lforw(lp);
  1286. X        }
  1287. X    else
  1288. X        {
  1289. X        while (n-- && lback(lp)!=curbp->b_linep)
  1290. X            lp = lback(lp);
  1291. X        }
  1292. X
  1293. X    curwp->w_linep = lp;
  1294. X    curwp->w_flag |= WFHARD;            /* Mode line is OK. */
  1295. X
  1296. X    for (i = 0; i < curwp->w_ntrows; ++i)
  1297. X        {
  1298. X        if (lp == curwp->w_dotp)
  1299. X            return (TRUE);
  1300. X        if (lp == curbp->b_linep)
  1301. X            break;
  1302. X        lp = lforw(lp);
  1303. X        }
  1304. X
  1305. X    lp = curwp->w_linep;
  1306. X    i  = curwp->w_ntrows/2;
  1307. X
  1308. X    while (i-- && lp != curbp->b_linep)
  1309. X        lp = lforw(lp);
  1310. X
  1311. X    curwp->w_dotp  = lp;
  1312. X    curwp->w_doto  = 0;
  1313. X    return (TRUE);
  1314. X    }
  1315. X
  1316. X/*
  1317. X * This command makes the current window the only window on the screen. Bound
  1318. X * to "C-X 1". Try to set the framing so that "." does not have to move on the
  1319. X * display. Some care has to be taken to keep the values of dot and mark in
  1320. X * the buffer structures right if the distruction of a window makes a buffer
  1321. X * become undisplayed.
  1322. X */
  1323. Xonlywind(f, n)
  1324. X{
  1325. X        register WINDOW *wp;
  1326. X        register LINE   *lp;
  1327. X        register int    i;
  1328. X
  1329. X        while (wheadp != curwp) {
  1330. X                wp = wheadp;
  1331. X                wheadp = wp->w_wndp;
  1332. X                if (--wp->w_bufp->b_nwnd == 0) {
  1333. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  1334. X                        wp->w_bufp->b_doto  = wp->w_doto;
  1335. X                        wp->w_bufp->b_markp = wp->w_markp;
  1336. X                        wp->w_bufp->b_marko = wp->w_marko;
  1337. X                }
  1338. X                free((char *) wp);
  1339. X        }
  1340. X        while (curwp->w_wndp != NULL) {
  1341. X                wp = curwp->w_wndp;
  1342. X                curwp->w_wndp = wp->w_wndp;
  1343. X                if (--wp->w_bufp->b_nwnd == 0) {
  1344. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  1345. X                        wp->w_bufp->b_doto  = wp->w_doto;
  1346. X                        wp->w_bufp->b_markp = wp->w_markp;
  1347. X                        wp->w_bufp->b_marko = wp->w_marko;
  1348. X                }
  1349. X                free((char *) wp);
  1350. X        }
  1351. X        lp = curwp->w_linep;
  1352. X        i  = curwp->w_toprow;
  1353. X        while (i!=0 && lback(lp)!=curbp->b_linep) {
  1354. X                --i;
  1355. X                lp = lback(lp);
  1356. X        }
  1357. X        curwp->w_toprow = 0;
  1358. X        curwp->w_ntrows = term.t_nrow-1;
  1359. X        curwp->w_linep  = lp;
  1360. X        curwp->w_flag  |= WFMODE|WFHARD;
  1361. X        return (TRUE);
  1362. X}
  1363. X
  1364. X/*
  1365. X * Delete the current window, placing its space in the window above,
  1366. X * or, if it is the top window, the window below. Bound to C-X 0.
  1367. X */
  1368. X
  1369. Xdelwind(f,n)
  1370. X
  1371. Xint f, n;    /* arguments are ignored for this command */
  1372. X
  1373. X{
  1374. X    register WINDOW *wp;    /* window to recieve deleted space */
  1375. X    register WINDOW *lwp;    /* ptr window before curwp */
  1376. X    register int target;    /* target line to search for */
  1377. X
  1378. X    /* if there is only one window, don't delete it */
  1379. X    if (wheadp->w_wndp == NULL) {
  1380. X        mlwrite("Can not delete this window");
  1381. X        return(FALSE);
  1382. X    }
  1383. X
  1384. X    /* find window before curwp in linked list */
  1385. X    wp = wheadp;
  1386. X    lwp = NULL;
  1387. X    while (wp != NULL) {
  1388. X        if (wp == curwp)
  1389. X            break;
  1390. X        lwp = wp;
  1391. X        wp = wp->w_wndp;
  1392. X    }
  1393. X
  1394. X    /* find recieving window and give up our space */
  1395. X    wp = wheadp;
  1396. X    if (curwp->w_toprow == 0) {
  1397. X        /* find the next window down */
  1398. X        target = curwp->w_ntrows + 1;
  1399. X        while (wp != NULL) {
  1400. X            if (wp->w_toprow == target)
  1401. X                break;
  1402. X            wp = wp->w_wndp;
  1403. X        }
  1404. X        if (wp == NULL)
  1405. X            return(FALSE);
  1406. X        wp->w_toprow = 0;
  1407. X        wp->w_ntrows += target;
  1408. X    } else {
  1409. X        /* find the next window up */
  1410. X        target = curwp->w_toprow - 1;
  1411. X        while (wp != NULL) {
  1412. X            if ((wp->w_toprow + wp->w_ntrows) == target)
  1413. X                break;
  1414. X            wp = wp->w_wndp;
  1415. X        }
  1416. X        if (wp == NULL)
  1417. X            return(FALSE);
  1418. X        wp->w_ntrows += 1 + curwp->w_ntrows;
  1419. X    }
  1420. X
  1421. X    /* get rid of the current window */
  1422. X    if (--curwp->w_bufp->b_nwnd == 0) {
  1423. X        curwp->w_bufp->b_dotp = curwp->w_dotp;
  1424. X        curwp->w_bufp->b_doto = curwp->w_doto;
  1425. X        curwp->w_bufp->b_markp = curwp->w_markp;
  1426. X        curwp->w_bufp->b_marko = curwp->w_marko;
  1427. X    }
  1428. X    if (lwp == NULL)
  1429. X        wheadp = curwp->w_wndp;
  1430. X    else
  1431. X        lwp->w_wndp = curwp->w_wndp;
  1432. X    free((char *)curwp);
  1433. X    curwp = wp;
  1434. X    wp->w_flag |= WFHARD;
  1435. X    curbp = wp->w_bufp;
  1436. X    upmode();
  1437. X    return(TRUE);
  1438. X}
  1439. X
  1440. X/*
  1441. X
  1442. XSplit the current window.  A window smaller than 3 lines cannot be
  1443. Xsplit.  An argument of 1 forces the cursor into the upper window, an
  1444. Xargument of two forces the cursor to the lower window.  The only other
  1445. Xerror that is possible is a "malloc" failure allocating the structure
  1446. Xfor the new window.  Bound to "C-X 2". 
  1447. X
  1448. X */
  1449. Xsplitwind(f, n)
  1450. X
  1451. Xint f, n;    /* default flag and numeric argument */
  1452. X
  1453. X{
  1454. X        register WINDOW *wp;
  1455. X        register LINE   *lp;
  1456. X        register int    ntru;
  1457. X        register int    ntrl;
  1458. X        register int    ntrd;
  1459. X        register WINDOW *wp1;
  1460. X        register WINDOW *wp2;
  1461. X    char *malloc();
  1462. X
  1463. X        if (curwp->w_ntrows < 3) {
  1464. X                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  1465. X                return (FALSE);
  1466. X        }
  1467. X        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  1468. X                mlwrite("Cannot allocate WINDOW block");
  1469. X                return (FALSE);
  1470. X        }
  1471. X        ++curbp->b_nwnd;                        /* Displayed twice.     */
  1472. X        wp->w_bufp  = curbp;
  1473. X        wp->w_dotp  = curwp->w_dotp;
  1474. X        wp->w_doto  = curwp->w_doto;
  1475. X        wp->w_markp = curwp->w_markp;
  1476. X        wp->w_marko = curwp->w_marko;
  1477. X        wp->w_flag  = 0;
  1478. X        wp->w_force = 0;
  1479. X#if    COLOR
  1480. X    /* set the colors of the new window */
  1481. X    wp->w_fcolor = gfcolor;
  1482. X    wp->w_bcolor = gbcolor;
  1483. X#endif
  1484. X        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  1485. X        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  1486. X        lp = curwp->w_linep;
  1487. X        ntrd = 0;
  1488. X        while (lp != curwp->w_dotp) {
  1489. X                ++ntrd;
  1490. X                lp = lforw(lp);
  1491. X        }
  1492. X        lp = curwp->w_linep;
  1493. X        if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  1494. X                /* Old is upper window. */
  1495. X                if (ntrd == ntru)               /* Hit mode line.       */
  1496. X                        lp = lforw(lp);
  1497. X                curwp->w_ntrows = ntru;
  1498. X                wp->w_wndp = curwp->w_wndp;
  1499. X                curwp->w_wndp = wp;
  1500. X                wp->w_toprow = curwp->w_toprow+ntru+1;
  1501. X                wp->w_ntrows = ntrl;
  1502. X        } else {                                /* Old is lower window  */
  1503. X                wp1 = NULL;
  1504. X                wp2 = wheadp;
  1505. X                while (wp2 != curwp) {
  1506. X                        wp1 = wp2;
  1507. X                        wp2 = wp2->w_wndp;
  1508. X                }
  1509. X                if (wp1 == NULL)
  1510. X                        wheadp = wp;
  1511. X                else
  1512. X                        wp1->w_wndp = wp;
  1513. X                wp->w_wndp   = curwp;
  1514. X                wp->w_toprow = curwp->w_toprow;
  1515. X                wp->w_ntrows = ntru;
  1516. X                ++ntru;                         /* Mode line.           */
  1517. X                curwp->w_toprow += ntru;
  1518. X                curwp->w_ntrows  = ntrl;
  1519. X                while (ntru--)
  1520. X                        lp = lforw(lp);
  1521. X        }
  1522. X        curwp->w_linep = lp;                    /* Adjust the top lines */
  1523. X        wp->w_linep = lp;                       /* if necessary.        */
  1524. X        curwp->w_flag |= WFMODE|WFHARD;
  1525. X        wp->w_flag |= WFMODE|WFHARD;
  1526. X        return (TRUE);
  1527. X}
  1528. X
  1529. X/*
  1530. X * Enlarge the current window. Find the window that loses space. Make sure it
  1531. X * is big enough. If so, hack the window descriptions, and ask redisplay to do
  1532. X * all the hard work. You don't just set "force reframe" because dot would
  1533. X * move. Bound to "C-X Z".
  1534. X */
  1535. Xenlargewind(f, n)
  1536. X{
  1537. X        register WINDOW *adjwp;
  1538. X        register LINE   *lp;
  1539. X        register int    i;
  1540. X
  1541. X        if (n < 0)
  1542. X                return (shrinkwind(f, -n));
  1543. X        if (wheadp->w_wndp == NULL) {
  1544. X                mlwrite("Only one window");
  1545. X                return (FALSE);
  1546. X        }
  1547. X        if ((adjwp=curwp->w_wndp) == NULL) {
  1548. X                adjwp = wheadp;
  1549. X                while (adjwp->w_wndp != curwp)
  1550. X                        adjwp = adjwp->w_wndp;
  1551. X        }
  1552. X        if (adjwp->w_ntrows <= n) {
  1553. X                mlwrite("Impossible change");
  1554. X                return (FALSE);
  1555. X        }
  1556. X        if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
  1557. X                lp = adjwp->w_linep;
  1558. X                for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  1559. X                        lp = lforw(lp);
  1560. X                adjwp->w_linep  = lp;
  1561. X                adjwp->w_toprow += n;
  1562. X        } else {                                /* Shrink above.        */
  1563. X                lp = curwp->w_linep;
  1564. X                for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  1565. X                        lp = lback(lp);
  1566. X                curwp->w_linep  = lp;
  1567. X                curwp->w_toprow -= n;
  1568. X        }
  1569. X        curwp->w_ntrows += n;
  1570. X        adjwp->w_ntrows -= n;
  1571. X        curwp->w_flag |= WFMODE|WFHARD;
  1572. X        adjwp->w_flag |= WFMODE|WFHARD;
  1573. X        return (TRUE);
  1574. X}
  1575. X
  1576. X/*
  1577. X * Shrink the current window. Find the window that gains space. Hack at the
  1578. X * window descriptions. Ask the redisplay to do all the hard work. Bound to
  1579. X * "C-X C-Z".
  1580. X */
  1581. Xshrinkwind(f, n)
  1582. X{
  1583. X        register WINDOW *adjwp;
  1584. X        register LINE   *lp;
  1585. X        register int    i;
  1586. X
  1587. X        if (n < 0)
  1588. X                return (enlargewind(f, -n));
  1589. X        if (wheadp->w_wndp == NULL) {
  1590. X                mlwrite("Only one window");
  1591. X                return (FALSE);
  1592. X        }
  1593. X        if ((adjwp=curwp->w_wndp) == NULL) {
  1594. X                adjwp = wheadp;
  1595. X                while (adjwp->w_wndp != curwp)
  1596. X                        adjwp = adjwp->w_wndp;
  1597. X        }
  1598. X        if (curwp->w_ntrows <= n) {
  1599. X                mlwrite("Impossible change");
  1600. X                return (FALSE);
  1601. X        }
  1602. X        if (curwp->w_wndp == adjwp) {           /* Grow below.          */
  1603. X                lp = adjwp->w_linep;
  1604. X                for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  1605. X                        lp = lback(lp);
  1606. X                adjwp->w_linep  = lp;
  1607. X                adjwp->w_toprow -= n;
  1608. X        } else {                                /* Grow above.          */
  1609. X                lp = curwp->w_linep;
  1610. X                for (i=0; i<n && lp!=curbp->b_linep; ++i)
  1611. X                        lp = lforw(lp);
  1612. X                curwp->w_linep  = lp;
  1613. X                curwp->w_toprow += n;
  1614. X        }
  1615. X        curwp->w_ntrows -= n;
  1616. X        adjwp->w_ntrows += n;
  1617. X        curwp->w_flag |= WFMODE|WFHARD;
  1618. X        adjwp->w_flag |= WFMODE|WFHARD;
  1619. X        return (TRUE);
  1620. X}
  1621. X
  1622. X/*    Resize the current window to the requested size    */
  1623. X
  1624. Xresize(f, n)
  1625. X
  1626. Xint f, n;    /* default flag and numeric argument */
  1627. X
  1628. X{
  1629. X    int clines;    /* current # of lines in window */
  1630. X    
  1631. X    /* must have a non-default argument, else ignore call */
  1632. X    if (f == FALSE)
  1633. X        return(TRUE);
  1634. X
  1635. X    /* find out what to do */
  1636. X    clines = curwp->w_ntrows;
  1637. X
  1638. X    /* already the right size? */
  1639. X    if (clines == n)
  1640. X        return(TRUE);
  1641. X
  1642. X    return(enlargewind(TRUE, n - clines));
  1643. X}
  1644. X
  1645. X/*
  1646. X * Pick a window for a pop-up. Split the screen if there is only one window.
  1647. X * Pick the uppermost window that isn't the current window. An LRU algorithm
  1648. X * might be better. Return a pointer, or NULL on error.
  1649. X */
  1650. XWINDOW  *
  1651. Xwpopup()
  1652. X{
  1653. X        register WINDOW *wp;
  1654. X
  1655. X        if (wheadp->w_wndp == NULL              /* Only 1 window        */
  1656. X        && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
  1657. X                return (NULL);
  1658. X        wp = wheadp;                            /* Find window to use   */
  1659. X        while (wp!=NULL && wp==curwp)
  1660. X                wp = wp->w_wndp;
  1661. X        return (wp);
  1662. X}
  1663. X
  1664. Xscrnextup(f, n)        /* scroll the next window up (back) a page */
  1665. X
  1666. X{
  1667. X    nextwind(FALSE, 1);
  1668. X    backpage(f, n);
  1669. X    prevwind(FALSE, 1);
  1670. X}
  1671. X
  1672. Xscrnextdw(f, n)        /* scroll the next window down (forward) a page */
  1673. X
  1674. X{
  1675. X    nextwind(FALSE, 1);
  1676. X    forwpage(f, n);
  1677. X    prevwind(FALSE, 1);
  1678. X}
  1679. X
  1680. Xsavewnd(f, n)        /* save ptr to current window */
  1681. X
  1682. X{
  1683. X    swindow = curwp;
  1684. X    return(TRUE);
  1685. X}
  1686. X
  1687. Xrestwnd(f, n)        /* restore the saved screen */
  1688. X
  1689. X{
  1690. X    register WINDOW *wp;
  1691. X
  1692. X    /* find the window */
  1693. X    wp = wheadp;
  1694. X    while (wp != NULL) {
  1695. X        if (wp == swindow) {
  1696. X            curwp = wp;
  1697. X            curbp = wp->w_bufp;
  1698. X            upmode();
  1699. X            return (TRUE);
  1700. X        }
  1701. X        wp = wp->w_wndp;
  1702. X    }
  1703. X
  1704. X    mlwrite("[No such window exists]");
  1705. X    return(FALSE);
  1706. X}
  1707. FRIDAY_NIGHT
  1708. echo es.11 completed!
  1709. : That's all folks!
  1710.  
  1711.