home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / ee / part01 < prev    next >
Encoding:
Text File  |  1993-02-21  |  53.8 KB  |  1,890 lines

  1. Newsgroups: comp.sources.misc
  2. From: hugh@nsmdserv.cnd.hp.com (Hugh F. Mahon)
  3. Subject: v35i080:  ee - Easy Editor, a simple editor for UNIX, Part01/05
  4. Message-ID: <csm-v35i080=ee.220843@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 192044ca308a2e3f6c82f3ce4394b8e4
  6. Date: Mon, 22 Feb 1993 04:10:13 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: hugh@nsmdserv.cnd.hp.com (Hugh F. Mahon)
  10. Posting-number: Volume 35, Issue 80
  11. Archive-name: ee/part01
  12. Environment: SYSV, SunOS, Curses
  13.  
  14. This is ee ("Easy Editor"), a text editor so simple to learn no instruction 
  15. is required.  ee is intended for simple editing tasks such as E-mail messages 
  16. and news articles.
  17.  
  18. ee should compile on most System V based platforms, but may be able to 
  19. operate on other platforms with appropriate curses support.  On systems 
  20. with support for X/Open localization, it is possible to localize ee for 
  21. languages with single octet character sets.  
  22.  
  23. Hugh Mahon              |___|     
  24. h_mahon@fc.hp.com       |   |     
  25.                             |\  /|
  26.                             | \/ |
  27. --------------------
  28. #! /bin/sh
  29. # This is a shell archive.  Remove anything before this line, then feed it
  30. # into a shell via "sh file" or similar.  To overwrite existing files,
  31. # type "sh file -c".
  32. # Contents:  README.ee ee.i18n.guide new_curse.c.B
  33. # Wrapped by kent@sparky on Sat Feb 20 21:31:17 1993
  34. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  35. echo If this archive is complete, you will see the following message:
  36. echo '          "shar: End of archive 1 (of 5)."'
  37. if test -f 'README.ee' -a "${1}" != "-c" ; then 
  38.   echo shar: Will not clobber existing file \"'README.ee'\"
  39. else
  40.   echo shar: Extracting \"'README.ee'\" \(5919 characters\)
  41.   sed "s/^X//" >'README.ee' <<'END_OF_FILE'
  42. X          THIS MATERIAL IS PROVIDED "AS IS".  THERE ARE NO WARRANTIES OF 
  43. X          ANY KIND WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT 
  44. X          LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
  45. X          FITNESS FOR A PARTICULAR PURPOSE.  Neither Hewlett-Packard nor 
  46. X          Hugh Mahon shall be liable for errors contained herein, nor for 
  47. X          incidental or consequential damages in connection with the 
  48. X          furnishing, performance or use of this material.  Neither 
  49. X          Hewlett-Packard nor Hugh Mahon assumes any responsibility for 
  50. X          the use or reliability of this software or documentation.  This 
  51. X          software and documentation is totally UNSUPPORTED.  There is no 
  52. X          support contract available.  Hewlett-Packard has done NO 
  53. X          Quality Assurance on ANY of the program or documentation.  You 
  54. X          may find the quality of the materials inferior to supported 
  55. X          materials. 
  56. X
  57. X      This software is for free distribution, and is not to be sold, or 
  58. X      otherwise traded for value without the expressed, written consent 
  59. X      of the author.  Likewise, any derivatives of this software cannot 
  60. X      be sold or traded without the consent of the author.  
  61. X
  62. X      This notice must be included with this software and any 
  63. X      derivatives. 
  64. X
  65. X      Any modifications to this software by anyone but the original author 
  66. X      must be so noted. 
  67. X
  68. X
  69. XThe editor 'ee' (easy editor) is intended to be a simple, easy to use 
  70. Xterminal-based screen oriented editor that requires no instruction to 
  71. Xuse.  Its primary use would be for people who are new to computers, or who 
  72. Xuse computers only for things like e-mail.
  73. X
  74. Xee's simplified interface is highlighted by the use of pop-up menus which 
  75. Xmake it possible for users to carry out tasks without the need to 
  76. Xremember commands.  An information window at the top of the screen shows 
  77. Xthe user the operations available with control-keys.
  78. X
  79. Xee relies on the virtual memory abilities of the platform it is running on 
  80. Xand does not have its own memory management capabilities.
  81. X
  82. XI am releasing ee because I hate to see new users and non-computer types 
  83. Xget frustrated by vi, and would like to see more intuitive interfaces for 
  84. Xbasic tools (both character-based and graphical) become more pervasive.
  85. XTerminal capabilities and communication speeds have evolved considerably 
  86. Xsince the time in which vi's interface was created, allowing much more 
  87. Xintuitive interfaces to be used.  Since character-based I/O won't be 
  88. Xcompletely replaced by graphical user interfaces for at least a few more 
  89. Xyears, I'd like to do what I can to make using computers with less 
  90. Xglamorous interfaces as easy to use as possible.  If terminal interfaces 
  91. Xare still used in ten years, I hope neophytes won't still be stuck with 
  92. Xonly vi.  
  93. X
  94. XFor a text editor to be easy to use requires a certain set of abilities.  In 
  95. Xorder for ee to work, a terminal must have the ability to position the cursor 
  96. Xon the screen, and should have arrow keys that send unique sequences 
  97. X(multiple characters, the first character is an "escape", octal code 
  98. X'\033').  All of this information needs to be in a database called "terminfo" 
  99. X(System V implementations) or "termcap" (usually used for BSD systems).  In 
  100. Xcase the arrow keys do not transmit unique sequences, motion operations are 
  101. Xmapped to control keys as well, but this at least partially defeats the 
  102. Xpurpose.  The curses package is used to handle the I/O which deals with the 
  103. Xterminal's capabilities.  
  104. X
  105. XWhile ee is based on curses, I have included here the source code to 
  106. Xnew_curse, a subset of curses developed for use with ee.  'curses' often  
  107. Xwill have a defect that reduces the usefulness of the editor relying upon 
  108. Xit.  
  109. X
  110. XThe new_curse source is provided simply as a back up in case the curses on 
  111. Xyour system has such a defect.  The code is a rather nasty hack, and can be 
  112. Xnoticeably slower than real curses.  Also, although there is code for 
  113. Xhandling non-System V systems, this code has been much less used, and so may 
  114. Xnow be non-functional.  Likewise with the code for handling termcap.  I just 
  115. Xfelt that since it was already there, I may as well leave it since someone 
  116. Xmay find it useful.  While new_curse is somewhat poorly written code in some 
  117. Xplaces, it is source code that can be hacked if all else fails.  Note, 
  118. Xhowever, that if you're having problems, first make sure of the terminal 
  119. Xconfiguration, especially if you're using a terminal emulator, and make sure 
  120. Xthat you are using the right terminfo entry before rummaging through code.  
  121. XTerminfo entries often contain inaccuracies, or incomplete information, or 
  122. Xmay not totally match the terminal or emulator the terminal information is 
  123. Xbeing used with.  Complaints that ee isn't working quite right often end up 
  124. Xbeing something else (like the terminal emulator being used). 
  125. X
  126. XBoth ee and new_curse were developed using K&R C (also known as "classic 
  127. XC").  Some tweaks may be required to make ee and new_curse compile on 
  128. Xsome platforms.
  129. X
  130. Xee is the result of several conflicting design goals.  While I know that it 
  131. Xsolves the problems of some users, I also have no doubt that some will decry 
  132. Xits lack of more features.  I will settle for knowing that ee does fulfill 
  133. Xthe needs of a minority (but still large number) of users.  The goals of ee 
  134. Xare: 
  135. X
  136. X        1. To be so easy to use as to require no instruction.
  137. X        2. To be easy to compile and, if necessary, port to new platforms 
  138. X           by people with relatively little knowledge of C and UNIX.
  139. X        3. To have a minimum number of files to be dealt with, for compile 
  140. X           and installation.
  141. X        4. To have enough functionality to be useful to a large number of 
  142. X           people.
  143. X
  144. XHugh Mahon              |___|     
  145. Xh_mahon@fc.hp.com       |   |     
  146. X                            |\  /|
  147. X                            | \/ |
  148. X
  149. END_OF_FILE
  150.   if test 5919 -ne `wc -c <'README.ee'`; then
  151.     echo shar: \"'README.ee'\" unpacked with wrong size!
  152.   fi
  153.   # end of 'README.ee'
  154. fi
  155. if test -f 'ee.i18n.guide' -a "${1}" != "-c" ; then 
  156.   echo shar: Will not clobber existing file \"'ee.i18n.guide'\"
  157. else
  158.   echo shar: Extracting \"'ee.i18n.guide'\" \(6826 characters\)
  159.   sed "s/^X//" >'ee.i18n.guide' <<'END_OF_FILE'
  160. XEasy Editor ("ee") provides the ability to translate the messages displayed to 
  161. Xthe user and the commands entered.  This is done via message catalogs, 
  162. Xfollowing X/Open standards.  ee only supports eight bit characters.
  163. X
  164. X(The name ee.i18n.guide is for "ee internationalization guide".  The i18n 
  165. Xabbreviation is used because there are 18 characters between the first 
  166. Xletter ("i") and last ("n") of "internationalization".)
  167. X
  168. XAll of the messages, warnings, information, and commands, are contained in the 
  169. Xmessage catalog.  Each numbered entry represents an individual string used by 
  170. Xee.  Some strings contain formatting information for formatted print 
  171. Xstatements, which are of the form "%s", or "%d", these must be preserved in 
  172. Xthe translation, or the correct information will not be displayed.  For those 
  173. Xstrings containing multiple formatting codes, the order of each item must be 
  174. Xpreserved as well.
  175. X
  176. XMessage        content 
  177. X1         title for modes, or settings menu
  178. X2 - 8        entries for modes menu, each line should be the same length 
  179. X         (padded with spaces)
  180. X9 - 34        other menu titles and entries
  181. X35 - 56     help screen 
  182. X57 - 61     actions assigned to control keys 
  183. X62 - 66     commands information 
  184. X67         message displayed when info window turned off
  185. X68         indication that no file name was entered when invoking ee
  186. X69        prompt for decimal value of character to be entered
  187. X70        message displaying the print command being invoked
  188. X71         prompt for command 
  189. X72        prompt for name of file to be written 
  190. X73        prompt for name of file to be read 
  191. X74        string used to display the decimal value of the character 
  192. X         the cursor is on 
  193. X75        string displaying an unrecognized command 
  194. X76         string indicating that the command entered is not a unique 
  195. X         substring of a valid command
  196. X77        string indicating the current line number 
  197. X78        string for displaying the length of the line 
  198. X79        string for displaying the name of the file 
  199. X80 - 83        strings showing how to invoke ee, and its options
  200. X84        message indicating that the file entered is a directory, not a 
  201. X         text file
  202. X85        message informing that the entered file does not yet exist 
  203. X86        message informing that the file can't be opened (because of 
  204. X         permission problems)
  205. X87        message after file has been read with the file name and number 
  206. X         of lines read
  207. X88        message indicating that the file has been read
  208. X89        message indicating that the file is being read
  209. X90        message indicating that permissions only allow the file to be 
  210. X         read, not written
  211. X91        message after file has been read with the file name and number 
  212. X         of lines read
  213. X92        prompt for name of file to be saved (used when no name was 
  214. X         entered for a file to edit)
  215. X93        message indicating that the file was not written, since no 
  216. X         name was entered at the prompt
  217. X94        prompt asking user if changes should not be saved ("yes_char" 
  218. X         will be expected for affirmative response)
  219. X95        "yes" character, single character expected to confirm action 
  220. X         (can be upper or lower case, will be converted to upper-case 
  221. X         during test)
  222. X96        prompt
  223. X97        error message
  224. X98        message indicating that the named file is being written
  225. X99        message indicating the name of the file written, the number of 
  226. X         lines, and the number of characters (order of items must be 
  227. X         maintained)
  228. X100        search in progress message
  229. X101        message that the string was not found
  230. X102        prompt for search
  231. X103        message that string could not be executed
  232. X104        self-explanatory
  233. X105        message for menus, indicating that the Escape character will 
  234. X         allow the user to exit the menu
  235. X106        error message indicating the menu won't fit on the screen
  236. X107        self-explanatory
  237. X108        prompt for shell command
  238. X109        message displayed while formatting a paragraph
  239. X110        string which places message for spell checking at top of 
  240. X         buffer (the portions 'list of unrecognized words' and 
  241. X         '-=-=-=-=-=-' may be replaced, but the rest must remain the 
  242. X         same)
  243. X111        message informing that spell checking is in progress
  244. X112        prompt for right margin
  245. X113        error informing user that operation is not permitted in ree
  246. X114        string indicating mode is turned 'on' in modes menu
  247. X115        string indicating mode is turned 'off' in modes menu
  248. X116 - 131    strings used for commands (some also used for initialization)
  249. X132 - 144    strings used for initialization
  250. X
  251. XCare should be taken when translating commands and initialization keywords 
  252. Xbecause the algorithm used for detecting uniqueness of entered commands 
  253. Xwill not be able to distinguish words that are not unique before the end 
  254. Xof the shorter word, for example, it would not be able to distinguish the 
  255. Xcommand 'abcd' from 'abcde'.
  256. X
  257. XAfter translating the messages, use the 'gencat' command to create the compiled 
  258. Xcatalog used when running the software.  The standard syntax would be:
  259. X
  260. X    gencat ee.cat ee.msg
  261. X
  262. XWhere ee.msg is the file containing the translations, and ee.cat is the 
  263. Xcompiled catalog.  If the file ee.cat does not exist, it will be created.  
  264. XCheck the documentation for your system for proper syntax.  
  265. X
  266. XMessage catalog placement varies from system to system.  A common location 
  267. Xfor message catalogs is in /usr/lib/nls.  In this directory are 
  268. Xdirectories with the names of other languages.  The default language is 
  269. X'C'.  There is also an environment variable, named NLSPATH used to 
  270. Xdetermine where message catalogs can be found.  This variable is similar 
  271. Xto the PATH variable used for commands, but with some differences.  The 
  272. XNLSPATH variable must have the ability to handle different names for 
  273. Xlanguages and the catalog files, so it has field descriptors for these.  A 
  274. Xtypical setting for NLSPATH could be:
  275. X
  276. X    NLSPATH=/usr/lib/nls/%L/%N.cat:/usr/local/lib/nls/%L/%N.cat
  277. X
  278. XWhere "%L" is the field descriptor for the language (obtained from the 
  279. XLANG environment variable) and "%N" is the name of the file (with the 
  280. X".cat" appended by the path variable, it is not passed from the requesting 
  281. Xprogram).  The colon (:) is used to separate paths, so in the above 
  282. Xexample there are two paths possible for message catalogs.  You may wish 
  283. Xto maintain catalogs for applications that are not supported by your 
  284. Xsystem vendor in a location unique for you, and this is facilitated by the 
  285. XNLSPATH variable.  Remember to set and export both the LANG and NLSPATH 
  286. Xvariables for each user that expects to use localization either in a 
  287. Xsystem-wide profile or in each user's profile.  See your system 
  288. Xdocumentation for more information.
  289. X
  290. XThe message catalog supplied with ee also uses the '$quote' directive to 
  291. Xspecify a quote around strings to ensure proper padding.  This directive 
  292. Xmay not be supported on all systems, and lead to quotes being included in 
  293. Xthe string used in ee, which will cause incorrect behavior.  If the 
  294. X'$quote' directive is not supported by your system's gencat command, edit 
  295. Xthe msg file to remove the leading and trailing quotation marks.
  296. END_OF_FILE
  297.   if test 6826 -ne `wc -c <'ee.i18n.guide'`; then
  298.     echo shar: \"'ee.i18n.guide'\" unpacked with wrong size!
  299.   fi
  300.   # end of 'ee.i18n.guide'
  301. fi
  302. if test -f 'new_curse.c.B' -a "${1}" != "-c" ; then 
  303.   echo shar: Will not clobber existing file \"'new_curse.c.B'\"
  304. else
  305.   echo shar: Extracting \"'new_curse.c.B'\" \(37082 characters\)
  306.   sed "s/^X//" >'new_curse.c.B' <<'END_OF_FILE'
  307. Xatoi(string)        /* convert ascii text to integers    */
  308. Xchar *string;
  309. X{
  310. X    int Temp;
  311. X    char *astring;
  312. X
  313. X    astring = string;
  314. X    Temp = 0;
  315. X    while ((*astring >= '0') && (*astring <= '9'))
  316. X    {
  317. X        Temp = (Temp * 10) + (*astring - '0');
  318. X        astring++;
  319. X    }
  320. X    return(Temp);
  321. X}
  322. X
  323. Xwmove(window, row, column)    /* move cursor to indicated position in window */
  324. XWINDOW *window;
  325. Xint row, column;
  326. X{
  327. X    if ((row < window->Num_lines) && (column < window->Num_cols))
  328. X    {
  329. X        window->LX = column;
  330. X        window->LY = row;
  331. X    }
  332. X}
  333. X
  334. Xclear_line(line, column, cols)
  335. Xstruct _line *line;
  336. Xint column;
  337. X{
  338. X    int j;
  339. X
  340. X    if (column > line->last_char)
  341. X        line->row[line->last_char] = ' ';
  342. X    line->last_char = column;
  343. X    line->row[column] = NULL;
  344. X    line->attributes[column] = NULL;
  345. X    line->changed = TRUE;
  346. X/*    if (column == 0)
  347. X        line->scroll = FALSE;*/
  348. X    for (j = column + 1; j < cols; j++)
  349. X    {
  350. X        line->row[j] = ' ';
  351. X        line->attributes[j] = NULL;
  352. X    }
  353. X}
  354. X
  355. Xwerase(window)            /* clear the specified window        */
  356. XWINDOW *window;
  357. X{
  358. X    int i;
  359. X    struct _line *tmp;
  360. X
  361. X    window->SCROLL_CLEAR = CLEAR;
  362. X    window->scroll_up = window->scroll_down = 0;
  363. X    for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
  364. X        clear_line(tmp, 0, window->Num_cols);
  365. X}
  366. X
  367. Xwclrtoeol(window)    /* erase from current cursor position to end of line */
  368. XWINDOW *window;
  369. X{
  370. X    int column, row;
  371. X    struct _line *tmp;
  372. X
  373. X    window->SCROLL_CLEAR = CHANGE;
  374. X    column = window->LX;
  375. X    row = window->LY;
  376. X    for (row = 0, tmp = window->first_line; row < window->LY; row++)
  377. X        tmp = tmp->next_screen;
  378. X    clear_line(tmp, column, window->Num_cols);
  379. X}
  380. X
  381. Xwrefresh(window)        /* flush all previous output        */
  382. XWINDOW *window;
  383. X{
  384. X    int old_arg, value;
  385. X/*#ifndef SYS5
  386. X    old_arg = fcntl(0, F_GETFL, 0);
  387. X    value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);
  388. X#endif   to be uncommented if setting to nodelay on input only is unsuitable */
  389. X    wnoutrefresh(window);
  390. X#ifdef DIAG
  391. X{
  392. X    struct _line *temp;
  393. X    fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
  394. X    for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
  395. X    {
  396. X        if (temp->number == -1)
  397. X            fprintf(stderr, "line moved ");
  398. X        if (temp->scroll)
  399. X            fprintf(stderr, "scroll_x is set:  ");
  400. X        fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
  401. X    }
  402. X    fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
  403. X    fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
  404. X    for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
  405. X    {
  406. X        if (temp->number == -1)
  407. X            fprintf(stderr, "line moved ");
  408. X        if (temp->scroll)
  409. X            fprintf(stderr, "scroll_x is set:  ");
  410. X        fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
  411. X    }
  412. X    fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
  413. X    for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
  414. X        fprintf(stderr, "line=%s|\n", temp->row);
  415. X}
  416. X#endif
  417. X    doupdate();
  418. X    virtual_scr->SCROLL_CLEAR = FALSE;
  419. X    virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
  420. X    fflush(stdout);
  421. X/*#ifndef SYS5
  422. X    value = fcntl(0, F_SETFL, old_arg | FNDELAY);
  423. X#endif*/
  424. X}
  425. X
  426. Xtouchwin(window)
  427. XWINDOW *window;
  428. X{
  429. X    struct _line *user_line;
  430. X    int line_counter = 0;
  431. X
  432. X    for (line_counter = 0, user_line = window->first_line; 
  433. X        line_counter < window->Num_lines; line_counter++)
  434. X    {
  435. X        user_line->changed = TRUE;
  436. X    }
  437. X    window->SCROLL_CLEAR = TRUE;
  438. X}
  439. X
  440. Xwnoutrefresh(window)
  441. XWINDOW *window;
  442. X{
  443. X    struct _line *user_line;
  444. X    struct _line *virtual_line;
  445. X    int line_counter = 0;
  446. X    int user_col = 0;
  447. X    int virt_col = 0;
  448. X
  449. X    user_line = window->first_line;
  450. X    virtual_line = virtual_scr->first_line;
  451. X    virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
  452. X    virtual_scr->LX = window->LX + window->SC;
  453. X    virtual_scr->LY = window->LY + window->SR;
  454. X    virtual_scr->scroll_up = window->scroll_up;
  455. X    virtual_scr->scroll_down = window->scroll_down;
  456. X    if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
  457. X        return;
  458. X    for (line_counter = 0; line_counter < window->SR; line_counter++)
  459. X    {
  460. X        virtual_line = virtual_line->next_screen;
  461. X    }
  462. X    for (line_counter = 0; line_counter < window->Num_lines; line_counter++)
  463. X    {
  464. X        if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
  465. X        {
  466. X            for (user_col = 0, virt_col = window->SC; user_col < window->Num_cols; virt_col++, user_col++)
  467. X            {
  468. X                virtual_line->row[virt_col] = user_line->row[user_col];
  469. X                virtual_line->attributes[virt_col] = user_line->attributes[user_col];
  470. X            }
  471. X        }
  472. X        if (virtual_scr->Num_cols != window->Num_cols)
  473. X        {
  474. X            if (virtual_line->last_char < (user_line->last_char + window->SC))
  475. X            {
  476. X                if (virtual_line->row[virtual_line->last_char] == NULL)
  477. X                    virtual_line->row[virtual_line->last_char] = ' ';
  478. X                virtual_line->last_char = user_line->last_char + window->SC;
  479. X            }
  480. X            else if (virtual_line->last_char > (user_line->last_char + window->SC))
  481. X            {
  482. X                virtual_line->row[window->SC + user_line->last_char] = ' ';
  483. X            }
  484. X        }
  485. X        else
  486. X            virtual_line->last_char = user_line->last_char;
  487. X        virtual_line->row[virtual_line->last_char] = NULL;
  488. X        virtual_line->changed = user_line->changed;
  489. X        virtual_line = virtual_line->next_screen;
  490. X        user_line = user_line->next_screen;
  491. X    }
  492. X    window->SCROLL_CLEAR = FALSE;
  493. X    window->scroll_up = window->scroll_down = 0;
  494. X    last_window_refreshed = window;
  495. X}
  496. X
  497. Xflushinp()            /* flush input                */
  498. X{
  499. X    int value;
  500. X/*
  501. X#ifdef SYS5
  502. X    value = ioctl(0, TCFLSH, 0);
  503. X#else
  504. X    value = ioctl(0, TIOCFLUSH, 0);
  505. X#endif
  506. X*/
  507. X}
  508. X
  509. Xungetch(c)            /* push a character back on input    */
  510. Xint c;
  511. X{
  512. X    if (bufp < 100)
  513. X        in_buff[bufp++] = c;
  514. X}
  515. X
  516. Xint 
  517. Xwgetch(window)            /* get character from specified window    */
  518. XWINDOW *window;
  519. X{
  520. X    int old_arg;
  521. X    int in_value;
  522. X
  523. X#ifndef SYS5
  524. X    if (!Nowait)
  525. X    {
  526. X        Time_Out = FALSE;
  527. X        Nowait = TRUE;
  528. X        old_arg = fcntl(0, F_GETFL, 0);
  529. X        value = fcntl(0, F_SETFL, old_arg | FNDELAY);
  530. X    }
  531. X#endif
  532. X    in_value = ((bufp > 0) ? in_buff[--bufp] : getchar());
  533. X    if (in_value != -1) 
  534. X    {
  535. X        in_value &= 0xff;
  536. X        if ((Parity) && (Num_bits < 8))    /* strip eighth bit if parity in use */
  537. X        in_value &= 0177;
  538. X    }
  539. X    if ((in_value == '\033') || (in_value == '\037'))        /* escape character        */
  540. X        in_value = Get_key(in_value);
  541. X#ifndef SYS5
  542. X    if (!Time_Out)
  543. X    {
  544. X        Nowait = FALSE;
  545. X        value = fcntl(0, F_SETFL, old_arg);
  546. X    }
  547. X#endif
  548. X    return(in_value);
  549. X}
  550. X
  551. XClear()        /* notify that time out has occurred    */
  552. X{
  553. X    Time_Out = TRUE;
  554. X}
  555. X
  556. Xint 
  557. XGet_key(first_char)            /* try to decode key sequence        */
  558. Xint first_char;                /* first character of sequence        */
  559. X{
  560. X    int in_char;
  561. X    int Count;
  562. X    char string[128];
  563. X    char *Gtemp;
  564. X    int value;
  565. X    int Found;
  566. X    int old_arg;
  567. X#ifdef SYS5
  568. X    struct termio Gterminal;
  569. X#else
  570. X    struct sgttyb Gterminal;
  571. X#endif
  572. X    struct KEY_STACK *St_point;
  573. X
  574. X    Count = 0;
  575. X    Gtemp = string;
  576. X    string[Count++] = first_char;
  577. X    string[Count] = NULL;
  578. X    Time_Out = FALSE;
  579. X    signal(SIGALRM, Clear);
  580. X    value = alarm(1);
  581. X#ifdef SYS5
  582. X/*    value = ioctl(0, TCGETA, &Gterminal);
  583. X    Gterminal.c_cc[VMIN] = 0;    /* minimum of zero characters    */
  584. X    Gterminal.c_cc[VTIME] = 0;        /* timeout value    */
  585. X    Gterminal.c_lflag &= ~ICANON;    /* disable canonical operation    */
  586. X    Gterminal.c_lflag &= ~ECHO;        /* disable echo        */
  587. X/*    value = ioctl(0, TCSETA, &Gterminal);    /* set characteristics    */
  588. X#else
  589. X/*    value = ioctl(0, TIOCGETP, &Gterminal);
  590. X    Gterminal.sg_flags |= RAW ;
  591. X    Gterminal.sg_flags &= ~ECHO;
  592. X    value = ioctl(0, TIOCSETP, &Gterminal);    /* set characteristics    */
  593. X/*    old_arg = fcntl(0, F_GETFL, 0);
  594. X    value = fcntl(0, F_SETFL, old_arg | FNDELAY);*/
  595. X#endif
  596. X    Count = 1;
  597. X    Found = FALSE;
  598. X    while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
  599. X    {
  600. X        in_char = wgetch(stdscr);
  601. X        if (in_char != -1)
  602. X        {
  603. X            string[Count++] = in_char;
  604. X            string[Count] = NULL;
  605. X            St_point = KEY_TOS;
  606. X            while ((St_point != NULL) && (!Found))
  607. X            {
  608. X                if (!strcmp(string, St_point->element->string))
  609. X                    Found = TRUE;
  610. X                else
  611. X                    St_point = St_point->next;
  612. X            }
  613. X        }
  614. X    }
  615. X    if (!Time_Out)
  616. X        value = alarm(0);
  617. X#ifdef SYS5
  618. X/*    value = ioctl(0, TCSETA, &Terminal);*/
  619. X#else
  620. X    value = ioctl(0, TIOCSETP, &Terminal);
  621. X/*    value = fcntl(0, F_SETFL, old_arg);*/
  622. X#endif
  623. X    if (Found)
  624. X    {
  625. X        return(St_point->element->value);
  626. X    }
  627. X    else
  628. X    {
  629. X        while (Count > 1)
  630. X        {
  631. X            if ((string[--Count] != -1) && (string[Count] != 255))
  632. X            {
  633. X#ifdef DIAG
  634. Xfprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
  635. X#endif
  636. X                ungetch(string[Count]);
  637. X            }
  638. X        }
  639. X        return(first_char);
  640. X    }
  641. X}
  642. X
  643. Xwaddch(window, c)    /* output the character in the specified window    */
  644. XWINDOW *window;
  645. Xint c;
  646. X{
  647. X    int i, j;
  648. X    int row, column;
  649. X    int shift;    /* number of spaces to shift if a tab        */
  650. X    struct _line *tmpline;
  651. X
  652. X#ifdef DIAG
  653. X/*printf("starting waddch \n");fflush(stdout);*/
  654. X#endif
  655. X    row = window->LY;
  656. X    column = window->LX;
  657. X    if (c == '\t')
  658. X    {
  659. X        shift = (column + 1) % 8;
  660. X        if (shift == 0)
  661. X            shift++;
  662. X        else
  663. X            shift = 9 - shift;
  664. X        while (shift > 0)
  665. X        {
  666. X            shift--;
  667. X            waddch(window, ' ');
  668. X        }
  669. X    }
  670. X    else if ((column < window->Num_cols) && (row < window->Num_lines))
  671. X    {
  672. X        if ((c == '~') && (Booleans[hz__]))
  673. X            c = '@';
  674. X
  675. X        if (( c != '\b') && (c != '\n') && (c != '\r'))
  676. X        {
  677. X            row = 0;
  678. X            tmpline = window->first_line; 
  679. X            while (row < window->LY)
  680. X            {
  681. X                row++;
  682. X                tmpline = tmpline->next_screen;
  683. X            }
  684. X            tmpline->row[column] = c;
  685. X            tmpline->attributes[column] = window->Attrib;
  686. X            tmpline->changed = TRUE;
  687. X            if (column >= tmpline->last_char)
  688. X            {
  689. X                if (column > tmpline->last_char)
  690. X                    tmpline->row[tmpline->last_char] = ' ';
  691. X                tmpline->row[column + 1] = NULL;
  692. X                tmpline->attributes[column + 1] = NULL;
  693. X                tmpline->last_char = column + 1;
  694. X            }
  695. X        }
  696. X        if (c == '\n')
  697. X        {
  698. X            wclrtoeol(window);
  699. X            window->LX = window->Num_cols;
  700. X        }
  701. X        else if (c == '\r')
  702. X            window->LX = 0;
  703. X        else if (c == '\b')
  704. X            window->LX--;
  705. X        else
  706. X            window->LX++;
  707. X    }
  708. X    if (window->LX >= window->Num_cols)
  709. X    {
  710. X        window->LX = 0;
  711. X        window->LY++;
  712. X        if (window->LY >= window->Num_lines)
  713. X        {
  714. X            window->LY = window->Num_lines - 1;
  715. X/*            window->LY = row;
  716. X            wmove(window, 0, 0);
  717. X            wdeleteln(window);
  718. X            wmove(window, row, 0);*/
  719. X        }
  720. X    }
  721. X    window->SCROLL_CLEAR = CHANGE;
  722. X}
  723. X
  724. Xwinsertln(window)    /* insert a blank line into the specified window */
  725. XWINDOW *window;
  726. X{
  727. X    int row, column;
  728. X    struct _line *tmp;
  729. X    struct _line *tmp1;
  730. X
  731. X    window->scroll_down += 1;
  732. X    window->SCROLL_CLEAR = SCROLL;
  733. X    column = window->LX;
  734. X    row = window->LY;
  735. X    for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
  736. X        tmp = tmp->next_screen;
  737. X    if (tmp->prev_screen != NULL)
  738. X        tmp->prev_screen->next_screen = NULL;
  739. X    tmp1 = tmp;
  740. X    clear_line(tmp1, 0, window->Num_cols);
  741. X    tmp1->number = -1;
  742. X    for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
  743. X        tmp = tmp->next_screen;
  744. X    if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
  745. X    {
  746. X        tmp1->next_screen = tmp->next_screen;
  747. X        tmp->next_screen = tmp1;
  748. X        tmp->changed = TRUE;
  749. X        tmp->next_screen->prev_screen = tmp;
  750. X    }
  751. X    else if (window->Num_lines > 1)
  752. X    {
  753. X        if (tmp->prev_screen != NULL)
  754. X            tmp->prev_screen->next_screen = tmp1;
  755. X        tmp1->prev_screen = tmp->prev_screen;
  756. X        tmp->prev_screen = tmp1;
  757. X        tmp1->next_screen = tmp;
  758. X        tmp->changed = TRUE;
  759. X        tmp->scroll = DOWN;
  760. X    }
  761. X    if (window->LY == 0)
  762. X        window->first_line = tmp1;
  763. X}
  764. X
  765. Xwdeleteln(window)    /* delete a line in the specified window */
  766. XWINDOW *window;
  767. X{
  768. X    int row, column;
  769. X    struct _line *tmp;
  770. X    struct _line  *tmpline;
  771. X
  772. X    if (window->Num_lines > 1)
  773. X    {
  774. X        window->scroll_up += 1;
  775. X        window->SCROLL_CLEAR = SCROLL;
  776. X        column = window->LX;
  777. X        row = window->LY;
  778. X        for (row = 0, tmp = window->first_line; row < window->LY; row++)
  779. X            tmp = tmp->next_screen;
  780. X        if (window->LY == 0)
  781. X            window->first_line = tmp->next_screen;
  782. X        if (tmp->prev_screen != NULL)
  783. X            tmp->prev_screen->next_screen = tmp->next_screen;
  784. X        if (tmp->next_screen != NULL)
  785. X        {
  786. X            tmp->next_screen->changed = TRUE;
  787. X            tmp->next_screen->scroll = UP;
  788. X            tmp->next_screen->prev_screen = tmp->prev_screen;
  789. X        }
  790. X        tmpline = tmp;
  791. X        clear_line(tmpline, 0, window->Num_cols);
  792. X        tmpline->number = -1;
  793. X        for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
  794. X            tmp = tmp->next_screen;
  795. X        if (tmp != NULL)
  796. X        {
  797. X            tmp->next_screen = tmpline;
  798. X            tmp->next_screen->prev_screen = tmp;
  799. X            tmp->changed = TRUE;
  800. X            tmp = tmp->next_screen;
  801. X        }
  802. X        else
  803. X            tmp = tmpline;
  804. X        tmp->next_screen = NULL;
  805. X    }
  806. X    else
  807. X    {
  808. X        clear_line(window->first_line, 0, window->Num_cols);
  809. X    }
  810. X}
  811. X
  812. Xwclrtobot(window)    /* delete from current position to end of the window */
  813. XWINDOW *window;
  814. X{
  815. X    int row, column;
  816. X    int Trow;
  817. X    struct _line *tmp;
  818. X
  819. X    window->SCROLL_CLEAR |= CLEAR;
  820. X    column = window->LX;
  821. X    row = window->LY;
  822. X    for (row = 0, tmp = window->first_line; row < window->LY; row++)
  823. X        tmp = tmp->next_screen;
  824. X    clear_line(tmp, column, window->Num_cols);
  825. X    for (row = (window->LY + 1); row < window->Num_lines; row++)
  826. X    {
  827. X        tmp = tmp->next_screen;
  828. X        clear_line(tmp, 0, window->Num_cols);
  829. X    }
  830. X    wmove(window, row, column);
  831. X}
  832. X
  833. Xwstandout(window)    /* begin standout mode in window    */
  834. XWINDOW *window;
  835. X{
  836. X    if (Numbers[sg__] < 1)    /* if not magic cookie glitch    */
  837. X        window->Attrib |= A_STANDOUT;
  838. X}
  839. X
  840. Xwstandend(window)    /* end standout mode in window    */
  841. XWINDOW *window;
  842. X{
  843. X    window->Attrib &= ~A_STANDOUT;
  844. X}
  845. X
  846. Xwaddstr(window, string)    /* write 'string' in window    */
  847. XWINDOW *window;
  848. Xchar *string;
  849. X{
  850. X    char *wstring;
  851. X
  852. X    for (wstring = string; *wstring != NULL; wstring++)
  853. X        waddch(window, *wstring);
  854. X}
  855. X
  856. Xclearok(window, flag)    /* erase screen and redraw at next refresh    */
  857. XWINDOW *window;
  858. Xint flag;
  859. X{
  860. X    Repaint_screen = TRUE;
  861. X}
  862. X
  863. Xecho()            /* turn on echoing                */
  864. X{
  865. X    int value;
  866. X
  867. X#ifdef SYS5
  868. X    Terminal.c_lflag |= ECHO;        /* enable echo        */
  869. X    value = ioctl(0, TCSETA, &Terminal);    /* set characteristics    */
  870. X#else
  871. X    Terminal.sg_flags |= ECHO;        /* enable echo        */
  872. X    value = ioctl(0, TIOCSETP, &Terminal);    /* set characteristics    */
  873. X#endif
  874. X}
  875. X
  876. Xnoecho()        /* turn off echoing                */
  877. X{
  878. X    int value;
  879. X
  880. X#ifdef SYS5
  881. X    Terminal.c_lflag &= ~ECHO;        /* disable echo        */
  882. X    value = ioctl(0, TCSETA, &Terminal);    /* set characteristics    */
  883. X#else
  884. X    Terminal.sg_flags &= ~ECHO;        /* disable echo        */
  885. X    value = ioctl(0, TIOCSETP, &Terminal);    /* set characteristics    */
  886. X#endif
  887. X}
  888. X
  889. Xraw()            /* set to read characters immediately        */
  890. X{
  891. X    int value;
  892. X    int old_arg;
  893. X
  894. X#ifdef SYS5
  895. X    Intr = Terminal.c_cc[VINTR];    /* get the interrupt character    */
  896. X    Terminal.c_lflag &= ~ICANON;    /* disable canonical operation    */
  897. X    Terminal.c_lflag &= ~ISIG;    /* disable signal checking    */
  898. X#ifdef SUN
  899. X    Terminal.c_lflag &= ~FLUSHO;
  900. X    Terminal.c_lflag &= ~PENDIN;
  901. X    Terminal.c_lflag &= ~IEXTEN;
  902. X#endif
  903. X    Terminal.c_cc[VMIN] = 1;        /* minimum of one character */
  904. X    Terminal.c_cc[VTIME] = 255;        /* timeout value    */
  905. X    Terminal.c_cc[VINTR] = 0;        /* eliminate interrupt    */
  906. X    value = ioctl(0, TCSETA, &Terminal);    /* set characteristics    */
  907. X#else
  908. X    Terminal.sg_flags |= RAW;    /* enable raw mode        */
  909. X    value = ioctl(0, TIOCSETP, &Terminal);    /* set characteristics    */
  910. X/*    old_arg = fcntl(0, F_GETFL, 0);
  911. X    value = fcntl(0, F_SETFL, old_arg | FNDELAY);*/
  912. X#endif
  913. X}
  914. X
  915. Xnoraw()            /* set to normal character read mode        */
  916. X{
  917. X    int value;
  918. X    int old_arg;
  919. X
  920. X#ifdef SYS5
  921. X    Terminal.c_lflag |= ICANON;    /* enable canonical operation    */
  922. X    Terminal.c_lflag |= ISIG;    /* enable signal checking    */
  923. X    Terminal.c_cc[VEOF] = 4;        /* EOF character = 4    */
  924. X    Terminal.c_cc[VEOL] = NULL;        /* EOL = 0        */
  925. X    Terminal.c_cc[VINTR] = Intr;        /* reset interrupt char    */
  926. X    value = ioctl(0, TCSETA, &Terminal);    /* set characteristics    */
  927. X#else
  928. X    Terminal.sg_flags &= ~RAW;    /* disable raw mode        */
  929. X    value = ioctl(0, TIOCSETP, &Terminal);    /* set characteristics    */
  930. X/*    old_arg = fcntl(0, F_GETFL, 0);
  931. X    value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
  932. X#endif
  933. X}
  934. X
  935. Xnl()
  936. X{
  937. X    int value;
  938. X
  939. X#ifdef SYS5
  940. X    Terminal.c_iflag |= ICRNL;    /* enable carriage-return to line-feed mapping    */
  941. X    value = ioctl(0, TCSETA, &Terminal);    /* set characteristics    */
  942. X#endif
  943. X}
  944. X
  945. Xnonl()
  946. X{
  947. X    int value;
  948. X
  949. X#ifdef SYS5
  950. X    Terminal.c_iflag &= ~ICRNL;    /* disable carriage-return to line-feed mapping    */
  951. X    Terminal.c_iflag &= ~IGNCR;    /* do not ignore carriage-return    */
  952. X    value = ioctl(0, TCSETA, &Terminal);    /* set characteristics    */
  953. X#endif
  954. X}
  955. X
  956. Xsaveterm()
  957. X{
  958. X}
  959. X
  960. Xfixterm()
  961. X{
  962. X}
  963. X
  964. Xresetterm()
  965. X{
  966. X}
  967. X
  968. Xnodelay(window, flag)
  969. XWINDOW *window;
  970. Xint flag;
  971. X{
  972. X}
  973. X
  974. Xidlok(window, flag)
  975. XWINDOW *window;
  976. Xint flag;
  977. X{
  978. X}
  979. X
  980. Xkeypad(window, flag)
  981. XWINDOW *window;
  982. Xint flag;
  983. X{
  984. X    if (flag)
  985. X        String_Out(String_table[ks__], NULL, 0);
  986. X    else
  987. X        String_Out(String_table[ke__], NULL, 0);
  988. X}
  989. X
  990. Xsavetty()        /* save current tty stats            */
  991. X{
  992. X    int value;
  993. X
  994. X#ifdef SYS5
  995. X    value = ioctl(0, TCGETA, &Saved_tty);    /* set characteristics    */
  996. X#else
  997. X    value = ioctl(0, TIOCGETP, &Saved_tty);    /* set characteristics    */
  998. X#endif
  999. X}
  1000. X
  1001. Xresetty()        /* restore previous tty stats            */
  1002. X{
  1003. X    int value;
  1004. X
  1005. X#ifdef SYS5
  1006. X    value = ioctl(0, TCSETA, &Saved_tty);    /* set characteristics    */
  1007. X#else
  1008. X    value = ioctl(0, TIOCSETP, &Saved_tty);    /* set characteristics    */
  1009. X#endif
  1010. X}
  1011. X
  1012. Xendwin()        /* end windows                    */
  1013. X{
  1014. X    keypad(stdscr, FALSE);
  1015. X    free(stdscr);
  1016. X    initialized = FALSE;
  1017. X    delwin(curscr);
  1018. X    delwin(virtual_scr);
  1019. X    delwin(stdscr);
  1020. X#ifndef SYS5
  1021. X{
  1022. X    int old_arg, value;
  1023. X/*    old_arg = fcntl(0, F_GETFL, 0);
  1024. X    value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
  1025. X}
  1026. X#endif
  1027. X}
  1028. X
  1029. Xdelwin(window)        /* delete the window structure            */
  1030. XWINDOW *window;
  1031. X{
  1032. X    int i;
  1033. X
  1034. X    for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
  1035. X    {
  1036. X        window->first_line = window->first_line->next_screen;
  1037. X        free(window->first_line->prev_screen->row);
  1038. X        free(window->first_line->prev_screen->attributes);
  1039. X        free(window->first_line->prev_screen);
  1040. X    }
  1041. X    if (window == last_window_refreshed)
  1042. X        last_window_refreshed = 0;
  1043. X    if (window->first_line != NULL)
  1044. X    {
  1045. X        free(window->first_line->row);
  1046. X        free(window->first_line->attributes);
  1047. X        free(window->first_line);
  1048. X        free(window);
  1049. X    }
  1050. X}
  1051. X
  1052. Xwprintw(va_alist)
  1053. Xva_dcl
  1054. X{
  1055. X    WINDOW *window;
  1056. X    va_list ap;
  1057. X    char *format;
  1058. X    int value;
  1059. X    char *fpoint;
  1060. X    char *wtemp;
  1061. X
  1062. X    va_start(ap);
  1063. X    window = va_arg(ap, WINDOW *);
  1064. X    format = va_arg(ap, char *);
  1065. X    fpoint = format;
  1066. X    while (*fpoint != NULL)
  1067. X    {
  1068. X        if (*fpoint == '%')
  1069. X        {
  1070. X            fpoint++;
  1071. X            if (*fpoint == 'd')
  1072. X            {
  1073. X                value = va_arg(ap, int);
  1074. X                iout(window, value);
  1075. X            }
  1076. X            else if (*fpoint == 'c')
  1077. X            {
  1078. X                value = va_arg(ap, int);
  1079. X                waddch(window, value);
  1080. X            }
  1081. X            else if (*fpoint == 's')
  1082. X            {
  1083. X                wtemp = va_arg(ap, char *);
  1084. X                    waddstr(window, wtemp);
  1085. X            }
  1086. X            fpoint++;
  1087. X        }
  1088. X        else if (*fpoint == '\\')
  1089. X        {
  1090. X            fpoint++;
  1091. X            if (*fpoint == 'n')
  1092. X                waddch(window, '\n');
  1093. X            else if ((*fpoint >= '0') && (*fpoint <= '9'))
  1094. X            {
  1095. X                value = 0;
  1096. X                while ((*fpoint >= '0') && (*fpoint <= '9'))
  1097. X                {
  1098. X                    value = (value * 8) + (*fpoint - '0');
  1099. X                    fpoint++;
  1100. X                }
  1101. X                waddch(window, value);
  1102. X            }
  1103. X            fpoint++;
  1104. X        }
  1105. X        else
  1106. X            waddch(window, *fpoint++);
  1107. X    }
  1108. X}
  1109. X
  1110. Xiout(window, value)    /* output characters        */
  1111. XWINDOW *window;
  1112. Xint value;
  1113. X{
  1114. X    int i;
  1115. X
  1116. X    if ((i = value / 10) != 0)
  1117. X        iout(window, i);
  1118. X    waddch(window, ((value % 10) + '0'));
  1119. X}
  1120. X
  1121. XComp_line(line1, line2)        /* compare lines    */
  1122. Xstruct _line *line1;
  1123. Xstruct _line *line2;
  1124. X{
  1125. X    int count1, count2;
  1126. X    int i;
  1127. X    char *att1, *att2;
  1128. X    char *c1, *c2;
  1129. X
  1130. X    c1 = line1->row;
  1131. X    c2 = line2->row;
  1132. X    att1 = line1->attributes;
  1133. X    att2 = line2->attributes;
  1134. X    count2 = strlen(c1) + 1;
  1135. X    count1 = strlen(c2) + 1;
  1136. X    if (count1 > count2)
  1137. X    {
  1138. X        i = count2;
  1139. X        count2 = count1;
  1140. X        count1 = i;
  1141. X    }
  1142. X    if (count2 > (count1 + count1))
  1143. X        return(2);
  1144. X    i = 0;
  1145. X    while ((c1[i] != NULL) && (c2[i] != NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
  1146. X        i++;
  1147. X    count1 = i + 1;
  1148. X    if ((count1 == 1) && (count2 == 1))
  1149. X        count1 = 0;            /* both lines blank    */
  1150. X    else if (count2 == count1)
  1151. X        count1 = -1;            /* equal        */
  1152. X    else
  1153. X        count1 = count2 / count1;    /* lines unequal    */
  1154. X    return(count1);
  1155. X}
  1156. X
  1157. Xstruct _line *
  1158. XInsert_line(row, window)    /* insert line into screen */
  1159. Xint row;
  1160. XWINDOW *window;
  1161. X{
  1162. X    int i;
  1163. X    struct _line *tmp;
  1164. X    struct _line *tmp1;
  1165. X
  1166. X    for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
  1167. X        tmp = tmp->next_screen;
  1168. X    top_of_win = tmp;
  1169. X    /*
  1170. X     |    find bottom line to delete
  1171. X     */
  1172. X    for (i = 1, tmp = top_of_win; (tmp->next_screen != NULL) && (i < window->Num_lines); i++)
  1173. X        tmp = tmp->next_screen;
  1174. X    if (tmp->prev_screen != NULL)
  1175. X        tmp->prev_screen->next_screen = tmp->next_screen;
  1176. X    if (tmp->next_screen != NULL)
  1177. X        tmp->next_screen->prev_screen = tmp->prev_screen;
  1178. X    /*
  1179. X     |    clear deleted line
  1180. X     */
  1181. X    tmp1 = tmp;
  1182. X    clear_line(tmp, 0, window->Num_cols);
  1183. X    tmp1->number = -1;
  1184. X    for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
  1185. X        tmp = tmp->next_screen;
  1186. X    top_of_win = tmp;
  1187. X    for (i = 0, tmp = top_of_win; i < row; i++)
  1188. X        tmp = tmp->next_screen;
  1189. X    if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
  1190. X        tmp->prev_screen->next_screen = tmp1;
  1191. X    tmp1->prev_screen = tmp->prev_screen;
  1192. X    tmp->prev_screen = tmp1;
  1193. X    tmp1->next_screen = tmp;
  1194. X    if ((row + window->SR) == 0)
  1195. X        curscr->first_line = tmp1;
  1196. X    if (tmp1->next_screen != NULL)
  1197. X        tmp1 = tmp1->next_screen;
  1198. X/*    Position(window, (window->Num_lines -1), 0);
  1199. X    String_Out(String_table[dl__], NULL, 0);*/
  1200. X    Position(window, row, 0);
  1201. X    String_Out(String_table[al__], NULL, 0);
  1202. X    for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
  1203. X        top_of_win = top_of_win->next_screen;
  1204. X    return(tmp1);
  1205. X}
  1206. X
  1207. Xstruct _line *
  1208. XDelete_line(row, window)    /* delete a line on screen */
  1209. Xint row;
  1210. XWINDOW *window;
  1211. X{
  1212. X    int i;
  1213. X    struct _line *tmp;
  1214. X    struct _line *tmp1;
  1215. X    struct _line *tmp2;
  1216. X
  1217. X    i = 0;
  1218. X    tmp = curscr->first_line;
  1219. X    while (i < window->SR)
  1220. X    {
  1221. X        i++;
  1222. X        tmp = tmp->next_screen;
  1223. X    }
  1224. X    /*
  1225. X     |    find line to delete
  1226. X     */
  1227. X    top_of_win = tmp;
  1228. X    if ((row + window->SR) == 0)
  1229. X        curscr->first_line = top_of_win->next_screen;
  1230. X    for (i = 0, tmp = top_of_win; i < row; i++)
  1231. X        tmp = tmp->next_screen;
  1232. X    if (tmp->prev_screen != NULL)
  1233. X        tmp->prev_screen->next_screen = tmp->next_screen;
  1234. X    if (tmp->next_screen != NULL)
  1235. X        tmp->next_screen->prev_screen = tmp->prev_screen;
  1236. X    tmp2 = tmp->next_screen;
  1237. X    tmp1 = tmp;
  1238. X    /*
  1239. X     |    clear deleted line
  1240. X     */
  1241. X    clear_line(tmp1, 0, window->Num_cols);
  1242. X    tmp1->number = -1;
  1243. X    /*
  1244. X     |    find location to insert deleted line
  1245. X     */
  1246. X    for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
  1247. X        tmp = tmp->next_screen;
  1248. X    top_of_win = tmp;
  1249. X    for (i = 1, tmp = top_of_win; (i < window->Num_lines) && (tmp->next_screen != NULL); i++)
  1250. X        tmp = tmp->next_screen;
  1251. X    tmp1->next_screen = tmp->next_screen;
  1252. X    tmp1->prev_screen = tmp;
  1253. X    if (tmp1->next_screen != NULL)
  1254. X        tmp1->next_screen->prev_screen = tmp1;
  1255. X    tmp->next_screen = tmp1;
  1256. X    Position(window, row, 0);
  1257. X    String_Out(String_table[dl__], NULL, 0);
  1258. X/*    Position(window, (window->Num_lines -1), 0);
  1259. X    String_Out(String_table[al__], NULL, 0);*/
  1260. X    if (row == (window->Num_lines-1))
  1261. X        tmp2 = tmp1;
  1262. X    if ((row + window->SR) == 0)
  1263. X        curscr->first_line = top_of_win = tmp2;
  1264. X    return(tmp2);
  1265. X}
  1266. X
  1267. XCLEAR_TO_EOL(window, row, column)
  1268. XWINDOW *window;
  1269. Xint row, column;
  1270. X{
  1271. X    int x, y;
  1272. X    struct _line *tmp1;
  1273. X
  1274. X    for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
  1275. X        tmp1 = tmp1->next_screen;
  1276. X    for (x = column; x<window->Num_cols; x++)
  1277. X    {
  1278. X        tmp1->row[x] = ' ';
  1279. X        tmp1->attributes[x] = NULL;
  1280. X    }
  1281. X    tmp1->row[column] = NULL;
  1282. X    tmp1->last_char = column;
  1283. X    if (column < COLS)
  1284. X    {
  1285. X        if (String_table[ce__] != NULL)
  1286. X            String_Out(String_table[ce__], NULL, 0);
  1287. X        else
  1288. X        {
  1289. X            for (x = column; x < window->Num_cols; x++)
  1290. X                putchar(' ');
  1291. X        }
  1292. X    }
  1293. X}
  1294. X
  1295. Xcheck_delete(window, line, offset, pointer_new, pointer_old)
  1296. XWINDOW *window;
  1297. Xint line, offset;
  1298. Xstruct _line *pointer_new, *pointer_old;
  1299. X{
  1300. X    int end_old;
  1301. X    int end_new;
  1302. X    int k;
  1303. X    int i;
  1304. X    int changed;
  1305. X    char *old_lin;
  1306. X    char *new_lin;
  1307. X    char *old_att;
  1308. X    char *new_att;
  1309. X    
  1310. X    changed = FALSE;
  1311. X    new_lin = pointer_new->row;
  1312. X    new_att = pointer_new->attributes;
  1313. X    old_lin = pointer_old->row;
  1314. X    old_att = pointer_old->attributes;
  1315. X    end_old = end_new = offset;
  1316. X    while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != NULL) && (new_lin[end_old] != NULL))
  1317. X        end_old++;
  1318. X    if (old_lin[end_old] != NULL)
  1319. X    {
  1320. X        k = 0;
  1321. X        while ((old_lin[end_old+k] == new_lin[end_new+k]) && (new_att[end_new+k] == old_att[end_old+k]) && (new_lin[end_new+k] != NULL) && (old_lin[end_old+k] != NULL) && (k < 10))
  1322. X            k++;
  1323. X        if ((k > 8) || ((new_lin[end_new+k] == NULL) && (k != 0)))
  1324. X        {
  1325. X            if (new_lin[end_new+k] == NULL)
  1326. X            {
  1327. X                Position(window, line, (end_new+k));
  1328. X                        CLEAR_TO_EOL(window, line, (end_new+k));
  1329. X            }
  1330. X            Position(window, line, offset);
  1331. X            for (k = offset; k < end_old; k++)
  1332. X                Char_del(old_lin, old_att, offset, window->Num_cols);
  1333. X            while ((old_lin[offset] != NULL) && (offset < COLS))
  1334. X                offset++;
  1335. X            pointer_old->last_char = offset;
  1336. X            changed = TRUE;
  1337. X        }
  1338. X    }
  1339. X    return(changed);
  1340. X}
  1341. X
  1342. Xcheck_insert(window, line, offset, pointer_new, pointer_old)
  1343. XWINDOW *window;
  1344. Xint line, offset;
  1345. Xstruct _line *pointer_new, *pointer_old;
  1346. X{
  1347. X    int changed;
  1348. X    int count1, count2;
  1349. X    int begin_old, begin_new;
  1350. X    int end_old, end_new;
  1351. X    int i, j, k;
  1352. X    int same = FALSE;
  1353. X    int old_off;
  1354. X    int insert;
  1355. X    char *old_lin;
  1356. X    char *new_lin;
  1357. X    char *old_att;
  1358. X    char *new_att;
  1359. X
  1360. X    changed = FALSE;
  1361. X    new_lin = pointer_new->row;
  1362. X    new_att = pointer_new->attributes;
  1363. X    old_lin = pointer_old->row;
  1364. X    old_att = pointer_old->attributes;
  1365. X    end_old = end_new = offset;
  1366. X    while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != NULL) && (old_lin[end_new] != NULL))
  1367. X        end_new++;
  1368. X    if (new_lin[end_new] != NULL)
  1369. X    {
  1370. X        k = 0;
  1371. X        while ((old_lin[end_old+k] == new_lin[end_new+k]) && (old_att[end_old+k] == new_att[end_new+k]) && (new_lin[end_new+k] != NULL) && (old_lin[end_old+k] != NULL) && (k < 10))
  1372. X            k++;
  1373. X        /*
  1374. X         |  check for commonality between rest of lines (are the old 
  1375. X         |  and new lines the same, except for a chunk in the middle?)
  1376. X         |  if the rest of the lines are common, do not insert text
  1377. X         */
  1378. X        old_off = end_new;
  1379. X        while ((old_lin[old_off] != NULL) && (new_lin[old_off] != NULL) && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
  1380. X            old_off++;
  1381. X        if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
  1382. X            same = TRUE;
  1383. X        if ((!same) && ((k > 8) || ((new_lin[end_new+k] == NULL) && (k != 0))))
  1384. X        {
  1385. X            Position(window, line, offset);
  1386. X            insert = FALSE;
  1387. X            if (String_table[ic__] == NULL)
  1388. X            {
  1389. X                String_Out(String_table[im__], NULL, 0);
  1390. X                insert = TRUE;
  1391. X            }
  1392. X            for (k = offset; k < end_new; k++)
  1393. X            {
  1394. X                if (!insert)
  1395. X                    String_Out(String_table[ic__], NULL, 0);
  1396. X                Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
  1397. X            }
  1398. X            if (insert)
  1399. X                String_Out(String_table[ei__], NULL, 0);
  1400. X/*                j += k;*/
  1401. X            while ((old_lin[offset] != NULL) && (offset < COLS))
  1402. X                offset++;
  1403. X            pointer_old->last_char = offset;
  1404. X            changed = TRUE;
  1405. X        }
  1406. X    }
  1407. X    return(changed);
  1408. X}
  1409. X
  1410. Xdoupdate()
  1411. X{
  1412. X    WINDOW *window;
  1413. X    int similar;
  1414. X    int diff;
  1415. X    int begin_old, begin_new;
  1416. X    int end_old, end_new;
  1417. X    int count1, j;
  1418. X    int from_top, tmp_ft, offset;
  1419. X    int changed;
  1420. X    int first_time;
  1421. X    int first_same;
  1422. X    int last_same;
  1423. X
  1424. X
  1425. X    struct _line *curr;
  1426. X    struct _line *virt;
  1427. X    struct _line *old;
  1428. X
  1429. X    struct _line *new;
  1430. X
  1431. X    char *cur_lin;
  1432. X    char *vrt_lin;
  1433. X    char *cur_att;
  1434. X    char *vrt_att;
  1435. X    char *att1, *att2;
  1436. X    char *c1, *c2;
  1437. X
  1438. X    window = virtual_scr;
  1439. X
  1440. X    if (Repaint_screen)
  1441. X    {
  1442. X        if (String_table[cl__])
  1443. X            String_Out(String_table[cl__], NULL, 0);
  1444. X        else
  1445. X        {
  1446. X            from_top = 0;
  1447. X            while (from_top < LINES)
  1448. X            {
  1449. X                Position(curscr, from_top, 0);
  1450. X                if (String_table[ce__] != NULL)
  1451. X                    String_Out(String_table[ce__], NULL, 0);
  1452. X                else
  1453. X                {
  1454. X                    for (j = 0; j < window->Num_cols; j++)
  1455. X                        putchar(' ');
  1456. X                }
  1457. X                from_top++;
  1458. X            }
  1459. X        }
  1460. X        for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
  1461. X        {
  1462. X            Position(curscr, from_top, 0);
  1463. X            for (j = 0; (curr->row[j] != NULL) && (j < curscr->Num_cols); j++)
  1464. X            {
  1465. X                Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
  1466. X            }
  1467. X            if (STAND)
  1468. X            {
  1469. X                STAND = FALSE;
  1470. X                Position(curscr, from_top, j);
  1471. X                attribute_off();
  1472. X            }
  1473. X        }
  1474. X        Repaint_screen = FALSE;
  1475. X    }
  1476. X
  1477. X    similar = 0;
  1478. X    diff = FALSE;
  1479. X    top_of_win = curscr->first_line;
  1480. X
  1481. X    for (from_top = 0, curr = top_of_win, virt = window->first_line; 
  1482. X            from_top < window->Num_lines; from_top++)
  1483. X    {
  1484. X        virtual_lines[from_top] = TRUE;
  1485. X        if ((similar = Comp_line(curr, virt)) > 0)
  1486. X        {
  1487. X            diff = TRUE;
  1488. X            virtual_lines[from_top] = FALSE;
  1489. X        }
  1490. X        curr = curr->next_screen;
  1491. X        virt = virt->next_screen;
  1492. X    }
  1493. X
  1494. X    from_top = 0;
  1495. X    virt = window->first_line;
  1496. X    curr = top_of_win;
  1497. X    similar = 0;
  1498. X    /*
  1499. X     |  if the window has lines that are different
  1500. X     */
  1501. X    if (diff)
  1502. X    {
  1503. X        last_same = -1;
  1504. X        changed = FALSE;
  1505. X        while ((from_top < window->Num_lines) && (String_table[al__]) && (String_table[dl__]))    /* check entire lines for diffs    */
  1506. X        {
  1507. X
  1508. X            if (!virtual_lines[from_top])
  1509. X            {
  1510. X                for (first_same = window->Num_lines; (first_same > from_top) && (virtual_lines[first_same - 1]); first_same--)
  1511. X                    ;
  1512. X                count1 = first_same - 1;
  1513. X                diff = TRUE;
  1514. X                /*
  1515. X                 |    check for lines deleted (scroll up)
  1516. X                 */
  1517. X                for (tmp_ft = from_top+1, old = curr->next_screen; 
  1518. X                    ((window->scroll_up) && (diff) && 
  1519. X                    (tmp_ft < window->Num_lines) && 
  1520. X                    (!virtual_lines[tmp_ft]));
  1521. X                        tmp_ft++)
  1522. X                {
  1523. X                    if ((Comp_line(old, virt) == -1) && (!virtual_lines[tmp_ft]))
  1524. X                    {
  1525. X                        for (offset = (tmp_ft - from_top); (offset > 0); offset--)
  1526. X                        {
  1527. X                            old = Delete_line(from_top, window);
  1528. X                            if (first_same < window->Num_lines)
  1529. X                            {
  1530. X                                old = Insert_line(count1, window);
  1531. X                            }
  1532. X                            else
  1533. X                            {
  1534. X                                Position(window, (window->Num_lines -1), 0);
  1535. X                                String_Out(String_table[al__], NULL, 0);
  1536. X                            }
  1537. X                            window->scroll_up--;
  1538. X                            diff = FALSE;
  1539. X                        }
  1540. X                        top_of_win = curscr->first_line;
  1541. X                        curr = top_of_win;
  1542. X                        for (offset = 0; offset < from_top; offset++)
  1543. X                            curr = curr->next_screen;
  1544. X                        for (offset = from_top, old=curr, new=virt; 
  1545. X                           offset < window->Num_lines; 
  1546. X                           old=old->next_screen, new=new->next_screen,
  1547. X                           offset++)
  1548. X                        {
  1549. X                            virtual_lines[offset] = TRUE;
  1550. X                            if ((similar = Comp_line(old, new)) > 0)
  1551. X                            {
  1552. X                                virtual_lines[offset] = FALSE;
  1553. X                            }
  1554. X                        }
  1555. X                    }
  1556. X                    else
  1557. X                        old = old->next_screen;
  1558. X                }
  1559. X                /*
  1560. X                 |    check for lines inserted (scroll down)
  1561. X                 */
  1562. X                for (tmp_ft = from_top-1, old = curr->prev_screen; 
  1563. X                    ((window->scroll_down) && (tmp_ft >= 0) && 
  1564. X                    (diff) && 
  1565. X                    (!virtual_lines[tmp_ft])); 
  1566. X                      tmp_ft--)
  1567. X                {
  1568. X                    if (Comp_line(old, virt) == -1)
  1569. X                    {
  1570. X                        for (first_same = window->Num_lines; (first_same > from_top) && (virtual_lines[first_same - 1]); first_same--)
  1571. X                            ;
  1572. X                        count1 = first_same -  1;
  1573. X                        for (offset = (from_top - tmp_ft); (offset > 0); offset--)
  1574. X                        {
  1575. X                            if (first_same < window->Num_lines)
  1576. X                            {
  1577. X                                old = Delete_line(count1, window);
  1578. X                            }
  1579. X                            else
  1580. X                            {
  1581. X                                Position(window, (window->Num_lines -1), 0);
  1582. X                                String_Out(String_table[dl__], NULL, 0);
  1583. X                            }
  1584. X                            old = Insert_line(tmp_ft, window);
  1585. X                            window->scroll_down--;
  1586. X                            diff = FALSE;
  1587. X                        }
  1588. X                        top_of_win = curscr->first_line;
  1589. X                        curr = top_of_win;
  1590. X                        for (offset = 0; offset < from_top; offset++)
  1591. X                            curr = curr->next_screen;
  1592. X                        for (offset = from_top, old=curr, new=virt; 
  1593. X                           offset < window->Num_lines; 
  1594. X                           old=old->next_screen, new=new->next_screen,
  1595. X                           offset++)
  1596. X                        {
  1597. X                            virtual_lines[offset] = TRUE;
  1598. X                            if ((similar = Comp_line(old, new)) > 0)
  1599. X                            {
  1600. X                                virtual_lines[offset] = FALSE;
  1601. X                            }
  1602. X                        }
  1603. X                    }
  1604. X                    else
  1605. X                        old = old->prev_screen;
  1606. X                }
  1607. X            }
  1608. X            from_top++;
  1609. X            curr = curr->next_screen;
  1610. X            virt = virt->next_screen;
  1611. X        }
  1612. X    }
  1613. X    for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
  1614. X        curr = curr->next_screen;
  1615. X    top_of_win = curr;
  1616. X    for (from_top = 0, curr = top_of_win, virt = window->first_line; from_top < window->Num_lines; from_top++, curr = curr->next_screen, virt = virt->next_screen)
  1617. X    {
  1618. X        if (((String_table[ic__]) || (String_table[im__])) && (String_table[dc__]) && (curr->row[0] != NULL))
  1619. X        {
  1620. X            j = 0;
  1621. X            first_time = TRUE;
  1622. X            vrt_lin = virt->row;
  1623. X            vrt_att = virt->attributes;
  1624. X            cur_lin = curr->row;
  1625. X            cur_att = curr->attributes;
  1626. X            while ((vrt_lin[j] != NULL) && (j < window->Num_cols))
  1627. X            {
  1628. X                if ((STAND) && (Booleans[xs__]))
  1629. X                {
  1630. X                    while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != NULL) && (vrt_att[j]))
  1631. X                        j++;
  1632. X                    if ((STAND) && (!vrt_att[j]))
  1633. X                    {
  1634. X                        STAND = FALSE;
  1635. X                        Position(window, from_top, j);
  1636. X                        attribute_off();
  1637. X                        attribute_off();
  1638. X                    }
  1639. X                }
  1640. X                else
  1641. X                {
  1642. X                    while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != NULL))
  1643. X                        j++;
  1644. X                }
  1645. X                if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
  1646. X                {
  1647. X                    Position(window, from_top, j);
  1648. X/*                    CLEAR_TO_EOL(window, from_top, j);*/
  1649. X                    attribute_off();
  1650. X                    attribute_off();
  1651. X                }
  1652. X                if (vrt_lin[j] != NULL)
  1653. X                {
  1654. X                    begin_new = j;
  1655. X                    begin_old = j;
  1656. X                    end_old = j;
  1657. X                    end_new = j;
  1658. X                    if ((first_time) && (virt->changed))
  1659. X                    {
  1660. X                        if (curr->last_char <= virt->last_char)
  1661. X                            changed = check_insert(window, from_top, j, virt, curr);
  1662. X                    }
  1663. X                    changed = check_delete(window, from_top, j, virt, curr);
  1664. X                    first_time = FALSE;
  1665. X                    virt->changed = FALSE;
  1666. X                    if (!changed)
  1667. X                        changed = check_insert(window, from_top, j, virt, curr);
  1668. X                    if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
  1669. X                    {
  1670. X                        if ((vrt_lin[j] == ' ') && (cur_lin[j] == NULL) && (vrt_att[j] == cur_att[j]))
  1671. X                            cur_lin[j] = ' ';
  1672. X                        else
  1673. X                        {
  1674. X                            Position(window, from_top, j);
  1675. X                            Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
  1676. X                        }
  1677. X                    }
  1678. X                    if ((vrt_lin[j] != NULL) && (cur_lin[j] != NULL))
  1679. X                        j++;
  1680. X                }
  1681. X                if ((STAND) && (!vrt_att[j]))
  1682. X                {
  1683. X                    STAND = FALSE;
  1684. X                    Position(window, from_top, j);
  1685. X                    attribute_off();
  1686. X                }
  1687. X            }
  1688. X            if ((vrt_lin[j] == NULL) && (cur_lin[j] != NULL))
  1689. X            {
  1690. X                Position(window, from_top, j);
  1691. X                CLEAR_TO_EOL(window, from_top, j);
  1692. X            }
  1693. X        }
  1694. X        else /*if ((similar != -1) && (similar != 0))*/
  1695. X        {
  1696. X            j = 0;
  1697. X            c1 = curr->row;
  1698. X            att1 = curr->attributes;
  1699. X            c2 = virt->row;
  1700. X            att2 = virt->attributes;
  1701. X            while ((j < window->Num_cols) && (c2[j] != NULL))
  1702. X            {
  1703. X                while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != NULL))
  1704. X                    j++;
  1705. X                begin_old = j;
  1706. X                begin_new = j;
  1707. X                if ((j < window->Num_cols) && (c2[j] != NULL))
  1708. X                {
  1709. X                    Position(window, from_top, begin_old);
  1710. X                    CLEAR_TO_EOL(window, from_top, j);
  1711. X                    Position(window, from_top, begin_old);
  1712. X                    for (j = begin_old; (c2[j] != NULL) && (j < window->Num_cols); j++)
  1713. X                        Char_out(c2[j], att2[j], c1, att1, j);
  1714. X                }
  1715. X            }
  1716. X            if ((c2[j] == NULL) && (c1[j] != NULL))
  1717. X            {
  1718. X                Position(window, from_top, j);
  1719. X                CLEAR_TO_EOL(window, from_top, j);
  1720. X            }
  1721. X        }
  1722. X        if (STAND)
  1723. X        {
  1724. X            STAND = FALSE;
  1725. X            Position(window, from_top, j);
  1726. X            attribute_off();
  1727. X        }
  1728. X        virt->number = from_top;
  1729. X    }
  1730. X    Position(window, window->LY, window->LX);
  1731. X}
  1732. X
  1733. XPosition(window, row, col)    /* position the cursor for output on the screen    */
  1734. XWINDOW *window;
  1735. Xint row;
  1736. Xint col;
  1737. X{
  1738. X    int list[10];
  1739. X    int place;
  1740. X
  1741. X    int pos_row;
  1742. X    int pos_column;
  1743. X
  1744. X    pos_row = row + window->SR;
  1745. X    pos_column = col + window->SC;
  1746. X    if ((pos_row != Curr_y) || (pos_column != Curr_x))
  1747. X    {
  1748. X        if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/ 
  1749. X        {
  1750. X            place = 0;
  1751. X            list[place++] = pos_column;
  1752. X            list[place++] = pos_row;
  1753. X            String_Out(String_table[cm__], list, place);
  1754. X            if ((STAND) && (!Booleans[ms__]))
  1755. X                attribute_on();
  1756. X        }
  1757. X        Curr_x = pos_column;
  1758. X        Curr_y = pos_row;
  1759. X    }
  1760. X}
  1761. X
  1762. XChar_del(line, attrib, offset, maxlen)    /* delete chars from line    */
  1763. Xchar *line;
  1764. Xchar *attrib;
  1765. Xint offset;
  1766. Xint maxlen;
  1767. X{
  1768. X    int one, two;
  1769. X
  1770. X    for (one = offset, two = offset+1; (line[one] != NULL) && (one < maxlen); one++, two++)
  1771. X    {
  1772. X        line[one] = line[two];
  1773. X        attrib[one] = attrib[two];
  1774. X    }
  1775. X    String_Out(String_table[dc__], NULL, 0);
  1776. X}
  1777. X
  1778. XChar_ins(line, attrib, newc, newatt, offset, maxlen)    /* insert chars in line    */
  1779. Xchar *line;
  1780. Xchar *attrib;
  1781. Xchar newc;
  1782. Xchar newatt;
  1783. Xint offset;
  1784. Xint maxlen;
  1785. X{
  1786. X    int one, two;
  1787. X
  1788. X    one = 0;
  1789. X    while ((line[one] != NULL) && (one < (maxlen - 2)))
  1790. X        one++;
  1791. X    for (two = one + 1; (two > offset); one--, two--)
  1792. X    {
  1793. X        line[two] = line[one];
  1794. X        attrib[two] = attrib[one];
  1795. X    }
  1796. X    line[offset] = newc;
  1797. X    attrib[offset] = newatt;
  1798. X    Char_out(newc, newatt, line, attrib, offset);
  1799. X}
  1800. X
  1801. Xattribute_on()
  1802. X{
  1803. X    if (String_table[sa__])
  1804. X    {
  1805. X        attributes_set[0] = 1;
  1806. X        String_Out(String_table[sa__], attributes_set, 1);
  1807. X    }
  1808. X    else if (String_table[so__])
  1809. X        String_Out(String_table[so__], NULL, 0);
  1810. X}
  1811. X
  1812. Xattribute_off()
  1813. X{
  1814. X    if (String_table[me__])
  1815. X        String_Out(String_table[me__], NULL, 0);
  1816. X    else if (String_table[sa__])
  1817. X    {
  1818. X        attributes_set[0] = 0;
  1819. X        String_Out(String_table[sa__], attributes_set, 1);
  1820. X    }
  1821. X    else if (String_table[sa__])
  1822. X        String_Out(String_table[se__], NULL, 0);
  1823. X}
  1824. X
  1825. XChar_out(newc, newatt, line, attrib, offset)    /* output character with proper attribute    */
  1826. Xchar newc;
  1827. Xchar newatt;
  1828. Xchar *line;
  1829. Xchar *attrib;
  1830. Xint offset;
  1831. X{
  1832. X
  1833. X
  1834. X    if ((newatt) && (!STAND))
  1835. X    {
  1836. X        STAND = TRUE;
  1837. X        attribute_on();
  1838. X    }
  1839. X    else if ((STAND) && (!newatt))
  1840. X    {
  1841. X        STAND = FALSE;
  1842. X        attribute_off();
  1843. X    }
  1844. X
  1845. X    if ((newatt) && (STAND) && (Booleans[xs__]))
  1846. X    {
  1847. X        attribute_on();
  1848. X    }
  1849. X
  1850. X    if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
  1851. X    {
  1852. X        putchar(newc);
  1853. X        line[offset] = newc;
  1854. X        attrib[offset] = newatt;
  1855. X    }
  1856. X    Curr_x++;
  1857. X}
  1858. X
  1859. END_OF_FILE
  1860.   if test 37082 -ne `wc -c <'new_curse.c.B'`; then
  1861.     echo shar: \"'new_curse.c.B'\" unpacked with wrong size!
  1862.   elif test -f 'new_curse.c.A'; then
  1863.     echo shar: Combining  \"'new_curse.c'\" \(73709 characters\)
  1864.     cat 'new_curse.c.A' 'new_curse.c.B' > 'new_curse.c'
  1865.     if test 73709 -ne `wc -c <'new_curse.c'`; then
  1866.       echo shar: \"'new_curse.c'\" combined with wrong size!
  1867.     else
  1868.       rm new_curse.c.A new_curse.c.B
  1869.     fi
  1870.   fi
  1871.   # end of 'new_curse.c.B'
  1872. fi
  1873. echo shar: End of archive 1 \(of 5\).
  1874. cp /dev/null ark1isdone
  1875. MISSING=""
  1876. for I in 1 2 3 4 5 ; do
  1877.     if test ! -f ark${I}isdone ; then
  1878.     MISSING="${MISSING} ${I}"
  1879.     fi
  1880. done
  1881. if test "${MISSING}" = "" ; then
  1882.     echo You have unpacked all 5 archives.
  1883.     rm -f ark[1-9]isdone
  1884. else
  1885.     echo You still must unpack the following archives:
  1886.     echo "        " ${MISSING}
  1887. fi
  1888. exit 0
  1889. exit 0 # Just in case...
  1890.