home *** CD-ROM | disk | FTP | other *** search
- /*
- * Macintosh Tar
- *
- * Written by Craig Ruff
- *
- * Window manipulation routines for display (and printer) listings of archives.
- */
-
- #include "tar.h"
- #include <Resources.h>
- #include <StdArg.h>
-
- #define dispID 129 /* Display window ID (in resource file) */
- #define LEFTMAR 5
- #define TOPMAR 5
-
- WindowPtr dispWind;
- Boolean windOpen = false;
- short fontHeight;
- short bottomMargin;
- short bottomLine;
- short topLine;
- short curLine;
- short wLines;
- short wCurLine = 0;
- RgnHandle update;
- TPPrPort prPort;
- GrafPtr savedPort;
-
- /*
- * WindInit - either open the window or printer port
- *
- * Returns true if an error is found, false otherwise.
- *
- * Separate routines for screen and printer are not really needed.
- */
- Boolean
- WindInit() {
- FontInfo fInfo;
- char *routine = "\pWindInit";
-
- if (doPrint) {
- /*
- * We are listing to the printer.
- * Make sure we have opened the printer driver.
- */
- if (!pOpen && PrSetup())
- return(true);
-
- /*
- * Ask about this listings specifics.
- */
- if (PrJobDialog(prRecHdl) == false)
- return(true);
-
- if (PrError() != noErr) {
- OSAlert(routine, "\pPrJobDialog", nil, PrError());
- return(true);
- }
-
- /*
- * Open the printer document (once per listing).
- */
- prPort = PrOpenDoc(prRecHdl, nil, nil);
- if (PrError() != noErr) {
- OSAlert(routine, "\pPrOpenDoc", nil, PrError());
- return(true);
- }
-
- /*
- * Open the page (once per physical page).
- */
- PrOpenPage(prPort, nil);
- if (PrError() != noErr) {
- OSAlert(routine, "\pPrOpenPage", nil, PrError());
- return(true);
- }
-
- /*
- * Use monaco 9 so our listing lines up properly.
- * (Lazy)
- */
- GetPort(&savedPort);
- SetPort(&prPort->gPort);
- TextFont(monaco);
- TextSize(9);
-
- /*
- * Figure out how many lines fit on a page.
- */
- GetFontInfo(&fInfo);
- fontHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
- MoveTo(LEFTMAR, curLine = fontHeight);
- bottomLine = (((**prRecHdl).prInfo.rPage.bottom / fontHeight) - 1)
- * fontHeight;
-
- return(false);
- }
-
- /*
- * Listing to screen.
- * Get a temporary region for scrolling bits.
- * Get the window template from the resource file.
- */
- if ((update = NewRgn()) == nil) {
- OSAlert(routine, "\pNewRgn", nil, MemError());
- return(true);
- }
-
- if ((dispWind = GetNewWindow(dispID, nil, (WindowPtr) -1)) == nil) {
- OSAlert(routine, "\pGetNewWindow", nil, ResError());
- return(true);
- }
-
- /*
- * Use monaco 9 so our listing lines up.
- */
- SetPort(dispWind);
- TextFont(monaco);
- TextSize(9);
-
- /*
- * Figure out how many lines fit on a page, save this as margin info.
- */
- GetFontInfo(&fInfo);
- fontHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
-
- MoveTo(LEFTMAR, curLine = fontHeight);
- topLine = curLine + fInfo.descent + fInfo.leading;
- bottomLine = (wLines = dispWind->portRect.bottom / fontHeight) * fontHeight;
- bottomMargin = bottomLine + fInfo.descent + fInfo.leading;
-
- wCurLine = 0;
- windOpen = true;
- return(false);
- }
-
- /*
- * WindEnd - clean up after a listing to screen or printer
- */
- WindEnd(keyWait)
- Boolean keyWait;
- {
- if (pOpen) {
- TPrStatus prSt;
- char *routine = "\pWindEnd";
- short err;
-
- /*
- * Printing, close page and document.
- */
- PrClosePage(prPort);
- if ((err = PrError()) != noErr) {
- if (err != iPrAbort)
- OSAlert(routine, "\pPrClosePage", nil, PrError());
- goto done;
- }
-
- PrCloseDoc(prPort);
- if ((err = PrError()) != noErr) {
- if (err != iPrAbort)
- OSAlert(routine, "\pPrCloseDoc", nil, PrError());
- goto done;
- }
-
- /*
- * If the printing involved spooling, spool it now.
- */
- if ((**prRecHdl).prJob.bJDocLoop == bSpoolLoop)
- PrPicFile(prRecHdl, nil, nil, nil, &prSt);
-
- done: SetPort(savedPort);
- pOpen = false;
- return;
- }
-
- /*
- * Listing to screen. See if we should wait for a key press to continue.
- */
- if (keyWait) {
- EventRecord e;
- Boolean oldAutoPage = autoPage;
-
- autoPage = false; /* So we don't get two messages */
- if (!doPrint)
- WPrintf("Press any key to continue");
-
- do {
- SystemTask();
- if (GetNextEvent(keyDownMask, &e) == false)
- e.what = nullEvent;
- } while (e.what != keyDown);
-
- autoPage = oldAutoPage;
- }
-
- DisposeWindow(dispWind);
- DisposeRgn(update);
- windOpen = false;
- }
-
- /*
- * WPrintf - printf to the screen or printer
- *
- * Used like you'd expect, but does NOT handle paper motion
- * characters like newline, etc.
- */
- WPrintf(char *fmt, ...)
- {
- Rect r;
- char buf[256];
- EventRecord e;
- char *routine = "\pWPrintf";
- short err;
- va_list ap;
-
- if (!windOpen && !pOpen)
- return;
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- if (strlen(buf) >= sizeof(buf))
- StkErrAlert(); /* Sanity check, stack overrun */
-
- if (doPrint) {
- /*
- * Printing.
- */
- if (curLine > bottomLine) {
- /*
- * At end of page, start a new one.
- */
- PrClosePage(prPort);
- if ((err = PrError()) != noErr) {
- if (err != iPrAbort)
- OSAlert(routine, "\pPrClosePage", nil,
- PrError());
- return;
- }
-
- PrOpenPage(prPort, nil);
- if (PrError() != noErr) {
- if (err != iPrAbort)
- OSAlert(routine, "\pPrClosePage", nil,
- PrError());
- return;
- }
-
- /*
- * Yes, we really must reset the font.
- */
- MoveTo(LEFTMAR, curLine = fontHeight);
- TextFace(underline);
- DrawText(header, 0, strlen(header));
- TextFace(0);
- MoveTo(LEFTMAR, curLine += fontHeight);
- }
-
- DrawText(buf, 0, strlen(buf));
- MoveTo(LEFTMAR, curLine += fontHeight);
- return;
- }
-
- /*
- * On screen.
- */
- SetPort(dispWind);
- if (curLine > bottomLine) {
- /*
- * At end of screen, scroll up.
- */
- SetRect(&r, dispWind->portRect.left, topLine,
- dispWind->portRect.right, bottomMargin);
- ScrollRect(&r, 0, -fontHeight, update);
- SetEmptyRgn(update);
- MoveTo(LEFTMAR, curLine = bottomLine);
- }
-
- if (autoPage && (++wCurLine == wLines)) {
- /*
- * At end of screen, wait for key press.
- */
- wCurLine = 0;
- DrawText("Press any key to continue", 0, 25);
- do {
- SystemTask();
- if (GetNextEvent(keyDownMask, &e) == false)
- e.what = nullEvent;
- } while (e.what != keyDown);
-
- SetRect(&r, dispWind->portRect.left, bottomMargin - fontHeight,
- dispWind->portRect.right, bottomMargin);
- EraseRect(&r);
- MoveTo(LEFTMAR, curLine);
-
- } else {
- /*
- * No auto page, only stop if command S is pressed.
- */
- if (GetNextEvent(keyDownMask, &e)) {
- if (((e.message & charCodeMask & ~0x20) == 'S')
- && (e.modifiers & cmdKey)) {
- do {
- /*
- * Start again after command Q.
- */
- SystemTask();
- if (GetNextEvent(keyDownMask, &e) == false)
- e.message = 0;
-
- e.message &= charCodeMask & ~0x20;
- } while (e.message != 'Q');
- }
- }
- }
-
- DrawText(buf, 0, strlen(buf));
- MoveTo(LEFTMAR, curLine += fontHeight);
- }
-
- /*
- * PrSetup - make sure the printer driver has been opened.
- *
- * Returns true if an error is found, false otherwise.
- */
- Boolean
- PrSetup() {
- char *routine = "\pPrSetup";
-
- if (!pOpen) {
- PrOpen();
- if (PrError() != noErr) {
- OSAlert(routine, "\pPrOpen", nil, PrError());
- return(true);
- }
-
- pOpen = true;
- PrintDefault(prRecHdl);
- if (PrError() != noErr) {
- OSAlert(routine, "\pPrintDefault", nil, PrError());
- return(true);
- }
- }
-
- return(false);
- }
-