summaryrefslogtreecommitdiff
path: root/sys/mac/MacCommandWin.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/mac/MacCommandWin.c')
-rw-r--r--sys/mac/MacCommandWin.c764
1 files changed, 764 insertions, 0 deletions
diff --git a/sys/mac/MacCommandWin.c b/sys/mac/MacCommandWin.c
new file mode 100644
index 0000000..c3336aa
--- /dev/null
+++ b/sys/mac/MacCommandWin.c
@@ -0,0 +1,764 @@
+//=============================================================================
+// All command window updates, input, etc happen here -EAD
+//=============================================================================
+#include <Controls.h>
+/* #include <ControlDefinitions.h> */
+#include <Events.h>
+#include <Fonts.h>
+#include <MacWindows.h>
+#include "MacGlobals.h"
+#include "macint.h"
+#include <ctype.h>
+#define NIL ((void *) 0)
+
+//=============================================================================
+// local variables
+//=============================================================================
+
+ControlHandle vScroll;
+int cursorPos; /* the cursor's position on the line */
+short linesInView; /* how many lines are in the window */
+int cmdStart; /* where (in text record) the current command starts */
+TextStyle textStyle[2]; /* styles: bold for user input, plain for output */
+/* output is buffered */
+Handle hOutputBuffer = NULL;
+enum currentStyle { plainStyle, boldStyle } currentStyle;
+
+static void GoStartOfLine (void);
+static void GoEndOfLine (void);
+static void GoBackOneWord (void);
+static void GoForwardOneWord (void);
+
+//=============================================================================
+// static void DoScrollBar (ControlHandle control, short change)
+//=============================================================================
+/* keep track of the user as he fiddles with the scroll bar */
+/* This routine is called while the user has the mouse down. */
+/* It makes sure the thumb isn't dragged out-of-bounds. */
+//=============================================================================
+
+static void DoScrollBar (ControlHandle control, short change) {
+ short value = GetControlValue (control), max = GetControlMaximum (control);
+ long newval = value + change; /* this is a long in case we try to go past MAX_INT */
+ if (newval < 0) newval = 0; else if (newval > max) newval = max;
+ SetControlValue (control, (short) newval);
+ if (newval != value) TEScroll (0, (short) (value - newval) * LINEHEIGHT, hTERec);
+}
+
+//=============================================================================
+// pascal Boolean ScrollClickLoop (void)
+//=============================================================================
+//
+//=============================================================================
+
+pascal Boolean ScrollClickLoop (void) {
+ Rect tempRect;
+ Point mouse;
+ GrafPtr oldPort;
+ RgnHandle oldClip;
+ short amount = 0;
+
+ if (FrontWindow () != gCommandWin) return false;
+
+ GetPort (&oldPort);
+ SetPort (gCommandWin);
+ GetClip (oldClip = NewRgn ());
+ SetRect (&tempRect, INT_MIN, INT_MIN, INT_MAX, INT_MAX);
+ ClipRect (&tempRect);
+
+ GetMouse (&mouse);
+ if (mouse.v < TEXTREC->viewRect.top) DoScrollBar (vScroll, -1);
+ else if (mouse.v > TEXTREC->viewRect.bottom) DoScrollBar (vScroll, 1);
+
+ SetClip (oldClip);
+ DisposeRgn (oldClip);
+ SetPort (oldPort);
+ return true;
+}
+
+//=============================================================================
+// static pascal void ScrollProc (ControlHandle control, short thePart)
+//=============================================================================
+// for clicks in the scroll bar or arrows; update the window properly
+//=============================================================================
+
+pascal void ScrollProc (ControlHandle control, short thePart) {
+ short amount;
+ WindowPtr window;
+
+ if (!thePart) return;
+ window = (*control)->contrlOwner;
+ switch (thePart) {
+ case kControlUpButtonPart: amount = -1; break;
+ case kControlDownButtonPart: amount = 1; break;
+ case kControlPageUpPart: amount = -linesInView; break;
+ case kControlPageDownPart: amount = linesInView; break;
+ }
+ DoScrollBar (control, amount);
+}
+
+//=============================================================================
+// Rect SetTERect (void)
+//=============================================================================
+// set the dimensions of the text record in its window
+//=============================================================================
+
+Rect SetTERect (void) {
+ Rect teRect = gCommandWin->portRect;
+ teRect.right -= SCROLLER_WIDTH;
+ InsetRect (&teRect, TEXT_MARGIN, TEXT_MARGIN);
+ linesInView = (teRect.bottom - teRect.top) / LINEHEIGHT;
+ teRect.bottom = teRect.top + linesInView * LINEHEIGHT; /* round off */
+ return teRect;
+}
+
+//=============================================================================
+// static void AdjustCursor (EventRecord *theEvent)
+//=============================================================================
+// make the pointer an I-beam iff it's in the text window
+//=============================================================================
+
+void AdjustCursor (Point theLoc, RgnHandle theRgn)
+{
+ RgnHandle arrowRgn, iBeamRgn, hiliteRgn, tempRgn;
+ Rect theRect;
+ Point thePoint;
+
+ if (gInBackground)
+ return;
+
+ arrowRgn = NewRgn();
+ SetRectRgn(arrowRgn, -32767, -32767, 32767, 32767);
+
+// GlobalToLocal ((theLoc); ???
+
+ if (gCommandWin == FrontWindow () ) {
+ SetPort(gCommandWin);
+ iBeamRgn = NewRgn();
+ hiliteRgn = NewRgn();
+
+ theRect = TEXTREC->viewRect;
+ LocalToGlobal((Point *)&(theRect.top));
+ LocalToGlobal((Point *)&(theRect.bottom));
+ RectRgn(iBeamRgn, &theRect);
+
+ TEGetHiliteRgn(hiliteRgn, hTERec);
+ thePoint.h = thePoint.v = 0;
+ LocalToGlobal(&thePoint);
+ OffsetRgn(hiliteRgn, thePoint.h, thePoint.v);
+
+ DiffRgn(arrowRgn, hiliteRgn, arrowRgn);
+ DiffRgn(arrowRgn, iBeamRgn, arrowRgn);
+
+ DiffRgn(iBeamRgn, hiliteRgn, iBeamRgn);
+
+ if (PtInRgn(theLoc, iBeamRgn)) {
+ SetCursor(*GetCursor(iBeamCursor));
+ CopyRgn(iBeamRgn, theRgn);
+ } else if (PtInRgn(theLoc, hiliteRgn)) {
+ SetCursor(&qd.arrow);
+ CopyRgn(hiliteRgn, theRgn);
+ } else {
+ SetCursor(&qd.arrow);
+ CopyRgn(arrowRgn, theRgn);
+ }
+
+ DisposeRgn(iBeamRgn);
+ DisposeRgn(hiliteRgn);
+
+ } else {
+ SetCursor(&qd.arrow);
+ CopyRgn(arrowRgn, theRgn);
+ }
+
+ DisposeRgn(arrowRgn);
+}
+
+
+
+//=============================================================================
+// static void SetScrollRect (void)
+//=============================================================================
+// Set Scroll bar rec size
+//=============================================================================
+
+void SetScrollRect (void) {
+ /* set the dimensions of the scroll bar in its window */
+
+// This change fixes the double flash on window resize -EAD
+
+// MoveControl (vScroll, commandWin->portRect.right - SCROLLER_WIDTH, -1);
+// SizeControl (vScroll, SCROLLER_WIDTH + 1,
+// (commandWin->portRect.bottom - commandWin->portRect.top) - (SCROLLER_WIDTH - 2));
+ (*vScroll)->contrlRect.left = gCommandWin->portRect.right - SCROLLER_WIDTH;
+ (*vScroll)->contrlRect.top = -1;
+ (*vScroll)->contrlRect.right = gCommandWin->portRect.right + 1;
+ (*vScroll)->contrlRect.bottom = gCommandWin->portRect.bottom - (SCROLLER_WIDTH - 1);
+
+}
+
+//=============================================================================
+// static void AdjustScrollBar (void)
+//=============================================================================
+// Set the thumb on scrollbar
+//=============================================================================
+
+static void AdjustScrollBar (void) {
+ /* adjust the scroll bar to match the position of the text view */
+ short oldval = GetControlValue (vScroll), oldmax = GetControlMaximum (vScroll);
+ short value, max;
+ short test;
+
+ max = TEXTREC->nLines - linesInView;
+ if ((TEXTREC->teLength > 0) && (*(*TEXTREC->hText + TEXTREC->teLength - 1) == '\r')) max++;
+ if (max < 0) max = 0;
+ if (max != oldmax) SetControlMaximum (vScroll, max);
+ value = (short)((TEXTREC->viewRect.top - TEXTREC->destRect.top) / LINEHEIGHT);
+// value = roundup ((TEXTREC->viewRect.top - TEXTREC->destRect.top) / LINEHEIGHT);
+ if (value < 0) value = 0; else if (value > max) value = max;
+ if (value != oldval) SetControlValue (vScroll, value);
+}
+
+static short roundup (float x) { /* a kludge to round up a float to an int */
+ if (((int) x) != ((int) (x += 0.5))) x += 0.5;
+ return (int) x;
+}
+
+//=============================================================================
+// void DoKeyPress (EventRecord *theEvent)
+//=============================================================================
+// Hanlde Keyboard Input
+//=============================================================================
+
+void DoKeyPress (EventRecord *theEvent) {
+ short whatKey = theEvent->message & charCodeMask;
+ if (theEvent->modifiers & cmdKey) {
+ long choice;
+ AdjustMenus ();
+ if (choice = MenuKey (theEvent->message)) DoMenu (choice);
+ else if (((whatKey == 'w') || (whatKey == 'W')) && (FrontWindow () == gGraphicsWin))
+ HideGrafWin ();
+ else if (whatKey == LEFTARROW) GoStartOfLine ();
+ else if (whatKey == RIGHTARROW) GoEndOfLine ();
+ else if (whatKey == UPARROW) DoScrollBar (vScroll, - linesInView);
+ else if (whatKey == DOWNARROW) DoScrollBar (vScroll, linesInView);
+ }
+ else if (theEvent->modifiers & optionKey) {
+ if (whatKey == LEFTARROW) GoBackOneWord ();
+ else if (whatKey == RIGHTARROW) GoForwardOneWord ();
+ }
+ else switch (whatKey) {
+ case PAGEUP: DoScrollBar (vScroll, -linesInView); break;
+ case PAGEDN: DoScrollBar (vScroll, linesInView); break;
+ case HOMEKEY: DoScrollBar (vScroll, INT_MIN); break;
+ case ENDKEY: DoScrollBar (vScroll, INT_MAX); break;
+ case FNKEY: break;
+ case HELPKEY: break;
+ default: recentChar = theEvent->message & charCodeMask;
+ }
+}
+
+//=============================================================================
+// static void DrawOnlyGrowIcon (WindowPtr window)
+//=============================================================================
+// draw growbox on command window with no scoll bars
+//=============================================================================
+
+static void DrawOnlyGrowIcon (WindowPtr window)
+{
+ RgnHandle saveRgn;
+ Rect growRect;
+
+ growRect = window->portRect;
+ growRect.top = growRect.bottom - SCROLLER_WIDTH;
+ growRect.left = growRect.right - SCROLLER_WIDTH;
+ GetClip (saveRgn = NewRgn ());
+ ClipRect (&growRect);
+ DrawGrowIcon (window);
+ SetClip (saveRgn);
+ DisposeRgn (saveRgn);
+}
+
+//=============================================================================
+// void SetSelection (short start, short end)
+//=============================================================================
+// set text selection in the command window
+//=============================================================================
+
+void SetSelection (short start, short end) {
+ TEXTREC->clikStuff = 255; /* to make sure the caret appears at the start of a line when it should */
+ /* see tech note "TextEdit EOL Ambiguity" for more information */
+ TESetSelect (start, end, hTERec);
+}
+
+//=============================================================================
+// static void CancelFlash (void)
+//=============================================================================
+// cancel the matching-paren flashing
+//=============================================================================
+
+static void CancelFlash (void) {
+ if (flashTime) {
+ flashTime = 0;
+ SetSelection (cursorBeforeFlash, cursorBeforeFlash);
+ }
+}
+
+//=============================================================================
+// static void StopPasting (void)
+//=============================================================================
+// clean up after finishing a paste
+//=============================================================================
+
+void StopPasting (void) {
+ pastedLength = 0;
+ if (pastedTextH) {
+ DisposeHandle (pastedTextH);
+ pastedTextH = NULL;
+ }
+}
+
+//=============================================================================
+// static void DoStyle (int whatStyle)
+//=============================================================================
+// set the text to a certain style
+//=============================================================================
+
+static void DoStyle (int whatStyle) {
+ TESetStyle (doFace, &(textStyle[whatStyle]), false, hTERec);
+}
+
+//=============================================================================
+// static void FlushOutput (void)
+//=============================================================================
+// clear out the output buffer, dumping its contents to the window
+//=============================================================================
+
+void FlushOutput (void) {
+ short totalLines, scrollAmount, max;
+
+ if (outputBufferLength == 0) return;
+ CancelFlash ();
+ DoStyle (plainStyle);
+ HLock (hOutputBuffer);
+ TEInsert (*hOutputBuffer, outputBufferLength, hTERec);
+ HUnlock (hOutputBuffer);
+ outputBufferLength = 0;
+
+ if (TEXTREC->teLength > SCROLLBACK_THRESHHOLD) {
+ /* make sure TE record isn't too long */
+#ifdef ORIGINALCODE
+ /* I replaced this because Nyquist was crashing after the
+ buffer got filled. The replacement below is simpler and
+ eliminates the crashes, although it probably could cause
+ problems by clearing the selection.
+ */
+ int i = 1, newLength;
+ TEPtr textPtr;
+ while ((TEXTREC->teLength - TEXTREC->lineStarts[i]) >
+ (SCROLLBACK_THRESHHOLD - DELETE_BLOCK)) i++;
+ i = TEXTREC->lineStarts[i];
+ newLength = TEXTREC->teLength - i;
+ textPtr = (TEPtr)(*(TEXTREC->hText));
+ BlockMoveData ((Ptr)((long)textPtr + i), textPtr, newLength);
+ SetHandleSize (TEXTREC->hText, newLength);
+ TEXTREC->destRect.top += LINEHEIGHT;
+ TECalText (hTERec);
+ TEUpdate (&(TEXTREC->viewRect), hTERec);
+#else
+ /* find the line start after DELETE_BLOCK */
+ int i = 1;
+ while (TEXTREC->lineStarts[i] < DELETE_BLOCK) i++;
+ TESetSelect(0, TEXTREC->lineStarts[i], hTERec);
+ TEDelete(hTERec);
+ /* after deletion, put cursor back at end of buffer */
+ TESetSelect(TEXTREC->teLength, TEXTREC->teLength, hTERec);
+#endif
+ }
+ TESelView (hTERec);
+ AdjustScrollBar ();
+}
+
+//=============================================================================
+// void PrepareForInput (void)
+//=============================================================================
+// get ready to take input
+//=============================================================================
+
+void PrepareForInput (void) {
+ FlushOutput ();
+ cmdStart = TEXTREC->selStart;
+}
+
+//=============================================================================
+// static void DeleteRange (void)
+//=============================================================================
+// delete the selected range of text, updating cmdStart as necessary
+//=============================================================================
+
+void DeleteRange (void) {
+ if (TEXTREC->selEnd <= cmdStart) return;
+ if (TEXTREC->selStart < cmdStart) SetSelection (cmdStart, TEXTREC->selEnd);
+ TEDelete (hTERec);
+}
+
+//=============================================================================
+// static void CopyThisLineToEnd (void)
+//=============================================================================
+// copy the line the caret is on to the end
+//=============================================================================
+
+static void CopyThisLineToEnd (void) {
+ char *buffer;
+ short b, i, caretOffset;
+
+ /* first find out exactly where it starts */
+ i = TEXTREC->nLines-1; /* first find which line */
+ while (TEXTREC->selStart < TEXTREC->lineStarts[i]) i--;
+ while ((i > 0) && ((*(TEXTREC->hText))[TEXTREC->lineStarts[i]-1] != '\r'))
+ i--; /* for wrapped lines */
+ i = TEXTREC->lineStarts[i]; /* now zero in on the exact character where it begins */
+ while ((TEXTCHAR(i) >= '0') && (TEXTCHAR(i) <= '9')) i++; /* skip error level */
+ if ((TEXTCHAR(i) == '>') && (TEXTCHAR(i+1) == ' ')) i+=2; /* get rid of leading prompt */
+
+ caretOffset = TEXTREC->selStart - i; /* how many characters in is the caret? */
+
+ /* now put the line into the buffer */
+ b = 0;
+ while ((TEXTCHAR(i+b) != '\r') && (i+b < TEXTREC->teLength)) b++; /* find the end of the line */
+ buffer = (char *) NewPtr (b);
+ BlockMoveData (*TEXTREC->hText + i, buffer, b);
+ buffer[b] = '\0';
+
+ /* delete whatever's already on the last line */
+ SetSelection (cmdStart, TEXTREC->teLength);
+ TEDelete (hTERec);
+
+ DoStyle (boldStyle);
+ TEInsert (buffer, b, hTERec);
+ DisposePtr (buffer);
+
+ if (caretOffset < 0) caretOffset = b;
+ SetSelection (cmdStart + caretOffset, cmdStart + caretOffset);
+}
+
+//=============================================================================
+// Next four functions possition cursor in text
+//=============================================================================
+
+static void GoStartOfLine (void) {
+ short whichLine = TEXTREC->nLines - 1; /* look for the caret; start at the end and go up */
+ while (TEXTREC->lineStarts[whichLine] > TEXTREC->selStart) whichLine--;
+ SetSelection (TEXTREC->lineStarts[whichLine], TEXTREC->lineStarts[whichLine]);
+ AdjustScrollBar ();
+}
+
+static void GoEndOfLine (void) {
+ short whichLine = TEXTREC->nLines - 1; /* look for the caret; start at the end and go up */
+ while (TEXTREC->lineStarts[whichLine] > TEXTREC->selStart) whichLine--;
+ if (whichLine == TEXTREC->nLines - 1)
+ SetSelection (TEXTREC->teLength, TEXTREC->teLength);
+ else SetSelection (TEXTREC->lineStarts[whichLine+1] - 1, TEXTREC->lineStarts[whichLine+1] - 1);
+ AdjustScrollBar ();
+}
+
+static void GoBackOneWord (void) {
+ short i = TEXTREC->selStart;
+ while ((i > 0) && !isalnum (TEXTCHAR(i-1))) i--;
+ while ((i > 0) && isalnum (TEXTCHAR(i-1))) i--;
+ SetSelection (i, i);
+}
+
+static void GoForwardOneWord (void) {
+ short i = TEXTREC->selStart;
+ while ((i < TEXTREC->teLength) && !isalnum (TEXTCHAR(i))) i++;
+ while ((i < TEXTREC->teLength) && isalnum (TEXTCHAR(i))) i++;
+ SetSelection (i, i);
+}
+
+
+//=============================================================================
+// static void EditFreely (void)
+//=============================================================================
+// Enter text into the command windows
+//=============================================================================
+
+static void EditFreely (void) {
+ Boolean done;
+ do {
+ done = false;
+ DoEvent ();
+ if (pastedLength > 0) { /* if there is still text to paste, paste it */
+ int i = 0;
+ CancelFlash ();
+ if (TEXTREC->selStart < cmdStart) StopPasting ();
+ else {
+ while ((i < pastedLength) && (((char *)(*pastedTextH))[i] != '\r')) i++;
+ DoStyle (boldStyle);
+ TEInsert (*pastedTextH, i, hTERec);
+ AdjustScrollBar ();
+ if (i < pastedLength) { /* we were stopped by a carriage return, so eat it */
+ i++;
+ done = true;
+ }
+ pastedLength -= i;
+ if (pastedLength > 0) {
+ BlockMoveData ((Ptr)((long)(*pastedTextH) + i), *pastedTextH, pastedLength);
+ SetHandleSize (pastedTextH, pastedLength);
+ } else StopPasting ();
+ }
+ }
+ else if (recentChar) { /* if the last event got us a character, process it */
+ int i;
+ Boolean wasOnLastLine;
+ CancelFlash ();
+
+ if ((TEXTREC->selEnd <= cmdStart) && (TEXTREC->selStart != TEXTREC->selEnd)) continue;
+ if (TEXTREC->selStart < cmdStart) SetSelection (cmdStart, TEXTREC->selEnd);
+ wasOnLastLine = (TEXTREC->selStart >= cmdStart);
+
+ if ((recentChar & 0xfc) == 0x1c) { /* was this an arrow key? */
+ TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
+ TEKey (recentChar, hTERec);
+ AdjustScrollBar ();
+ continue;
+ }
+ if (!wasOnLastLine) CopyThisLineToEnd ();
+ switch (recentChar) {
+ case FWDDEL:
+ if (TEXTREC->selStart != TEXTREC->selEnd) DeleteRange ();
+ else if ((TEXTREC->selStart >= cmdStart) && (TEXTREC->selStart < TEXTREC->teLength)) {
+ TEDeactivate (hTERec);
+ SetSelection (TEXTREC->selStart, TEXTREC->selStart + 1);
+ TEDelete (hTERec);
+ if (FrontWindow () == gCommandWin) TEActivate (hTERec);
+ }
+ break;
+ case CLRKEY:
+ if (TEXTREC->selStart != TEXTREC->selEnd) DeleteRange ();
+ break;
+ case DELETE:
+ if (TEXTREC->selStart != TEXTREC->selEnd) DeleteRange ();
+ else if (TEXTREC->selStart > cmdStart) {
+ TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
+ TEKey (DELETE, hTERec);
+ }
+ break;
+ case RETURN:
+ if (wasOnLastLine) done = true;
+ break;
+ case ENTER: /* ENTER ends command no matter what */
+ done = true;
+ break;
+ default:
+ DoStyle (boldStyle);
+ TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
+ TEKey (recentChar, hTERec);
+ if ((recentChar == ')') && (TEXTREC->selStart > cmdStart)) {
+ short parenCount = -1;
+ Boolean inQuotes = false;
+ i = TEXTREC->selStart - 1;
+ while ((--i >= cmdStart) && (parenCount != 0))
+ switch ((*TEXTREC->hText)[i]) {
+ case DBLQUOTE: inQuotes = !inQuotes; break;
+ case '(': if (!inQuotes) parenCount++; break;
+ case ')': if (!inQuotes) parenCount--; break;
+ }
+ if (parenCount == 0) {
+ cursorBeforeFlash = TEXTREC->selStart;
+ SetSelection (i+1, i+2); /* flash the matching open-paren */
+ flashTime = 10;
+ }
+ } else if ((recentChar == DBLQUOTE) && (TEXTREC->selStart > cmdStart)) {
+ i = TEXTREC->selStart - 1;
+ while ((--i >= cmdStart) && ((*TEXTREC->hText)[i] != DBLQUOTE)) ;
+ if ((*TEXTREC->hText)[i] == DBLQUOTE) {
+ cursorBeforeFlash = TEXTREC->selStart;
+ SetSelection (i, i+1); /* flash the matching double-quote */
+ flashTime = 10;
+ }
+ }
+ }
+ AdjustScrollBar ();
+ }
+ } while (!done);
+}
+
+char *macgets (void) {
+ /* retrieve a typed character */
+ /* Note that this uses some extensive (and clever, if I may say so myself) buffering. */
+ int i, b, bufSize;
+ char *ptr, *buffer;
+ Boolean done, onLastLine;
+
+ PrepareForInput ();
+ do { /* repeat until a full expression has been typed */
+ EditFreely (); /* allow free editing for a while */
+
+ /* Now, we have a complete command to parse, if and only if: */
+ /* - the cursor was on the last line when the user pressed Return or Enter, and */
+ /* - the user either pressed Enter, or else every '(' since the beginning */
+ /* of the command is matched by a ')'. */
+ /* Quoting is watched for. ( ") is not a complete expression. */
+
+ done = true;
+ if (TEXTREC->selStart != TEXTREC->teLength) /* if we're not at the end already */
+ SetSelection (TEXTREC->teLength, TEXTREC->teLength); /* send cursor to end */
+ TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
+ TEKey ('\r', hTERec);
+
+ /* check and see if we've completed the command yet */
+ if (recentChar != ENTER) {
+ Boolean inQuotes = false;
+ short parenCount = 0;
+ for (i = cmdStart; i < TEXTREC->teLength; i++)
+ switch ((*TEXTREC->hText)[i]) {
+ case DBLQUOTE: inQuotes = !inQuotes; break;
+ case '(': if (!inQuotes) parenCount++; break;
+ case ')': if (!inQuotes) parenCount--; break;
+ }
+ if ((parenCount > 0) || inQuotes) done = false;
+ }
+
+ AdjustScrollBar ();
+ } while (!done);
+
+ /* put the entire command into the buffer, and return it */
+ bufSize = TEXTREC->teLength - cmdStart;
+ buffer = (char *) NewPtr (bufSize + 1);
+ BlockMoveData (*TEXTREC->hText + cmdStart, buffer, bufSize);
+ buffer[bufSize] = '\0';
+ return buffer;
+}
+
+void macputc (int ch) {
+ /* put a char into the output buffer, and flush the buffer if necessary */
+ switch (ch) {
+ case '\t':
+ do { macputc (' '); } while (cursorPos & 7);
+ break;
+ case DELETE:
+ if (cursorPos) cursorPos--; /* and fall through to default */
+ default:
+ if (outputBufferLength == MAX_BUF) FlushOutput ();
+ if (ch == '\n') {
+ cursorPos = 0;
+ (*hOutputBuffer)[outputBufferLength++] = '\r';
+ } else {
+ cursorPos++;
+ (*hOutputBuffer)[outputBufferLength++] = ch;
+ }
+ }
+}
+
+void macputs (char *s) {
+ /* for completeness */
+ while (*s) macputc (*s++);
+}
+
+void scrflush (void) {
+ extern void osflush (void);
+ /* clear out everything */
+ FlushOutput ();
+ osflush ();
+}
+
+void scrclear (void) {
+ /* clear text window -- not implemented */
+}
+
+//=============================================================================
+// static void UpdateCmdWindow (void)
+//=============================================================================
+// main command window update procedure
+//=============================================================================
+
+
+void UpdateCmdWindow (void) {
+ long textBottom;
+ Rect tempRect;
+
+ InvalRect (&(gCommandWin->portRect));
+ BeginUpdate (gCommandWin);
+ BlockMoveData(&(gCommandWin->portRect), &tempRect, sizeof(Rect));
+ tempRect.right -= SCROLLER_WIDTH;
+ EraseRect (&tempRect);
+ if (gCommandWinResized) {
+ TEXTREC->viewRect = SetTERect ();
+ TEXTREC->destRect.right = TEXTREC->viewRect.right;
+ TECalText (hTERec);
+ SetScrollRect ();
+ gCommandWinResized = false;
+ }
+ DrawOnlyGrowIcon (gCommandWin);
+ FlushOutput ();
+
+ TEXTREC->viewRect = SetTERect (); /* adjust for possible change in height of status line */
+
+ textBottom = TEXTREC->destRect.top + (TEXTREC->nLines * LINEHEIGHT);
+ if (TEXTREC->destRect.top > TEXTREC->viewRect.top)
+ TEScroll (0, (TEXTREC->viewRect.top - TEXTREC->destRect.top), hTERec);
+
+ if (TEXTREC->destRect.top < TEXTREC->viewRect.top) { /* make sure we don't get fractions of lineheights */
+ int amountOffTheTop = TEXTREC->viewRect.top - TEXTREC->destRect.top;
+ if (amountOffTheTop % LINEHEIGHT) TEScroll (0, amountOffTheTop % LINEHEIGHT, hTERec);
+ }
+ TEUpdate (&(TEXTREC->viewRect), hTERec);
+ AdjustScrollBar ();
+ UpdateControls (gCommandWin, gCommandWin->visRgn);
+ EndUpdate (gCommandWin);
+}
+
+void ActivateCmdWindow(void)
+{
+ TEActivate (hTERec);
+ HiliteControl (vScroll, 0);
+ DrawOnlyGrowIcon (gCommandWin);
+}
+
+void DeactivateCmdWindow(void)
+{
+ TEDeactivate (hTERec);
+ HiliteControl (vScroll, 255);
+ DrawOnlyGrowIcon (gCommandWin);
+}
+
+void InitalizeCmdWindow(void)
+{
+
+ /* setup the font, size and writing mode for the command window */
+ TextFont (kFontIDMonaco);
+ TextSize (9);
+ TextFace (0);
+ TextMode (srcCopy);
+ textStyle[plainStyle].tsFace = 0;
+ textStyle[boldStyle].tsFace = bold;
+
+ currentStyle = plainStyle;
+
+ { /* set up scroll bar */
+ Rect scrollRect;
+ vScroll = NewControl (gCommandWin, &scrollRect, "\p", 0, 0, 0, 0, scrollBarProc, 0L);
+ SetScrollRect ();
+ ShowControl (vScroll);
+ }
+
+ { /* set up command text record */
+ Rect teRect = SetTERect ();
+ hTERec = (TEHandle)TEStyleNew (&teRect, &teRect);
+ TECalText (hTERec);
+ TEAutoView (true, hTERec);
+ TESetClickLoop (uppScrollClickLoop, hTERec);
+ TEActivate (hTERec);
+ }
+
+ hOutputBuffer = NewHandle (MAX_BUF); /* a handle to a buffer for text to be displayed */
+}
+
+void CleanupCmdWindow(void)
+{
+ StopPasting ();
+ CloseWindow (gCommandWin);
+ TEDispose (hTERec);
+ DisposeHandle (hOutputBuffer);
+}