home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / VBROWSE.ZIP / BROWSE.C < prev    next >
C/C++ Source or Header  |  1989-02-08  |  6KB  |  245 lines

  1. /*
  2.     VIO File Browsing Application
  3.     Created by Microsoft Corporation, 1989
  4. */
  5. #define     INCL_KBD
  6. #define     INCL_VIO
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <os2.h>
  10. #include <string.h>
  11. #include "browse.h"
  12. /*
  13.     Global Variables
  14. */
  15. FILE    *pfInput;
  16. char    *aszLines[NUM_DATA_LINES];
  17. SHORT    sTopLine= -1;
  18. SHORT    sRows;
  19. SHORT    HorScrollPos=0;
  20. BYTE    abBlank[2] = { 0x20, 0x07 }; 
  21.  
  22. /*
  23.     Macros for Vio calls
  24.     The last parameter is zero because we're using a VIO PS
  25. */
  26. #define ClearScreen()    VioScrollDn(0, 0, -1, -1, -1, abBlank, 0)
  27. #define    Move(r,c)    VioSetCurPos(r, c, 0)
  28. #define ScrollDown(n)    VioScrollDn(0, 0, -1, -1,  n, abBlank, 0)
  29. #define ScrollUp(n)    VioScrollUp(0, 0, -1, -1,  n, abBlank, 0)
  30. #define Write(s)    VioWrtTTY(s, strlen(s), 0)
  31. /*
  32.     Macros for bounds checking
  33. */
  34. #define Abs(x)        (((x) > 0) ? (x) : (-(x)))
  35. #define Max(x, y)    (((x) > (y)) ? (x) : (y))
  36. #define Min(x, y)    (((x) < (y)) ? (x) : (y))
  37. #define LowerBound(pos, disp, lbound)    Max(pos - disp, lbound)
  38. #define UpperBound(pos, disp, ubound)    Min(pos + disp, ubound)
  39.  
  40. /*
  41.     Functions
  42. */
  43. int cdecl main(int argc, char *argv[]) {
  44. /*
  45.     Open the input file and initialize globals
  46. */
  47.     char    *szFilename;
  48.     VIOMODEINFO    viomiMode;
  49.  
  50.     /*
  51.     Open the Input File
  52.     */
  53.     if (argc == 1)
  54.     pfInput = stdin;
  55.     else {
  56.     szFilename = argv[1];
  57.     if (!(pfInput = fopen(szFilename,"r"))) {
  58.         fprintf(stderr, "***Error:  Could not open %s", szFilename);
  59.         return(-1);
  60.     }
  61.     }
  62.     /*
  63.     Read it into the line buffer
  64.     */
  65.     if (ReadFile()) return(-1);
  66.     /*
  67.     Get the video parameters
  68.     */
  69.     viomiMode.cb = sizeof(viomiMode);
  70.     VioGetMode(&viomiMode, 0);
  71.     sRows = (SHORT) viomiMode.row;
  72.  
  73.     DisplayScreen(0, TRUE);
  74.     ManipulateFile();
  75.  
  76.     return 0;
  77. }
  78.  
  79. SHORT ReadFile(VOID) {
  80. /*
  81.     Read lines from the file into the line buffer
  82.     If there's an error, abort the program (return -1)
  83. */
  84.     char szLine[MAXLINELENGTH];
  85.  
  86.     while (fgets(szLine, MAXLINELENGTH, pfInput)) {
  87.  
  88.     /* Convert LF (\n) character to NULL (\0) */
  89.     if (szLine[strlen(szLine)-1] == '\n')
  90.         szLine[strlen(szLine)-1] = 0;
  91.     else {
  92.         fprintf(stderr,"***Error:  Incomplete line read\n");
  93.         return(-1);
  94.     }
  95.  
  96.     /* Put the line into the line buffer */
  97.     if (StoreLine(szLine)) {
  98.         fprintf(stderr,"***Error:  Line buffer full\n");
  99.         return(-1);
  100.     }
  101.     }
  102.  
  103.     /* Close the Input file */
  104.     fclose(pfInput);
  105.     return 0;
  106. }
  107.  
  108. VOID ManipulateFile(VOID) {
  109. /*
  110.     Main loop for display processing
  111. */
  112.     CHAR    ch;
  113.     SHORT   sLine = 0;
  114.  
  115.     /* The main command loop */
  116.     while ((ch = GetKbdInput()) != ESC) {
  117.     /*
  118.         Take user input and compute new top line of screen
  119.         by taking appropriate jump in jumptable.
  120.  
  121.         Note:  no horizontal scrolling.
  122.     */
  123.     switch (ch) {
  124.     case LINE_UP:     sLine = LowerBound(sLine, 1, 0);        break;
  125.     case LINE_DOWN:  sLine = UpperBound(sLine, 1, BOTTOM);        break;
  126.     case PAGE_UP:     sLine = LowerBound(sLine, sRows, 0);        break;
  127.     case PAGE_DOWN:  sLine = UpperBound(sLine, sRows, BOTTOM);    break;
  128.     case HOME_KEY:     sLine = 0;                    break;
  129.     case END_KEY:     sLine = BOTTOM;                break;
  130.     default:                            break;
  131.     }
  132.     DisplayScreen((USHORT) sLine, !ch);
  133.     }
  134.  
  135.     /* Set Cursor to the bottom of the screen */
  136.     Move((USHORT) sRows - 1, 0);
  137. }
  138.  
  139. SHORT StoreLine(char *szLine) {
  140. /*
  141.     Put a line into the line buffer; line numbers are free
  142.     For > 64K data, add code here and in RetrieveLine
  143. */
  144.     /*
  145.     Check if top line exceeded, or if malloc() fails
  146.     */
  147.     if ((sTopLine == NUM_DATA_LINES) ||
  148.     ((aszLines[++sTopLine] = malloc(strlen(szLine) + 1)) == NULL))
  149.  
  150.     return -1;
  151.     /*
  152.     Copy szLine into the line buffer
  153.     */
  154.     strcpy(aszLines[sTopLine], szLine);
  155.     return 0;
  156. }
  157.  
  158. SHORT RetrieveLine(char **pszLine , USHORT usLineNum) {
  159. /*
  160.     Return line numbered usLineNum
  161. */
  162.     if (usLineNum > sTopLine) return -1;  /* Out of range */
  163.     *pszLine = aszLines[usLineNum];
  164.     return 0;
  165. }
  166.  
  167. VOID DisplayScreen(USHORT usDisplayTop, BOOL fForceDraw) {
  168. /*
  169.     Display lines on the screen, starting at usDisplayTop
  170.     by scrolling, then painting new information
  171. */
  172.     SHORT        sDelta;
  173.     static USHORT   usOldDispTop;
  174.  
  175.     sDelta = usDisplayTop - usOldDispTop;
  176.     /*
  177.     If only a few lines need repainting...
  178.     */
  179.     if ((Abs(sDelta) < sRows) && !fForceDraw ) {
  180.     /*
  181.         Moving to a "higher line", so:
  182.         Scroll down by the amount (make the difference positive)
  183.         Paint in the lines at the top
  184.     */
  185.     if (sDelta < 0) {
  186.         ScrollDown(-sDelta);
  187.         Refresh(usDisplayTop, -sDelta, 0);
  188.     } else {
  189.         /*
  190.         Moving to a "lower line", so:
  191.         Scroll the information up, and paint at the bottom
  192.         */
  193.         ScrollUp(sDelta);
  194.         Refresh(usDisplayTop + sRows - sDelta, sDelta, sRows - sDelta);
  195.     }
  196.     } else {    /* Paint the entire screen */
  197.     ClearScreen();
  198.     Refresh(usDisplayTop, sRows, 0);
  199.     }
  200.     usOldDispTop = usDisplayTop;
  201. }
  202.  
  203. VOID Refresh (USHORT iLine, USHORT usLines, USHORT usStart) {
  204. /*
  205.     Updates usLines lines, starting at line iLine in the line
  206.     buffer, and line usStart on the screen
  207. */
  208.     USHORT usLine;
  209.     char   *szLine;
  210.  
  211.     for (usLine = 0; usLine < usLines; usLine++) {
  212.     /*
  213.         Read the line, set the cursor, print the line
  214.     */
  215.     if (RetrieveLine(&szLine, (iLine + usLine))) break;
  216.     Move((usStart + usLine), 0);
  217.     Write(szLine);
  218.     }
  219. }
  220.  
  221. CHAR GetKbdInput(VOID) {
  222. /*
  223.     Get chars, then check scan codes and return our own values
  224. */
  225.     KBDKEYINFO kbciKeyInfo;
  226.  
  227.     /*
  228.     Wait for characters
  229.     */
  230.     KbdCharIn(&kbciKeyInfo, IO_WAIT, 0);
  231.  
  232.     switch (kbciKeyInfo.chScan) {
  233.     case ESC:             /* escape */
  234.     case LINE_UP:
  235.     case LINE_DOWN:
  236.     case PAGE_UP:
  237.     case PAGE_DOWN:
  238.     case HOME_KEY:
  239.     case END_KEY:
  240.         return kbciKeyInfo.chScan; break;
  241.     default:
  242.        return(NULL); break;
  243.     }
  244. }
  245.