home *** CD-ROM | disk | FTP | other *** search
- /*
- helpxref.c 5/5/87
-
- % help_Xref
-
- C-scape 3.2
- Copyright (c) 1986, 1987, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 7/09/87 jmd fixed no fields bug.
- 7/16/87 jmd added first letter search.
- 7/25/87 jmd added data structure and colors.
- 8/06/87 jmd fixed "empty screen" problem
- 8/08/88 jmd removed vid_ calls
- 8/14/88 jmd now passes xref by reference
- adjusted for windows, sed is no longer static
- 10/20/88 jmd now passes xref by value again
- removed @c[] statement
- 11/05/88 jmd removed menu_Close
-
- 4/22/89 jmd changed border to bord
- 8/02/89 jmd Added mouse support
- 8/24/89 jmd removed dependence on bd_xref
-
- 3/28/90 jmd ansi-fied
- 4/03/90 jmd added additional cast to xref
- 8/27/90 jmd added use of ocountry struct
- 10/04/90 pmcm removed isprint from search
- 10/19/90 jmd added iarray to hold xref values
- 10/30/90 jmd made iarray "external" to fix realloc trouble
- */
-
- #include <stdio.h>
- #include <ctype.h>
-
-
- #include "cscape.h"
- #include "ostdlib.h" /* for atoi() */
-
- #include "scancode.h"
- #include "helpdecl.h"
-
- #define RING_LEN 22 /* must be greater than 1 */
-
- static int ringbuf[RING_LEN]; /* used to remember previous help screens */
- static int top, bot;
-
- OSTATIC void help_fkey(sed_type sed);
-
- static field_funcs_struct help_funcs = {
- FNULL,
- FNULL,
- help_fkey,
- FNULL,
- FNULL,
- 0
- };
-
- int help_Xref(help_type h)
- /*
- Cross referenced help display routine.
- Looks for special cross referenced help symbols in the help text.
- The syntax is "@3[word]". This means that "word" will highlighted and
- will be a cross reference to message number 3. Any number of cross
- references can appear in the help text. The regular C-scape commands
- (@[] @p[] @c) can also be imbedded in the help text if you feel like it.
- The backspace key is used to cycle back through previous screens.
- A ring buffer is used to remember the previous screens.
-
- The cross-reference values for the fields are stored in an external
- iarray. This is connected to the sed data pointer.
- */
- {
- menu_type menu;
- sed_type sed;
- sed_type prevsed = NULL;
- iarray ia;
-
- int key;
- char *p, *q, hold;
- int mode, xref, x, fldno;
- int msg = -1;
-
- char bk_clr, reg_clr, sel_clr, bd_clr;
- bd_fptr bord;
- struct hx_struct *hx;
-
- hx = (struct hx_struct *) help_GetData(h);
-
- if (hx == NULL) {
- bk_clr = ATTR_NORMAL;
- reg_clr = ATTR_BOLD;
- sel_clr = ATTR_REVERSE;
- bd_clr = ATTR_NORMAL;
- bord = FNULL;
- }
- else {
- bk_clr = hx->bk_clr;
- reg_clr = hx->reg_clr;
- sel_clr = hx->sel_clr;
- bd_clr = hx->bd_clr;
- bord = hx->bord;
- }
-
- /* initialize ring buffer */
- top = bot = 0;
-
- while (msg != 0) {
-
- /* create an array to hold cross reference values */
- if ((ia = ia_Open(10)) == NULL) {
- break;
- }
-
- if ((menu = menu_Open()) == NULL) {
- ia_Close(ia);
- break;
- }
-
- /* search for cross-references */
- for (mode = 0, q = p = help_GetText(h); *p != '\0'; p++) {
- switch (mode) {
- case 0:
- if (*p == '@') {
- mode = 1;
- }
- break;
- case 1:
- if (*p == '@' || *p == '[' || *p == 'c' || *p == 'p') {
- mode = 0;
- }
- else {
- hold = *(p-1);
- *(p-1) = '\0';
- menu_Printf(menu, q);
- *(p-1) = hold;
- mode = 2;
- q = p;
- }
- break;
- case 2:
- if (*p == '[') {
- xref = atoi(q);
- q = p + 1;
- mode = 3;
- }
- break;
- case 3:
- if (*p == ']') {
- hold = *p;
- *p = '\0';
-
- /* store xref value into iarray */
- fldno = menu_GetFieldCount(menu);
- ia_Put(ia, fldno, xref);
-
- menu_Printf(menu, "@f[%s]", NULL, &help_funcs, q);
-
- *p = hold;
- q = p+1;
- mode = 0;
- }
- break;
- default:
- break;
- }
- }
-
- menu_Printf(menu, q);
-
- menu_Flush(menu);
-
- if ((sed = sed_Open(menu)) == NULL) {
- ia_Close(ia);
- menu_Destroy(menu);
- break;
- }
-
- /* place the iarray into the sed's generic data pointer */
- sed_SetData(sed, (VOID *) ia);
-
- sed_SetMouse(sed, sedmou_GreedyTrack);
- sed_SetColors(sed, reg_clr, bk_clr, sel_clr);
-
- if (bord != FNULL) {
- sed_SetBorder(sed, bord);
- sed_SetBorderColor(sed, bd_clr);
- sed_SetBorderTitle(sed, help_GetTitle(h));
- }
-
- /* adjust height and width to fill the display */
- x = sed_GetBorderHeight(sed) - sed_GetHeight(sed);
- sed_SetHeight(sed, disp_GetHeight() - x);
-
- x = sed_GetBorderWidth(sed) - sed_GetWidth(sed);
- sed_SetWidth(sed, disp_GetWidth() - x);
-
- sed_SetPosition(sed, 0, 0);
-
- sed_Repaint(sed);
-
- /* remove previous sed */
- if (prevsed != NULL) {
- if (sed_GetData(prevsed) != NULL) {
- ia_Close((iarray) sed_GetData(prevsed));
- }
- sed_Close(prevsed);
- prevsed = NULL;
- }
-
- sed_BorderPrompt(sed, ocountry.helpxrefmsg);
-
- if (sed_GetFieldCount(sed) > 0) {
- msg = sed_Go(sed);
- }
- else {
- /* no fields... wait for ESC to be pressed */
- while(TRUE){
- key = kb_Read();
- if (key == ESC) {
- msg = 0;
- break;
- }
- if (key == BACKSPACE) {
- msg = -1;
- break;
- }
- }
- }
-
- /* save old sed until new one is created to avoid unecessary painting */
- prevsed = sed;
-
- if (msg == -1) {
- /* look up previous screen */
- if (top != bot) {
- top = (top == 0) ? RING_LEN - 1 : top - 1;
- if (!help_LookUp(ringbuf[top])) {
- break;
- }
- }
- }
- else if (msg > 0) {
- /* adjust ring buffer */
- ringbuf[top++] = help_GetMessage(h);
- top %= RING_LEN;
- if (top == bot) {
- bot++;
- bot %= RING_LEN;
- }
-
- if (!help_LookUp(msg)) {
- break;
- }
- }
- }
-
- /* close the sed */
- if (prevsed != NULL) {
- if (sed_GetData(prevsed) != NULL) {
- ia_Close((iarray) sed_GetData(prevsed));
- }
- sed_Close(prevsed);
- }
-
- return(0);
- }
-
- static void help_fkey(sed_type sed)
- /*
- fkey function for x-referenced help screen.
- return the following in the baton:
- -1) put up previous help screen
- 0) exit help system
- n) put up help message n
- */
- {
- int scancode, letter, choice, x;
- iarray ia;
-
- switch(scancode = kb_Read()) {
- case MOU_HERE:
- break;
-
- case MOU_THERE:
- case ESC:
- sed_SetBaton(sed, 0);
- sed_ToggleExit(sed);
- break;
- case BACKSPACE:
- /* look up the previous message, if there is one */
- if (top != bot) {
- sed_SetBaton(sed, -1);
- sed_ToggleExit(sed);
- }
- break;
-
- case MOU_CLICK:
- case ENTER:
- /* get the xref value from external iarray */
- ia = (iarray) sed_GetData(sed);
- x = ia_Get(ia, sed_GetFieldNo(sed));
-
- if (x == -1 && top == bot) {
- /* ignore request for previous screen */
- break;
- }
-
- sed_SetBaton(sed, x);
- sed_ToggleExit(sed);
- break;
-
- case HOME:
- sed_GotoFirstField(sed);
- break;
- case END:
- sed_GotoLastField(sed);
- break;
- case UP:
- if (sed_UpField(sed) == SED_STUCK) {
- sed_GotoLastField(sed);
- }
- break;
- case DOWN:
- if (sed_DownField(sed) == SED_STUCK) {
- sed_GotoFirstField(sed);
- }
- break;
- case LEFT:
- if (sed_DecField(sed) == SED_STUCK) {
- sed_GotoLastField(sed);
- }
- break;
- case RIGHT:
- if (sed_IncField(sed) == SED_STUCK) {
- sed_GotoFirstField(sed);
- }
- break;
- default:
- /* do letter search */
- letter = ascii(scancode);
- if ((choice = sed_SearchMerge(sed, (char)letter)) != -1) {
- sed_GotoField(sed, choice);
- }
- break;
- }
- }
-