|
|
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.