home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume4 / uemacs3.6 / part8 < prev    next >
Text File  |  1986-11-30  |  47KB  |  1,702 lines

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