macscreen.c
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:10k
源码类别:

压缩解压

开发平台:

MultiPlatform

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