home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v14i049: umoria4 - single player dungeon simulation (ver. 5.5), Part17/39
- Message-ID: <3407@master.CNA.TEK.COM>
- Date: 20 Aug 92 18:05:32 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2353
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: grabiner@math.harvard.edu (David Grabiner)
- Posting-number: Volume 14, Issue 49
- Archive-name: umoria4/Part17
- Supersedes: umoria3: Volume 9, Issue 55-97; Volume 10, Issue 15-17
- Environment: Curses, Unix, Mac, MS-DOS, Atari-ST, Amiga, VMS
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 17 (of 39)."
- # Contents: mac/scrnmgr/ScrnMgr.c.2 mac/scrnmgr/ScrnMgr.doc
- # util/scores/README
- # Wrapped by billr@saab on Thu Aug 20 09:11:30 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'mac/scrnmgr/ScrnMgr.c.2' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mac/scrnmgr/ScrnMgr.c.2'\"
- else
- echo shar: Extracting \"'mac/scrnmgr/ScrnMgr.c.2'\" \(31691 characters\)
- sed "s/^X//" >'mac/scrnmgr/ScrnMgr.c.2' <<'END_OF_FILE'
- X }
- X }
- X else {
- X if (PtInRect(mouse, &charCell)) {
- X XSetScreenCharAttr(false, c, ar, h, v);
- X UpdateScreen();
- X reversed = true;
- X }
- X }
- X }
- X
- X if (reversed) {
- X
- X XSetScreenCharAttr(false, c, an, h, v);
- X UpdateScreen();
- X reversed = false;
- X
- X PushQueue(0, modifiers, 0, h, v);
- X
- X }
- X
- X }
- X
- X }
- X
- X return;
- X}
- X
- Xstatic void DoContentClick(whichWindow, cursorLoc)
- XWindowPtr whichWindow;
- XPoint *cursorLoc;
- X
- X{
- X short thePart;
- X ControlHandle theControl;
- X Point localCursor;
- X
- X if (whichWindow == theScreen.window) {
- X localCursor = *cursorLoc;
- X GlobalToLocal(&localCursor);
- X if (thePart = FindControl(localCursor, whichWindow, &theControl)) {
- X if (theControl == theScreen.hScrollHandle)
- X DoHScroll(&localCursor, thePart);
- X else if (theControl == theScreen.vScrollHandle)
- X DoVScroll(&localCursor, thePart);
- X }
- X else
- X if (theScreen.mouseFlag) DoCharClick();
- X }
- X
- X return;
- X}
- X
- Xstatic void DoMouseDown(cursorLoc)
- XPoint *cursorLoc;
- X
- X{
- X long part;
- X WindowPtr whichWindow;
- X
- X switch (part = FindWindow(*cursorLoc, &whichWindow)) {
- X
- X case inMenuBar: DoMenuItem(MenuSelect(*cursorLoc));
- X break;
- X
- X case inDrag: DoDrag(whichWindow, cursorLoc);
- X break;
- X
- X case inGrow: DoGrow(whichWindow, cursorLoc);
- X break;
- X
- X case inSysWindow: SystemClick(&theScreen.event, whichWindow);
- X break;
- X
- X case inContent: if (whichWindow != FrontWindow())
- X SelectWindow(whichWindow);
- X else
- X DoContentClick(whichWindow, cursorLoc);
- X break;
- X
- X case inZoomIn:
- X case inZoomOut: if (whichWindow == theScreen.window)
- X if (TrackBox(whichWindow, *cursorLoc, part))
- X DoZoom(whichWindow, part);
- X break;
- X
- X case inGoAway: if (whichWindow == theScreen.window)
- X if (TrackGoAway(whichWindow, *cursorLoc)) {
- X if (theScreen.fileMenuProc != NULL)
- X (*theScreen.fileMenuProc)(closeBoxItem);
- X else
- X DoFileMenu(closeBoxItem);
- X }
- X break;
- X
- X }
- X
- X return;
- X}
- X
- Xstatic void DoKeyDown(cmdFlag)
- Xint cmdFlag;
- X
- X{
- X char keycode, modifiers, ascii;
- X char upper;
- X
- X if ( (theScreen.event.when > theScreen.keyFlush) &&
- X (theScreen.window == FrontWindow()) &&
- X (((WindowPeek) theScreen.window)->visible) ) {
- X
- X ObscureCursor();
- X
- X keycode = (char) ((theScreen.event.message & keyCodeMask) >> 8);
- X
- X modifiers = (char) ((theScreen.event.modifiers & 0xFF00) >> 8);
- X modifiers &= ~maskModMouse;
- X
- X ascii = (char) (theScreen.event.message & charCodeMask);
- X if (theScreen.escMapFlag) {
- X if (ascii == BACKQUOTE) ascii = ESC;
- X }
- X if (cmdFlag) {
- X upper = ascii;
- X if ( (upper >= 'a') && (upper <= 'z') )
- X upper = 'A' + (upper - 'a');
- X if ( (upper >= '@') && (upper <= '_') )
- X ascii = upper - '@';
- X }
- X
- X PushQueue(keycode, modifiers, ascii, 0, 0);
- X
- X }
- X
- X return;
- X}
- X
- Xstatic void DoUpdate(whichWindow)
- XWindowPtr whichWindow;
- X
- X{
- X if (whichWindow == theScreen.window) {
- X UpdateScreen();
- X }
- X
- X return;
- X}
- X
- Xstatic void DoActivate(whichWindow, activated)
- XWindowPtr whichWindow;
- XBoolean activated;
- X
- X{
- X MenuHandle menu;
- X
- X menu = GetMHandle(theScreen.cmdKeyFlag ? editID1 : editID2);
- X
- X if (whichWindow == theScreen.window) {
- X
- X if (activated) {
- X DisableItem(menu, undoItem);
- X DisableItem(menu, cutItem);
- X DisableItem(menu, copyItem);
- X DisableItem(menu, pasteItem);
- X DisableItem(menu, clearItem);
- X ShowControl(theScreen.vScrollHandle);
- X ShowControl(theScreen.hScrollHandle);
- X DrawGrowIcon(whichWindow);
- X }
- X else {
- X EnableItem(menu, undoItem);
- X EnableItem(menu, cutItem);
- X EnableItem(menu, copyItem);
- X EnableItem(menu, pasteItem);
- X EnableItem(menu, clearItem);
- X HideControl(theScreen.vScrollHandle);
- X HideControl(theScreen.hScrollHandle);
- X DrawGrowIcon(whichWindow);
- X }
- X }
- X
- X return;
- X}
- X
- Xstatic void InvalScreenRect(d, r)
- Xint d;
- XRect *r;
- X
- X{
- X register long v;
- X register short *left, *right;
- X short rl, rt, rr, rb;
- X
- X if (d) {
- X
- X rl = r->left;
- X rt = r->top;
- X rr = r->right;
- X rb = r->bottom;
- X
- X left = *theScreen.updLeft + rt;
- X right = *theScreen.updRight + rt;
- X
- X for (v = rt; v < rb; v++, left++, right++) {
- X if (rl < *left) *left = rl;
- X if (rr > *right) *right = rr;
- X }
- X
- X }
- X
- X else {
- X
- X r->left *= theScreen.charPDims.h;
- X r->right *= theScreen.charPDims.h;
- X r->top *= theScreen.charPDims.v;
- X r->bottom *= theScreen.charPDims.v;
- X
- X SetOrigin(theScreen.origin.h, theScreen.origin.v);
- X InvalRect(r);
- X SetOrigin(0, 0);
- X
- X }
- X
- X return;
- X}
- X
- Xstatic void InvalCursor(d)
- Xint d;
- X
- X{
- X Rect curs;
- X
- X curs.left = curs.right = theScreen.cursor.h;
- X curs.top = curs.bottom = theScreen.cursor.v;
- X curs.right += 1;
- X curs.bottom += 1;
- X
- X if (d)
- X InvalScreenRect(d, &curs);
- X
- X else {
- X
- X curs.left *= theScreen.charPDims.h;
- X curs.right *= theScreen.charPDims.h;
- X curs.top = curs.bottom = curs.bottom * theScreen.charPDims.v;
- X curs.top -= theScreen.cursorLines;
- X
- X SetOrigin(theScreen.origin.h, theScreen.origin.v);
- X InvalRect(&curs);
- X SetOrigin(0, 0);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XSetScreenChar(d, c, h, v)
- Xint d;
- Xchar c;
- Xlong h, v;
- X
- X{
- X long loc;
- X Rect area;
- X Point pos;
- X
- X pos.h = h;
- X pos.v = v;
- X
- X if (PtInRect(pos, &theScreen.scrnCRect)) {
- X
- X loc = v * theScreen.scrnCDims.h + h;
- X (*theScreen.chars)[loc] = c;
- X
- X area.left = area.right = h;
- X area.right += 1;
- X area.top = area.bottom = v;
- X area.bottom += 1;
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XSetScreenBuffer(d, c, row, bounds, h, v)
- Xint d;
- Xchar *c;
- Xlong row;
- XRect *bounds;
- Xlong h, v;
- X
- X{
- X long i;
- X long wid;
- X long srcLoc, dstLoc;
- X char *srcC, *dstC;
- X Rect temp, area;
- X
- X temp.right = temp.left = h;
- X temp.right += bounds->right - bounds->left;
- X temp.bottom = temp.top = v;
- X temp.bottom += bounds->bottom - bounds->top;
- X
- X if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
- X
- X srcLoc = (area.top + bounds->top - v) * row +
- X (area.left + bounds->left - h);
- X dstLoc = area.top * theScreen.scrnCDims.h + area.left;
- X
- X srcC = c + srcLoc;
- X dstC = *theScreen.chars + dstLoc;
- X
- X wid = area.right - area.left;
- X
- X if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
- X wid *= (area.bottom - area.top);
- X memcpy(dstC, srcC, wid);
- X }
- X
- X else {
- X
- X for (i = area.top; i < area.bottom; i++) {
- X memcpy(dstC, srcC, wid);
- X srcC += row;
- X dstC += theScreen.scrnCDims.h;
- X }
- X
- X }
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XSetScreenString(d, s, h, v)
- Xint d;
- Xchar *s;
- Xlong h, v;
- X
- X{
- X Rect bounds;
- X
- X bounds.left = 0;
- X bounds.right = strlen(s);
- X bounds.top = 0;
- X bounds.bottom = 1;
- X
- X XSetScreenBuffer(d, s, bounds.right, &bounds, h, v);
- X
- X return;
- X}
- X
- Xvoid XSetScreenCharAttr(d, c, a, h, v)
- Xint d;
- Xchar c;
- Xchar a;
- Xlong h, v;
- X
- X{
- X long loc;
- X Rect area;
- X Point pos;
- X
- X pos.h = h;
- X pos.v = v;
- X
- X if (PtInRect(pos, &theScreen.scrnCRect)) {
- X
- X loc = v * theScreen.scrnCDims.h + h;
- X (*theScreen.chars)[loc] = c;
- X (*theScreen.attrs)[loc] = a;
- X
- X area.left = area.right = h;
- X area.right += 1;
- X area.top = area.bottom = v;
- X area.bottom += 1;
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XSetScreenBufferAttr(d, c, a, row, bounds, h, v)
- Xint d;
- Xchar *c;
- Xchar a;
- Xlong row;
- XRect *bounds;
- Xlong h, v;
- X
- X{
- X long i;
- X long wid;
- X long srcLoc, dstLoc;
- X char *srcC, *dstC;
- X char *dstA;
- X Rect temp, area;
- X
- X temp.right = temp.left = h;
- X temp.right += bounds->right - bounds->left;
- X temp.bottom = temp.top = v;
- X temp.bottom += bounds->bottom - bounds->top;
- X
- X if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
- X
- X srcLoc = (area.top + bounds->top - v) * row +
- X (area.left + bounds->left - h);
- X dstLoc = area.top * theScreen.scrnCDims.h + area.left;
- X
- X srcC = c + srcLoc;
- X dstC = *theScreen.chars + dstLoc;
- X
- X dstA = *theScreen.attrs + dstLoc;
- X
- X wid = area.right - area.left;
- X
- X if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
- X wid *= (area.bottom - area.top);
- X memcpy(dstC, srcC, wid);
- X memset(dstA, a, wid);
- X }
- X
- X else {
- X
- X for (i = area.top; i < area.bottom; i++) {
- X memcpy(dstC, srcC, wid);
- X memset(dstA, a, wid);
- X srcC += row;
- X dstC += theScreen.scrnCDims.h;
- X dstA += theScreen.scrnCDims.h;
- X }
- X
- X }
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XSetScreenStringAttr(d, s, a, h, v)
- Xint d;
- Xchar *s;
- Xchar a;
- Xlong h, v;
- X
- X{
- X Rect bounds;
- X
- X bounds.left = 0;
- X bounds.right = strlen(s);
- X bounds.top = 0;
- X bounds.bottom = 1;
- X
- X XSetScreenBufferAttr(d, s, a, bounds.right, &bounds, h, v);
- X
- X return;
- X}
- X
- Xvoid XSetScreenImage(d, c, a, row, bounds, h, v)
- Xint d;
- Xchar *c;
- Xchar *a;
- Xlong row;
- XRect *bounds;
- Xlong h, v;
- X
- X{
- X long i;
- X long wid;
- X long srcLoc, dstLoc;
- X char *srcC, *dstC;
- X char *srcA, *dstA;
- X Rect temp, area;
- X
- X temp.right = temp.left = h;
- X temp.right += bounds->right - bounds->left;
- X temp.bottom = temp.top = v;
- X temp.bottom += bounds->bottom - bounds->top;
- X
- X if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
- X
- X srcLoc = (area.top + bounds->top - v) * row +
- X (area.left + bounds->left - h);
- X dstLoc = area.top * theScreen.scrnCDims.h + area.left;
- X
- X srcC = c + srcLoc;
- X dstC = *theScreen.chars + dstLoc;
- X
- X srcA = a + srcLoc;
- X dstA = *theScreen.attrs + dstLoc;
- X
- X wid = area.right - area.left;
- X
- X if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
- X wid *= (area.bottom - area.top);
- X memcpy(dstC, srcC, wid);
- X memcpy(dstA, srcA, wid);
- X }
- X
- X else {
- X
- X for (i = area.top; i < area.bottom; i++) {
- X memcpy(dstC, srcC, wid);
- X memcpy(dstA, srcA, wid);
- X srcC += row;
- X srcA += row;
- X dstC += theScreen.scrnCDims.h;
- X dstA += theScreen.scrnCDims.h;
- X }
- X
- X }
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XWriteScreenChar(d, c)
- Xint d;
- Xchar c;
- X
- X{
- X InvalCursor(d);
- X
- X XSetScreenChar(d, c, theScreen.cursor.h, theScreen.cursor.v);
- X theScreen.cursor.h++;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XWriteScreenBuffer(d, c, row, bounds)
- Xint d;
- Xchar *c;
- Xlong row;
- XRect *bounds;
- X
- X{
- X XSetScreenBuffer(d, c, row, bounds, theScreen.cursor.h,
- X theScreen.cursor.v);
- X theScreen.cursor.h += bounds->right - bounds->left;
- X theScreen.cursor.v += bounds->bottom - bounds->top;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XWriteScreenString(d, s)
- Xint d;
- Xchar *s;
- X
- X{
- X XSetScreenString(d, s, theScreen.cursor.h, theScreen.cursor.v);
- X theScreen.cursor.h += strlen(s);
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XWriteScreenCharAttr(d, c, a)
- Xint d;
- Xchar c;
- Xchar a;
- X
- X{
- X XSetScreenCharAttr(d, c, a, theScreen.cursor.h, theScreen.cursor.v);
- X theScreen.cursor.h++;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XWriteScreenBufferAttr(d, c, a, row, bounds)
- Xint d;
- Xchar *c;
- Xchar a;
- Xlong row;
- XRect *bounds;
- X
- X{
- X XSetScreenBufferAttr(d, c, a, row, bounds, theScreen.cursor.h,
- X theScreen.cursor.v);
- X theScreen.cursor.h += bounds->right - bounds->left;
- X theScreen.cursor.v += bounds->bottom - bounds->top;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XWriteScreenStringAttr(d, s, a)
- Xint d;
- Xchar *s;
- Xchar a;
- X
- X{
- X XSetScreenStringAttr(d, s, a, theScreen.cursor.h, theScreen.cursor.v);
- X theScreen.cursor.h += strlen(s);
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XWriteScreenImage(d, c, a, row, bounds)
- Xint d;
- Xchar *c;
- Xchar *a;
- Xlong row;
- XRect *bounds;
- X
- X{
- X XSetScreenImage(d, c, a, row, bounds, theScreen.cursor.h,
- X theScreen.cursor.v);
- X theScreen.cursor.h += bounds->right - bounds->left;
- X theScreen.cursor.v += bounds->bottom - bounds->top;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XFillScreen(d, c, a, bounds)
- Xint d;
- Xchar c;
- Xchar a;
- XRect *bounds;
- X
- X{
- X long i;
- X long wid;
- X long dstLoc;
- X char *dstC;
- X char *dstA;
- X Rect area;
- X
- X if (SectRect(bounds, &theScreen.scrnCRect, &area)) {
- X
- X dstLoc = area.top * theScreen.scrnCDims.h + area.left;
- X
- X dstC = *theScreen.chars + dstLoc;
- X
- X dstA = *theScreen.attrs + dstLoc;
- X
- X wid = area.right - area.left;
- X
- X if (wid == theScreen.scrnCDims.h) {
- X wid *= (area.bottom - area.top);
- X memset(dstC, c, wid);
- X memset(dstA, a, wid);
- X }
- X
- X else {
- X
- X for (i = area.top; i < area.bottom; i++) {
- X memset(dstC, c, wid);
- X memset(dstA, a, wid);
- X dstC += theScreen.scrnCDims.h;
- X dstA += theScreen.scrnCDims.h;
- X }
- X
- X }
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XEraseScreen(d, bounds)
- Xint d;
- XRect *bounds;
- X
- X{
- X XFillScreen(d, ' ', attrNormal, bounds);
- X return;
- X}
- X
- Xstatic void ScrollScreenPositive(area, offset, factor)
- XRect *area;
- Xlong offset;
- Xshort factor;
- X
- X{
- X register short i, j;
- X short loc; /* Index of initial destination. */
- X short nxt; /* Amount to skip going from one row to the next. */
- X register char *srcc, *dstc;
- X register char *srca, *dsta;
- X
- X loc = (area->bottom - 1) * theScreen.scrnCDims.h + area->right - 1;
- X
- X dstc = *theScreen.chars + loc;
- X srcc = dstc - offset * factor;
- X
- X dsta = *theScreen.attrs + loc;
- X srca = dsta - offset * factor;
- X
- X nxt = theScreen.scrnCDims.h - (area->right - area->left);
- X
- X for (j = area->bottom; j > area->top; j--) {
- X for (i = area->right; i > area->left; i--) {
- X *dstc-- = *srcc--;
- X *dsta-- = *srca--;
- X }
- X srcc -= nxt;
- X dstc -= nxt;
- X srca -= nxt;
- X dsta -= nxt;
- X }
- X
- X return;
- X}
- X
- Xstatic void ScrollScreenNegative(area, offset, factor)
- XRect *area;
- Xlong offset;
- Xshort factor;
- X
- X{
- X register short i, j;
- X short loc;
- X short nxt;
- X register char *srcc, *dstc;
- X register char *srca, *dsta;
- X
- X loc = area->top * theScreen.scrnCDims.h + area->left;
- X
- X dstc = *theScreen.chars + loc;
- X srcc = dstc - offset * factor; /* Offset is negative! */
- X
- X dsta = *theScreen.attrs + loc;
- X srca = dsta - offset * factor;
- X
- X nxt = theScreen.scrnCDims.h - (area->right - area->left);
- X
- X for (j = area->top; j < area->bottom; j++) {
- X for (i = area->left; i < area->right; i++) {
- X *dstc++ = *srcc++;
- X *dsta++ = *srca++;
- X }
- X srcc += nxt;
- X dstc += nxt;
- X srca += nxt;
- X dsta += nxt;
- X }
- X
- X return;
- X}
- X
- Xvoid XScrollScreen(d, dh, dv, bounds, attr)
- Xint d;
- Xlong dh, dv;
- XRect *bounds;
- Xchar attr;
- X
- X{
- X long wid, dep;
- X Rect area, clear;
- X
- X if (!dh && !dv) return;
- X
- X if (SectRect(bounds, &theScreen.scrnCRect, &area)) {
- X
- X wid = area.right - area.left;
- X dep = area.bottom - area.top;
- X
- X if ( (ABS(dh) >= wid) || (ABS(dv) >= dep) )
- X
- X XFillScreen(d, ' ', attr, &area);
- X
- X else {
- X
- X if (dv > 0) {
- X clear = area;
- X clear.bottom = area.top += dv;
- X ScrollScreenPositive(&area, dv, (short)theScreen.scrnCDims.h);
- X XFillScreen(d, ' ', attr, &clear);
- X }
- X
- X else if (dv < 0) {
- X clear = area;
- X clear.top = area.bottom += dv;
- X ScrollScreenNegative(&area, dv, (short)theScreen.scrnCDims.h);
- X XFillScreen(d, ' ', attr, &clear);
- X }
- X
- X if (dh > 0) {
- X clear = area;
- X clear.right = area.left += dh;
- X ScrollScreenPositive(&area, dh, (short)1);
- X XFillScreen(d, ' ', attr, &clear);
- X }
- X
- X else if (dh < 0) {
- X clear = area;
- X clear.left = area.right += dh;
- X ScrollScreenNegative(&area, dh, (short)1);
- X XFillScreen(d, ' ', attr, &clear);
- X }
- X
- X InvalScreenRect(d, &area);
- X
- X }
- X
- X }
- X
- X return;
- X}
- X
- Xvoid GetScreenCharAttr(c, a, h, v)
- Xchar *c;
- Xchar *a;
- Xlong h, v;
- X
- X{
- X long loc;
- X Point pos;
- X
- X pos.h = h;
- X pos.v = v;
- X
- X if (PtInRect(pos, &theScreen.scrnCRect)) {
- X
- X loc = v * theScreen.scrnCDims.h + h;
- X *c = (*theScreen.chars)[loc];
- X *a = (*theScreen.attrs)[loc];
- X
- X }
- X
- X return;
- X}
- X
- Xvoid GetScreenImage(c, a, row, bounds, h, v)
- Xchar *c;
- Xchar *a;
- Xlong row;
- XRect *bounds;
- Xlong h, v;
- X
- X{
- X long i;
- X long wid;
- X long srcLoc, dstLoc;
- X char *srcC, *dstC;
- X char *srcA, *dstA;
- X Rect temp, area;
- X
- X temp.right = temp.left = h;
- X temp.right += bounds->right - bounds->left;
- X temp.bottom = temp.top = v;
- X temp.bottom += bounds->bottom - bounds->top;
- X
- X if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
- X
- X dstLoc = (area.top + bounds->top - v) * row +
- X (area.left + bounds->left - h);
- X srcLoc = area.top * theScreen.scrnCDims.h + area.left;
- X
- X dstC = c + dstLoc;
- X srcC = *theScreen.chars + srcLoc;
- X
- X dstA = a + dstLoc;
- X srcA = *theScreen.attrs + srcLoc;
- X
- X wid = area.right - area.left;
- X
- X if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
- X wid *= (area.bottom - area.top);
- X memcpy(dstC, srcC, wid);
- X memcpy(dstA, srcA, wid);
- X }
- X
- X else {
- X
- X for (i = area.top; i < area.bottom; i++) {
- X memcpy(dstC, srcC, wid);
- X memcpy(dstA, srcA, wid);
- X dstC += row;
- X dstA += row;
- X srcC += theScreen.scrnCDims.h;
- X srcA += theScreen.scrnCDims.h;
- X }
- X
- X }
- X
- X }
- X
- X return;
- X}
- X
- Xvoid XMoveScreenCursor(d, h, v)
- Xint d;
- Xlong h, v;
- X
- X{
- X InvalCursor(d);
- X
- X theScreen.cursor.h += h;
- X theScreen.cursor.v += v;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid XSetScreenCursor(d, h, v)
- Xint d;
- Xlong h, v;
- X
- X{
- X InvalCursor(d);
- X
- X theScreen.cursor.h = h;
- X theScreen.cursor.v = v;
- X
- X InvalCursor(d);
- X
- X return;
- X}
- X
- Xvoid GetScreenCursor(h, v)
- Xlong *h, *v;
- X{
- X *h = theScreen.cursor.h;
- X *v = theScreen.cursor.v;
- X return;
- X}
- X
- Xstatic long CheckCursorStatus()
- X
- X{
- X long oldStatus;
- X long changed;
- X
- X oldStatus = theScreen.cursorStatus;
- X
- X if (theScreen.cursorLevel <= 0)
- X theScreen.cursorStatus = 0;
- X else if (!theScreen.cursorBlink)
- X theScreen.cursorStatus = 1;
- X else if (theScreen.cursorChangeTick <= TickCount())
- X theScreen.cursorStatus = !oldStatus;
- X
- X changed = theScreen.cursorStatus != oldStatus;
- X
- X if (changed) {
- X theScreen.cursorChangeTick = TickCount() + theScreen.cursorBlink;
- X InvalCursor(0);
- X }
- X
- X return(changed);
- X}
- X
- Xstatic void InvalDelayed()
- X
- X{
- X long v;
- X short *left, *right;
- X Rect inval;
- X
- X v = 0;
- X left = *theScreen.updLeft;
- X right = *theScreen.updRight;
- X
- X while (v < theScreen.scrnCDims.v) {
- X
- X if (!*right) {
- X
- X v++;
- X left++;
- X right++;
- X
- X }
- X
- X else {
- X
- X inval.top = v;
- X inval.left = *left;
- X inval.right = *right;
- X
- X do {
- X v++;
- X *left++ = theScreen.scrnCDims.h;
- X *right++ = 0;
- X } while ( (v < theScreen.scrnCDims.v) &&
- X (*left == inval.left) &&
- X (*right == inval.right) );
- X
- X inval.bottom = v;
- X
- X InvalScreenRect(0, &inval);
- X
- X left = *theScreen.updLeft + v;
- X right = *theScreen.updRight + v;
- X
- X }
- X
- X }
- X
- X return;
- X
- X}
- X
- Xstatic void UpdateScreenLine(area, c, a, len)
- XRect *area;
- Xchar *c;
- Xchar *a;
- Xlong len;
- X
- X{
- X long count;
- X char attr;
- X char *last, *prev;
- X short face;
- X Rect temp;
- X
- X temp = *area;
- X
- X last = a + len;
- X
- X while (a < last) {
- X
- X attr = *a;
- X
- X prev = a;
- X while ( (a < last) && (*a == attr) ) a++;
- X count = a - prev;
- X
- X temp.right = temp.left + count * theScreen.charPDims.h;
- X
- X face = normal;
- X if (attr & attrUnderlined) face |= underline;
- X if (attr & attrItalicized) face |= italic;
- X TextFace(face);
- X
- X if (theScreen.colorFlag) {
- X ForeColor(colors[AttrFore(attr)]);
- X BackColor(colors[AttrBack(attr)]);
- X }
- X else {
- X ForeColor(
- X colors[
- X (AttrFore(attr) == attrColorBack) ?
- X theScreen.colorStdBack : theScreen.colorStdFore]);
- X BackColor(
- X colors[
- X (AttrBack(attr) == attrColorBack) ?
- X theScreen.colorStdBack : theScreen.colorStdFore]);
- X }
- X
- X EraseRect(&temp);
- X
- X DrawText(c, 0, count);
- X
- X temp.left = temp.right;
- X
- X c += count;
- X
- X }
- X
- X return;
- X}
- X
- Xvoid UpdateScreen()
- X
- X{
- X long j;
- X long top, dep, left, wid;
- X Rect clear, area, curs;
- X RgnHandle vis;
- X char *c, *a;
- X long cursorLoc;
- X
- X InvalDelayed();
- X
- X BeginUpdate(theScreen.window);
- X
- X SetOrigin(theScreen.origin.h, theScreen.origin.v);
- X
- X ClipRect(&theScreen.picLRect);
- X
- X if (!theScreen.colorFlag)
- X BackColor(colors[theScreen.colorStdBack]);
- X
- X if (theScreen.picLRect.top < theScreen.scrnLRect.top) {
- X clear = theScreen.picLRect;
- X clear.bottom = theScreen.scrnLRect.top;
- X EraseRect(&clear);
- X }
- X
- X if (theScreen.picLRect.left < theScreen.scrnLRect.left) {
- X clear = theScreen.picLRect;
- X clear.right = theScreen.scrnLRect.left;
- X EraseRect(&clear);
- X }
- X
- X if (theScreen.picLRect.right > theScreen.scrnLRect.right) {
- X clear = theScreen.picLRect;
- X clear.left = theScreen.scrnLRect.right;
- X EraseRect(&clear);
- X }
- X
- X if (theScreen.picLRect.bottom > theScreen.scrnLRect.bottom) {
- X clear = theScreen.picLRect;
- X clear.top = theScreen.scrnLRect.bottom;
- X EraseRect(&clear);
- X }
- X
- X ClipRect(&theScreen.drawLRect);
- X
- X vis = theScreen.window->visRgn;
- X
- X top = theScreen.drawXCRect.top;
- X dep = theScreen.drawXCRect.bottom - top;
- X
- X left = theScreen.drawXCRect.left;
- X wid = theScreen.drawXCRect.right - left;
- X
- X HLock((Handle) theScreen.chars);
- X HLock((Handle) theScreen.attrs);
- X
- X c = *theScreen.chars + top * theScreen.scrnCDims.h + left;
- X a = *theScreen.attrs + top * theScreen.scrnCDims.h + left;
- X
- X area = theScreen.drawXLRect;
- X area.bottom = area.top + theScreen.charPDims.v;
- X
- X for (j = 0; j < dep; j++) {
- X
- X if (RectInRgn(&area, vis)) {
- X MoveTo(area.left, area.top + theScreen.info.ascent);
- X UpdateScreenLine(&area, c, a, wid);
- X }
- X
- X area.top = area.bottom;
- X area.bottom += theScreen.charPDims.v;
- X
- X c += theScreen.scrnCDims.h;
- X a += theScreen.scrnCDims.h;
- X
- X }
- X
- X HUnlock((Handle) theScreen.chars);
- X HUnlock((Handle) theScreen.attrs);
- X
- X if (theScreen.cursorStatus) {
- X curs.left = curs.right = theScreen.cursor.h * theScreen.charPDims.h;
- X curs.right += theScreen.charPDims.h;
- X curs.bottom = curs.top = (theScreen.cursor.v + 1) * theScreen.charPDims.v;
- X if (theScreen.cursorLines <= theScreen.charPDims.v)
- X curs.top -= theScreen.cursorLines;
- X else
- X curs.top -= theScreen.charPDims.v;
- X if (theScreen.colorFlag)
- X BackColor(colors[theScreen.cursorColor]);
- X else {
- X cursorLoc = theScreen.cursor.v * theScreen.scrnCDims.h
- X + theScreen.cursor.h;
- X BackColor(
- X colors[
- X (AttrFore((*theScreen.attrs)[cursorLoc]) == attrColorBack) ?
- X theScreen.colorStdBack : theScreen.colorStdFore]);
- X }
- X EraseRect(&curs);
- X }
- X
- X SetOrigin(0, 0);
- X
- X TextFace(normal);
- X
- X ForeColor(blackColor);
- X BackColor(whiteColor);
- X
- X MoveTo(0, 0);
- X
- X ClipRect(&theScreen.window->portRect);
- X
- X UpdtControl(theScreen.window, theScreen.window->visRgn);
- X DrawGrowIcon(theScreen.window);
- X
- X EndUpdate(theScreen.window);
- X
- X return;
- X}
- X
- Xvoid IdleScreenMgr()
- X
- X{
- X long more;
- X short mask;
- X
- X do {
- X
- X mask = everyEvent;
- X if (theScreen.waitFlag) {
- X mask -= mDownMask;
- X mask -= keyDownMask;
- X mask -= autoKeyMask;
- X }
- X
- X if ( (!theScreen.backgrounding) && (theScreen.window == FrontWindow()) )
- X CheckCursorStatus();
- X
- X if (theScreen.wneImplemented) {
- X more = WaitNextEvent(mask, &theScreen.event, 0, NULL);
- X }
- X else {
- X SystemTask();
- X more = GetNextEvent(mask, &theScreen.event);
- X }
- X
- X if (more)
- X switch (theScreen.event.what) {
- X
- X case mouseDown: DoMouseDown(&theScreen.event.where);
- X break;
- X
- X case autoKey:
- X case keyDown: if (theScreen.event.modifiers & cmdKey) {
- X if (theScreen.cmdKeyFlag) {
- X if (theScreen.event.what != autoKey)
- X DoMenuItem(MenuKey(theScreen.event.message & charCodeMask));
- X }
- X else
- X DoKeyDown(true);
- X }
- X else
- X DoKeyDown(false);
- X break;
- X
- X case updateEvt: DoUpdate((WindowPtr) theScreen.event.message);
- X break;
- X
- X case activateEvt: DoActivate((WindowPtr) theScreen.event.message,
- X theScreen.event.modifiers & activeFlag);
- X break;
- X
- X case osEvent: if ((theScreen.event.message >> 24)
- X == suspendResumeMessage) {
- X if (theScreen.event.message & resumeMask) {
- X theScreen.backgrounding = false;
- X DoActivate((WindowPtr) FrontWindow(), true);
- X }
- X else {
- X theScreen.backgrounding = true;
- X DoActivate((WindowPtr) FrontWindow(), false);
- X }
- X }
- X
- X }
- X
- X } while (more);
- X
- X return;
- X}
- X
- Xvoid FlushScreenKeys()
- X
- X{
- X theScreen.keyFlush = theScreen.mouseFlush = TickCount();
- X FlushQueue();
- X return;
- X}
- X
- Xlong CountScreenKeys()
- X
- X{
- X return(LenQueue());
- X}
- X
- Xint GetScreenKeys(keycode, modifiers, ascii, h, v)
- Xchar *keycode;
- Xchar *modifiers;
- Xchar *ascii;
- Xshort *h;
- Xshort *v;
- X
- X{
- X short flag;
- X short th, tv;
- X
- X if (flag = PopQueue(keycode, modifiers, ascii, &th, &tv)) {
- X if (h != NULL) *h = th;
- X if (v != NULL) *v = tv;
- X }
- X
- X return(flag);
- X}
- X
- Xvoid EnableScreenMouse(flag)
- Xlong flag;
- X
- X{
- X if ( (flag) && (!theScreen.mouseFlag) ) theScreen.mouseFlush = TickCount();
- X theScreen.mouseFlag = flag;
- X return;
- X}
- X
- Xvoid ClipScreenMouse(area)
- XRect *area;
- X
- X{
- X theScreen.mouseLRect = theScreen.mouseCRect = *area;
- X theScreen.mouseLRect.left *= theScreen.charPDims.h;
- X theScreen.mouseLRect.top *= theScreen.charPDims.v;
- X theScreen.mouseLRect.right *= theScreen.charPDims.h;
- X theScreen.mouseLRect.bottom *= theScreen.charPDims.v;
- X
- X return;
- X}
- X
- Xvoid DefineScreenCursor(color, lines, blinkRate)
- Xlong color;
- Xlong lines;
- Xlong blinkRate;
- X
- X{
- X theScreen.cursorColor = color;
- X theScreen.cursorLines = lines;
- X theScreen.cursorBlink = blinkRate;
- X
- X InvalCursor(0);
- X
- X return;
- X}
- X
- Xvoid HideScreenCursor()
- X
- X{
- X theScreen.cursorLevel--;
- X CheckCursorStatus();
- X return;
- X}
- X
- Xvoid ShowScreenCursor()
- X
- X{
- X theScreen.cursorLevel++;
- X CheckCursorStatus();
- X return;
- X}
- X
- Xvoid SetScreenAboutProc(procPtr)
- Xvoid (*procPtr)();
- X
- X{
- X theScreen.aboutProc = procPtr;
- X return;
- X}
- X
- Xvoid SetScreenQuitProc(procPtr, flag)
- Xvoid (*procPtr)();
- Xlong flag;
- X
- X{
- X theScreen.quitProc = procPtr;
- X theScreen.quitReturns = flag;
- X return;
- X}
- X
- Xlong YesOrNo(text)
- Xchar *text;
- X
- X{
- X DialogPtr theDialog;
- X short itemHit;
- X short itsType;
- X Handle itsHandle;
- X Rect itsRect;
- X Str255 ptext;
- X long h, v;
- X
- X theDialog = GetNewDialog(yesOrNoDlgID, nil, (WindowPtr) -1);
- X
- X CenterScreenDLOG(yesOrNoDlgID, fixHalf, fixThird, &h, &v);
- X MoveWindow((WindowPtr) theDialog, (short) h, (short) v, false);
- X
- X GetDItem(theDialog, ok, &itsType, &itsHandle, &itsRect);
- X InsetRect(&itsRect, -4, -4);
- X
- X SetDItem(theDialog, yesOrNoDfltBorder, userItem,
- X (Handle) DrawDefaultBorder, &itsRect);
- X
- X if (text != NULL) {
- X strncpy((char *)ptext, text, 255);
- X ptext[255] = '\0';
- X c2pstr((char *)ptext);
- X GetDItem(theDialog, yesOrNoText, &itsType, &itsHandle, &itsRect);
- X SetIText(itsHandle, ptext);
- X }
- X
- X ShowWindow((WindowPtr) theDialog);
- X
- X do {
- X ModalDialog(nil, &itemHit);
- X } while ( (itemHit != ok) && (itemHit != cancel) );
- X
- X DisposDialog(theDialog);
- X
- X return(itemHit == ok);
- X}
- X
- Xvoid ShowScreen(visible)
- Xlong visible;
- X
- X{
- X if (visible)
- X ShowWindow(theScreen.window);
- X else
- X HideWindow(theScreen.window);
- X
- X return;
- X}
- X
- Xvoid GetScreenBounds(bounds)
- XRect *bounds;
- X
- X{
- X
- X#ifdef THINK_C
- X
- X *bounds = screenBits.bounds;
- X bounds->top += GetMBarHeight();
- X
- X#else /* I think we can live without this. -- BS */
- X
- X Point mouse;
- X GDHandle gdh;
- X
- X if (!theScreen.env.hasColorQD) {
- X *bounds = qd.screenBits.bounds;
- X bounds->top += GetMBarHeight();
- X }
- X
- X else {
- X
- X *bounds = (*GetMainDevice())->gdRect;
- X
- X GetMouse(&mouse);
- X LocalToGlobal(&mouse);
- X
- X gdh = GetDeviceList();
- X
- X while (gdh != NULL) {
- X
- X if (PtInRect(mouse, &(*gdh)->gdRect)) {
- X *bounds = (*gdh)->gdRect;
- X if (gdh == GetMainDevice()) bounds->top += GetMBarHeight();
- X gdh = NULL;
- X }
- X
- X else
- X gdh = GetNextDevice(gdh);
- X
- X }
- X
- X }
- X#endif
- X
- X return;
- X}
- X
- X
- Xvoid CenterScreenDLOG(id, hRatio, vRatio, h, v)
- Xlong id;
- XFixed hRatio, vRatio;
- Xlong *h, *v;
- X
- X{
- X long wid, hgt;
- X DialogTHndl d;
- X Rect bounds;
- X
- X d = (DialogTHndl) GetResource('DLOG', (short) id);
- X
- X if (d != NULL) {
- X
- X wid = (*d)->boundsRect.right - (*d)->boundsRect.left;
- X hgt = (*d)->boundsRect.bottom - (*d)->boundsRect.top;
- X
- X GetScreenBounds(&bounds);
- X
- X wid = (bounds.right - bounds.left) - wid;
- X hgt = (bounds.bottom - bounds.top) - hgt;
- X
- X *h = bounds.left + FixRound(hRatio * wid);
- X *v = bounds.top + FixRound(vRatio * hgt);
- X
- X }
- X
- X return;
- X}
- X
- Xlong DoScreenALRT(id, kind, hRatio, vRatio)
- Xlong id;
- Xlong kind;
- XFixed hRatio, vRatio;
- X
- X{
- X long wid, hgt, h, v;
- X long item;
- X AlertTHndl a;
- X Rect bounds;
- X
- X a = (AlertTHndl) GetResource('ALRT', (short) id);
- X
- X if (a != NULL) {
- X
- X wid = (*a)->boundsRect.right - (*a)->boundsRect.left;
- X hgt = (*a)->boundsRect.bottom - (*a)->boundsRect.top;
- X
- X GetScreenBounds(&bounds);
- X
- X wid = (bounds.right - bounds.left) - wid;
- X hgt = (bounds.bottom - bounds.top) - hgt;
- X
- X h = bounds.left + FixRound(hRatio * wid) - (*a)->boundsRect.left;
- X v = bounds.top + FixRound(vRatio * hgt) - (*a)->boundsRect.top;
- X
- X OffsetRect(&(*a)->boundsRect, (short) h, (short) v);
- X
- X MoveHHi((Handle) a);
- X HLock((Handle) a);
- X
- X switch (kind) {
- X case akNormal: item = Alert((short) id, NULL); break;
- X case akStop: item = StopAlert((short) id, NULL); break;
- X case akNote: item = NoteAlert((short) id, NULL); break;
- X case akCaution: item = CautionAlert((short) id, NULL); break;
- X }
- X
- X HUnlock((Handle) a);
- X
- X }
- X
- X else
- X
- X item = -1;
- X
- X return(item);
- X}
- X
- Xvoid ConfigScreenMgr(force, theType, theID, ConfigProc)
- Xlong force;
- XResType theType;
- Xlong theID;
- Xlong (*ConfigProc)(Handle theData);
- X
- X{
- X short saveResFile, homeResFile;
- X short attrs;
- X short itsID;
- X ResType itsType;
- X Str255 itsName;
- X Handle theData;
- X
- X saveResFile = CurResFile();
- X UseResFile(theScreen.infoResFile);
- X
- X theData = GetResource(theType, (short) theID);
- X
- X if (theData != NULL) {
- X
- X homeResFile = HomeResFile(theData);
- X
- X if ( (theScreen.reconfigFlag) ||
- X (force) ||
- X (homeResFile != theScreen.infoResFile) ) {
- X
- X if ((*ConfigProc)(theData)) {
- X
- X if (homeResFile != theScreen.infoResFile) {
- X GetResInfo(theData, &itsID, &itsType, itsName);
- X attrs = GetResAttrs(theData);
- X attrs |= resChanged;
- X DetachResource(theData);
- X AddResource(theData, itsType, itsID, itsName);
- X SetResAttrs(theData, attrs);
- X }
- X else
- X ChangedResource(theData);
- X
- X WriteResource(theData);
- X
- X }
- X
- X }
- X
- X }
- X
- X UseResFile(saveResFile);
- X
- X return;
- X}
- X
- Xstatic pascal void AnimateCursor()
- X
- X{
- X short next;
- X long oldA5;
- X
- X oldA5 = SetCurrentA5();
- X
- X next = (*theScreen.acur)->next + 1;
- X if (next >= (*theScreen.acur)->frames) next = 0;
- X SetCursor(*((*theScreen.acur)->table[next].cursHandle));
- X (*theScreen.acur)->next = next;
- X
- X theScreen.vbl.vblCount = (short) theScreen.waitRate;
- X
- X (void) SetA5(oldA5);
- X
- X return;
- X}
- X
- Xvoid BeginScreenWait(rate)
- Xlong rate;
- X
- X{
- X if (!theScreen.waitFlag) {
- X
- X (*theScreen.acur)->next = 0;
- X
- X SetCursor(*((*theScreen.acur)->table[0].cursHandle));
- X ShowCursor();
- X
- X theScreen.waitFlag = true;
- X theScreen.waitRate = rate;
- X
- X theScreen.vbl.qType = vType;
- X#ifdef THINK_C
- X theScreen.vbl.vblAddr = (int (*)())AnimateCursor;
- X#else
- X theScreen.vbl.vblAddr = AnimateCursor;
- X#endif
- X theScreen.vbl.vblCount = (short) theScreen.waitRate;
- X theScreen.vbl.vblPhase = 0;
- X
- X (void) VInstall((QElemPtr) &theScreen.vbl);
- X
- X }
- X
- X return;
- X}
- X
- Xvoid EndScreenWait()
- X
- X{
- X if (theScreen.waitFlag) {
- X
- X (void) VRemove((QElemPtr) &theScreen.vbl);
- X
- X theScreen.waitFlag = false;
- X
- X InitCursor();
- X
- X }
- X
- X return;
- X}
- X
- XHandle GetFileMHandle()
- X
- X{
- X return((Handle) GetMHandle(theScreen.cmdKeyFlag ? fileID1 : fileID2));
- X}
- X
- XHandle GetAppMHandle()
- X
- X{
- X return((Handle) GetMHandle(theScreen.cmdKeyFlag ? appID1 : appID2));
- X}
- X
- Xlong PushScreen()
- X
- X{
- X long errcode;
- X char **chars, **attrs;
- X SaveScreenHandle next;
- X OSErr oops;
- X
- X next = (SaveScreenHandle) NewHandle(sizeof(SaveScreenRec));
- X
- X if (next != NULL) {
- X
- X chars = theScreen.chars;
- X oops = HandToHand((Handle *) &chars);
- X
- X if (oops == noErr) {
- X
- X attrs = theScreen.attrs;
- X oops = HandToHand((Handle *) &attrs);
- X
- X if (oops == noErr) {
- X
- X (*next)->link = theScreen.stack;
- X (*next)->chars = chars;
- X (*next)->attrs = attrs;
- X (*next)->cursor = theScreen.cursor;
- X
- X theScreen.stack = next;
- X
- X errcode = scrnErrOk;
- X
- X }
- X
- X else {
- X
- X DisposHandle((Handle) chars);
- X DisposHandle((Handle) next);
- X
- X errcode = scrnErrNoMem;
- X
- X }
- X
- X }
- X
- X else {
- X
- X DisposHandle((Handle) next);
- X
- X errcode = scrnErrNoMem;
- X
- X }
- X
- X }
- X
- X else {
- X
- X errcode = scrnErrNoMem;
- X
- X }
- X
- X return(errcode);
- X}
- X
- Xvoid PopScreen()
- X
- X{
- X if (theScreen.stack != NULL) {
- X
- X HLock((Handle) (*theScreen.stack)->chars);
- X HLock((Handle) (*theScreen.stack)->attrs);
- X
- X XSetScreenImage(0,
- X *(*theScreen.stack)->chars,
- X *(*theScreen.stack)->attrs,
- X theScreen.scrnCDims.h,
- X &theScreen.scrnCRect,
- X 0, 0);
- X
- X XSetScreenCursor(0, (*theScreen.stack)->cursor.h,
- X (*theScreen.stack)->cursor.v);
- X
- X DisposeStackTop();
- X
- X UpdateScreen();
- X
- X }
- X
- X return;
- X}
- END_OF_FILE
- if test 31691 -ne `wc -c <'mac/scrnmgr/ScrnMgr.c.2'`; then
- echo shar: \"'mac/scrnmgr/ScrnMgr.c.2'\" unpacked with wrong size!
- fi
- # end of 'mac/scrnmgr/ScrnMgr.c.2'
- fi
- if test -f 'mac/scrnmgr/ScrnMgr.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mac/scrnmgr/ScrnMgr.doc'\"
- else
- echo shar: Extracting \"'mac/scrnmgr/ScrnMgr.doc'\" \(20461 characters\)
- sed "s/^X//" >'mac/scrnmgr/ScrnMgr.doc' <<'END_OF_FILE'
- XCopyright (c) 1989-1991 Curtis McCauley, James E. Wilson
- X
- XYou may copy this subroutine package freely, modify it as you desire,
- Xand distribute it at will, as long as the copyright notice in the
- Xsource material is not disturbed, excepting that no one may use this
- Xpackage or any part of it for commercial purposes of any kind without
- Xthe express written consent of its author.
- X
- XThis document describes a package of subroutines I have decided to
- Xcall the Screen Manager.
- X
- XEnclosed files:
- X
- XScrnMgr.doc What you are reading
- X
- XScrnMgr.c The source for the subroutine package
- XScrnMgr.r Resources used by the subroutines
- XScrnMgr.h Include file for applications
- X
- XScrnMgr.rsrc The Rez output from ScrnMgr.r (if you do not have Rez)
- X
- XScrnTest.c A test application
- XScrnTest.r Resources used by the test application
- X
- XMakeFile What the name implies
- X
- XThe package is pretty heavily built around MPW. It is specifically
- Xtailored for version 3.0, but should work with 2.0.2. The only thing
- XI think you would have to modify for the older version is the SIZE
- Xresource. Porting the package to other environments is not something
- XI would recommend.
- X
- XThe make file recognizes two primary targets: ScrnTest - which will
- Xbuild the test application along with the subroutine package object
- Xfile, and Install - which will copy the object files to appropriate
- Xdirectories. If you have a non-standard MPW directory structure, you
- Xwill want to modify the rules for Install.
- X
- XI initially built the subroutine package around a model of the IBM PC
- Xscreen BIOS calls. The idea was to take a public domain curses
- Xpackage for the PC and replace all the BIOS calls with calls to my
- Xpackage. Since my ultimate goal was to port the UNIX moria program
- Xwhich relied on curses, and the only copy of curses I had was the PC
- Xversion, this strategy initially seemed to make sense. Moria, as it
- Xturns out, only calls a few of the curses routines, so I never had to
- Xactually port the whole PC curses package. It was a lot easier to
- Xjust replace the curses calls in moria with direct calls to my
- Xsubroutine package. By reducing the number of software layers I
- Xachieved better performance, anyway.
- X
- XStill, the internal structure of the package resembles the PC BIOS. I
- Xkeep two large byte arrays to hold the entire screen, one with the
- Xcharacters, the other with the attributes. The attributes are
- Xforeground and background color (the eight original quickdraw colors),
- Xunderlined, and italicized. The bulk of the package, at least in
- Xnumber of functions, is taken up with routines to manipulate these
- Xbuffers, either to put data in or take data out. Whenever the
- Xcontents of the buffers are changed, the window is not immediately
- Xupdated to reflect the change. Instead, I "invalidate" the portion of
- Xthe window changed. This is done by using InvalRect(), which causes
- Xthe area to be accumulated in the update region of the window, or by
- Xadding the area to an internal representation of the dirty area of the
- Xscreen. This internal representation is less precise than the region
- Xwhich is kept by quickdraw calls to InvalRect(). It consists of the
- Xbeginning and ending dirty area on each screen line. The latter
- Xmethod is faster, but the screen changes will only be noticed when a
- Xcall to update the screen is explicitly made, as opposed to the idle
- Xroutine (see below) catching an update event. There are two sets of
- Xroutines, then, to change the screen buffers. The ones prefixed with
- Xa 'D' (for delayed update) use the later method.
- X
- XA program which uses this package, at a minimum, has to call
- XInitScreenMgr() at the beginning to open the window, call
- XIdleScreenMgr() frequently in the middle to handle all the standard
- Xmac events (mouse and keyboard events, especially, but also the
- XMultiFinder stuff as well), and call CloseScreenMgr() at the end. The
- Xbest time to call the idle routine is whenever your program is waiting
- Xfor a keystroke. Another good time is at regular intervals in a heavy
- Xcompute loop. If you do this, you can actually get your program to
- Xrun in the background, but all the idle calls will, of course, slow
- Xthings down some. In heavy compute passages, then, you might instead
- Xwant to bracket the code with calls to BeginScreenWait() and
- XEndScreenWait() to change the mouse cursor to a spinning watch.
- X
- XA description of each routine in the package follows --
- X
- Xint InitScreenMgr(int h, int v, char *title,
- X char *resFile, OSType rfCreator, OSType rfType,
- X void (*fileMenuProc)(int item),
- X void (*appMenuProc)(int item),
- X int multiColorFlag);
- X
- XThis routine initializes the package, allocates buffers, and puts the
- Xwindow on the monitor. H and v are the dimensions of the screen in
- Xcharacters. Title is the window title. ResFile, rfCreator, and
- XrfType describe the file to contain the configuration information.
- XThis file will be maintained in the system folder. It remembers the
- Xposition and size of the window, the font size selected, and, if the
- Xscreen is only two colors, the user's choices for foreground and
- Xbackground color. FileMenuProc points to a routine to be called when
- Xa selection from the file menu is made. A click in the window's close
- Xbox is considered like a selection from the menu, resulting in a call
- Xto fileMenuProc with the item number equal to the constant
- XcloseBoxItem. AppMenuProc points to a routine to be called when a
- Xselection from the application menu is made. Both can be NULL, in
- Xwhich case the subroutine package will handle them as best it can.
- XMultiColorFlag is non-zero when more than two colors will be displayed
- Xon the screen.
- X
- Xvoid IdleScreenMgr(void);
- X
- XThis routine handles the macintosh event queue. It must be called
- Xfrequently, or the user will not be able to select from menus, switch
- Xto another program or desk accessory, etc. It also blinks the screen
- Xcursor.
- X
- Xvoid ShowScreen(int visible);
- X
- XShows or hides the screen window, depending upon the visible flag.
- X
- Xvoid CloseScreenMgr(void);
- X
- XCloses the window, deallocates buffers.
- X
- Xvoid SetScreenQuitProc(void (*quitProc)(void), int willReturnFlag);
- X
- XTells the package what routine to call when quit is chosen. If the
- Xroutine pointed to by quitProc will always return (as opposed to doing
- Xsomething like ExitToShell()), willReturnFlag should be non-zero.
- X
- Xvoid SetScreenAboutProc(void (*aboutProc)(void));
- X
- XAllows the standard about box to be overridden. AboutProc points to a
- Xroutine which should be called when the about item is chosen from the
- Xapple menu.
- X
- XThe following routines all manipulate the screen buffers. Calls
- Xbeginning with 'Set' do not move the screen cursor and need to be told
- Xwhere to begin the operation. Calls beginning with 'Write' move the
- Xcursor and begin the operation at the current cursor location. All of
- Xthese routines can be prefixed with a 'D' to make changes to the
- Xinternal dirty area instead of calling InvalRect(). The internal
- Xdirty area is updated only when a call to UpdateScreen() is made or
- Xsome external update event is generated and caught by the idle
- Xroutine.
- X
- XThe screen cells are indicated by column (h) and row (v) numbers which
- Xincrease from left to right and top to bottom. Hence the upper left
- Xof the screen is (0, 0) and the bottom right is (h, v) as set by the
- Xcall to InitScreenMgr().
- X
- Xvoid SetScreenChar(char c, int h, int v);
- X
- Xvoid SetScreenCharAttr(char c, char a, int h, int v);
- X
- Xvoid WriteScreenChar(char c);
- X
- Xvoid WriteScreenCharAttr(char c, char a);
- X
- XSets the character at (h, v) to c and the attribute to a.
- X
- Xvoid SetScreenBuffer(char *buffer, int rowBytes,
- X Rect *area, int h, int v);
- X
- Xvoid SetScreenBufferAttr(char *buffer, char a,
- X int rowBytes, Rect *area, int h, int v);
- X
- Xvoid WriteScreenBuffer(char *buffer, int rowBytes, Rect *area);
- X
- Xvoid WriteScreenBufferAttr(char *buffer, char a,
- X int rowBytes, Rect *area);
- X
- XSets the block of characters at (h, v) to the contents of buffer and
- Xall the attributes to a. RowBytes indicates the number of bytes in a
- Xrow in buffer. Area indicates the block of characters to copy,
- Xassuming that the first byte in buffer is at (0, 0). Note: This means
- Xthat the area rectangle is in buffer coordinates, not screen
- Xcoordinates.
- X
- Xvoid SetScreenString(char *str, int h, int v);
- X
- Xvoid SetScreenStringAttr(char *str, char a, int h, int v);
- X
- Xvoid WriteScreenString(char *str);
- X
- Xvoid WriteScreenStringAttr(char *str, char a);
- X
- XSets the characters at (h, v) and following to the contents of string
- Xand all the attributes to a.
- X
- Xvoid SetScreenImage(char *c, char *a, int rowBytes,
- X Rect *area, int h, int v);
- X
- Xvoid WriteScreenImage(char *c, char *a,
- X int rowBytes, Rect *area);
- X
- XSets the block of characters at (h, v) to the contents of c and the
- Xattributes to the contents of a. RowBytes indicates the number of
- Xbytes in a row in the c and a buffers. Area indicates the block of
- Xbytes to copy, assuming that the first byte in the buffers is at (0,
- X0). Note: This means that the area rectangle is in buffer
- Xcoordinates, not screen coordinates.
- X
- Xvoid FillScreen(char c, char a, Rect *area);
- X
- XFills the part of the screen indicated by area with the character c
- Xand the attribute a. Area is in screen coordinates.
- X
- Xvoid EraseScreen(Rect *area);
- X
- XFills the part of the screen indicated by area with the blank
- Xcharacter (0x20) and the normal attribute (attrNormal). Area is in
- Xscreen coordinates.
- X
- Xvoid ScrollScreen(int dh, int dv, Rect *area, char a);
- X
- XScrolls the part of the screen indicated by area the distance
- Xindicated by dh and dv (which may be negative). The leftover space is
- Xfilled with the blank character (0x20) and the normal attribute
- X(attrNormal). Area is in screen coordinates.
- X
- Xvoid MoveScreenCursor(int dh, int dv);
- X
- XMoves the screen cursor by the number of character cells indicated by
- Xdh and dv (which may be negative).
- X
- Xvoid SetScreenCursor(int h, int v);
- X
- XPositions the screen cursor at the character cell indicated by h and v.
- X
- Xvoid DefineScreenCursor(int color, int lines, int blinkRate);
- X
- XDefines the screen cursor. Color indicates what you would expect,
- Xlines indicates the height of the cursor in pixels (up to the height
- Xof the character cell, so lines = 32767 will probably give you a block
- Xcursor), and blinkRate indicates the number of clock ticks between
- Xcursor blinks or zero for a non-blinking cursor (a really friendly
- Xprogram will use GetCaretTime() to set this). The default cursor uses
- Xblack, 2 lines, and no blinks. It is initially hidden.
- X
- Xvoid HideScreenCursor(void);
- X
- Xvoid ShowScreenCursor(void);
- X
- XAn internal counter is used to keep track of whether the cursor is to
- Xbe shown on the screen. When it is less than or equal to zero, the
- Xcursor is hidden. Otherwise it is shown. The hide routine decrements
- Xthis counter. Show increments it.
- X
- Xvoid UpdateScreen(void);
- X
- XImmediately draws the dirty portion of the screen. The dirty portion
- Xincludes the update region of the window and the internal dirty area
- Xmaintained by the 'D' buffer manipulation routines.
- X
- XIn addition to the macintosh event queue, this package maintains a
- Xbuffer of keystrokes and mouse clicks. Whenever the idle routine is
- Xcalled, the events are pulled out of the macintosh queue and put into
- Xthe internal buffer.
- X
- Xvoid FlushScreenKeys(void);
- X
- XFlushes the internal buffer of keystrokes and the macintosh event queue.
- X
- Xint CountScreenKeys(void);
- X
- XCounts the number of entries in the internal keystroke buffer.
- X
- Xint GetScreenKeys(char *keyCode, char *modifiers, char *ascii,
- X int *h, int *v);
- X
- XPulls the top element off the internal buffer. KeyCode contains the
- Xkeycode as described in the IM Event Manager documentation. Modifiers
- Xcontains bits which indicate the state of the control keys (command,
- Xshift, caps lock, option, and control) and whether the event is a
- Xmouse click. There are masks defined in ScrnMgr.h that indicate the
- Xexact bit for each. In the case of a mouse click, h and v will be
- Xset. If you are not interested in mouse clicks, you can pass NULLs
- Xfor both. Ascii will get the ascii code of the key hit. If the
- Xkeyboard in use has a control key, the ascii value is taken right from
- Xthe event which will contain the appropriate control code. If the
- Xkeyboard does not have a control key, a test is made to see if the
- Xcommand modifier key is down. If so, the ascii value is converted to
- Xthe appropriate control code. See the discussion on MENU resources
- Xbelow to see how command key equivalents work on machines without a
- Xcontrol key.
- X
- Xvoid EnableScreenMouse(int flag);
- X
- XEnables or disables the queuing of mouse clicks in the internal
- Xbuffer, according to flag. Initially, mouse clicks are disabled.
- X
- Xvoid ClipScreenMouse(Rect *clip);
- X
- XLimits the detection of mouse clicks to the area indicated by clip,
- Xmeasured in character cells on the screen.
- X
- Xvoid GetScreenCharAttr(char *c, char *a, int h, int v);
- X
- XReturns in c and a the character and attribute at (h, v).
- X
- Xvoid GetScreenImage(char *c, char *a, int rowBytes,
- X Rect *area, int h, int v);
- X
- XReturns in c and a the block of characters and attributes beginning at
- X(h, v). RowBytes indicates the number of bytes in a row in the c and
- Xa buffers. Area indicates the block of bytes to copy, assuming that
- Xthe first byte in the buffers is at (0, 0). Note: This means that the
- Xarea rectangle is in buffer coordinates, not screen coordinates.
- X
- Xvoid GetScreenCursor(int *h, int *v);
- X
- XReturns the screen coordinates of the cursor.
- X
- XThe next few routines help with dialogs. They are designed to work
- Xwith multi-monitor systems. On such systems, the active monitor is
- Xchosen by the current mouse location, arguably not a good choice, but
- Xprobably a choice as good as any other.
- X
- Xint YesOrNo(char *question);
- X
- XPuts up a dialog box with the string pointed to by question, a button
- Xfor yes (the default), and a button for no. Returns true if yes is
- Xselected. The box will be centered horizontally on the active
- Xmonitor, one-third of the way from the top.
- X
- Xint DoScreenALRT(int id, int kind, Fixed hRatio, Fixed vRatio);
- X
- XPuts up the alert indicated by id. Kind specifies the type of alert
- X(normal, stop, note, or caution). There are constants defined in
- XScrnMgr.h for each of these kinds. The alert will be centered hRatio
- Xof the way from the left and vRatio of the way from the top of the
- Xactive monitor. (I.e., if hRatio = vRatio = .5, the alert will be
- Xexactly in the middle of the screen.) ScrnMgr.h contains fixed
- Xconstants for common ratios. See IM for a general discussion of fixed
- Xnumbers. Returns the item number of the button pressed.
- X
- Xvoid CenterScreenDLOG(int id, Fixed hRatio, Fixed vRatio,
- X int *h, int *v);
- X
- XGiven a DLOG, which does not have to be currently shown on the screen,
- Xindicated by id, and hRatio and vRatio, returns where to position its
- Xtop left corner in h and v. See DoScreenALRT for an explanation of
- XhRatio and vRatio. This routine is generally used prior to calling
- XGetNewDialog(). You should declare your DLOG to be invisible, call
- XMoveWindow() using h and v to center it, and then call ShowWindow().
- X
- Xvoid GetScreenBounds(Rect *bounds);
- X
- XReturns the bounds in global coordinates of the active monitor, less
- Xthe menu bar if it is on this monitor.
- X
- Xpascal void DrawDefaultBorder();
- X
- Xpascal void DrawGroupRect();
- X
- XTwo handy routines for installing in dialog userItems.
- X
- Xvoid ConfigScreenMgr(int force, ResType theType, int theID,
- X int (*configProc)(Handle theData));
- X
- XA routine to manipulate resources in the configuration file. Checks
- Xfor the presence of the resource indicated by theType and theID. If
- Xthis resource is not found, it does nothing. If the resource is found
- Xsomewhere other than in the configuration file (see InitScreenMgr()),
- Xthis routine assumes that some action needs to be taken. The usual
- Xplace other the the configuration file to find this kind of resource
- Xis in the program file itself and logically represents default values.
- XIf some action needs to be taken or force is non-zero, the routine
- Xpointed to by configProc is called. TheData contains a handle to the
- Xresource found as described above. ConfigProc should generally put up
- Xa dialog box to change the data in theHandle. If it does change the
- Xdata, configProc should return true. Otherwise, false. If configProc
- Xreturns true, the handle is marked changed so that it is added to the
- Xconfiguration file. A nice time to call this routine is at the start
- Xof your program with force false, so that initial configuration
- Xinformation can be obtained from the user. Then provide a menu item
- Xin the application menu to allow the user to change it later, calling
- Xthis routine with force true.
- X
- Xvoid BeginScreenWait(int rate);
- X
- XChanges the cursor to a spinning wristwatch. Rate indicates the
- Xnumber of ticks between each spin.
- X
- Xvoid EndScreenWait(void);
- X
- XReturns the cursor to the standard arrow.
- X
- XHandle GetFileMHandle(void);
- X
- XHandle GetAppMHandle(void);
- X
- XReturns a handle to the file or application menu.
- X
- Xint PushScreen();
- X
- XSaves the current screen buffer (characters, attributes, and cursor
- Xlocation) on a stack. Allocates a significant amount of memory.
- XReturns 0 if successful.
- X
- Xvoid PopScreen()
- X
- XSets the screen contents to the last screen saved by PushScreen(). If
- Xthere are no saved screens on the stack, does nothing.
- X
- XYou should include in your application all the resources found in the
- Xfile ScrnMgr.rsrc. This file is produced from ScrnMgr.r by the MPW
- Xtool Rez. The best way to do this, assuming you have Rez, is to
- Xinclude at the beginning of your program's .r file, the line 'include
- X"ScrnMgr.rsrc";'
- X
- XThis package assumes that your program will have 4 or 5 menus: the
- XApple, File, Edit, Screen (FontSize), and optionally an "application"
- Xmenu. You can override the standard file menu, if you provide a
- XfileMenuProc in the InitScreenMgr() call. If you do override, you
- Xshould provide two menu resources to replace the default ones in
- XScrnMgr.rsrc. The first must be MENU(129). The second, MENU(229),
- Xmust be a copy of the first, except for not having any command key
- Xequivalents. It will be used on machines without a control key. In
- Xother words, machines without a control key on the keyboard cannot use
- Xcommand key equivalents. If you want to implement an application
- Xmenu, you must provide an appMenuProc to the initialization routine,
- Xalong with MENU(133) and MENU(233). The first menu is the application
- Xmenu with command key equivalents, the second without.
- X
- XYou will probably want to override the STR(128) resource which
- Xcontains the title of the first item in the apple menu (i.e, the about
- Xitem). If you override the DLOG(128) and DITL(128) resources, you can
- Xrely on the package to put up your customized about box. Otherwise,
- Xyou can call SetScreenAboutProc() to really customize things. The
- Xdefault about box mentions the version of this package and its
- Xprogrammer.
- X
- XThe STR(129) resource contains the name of the font the package should
- Xuse. Any true monospaced font should work. Be forewarned that very
- Xfew fonts are completely monospaced. Many have a few odd characters
- Xwhose width is not the same as most others. Since this package relies
- Xon GetFontInfo() and the returned widMax to setup the screen, even the
- Xpresence of one extra wide character in the font will cause funny
- Xthings to happen.
- X
- XYou will probably want to override the INFO(1) resource. This
- Xresource contains the window size, position, font size, and colors. A
- Xcopy of it is made the first time your program is run in the
- Xconfiguration file and is thereafter kept up to date. Hence, the copy
- Xyou keep in you application file should contain the default initial
- Xvalues. The window size and position are indicated by a rectangle in
- Xglobal coordinates. Since ResEdit does not provide a template for
- Xthis kind of resource, you will have to at least look at the ScrnMgr.r
- Xfile to see the format of the resource if you want to use ResEdit to
- Xmodify it.
- X
- XFinally, you will want to supply a SIZE resource to make your program
- XMultiFinder friendly.
- X
- XI am somewhat ambivalent about releasing this package to the public.
- XI do not think that it is particularly well-written. And I certainly
- Xdo not think that it does justice to what the mac is all about. It is
- Xprobably full of bugs. The only real testing that it has had is in
- Xthe moria port, which doesn't call all of the routines available.
- XHence, I do not provide an express or implied warranty of any kind.
- XYou use the package at your own risk. If you have any questions, I
- Xcan be reached at 73230.224@compuserve.com or at 73230,224 on CIS.
- X
- XCurtis McCauley
- X22 July 1989
- END_OF_FILE
- if test 20461 -ne `wc -c <'mac/scrnmgr/ScrnMgr.doc'`; then
- echo shar: \"'mac/scrnmgr/ScrnMgr.doc'\" unpacked with wrong size!
- fi
- # end of 'mac/scrnmgr/ScrnMgr.doc'
- fi
- if test -f 'util/scores/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/scores/README'\"
- else
- echo shar: Extracting \"'util/scores/README'\" \(1838 characters\)
- sed "s/^X//" >'util/scores/README' <<'END_OF_FILE'
- XThis directory contains two simple utilities for dealing with score files.
- X
- XThe first, prscore, will simply print a list of every score in the given
- Xscorefile to standard output. The second, delscore, will send a copy of the
- Xscorefile to standard output, except that the nth entry will be deleted.
- X
- XIf you wish to delete an entry from your scorefile, use them as follows.
- XRun "prscore scorefile" to see every entry in the scorefile. Note the index
- X(i.e. rank) of the entry you want to delete. Then run "delscore scorefile
- Xn > tmp.score" where 'n' is the number of the entry you want to delete.
- XThen run "prscore tmp.score" to ensure that the scorefile is OK. You
- Xcan then copy the tmp.score file over your current scorefile.
- X
- XNote: do not try to run "delscore scorefile n > scorefile". You will lose
- Xyour scorefile if you do this.
- X
- XERRORS:
- X1) This has not been well tested. It may not work for everyone. It probably
- X won't compile on every machine that umoria currently supports without
- X a few changes.
- X
- X2) If people are playing umoria while you use these utilties to edit the
- X scorefile, you may lose an entry when copying the new scorefile over the
- X old. These utilities really should lock the scorefile, and then do their
- X work inplace. Meanwhile, to be safe, only do this when no one is playing
- X (you can use the hours file to force this), or else do this really really
- X fast.
- X
- X3) It includes parts of save.c to make compilation easier. This may cause
- X this to fail if save.c is modified and these programs aren't. It really
- X should be linked with save.o.
- X
- X4) It should prompt for the output file name, and then verify that the output
- X file and the input file are different, to prevent people from accidently
- X destroying their scorefile. (Or, this can also be fixed by doing all work
- X in place.)
- X
- X
- END_OF_FILE
- if test 1838 -ne `wc -c <'util/scores/README'`; then
- echo shar: \"'util/scores/README'\" unpacked with wrong size!
- fi
- # end of 'util/scores/README'
- fi
- echo shar: End of archive 17 \(of 39\).
- cp /dev/null ark17isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 39 archives.
- echo "Now run "bldfiles.sh" to build split files"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-