home *** CD-ROM | disk | FTP | other *** search
/ Phoenix Heaven Sunny 2 / APPARE2.BIN / oh_towns / dic / src / scrn.c < prev    next >
C/C++ Source or Header  |  1995-06-20  |  14KB  |  678 lines

  1. /********************************************
  2.  
  3.     Screen Display Func
  4.  
  5. *********************************************/
  6. #include    "defs.h"
  7. #include    "scrn.h"
  8.  
  9. #ifdef    MSDOS
  10. static    char far *FAR_STRCPY(char far *buf, register char *s)
  11. {
  12.     register char far *p = buf;
  13.  
  14.     while ( *s != '\0' )
  15.     *(p++) = *(s++);
  16.     *p = '\0';
  17.  
  18.     return buf;
  19. }
  20. static    char *NEAR_STRCPY(char *buf, register char far *s)
  21. {
  22.     register char *p = buf;
  23.  
  24.     while ( *s != '\0' )
  25.     *(p++) = *(s++);
  26.     *p = '\0';
  27.  
  28.     return buf;
  29. }
  30. #endif    /* MSDOS */
  31.  
  32. typedef    struct _LINPTR {
  33.     struct _LINPTR    FAR    *next;
  34.     struct _LINPTR    FAR    *back;
  35.     int        line;
  36.     char        str[1];
  37. } LINPTR;
  38.  
  39. static    LINPTR    FAR    *dic_line_now = NULL;
  40. static    int    dic_line_count = 0;
  41. static    int    dic_mem_flag = FALSE;
  42. static    char    dic_str_tmp[COLS_MAX + 2];
  43.  
  44. static    LINPTR    FAR    *dic_alloc_line(char *str, int line)
  45. {
  46.     LINPTR FAR *lp;
  47.  
  48.     if ( (lp = (LINPTR FAR *)MALLOC(sizeof(LINPTR) + strlen(str))) == NULL )
  49.     return NULL;
  50.     lp->next = lp->back = NULL;
  51.     lp->line = line;
  52.     FAR_STRCPY(lp->str, str);
  53.     return lp;
  54. }
  55. static    void    dic_free_line()
  56. {
  57.     LINPTR FAR *lp;
  58.  
  59.     if ( dic_line_now != NULL ) {
  60.         while ( (lp = dic_line_now->back) != NULL )
  61.         dic_line_now = lp;
  62.     }
  63.  
  64.     while ( (lp = dic_line_now) != NULL ) {
  65.     dic_line_now = lp->next;
  66.     FREE(lp);
  67.     }
  68. }
  69. static    char    *dic_next_line()
  70. {
  71.     LINPTR FAR *lp;
  72.  
  73.     if ( cd_gets(dic_str_tmp, cols_max - 1, dic_line_count) == NULL ) {
  74.     while ( menu_top != NULL ) {
  75.         menu_max--;
  76.         menu_top = menu_top->next;
  77.     }
  78.     while ( betu_top != NULL ) {
  79.         betu_max--;
  80.         betu_top = betu_top->next;
  81.     }
  82.     return NULL;
  83.     }
  84.  
  85.     if ( dic_mem_flag )
  86.     return dic_str_tmp;
  87.  
  88.     if ( (lp = dic_alloc_line(dic_str_tmp, dic_line_count)) == NULL ) {
  89.     dic_mem_flag = TRUE;
  90.     dic_free_line();
  91.     return dic_str_tmp;
  92.     }
  93.  
  94.     dic_line_count++;
  95.     if ( dic_line_now != NULL ) {
  96.     dic_line_now->next = lp;
  97.     lp->back = dic_line_now;
  98.     }
  99.     dic_line_now = lp;
  100.  
  101.     return NEAR_STRCPY(dic_str_tmp, lp->str);
  102. }
  103. static    char    *dic_goto_line(int line)
  104. {
  105.     if ( dic_line_now == NULL )
  106.     return NULL;
  107.  
  108.     while ( line < dic_line_now->line ) {
  109.     if ( dic_line_now->back == NULL )
  110.         return NULL;
  111.     dic_line_now = dic_line_now->back;
  112.     }
  113.  
  114.     while ( line > dic_line_now->line ) {
  115.     if ( dic_line_now->next == NULL )
  116.         return NULL;
  117.     dic_line_now = dic_line_now->next;
  118.     }
  119.  
  120.     return NEAR_STRCPY(dic_str_tmp, dic_line_now->str);
  121. }
  122. static    LINPTR    FAR    *dic_set_line(char *str)
  123. {
  124.     LINPTR FAR *lp;
  125.  
  126.     if ( (lp = dic_alloc_line(str, dic_line_count)) == NULL )
  127.     return NULL;
  128.  
  129.     dic_line_count++;
  130.     if ( dic_line_now != NULL ) {
  131.     dic_line_now->next = lp;
  132.     lp->back = dic_line_now;
  133.     }
  134.     dic_line_now = lp;
  135.  
  136.     return lp;
  137. }
  138. static    void    dic_set_menu(int line, int sx, int bx)
  139. {
  140.     if ( menu_max >= MENU_MAX )
  141.     return;
  142.     menu_tab[menu_max].sx = sx;
  143.     menu_tab[menu_max].bx = bx;
  144.     menu_tab[menu_max].sy = menu_tab[menu_max].by = line;
  145.     menu_max++;
  146. }
  147. static    void    dic_init_line(int sw)
  148. {
  149.     dic_free_line();
  150.     dic_line_count = 0;
  151.     dic_mem_flag = sw ? FALSE:TRUE;
  152. }
  153.  
  154. static    struct {
  155.     short    flag;
  156.     int    line;
  157.     } scrn_tab[LINE_MAX];
  158.  
  159. static    void    dic_scrn_clear()
  160. {
  161.     int     n;
  162.  
  163.     for ( n = 0 ; n < lines_max ; n++ ) {
  164.     scrn_tab[n].flag = (-3);
  165.     scrn_tab[n].line = (-1);
  166.     }
  167. }
  168. static    int    dic_menu_screen(int top, int menu)
  169. {
  170.     int     n;
  171.     int     line;
  172.     int     ps, st, ed;
  173.     int     ex, flag;
  174.     uchar   *p;
  175.  
  176.     while ( top > menu_tab[menu].sy )
  177.     top--;
  178.  
  179.     while ( (menu_tab[menu].by - top) >= (lines_max - 1) )
  180.     top++;
  181.  
  182.     line = top;
  183.     st = menu_tab[menu].sy * COLS_MAX + menu_tab[menu].sx;
  184.     ed = menu_tab[menu].by * COLS_MAX + menu_tab[menu].bx;
  185.  
  186.     CUROFF();
  187.     for ( n = 0 ; n < (lines_max - 1) ; n++, line++ ) {
  188.  
  189.     flag = (line >= menu_tab[menu].sy &&
  190.         line <= menu_tab[menu].by ? menu : (-1));
  191.  
  192.     if ( scrn_tab[n].flag == flag && scrn_tab[n].line == line )
  193.         continue;
  194.  
  195.     scrn_tab[n].line = line;
  196.     scrn_tab[n].flag = flag;
  197.  
  198.     LOCATE(0, n);
  199.  
  200.     if ( (p = dic_goto_line(line)) == NULL ) {
  201.         ERALINE();
  202.         continue;
  203.     }
  204.  
  205.     ex = FALSE;
  206.     ps = line * COLS_MAX;
  207.     while ( *p != '\n' && *p != '\0' ) {
  208.         if ( ex == FALSE && ps >= st && ps < ed ) {
  209.         REVCOL();
  210.         ex = TRUE;
  211.         }
  212.         if ( ex != FALSE && ps >= ed ) {
  213.         STDCOL();
  214.         ex = FALSE;
  215.         }
  216.         if ( *p >= ' ' )
  217.             PUTC(*p);
  218.         p++;
  219.         ps++;
  220.     }
  221.     if ( ex != FALSE )
  222.         STDCOL();
  223.     if ( *p == '\n' )
  224.         ERALINE();
  225.     }
  226.  
  227.     LOCATE(0, n);
  228.     ERALINE();
  229.     CURON();
  230.     FLUSH();
  231.  
  232.     return top;
  233. }
  234. static    int    dic_menu_select(int top, int menu)
  235. {
  236.     int     ch;
  237.  
  238. #ifdef    CURSES
  239. #ifdef    NEWS
  240.     setlocale(LC_CTYPE, "");
  241. #endif
  242.     initscr();
  243.     cbreak();
  244.     noecho();
  245.     scrollok(stdscr, TRUE);
  246.     idlok(stdscr, TRUE);
  247.     cols_max = COLS;
  248.     lines_max = LINES;
  249. #endif    /* CURSES */
  250.  
  251.     dic_scrn_clear();
  252.     for ( ; ; ) {
  253.     top = dic_menu_screen(top, menu);
  254.     ch = GETCH();
  255.  
  256.     switch(ch) {
  257.     case '\n': case '\r':
  258.         goto ENDOF;
  259.  
  260.     case '\033':
  261.     case 'q': case 'Q': case 'Q'-'@':
  262.         menu = ERR;
  263.         goto ENDOF;
  264.  
  265.     case ' ':
  266.     case '\x1F': case '\x1C':
  267.     case 'd': case 'D': case 'D'-'@':
  268.     case 'n': case 'N': case 'N'-'@':
  269.     case 'j': case 'J': /* case 'J'-'@': */
  270.         if ( ++menu >= menu_max )
  271.         menu = 0;
  272.         break;
  273.  
  274.     case '\b':
  275.     case '\x1E': case '\x1D':
  276.     case 'u': case 'U': case 'U'-'@':
  277.     case 'p': case 'P': case 'P'-'@':
  278.     case 'k': case 'K': case 'K'-'@':
  279.         if ( --menu < 0 )
  280.         menu = menu_max - 1;
  281.         break;
  282.  
  283.     case 'L'-'@':
  284.         REFRESH();
  285.         break;
  286.     }
  287.     }
  288.  
  289. ENDOF:
  290.  
  291.     CLS();
  292.     FLUSH();
  293.  
  294. #ifdef    CURSES
  295.     endwin();
  296. #endif
  297.  
  298.     return menu;
  299. }
  300. static    void    dic_puts(uchar *str, FILE *fp)
  301. {
  302.     for ( ; *str != '\0' ; str++ ) {
  303.     if ( fp != NULL ) {
  304.         if ( tex_out_flag ) {
  305.             switch(*str) {
  306.             case CH_BOLD_ON:
  307.             fputs("\\bold{", fp);
  308.             break;
  309.             case CH_BOLD_OFF:
  310.             putc('}', fp);
  311.             break;
  312.             case CH_ITALIC_ON:
  313.             fputs("\\slide{", fp);
  314.             break;
  315.             case CH_ITALIC_OFF:
  316.             putc('}', fp);
  317.             break;
  318.             default:
  319.             putc(*str, fp);
  320.             break;
  321.         }
  322.         } else {
  323.             if ( *str >= '\n' )
  324.             putc(*str, fp);
  325.         }
  326.     } else if ( color_flag ) {
  327.         switch(*str) {
  328.         case CH_BOLD_ON:    BOLD_ON(); break;
  329.         case CH_BOLD_OFF:   BOLD_OFF(); break;
  330.         case CH_ITALIC_ON:  ITALIC_ON(); break;
  331.         case CH_ITALIC_OFF: ITALIC_OFF(); break;
  332.         case '\n': ERALINE(); PUTC('\n'); break;
  333.         default: PUTC(*str); break;
  334.         }
  335.     } else {
  336.         if ( *str > '\n' )
  337.           PUTC(*str);
  338.         else if ( *str == '\n' ) {
  339.         ERALINE();
  340.         PUTC('\n');
  341.         }
  342.     }
  343.     }
  344. }
  345. int    dic_display(ulong block, ushort offset)
  346. {
  347.     int     ch;
  348.     int     line, max, menu;
  349.     int     fg = FALSE;
  350.     char    *p;
  351.     POINT   tab[1];
  352. #ifdef    MORE
  353.     FILE    *fp;
  354. #endif    /* MORE */
  355.  
  356. LOOP:
  357.     if ( dic_seek(block, offset) )
  358.     return ERR;
  359.  
  360.     dic_init_line(menu_disp_flg);
  361.  
  362.     if ( menu_disp_flg == FALSE )
  363.     goto NOMENU;
  364.  
  365.     for ( max = 0 ; max < MENU_CHK_LINE &&
  366.         (p = dic_next_line()) != NULL ; max++ )
  367.     ;
  368.  
  369.     if ( dic_mem_flag ) {
  370.     fprintf(stderr, "Menu Memory Alloc Error\n");
  371.     return ERR;
  372.     }
  373.  
  374.     if ( menu_max > 0 ) {
  375.     while ( max < HONBUN_MAX_LINE && (p = dic_next_line()) != NULL )
  376.         max++;
  377.     if ( dic_mem_flag ) {
  378.         fprintf(stderr, "Menu Memory Alloc Error\n");
  379.         return ERR;
  380.     }
  381.     line = max - lines_max + 1;
  382.         if ( (menu = dic_menu_select(0, 0)) < 0 )
  383.         return ERR;
  384.     dic_display(menu_tab[menu].pos.block,
  385.             menu_tab[menu].pos.offset);
  386.         goto LOOP;
  387.     }
  388.  
  389.     fg = TRUE;
  390.  
  391. NOMENU:
  392.     if ( extdisp_flag ) {
  393.     tab[0].block = block;
  394.     tab[0].offset = offset;
  395.     pager(tab, 1, menu_disp_flg);
  396.     return FALSE;
  397.     }
  398.  
  399. #ifdef    MORE
  400.     if ( pause_flg == FALSE || (fp = popen(MORE, "w")) == NULL )
  401.     fp = stdout;
  402. #endif    /* MORE */
  403.  
  404.     for ( max = line = 0 ; max < HONBUN_MAX_LINE ; max++ ) {
  405.  
  406.     if ( fg == TRUE && (p = dic_goto_line(max)) == NULL ) {
  407.         dic_mem_flag = TRUE;
  408.         dic_free_line();
  409.         fg = FALSE;
  410.     }
  411.  
  412.     if ( fg == FALSE && (p = dic_next_line()) == NULL )
  413.         break;
  414.  
  415.     if ( ext_out_fp != NULL )
  416.         dic_puts(p, ext_out_fp);
  417.  
  418. #ifdef    MORE
  419.     dic_puts(p, fp);
  420. #else
  421.     if ( ++line >= lines_max ) {
  422.         if ( pause_flg ) {
  423.         printf("--- more ---"); fflush(stdout);
  424.         ch = INKEY();
  425.         printf("\r            \r"); fflush(stdout);
  426.         if ( ch == '\033' )
  427.             return ERR;
  428.         }
  429.         line = 0;
  430.     }
  431.     dic_puts(p, color_flag ? NULL:stdout);
  432. #endif    /* !MORE */
  433.     }
  434.  
  435. #ifdef    MORE
  436.     if ( fp != stdout )
  437.     pclose(fp);
  438. #endif
  439.  
  440. /*
  441.     if ( color_flag ) {
  442.     BOLD_OFF();
  443.     ITALIC_OFF();
  444.     }
  445. */
  446.  
  447.     if ( pause_flg ) {
  448.     printf("Hit Return Key >"); fflush(stdout);
  449.     ch = INKEY();
  450. #ifndef    MORE
  451.     printf("\r                 \r"); fflush(stdout);
  452. #endif
  453.     }
  454.  
  455.     return FALSE;
  456. }
  457. static    uchar    *pager_get_line(int line, POINT *tab, int *no, int max)
  458. {
  459.     uchar   *p;
  460.  
  461.     if ( dic_mem_flag )
  462.     return NULL;
  463.     while ( (p = dic_goto_line(line)) == NULL ) {
  464.         while ( (p = dic_next_line()) == NULL ) {
  465.             if ( *no >= max )
  466.             return "\n";
  467.         if ( dic_seek(tab[*no].block, tab[*no].offset) )
  468.             return NULL;
  469.         *no += 1;
  470.     }
  471.     }
  472.     return p;
  473. }
  474. void    pager(POINT *tab, int max, int fg)
  475. {
  476.     int     ch, n;
  477.     int     no = 0;
  478.     int     line = 0;
  479.     int     top = 0;
  480.     uchar   *p;
  481.  
  482.     if ( no >= max )
  483.     return;
  484.  
  485. #ifdef    CURSES
  486. #ifdef    NEWS
  487.     setlocale(LC_CTYPE, "");
  488. #endif
  489.     initscr();
  490.     cbreak();
  491.     noecho();
  492.     scrollok(stdscr, TRUE);
  493.     idlok(stdscr, TRUE);
  494.     cols_max = COLS;
  495.     lines_max = LINES;
  496. #endif
  497.  
  498.     if ( !fg ) {
  499.         dic_seek(tab[no].block, tab[no].offset);
  500.         dic_init_line(TRUE);
  501.     }
  502.  
  503.     no++;
  504.  
  505.     CUROFF();
  506.     for ( n = 0 ; n < (lines_max - 1) ; n++ ) {
  507.     if ( (p = pager_get_line(n, tab, &no, max)) == NULL )
  508.         goto ENDOF;
  509.         LOCATE(0, n);
  510.         dic_puts(p, NULL);
  511.     }
  512.     LOCATE(0, lines_max - 1);
  513.     ERALINE();
  514.     FLUSH();
  515.  
  516.     for ( ; ; ) {
  517.     if ( color_flag ) {
  518.         if ( top != line ) {
  519. /****************************
  520.             BOLD_OFF();
  521.         ITALIC_OFF();
  522. *****************************/
  523.             for ( n = 0 ; n < (lines_max - 1) ; n++ ) {
  524.                 if ( (p = pager_get_line(line + n,
  525.                     tab, &no, max)) == NULL )
  526.                 goto ENDOF;
  527.                 LOCATE(0, n);
  528.             dic_puts(p, NULL);
  529.             }
  530.             LOCATE(0, lines_max - 1);
  531.             ERALINE();
  532.             FLUSH();
  533.             top = line;
  534.         }
  535.     } else {
  536.         while ( top < line ) {
  537.             top++;
  538.             if ( (p = pager_get_line(top + lines_max - 2,
  539.                     tab, &no, max)) == NULL )
  540.             goto ENDOF;
  541.             FORSCROOL();
  542.             LOCATE(0, lines_max - 2);
  543.             dic_puts(p, NULL);
  544.             FLUSH();
  545.         }
  546.         while ( top > line ) {
  547.             top--;
  548.             if ( (p = pager_get_line(top, tab, &no, max)) == NULL )
  549.             goto ENDOF;
  550.             BACKSCROOL();
  551.             LOCATE(0, 0);
  552.             dic_puts(p, NULL);
  553.             LOCATE(0, lines_max - 1);
  554.             ERALINE();
  555.             FLUSH();
  556.         }
  557.     }
  558.  
  559.     ch = GETCH();
  560.     switch(ch) {
  561.     case '\n': case '\r':
  562.     case '\x1F':
  563.     case 'x': case 'X': case 'X'-'@':
  564.     case 'u': case 'U': case 'U'-'@':
  565.     case 'j': case 'J': /* case 'J'-'@': */
  566.         line++;
  567.         break;
  568.     case '\x1E':
  569.     case 'e': case 'E': case 'E'-'@':
  570.     case 'd': case 'D': case 'D'-'@':
  571.     case 'k': case 'K': case 'K'-'@':
  572.         if ( line > 0 )
  573.         line--;
  574.         break;
  575.     case ' ':
  576.     case 'c': case 'C': case 'C'-'@':
  577.     case 'n': case 'N': case 'N'-'@':
  578.     case 'f': case 'F': case 'F'-'@':
  579.         line += (lines_max - 3);
  580.         break;
  581.     case '\b':
  582.     case 'r': case 'R': case 'R'-'@':
  583.     case 'b': case 'B': case 'B'-'@':
  584.     case 'p': case 'P': case 'P'-'@':
  585.         if ( (line -= (lines_max - 3)) < 0 )
  586.         line = 0;
  587.         break;
  588.     case '\033':
  589.     case 'q': case 'Q': case 'Q'-'@':
  590.         goto ENDOF;
  591.     case 's': case 'S': case 'S'-'@':
  592.     case 'l': case 'L': /* case 'L'-'@': */
  593.         if ( ext_out_fp != NULL ) {
  594.             for ( n = 0 ; n < (lines_max - 1) ; n++ ) {
  595.                 if ( (p = pager_get_line(line + n,
  596.                     tab, &no, max)) == NULL )
  597.                 goto ENDOF;
  598.                 dic_puts(p, ext_out_fp);
  599.         }
  600.         }
  601.         break;
  602.     case 'L'-'@':
  603.         REFRESH();
  604.         break;
  605.     }
  606.     }
  607.     ENDOF:
  608.  
  609. /*
  610.     if ( color_flag ) {
  611.     BOLD_OFF();
  612.     ITALIC_OFF();
  613.     }
  614. */
  615.  
  616.     LOCATE(0, lines_max - 1);
  617.     CURON();
  618.     FLUSH();
  619.  
  620. #ifdef    CURSES
  621.     endwin();
  622. #endif
  623.  
  624.     if ( dic_mem_flag )
  625.     fprintf(stderr, "Memory Alloc Error\n");
  626. }
  627. int    more(POINT *tab, int max)
  628. {
  629.     int     n;
  630.     uchar   *p;
  631. #ifdef    MORE
  632.     FILE    *fp;
  633. #else
  634.     int     ch;
  635.     int     line = 0;
  636. #endif
  637.  
  638. #ifdef    MORE
  639.     if ( pause_flg == FALSE || (fp = popen(MORE, "w")) == NULL )
  640.     fp = stdout;
  641. #endif    /* MORE */
  642.  
  643.     for ( n = 0 ; n < max ; n++ ) {
  644.     if ( dic_seek(tab[n].block, tab[n].offset) )
  645.         return ERR;
  646.     dic_init_line(FALSE);
  647.         while ( (p = dic_next_line()) != NULL ) {
  648. #ifdef    MORE
  649.         if ( ferror(fp) )
  650.         goto ENDOF;
  651.         dic_puts(p, fp);
  652. #else
  653.         if ( ++line >= lines_max ) {
  654.             if ( pause_flg ) {
  655.             printf("--- more ---"); fflush(stdout);
  656.             ch = INKEY();
  657.             printf("\r            \r"); fflush(stdout);
  658.             if ( ch == '\033' )
  659.                 return ERR;
  660.             }
  661.             line = 0;
  662.         }
  663.         dic_puts(p, color_flag ? NULL:stdout);
  664. #endif
  665.         if ( ext_out_fp != NULL )
  666.             dic_puts(p, ext_out_fp);
  667.     }
  668.     }
  669.  
  670. #ifdef    MORE
  671. ENDOF:
  672.     if ( fp != stdout )
  673.     pclose(fp);
  674. #endif
  675.  
  676.     return FALSE;
  677. }
  678.