Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6725 | siemargl | 1 | /* |
2 | Copyright (c) 1990-2000 Info-ZIP. All rights reserved. |
||
3 | |||
4 | See the accompanying file LICENSE, version 2000-Apr-09 or later |
||
5 | (the contents of which are also included in unzip.h) for terms of use. |
||
6 | If, for some reason, all these files are missing, the Info-ZIP license |
||
7 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html |
||
8 | */ |
||
9 | /*--------------------------------------------------------------------------- |
||
10 | |||
11 | macscreen.c |
||
12 | This file is only linked into the standalone version (not SIOUX) of unzip. |
||
13 | Macintosh-GUI routines. |
||
14 | |||
15 | ---------------------------------------------------------------------------*/ |
||
16 | |||
17 | |||
18 | /*****************************************************************************/ |
||
19 | /* Includes */ |
||
20 | /*****************************************************************************/ |
||
21 | |||
22 | #include |
||
23 | |||
24 | #include |
||
25 | #include |
||
26 | #include |
||
27 | |||
28 | |||
29 | /*****************************************************************************/ |
||
30 | /* Macros, typedefs */ |
||
31 | /*****************************************************************************/ |
||
32 | |||
33 | #define bufferSize 4096 |
||
34 | |||
35 | #define screenWindow 128 |
||
36 | |||
37 | #define pauseOption 0x0001 |
||
38 | #define scrollOption 0x0002 |
||
39 | |||
40 | |||
41 | /*****************************************************************************/ |
||
42 | /* Module level Vars */ |
||
43 | /*****************************************************************************/ |
||
44 | |||
45 | static Rect scrollRect, pauseRect; |
||
46 | static WindowPtr theWindow; |
||
47 | static RgnHandle scrollRgn; |
||
48 | |||
49 | static short fontHeight, fontWidth, screenHeight, screenWidth; |
||
50 | static short currentPosition, maxPosition, pausePosition; |
||
51 | |||
52 | static short *screenLength, startLine, endLine; |
||
53 | static char *screenImage, **screenLine; |
||
54 | |||
55 | static int screenOptions; |
||
56 | |||
57 | |||
58 | |||
59 | /*****************************************************************************/ |
||
60 | /* Prototypes */ |
||
61 | /*****************************************************************************/ |
||
62 | |||
63 | void screenOpen(char *); |
||
64 | void screenControl(char *, int); |
||
65 | void screenClose(void); |
||
66 | void screenUpdate(WindowPtr); |
||
67 | void screenDisplay(char *); |
||
68 | void screenDump(char *, long); |
||
69 | |||
70 | char *macfgets(char *, int, FILE *); |
||
71 | int macfprintf(FILE *, char *, ...); |
||
72 | int macprintf(char *, ...); |
||
73 | int macgetch(void); |
||
74 | |||
75 | |||
76 | /*****************************************************************************/ |
||
77 | /* Functions */ |
||
78 | /*****************************************************************************/ |
||
79 | |||
80 | void screenOpen(char *Title) { |
||
81 | FontInfo fontInfo; |
||
82 | int n; |
||
83 | short fontFamID; |
||
84 | |||
85 | theWindow = GetNewWindow(screenWindow, nil, (WindowPtr)(-1)); |
||
86 | |||
87 | if ((Title != NULL) && (*Title != '\0')) { |
||
88 | c2pstr(Title); |
||
89 | SetWTitle(theWindow, (StringPtr)Title); |
||
90 | p2cstr((StringPtr)Title); |
||
91 | } |
||
92 | |||
93 | ShowWindow(theWindow); |
||
94 | |||
95 | SetPort(theWindow); |
||
96 | GetFNum( "\pMonaco", &fontFamID ); |
||
97 | TextFont(fontFamID); |
||
98 | TextSize(9); |
||
99 | |||
100 | GetFontInfo(&fontInfo); |
||
101 | fontHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading; |
||
102 | fontWidth = fontInfo.widMax; |
||
103 | |||
104 | scrollRgn = NewRgn(); |
||
105 | |||
106 | screenWidth = (theWindow->portRect.right - theWindow->portRect.left - 10) / |
||
107 | fontWidth; |
||
108 | screenHeight = (theWindow->portRect.bottom - theWindow->portRect.top) / |
||
109 | fontHeight; |
||
110 | maxPosition = screenHeight * fontHeight; |
||
111 | pausePosition = maxPosition - (currentPosition = fontHeight); |
||
112 | |||
113 | SetRect(&scrollRect, theWindow->portRect.left, |
||
114 | theWindow->portRect.top + fontInfo.descent, |
||
115 | theWindow->portRect.right, |
||
116 | theWindow->portRect.bottom); |
||
117 | SetRect(&pauseRect, theWindow->portRect.left, |
||
118 | pausePosition + fontInfo.descent, |
||
119 | theWindow->portRect.right, |
||
120 | theWindow->portRect.bottom); |
||
121 | |||
122 | MoveTo(5, currentPosition); |
||
123 | |||
124 | n = (sizeof(char *) + sizeof(short) + screenWidth) * screenHeight; |
||
125 | |||
126 | screenLine = (char **)NewPtr(n); |
||
127 | |||
128 | screenLength = (short *)&screenLine[screenHeight]; |
||
129 | screenImage = (char *)&screenLength[screenHeight]; |
||
130 | |||
131 | for (n = 0; n < screenHeight; n++) { |
||
132 | screenLine[n] = &screenImage[n * screenWidth]; |
||
133 | screenLength[n] = 0; |
||
134 | } |
||
135 | |||
136 | startLine = endLine = 0; |
||
137 | |||
138 | screenOptions = 0; |
||
139 | |||
140 | return; |
||
141 | } |
||
142 | |||
143 | |||
144 | |||
145 | |||
146 | void screenControl(char *options, int setting) { |
||
147 | int n = 0; |
||
148 | |||
149 | while (*options) { |
||
150 | switch (*options) { |
||
151 | case 'p': |
||
152 | n |= pauseOption; |
||
153 | break; |
||
154 | case 's': |
||
155 | n |= scrollOption; |
||
156 | break; |
||
157 | default: |
||
158 | break; |
||
159 | } |
||
160 | options += 1; |
||
161 | } |
||
162 | |||
163 | if (setting == 0) |
||
164 | screenOptions &= (n ^ (-1)); |
||
165 | else |
||
166 | screenOptions |= n; |
||
167 | |||
168 | if ((pausePosition = maxPosition - currentPosition) == 0) |
||
169 | pausePosition = maxPosition - fontHeight; |
||
170 | |||
171 | return; |
||
172 | } |
||
173 | |||
174 | |||
175 | |||
176 | |||
177 | void screenClose(void) { |
||
178 | DisposePtr((Ptr)screenLine); |
||
179 | |||
180 | DisposeWindow(theWindow); |
||
181 | |||
182 | return; |
||
183 | } |
||
184 | |||
185 | |||
186 | |||
187 | |||
188 | void screenUpdate(WindowPtr window) { |
||
189 | GrafPort *savePort; |
||
190 | int m, n; |
||
191 | |||
192 | if (window == theWindow) { |
||
193 | BeginUpdate(window); |
||
194 | if (!EmptyRgn(window->visRgn)) { |
||
195 | GetPort(&savePort); |
||
196 | SetPort(window); |
||
197 | n = startLine; |
||
198 | for (m = 1; ; m++) { |
||
199 | MoveTo(5, m * fontHeight); |
||
200 | if (screenLength[n] != 0) |
||
201 | DrawText(screenLine[n], 0, screenLength[n]); |
||
202 | if (n == endLine) break; |
||
203 | if ((n += 1) == screenHeight) n = 0; |
||
204 | } |
||
205 | SetPort(savePort); |
||
206 | } |
||
207 | EndUpdate(window); |
||
208 | } |
||
209 | |||
210 | return; |
||
211 | } |
||
212 | |||
213 | |||
214 | |||
215 | |||
216 | static void screenNewline(void) { |
||
217 | MoveTo(5, currentPosition += fontHeight); |
||
218 | if (currentPosition > maxPosition) { |
||
219 | if (screenOptions & scrollOption) { |
||
220 | ScrollRect(&scrollRect, 0, -fontHeight, scrollRgn); |
||
221 | MoveTo(5, currentPosition = maxPosition); |
||
222 | if ((startLine += 1) == screenHeight) startLine = 0; |
||
223 | } else { |
||
224 | ScrollRect(&scrollRect, 0, -maxPosition + fontHeight, scrollRgn); |
||
225 | MoveTo(5, currentPosition = fontHeight + fontHeight); |
||
226 | startLine = endLine; |
||
227 | } |
||
228 | } |
||
229 | pausePosition -= fontHeight; |
||
230 | |||
231 | if ((endLine += 1) == screenHeight) endLine = 0; |
||
232 | screenLength[endLine] = 0; |
||
233 | |||
234 | return; |
||
235 | } |
||
236 | |||
237 | |||
238 | |||
239 | |||
240 | static char waitChar(void) { |
||
241 | WindowPtr whichWindow; |
||
242 | EventRecord theEvent; |
||
243 | |||
244 | for ( ; ; ) { |
||
245 | SystemTask(); |
||
246 | if (GetNextEvent(everyEvent, &theEvent)) { |
||
247 | switch (theEvent.what) { |
||
248 | case keyDown: |
||
249 | if ((theEvent.modifiers & cmdKey) && |
||
250 | ((theEvent.message & charCodeMask) == '.')) |
||
251 | ExitToShell(); |
||
252 | return(theEvent.message & charCodeMask); |
||
253 | case mouseDown: |
||
254 | if (FindWindow(theEvent.where, &whichWindow) == inSysWindow) |
||
255 | SystemClick(&theEvent, whichWindow); |
||
256 | break; |
||
257 | case updateEvt: |
||
258 | screenUpdate((WindowPtr)theEvent.message); |
||
259 | break; |
||
260 | } |
||
261 | } |
||
262 | } |
||
263 | } |
||
264 | |||
265 | |||
266 | |||
267 | |||
268 | static void screenPause(void) { |
||
269 | if (pausePosition == 0) { |
||
270 | if (screenOptions & pauseOption) { |
||
271 | DrawText("Press any key to continue ...", 0, 29); |
||
272 | memcpy(screenLine[endLine], "Press any key to continue ...", 29); |
||
273 | screenLength[endLine] = 29; |
||
274 | |||
275 | (void)waitChar(); |
||
276 | |||
277 | EraseRect(&pauseRect); |
||
278 | MoveTo(5, currentPosition); |
||
279 | screenLength[endLine] = 0; |
||
280 | } |
||
281 | |||
282 | pausePosition = maxPosition - fontHeight; |
||
283 | } |
||
284 | |||
285 | return; |
||
286 | } |
||
287 | |||
288 | |||
289 | |||
290 | |||
291 | void screenDisplay(char *s) { |
||
292 | GrafPort *savePort; |
||
293 | int m, n; |
||
294 | char *t; |
||
295 | |||
296 | GetPort(&savePort); |
||
297 | SetPort(theWindow); |
||
298 | |||
299 | while (*s) { |
||
300 | screenPause(); |
||
301 | |||
302 | for (t = s; (*s) && (*s != '\n') && (*s != '\r'); s++) |
||
303 | ; /* empty body */ |
||
304 | |||
305 | if ((n = s - t) > (m = screenWidth - screenLength[endLine])) n = m; |
||
306 | |||
307 | if (n > 0) { |
||
308 | DrawText(t, 0, n); |
||
309 | memcpy(screenLine[endLine] + screenLength[endLine], t, n); |
||
310 | screenLength[endLine] += n; |
||
311 | } |
||
312 | |||
313 | if ((*s == '\n') || (*s == '\r')) { |
||
314 | screenNewline(); |
||
315 | s += 1; |
||
316 | } |
||
317 | } |
||
318 | |||
319 | SetPort(savePort); |
||
320 | |||
321 | return; |
||
322 | } |
||
323 | |||
324 | |||
325 | |||
326 | |||
327 | void screenDump(char *s, long n) { |
||
328 | GrafPort *savePort; |
||
329 | int k, m; |
||
330 | char *t; |
||
331 | |||
332 | GetPort(&savePort); |
||
333 | SetPort(theWindow); |
||
334 | |||
335 | while (n) { |
||
336 | screenPause(); |
||
337 | |||
338 | for (t = s; (n) && (*s != '\n') && (*s != '\r'); s++, n--) |
||
339 | ; /* empty body */ |
||
340 | |||
341 | if ((k = s - t) > (m = screenWidth - screenLength[endLine])) k = m; |
||
342 | |||
343 | if (k > 0) { |
||
344 | DrawText(t, 0, k); |
||
345 | memcpy(screenLine[endLine] + screenLength[endLine], t, k); |
||
346 | screenLength[endLine] += k; |
||
347 | } |
||
348 | |||
349 | if ((*s == '\n') || (*s == '\r')) { |
||
350 | screenNewline(); |
||
351 | s += 1; |
||
352 | n -= 1; |
||
353 | } |
||
354 | } |
||
355 | |||
356 | SetPort(savePort); |
||
357 | |||
358 | return; |
||
359 | } |
||
360 | |||
361 | |||
362 | |||
363 | |||
364 | char *macfgets(char *s, int n, FILE *stream) { |
||
365 | GrafPort *savePort; |
||
366 | char c, *t = s; |
||
367 | |||
368 | stream = stream; |
||
369 | |||
370 | GetPort(&savePort); |
||
371 | SetPort(theWindow); |
||
372 | |||
373 | for (n -= 1; (n > 0) && ((c = waitChar()) != '\r'); n -= 1) { |
||
374 | DrawChar(*t++ = c); |
||
375 | if (screenLength[endLine] < screenWidth) |
||
376 | screenLine[endLine][screenLength[endLine]++] = c; |
||
377 | } |
||
378 | |||
379 | if (c == '\r') screenNewline(); |
||
380 | |||
381 | *t = '\0'; |
||
382 | |||
383 | SetPort(savePort); |
||
384 | |||
385 | return(s); |
||
386 | } |
||
387 | |||
388 | |||
389 | |||
390 | |||
391 | int macfprintf(FILE *stream, char *format, ...) |
||
392 | { |
||
393 | char buffer[bufferSize]; |
||
394 | va_list ap; |
||
395 | int rc; |
||
396 | |||
397 | stream = stream; |
||
398 | |||
399 | va_start(ap, format); |
||
400 | rc = vsprintf(buffer, format, ap); |
||
401 | va_end(ap); |
||
402 | |||
403 | screenDisplay(buffer); |
||
404 | |||
405 | return rc; |
||
406 | } |
||
407 | |||
408 | |||
409 | |||
410 | |||
411 | int macprintf(char *format, ...) |
||
412 | { |
||
413 | char buffer[bufferSize]; |
||
414 | va_list ap; |
||
415 | int rc; |
||
416 | |||
417 | va_start(ap, format); |
||
418 | rc = vsprintf(buffer, format, ap); |
||
419 | va_end(ap); |
||
420 | |||
421 | screenDisplay(buffer); |
||
422 | |||
423 | return rc; |
||
424 | } |
||
425 | |||
426 | |||
427 | |||
428 | /***********************/ |
||
429 | /* Function macgetch() */ |
||
430 | /***********************/ |
||
431 | |||
432 | int macgetch(void) |
||
433 | { |
||
434 | WindowPtr whichWindow; |
||
435 | EventRecord theEvent; |
||
436 | char c; /* one-byte buffer for read() to use */ |
||
437 | |||
438 | do { |
||
439 | SystemTask(); |
||
440 | if (!GetNextEvent(everyEvent, &theEvent)) |
||
441 | theEvent.what = nullEvent; |
||
442 | else { |
||
443 | switch (theEvent.what) { |
||
444 | case keyDown: |
||
445 | c = theEvent.message & charCodeMask; |
||
446 | break; |
||
447 | case mouseDown: |
||
448 | if (FindWindow(theEvent.where, &whichWindow) == |
||
449 | inSysWindow) |
||
450 | SystemClick(&theEvent, whichWindow); |
||
451 | break; |
||
452 | case updateEvt: |
||
453 | screenUpdate((WindowPtr)theEvent.message); |
||
454 | break; |
||
455 | } |
||
456 | } |
||
457 | } while (theEvent.what != keyDown); |
||
458 | |||
459 | macprintf("*"); |
||
460 | |||
461 | return (int)c; |
||
462 | }>> |