home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GAMES / infocom_src.lha / io.c < prev    next >
Text File  |  1993-07-18  |  63KB  |  3,617 lines

  1. /*
  2. **    File:    io.c
  3. **
  4. **    (C)opyright 1987-1992 InfoTaskforce.
  5. */
  6.  
  7. #include    <stdio.h>
  8. #include    "infocom.h"
  9.  
  10. #include    <ctype.h>
  11.  
  12. #define        MAXATTR    10
  13.  
  14. #define        NORMAL_MODE            ((word)0x00)
  15. #define        INVERSE_MODE        ((word)0x01)
  16. #define        BOLD_MODE            ((word)0x02)
  17. #define        UNDERLINE_MODE        ((word)0x04)
  18.  
  19. #define        INV_BOLD_MODE        ((word)0x03)
  20. #define        INV_UNDER_MODE        ((word)0x05)
  21. #define        BOLD_UNDER_MODE        ((word)0x06)
  22. #define        INV_BOLD_UNDER_MODE    ((word)0x07)
  23.  
  24. static long    vidc[8][MAXATTR];
  25. static word    text_mode = NORMAL_MODE;
  26.  
  27. #if (defined(CURSES) && !defined(BSD)) || defined(TERMINFO)
  28.  
  29. #ifndef A_NORMAL
  30. #define    A_NORMAL        0
  31. #endif
  32.  
  33. #define A_HIGH            A_BOLD
  34. #define A_LOW            A_DIM
  35. #define A_ITALIC        A_STANDOUT
  36. #define A_FASTBLINK        A_BLINK
  37.  
  38. #define A_FGOFFSET        0
  39. #define A_BGOFFSET        10
  40.  
  41. #elif defined(ANSI_ESCAPE)
  42.  
  43. /* ANSI Attributes */
  44. #define    A_NORMAL        0
  45. #define A_HIGH            1
  46. #define A_LOW            2
  47. #define A_ITALIC        3
  48. #define A_UNDERLINE        4
  49. #define A_BLINK            5
  50. #define A_FASTBLINK        6
  51. #define A_REVERSE        7
  52.  
  53. #ifdef WANT_COLOR
  54. #define COLOR_BLACK        0
  55. #define COLOR_RED        1
  56. #define COLOR_GREEN        2
  57. #define COLOR_YELLOW    3
  58. #define COLOR_BLUE        4
  59. #define COLOR_MAGENTA    5
  60. #define COLOR_CYAN        6
  61. #define COLOR_WHITE        7
  62.  
  63. #define A_FGOFFSET        30
  64. #define A_BGOFFSET        40
  65.  
  66. #endif /* WANT_COLOR */
  67.  
  68. static boolean    use_save_cursor = FALSE ;
  69.  
  70. #elif defined(MSC) || defined(TURBOC)
  71.  
  72. /* Microsoft C Color Attributes */
  73. #define    A_NORMAL        0
  74. #define A_HIGH            1
  75. #define A_LOW            0
  76. #define A_ITALIC        0
  77. #define A_UNDERLINE        0
  78. #define A_BLINK            5
  79. #define A_FASTBLINK        5
  80. #define A_REVERSE        0
  81. #define COLOR_BLACK        0
  82. #define COLOR_RED        4
  83. #define COLOR_GREEN        2
  84. #define COLOR_YELLOW    6
  85. #define COLOR_BLUE        1
  86. #define COLOR_MAGENTA    5
  87. #define COLOR_CYAN        3
  88. #define COLOR_WHITE        7
  89.  
  90. #define A_FGOFFSET        10
  91. #define A_BGOFFSET        20
  92.  
  93. #else
  94.  
  95. /* Dummy entries */
  96. #define    A_NORMAL        0
  97. #define A_HIGH            0
  98. #define A_LOW            0
  99. #define A_ITALIC        0
  100. #define A_UNDERLINE        0
  101. #define A_BLINK            0
  102. #define A_FASTBLINK        0
  103. #define A_REVERSE        0
  104. #define COLOR_BLACK        0
  105. #define COLOR_RED        0
  106. #define COLOR_GREEN        0
  107. #define COLOR_YELLOW    0
  108. #define COLOR_BLUE        0
  109. #define COLOR_MAGENTA    0
  110. #define COLOR_CYAN        0
  111. #define COLOR_WHITE        0
  112.  
  113. #define A_FGOFFSET        0
  114. #define A_BGOFFSET        0
  115.  
  116. #endif
  117.  
  118. typedef struct attrtype
  119. {
  120.     char    *attrtok;
  121.     long    attrnum;
  122. } ATYPE;
  123.  
  124. static ATYPE    vidattrs[] =
  125. {
  126.     { "normal",    A_NORMAL },
  127.     { "high",    A_HIGH },
  128.     { "low",    A_LOW },
  129.     { "italic",    A_ITALIC },
  130.     { "underline",    A_UNDERLINE },
  131.     { "blink",    A_BLINK },
  132.     { "fastblink",    A_FASTBLINK },
  133.     { "reverse",    A_REVERSE },
  134. #ifdef WANT_COLOR
  135.     { "f_black",    A_FGOFFSET + COLOR_BLACK },
  136.     { "f_red",    A_FGOFFSET + COLOR_RED },
  137.     { "f_green",    A_FGOFFSET + COLOR_GREEN },
  138.     { "f_yellow",    A_FGOFFSET + COLOR_YELLOW },
  139.     { "f_blue",    A_FGOFFSET + COLOR_BLUE },
  140.     { "f_magenta",    A_FGOFFSET + COLOR_MAGENTA },
  141.     { "f_cyan",    A_FGOFFSET + COLOR_CYAN },
  142.     { "f_white",    A_FGOFFSET + COLOR_WHITE },
  143.     { "b_black",    A_BGOFFSET + COLOR_BLACK },
  144.     { "b_red",    A_BGOFFSET + COLOR_RED },
  145.     { "b_green",    A_BGOFFSET + COLOR_GREEN },
  146.     { "b_yellow",    A_BGOFFSET + COLOR_YELLOW },
  147.     { "b_blue",    A_BGOFFSET + COLOR_BLUE },
  148.     { "b_magenta",    A_BGOFFSET + COLOR_MAGENTA },
  149.     { "b_cyan",    A_BGOFFSET + COLOR_CYAN },
  150.     { "b_white",    A_BGOFFSET + COLOR_WHITE }
  151. #endif
  152. };
  153.  
  154. static char *
  155. rc_get_token ( pstr )
  156. char    **pstr;
  157. {
  158.     char    *tok ;
  159.  
  160.     while ( **pstr && isspace( **pstr ) )
  161.         ( *pstr )++ ;
  162.  
  163.     if (!**pstr)
  164.         return 0 ;
  165.  
  166.     /* read keyword */
  167.     tok = *pstr ;
  168.     while ( **pstr && ! isspace ( **pstr ) )
  169.     {
  170.         if ( isupper ( **pstr ) )
  171.             **pstr = tolower( **pstr ) ;
  172.         ( *pstr )++ ;
  173.     }
  174.  
  175.     return tok;
  176. }
  177.  
  178. static Void
  179. rc_parse_attr ( attrnum, str )
  180. int        attrnum;
  181. char    *str;
  182. {
  183.     char    *attr ;
  184.  
  185.     vidc[attrnum][0] = 0 ;
  186.  
  187.     while ( attr = rc_get_token ( &str ) )
  188.     {
  189.         int    i ;
  190.  
  191.         for ( i = 0 ; i < sizeof ( vidattrs ) / sizeof ( ATYPE ) ; i++ )
  192.             if ( !strncmp ( attr,vidattrs[i].attrtok,str - attr ) )
  193.                 vidc[attrnum][++vidc[attrnum][0]] = vidattrs[i].attrnum ;
  194.     }
  195. }
  196.  
  197. static Void
  198. default_attrs ()
  199. {
  200. #ifdef WANT_COLOR
  201.  
  202.     /* default colors */
  203.     vidc[NORMAL_MODE][0] = 2 ;
  204.     vidc[NORMAL_MODE][1] = COLOR_CYAN + A_BGOFFSET ;
  205.     vidc[NORMAL_MODE][2] = COLOR_BLACK + A_FGOFFSET ;
  206.  
  207.     vidc[INVERSE_MODE][0] = 3 ;
  208.     vidc[INVERSE_MODE][1] = COLOR_RED + A_BGOFFSET ;
  209.     vidc[INVERSE_MODE][2] = COLOR_CYAN + A_FGOFFSET ;
  210.     vidc[INVERSE_MODE][3] = A_HIGH ;
  211.  
  212.     vidc[BOLD_MODE][0] = 2 ;
  213.     vidc[BOLD_MODE][1] = COLOR_CYAN + A_BGOFFSET ;
  214.     vidc[BOLD_MODE][2] = COLOR_YELLOW + A_FGOFFSET ;
  215.  
  216.     vidc[INV_BOLD_MODE][0] = 2 ;
  217.     vidc[INV_BOLD_MODE][1] = COLOR_RED + A_BGOFFSET ;
  218.     vidc[INV_BOLD_MODE][2] = COLOR_YELLOW + A_FGOFFSET ;
  219.  
  220.     vidc[UNDERLINE_MODE][0] = 3 ;
  221.     vidc[UNDERLINE_MODE][1] = COLOR_CYAN + A_BGOFFSET ;
  222.     vidc[UNDERLINE_MODE][2] = COLOR_GREEN + A_FGOFFSET ;
  223.     vidc[UNDERLINE_MODE][3] = A_HIGH ;
  224.  
  225.     vidc[INV_UNDER_MODE][0] = 3 ;
  226.     vidc[INV_UNDER_MODE][1] = COLOR_RED + A_BGOFFSET ;
  227.     vidc[INV_UNDER_MODE][2] = COLOR_GREEN + A_FGOFFSET ;
  228.     vidc[INV_UNDER_MODE][3] = A_HIGH ;
  229.  
  230.     vidc[BOLD_UNDER_MODE][0] = 2 ;
  231.     vidc[BOLD_UNDER_MODE][1] = COLOR_CYAN + A_BGOFFSET ;
  232.     vidc[BOLD_UNDER_MODE][2] = COLOR_WHITE + A_FGOFFSET ;
  233.  
  234.     vidc[INV_BOLD_UNDER_MODE][0] = 2 ;
  235.     vidc[INV_BOLD_UNDER_MODE][1] = COLOR_RED + A_BGOFFSET ;
  236.     vidc[INV_BOLD_UNDER_MODE][2] = COLOR_WHITE + A_FGOFFSET ;
  237.  
  238. #else
  239.  
  240.     /* default colors */
  241.     vidc[NORMAL_MODE][0] = 1 ;
  242.     vidc[NORMAL_MODE][1] = A_NORMAL ;
  243.  
  244.     vidc[INVERSE_MODE][0] = 1 ;
  245.     vidc[INVERSE_MODE][1] = A_REVERSE ;
  246.  
  247.     vidc[BOLD_MODE][0] = 1 ;
  248.     vidc[BOLD_MODE][1] = A_HIGH ;
  249.  
  250.     vidc[INV_BOLD_MODE][0] = 2 ;
  251.     vidc[INV_BOLD_MODE][1] = A_REVERSE ;
  252.     vidc[INV_BOLD_MODE][2] = A_HIGH ;
  253.  
  254.     vidc[UNDERLINE_MODE][0] = 1 ;
  255.     vidc[UNDERLINE_MODE][1] = A_UNDERLINE ;
  256.  
  257.     vidc[INV_UNDER_MODE][0] = 2 ;
  258.     vidc[INV_UNDER_MODE][1] = A_REVERSE ;
  259.     vidc[INV_UNDER_MODE][2] = A_UNDERLINE ;
  260.  
  261.     vidc[BOLD_UNDER_MODE][0] = 2 ;
  262.     vidc[BOLD_UNDER_MODE][1] = A_HIGH ;
  263.     vidc[BOLD_UNDER_MODE][2] = A_UNDERLINE ;
  264.  
  265.     vidc[INV_BOLD_UNDER_MODE][0] = 3 ;
  266.     vidc[INV_BOLD_UNDER_MODE][1] = A_REVERSE ;
  267.     vidc[INV_BOLD_UNDER_MODE][2] = A_HIGH ;
  268.     vidc[INV_BOLD_UNDER_MODE][3] = A_UNDERLINE ;
  269.  
  270. #endif /* WANT COLOR */
  271. }
  272.  
  273. static Void
  274. read_rcfile()
  275. {
  276.     extern int    screen_width ;
  277.     extern int    screen_height ;
  278.  
  279.     extern long atol();
  280.     extern char *getenv();
  281.  
  282.     static char default_rcfile[] = RCFILE;
  283.     char    *home = getenv("HOME");
  284.     char    rcfile[BUFSIZ];
  285.     FILE    *rc;
  286.  
  287.     if (home)
  288.         sprintf(rcfile, "%s/%s", home, default_rcfile);
  289.     else
  290.         strcpy(rcfile, default_rcfile);
  291.  
  292.     if ( (rc = fopen(rcfile, "r")) || (rc = fopen(RCFILE, "r")) )
  293.     {
  294.         int    attrnum = 0;
  295.  
  296.         while    (fgets(rcfile, BUFSIZ, rc))
  297.         {
  298.             char    *p = rcfile, *q;
  299.             int    len;
  300.  
  301.             q = rc_get_token(&p);
  302.  
  303.             if (*q == '#')
  304.                 continue; /* comment character */
  305.  
  306.             len = p - q;
  307.  
  308.             if (!strncmp(q, "height", len))
  309.             {
  310.                 long    l = atol(p);
  311.  
  312.                 if (l)
  313.                     screen_height = (int)l;
  314.             }
  315.             else if (!strncmp(q, "width", len))
  316.             {
  317.                 long    l = atol(p);
  318.  
  319.                 if (l)
  320.                     screen_width = (int)l;
  321.             }
  322. #ifdef ANSI_ESCAPE
  323.             else if (!strncmp(q, "save", len))
  324.                 use_save_cursor = TRUE ;
  325. #endif
  326.             else if (!strncmp(q, "attr", len))
  327.                 rc_parse_attr(attrnum++, p);
  328.         }
  329.         fclose(rc);
  330.     }
  331. }
  332.  
  333. Void
  334. print_status ( s_buffer )
  335. byte    s_buffer[] ;
  336. {
  337.     Void    PUT_CHAR () ;
  338.     Void    GOTO_XY () ;
  339.     extern int    screen_width ;
  340.     extern int    screen_height ;
  341.  
  342.     byte        *ptr    = s_buffer ;
  343.     int            i        = screen_width ;
  344.  
  345.     /*
  346.     **    Note:
  347.     **        The variable "ptr" is of type "byte *"
  348.     **        NOT "byte_ptr" - these definitions are
  349.     **        different for MSDOS Compilers ("byte_ptr" is huge).
  350.     */
  351.  
  352.     GOTO_XY ( 0,0 ) ;
  353.     PUT_CHAR ( (char)2 ) ;
  354.     while ( i-- )
  355.         out_char ( (char)*ptr++ ) ;
  356.     PUT_CHAR ( (char)1 ) ;
  357.     GOTO_XY ( 0,screen_height-1 ) ;
  358. }
  359.  
  360. Void
  361. display ( s )
  362. char    *s ;
  363. {
  364.     Void    PUT_CHAR () ;
  365.  
  366.     while ( *s != '\0' )
  367.         PUT_CHAR ( *s++ ) ;
  368. }
  369.  
  370. Void
  371. raw_display ( s )
  372. char    *s ;
  373. {
  374.     /*
  375.     **    "raw_display ()" must be used to print ANSI_ESCAPE sequences
  376.     **    since we want these strings printed regardless of the state of
  377.     **    "enable_screen". If "display ()" is used, then the "PUT_CHAR" routine
  378.     **    will be called to print each character of the string - which will
  379.     **    only happen if "enable_screen" is true.
  380.     */
  381.  
  382.     printf ( s ) ;
  383. }
  384.  
  385. char    hex_string[] =    {
  386.                             '0','1','2','3','4','5','6','7',
  387.                             '8','9','A','B','C','D','E','F'
  388.                         } ;
  389.  
  390. Void
  391. hex_digit ( n,level )
  392. word    n ;
  393. int        level ;
  394. {
  395.     Void    PUT_CHAR () ;
  396.  
  397.     if ( level < 4 )
  398.     {
  399.         hex_digit ( n/16,level+1 ) ;
  400.         PUT_CHAR ( hex_string[n % 16] ) ;
  401.     }
  402. }
  403.  
  404. Void
  405. hex_display ( n )
  406. word    n ;
  407. {
  408.     hex_digit ( n,0 ) ;
  409. }
  410.  
  411. char
  412. read_char ()
  413. {
  414.     extern boolean    echo_in ;
  415.     extern boolean    enhanced ;
  416.     Void    PUT_CHAR () ;
  417.  
  418.     char            ch ;
  419.     int                in ;
  420.  
  421.     if ( enhanced )
  422.     {
  423.         if (( in = GET_CH ()) == EOF)
  424.         {
  425.             /*
  426.             **    If input is from file, handle EOF
  427.             */
  428.  
  429.             ch = '\n' ;
  430.             quit () ;
  431.         }
  432.         else
  433.             ch = (char)in ;
  434.         if ( ch == '\r' )
  435.             ch = '\n' ;
  436.         PUT_CHAR ( ch ) ;
  437.     }
  438.     else
  439.     {
  440.         if (( in = getchar ()) == EOF )
  441.         {
  442.             /*
  443.             **    If input is from file, handle EOF
  444.             */
  445.  
  446.             ch = '\n' ;
  447.             quit () ;
  448.         }
  449.         else
  450.             ch = (char)in ;
  451.         if ( echo_in )
  452.             putchar ( ch ) ;
  453.     }
  454.     script_char ( ch ) ;
  455.     return ( ch ) ;
  456. }
  457.  
  458. Void
  459. out_char ( c )
  460. char    c ;
  461. {
  462.     extern boolean    enhanced ;
  463.     extern boolean    windowing_enabled ;
  464.     extern word        current_window ;
  465.     extern word        window_height ;
  466.     extern boolean    enable_screen ;
  467.     extern int        screen_height ;
  468.     extern int        linecount ;
  469.     Void    PUT_CHAR () ;
  470.     
  471.     script_char ( c ) ;
  472.     PUT_CHAR ( c ) ;
  473.     if (( enable_screen ) && ( c == '\n' ))
  474.     {
  475.         if ( enhanced )
  476.         {
  477.             if ( windowing_enabled == FALSE )
  478.             {
  479.                 if ( linecount++ >= screen_height - 4 )
  480.                 {
  481.                     more () ;
  482.                     linecount = 0 ;
  483.                 }
  484.                 return ;
  485.             }
  486.             if (( windowing_enabled == TRUE ) && ( current_window == 0 ))
  487.             {
  488.                 if ( linecount++ >= screen_height - (int)window_height - 4 )
  489.                 {
  490.                     more () ;
  491.                     linecount = 0 ;
  492.                 }
  493.                 return ;
  494.             }
  495.         }
  496.         else
  497.         {
  498.             if ( linecount++ >= screen_height - 4 )
  499.             {
  500.                 more () ;
  501.                 linecount = 0 ;
  502.             }
  503.         }
  504.     }
  505. }
  506.  
  507. Void
  508. more ()
  509. {
  510.     extern boolean    page_out ;
  511.  
  512.     int                in ;
  513.  
  514.     if ( !page_out )
  515.     {
  516.         display ( "[MORE]" ) ;
  517.         in = GET_CH () ;
  518.         display ( "\b\b\b\b\b\b      \b\b\b\b\b\b" ) ;
  519.     }
  520. }
  521.  
  522. word
  523. allocate ( max_blocks )
  524. word    max_blocks ;
  525. {
  526.     /*
  527.     **    This routine allocates a page_table with 'max_blocks + 1' entries.
  528.     **    This is because the page table needs one entry more than the number
  529.     **    of allocated blocks. If it fails to allocate a table for the maximum
  530.     **    number of blocks required, then it returns 0 - if it cannot allocate
  531.     **    enough space for this table, then there will not be enough memory for
  532.     **    a workable interpreter ... there isn't much point in trying to allocate
  533.     **    a smaller table.
  534.     **
  535.     **    It then tries to allocate a contiguous block of memory
  536.     **    that is at least 'max_blocks * BLOCK_SIZE' bytes long. If one
  537.     **    is not available, 'BLOCK_SIZE' is continually subtracted from
  538.     **    this amount, and it tries again.
  539.     */
  540.  
  541.     extern byte_ptr            base_ptr ;
  542.     extern page_table_ptr    strt_page_table ;
  543.  
  544.     long                    size ;
  545.  
  546.     size = ((long)max_blocks + 1 ) * sizeof ( page_table_t ) ;
  547.     if ((strt_page_table = (page_table_ptr) MALLOC(size)) == (page_table_ptr)0)
  548.     {
  549.         base_ptr = (byte_ptr)0 ;
  550.         return ( (word)0 ) ;
  551.     }
  552.     size = (long)max_blocks * BLOCK_SIZE ;
  553.     while ((size != 0) && ((base_ptr = (byte_ptr) MALLOC(size)) == (byte_ptr)0))
  554.         size -= BLOCK_SIZE ;
  555.     return ((word)( size / (long)BLOCK_SIZE )) ;
  556. }
  557.  
  558. Void
  559. deallocate ()
  560. {
  561.     extern byte_ptr            base_ptr ;
  562.     extern page_table_ptr    strt_page_table ;
  563.  
  564.     if ( base_ptr != (byte_ptr)0 )
  565.     {
  566.         FREE ( base_ptr ) ;
  567.         base_ptr = (byte_ptr)0 ;
  568.     }
  569.     if ( strt_page_table != (page_table_ptr)0 )
  570.     {
  571.         FREE ( strt_page_table ) ;
  572.         strt_page_table = (page_table_ptr)0 ;
  573.     }
  574. }
  575.  
  576. Void
  577. seed_random ()
  578. {
  579.     /*
  580.     **    This routine seeds the random number generator.
  581.     */
  582.  
  583.     extern word        random1 ;
  584.     extern word        random2 ;
  585.  
  586.     random1 = (word)(TIME_FUNCTION >> 16) ;
  587.     random2 = (word)TIME_FUNCTION ;
  588. }
  589.  
  590. /*
  591. **    Default Signal Trapping Routine.
  592. */
  593.  
  594. /*ARGSUSED*/
  595. Void
  596. default_signal_init ( sig_action )
  597. int        sig_action ;
  598. {
  599.     /*
  600.     **    Do nothing ...
  601.     */
  602. }
  603.  
  604. /*ARGSUSED*/
  605. Void
  606. default_signal_quit ( sig_action )
  607. int        sig_action ;
  608. {
  609.     /*
  610.     **    Do nothing ...
  611.     */
  612. }
  613.  
  614.  
  615. #ifdef OSK
  616.  
  617. int
  618. osk_time()
  619. {
  620.     long    longtime;
  621.     int        time,date,tick;
  622.     short    day;
  623.  
  624.     _sysdate(1,&time,&date,&day,&tick);
  625.     longtime = (date-2440000) * 24 * 60 * 60 + time;
  626.     return(longtime);
  627. }
  628.  
  629. Void
  630. osk_signal_ignore ( Sig )
  631. int    Sig;
  632. {
  633.     if (Sig != 3) signal_shit(Sig);
  634. }
  635.  
  636. #ifndef sg_pause
  637. #include <sgstat.h>
  638. #endif
  639.  
  640. static    struct    sgbuf    oldopts;
  641.  
  642. /*ARGSUSED*/
  643. Void
  644. osk_signal_init ( sig_action )
  645. int        sig_action ;
  646. {
  647.     struct    sgbuf    opts;
  648.  
  649.     intercept(osk_signal_ignore);
  650.     _gs_opt(0,&oldopts);
  651.     _gs_opt(0,&opts);
  652.     opts.sg_pause = 0;
  653.     opts.sg_eofch = 0;
  654.     opts.sg_kbich = 0;
  655.     _ss_opt(0,&opts);
  656. }
  657.  
  658. /*ARGSUSED*/
  659. Void
  660. osk_signal_quit ( sig_action )
  661. int        sig_action ;
  662. {
  663.     _ss_opt(0,&oldopts);
  664. }
  665.  
  666.  
  667. #ifdef KWINDOWS
  668. /*
  669. **    The Enhanced Windowing I/O Functions.
  670. */
  671.  
  672. #ifdef writeln
  673. #undef writeln
  674. #endif
  675.  
  676. static            int        fs_x,fs_y,cur_x,cur_y;
  677. static            int        win_y1,win_y2;
  678. static            word    curtext = NORMAL_MODE;
  679.  
  680. #define kwin_cwarea(p,a,b,c,d)    CWArea(p,a,win_y1=(b),c,win_y2=(d))
  681.  
  682. Void
  683. kwin_init_io()
  684. {
  685.     extern int        screen_width ;
  686.     extern int        screen_height ;
  687.  
  688.     _gs_scsz(1,&fs_x,&fs_y);
  689.     screen_width  = fs_x;
  690.     screen_height = fs_y;
  691.     Clear(1);
  692.     CurXY(1,0,fs_y-1);
  693. }
  694.  
  695. Void
  696. kwin_exit_io()
  697. {
  698.     char cr = '\n';
  699.  
  700.     _ss_opt(0,&oldopts);
  701.     CWArea(1,0,0,fs_x,fs_y);
  702.     CurXY(1,0,fs_y-1);
  703.     writeln(1,&cr,1);
  704. }
  705.  
  706. Void
  707. kwin_putchar ( c )
  708. char    c ;
  709. {
  710.     extern word        text_mode ;
  711.     extern boolean    enable_screen ;
  712.  
  713.     switch ( c )
  714.     {
  715.         case 1:
  716.                 text_mode = NORMAL_MODE ;
  717.                 break ;
  718.         case 2:
  719.                 text_mode |= INVERSE_MODE ;
  720.                 break ;
  721.         case 3:
  722.                 text_mode |= BOLD_MODE ;
  723.                 break ;
  724.         case 4:
  725.                 break ;
  726.         case 5:
  727.                 text_mode |= UNDERLINE_MODE ;
  728.                 break ;
  729.         case 0:
  730.                 c = ' ' ;
  731.  
  732.                 /*
  733.                 **    Fall Through ...
  734.                 */
  735.  
  736.         default:
  737.                 if ( enable_screen )
  738.                 {
  739.                     if (text_mode != curtext) {
  740.                         if (text_mode & INVERSE_MODE) {
  741.                             RevOn(1);
  742.                         } else {
  743.                             RevOff(1);
  744.                         }
  745.                         if (text_mode & UNDERLINE_MODE) {
  746.                             UndlnOn(1);
  747.                         } else {
  748.                             UndlnOff(1);
  749.                         }
  750.                         curtext = text_mode;
  751.                     }
  752.                     if (c == '\b') {
  753.                         if (cur_x > 1) {
  754.                                         write(1,&c,1);
  755.                             c = ' ';    write(1,&c,1);
  756.                             c = '\b';    write(1,&c,1);
  757.                             cur_x--;
  758.                         }
  759.                     } else {
  760.                         writeln(1,&c,1);
  761.                         if (c == '\n') {
  762.                             cur_x = 0;    cur_y++;
  763.                             if (cur_y >= win_y2) cur_y = win_y2-1;
  764.                         } else {
  765.                             cur_x++;
  766.                         }
  767.                     }
  768.                 }
  769.                 break ;
  770.     }
  771. }
  772.  
  773. Void
  774. kwin_goto_xy(x,y)
  775. int x,y;
  776. {
  777.     CurXY(1,x,y);
  778.     cur_x = x;
  779.     cur_y = y;
  780. }
  781.  
  782. int
  783. kwin_get_x()
  784. {
  785.     return(0);
  786. /*    return(cur_x);    */
  787. }
  788.  
  789. int
  790. kwin_get_y()
  791. {
  792.     return(cur_y);
  793. }
  794.  
  795. Void
  796. kwin_use_window ( the_window )
  797. word    the_window ;
  798. {
  799.     extern word        window_height ;
  800.  
  801.     switch ( the_window )
  802.     {
  803.         case WINDOW_0:
  804.                         /*
  805.                         **    Use the Lower Window.
  806.                         */
  807.  
  808.                         kwin_cwarea(1, 0,window_height, fs_x,fs_y-window_height);
  809.                         break ;
  810.         case WINDOW_1:
  811.                         /*
  812.                         **    Use the Upper Window.
  813.                         */
  814.                         
  815.                         kwin_cwarea(1, 0,0, fs_x,window_height+1);
  816.                         break ;
  817.         case FULL_SCREEN:
  818.                         /*
  819.                         **    Use the entire Screen.
  820.                         */
  821.                         
  822.                         kwin_cwarea(1, 0,0, fs_x,fs_y);
  823.                         break ;
  824.     }
  825. }
  826.  
  827.  
  828. int
  829. kwin_get_ch()
  830. {
  831.     struct    sgbuf    opts;
  832.     char    letter,echo;
  833.  
  834.     _gs_opt(0,&opts);
  835.     echo = opts.sg_echo;
  836.     opts.sg_echo = 0;
  837.     _ss_opt(0,&opts);
  838.  
  839.     do {
  840.         read(0,&letter,1);
  841.     } while (letter < 32 && letter != '\b' && letter != '\n');
  842.  
  843.     opts.sg_echo = echo;
  844.     _ss_opt(0,&opts);
  845.     return(letter);
  846. }
  847.  
  848. int
  849. kwin_kbd_hit()
  850. {
  851.     return( (_gs_rdy(1) > 0) ? 1 : 0 );
  852. }
  853.  
  854. Void
  855. kwin_erase_eoln()
  856. {
  857.     ErEOLine(1);
  858. }
  859.  
  860. Void
  861. kwin_erase_win(top_of_window, bottom_of_window)
  862. word    top_of_window, bottom_of_window;
  863. {
  864.     CWArea(1, 0,top_of_window+win_y1, fs_x,bottom_of_window-top_of_window+win_y1);
  865.     Clear();
  866.     CWArea(1, 0,win_y1, fs_x,win_y2);
  867.     CurXY(1,cur_x,cur_y);
  868. }
  869.  
  870. #endif /* KWINDOWS */
  871.  
  872. #endif
  873.  
  874.  
  875. /*ARGSUSED*/
  876. Void
  877. signal_shit ( action )
  878. int        action ;
  879. {
  880.     extern int    sig_async ;
  881.     extern int    sig_action ;
  882.  
  883.     switch ( sig_async )
  884.     {
  885.         case SH_INIT:
  886.                         /*
  887.                         **    Close I/O, files and memory.
  888.                         **    "main ()" will call "SIG_QUIT ()".
  889.                         */
  890.  
  891.                         sig_action |= ( SH_CLOSE | SH_IO ) ;
  892.                         break ;
  893.         case SH_NORMAL:
  894.                         /*
  895.                         **    Close I/O, files and memory. Do it NOW !
  896.                         */
  897.  
  898.                         SIGNAL_QUIT ( sig_action | SH_CLOSE | SH_IO ) ;
  899.                         break ;
  900.         case SH_NO_IO:
  901.                         /*
  902.                         **    Close files and memory only. Do it NOW !
  903.                         */
  904.  
  905.                         SIGNAL_QUIT ( sig_action | SH_CLOSE ) ;
  906.                         break ;
  907.         default:
  908.                         break ;
  909.     }
  910. }
  911.  
  912.  
  913. /*ARGSUSED*/
  914. Void
  915. signal_chit ( action )
  916. int        action ;
  917. {
  918.     extern int    sig_action ;
  919.  
  920.     /*
  921.     **    Request a core dump.
  922.     */
  923.  
  924.     sig_action |= SH_COREDUMP ;
  925.     signal_shit () ;
  926. }
  927.  
  928. /*
  929. **    Default I/O Routines.
  930. */
  931.  
  932. Void
  933. null_io ()
  934. {
  935.     /*
  936.     **    Do nothing ...
  937.     */
  938. }
  939.  
  940. Void
  941. default_putchar ( c )
  942. char    c ;
  943. {
  944.     extern boolean    enable_screen ;
  945.  
  946.     switch ( c )
  947.     {
  948.         case 1:
  949.         case 2:
  950.         case 3:
  951.         case 4:
  952.         case 5:
  953.                 /*
  954.                 **    Special Text Modes.
  955.                 */
  956.  
  957.                 break ;
  958.         case 0:
  959.                 c = ' ' ;
  960.  
  961.                 /*
  962.                 **    Fall Through ...
  963.                 */
  964.  
  965.         default:
  966.                 if ( enable_screen )
  967.                     putchar ( c ) ;
  968.                 break ;
  969.     }
  970. }
  971.  
  972. Void
  973. default_goto_xy ( x,y )
  974. int        x,y ;
  975. {
  976.     out_char ( '\n' ) ;
  977. }
  978.  
  979. int
  980. default_get_x ()
  981. {
  982.     return ( 0 ) ;
  983. }
  984.  
  985. int
  986. default_get_y ()
  987. {
  988.     extern int    screen_height ;
  989.  
  990.     return ( screen_height - 1 ) ;
  991. }
  992.  
  993. /*
  994. **    The Enhanced Windowing Default I/O Functions.
  995. */
  996.  
  997. int        saved_cursor_x ;
  998. int        saved_cursor_y ;
  999.  
  1000. Void
  1001. default_save_cursor ()
  1002. {
  1003.     extern int    saved_cursor_x ;
  1004.     extern int    saved_cursor_y ;
  1005.  
  1006.     saved_cursor_x = GET_X () ;
  1007.     saved_cursor_y = GET_Y () ;
  1008. }
  1009.  
  1010. Void
  1011. default_restore_cursor ()
  1012. {
  1013.     Void        GOTO_XY () ;
  1014.  
  1015.     extern int    saved_cursor_x ;
  1016.     extern int    saved_cursor_y ;
  1017.  
  1018.     GOTO_XY ( saved_cursor_x,saved_cursor_y ) ;
  1019. }
  1020.  
  1021. /*
  1022. **    The PLUS Series Default I/O Functions.
  1023. */
  1024.  
  1025. int
  1026. default_kbd_hit ()
  1027. {
  1028.     return ( TRUE ) ;
  1029. }
  1030.  
  1031. /*
  1032. **    Lightspeed C Version 2.01 I/O Routines.
  1033. **
  1034. **    Only compiled if LSC is defined.
  1035. */
  1036.  
  1037. #ifdef    LSC
  1038.  
  1039. #undef        FALSE
  1040. #undef        TRUE
  1041. #include    <Quickdraw.h>
  1042. #define        FALSE        (0)
  1043. #define        TRUE        (!FALSE)
  1044.  
  1045. FontInfo    fi ;
  1046. Rect        full_screen ;
  1047. int            line_height ;
  1048.  
  1049. Void
  1050. lsc_init_io ()
  1051. {
  1052.     extern FontInfo        fi ;
  1053.     extern Rect            full_screen ;
  1054.     extern int            line_height ;
  1055.     extern word            top_screen_line ;
  1056.  
  1057.     GetFontInfo ( &fi ) ;
  1058.     line_height = fi.ascent + fi.descent + fi.leading ;
  1059.     thePort -> portRect.top += top_screen_line * line_height ;
  1060.     full_screen = thePort -> portRect ;
  1061. }
  1062.  
  1063. #define        CHAR_OFFSET        1
  1064.  
  1065. Void
  1066. lsc_putchar ( c )
  1067. char    c ;
  1068. {
  1069.     extern FontInfo    fi ;
  1070.     extern boolean    enable_screen ;
  1071.     extern word        text_mode ;
  1072.  
  1073.     Point            pn_loc ;
  1074.     RgnHandle        update ;
  1075.     Rect            r ;
  1076.  
  1077.     switch ( c )
  1078.     {
  1079.         case 1:
  1080.                 text_mode = NORMAL_MODE ;
  1081.                 break ;
  1082.         case 2:
  1083.                 text_mode |= INVERSE_MODE ;
  1084.                 break ;
  1085.         case 3:
  1086.                 text_mode |= BOLD_MODE ;
  1087.                 break ;
  1088.         case 4:
  1089.                 break ;
  1090.         case 5:
  1091.                 text_mode |= UNDERLINE_MODE ;
  1092.                 break ;
  1093.         case 0:
  1094.                 c = ' ' ;
  1095.  
  1096.                 /*
  1097.                 **    Fall Through ...
  1098.                 */
  1099.  
  1100.         default:
  1101.                 if ( enable_screen )
  1102.                 {
  1103.                     GetPen ( &pn_loc ) ;
  1104.                     SetRect ( &r,pn_loc.h-CHAR_OFFSET,pn_loc.v-fi.ascent,pn_loc.h+fi.widMax,pn_loc.v+fi.descent ) ;
  1105.                     EraseRect ( &r ) ;
  1106.                     if ( text_mode & BOLD_MODE )
  1107.                     {
  1108.                         TextFace ( bold ) ;
  1109.                         putchar ( c ) ;
  1110.                         TextFace ( 0 ) ;
  1111.                         update = NewRgn () ;
  1112.                         ScrollRect ( &r,-CHAR_OFFSET,0,update ) ;
  1113.                         DisposeRgn ( update ) ;
  1114.                         GOTO_XY ( GET_X (),GET_Y () ) ;
  1115.                     }
  1116.                     else
  1117.                         putchar ( c ) ;
  1118.                     if ( text_mode & UNDERLINE_MODE )
  1119.                     {
  1120.                         MoveTo ( pn_loc.h-CHAR_OFFSET,pn_loc.v+fi.descent-1 ) ;
  1121.                         LineTo ( pn_loc.h+fi.widMax,pn_loc.v+fi.descent-1 ) ;
  1122.                         GOTO_XY ( GET_X (),GET_Y () ) ;
  1123.                     }
  1124.                     if ( text_mode & INVERSE_MODE )
  1125.                         InvertRect ( &r ) ;
  1126.                 }
  1127.                 break ;
  1128.     }
  1129. }
  1130.  
  1131. /*
  1132. **    The Enhanced Windowing LSC I/O Functions.
  1133. */
  1134.  
  1135. Void
  1136. lsc_use_window ( the_window )
  1137. word    the_window ;
  1138. {
  1139.     extern word        window_height ;
  1140.     extern Rect        full_screen ;
  1141.     extern int        line_height ;
  1142.  
  1143.     switch ( the_window )
  1144.     {
  1145.         case WINDOW_0:
  1146.                         /*
  1147.                         **    Use the Lower Window.
  1148.                         */
  1149.                         
  1150.                         thePort -> portRect.top = full_screen.top + window_height * line_height ;
  1151.                         thePort -> portRect.bottom = full_screen.bottom ;
  1152.                         break ;
  1153.         case WINDOW_1:
  1154.                         /*
  1155.                         **    Use the Upper Window.
  1156.                         */
  1157.                         
  1158.                         thePort -> portRect.top = full_screen.top ;
  1159.                         thePort -> portRect.bottom = full_screen.top + window_height * line_height ;
  1160.                         break ;
  1161.         case FULL_SCREEN:
  1162.                         /*
  1163.                         **    Use the entire Screen.
  1164.                         */
  1165.                         
  1166.                         thePort -> portRect.top = full_screen.top ;
  1167.                         thePort -> portRect.bottom = full_screen.bottom ;
  1168.                         break ;
  1169.     }
  1170. }
  1171.  
  1172. #define        _CONTROLWIDTH    15        /* Width of Scroll Bar */
  1173. #define        _LEFTEDGE        4        /* Margins             */
  1174. #define        _TOPEDGE        4
  1175.  
  1176. Void
  1177. lsc_erase_window ( top_of_window,bottom_of_window )
  1178. word    top_of_window ;
  1179. word    bottom_of_window ;
  1180. {
  1181.     extern Rect        full_screen ;
  1182.     extern int        line_height ;
  1183.     extern int        screen_height ;
  1184.     extern word        top_screen_line ;
  1185.     
  1186.     Rect            r ;
  1187.  
  1188.     /*
  1189.     **    The problem with using Lightspeed C stdio is that when erasing
  1190.     **    the console window, its text buffer should also be cleared. Since
  1191.     **    this is quite tricky, we fudge it by printing a '\f' character
  1192.     **    when clearing the whole screen. When the screen is only partially
  1193.     **    cleared, we do not clear those lines from the console window's
  1194.     **    screen buffer ... this may sometimes cause problems !!!
  1195.     */
  1196.             
  1197.     if    (
  1198.             ( top_of_window == top_screen_line )
  1199.             &&
  1200.             ( bottom_of_window == (word)screen_height )
  1201.         )
  1202.     {
  1203.         out_char ( '\f' ) ;
  1204.     }
  1205.     else
  1206.     {
  1207.         r.bottom = full_screen.top + bottom_of_window * line_height ;
  1208.         r.top = full_screen.top + _TOPEDGE + ( top_of_window - top_screen_line ) * line_height ;
  1209.         r.left = full_screen.left + _LEFTEDGE ;
  1210.         r.right = full_screen.right - _CONTROLWIDTH ;
  1211.         EraseRect ( &r ) ;
  1212.     }
  1213. }
  1214.  
  1215. /*
  1216. **    The PLUS Series LSC I/O Functions.
  1217. */
  1218.  
  1219. Void
  1220. lsc_erase_to_eoln ()
  1221. {
  1222.     /*
  1223.     **    The characters at the cursor and to the right are erased.
  1224.     **    The cursor itself is not moved.
  1225.     */
  1226.  
  1227.     extern int    screen_width ;
  1228.     int            saved_x_posn ;
  1229.     int            saved_y_posn ;
  1230.     int            i ;
  1231.  
  1232.     saved_x_posn = GET_X () ;
  1233.     saved_y_posn = GET_Y () ;
  1234.     for ( i = saved_x_posn ; i < screen_width ; i++ )
  1235.         out_char ( ' ' ) ;
  1236.     GOTO_XY ( saved_x_posn,saved_y_posn ) ;
  1237. }
  1238.  
  1239. #endif    /* LSC */
  1240.  
  1241. /*
  1242. **    MICROSOFT C I/O Routines
  1243. **
  1244. **    Only compiled if MSC defined.
  1245. */
  1246.  
  1247. #ifdef    MSC
  1248.  
  1249. #include    <graph.h>
  1250.  
  1251. boolean            isvideoinit        = FALSE ;
  1252. boolean            saved_vidpage ;
  1253. short            user_vidpage ;
  1254. char            chs[9] ;
  1255.  
  1256. Void
  1257. msc_textattr ( modestr )
  1258. long    *modestr ;
  1259. {
  1260.     int    i, maxi;
  1261.     int    textmode = 0;
  1262.  
  1263.     for (maxi = *modestr, i = 1; i <= maxi; i++)
  1264.     {
  1265.         if (modestr[i] >= A_BGOFFSET)
  1266.             _setbkcolor ( (int) modestr[i] - A_BGOFFSET ) ;
  1267.         else if (modestr[i] >= A_FGOFFSET)
  1268.             textmode |= (int) modestr[i] - A_FGOFFSET ;
  1269.         else if (modestr[i] == A_BLINK)
  1270.             textmode |= 0x10 ;
  1271.         else if (modestr[i] == A_HIGH)
  1272.             textmode |= 0x08 ;
  1273.     }
  1274.     _settextcolor ( textmode ) ;
  1275. }
  1276.  
  1277. Void
  1278. msc_init_io ()
  1279. {
  1280.     extern boolean        enhanced ;
  1281.     extern boolean        isvideoinit ;
  1282.     extern int            screen_width ;
  1283.     extern int            screen_height ;
  1284.     extern word            text_mode ;
  1285.     extern boolean        saved_vidpage ;
  1286.     extern short        user_vidpage ;
  1287.  
  1288.     struct videoconfig    conf ;
  1289.     short                npages ;
  1290.     short                newvidpage ;
  1291.  
  1292.     enhanced = TRUE ;
  1293.     isvideoinit = TRUE ;
  1294.     _getvideoconfig ( &conf ) ;
  1295.     screen_width = conf.numtextcols ;
  1296.     screen_height = conf.numtextrows ;
  1297.  
  1298.     default_attrs () ;
  1299.     read_rcfile () ;
  1300.  
  1301.     if ( saved_vidpage = (( npages = conf.numvideopages ) > 1 ))
  1302.     {
  1303.         user_vidpage = _getactivepage () ;
  1304.         newvidpage = ( user_vidpage + 1 ) % npages ;
  1305.         _setactivepage ( newvidpage ) ;
  1306.     }
  1307.  
  1308.     text_mode = NORMAL_MODE ;
  1309.     msc_textattr ( vidc[NORMAL_MODE] ) ;
  1310.     _clearscreen ( _GCLEARSCREEN ) ;
  1311.     GOTO_XY ( 0,screen_height - 1 ) ;
  1312.     if ( saved_vidpage )
  1313.         _setvisualpage ( newvidpage ) ;
  1314. }
  1315.  
  1316. Void
  1317. msc_exit_io ()
  1318. {
  1319.     extern boolean    saved_vidpage ;
  1320.     extern short    user_vidpage ;
  1321.  
  1322.     if ( saved_vidpage )
  1323.     {
  1324.         _setactivepage ( user_vidpage ) ;
  1325.         _setvisualpage ( user_vidpage ) ;
  1326.     }
  1327. }
  1328.  
  1329. Void
  1330. msc_putchar ( c )
  1331. char    c ;
  1332. {
  1333.     extern boolean    enhanced ;
  1334.     extern boolean    isvideoinit ;
  1335.     extern boolean    enable_screen ;
  1336.     extern word        text_mode ;
  1337.     extern int        screen_width ;
  1338.     extern int        screen_height ;
  1339.     extern boolean    windowing_enabled ;
  1340.     extern word        window_height ;
  1341.     extern word        top_screen_line ;
  1342.     extern char        chs[] ;
  1343.  
  1344.     if ( isvideoinit )
  1345.     {
  1346.         switch ( c )
  1347.         {
  1348.             case 1:
  1349.                     text_mode = NORMAL_MODE ;
  1350.                     msc_textattr ( vidc[text_mode] ) ;
  1351.                     break ;
  1352.             case 2:
  1353.                     text_mode |= INVERSE_MODE ;
  1354.                     msc_textattr ( vidc[text_mode] ) ;
  1355.                     break ;
  1356.             case 3:
  1357.                     text_mode |= BOLD_MODE ;
  1358.                     msc_textattr ( vidc[text_mode] ) ;
  1359.                     break ;
  1360.             case 4:
  1361.                     break ;
  1362.             case 5:
  1363.                     text_mode |= UNDERLINE_MODE ;
  1364.                     msc_textattr ( vidc[text_mode] ) ;
  1365.                     break ;
  1366.             case 0:
  1367.                     c = ' ' ;
  1368.  
  1369.                     /*
  1370.                     **    Fall Through ...
  1371.                     */
  1372.  
  1373.             default:
  1374.                     if ( enable_screen )
  1375.                     {
  1376.                         if ( c == '\n' )
  1377.                         {
  1378.                             if ( GET_Y () == screen_height - 1 )
  1379.                             {
  1380.                                 if ( enhanced )
  1381.                                 {
  1382.                                     if ( windowing_enabled == TRUE )
  1383.                                     {
  1384.                                         _settextwindow ( window_height + top_screen_line + 1,1,screen_height,screen_width ) ;
  1385.                                         _scrolltextwindow ( _GSCROLLUP ) ;
  1386.                                         _settextwindow ( 1,1,screen_height,screen_width ) ;
  1387.                                         GOTO_XY ( 0,screen_height - 1 ) ;
  1388.                                     }
  1389.                                     else
  1390.                                         _outtext ( "\n" ) ;
  1391.                                 }
  1392.                                 else
  1393.                                     _outtext ( "\n" ) ;
  1394.                             }
  1395.                             else
  1396.                                 _outtext ( "\n" ) ;
  1397.                         }
  1398.                         else
  1399.                         {
  1400.                             if ( c < 0x20 )
  1401.                             {
  1402.                                 if ( c == '\b' )
  1403.                                 {
  1404.                                     /*
  1405.                                     **    destructive backspace
  1406.                                     */
  1407.  
  1408.                                     int        col ;
  1409.  
  1410.                                     col = GET_X () ;
  1411.                                     if ( col > 0 )
  1412.                                     {
  1413.                                         --col ;
  1414.                                         GOTO_XY ( col,GET_Y () ) ;
  1415.                                         chs[0] = ' ' ;
  1416.                                         chs[1] = '\0' ;
  1417.                                         _outtext ( chs ) ;
  1418.                                         GOTO_XY ( col,GET_Y () ) ;
  1419.                                     }
  1420.                                 }
  1421.                                 else
  1422.                                 {
  1423.                                     if ( c == '\t' )
  1424.                                     {
  1425.                                         int        n ;
  1426.                                         int        i ;
  1427.  
  1428.                                         n = 8 - (( GET_X () - 1 ) % 8 ) ;
  1429.                                         for ( i = 0 ; i < n ; i++ )
  1430.                                             chs[i] = ' ' ;
  1431.                                         chs[n] = '\0' ;
  1432.                                         _outtext ( chs ) ;
  1433.                                     }
  1434.                                 }
  1435.                             }
  1436.                             else
  1437.                             {
  1438.                                 chs[0] = c ;
  1439.                                 chs[1] = '\0' ;
  1440.                                 _outtext ( chs ) ;
  1441.                             }
  1442.                         }
  1443.                     }
  1444.                     break ;
  1445.         }
  1446.     }
  1447.     else
  1448.     {
  1449.         if ( enable_screen )
  1450.         {
  1451.             if ( c == '\0' )
  1452.                 c = ' ' ;
  1453.             if ( c > 5 )
  1454.                 putchar ( c ) ;
  1455.         }
  1456.     }
  1457. }
  1458.  
  1459. Void
  1460. msc_goto_xy ( x,y )
  1461. int        x,y ;
  1462. {
  1463.     _settextposition ( y+1,x+1 ) ;
  1464. }
  1465.  
  1466. int
  1467. msc_get_x ()
  1468. {
  1469.     struct rccoord    cursor ;
  1470.  
  1471.     cursor = _gettextposition () ;
  1472.     return ( cursor.col - 1 ) ;
  1473. }
  1474.  
  1475. int
  1476. msc_get_y ()
  1477. {
  1478.     struct rccoord    cursor ;
  1479.  
  1480.     cursor = _gettextposition () ;
  1481.     return ( cursor.row - 1 ) ;
  1482. }
  1483.  
  1484. /*
  1485. **    The Enhanced Windowing MICROSOFT I/O Functions.
  1486. */
  1487.  
  1488. Void
  1489. msc_erase_window ( top_of_window,bottom_of_window )
  1490. word    top_of_window ;
  1491. word    bottom_of_window ;
  1492. {
  1493.     extern int    screen_width ;
  1494.     extern int    screen_height ;
  1495.  
  1496.     _settextwindow ( top_of_window+1,1,bottom_of_window,screen_width ) ;
  1497.     _clearscreen ( _GWINDOW ) ;
  1498.     _settextwindow ( 1,1,screen_height,screen_width ) ;
  1499.     GOTO_XY ( 0,top_of_window ) ;
  1500. }
  1501.  
  1502. /*
  1503. **    The PLUS Series MICROSOFT I/O Functions.
  1504. */
  1505.  
  1506. Void
  1507. msc_erase_to_eoln ()
  1508. {
  1509.     extern int        screen_width ;
  1510.     extern int        screen_height ;
  1511.  
  1512.     int                row ;
  1513.     int                col ;
  1514.  
  1515.     col = GET_X () ;
  1516.     row = GET_Y () ;
  1517.     _settextwindow ( row+1,col+1,row+1,screen_width ) ;
  1518.     _clearscreen ( _GWINDOW ) ;
  1519.     _settextwindow ( 1,1,screen_height,screen_width ) ;
  1520.     GOTO_XY ( col,row ) ;
  1521. }
  1522.  
  1523. #endif    /* MSC */
  1524.  
  1525. /*
  1526. **    TURBO C I/O Routines
  1527. **
  1528. **    Only compiled if TURBOC defined.
  1529. */
  1530.  
  1531. #ifdef    TURBOC
  1532.  
  1533. #include    <conio.h>
  1534. #include    <signal.h>
  1535. /* #include    <string.h> */
  1536.  
  1537. #define        CTRL_C            ((byte)0x03)
  1538.  
  1539. boolean        isvideoinit        = FALSE ;
  1540.  
  1541. /*
  1542. **    The way to get more than 25 lines in TURBOC is to manipulate the
  1543. **    undocumented "_video" structure. The structure definition outlined
  1544. **    below is only a guess, but it seems to make sense. The address
  1545. **    "( &_video ) + 7" is what is used by "window ()", "gotoxy ()", etc. to
  1546. **    determine screen height. It is not initialised to above 25 in the
  1547. **    TURBOC startup routine, so "tc_init_io ()" does it explicitly ...
  1548. */
  1549.  
  1550. extern struct    video_def
  1551. {
  1552.     unsigned char    wleft_dec ;
  1553.     unsigned char    wtop_dec ;
  1554.     unsigned char    wright_dec ;
  1555.     unsigned char    wbottom_dec ;
  1556.     unsigned char    tattr ;
  1557.     unsigned char    nattr ;
  1558.     unsigned char    vmode ;
  1559.     unsigned char    srows ;
  1560.     unsigned char    scols ;
  1561. } _video ;
  1562.  
  1563. Void
  1564. tc_textattr ( modestr )
  1565. long    *modestr ;
  1566. {
  1567.     int    i, maxi;
  1568.     int    textmode = 0;
  1569.  
  1570.     for (maxi = *modestr, i = 1; i <= maxi; i++)
  1571.     {
  1572.         if (modestr[i] >= A_BGOFFSET)
  1573.             textmode |= (int) ( modestr[i] - A_BGOFFSET ) << 4 ;
  1574.         else if (modestr[i] >= A_FGOFFSET)
  1575.             textmode |= (int) modestr[i] - A_FGOFFSET ;
  1576.         else if (modestr[i] == A_BLINK)
  1577.             textmode |= 0x10 ;
  1578.         else if (modestr[i] == A_HIGH)
  1579.             textmode |= 0x08 ;
  1580.     }
  1581.     textattr ( textmode ) ;
  1582. }
  1583.  
  1584. Void
  1585. tc_init_io ()
  1586. {
  1587.     extern boolean    enhanced ;
  1588.     extern boolean    isvideoinit ;
  1589.     extern int        screen_width ;
  1590.     extern int        screen_height ;
  1591.     extern word        text_mode ;
  1592.  
  1593.     unsigned char    srows ;
  1594.  
  1595.     enhanced = TRUE ;
  1596.     isvideoinit = TRUE ;
  1597.  
  1598.     /*
  1599.     **    update TURBOC "_video" structure with BIOS
  1600.     **    data area values for screen size.
  1601.     */
  1602.  
  1603.     srows = peekb ( 0x40,0x84 ) + 1 ;
  1604.     if ( srows != 0 )
  1605.         _video.srows = srows ;
  1606.     _video.scols = peekb ( 0x40,0x4A ) ;
  1607.  
  1608.     screen_width = _video.scols ;
  1609.     screen_height = _video.srows ;
  1610.  
  1611.     default_attrs () ;
  1612.     read_rcfile () ;
  1613.  
  1614.     window ( 1,1,screen_width,screen_height ) ;
  1615.     text_mode = NORMAL_MODE ;
  1616.     tc_textattr ( vidc[NORMAL_MODE] ) ;
  1617.     clrscr () ;
  1618.     GOTO_XY ( 0,screen_height - 1 ) ;
  1619. }
  1620.  
  1621. Void
  1622. tc_putchar ( c )
  1623. char    c ;
  1624. {
  1625.     extern boolean    enhanced ;
  1626.     extern boolean    isvideoinit ;
  1627.     extern boolean    enable_screen ;
  1628.     extern word        text_mode ;
  1629.     extern int        screen_width ;
  1630.     extern int        screen_height ;
  1631.     extern boolean    windowing_enabled ;
  1632.     extern word        window_height ;
  1633.     extern word        top_screen_line ;
  1634.  
  1635.     if ( isvideoinit )
  1636.     {
  1637.         switch ( c )
  1638.         {
  1639.             case 1:
  1640.                     text_mode = NORMAL_MODE ;
  1641.                     tc_textattr ( vidc[text_mode] ) ;
  1642.                     break ;
  1643.             case 2:
  1644.                     text_mode |= INVERSE_MODE ;
  1645.                     tc_textattr ( vidc[text_mode] ) ;
  1646.                     break ;
  1647.             case 3:
  1648.                     text_mode |= BOLD_MODE ;
  1649.                     tc_textattr ( vidc[text_mode] ) ;
  1650.                     break ;
  1651.             case 4:
  1652.                     break ;
  1653.             case 5:
  1654.                     text_mode |= UNDERLINE_MODE ;
  1655.                     tc_textattr ( vidc[text_mode] ) ;
  1656.                     break ;
  1657.             case 0:
  1658.                     c = ' ' ;
  1659.  
  1660.                     /*
  1661.                     **    Fall Through ...
  1662.                     */
  1663.  
  1664.             default:
  1665.                     if ( enable_screen )
  1666.                     {
  1667.                         if ( c == '\n' )
  1668.                         {
  1669.                             if ( GET_Y () == screen_height - 1 )
  1670.                             {
  1671.                                 if ( enhanced )
  1672.                                 {
  1673.                                     if ( windowing_enabled == TRUE )
  1674.                                     {
  1675.                                         window ( 1,window_height + top_screen_line + 1,screen_width,screen_height ) ;
  1676.                                         gotoxy ( 1,screen_height - window_height - top_screen_line ) ;
  1677.                                         cprintf ( "\n\r" ) ;
  1678.                                         clreol () ;
  1679.                                         window ( 1,1,screen_width,screen_height ) ;
  1680.                                         GOTO_XY ( 0,screen_height - 1 ) ;
  1681.                                     }
  1682.                                     else
  1683.                                     {
  1684.                                         cprintf ( "\n\r" ) ;
  1685.                                         clreol () ;
  1686.                                     }
  1687.                                 }
  1688.                                 else
  1689.                                 {
  1690.                                     cprintf ( "\n\r" ) ;
  1691.                                     clreol () ;
  1692.                                 }
  1693.                             }
  1694.                             else
  1695.                                 cprintf ( "\n\r" ) ;
  1696.                         }
  1697.                         else
  1698.                         {
  1699.                             if ( c < 0x20 )
  1700.                             {
  1701.                                 if ( c == '\b' )
  1702.                                 {
  1703.                                     /*
  1704.                                     **    destructive backspace
  1705.                                     */
  1706.  
  1707.                                     int        col ;
  1708.  
  1709.                                     col = GET_X () ;
  1710.                                     if ( col > 0 )
  1711.                                     {
  1712.                                         --col ;
  1713.                                         GOTO_XY ( col,GET_Y () ) ;
  1714.                                         putch ( ' ' ) ;
  1715.                                         GOTO_XY ( col,GET_Y () ) ;
  1716.                                     }
  1717.                                 }
  1718.                                 else
  1719.                                 {
  1720.                                     if ( c == '\t' )
  1721.                                     {
  1722.                                         int        n ;
  1723.                                         int        i ;
  1724.  
  1725.                                         n = 8 - (( GET_X () - 1 ) % 8 ) ;
  1726.                                         for ( i = 0 ; i < n ; i++ )
  1727.                                             putch ( ' ' ) ;
  1728.                                     }
  1729.                                 }
  1730.                             }
  1731.                             else
  1732.                                 putch ( c ) ;
  1733.                         }
  1734.                     }
  1735.                     break ;
  1736.         }
  1737.     }
  1738.     else
  1739.     {
  1740.         if ( enable_screen )
  1741.         {
  1742.             if ( c == '\0' )
  1743.                 c = ' ' ;
  1744.             if ( c > 5 )
  1745.                 putchar ( c ) ;
  1746.         }
  1747.     }
  1748. }
  1749.  
  1750. Void
  1751. tc_goto_xy ( x,y )
  1752. int        x,y ;
  1753. {
  1754.     gotoxy ( x+1,y+1 ) ;
  1755. }
  1756.  
  1757. int
  1758. tc_get_x ()
  1759. {
  1760.     return ( wherex () - 1 ) ;
  1761. }
  1762.  
  1763. int
  1764. tc_get_y ()
  1765. {
  1766.     return ( wherey () - 1 ) ;
  1767. }
  1768.  
  1769. int
  1770. tc_getch ()
  1771. {
  1772.     int        in_char ;
  1773.  
  1774.     if (( in_char = getch ()) == CTRL_C )
  1775.         raise ( SIGINT ) ;
  1776.     return ( in_char ) ;
  1777. }
  1778.  
  1779. /*
  1780. **    The Enhanced Windowing TURBOC I/O Functions.
  1781. */
  1782.  
  1783. Void
  1784. tc_erase_window ( top_of_window,bottom_of_window )
  1785. word    top_of_window ;
  1786. word    bottom_of_window ;
  1787. {
  1788.     extern int    screen_width ;
  1789.     extern int    screen_height ;
  1790.  
  1791.     window ( 1,top_of_window+1,screen_width,bottom_of_window ) ;
  1792.     clrscr () ;
  1793.     window ( 1,1,screen_width,screen_height ) ;
  1794.     GOTO_XY ( 0,top_of_window ) ;
  1795. }
  1796.  
  1797. /*
  1798. **    The PLUS Series TURBOC I/O Functions.
  1799. */
  1800.  
  1801. Void
  1802. tc_erase_to_eoln ()
  1803. {
  1804.     clreol () ;
  1805. }
  1806.  
  1807. #endif    /* TURBOC */
  1808.  
  1809. #ifdef ANSI_ESCAPE
  1810.  
  1811. static Void
  1812. ansi_textattr ( modestr )
  1813. long    *modestr ;
  1814. {
  1815.     char    attrstr[BUFSIZ];
  1816.     char    *p;
  1817.     int        i, maxi;
  1818.  
  1819.     strcpy ( attrstr,"\033[0" );
  1820.     p = attrstr + strlen ( attrstr ) ;
  1821.     for ( maxi = (int) *modestr, i = 1 ; i <= maxi ; i++ )
  1822.     {
  1823.         sprintf ( p,";%ld",modestr[i] ) ;
  1824.         p += strlen ( p ) ;
  1825.     }
  1826.     *p++ = 'm' ;
  1827.     *p = 0 ;
  1828.     raw_display ( attrstr ) ;
  1829. }
  1830.  
  1831. #endif /* ANSI_ESCAPE */
  1832.  
  1833. /*
  1834. **    MSDOS Signal Handling Routines.
  1835. */
  1836.  
  1837. #ifdef    MSDOS
  1838.  
  1839. #include    <signal.h>
  1840.  
  1841. Void
  1842. msdos_signal_init ()
  1843. {
  1844.     signal ( SIGINT,signal_shit ) ;
  1845.     signal ( SIGTERM,signal_shit ) ;
  1846. }
  1847.  
  1848. Void
  1849. msdos_signal_quit ( sig_action )
  1850. int        sig_action ;
  1851. {
  1852.     Void    EXIT_IO () ;
  1853.  
  1854.     if ( sig_action & SH_IO )
  1855.         EXIT_IO () ;
  1856.     if ( sig_action & SH_CLOSE )
  1857.     {
  1858.         close_script () ;
  1859.         close_file () ;
  1860.         deallocate () ;
  1861.     }
  1862.     if ( sig_action & SH_COREDUMP )
  1863.         abort () ;
  1864.     exit () ;
  1865. }
  1866.  
  1867. #ifndef    MSC
  1868. #ifndef    TURBOC
  1869. #ifdef    ANSI_ESCAPE
  1870.  
  1871. /*
  1872. **    MSDOS ANSI_ESCAPE I/O Routines.
  1873. **
  1874. **    Only compiled if MSDOS and ANSI_ESCAPE are defined.
  1875. */
  1876.  
  1877. Void
  1878. msdos_putchar ( c )
  1879. char    c ;
  1880. {
  1881.     extern boolean    enhanced ;
  1882.     extern boolean    enable_screen ;
  1883.     extern int        screen_width ;
  1884.     extern int        screen_height ;
  1885.     extern int        current_line ;
  1886.     extern boolean    windowing_enabled ;
  1887.     extern word        window_height ;
  1888.     extern word        top_screen_line ;
  1889.  
  1890.     union REGS        inregs ;
  1891.  
  1892.     switch ( c )
  1893.     {
  1894.         case 1:
  1895.                 text_mode = NORMAL_MODE ;
  1896.                 ansi_textattr ( vidc[text_mode] ) ;
  1897.                 break ;
  1898.         case 2:
  1899.                 text_mode |= INVERSE_MODE ;
  1900.                 ansi_textattr ( vidc[text_mode] ) ;
  1901.                 break ;
  1902.         case 3:
  1903.                 text_mode |= BOLD_MODE ;
  1904.                 ansi_textattr ( vidc[text_mode] ) ;
  1905.                 break ;
  1906.         case 4:
  1907.                 break ;
  1908.         case 5:
  1909.                 text_mode |= UNDERLINE_MODE ;
  1910.                 ansi_textattr ( vidc[text_mode] ) ;
  1911.                 break ;
  1912.         case 0:
  1913.                 c = ' ' ;
  1914.  
  1915.                 /*
  1916.                 **    Fall Through ...
  1917.                 */
  1918.  
  1919.         default:
  1920.                 if ( enable_screen )
  1921.                 {
  1922.                     if ( c == '\n' )
  1923.                     {
  1924.                         if ( current_line == screen_height - 1 )
  1925.                         {
  1926.                             if ( enhanced )
  1927.                             {
  1928.                                 if ( windowing_enabled == TRUE )
  1929.                                 {
  1930.                                     inregs.h.ah = 6 ;
  1931.                                     inregs.h.al = 1 ;
  1932.                                     inregs.h.bh = 7 ;
  1933.                                     inregs.h.ch = window_height + top_screen_line ;
  1934.                                     inregs.h.cl = 0 ;
  1935.                                     inregs.h.dh = screen_height - 1 ;
  1936.                                     inregs.h.dl = screen_width - 1 ;
  1937.                                     int86 ( 0x10,&inregs,&inregs ) ;
  1938.                                     GOTO_XY ( 0,screen_height - 1 ) ;
  1939.                                 }
  1940.                                 else
  1941.                                     putchar ( '\n' ) ;
  1942.                             }
  1943.                             else
  1944.                                 putchar ( '\n' ) ;
  1945.                         }
  1946.                         else
  1947.                         {
  1948.                             ++current_line ;
  1949.                             putchar ( '\n' ) ;
  1950.                         }
  1951.                     }
  1952.                     else
  1953.                         putchar ( c ) ;
  1954.                 }
  1955.                 break ;
  1956.     }
  1957. }
  1958.  
  1959. #endif    /* ANSI_ESCAPE */
  1960. #endif    /* TURBOC */
  1961. #endif    /* MSC */
  1962. #endif    /* MSDOS */
  1963.  
  1964. /*
  1965. **    ANSI_ESCAPE I/O Routines.
  1966. **
  1967. **    Only compiled if ANSI_ESCAPE is defined.
  1968. */
  1969.  
  1970. #ifdef    ANSI_ESCAPE
  1971.  
  1972. int        current_line ;
  1973. int        saved_current_line ;
  1974.  
  1975. Void
  1976. ansi_init_io ()
  1977. {
  1978.     extern int    screen_height ;
  1979.  
  1980.     /*
  1981.     **    Initialise the "current_line" variable using a call to "GOTO_XY".
  1982.     */
  1983.  
  1984. #ifdef UNIX
  1985.     unix_init_io();
  1986. #endif
  1987.  
  1988.     GOTO_XY ( 0,screen_height - 1 ) ;
  1989.  
  1990.     default_attrs () ;
  1991.     read_rcfile () ;
  1992.  
  1993.     ansi_textattr(vidc[NORMAL_MODE]);
  1994.  
  1995.     raw_display ( "\033[2J" ) ; /* clear screen */
  1996. }
  1997.  
  1998. Void
  1999. ansi_exit_io ()
  2000. {
  2001.     raw_display ( "\033[0m" ) ;
  2002.  
  2003. #ifdef UNIX
  2004.     unix_exit_io();
  2005. #endif
  2006. }
  2007.  
  2008. Void
  2009. ansi_putchar ( c )
  2010. char    c ;
  2011. {
  2012.     extern boolean    enhanced ;
  2013.     extern boolean    enable_screen ;
  2014.     extern int        screen_width ;
  2015.     extern int        screen_height ;
  2016.     extern int        current_line ;
  2017.     extern boolean    windowing_enabled ;
  2018.     extern word        window_height ;
  2019.     extern word        top_screen_line ;
  2020.  
  2021.     switch ( c )
  2022.     {
  2023.         case 1:
  2024.                 text_mode = NORMAL_MODE ;
  2025.                 ansi_textattr ( vidc[text_mode] ) ;
  2026.                 break ;
  2027.         case 2:
  2028.                 text_mode |= INVERSE_MODE ;
  2029.                 ansi_textattr ( vidc[text_mode] ) ;
  2030.                 break ;
  2031.         case 3:
  2032.                 text_mode |= BOLD_MODE ;
  2033.                 ansi_textattr ( vidc[text_mode] ) ;
  2034.                 break ;
  2035.         case 4:
  2036.                 break ;
  2037.         case 5:
  2038.                 text_mode |= UNDERLINE_MODE ;
  2039.                 ansi_textattr ( vidc[text_mode] ) ;
  2040.                 break ;
  2041.         case 0:
  2042.                 c = ' ' ;
  2043.  
  2044.                 /*
  2045.                 **    Fall Through ...
  2046.                 */
  2047.  
  2048.         default:
  2049.                 if ( enable_screen )
  2050.                 {
  2051.                     if ( c == '\n' )
  2052.                     {
  2053.                         if ( current_line == screen_height - 1 )
  2054.                         {
  2055.                             if ( enhanced )
  2056.                             {
  2057.                                 if ( windowing_enabled == TRUE )
  2058.                                 {
  2059.                                     GOTO_XY ( 0,window_height + top_screen_line ) ;
  2060.                                     raw_display ( "\033[1M" ) ;
  2061.                                     GOTO_XY ( 0,screen_height - 1 ) ;
  2062.                                 }
  2063.                                 else
  2064.                                     putchar ( '\n' ) ;
  2065.                             }
  2066.                             else
  2067.                                 putchar ( '\n' ) ;
  2068.                         }
  2069.                         else
  2070.                         {
  2071.                             ++current_line ;
  2072.                             putchar ( '\n' ) ;
  2073.                         }
  2074.                     }
  2075.                     else
  2076.                         putchar ( c ) ;
  2077.                 }
  2078.                 break ;
  2079.     }
  2080. }
  2081.  
  2082. Void
  2083. ansi_goto_xy ( x,y )
  2084. int        x,y ;
  2085. {
  2086.     extern int    current_line ;
  2087.  
  2088.     current_line = y ;
  2089.     ++x ;
  2090.     ++y ;
  2091.     raw_display ( "\033[" ) ;
  2092.     putchar ( (char)( y / 10 + '0' )) ;
  2093.     putchar ( (char)( y % 10 + '0' )) ;
  2094.     putchar ( ';' ) ;
  2095.     putchar ( (char)( x / 10 + '0' )) ;
  2096.     putchar ( (char)( x % 10 + '0' )) ;
  2097.     putchar ( 'H' ) ;
  2098. }
  2099.  
  2100. int
  2101. ansi_get_x ()
  2102. {
  2103.     return ( 0 ) ;
  2104. }
  2105.  
  2106. int
  2107. ansi_get_y ()
  2108. {
  2109.     extern int    current_line ;
  2110.  
  2111.     return ( current_line ) ;
  2112. }
  2113.  
  2114. /*
  2115. **    The Enhanced Windowing ANSI_ESCAPE I/O Functions.
  2116. */
  2117.  
  2118. Void
  2119. ansi_erase_window ( top_of_window,bottom_of_window )
  2120. word    top_of_window ;
  2121. word    bottom_of_window ;
  2122. {
  2123.     extern int        screen_width ;
  2124.     extern word        top_screen_line ;
  2125.  
  2126.     /*
  2127.     **    Erase Screen from the line specified by "top_of_window"
  2128.     **    to the line ABOVE that specified by "bottom_of_window".
  2129.     **    Leave Cursor at the top, left-hand corner of the erased window.
  2130.     */
  2131.  
  2132. #ifdef    SIMPLE_ANSI_ESCAPE
  2133.  
  2134.     word            i ;
  2135.  
  2136.     for ( i = bottom_of_window ; i > top_of_window ; i-- )
  2137.     {
  2138.         GOTO_XY ( 0,i-1 ) ;
  2139.         raw_display ( "\033[K" ) ;
  2140.     }
  2141.  
  2142. #else    /* SIMPLE_ANSI_ESCAPE */
  2143.  
  2144.     if ( top_of_window == top_screen_line )
  2145.     {
  2146.         GOTO_XY ( screen_width - 1,bottom_of_window - 1 ) ;
  2147.         raw_display ( "\033[1J" ) ;
  2148.         GOTO_XY ( 0,top_of_window ) ;
  2149.     }
  2150.     else
  2151.     {
  2152.         GOTO_XY ( 0,top_of_window ) ;
  2153.         raw_display ( "\033[0J" ) ;
  2154.     }
  2155.  
  2156. #endif    /* SIMPLE_ANSI_ESCAPE */
  2157. }
  2158.  
  2159. Void
  2160. ansi_save_cursor ()
  2161. {
  2162.     extern int    current_line ;
  2163.     extern int    saved_current_line ;
  2164.  
  2165.     saved_current_line = current_line ;
  2166.     if ( use_save_cursor )
  2167.         raw_display ( "\033[s" ) ;
  2168. }
  2169.  
  2170. Void
  2171. ansi_restore_cursor ()
  2172. {
  2173.     extern int    current_line ;
  2174.     extern int    saved_current_line ;
  2175.  
  2176.     current_line = saved_current_line ;
  2177.     if ( use_save_cursor )
  2178.         raw_display ( "\033[u" ) ;
  2179.     else
  2180.         GOTO_XY ( 0,current_line ) ;
  2181. }
  2182.  
  2183. /*
  2184. **    The PLUS Series ANSI_ESCAPE I/O Functions.
  2185. */
  2186.  
  2187. Void
  2188. ansi_erase_to_eoln ()
  2189. {
  2190.     raw_display ( "\033[K" ) ;
  2191. }
  2192.  
  2193. #endif    /* ANSI_ESCAPE */
  2194.  
  2195. /*
  2196. **    UNIX I/O Routines.
  2197. **
  2198. **    Only compiled if UNIX is defined.
  2199. */
  2200.  
  2201. #ifdef    UNIX
  2202.  
  2203. #ifdef    SYS_V
  2204. static struct termio    s ;
  2205. #endif    /* SYS_V */
  2206.  
  2207. #ifdef    BSD
  2208. static struct sgttyb    s ;
  2209. #endif    /* BSD */
  2210.  
  2211. #if defined(TIOCGWINSZ) && defined(SYS_V)
  2212. /* What??? TIOCGWINSZ in a System V box???  We better include the right files */
  2213. #include <sys/types.h>
  2214. #include <sys/stream.h>
  2215. #include <sys/ptem.h>
  2216. #endif
  2217.  
  2218. /* Sun window size ioctl supported */
  2219. /*ARGSUSED*/
  2220. static Void
  2221. signal_winch ( sig_action )
  2222. int        sig_action ;
  2223. {
  2224.     extern int    screen_height, screen_width ;
  2225.  
  2226. #if defined(TIOCGWINSZ)
  2227.     struct winsize    w ;
  2228.  
  2229.     if ( !ioctl ( fileno(stdin), TIOCGWINSZ, &w) )
  2230.     {
  2231.         screen_height = w.ws_row ;
  2232.         screen_width = w.ws_col ;
  2233.     }
  2234. #endif
  2235. }
  2236.  
  2237. Void
  2238. unix_init_io ()
  2239. {
  2240.     extern boolean    enhanced ;
  2241.  
  2242. #ifdef    SYS_V
  2243.  
  2244.     struct termio    t ;
  2245.  
  2246.     enhanced = TRUE ;
  2247.     ioctl ( fileno(stdin),TCGETA,&s ) ;
  2248.     ioctl ( fileno(stdin),TCGETA,&t ) ;
  2249.     t.c_iflag |= ICRNL ;
  2250.     t.c_lflag &= ~(ECHO | ICANON) ;
  2251.     t.c_cc[VMIN] = 1 ;
  2252.     t.c_cc[VTIME] = 0 ;
  2253.     ioctl ( fileno(stdin),TCSETA,&t ) ;
  2254.     setbuf(stdin, (char *)0);
  2255.  
  2256. #endif    /* SYS_V */
  2257.  
  2258. #ifdef    BSD
  2259.  
  2260.     struct sgttyb    t ;
  2261.  
  2262.     enhanced = TRUE ;
  2263.     ioctl ( fileno(stdin),TIOCGETP,&s ) ;
  2264.     ioctl ( fileno(stdin),TIOCGETP,&t ) ;
  2265.     t.sg_flags |= CBREAK ;
  2266.     t.sg_flags &= ~ECHO ;
  2267.     ioctl ( fileno(stdin),TIOCSETP,&t ) ;
  2268.  
  2269. #endif    /* BSD */
  2270.  
  2271.     signal_winch ( 0 ) ;
  2272. }
  2273.  
  2274. Void
  2275. unix_exit_io ()
  2276. {
  2277. #ifdef    SYS_V
  2278.  
  2279.     ioctl ( fileno(stdin),TCSETA,&s ) ;
  2280.  
  2281. #endif    /* SYS_V */
  2282.  
  2283. #ifdef    BSD
  2284.  
  2285.     ioctl ( fileno(stdin),TIOCSETP,&s ) ;
  2286.  
  2287. #endif    /* BSD */
  2288. }
  2289.  
  2290. /*
  2291. **    UNIX Signal Handling Routines.
  2292. */
  2293.  
  2294. #include    <signal.h>
  2295.  
  2296. Void
  2297. unix_signal_init ()
  2298. {
  2299.     signal ( SIGHUP,signal_shit ) ;
  2300.     signal ( SIGINT,signal_shit ) ;
  2301.     signal ( SIGTERM,signal_shit ) ;
  2302.     signal ( SIGQUIT,signal_chit ) ;
  2303. #ifdef SIGWINCH
  2304.     signal ( SIGWINCH, signal_winch ) ;
  2305. #endif
  2306. }
  2307.  
  2308. Void
  2309. unix_signal_quit ( sig_action )
  2310. int        sig_action ;
  2311. {
  2312.     Void    EXIT_IO () ;
  2313.  
  2314.     if ( sig_action & SH_IO )
  2315.         EXIT_IO () ;
  2316.     if ( sig_action & SH_CLOSE )
  2317.     {
  2318.         close_script () ;
  2319.         close_file () ;
  2320.         deallocate () ;
  2321.     }
  2322.     if ( sig_action & SH_COREDUMP )
  2323.         abort () ;
  2324.     exit (1) ;
  2325. }
  2326.  
  2327. #endif    /* UNIX */
  2328.  
  2329. /*
  2330. **    TERMCAP I/O Routines.
  2331. **
  2332. **    Only compiled if TERMCAP is defined.
  2333. */
  2334.  
  2335. #ifdef    TERMCAP
  2336.  
  2337. #ifdef OSK
  2338. #include <termcap.h>
  2339. char    PC_,*BC,*UP;
  2340. short    ospeed;
  2341. #endif
  2342.  
  2343. char        *CE ;                /* Cursor_Eoln      */
  2344. char        *CL ;                /* Clear_Screen     */
  2345. char        *CM ;                /* Cursor_Move      */
  2346. char        *DL ;                /* Delete_Line      */
  2347. char        *PDL ;                /* Parametised Delete_Line      */
  2348. char        *RC ;                /* Restore_Cursor   */
  2349. char        *SC ;                /* Save_Cursor      */
  2350. char        *SE ;                /* Stand_End        */
  2351. char        *SO ;                /* Stand_Out        */
  2352. char        *TE ;                /* Terminal_Exit    */
  2353. char        *TI ;                /* Terminal_Init    */
  2354. char        *UE ;                /* Underscore_End   */
  2355. char        *US ;                /* Underscore_Start */
  2356.  
  2357. char        cmdbuf[1024] ;
  2358. char        *cmd_p = cmdbuf ;
  2359. char        termbuf[1024] ;
  2360.  
  2361. char        *getenv() ;
  2362. char        *tgetstr() ;
  2363. char        *tgoto() ;
  2364.  
  2365. int            current_line ;
  2366. int            saved_current_line ;
  2367.  
  2368. Void
  2369. tcap_init_io ()
  2370. {
  2371.     extern int    screen_width ;
  2372.     extern int    screen_height ;
  2373.  
  2374.     char        *term ;
  2375.  
  2376. #ifdef    UNIX
  2377.     unix_init_io () ;
  2378. #endif    /* UNIX */
  2379.  
  2380.     cmd_p = cmdbuf ;
  2381.     if (((term = getenv("TERM")) == NULL) || tgetent( termbuf,term ) <= 0)
  2382.     {
  2383.         CE = CL = CM = DL = RC = SC = SE = SO = TE = TI = UE = US = "" ;
  2384.         return ;
  2385.     }
  2386.  
  2387.     if ((CE = tgetstr("ce", &cmd_p)) == NULL)
  2388.         CE = "" ;
  2389.     if ((CL = tgetstr("cl", &cmd_p)) == NULL)
  2390.         CL = "" ;
  2391.     if ((CM = tgetstr("cm", &cmd_p)) == NULL)
  2392.         CM = "" ;
  2393.     if ((DL = tgetstr("dl", &cmd_p)) == NULL)
  2394.         DL = "" ;
  2395.     if ((PDL = tgetstr("DL", &cmd_p)) == NULL)
  2396.         PDL = "" ;
  2397.     if
  2398.     (
  2399.         ((RC = tgetstr("rc", &cmd_p)) == NULL)
  2400.         ||
  2401.         ((SC = tgetstr("sc", &cmd_p)) == NULL)
  2402.     )
  2403.         RC = SC = "" ;
  2404.     if
  2405.     (
  2406.         ((SE = tgetstr("se", &cmd_p)) == NULL)
  2407.         ||
  2408.         ((SO = tgetstr("so", &cmd_p)) == NULL)
  2409.     )
  2410.         SE = SO = "" ;
  2411.     if
  2412.     (
  2413.         ((TE = tgetstr("te", &cmd_p)) == NULL)
  2414.         ||
  2415.         ((TI = tgetstr("ti", &cmd_p)) == NULL)
  2416.     )
  2417.         TE = TI = "" ;
  2418.     if
  2419.     (
  2420.         ((UE = tgetstr("ue", &cmd_p)) == NULL)
  2421.         ||
  2422.         ((US = tgetstr("us", &cmd_p)) == NULL)
  2423.     )
  2424.         UE = US = "" ;
  2425.  
  2426.     if ((screen_width = tgetnum("co")) == -1)
  2427.         screen_width = SCREEN_WIDTH ;
  2428.     if ((screen_height = tgetnum("li")) == -1)
  2429.         screen_height = SCREEN_HEIGHT ;
  2430.  
  2431.     tputs ( TI,0,out_char ) ;
  2432.     tputs ( CL,0,out_char ) ;
  2433.     GOTO_XY ( 0,screen_height-1 ) ;
  2434. }
  2435.  
  2436. Void
  2437. tcap_exit_io ()
  2438. {
  2439.     /*
  2440.     **    Turn off any modes before quitting.
  2441.     */
  2442.  
  2443.     if ( text_mode & INVERSE_MODE )
  2444.         tputs ( SE,0,out_char ) ;
  2445.     if ( text_mode & UNDERLINE_MODE )
  2446.         tputs ( UE,0,out_char ) ;
  2447.  
  2448.     tputs ( TE,0,out_char ) ;
  2449.  
  2450. #ifdef    UNIX
  2451.     unix_exit_io () ;
  2452. #endif    /* UNIX */
  2453. }
  2454.  
  2455. Void
  2456. tcap_putchar ( c )
  2457. char    c ;
  2458. {
  2459.     extern boolean    enhanced ;
  2460.     extern boolean    enable_screen ;
  2461.     extern int        screen_height ;
  2462.     extern int        current_line ;
  2463.     extern boolean    windowing_enabled ;
  2464.     extern word        window_height ;
  2465.     extern word        top_screen_line ;
  2466.  
  2467.     switch ( c )
  2468.     {
  2469.         case 1:
  2470.                 text_mode = NORMAL_MODE ;
  2471.                 tputs ( UE,0,out_char ) ;
  2472.                 tputs ( SE,0,out_char ) ;
  2473.                 break ;
  2474.         case 2:
  2475.                 text_mode |= INVERSE_MODE ;
  2476.                 tputs ( SO,0,out_char ) ;
  2477.                 break ;
  2478.         case 3:
  2479.                 /*
  2480.                 **    TERMCAP doesn't support Bold Text Modes.
  2481.                 */
  2482.  
  2483.                 text_mode |= BOLD_MODE ;
  2484.                 break ;
  2485.         case 4:
  2486.                 break ;
  2487.         case 5:
  2488.                 text_mode |= UNDERLINE_MODE ;
  2489.                 tputs ( US,0,out_char ) ;
  2490.                 break ;
  2491.         case 0:
  2492.                 c = ' ' ;
  2493.  
  2494.                 /*
  2495.                 **    Fall Through ...
  2496.                 */
  2497.  
  2498.         default:
  2499.                 if ( enable_screen )
  2500.                 {
  2501.                     if ( c == '\n' )
  2502.                     {
  2503.                         /*
  2504.                         **    Turn off any modes before printing a '\n'.
  2505.                         */
  2506.  
  2507.                         if ( text_mode & INVERSE_MODE )
  2508.                             tputs ( SE,0,out_char ) ;
  2509.                         if ( text_mode & UNDERLINE_MODE )
  2510.                             tputs ( UE,0,out_char ) ;
  2511.  
  2512.                         if ( current_line == screen_height - 1 )
  2513.                         {
  2514.                             if ( enhanced )
  2515.                             {
  2516.                                 if ( windowing_enabled == TRUE )
  2517.                                 {
  2518.                                     GOTO_XY ( 0,window_height + top_screen_line ) ;
  2519.                                     if ( DL )
  2520.                                         tputs ( DL,0,out_char ) ;
  2521.                                     else if ( PDL )
  2522.                                         tputs ( PDL,1,out_char ) ;
  2523.                                     GOTO_XY ( 0,screen_height - 1 ) ;
  2524.                                 }
  2525.                                 else
  2526.                                     putchar ( '\n' ) ;
  2527.                             }
  2528.                             else
  2529.                                 putchar ( '\n' ) ;
  2530.                         }
  2531.                         else
  2532.                         {
  2533.                             ++current_line ;
  2534.                             putchar ( '\n' ) ;
  2535.                         }
  2536.  
  2537.                         /*
  2538.                         **    Restore modes.
  2539.                         */
  2540.  
  2541.                         if ( text_mode & INVERSE_MODE )
  2542.                             tputs ( SO,0,out_char ) ;
  2543.                         if ( text_mode & UNDERLINE_MODE )
  2544.                             tputs ( US,0,out_char ) ;
  2545.                     }
  2546.                     else
  2547.                         putchar ( c ) ;
  2548.                 }
  2549.                 break ;
  2550.     }
  2551. }
  2552.  
  2553. Void
  2554. tcap_goto_xy ( x,y )
  2555. int        x,y ;
  2556. {
  2557.     extern int    current_line ;
  2558.  
  2559.     /*
  2560.     **    Turn off any modes before moving the cursor.
  2561.     */
  2562.  
  2563.     if ( text_mode & INVERSE_MODE )
  2564.         tputs ( SE,0,out_char ) ;
  2565.     if ( text_mode & UNDERLINE_MODE )
  2566.         tputs ( UE,0,out_char ) ;
  2567.  
  2568.     /*
  2569.     **    Move the cursor.
  2570.     */
  2571.  
  2572.     current_line = y ;
  2573.     tputs ( tgoto ( CM,x,y ),0,out_char ) ;
  2574.  
  2575.     /*
  2576.     **    Restore modes.
  2577.     */
  2578.  
  2579.     if ( text_mode & INVERSE_MODE )
  2580.         tputs ( SO,0,out_char ) ;
  2581.     if ( text_mode & UNDERLINE_MODE )
  2582.         tputs ( US,0,out_char ) ;
  2583. }
  2584.  
  2585. int
  2586. tcap_get_x ()
  2587. {
  2588.     return ( 0 ) ;
  2589. }
  2590.  
  2591. int
  2592. tcap_get_y ()
  2593. {
  2594.     extern int    current_line ;
  2595.  
  2596.     return ( current_line ) ;
  2597. }
  2598.  
  2599. /*
  2600. **    The Enhanced Windowing TERMCAP I/O Functions.
  2601. */
  2602.  
  2603. Void
  2604. tcap_erase_window ( top_of_window,bottom_of_window )
  2605. word    top_of_window ;
  2606. word    bottom_of_window ;
  2607. {
  2608.     extern int    screen_width ;
  2609.  
  2610.     int            i ;
  2611.  
  2612.     /*
  2613.     **    Erase Screen from the line specified by "top_of_window"
  2614.     **    to the line ABOVE that specified by "bottom_of_window".
  2615.     **    Leave Cursor at the top, left-hand corner of the erased window.
  2616.     */
  2617.  
  2618.     for ( i = (int)top_of_window ; i < (int)bottom_of_window ; i++ )
  2619.     {
  2620.         GOTO_XY ( 0,i ) ;
  2621.         tcap_erase_to_eoln () ;
  2622.     }
  2623.     GOTO_XY ( 0,top_of_window ) ;
  2624. }
  2625.  
  2626. Void
  2627. tcap_save_cursor ()
  2628. {
  2629.     extern int    current_line ;
  2630.     extern int    saved_current_line ;
  2631.  
  2632.     /*
  2633.     **    Turn off any modes before moving the cursor.
  2634.     */
  2635.  
  2636.     if ( text_mode & INVERSE_MODE )
  2637.         tputs ( SE,0,out_char ) ;
  2638.     if ( text_mode & UNDERLINE_MODE )
  2639.         tputs ( UE,0,out_char ) ;
  2640.  
  2641.     /*
  2642.     **    Save the cursor.
  2643.     */
  2644.  
  2645.     saved_current_line = current_line ;
  2646.     if ( *SC )
  2647.         tputs ( SC,0,out_char ) ;
  2648.  
  2649.     /*
  2650.     **    Restore modes.
  2651.     */
  2652.  
  2653.     if ( text_mode & INVERSE_MODE )
  2654.         tputs ( SO,0,out_char ) ;
  2655.     if ( text_mode & UNDERLINE_MODE )
  2656.         tputs ( US,0,out_char ) ;
  2657. }
  2658.  
  2659. Void
  2660. tcap_restore_cursor ()
  2661. {
  2662.     extern int    current_line ;
  2663.     extern int    saved_current_line ;
  2664.  
  2665.     /*
  2666.     **    Turn off any modes before moving the cursor.
  2667.     */
  2668.  
  2669.     if ( text_mode & INVERSE_MODE )
  2670.         tputs ( SE,0,out_char ) ;
  2671.     if ( text_mode & UNDERLINE_MODE )
  2672.         tputs ( UE,0,out_char ) ;
  2673.  
  2674.     /*
  2675.     **    Restore the cursor.
  2676.     */
  2677.  
  2678.     current_line = saved_current_line ;
  2679.     if ( *RC )
  2680.         tputs ( RC,0,out_char ) ;
  2681.     else
  2682.         GOTO_XY ( 0,current_line ) ;
  2683.  
  2684.     /*
  2685.     **    Restore modes.
  2686.     */
  2687.  
  2688.     if ( text_mode & INVERSE_MODE )
  2689.         tputs ( SO,0,out_char ) ;
  2690.     if ( text_mode & UNDERLINE_MODE )
  2691.         tputs ( US,0,out_char ) ;
  2692. }
  2693.  
  2694. /*
  2695. **    The PLUS Series TERMCAP I/O Functions.
  2696. */
  2697.  
  2698. Void
  2699. tcap_erase_to_eoln ()
  2700. {
  2701.     /*
  2702.     **    The characters at the cursor and to the right are erased.
  2703.     **    The cursor itself is not moved.
  2704.     */
  2705.  
  2706.     /*
  2707.     **    Turn off any modes before moving the cursor.
  2708.     */
  2709.  
  2710.     if ( text_mode & INVERSE_MODE )
  2711.         tputs ( SE,0,out_char ) ;
  2712.     if ( text_mode & UNDERLINE_MODE )
  2713.         tputs ( UE,0,out_char ) ;
  2714.  
  2715.     /*
  2716.     **    Erase the line.
  2717.     */
  2718.  
  2719.     tputs ( CE,0,out_char ) ;
  2720.  
  2721.     /*
  2722.     **    Restore modes.
  2723.     */
  2724.  
  2725.     if ( text_mode & INVERSE_MODE )
  2726.         tputs ( SO,0,out_char ) ;
  2727.     if ( text_mode & UNDERLINE_MODE )
  2728.         tputs ( US,0,out_char ) ;
  2729. }
  2730.  
  2731. #endif    /* TERMCAP */
  2732.  
  2733. /*
  2734. **    TERMINFO I/O Routines.
  2735. **
  2736. **    Only compiled if TERMINFO is defined.
  2737. */
  2738.  
  2739. #ifdef    TERMINFO
  2740.  
  2741. int            current_col ;
  2742. int            current_line ;
  2743. int            saved_current_col ;
  2744. int            saved_current_line ;
  2745. chtype        cur_attrs = A_NORMAL ;
  2746.  
  2747. #if defined(__STDC__)
  2748. #define    OUT_CHAR    (int (*)(char))out_char
  2749. #else
  2750. #define    OUT_CHAR    out_char
  2751. #endif
  2752.  
  2753. Void
  2754. tinfo_init_io ()
  2755. {
  2756.     extern int    screen_width ;
  2757.     extern int    screen_height ;
  2758.     Void        GOTO_XY () ;
  2759.  
  2760.     setupterm ((char *)0,1,(int *)0) ;
  2761.  
  2762.     screen_width = columns ;
  2763.     screen_height = lines ;
  2764.  
  2765.     putp ( enter_ca_mode ) ;
  2766.     putp ( clear_screen ) ;
  2767.     GOTO_XY ( 0,screen_height-1 ) ;
  2768.     vidattr ( cur_attrs = A_NORMAL ) ;
  2769.  
  2770. #ifdef    UNIX
  2771.     unix_init_io () ;
  2772. #endif    /* UNIX */
  2773. }
  2774.  
  2775. Void
  2776. tinfo_exit_io ()
  2777. {
  2778.     /*
  2779.     **    Turn off any modes before quitting.
  2780.     */
  2781.  
  2782. #ifdef    UNIX
  2783.     unix_exit_io () ;
  2784. #endif    /* UNIX */
  2785.  
  2786.     vidputs ( cur_attrs = A_NORMAL,OUT_CHAR ) ;
  2787.     tputs ( exit_ca_mode,1,OUT_CHAR ) ;
  2788.  
  2789.     reset_shell_mode () ;
  2790. }
  2791.  
  2792. Void
  2793. tinfo_putchar ( c )
  2794. char    c ;
  2795. {
  2796.     extern boolean    enhanced ;
  2797.     extern boolean    enable_screen ;
  2798.     extern int        screen_height ;
  2799.     extern int        current_line ;
  2800.     extern boolean    windowing_enabled ;
  2801.     extern word        window_height ;
  2802.     extern word        top_screen_line ;
  2803.     Void            GOTO_XY () ;
  2804.  
  2805.     switch ( c )
  2806.     {
  2807.         case 1:
  2808.                 vidputs ( cur_attrs = A_NORMAL,OUT_CHAR );
  2809.                 break ;
  2810.         case 2:
  2811.                 if ( enter_reverse_mode )
  2812.                     vidputs ( cur_attrs |= A_REVERSE,OUT_CHAR );
  2813.                 break ;
  2814.         case 3:
  2815.                 if ( enter_bold_mode )
  2816.                     vidputs ( cur_attrs |= A_BOLD,OUT_CHAR );
  2817.                 break ;
  2818.         case 4:
  2819.                 break ;
  2820.         case 5:
  2821.                 if ( enter_underline_mode )
  2822.                     vidputs ( cur_attrs |= A_UNDERLINE,OUT_CHAR );
  2823.                 break ;
  2824.         case 0:
  2825.                 c = ' ' ;
  2826.  
  2827.                 /*
  2828.                 **    Fall Through ...
  2829.                 */
  2830.  
  2831.         default:
  2832.                 if ( enable_screen )
  2833.                 {
  2834.                     if ( c == '\n' )
  2835.                     {
  2836.                         /*
  2837.                         **    Turn off any modes before printing a '\n'.
  2838.                         */
  2839.  
  2840.                         vidputs ( A_NORMAL,OUT_CHAR ) ;
  2841.  
  2842.                         if ( current_line == screen_height - 1 )
  2843.                         {
  2844.                             if ( enhanced )
  2845.                             {
  2846.                                 if ( windowing_enabled == TRUE )
  2847.                                 {
  2848.                                     GOTO_XY ( 0,window_height + top_screen_line ) ;
  2849.                                     if ( delete_line )
  2850.                                         tputs ( delete_line,1,OUT_CHAR ) ;
  2851.                                     else if ( parm_delete_line )
  2852.                                         tputs ( tparm ( parm_delete_line,1 ),1,OUT_CHAR ) ;
  2853.                                     GOTO_XY ( 0,screen_height - 1 ) ;
  2854.                                 }
  2855.                                 else
  2856.                                     putchar ( '\n' ) ;
  2857.                             }
  2858.                             else
  2859.                                 putchar ( '\n' ) ;
  2860.                         }
  2861.                         else
  2862.                         {
  2863.                             ++current_line ;
  2864.                             putchar ( '\r' ) ;
  2865.                             putchar ( '\n' ) ;
  2866.                         }
  2867.  
  2868.                         current_col = 0 ;
  2869.  
  2870.                         /*
  2871.                         **    Restore modes.
  2872.                         */
  2873.  
  2874.                         vidputs ( cur_attrs,OUT_CHAR ) ;
  2875.                     }
  2876.                     else
  2877.                     {
  2878.                         putchar ( c ) ;
  2879.                         ++current_col ;
  2880.                     }
  2881.                 }
  2882.                 break ;
  2883.     }
  2884. }
  2885.  
  2886. Void
  2887. tinfo_goto_xy ( x,y )
  2888. int        x,y ;
  2889. {
  2890.     extern int    current_line ;
  2891.  
  2892.     /*
  2893.     **    Turn off any modes before moving the cursor.
  2894.     */
  2895.  
  2896.     vidputs ( A_NORMAL,OUT_CHAR ) ;
  2897.  
  2898.     /*
  2899.     **    Move the cursor.
  2900.     */
  2901.  
  2902.     current_col = x ;
  2903.     current_line = y ;
  2904.     tputs ( tparm ( cursor_address,y,x ),0,OUT_CHAR ) ;
  2905.  
  2906.     /*
  2907.     **    Restore modes.
  2908.     */
  2909.  
  2910.     vidputs ( cur_attrs,OUT_CHAR ) ;
  2911. }
  2912.  
  2913. int
  2914. tinfo_get_x ()
  2915. {
  2916.     extern int    current_col ;
  2917.  
  2918.     return ( 0 ) ;
  2919. }
  2920.  
  2921. int
  2922. tinfo_get_y ()
  2923. {
  2924.     extern int    current_line ;
  2925.  
  2926.     return ( current_line ) ;
  2927. }
  2928.  
  2929. /*
  2930. **    The Enhanced Windowing TERMCAP I/O Functions.
  2931. */
  2932.  
  2933. Void
  2934. tinfo_erase_window ( top_of_window,bottom_of_window )
  2935. word    top_of_window ;
  2936. word    bottom_of_window ;
  2937. {
  2938.     Void        tinfo_erase_to_eoln () ;
  2939.     extern int    screen_width ;
  2940.  
  2941.     int            i ;
  2942.  
  2943.     /*
  2944.     **    Erase Screen from the line specified by "top_of_window"
  2945.     **    to the line ABOVE that specified by "bottom_of_window".
  2946.     **    Leave Cursor at the top, left-hand corner of the erased window.
  2947.     */
  2948.  
  2949.     for ( i = (int)top_of_window ; i < (int)bottom_of_window ; i++ )
  2950.     {
  2951.         GOTO_XY ( 0,i ) ;
  2952.         tinfo_erase_to_eoln () ;
  2953.     }
  2954.     GOTO_XY ( 0,top_of_window ) ;
  2955. }
  2956.  
  2957. Void
  2958. tinfo_save_cursor ()
  2959. {
  2960.     extern int    current_col ;
  2961.     extern int    current_line ;
  2962.     extern int    saved_current_col ;
  2963.     extern int    saved_current_line ;
  2964.  
  2965.     /*
  2966.     **    Turn off any modes before moving the cursor.
  2967.     */
  2968.  
  2969.     vidputs ( A_NORMAL,OUT_CHAR ) ;
  2970.  
  2971.     /*
  2972.     **    Save the cursor.
  2973.     */
  2974.  
  2975.     saved_current_col = current_col ;
  2976.     saved_current_line = current_line ;
  2977.     if ( save_cursor )
  2978.         tputs ( save_cursor,0,OUT_CHAR ) ;
  2979.  
  2980.     /*
  2981.     **    Restore modes.
  2982.     */
  2983.  
  2984.     vidputs ( cur_attrs,OUT_CHAR ) ;
  2985. }
  2986.  
  2987. Void
  2988. tinfo_restore_cursor ()
  2989. {
  2990.     extern int    current_col ;
  2991.     extern int    current_line ;
  2992.     extern int    saved_current_col ;
  2993.     extern int    saved_current_line ;
  2994.  
  2995.     /*
  2996.     **    Turn off any modes before moving the cursor.
  2997.     */
  2998.  
  2999.     vidputs ( A_NORMAL,OUT_CHAR ) ;
  3000.  
  3001.     /*
  3002.     **    Restore the cursor.
  3003.     */
  3004.  
  3005.     current_col = saved_current_col ;
  3006.     current_line = saved_current_line ;
  3007.     if ( restore_cursor )
  3008.         tputs ( restore_cursor,0,OUT_CHAR ) ;
  3009.     else
  3010.         GOTO_XY ( 0,current_line ) ;
  3011.  
  3012.     /*
  3013.     **    Restore modes.
  3014.     */
  3015.  
  3016.     vidputs ( cur_attrs,OUT_CHAR ) ;
  3017. }
  3018.  
  3019. /*
  3020. **    The PLUS Series TERMCAP I/O Functions.
  3021. */
  3022.  
  3023. Void
  3024. tinfo_erase_to_eoln ()
  3025. {
  3026.     /*
  3027.     **    The characters at the cursor and to the right are erased.
  3028.     **    The cursor itself is not moved.
  3029.     */
  3030.  
  3031.     /*
  3032.     **    Turn off any modes before moving the cursor.
  3033.     */
  3034.  
  3035.     vidputs ( A_NORMAL,OUT_CHAR ) ;
  3036.  
  3037.     /*
  3038.     **    Erase the line.
  3039.     */
  3040.  
  3041.     tputs ( clr_eol,1,OUT_CHAR ) ;
  3042.  
  3043.     /*
  3044.     **    Restore modes.
  3045.     */
  3046.  
  3047.     vidputs ( cur_attrs,OUT_CHAR ) ;
  3048. }
  3049.  
  3050. #endif    /* TERMINFO */
  3051.  
  3052. /*
  3053. **    CURSES I/O Routines.
  3054. **
  3055. **    Only compiled if CURSES is defined.
  3056. */
  3057.  
  3058. #ifdef    CURSES
  3059. #ifdef OSK
  3060. #define BSD
  3061. #endif
  3062.  
  3063. #ifndef BSD
  3064.  
  3065. static long    vida[8] ;
  3066.  
  3067. static Void
  3068. curses_init_attrs ()
  3069. {
  3070.     int        i,j,n ;
  3071.  
  3072.     for ( i = 0 ; i < 8 ; i++ )
  3073.     {
  3074.         short    fg = -1, bg = -1;
  3075.  
  3076.         vida[i] = A_NORMAL ;
  3077.  
  3078.         for ( n = vidc[i][0], j = 1 ; j <= n ; j++ )
  3079.         {
  3080.             long    mode = vidc[i][j] ;
  3081.  
  3082.             switch ( mode )
  3083.             {
  3084.             case    A_STANDOUT:
  3085.         /*    case    A_UNDERLINE:*/
  3086.         /*    case    A_REVERSE:    */
  3087.         /*    case    A_BLINK:    */
  3088.         /*    case    A_DIM:        */
  3089.         /*    case    A_BOLD:        */
  3090.                     vida[i] |= mode ;
  3091.                     break ;
  3092.  
  3093.             case    A_NORMAL:
  3094.                     vida[i] = A_NORMAL ;
  3095.                     break ;
  3096.             }
  3097.  
  3098. #ifdef WANT_COLOR
  3099.             if ( mode < A_BGOFFSET && mode >= A_FGOFFSET )
  3100.                 fg = mode - A_FGOFFSET;
  3101.  
  3102.             if ( mode <= A_CHARTEXT && mode >= A_BGOFFSET )
  3103.                 bg = mode - A_BGOFFSET;
  3104.  
  3105.             if ( fg >= 0 && bg >= 0 && has_colors () && i < COLOR_PAIRS )
  3106.             {
  3107.                 init_pair ( i + 1,fg,bg ) ;
  3108.                 vida[i] |= COLOR_PAIR ( i + 1 ) ;
  3109.             }
  3110. #endif
  3111.         }
  3112.     }
  3113. }
  3114.  
  3115. #endif
  3116.  
  3117. Void
  3118. curses_init_io ()
  3119. {
  3120.     extern boolean    enhanced ;
  3121.     extern int        screen_width ;
  3122.     extern int        screen_height ;
  3123.  
  3124.     /*
  3125.     **    If CURSES is being used, then "enhanced" should be TRUE.
  3126.     */
  3127.  
  3128.     default_attrs () ;
  3129.     read_rcfile () ;
  3130.     enhanced = TRUE ;
  3131.     initscr () ;
  3132.  
  3133. #ifdef WANT_COLOR
  3134.     start_color () ;
  3135. #endif
  3136.  
  3137.     screen_width = COLS ;
  3138.     screen_height = LINES ;
  3139.     nonl () ;
  3140. #if defined(cbreak)
  3141.     cbreak () ;
  3142. #elif defined(crmode)
  3143.     crmode () ;
  3144. #else
  3145. /*    @@@ I need either cbreak() or crmode() defined!!! @@@    */
  3146.     crmode();
  3147. #endif
  3148.     noecho () ;
  3149.     scrollok ( stdscr,1 ) ;
  3150.     scrollok ( curscr,1 ) ;
  3151. /*    idlok ( stdscr,1 ) ;
  3152.     idlok ( curscr,1 ) ;    */
  3153.     GOTO_XY ( 0,screen_height-1 ) ;
  3154.  
  3155. #ifdef SYS_V
  3156.     curses_init_attrs () ;
  3157.     attrset ( vida[text_mode = NORMAL_MODE] ) ;
  3158. #endif
  3159.  
  3160. }
  3161.  
  3162. Void
  3163. curses_exit_io ()
  3164. {
  3165. #ifdef SYS_V
  3166.     attrset ( A_NORMAL ) ;
  3167. #endif
  3168.     addch ( '\n' ) ;
  3169.     refresh () ;
  3170.     echo () ;
  3171. #if defined(nocbreak)
  3172.     nocbreak () ;
  3173. #elif defined(nocrmode)
  3174.     nocrmode () ;
  3175. #else
  3176. /*    @@@ I need either nocbreak() or nocrmode() defined!!! @@@    */
  3177.     nocrmode();
  3178. #endif
  3179.     nl () ;
  3180.     endwin () ;
  3181. }
  3182.  
  3183. Void
  3184. curses_putchar ( c )
  3185. char    c ;
  3186. {
  3187.     extern boolean    enable_screen ;
  3188.     extern int        screen_height ;
  3189.     extern boolean    windowing_enabled ;
  3190.     extern word        window_height ;
  3191.     extern word        top_screen_line ;
  3192.  
  3193.     switch ( c )
  3194.     {
  3195. #ifdef SYS_V
  3196.         case 1:
  3197.                 text_mode = NORMAL_MODE ;
  3198.                 attrset ( vida[text_mode] ) ;
  3199.                 break ;
  3200.         case 2:
  3201.                 text_mode |= INVERSE_MODE ;
  3202.                 attrset ( vida[text_mode] ) ;
  3203.                 break ;
  3204.         case 3:
  3205.                 text_mode |= BOLD_MODE ;
  3206.                 attrset ( vida[text_mode] ) ;
  3207.                 break ;
  3208.         case 4:
  3209.                 break ;
  3210.         case 5:
  3211.                 text_mode |= UNDERLINE_MODE ;
  3212.                 attrset ( vida[text_mode] ) ;
  3213.                 break ;
  3214. #endif    /* SYS_V */
  3215. #ifdef    BSD
  3216.         case 1:
  3217.                 standend () ;
  3218.                 break ;
  3219.         case 2:
  3220.                 standout () ;
  3221.                 break ;
  3222.         case 3:
  3223.                 standout () ;
  3224.                 break ;
  3225.         case 4:
  3226.                 break ;
  3227.         case 5:
  3228.                 standout () ;
  3229.                 break ;
  3230. #endif    /* BSD */
  3231.         case 0:
  3232.                 c = ' ' ;
  3233.  
  3234.                 /*
  3235.                 **    Fall Through ...
  3236.                 */
  3237.  
  3238.         default:
  3239.                 if ( enable_screen )
  3240.                 {
  3241.                     if ( c == '\n' )
  3242.                     {
  3243.                         if ( GET_Y () == screen_height - 1 )
  3244.                         {
  3245.                             if ( windowing_enabled == TRUE )
  3246.                             {
  3247.                                 GOTO_XY ( 0,window_height + top_screen_line ) ;
  3248.                                 deleteln () ;
  3249.                                 GOTO_XY ( 0,screen_height - 1 ) ;
  3250.                             }
  3251.                             else
  3252.                                 addch ( '\n' ) ;
  3253.                         }
  3254.                         else
  3255.                             addch ( '\n' ) ;
  3256.                     }
  3257.                     else
  3258.                         addch ( c ) ;
  3259.                 }
  3260.                 break ;
  3261.     }
  3262. }
  3263.  
  3264. Void
  3265. curses_goto_xy ( x,y )
  3266. int        x,y ;
  3267. {
  3268.     move ( y,x ) ;
  3269. }
  3270.  
  3271. int
  3272. curses_get_x ()
  3273. {
  3274.     int        x ;
  3275.     int        y ;
  3276.  
  3277.     /*
  3278.     **    "getyx ()" is a MACRO which returns integers in "x" and "y".
  3279.     **    Note that "x" and "y" are used here, not "&x" and "&y" as expected
  3280.     **    for variables being returned.
  3281.     */
  3282.  
  3283.     getyx ( stdscr,y,x ) ;
  3284.     return ( x ) ;
  3285. }
  3286.  
  3287. int
  3288. curses_get_y ()
  3289. {
  3290.     int        x ;
  3291.     int        y ;
  3292.  
  3293.     /*
  3294.     **    "getyx ()" is a MACRO which returns integers in "x" and "y".
  3295.     **    Note that "x" and "y" are used here, not "&x" and "&y" as expected
  3296.     **    for variables being returned.
  3297.     */
  3298.  
  3299.     getyx ( stdscr,y,x ) ;
  3300.     return ( y ) ;
  3301. }
  3302.  
  3303. /*
  3304. **    The Enhanced Windowing CURSES I/O Functions.
  3305. */
  3306.  
  3307. Void
  3308. curses_erase_window ( top_of_window,bottom_of_window )
  3309. word    top_of_window ;
  3310. word    bottom_of_window ;
  3311. {
  3312.     extern int    screen_width ;
  3313.  
  3314.     int            i ;
  3315.  
  3316.     /*
  3317.     **    Erase Screen from the line specified by "top_of_window"
  3318.     **    to the line ABOVE that specified by "bottom_of_window".
  3319.     **    Leave Cursor at the top, left-hand corner of the erased window.
  3320.     */
  3321.  
  3322.     for ( i = (int)top_of_window ; i < (int)bottom_of_window ; i++ )
  3323.     {
  3324.         GOTO_XY ( 0,i ) ;
  3325.         clrtoeol () ;
  3326.     }
  3327.     GOTO_XY ( 0,top_of_window ) ;
  3328. }
  3329.  
  3330. int
  3331. curses_get_ch ()
  3332. {
  3333.     refresh () ;
  3334.     return ( getch () ) ;
  3335. }
  3336.  
  3337. /*
  3338. **    The PLUS Series CURSES I/O Functions.
  3339. */
  3340.  
  3341. Void
  3342. curses_erase_to_eoln ()
  3343. {
  3344.     /*
  3345.     **    The characters at the cursor and to the right are erased.
  3346.     **    The cursor itself is not moved.
  3347.     */
  3348.  
  3349.     clrtoeol () ;
  3350. }
  3351.  
  3352. #ifdef OSK
  3353. #undef BSD
  3354. #endif
  3355. #endif    /* CURSES */
  3356.  
  3357. /*
  3358. **    THINK C Version 4.0 I/O Routines.
  3359. **
  3360. **    Only compiled if THINKC is defined.
  3361. */
  3362.  
  3363. #ifdef    THINKC
  3364.  
  3365. #undef        main
  3366.  
  3367. void
  3368. main ( argc,argv )
  3369. int        argc ;
  3370. char    *argv[] ;
  3371. {
  3372.     argc = ccommand ( &argv ) ;
  3373.     _main ( argc,argv ) ;
  3374. }
  3375.  
  3376. #undef        FALSE
  3377. #undef        TRUE
  3378. #include    <Quickdraw.h>
  3379. #define        FALSE        (0)
  3380. #define        TRUE        (!FALSE)
  3381.  
  3382. FILE        *console ;
  3383. FontInfo    fi ;
  3384. Rect        full_screen ;
  3385. int            line_height ;
  3386.  
  3387. Void
  3388. thinkc_init_io ()
  3389. {
  3390.     extern FILE            *console ;
  3391.     extern FontInfo        fi ;
  3392.     extern Rect            full_screen ;
  3393.     extern int            line_height ;
  3394.     extern word            top_screen_line ;
  3395.  
  3396.     if (( console = fopenc () ) == (FILE *)0 )
  3397.         exit ( 1 ) ;
  3398.     GetFontInfo ( &fi ) ;
  3399.     line_height = fi.ascent + fi.descent + fi.leading ;
  3400.     thePort -> portRect.top += top_screen_line * line_height ;
  3401.     full_screen = thePort -> portRect ;
  3402. }
  3403.  
  3404. Void
  3405. thinkc_exit_io ()
  3406. {
  3407.     extern FILE            *console ;
  3408.  
  3409.     fclose ( console ) ;
  3410. }
  3411.  
  3412. #define        CHAR_OFFSET        1
  3413.  
  3414. Void
  3415. thinkc_putchar ( c )
  3416. char    c ;
  3417. {
  3418.     extern FontInfo    fi ;
  3419.     extern boolean    enable_screen ;
  3420.     extern word        text_mode ;
  3421.  
  3422.     Point            pn_loc ;
  3423.     RgnHandle        update ;
  3424.     Rect            r ;
  3425.  
  3426.     switch ( c )
  3427.     {
  3428.         case 1:
  3429.                 text_mode = NORMAL_MODE ;
  3430.                 break ;
  3431.         case 2:
  3432.                 text_mode |= INVERSE_MODE ;
  3433.                 break ;
  3434.         case 3:
  3435.                 text_mode |= BOLD_MODE ;
  3436.                 break ;
  3437.         case 4:
  3438.                 break ;
  3439.         case 5:
  3440.                 text_mode |= UNDERLINE_MODE ;
  3441.                 break ;
  3442.         case 0:
  3443.                 c = ' ' ;
  3444.  
  3445.                 /*
  3446.                 **    Fall Through ...
  3447.                 */
  3448.  
  3449.         default:
  3450.                 if ( enable_screen )
  3451.                 {
  3452.                     GetPen ( &pn_loc ) ;
  3453.                     SetRect ( &r,pn_loc.h-CHAR_OFFSET,pn_loc.v-fi.ascent,pn_loc.h+fi.widMax,pn_loc.v+fi.descent ) ;
  3454.                     EraseRect ( &r ) ;
  3455.                     if ( text_mode & BOLD_MODE )
  3456.                     {
  3457.                         TextFace ( bold ) ;
  3458.                         putchar ( c ) ;
  3459.                         TextFace ( 0 ) ;
  3460.                         update = NewRgn () ;
  3461.                         ScrollRect ( &r,-CHAR_OFFSET,0,update ) ;
  3462.                         DisposeRgn ( update ) ;
  3463.                         GOTO_XY ( GET_X (),GET_Y () ) ;
  3464.                     }
  3465.                     else
  3466.                         putchar ( c ) ;
  3467.                     if ( text_mode & UNDERLINE_MODE )
  3468.                     {
  3469.                         MoveTo ( pn_loc.h-CHAR_OFFSET,pn_loc.v+fi.descent-1 ) ;
  3470.                         LineTo ( pn_loc.h+fi.widMax,pn_loc.v+fi.descent-1 ) ;
  3471.                         GOTO_XY ( GET_X (),GET_Y () ) ;
  3472.                     }
  3473.                     if ( text_mode & INVERSE_MODE )
  3474.                         InvertRect ( &r ) ;
  3475.                 }
  3476.                 break ;
  3477.     }
  3478. }
  3479.  
  3480. Void
  3481. thinkc_goto_xy ( x,y )
  3482. int        x ;
  3483. int        y ;
  3484. {
  3485.     extern FILE        *console ;
  3486.  
  3487.     cgotoxy ( x,y,console ) ;
  3488. }
  3489.  
  3490. int
  3491. thinkc_get_x ()
  3492. {
  3493.     extern FILE        *console ;
  3494.  
  3495.     int                x ;
  3496.     int                y ;
  3497.  
  3498.     cgetxy ( &x,&y,console ) ;
  3499.     return ( x ) ;
  3500. }
  3501.  
  3502. int
  3503. thinkc_get_y ()
  3504. {
  3505.     extern FILE        *console ;
  3506.  
  3507.     int                x ;
  3508.     int                y ;
  3509.  
  3510.     cgetxy ( &x,&y,console ) ;
  3511.     return ( y ) ;
  3512. }
  3513.  
  3514. /*
  3515. **    The Enhanced Windowing THINK C I/O Functions.
  3516. */
  3517.  
  3518. Void
  3519. thinkc_use_window ( the_window )
  3520. word    the_window ;
  3521. {
  3522.     extern word        window_height ;
  3523.     extern Rect        full_screen ;
  3524.     extern int        line_height ;
  3525.  
  3526.     switch ( the_window )
  3527.     {
  3528.         case WINDOW_0:
  3529.                         /*
  3530.                         **    Use the Lower Window.
  3531.                         */
  3532.                         
  3533.                         thePort -> portRect.top = full_screen.top + window_height * line_height ;
  3534.                         thePort -> portRect.bottom = full_screen.bottom ;
  3535.                         break ;
  3536.         case WINDOW_1:
  3537.                         /*
  3538.                         **    Use the Upper Window.
  3539.                         */
  3540.                         
  3541.                         thePort -> portRect.top = full_screen.top ;
  3542.                         thePort -> portRect.bottom = full_screen.top + window_height * line_height ;
  3543.                         break ;
  3544.         case FULL_SCREEN:
  3545.                         /*
  3546.                         **    Use the entire Screen.
  3547.                         */
  3548.                         
  3549.                         thePort -> portRect.top = full_screen.top ;
  3550.                         thePort -> portRect.bottom = full_screen.bottom ;
  3551.                         break ;
  3552.     }
  3553. }
  3554.  
  3555. #define        _CONTROLWIDTH    15        /* Width of Scroll Bar */
  3556. #define        _LEFTEDGE        4        /* Margins             */
  3557. #define        _TOPEDGE        4
  3558.  
  3559. Void
  3560. thinkc_erase_window ( top_of_window,bottom_of_window )
  3561. word    top_of_window ;
  3562. word    bottom_of_window ;
  3563. {
  3564.     extern FILE        *console ;
  3565.     extern Rect        full_screen ;
  3566.     extern int        line_height ;
  3567.     extern int        screen_height ;
  3568.     extern word        top_screen_line ;
  3569.     
  3570.     Rect            r ;
  3571.  
  3572.     /*
  3573.     **    The problem with using Lightspeed C stdio is that when erasing
  3574.     **    the console window, its text buffer should also be cleared. Since
  3575.     **    this is quite tricky, we fudge it by calling "ccleos ()"
  3576.     **    when clearing the whole screen. When the screen is only partially
  3577.     **    cleared, we do not clear those lines from the console window's
  3578.     **    screen buffer ... this may sometimes cause problems !!!
  3579.     */
  3580.             
  3581.     if    (
  3582.             ( top_of_window == top_screen_line )
  3583.             &&
  3584.             ( bottom_of_window == (word)screen_height )
  3585.         )
  3586.     {
  3587.         ccleos ( console ) ;
  3588.     }
  3589.     else
  3590.     {
  3591.         r.bottom = full_screen.top + bottom_of_window * line_height ;
  3592.         r.top = full_screen.top + _TOPEDGE + ( top_of_window - top_screen_line ) * line_height ;
  3593.         r.left = full_screen.left + _LEFTEDGE ;
  3594.         r.right = full_screen.right - _CONTROLWIDTH ;
  3595.         EraseRect ( &r ) ;
  3596.     }
  3597. }
  3598.  
  3599. /*
  3600. **    The PLUS Series THINK C I/O Functions.
  3601. */
  3602.  
  3603. Void
  3604. thinkc_erase_to_eoln ()
  3605. {
  3606.     extern FILE        *console ;
  3607.  
  3608.     /*
  3609.     **    The characters at the cursor and to the right are erased.
  3610.     **    The cursor itself is not moved.
  3611.     */
  3612.  
  3613.     ccleol ( console ) ;
  3614. }
  3615.  
  3616. #endif    /* THINKC */
  3617.