Annotation of os2sdk/demos/apps/lqh/lqhmain.c, revision 1.1.1.1

1.1       root        1: /****************************************************************************
                      2: 
                      3:     PROGRAM: lqh.c
                      4: 
                      5:     MODULE: lqhmain.c
                      6: 
                      7:     PURPOSE: Displays on-line information
                      8: 
                      9:     FUNCTIONS:
                     10:         main()
                     11:         ReadScreen()    Checks if cursor is over a function name
                     12:         ScrollDown()    Scroll screen down
                     13:         ScrollUp()      Scroll screen up
                     14:         Abort()         Called upon program termination
                     15:         MouseRelease()  Waits until mouse button is released
                     16:         isalpha()       Returns TRUE if character is alphabetic
                     17: 
                     18: 
                     19:     COMMENTS:
                     20:         This program provides a subset of the capabilities of the Microsoft
                     21:         QuickHelp program. It is provided as an example application using
                     22:         MS OS/2.
                     23: 
                     24: ****************************************************************************/
                     25: 
                     26: #include "lqh.h"
                     27: 
                     28: CHAR chMenu[] = { /* Top menu defined as character-attribute string */
                     29:     ' ', atMENU,
                     30:     'R', atLEAD,                                              /* #1 */
                     31:     'e', atMENU,
                     32:     'f', atMENU,
                     33:     'e', atMENU,
                     34:     'r', atMENU,
                     35:     'e', atMENU,
                     36:     'n', atMENU,
                     37:     'c', atMENU,
                     38:     'e', atMENU,
                     39:     's', atMENU,
                     40:     ' ', atMENU,
                     41:     ' ', atMENU,
                     42:     'C', atLEAD,                                             /* #13 */
                     43:     'a', atMENU,
                     44:     't', atMENU,
                     45:     'e', atMENU,
                     46:     'g', atMENU,
                     47:     'o', atMENU,
                     48:     'r', atMENU,
                     49:     'i', atMENU,
                     50:     'e', atMENU,
                     51:     's', atMENU,
                     52:     ' ', atMENU,
                     53:     ' ', atMENU,
                     54:     'V', atLEAD,                                             /* #25 */
                     55:     'i', atMENU,
                     56:     'e', atMENU,
                     57:     'w', atMENU,
                     58:     ' ', atMENU,
                     59:     ' ', atMENU,
                     60:     ' ', atMENU,
                     61:     ' ', atMENU,
                     62:     'O', atLEAD,                                             /* #33 */
                     63:     'p', atMENU,
                     64:     't', atMENU,
                     65:     'i', atMENU,
                     66:     'o', atMENU,
                     67:     'n', atMENU,
                     68:     's', atMENU,
                     69:     ' ', atMENU,
                     70:     ' ', atMENU,
                     71:     ' ', atMENU,
                     72:     ' ', atMENU,
                     73:     ' ', atMENU,
                     74:     ' ', atMENU,
                     75:     ' ', atMENU,
                     76:     ' ', atMENU,
                     77:     ' ', atMENU,
                     78:     ' ', atMENU,
                     79:     ' ', atMENU,
                     80:     ' ', atMENU,
                     81:     ' ', atMENU,
                     82:     ' ', atMENU,
                     83:     ' ', atMENU,
                     84:     ' ', atMENU,
                     85:     ' ', atMENU,
                     86:     ' ', atMENU,
                     87:     ' ', atMENU,
                     88:     ' ', atMENU,
                     89:     ' ', atMENU,
                     90:     ' ', atMENU,
                     91:     ' ', atMENU,
                     92:     ' ', atMENU,
                     93:     ' ', atMENU,
                     94:     ' ', atMENU,
                     95:     ' ', atMENU,
                     96:     ' ', atMENU,
                     97:     ' ', atMENU,
                     98:     ' ', atMENU,
                     99:     0xB3, atMENU,
                    100:     ' ', atMENU,
                    101:     'F', atMENU,
                    102:     '1', atMENU,
                    103:     '=', atMENU,
                    104:     'H', atLEAD,
                    105:     'e', atMENU,
                    106:     'l', atMENU,
                    107:     'p', atMENU,
                    108:     ' ', atMENU,
                    109:     };
                    110: 
                    111: VIOCURSORINFO viociCursor;    /* cursor data                        */
                    112: KBDKEYINFO kbdciKeyInfo;      /* structure for key data             */
                    113: QHBOX qhbBox;                 /*  box dimensions                    */
                    114: 
                    115: CHAR achBlank[2];             /* used to clear the screen           */
                    116: BYTE bHoldString[160];        /* Holds string prior to highlighting */
                    117: USHORT cbHoldLength = ((BOXRIGHT - 1) - (BOXLEFT + 1)) * 2;
                    118: 
                    119: CHAR chReference[MAXLIST * MAXNAMESIZE]; /* Stores reference names  */
                    120: NPSZ npszRefTable[MAXLIST];       /* table of reference functions   */
                    121: STRTABLE strTable[2000];          /* Maintains address of each line */
                    122: USHORT usRefCount;                /* number of reference functions  */
                    123: LIST lstList[MAXLIST];            /* list of category names         */
                    124: USHORT usListPos;                 /* position in tables             */
                    125: USHORT usCurListPos;              /* position in tables             */
                    126: 
                    127: USHORT hmou;                      /* handle to the mouse            */
                    128: MOUEVENTINFO mouevEvent;          /* mouse event packet structure   */
                    129: NOPTRRECT mourtRect;              /* structure for hiding the mouse */
                    130: BOOL fMouButton = FALSE;          /* TRUE if button it clicked      */
                    131: USHORT MouReadType = 0;           /* don't wait for mouse event     */
                    132: 
                    133: BYTE bNormalAtt = atNORMAL;       /* default attributes             */
                    134: BYTE bHiAtt = atHILITE;
                    135: BYTE bBoldAtt = atBOLD;
                    136: BYTE bItalicAtt = atITALIC;
                    137: BYTE bMenuAtt = atMENU;
                    138: BYTE bHiMenuAtt = atNORMAL;
                    139: 
                    140: SEL selBoxSave;              /* selector to memory for screen save  */
                    141: SEL selStringTable;          /* selector for char-attribute strings */
                    142: 
                    143: USHORT usBottomLine;         /* current bottom-line number          */
                    144: USHORT usInterior;           /* maximum number of displayed lines   */
                    145: USHORT usTotalLines;         /* total number of lines               */
                    146: USHORT usStructLine;         /* starting line of structure section  */
                    147: BOOL fListDisplay;      /* TRUE if function list is being displayed */
                    148: BOOL fBack = FALSE;     /* TRUE if HelpNcBack() was called          */
                    149: USHORT usSaveMenuPos = 2;    /* current List menu position          */
                    150: 
                    151: /* The selTable contains a list of preloaded topics. Whenever a request is
                    152:  * made for a topic, this table is checked to see if the topic is in memory.
                    153:  */
                    154: 
                    155: SELTABLE selTable[MAXPRELOAD];  /* table of preloaded topics        */
                    156: USHORT usCurrent = 0;           /* current index in selTable        */
                    157: 
                    158: ULONG FAR hsemNewRef = 0;      /* RAM semaphore used by PreLoad()   */
                    159: TID tidPreLoad;                /* identifier for the PreLoad thread */
                    160: BYTE bThreadStack[512];        /* stack for the thread              */
                    161: 
                    162: /* The chMenuTable contains the scan codes of the first letter of each
                    163:  * menu. When a horizontal cursor key is pressed, the scan code for that menu
                    164:  * is taken from this table and processed as if the user had pressed the
                    165:  * key.
                    166:  */
                    167: 
                    168: CHAR chMenuTable[] = { 19, 46, 47, 24 };
                    169: SHORT sMenuTablePos;        /* position in the scan code table      */
                    170: SHORT sDirection = 0;       /* direction to move in scan code table */
                    171: 
                    172: NC ncHelp;                  /* handle to the help data file         */
                    173: 
                    174: /* The help engine uses an array of attributes to determine the colors of
                    175:  * normal, bold, and italic text.
                    176:  */
                    177: 
                    178: BYTE bAttr[5] = { atNORMAL, atBOLD, atITALIC, atBOX, atMENU };
                    179: CHAR chHelpName[80];             /*  data file name                 */
                    180: VIOMODEINFO vmiMode;             /* video-mode structure            */
                    181: 
                    182: VOID cdecl main(argc, argv)
                    183: INT argc;
                    184: CHAR *argv[];
                    185: {
                    186:     USHORT usTmp, i, y;          /* temporary variables             */
                    187:     BOOL fNewPage = FALSE;       /* TRUE draws a new page           */
                    188:     BOOL fFound;                 /* TRUE means topic has been found */
                    189:     PTRLOC mouplInit;            /* initial mouse position          */
                    190:     PSZ pszDefaults;             /* LQH defaults from environment   */
                    191:     PCH pchPtr;                  /* temporary pointer               */
                    192:     CHAR chBuf[80];              /* temporary buffer                */
                    193: 
                    194:     /* The hsemNewRef variable is set to indicate that there are no new
                    195:      * reference topics to preload. This prevents the thread from starting
                    196:      * when it is created. The HelpSearch() function clears the semaphore
                    197:      * whenever a new function is loaded.
                    198:      */
                    199: 
                    200:     DosSemSet((HSEM) &hsemNewRef);
                    201:     DosCreateThread(PreLoadThread, /* address of the thread         */
                    202:         &tidPreLoad,               /* address of the thread ID      */
                    203:         bThreadStack + 512);       /* address of the thread's stack */
                    204: 
                    205:     /* The thread is allowed to run only while waiting for input. The
                    206:      * Input() function resumes execution of the thread when it is called, and
                    207:      * suspends execution before it returns. This maximizes response time to a
                    208:      * keystroke or mouse event while allowing the thread to preload topics
                    209:      * when the user is reading the current topic and not pressing keys or
                    210:      * pressing the mouse button.
                    211:      */
                    212: 
                    213:     DosSuspendThread(tidPreLoad);
                    214: 
                    215:     achBlank[0] = 0x20;                /* used for clearing the box */
                    216:     achBlank[1] = bNormalAtt;
                    217: 
                    218:     MouOpen(0L, (PHMOU) &hmou);        /* Opens the mouse device    */
                    219: 
                    220:     /* The selStringTable selector is set to a 64-K block of memory that is
                    221:      * used to store the character-attribute strings. The strTable[] structure
                    222:      * contains a list of pointers to each character-attribute string within
                    223:      * this table and its length.
                    224:      */
                    225: 
                    226:     if (DosAllocSeg(0, &selStringTable, 0)) {
                    227:         BoxMessage(" Insufficient memory ", /* message              */
                    228:             atWARNING,                /* attribute                  */
                    229:             THIN,                     /* box line type              */
                    230:             hmou,                     /* handle to the mouse        */
                    231:             TRUE);                    /* TRUE sounds a warning tone */
                    232:         DosExit(EXIT_PROCESS, 1);
                    233:     }
                    234: 
                    235:     /* Get the current screen mode */
                    236: 
                    237:     vmiMode.cb = sizeof(vmiMode);
                    238:     VioGetMode(&vmiMode, 0);
                    239: 
                    240:     /* If the display is monochrome, then all the character attributes need
                    241:      * to be changed.
                    242:      */
                    243: 
                    244:     if (vmiMode.fbType == 0) {
                    245:         bAttr[2] = bItalicAtt = 1;
                    246:         bHiAtt = bHiMenuAtt = 0x78;
                    247:         chMenu[3] = chMenu[27] = chMenu[51] = chMenu[67] =
                    248:             chMenu[81] = chMenu[99] = chMenu[149] = 1;
                    249:     }
                    250: 
                    251:     /* All the dimensions for the box are set except the bottom. The bottom
                    252:      * of the box is determined after examining the environment for a LQH
                    253:      * variable and checking the size of the current display.
                    254:      */
                    255: 
                    256:     mourtRect.row = qhbBox.top = 0;
                    257:     mourtRect.col = qhbBox.left = BOXLEFT;
                    258:     mourtRect.cCol = qhbBox.right = BOXRIGHT;
                    259:     qhbBox.BorderAtt = atBOX;
                    260:     qhbBox.FillAtt = atBOX;
                    261:     qhbBox.BoxType = THIN;
                    262: 
                    263:     Dstrcpy((PCH) chHelpName, "qh.hlp");              /*  data file */
                    264: 
                    265:     /* Scan the environment for a LQH variable. If LQH is found, process it
                    266:      * to get the default data file and the window size.
                    267:      */
                    268: 
                    269:     if (!DosScanEnv("LQH", &pszDefaults)) {
                    270:         pchPtr = pszDefaults;
                    271: 
                    272:         /* If the first letter is not numeric, convert it into a filename,
                    273:          * and use that filename as the database.
                    274:          */
                    275: 
                    276:         if (*pchPtr != ',' && *pchPtr > '9') {
                    277:             Dstrcpy((PCH) chHelpName, pszDefaults);
                    278:             for (pchPtr = chHelpName; *pchPtr && *pchPtr != ',';
                    279:                 pchPtr++);
                    280:             if (*pchPtr == ',')
                    281:                 *pchPtr++ = 0;
                    282:         }
                    283: 
                    284:         /* If the character is numeric, convert it into the window size. */
                    285: 
                    286:         for (i = 0; pchPtr[i] != 0; i++)
                    287:             if (pchPtr[i] > '0' && pchPtr[i] <= '9')
                    288:                 break;
                    289:         if (pchPtr[i + 1] < '0')
                    290:             usTmp = pchPtr[i] - '0';
                    291:         else
                    292:             usTmp = ((pchPtr[i] - '0') * 10) + pchPtr[i + 1] - '0';
                    293:         if (usTmp < 5)
                    294:             usTmp = 5;
                    295:         else
                    296:             usTmp++;                            /* First line is #0 */
                    297:         vmiMode.cb = sizeof(vmiMode);
                    298:         VioGetMode(&vmiMode, 0);
                    299:         if (usTmp >= vmiMode.row)
                    300:             usTmp = vmiMode.row - 1;
                    301:     }
                    302:     else
                    303:         usTmp = vmiMode.row - 1;
                    304:     mourtRect.cRow = qhbBox.bottom = usTmp;
                    305: 
                    306:     if (argc > 2)
                    307:         Dstrcpy((PCH) chHelpName, argv[2]);
                    308: 
                    309:     /* Call Init() to open the data file and initialize the various tables */
                    310: 
                    311:     if (!Init())
                    312:         DosExit(EXIT_PROCESS, 1);
                    313: 
                    314:     /* If nothing was passed via the command line, then try to get a function
                    315:      * name from whatever the cursor is over when LQH is called.
                    316:      */
                    317: 
                    318:     if (argc < 2)
                    319:         fFound = ReadScreen(TRUE);
                    320:     else
                    321:         fFound = HelpSearch((NPSZ) argv[1], TRUE, 0L);
                    322: 
                    323:     /* Save the portion of the screen the box will be in */
                    324: 
                    325:     if (!(selBoxSave = BoxSave(&qhbBox)))
                    326:         DosExit(EXIT_PROCESS, 1);
                    327: 
                    328:     /* Now that the screen area for the box and the menu is saved, increase
                    329:      * the top of the box to leave room for the menu. The top will be decreased
                    330:      * by one before the screen area is restored.
                    331:      */
                    332: 
                    333:     qhbBox.top++;
                    334: 
                    335:     /* DosExit list is called so that when the program is terminated, the
                    336:      * cursor and screen will be restored to their original state.
                    337:      */
                    338: 
                    339:     DosExitList(EXLST_ADD, Abort);
                    340: 
                    341:     VioGetCurType(&viociCursor, 0);       /* Gets the current cursor data */
                    342:     viociCursor.attr = 0xFFFF;            /* Sets the attribute to hidden */
                    343:     VioSetCurType(&viociCursor, 0);
                    344: 
                    345:     /* Set the initial mouse position */
                    346: 
                    347:     mouplInit.row = 4;
                    348:     mouplInit.col = 11;
                    349:     MouSetPtrPos(&mouplInit, hmou);
                    350: 
                    351:     BoxDraw(&qhbBox);                              /* Draws the box */
                    352:     VioWrtCellStr(chMenu, 160, BOXTOP - 1, BOXLEFT, 0); /* Adds menu */
                    353: 
                    354:     if (!fFound)
                    355:         fFound = HelpSearch("QuickHelp", FALSE, 0L);
                    356: 
                    357:     /* If a topic hasn't been found, try to load the first list of topics
                    358:      * from the List menu.
                    359:      */
                    360: 
                    361:     if (!fFound && usListPos)
                    362:         fFound = HelpSearch((NPSZ) lstList[0].name, FALSE, 0L);
                    363: 
                    364:     /* If all else fails, prompt the user for a topic. */
                    365: 
                    366:     while (!fFound) {
                    367:         if (!BoxGetString(" Enter topic to find:", chBuf, 25, atMENU, hmou))
                    368:             DosExitList(EXLST_ADD, Abort);
                    369:         fFound = HelpSearch(chBuf, TRUE, 0L);
                    370:     }
                    371: 
                    372:     usInterior = qhbBox.bottom - (BOXTOP + 2);
                    373:     Display();                      /* Displays the current topic   */
                    374: 
                    375:     for (;; ) {                     /* infinite loop                */
                    376:         Input();                    /* Waits for key or mouse input */
                    377:         if (!kbdciKeyInfo.fbStatus) {   /* If not a keystroke       */
                    378:             fMouButton = FALSE;         /* Resets mouse button flag */
                    379:             if (mouevEvent.row == BOXTOP - 1) { /* If over a menu   */
                    380:                 if (mouevEvent.col < 12)
                    381:                     kbdciKeyInfo.chScan = 19;                /* 'r' */
                    382:                 else if (mouevEvent.col < 24)
                    383:                     kbdciKeyInfo.chScan = 46;                /* 'c' */
                    384:                 else if (mouevEvent.col < 32)
                    385:                     kbdciKeyInfo.chScan = 47;                /* 'v' */
                    386:                 else if (mouevEvent.col < 41)
                    387:                     kbdciKeyInfo.chScan = 24;                /* 'o' */
                    388:                 else if (mouevEvent.col > 71)
                    389:                     kbdciKeyInfo.chScan = 35;                /* 'h' */
                    390:                 else
                    391:                     continue;
                    392:             }
                    393: 
                    394:             /* Scroll the text if the mouse button is pressed when the
                    395:              * mouse pointer is on the scroll bar.
                    396:              */
                    397: 
                    398:             else if(mouevEvent.col == BOXRIGHT) {
                    399:                 if (mouevEvent.row > usInterior / 2 &&
                    400:                         mouevEvent.row < qhbBox.bottom) {
                    401:                     do {
                    402:                         ScrollDown();
                    403:                         MouReadEventQue(&mouevEvent, &MouReadType, hmou);
                    404:                     }
                    405:                     while (!mouevEvent.Time);
                    406:                 }
                    407:                 else if (mouevEvent.row < qhbBox.bottom) {
                    408:                     do {
                    409:                         ScrollUp();
                    410:                         MouReadEventQue(&mouevEvent, &MouReadType, hmou);
                    411:                     }
                    412:                     while (!mouevEvent.Time);
                    413:                 }
                    414:                 continue;
                    415:             }
                    416: 
                    417:             /* If the mouse pointer wasn't over a menu or the scroll bar,
                    418:              * try to find whatever topic is under the mouse.
                    419:              */
                    420: 
                    421:             else {
                    422:                 if (fListDisplay && mouevEvent.row < qhbBox.bottom) {
                    423: 
                    424:                     /* Set the cursor position to the mouse position */
                    425: 
                    426:                     VioSetCurPos(mouevEvent.row, 2, 0);
                    427:                     MouseRelease();   /* Waits for a button release */
                    428:                     if (ReadScreen(FALSE))
                    429:                         Display();
                    430: 
                    431:                     /* If a word on the screen couldn't be found, try
                    432:                      * the entire line.
                    433:                      */
                    434: 
                    435:                     else {
                    436:                         y = 40;                    /* largest topic */
                    437:                         VioReadCharStr(chBuf, &y, mouevEvent.row, 2, 0);
                    438:                         y = Dstrlen(chBuf) - 1;
                    439:                         while (y && chBuf[y] == ' ')
                    440:                             chBuf[y--] = 0;
                    441:                         if (HelpSearch(chBuf, TRUE, 0L))
                    442:                             Display();
                    443:                     }
                    444:                 }
                    445:                 else {
                    446:                     VioSetCurPos(mouevEvent.row, mouevEvent.col, 0);
                    447:                     MouseRelease();     /* Waits for button release */
                    448:                     if (ReadScreen(TRUE))
                    449:                         Display();
                    450:                 }
                    451:                 continue;
                    452:             }
                    453:         }
                    454: 
                    455:         /* The key scan code is processed instead of the character so that
                    456:          * alternate, shift, and control key combinations are all accepted.
                    457:          */
                    458: 
                    459:         switch(kbdciKeyInfo.chScan) {
                    460:             case 45:                                         /* 'x' */
                    461: 
                    462:                 /* Calling DosExit will invoke the DosExitList function
                    463:                  * Abort(), which will restore the cursor and the screen.
                    464:                  */
                    465: 
                    466:                 DosExit(EXIT_PROCESS, 0);
                    467: 
                    468:             case 28:                                       /* ENTER */
                    469: 
                    470:                 /* If a list of topics is being displayed, then set the
                    471:                  * cursor to the second column and call the ReadScreen()
                    472:                  * function to search for the topic name at that position.
                    473:                  */
                    474: 
                    475:                 if (fListDisplay) {
                    476:                     VioSetCurPos(selTable[usCurrent].usHighLight + 1, 2, 0);
                    477:                     if (ReadScreen(FALSE))
                    478:                         Display();
                    479:                     else {
                    480:                         y = 40;
                    481:                         VioReadCharStr(chBuf, &y,
                    482:                             selTable[usCurrent].usHighLight + 1 , 2, 0);                                 /* Vio handle           */
                    483:                         y = Dstrlen(chBuf) - 1;
                    484:                         while (y && chBuf[y] == ' ')
                    485:                             chBuf[y--] = 0;
                    486:                         if (HelpSearch(chBuf, TRUE, 0L))
                    487:                             Display();
                    488:                     }
                    489:                 }
                    490:                 break;
                    491: 
                    492:             case 23:                                       /* 'i' */
                    493:                 fBack = TRUE;
                    494:                 if (HelpSearch("", FALSE, HelpNcBack()))
                    495:                     Display();
                    496:                 else
                    497:                     BoxMessage(" No prior screen displayed ",
                    498:                         bMenuAtt, THIN, hmou, TRUE);
                    499:                 break;
                    500: 
                    501:             case 49:                                         /* 'n' */
                    502:                 if (HelpSearch("", FALSE,
                    503:                         HelpNcNext(selTable[usCurrent].ncContext)))
                    504:                     Display();
                    505:                 else
                    506:                     BoxMessage(" You are at the end of the database ",
                    507:                         bMenuAtt, THIN, hmou, TRUE);
                    508:                 break;
                    509: 
                    510:             case 31:                                         /* 's' */
                    511:                 if (BoxGetString(" Enter topic to find:", chBuf, 25,
                    512:                         atMENU, hmou))
                    513:                     if (HelpSearch(chBuf, TRUE, 0L))
                    514:                         Display();
                    515:                 break;
                    516: 
                    517:             case 47:                                         /* 'v' */
                    518:                 sMenuTablePos = 2;
                    519:                 Search();
                    520:                 break;
                    521: 
                    522:             case 24:                                         /* 'o' */
                    523:                 sMenuTablePos = 3;
                    524:                 Options();
                    525:                 break;
                    526: 
                    527:             case 19:                                         /* 'r' */
                    528:                 sMenuTablePos = 0;
                    529:                 Reference();
                    530:                 break;
                    531: 
                    532:             case 46:                                          /* 'c */
                    533:                 sMenuTablePos = 1;
                    534:                 ListMenu();
                    535:                 break;
                    536: 
                    537:             case 59:                                          /* F1 */
                    538:             case 35:                                         /* 'h' */
                    539:                 if (HelpSearch("QuickHelp", TRUE, 0L))
                    540:                     Display();
                    541:                 break;
                    542: 
                    543:             case 72:                                   /* cursor up */
                    544:                 ScrollUp();
                    545:                 break;
                    546: 
                    547:             case 80:                                 /* cursor down */
                    548:                 ScrollDown();
                    549:                 break;
                    550: 
                    551:             case 81:                                   /* PAGE DOWN */
                    552:                 if (usTotalLines <= usInterior)
                    553:                     break;
                    554:                 if (usBottomLine != usTotalLines) {
                    555:                     usBottomLine += usInterior;
                    556:                     if (usBottomLine > usTotalLines)
                    557:                         usBottomLine = usTotalLines;
                    558:                     fNewPage = TRUE;           /* Requests new page */
                    559:                 }
                    560:                 break;
                    561: 
                    562:             case 73:                                     /* PAGE UP */
                    563:                 if (usTotalLines <= usInterior ||
                    564:                         selTable[usCurrent].usTopLine == 1)
                    565:                     break;
                    566:                 if (selTable[usCurrent].usTopLine > usInterior + 1)
                    567:                     usBottomLine -= usInterior;
                    568:                 else {
                    569:                     usBottomLine = usInterior + 1;
                    570:                 }
                    571:                 fNewPage = TRUE;             /* Requests a new page */
                    572:                 break;
                    573: 
                    574:             case 71:                                        /* HOME */
                    575:                 usBottomLine = usInterior + 1;
                    576:                 if (usBottomLine > usTotalLines)
                    577:                     usBottomLine = usTotalLines;
                    578:                 fNewPage = TRUE;             /* Requests a new page */
                    579:                 break;
                    580: 
                    581:             case 79:                                         /* END */
                    582:                 if (usTotalLines <= usInterior)
                    583:                     break;
                    584:                 if (usBottomLine != usTotalLines) {
                    585:                     usBottomLine = usTotalLines;
                    586:                     fNewPage = TRUE;
                    587:                 }
                    588:                 break;
                    589: 
                    590:             default:
                    591:                 break;
                    592:         }
                    593: 
                    594:         if (fNewPage) {
                    595:             selTable[usCurrent].usTopLine = usBottomLine - usInterior;
                    596:             Display();
                    597:             fNewPage = FALSE;
                    598:         }
                    599:     }
                    600: }
                    601: 
                    602: /****************************************************************************
                    603: 
                    604:     FUNCTION: Abort();
                    605: 
                    606:     PURPOSE: Restore the cursor, and clean up memory
                    607: 
                    608:     COMMENTS:
                    609:         This function is called when the program is aborted to restore the
                    610:         cursor type, cursor position, and the screen.
                    611: 
                    612: ****************************************************************************/
                    613: 
                    614: VOID FAR Abort() {
                    615:     qhbBox.top--;           /* Restores the menu as well as the box */
                    616:     BoxRestore(&qhbBox, selBoxSave); /* Restores the screen         */
                    617:     DosExitList(EXLST_EXIT, 0L);     /* termination completed       */
                    618: }
                    619: 
                    620: /****************************************************************************
                    621: 
                    622:     FUNCTION: ReadScreen();
                    623: 
                    624:     PURPOSE: If the cursor is over a topic name, retrieve the topic
                    625: 
                    626:     COMMENTS:
                    627:         This function takes the current cursor position on the screen,
                    628:         backs up to the first non-alphabetic character or the beginning of
                    629:         the line, and then forms a search string by copying all characters
                    630:         up until the first non-alphabetic character. It then calls the
                    631:         HelpSearch() function to retrieve the topic matching the search
                    632:         string.
                    633: 
                    634: ****************************************************************************/
                    635: 
                    636: BOOL ReadScreen(fFlag)
                    637: BOOL fFlag;
                    638: {
                    639:     USHORT usRow, usCol, usLen = 80;
                    640:     INT i, j;
                    641:     CHAR chPatBuf[80];
                    642: 
                    643:     VioGetCurPos(&usRow, &usCol, 0);        /* get cursor position  */
                    644:     j = usCol;                              /* save cursor column   */
                    645:     VioReadCharStr(chPatBuf,                /* buffer for string    */
                    646:         &usLen,                             /* length of the buffer */
                    647:         usRow,                              /* starting row         */
                    648:         0,                                  /* starting column      */
                    649:         0);                                 /* Vio handle           */
                    650: 
                    651:     if (usCol && !isalpha(chPatBuf[usCol]))
                    652:         usCol--;
                    653: 
                    654:     /* Back up the cursor to the first non-letter, or beginning of the line */
                    655: 
                    656:     for (i = usCol; isalpha(chPatBuf[i]) && i >= 0; i--);
                    657:     i++;                /* Backs up to the first letter of the word */
                    658: 
                    659:     /* Copy everything up to the first non-letter into the first part of
                    660:      * the pattern buffer.
                    661:      */
                    662: 
                    663:     for (j = 0; isalpha(chPatBuf[i]) && i < 80; i++, j++)
                    664:         chPatBuf[j] = chPatBuf[i];
                    665:     if (i < 80 && j > 2) {
                    666:         chPatBuf[j] = 0;
                    667:         return (HelpSearch(chPatBuf, fFlag, 0L));
                    668:     }
                    669:     return FALSE;
                    670: }
                    671: 
                    672: /****************************************************************************
                    673: 
                    674:     FUNCTION: ScrollUp()
                    675: 
                    676:     PURPOSE: Scroll the text up one line
                    677: 
                    678:     COMMENTS:
                    679:         This function is called to scroll up either a highlighted line or
                    680:         the text.
                    681: 
                    682: ****************************************************************************/
                    683: 
                    684: VOID ScrollUp() {
                    685:     if (selTable[usCurrent].usTopLine == 1 &&
                    686:             selTable[usCurrent].usHighLight == BOXTOP)
                    687:         return;
                    688:     if (fListDisplay)
                    689:         VioWrtCellStr(bHoldString, cbHoldLength,
                    690:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    691: 
                    692:     if (fListDisplay && selTable[usCurrent].usHighLight > 1) {
                    693:         selTable[usCurrent].usHighLight--;
                    694:     }
                    695: 
                    696:     else if (selTable[usCurrent].usTopLine > 1) {
                    697:         VioScrollDn(qhbBox.top + 1,              /* top row         */
                    698:             BOXLEFT + 2,                         /* left column     */
                    699:             qhbBox.bottom - 1,                   /* bottom row      */
                    700:             BOXRIGHT - 1,                        /* right column    */
                    701:             1,                                   /* lines to scroll */
                    702:             achBlank,
                    703:             0);
                    704:         selTable[usCurrent].usTopLine--;
                    705:         usBottomLine--;
                    706:         VioWrtCellStr(strTable[selTable[usCurrent].usTopLine].addr,
                    707:             strTable[selTable[usCurrent].usTopLine].cb,
                    708:             BOXTOP + 1, BOXLEFT + 2, 0);
                    709:     }
                    710:     if (fListDisplay) {                    /* Turns on highlighting */
                    711:         VioReadCellStr(bHoldString, &cbHoldLength,
                    712:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    713:         VioWrtNAttr(&bHiAtt, (BOXRIGHT - 1) - (BOXLEFT + 1),
                    714:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    715:     }
                    716:     BoxScroll(&qhbBox, usTotalLines, selTable[usCurrent].usTopLine, atBOX);
                    717: }
                    718: 
                    719: /****************************************************************************
                    720: 
                    721:     FUNCTION: ScrollUp()
                    722: 
                    723:     PURPOSE: Scroll the text up one line
                    724: 
                    725:     COMMENTS:
                    726:         This function is called to scroll down either a highlighted line or
                    727:         the text.
                    728: 
                    729: ****************************************************************************/
                    730: 
                    731: VOID ScrollDown() {
                    732:     if (usBottomLine == usTotalLines &&
                    733:             selTable[usCurrent].usHighLight == usBottomLine)
                    734:         return;
                    735:     if (fListDisplay)
                    736:         VioWrtCellStr(bHoldString, cbHoldLength,
                    737:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    738: 
                    739:     if (fListDisplay && selTable[usCurrent].usHighLight <= usInterior)
                    740:         selTable[usCurrent].usHighLight++;
                    741:     else if (usBottomLine < usTotalLines) {
                    742:         VioScrollUp(qhbBox.top + 1,              /* top row         */
                    743:             BOXLEFT + 2,                         /* left column     */
                    744:             qhbBox.bottom - 1,                   /* bottom row      */
                    745:             BOXRIGHT - 1,                        /* right column    */
                    746:             1,                                   /* lines to scroll */
                    747:             achBlank,
                    748:             0);
                    749:         selTable[usCurrent].usTopLine++;
                    750:         usBottomLine++;
                    751:         VioWrtCellStr(strTable[usBottomLine].addr, strTable[usBottomLine].cb,
                    752:             qhbBox.bottom - 1, BOXLEFT + 2, 0);
                    753:     }
                    754:     if (fListDisplay) {                    /* Turns on highlighting */
                    755:         VioReadCellStr(bHoldString, &cbHoldLength,
                    756:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    757:         VioWrtNAttr(&bHiAtt, (BOXRIGHT - 1) - (BOXLEFT + 1),
                    758:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    759:     }
                    760:     BoxScroll(&qhbBox, usTotalLines, selTable[usCurrent].usTopLine, atBOX);
                    761: }
                    762: 
                    763: /****************************************************************************
                    764: 
                    765:     FUNCTION: Display();
                    766: 
                    767:     PURPOSE: Display a page from the current topic
                    768: 
                    769:     COMMENTS:
                    770:         This function first clears the interior of the box by scrolling
                    771:         spaces with a normal attribute into the box. It then retrieves the
                    772:         top-line number from the selTable structure and uses the global
                    773:         usBottomLine variable to determine how many lines to display. It
                    774:         then checks the usHighLight member of the selTable strucutre to
                    775:         determine if one of the lines is to be highlighted. The final
                    776:         action is to call BoxScroll to position the inverse block on the
                    777:         right side of the box border to indicate where the current line is
                    778:         in the text.
                    779: 
                    780: ****************************************************************************/
                    781: 
                    782: VOID Display() {
                    783:     USHORT usLine, i;
                    784: 
                    785:     usBottomLine = usInterior + selTable[usCurrent].usTopLine;
                    786:     if (usBottomLine > usTotalLines)
                    787:         usBottomLine = usTotalLines;
                    788: 
                    789:     VioScrollDn(BOXTOP + 1, BOXLEFT + 1, qhbBox.bottom - 1,
                    790:         BOXRIGHT - 1, usInterior + 1, achBlank, 0);
                    791:     for (i = 1, usLine = selTable[usCurrent].usTopLine;
                    792:             usLine <= usBottomLine; usLine++, i++)
                    793:         VioWrtCellStr(strTable[usLine].addr, strTable[usLine].cb,
                    794:             BOXTOP + i, BOXLEFT + 2, 0);
                    795:     if (selTable[usCurrent].usHighLight) {
                    796: 
                    797:         /* Before highlighting a line, read the entire line into a buffer
                    798:          * so that when the user is scrolling, the line can be restored with
                    799:          * the previous attributes.
                    800:          */
                    801: 
                    802:         VioReadCellStr(bHoldString, &cbHoldLength,
                    803:             selTable[usCurrent].usHighLight + 1,BOXLEFT + 1, 0);
                    804:         VioWrtNAttr(&bHiAtt, (BOXRIGHT - 1) - (BOXLEFT + 1),
                    805:             selTable[usCurrent].usHighLight + 1, BOXLEFT + 1, 0);
                    806:     }
                    807:     BoxScroll(&qhbBox, usTotalLines, selTable[usCurrent].usTopLine, atBOX);
                    808: }
                    809: 
                    810: /****************************************************************************
                    811: 
                    812:     FUNCTION:
                    813:         MouseRelease();
                    814: 
                    815:     PURPOSE: Waits for the release of the mouse button
                    816: 
                    817: ****************************************************************************/
                    818: 
                    819: VOID MouseRelease() {
                    820:     USHORT usMouWait = 1;                /* Waits for a mouse event */
                    821: 
                    822:     do {
                    823:         MouReadEventQue(&mouevEvent, &usMouWait, hmou);
                    824:     }
                    825:     while (mouevEvent.fs > 1);   /* while a mouse button is pressed */
                    826: }
                    827: 
                    828: /****************************************************************************
                    829: 
                    830:     FUNCTION:
                    831:         isalpha(PCH, PCH, USHORT);
                    832: 
                    833:     PURPOSE: Returns TRUE if character is alphabetic
                    834: 
                    835:     COMMENTS:
                    836:         This function is defined here to avoid bringing in the C runtime.
                    837: 
                    838: ****************************************************************************/
                    839: 
                    840: BOOL isalpha(chVal)
                    841: CHAR chVal;
                    842: {
                    843:     return ((chVal >= 'A' && chVal <= 'Z') ||
                    844:         (chVal >= 'a' && chVal <= 'z'));
                    845: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.