home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
tarsrc.sit
/
window.c
< prev
Wrap
Text File
|
1989-09-14
|
7KB
|
348 lines
/*
* 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);
}