home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume1 / 8706 / 23 < prev    next >
Internet Message Format  |  1993-09-02  |  62KB

  1. From mipos3!intelca!uccba!hal!ncoast!allbery Fri Jun 19 14:07:40 PDT 1987
  2. Article 16 of comp.sources.misc:
  3. Path: td2cad!mipos3!intelca!uccba!hal!ncoast!allbery
  4. >From: davidsen@steinmetz.UUCP (William E. Davidsen Jr)
  5. Newsgroups: comp.sources.misc
  6. Subject: memacs 3.8i 11 of 11
  7. Message-ID: <2666@ncoast.UUCP>
  8. Date: 15 Jun 87 19:12:51 GMT
  9. Sender: allbery@ncoast.UUCP
  10. Lines: 2186
  11. Approved: allbery@ncoast.UUCP
  12. X-Archive: comp.sources.misc/8706/23
  13.  
  14. :
  15. #!/bin/sh
  16. # shar+ created from directory /usr2/davidsen/emacs38i
  17. # 13:42 on Thu Jun 11, 1987 by davidsen
  18. echo 'x - window.c (text)'
  19. sed << 'E!O!F' 's/^X//' > window.c
  20. X/*
  21. X * Window management. Some of the functions are internal, and some are
  22. X * attached to keys that the user actually types.
  23. X */
  24. X
  25. X#include        <stdio.h>
  26. X#include        "estruct.h"
  27. X#include    "edef.h"
  28. X
  29. X#if    MEGAMAX & ST520
  30. Xoverlay    "window"
  31. X#endif
  32. X
  33. X/*
  34. X * Reposition dot in the current window to line "n". If the argument is
  35. X * positive, it is that line. If it is negative it is that line from the
  36. X * bottom. If it is 0 the window is centered (this is what the standard
  37. X * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  38. X */
  39. Xreposition(f, n)
  40. X    {
  41. X    if (f == FALSE)    /* default to 0 to center screen */
  42. X    n = 0;
  43. X    curwp->w_force = n;
  44. X    curwp->w_flag |= WFFORCE;
  45. X    return (TRUE);
  46. X    }
  47. X
  48. X/*
  49. X * Refresh the screen. With no argument, it just does the refresh. With an
  50. X * argument it recenters "." in the current window. Bound to "C-L".
  51. X */
  52. Xrefresh(f, n)
  53. X    {
  54. X    if (f == FALSE)
  55. X        sgarbf = TRUE;
  56. X    else
  57. X        {
  58. X        curwp->w_force = 0;             /* Center dot. */
  59. X        curwp->w_flag |= WFFORCE;
  60. X        }
  61. X
  62. X    return (TRUE);
  63. X    }
  64. X
  65. X/*
  66. X * The command make the next window (next => down the screen) the current
  67. X * window. There are no real errors, although the command does nothing if
  68. X * there is only 1 window on the screen. Bound to "C-X C-N".
  69. X *
  70. X * with an argument this command finds the <n>th window from the top
  71. X *
  72. X */
  73. Xnextwind(f, n)
  74. X
  75. Xint f, n;    /* default flag and numeric argument */
  76. X
  77. X{
  78. X    register WINDOW *wp;
  79. X    register int nwindows;        /* total number of windows */
  80. X
  81. X    if (f) {
  82. X
  83. X        /* first count the # of windows */
  84. X        wp = wheadp;
  85. X        nwindows = 1;
  86. X        while (wp->w_wndp != NULL) {
  87. X            nwindows++;
  88. X            wp = wp->w_wndp;
  89. X        }
  90. X
  91. X        /* if the argument is negative, it is the nth window
  92. X           from the bottom of the screen            */
  93. X        if (n < 0)
  94. X            n = nwindows + n + 1;
  95. X
  96. X        /* if an argument, give them that window from the top */
  97. X        if (n > 0 && n <= nwindows) {
  98. X            wp = wheadp;
  99. X            while (--n)
  100. X                wp = wp->w_wndp;
  101. X        } else {
  102. X            mlwrite("Window number out of range");
  103. X            return(FALSE);
  104. X        }
  105. X    } else
  106. X        if ((wp = curwp->w_wndp) == NULL)
  107. X            wp = wheadp;
  108. X    curwp = wp;
  109. X    curbp = wp->w_bufp;
  110. X    upmode();
  111. X    return (TRUE);
  112. X}
  113. X
  114. X/*
  115. X * This command makes the previous window (previous => up the screen) the
  116. X * current window. There arn't any errors, although the command does not do a
  117. X * lot if there is 1 window.
  118. X */
  119. Xprevwind(f, n)
  120. X{
  121. X    register WINDOW *wp1;
  122. X    register WINDOW *wp2;
  123. X
  124. X    /* if we have an argument, we mean the nth window from the bottom */
  125. X    if (f)
  126. X        return(nextwind(f, -n));
  127. X
  128. X    wp1 = wheadp;
  129. X    wp2 = curwp;
  130. X
  131. X    if (wp1 == wp2)
  132. X        wp2 = NULL;
  133. X
  134. X    while (wp1->w_wndp != wp2)
  135. X        wp1 = wp1->w_wndp;
  136. X
  137. X    curwp = wp1;
  138. X    curbp = wp1->w_bufp;
  139. X    upmode();
  140. X    return (TRUE);
  141. X}
  142. X
  143. X/*
  144. X * This command moves the current window down by "arg" lines. Recompute the
  145. X * top line in the window. The move up and move down code is almost completely
  146. X * the same; most of the work has to do with reframing the window, and picking
  147. X * a new dot. We share the code by having "move down" just be an interface to
  148. X * "move up". Magic. Bound to "C-X C-N".
  149. X */
  150. Xmvdnwind(f, n)
  151. X
  152. Xint n;
  153. X
  154. X{
  155. X    return (mvupwind(f, -n));
  156. X}
  157. X
  158. X/*
  159. X * Move the current window up by "arg" lines. Recompute the new top line of
  160. X * the window. Look to see if "." is still on the screen. If it is, you win.
  161. X * If it isn't, then move "." to center it in the new framing of the window
  162. X * (this command does not really move "."; it moves the frame). Bound to
  163. X * "C-X C-P".
  164. X */
  165. Xmvupwind(f, n)
  166. X    int n;
  167. X    {
  168. X    register LINE *lp;
  169. X    register int i;
  170. X
  171. X    lp = curwp->w_linep;
  172. X
  173. X    if (n < 0)
  174. X        {
  175. X        while (n++ && lp!=curbp->b_linep)
  176. X            lp = lforw(lp);
  177. X        }
  178. X    else
  179. X        {
  180. X        while (n-- && lback(lp)!=curbp->b_linep)
  181. X            lp = lback(lp);
  182. X        }
  183. X
  184. X    curwp->w_linep = lp;
  185. X    curwp->w_flag |= WFHARD;            /* Mode line is OK. */
  186. X
  187. X    for (i = 0; i < curwp->w_ntrows; ++i)
  188. X        {
  189. X        if (lp == curwp->w_dotp)
  190. X            return (TRUE);
  191. X        if (lp == curbp->b_linep)
  192. X            break;
  193. X        lp = lforw(lp);
  194. X        }
  195. X
  196. X    lp = curwp->w_linep;
  197. X    i  = curwp->w_ntrows/2;
  198. X
  199. X    while (i-- && lp != curbp->b_linep)
  200. X        lp = lforw(lp);
  201. X
  202. X    curwp->w_dotp  = lp;
  203. X    curwp->w_doto  = 0;
  204. X    return (TRUE);
  205. X    }
  206. X
  207. X/*
  208. X * This command makes the current window the only window on the screen. Bound
  209. X * to "C-X 1". Try to set the framing so that "." does not have to move on the
  210. X * display. Some care has to be taken to keep the values of dot and mark in
  211. X * the buffer structures right if the distruction of a window makes a buffer
  212. X * become undisplayed.
  213. X */
  214. Xonlywind(f, n)
  215. X{
  216. X        register WINDOW *wp;
  217. X        register LINE   *lp;
  218. X        register int    i;
  219. X
  220. X        while (wheadp != curwp) {
  221. X                wp = wheadp;
  222. X                wheadp = wp->w_wndp;
  223. X                if (--wp->w_bufp->b_nwnd == 0) {
  224. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  225. X                        wp->w_bufp->b_doto  = wp->w_doto;
  226. X                        wp->w_bufp->b_markp = wp->w_markp;
  227. X                        wp->w_bufp->b_marko = wp->w_marko;
  228. X                }
  229. X                free((char *) wp);
  230. X        }
  231. X        while (curwp->w_wndp != NULL) {
  232. X                wp = curwp->w_wndp;
  233. X                curwp->w_wndp = wp->w_wndp;
  234. X                if (--wp->w_bufp->b_nwnd == 0) {
  235. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  236. X                        wp->w_bufp->b_doto  = wp->w_doto;
  237. X                        wp->w_bufp->b_markp = wp->w_markp;
  238. X                        wp->w_bufp->b_marko = wp->w_marko;
  239. X                }
  240. X                free((char *) wp);
  241. X        }
  242. X        lp = curwp->w_linep;
  243. X        i  = curwp->w_toprow;
  244. X        while (i!=0 && lback(lp)!=curbp->b_linep) {
  245. X                --i;
  246. X                lp = lback(lp);
  247. X        }
  248. X        curwp->w_toprow = 0;
  249. X        curwp->w_ntrows = term.t_nrow-1;
  250. X        curwp->w_linep  = lp;
  251. X        curwp->w_flag  |= WFMODE|WFHARD;
  252. X        return (TRUE);
  253. X}
  254. X
  255. X/*
  256. X * Delete the current window, placing its space in the window above,
  257. X * or, if it is the top window, the window below. Bound to C-X 0.
  258. X */
  259. X
  260. Xdelwind(f,n)
  261. X
  262. Xint f, n;    /* arguments are ignored for this command */
  263. X
  264. X{
  265. X    register WINDOW *wp;    /* window to recieve deleted space */
  266. X    register WINDOW *lwp;    /* ptr window before curwp */
  267. X    register int target;    /* target line to search for */
  268. X
  269. X    /* if there is only one window, don't delete it */
  270. X    if (wheadp->w_wndp == NULL) {
  271. X        mlwrite("Can not delete this window");
  272. X        return(FALSE);
  273. X    }
  274. X
  275. X    /* find window before curwp in linked list */
  276. X    wp = wheadp;
  277. X    lwp = NULL;
  278. X    while (wp != NULL) {
  279. X        if (wp == curwp)
  280. X            break;
  281. X        lwp = wp;
  282. X        wp = wp->w_wndp;
  283. X    }
  284. X
  285. X    /* find recieving window and give up our space */
  286. X    wp = wheadp;
  287. X    if (curwp->w_toprow == 0) {
  288. X        /* find the next window down */
  289. X        target = curwp->w_ntrows + 1;
  290. X        while (wp != NULL) {
  291. X            if (wp->w_toprow == target)
  292. X                break;
  293. X            wp = wp->w_wndp;
  294. X        }
  295. X        if (wp == NULL)
  296. X            return(FALSE);
  297. X        wp->w_toprow = 0;
  298. X        wp->w_ntrows += target;
  299. X    } else {
  300. X        /* find the next window up */
  301. X        target = curwp->w_toprow - 1;
  302. X        while (wp != NULL) {
  303. X            if ((wp->w_toprow + wp->w_ntrows) == target)
  304. X                break;
  305. X            wp = wp->w_wndp;
  306. X        }
  307. X        if (wp == NULL)
  308. X            return(FALSE);
  309. X        wp->w_ntrows += 1 + curwp->w_ntrows;
  310. X    }
  311. X
  312. X    /* get rid of the current window */
  313. X    if (--curwp->w_bufp->b_nwnd == 0) {
  314. X        curwp->w_bufp->b_dotp = curwp->w_dotp;
  315. X        curwp->w_bufp->b_doto = curwp->w_doto;
  316. X        curwp->w_bufp->b_markp = curwp->w_markp;
  317. X        curwp->w_bufp->b_marko = curwp->w_marko;
  318. X    }
  319. X    if (lwp == NULL)
  320. X        wheadp = curwp->w_wndp;
  321. X    else
  322. X        lwp->w_wndp = curwp->w_wndp;
  323. X    free((char *)curwp);
  324. X    curwp = wp;
  325. X    wp->w_flag |= WFHARD;
  326. X    curbp = wp->w_bufp;
  327. X    upmode();
  328. X    return(TRUE);
  329. X}
  330. X
  331. X/*
  332. X
  333. XSplit the current window.  A window smaller than 3 lines cannot be
  334. Xsplit.  An argument of 1 forces the cursor into the upper window, an
  335. Xargument of two forces the cursor to the lower window.  The only other
  336. Xerror that is possible is a "malloc" failure allocating the structure
  337. Xfor the new window.  Bound to "C-X 2". 
  338. X
  339. X */
  340. Xsplitwind(f, n)
  341. X
  342. Xint f, n;    /* default flag and numeric argument */
  343. X
  344. X{
  345. X        register WINDOW *wp;
  346. X        register LINE   *lp;
  347. X        register int    ntru;
  348. X        register int    ntrl;
  349. X        register int    ntrd;
  350. X        register WINDOW *wp1;
  351. X        register WINDOW *wp2;
  352. X    char *malloc();
  353. X
  354. X        if (curwp->w_ntrows < 3) {
  355. X                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  356. X                return (FALSE);
  357. X        }
  358. X        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  359. X                mlwrite("Cannot allocate WINDOW block");
  360. X                return (FALSE);
  361. X        }
  362. X        ++curbp->b_nwnd;                        /* Displayed twice.     */
  363. X        wp->w_bufp  = curbp;
  364. X        wp->w_dotp  = curwp->w_dotp;
  365. X        wp->w_doto  = curwp->w_doto;
  366. X        wp->w_markp = curwp->w_markp;
  367. X        wp->w_marko = curwp->w_marko;
  368. X        wp->w_flag  = 0;
  369. X        wp->w_force = 0;
  370. X#if    COLOR
  371. X    /* set the colors of the new window */
  372. X    wp->w_fcolor = gfcolor;
  373. X    wp->w_bcolor = gbcolor;
  374. X#endif
  375. X        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  376. X        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  377. X        lp = curwp->w_linep;
  378. X        ntrd = 0;
  379. X        while (lp != curwp->w_dotp) {
  380. X                ++ntrd;
  381. X                lp = lforw(lp);
  382. X        }
  383. X        lp = curwp->w_linep;
  384. X        if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  385. X                /* Old is upper window. */
  386. X                if (ntrd == ntru)               /* Hit mode line.       */
  387. X                        lp = lforw(lp);
  388. X                curwp->w_ntrows = ntru;
  389. X                wp->w_wndp = curwp->w_wndp;
  390. X                curwp->w_wndp = wp;
  391. X                wp->w_toprow = curwp->w_toprow+ntru+1;
  392. X                wp->w_ntrows = ntrl;
  393. X        } else {                                /* Old is lower window  */
  394. X                wp1 = NULL;
  395. X                wp2 = wheadp;
  396. X                while (wp2 != curwp) {
  397. X                        wp1 = wp2;
  398. X                        wp2 = wp2->w_wndp;
  399. X                }
  400. X                if (wp1 == NULL)
  401. X                        wheadp = wp;
  402. X                else
  403. X                        wp1->w_wndp = wp;
  404. X                wp->w_wndp   = curwp;
  405. X                wp->w_toprow = curwp->w_toprow;
  406. X                wp->w_ntrows = ntru;
  407. X                ++ntru;                         /* Mode line.           */
  408. X                curwp->w_toprow += ntru;
  409. X                curwp->w_ntrows  = ntrl;
  410. X                while (ntru--)
  411. X                        lp = lforw(lp);
  412. X        }
  413. X        curwp->w_linep = lp;                    /* Adjust the top lines */
  414. X        wp->w_linep = lp;                       /* if necessary.        */
  415. X        curwp->w_flag |= WFMODE|WFHARD;
  416. X        wp->w_flag |= WFMODE|WFHARD;
  417. X        return (TRUE);
  418. X}
  419. X
  420. X/*
  421. X * Enlarge the current window. Find the window that loses space. Make sure it
  422. X * is big enough. If so, hack the window descriptions, and ask redisplay to do
  423. X * all the hard work. You don't just set "force reframe" because dot would
  424. X * move. Bound to "C-X Z".
  425. X */
  426. Xenlargewind(f, n)
  427. X{
  428. X        register WINDOW *adjwp;
  429. X        register LINE   *lp;
  430. X        register int    i;
  431. X
  432. X        if (n < 0)
  433. X                return (shrinkwind(f, -n));
  434. X        if (wheadp->w_wndp == NULL) {
  435. X                mlwrite("Only one window");
  436. X                return (FALSE);
  437. X        }
  438. X        if ((adjwp=curwp->w_wndp) == NULL) {
  439. X                adjwp = wheadp;
  440. X                while (adjwp->w_wndp != curwp)
  441. X                        adjwp = adjwp->w_wndp;
  442. X        }
  443. X        if (adjwp->w_ntrows <= n) {
  444. X                mlwrite("Impossible change");
  445. X                return (FALSE);
  446. X        }
  447. X        if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
  448. X                lp = adjwp->w_linep;
  449. X                for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  450. X                        lp = lforw(lp);
  451. X                adjwp->w_linep  = lp;
  452. X                adjwp->w_toprow += n;
  453. X        } else {                                /* Shrink above.        */
  454. X                lp = curwp->w_linep;
  455. X                for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  456. X                        lp = lback(lp);
  457. X                curwp->w_linep  = lp;
  458. X                curwp->w_toprow -= n;
  459. X        }
  460. X        curwp->w_ntrows += n;
  461. X        adjwp->w_ntrows -= n;
  462. X        curwp->w_flag |= WFMODE|WFHARD;
  463. X        adjwp->w_flag |= WFMODE|WFHARD;
  464. X        return (TRUE);
  465. X}
  466. X
  467. X/*
  468. X * Shrink the current window. Find the window that gains space. Hack at the
  469. X * window descriptions. Ask the redisplay to do all the hard work. Bound to
  470. X * "C-X C-Z".
  471. X */
  472. Xshrinkwind(f, n)
  473. X{
  474. X        register WINDOW *adjwp;
  475. X        register LINE   *lp;
  476. X        register int    i;
  477. X
  478. X        if (n < 0)
  479. X                return (enlargewind(f, -n));
  480. X        if (wheadp->w_wndp == NULL) {
  481. X                mlwrite("Only one window");
  482. X                return (FALSE);
  483. X        }
  484. X        if ((adjwp=curwp->w_wndp) == NULL) {
  485. X                adjwp = wheadp;
  486. X                while (adjwp->w_wndp != curwp)
  487. X                        adjwp = adjwp->w_wndp;
  488. X        }
  489. X        if (curwp->w_ntrows <= n) {
  490. X                mlwrite("Impossible change");
  491. X                return (FALSE);
  492. X        }
  493. X        if (curwp->w_wndp == adjwp) {           /* Grow below.          */
  494. X                lp = adjwp->w_linep;
  495. X                for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  496. X                        lp = lback(lp);
  497. X                adjwp->w_linep  = lp;
  498. X                adjwp->w_toprow -= n;
  499. X        } else {                                /* Grow above.          */
  500. X                lp = curwp->w_linep;
  501. X                for (i=0; i<n && lp!=curbp->b_linep; ++i)
  502. X                        lp = lforw(lp);
  503. X                curwp->w_linep  = lp;
  504. X                curwp->w_toprow += n;
  505. X        }
  506. X        curwp->w_ntrows -= n;
  507. X        adjwp->w_ntrows += n;
  508. X        curwp->w_flag |= WFMODE|WFHARD;
  509. X        adjwp->w_flag |= WFMODE|WFHARD;
  510. X        return (TRUE);
  511. X}
  512. X
  513. X/*    Resize the current window to the requested size    */
  514. X
  515. Xresize(f, n)
  516. X
  517. Xint f, n;    /* default flag and numeric argument */
  518. X
  519. X{
  520. X    int clines;    /* current # of lines in window */
  521. X    
  522. X    /* must have a non-default argument, else ignore call */
  523. X    if (f == FALSE)
  524. X        return(TRUE);
  525. X
  526. X    /* find out what to do */
  527. X    clines = curwp->w_ntrows;
  528. X
  529. X    /* already the right size? */
  530. X    if (clines == n)
  531. X        return(TRUE);
  532. X
  533. X    return(enlargewind(TRUE, n - clines));
  534. X}
  535. X
  536. X/*
  537. X * Pick a window for a pop-up. Split the screen if there is only one window.
  538. X * Pick the uppermost window that isn't the current window. An LRU algorithm
  539. X * might be better. Return a pointer, or NULL on error.
  540. X */
  541. XWINDOW  *
  542. Xwpopup()
  543. X{
  544. X        register WINDOW *wp;
  545. X
  546. X        if (wheadp->w_wndp == NULL              /* Only 1 window        */
  547. X        && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
  548. X                return (NULL);
  549. X        wp = wheadp;                            /* Find window to use   */
  550. X        while (wp!=NULL && wp==curwp)
  551. X                wp = wp->w_wndp;
  552. X        return (wp);
  553. X}
  554. X
  555. Xscrnextup(f, n)        /* scroll the next window up (back) a page */
  556. X
  557. X{
  558. X    nextwind(FALSE, 1);
  559. X    backpage(f, n);
  560. X    prevwind(FALSE, 1);
  561. X}
  562. X
  563. Xscrnextdw(f, n)        /* scroll the next window down (forward) a page */
  564. X
  565. X{
  566. X    nextwind(FALSE, 1);
  567. X    forwpage(f, n);
  568. X    prevwind(FALSE, 1);
  569. X}
  570. X
  571. Xsavewnd(f, n)        /* save ptr to current window */
  572. X
  573. X{
  574. X    swindow = curwp;
  575. X    return(TRUE);
  576. X}
  577. X
  578. Xrestwnd(f, n)        /* restore the saved screen */
  579. X
  580. X{
  581. X    register WINDOW *wp;
  582. X
  583. X    /* find the window */
  584. X    wp = wheadp;
  585. X    while (wp != NULL) {
  586. X        if (wp == swindow) {
  587. X            curwp = wp;
  588. X            curbp = wp->w_bufp;
  589. X            upmode();
  590. X            return (TRUE);
  591. X        }
  592. X        wp = wp->w_wndp;
  593. X    }
  594. X
  595. X    mlwrite("[No such window exists]");
  596. X    return(FALSE);
  597. X}
  598. X
  599. Xnewsize(f, n)    /* resize the screen, re-writing the screen */
  600. X
  601. Xint f;    /* default flag */
  602. Xint n;    /* numeric argument */
  603. X
  604. X{
  605. X    WINDOW *wp;    /* current window being examined */
  606. X    WINDOW *nextwp;    /* next window to scan */
  607. X    WINDOW *lastwp;    /* last window scanned */
  608. X    int lastline;    /* screen line of last line of current window */
  609. X
  610. X    /* if the command defaults, assume the largest */
  611. X    if (f == FALSE)
  612. X        n = term.t_mrow + 1;
  613. X
  614. X    /* make sure it's in range */
  615. X    if (n < 3 || n > term.t_mrow + 1) {
  616. X        mlwrite("%%Screen size out of range");
  617. X        return(FALSE);
  618. X    }
  619. X
  620. X    if (term.t_nrow == n - 1)
  621. X        return(TRUE);
  622. X    else if (term.t_nrow < n - 1) {
  623. X
  624. X        /* go to the last window */
  625. X        wp = wheadp;
  626. X        while (wp->w_wndp != NULL)
  627. X            wp = wp->w_wndp;
  628. X
  629. X        /* and enlarge it as needed */
  630. X        wp->w_ntrows = n - wp->w_toprow - 2;
  631. X        wp->w_flag |= WFHARD|WFMODE;
  632. X
  633. X    } else {
  634. X
  635. X        /* rebuild the window structure */
  636. X        nextwp = wheadp;
  637. X        wp = NULL;
  638. X        lastwp = NULL;
  639. X        while (nextwp != NULL) {
  640. X            wp = nextwp;
  641. X            nextwp = wp->w_wndp;
  642. X    
  643. X            /* get rid of it if it is too low */
  644. X            if (wp->w_toprow > n - 2) {
  645. X
  646. X                /* save the point/mark if needed */
  647. X                if (--wp->w_bufp->b_nwnd == 0) {
  648. X                    wp->w_bufp->b_dotp = wp->w_dotp;
  649. X                    wp->w_bufp->b_doto = wp->w_doto;
  650. X                    wp->w_bufp->b_markp = wp->w_markp;
  651. X                    wp->w_bufp->b_marko = wp->w_marko;
  652. X                }
  653. X    
  654. X                /* update curwp and lastwp if needed */
  655. X                if (wp == curwp)
  656. X                    curwp = wheadp;
  657. X                    curbp = curwp->w_bufp;
  658. X                if (lastwp != NULL)
  659. X                    lastwp->w_wndp = NULL;
  660. X
  661. X                /* free the structure */
  662. X                free((char *)wp);
  663. X                wp = NULL;
  664. X
  665. X            } else {
  666. X                /* need to change this window size? */
  667. X                lastline = wp->w_toprow + wp->w_ntrows - 1;
  668. X                if (lastline >= n - 2) {
  669. X                    wp->w_ntrows = n - wp->w_toprow - 2;
  670. X                    wp->w_flag |= WFHARD|WFMODE;
  671. X                }
  672. X            }
  673. X    
  674. X            lastwp = wp;
  675. X        }
  676. X    }
  677. X
  678. X    /* screen is garbage */
  679. X    term.t_nrow = n - 1;
  680. X    sgarbf = TRUE;
  681. X    return(TRUE);
  682. X}
  683. X
  684. Xnewwidth(f, n)    /* resize the screen, re-writing the screen */
  685. X
  686. Xint f;    /* default flag */
  687. Xint n;    /* numeric argument */
  688. X
  689. X{
  690. X    /* if the command defaults, assume the largest */
  691. X    if (f == FALSE)
  692. X        n = term.t_mcol;
  693. X
  694. X    /* make sure it's in range */
  695. X    if (n < 10 || n > term.t_mcol) {
  696. X        mlwrite("%%Screen width out of range");
  697. X        return(FALSE);
  698. X    }
  699. X
  700. X    /* otherwise, just re-width it (no big deal) */
  701. X    term.t_ncol = n;
  702. X    term.t_margin = n / 10;
  703. X    term.t_scrsiz = n - (term.t_margin * 2);
  704. X    curwp->w_flag |= WFHARD | WFMOVE | WFMODE;
  705. X    sgarbf = TRUE;
  706. X    return(TRUE);
  707. X}
  708. E!O!F
  709. newsize=`wc -c < window.c`
  710. if [ $newsize -ne 18032 ]
  711. then echo "File window.c was $newsize bytes, 18032 expected"
  712. fi
  713. echo 'x - word.c (text)'
  714. sed << 'E!O!F' 's/^X//' > word.c
  715. X/*
  716. X * The routines in this file implement commands that work word or a
  717. X * paragraph at a time.  There are all sorts of word mode commands.  If I
  718. X * do any sentence mode commands, they are likely to be put in this file. 
  719. X */
  720. X
  721. X#if    MEGAMAX & ST520
  722. Xoverlay    "word"
  723. X#endif
  724. X
  725. X#include        <stdio.h>
  726. X#include        "estruct.h"
  727. X#include    "edef.h"
  728. X
  729. X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
  730. X * line and stop on the first word-break or the beginning of the line. If we
  731. X * reach the beginning of the line, jump back to the end of the word and start
  732. X * a new line.  Otherwise, break the line at the word-break, eat it, and jump
  733. X * back to the end of the word.
  734. X * Returns TRUE on success, FALSE on errors.
  735. X */
  736. Xwrapword(f, n)
  737. X
  738. Xint f;        /* default flag */
  739. Xint n;        /* numeric argument */
  740. X
  741. X{
  742. X        register int cnt;    /* size of word wrapped to next line */
  743. X    register int c;        /* charector temporary */
  744. X
  745. X    /* backup from the <NL> 1 char */
  746. X        if (!backchar(0, 1))
  747. X            return(FALSE);
  748. X
  749. X    /* back up until we aren't in a word,
  750. X       make sure there is a break in the line */
  751. X        cnt = 0;
  752. X    while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ')
  753. X                && (c != '\t')) {
  754. X                cnt++;
  755. X                if (!backchar(0, 1))
  756. X                        return(FALSE);
  757. X        /* if we make it to the beginning, start a new line */
  758. X        if (curwp->w_doto == 0) {
  759. X            gotoeol(FALSE, 0);
  760. X            return(lnewline());
  761. X        }
  762. X        }
  763. X
  764. X    /* delete the forward white space */
  765. X        if (!forwdel(0, 1))
  766. X                return(FALSE);
  767. X
  768. X    /* put in a end of line */
  769. X        if (!lnewline())
  770. X                return(FALSE);
  771. X
  772. X    /* and past the first word */
  773. X    while (cnt-- > 0) {
  774. X        if (forwchar(FALSE, 1) == FALSE)
  775. X            return(FALSE);
  776. X    }
  777. X        return(TRUE);
  778. X}
  779. X
  780. X/*
  781. X * Move the cursor backward by "n" words. All of the details of motion are
  782. X * performed by the "backchar" and "forwchar" routines. Error if you try to
  783. X * move beyond the buffers.
  784. X */
  785. Xbackword(f, n)
  786. X{
  787. X        if (n < 0)
  788. X                return (forwword(f, -n));
  789. X        if (backchar(FALSE, 1) == FALSE)
  790. X                return (FALSE);
  791. X        while (n--) {
  792. X                while (inword() == FALSE) {
  793. X                        if (backchar(FALSE, 1) == FALSE)
  794. X                                return (FALSE);
  795. X                }
  796. X                while (inword() != FALSE) {
  797. X                        if (backchar(FALSE, 1) == FALSE)
  798. X                                return (FALSE);
  799. X                }
  800. X        }
  801. X        return (forwchar(FALSE, 1));
  802. X}
  803. X
  804. X/*
  805. X * Move the cursor forward by the specified number of words. All of the motion
  806. X * is done by "forwchar". Error if you try and move beyond the buffer's end.
  807. X */
  808. Xforwword(f, n)
  809. X{
  810. X        if (n < 0)
  811. X                return (backword(f, -n));
  812. X        while (n--) {
  813. X#if    NFWORD
  814. X                while (inword() != FALSE) {
  815. X                        if (forwchar(FALSE, 1) == FALSE)
  816. X                                return (FALSE);
  817. X                }
  818. X#endif
  819. X                while (inword() == FALSE) {
  820. X                        if (forwchar(FALSE, 1) == FALSE)
  821. X                                return (FALSE);
  822. X                }
  823. X#if    NFWORD == 0
  824. X                while (inword() != FALSE) {
  825. X                        if (forwchar(FALSE, 1) == FALSE)
  826. X                                return (FALSE);
  827. X                }
  828. X#endif
  829. X        }
  830. X    return(TRUE);
  831. X}
  832. X
  833. X/*
  834. X * Move the cursor forward by the specified number of words. As you move,
  835. X * convert any characters to upper case. Error if you try and move beyond the
  836. X * end of the buffer. Bound to "M-U".
  837. X */
  838. Xupperword(f, n)
  839. X{
  840. X        register int    c;
  841. X
  842. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  843. X        return(rdonly());    /* we are in read only mode    */
  844. X        if (n < 0)
  845. X                return (FALSE);
  846. X        while (n--) {
  847. X                while (inword() == FALSE) {
  848. X                        if (forwchar(FALSE, 1) == FALSE)
  849. X                                return (FALSE);
  850. X                }
  851. X                while (inword() != FALSE) {
  852. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  853. X                        if (c>='a' && c<='z') {
  854. X                                c -= 'a'-'A';
  855. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  856. X                                lchange(WFHARD);
  857. X                        }
  858. X                        if (forwchar(FALSE, 1) == FALSE)
  859. X                                return (FALSE);
  860. X                }
  861. X        }
  862. X        return (TRUE);
  863. X}
  864. X
  865. X/*
  866. X * Move the cursor forward by the specified number of words. As you move
  867. X * convert characters to lower case. Error if you try and move over the end of
  868. X * the buffer. Bound to "M-L".
  869. X */
  870. Xlowerword(f, n)
  871. X{
  872. X        register int    c;
  873. X
  874. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  875. X        return(rdonly());    /* we are in read only mode    */
  876. X        if (n < 0)
  877. X                return (FALSE);
  878. X        while (n--) {
  879. X                while (inword() == FALSE) {
  880. X                        if (forwchar(FALSE, 1) == FALSE)
  881. X                                return (FALSE);
  882. X                }
  883. X                while (inword() != FALSE) {
  884. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  885. X                        if (c>='A' && c<='Z') {
  886. X                                c += 'a'-'A';
  887. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  888. X                                lchange(WFHARD);
  889. X                        }
  890. X                        if (forwchar(FALSE, 1) == FALSE)
  891. X                                return (FALSE);
  892. X                }
  893. X        }
  894. X        return (TRUE);
  895. X}
  896. X
  897. X/*
  898. X * Move the cursor forward by the specified number of words. As you move
  899. X * convert the first character of the word to upper case, and subsequent
  900. X * characters to lower case. Error if you try and move past the end of the
  901. X * buffer. Bound to "M-C".
  902. X */
  903. Xcapword(f, n)
  904. X{
  905. X        register int    c;
  906. X
  907. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  908. X        return(rdonly());    /* we are in read only mode    */
  909. X        if (n < 0)
  910. X                return (FALSE);
  911. X        while (n--) {
  912. X                while (inword() == FALSE) {
  913. X                        if (forwchar(FALSE, 1) == FALSE)
  914. X                                return (FALSE);
  915. X                }
  916. X                if (inword() != FALSE) {
  917. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  918. X                        if (c>='a' && c<='z') {
  919. X                                c -= 'a'-'A';
  920. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  921. X                                lchange(WFHARD);
  922. X                        }
  923. X                        if (forwchar(FALSE, 1) == FALSE)
  924. X                                return (FALSE);
  925. X                        while (inword() != FALSE) {
  926. X                                c = lgetc(curwp->w_dotp, curwp->w_doto);
  927. X                                if (c>='A' && c<='Z') {
  928. X                                        c += 'a'-'A';
  929. X                                        lputc(curwp->w_dotp, curwp->w_doto, c);
  930. X                                        lchange(WFHARD);
  931. X                                }
  932. X                                if (forwchar(FALSE, 1) == FALSE)
  933. X                                        return (FALSE);
  934. X                        }
  935. X                }
  936. X        }
  937. X        return (TRUE);
  938. X}
  939. X
  940. X/*
  941. X * Kill forward by "n" words. Remember the location of dot. Move forward by
  942. X * the right number of words. Put dot back where it was and issue the kill
  943. X * command for the right number of characters. Bound to "M-D".
  944. X */
  945. Xdelfword(f, n)
  946. X{
  947. X        register LINE   *dotp;
  948. X        register int    doto;
  949. X        long size;
  950. X
  951. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  952. X        return(rdonly());    /* we are in read only mode    */
  953. X        if (n < 0)
  954. X                return (FALSE);
  955. X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
  956. X                kdelete();              /* last wasn't a kill.  */
  957. X        thisflag |= CFKILL;
  958. X        dotp = curwp->w_dotp;
  959. X        doto = curwp->w_doto;
  960. X        size = 0;
  961. X        while (n--) {
  962. X#if    NFWORD
  963. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  964. X            if (forwchar(FALSE,1) == FALSE)
  965. X                return(FALSE);
  966. X            ++size;
  967. X        }
  968. X
  969. X        if (inword()) {
  970. X            while (inword() != FALSE) {
  971. X                if (forwchar(FALSE,1) == FALSE)
  972. X                    return(FALSE);
  973. X                ++size;
  974. X            }
  975. X    
  976. X                    while ((iswhite()) &&
  977. X                    (curwp->w_doto != llength(curwp->w_dotp))) {
  978. X                            if (forwchar(FALSE, 1) == FALSE)
  979. X                                    return (FALSE);
  980. X                            ++size;
  981. X                    }
  982. X        }
  983. X        else {
  984. X            while ((inword() == FALSE) &&
  985. X                    (curwp->w_doto != llength(curwp->w_dotp))) {
  986. X                if (forwchar(FALSE,1) == FALSE)
  987. X                    return(FALSE);
  988. X                ++size;
  989. X            }
  990. X        }
  991. X#else
  992. X                while (inword() == FALSE) {
  993. X                        if (forwchar(FALSE, 1) == FALSE)
  994. X                                return (FALSE);
  995. X                        ++size;
  996. X                }
  997. X
  998. X                while (inword() != FALSE) {
  999. X                        if (forwchar(FALSE, 1) == FALSE)
  1000. X                                return (FALSE);
  1001. X                        ++size;
  1002. X                }
  1003. X#endif
  1004. X        }
  1005. X        curwp->w_dotp = dotp;
  1006. X        curwp->w_doto = doto;
  1007. X        return (ldelete(size, TRUE));
  1008. X}
  1009. X
  1010. X/*
  1011. X * Kill backwards by "n" words. Move backwards by the desired number of words,
  1012. X * counting the characters. When dot is finally moved to its resting place,
  1013. X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
  1014. X */
  1015. Xdelbword(f, n)
  1016. X{
  1017. X        long size;
  1018. X
  1019. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1020. X        return(rdonly());    /* we are in read only mode    */
  1021. X        if (n < 0)
  1022. X                return (FALSE);
  1023. X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
  1024. X                kdelete();              /* last wasn't a kill.  */
  1025. X        thisflag |= CFKILL;
  1026. X        if (backchar(FALSE, 1) == FALSE)
  1027. X                return (FALSE);
  1028. X        size = 0;
  1029. X        while (n--) {
  1030. X                while (inword() == FALSE) {
  1031. X                        if (backchar(FALSE, 1) == FALSE)
  1032. X                                return (FALSE);
  1033. X                        ++size;
  1034. X                }
  1035. X                while (inword() != FALSE) {
  1036. X                        if (backchar(FALSE, 1) == FALSE)
  1037. X                                return (FALSE);
  1038. X                        ++size;
  1039. X                }
  1040. X        }
  1041. X        if (forwchar(FALSE, 1) == FALSE)
  1042. X                return (FALSE);
  1043. X        return (ldelete(size, TRUE));
  1044. X}
  1045. X
  1046. X/*
  1047. X * Return TRUE if the character at dot is a character that is considered to be
  1048. X * part of a word. The word character list is hard coded. Should be setable.
  1049. X */
  1050. Xinword()
  1051. X{
  1052. X        register int    c;
  1053. X
  1054. X        if (curwp->w_doto == llength(curwp->w_dotp))
  1055. X                return (FALSE);
  1056. X        c = lgetc(curwp->w_dotp, curwp->w_doto);
  1057. X        if (c>='a' && c<='z')
  1058. X                return (TRUE);
  1059. X        if (c>='A' && c<='Z')
  1060. X                return (TRUE);
  1061. X        if (c>='0' && c<='9')
  1062. X                return (TRUE);
  1063. X        if (c=='$' || c=='_')                   /* For identifiers      */
  1064. X                return (TRUE);
  1065. X        return (FALSE);
  1066. X}
  1067. X
  1068. X/*
  1069. X *  return TRUE if the current character is whitespace,
  1070. X *  else return FALSE.
  1071. X */
  1072. X
  1073. Xiswhite()
  1074. X{
  1075. X        register int    c;
  1076. X
  1077. X        if (curwp->w_doto == llength(curwp->w_dotp))
  1078. X                return (FALSE);
  1079. X        c = lgetc(curwp->w_dotp, curwp->w_doto);
  1080. X    if (c == ' ' || c == '\t') return (TRUE);
  1081. X        return (FALSE);
  1082. X}
  1083. X
  1084. X#if    WORDPRO
  1085. Xfillpara(f, n)    /* Fill the current paragraph according to the current
  1086. X           fill column                        */
  1087. X
  1088. Xint f, n;    /* deFault flag and Numeric argument */
  1089. X
  1090. X{
  1091. X    register int c;            /* current char durring scan    */
  1092. X    register int wordlen;        /* length of current word    */
  1093. X    register int clength;        /* position on line during fill    */
  1094. X    register int i;            /* index during word copy    */
  1095. X    register int newlength;        /* tentative new line length    */
  1096. X    register int eopflag;        /* Are we at the End-Of-Paragraph? */
  1097. X    register int firstflag;        /* first word? (needs no space)    */
  1098. X    register LINE *eopline;        /* pointer to line just past EOP */
  1099. X    register int dotflag;        /* was the last char a period?    */
  1100. X    char wbuf[NSTRING];        /* buffer for current word    */
  1101. X
  1102. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1103. X        return(rdonly());    /* we are in read only mode    */
  1104. X    if (fillcol == 0) {    /* no fill column set */
  1105. X        mlwrite("No fill column set");
  1106. X        return(FALSE);
  1107. X    }
  1108. X
  1109. X    /* record the pointer to the line just past the EOP */
  1110. X    gotoeop(FALSE, 1);
  1111. X    eopline = lforw(curwp->w_dotp);
  1112. X
  1113. X    /* and back top the beginning of the paragraph */
  1114. X    gotobop(FALSE, 1);
  1115. X
  1116. X    /* initialize various info */
  1117. X    clength = curwp->w_doto;
  1118. X    if (clength && curwp->w_dotp->l_text[0] == TAB)
  1119. X        clength = 8;
  1120. X    wordlen = 0;
  1121. X    dotflag = FALSE;
  1122. X
  1123. X    /* scan through lines, filling words */
  1124. X    firstflag = TRUE;
  1125. X    eopflag = FALSE;
  1126. X    while (!eopflag) {
  1127. X        /* get the next character in the paragraph */
  1128. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  1129. X            c = ' ';
  1130. X            if (lforw(curwp->w_dotp) == eopline)
  1131. X                eopflag = TRUE;
  1132. X        } else
  1133. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  1134. X
  1135. X        /* and then delete it */
  1136. X        ldelete(1L, FALSE);
  1137. X
  1138. X        /* if not a separator, just add it in */
  1139. X        if (c != ' ' && c != '\t') {
  1140. X            dotflag = (c == '.');        /* was it a dot */
  1141. X            if (wordlen < NSTRING - 1)
  1142. X                wbuf[wordlen++] = c;
  1143. X        } else if (wordlen) {
  1144. X            /* at a word break with a word waiting */
  1145. X            /* calculate tantitive new length with word added */
  1146. X            newlength = clength + 1 + wordlen;
  1147. X            if (newlength <= fillcol) {
  1148. X                /* add word to current line */
  1149. X                if (!firstflag) {
  1150. X                    linsert(1, ' '); /* the space */
  1151. X                    ++clength;
  1152. X                }
  1153. X                firstflag = FALSE;
  1154. X            } else {
  1155. X                /* start a new line */
  1156. X                lnewline();
  1157. X                clength = 0;
  1158. X            }
  1159. X
  1160. X            /* and add the word in in either case */
  1161. X            for (i=0; i<wordlen; i++) {
  1162. X                linsert(1, wbuf[i]);
  1163. X                ++clength;
  1164. X            }
  1165. X            if (dotflag) {
  1166. X                linsert(1, ' ');
  1167. X                ++clength;
  1168. X            }
  1169. X            wordlen = 0;
  1170. X        }
  1171. X    }
  1172. X    /* and add a last newline for the end of our new paragraph */
  1173. X    lnewline();
  1174. X    return(TRUE);
  1175. X}
  1176. X
  1177. Xkillpara(f, n)    /* delete n paragraphs starting with the current one */
  1178. X
  1179. Xint f;    /* default flag */
  1180. Xint n;    /* # of paras to delete */
  1181. X
  1182. X{
  1183. X    register int status;    /* returned status of functions */
  1184. X
  1185. X    while (n--) {        /* for each paragraph to delete */
  1186. X
  1187. X        /* mark out the end and beginning of the para to delete */
  1188. X        gotoeop(FALSE, 1);
  1189. X
  1190. X        /* set the mark here */
  1191. X            curwp->w_markp = curwp->w_dotp;
  1192. X            curwp->w_marko = curwp->w_doto;
  1193. X
  1194. X        /* go to the beginning of the paragraph */
  1195. X        gotobop(FALSE, 1);
  1196. X        curwp->w_doto = 0;    /* force us to the beginning of line */
  1197. X    
  1198. X        /* and delete it */
  1199. X        if ((status = killregion(FALSE, 1)) != TRUE)
  1200. X            return(status);
  1201. X
  1202. X        /* and clean up the 2 extra lines */
  1203. X        ldelete(2L, TRUE);
  1204. X    }
  1205. X    return(TRUE);
  1206. X}
  1207. X
  1208. X
  1209. X/*    wordcount:    count the # of words in the marked region,
  1210. X            along with average word sizes, # of chars, etc,
  1211. X            and report on them.            */
  1212. X
  1213. Xwordcount(f, n)
  1214. X
  1215. Xint f, n;    /* ignored numeric arguments */
  1216. X
  1217. X{
  1218. X    register LINE *lp;    /* current line to scan */
  1219. X    register int offset;    /* current char to scan */
  1220. X    long size;        /* size of region left to count */
  1221. X    register int ch;    /* current character to scan */
  1222. X    register int wordflag;    /* are we in a word now? */
  1223. X    register int lastword;    /* were we just in a word? */
  1224. X    long nwords;        /* total # of words */
  1225. X    long nchars;        /* total number of chars */
  1226. X    int nlines;        /* total number of lines in region */
  1227. X    int avgch;        /* average number of chars/word */
  1228. X    int status;        /* status return code */
  1229. X    REGION region;        /* region to look at */
  1230. X
  1231. X    /* make sure we have a region to count */
  1232. X        if ((status = getregion(®ion)) != TRUE)
  1233. X                return(status);
  1234. X    lp = region.r_linep;
  1235. X    offset = region.r_offset;
  1236. X    size = region.r_size;
  1237. X
  1238. X    /* count up things */
  1239. X    lastword = FALSE;
  1240. X    nchars = 0L;
  1241. X    nwords = 0L;
  1242. X    nlines = 0;
  1243. X    while (size--) {
  1244. X
  1245. X        /* get the current character */
  1246. X        if (offset == llength(lp)) {    /* end of line */
  1247. X            ch = '\n';
  1248. X            lp = lforw(lp);
  1249. X            offset = 0;
  1250. X            ++nlines;
  1251. X        } else {
  1252. X            ch = lgetc(lp, offset);
  1253. X            ++offset;
  1254. X        }
  1255. X
  1256. X        /* and tabulate it */
  1257. X        wordflag = ((ch >= 'a' && ch <= 'z') ||
  1258. X                (ch >= 'A' && ch <= 'Z') ||
  1259. X                (ch >= '0' && ch <= '9') ||
  1260. X                (ch == '$' || ch == '_'));
  1261. X        if (wordflag == TRUE && lastword == FALSE)
  1262. X            ++nwords;
  1263. X        lastword = wordflag;
  1264. X        ++nchars;
  1265. X    }
  1266. X
  1267. X    /* and report on the info */
  1268. X    if (nwords > 0L)
  1269. X        avgch = (int)((100L * nchars) / nwords);
  1270. X    else
  1271. X        avgch = 0;
  1272. X
  1273. X    mlwrite("Words %D Chars %D Lines %d Avg chars/word %f",
  1274. X        nwords, nchars, nlines + 1, avgch);
  1275. X    return(TRUE);
  1276. X}
  1277. X#endif
  1278. E!O!F
  1279. newsize=`wc -c < word.c`
  1280. if [ $newsize -ne 16421 ]
  1281. then echo "File word.c was $newsize bytes, 16421 expected"
  1282. fi
  1283. echo 'x - word.old (text)'
  1284. sed << 'E!O!F' 's/^X//' > word.old
  1285. X/*
  1286. X * The routines in this file implement commands that work word or a
  1287. X * paragraph at a time.  There are all sorts of word mode commands.  If I
  1288. X * do any sentence mode commands, they are likely to be put in this file. 
  1289. X */
  1290. X
  1291. X#if    MEGAMAX & ST520
  1292. Xoverlay    "word"
  1293. X#endif
  1294. X
  1295. X#include        <stdio.h>
  1296. X#include        "estruct.h"
  1297. X#include    "edef.h"
  1298. X
  1299. X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
  1300. X * line and stop on the first word-break or the beginning of the line. If we
  1301. X * reach the beginning of the line, jump back to the end of the word and start
  1302. X * a new line.  Otherwise, break the line at the word-break, eat it, and jump
  1303. X * back to the end of the word.
  1304. X * Returns TRUE on success, FALSE on errors.
  1305. X */
  1306. Xwrapword(f, n)
  1307. X
  1308. Xint f;        /* default flag */
  1309. Xint n;        /* numeric argument */
  1310. X
  1311. X{
  1312. X        register int cnt;    /* size of word wrapped to next line */
  1313. X    register int c;        /* charector temporary */
  1314. X
  1315. X    /* backup from the <NL> 1 char */
  1316. X        if (!backchar(0, 1))
  1317. X            return(FALSE);
  1318. X
  1319. X    /* back up until we aren't in a word,
  1320. X       make sure there is a break in the line */
  1321. X        cnt = 0;
  1322. X    while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ')
  1323. X                && (c != '\t')) {
  1324. X                cnt++;
  1325. X                if (!backchar(0, 1))
  1326. X                        return(FALSE);
  1327. X        /* if we make it to the beginning, start a new line */
  1328. X        if (curwp->w_doto == 0) {
  1329. X            gotoeol(FALSE, 0);
  1330. X            return(lnewline());
  1331. X        }
  1332. X        }
  1333. X
  1334. X    /* delete the forward white space */
  1335. X        if (!forwdel(0, 1))
  1336. X                return(FALSE);
  1337. X
  1338. X    /* put in a end of line */
  1339. X        if (!lnewline())
  1340. X                return(FALSE);
  1341. X
  1342. X    /* and past the first word */
  1343. X    while (cnt-- > 0) {
  1344. X        if (forwchar(FALSE, 1) == FALSE)
  1345. X            return(FALSE);
  1346. X    }
  1347. X        return(TRUE);
  1348. X}
  1349. X
  1350. X/*
  1351. X * Move the cursor backward by "n" words. All of the details of motion are
  1352. X * performed by the "backchar" and "forwchar" routines. Error if you try to
  1353. X * move beyond the buffers.
  1354. X */
  1355. Xbackword(f, n)
  1356. X{
  1357. X        if (n < 0)
  1358. X                return (forwword(f, -n));
  1359. X        if (backchar(FALSE, 1) == FALSE)
  1360. X                return (FALSE);
  1361. X        while (n--) {
  1362. X                while (inword() == FALSE) {
  1363. X                        if (backchar(FALSE, 1) == FALSE)
  1364. X                                return (FALSE);
  1365. X                }
  1366. X                while (inword() != FALSE) {
  1367. X                        if (backchar(FALSE, 1) == FALSE)
  1368. X                                return (FALSE);
  1369. X                }
  1370. X        }
  1371. X        return (forwchar(FALSE, 1));
  1372. X}
  1373. X
  1374. X/*
  1375. X * Move the cursor forward by the specified number of words. All of the motion
  1376. X * is done by "forwchar". Error if you try and move beyond the buffer's end.
  1377. X */
  1378. Xforwword(f, n)
  1379. X{
  1380. X        if (n < 0)
  1381. X                return (backword(f, -n));
  1382. X        while (n--) {
  1383. X#if    NFWORD
  1384. X                while (inword() != FALSE) {
  1385. X                        if (forwchar(FALSE, 1) == FALSE)
  1386. X                                return (FALSE);
  1387. X                }
  1388. X#endif
  1389. X                while (inword() == FALSE) {
  1390. X                        if (forwchar(FALSE, 1) == FALSE)
  1391. X                                return (FALSE);
  1392. X                }
  1393. X#if    NFWORD == 0
  1394. X                while (inword() != FALSE) {
  1395. X                        if (forwchar(FALSE, 1) == FALSE)
  1396. X                                return (FALSE);
  1397. X                }
  1398. X#endif
  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 any characters to upper case. Error if you try and move beyond the
  1406. X * end of the buffer. Bound to "M-U".
  1407. X */
  1408. Xupperword(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 characters to lower case. Error if you try and move over the end of
  1438. X * the buffer. Bound to "M-L".
  1439. X */
  1440. Xlowerword(f, n)
  1441. X{
  1442. X        register int    c;
  1443. X
  1444. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1445. X        return(rdonly());    /* we are in read only mode    */
  1446. X        if (n < 0)
  1447. X                return (FALSE);
  1448. X        while (n--) {
  1449. X                while (inword() == FALSE) {
  1450. X                        if (forwchar(FALSE, 1) == FALSE)
  1451. X                                return (FALSE);
  1452. X                }
  1453. X                while (inword() != FALSE) {
  1454. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  1455. X                        if (c>='A' && c<='Z') {
  1456. X                                c += 'a'-'A';
  1457. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  1458. X                                lchange(WFHARD);
  1459. X                        }
  1460. X                        if (forwchar(FALSE, 1) == FALSE)
  1461. X                                return (FALSE);
  1462. X                }
  1463. X        }
  1464. X        return (TRUE);
  1465. X}
  1466. X
  1467. X/*
  1468. X * Move the cursor forward by the specified number of words. As you move
  1469. X * convert the first character of the word to upper case, and subsequent
  1470. X * characters to lower case. Error if you try and move past the end of the
  1471. X * buffer. Bound to "M-C".
  1472. X */
  1473. Xcapword(f, n)
  1474. X{
  1475. X        register int    c;
  1476. X
  1477. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1478. X        return(rdonly());    /* we are in read only mode    */
  1479. X        if (n < 0)
  1480. X                return (FALSE);
  1481. X        while (n--) {
  1482. X                while (inword() == FALSE) {
  1483. X                        if (forwchar(FALSE, 1) == FALSE)
  1484. X                                return (FALSE);
  1485. X                }
  1486. X                if (inword() != FALSE) {
  1487. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  1488. X                        if (c>='a' && c<='z') {
  1489. X                                c -= 'a'-'A';
  1490. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  1491. X                                lchange(WFHARD);
  1492. X                        }
  1493. X                        if (forwchar(FALSE, 1) == FALSE)
  1494. X                                return (FALSE);
  1495. X                        while (inword() != FALSE) {
  1496. X                                c = lgetc(curwp->w_dotp, curwp->w_doto);
  1497. X                                if (c>='A' && c<='Z') {
  1498. X                                        c += 'a'-'A';
  1499. X                                        lputc(curwp->w_dotp, curwp->w_doto, c);
  1500. X                                        lchange(WFHARD);
  1501. X                                }
  1502. X                                if (forwchar(FALSE, 1) == FALSE)
  1503. X                                        return (FALSE);
  1504. X                        }
  1505. X                }
  1506. X        }
  1507. X        return (TRUE);
  1508. X}
  1509. X
  1510. X/*
  1511. X * Kill forward by "n" words. Remember the location of dot. Move forward by
  1512. X * the right number of words. Put dot back where it was and issue the kill
  1513. X * command for the right number of characters. Bound to "M-D".
  1514. X */
  1515. Xdelfword(f, n)
  1516. X{
  1517. X        register LINE   *dotp;
  1518. X        register int    doto;
  1519. X        long size;
  1520. X
  1521. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1522. X        return(rdonly());    /* we are in read only mode    */
  1523. X        if (n < 0)
  1524. X                return (FALSE);
  1525. X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
  1526. X                kdelete();              /* last wasn't a kill.  */
  1527. X        thisflag |= CFKILL;
  1528. X        dotp = curwp->w_dotp;
  1529. X        doto = curwp->w_doto;
  1530. X        size = 0;
  1531. X        while (n--) {
  1532. X#if    NFWORD
  1533. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  1534. X            if (forwchar(FALSE,1) == FALSE)
  1535. X                return(FALSE);
  1536. X            ++size;
  1537. X        }
  1538. X
  1539. X        while (inword() != FALSE) {
  1540. X            if (forwchar(FALSE,1) == FALSE)
  1541. X                return(FALSE);
  1542. X            ++size;
  1543. X        }
  1544. X
  1545. X                while ((inword() == FALSE) &&
  1546. X                (curwp->w_doto != llength(curwp->w_dotp))) {
  1547. X                        if (forwchar(FALSE, 1) == FALSE)
  1548. X                                return (FALSE);
  1549. X                        ++size;
  1550. X                }
  1551. X#else
  1552. X                while (inword() == FALSE) {
  1553. X                        if (forwchar(FALSE, 1) == FALSE)
  1554. X                                return (FALSE);
  1555. X                        ++size;
  1556. X                }
  1557. X
  1558. X                while (inword() != FALSE) {
  1559. X                        if (forwchar(FALSE, 1) == FALSE)
  1560. X                                return (FALSE);
  1561. X                        ++size;
  1562. X                }
  1563. X#endif
  1564. X        }
  1565. X        curwp->w_dotp = dotp;
  1566. X        curwp->w_doto = doto;
  1567. X        return (ldelete(size, TRUE));
  1568. X}
  1569. X
  1570. X/*
  1571. X * Kill backwards by "n" words. Move backwards by the desired number of words,
  1572. X * counting the characters. When dot is finally moved to its resting place,
  1573. X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
  1574. X */
  1575. Xdelbword(f, n)
  1576. X{
  1577. X        long size;
  1578. X
  1579. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1580. X        return(rdonly());    /* we are in read only mode    */
  1581. X        if (n < 0)
  1582. X                return (FALSE);
  1583. X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
  1584. X                kdelete();              /* last wasn't a kill.  */
  1585. X        thisflag |= CFKILL;
  1586. X        if (backchar(FALSE, 1) == FALSE)
  1587. X                return (FALSE);
  1588. X        size = 0;
  1589. X        while (n--) {
  1590. X                while (inword() == FALSE) {
  1591. X                        if (backchar(FALSE, 1) == FALSE)
  1592. X                                return (FALSE);
  1593. X                        ++size;
  1594. X                }
  1595. X                while (inword() != FALSE) {
  1596. X                        if (backchar(FALSE, 1) == FALSE)
  1597. X                                return (FALSE);
  1598. X                        ++size;
  1599. X                }
  1600. X        }
  1601. X        if (forwchar(FALSE, 1) == FALSE)
  1602. X                return (FALSE);
  1603. X        return (ldelete(size, TRUE));
  1604. X}
  1605. X
  1606. X/*
  1607. X * Return TRUE if the character at dot is a character that is considered to be
  1608. X * part of a word. The word character list is hard coded. Should be setable.
  1609. X */
  1610. Xinword()
  1611. X{
  1612. X        register int    c;
  1613. X
  1614. X        if (curwp->w_doto == llength(curwp->w_dotp))
  1615. X                return (FALSE);
  1616. X        c = lgetc(curwp->w_dotp, curwp->w_doto);
  1617. X        if (c>='a' && c<='z')
  1618. X                return (TRUE);
  1619. X        if (c>='A' && c<='Z')
  1620. X                return (TRUE);
  1621. X        if (c>='0' && c<='9')
  1622. X                return (TRUE);
  1623. X        if (c=='$' || c=='_')                   /* For identifiers      */
  1624. X                return (TRUE);
  1625. X        return (FALSE);
  1626. X}
  1627. X
  1628. X#if    WORDPRO
  1629. Xfillpara(f, n)    /* Fill the current paragraph according to the current
  1630. X           fill column                        */
  1631. X
  1632. Xint f, n;    /* deFault flag and Numeric argument */
  1633. X
  1634. X{
  1635. X    register int c;            /* current char durring scan    */
  1636. X    register int wordlen;        /* length of current word    */
  1637. X    register int clength;        /* position on line during fill    */
  1638. X    register int i;            /* index during word copy    */
  1639. X    register int newlength;        /* tentative new line length    */
  1640. X    register int eopflag;        /* Are we at the End-Of-Paragraph? */
  1641. X    register int firstflag;        /* first word? (needs no space)    */
  1642. X    register LINE *eopline;        /* pointer to line just past EOP */
  1643. X    register int dotflag;        /* was the last char a period?    */
  1644. X    char wbuf[NSTRING];        /* buffer for current word    */
  1645. X
  1646. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1647. X        return(rdonly());    /* we are in read only mode    */
  1648. X    if (fillcol == 0) {    /* no fill column set */
  1649. X        mlwrite("No fill column set");
  1650. X        return(FALSE);
  1651. X    }
  1652. X
  1653. X    /* record the pointer to the line just past the EOP */
  1654. X    gotoeop(FALSE, 1);
  1655. X    eopline = lforw(curwp->w_dotp);
  1656. X
  1657. X    /* and back top the beginning of the paragraph */
  1658. X    gotobop(FALSE, 1);
  1659. X
  1660. X    /* initialize various info */
  1661. X    clength = curwp->w_doto;
  1662. X    if (clength && curwp->w_dotp->l_text[0] == TAB)
  1663. X        clength = 8;
  1664. X    wordlen = 0;
  1665. X    dotflag = FALSE;
  1666. X
  1667. X    /* scan through lines, filling words */
  1668. X    firstflag = TRUE;
  1669. X    eopflag = FALSE;
  1670. X    while (!eopflag) {
  1671. X        /* get the next character in the paragraph */
  1672. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  1673. X            c = ' ';
  1674. X            if (lforw(curwp->w_dotp) == eopline)
  1675. X                eopflag = TRUE;
  1676. X        } else
  1677. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  1678. X
  1679. X        /* and then delete it */
  1680. X        ldelete(1L, FALSE);
  1681. X
  1682. X        /* if not a separator, just add it in */
  1683. X        if (c != ' ' && c != '\t') {
  1684. X            dotflag = (c == '.');        /* was it a dot */
  1685. X            if (wordlen < NSTRING - 1)
  1686. X                wbuf[wordlen++] = c;
  1687. X        } else if (wordlen) {
  1688. X            /* at a word break with a word waiting */
  1689. X            /* calculate tantitive new length with word added */
  1690. X            newlength = clength + 1 + wordlen;
  1691. X            if (newlength <= fillcol) {
  1692. X                /* add word to current line */
  1693. X                if (!firstflag) {
  1694. X                    linsert(1, ' '); /* the space */
  1695. X                    ++clength;
  1696. X                }
  1697. X                firstflag = FALSE;
  1698. X            } else {
  1699. X                /* start a new line */
  1700. X                lnewline();
  1701. X                clength = 0;
  1702. X            }
  1703. X
  1704. X            /* and add the word in in either case */
  1705. X            for (i=0; i<wordlen; i++) {
  1706. X                linsert(1, wbuf[i]);
  1707. X                ++clength;
  1708. X            }
  1709. X            if (dotflag) {
  1710. X                linsert(1, ' ');
  1711. X                ++clength;
  1712. X            }
  1713. X            wordlen = 0;
  1714. X        }
  1715. X    }
  1716. X    /* and add a last newline for the end of our new paragraph */
  1717. X    lnewline();
  1718. X    return(TRUE);
  1719. X}
  1720. X
  1721. Xkillpara(f, n)    /* delete n paragraphs starting with the current one */
  1722. X
  1723. Xint f;    /* default flag */
  1724. Xint n;    /* # of paras to delete */
  1725. X
  1726. X{
  1727. X    register int status;    /* returned status of functions */
  1728. X
  1729. X    while (n--) {        /* for each paragraph to delete */
  1730. X
  1731. X        /* mark out the end and beginning of the para to delete */
  1732. X        gotoeop(FALSE, 1);
  1733. X
  1734. X        /* set the mark here */
  1735. X            curwp->w_markp = curwp->w_dotp;
  1736. X            curwp->w_marko = curwp->w_doto;
  1737. X
  1738. X        /* go to the beginning of the paragraph */
  1739. X        gotobop(FALSE, 1);
  1740. X        curwp->w_doto = 0;    /* force us to the beginning of line */
  1741. X    
  1742. X        /* and delete it */
  1743. X        if ((status = killregion(FALSE, 1)) != TRUE)
  1744. X            return(status);
  1745. X
  1746. X        /* and clean up the 2 extra lines */
  1747. X        ldelete(2L, TRUE);
  1748. X    }
  1749. X    return(TRUE);
  1750. X}
  1751. X
  1752. X
  1753. X/*    wordcount:    count the # of words in the marked region,
  1754. X            along with average word sizes, # of chars, etc,
  1755. X            and report on them.            */
  1756. X
  1757. Xwordcount(f, n)
  1758. X
  1759. Xint f, n;    /* ignored numeric arguments */
  1760. X
  1761. X{
  1762. X    register LINE *lp;    /* current line to scan */
  1763. X    register int offset;    /* current char to scan */
  1764. X    long size;        /* size of region left to count */
  1765. X    register int ch;    /* current character to scan */
  1766. X    register int wordflag;    /* are we in a word now? */
  1767. X    register int lastword;    /* were we just in a word? */
  1768. X    long nwords;        /* total # of words */
  1769. X    long nchars;        /* total number of chars */
  1770. X    int nlines;        /* total number of lines in region */
  1771. X    int avgch;        /* average number of chars/word */
  1772. X    int status;        /* status return code */
  1773. X    REGION region;        /* region to look at */
  1774. X
  1775. X    /* make sure we have a region to count */
  1776. X        if ((status = getregion(®ion)) != TRUE)
  1777. X                return(status);
  1778. X    lp = region.r_linep;
  1779. X    offset = region.r_offset;
  1780. X    size = region.r_size;
  1781. X
  1782. X    /* count up things */
  1783. X    lastword = FALSE;
  1784. X    nchars = 0L;
  1785. X    nwords = 0L;
  1786. X    nlines = 0;
  1787. X    while (size--) {
  1788. X
  1789. X        /* get the current character */
  1790. X        if (offset == llength(lp)) {    /* end of line */
  1791. X            ch = '\n';
  1792. X            lp = lforw(lp);
  1793. X            offset = 0;
  1794. X            ++nlines;
  1795. X        } else {
  1796. X            ch = lgetc(lp, offset);
  1797. X            ++offset;
  1798. X        }
  1799. X
  1800. X        /* and tabulate it */
  1801. X        wordflag = ((ch >= 'a' && ch <= 'z') ||
  1802. X                (ch >= 'A' && ch <= 'Z') ||
  1803. X                (ch >= '0' && ch <= '9') ||
  1804. X                (ch == '$' || ch == '_'));
  1805. X        if (wordflag == TRUE && lastword == FALSE)
  1806. X            ++nwords;
  1807. X        lastword = wordflag;
  1808. X        ++nchars;
  1809. X    }
  1810. X
  1811. X    /* and report on the info */
  1812. X    if (nwords > 0L)
  1813. X        avgch = (int)((100L * nchars) / nwords);
  1814. X    else
  1815. X        avgch = 0;
  1816. X
  1817. X    mlwrite("Words %D Chars %D Lines %d Avg chars/word %f",
  1818. X        nwords, nchars, nlines + 1, avgch);
  1819. X    return(TRUE);
  1820. X}
  1821. X#endif
  1822. E!O!F
  1823. newsize=`wc -c < word.old`
  1824. if [ $newsize -ne 15895 ]
  1825. then echo "File word.old was $newsize bytes, 15895 expected"
  1826. fi
  1827. echo 'x - z309.c (text)'
  1828. sed << 'E!O!F' 's/^X//' > z309.c
  1829. X/*
  1830. X * The routines in this file provide support for the Zenith Z-100 PC
  1831. X * family.  It goes directly to the graphics RAM to do screen output. 
  1832. X * It compiles into nothing if not a Zenith driver.
  1833. X */
  1834. X
  1835. X#define    termdef    1            /* don't define "term" external */
  1836. X
  1837. X#include        <stdio.h>
  1838. X#include    "estruct.h"
  1839. X#include        "edef.h"
  1840. X
  1841. X#if     Z309
  1842. X
  1843. X/* set NROW to 25 for 25-line interlaced mode */
  1844. X#define NROW    50                      /* Screen size.                 */
  1845. X#define NCOL    80                      /* Edit if you want to.         */
  1846. X#define    MARGIN    8            /* size of minimim margin and    */
  1847. X#define    SCRSIZ    64            /* scroll size for extended lines */
  1848. X#define    NPAUSE    200            /* # times thru update to pause */
  1849. X#define BEL     0x07                    /* BEL character.               */
  1850. X#define ESC     0x1B                    /* ESC character.               */
  1851. X#define    SPACE    32            /* space character        */
  1852. X
  1853. X#define    SCADC    0xb8000000L        /* CGA address of screen RAM    */
  1854. X#define    SCADM    0xb0000000L        /* MONO address of screen RAM    */
  1855. X
  1856. X#define    CDMONO    0            /* monochrome text card        */
  1857. X#define    CDCGA50    1            /* 50-line color graphics card    */
  1858. X#define CDCGI25 2            /* 25-line interlaced CGA text    */
  1859. X#define CDCGA25 3            /* 25-line color graphics card    */
  1860. X#define    CDSENSE    9            /* detect the card type        */
  1861. X
  1862. Xint dtype = CDCGA50;            /* current display type        */
  1863. Xlong scadd;                /* address of screen ram    */
  1864. Xint *scptr[NROW];            /* pointer to screen lines    */
  1865. Xint sline[NCOL];            /* screen line image        */
  1866. Xextern union REGS rg;            /* cpu register for use of DOS calls */
  1867. X
  1868. Xextern  int     ttopen();               /* Forward references.          */
  1869. Xextern  int     ttgetc();
  1870. Xextern  int     ttputc();
  1871. Xextern  int     ttflush();
  1872. Xextern  int     ttclose();
  1873. Xextern  int     z309move();
  1874. Xextern  int     z309eeol();
  1875. Xextern  int     z309eeop();
  1876. Xextern  int     z309beep();
  1877. Xextern  int     z309open();
  1878. Xextern    int    z309rev();
  1879. Xextern    int    z309cres();
  1880. Xextern    int    z309close();
  1881. Xextern    int    z309putc();
  1882. Xextern    int    z309kopen();
  1883. Xextern    int    z309kclose();
  1884. X
  1885. X#if    COLOR
  1886. Xextern    int    z309fcol();
  1887. Xextern    int    z309bcol();
  1888. X
  1889. Xint    cfcolor = -1;        /* current forground color */
  1890. Xint    cbcolor = -1;        /* current background color */
  1891. Xint    ctrans[] =        /* ansi to z309 color translation table */
  1892. X    {0, 4, 2, 6, 1, 5, 3, 7};
  1893. X#endif
  1894. X
  1895. X/*
  1896. X * Standard terminal interface dispatch table. Most of the fields point into
  1897. X * "termio" code.
  1898. X */
  1899. XTERM    term    = {
  1900. X    NROW-1,
  1901. X        NROW-1,
  1902. X        NCOL,
  1903. X        NCOL,
  1904. X    MARGIN,
  1905. X    SCRSIZ,
  1906. X    NPAUSE,
  1907. X        z309open,
  1908. X        z309close,
  1909. X    z309kopen,
  1910. X    z309kclose,
  1911. X        ttgetc,
  1912. X    z309putc,
  1913. X        ttflush,
  1914. X        z309move,
  1915. X        z309eeol,
  1916. X        z309eeop,
  1917. X        z309beep,
  1918. X    z309rev,
  1919. X    z309cres
  1920. X#if    COLOR
  1921. X    , z309fcol,
  1922. X    z309bcol
  1923. X#endif
  1924. X};
  1925. X
  1926. Xextern union REGS rg;
  1927. X
  1928. X#if    COLOR
  1929. Xz309fcol(color)        /* set the current output color */
  1930. X
  1931. Xint color;    /* color to set */
  1932. X
  1933. X{
  1934. X    cfcolor = ctrans[color];
  1935. X}
  1936. X
  1937. Xz309bcol(color)        /* set the current background color */
  1938. X
  1939. Xint color;    /* color to set */
  1940. X
  1941. X{
  1942. X        cbcolor = ctrans[color];
  1943. X}
  1944. X#endif
  1945. Xz309move(row, col)
  1946. X{
  1947. X    rg.h.ah = 2;        /* set cursor position function code */
  1948. X    rg.h.dl = col;
  1949. X    rg.h.dh = row;
  1950. X    rg.h.bh = 0;        /* set screen page number */
  1951. X    int86(0x10, &rg, &rg);
  1952. X}
  1953. X
  1954. Xz309eeol()    /* erase to the end of the line */
  1955. X
  1956. X{
  1957. X    int attr;    /* attribute byte mask to place in RAM */
  1958. X    int *lnptr;    /* pointer to the destination line */
  1959. X    int i;
  1960. X    int ccol;    /* current column cursor lives */
  1961. X    int crow;    /*       row    */
  1962. X
  1963. X    /* find the current cursor position */
  1964. X    rg.h.ah = 3;        /* read cursor position function code */
  1965. X    rg.h.bh = 0;        /* current video page */
  1966. X    int86(0x10, &rg, &rg);
  1967. X    ccol = rg.h.dl;        /* record current column */
  1968. X    crow = rg.h.dh;        /* and row */
  1969. X
  1970. X    /* build the attribute byte and setup the screen pointer */
  1971. X#if    COLOR
  1972. X    if (dtype != CDMONO)
  1973. X        attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8;
  1974. X    else
  1975. X        attr = 0x0700;
  1976. X#else
  1977. X    attr = 0x0700;
  1978. X#endif
  1979. X    lnptr = &sline[0];
  1980. X    for (i=0; i < term.t_ncol; i++)
  1981. X        *lnptr++ = SPACE | attr;
  1982. X
  1983. X#if 0    /* Heath/Zenith builds flicker-less CGAs */
  1984. X    if (flickcode) {
  1985. X        /* wait for vertical retrace to be off */
  1986. X        while ((inp(0x3da) & 8))
  1987. X            ;
  1988. X    
  1989. X        /* and to be back on */
  1990. X        while ((inp(0x3da) & 8) == 0)
  1991. X            ;
  1992. X    }
  1993. X#endif
  1994. X
  1995. X    /* and send the string out */
  1996. X    movmem(&sline[0], scptr[crow]+ccol, (term.t_ncol-ccol)*2);
  1997. X
  1998. X}
  1999. X
  2000. Xz309putc(ch)    /* put a character at the current position in the
  2001. X           current colors */
  2002. X
  2003. Xint ch;
  2004. X
  2005. X{
  2006. X    rg.h.ah = 14;        /* write char to screen with current attrs */
  2007. X    rg.h.al = ch;
  2008. X#if    COLOR
  2009. X    if (dtype != CDMONO)
  2010. X        rg.h.bl = cfcolor;
  2011. X    else
  2012. X        rg.h.bl = 0x07;
  2013. X#else
  2014. X    rg.h.bl = 0x07;
  2015. X#endif
  2016. X    int86(0x10, &rg, &rg);
  2017. X}
  2018. X
  2019. Xz309eeop()
  2020. X{
  2021. X    int attr;        /* attribute to fill screen with */
  2022. X
  2023. X    rg.h.ah = 6;        /* scroll page up function code */
  2024. X    rg.h.al = 0;        /* # lines to scroll (clear it) */
  2025. X    rg.x.cx = 0;        /* upper left corner of scroll */
  2026. X/*HERE*/    rg.x.dx = 0x184f;    /* lower right corner of scroll */
  2027. X#if    COLOR
  2028. X    if (dtype != CDMONO)
  2029. X        attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15);
  2030. X    else
  2031. X        attr = 0;
  2032. X#else
  2033. X    attr = 0;
  2034. X#endif
  2035. X    rg.h.bh = attr;
  2036. X    int86(0x10, &rg, &rg);
  2037. X}
  2038. X
  2039. Xz309rev(state)        /* change reverse video state */
  2040. X
  2041. Xint state;    /* TRUE = reverse, FALSE = normal */
  2042. X
  2043. X{
  2044. X    /* This never gets used under the z309-PC driver */
  2045. X}
  2046. X
  2047. Xz309cres(res)    /* change screen resolution */
  2048. X
  2049. Xchar *res;    /* resolution to change to */
  2050. X
  2051. X{
  2052. X    if (strcmp(res, "CGA50") == 0) {
  2053. X        scinit(CDCGA50);
  2054. X        return(TRUE);
  2055. X    } else if (strcmp(res, "MONO") == 0) {
  2056. X        scinit(CDMONO);
  2057. X        return(TRUE);
  2058. X    } else
  2059. X        return(FALSE);
  2060. X}
  2061. X
  2062. Xz309beep()
  2063. X{
  2064. X#if    MWC86
  2065. X    putcnb(BEL);
  2066. X#else
  2067. X    bdos(6, BEL, 0);
  2068. X#endif
  2069. X}
  2070. X
  2071. Xz309open()
  2072. X{
  2073. X    scinit(CDSENSE);
  2074. X    revexist = TRUE;
  2075. X        ttopen();
  2076. X}
  2077. X
  2078. Xz309close()
  2079. X
  2080. X{
  2081. X    rg.h.ah = 101;
  2082. X    rg.h.al = 1;    /* 25-line interlace mode */
  2083. X    int86(0x10, &rg, &rg); 
  2084. X#if    COLOR
  2085. X    z309fcol(7);
  2086. X    z309bcol(0);
  2087. X#endif
  2088. X    ttclose();
  2089. X}
  2090. X
  2091. Xz309kopen()    /* open the keyboard */
  2092. X
  2093. X{
  2094. X}
  2095. X
  2096. Xz309kclose()    /* close the keyboard */
  2097. X
  2098. X{
  2099. X}
  2100. X
  2101. Xscinit(type)    /* initialize the screen head pointers */
  2102. X
  2103. Xint type;    /* type of adapter to init for */
  2104. X
  2105. X{
  2106. X    union {
  2107. X        long laddr;    /* long form of address */
  2108. X        int *paddr;    /* pointer form of address */
  2109. X    } addr;
  2110. X    int i;
  2111. X
  2112. X    /* if asked...find out what display is connected */
  2113. X    int86(0x11, &rg, &rg);
  2114. X    dtype = CDCGA50;
  2115. X    scadd = SCADC;
  2116. X    strcpy(sres, "CGA50");
  2117. X    if ((((rg.x.ax >> 4) & 11) == 3) || type == CDMONO) {
  2118. X        strcpy(sres, "MONO");
  2119. X        dtype = CDMONO;
  2120. X        scadd = SCADM;
  2121. X    }
  2122. X    else {
  2123. X        rg.h.ah = 101;
  2124. X/* set al = 1 for 25-line interlace mode */        
  2125. X        rg.h.al = 2;    /* 50-line interlace mode */
  2126. X        int86(0x10, &rg, &rg); 
  2127. X    }
  2128. X
  2129. X    /* initialize the screen pointer array */
  2130. X    for (i = 0; i < NROW; i++) {
  2131. X        addr.laddr = scadd + (long)(NCOL * i * 2);
  2132. X        scptr[i] = addr.paddr;
  2133. X    }
  2134. X}
  2135. X
  2136. Xscwrite(row, outstr, forg, bacg)    /* write a line out*/
  2137. X
  2138. Xint row;    /* row of screen to place outstr on */
  2139. Xchar *outstr;    /* string to write out (must be term.t_ncol long) */
  2140. Xint forg;    /* forground color of string to write */
  2141. Xint bacg;    /* background color */
  2142. X
  2143. X{
  2144. X    int attr;    /* attribute byte mask to place in RAM */
  2145. X    int *lnptr;    /* pointer to the destination line */
  2146. X    int i;
  2147. X
  2148. X    /* build the attribute byte and setup the screen pointer */
  2149. X#if    COLOR
  2150. X    if (dtype != CDMONO)
  2151. X        attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8;
  2152. X    else
  2153. X        attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
  2154. X#else
  2155. X    attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
  2156. X#endif
  2157. X    lnptr = &sline[0];
  2158. X    for (i=0; i<term.t_ncol; i++)
  2159. X        *lnptr++ = (outstr[i] & 255) | attr;
  2160. X
  2161. X#if 0    /* Heath/Zenith builds flicker-less CGAs */
  2162. X    if (flickcode) {
  2163. X        /* wait for vertical retrace to be off */
  2164. X        while ((inp(0x3da) & 8))
  2165. X            ;
  2166. X    
  2167. X        /* and to be back on */
  2168. X        while ((inp(0x3da) & 8) == 0)
  2169. X            ;
  2170. X    }
  2171. X#endif    
  2172. X
  2173. X    /* and send the string out */
  2174. X    movmem(&sline[0], scptr[row],term.t_ncol*2);
  2175. X}
  2176. X
  2177. X#if    FLABEL
  2178. Xfnclabel(f, n)        /* label a function key */
  2179. X
  2180. Xint f,n;    /* default flag, numeric argument [unused] */
  2181. X
  2182. X{
  2183. X    /* on machines with no function keys...don't bother */
  2184. X    return(TRUE);
  2185. X}
  2186. X#endif
  2187. X#else
  2188. Xz309hello()
  2189. X{
  2190. X}
  2191. X#endif
  2192. E!O!F
  2193. newsize=`wc -c < z309.c`
  2194. if [ $newsize -ne 7806 ]
  2195. then echo "File z309.c was $newsize bytes, 7806 expected"
  2196. fi
  2197.     bill davidsen        (wedu@ge-crd.arpa)
  2198.   {chinet | philabs | sesimo}!steinmetz!crdos1!davidsen
  2199. "Stupidity, like virtue, is its own reward" -me
  2200.  
  2201.  
  2202.