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