|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.