1 /******************************************************************************
2 *
3 * NSSDC/CDF Toolbox of routines for CDF Toolkit (Macintosh).
4 *
5 * Version 1.2a, 15-Nov-97, Hughes STX.
6 *
7 * Modification history:
8 *
9 * V1.0 26-Oct-94, J Love Original version.
10 * V1.1 19-Sep-95, J Love Macintosh event handling.
11 * V1.1a 29-Sep-95, J Love Macintosh dialog filtering. Outline default
12 * button. The CDF cursor.
13 * V1.2 15-Aug-95, J Love CDF V2.6.
14 * V1.2a 15-Nov-97, J Love Windows NT (renamed functions).
15 *
16 ******************************************************************************/
17
18 #define TOOLBOX2
19 #include "windoz.h"
20
21 #if defined(mac)
22 #include "cdfdist.rh"
23 #include "so.rh"
24 #endif
25
26 /******************************************************************************
27 * Macros.
28 ******************************************************************************/
29
30 #define ToBottom(textH,atPoint) \
31 (((*textH)->nLines * (*textH)->lineHeight) - atPoint.v)
32
33 #define MAX_TE_TEXT_LEN 30000 /* 32767 doesn't seem to work. */
34 #define MAX_TE_TEXT_LEN_wNL (MAX_TE_TEXT_LEN - NUMsoCOLS)
35
36 /******************************************************************************
37 * Local function prototypes.
38 ******************************************************************************/
39
40 static void FlashButton PROTOARGs((DialogPtr dialog, int itemN));
41 static void delay PROTOARGs((double seconds));
42 static void UpdateCursorSO PROTOARGs((EventRecord *event));
43 static void SaveStatusLine PROTOARGs((char *text));
44
45 /******************************************************************************
46 * MacExecuteSO.
47 ******************************************************************************/
48
49 void MacExecuteSO (exeFnc, qopFnc)
50 Logical (*exeFnc) PROTOARGs((int argC, char *argV[]));
51 Logical (*qopFnc) PROTOARGs((int *argC, char **argV[]));
52 {
53 int argC; char **argV; EventRecord event; WindowPtr whichWindow;
54 InitMacUI ();
55 InitMacMenusSO ();
56 if (!(*qopFnc)(&argC,&argV)) return;
57 InitMacSO ();
58 MacExecuteTimer (exeFnc, argC, argV);
59 UpdateSOscrollBars ();
60 FreeMacQOPs (argC, argV);
61 for (;;) {
62 SystemTask ();
63 TEIdle (soTextH);
64 GetNextEvent (everyEvent, &event);
65 switch (event.what) {
66 /*********************************************************************
67 * Check if a null event;
68 *********************************************************************/
69 case nullEvent:
70 UpdateCursorSO (&event);
71 break;
72 /*********************************************************************
73 * Check if a mouse down event.
74 *********************************************************************/
75 case mouseDown: {
76 switch (FindWindow(event.where,&whichWindow)) {
77 /*****************************************************************
78 * Check if mouse down in menu bar.
79 *****************************************************************/
80 case inMenuBar: {
81 long tempL = MenuSelect (event.where);
82 short menuId = HighSHORTinLONG (tempL);
83 short itemN = LowSHORTinLONG (tempL);
84 switch (menuId) {
85 case APPLEmi:
86 switch (itemN) {
87 case ABOUTin:
88 DisplayAbout ();
89 break;
90 default: {
91 Str255 name;
92 GetItem (appleMenuHso, itemN, name);
93 OpenDeskAcc (name);
94 SetPort (soWindowP);
95 break;
96 }
97 }
98 break;
99 case FILEmi:
100 switch (itemN) {
101 case EXECUTEin:
102 if ((*qopFnc)(&argC,&argV)) {
103 MacExecuteTimer (exeFnc, argC, argV);
104 UpdateSOscrollBars ();
105 FreeMacQOPs (argC, argV);
106 }
107 break;
108 case SAVEinFILE:
109 SaveSO (FALSE);
110 break;
111 case SAVEASinFILE:
112 SaveSO (TRUE);
113 break;
114 case CLEARinFILE:
115 ResetSO (TRUE);
116 break;
117 case QUITin:
118 return;
119 }
120 break;
121 }
122 HiliteMenu (0);
123 break;
124 }
125 /*****************************************************************
126 * Check for mouse down in drag region of a window.
127 *****************************************************************/
128 case inDrag: {
129 RectPtr screen = &qd.screenBits.bounds;
130 Rect dragRect;
131 dragRect.top = screen->top + 40;
132 dragRect.left = screen->left + 40;
133 dragRect.bottom = screen->bottom - 40;
134 dragRect.right = screen->right - 40;
135 DragWindow (whichWindow, event.where, &dragRect);
136 break;
137 }
138 /*****************************************************************
139 * Check for mouse down in system window.
140 *****************************************************************/
141 case inSysWindow:
142 SystemClick (&event, whichWindow);
143 break;
144 /*****************************************************************
145 * Check for mouse down in body of a window.
146 *****************************************************************/
147 case inContent: {
148 Point tPoint = event.where; ControlHandle controlHandle;
149 short partCode;
150 GlobalToLocal (&tPoint);
151 partCode = FindControl (tPoint, whichWindow, &controlHandle);
152 if (partCode != 0) {
153 float pct;
154 short delta, toBottom, value, newAtPointV;
155 long ref = GetCRefCon (controlHandle);
156 switch (ref) {
157 case VSCROLLsoREFCON:
158 switch (partCode) {
159 case inUpButton:
160 if (soAtPoint.v > 0) {
161 delta = MINIMUM (soLineHeight, soAtPoint.v);
162 TEScroll ((short) 0, delta, soTextH);
163 soAtPoint.v -= delta;
164 }
165 break;
166 case inDownButton:
167 toBottom = ToBottom (soTextH, soAtPoint);
168 if (toBottom > 0) {
169 delta = MINIMUM (soLineHeight, toBottom);
170 TEScroll ((short) 0, -delta, soTextH);
171 soAtPoint.v += delta;
172 }
173 break;
174 case inPageUp:
175 if (soAtPoint.v > 0) {
176 delta = MINIMUM (soViewHeight, soAtPoint.v);
177 TEScroll ((short) 0, delta, soTextH);
178 soAtPoint.v -= delta;
179 }
180 break;
181 case inPageDown:
182 toBottom = ToBottom (soTextH, soAtPoint);
183 if (toBottom > 0) {
184 delta = MINIMUM (soViewHeight, toBottom);
185 TEScroll ((short) 0, -delta, soTextH);
186 soAtPoint.v += delta;
187 }
188 break;
189 case inThumb:
190 if (TrackControl(controlHandle,tPoint,NULL) != 0) {
191 if (soDestHeight > soViewHeight) {
192 value = GetCtlValue (controlHandle);
193 pct = ((float) value) /
194 ((float) (SCROLLsoMAX - SCROLLsoMIN));
195 newAtPointV = soDestHeight * pct;
196 newAtPointV -= (newAtPointV % soLineHeight);
197 delta = newAtPointV - soAtPoint.v;
198 TEScroll ((short) 0, -delta, soTextH);
199 soAtPoint.v = newAtPointV;
200 }
201 }
202 break;
203 }
204 UpdateSOscrollBars ();
205 break;
206 }
207 }
208 break;
209 }
210 }
211 break;
212 }
213 /*********************************************************************
214 * Check if a key down event.
215 *********************************************************************/
216 case keyDown:
217 case autoKey: {
218 char keyCode = (char) ((event.message & keyCodeMask) >> 8);
219 short delta, toBottom;
220 switch (keyCode) {
221 case PAGEup_KEYCODE:
222 if (soAtPoint.v > 0) {
223 delta = MINIMUM (soViewHeight, soAtPoint.v);
224 TEScroll ((short) 0, delta, soTextH);
225 soAtPoint.v -= delta;
226 }
227 break;
228 case PAGEdown_KEYCODE:
229 toBottom = ToBottom (soTextH, soAtPoint);
230 if (toBottom > 0) {
231 delta = MINIMUM (soViewHeight, toBottom);
232 TEScroll ((short) 0, -delta, soTextH);
233 soAtPoint.v += delta;
234 }
235 break;
236 case R_KEYCODE:
237 if ((event.modifiers & cmdKey) != 0) {
238 if ((*qopFnc)(&argC,&argV)) {
239 MacExecuteTimer (exeFnc, argC, argV);
240 UpdateSOscrollBars ();
241 FreeMacQOPs (argC, argV);
242 }
243 }
244 break;
245 case S_KEYCODE:
246 if ((*soTextH)->teLength > 0) SaveSO (FALSE);
247 break;
248 case Q_KEYCODE:
249 if ((event.modifiers & cmdKey) != 0) return;
250 break;
251 default:
252 break;
253 }
254 UpdateSOscrollBars ();
255 break;
256 }
257 /*********************************************************************
258 * Check for an activation event (activate or deactivate).
259 *********************************************************************/
260 case activateEvt:
261 if ((event.modifiers & activeFlag) != 0) {
262 TEActivate (soTextH);
263 ShowControl (soVscrollH);
264 SetCursor (CDF_CURSOR);
265 }
266 else {
267 TEDeactivate (soTextH);
268 HideControl (soVscrollH);
269 }
270 break;
271 /*********************************************************************
272 * Check for an update event for a window.
273 *********************************************************************/
274 case updateEvt: {
275 BeginUpdate ((WindowPtr) event.message);
276 EraseRect (&soTextRect);
277 TEUpdate (&soTextRect, soTextH);
278 DrawControls (soWindowP);
279 DrawStatusLine (NULL);
280 EndUpdate ((WindowPtr) event.message);
281 break;
282 }
283 }
284 }
285
286 }
287
288 /******************************************************************************
289 * MacExecuteTimer.
290 ******************************************************************************/
291
292 void MacExecuteTimer (exeFnc, argC, argV)
293 Logical (*exeFnc) PROTOARGs((int argC, char *argV[]));
294 int argC;
295 char *argV[];
296 {
297 char text[SO_STATUS_LINE_LEN+1]; clock_t endClock, totalClock;
298 int hour, minute, second, hundredths, i;
299 ResetSO (FALSE);
300 if ((*soTextH)->teLength > 0) {
301 TEScroll ((short) 0, -soLineHeight, soTextH);
302 soAtPoint.v += soLineHeight;
303 for (i = 0; i < NUMsoCOLS - 1; i++) WriteOut (stdout, "-");
304 WriteOut (stdout, "\n");
305 }
306 strcpyX (text, "Executing...", 0);
307 CatNcharacters (text, 46, (int) ' ');
308 strcatX (text, "Elapsed time: 00:00:00.00", 0);
309 DrawStatusLine (text);
310 startClock = clock ();
311 lastSecond = 0;
312 (*exeFnc) (argC, argV);
313 endClock = clock ();
314 totalClock = endClock - startClock;
315 hour = (int) ((totalClock / CLOCKS_PER_SEC) / 3600);
316 minute = (int) ((totalClock / CLOCKS_PER_SEC) / 60);
317 second = (int) ((totalClock / CLOCKS_PER_SEC) % 60);
318 hundredths = (int) (((totalClock % CLOCKS_PER_SEC) * 100) / CLOCKS_PER_SEC);
319 strcpyX (text, "Executing...complete.", 0);
320 CatNcharacters (text, 37, (int) ' ');
321 sprintf (EofS(text), "Elapsed time: %02d:%02d:%02d.%02d",
322 hour, minute, second, hundredths);
323 DrawStatusLine (text);
324 return;
325 }
326
327 /******************************************************************************
328 * InitMacUI.
329 * Initialize the Macintosh User Interface.
330 ******************************************************************************/
331
InitMacUI()332 void InitMacUI () {
333 InitGraf (&qd.thePort);
334 InitFonts ();
335 FlushEvents ((short) everyEvent, (short) 0);
336 InitWindows ();
337 TEInit ();
338 InitDialogs (NULL);
339 InitCursor ();
340 return;
341 }
342
343 /******************************************************************************
344 * InitMacSO.
345 * Initialize the Macintosh standard output window.
346 ******************************************************************************/
347
InitMacSO()348 void InitMacSO () {
349 static WindowRecord wRecord;
350 WindowPtr behindWindow = (WindowPtr) -1; /* On top of all other windows. */
351 soWindowP = GetNewWindow (SOri, &wRecord, behindWindow);
352 ShowWindow (soWindowP);
353 SetPort (soWindowP);
354 TextFont (monaco);
355 soTextRect.top = MARGINsoSIZE;
356 soTextRect.left = MARGINsoSIZE;
357 soTextRect.bottom = MARGINsoSIZE + (NUMsoROWS * FONTsoHEIGHT);
358 soTextRect.right = MARGINsoSIZE + (NUMsoCOLS * FONTsoWIDTH);
359 soTextH = TENew (&soTextRect, &soTextRect);
360 soViewHeight = soTextRect.bottom - soTextRect.top;
361 soLineHeight = (*soTextH)->lineHeight;
362 soNviewLines = soViewHeight / soLineHeight;
363 soDestHeight = 0;
364 soAtPoint.v = 0;
365 soVscrollH = GetNewControl (SOSCROLLri, soWindowP);
366 soStatusRect.top = WINDOWsoHEIGHT - STATUSareaHEIGHT;
367 soStatusRect.left = 0;
368 soStatusRect.bottom = WINDOWsoHEIGHT;
369 soStatusRect.right = WINDOWsoWIDTH;
370 DrawStatusLine (NULL);
371 return;
372 }
373
374 /******************************************************************************
375 * InitMacMenusSO.
376 * Initialize the Macintosh menus for the standard output window.
377 ******************************************************************************/
378
InitMacMenusSO()379 void InitMacMenusSO () {
380 appleMenuHso = GetMenu (APPLEri);
381 AddResMenu (appleMenuHso, *((long *) "DRVR"));
382 InsertMenu (appleMenuHso, 0);
383 fileMenuHso = GetMenu (FILEri);
384 InsertMenu (fileMenuHso, 0);
385 DrawMenuBar ();
386 DisableItem (fileMenuHso, SAVEinFILE);
387 DisableItem (fileMenuHso, SAVEASinFILE);
388 DisableItem (fileMenuHso, CLEARinFILE);
389 return;
390 }
391
392 /******************************************************************************
393 * UpdateCursorSO.
394 ******************************************************************************/
395
UpdateCursorSO(event)396 static void UpdateCursorSO (event)
397 EventRecord *event;
398 {
399 WindowPtr whichWindow;
400 switch (FindWindow(event->where,&whichWindow)) {
401 case inContent: {
402 Point tPoint = event->where; ControlHandle controlHandle;
403 GlobalToLocal (&tPoint);
404 if (FindControl(tPoint,whichWindow,&controlHandle) == 0)
405 SetCursor (CDF_CURSOR);
406 else
407 SetCursor (ARROW_CURSOR);
408 break;
409 }
410 default:
411 SetCursor (ARROW_CURSOR);
412 break;
413 }
414 return;
415 }
416
417 /******************************************************************************
418 * MacMessageDialog.
419 ******************************************************************************/
420
MacMessageDialog(severityText,messageText)421 void MacMessageDialog (severityText, messageText)
422 char *severityText;
423 char *messageText;
424 {
425 DialogRecord dRecord; DialogPtr dialogP; static Rect rect0s = { 0,0,0,0 };
426 WindowPtr behind = (WindowPtr) -1;
427 #ifndef __MWERKS__
428 short itemN;
429 #else
430 SInt16 itemN;
431 UserItemUPP OutlineDefaultButtonUPP;
432 OutlineDefaultButtonUPP = NewUserItemProc (OutlineDefaultButton);
433 #endif
434 ParamText (CtoPstr(severityText), CtoPstr(messageText),
435 CtoPstr(""), CtoPstr(""));
436 PtoCstr ((uChar *) severityText);
437 PtoCstr ((uChar *) messageText);
438 dialogP = GetNewDialog (MESSAGEri, &dRecord, behind);
439 #ifndef __MWERKS__
440 SetDItem (dialogP, (short) ODBinMD, (short) userItem,
441 (Handle) OutlineDefaultButton, &rect0s);
442 #else
443 SetDItem (dialogP, (short) ODBinMD, (short) userItem,
444 (Handle) OutlineDefaultButtonUPP, &rect0s);
445 #endif
446 if (soWindowP != NULL) { /* Only if SO. */
447 HideControl (soVscrollH);
448 TEDeactivate (soTextH);
449 }
450 ShowWindow ((WindowPtr) dialogP);
451 ModalDialog (NULL, &itemN);
452 CloseDialog (dialogP);
453 if (soWindowP != NULL) { /* Only if SO. */
454 ShowControl (soVscrollH);
455 TEActivate (soTextH);
456 }
457 return;
458 }
459
460 /******************************************************************************
461 * DrawStatusLine.
462 * Note that `soStatusLine' is blank padded just in case it got shorter.
463 ******************************************************************************/
464
DrawStatusLine(text)465 void DrawStatusLine (text)
466 char *text;
467 {
468 int i;
469 MoveTo ((short) soStatusRect.left, (short) soStatusRect.top);
470 LineTo ((short) soStatusRect.right, (short) soStatusRect.top);
471 MoveTo ((short) (soStatusRect.left + 2), (short) (soStatusRect.bottom - 4));
472 TextFont (monaco);
473 TextMode (srcCopy);
474 if (text != NULL) strcpyX (soStatusLine, text, SO_STATUS_LINE_LEN);
475 for (i = strlen(soStatusLine); i < SO_STATUS_LINE_LEN; i++) {
476 soStatusLine[i] = ' ';
477 }
478 CtoPstr (soStatusLine);
479 DrawString ((uChar *) soStatusLine);
480 PtoCstr ((uChar *) soStatusLine);
481 return;
482 }
483
484 /******************************************************************************
485 * SaveStatusLine.
486 ******************************************************************************/
487
SaveStatusLine(text)488 static void SaveStatusLine (text)
489 char *text;
490 {
491 strcpyX (text, soStatusLine, SO_STATUS_LINE_LEN);
492 return;
493 }
494
495 /******************************************************************************
496 * FreeMacQOPs.
497 ******************************************************************************/
498
FreeMacQOPs(argC,argV)499 void FreeMacQOPs (argC, argV)
500 int argC;
501 char *argV[];
502 {
503 int argN;
504 for (argN = 0; argN < argC; argN++) cdf_FreeMemory (argV[argN], FatalError);
505 cdf_FreeMemory (argV, FatalError);
506 return;
507 }
508
509 /******************************************************************************
510 * CalcBounds.
511 ******************************************************************************/
512
CalcBounds(rect,width,height,topPct,leftPct)513 void CalcBounds (rect, width, height, topPct, leftPct)
514 Rect *rect;
515 int width;
516 int height;
517 double topPct;
518 double leftPct;
519 {
520 Rect screenRect = qd.screenBits.bounds;
521 short screenWidth = screenRect.right - screenRect.left;
522 short screenHeight = screenRect.bottom - screenRect.top;
523 rect->left = (screenWidth - width) * leftPct;
524 rect->right = rect->left + width;
525 rect->top = ((screenHeight -
526 MENUbarHEIGHT -
527 TITLEbarHEIGHT -
528 height) * topPct) + MENUbarHEIGHT + TITLEbarHEIGHT;
529 rect->bottom = rect->top + height;
530 return;
531 }
532
533 /******************************************************************************
534 * ResetSO.
535 ******************************************************************************/
536
ResetSO(clear)537 void ResetSO (clear)
538 Logical clear;
539 {
540 if (clear) {
541 TEScroll ((short) 0, soAtPoint.v, soTextH);
542 soAtPoint.v = 0;
543 TESetSelect (0L, (long) (*soTextH)->teLength, soTextH);
544 TEDelete (soTextH);
545 TESetSelect (0L, 0L, soTextH);
546 soDestHeight = 0;
547 DisableItem (fileMenuHso, SAVEinFILE);
548 DisableItem (fileMenuHso, SAVEASinFILE);
549 DisableItem (fileMenuHso, CLEARinFILE);
550 }
551 else {
552 short toBottom = ToBottom (soTextH, soAtPoint);
553 if (toBottom > 0) {
554 TEScroll ((short) 0, -toBottom, soTextH);
555 soAtPoint.v += toBottom;
556 }
557 }
558 UpdateSOscrollBars ();
559 soLineCount = 0;
560 return;
561 }
562
563 /******************************************************************************
564 * UpdateSOscrollBars.
565 * Currently only a vertical scroll bar is used.
566 ******************************************************************************/
567
UpdateSOscrollBars(void)568 void UpdateSOscrollBars (void) {
569 float pct = BOO(soDestHeight == 0,0.0,
570 ((float) soAtPoint.v) / ((float) soDestHeight));
571 short value = SCROLLsoMIN + (pct * (SCROLLsoMAX - SCROLLsoMIN));
572 SetCtlValue (soVscrollH, value);
573 return;
574 }
575
576 /******************************************************************************
577 * SaveSO.
578 * Returns TRUE if the standard output was successfully saved.
579 ******************************************************************************/
580
SaveSO(as)581 Logical SaveSO (as)
582 Logical as; /* If TRUE, prompt for file in which to save output. */
583 {
584 Logical overWrite = FALSE;
585 char errorMsg[] = "Unable to save output.";
586 char fileName[DU_MAX_PATH_LEN+1], a_mode[1+1];
587 FILE *fp;
588 /****************************************************************************
589 * If necessary, prompt for file.
590 ****************************************************************************/
591 if (as) {
592 StandardFileReply reply;
593 char prompt[] = "Enter output file:";
594 char defaultName[] = "";
595 StandardPutFile (CtoPstr(prompt), CtoPstr(defaultName), &reply);
596 if (reply.sfGood) {
597 BuildMacPath (&reply.sfFile, fileName, FALSE);
598 if (reply.sfReplacing) overWrite = TRUE;
599 }
600 else
601 return FALSE;
602 }
603 else {
604 strcpyX (fileName, pgmName, DU_MAX_NAME_LEN);
605 strcatX (fileName, ".so", DU_MAX_NAME_LEN);
606 MakeLowerString (fileName);
607 }
608 /****************************************************************************
609 * If the file exists, prompt for what to do.
610 ****************************************************************************/
611 if (IsReg(fileName)) {
612 if (!overWrite) {
613 DialogPtr dialog; DialogRecord dRecord;
614 static Rect rect0s = { 0,0,0,0 }; WindowPtr behind = (WindowPtr) -1;
615 #ifndef __MWERKS__
616 short itemN;
617 #else
618 SInt16 itemN;
619 UserItemUPP OutlineDefaultButtonUPP;
620 OutlineDefaultButtonUPP = NewUserItemProc (OutlineDefaultButton);
621 #endif
622 ParamText (CtoPstr(fileName),CtoPstr(""),CtoPstr(""),CtoPstr(""));
623 PtoCstr ((uChar *) fileName);
624 dialog = GetNewDialog (OFEXISTSri, &dRecord, behind);
625 #ifndef __MWERKS__
626 SetDItem (dialog, (short) ODBinEXISTS, (short) userItem,
627 (Handle) OutlineDefaultButton, &rect0s);
628 #else
629 SetDItem (dialog, (short) ODBinEXISTS, (short) userItem,
630 (Handle) OutlineDefaultButtonUPP, &rect0s);
631 #endif
632 HideControl (soVscrollH);
633 TEDeactivate (soTextH);
634 ShowWindow ((WindowPtr) dialog);
635 SetCursor (ARROW_CURSOR);
636 ModalDialog (NULL, &itemN);
637 CloseDialog (dialog);
638 TEActivate (soTextH);
639 ShowControl (soVscrollH);
640 switch (itemN) {
641 case OVERinEXISTS:
642 strcpyX (a_mode, "w", 0);
643 break;
644 case APPENDinEXISTS:
645 strcpyX (a_mode, "a", 0);
646 break;
647 case CANCELinEXISTS:
648 return FALSE;
649 }
650 }
651 else
652 strcpyX (a_mode, "w", 0);
653 }
654 else
655 strcpyX (a_mode, "w", 0);
656 /****************************************************************************
657 * Open file.
658 ****************************************************************************/
659 fp = fopen (fileName, a_mode);
660 if (fp == NULL) {
661 DisplayError (errorMsg);
662 return FALSE;
663 }
664 /****************************************************************************
665 * Write to the file.
666 ****************************************************************************/
667 if ((*soTextH)->teLength > 0) {
668 if (fwrite (*((*soTextH)->hText),(*soTextH)->teLength,1,fp) != 1) {
669 DisplayError (errorMsg);
670 fclose (fp);
671 return FALSE;
672 }
673 }
674 /****************************************************************************
675 * Close file.
676 ****************************************************************************/
677 if (fclose(fp) == EOF) {
678 DisplayError (errorMsg);
679 return FALSE;
680 }
681 return TRUE;
682 }
683
684 /******************************************************************************
685 * BuildMacPath.
686 ******************************************************************************/
687
688 #define ROOT_dirID 2
689
BuildMacPath(spec,path,stripExt)690 Logical BuildMacPath (spec, path, stripExt)
691 FSSpec *spec; /* In: File specification from File Manager. */
692 char path[DU_MAX_PATH_LEN+1]; /* Out: Full/relative path. */
693 Logical stripExt; /* In: If TRUE, strip off file extension. */
694 {
695 long parID = spec->parID, /* Parent directory identifier. */
696 curID; /* Current directory identifier. */
697 CInfoPBRec pb;
698 char dir[DU_MAX_DIR_LEN+1];
699 HGetVol (NULL, NULL, &curID);
700 PstrcpyX (path, (char *) spec->name, DU_MAX_PATH_LEN);
701 if (stripExt) {
702 char *dot = strchr (path, '.');
703 if (dot != NULL) *dot = NUL;
704 }
705 if (parID == curID) return TRUE;
706 pb.dirInfo.ioCompletion = NULL;
707 pb.dirInfo.ioNamePtr = (StringPtr) dir;
708 pb.dirInfo.ioVRefNum = spec->vRefNum;
709 pb.dirInfo.ioFDirIndex = -1;
710 while (parID != ROOT_dirID) {
711 pb.dirInfo.ioDrDirID = parID;
712 if (PBGetCatInfo(&pb,FALSE) != noErr) return FALSE;
713 prependX (path, ":", DU_MAX_PATH_LEN);
714 PprependX (path, (char *) pb.dirInfo.ioNamePtr, DU_MAX_PATH_LEN);
715 parID = pb.dirInfo.ioDrParID;
716 if (parID == curID) {
717 prependX (path, ":", DU_MAX_PATH_LEN);
718 return TRUE;
719 }
720 }
721 pb.dirInfo.ioDrDirID = parID;
722 if (PBGetCatInfo(&pb,FALSE) != noErr) return FALSE;
723 prependX (path, ":", DU_MAX_PATH_LEN);
724 PprependX (path, (char *) pb.dirInfo.ioNamePtr, DU_MAX_PATH_LEN);
725 return TRUE;
726 }
727
728 /******************************************************************************
729 * DisplayAbout.
730 ******************************************************************************/
731
DisplayAbout()732 void DisplayAbout () {
733 DialogRecord dRecord;
734 DialogPtr dialogP;
735 WindowPtr behind = (WindowPtr) -1;
736 char tempS[15+1], subIncrement;
737 long version, release, increment;
738 #ifndef __MWERKS__
739 short itemN;
740 #else
741 SInt16 itemN;
742 #endif
743 CDFlib (GET_, LIB_VERSION_, &version,
744 LIB_RELEASE_, &release,
745 LIB_INCREMENT_, &increment,
746 LIB_subINCREMENT_, &subIncrement,
747 NULL_);
748 sprintf (tempS, "V%ld.%ld.%ld%c", version, release, increment, subIncrement);
749 ParamText (CtoPstr(tempS), CtoPstr(""), CtoPstr(""), CtoPstr(""));
750 dialogP = GetNewDialog (ABOUTri, &dRecord, behind);
751 ShowWindow ((WindowPtr) dialogP);
752 ModalDialog (NULL, &itemN);
753 CloseDialog (dialogP);
754 return;
755 }
756
757 /******************************************************************************
758 * WriteOutMacSO.
759 ******************************************************************************/
760
WriteOutMacSO(text)761 void WriteOutMacSO (text)
762 char *text;
763 {
764 char *ptr = text, *ptrNL; size_t len;
765 /**************************************************************************
766 * If paging is on, first prompt for `more...' if the end of the standard
767 * output screen has been reached.
768 **************************************************************************/
769 for (;;) {
770 /***********************************************************************
771 * If the maximum number of lines have been written that will fit on
772 * the screen, then if paging prompt for RETURN before resetting the SO
773 * window, otherwise automatically reset the SO window.
774 ***********************************************************************/
775 if (soLineCount == MAX_LINES_WHEN_PAGING) {
776 if (pagingOn) {
777 char key = NUL; char savedStatusLine[SO_STATUS_LINE_LEN+1];
778 SaveStatusLine (savedStatusLine);
779 DrawStatusLine ("Enter RETURN for more...");
780 MacReadKeySO (&key);
781 if (key != '\r' && key != '\n') pagingOn = FALSE;
782 ResetSO (FALSE);
783 DrawStatusLine (savedStatusLine);
784 soLineCount = 0;
785 }
786 else
787 ResetSO (FALSE);
788 }
789 /***********************************************************************
790 * Write the string up to the next newline character. If there aren't
791 * any(more) newline characters, write the rest of the string.
792 ***********************************************************************/
793 ptrNL = strchr (ptr, Nl);
794 if (ptrNL == NULL) {
795 len = strlen (ptr);
796 if (len + (*soTextH)->teLength > MAX_TE_TEXT_LEN) MacSOoverFlow ();
797 WriteStringSO (ptr, len);
798 break;
799 }
800 else {
801 len = (int) (ptrNL - ptr + 1);
802 if (len + (*soTextH)->teLength > MAX_TE_TEXT_LEN) MacSOoverFlow ();
803 WriteStringSO (ptr, len);
804 if ((*soTextH)->teLength > MAX_TE_TEXT_LEN_wNL)
805 MacSOoverFlow ();
806 else
807 soLineCount++;
808 ptr = ptrNL + 1;
809 if (*ptr == NUL) break;
810 }
811 }
812 return;
813 }
814
815 /******************************************************************************
816 * WriteStringSO.
817 * `TEKey' is used if the string contains one or more backspace characters
818 * because `TEInsert' doesn't handle them properly. Also, all newline
819 * characters must first be converted to carriage return characters (for
820 * TextEdit). Note that because MPW C has reversed the values normally
821 * associated with '\r' and '\n', the actual numeric values must be used
822 * ('\015' and '\012', respectively).
823 ******************************************************************************/
824
WriteStringSO(string,length)825 void WriteStringSO (string, length)
826 char *string;
827 size_t length;
828 {
829 int i; char *ptr;
830 if (length > 0 && (*soTextH)->teLength == 0) {
831 EnableItem (fileMenuHso, SAVEinFILE);
832 EnableItem (fileMenuHso, SAVEASinFILE);
833 EnableItem (fileMenuHso, CLEARinFILE);
834 }
835 ptr = (char *) cdf_AllocateMemory (length + 1, FatalError);
836 strcpyX (ptr, string, length);
837 for (i = 0; ptr[i] != NUL; i++) if (ptr[i] == '\012') ptr[i] = '\015';
838 if (strchr(ptr,Bs) != NULL) {
839 for (i = 0; ptr[i] != NUL; i++) TEKey (ptr[i], soTextH);
840 }
841 else
842 TEInsert (ptr, (long) length, soTextH);
843 cdf_FreeMemory (ptr, FatalError);
844 soDestHeight = (*soTextH)->nLines * soLineHeight;
845 return;
846 }
847
848 /******************************************************************************
849 * MacSOoverFlow.
850 ******************************************************************************/
851
MacSOoverFlow()852 void MacSOoverFlow () {
853 DialogPtr dialog; DialogRecord dRecord;
854 WindowPtr behind = (WindowPtr) -1; static Rect rect0s = { 0,0,0,0 };
855 char savedStatusLine[SO_STATUS_LINE_LEN+1];
856 #ifndef __MWERKS__
857 short itemN;
858 #else
859 SInt16 itemN;
860 UserItemUPP OutlineDefaultButtonUPP;
861 OutlineDefaultButtonUPP = NewUserItemProc (OutlineDefaultButton);
862 #endif
863 SaveStatusLine (savedStatusLine);
864 DrawStatusLine ("");
865 dialog = GetNewDialog (SOOFLOWri, &dRecord, behind);
866 #ifndef __MWERKS__
867 SetDItem (dialog, (short) ODBinOFLOW, (short) userItem,
868 (Handle) OutlineDefaultButton, &rect0s);
869 #else
870 SetDItem (dialog, (short) ODBinOFLOW, (short) userItem,
871 (Handle) OutlineDefaultButtonUPP, &rect0s);
872 #endif
873 HideControl (soVscrollH);
874 TEDeactivate (soTextH);
875 ShowWindow ((WindowPtr) dialog);
876 SetCursor (ARROW_CURSOR);
877 ModalDialog (NULL, &itemN);
878 CloseDialog (dialog);
879 TEActivate (soTextH);
880 ShowControl (soVscrollH);
881 switch (itemN) {
882 case SAVEinOFLOW:
883 SaveSO (FALSE);
884 break;
885 case SAVEASinOFLOW:
886 SaveSO (TRUE);
887 break;
888 case CLEARinOFLOW:
889 break;
890 case ABORTinOFLOW:
891 Exit;
892 }
893 ResetSO (TRUE);
894 DrawStatusLine (savedStatusLine);
895 }
896
897 /******************************************************************************
898 * MacReadKeySO.
899 * Read a character from the keyboard. This routine should only be used in
900 * `standard output' programs.
901 ******************************************************************************/
902
MacReadKeySO(key)903 void MacReadKeySO (key)
904 char *key;
905 {
906 EventRecord event;
907 for (;;) {
908 SystemTask ();
909 TEIdle (soTextH);
910 GetNextEvent(everyEvent,&event);
911 switch (event.what) {
912 /*********************************************************************
913 * Null event.
914 *********************************************************************/
915 case nullEvent:
916 UpdateCursorSO (&event);
917 break;
918 /*********************************************************************
919 * Key down event.
920 *********************************************************************/
921 case keyDown: {
922 if (ABORTkeyMAC(event)) {
923 cdf_FreeMemory (NULL, FatalError);
924 Exit;
925 }
926 *key = (char) (event.message & charCodeMask);
927 return;
928 }
929 /*********************************************************************
930 * Check for an activation event (activate or deactivate).
931 *********************************************************************/
932 case activateEvt:
933 if ((event.modifiers & activeFlag) != 0) {
934 TEActivate (soTextH);
935 ShowControl (soVscrollH);
936 SetCursor (CDF_CURSOR);
937 }
938 else {
939 TEDeactivate (soTextH);
940 HideControl (soVscrollH);
941 }
942 break;
943 /*********************************************************************
944 * Check for an update event for a window.
945 *********************************************************************/
946 case updateEvt: {
947 BeginUpdate ((WindowPtr) event.message);
948 EraseRect (&soTextRect);
949 TEUpdate (&soTextRect, soTextH);
950 DrawControls (soWindowP);
951 DrawStatusLine (NULL);
952 EndUpdate ((WindowPtr) event.message);
953 break;
954 }
955 }
956 }
957 }
958
959 /******************************************************************************
960 * CheckForAbortSOmac.
961 ******************************************************************************/
962
CheckForAbortSOmac()963 void CheckForAbortSOmac () {
964 EventRecord event; clock_t currentClock, totalClock;
965 int hour, minute, second; char text[SO_STATUS_LINE_LEN+1];
966 SystemTask ();
967 TEIdle (soTextH);
968 GetNextEvent (everyEvent, &event);
969 switch (event.what) {
970 case nullEvent:
971 break;
972 case mouseDown: {
973 WindowPtr whichWindow;
974 switch (FindWindow(event.where,&whichWindow)) {
975 case inMenuBar:
976 break;
977 case inDrag: {
978 RectPtr screen = &qd.screenBits.bounds; Rect dragRect;
979 dragRect.top = screen->top + 40;
980 dragRect.left = screen->left + 40;
981 dragRect.bottom = screen->bottom - 40;
982 dragRect.right = screen->right - 40;
983 DragWindow (whichWindow, event.where, &dragRect);
984 break;
985 }
986 case inSysWindow:
987 SystemClick (&event, whichWindow);
988 break;
989 case inContent:
990 break;
991 }
992 }
993 case keyDown:
994 if (ABORTkeyMAC(event)) {
995 cdf_FreeMemory (NULL, FatalError);
996 Exit;
997 }
998 break;
999 case activateEvt:
1000 if ((event.modifiers & activeFlag) != 0) {
1001 TEActivate (soTextH);
1002 ShowControl (soVscrollH);
1003 SetCursor (CDF_CURSOR);
1004 }
1005 else {
1006 TEDeactivate (soTextH);
1007 HideControl (soVscrollH);
1008 }
1009 break;
1010 case updateEvt:
1011 BeginUpdate ((WindowPtr) event.message);
1012 EraseRect (&soTextRect);
1013 TEUpdate (&soTextRect, soTextH);
1014 DrawControls (soWindowP);
1015 DrawStatusLine (NULL);
1016 EndUpdate ((WindowPtr) event.message);
1017 break;
1018 }
1019 currentClock = clock ();
1020 totalClock = currentClock - startClock;
1021 second = (totalClock / CLOCKS_PER_SEC) % 60;
1022 if (second != lastSecond) {
1023 hour = (totalClock / CLOCKS_PER_SEC) / 3600;
1024 minute = (totalClock / CLOCKS_PER_SEC) / 60;
1025 strcpyX (text, "Executing...", 0);
1026 CatNcharacters (text, 46, (int) ' ');
1027 sprintf (EofS(text), "Elapsed time: %02d:%02d:%02d.00",
1028 hour, minute, second);
1029 DrawStatusLine (text);
1030 lastSecond = second;
1031 UpdateCursorSO (&event);
1032 }
1033 return;
1034 }
1035
1036 /******************************************************************************
1037 * OutlineDefaultButton.
1038 ******************************************************************************/
1039 #ifndef __MWERKS__
OutlineDefaultButton(window,itemN)1040 pascal void OutlineDefaultButton (window, itemN)
1041 DialogPtr window;
1042 short itemN;
1043 #else
1044 pascal void OutlineDefaultButton (DialogPtr window, SInt16 itemN)
1045 #endif
1046 {
1047 short itemType; Handle handle; Rect rect;
1048 itemN = 1; /* Set to default button's item number. */
1049 GetDItem ((DialogPtr) window, itemN, &itemType, &handle, &rect);
1050 PenSize ((short) 3, (short) 3);
1051 InsetRect (&rect, (short) -4, (short) -4);
1052 FrameRoundRect (&rect, (short) 22, (short) 22);
1053 PenNormal ();
1054 return;
1055 }
1056
1057 /******************************************************************************
1058 * FilterForSKTs.
1059 ******************************************************************************/
1060
FilterForSKTs(pb)1061 pascal Boolean FilterForSKTs (pb)
1062 ParmBlkPtr pb;
1063 {
1064 char *name = PtoCstr (pb->fileParam.ioNamePtr);
1065 Boolean filterOut = (!Trailer(name,".skt") && !Trailer(name,".SKT") &&
1066 !Trailer(name,".skt;1") && !Trailer(name,".SKT;1"));
1067 CtoPstr (name);
1068 return filterOut;
1069 }
1070
1071 /******************************************************************************
1072 * FilterForCDFs.
1073 ******************************************************************************/
1074
FilterForCDFs(pb)1075 pascal Boolean FilterForCDFs (pb)
1076 ParmBlkPtr pb;
1077 {
1078 char *name = PtoCstr (pb->fileParam.ioNamePtr);
1079 Boolean filterOut = (!Trailer(name,".cdf") && !Trailer(name,".CDF") &&
1080 !Trailer(name,".cdf;1") && !Trailer(name,".CDF;1"));
1081 CtoPstr (name);
1082 return filterOut;
1083 }
1084
1085 /******************************************************************************
1086 * FilterDialogQOPfsi.
1087 ******************************************************************************/
FilterDialogQOPfsi(dialog,event,itemN)1088 pascal Boolean FilterDialogQOPfsi (dialog, event, itemN)
1089 DialogPtr dialog;
1090 EventRecord *event;
1091 #ifndef __MWERKS__
1092 short *itemN;
1093 #else
1094 SInt16 *itemN;
1095 #endif
1096 {
1097 switch (event->what) {
1098 case keyDown: {
1099 char chr = (char) (event->message & charCodeMask);
1100 if ((event->modifiers & cmdKey) != 0) {
1101 if ('a' <= chr && chr <= 'z') chr ^= 0x60;
1102 }
1103 if (chr == (char) KB_RETURN) {
1104 FlashButton (dialog, OKin);
1105 *itemN = OKin;
1106 return TRUE;
1107 }
1108 if (chr == (char) EXITkey_FSI) {
1109 FlashButton (dialog, CANCELin);
1110 *itemN = CANCELin;
1111 return TRUE;
1112 }
1113 break;
1114 }
1115 }
1116 return FALSE;
1117 }
1118
1119 /******************************************************************************
1120 * FilterDialogQOPso.
1121 ******************************************************************************/
1122
FilterDialogQOPso(dialog,event,itemN)1123 pascal Boolean FilterDialogQOPso (dialog, event, itemN)
1124 DialogPtr dialog;
1125 EventRecord *event;
1126 #ifndef __MWERKS__
1127 short *itemN;
1128 #else
1129 SInt16 *itemN;
1130 #endif
1131 {
1132 switch (event->what) {
1133 case keyDown: {
1134 char key = (char) ((event->message & keyCodeMask) >> 8);
1135 if (key == RETURN_KEYCODE) {
1136 FlashButton (dialog, OKin);
1137 *itemN = OKin;
1138 return TRUE;
1139 }
1140 if ((event->modifiers & cmdKey) != 0 && key == Q_KEYCODE) {
1141 FlashButton (dialog, CANCELin);
1142 *itemN = CANCELin;
1143 return TRUE;
1144 }
1145 break;
1146 }
1147 }
1148 return FALSE;
1149 }
1150
1151 /******************************************************************************
1152 * FlashButton.
1153 ******************************************************************************/
1154
FlashButton(dialog,itemN)1155 static void FlashButton (dialog, itemN)
1156 DialogPtr dialog;
1157 int itemN;
1158 {
1159 short itemType, ovalWH = 15; Handle handle; Rect rect; GrafPtr currentPort;
1160 GetDItem (dialog, (short) itemN, &itemType, &handle, &rect);
1161 GetPort (¤tPort);
1162 SetPort ((GrafPtr) dialog);
1163 InvertRoundRect (&rect, ovalWH, ovalWH);
1164 FrameRoundRect (&rect, ovalWH, ovalWH);
1165 delay (0.1);
1166 InvertRoundRect (&rect, ovalWH, ovalWH);
1167 FrameRoundRect (&rect, ovalWH, ovalWH);
1168 delay (0.1);
1169 SetPort (currentPort);
1170 return;
1171 }
1172
1173 /******************************************************************************
1174 * delay.
1175 ******************************************************************************/
1176
delay(seconds)1177 static void delay (seconds)
1178 double seconds;
1179 {
1180 EventRecord event; long untilTick; short nullEventMask = 0;
1181 EventAvail (nullEventMask, &event);
1182 untilTick = event.when + (long) (seconds * 60);
1183 for (;;) {
1184 EventAvail (nullEventMask, &event);
1185 if (event.when > untilTick) break;
1186 }
1187 return;
1188 }
1189