macscreen.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 2000-Apr-09 or later
  4. (the contents of which are also included in unzip.h) for terms of use.
  5. If, for some reason, all these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  7. */
  8. /*---------------------------------------------------------------------------
  9. macscreen.c
  10. This file is only linked into the standalone version (not SIOUX) of unzip.
  11. Macintosh-GUI routines.
  12. ---------------------------------------------------------------------------*/
  13. /*****************************************************************************/
  14. /* Includes */
  15. /*****************************************************************************/
  16. #include <QuickDraw.h>
  17. #include <stdio.h>
  18. #include <stdarg.h>
  19. #include <string.h>
  20. /*****************************************************************************/
  21. /* Macros, typedefs */
  22. /*****************************************************************************/
  23. #define bufferSize 4096
  24. #define screenWindow 128
  25. #define pauseOption 0x0001
  26. #define scrollOption 0x0002
  27. /*****************************************************************************/
  28. /* Module level Vars */
  29. /*****************************************************************************/
  30. static Rect scrollRect, pauseRect;
  31. static WindowPtr theWindow;
  32. static RgnHandle scrollRgn;
  33. static short fontHeight, fontWidth, screenHeight, screenWidth;
  34. static short currentPosition, maxPosition, pausePosition;
  35. static short *screenLength, startLine, endLine;
  36. static char *screenImage, **screenLine;
  37. static int screenOptions;
  38. /*****************************************************************************/
  39. /* Prototypes */
  40. /*****************************************************************************/
  41. void screenOpen(char *);
  42. void screenControl(char *, int);
  43. void screenClose(void);
  44. void screenUpdate(WindowPtr);
  45. void screenDisplay(char *);
  46. void screenDump(char *, long);
  47. char *macfgets(char *, int, FILE *);
  48. int macfprintf(FILE *, char *, ...);
  49. int macprintf(char *, ...);
  50. int macgetch(void);
  51. /*****************************************************************************/
  52. /* Functions */
  53. /*****************************************************************************/
  54. void screenOpen(char *Title) {
  55. FontInfo fontInfo;
  56. int n;
  57. short fontFamID;
  58. theWindow = GetNewWindow(screenWindow, nil, (WindowPtr)(-1));
  59. if ((Title != NULL) && (*Title != '\0')) {
  60. c2pstr(Title);
  61. SetWTitle(theWindow, (StringPtr)Title);
  62. p2cstr((StringPtr)Title);
  63. }
  64. ShowWindow(theWindow);
  65. SetPort(theWindow);
  66. GetFNum( "\pMonaco", &fontFamID );
  67. TextFont(fontFamID);
  68. TextSize(9);
  69. GetFontInfo(&fontInfo);
  70. fontHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
  71. fontWidth = fontInfo.widMax;
  72. scrollRgn = NewRgn();
  73. screenWidth = (theWindow->portRect.right - theWindow->portRect.left - 10) /
  74. fontWidth;
  75. screenHeight = (theWindow->portRect.bottom - theWindow->portRect.top) /
  76. fontHeight;
  77. maxPosition = screenHeight * fontHeight;
  78. pausePosition = maxPosition - (currentPosition = fontHeight);
  79. SetRect(&scrollRect, theWindow->portRect.left,
  80. theWindow->portRect.top + fontInfo.descent,
  81. theWindow->portRect.right,
  82. theWindow->portRect.bottom);
  83. SetRect(&pauseRect, theWindow->portRect.left,
  84. pausePosition + fontInfo.descent,
  85. theWindow->portRect.right,
  86. theWindow->portRect.bottom);
  87. MoveTo(5, currentPosition);
  88. n = (sizeof(char *) + sizeof(short) + screenWidth) * screenHeight;
  89. screenLine = (char **)NewPtr(n);
  90. screenLength = (short *)&screenLine[screenHeight];
  91. screenImage = (char *)&screenLength[screenHeight];
  92. for (n = 0; n < screenHeight; n++) {
  93. screenLine[n] = &screenImage[n * screenWidth];
  94. screenLength[n] = 0;
  95. }
  96. startLine = endLine = 0;
  97. screenOptions = 0;
  98. return;
  99. }
  100. void screenControl(char *options, int setting) {
  101. int n = 0;
  102. while (*options) {
  103. switch (*options) {
  104. case 'p':
  105. n |= pauseOption;
  106. break;
  107. case 's':
  108. n |= scrollOption;
  109. break;
  110. default:
  111. break;
  112. }
  113. options += 1;
  114. }
  115. if (setting == 0)
  116. screenOptions &= (n ^ (-1));
  117. else
  118. screenOptions |= n;
  119. if ((pausePosition = maxPosition - currentPosition) == 0)
  120. pausePosition = maxPosition - fontHeight;
  121. return;
  122. }
  123. void screenClose(void) {
  124. DisposePtr((Ptr)screenLine);
  125. DisposeWindow(theWindow);
  126. return;
  127. }
  128. void screenUpdate(WindowPtr window) {
  129. GrafPort *savePort;
  130. int m, n;
  131. if (window == theWindow) {
  132. BeginUpdate(window);
  133. if (!EmptyRgn(window->visRgn)) {
  134. GetPort(&savePort);
  135. SetPort(window);
  136. n = startLine;
  137. for (m = 1; ; m++) {
  138. MoveTo(5, m * fontHeight);
  139. if (screenLength[n] != 0)
  140. DrawText(screenLine[n], 0, screenLength[n]);
  141. if (n == endLine) break;
  142. if ((n += 1) == screenHeight) n = 0;
  143. }
  144. SetPort(savePort);
  145. }
  146. EndUpdate(window);
  147. }
  148. return;
  149. }
  150. static void screenNewline(void) {
  151. MoveTo(5, currentPosition += fontHeight);
  152. if (currentPosition > maxPosition) {
  153. if (screenOptions & scrollOption) {
  154. ScrollRect(&scrollRect, 0, -fontHeight, scrollRgn);
  155. MoveTo(5, currentPosition = maxPosition);
  156. if ((startLine += 1) == screenHeight) startLine = 0;
  157. } else {
  158. ScrollRect(&scrollRect, 0, -maxPosition + fontHeight, scrollRgn);
  159. MoveTo(5, currentPosition = fontHeight + fontHeight);
  160. startLine = endLine;
  161. }
  162. }
  163. pausePosition -= fontHeight;
  164. if ((endLine += 1) == screenHeight) endLine = 0;
  165. screenLength[endLine] = 0;
  166. return;
  167. }
  168. static char waitChar(void) {
  169. WindowPtr whichWindow;
  170. EventRecord theEvent;
  171. for ( ; ; ) {
  172. SystemTask();
  173. if (GetNextEvent(everyEvent, &theEvent)) {
  174. switch (theEvent.what) {
  175. case keyDown:
  176. if ((theEvent.modifiers & cmdKey) &&
  177. ((theEvent.message & charCodeMask) == '.'))
  178. ExitToShell();
  179. return(theEvent.message & charCodeMask);
  180. case mouseDown:
  181. if (FindWindow(theEvent.where, &whichWindow) == inSysWindow)
  182. SystemClick(&theEvent, whichWindow);
  183. break;
  184. case updateEvt:
  185. screenUpdate((WindowPtr)theEvent.message);
  186. break;
  187. }
  188. }
  189. }
  190. }
  191. static void screenPause(void) {
  192. if (pausePosition == 0) {
  193. if (screenOptions & pauseOption) {
  194. DrawText("Press any key to continue ...", 0, 29);
  195. memcpy(screenLine[endLine], "Press any key to continue ...", 29);
  196. screenLength[endLine] = 29;
  197. (void)waitChar();
  198. EraseRect(&pauseRect);
  199. MoveTo(5, currentPosition);
  200. screenLength[endLine] = 0;
  201. }
  202. pausePosition = maxPosition - fontHeight;
  203. }
  204. return;
  205. }
  206. void screenDisplay(char *s) {
  207. GrafPort *savePort;
  208. int m, n;
  209. char *t;
  210. GetPort(&savePort);
  211. SetPort(theWindow);
  212. while (*s) {
  213. screenPause();
  214. for (t = s; (*s) && (*s != '\n') && (*s != '\r'); s++)
  215. ; /* empty body */
  216. if ((n = s - t) > (m = screenWidth - screenLength[endLine])) n = m;
  217. if (n > 0) {
  218. DrawText(t, 0, n);
  219. memcpy(screenLine[endLine] + screenLength[endLine], t, n);
  220. screenLength[endLine] += n;
  221. }
  222. if ((*s == '\n') || (*s == '\r')) {
  223. screenNewline();
  224. s += 1;
  225. }
  226. }
  227. SetPort(savePort);
  228. return;
  229. }
  230. void screenDump(char *s, long n) {
  231. GrafPort *savePort;
  232. int k, m;
  233. char *t;
  234. GetPort(&savePort);
  235. SetPort(theWindow);
  236. while (n) {
  237. screenPause();
  238. for (t = s; (n) && (*s != '\n') && (*s != '\r'); s++, n--)
  239. ; /* empty body */
  240. if ((k = s - t) > (m = screenWidth - screenLength[endLine])) k = m;
  241. if (k > 0) {
  242. DrawText(t, 0, k);
  243. memcpy(screenLine[endLine] + screenLength[endLine], t, k);
  244. screenLength[endLine] += k;
  245. }
  246. if ((*s == '\n') || (*s == '\r')) {
  247. screenNewline();
  248. s += 1;
  249. n -= 1;
  250. }
  251. }
  252. SetPort(savePort);
  253. return;
  254. }
  255. char *macfgets(char *s, int n, FILE *stream) {
  256. GrafPort *savePort;
  257. char c, *t = s;
  258. stream = stream;
  259. GetPort(&savePort);
  260. SetPort(theWindow);
  261. for (n -= 1; (n > 0) && ((c = waitChar()) != '\r'); n -= 1) {
  262. DrawChar(*t++ = c);
  263. if (screenLength[endLine] < screenWidth)
  264. screenLine[endLine][screenLength[endLine]++] = c;
  265. }
  266. if (c == '\r') screenNewline();
  267. *t = '\0';
  268. SetPort(savePort);
  269. return(s);
  270. }
  271. int macfprintf(FILE *stream, char *format, ...)
  272. {
  273. char buffer[bufferSize];
  274. va_list ap;
  275. int rc;
  276. stream = stream;
  277. va_start(ap, format);
  278. rc = vsprintf(buffer, format, ap);
  279. va_end(ap);
  280. screenDisplay(buffer);
  281. return rc;
  282. }
  283. int macprintf(char *format, ...)
  284. {
  285. char buffer[bufferSize];
  286. va_list ap;
  287. int rc;
  288. va_start(ap, format);
  289. rc = vsprintf(buffer, format, ap);
  290. va_end(ap);
  291. screenDisplay(buffer);
  292. return rc;
  293. }
  294. /***********************/
  295. /* Function macgetch() */
  296. /***********************/
  297. int macgetch(void)
  298. {
  299. WindowPtr whichWindow;
  300. EventRecord theEvent;
  301. char c; /* one-byte buffer for read() to use */
  302. do {
  303. SystemTask();
  304. if (!GetNextEvent(everyEvent, &theEvent))
  305. theEvent.what = nullEvent;
  306. else {
  307. switch (theEvent.what) {
  308. case keyDown:
  309. c = theEvent.message & charCodeMask;
  310. break;
  311. case mouseDown:
  312. if (FindWindow(theEvent.where, &whichWindow) ==
  313. inSysWindow)
  314. SystemClick(&theEvent, whichWindow);
  315. break;
  316. case updateEvt:
  317. screenUpdate((WindowPtr)theEvent.message);
  318. break;
  319. }
  320. }
  321. } while (theEvent.what != keyDown);
  322. macprintf("*");
  323. return (int)c;
  324. }