home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / HELPXREF.C < prev    next >
C/C++ Source or Header  |  1990-10-30  |  7KB  |  350 lines

  1. /*
  2.       helpxref.c    5/5/87
  3.  
  4.     % help_Xref
  5.  
  6.     C-scape 3.2
  7.     Copyright (c) 1986, 1987, by Oakland Group, Inc.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     -----------------
  12.     7/09/87  jmd    fixed no fields bug.
  13.     7/16/87  jmd    added first letter search.
  14.     7/25/87  jmd    added data structure and colors.
  15.     8/06/87  jmd    fixed "empty screen" problem
  16.     8/08/88  jmd    removed vid_ calls
  17.     8/14/88  jmd    now passes xref by reference
  18.                     adjusted for windows, sed is no longer static
  19.    10/20/88  jmd    now passes xref by value again
  20.                     removed @c[] statement
  21.     11/05/88 jmd    removed menu_Close
  22.  
  23.      4/22/89 jmd    changed border to bord
  24.      8/02/89 jmd    Added mouse support
  25.      8/24/89 jmd    removed dependence on bd_xref
  26.  
  27.      3/28/90 jmd    ansi-fied
  28.      4/03/90 jmd    added additional cast to xref
  29.      8/27/90 jmd    added use of ocountry struct
  30.     10/04/90 pmcm    removed isprint from search
  31.     10/19/90 jmd    added iarray to hold xref values
  32.     10/30/90 jmd    made iarray "external" to fix realloc trouble
  33. */
  34.  
  35. #include <stdio.h>
  36. #include <ctype.h>
  37.  
  38.  
  39. #include "cscape.h"
  40. #include "ostdlib.h"            /* for atoi() */
  41.  
  42. #include "scancode.h"
  43. #include "helpdecl.h"
  44.  
  45. #define RING_LEN    22     /* must be greater than 1 */
  46.  
  47. static int ringbuf[RING_LEN];    /* used to remember previous help screens */
  48. static int top, bot;
  49.  
  50. OSTATIC void help_fkey(sed_type sed);
  51.  
  52. static field_funcs_struct help_funcs = {
  53.     FNULL,
  54.     FNULL,
  55.     help_fkey,
  56.     FNULL,
  57.     FNULL,
  58.     0
  59. };
  60.  
  61. int help_Xref(help_type h)
  62. /*
  63.       Cross referenced help display routine.
  64.     Looks for special cross referenced help symbols in the help    text.
  65.     The syntax is "@3[word]".  This means that "word" will highlighted and
  66.     will be a cross reference to message number 3.  Any number of cross
  67.     references can appear in the help text.  The regular C-scape commands
  68.     (@[] @p[] @c) can also be imbedded in the help text if you feel like it.
  69.     The backspace key is used to cycle back through previous screens.
  70.     A ring buffer is used to remember the previous screens.
  71.  
  72.     The cross-reference values for the fields are stored in an external
  73.     iarray.  This is connected to the sed data pointer.
  74. */
  75. {
  76.     menu_type menu;
  77.     sed_type sed;
  78.     sed_type prevsed = NULL;
  79.     iarray ia;
  80.  
  81.     int key;
  82.     char *p, *q, hold;
  83.     int mode, xref, x, fldno;
  84.     int msg = -1;
  85.  
  86.     char bk_clr, reg_clr, sel_clr, bd_clr;
  87.     bd_fptr bord;
  88.     struct hx_struct *hx;
  89.  
  90.     hx = (struct hx_struct *) help_GetData(h);
  91.  
  92.     if (hx == NULL) {
  93.         bk_clr =   ATTR_NORMAL;
  94.         reg_clr =  ATTR_BOLD;
  95.         sel_clr =  ATTR_REVERSE;
  96.         bd_clr =   ATTR_NORMAL;
  97.         bord = FNULL;
  98.     }
  99.     else {
  100.         bk_clr =  hx->bk_clr;
  101.         reg_clr = hx->reg_clr;
  102.         sel_clr = hx->sel_clr;
  103.         bd_clr =  hx->bd_clr;
  104.         bord =  hx->bord;
  105.     }
  106.  
  107.     /* initialize ring buffer */
  108.     top = bot = 0;
  109.  
  110.     while (msg != 0) {
  111.  
  112.         /* create an array to hold cross reference values */
  113.         if ((ia = ia_Open(10)) == NULL) {
  114.             break;
  115.         }
  116.  
  117.         if ((menu = menu_Open()) == NULL) {
  118.             ia_Close(ia);
  119.             break;
  120.         }
  121.  
  122.         /* search for cross-references */
  123.         for (mode = 0, q = p = help_GetText(h); *p != '\0'; p++) {
  124.             switch (mode) {
  125.             case 0:
  126.                 if (*p == '@') {
  127.                     mode = 1;
  128.                 }
  129.                 break;
  130.             case 1:
  131.                 if (*p == '@' || *p == '[' || *p == 'c' || *p == 'p') {
  132.                     mode = 0;
  133.                 }
  134.                 else {
  135.                     hold = *(p-1);
  136.                     *(p-1) = '\0';
  137.                     menu_Printf(menu, q);
  138.                     *(p-1) = hold;
  139.                     mode = 2;
  140.                     q = p;
  141.                 }
  142.                 break;
  143.             case 2:
  144.                 if (*p == '[') {
  145.                     xref = atoi(q);
  146.                     q = p + 1;
  147.                     mode = 3;
  148.                 }
  149.                 break;
  150.             case 3:
  151.                 if (*p == ']') {
  152.                     hold = *p;
  153.                     *p = '\0';
  154.  
  155.                     /* store xref value into iarray */
  156.                     fldno = menu_GetFieldCount(menu);
  157.                     ia_Put(ia, fldno, xref);
  158.  
  159.                     menu_Printf(menu, "@f[%s]", NULL, &help_funcs, q);
  160.  
  161.                     *p = hold;
  162.                     q = p+1;
  163.                     mode = 0;
  164.                 }
  165.                 break;
  166.             default:
  167.                 break;
  168.             }
  169.         }
  170.  
  171.         menu_Printf(menu, q);
  172.  
  173.         menu_Flush(menu);
  174.  
  175.         if ((sed = sed_Open(menu)) == NULL) {
  176.             ia_Close(ia);
  177.             menu_Destroy(menu);
  178.             break;
  179.         }
  180.  
  181.         /* place the iarray into the sed's generic data pointer */
  182.         sed_SetData(sed, (VOID *) ia);
  183.  
  184.         sed_SetMouse(sed, sedmou_GreedyTrack);
  185.         sed_SetColors(sed, reg_clr, bk_clr, sel_clr);
  186.  
  187.         if (bord != FNULL) {
  188.             sed_SetBorder(sed, bord);
  189.             sed_SetBorderColor(sed, bd_clr);
  190.             sed_SetBorderTitle(sed, help_GetTitle(h));
  191.         }
  192.  
  193.         /* adjust height and width to fill the display */
  194.         x = sed_GetBorderHeight(sed) - sed_GetHeight(sed);
  195.         sed_SetHeight(sed, disp_GetHeight() - x);
  196.  
  197.         x = sed_GetBorderWidth(sed) - sed_GetWidth(sed);
  198.         sed_SetWidth(sed, disp_GetWidth() - x);
  199.  
  200.         sed_SetPosition(sed, 0, 0);
  201.  
  202.         sed_Repaint(sed);
  203.  
  204.         /* remove previous sed */
  205.         if (prevsed != NULL) {
  206.             if (sed_GetData(prevsed) != NULL) {
  207.                 ia_Close((iarray) sed_GetData(prevsed));
  208.             }
  209.             sed_Close(prevsed);
  210.             prevsed = NULL;
  211.         }
  212.  
  213.         sed_BorderPrompt(sed, ocountry.helpxrefmsg);
  214.  
  215.         if (sed_GetFieldCount(sed) > 0) {
  216.             msg = sed_Go(sed);
  217.         }
  218.         else {
  219.             /* no fields... wait for ESC to be pressed */
  220.             while(TRUE){
  221.                 key = kb_Read();
  222.                 if (key == ESC) {
  223.                     msg = 0;
  224.                     break;
  225.                 }
  226.                 if (key == BACKSPACE) {
  227.                     msg = -1;
  228.                     break;
  229.                 }
  230.             }
  231.         }
  232.  
  233.         /* save old sed until new one is created to avoid unecessary painting */
  234.         prevsed = sed;
  235.  
  236.         if (msg == -1) {
  237.             /* look up previous screen */
  238.             if (top != bot) {
  239.                 top = (top == 0) ? RING_LEN - 1 : top - 1;
  240.                 if (!help_LookUp(ringbuf[top])) {
  241.                     break;
  242.                 }
  243.             }
  244.         }
  245.         else if (msg > 0) {
  246.             /* adjust ring buffer */
  247.             ringbuf[top++] = help_GetMessage(h);
  248.             top %= RING_LEN;
  249.             if (top == bot) {
  250.                 bot++;
  251.                 bot %= RING_LEN;
  252.             }
  253.  
  254.             if (!help_LookUp(msg)) {
  255.                 break;
  256.             }
  257.         }
  258.     }
  259.  
  260.     /* close the sed */
  261.     if (prevsed != NULL) {
  262.         if (sed_GetData(prevsed) != NULL) {
  263.             ia_Close((iarray) sed_GetData(prevsed));
  264.         }
  265.         sed_Close(prevsed);
  266.     }
  267.  
  268.     return(0);
  269. }
  270.  
  271. static void help_fkey(sed_type sed)
  272. /*
  273.     fkey function for x-referenced help screen.
  274.     return the following in the baton:
  275.     -1)    put up previous help screen
  276.      0)    exit help system
  277.      n)    put up help message n
  278. */
  279. {
  280.     int    scancode, letter, choice, x;
  281.     iarray ia;
  282.  
  283.     switch(scancode = kb_Read()) {
  284.     case MOU_HERE:
  285.         break;
  286.  
  287.     case MOU_THERE:
  288.     case ESC:
  289.         sed_SetBaton(sed, 0);
  290.         sed_ToggleExit(sed);
  291.         break;
  292.     case BACKSPACE:
  293.         /* look up the previous message, if there is one */
  294.         if (top != bot) {
  295.             sed_SetBaton(sed, -1);
  296.             sed_ToggleExit(sed);
  297.         }
  298.         break;
  299.  
  300.     case MOU_CLICK:
  301.     case ENTER:
  302.         /* get the xref value from external iarray */
  303.         ia = (iarray) sed_GetData(sed);
  304.         x = ia_Get(ia, sed_GetFieldNo(sed));
  305.  
  306.         if (x == -1 && top == bot) {
  307.             /* ignore request for previous screen */
  308.             break;
  309.         }
  310.  
  311.         sed_SetBaton(sed, x);
  312.         sed_ToggleExit(sed);
  313.         break;
  314.  
  315.     case HOME:
  316.         sed_GotoFirstField(sed);
  317.         break;
  318.     case END:
  319.         sed_GotoLastField(sed);
  320.         break;
  321.     case UP:
  322.         if (sed_UpField(sed) == SED_STUCK) {
  323.             sed_GotoLastField(sed);
  324.         }
  325.         break;
  326.     case DOWN:
  327.         if (sed_DownField(sed) == SED_STUCK) {
  328.             sed_GotoFirstField(sed);
  329.         }
  330.         break;
  331.     case LEFT:
  332.         if (sed_DecField(sed) == SED_STUCK) {
  333.             sed_GotoLastField(sed);
  334.         }
  335.         break;
  336.     case RIGHT:
  337.         if (sed_IncField(sed) == SED_STUCK) {
  338.             sed_GotoFirstField(sed);
  339.         }
  340.         break;
  341.     default:
  342.         /* do letter search */
  343.         letter = ascii(scancode);
  344.         if ((choice = sed_SearchMerge(sed, (char)letter)) != -1) {
  345.             sed_GotoField(sed, choice);
  346.         }
  347.         break;
  348.     }
  349. }
  350.