1 //=============================================================================
2 // All command window updates, input, etc happen here -EAD
3 //=============================================================================
4 #include <Controls.h>
5 /* #include <ControlDefinitions.h> */
6 #include <Events.h>
7 #include <Fonts.h>
8 #include <MacWindows.h>
9 #include "MacGlobals.h"
10 #include "macint.h"
11 #include <ctype.h>
12 #define NIL ((void *) 0)
13
14 //=============================================================================
15 // local variables
16 //=============================================================================
17
18 ControlHandle vScroll;
19 int cursorPos; /* the cursor's position on the line */
20 short linesInView; /* how many lines are in the window */
21 int cmdStart; /* where (in text record) the current command starts */
22 TextStyle textStyle[2]; /* styles: bold for user input, plain for output */
23 /* output is buffered */
24 Handle hOutputBuffer = NULL;
25 enum currentStyle { plainStyle, boldStyle } currentStyle;
26
27 static void GoStartOfLine (void);
28 static void GoEndOfLine (void);
29 static void GoBackOneWord (void);
30 static void GoForwardOneWord (void);
31
32 //=============================================================================
33 // static void DoScrollBar (ControlHandle control, short change)
34 //=============================================================================
35 /* keep track of the user as he fiddles with the scroll bar */
36 /* This routine is called while the user has the mouse down. */
37 /* It makes sure the thumb isn't dragged out-of-bounds. */
38 //=============================================================================
39
DoScrollBar(ControlHandle control,short change)40 static void DoScrollBar (ControlHandle control, short change) {
41 short value = GetControlValue (control), max = GetControlMaximum (control);
42 long newval = value + change; /* this is a long in case we try to go past MAX_INT */
43 if (newval < 0) newval = 0; else if (newval > max) newval = max;
44 SetControlValue (control, (short) newval);
45 if (newval != value) TEScroll (0, (short) (value - newval) * LINEHEIGHT, hTERec);
46 }
47
48 //=============================================================================
49 // pascal Boolean ScrollClickLoop (void)
50 //=============================================================================
51 //
52 //=============================================================================
53
ScrollClickLoop(void)54 pascal Boolean ScrollClickLoop (void) {
55 Rect tempRect;
56 Point mouse;
57 GrafPtr oldPort;
58 RgnHandle oldClip;
59 short amount = 0;
60
61 if (FrontWindow () != gCommandWin) return false;
62
63 GetPort (&oldPort);
64 SetPort (gCommandWin);
65 GetClip (oldClip = NewRgn ());
66 SetRect (&tempRect, INT_MIN, INT_MIN, INT_MAX, INT_MAX);
67 ClipRect (&tempRect);
68
69 GetMouse (&mouse);
70 if (mouse.v < TEXTREC->viewRect.top) DoScrollBar (vScroll, -1);
71 else if (mouse.v > TEXTREC->viewRect.bottom) DoScrollBar (vScroll, 1);
72
73 SetClip (oldClip);
74 DisposeRgn (oldClip);
75 SetPort (oldPort);
76 return true;
77 }
78
79 //=============================================================================
80 // static pascal void ScrollProc (ControlHandle control, short thePart)
81 //=============================================================================
82 // for clicks in the scroll bar or arrows; update the window properly
83 //=============================================================================
84
ScrollProc(ControlHandle control,short thePart)85 pascal void ScrollProc (ControlHandle control, short thePart) {
86 short amount;
87 WindowPtr window;
88
89 if (!thePart) return;
90 window = (*control)->contrlOwner;
91 switch (thePart) {
92 case kControlUpButtonPart: amount = -1; break;
93 case kControlDownButtonPart: amount = 1; break;
94 case kControlPageUpPart: amount = -linesInView; break;
95 case kControlPageDownPart: amount = linesInView; break;
96 }
97 DoScrollBar (control, amount);
98 }
99
100 //=============================================================================
101 // Rect SetTERect (void)
102 //=============================================================================
103 // set the dimensions of the text record in its window
104 //=============================================================================
105
SetTERect(void)106 Rect SetTERect (void) {
107 Rect teRect = gCommandWin->portRect;
108 teRect.right -= SCROLLER_WIDTH;
109 InsetRect (&teRect, TEXT_MARGIN, TEXT_MARGIN);
110 linesInView = (teRect.bottom - teRect.top) / LINEHEIGHT;
111 teRect.bottom = teRect.top + linesInView * LINEHEIGHT; /* round off */
112 return teRect;
113 }
114
115 //=============================================================================
116 // static void AdjustCursor (EventRecord *theEvent)
117 //=============================================================================
118 // make the pointer an I-beam iff it's in the text window
119 //=============================================================================
120
AdjustCursor(Point theLoc,RgnHandle theRgn)121 void AdjustCursor (Point theLoc, RgnHandle theRgn)
122 {
123 RgnHandle arrowRgn, iBeamRgn, hiliteRgn, tempRgn;
124 Rect theRect;
125 Point thePoint;
126
127 if (gInBackground)
128 return;
129
130 arrowRgn = NewRgn();
131 SetRectRgn(arrowRgn, -32767, -32767, 32767, 32767);
132
133 // GlobalToLocal ((theLoc); ???
134
135 if (gCommandWin == FrontWindow () ) {
136 SetPort(gCommandWin);
137 iBeamRgn = NewRgn();
138 hiliteRgn = NewRgn();
139
140 theRect = TEXTREC->viewRect;
141 LocalToGlobal((Point *)&(theRect.top));
142 LocalToGlobal((Point *)&(theRect.bottom));
143 RectRgn(iBeamRgn, &theRect);
144
145 TEGetHiliteRgn(hiliteRgn, hTERec);
146 thePoint.h = thePoint.v = 0;
147 LocalToGlobal(&thePoint);
148 OffsetRgn(hiliteRgn, thePoint.h, thePoint.v);
149
150 DiffRgn(arrowRgn, hiliteRgn, arrowRgn);
151 DiffRgn(arrowRgn, iBeamRgn, arrowRgn);
152
153 DiffRgn(iBeamRgn, hiliteRgn, iBeamRgn);
154
155 if (PtInRgn(theLoc, iBeamRgn)) {
156 SetCursor(*GetCursor(iBeamCursor));
157 CopyRgn(iBeamRgn, theRgn);
158 } else if (PtInRgn(theLoc, hiliteRgn)) {
159 SetCursor(&qd.arrow);
160 CopyRgn(hiliteRgn, theRgn);
161 } else {
162 SetCursor(&qd.arrow);
163 CopyRgn(arrowRgn, theRgn);
164 }
165
166 DisposeRgn(iBeamRgn);
167 DisposeRgn(hiliteRgn);
168
169 } else {
170 SetCursor(&qd.arrow);
171 CopyRgn(arrowRgn, theRgn);
172 }
173
174 DisposeRgn(arrowRgn);
175 }
176
177
178
179 //=============================================================================
180 // static void SetScrollRect (void)
181 //=============================================================================
182 // Set Scroll bar rec size
183 //=============================================================================
184
SetScrollRect(void)185 void SetScrollRect (void) {
186 /* set the dimensions of the scroll bar in its window */
187
188 // This change fixes the double flash on window resize -EAD
189
190 // MoveControl (vScroll, commandWin->portRect.right - SCROLLER_WIDTH, -1);
191 // SizeControl (vScroll, SCROLLER_WIDTH + 1,
192 // (commandWin->portRect.bottom - commandWin->portRect.top) - (SCROLLER_WIDTH - 2));
193 (*vScroll)->contrlRect.left = gCommandWin->portRect.right - SCROLLER_WIDTH;
194 (*vScroll)->contrlRect.top = -1;
195 (*vScroll)->contrlRect.right = gCommandWin->portRect.right + 1;
196 (*vScroll)->contrlRect.bottom = gCommandWin->portRect.bottom - (SCROLLER_WIDTH - 1);
197
198 }
199
200 //=============================================================================
201 // static void AdjustScrollBar (void)
202 //=============================================================================
203 // Set the thumb on scrollbar
204 //=============================================================================
205
AdjustScrollBar(void)206 static void AdjustScrollBar (void) {
207 /* adjust the scroll bar to match the position of the text view */
208 short oldval = GetControlValue (vScroll), oldmax = GetControlMaximum (vScroll);
209 short value, max;
210 short test;
211
212 max = TEXTREC->nLines - linesInView;
213 if ((TEXTREC->teLength > 0) && (*(*TEXTREC->hText + TEXTREC->teLength - 1) == '\r')) max++;
214 if (max < 0) max = 0;
215 if (max != oldmax) SetControlMaximum (vScroll, max);
216 value = (short)((TEXTREC->viewRect.top - TEXTREC->destRect.top) / LINEHEIGHT);
217 // value = roundup ((TEXTREC->viewRect.top - TEXTREC->destRect.top) / LINEHEIGHT);
218 if (value < 0) value = 0; else if (value > max) value = max;
219 if (value != oldval) SetControlValue (vScroll, value);
220 }
221
roundup(float x)222 static short roundup (float x) { /* a kludge to round up a float to an int */
223 if (((int) x) != ((int) (x += 0.5))) x += 0.5;
224 return (int) x;
225 }
226
227 //=============================================================================
228 // void DoKeyPress (EventRecord *theEvent)
229 //=============================================================================
230 // Hanlde Keyboard Input
231 //=============================================================================
232
DoKeyPress(EventRecord * theEvent)233 void DoKeyPress (EventRecord *theEvent) {
234 short whatKey = theEvent->message & charCodeMask;
235 if (theEvent->modifiers & cmdKey) {
236 long choice;
237 AdjustMenus ();
238 if (choice = MenuKey (theEvent->message)) DoMenu (choice);
239 else if (((whatKey == 'w') || (whatKey == 'W')) && (FrontWindow () == gGraphicsWin))
240 HideGrafWin ();
241 else if (whatKey == LEFTARROW) GoStartOfLine ();
242 else if (whatKey == RIGHTARROW) GoEndOfLine ();
243 else if (whatKey == UPARROW) DoScrollBar (vScroll, - linesInView);
244 else if (whatKey == DOWNARROW) DoScrollBar (vScroll, linesInView);
245 }
246 else if (theEvent->modifiers & optionKey) {
247 if (whatKey == LEFTARROW) GoBackOneWord ();
248 else if (whatKey == RIGHTARROW) GoForwardOneWord ();
249 }
250 else switch (whatKey) {
251 case PAGEUP: DoScrollBar (vScroll, -linesInView); break;
252 case PAGEDN: DoScrollBar (vScroll, linesInView); break;
253 case HOMEKEY: DoScrollBar (vScroll, INT_MIN); break;
254 case ENDKEY: DoScrollBar (vScroll, INT_MAX); break;
255 case FNKEY: break;
256 case HELPKEY: break;
257 default: recentChar = theEvent->message & charCodeMask;
258 }
259 }
260
261 //=============================================================================
262 // static void DrawOnlyGrowIcon (WindowPtr window)
263 //=============================================================================
264 // draw growbox on command window with no scoll bars
265 //=============================================================================
266
DrawOnlyGrowIcon(WindowPtr window)267 static void DrawOnlyGrowIcon (WindowPtr window)
268 {
269 RgnHandle saveRgn;
270 Rect growRect;
271
272 growRect = window->portRect;
273 growRect.top = growRect.bottom - SCROLLER_WIDTH;
274 growRect.left = growRect.right - SCROLLER_WIDTH;
275 GetClip (saveRgn = NewRgn ());
276 ClipRect (&growRect);
277 DrawGrowIcon (window);
278 SetClip (saveRgn);
279 DisposeRgn (saveRgn);
280 }
281
282 //=============================================================================
283 // void SetSelection (short start, short end)
284 //=============================================================================
285 // set text selection in the command window
286 //=============================================================================
287
SetSelection(short start,short end)288 void SetSelection (short start, short end) {
289 TEXTREC->clikStuff = 255; /* to make sure the caret appears at the start of a line when it should */
290 /* see tech note "TextEdit EOL Ambiguity" for more information */
291 TESetSelect (start, end, hTERec);
292 }
293
294 //=============================================================================
295 // static void CancelFlash (void)
296 //=============================================================================
297 // cancel the matching-paren flashing
298 //=============================================================================
299
CancelFlash(void)300 static void CancelFlash (void) {
301 if (flashTime) {
302 flashTime = 0;
303 SetSelection (cursorBeforeFlash, cursorBeforeFlash);
304 }
305 }
306
307 //=============================================================================
308 // static void StopPasting (void)
309 //=============================================================================
310 // clean up after finishing a paste
311 //=============================================================================
312
StopPasting(void)313 void StopPasting (void) {
314 pastedLength = 0;
315 if (pastedTextH) {
316 DisposeHandle (pastedTextH);
317 pastedTextH = NULL;
318 }
319 }
320
321 //=============================================================================
322 // static void DoStyle (int whatStyle)
323 //=============================================================================
324 // set the text to a certain style
325 //=============================================================================
326
DoStyle(int whatStyle)327 static void DoStyle (int whatStyle) {
328 TESetStyle (doFace, &(textStyle[whatStyle]), false, hTERec);
329 }
330
331 //=============================================================================
332 // static void FlushOutput (void)
333 //=============================================================================
334 // clear out the output buffer, dumping its contents to the window
335 //=============================================================================
336
FlushOutput(void)337 void FlushOutput (void) {
338 short totalLines, scrollAmount, max;
339
340 if (outputBufferLength == 0) return;
341 CancelFlash ();
342 DoStyle (plainStyle);
343 HLock (hOutputBuffer);
344 TEInsert (*hOutputBuffer, outputBufferLength, hTERec);
345 HUnlock (hOutputBuffer);
346 outputBufferLength = 0;
347
348 if (TEXTREC->teLength > SCROLLBACK_THRESHHOLD) {
349 /* make sure TE record isn't too long */
350 #ifdef ORIGINALCODE
351 /* I replaced this because Nyquist was crashing after the
352 buffer got filled. The replacement below is simpler and
353 eliminates the crashes, although it probably could cause
354 problems by clearing the selection.
355 */
356 int i = 1, newLength;
357 TEPtr textPtr;
358 while ((TEXTREC->teLength - TEXTREC->lineStarts[i]) >
359 (SCROLLBACK_THRESHHOLD - DELETE_BLOCK)) i++;
360 i = TEXTREC->lineStarts[i];
361 newLength = TEXTREC->teLength - i;
362 textPtr = (TEPtr)(*(TEXTREC->hText));
363 BlockMoveData ((Ptr)((long)textPtr + i), textPtr, newLength);
364 SetHandleSize (TEXTREC->hText, newLength);
365 TEXTREC->destRect.top += LINEHEIGHT;
366 TECalText (hTERec);
367 TEUpdate (&(TEXTREC->viewRect), hTERec);
368 #else
369 /* find the line start after DELETE_BLOCK */
370 int i = 1;
371 while (TEXTREC->lineStarts[i] < DELETE_BLOCK) i++;
372 TESetSelect(0, TEXTREC->lineStarts[i], hTERec);
373 TEDelete(hTERec);
374 /* after deletion, put cursor back at end of buffer */
375 TESetSelect(TEXTREC->teLength, TEXTREC->teLength, hTERec);
376 #endif
377 }
378 TESelView (hTERec);
379 AdjustScrollBar ();
380 }
381
382 //=============================================================================
383 // void PrepareForInput (void)
384 //=============================================================================
385 // get ready to take input
386 //=============================================================================
387
PrepareForInput(void)388 void PrepareForInput (void) {
389 FlushOutput ();
390 cmdStart = TEXTREC->selStart;
391 }
392
393 //=============================================================================
394 // static void DeleteRange (void)
395 //=============================================================================
396 // delete the selected range of text, updating cmdStart as necessary
397 //=============================================================================
398
DeleteRange(void)399 void DeleteRange (void) {
400 if (TEXTREC->selEnd <= cmdStart) return;
401 if (TEXTREC->selStart < cmdStart) SetSelection (cmdStart, TEXTREC->selEnd);
402 TEDelete (hTERec);
403 }
404
405 //=============================================================================
406 // static void CopyThisLineToEnd (void)
407 //=============================================================================
408 // copy the line the caret is on to the end
409 //=============================================================================
410
CopyThisLineToEnd(void)411 static void CopyThisLineToEnd (void) {
412 char *buffer;
413 short b, i, caretOffset;
414
415 /* first find out exactly where it starts */
416 i = TEXTREC->nLines-1; /* first find which line */
417 while (TEXTREC->selStart < TEXTREC->lineStarts[i]) i--;
418 while ((i > 0) && ((*(TEXTREC->hText))[TEXTREC->lineStarts[i]-1] != '\r'))
419 i--; /* for wrapped lines */
420 i = TEXTREC->lineStarts[i]; /* now zero in on the exact character where it begins */
421 while ((TEXTCHAR(i) >= '0') && (TEXTCHAR(i) <= '9')) i++; /* skip error level */
422 if ((TEXTCHAR(i) == '>') && (TEXTCHAR(i+1) == ' ')) i+=2; /* get rid of leading prompt */
423
424 caretOffset = TEXTREC->selStart - i; /* how many characters in is the caret? */
425
426 /* now put the line into the buffer */
427 b = 0;
428 while ((TEXTCHAR(i+b) != '\r') && (i+b < TEXTREC->teLength)) b++; /* find the end of the line */
429 buffer = (char *) NewPtr (b);
430 BlockMoveData (*TEXTREC->hText + i, buffer, b);
431 buffer[b] = '\0';
432
433 /* delete whatever's already on the last line */
434 SetSelection (cmdStart, TEXTREC->teLength);
435 TEDelete (hTERec);
436
437 DoStyle (boldStyle);
438 TEInsert (buffer, b, hTERec);
439 DisposePtr (buffer);
440
441 if (caretOffset < 0) caretOffset = b;
442 SetSelection (cmdStart + caretOffset, cmdStart + caretOffset);
443 }
444
445 //=============================================================================
446 // Next four functions possition cursor in text
447 //=============================================================================
448
GoStartOfLine(void)449 static void GoStartOfLine (void) {
450 short whichLine = TEXTREC->nLines - 1; /* look for the caret; start at the end and go up */
451 while (TEXTREC->lineStarts[whichLine] > TEXTREC->selStart) whichLine--;
452 SetSelection (TEXTREC->lineStarts[whichLine], TEXTREC->lineStarts[whichLine]);
453 AdjustScrollBar ();
454 }
455
GoEndOfLine(void)456 static void GoEndOfLine (void) {
457 short whichLine = TEXTREC->nLines - 1; /* look for the caret; start at the end and go up */
458 while (TEXTREC->lineStarts[whichLine] > TEXTREC->selStart) whichLine--;
459 if (whichLine == TEXTREC->nLines - 1)
460 SetSelection (TEXTREC->teLength, TEXTREC->teLength);
461 else SetSelection (TEXTREC->lineStarts[whichLine+1] - 1, TEXTREC->lineStarts[whichLine+1] - 1);
462 AdjustScrollBar ();
463 }
464
GoBackOneWord(void)465 static void GoBackOneWord (void) {
466 short i = TEXTREC->selStart;
467 while ((i > 0) && !isalnum (TEXTCHAR(i-1))) i--;
468 while ((i > 0) && isalnum (TEXTCHAR(i-1))) i--;
469 SetSelection (i, i);
470 }
471
GoForwardOneWord(void)472 static void GoForwardOneWord (void) {
473 short i = TEXTREC->selStart;
474 while ((i < TEXTREC->teLength) && !isalnum (TEXTCHAR(i))) i++;
475 while ((i < TEXTREC->teLength) && isalnum (TEXTCHAR(i))) i++;
476 SetSelection (i, i);
477 }
478
479
480 //=============================================================================
481 // static void EditFreely (void)
482 //=============================================================================
483 // Enter text into the command windows
484 //=============================================================================
485
EditFreely(void)486 static void EditFreely (void) {
487 Boolean done;
488 do {
489 done = false;
490 DoEvent ();
491 if (pastedLength > 0) { /* if there is still text to paste, paste it */
492 int i = 0;
493 CancelFlash ();
494 if (TEXTREC->selStart < cmdStart) StopPasting ();
495 else {
496 while ((i < pastedLength) && (((char *)(*pastedTextH))[i] != '\r')) i++;
497 DoStyle (boldStyle);
498 TEInsert (*pastedTextH, i, hTERec);
499 AdjustScrollBar ();
500 if (i < pastedLength) { /* we were stopped by a carriage return, so eat it */
501 i++;
502 done = true;
503 }
504 pastedLength -= i;
505 if (pastedLength > 0) {
506 BlockMoveData ((Ptr)((long)(*pastedTextH) + i), *pastedTextH, pastedLength);
507 SetHandleSize (pastedTextH, pastedLength);
508 } else StopPasting ();
509 }
510 }
511 else if (recentChar) { /* if the last event got us a character, process it */
512 int i;
513 Boolean wasOnLastLine;
514 CancelFlash ();
515
516 if ((TEXTREC->selEnd <= cmdStart) && (TEXTREC->selStart != TEXTREC->selEnd)) continue;
517 if (TEXTREC->selStart < cmdStart) SetSelection (cmdStart, TEXTREC->selEnd);
518 wasOnLastLine = (TEXTREC->selStart >= cmdStart);
519
520 if ((recentChar & 0xfc) == 0x1c) { /* was this an arrow key? */
521 TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
522 TEKey (recentChar, hTERec);
523 AdjustScrollBar ();
524 continue;
525 }
526 if (!wasOnLastLine) CopyThisLineToEnd ();
527 switch (recentChar) {
528 case FWDDEL:
529 if (TEXTREC->selStart != TEXTREC->selEnd) DeleteRange ();
530 else if ((TEXTREC->selStart >= cmdStart) && (TEXTREC->selStart < TEXTREC->teLength)) {
531 TEDeactivate (hTERec);
532 SetSelection (TEXTREC->selStart, TEXTREC->selStart + 1);
533 TEDelete (hTERec);
534 if (FrontWindow () == gCommandWin) TEActivate (hTERec);
535 }
536 break;
537 case CLRKEY:
538 if (TEXTREC->selStart != TEXTREC->selEnd) DeleteRange ();
539 break;
540 case DELETE:
541 if (TEXTREC->selStart != TEXTREC->selEnd) DeleteRange ();
542 else if (TEXTREC->selStart > cmdStart) {
543 TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
544 TEKey (DELETE, hTERec);
545 }
546 break;
547 case RETURN:
548 if (wasOnLastLine) done = true;
549 break;
550 case ENTER: /* ENTER ends command no matter what */
551 done = true;
552 break;
553 default:
554 DoStyle (boldStyle);
555 TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
556 TEKey (recentChar, hTERec);
557 if ((recentChar == ')') && (TEXTREC->selStart > cmdStart)) {
558 short parenCount = -1;
559 Boolean inQuotes = false;
560 i = TEXTREC->selStart - 1;
561 while ((--i >= cmdStart) && (parenCount != 0))
562 switch ((*TEXTREC->hText)[i]) {
563 case DBLQUOTE: inQuotes = !inQuotes; break;
564 case '(': if (!inQuotes) parenCount++; break;
565 case ')': if (!inQuotes) parenCount--; break;
566 }
567 if (parenCount == 0) {
568 cursorBeforeFlash = TEXTREC->selStart;
569 SetSelection (i+1, i+2); /* flash the matching open-paren */
570 flashTime = 10;
571 }
572 } else if ((recentChar == DBLQUOTE) && (TEXTREC->selStart > cmdStart)) {
573 i = TEXTREC->selStart - 1;
574 while ((--i >= cmdStart) && ((*TEXTREC->hText)[i] != DBLQUOTE)) ;
575 if ((*TEXTREC->hText)[i] == DBLQUOTE) {
576 cursorBeforeFlash = TEXTREC->selStart;
577 SetSelection (i, i+1); /* flash the matching double-quote */
578 flashTime = 10;
579 }
580 }
581 }
582 AdjustScrollBar ();
583 }
584 } while (!done);
585 }
586
macgets(void)587 char *macgets (void) {
588 /* retrieve a typed character */
589 /* Note that this uses some extensive (and clever, if I may say so myself) buffering. */
590 int i, b, bufSize;
591 char *ptr, *buffer;
592 Boolean done, onLastLine;
593
594 PrepareForInput ();
595 do { /* repeat until a full expression has been typed */
596 EditFreely (); /* allow free editing for a while */
597
598 /* Now, we have a complete command to parse, if and only if: */
599 /* - the cursor was on the last line when the user pressed Return or Enter, and */
600 /* - the user either pressed Enter, or else every '(' since the beginning */
601 /* of the command is matched by a ')'. */
602 /* Quoting is watched for. ( ") is not a complete expression. */
603
604 done = true;
605 if (TEXTREC->selStart != TEXTREC->teLength) /* if we're not at the end already */
606 SetSelection (TEXTREC->teLength, TEXTREC->teLength); /* send cursor to end */
607 TEXTREC->clikStuff = 255; /* to make sure the caret appears where it should */
608 TEKey ('\r', hTERec);
609
610 /* check and see if we've completed the command yet */
611 if (recentChar != ENTER) {
612 Boolean inQuotes = false;
613 short parenCount = 0;
614 for (i = cmdStart; i < TEXTREC->teLength; i++)
615 switch ((*TEXTREC->hText)[i]) {
616 case DBLQUOTE: inQuotes = !inQuotes; break;
617 case '(': if (!inQuotes) parenCount++; break;
618 case ')': if (!inQuotes) parenCount--; break;
619 }
620 if ((parenCount > 0) || inQuotes) done = false;
621 }
622
623 AdjustScrollBar ();
624 } while (!done);
625
626 /* put the entire command into the buffer, and return it */
627 bufSize = TEXTREC->teLength - cmdStart;
628 buffer = (char *) NewPtr (bufSize + 1);
629 BlockMoveData (*TEXTREC->hText + cmdStart, buffer, bufSize);
630 buffer[bufSize] = '\0';
631 return buffer;
632 }
633
macputc(int ch)634 void macputc (int ch) {
635 /* put a char into the output buffer, and flush the buffer if necessary */
636 switch (ch) {
637 case '\t':
638 do { macputc (' '); } while (cursorPos & 7);
639 break;
640 case DELETE:
641 if (cursorPos) cursorPos--; /* and fall through to default */
642 default:
643 if (outputBufferLength == MAX_BUF) FlushOutput ();
644 if (ch == '\n') {
645 cursorPos = 0;
646 (*hOutputBuffer)[outputBufferLength++] = '\r';
647 } else {
648 cursorPos++;
649 (*hOutputBuffer)[outputBufferLength++] = ch;
650 }
651 }
652 }
653
macputs(char * s)654 void macputs (char *s) {
655 /* for completeness */
656 while (*s) macputc (*s++);
657 }
658
scrflush(void)659 void scrflush (void) {
660 extern void osflush (void);
661 /* clear out everything */
662 FlushOutput ();
663 osflush ();
664 }
665
scrclear(void)666 void scrclear (void) {
667 /* clear text window -- not implemented */
668 }
669
670 //=============================================================================
671 // static void UpdateCmdWindow (void)
672 //=============================================================================
673 // main command window update procedure
674 //=============================================================================
675
676
UpdateCmdWindow(void)677 void UpdateCmdWindow (void) {
678 long textBottom;
679 Rect tempRect;
680
681 InvalRect (&(gCommandWin->portRect));
682 BeginUpdate (gCommandWin);
683 BlockMoveData(&(gCommandWin->portRect), &tempRect, sizeof(Rect));
684 tempRect.right -= SCROLLER_WIDTH;
685 EraseRect (&tempRect);
686 if (gCommandWinResized) {
687 TEXTREC->viewRect = SetTERect ();
688 TEXTREC->destRect.right = TEXTREC->viewRect.right;
689 TECalText (hTERec);
690 SetScrollRect ();
691 gCommandWinResized = false;
692 }
693 DrawOnlyGrowIcon (gCommandWin);
694 FlushOutput ();
695
696 TEXTREC->viewRect = SetTERect (); /* adjust for possible change in height of status line */
697
698 textBottom = TEXTREC->destRect.top + (TEXTREC->nLines * LINEHEIGHT);
699 if (TEXTREC->destRect.top > TEXTREC->viewRect.top)
700 TEScroll (0, (TEXTREC->viewRect.top - TEXTREC->destRect.top), hTERec);
701
702 if (TEXTREC->destRect.top < TEXTREC->viewRect.top) { /* make sure we don't get fractions of lineheights */
703 int amountOffTheTop = TEXTREC->viewRect.top - TEXTREC->destRect.top;
704 if (amountOffTheTop % LINEHEIGHT) TEScroll (0, amountOffTheTop % LINEHEIGHT, hTERec);
705 }
706 TEUpdate (&(TEXTREC->viewRect), hTERec);
707 AdjustScrollBar ();
708 UpdateControls (gCommandWin, gCommandWin->visRgn);
709 EndUpdate (gCommandWin);
710 }
711
ActivateCmdWindow(void)712 void ActivateCmdWindow(void)
713 {
714 TEActivate (hTERec);
715 HiliteControl (vScroll, 0);
716 DrawOnlyGrowIcon (gCommandWin);
717 }
718
DeactivateCmdWindow(void)719 void DeactivateCmdWindow(void)
720 {
721 TEDeactivate (hTERec);
722 HiliteControl (vScroll, 255);
723 DrawOnlyGrowIcon (gCommandWin);
724 }
725
InitalizeCmdWindow(void)726 void InitalizeCmdWindow(void)
727 {
728
729 /* setup the font, size and writing mode for the command window */
730 TextFont (kFontIDMonaco);
731 TextSize (9);
732 TextFace (0);
733 TextMode (srcCopy);
734 textStyle[plainStyle].tsFace = 0;
735 textStyle[boldStyle].tsFace = bold;
736
737 currentStyle = plainStyle;
738
739 { /* set up scroll bar */
740 Rect scrollRect;
741 vScroll = NewControl (gCommandWin, &scrollRect, "\p", 0, 0, 0, 0, scrollBarProc, 0L);
742 SetScrollRect ();
743 ShowControl (vScroll);
744 }
745
746 { /* set up command text record */
747 Rect teRect = SetTERect ();
748 hTERec = (TEHandle)TEStyleNew (&teRect, &teRect);
749 TECalText (hTERec);
750 TEAutoView (true, hTERec);
751 TESetClickLoop (uppScrollClickLoop, hTERec);
752 TEActivate (hTERec);
753 }
754
755 hOutputBuffer = NewHandle (MAX_BUF); /* a handle to a buffer for text to be displayed */
756 }
757
CleanupCmdWindow(void)758 void CleanupCmdWindow(void)
759 {
760 StopPasting ();
761 CloseWindow (gCommandWin);
762 TEDispose (hTERec);
763 DisposeHandle (hOutputBuffer);
764 }
765