this repo has no description
1/*
2 OSGLUMAC.c
3
4 Copyright (C) 2009 Philip Cummins, Richard F. Bannister,
5 Paul C. Pratt
6
7 You can redistribute this file and/or modify it under the terms
8 of version 2 of the GNU General Public License as published by
9 the Free Software Foundation. You should have received a copy
10 of the license along with this file; see the file COPYING.
11
12 This file is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 license for more details.
16*/
17
18/*
19 Operating System GLUe for MACintosh
20
21 All operating system dependent code for the
22 Macintosh (pre OS X) platform should go here.
23
24 This code is descended from Richard F. Bannister's Macintosh
25 port of vMac, by Philip Cummins.
26*/
27
28#include "OSGCOMUI.h"
29#include "OSGCOMUD.h"
30
31#ifdef WantOSGLUMAC
32
33#ifndef NavigationAvail
34#define NavigationAvail 1
35#endif
36
37#ifndef AppearanceAvail
38#define AppearanceAvail 1
39#endif
40
41#ifndef NewNamesAvail
42#define NewNamesAvail 1
43#endif
44
45#ifndef CALL_NOT_IN_CARBON
46#define CALL_NOT_IN_CARBON 1
47#endif /* !defined(CALL_NOT_IN_CARBON) */
48
49
50/* --- information about the environment --- */
51
52/*
53 code to determine characteristics
54 of the current run time environment.
55*/
56
57#define TestBit(i, p) (((uimr)(i) & ((uimr)1 << (p))) != 0)
58
59#ifndef HaveCPUfamM68K
60#define HaveCPUfamM68K 0
61#endif
62
63#if HaveCPUfamM68K
64
65/* MACENVRN.i */
66
67#ifndef Support64kROM
68#define Support64kROM 1
69#endif
70
71#define Have64kROM() (LMGetROM85() < 0)
72
73/* -- basic environment checking -- */
74
75#ifndef DebugTrapAvailableChecks
76#define DebugTrapAvailableChecks 0
77#endif
78
79LOCALFUNC blnr LowToolTrapAvailable(short trap_num)
80{
81#if DebugTrapAvailableChecks
82 if ((trap_num & 0x0800) == 0) {
83 DebugStr("\pOSTrap in LowToolTrapAvailable");
84 return falseblnr;
85 }
86 if ((trap_num & 0x07ff) >= 0x200) {
87 DebugStr("\pHiToolTrap in LowToolTrapAvailable");
88 return falseblnr;
89 }
90#endif
91 return GetToolTrapAddress(trap_num) !=
92 GetToolTrapAddress(_Unimplemented);
93}
94
95LOCALFUNC blnr HiToolTrapAvailable(short trap_num)
96{
97#if DebugTrapAvailableChecks
98 if ((trap_num & 0x0800) == 0) {
99 DebugStr("\pOSTrap in HiToolTrapAvailable");
100 return falseblnr;
101 }
102 if (((trap_num & 0x07ff) < 0x200)
103 || ((trap_num & 0x07ff) >= 0x400))
104 {
105 DebugStr("\pLowToolTrap in HiToolTrapAvailable");
106 return falseblnr;
107 }
108#endif
109 if (GetToolTrapAddress(_InitGraf)
110 == GetToolTrapAddress(0xAA6E))
111 {
112 return falseblnr;
113 } else {
114 return GetToolTrapAddress(trap_num) !=
115 GetToolTrapAddress(_Unimplemented);
116 }
117}
118
119LOCALFUNC blnr OSTrapAvailable(short trap_num)
120{
121#if DebugTrapAvailableChecks
122 if ((trap_num & 0x0800) != 0) {
123 DebugStr("\pToolTrap in ToolTrapAvailable");
124 return falseblnr;
125 }
126#endif
127 return GetOSTrapAddress(trap_num) !=
128 GetToolTrapAddress(_Unimplemented);
129}
130
131LOCALVAR blnr MyEnvrAttrWaitNextEventAvail;
132LOCALVAR blnr HaveEnvrAttrWaitNextEventAvail = falseblnr;
133
134LOCALFUNC blnr HaveWaitNextEventAvail(void)
135{
136 if (! HaveEnvrAttrWaitNextEventAvail) {
137 MyEnvrAttrWaitNextEventAvail =
138 LowToolTrapAvailable(_WaitNextEvent);
139 HaveEnvrAttrWaitNextEventAvail = trueblnr;
140 }
141 return MyEnvrAttrWaitNextEventAvail;
142}
143
144LOCALVAR blnr MyEnvrAttrGestaltAvail;
145LOCALVAR blnr HaveEnvrAttrGestaltAvail = falseblnr;
146
147LOCALFUNC blnr HaveGestaltAvail(void)
148{
149 if (! HaveEnvrAttrGestaltAvail) {
150 MyEnvrAttrGestaltAvail =
151 (! Have64kROM()) &&
152 OSTrapAvailable(_Gestalt);
153 /*
154 contrary to all the documentation,
155 TrapAvailable check by itself doesn't
156 work on 64k ROM, because a tool box trap
157 has the same trap number, and both
158 GetOSTrapAddress and GetToolTrapAddress
159 are the same as GetTrapAddress on a 64k ROM.
160 */
161 HaveEnvrAttrGestaltAvail = trueblnr;
162 }
163 return MyEnvrAttrGestaltAvail;
164}
165
166#else
167
168/* for PowerPC, assume always have these routines */
169
170#define HaveWaitNextEventAvail() trueblnr
171#define HaveGestaltAvail() trueblnr
172
173#endif
174
175LOCALVAR blnr MyEnvrAttrAliasMgrAvail;
176LOCALVAR blnr HaveEnvrAttrAliasMgrAvail = falseblnr;
177
178LOCALFUNC blnr HaveAliasMgrAvail(void)
179{
180 if (! HaveEnvrAttrAliasMgrAvail) {
181 long reply;
182
183 MyEnvrAttrAliasMgrAvail =
184 HaveGestaltAvail()
185 && (noErr == Gestalt(gestaltAliasMgrAttr, &reply))
186 && TestBit(reply, gestaltAliasMgrPresent);
187 HaveEnvrAttrAliasMgrAvail = trueblnr;
188 }
189 return MyEnvrAttrAliasMgrAvail;
190}
191
192LOCALVAR blnr MyEnvrAttrAppleEvtMgrAvail;
193LOCALVAR blnr HaveEnvrAttrAppleEvtMgrAvail = falseblnr;
194
195LOCALFUNC blnr HaveAppleEvtMgrAvail(void)
196{
197 if (! HaveEnvrAttrAppleEvtMgrAvail) {
198 long reply;
199
200 MyEnvrAttrAppleEvtMgrAvail =
201 HaveGestaltAvail()
202 && (noErr == Gestalt(gestaltAppleEventsAttr, &reply))
203 && TestBit(reply, gestaltAppleEventsPresent);
204 HaveEnvrAttrAppleEvtMgrAvail = trueblnr;
205 }
206 return MyEnvrAttrAppleEvtMgrAvail;
207}
208
209#if EnableDragDrop
210
211LOCALVAR blnr MyEnvrAttrDragMgrAvail;
212LOCALVAR blnr HaveEnvrAttrDragMgrAvail = falseblnr;
213
214LOCALFUNC blnr HaveDragMgrAvail(void)
215{
216 if (! HaveEnvrAttrDragMgrAvail) {
217 long reply;
218
219 MyEnvrAttrDragMgrAvail =
220 HaveGestaltAvail()
221 && (noErr == Gestalt(gestaltDragMgrAttr, &reply))
222 && TestBit(reply, gestaltDragMgrPresent);
223 HaveEnvrAttrDragMgrAvail = trueblnr;
224 }
225 return MyEnvrAttrDragMgrAvail;
226}
227
228#endif
229
230#ifndef Windows85APIAvail
231#define Windows85APIAvail 1
232#endif
233
234#if Windows85APIAvail
235LOCALVAR blnr MyEnvrAttrHideShowMenuAvail;
236LOCALVAR blnr HaveEnvrAttrHideShowMenuAvail = falseblnr;
237
238LOCALFUNC blnr HaveHideShowMenuAvail(void)
239{
240 if (! HaveEnvrAttrHideShowMenuAvail) {
241 long reply;
242
243 MyEnvrAttrHideShowMenuAvail =
244 HaveGestaltAvail()
245 && (noErr == Gestalt(gestaltMenuMgrAttr, &reply));
246 HaveEnvrAttrHideShowMenuAvail = trueblnr;
247 }
248 return MyEnvrAttrHideShowMenuAvail;
249}
250#endif
251
252#if AppearanceAvail
253LOCALVAR blnr MyEnvrAttrAppearanceAvail;
254LOCALVAR blnr HaveEnvrAttrAppearanceAvail = falseblnr;
255
256LOCALFUNC blnr HaveAppearanceAvail(void)
257{
258 if (! HaveEnvrAttrAppearanceAvail) {
259 long reply;
260
261 MyEnvrAttrAppearanceAvail =
262 HaveGestaltAvail()
263 && (noErr == Gestalt(gestaltAppearanceAttr, &reply));
264 HaveEnvrAttrAppearanceAvail = trueblnr;
265 }
266 return MyEnvrAttrAppearanceAvail;
267}
268#endif
269
270#if HaveCPUfamM68K
271LOCALVAR blnr MyEnvrAttrSndMngrAvail;
272LOCALVAR blnr HaveEnvrAttrSndMngrAvail = falseblnr;
273
274LOCALFUNC blnr HaveSndMngrAvail(void)
275{
276 if (! HaveEnvrAttrSndMngrAvail) {
277 MyEnvrAttrSndMngrAvail = LowToolTrapAvailable(_SndNewChannel);
278 HaveEnvrAttrSndMngrAvail = trueblnr;
279 }
280 return MyEnvrAttrSndMngrAvail;
281}
282#endif
283
284#if NavigationAvail
285LOCALVAR blnr MyEnvrAttrNavServicesAvail;
286LOCALVAR blnr HaveEnvrAttrNavServicesAvail = falseblnr;
287
288LOCALFUNC blnr HaveNavServicesAvail(void)
289{
290 if (! HaveEnvrAttrNavServicesAvail) {
291 MyEnvrAttrNavServicesAvail = NavServicesAvailable();
292 HaveEnvrAttrNavServicesAvail = trueblnr;
293 }
294 return MyEnvrAttrNavServicesAvail;
295}
296#endif
297
298#if HaveCPUfamM68K
299LOCALVAR blnr MyEnvrAttrFSSpecCallsAvail;
300LOCALVAR blnr HaveEnvrAttrFSSpecCallsAvail = falseblnr;
301
302LOCALFUNC blnr HaveFSSpecCallsAvail(void)
303{
304 if (! HaveEnvrAttrFSSpecCallsAvail) {
305 long reply;
306
307 MyEnvrAttrFSSpecCallsAvail =
308 HaveGestaltAvail()
309 && (noErr == Gestalt(gestaltFSAttr, &reply))
310 && TestBit(reply, gestaltHasFSSpecCalls);
311 HaveEnvrAttrFSSpecCallsAvail = trueblnr;
312 }
313 return MyEnvrAttrFSSpecCallsAvail;
314}
315#endif
316
317#if Windows85APIAvail
318LOCALVAR blnr MyEnvrAttrNewWndMgrAvail;
319LOCALVAR blnr HaveEnvrAttrNewWndMgrAvail = falseblnr;
320
321LOCALFUNC blnr HaveNewWndMgrAvail(void)
322{
323 if (! HaveEnvrAttrNewWndMgrAvail) {
324 long reply;
325
326 MyEnvrAttrNewWndMgrAvail =
327 HaveGestaltAvail()
328 && (noErr == Gestalt(gestaltWindowMgrAttr, &reply))
329 && TestBit(reply, gestaltWindowMgrPresentBit);
330 HaveEnvrAttrNewWndMgrAvail = trueblnr;
331 }
332 return MyEnvrAttrNewWndMgrAvail;
333}
334#endif
335
336/* --- initial initialization --- */
337
338#if defined(__SC__) || ((defined(powerc) || defined(__powerc)) \
339 && ! defined(__MWERKS__))
340
341/* GLOBALVAR */ QDGlobals qd;
342#endif
343
344LOCALFUNC blnr InitMacManagers(void)
345{
346 MaxApplZone();
347
348 {
349 int i;
350
351 for (i = 7; --i >= 0; ) {
352 MoreMasters();
353 }
354 }
355
356 InitGraf(&qd.thePort);
357 InitFonts();
358 InitWindows();
359 InitMenus();
360 TEInit();
361 InitDialogs(NULL);
362 InitCursor();
363 return trueblnr;
364}
365
366
367/* --- mac style errors --- */
368
369#define CheckSavetMacErr(result) (mnvm_noErr == (err = (result)))
370 /*
371 where 'err' is a variable of type tMacErr in the function
372 this is used in
373 */
374
375#define To_tMacErr(result) ((tMacErr)(ui4b)(result))
376
377#define CheckSaveMacErr(result) (CheckSavetMacErr(To_tMacErr(result)))
378
379
380#define NotAfileRef (-1)
381
382struct MyDir_R {
383 long DirId;
384 short VRefNum;
385};
386typedef struct MyDir_R MyDir_R;
387
388LOCALFUNC tMacErr OpenNamedFileInFolder(MyDir_R *d,
389 ps3p fileName, short *refnum)
390{
391 tMacErr err;
392
393#if HaveCPUfamM68K
394 if (! HaveFSSpecCallsAvail()) {
395 err = To_tMacErr(FSOpen(fileName, d->VRefNum, refnum));
396 } else
397#endif
398 {
399 Boolean isFolder;
400 Boolean isAlias;
401 FSSpec spec;
402
403 if (CheckSaveMacErr(
404 FSMakeFSSpec(d->VRefNum, d->DirId, fileName, &spec)))
405 if (CheckSaveMacErr(
406 ResolveAliasFile(&spec, trueblnr, &isFolder, &isAlias)))
407 if (CheckSaveMacErr(
408 FSpOpenDF(&spec, fsRdPerm, refnum)))
409 {
410 }
411 }
412
413 return err;
414}
415
416/* --- sending debugging info to file --- */
417
418#if dbglog_HAVE
419
420#define Support64kROM 0
421#define tMyErr tMacErr
422
423typedef unsigned char * MyPtr;
424
425LOCALFUNC tMyErr MyHGetDir_v2(MyDir_R *d)
426{
427 tMyErr err;
428 WDPBRec r;
429
430 r.ioCompletion = NULL;
431 r.ioNamePtr = NULL;
432
433#if Support64kROM
434 if (Have64kROM()) {
435 err = PBGetVolSync((ParamBlockRec *)&r);
436 d->VRefNum = r.ioVRefNum;
437 d->DirId = 0;
438 } else
439#endif
440 {
441 err = PBHGetVolSync(&r);
442 d->VRefNum = r.ioWDVRefNum;
443 d->DirId = r.ioWDDirID;
444 }
445
446 return err;
447}
448
449LOCALFUNC tMyErr MyWriteBytes_v2(short refNum, MyPtr p, uimr L)
450{
451 ParamBlockRec r;
452
453 r.ioParam.ioCompletion = NULL;
454 r.ioParam.ioRefNum = refNum;
455 r.ioParam.ioBuffer = (Ptr)p;
456 r.ioParam.ioReqCount = L;
457 r.ioParam.ioPosMode = (short) fsFromMark;
458 r.ioParam.ioPosOffset = 0;
459
460 return PBWriteSync(&r);
461}
462
463LOCALFUNC tMyErr MyCloseFile_v2(short refNum)
464{
465 ParamBlockRec r;
466
467 r.ioParam.ioCompletion = NULL;
468 r.ioParam.ioRefNum = refNum;
469
470 return PBCloseSync(&r);
471#if 0
472 return (tMyErr)FSClose(refNum);
473#endif
474}
475
476#define NotAfileRef (-1)
477
478/*
479 Probably should use PBHOpenDF instead
480 of PBHOpen when it is available.
481 (System 7 according to Technical Note FL515)
482*/
483
484LOCALFUNC tMyErr MyFileOpen_v2(MyDir_R *d, StringPtr s,
485 char Permssn, short *refnum)
486{
487 tMyErr err;
488 HParamBlockRec r;
489
490 r.ioParam.ioCompletion = NULL;
491 r.ioParam.ioNamePtr = s;
492 r.ioParam.ioVRefNum = d->VRefNum;
493 r.ioParam.ioPermssn = Permssn;
494 r.ioParam.ioMisc = 0; /* use volume buffer */
495 r.ioParam.ioVersNum = 0; /* needed if MFS volume */
496
497#if Support64kROM
498 if (Have64kROM()) {
499 err = PBOpenSync((ParamBlockRec *)&r);
500 } else
501#endif
502 {
503 r.fileParam.ioDirID = d->DirId;
504 err = PBHOpenSync(&r);
505 }
506
507 if (noErr == err) {
508 *refnum = r.ioParam.ioRefNum;
509 /*
510 Don't change *refnum unless file opened,
511 so can initialize to NotAfileRef, and
512 compare later before closing in uninit.
513 */
514 }
515 return err;
516}
517
518LOCALFUNC tMyErr MyFileOpenWrite_v2(MyDir_R *d, StringPtr s,
519 short *refnum)
520{
521 return MyFileOpen_v2(d, s, (char)fsWrPerm, refnum);
522}
523
524LOCALFUNC tMyErr MyDeleteFile_v2(MyDir_R *d, StringPtr s)
525{
526 tMyErr err;
527 HParamBlockRec r;
528
529 r.fileParam.ioCompletion = NULL;
530 r.fileParam.ioVRefNum = d->VRefNum;
531 r.fileParam.ioNamePtr = s;
532 r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
533
534#if Support64kROM
535 if (Have64kROM()) {
536 err = PBDeleteSync((ParamBlockRec *)&r);
537 } else
538#endif
539 {
540 r.fileParam.ioDirID = d->DirId;
541 err = PBHDeleteSync(&r);
542 }
543
544 return err;
545}
546
547LOCALFUNC tMyErr MyCreateFile_v2(MyDir_R *d, StringPtr s)
548{
549 tMyErr err;
550 HParamBlockRec r;
551
552 r.fileParam.ioFlVersNum = 0;
553 /*
554 Think reference says to do this,
555 but not Inside Mac IV
556 */
557
558 r.fileParam.ioCompletion = NULL;
559 r.fileParam.ioNamePtr = s;
560 r.fileParam.ioVRefNum = d->VRefNum;
561 r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
562
563#if Support64kROM
564 if (Have64kROM()) {
565 err = PBCreateSync((ParamBlockRec *)&r);
566 } else
567#endif
568 {
569 r.fileParam.ioDirID = d->DirId;
570 err = PBHCreateSync(&r);
571 }
572
573 return err;
574}
575
576LOCALFUNC tMyErr MyFileGetInfo_v2(MyDir_R *d, StringPtr s,
577 HParamBlockRec *r)
578{
579 tMyErr err;
580
581 r->fileParam.ioCompletion = NULL;
582 r->fileParam.ioNamePtr = s;
583 r->fileParam.ioVRefNum = d->VRefNum;
584 r->fileParam.ioFVersNum = (char)0; /* needed if MFS volume */
585 r->fileParam.ioFDirIndex = (short)0;
586
587#if Support64kROM
588 if (Have64kROM()) {
589 err = PBGetFInfoSync((ParamBlockRec *)r);
590 } else
591#endif
592 {
593 r->fileParam.ioDirID = d->DirId;
594 err = PBHGetFInfoSync(r);
595 }
596
597 return err;
598}
599
600LOCALFUNC tMyErr MyFileSetInfo_v2(MyDir_R *d, StringPtr s,
601 HParamBlockRec *r)
602{
603 tMyErr err;
604
605 r->fileParam.ioCompletion = NULL;
606 r->fileParam.ioNamePtr = s;
607 r->fileParam.ioVRefNum = d->VRefNum;
608 r->fileParam.ioFVersNum = (char)0; /* needed if MFS volume */
609
610#if Support64kROM
611 if (Have64kROM()) {
612 err = PBSetFInfoSync((ParamBlockRec *)r);
613 } else
614#endif
615 {
616 r->fileParam.ioDirID = d->DirId;
617 err = PBHSetFInfoSync(r);
618 }
619
620 return err;
621}
622
623LOCALFUNC tMyErr MyFileSetTypeCreator_v2(MyDir_R *d, StringPtr s,
624 OSType creator, OSType fileType)
625{
626 tMyErr err;
627 HParamBlockRec r;
628
629 if (noErr == (err = MyFileGetInfo_v2(d, s, &r))) {
630 r.fileParam.ioFlFndrInfo.fdType = fileType;
631 r.fileParam.ioFlFndrInfo.fdCreator = creator;
632 err = MyFileSetInfo_v2(d, s, &r);
633 }
634
635 return err;
636}
637
638LOCALFUNC tMyErr MyCreateFileOverWrite_v2(MyDir_R *d, StringPtr s)
639{
640 tMyErr err;
641
642 err = MyCreateFile_v2(d, s);
643 if (dupFNErr == err) {
644 if (noErr == (err = MyDeleteFile_v2(d, s))) {
645 err = MyCreateFile_v2(d, s);
646 }
647 }
648
649 return err;
650}
651
652LOCALFUNC tMyErr MyOpenNewFile_v3(MyDir_R *d, StringPtr s,
653 OSType creator, OSType fileType,
654 short *refnum)
655/*
656 Deletes old file if already exists.
657*/
658{
659 tMyErr err;
660
661 err = MyCreateFileOverWrite_v2(d, s);
662 if (noErr == err) {
663 err = MyFileSetTypeCreator_v2(d, s,
664 creator, fileType);
665 if (noErr == err) {
666 err = MyFileOpenWrite_v2(d, s, refnum);
667 }
668
669 if (noErr != err) {
670 (void) MyDeleteFile_v2(d, s);
671 /* ignore any error, since already got one */
672 }
673 }
674
675 return err;
676}
677
678
679LOCALVAR short dbglog_File = NotAfileRef;
680LOCALVAR tMyErr dbglog_err = noErr;
681
682LOCALFUNC blnr dbglog_open0(void)
683{
684 tMacErr err;
685 MyDir_R d;
686
687 if (noErr == (err = MyHGetDir_v2(&d))) {
688 err = MyFileOpen_v2(&d, (StringPtr)"\pdbglog",
689 (char)fsWrPerm, &dbglog_File);
690 if (mnvm_noErr /* fnfErr */ == err) {
691 err = SetEOF(dbglog_File, 0);
692 } else {
693 err = MyOpenNewFile_v3(&d, (StringPtr)"\pdbglog",
694 'MPS ', 'TEXT', &dbglog_File);
695 err = mnvm_noErr;
696 }
697
698 }
699
700 return (mnvm_noErr == err);
701}
702
703LOCALPROC dbglog_write0(char *s, uimr L)
704{
705 if (NotAfileRef != dbglog_File)
706 if (noErr == dbglog_err)
707 {
708 dbglog_err = MyWriteBytes_v2(dbglog_File, (MyPtr)s, L);
709 }
710}
711
712LOCALPROC dbglog_close0(void)
713{
714 if (NotAfileRef != dbglog_File) {
715 (void) MyCloseFile_v2(dbglog_File);
716 dbglog_File = NotAfileRef;
717 }
718}
719
720#endif /* dbglog_HAVE */
721
722
723/* --- control mode and internationalization --- */
724
725#define NeedCell2MacAsciiMap 1
726
727#define WantColorTransValid 1
728#define NeedRequestInsertDisk 1
729#define NeedDoMoreCommandsMsg 1
730#define NeedDoAboutMsg 1
731
732#include "INTLCHAR.h"
733
734#include "COMOSGLU.h"
735
736#define WantKeyboard_RemapMac 1
737
738#include "CONTROLM.h"
739
740/* --- some simple utilities --- */
741
742GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
743{
744 BlockMove((Ptr)srcPtr, (Ptr)destPtr, byteCount);
745}
746
747/* don't want to include c libraries, so: */
748LOCALFUNC si5b CStrLen(char *src)
749{
750 char *p = src;
751 while (*p++ != 0) {
752 }
753 return ((si5b)p) - ((si5b)src) - 1;
754}
755
756#define PStrMaxLength 255
757
758LOCALPROC PStrFromCStr(ps3p r, /* CONST */ char *s)
759{
760 unsigned short L;
761
762 L = CStrLen(s);
763 if (L > PStrMaxLength) {
764 L = PStrMaxLength;
765 }
766 *r++ = L;
767 MyMoveBytes((anyp)s, (anyp)r, L);
768}
769
770LOCALPROC PStrFromChar(ps3p r, char x)
771{
772 r[0] = 1;
773 r[1] = (char)x;
774}
775
776LOCALPROC PStrFromHandle(ps3p r, Handle h, ui5b MaxL)
777{
778 ui5b L = GetHandleSize(h);
779
780 if (L > MaxL) {
781 L = MaxL;
782 }
783
784 *r++ = L;
785 BlockMove(*h, (Ptr)r, L);
786}
787
788LOCALFUNC tMacErr PStrToHand(ps3p s, Handle *r)
789{
790 return To_tMacErr(PtrToHand((Ptr)(s + 1), r, s[0]));
791}
792
793/* --- utilities for adapting to the environment --- */
794
795#ifndef MightNotHaveAppearanceMgrAvail
796#define MightNotHaveAppearanceMgrAvail 1
797#endif
798
799#ifndef MightNotHaveWindows85Avail
800#define MightNotHaveWindows85Avail MightNotHaveAppearanceMgrAvail
801#endif
802
803#ifndef LowMemAPIAvail
804#define LowMemAPIAvail 1
805#endif
806
807#ifndef My_LMGetTime
808#if LowMemAPIAvail
809#define My_LMGetTime LMGetTime
810#else
811#define My_LMGetTime() (*(SInt32 *)(0x020C))
812#endif
813#endif
814
815#ifndef My_LMGetMBarHeight
816#if LowMemAPIAvail
817#define My_LMGetMBarHeight LMGetMBarHeight
818#else
819#define My_LMGetMBarHeight() (*(short *)(0x0BAA))
820#endif
821#endif
822
823#ifndef My_GetGrayRgn
824#if /* LowMemAPIAvail */ 0
825#define My_GetGrayRgn LMGetGrayRgn
826#else
827#define My_GetGrayRgn() (*(RgnHandle *)(0x9EE))
828#endif
829#endif
830
831#ifndef My_LMGetCurApName
832#if LowMemAPIAvail
833#define My_LMGetCurApName LMGetCurApName
834#else
835#define My_LMGetCurApName() ((StringPtr) 0x0910)
836#endif
837#endif
838
839#define MyGetScreenBitsBounds(r) (*r) = qd.screenBits.bounds
840
841#define My_GetRegionBounds(region, bounds) *(bounds) = \
842 (**(region)).rgnBBox
843
844#define My_GetPortPixMap(p) ((p)->portPixMap)
845
846#ifndef My_WindowRef
847#if NewNamesAvail
848#define My_WindowRef WindowRef
849#else
850#define My_WindowRef WindowPtr
851#endif
852#endif
853
854#define My_SetPortWindowPort(w) SetPort(w)
855
856LOCALPROC My_InvalWindowRect(My_WindowRef mw, Rect *r)
857{
858 GrafPtr SavePort;
859
860 GetPort(&SavePort);
861 My_SetPortWindowPort(mw);
862 InvalRect(r);
863 SetPort(SavePort);
864}
865
866#define My_GetWindowPortBounds(w, r) *(r) = ((w)->portRect)
867
868LOCALPROC InvalWholeWindow(My_WindowRef mw)
869{
870 Rect bounds;
871
872 My_GetWindowPortBounds(mw, &bounds);
873 My_InvalWindowRect(mw, &bounds);
874}
875
876LOCALPROC MySetMacWindContRect(My_WindowRef mw, Rect *r)
877{
878#if Windows85APIAvail
879 if (HaveNewWndMgrAvail()) {
880 (void) SetWindowBounds (mw, kWindowContentRgn, r);
881 } else
882#endif
883 {
884#if MightNotHaveWindows85Avail
885 MoveWindow(mw, r->left, r->top, falseblnr);
886 SizeWindow(mw, r->right - r->left, r->bottom - r->top,
887 trueblnr);
888#endif
889 }
890 InvalWholeWindow(mw);
891}
892
893LOCALFUNC blnr MyGetWindowTitleBounds(My_WindowRef mw, Rect *r)
894{
895#if Windows85APIAvail
896 if (HaveNewWndMgrAvail()) {
897 return (noErr == GetWindowBounds(mw,
898 kWindowTitleBarRgn, r));
899 } else
900#endif
901 {
902#if MightNotHaveWindows85Avail
903 My_GetRegionBounds(((WindowPeek)mw)->strucRgn, r);
904 r->bottom = r->top + 15;
905 r->left += 4;
906 r->right -= 4;
907#endif
908 return trueblnr;
909 }
910}
911
912#define topLeft(r) (((Point *) &(r))[0])
913#define botRight(r) (((Point *) &(r))[1])
914
915LOCALFUNC blnr MyGetWindowContBounds(My_WindowRef mw, Rect *r)
916{
917#if Windows85APIAvail
918 if (HaveNewWndMgrAvail()) {
919 return (noErr == GetWindowBounds(mw,
920 kWindowContentRgn, r));
921 } else
922#endif
923 {
924#if MightNotHaveWindows85Avail
925 GrafPtr oldPort;
926 GetPort(&oldPort);
927 My_SetPortWindowPort(mw);
928 My_GetWindowPortBounds(mw, r);
929 LocalToGlobal(&topLeft(*r));
930 LocalToGlobal(&botRight(*r));
931 SetPort(oldPort);
932#endif
933 return trueblnr;
934 }
935}
936
937LOCALPROC MyGetGrayRgnBounds(Rect *r)
938{
939 My_GetRegionBounds(My_GetGrayRgn(), (Rect *)r);
940}
941
942/* --- main window data --- */
943
944LOCALVAR WindowPtr gMyMainWindow = NULL;
945
946#if MayFullScreen
947LOCALVAR short hOffset;
948LOCALVAR short vOffset;
949#endif
950
951#if MayFullScreen
952LOCALVAR blnr GrabMachine = falseblnr;
953#endif
954
955#if VarFullScreen
956LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
957#endif
958
959#if EnableMagnify
960LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
961#endif
962
963#if EnableMagnify
964LOCALPROC MyScaleRect(Rect *r)
965{
966 r->left *= MyWindowScale;
967 r->right *= MyWindowScale;
968 r->top *= MyWindowScale;
969 r->bottom *= MyWindowScale;
970}
971#endif
972
973LOCALPROC SetScrnRectFromCoords(Rect *r,
974 si4b top, si4b left, si4b bottom, si4b right)
975{
976 r->left = left;
977 r->right = right;
978 r->top = top;
979 r->bottom = bottom;
980
981#if VarFullScreen
982 if (UseFullScreen)
983#endif
984#if MayFullScreen
985 {
986 OffsetRect(r, - ViewHStart, - ViewVStart);
987 }
988#endif
989
990#if EnableMagnify
991 if (UseMagnify) {
992 MyScaleRect(r);
993 }
994#endif
995
996#if VarFullScreen
997 if (UseFullScreen)
998#endif
999#if MayFullScreen
1000 {
1001 OffsetRect(r, hOffset, vOffset);
1002 }
1003#endif
1004
1005}
1006
1007#if EnableMagnify
1008#define MyScaledHeight (MyWindowScale * vMacScreenHeight)
1009#define MyScaledWidth (MyWindowScale * vMacScreenWidth)
1010#endif
1011
1012#if EnableMagnify
1013LOCALVAR ui3p ScalingBuff = nullpr;
1014#endif
1015
1016#if EnableMagnify
1017
1018LOCALVAR ui3p ScalingTabl = nullpr;
1019#define ScalingTablsz (256 * MyWindowScale)
1020
1021#define ScrnMapr_DoMap UpdateScaledBWCopy
1022#define ScrnMapr_Src GetCurDrawBuff()
1023#define ScrnMapr_Dst ScalingBuff
1024#define ScrnMapr_SrcDepth 0
1025#define ScrnMapr_DstDepth 0
1026#define ScrnMapr_Map ScalingTabl
1027#define ScrnMapr_Scale MyWindowScale
1028
1029#include "SCRNMAPR.h"
1030
1031#endif
1032
1033#if EnableMagnify
1034LOCALPROC SetUpScalingTabl(void)
1035{
1036 ui3b *p4;
1037 int i;
1038 int j;
1039 int k;
1040 ui3r bitsRemaining;
1041 ui3b t1;
1042 ui3b t2;
1043
1044 p4 = ScalingTabl;
1045 for (i = 0; i < 256; ++i) {
1046 bitsRemaining = 8;
1047 t2 = 0;
1048 for (j = 8; --j >= 0; ) {
1049 t1 = (i >> j) & 1;
1050 for (k = MyWindowScale; --k >= 0; ) {
1051 t2 = (t2 << 1) | t1;
1052 if (--bitsRemaining == 0) {
1053 *p4++ = t2;
1054 bitsRemaining = 8;
1055 t2 = 0;
1056 }
1057 }
1058 }
1059 }
1060}
1061#endif
1062
1063LOCALPROC DefaultDrawScreenBuff(si4b top, si4b left,
1064 si4b bottom, si4b right)
1065{
1066 BitMap src;
1067 Rect SrcRect;
1068 Rect DstRect;
1069
1070 SrcRect.left = left;
1071 SrcRect.right = right;
1072 SrcRect.top = top;
1073 SrcRect.bottom = bottom;
1074
1075 src.rowBytes = vMacScreenMonoByteWidth;
1076 SetRect(&src.bounds, 0, 0, vMacScreenWidth, vMacScreenHeight);
1077#if EnableMagnify
1078 if (UseMagnify) {
1079
1080 if (! ColorTransValid) {
1081 SetUpScalingTabl();
1082 ColorTransValid = trueblnr;
1083 }
1084
1085 UpdateScaledBWCopy(top, left, bottom, right);
1086
1087 MyScaleRect(&SrcRect);
1088 MyScaleRect(&src.bounds);
1089
1090 src.baseAddr = (Ptr)ScalingBuff;
1091 src.rowBytes *= MyWindowScale;
1092 } else
1093#endif
1094 {
1095 src.baseAddr = (Ptr)GetCurDrawBuff();
1096 }
1097 SetScrnRectFromCoords(&DstRect, top, left, bottom, right);
1098 CopyBits(&src,
1099 &gMyMainWindow->portBits,
1100 &SrcRect, &DstRect, srcCopy, NULL);
1101 /* FrameRect(&SrcRect); for testing */
1102}
1103
1104LOCALPROC Update_Screen(void)
1105{
1106 GrafPtr savePort;
1107
1108 GetPort(&savePort);
1109 My_SetPortWindowPort(gMyMainWindow);
1110
1111#if VarFullScreen
1112 if (UseFullScreen)
1113#endif
1114#if MayFullScreen
1115 {
1116 PaintRect(&gMyMainWindow->portRect);
1117 }
1118#endif
1119
1120 DefaultDrawScreenBuff(0, 0, vMacScreenHeight, vMacScreenWidth);
1121 SetPort(savePort);
1122}
1123
1124LOCALPROC HaveChangedScreenBuff(si4b top, si4b left,
1125 si4b bottom, si4b right)
1126{
1127#if 0 /* experimental code in progress */
1128 if (UseFullScreen)
1129 {
1130 {
1131 PixMapHandle pm= (**GetMainDevice()).gdPMap;
1132
1133 /* LockPixels(pm); */
1134#if EnableMagnify
1135 if (! UseMagnify) {
1136#define PixelT ui5b
1137 PixelT *p1 = (PixelT *)GetPixBaseAddr(pm);
1138 int i;
1139 int j;
1140 int k;
1141 ui5b *p0 = (ui5b *)GetCurDrawBuff();
1142 ui5b SkipBytes = GetPixRowBytes(pm)
1143 - sizeof(PixelT) * vMacScreenWidth;
1144 ui5b t0;
1145 PixelT a[2];
1146
1147 ((Ptr)p1) += (long)GetPixRowBytes(pm) * (top + vOffset);
1148 p1 += hOffset;
1149 p0 += (long)top * vMacScreenWidth / 32;
1150
1151 a[0] = (PixelT) -1;
1152 a[1] = 0;
1153
1154#if 1
1155 for (i = bottom - top; --i >= 0; ) {
1156 for (j = vMacScreenWidth / 32; --j >= 0; ) {
1157 t0 = *p0++;
1158
1159 for (k = 32; --k >= 0; ) {
1160 PixelT v = a[(t0 >> k) & 1];
1161 *p1++ = v;
1162 }
1163 }
1164 ((Ptr)p1) += SkipBytes;
1165 }
1166#endif
1167 } else {
1168#define PixelT ui5b
1169 PixelT *p1 = (PixelT *)GetPixBaseAddr(pm);
1170 int i;
1171 int j;
1172 int k;
1173 ui5b *p0 = (ui5b *)GetCurDrawBuff();
1174 PixelT *p2;
1175 ui5b t0;
1176 PixelT a[2];
1177
1178 p1 += vOffset * MyScaledWidth;
1179 p1 += (long)MyWindowScale * (long)MyScaledWidth * top;
1180 p0 += (long)top * vMacScreenWidth / 32;
1181
1182 a[0] = (PixelT) -1;
1183 a[1] = 0;
1184
1185#if 1
1186 for (i = bottom - top; --i >= 0; ) {
1187 p2 = p1;
1188 for (j = vMacScreenWidth / 32; --j >= 0; ) {
1189 t0 = *p0++;
1190
1191 for (k = 32; --k >= 0; ) {
1192 PixelT v = a[(t0 >> k) & 1];
1193 /* ((t0 >> k) & 1) - 1 */
1194 *p1++ = v;
1195 *p1++ = v;
1196 }
1197 }
1198 for (j = MyScaledWidth; --j >= 0; ) {
1199 *p1++ = *p2++;
1200 }
1201 }
1202#endif
1203 }
1204#endif
1205 /* UnlockPixels(pm); */
1206 }
1207 } else
1208#endif
1209 {
1210 GrafPtr savePort;
1211
1212 GetPort(&savePort);
1213 My_SetPortWindowPort(gMyMainWindow);
1214 DefaultDrawScreenBuff(top, left, bottom, right);
1215 SetPort(savePort);
1216 }
1217}
1218
1219LOCALPROC MyDrawChangesAndClear(void)
1220{
1221 if (ScreenChangedBottom > ScreenChangedTop) {
1222 HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
1223 ScreenChangedBottom, ScreenChangedRight);
1224 ScreenClearChanges();
1225 }
1226}
1227
1228GLOBALOSGLUPROC DoneWithDrawingForTick(void)
1229{
1230#if EnableFSMouseMotion
1231 if (HaveMouseMotion) {
1232 AutoScrollScreen();
1233 }
1234#endif
1235 MyDrawChangesAndClear();
1236}
1237
1238/* --- keyboard --- */
1239
1240LOCALVAR ui5b LastEmKeys[4];
1241
1242LOCALPROC ZapEmKeys(void)
1243{
1244 LastEmKeys[0] = 0;
1245 LastEmKeys[1] = 0;
1246 LastEmKeys[2] = 0;
1247 LastEmKeys[3] = 0;
1248}
1249
1250LOCALPROC CheckKeyBoardState(void)
1251{
1252 int i;
1253 int j;
1254 ui5b NewKeys[4];
1255
1256 GetKeys(*(KeyMap *)NewKeys);
1257
1258 for (j = 0; j < 16; ++j) {
1259 ui3b k1 = ((ui3b *)NewKeys)[j];
1260 ui3b k2 = ((ui3b *)LastEmKeys)[j];
1261 ui3b k3 = k1 ^ k2;
1262
1263 if (k3 != 0) {
1264 for (i = 0; i < 8; ++i) {
1265 if ((k3 & (1 << i)) != 0) {
1266 Keyboard_UpdateKeyMap2(Keyboard_RemapMac(j * 8 + i),
1267 (k1 & (1 << i)) != 0);
1268 }
1269 }
1270 }
1271 }
1272 for (i = 0; i < 4; ++i) {
1273 LastEmKeys[i] = NewKeys[i];
1274 }
1275}
1276
1277LOCALVAR WantCmdOptOnReconnect = falseblnr;
1278
1279#define KeyMap_TestBit(m, key) \
1280 ((((ui3b *)m)[(key) / 8] & (1 << ((key) & 7))) != 0)
1281
1282LOCALPROC ReconnectKeyCodes3(void)
1283/* so keys already pressed will be ignored */
1284{
1285 int i;
1286 int j;
1287 blnr oldv;
1288 blnr newv;
1289 ui5b NewKeys[4];
1290
1291 GetKeys(*(KeyMap *)NewKeys);
1292
1293 /* except check CapsLock */
1294 oldv = KeyMap_TestBit(LastEmKeys, MKC_CapsLock);
1295 newv = KeyMap_TestBit(NewKeys, MKC_CapsLock);
1296 if (oldv != newv) {
1297 Keyboard_UpdateKeyMap2(MKC_formac_CapsLock, newv);
1298 }
1299
1300 /* and except for command/option on receive drop */
1301 if (WantCmdOptOnReconnect) {
1302 WantCmdOptOnReconnect = falseblnr;
1303
1304 for (i = 0; i < 16; ++i) {
1305 ui3b v = ((ui3b *)NewKeys)[i];
1306 for (j = 0; j < 8; ++j) {
1307 if (0 != ((1 << j) & v)) {
1308 ui3r k = i * 8 + j;
1309 if (MKC_CapsLock != k) {
1310 Keyboard_UpdateKeyMap2(Keyboard_RemapMac(k),
1311 trueblnr);
1312 }
1313 }
1314 }
1315 }
1316 }
1317
1318 for (i = 0; i < 4; ++i) {
1319 LastEmKeys[i] = NewKeys[i];
1320 }
1321}
1322
1323/* --- cursor hiding --- */
1324
1325LOCALVAR blnr HaveCursorHidden = falseblnr;
1326LOCALVAR blnr WantCursorHidden = falseblnr;
1327
1328LOCALPROC ForceShowCursor(void)
1329{
1330 if (HaveCursorHidden) {
1331 HaveCursorHidden = falseblnr;
1332 ShowCursor();
1333 }
1334}
1335
1336LOCALPROC SetCursorArrow(void)
1337{
1338 SetCursor(&qd.arrow);
1339}
1340
1341/* --- cursor moving --- */
1342
1343/*
1344 mouse moving code (non OS X) adapted from
1345 MoveMouse.c by Dan Sears, which says that
1346 "Based on code from Jon Wtte, Denis Pelli,
1347 Apple, and a timely suggestion from Bo Lindbergh."
1348 Also says 'For documentation of the CDM, see Apple
1349 Tech Note "HW 01 - ADB (The Untold Story: Space Aliens
1350 ate my mouse)"'
1351*/
1352
1353#ifndef TARGET_CPU_PPC
1354#error "TARGET_CPU_PPC undefined"
1355#endif
1356
1357#if TARGET_CPU_PPC
1358enum {
1359 glueUppCursorDeviceMoveToProcInfo =
1360 kD0DispatchedPascalStackBased |
1361 DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
1362 RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
1363 DISPATCHED_STACK_ROUTINE_PARAMETER(1,
1364 SIZE_CODE(sizeof(CursorDevicePtr))) |
1365 DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) |
1366 DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))),
1367 glueUppCursorDeviceNextDeviceProcInfo =
1368 kD0DispatchedPascalStackBased |
1369 DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
1370 RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
1371 DISPATCHED_STACK_ROUTINE_PARAMETER(1,
1372 SIZE_CODE(sizeof(CursorDevicePtr *)))
1373};
1374#endif
1375
1376#if TARGET_CPU_PPC
1377LOCALFUNC OSErr
1378CallCursorDeviceMoveTo(
1379 CursorDevicePtr ourDevice,
1380 long absX,
1381 long absY)
1382{
1383 return CallUniversalProc(
1384 GetToolboxTrapAddress(_CursorDeviceDispatch),
1385 glueUppCursorDeviceMoveToProcInfo,
1386 1, ourDevice, absX, absY);
1387}
1388#else
1389#define CallCursorDeviceMoveTo CursorDeviceMoveTo
1390#endif
1391
1392#if TARGET_CPU_PPC
1393LOCALFUNC OSErr
1394CallCursorDeviceNextDevice(
1395 CursorDevicePtr *ourDevice)
1396{
1397 return CallUniversalProc(
1398 GetToolboxTrapAddress(_CursorDeviceDispatch),
1399 glueUppCursorDeviceNextDeviceProcInfo,
1400 0xB, ourDevice);
1401}
1402#else
1403#define CallCursorDeviceNextDevice CursorDeviceNextDevice
1404#endif
1405
1406#if ! TARGET_CPU_PPC
1407pascal void CallCursorTask(void) =
1408{
1409 0x2078, 0x08EE, /* MOVE.L jCrsrTask,A0 */
1410 0x4E90 /* JSR (A0) */
1411};
1412#endif
1413
1414/*
1415 Low memory globals for the mouse
1416*/
1417
1418#define MyRawMouse 0x082C
1419 /* low memory global that has current mouse loc */
1420#define MyMTemp 0x0828
1421 /* low memory global that has current mouse loc */
1422#define MyCrsrNew 0x08CE
1423 /* set after you change mtemp and rawmouse */
1424#define MyCrsrCouple 0x08CF
1425 /* true if the cursor is tied to the mouse */
1426
1427LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
1428{
1429 GrafPtr oldPort;
1430 Point CurMousePos;
1431 Point NewMousePos;
1432 ui5b difftime;
1433 blnr IsOk;
1434 long int StartTime = TickCount();
1435
1436#if VarFullScreen
1437 if (UseFullScreen)
1438#endif
1439#if MayFullScreen
1440 {
1441 h -= ViewHStart;
1442 v -= ViewVStart;
1443 }
1444#endif
1445
1446#if EnableMagnify
1447 if (UseMagnify) {
1448 h *= MyWindowScale;
1449 v *= MyWindowScale;
1450 }
1451#endif
1452
1453#if VarFullScreen
1454 if (UseFullScreen)
1455#endif
1456#if MayFullScreen
1457 {
1458 h += hOffset;
1459 v += vOffset;
1460 }
1461#endif
1462
1463 CurMousePos.h = h;
1464 CurMousePos.v = v;
1465
1466 GetPort(&oldPort);
1467 My_SetPortWindowPort(gMyMainWindow);
1468 LocalToGlobal(&CurMousePos);
1469
1470 do {
1471
1472#if HaveCPUfamM68K
1473 if (! HiToolTrapAvailable(_CursorDeviceDispatch)) {
1474 *(Point *)MyRawMouse = CurMousePos;
1475 *(Point *)MyMTemp = CurMousePos;
1476 *(Ptr)MyCrsrNew = *(Ptr)MyCrsrCouple;
1477#if ! TARGET_CPU_PPC
1478 CallCursorTask();
1479#endif
1480 } else
1481#endif
1482 {
1483 CursorDevice *firstMouse = NULL;
1484 CallCursorDeviceNextDevice(&firstMouse);
1485 if (firstMouse != NULL) {
1486 CallCursorDeviceMoveTo(firstMouse,
1487 (long) CurMousePos.h,
1488 (long) CurMousePos.v);
1489 }
1490 }
1491
1492 GetMouse(&NewMousePos);
1493 IsOk = (h == NewMousePos.h) && (v == NewMousePos.v);
1494 difftime = (ui5b)(TickCount() - StartTime);
1495 } while ((! IsOk) && (difftime < 5));
1496
1497 SetPort(oldPort);
1498 return IsOk;
1499}
1500
1501#if EnableFSMouseMotion
1502LOCALPROC AdjustMouseMotionGrab(void)
1503{
1504 if (gMyMainWindow != NULL) {
1505#if MayFullScreen
1506 if (GrabMachine) {
1507 /*
1508 if magnification changes, need to reset,
1509 even if HaveMouseMotion already true
1510 */
1511 if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
1512 ViewVStart + (ViewVSize / 2)))
1513 {
1514 SavedMouseH = ViewHStart + (ViewHSize / 2);
1515 SavedMouseV = ViewVStart + (ViewVSize / 2);
1516 HaveMouseMotion = trueblnr;
1517 }
1518 } else
1519#endif
1520 {
1521 if (HaveMouseMotion) {
1522 (void) MyMoveMouse(CurMouseH, CurMouseV);
1523 HaveMouseMotion = falseblnr;
1524 }
1525 }
1526 }
1527}
1528#endif
1529
1530#if EnableFSMouseMotion
1531LOCALPROC MyMouseConstrain(void)
1532{
1533 si4b shiftdh;
1534 si4b shiftdv;
1535
1536 if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
1537 shiftdh = ViewHSize / 2;
1538 } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
1539 shiftdh = - ViewHSize / 2;
1540 } else {
1541 shiftdh = 0;
1542 }
1543 if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
1544 shiftdv = ViewVSize / 2;
1545 } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
1546 shiftdv = - ViewVSize / 2;
1547 } else {
1548 shiftdv = 0;
1549 }
1550 if ((shiftdh != 0) || (shiftdv != 0)) {
1551 SavedMouseH += shiftdh;
1552 SavedMouseV += shiftdv;
1553 if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
1554 HaveMouseMotion = falseblnr;
1555 }
1556 }
1557}
1558#endif
1559
1560LOCALPROC MousePositionNotify(Point NewMousePos)
1561{
1562 blnr ShouldHaveCursorHidden = trueblnr;
1563
1564#if VarFullScreen
1565 if (UseFullScreen)
1566#endif
1567#if MayFullScreen
1568 {
1569 NewMousePos.h -= hOffset;
1570 NewMousePos.v -= vOffset;
1571 }
1572#endif
1573#if VarFullScreen
1574 else
1575#endif
1576#if MayNotFullScreen
1577 {
1578 if (! PtInRgn(NewMousePos, gMyMainWindow->visRgn)) {
1579 ShouldHaveCursorHidden = falseblnr;
1580 }
1581 }
1582#endif
1583
1584#if EnableMagnify
1585 if (UseMagnify) {
1586 NewMousePos.h /= MyWindowScale;
1587 NewMousePos.v /= MyWindowScale;
1588 }
1589#endif
1590
1591#if VarFullScreen
1592 if (UseFullScreen)
1593#endif
1594#if MayFullScreen
1595 {
1596 NewMousePos.h += ViewHStart;
1597 NewMousePos.v += ViewVStart;
1598 }
1599#endif
1600
1601#if EnableFSMouseMotion
1602 if (HaveMouseMotion) {
1603 MyMousePositionSetDelta(
1604 NewMousePos.h - SavedMouseH, NewMousePos.v - SavedMouseV);
1605 SavedMouseH = NewMousePos.h;
1606 SavedMouseV = NewMousePos.v;
1607 } else
1608#endif
1609 {
1610 if (NewMousePos.h < 0) {
1611 NewMousePos.h = 0;
1612 ShouldHaveCursorHidden = falseblnr;
1613 } else if (NewMousePos.h >= vMacScreenWidth) {
1614 NewMousePos.h = vMacScreenWidth - 1;
1615 ShouldHaveCursorHidden = falseblnr;
1616 }
1617 if (NewMousePos.v < 0) {
1618 NewMousePos.v = 0;
1619 ShouldHaveCursorHidden = falseblnr;
1620 } else if (NewMousePos.v >= vMacScreenHeight) {
1621 NewMousePos.v = vMacScreenHeight - 1;
1622 ShouldHaveCursorHidden = falseblnr;
1623 }
1624
1625#if VarFullScreen
1626 if (UseFullScreen)
1627#endif
1628#if MayFullScreen
1629 {
1630 ShouldHaveCursorHidden = trueblnr;
1631 }
1632#endif
1633
1634 /* if (ShouldHaveCursorHidden || CurMouseButton) */
1635 /*
1636 for a game like arkanoid, would like mouse to still
1637 move even when outside window in one direction
1638 */
1639 MyMousePositionSet(NewMousePos.h, NewMousePos.v);
1640 }
1641
1642 WantCursorHidden = ShouldHaveCursorHidden;
1643}
1644
1645LOCALPROC MousePositionNotifyFromGlobal(Point NewMousePos)
1646{
1647 GrafPtr oldPort;
1648
1649 GetPort(&oldPort);
1650 My_SetPortWindowPort(gMyMainWindow);
1651 GlobalToLocal(&NewMousePos);
1652 SetPort(oldPort);
1653
1654 MousePositionNotify(NewMousePos);
1655}
1656
1657LOCALPROC CheckMouseState(void)
1658{
1659 Point NewMousePos;
1660 GrafPtr oldPort;
1661
1662 GetPort(&oldPort);
1663 My_SetPortWindowPort(gMyMainWindow);
1664 GetMouse(&NewMousePos);
1665 SetPort(oldPort);
1666
1667 MousePositionNotify(NewMousePos);
1668}
1669
1670LOCALPROC DisconnectKeyCodes3(void)
1671{
1672 DisconnectKeyCodes2();
1673
1674 MyMouseButtonSet(falseblnr);
1675
1676 ForceShowCursor();
1677}
1678
1679
1680/* --- time, date, location --- */
1681
1682#define dbglog_TimeStuff (0 && dbglog_HAVE)
1683
1684/*
1685 be sure to avoid getting confused if TickCount
1686 overflows and wraps.
1687*/
1688
1689LOCALVAR ui5b TrueEmulatedTime = 0;
1690
1691LOCALVAR long int LastTime;
1692
1693LOCALPROC StartUpTimeAdjust(void)
1694{
1695 LastTime = TickCount();
1696}
1697
1698LOCALPROC UpdateTrueEmulatedTime(void)
1699{
1700 long int LatestTime = TickCount();
1701 si5b TimeDiff = LatestTime - LastTime;
1702
1703 if (TimeDiff != 0) {
1704 LastTime = LatestTime;
1705
1706 if (TimeDiff >= 0) {
1707 if (TimeDiff > 16) {
1708 /* emulation interrupted, forget it */
1709 ++TrueEmulatedTime;
1710
1711#if dbglog_TimeStuff
1712 dbglog_writelnNum("emulation interrupted",
1713 TrueEmulatedTime);
1714#endif
1715 } else {
1716 TrueEmulatedTime += TimeDiff;
1717 }
1718 }
1719 }
1720}
1721
1722LOCALFUNC blnr CheckDateTime(void)
1723{
1724 ui5b NewMacDateInSecond;
1725
1726 NewMacDateInSecond = My_LMGetTime();
1727 if (CurMacDateInSeconds != NewMacDateInSecond) {
1728 CurMacDateInSeconds = NewMacDateInSecond;
1729 return trueblnr;
1730 } else {
1731 return falseblnr;
1732 }
1733}
1734
1735LOCALFUNC blnr InitLocationDat(void)
1736{
1737#if AutoLocation || AutoTimeZone
1738 MachineLocation loc;
1739
1740 ReadLocation(&loc);
1741#if AutoLocation
1742 CurMacLatitude = (ui5b)loc.latitude;
1743 CurMacLongitude = (ui5b)loc.longitude;
1744#endif
1745#if AutoTimeZone
1746 CurMacDelta = (ui5b)loc.u.gmtDelta;
1747#endif
1748#endif
1749
1750 (void) CheckDateTime();
1751
1752 return trueblnr;
1753}
1754
1755/* --- sound --- */
1756
1757#if MySoundEnabled
1758
1759#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
1760#define kSoundBuffers (1 << kLn2SoundBuffers)
1761#define kSoundBuffMask (kSoundBuffers - 1)
1762
1763#define DesiredMinFilledSoundBuffs 3
1764 /*
1765 if too big then sound lags behind emulation.
1766 if too small then sound will have pauses.
1767 */
1768
1769#define kLnOneBuffLen 9
1770#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
1771#define kOneBuffLen (1UL << kLnOneBuffLen)
1772#define kAllBuffLen (1UL << kLnAllBuffLen)
1773#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
1774#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
1775#define kOneBuffSz (1UL << kLnOneBuffSz)
1776#define kAllBuffSz (1UL << kLnAllBuffSz)
1777#define kOneBuffMask (kOneBuffLen - 1)
1778#define kAllBuffMask (kAllBuffLen - 1)
1779#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
1780
1781#define dbglog_SoundStuff (0 && dbglog_HAVE)
1782#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
1783
1784LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
1785volatile static ui4b ThePlayOffset;
1786volatile static ui4b TheFillOffset;
1787volatile static ui4b MinFilledSoundBuffs;
1788#if dbglog_SoundBuffStats
1789LOCALVAR ui4b MaxFilledSoundBuffs;
1790#endif
1791LOCALVAR ui4b TheWriteOffset;
1792
1793LOCALPROC MySound_Start0(void)
1794{
1795 /* Reset variables */
1796 ThePlayOffset = 0;
1797 TheFillOffset = 0;
1798 TheWriteOffset = 0;
1799 MinFilledSoundBuffs = kSoundBuffers + 1;
1800#if dbglog_SoundBuffStats
1801 MaxFilledSoundBuffs = 0;
1802#endif
1803}
1804
1805GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
1806{
1807 ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
1808 ui4b WriteBuffContig =
1809 kOneBuffLen - (TheWriteOffset & kOneBuffMask);
1810
1811 if (WriteBuffContig < n) {
1812 n = WriteBuffContig;
1813 }
1814 if (ToFillLen < n) {
1815 /* overwrite previous buffer */
1816#if dbglog_SoundStuff
1817 dbglog_writeln("sound buffer over flow");
1818#endif
1819 TheWriteOffset -= kOneBuffLen;
1820 }
1821
1822 *actL = n;
1823 return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
1824}
1825
1826#if 4 == kLn2SoundSampSz
1827LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
1828{
1829 int i;
1830
1831 for (i = kOneBuffLen; --i >= 0; ) {
1832 *p++ -= 0x8000;
1833 }
1834}
1835#else
1836#define ConvertSoundBlockToNative(p)
1837#endif
1838
1839LOCALPROC MySound_WroteABlock(void)
1840{
1841#if (4 == kLn2SoundSampSz)
1842 ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen;
1843 tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask);
1844#endif
1845
1846#if dbglog_SoundStuff
1847 dbglog_writeln("enter MySound_WroteABlock");
1848#endif
1849
1850 ConvertSoundBlockToNative(p);
1851
1852 TheFillOffset = TheWriteOffset;
1853
1854#if dbglog_SoundBuffStats
1855 {
1856 ui4b ToPlayLen = TheFillOffset
1857 - ThePlayOffset;
1858 ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen;
1859
1860 if (ToPlayBuffs > MaxFilledSoundBuffs) {
1861 MaxFilledSoundBuffs = ToPlayBuffs;
1862 }
1863 }
1864#endif
1865}
1866
1867LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
1868{
1869 blnr v;
1870
1871 TheWriteOffset += actL;
1872
1873 if (0 != (TheWriteOffset & kOneBuffMask)) {
1874 v = falseblnr;
1875 } else {
1876 /* just finished a block */
1877
1878 MySound_WroteABlock();
1879
1880 v = trueblnr;
1881 }
1882
1883 return v;
1884}
1885
1886LOCALPROC MySound_SecondNotify0(void)
1887{
1888 if (MinFilledSoundBuffs <= kSoundBuffers) {
1889 if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
1890#if dbglog_SoundStuff
1891 dbglog_writeln("MinFilledSoundBuffs too high");
1892#endif
1893 ++LastTime;
1894 } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
1895#if dbglog_SoundStuff
1896 dbglog_writeln("MinFilledSoundBuffs too low");
1897#endif
1898 ++TrueEmulatedTime;
1899 }
1900#if dbglog_SoundBuffStats
1901 dbglog_writelnNum("MinFilledSoundBuffs",
1902 MinFilledSoundBuffs);
1903 dbglog_writelnNum("MaxFilledSoundBuffs",
1904 MaxFilledSoundBuffs);
1905 MaxFilledSoundBuffs = 0;
1906#endif
1907 MinFilledSoundBuffs = kSoundBuffers + 1;
1908 }
1909}
1910
1911LOCALPROC RampSound(tpSoundSamp p,
1912 trSoundSamp BeginVal, trSoundSamp EndVal)
1913{
1914 int i;
1915 ui5r v = (((ui5r)BeginVal) << kLnOneBuffLen) + (kLnOneBuffLen >> 1);
1916
1917 for (i = kOneBuffLen; --i >= 0; ) {
1918 *p++ = v >> kLnOneBuffLen;
1919 v = v + EndVal - BeginVal;
1920 }
1921}
1922
1923#if 4 == kLn2SoundSampSz
1924#define ConvertSoundSampleFromNative(v) ((v) + 0x8000)
1925#else
1926#define ConvertSoundSampleFromNative(v) (v)
1927#endif
1928
1929struct MySoundR {
1930 tpSoundSamp fTheSoundBuffer;
1931 volatile ui4b (*fPlayOffset);
1932 volatile ui4b (*fFillOffset);
1933 volatile ui4b (*fMinFilledSoundBuffs);
1934
1935 volatile blnr PlayingBuffBlock;
1936 volatile trSoundSamp lastv;
1937 volatile blnr wantplaying;
1938 volatile blnr StartingBlocks;
1939
1940 CmpSoundHeader /* ExtSoundHeader */ soundHeader;
1941};
1942typedef struct MySoundR MySoundR;
1943
1944
1945/*
1946 Some of this code descended from CarbonSndPlayDB, an
1947 example from Apple, as found being used in vMac for Mac OS.
1948*/
1949
1950LOCALPROC InsertSndDoCommand(SndChannelPtr chan, SndCommand * newCmd)
1951{
1952 if (-1 == chan->qHead) {
1953 chan->qHead = chan->qTail;
1954 }
1955
1956 if (1 <= chan->qHead) {
1957 chan->qHead--;
1958 } else {
1959 chan->qHead = chan->qTail;
1960 }
1961
1962 chan->queue[chan->qHead] = *newCmd;
1963}
1964
1965/* call back */ static pascal void
1966MySound_CallBack(SndChannelPtr theChannel, SndCommand * theCallBackCmd)
1967{
1968 MySoundR *datp =
1969 (MySoundR *)(theCallBackCmd->param2);
1970 blnr wantplaying0 = datp->wantplaying;
1971 trSoundSamp v0 = datp->lastv;
1972
1973#if dbglog_SoundStuff
1974 dbglog_writeln("Enter MySound_CallBack");
1975#endif
1976
1977 if (datp->PlayingBuffBlock) {
1978 /* finish with last sample */
1979#if dbglog_SoundStuff
1980 dbglog_writeln("done with sample");
1981#endif
1982
1983 *datp->fPlayOffset += kOneBuffLen;
1984 datp->PlayingBuffBlock = falseblnr;
1985 }
1986
1987 if ((! wantplaying0) && (kCenterSound == v0)) {
1988#if dbglog_SoundStuff
1989 dbglog_writeln("terminating");
1990#endif
1991 } else {
1992 SndCommand playCmd;
1993 tpSoundSamp p;
1994 trSoundSamp v1 = v0;
1995 blnr WantRamp = falseblnr;
1996 ui4b CurPlayOffset = *datp->fPlayOffset;
1997 ui4b ToPlayLen = *datp->fFillOffset - CurPlayOffset;
1998 ui4b FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen;
1999
2000 if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) {
2001 *datp->fMinFilledSoundBuffs = FilledSoundBuffs;
2002 }
2003
2004 if (! wantplaying0) {
2005#if dbglog_SoundStuff
2006 dbglog_writeln("playing end transistion");
2007#endif
2008 v1 = kCenterSound;
2009
2010 WantRamp = trueblnr;
2011 } else
2012 if (datp->StartingBlocks) {
2013#if dbglog_SoundStuff
2014 dbglog_writeln("playing start block");
2015#endif
2016
2017 if ((ToPlayLen >> kLnOneBuffLen) < 12) {
2018 datp->StartingBlocks = falseblnr;
2019#if dbglog_SoundStuff
2020 dbglog_writeln("have enough samples to start");
2021#endif
2022
2023 p = datp->fTheSoundBuffer
2024 + (CurPlayOffset & kAllBuffMask);
2025 v1 = ConvertSoundSampleFromNative(*p);
2026 }
2027
2028 WantRamp = trueblnr;
2029 } else
2030 if (0 == FilledSoundBuffs) {
2031#if dbglog_SoundStuff
2032 dbglog_writeln("playing under run");
2033#endif
2034
2035 WantRamp = trueblnr;
2036 } else
2037 {
2038 /* play next sample */
2039 p = datp->fTheSoundBuffer
2040 + (CurPlayOffset & kAllBuffMask);
2041 datp->PlayingBuffBlock = trueblnr;
2042 v1 =
2043 ConvertSoundSampleFromNative(*(p + kOneBuffLen - 1));
2044#if dbglog_SoundStuff
2045 dbglog_writeln("playing sample");
2046#endif
2047 }
2048
2049 if (WantRamp) {
2050 p = datp->fTheSoundBuffer + kAllBuffLen;
2051
2052#if dbglog_SoundStuff
2053 dbglog_writelnNum("v0", v0);
2054 dbglog_writelnNum("v1", v1);
2055#endif
2056
2057 RampSound(p, v0, v1);
2058 ConvertSoundBlockToNative(p);
2059 }
2060
2061 datp->soundHeader.samplePtr = (Ptr)p;
2062 datp->soundHeader.numFrames =
2063 (unsigned long)kOneBuffLen;
2064
2065 /* Insert our callback command */
2066 InsertSndDoCommand (theChannel, theCallBackCmd);
2067
2068#if 0
2069 {
2070 int i;
2071 tpSoundSamp pS =
2072 (tpSoundSamp)datp->soundHeader.samplePtr;
2073
2074 for (i = datp->soundHeader.numFrames; --i >= 0; )
2075 {
2076 fprintf(stderr, "%d\n", *pS++);
2077 }
2078 }
2079#endif
2080
2081 /* Play the next buffer */
2082 playCmd.cmd = bufferCmd;
2083 playCmd.param1 = 0;
2084 playCmd.param2 = (long)&(datp->soundHeader);
2085 InsertSndDoCommand (theChannel, &playCmd);
2086
2087 datp->lastv = v1;
2088 }
2089}
2090
2091LOCALVAR MySoundR cur_audio;
2092
2093LOCALVAR SndCallBackUPP gCarbonSndPlayDoubleBufferCallBackUPP = NULL;
2094
2095LOCALVAR SndChannelPtr sndChannel = NULL; /* our sound channel */
2096
2097LOCALPROC MySound_Start(void)
2098{
2099 if (NULL == sndChannel)
2100#if HaveCPUfamM68K
2101 if (HaveSndMngrAvail())
2102#endif
2103 {
2104 SndCommand callBack;
2105 SndChannelPtr chan = NULL;
2106
2107 cur_audio.wantplaying = falseblnr;
2108 cur_audio.StartingBlocks = falseblnr;
2109
2110 MySound_Start0();
2111
2112 SndNewChannel(&chan, sampledSynth, initMono, nil);
2113 if (NULL != chan) {
2114 sndChannel = chan;
2115
2116 cur_audio.PlayingBuffBlock = falseblnr;
2117 cur_audio.lastv = kCenterSound;
2118 cur_audio.StartingBlocks = trueblnr;
2119 cur_audio.wantplaying = trueblnr;
2120
2121 callBack.cmd = callBackCmd;
2122 callBack.param1 = 0; /* unused */
2123 callBack.param2 = (long)&cur_audio;
2124
2125 sndChannel->callBack =
2126 gCarbonSndPlayDoubleBufferCallBackUPP;
2127
2128 (void) SndDoCommand (sndChannel, &callBack, true);
2129 }
2130 }
2131}
2132
2133#define IgnorableEventMask \
2134 (mUpMask | keyDownMask | keyUpMask | autoKeyMask)
2135
2136LOCALPROC MySound_Stop(void)
2137{
2138#if dbglog_SoundStuff
2139 dbglog_writeln("enter MySound_Stop");
2140#endif
2141
2142 if (NULL != sndChannel) {
2143 ui4r retry_limit = 50; /* half of a second */
2144 SCStatus r;
2145
2146 cur_audio.wantplaying = falseblnr;
2147#if dbglog_SoundStuff
2148 dbglog_writeln("cleared wantplaying");
2149#endif
2150
2151label_retry:
2152 r.scChannelBusy = falseblnr; /* what is this for? */
2153 if (noErr != SndChannelStatus(sndChannel,
2154 sizeof(SCStatus), &r))
2155 {
2156 /* fail */
2157 } else
2158 if ((! r.scChannelBusy) && (kCenterSound == cur_audio.lastv)) {
2159 /* done */
2160
2161 /*
2162 observed reporting not busy unexpectedly,
2163 so also check lastv.
2164 */
2165 } else
2166 if (0 == --retry_limit) {
2167#if dbglog_SoundStuff
2168 dbglog_writeln("retry limit reached");
2169#endif
2170 /*
2171 don't trust SndChannelStatus, make
2172 sure don't get in infinite loop.
2173 */
2174
2175 /* done */
2176 } else
2177 {
2178 /*
2179 give time back, particularly important
2180 if got here on a suspend event.
2181 */
2182 EventRecord theEvent;
2183
2184#if dbglog_SoundStuff
2185 dbglog_writeln("busy, so sleep");
2186#endif
2187
2188#if HaveCPUfamM68K
2189 if (! HaveWaitNextEventAvail()) {
2190 (void) GetNextEvent(IgnorableEventMask, &theEvent);
2191 } else
2192#endif
2193 {
2194 (void) WaitNextEvent(IgnorableEventMask,
2195 &theEvent, 1, NULL);
2196 }
2197 goto label_retry;
2198 }
2199
2200 SndDisposeChannel(sndChannel, true);
2201 sndChannel = NULL;
2202 }
2203
2204#if dbglog_SoundStuff
2205 dbglog_writeln("leave MySound_Stop");
2206#endif
2207}
2208
2209#define SOUND_SAMPLERATE rate22khz
2210 /* = 0x56EE8BA3 = (7833600 * 2 / 704) << 16 */
2211
2212LOCALFUNC blnr MySound_Init(void)
2213{
2214#if dbglog_SoundStuff
2215 dbglog_writeln("enter MySound_Init");
2216#endif
2217
2218 cur_audio.fTheSoundBuffer = TheSoundBuffer;
2219
2220 cur_audio.fPlayOffset = &ThePlayOffset;
2221 cur_audio.fFillOffset = &TheFillOffset;
2222 cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs;
2223 cur_audio.wantplaying = falseblnr;
2224
2225 /* Init basic per channel information */
2226 cur_audio.soundHeader.sampleRate = SOUND_SAMPLERATE;
2227 /* sample rate */
2228 cur_audio.soundHeader.numChannels = 1; /* one channel */
2229 cur_audio.soundHeader.loopStart = 0;
2230 cur_audio.soundHeader.loopEnd = 0;
2231 cur_audio.soundHeader.encode = cmpSH /* extSH */;
2232 cur_audio.soundHeader.baseFrequency = kMiddleC;
2233 cur_audio.soundHeader.numFrames =
2234 (unsigned long)kOneBuffLen;
2235 /* cur_audio.soundHeader.AIFFSampleRate = 0; */
2236 /* unused */
2237 cur_audio.soundHeader.markerChunk = nil;
2238 cur_audio.soundHeader.futureUse2 = 0;
2239 cur_audio.soundHeader.stateVars = nil;
2240 cur_audio.soundHeader.leftOverSamples = nil;
2241 cur_audio.soundHeader.compressionID = 0;
2242 /* no compression */
2243 cur_audio.soundHeader.packetSize = 0;
2244 /* no compression */
2245 cur_audio.soundHeader.snthID = 0;
2246 cur_audio.soundHeader.sampleSize = (1 << kLn2SoundSampSz);
2247 /* 8 or 16 bits per sample */
2248 cur_audio.soundHeader.sampleArea[0] = 0;
2249#if 3 == kLn2SoundSampSz
2250 cur_audio.soundHeader.format = kSoundNotCompressed;
2251#elif 4 == kLn2SoundSampSz
2252 cur_audio.soundHeader.format = k16BitNativeEndianFormat;
2253#else
2254#error "unsupported kLn2SoundSampSz"
2255#endif
2256 cur_audio.soundHeader.samplePtr = (Ptr)TheSoundBuffer;
2257
2258 gCarbonSndPlayDoubleBufferCallBackUPP =
2259 NewSndCallBackUPP(MySound_CallBack);
2260 if (gCarbonSndPlayDoubleBufferCallBackUPP != NULL) {
2261
2262 MySound_Start();
2263 /*
2264 This should be taken care of by LeaveSpeedStopped,
2265 but since takes a while to get going properly,
2266 start early.
2267 */
2268
2269 return trueblnr;
2270 }
2271 return falseblnr;
2272}
2273
2274GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
2275{
2276 if (MySound_EndWrite0(actL)) {
2277 }
2278}
2279
2280LOCALPROC MySound_SecondNotify(void)
2281{
2282 if (sndChannel != NULL) {
2283 MySound_SecondNotify0();
2284 }
2285}
2286
2287#endif
2288
2289#if MayFullScreen
2290LOCALPROC AdjustMachineGrab(void)
2291{
2292#if EnableFSMouseMotion
2293 AdjustMouseMotionGrab();
2294#endif
2295#if 0
2296 AdjustMainScreenGrab();
2297#endif
2298}
2299#endif
2300
2301#if MayFullScreen
2302LOCALPROC UngrabMachine(void)
2303{
2304 GrabMachine = falseblnr;
2305 AdjustMachineGrab();
2306}
2307#endif
2308
2309/* --- basic dialogs --- */
2310
2311LOCALPROC NativeStrFromCStr(ps3p r, char *s, blnr AddEllipsis)
2312{
2313 int i;
2314 int L;
2315 ui3b ps[ClStrMaxLength];
2316
2317 ClStrFromSubstCStr(&L, ps, s);
2318 if (AddEllipsis) {
2319 ClStrAppendChar(&L, ps, kCellEllipsis);
2320 }
2321
2322 if (L > 255) {
2323 L = 255;
2324 }
2325
2326 for (i = 0; i < L; ++i) {
2327 r[i + 1] = Cell2MacAsciiMap[ps[i]];
2328 }
2329
2330 r[0] = L;
2331}
2332
2333#ifndef HogCPU
2334#define HogCPU 1
2335#endif
2336
2337#if HogCPU
2338LOCALVAR long NoEventsCounter = 0;
2339#endif
2340
2341LOCALVAR blnr gBackgroundFlag = falseblnr;
2342LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
2343LOCALVAR blnr CurSpeedStopped = trueblnr;
2344
2345LOCALVAR blnr ADialogIsUp = falseblnr;
2346
2347LOCALPROC MyBeginDialog(void)
2348{
2349 DisconnectKeyCodes3();
2350 ADialogIsUp = trueblnr;
2351#if MayFullScreen
2352 UngrabMachine();
2353#endif
2354}
2355
2356LOCALPROC MyEndDialog(void)
2357{
2358#if HogCPU
2359 NoEventsCounter = 0;
2360#endif
2361 ADialogIsUp = falseblnr;
2362 ReconnectKeyCodes3();
2363}
2364
2365
2366#define kMyStandardAlert 128
2367
2368LOCALPROC CheckSavedMacMsg(void)
2369{
2370 Str255 briefMsgp;
2371 Str255 longMsgp;
2372
2373 if (nullpr != SavedBriefMsg) {
2374 NativeStrFromCStr(briefMsgp, SavedBriefMsg, falseblnr);
2375 NativeStrFromCStr(longMsgp, SavedLongMsg, falseblnr);
2376#if AppearanceAvail
2377 if (HaveAppearanceAvail()) {
2378 AlertStdAlertParamRec param;
2379 short itemHit;
2380
2381 param.movable = 0;
2382 param.filterProc = nil;
2383 param.defaultText = "\pOK";
2384 param.cancelText = nil;
2385 param.otherText = nil;
2386 param.helpButton = false;
2387 param.defaultButton = kAlertStdAlertOKButton;
2388 param.cancelButton = 0;
2389 param.position = kWindowDefaultPosition;
2390
2391 StandardAlert(
2392 (SavedFatalMsg) ? kAlertStopAlert : kAlertCautionAlert,
2393 briefMsgp, longMsgp, ¶m, &itemHit);
2394 } else
2395#endif
2396 {
2397 ParamText(briefMsgp, longMsgp, "\p", "\p");
2398 if (SavedFatalMsg) {
2399 while (StopAlert(kMyStandardAlert, NULL) != 1) {
2400 }
2401 } else {
2402 while (CautionAlert(kMyStandardAlert, NULL) != 1) {
2403 }
2404 }
2405 /* Alert (kMyStandardAlert, 0L); */
2406 }
2407
2408 SavedBriefMsg = nullpr;
2409 }
2410}
2411
2412/* --- hide/show menubar --- */
2413
2414#if MayFullScreen
2415#if MightNotHaveWindows85Avail
2416LOCALVAR RgnHandle GrayRgnSave = NULL;
2417LOCALVAR short mBarHeightSave;
2418#endif
2419#endif
2420
2421#if MayFullScreen
2422LOCALPROC My_HideMenuBar(void)
2423{
2424#if Windows85APIAvail
2425 if (HaveHideShowMenuAvail()) {
2426 if (IsMenuBarVisible()) {
2427 HideMenuBar();
2428 }
2429 } else
2430#endif
2431 {
2432#if MightNotHaveWindows85Avail
2433 if (NULL == GrayRgnSave) {
2434 RgnHandle mBarRgn = NewRgn();
2435 if (mBarRgn != NULL) {
2436 GrayRgnSave = NewRgn();
2437 if (GrayRgnSave != NULL) {
2438 CopyRgn(My_GetGrayRgn(), GrayRgnSave);
2439 RectRgn(mBarRgn, &qd.screenBits.bounds);
2440 DiffRgn(mBarRgn, My_GetGrayRgn(), mBarRgn);
2441 /*
2442 menu bar rgn, plus corner areas
2443 of main screen
2444 */
2445 mBarHeightSave = My_LMGetMBarHeight();
2446 LMSetMBarHeight(0);
2447 UnionRgn(My_GetGrayRgn(), mBarRgn, My_GetGrayRgn());
2448 PaintBehind(LMGetWindowList(), mBarRgn);
2449 CalcVisBehind(LMGetWindowList(), mBarRgn);
2450#if 0
2451 controlStripHidden = false;
2452 if (noErr == Gestalt(
2453 gestaltControlStripVersion, &result))
2454 {
2455 if (SBIsControlStripVisible()) {
2456 controlStripHidden = true;
2457 SBShowHideControlStrip(false);
2458 }
2459 }
2460#endif
2461 }
2462 DisposeRgn(mBarRgn);
2463 }
2464 }
2465#endif
2466 }
2467}
2468#endif
2469
2470#if MayFullScreen
2471LOCALPROC My_ShowMenuBar(void)
2472{
2473#if Windows85APIAvail
2474 if (HaveHideShowMenuAvail()) {
2475 if (! IsMenuBarVisible()) {
2476 ShowMenuBar();
2477 }
2478 } else
2479#endif
2480 {
2481#if MightNotHaveWindows85Avail
2482 if (GrayRgnSave != NULL) {
2483 LMSetMBarHeight(mBarHeightSave);
2484 CopyRgn(GrayRgnSave, My_GetGrayRgn());
2485 /*
2486 PaintBehind(LMGetWindowList(), GrayRgnSave);
2487 CalcVisBehind(LMGetWindowList(), GrayRgnSave);
2488 */
2489 DisposeRgn(GrayRgnSave);
2490 DrawMenuBar();
2491 GrayRgnSave = NULL;
2492#if 0
2493 if (controlStripHidden) {
2494 controlStripHidden = falseblnr;
2495 if (noErr ==
2496 Gestalt(gestaltControlStripVersion, &result))
2497 {
2498 SBShowHideControlStrip(true);
2499 }
2500 }
2501#endif
2502 }
2503#endif
2504 }
2505}
2506#endif
2507
2508#if IncludePbufs
2509LOCALVAR Handle PbufDat[NumPbufs];
2510#endif
2511
2512#if IncludePbufs
2513LOCALFUNC tMacErr PbufNewFromHandle(Handle h, ui5b count, tPbuf *r)
2514{
2515 tPbuf i;
2516 tMacErr err;
2517
2518 if (! FirstFreePbuf(&i)) {
2519 DisposeHandle(h);
2520 err = mnvm_miscErr;
2521 } else {
2522 *r = i;
2523 PbufDat[i] = h;
2524 PbufNewNotify(i, count);
2525 err = mnvm_noErr;
2526 }
2527
2528 return err;
2529}
2530#endif
2531
2532#if IncludePbufs
2533GLOBALOSGLUFUNC tMacErr PbufNew(ui5b count, tPbuf *r)
2534{
2535 Handle h;
2536 tMacErr err = mnvm_miscErr;
2537
2538 h = NewHandleClear(count);
2539 if (h != NULL) {
2540 err = PbufNewFromHandle(h, count, r);
2541 }
2542
2543 return err;
2544}
2545#endif
2546
2547#if IncludePbufs
2548GLOBALOSGLUPROC PbufDispose(tPbuf i)
2549{
2550 DisposeHandle(PbufDat[i]);
2551 PbufDisposeNotify(i);
2552}
2553#endif
2554
2555#if IncludePbufs
2556LOCALPROC UnInitPbufs(void)
2557{
2558 tPbuf i;
2559
2560 for (i = 0; i < NumPbufs; ++i) {
2561 if (PbufIsAllocated(i)) {
2562 PbufDispose(i);
2563 }
2564 }
2565}
2566#endif
2567
2568#if IncludePbufs
2569#define PbufHaveLock 1
2570#endif
2571
2572#if IncludePbufs
2573LOCALFUNC ui3p PbufLock(tPbuf i)
2574{
2575 ui3p p;
2576
2577 Handle h = PbufDat[i];
2578
2579 if (NULL == h) {
2580 p = nullpr;
2581 } else {
2582 HLock(h);
2583 p = (ui3p)*h;
2584 }
2585
2586 return p;
2587}
2588#endif
2589
2590#if IncludePbufs
2591LOCALPROC PbufUnlock(tPbuf i)
2592{
2593 HUnlock(PbufDat[i]);
2594}
2595#endif
2596
2597#if IncludePbufs
2598GLOBALOSGLUPROC PbufTransfer(ui3p Buffer,
2599 tPbuf i, ui5r offset, ui5r count, blnr IsWrite)
2600{
2601 Handle h = PbufDat[i];
2602
2603 HLock(h);
2604 {
2605 void *p = ((ui3p)*h) + offset;
2606 if (IsWrite) {
2607 BlockMove(Buffer, p, count);
2608 } else {
2609 BlockMove(p, Buffer, count);
2610 }
2611 }
2612 HUnlock(h);
2613}
2614#endif
2615
2616/* --- clipboard --- */
2617
2618#if IncludeHostTextClipExchange
2619GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
2620{
2621 OSErr err;
2622
2623 err = ZeroScrap();
2624 if (noErr == err) {
2625 ui5b L = PbufSize[i];
2626 Handle h = PbufDat[i];
2627 HLock(h);
2628 err = PutScrap(L, 'TEXT', *h);
2629 HUnlock(h);
2630 }
2631
2632 PbufDispose(i);
2633
2634 return (tMacErr)err;
2635}
2636#endif
2637
2638#if IncludeHostTextClipExchange
2639GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
2640{
2641 long off;
2642 long v;
2643 Handle h;
2644 OSErr err = (OSErr)mnvm_miscErr;
2645
2646 h = NewHandle(0);
2647 if (h != NULL) {
2648 v = GetScrap(h, 'TEXT', &off);
2649 if (v < 0) {
2650 err = v;
2651 } else {
2652 err = (OSErr)PbufNewFromHandle(h, v, r);
2653 h = NULL;
2654 }
2655 if (NULL != h) {
2656 DisposeHandle(h);
2657 }
2658 }
2659
2660 return (tMacErr)err;
2661}
2662#endif
2663
2664/* --- drives --- */
2665
2666LOCALVAR short Drives[NumDrives]; /* open disk image files */
2667#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
2668LOCALVAR Handle DriveNames[NumDrives];
2669#endif
2670
2671LOCALPROC InitDrives(void)
2672{
2673 /*
2674 This isn't really needed, Drives[i] and DriveNames[i]
2675 need not have valid values when not vSonyIsInserted[i].
2676 */
2677 tDrive i;
2678
2679 for (i = 0; i < NumDrives; ++i) {
2680 Drives[i] = NotAfileRef;
2681#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
2682 DriveNames[i] = NULL;
2683#endif
2684 }
2685}
2686
2687GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
2688 tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
2689 ui5r *Sony_ActCount)
2690{
2691 tMacErr result;
2692 ui5r NewSony_Count = Sony_Count;
2693
2694 result =
2695 (tMacErr)SetFPos(Drives[Drive_No], fsFromStart, Sony_Start);
2696 if (mnvm_noErr == result) {
2697 if (IsWrite) {
2698 /*
2699 write Sony_Count bytes from Buffer, to disk image
2700 number Drive_No, starting at offset Sony_Start.
2701 */
2702
2703 result = (tMacErr)FSWrite(Drives[Drive_No],
2704 (long *)&NewSony_Count, Buffer);
2705 } else {
2706 /*
2707 read Sony_Count bytes into Buffer, from disk image
2708 number Drive_No, starting at offset Sony_Start.
2709 */
2710
2711 result = (tMacErr)FSRead(Drives[Drive_No],
2712 (long *)&NewSony_Count, Buffer);
2713 }
2714 }
2715
2716 if (nullpr != Sony_ActCount) {
2717 *Sony_ActCount = NewSony_Count;
2718 }
2719
2720 return result;
2721}
2722
2723GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
2724{
2725 return GetEOF(Drives[Drive_No], (long *)Sony_Count);
2726}
2727
2728LOCALFUNC OSErr vSonyEject0(tDrive Drive_No)
2729{
2730 short refnum = Drives[Drive_No];
2731 Drives[Drive_No] = NotAfileRef; /* not really needed */
2732
2733 DiskEjectedNotify(Drive_No);
2734
2735#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
2736 {
2737 Handle h = DriveNames[Drive_No];
2738 if (NULL != h) {
2739 DisposeHandle(h);
2740 DriveNames[Drive_No] = NULL; /* not really needed */
2741 }
2742 }
2743#endif
2744
2745 return FSClose(refnum);
2746}
2747
2748GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
2749{
2750 OSErr result;
2751 short vRefNum;
2752 blnr DidEject = falseblnr;
2753 short refnum = Drives[Drive_No];
2754
2755 result = GetVRefNum(refnum, &vRefNum);
2756 if (noErr == result) {
2757 DidEject = trueblnr;
2758 result = vSonyEject0(Drive_No);
2759 (void) FlushVol(NULL, vRefNum);
2760 }
2761
2762 if (! DidEject) {
2763 result = vSonyEject0(Drive_No);
2764 }
2765
2766 return (tMacErr)result;
2767}
2768
2769#if IncludeSonyNew
2770GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
2771{
2772 OSErr result;
2773 Str255 s;
2774 blnr DidEject = falseblnr;
2775 short refnum = Drives[Drive_No];
2776
2777#if HaveCPUfamM68K
2778 if (! HaveFSSpecCallsAvail()) {
2779 Handle h = DriveNames[Drive_No];
2780 if (NULL != h) {
2781 short vRefNum;
2782 result = GetVRefNum(refnum, &vRefNum);
2783 if (noErr == result) {
2784 PStrFromHandle(s, h, 255);
2785 result = vSonyEject0(Drive_No);
2786 DidEject = trueblnr;
2787 (void) FSDelete(s, vRefNum);
2788 }
2789 }
2790 } else
2791#endif
2792 {
2793 FCBPBRec b;
2794
2795 b.ioCompletion = NULL;
2796 b.ioNamePtr = (StringPtr)s;
2797 b.ioVRefNum = 0;
2798 b.ioRefNum = refnum;
2799 b.ioFCBIndx = 0;
2800 result = PBGetFCBInfoSync(&b);
2801 if (noErr == result) {
2802 FSSpec spec;
2803 result = FSMakeFSSpec(b.ioFCBVRefNum, b.ioFCBParID,
2804 s, &spec);
2805 if (noErr == result) {
2806 result = vSonyEject0(Drive_No);
2807 DidEject = trueblnr;
2808 (void) FSpDelete(&spec);
2809 }
2810 }
2811 }
2812
2813 if (! DidEject) {
2814 (void) vSonyEject0(Drive_No);
2815 }
2816
2817 return (tMacErr)result;
2818}
2819#endif
2820
2821LOCALPROC UnInitDrives(void)
2822{
2823 tDrive i;
2824
2825 for (i = 0; i < NumDrives; ++i) {
2826 if (vSonyIsInserted(i)) {
2827 (void) vSonyEject(i);
2828 }
2829 }
2830}
2831
2832#if IncludeSonyGetName
2833GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
2834{
2835 FCBPBRec b;
2836 Str255 s;
2837 tMacErr err = mnvm_miscErr;
2838
2839#if HaveCPUfamM68K
2840 if (! HaveFSSpecCallsAvail()) {
2841 Handle h = DriveNames[Drive_No];
2842 if (NULL != h) {
2843 PStrFromHandle(s, h, 255);
2844 err = mnvm_noErr;
2845 }
2846 } else
2847#endif
2848 {
2849 b.ioCompletion = NULL;
2850 b.ioNamePtr = (StringPtr)s;
2851 b.ioVRefNum = 0;
2852 b.ioRefNum = Drives[Drive_No];
2853 b.ioFCBIndx = 0;
2854 err = To_tMacErr(PBGetFCBInfoSync(&b));
2855 }
2856
2857 if (mnvm_noErr == err) {
2858 Handle h;
2859 err = PStrToHand(s, &h);
2860 if (noErr == err) {
2861 err = PbufNewFromHandle(h, s[0], r);
2862 }
2863 }
2864
2865 return err;
2866}
2867#endif
2868
2869LOCALFUNC tMacErr Sony_Insert0(short refnum, blnr locked, ps3p s)
2870{
2871 tDrive Drive_No;
2872
2873#if ! ((IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K)
2874 UnusedParam(s);
2875#endif
2876
2877 if (! FirstFreeDisk(&Drive_No)) {
2878 (void) FSClose(refnum);
2879 return mnvm_tmfoErr; /* too many files open */
2880 } else {
2881 Drives[Drive_No] = refnum;
2882 DiskInsertNotify(Drive_No, locked);
2883#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
2884 if (s != NULL) {
2885 Handle h;
2886
2887 if (mnvm_noErr != PStrToHand(s, &h)) {
2888 h = NULL;
2889 }
2890 DriveNames[Drive_No] = h;
2891 }
2892#endif
2893 return mnvm_noErr;
2894 }
2895}
2896
2897LOCALPROC ReportStandardOpenDiskError(tMacErr err)
2898{
2899 if (mnvm_noErr != err) {
2900 if (mnvm_tmfoErr == err) {
2901 MacMsg(kStrTooManyImagesTitle,
2902 kStrTooManyImagesMessage, falseblnr);
2903 } else if (mnvm_opWrErr == err) {
2904 MacMsg(kStrImageInUseTitle,
2905 kStrImageInUseMessage, falseblnr);
2906 } else {
2907 MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
2908 }
2909 }
2910}
2911
2912LOCALFUNC tMacErr InsertADiskFromFileRef(FSSpec *spec)
2913{
2914 short refnum;
2915 tMacErr err;
2916 blnr locked = falseblnr;
2917
2918 err = To_tMacErr(FSpOpenDF(spec, fsRdWrPerm, &refnum));
2919 switch (err) {
2920 case mnvm_permErr:
2921 case mnvm_wrPermErr:
2922 case mnvm_afpAccessDenied:
2923 locked = trueblnr;
2924 err = To_tMacErr(FSpOpenDF(spec, fsRdPerm, &refnum));
2925 break;
2926 default:
2927 break;
2928 }
2929 if (mnvm_noErr == err) {
2930 err = Sony_Insert0(refnum, locked, NULL);
2931 }
2932
2933 return err;
2934}
2935
2936#if HaveCPUfamM68K
2937LOCALFUNC tMacErr InsertADiskFromNamevRef(ConstStr255Param fileName,
2938 short vRefNum)
2939{
2940 ParamBlockRec R;
2941 tMacErr err;
2942 blnr locked = falseblnr;
2943
2944 R.ioParam.ioCompletion = NULL;
2945 R.ioParam.ioNamePtr = (StringPtr)fileName;
2946 R.ioParam.ioVRefNum = vRefNum;
2947 R.ioParam.ioVersNum = 0;
2948 R.ioParam.ioPermssn = fsRdWrPerm;
2949 R.ioParam.ioMisc = NULL;
2950 err = To_tMacErr(PBOpen(&R, false));
2951 switch (err) {
2952 case mnvm_permErr:
2953 case mnvm_wrPermErr:
2954 case mnvm_afpAccessDenied:
2955 locked = trueblnr;
2956 R.ioParam.ioPermssn = fsRdPerm;
2957 err = To_tMacErr(PBOpen(&R, false));
2958 break;
2959 default:
2960 break;
2961 }
2962 if (mnvm_noErr == err) {
2963 err = Sony_Insert0(R.ioParam.ioRefNum, locked, (ps3p)fileName);
2964 }
2965
2966 return err;
2967}
2968#endif
2969
2970LOCALFUNC tMacErr LoadMacRomFromRefNum(short refnum)
2971{
2972 /*
2973 load the ROM image file into ptr ROM
2974 */
2975 tMacErr err;
2976 long count = kROM_Size;
2977
2978 if (mnvm_noErr != (err = To_tMacErr(
2979 FSRead(refnum, &count, ROM))))
2980 {
2981 if (mnvm_eofErr == err) {
2982 MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage);
2983 } else {
2984 MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage);
2985 }
2986 } else
2987 {
2988 err = ROM_IsValid();
2989 }
2990
2991 return err;
2992}
2993
2994LOCALFUNC tMacErr LoadMacRomFromFSSpec(FSSpec *spec)
2995{
2996 tMacErr err;
2997 short refnum;
2998
2999 if (mnvm_noErr == (err =
3000 To_tMacErr(FSpOpenDF(spec, fsRdPerm, &refnum))))
3001 {
3002 err = LoadMacRomFromRefNum(refnum);
3003 (void) FSClose(refnum);
3004 }
3005
3006 return err;
3007}
3008
3009#if HaveCPUfamM68K
3010LOCALFUNC tMacErr LoadMacRomFromNamevRef(ConstStr255Param fileName,
3011 short vRefNum)
3012{
3013 tMacErr err;
3014 ParamBlockRec R;
3015
3016 R.ioParam.ioCompletion = NULL;
3017 R.ioParam.ioNamePtr = (StringPtr)fileName;
3018 R.ioParam.ioVRefNum = vRefNum;
3019 R.ioParam.ioVersNum = 0;
3020 R.ioParam.ioPermssn = fsRdPerm;
3021 R.ioParam.ioMisc = NULL;
3022 if (mnvm_noErr == (err = To_tMacErr(PBOpen(&R, false)))) {
3023 err = LoadMacRomFromRefNum(R.ioParam.ioRefNum);
3024 (void) FSClose(R.ioParam.ioRefNum);
3025 }
3026
3027 return err;
3028}
3029#endif
3030
3031#if HaveCPUfamM68K
3032LOCALFUNC tMacErr InsertADiskFromNamevRef1(ConstStr255Param fileName,
3033 short vRefNum)
3034{
3035 tMacErr err;
3036
3037 if (! ROM_loaded) {
3038 err = LoadMacRomFromNamevRef(fileName, vRefNum);
3039 } else {
3040 err = InsertADiskFromNamevRef(fileName, vRefNum);
3041 }
3042
3043 return err;
3044}
3045#endif
3046
3047LOCALFUNC tMacErr InsertADiskOrAliasFromSpec(FSSpec *spec,
3048 blnr MaybeROM, blnr MaybeAlias)
3049{
3050 Boolean isFolder;
3051 Boolean isAlias;
3052 tMacErr err;
3053
3054 if ((! MaybeAlias)
3055 || CheckSaveMacErr(ResolveAliasFile(spec, true,
3056 &isFolder, &isAlias)))
3057 {
3058 if (MaybeROM && ! ROM_loaded) {
3059 err = LoadMacRomFromFSSpec(spec);
3060 } else {
3061 err = InsertADiskFromFileRef(spec);
3062 }
3063 }
3064
3065 return err;
3066}
3067
3068LOCALFUNC tMacErr InsertDisksFromDocList(AEDescList *docList)
3069{
3070 tMacErr err = mnvm_noErr;
3071 long itemsInList;
3072 long index;
3073 AEKeyword keyword;
3074 DescType typeCode;
3075 FSSpec spec;
3076 Size actualSize;
3077
3078 if (CheckSaveMacErr(AECountItems(docList, &itemsInList))) {
3079 for (index = 1; index <= itemsInList; ++index) {
3080 if (CheckSaveMacErr(AEGetNthPtr(docList, index, typeFSS,
3081 &keyword, &typeCode, (Ptr)&spec, sizeof(FSSpec),
3082 &actualSize)))
3083 if (CheckSavetMacErr(InsertADiskOrAliasFromSpec(&spec,
3084 trueblnr, falseblnr)))
3085 {
3086 }
3087 if (mnvm_noErr != err) {
3088 goto label_fail;
3089 }
3090 }
3091 }
3092
3093label_fail:
3094 return err;
3095}
3096
3097LOCALFUNC tMacErr InsertADiskFromNameEtc(MyDir_R *d,
3098 ConstStr255Param fileName)
3099{
3100 tMacErr err;
3101
3102#if HaveCPUfamM68K
3103 if (! HaveFSSpecCallsAvail()) {
3104 err = InsertADiskFromNamevRef(fileName, d->VRefNum);
3105 } else
3106#endif
3107 {
3108 FSSpec spec;
3109
3110 if (CheckSaveMacErr(
3111 FSMakeFSSpec(d->VRefNum, d->DirId, fileName, &spec)))
3112 {
3113 err = InsertADiskOrAliasFromSpec(&spec,
3114 falseblnr, trueblnr);
3115 }
3116 }
3117
3118 return err;
3119}
3120
3121#if NavigationAvail
3122pascal Boolean NavigationFilterProc(
3123 AEDesc* theItem, void* info, void* NavCallBackUserData,
3124 NavFilterModes theNavFilterModes);
3125pascal Boolean NavigationFilterProc(
3126 AEDesc* theItem, void* info, void* NavCallBackUserData,
3127 NavFilterModes theNavFilterModes)
3128{
3129 Boolean display = true;
3130 NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info;
3131 UnusedParam(theNavFilterModes);
3132 UnusedParam(NavCallBackUserData);
3133
3134 if (typeFSS == theItem->descriptorType) {
3135 if (! theInfo->isFolder) {
3136 /*
3137 use:
3138 'theInfo->fileAndFolder.fileInfo.finderInfo.fdType'
3139 to check for the file type you want to filter.
3140 */
3141 }
3142 }
3143 return display;
3144}
3145#endif
3146
3147
3148#if NavigationAvail
3149pascal void NavigationEventProc(
3150 NavEventCallbackMessage callBackSelector,
3151 NavCBRecPtr callBackParms, void *NavCallBackUserData);
3152pascal void NavigationEventProc(
3153 NavEventCallbackMessage callBackSelector,
3154 NavCBRecPtr callBackParms, void *NavCallBackUserData)
3155{
3156 UnusedParam(NavCallBackUserData);
3157
3158 if (kNavCBEvent == callBackSelector) {
3159 switch (callBackParms->eventData.eventDataParms.event->what) {
3160 case updateEvt:
3161 {
3162 WindowPtr which =
3163 (WindowPtr)callBackParms
3164 ->eventData.eventDataParms.event
3165 ->message;
3166
3167 BeginUpdate(which);
3168
3169 if (which == gMyMainWindow) {
3170 Update_Screen();
3171 }
3172
3173 EndUpdate(which);
3174 }
3175 break;
3176 }
3177 }
3178}
3179#endif
3180
3181#define PStrConstBlank ((ps3p)"\000")
3182
3183LOCALPROC InsertADisk0(void)
3184{
3185#if NavigationAvail
3186#define MyDisposeNavEventUPP(userUPP) \
3187 DisposeRoutineDescriptor(userUPP)
3188#define MyDisposeNavObjectFilterUPP(userUPP) \
3189 DisposeRoutineDescriptor(userUPP)
3190#define MyNewNavObjectFilterUPP NewNavObjectFilterProc
3191#define MyNewNavEventUPP NewNavEventProc
3192
3193 if (HaveNavServicesAvail()) {
3194 NavReplyRecord theReply;
3195 NavDialogOptions dialogOptions;
3196 OSErr theErr = noErr;
3197 NavTypeListHandle openList = NULL;
3198 NavObjectFilterUPP filterUPP =
3199 MyNewNavObjectFilterUPP(
3200 /* (NavObjectFilterProcPtr) */ NavigationFilterProc);
3201 NavEventUPP eventUPP = MyNewNavEventUPP(
3202 /* (NavEventProcPtr) */ NavigationEventProc);
3203
3204 theErr = NavGetDefaultDialogOptions(&dialogOptions);
3205
3206 dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
3207 /*
3208 dialogOptions.dialogOptionFlags &= ~ kNavAllowMultipleFiles;
3209 */
3210 dialogOptions.dialogOptionFlags &= ~ kNavAllowPreviews;
3211
3212 MyBeginDialog();
3213 theErr = NavGetFile(NULL,
3214 &theReply,
3215 &dialogOptions,
3216 /* NULL */ eventUPP,
3217 NULL,
3218 filterUPP,
3219 (NavTypeListHandle)openList,
3220 NULL);
3221 MyEndDialog();
3222
3223 MyDisposeNavObjectFilterUPP(filterUPP);
3224 MyDisposeNavEventUPP(eventUPP);
3225
3226
3227 if (noErr == theErr) {
3228 if (theReply.validRecord) {
3229 ReportStandardOpenDiskError(InsertDisksFromDocList(
3230 &theReply.selection));
3231 }
3232
3233 NavDisposeReply(&theReply);
3234 }
3235
3236 } else
3237#endif
3238#if HaveCPUfamM68K
3239 if (! HaveFSSpecCallsAvail()) {
3240 Point where;
3241 SFReply reply;
3242
3243 where.h = 50;
3244 where.v = 50;
3245 MyBeginDialog();
3246 SFGetFile(*(Point *)&where, PStrConstBlank, NULL,
3247 -1 /* kNumFileTypes */, NULL /* fileTypes */,
3248 NULL, &reply);
3249 MyEndDialog();
3250 if (reply.good) {
3251 ReportStandardOpenDiskError(
3252 InsertADiskFromNamevRef1(reply.fName, reply.vRefNum));
3253 }
3254 } else
3255#endif
3256 {
3257 StandardFileReply reply;
3258
3259 MyBeginDialog();
3260 StandardGetFile(0L, -1, 0L, &reply);
3261 MyEndDialog();
3262 if (reply.sfGood) {
3263 ReportStandardOpenDiskError(
3264 InsertADiskOrAliasFromSpec(&reply.sfFile,
3265 trueblnr, falseblnr));
3266 }
3267 }
3268}
3269
3270#ifndef MyAppIsBundle
3271#define MyAppIsBundle 0
3272#endif
3273
3274LOCALVAR MyDir_R MyDatDir;
3275
3276#if MyAppIsBundle
3277LOCALFUNC blnr DirectorySpec2DirId(FSSpec *spec, long *dirID)
3278{
3279 CInfoPBRec b;
3280
3281 b.hFileInfo.ioCompletion = NULL;
3282 b.hFileInfo.ioNamePtr = (StringPtr)spec->name;
3283 b.hFileInfo.ioVRefNum = spec->vRefNum;
3284 b.dirInfo.ioFDirIndex = 0;
3285 b.dirInfo.ioDrDirID = spec->parID;
3286 if (noErr == PBGetCatInfo(&b, false)) {
3287 *dirID = b.dirInfo.ioDrDirID;
3288 return trueblnr;
3289 } else {
3290 return falseblnr;
3291 }
3292}
3293#endif
3294
3295#if MyAppIsBundle
3296LOCALFUNC blnr FindNamedChildDirId(short TrueParentVol,
3297 long ParentDirId, StringPtr ChildName,
3298 short *TrueChildVol, long *ChildDirId)
3299{
3300
3301 FSSpec temp_spec;
3302 Boolean isFolder;
3303 Boolean isAlias;
3304
3305 if (noErr == FSMakeFSSpec(TrueParentVol, ParentDirId,
3306 ChildName, &temp_spec))
3307 if (noErr == ResolveAliasFile(&temp_spec, true,
3308 &isFolder, &isAlias))
3309 if (isFolder)
3310 if (DirectorySpec2DirId(&temp_spec, ChildDirId))
3311 {
3312 *TrueChildVol = temp_spec.vRefNum;
3313 return trueblnr;
3314 }
3315 return falseblnr;
3316}
3317#endif
3318
3319LOCALFUNC blnr InitMyApplInfo(void)
3320{
3321#if HaveCPUfamM68K
3322 if (! HaveFSSpecCallsAvail()) {
3323 if (noErr == GetVol(NULL, &MyDatDir.VRefNum)) {
3324 MyDatDir.DirId = 0;
3325 return trueblnr;
3326 }
3327 } else
3328#endif
3329 {
3330 FCBPBRec pb;
3331 Str255 fileName;
3332
3333 pb.ioCompletion = NULL;
3334 pb.ioNamePtr = fileName;
3335 pb.ioVRefNum = 0;
3336 pb.ioRefNum = CurResFile();
3337 pb.ioFCBIndx = 0;
3338 if (noErr == PBGetFCBInfoSync(&pb)) {
3339 MyDatDir.VRefNum = pb.ioFCBVRefNum;
3340 MyDatDir.DirId = pb.ioFCBParID;
3341 return trueblnr;
3342 }
3343 }
3344
3345 return falseblnr;
3346}
3347
3348LOCALFUNC tMacErr MyDirFromWD_v2(short VRefNum, MyDir_R *d)
3349{
3350 tMacErr err;
3351 Str63 s;
3352 WDPBRec pb;
3353
3354#if Support64kROM
3355 if (Have64kROM()) {
3356 d->VRefNum = VRefNum;
3357 d->DirId = 0;
3358 err = mnvm_noErr;
3359 } else
3360#endif
3361 {
3362 pb.ioCompletion = NULL;
3363 pb.ioNamePtr = s;
3364 pb.ioVRefNum = VRefNum;
3365 pb.ioWDIndex = 0;
3366 pb.ioWDProcID = 0;
3367 err = To_tMacErr(PBGetWDInfoSync(&pb));
3368 if (mnvm_noErr == err) {
3369 d->VRefNum = pb.ioWDVRefNum;
3370 d->DirId = pb.ioWDDirID;
3371 }
3372 }
3373
3374 return err;
3375}
3376
3377LOCALFUNC tMacErr FindPrefFolder(MyDir_R *d)
3378{
3379 tMacErr err;
3380 long reply;
3381
3382 if (HaveGestaltAvail()
3383 && (noErr == Gestalt(gestaltFindFolderAttr, &reply))
3384 && TestBit(reply, gestaltFindFolderPresent)
3385 )
3386 {
3387 err = To_tMacErr(FindFolder(
3388 kOnSystemDisk,
3389 kPreferencesFolderType,
3390 kDontCreateFolder,
3391 &d->VRefNum,
3392 &d->DirId));
3393 } else {
3394 SysEnvRec info;
3395
3396 err = To_tMacErr(SysEnvirons(1, &info));
3397 if (mnvm_noErr == err) {
3398 err = MyDirFromWD_v2(info.sysVRefNum, d);
3399 }
3400 }
3401
3402 return err;
3403}
3404
3405#define CatInfoIsFolder(cPB) \
3406 (((cPB)->hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0)
3407
3408#define PStrLength(s) (*(s))
3409#define SizeOfListMyChar(n) (n)
3410#define PStrToTotSize(s) (SizeOfListMyChar(PStrLength(s) + 1))
3411 /* + 1 for length byte */
3412
3413LOCALPROC PStrCopy(ps3p r, ps3p s)
3414{
3415 MyMoveBytes((anyp)s, (anyp)r, PStrToTotSize(s));
3416}
3417
3418LOCALFUNC tMacErr MyFindNamedChildDir_v2(MyDir_R *src_d, StringPtr s,
3419 MyDir_R *dst_d)
3420{
3421 tMacErr err;
3422 Str255 NameBuffer;
3423 CInfoPBRec cPB;
3424
3425 cPB.hFileInfo.ioCompletion = NULL;
3426 cPB.hFileInfo.ioVRefNum = src_d->VRefNum;
3427 cPB.dirInfo.ioDrDirID = src_d->DirId;
3428 cPB.hFileInfo.ioNamePtr = NameBuffer;
3429 PStrCopy(NameBuffer, s);
3430 cPB.dirInfo.ioFDirIndex = 0;
3431
3432 err = To_tMacErr(PBGetCatInfoSync(&cPB));
3433
3434 if (mnvm_noErr == err) {
3435 if (! CatInfoIsFolder(&cPB)) {
3436 err = mnvm_dirNFErr;
3437 } else {
3438 dst_d->VRefNum = cPB.hFileInfo.ioVRefNum;
3439 dst_d->DirId = cPB.dirInfo.ioDrDirID;
3440 }
3441 }
3442
3443 return err;
3444}
3445
3446LOCALFUNC tMacErr MyResolveAliasDir_v2(MyDir_R *src_d, StringPtr s,
3447 MyDir_R *dst_d)
3448{
3449 tMacErr err;
3450 FSSpec spec;
3451 Boolean isFolder;
3452 Boolean isAlias;
3453 MyDir_R src2_d;
3454
3455 spec.vRefNum = src_d->VRefNum;
3456 spec.parID = src_d->DirId;
3457 PStrCopy(spec.name, s);
3458 err = To_tMacErr(
3459 ResolveAliasFile(&spec, true, &isFolder, &isAlias));
3460 if (mnvm_noErr == err) {
3461 if (! isAlias) {
3462 err = mnvm_dirNFErr;
3463 } else {
3464 src2_d.VRefNum = spec.vRefNum;
3465 src2_d.DirId = spec.parID;
3466 err = MyFindNamedChildDir_v2(&src2_d, spec.name, dst_d);
3467 }
3468 }
3469
3470 return err;
3471}
3472
3473LOCALFUNC tMacErr MyResolveNamedChildDir_v2(MyDir_R *src_d, StringPtr s,
3474 MyDir_R *dst_d)
3475{
3476 tMacErr err;
3477
3478 err = MyFindNamedChildDir_v2(src_d, s, dst_d);
3479 if (mnvm_dirNFErr == err) {
3480 if (HaveAliasMgrAvail()) {
3481 err = MyResolveAliasDir_v2(src_d, s, dst_d);
3482 }
3483 }
3484
3485 return err;
3486}
3487
3488LOCALFUNC tMacErr OpenNamedFileInFolderCStr(MyDir_R *d,
3489 char *s, short *refnum)
3490{
3491 Str255 fileName;
3492
3493 PStrFromCStr(fileName, s);
3494 return OpenNamedFileInFolder(d, fileName, refnum);
3495}
3496
3497LOCALFUNC tMacErr MyResolveNamedChildDirCStr(MyDir_R *src_d,
3498 char *s, MyDir_R *dst_d)
3499{
3500 Str255 fileName;
3501
3502 PStrFromCStr(fileName, s);
3503 return MyResolveNamedChildDir_v2(src_d, fileName, dst_d);
3504}
3505
3506LOCALFUNC tMacErr LoadMacRomFromNameFolder(MyDir_R *d,
3507 char *s)
3508{
3509 tMacErr err;
3510 short refnum;
3511
3512 if (mnvm_noErr == (err =
3513 OpenNamedFileInFolderCStr(d, s, &refnum)))
3514 {
3515 err = LoadMacRomFromRefNum(refnum);
3516 (void) FSClose(refnum);
3517 }
3518
3519 return err;
3520}
3521
3522LOCALFUNC tMacErr LoadMacRomFromPrefDir(void)
3523{
3524 tMacErr err;
3525 MyDir_R PrefRef;
3526 MyDir_R GryphelRef;
3527 MyDir_R ROMsRef;
3528
3529 if (mnvm_noErr == (err = FindPrefFolder(&PrefRef)))
3530 if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&PrefRef,
3531 "Gryphel", &GryphelRef)))
3532 if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&GryphelRef,
3533 "mnvm_rom", &ROMsRef)))
3534 if (mnvm_noErr == (err = LoadMacRomFromNameFolder(&ROMsRef,
3535 RomFileName)))
3536 {
3537 /* ok */
3538 }
3539
3540 return err;
3541}
3542
3543LOCALFUNC blnr LoadMacRom(void)
3544{
3545 tMacErr err;
3546
3547 if (mnvm_fnfErr == (err =
3548 LoadMacRomFromNameFolder(&MyDatDir, RomFileName)))
3549 if (mnvm_fnfErr == (err =
3550 LoadMacRomFromPrefDir()))
3551 {
3552 }
3553
3554 return trueblnr; /* keep launching Mini vMac, regardless */
3555}
3556
3557LOCALFUNC blnr Sony_InsertIth(int i)
3558{
3559 if ((i > 9) || ! FirstFreeDisk(nullpr)) {
3560 return falseblnr;
3561 } else {
3562 Str255 s;
3563 tMacErr err = mnvm_noErr;
3564
3565 PStrFromCStr(s, "disk?.dsk");
3566
3567 s[5] = '0' + i;
3568 if (! CheckSavetMacErr(InsertADiskFromNameEtc(&MyDatDir, s))) {
3569 if (mnvm_fnfErr != err) {
3570 ReportStandardOpenDiskError(err);
3571 }
3572 return falseblnr;
3573 }
3574
3575 return trueblnr;
3576 }
3577}
3578
3579LOCALFUNC blnr LoadInitialImages(void)
3580{
3581 int i;
3582
3583 for (i = 1; Sony_InsertIth(i); ++i) {
3584 /* stop on first error (including file not found) */
3585 }
3586
3587 return trueblnr;
3588}
3589
3590#if IncludeSonyNew
3591LOCALFUNC tMacErr WriteZero(SInt16 refnum, ui5b L)
3592{
3593#define ZeroBufferSize 2048
3594 tMacErr err;
3595 ui5b i;
3596 ui3b buffer[ZeroBufferSize];
3597
3598 if (CheckSaveMacErr(SetFPos(refnum, fsFromStart, 0))) {
3599
3600 for (i = 0; i < ZeroBufferSize; ++i) {
3601 buffer[i] = 0;
3602 }
3603 while (L > 0) {
3604 i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
3605 err = To_tMacErr(FSWrite(refnum, (long *)&i, buffer));
3606 if (mnvm_noErr != err) {
3607 goto label_fail;
3608 }
3609 L -= i;
3610 }
3611 }
3612
3613label_fail:
3614 return err;
3615}
3616#endif
3617
3618#if HaveCPUfamM68K && IncludeSonyNew
3619LOCALPROC MakeNewDiskFromNamevRef(ps3p Name, short vRefNum,
3620 ui5b L)
3621{
3622 short refNum;
3623 tMacErr err;
3624
3625 err = To_tMacErr(Create(Name, vRefNum, '????', '????'));
3626 if (mnvm_dupFNErr == err) {
3627 if (CheckSaveMacErr(FSDelete(Name, vRefNum))) {
3628 err = To_tMacErr(Create(Name, vRefNum, '????', '????'));
3629 }
3630 }
3631 if (mnvm_noErr == err) {
3632 if (CheckSaveMacErr(FSOpen(Name, vRefNum, &refNum))) {
3633 if (CheckSaveMacErr(SetEOF(refNum, L))) {
3634 if (CheckSavetMacErr(WriteZero(refNum, L))) {
3635 err = Sony_Insert0(refNum, falseblnr, Name);
3636 ReportStandardOpenDiskError(err);
3637 refNum = NotAfileRef;
3638 }
3639 }
3640 if (NotAfileRef != refNum) {
3641 (void) FSClose(refNum);
3642 }
3643 }
3644 if (mnvm_noErr != err) {
3645 (void) FSDelete(Name, vRefNum);
3646 }
3647 }
3648}
3649#endif
3650
3651#if IncludeSonyNew
3652LOCALPROC MakeNewDiskFromSpec(FSSpec *NewFileSpec,
3653 ui5b L)
3654{
3655 short refNum;
3656 tMacErr err;
3657
3658 err = To_tMacErr(FSpCreate(NewFileSpec,
3659 '????', '????', smSystemScript));
3660 if (mnvm_dupFNErr == err) {
3661 err = To_tMacErr(FSpDelete(NewFileSpec));
3662 if (mnvm_noErr == err) {
3663 err = To_tMacErr(FSpCreate(NewFileSpec,
3664 '????', '????', smSystemScript));
3665 }
3666 }
3667 if (mnvm_noErr == err) {
3668 if (CheckSaveMacErr(
3669 FSpOpenDF(NewFileSpec, fsRdWrPerm, &refNum)))
3670 {
3671 if (CheckSaveMacErr(SetEOF(refNum, L))) {
3672 if (CheckSavetMacErr(WriteZero(refNum, L))) {
3673 err = Sony_Insert0(refNum, falseblnr, NULL);
3674 ReportStandardOpenDiskError(err);
3675 refNum = NotAfileRef;
3676 }
3677 }
3678 if (NotAfileRef != refNum) {
3679 (void) FSClose(refNum);
3680 }
3681 }
3682 if (mnvm_noErr != err) {
3683 (void) FSpDelete(NewFileSpec);
3684 }
3685 }
3686}
3687#endif
3688
3689#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
3690LOCALFUNC tMacErr MyMakeNamedDir_v2(MyDir_R *d, StringPtr s,
3691 MyDir_R *new_d)
3692{
3693 tMacErr err;
3694 HParamBlockRec r;
3695
3696 r.fileParam.ioCompletion = NULL;
3697 r.fileParam.ioVRefNum = d->VRefNum;
3698 r.fileParam.ioDirID = d->DirId;
3699 r.fileParam.ioNamePtr = s;
3700 err = To_tMacErr(PBDirCreateSync(&r));
3701 if (mnvm_noErr == err) {
3702 new_d->VRefNum = d->VRefNum;
3703 new_d->DirId = r.fileParam.ioDirID;
3704 }
3705
3706 return err;
3707}
3708#endif
3709
3710#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
3711LOCALFUNC tMacErr FindOrMakeMakeNamedDir_v2(MyDir_R *new_d,
3712 MyDir_R *d, StringPtr s)
3713{
3714 tMacErr err;
3715
3716 err = MyResolveNamedChildDir_v2(d, s, new_d);
3717 if (mnvm_fnfErr == err) {
3718 err = MyMakeNamedDir_v2(d, s, new_d);
3719 }
3720
3721 return err;
3722}
3723#endif
3724
3725#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
3726LOCALFUNC tMacErr FindOrMakeChildDirCStr(MyDir_R *new_d,
3727 MyDir_R *d, char *name)
3728{
3729 Str255 s;
3730
3731 PStrFromCStr(s, name);
3732 return FindOrMakeMakeNamedDir_v2(new_d, d, s);
3733}
3734#endif
3735
3736#if IncludeSonyNew
3737LOCALPROC MakeNewDisk(ui5b L, Handle NewDiskName)
3738{
3739#if SaveDialogEnable
3740 OSErr theErr;
3741
3742#if NavigationAvail
3743 if (HaveNavServicesAvail()) {
3744 NavReplyRecord theReply;
3745 NavDialogOptions dialogOptions;
3746 NavEventUPP eventUPP = MyNewNavEventUPP(
3747 /* (NavEventProcPtr) */ NavigationEventProc);
3748
3749 theErr = NavGetDefaultDialogOptions(&dialogOptions);
3750 dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
3751#if IncludeSonyNameNew
3752 if (NewDiskName != NULL) {
3753 PStrFromHandle(dialogOptions.savedFileName,
3754 NewDiskName, 255);
3755 }
3756#endif
3757 MyBeginDialog();
3758 theErr = NavPutFile(NULL, &theReply, &dialogOptions,
3759 /* NULL */ eventUPP, '????', '????', NULL);
3760 MyEndDialog();
3761
3762 MyDisposeNavEventUPP(eventUPP);
3763
3764 if (noErr == theErr) {
3765 if (theReply.validRecord) {
3766 long itemsInList;
3767 AEKeyword keyword;
3768 DescType typeCode;
3769 Size actualSize;
3770 FSSpec NewFileSpec;
3771
3772 if (noErr ==
3773 AECountItems(&theReply.selection, &itemsInList))
3774 if (1 == itemsInList)
3775 if (noErr == AEGetNthPtr(&theReply.selection,
3776 1, typeFSS, &keyword, &typeCode,
3777 (Ptr)&NewFileSpec, sizeof(FSSpec), &actualSize))
3778 {
3779 MakeNewDiskFromSpec(&NewFileSpec, L);
3780 }
3781 }
3782 NavDisposeReply(&theReply);
3783 }
3784 } else
3785#endif
3786 {
3787 Str255 Title;
3788 Str255 prompt;
3789
3790#if IncludeSonyNameNew
3791 if (NewDiskName != NULL) {
3792 PStrFromHandle(Title, NewDiskName, 255);
3793 } else
3794#endif
3795 {
3796 NativeStrFromCStr(Title, "untitled", falseblnr);
3797 }
3798 NativeStrFromCStr(prompt, "Please select a file", falseblnr);
3799
3800#if HaveCPUfamM68K
3801 if (! HaveFSSpecCallsAvail()) {
3802 Point where;
3803 SFReply reply;
3804
3805 where.h = 50;
3806 where.v = 50;
3807 MyBeginDialog();
3808 SFPutFile(*(Point *)&where, prompt, Title, NULL, &reply);
3809 MyEndDialog();
3810
3811 if (reply.good) {
3812 MakeNewDiskFromNamevRef(reply.fName,
3813 reply.vRefNum, L);
3814 }
3815 } else
3816#endif
3817 {
3818 StandardFileReply reply;
3819
3820 MyBeginDialog();
3821 StandardPutFile(prompt, Title, &reply);
3822 MyEndDialog();
3823
3824 if (reply.sfGood) {
3825 MakeNewDiskFromSpec(&reply.sfFile, L);
3826 }
3827 }
3828 }
3829#else /* SaveDialogEnable */
3830 tMacErr err;
3831 Str255 Title;
3832 MyDir_R OutDir;
3833 FSSpec spec;
3834
3835#if IncludeSonyNameNew
3836 if (NewDiskName != NULL) {
3837 PStrFromHandle(Title, NewDiskName, 255);
3838 } else
3839#endif
3840 {
3841 NativeStrFromCStr(Title, "untitled", falseblnr);
3842 }
3843
3844 if (mnvm_noErr == (err = FindOrMakeChildDirCStr(&OutDir,
3845 &MyDatDir, "out")))
3846 {
3847#if HaveCPUfamM68K
3848 if (! HaveFSSpecCallsAvail()) {
3849 MakeNewDiskFromNamevRef(Title, OutDir.VRefNum, L);
3850 } else
3851#endif
3852 {
3853 err = To_tMacErr(FSMakeFSSpec(OutDir.VRefNum, OutDir.DirId,
3854 Title, &spec));
3855 if ((mnvm_noErr == err) || (mnvm_fnfErr == err)) {
3856 MakeNewDiskFromSpec(&spec, L);
3857 }
3858 }
3859 }
3860#endif /* SaveDialogEnable */
3861}
3862#endif
3863
3864#if UseActvFile
3865
3866LOCALFUNC tMacErr MyCreateFile_v2(MyDir_R *d, StringPtr s)
3867{
3868 tMacErr err;
3869 HParamBlockRec r;
3870
3871 r.fileParam.ioFlVersNum = 0;
3872 /*
3873 Think reference says to do this,
3874 but not Inside Mac IV
3875 */
3876
3877 r.fileParam.ioCompletion = NULL;
3878 r.fileParam.ioNamePtr = s;
3879 r.fileParam.ioVRefNum = d->VRefNum;
3880 r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
3881
3882#if Support64kROM
3883 if (Have64kROM()) {
3884 err = To_tMacErr(PBCreateSync((ParamBlockRec *)&r));
3885 } else
3886#endif
3887 {
3888 r.fileParam.ioDirID = d->DirId;
3889 err = To_tMacErr(PBHCreateSync(&r));
3890 }
3891
3892 return err;
3893}
3894
3895LOCALFUNC tMacErr MyDeleteFile_v2(MyDir_R *d, StringPtr s)
3896{
3897 tMacErr err;
3898 HParamBlockRec r;
3899
3900 r.fileParam.ioCompletion = NULL;
3901 r.fileParam.ioVRefNum = d->VRefNum;
3902 r.fileParam.ioNamePtr = s;
3903 r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
3904
3905#if Support64kROM
3906 if (Have64kROM()) {
3907 err = To_tMacErr(PBDeleteSync((ParamBlockRec *)&r));
3908 } else
3909#endif
3910 {
3911 r.fileParam.ioDirID = d->DirId;
3912 err = To_tMacErr(PBHDeleteSync(&r));
3913 }
3914
3915 return err;
3916}
3917
3918LOCALFUNC tMacErr MyCreateFileOverWrite_v2(MyDir_R *d, StringPtr s)
3919{
3920 tMacErr err;
3921
3922 err = MyCreateFile_v2(d, s);
3923 if (mnvm_dupFNErr == err) {
3924 if (mnvm_noErr == (err = MyDeleteFile_v2(d, s))) {
3925 err = MyCreateFile_v2(d, s);
3926 }
3927 }
3928
3929 return err;
3930}
3931
3932LOCALFUNC tMacErr MyFileOpen_v2(MyDir_R *d, StringPtr s,
3933 char Permssn, short *refnum)
3934{
3935 tMacErr err;
3936 HParamBlockRec r;
3937
3938 r.ioParam.ioCompletion = NULL;
3939 r.ioParam.ioNamePtr = s;
3940 r.ioParam.ioVRefNum = d->VRefNum;
3941 r.ioParam.ioPermssn = Permssn;
3942 r.ioParam.ioMisc = 0; /* use volume buffer */
3943 r.ioParam.ioVersNum = 0; /* needed if MFS volume */
3944
3945#if Support64kROM
3946 if (Have64kROM()) {
3947 err = To_tMacErr(PBOpenSync((ParamBlockRec *)&r));
3948 } else
3949#endif
3950 {
3951 r.fileParam.ioDirID = d->DirId;
3952 err = To_tMacErr(PBHOpenSync(&r));
3953 }
3954
3955 if (noErr == err) {
3956 *refnum = r.ioParam.ioRefNum;
3957 /*
3958 Don't change *refnum unless file opened,
3959 so can initialize to NotAfileRef, and
3960 compare later before closing in uninit.
3961 */
3962 }
3963 return err;
3964}
3965
3966LOCALFUNC tMacErr MyFileOpenWrite_v2(MyDir_R *d, StringPtr s,
3967 short *refnum)
3968{
3969 return MyFileOpen_v2(d, s, (char)fsWrPerm, refnum);
3970}
3971
3972LOCALFUNC tMacErr MyOpenOverWriteFile_v2(MyDir_R *d, StringPtr s,
3973 short *refnum)
3974{
3975 tMacErr err;
3976
3977 err = MyCreateFileOverWrite_v2(d, s);
3978 if (mnvm_noErr == err) {
3979 err = MyFileOpenWrite_v2(d, s, refnum);
3980
3981 if (mnvm_noErr != err) {
3982 (void) MyDeleteFile_v2(d, s);
3983 /* ignore any error, since already got one */
3984 }
3985 }
3986
3987 return err;
3988}
3989
3990LOCALFUNC tMacErr MyOpenOverWriteFileCStr(MyDir_R *d, char *name,
3991 short *refnum)
3992{
3993 Str255 s;
3994
3995 PStrFromCStr(s, name);
3996 return MyOpenOverWriteFile_v2(d, s, refnum);
3997}
3998
3999#define ActvCodeFileName "act_1"
4000
4001LOCALFUNC tMacErr OpenActvCodeFile(short *refnum)
4002{
4003 tMacErr err;
4004 MyDir_R PrefRef;
4005 MyDir_R GryphelRef;
4006 MyDir_R ActRef;
4007
4008 if (mnvm_noErr == (err = FindPrefFolder(&PrefRef)))
4009 if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&PrefRef,
4010 "Gryphel", &GryphelRef)))
4011 if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&GryphelRef,
4012 "mnvm_act", &ActRef)))
4013 if (mnvm_noErr == (err = OpenNamedFileInFolderCStr(&ActRef,
4014 ActvCodeFileName, refnum)))
4015 {
4016 /* ok */
4017 }
4018
4019 return err;
4020}
4021
4022LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p)
4023{
4024 tMacErr err;
4025 short refnum;
4026
4027 if (CheckSavetMacErr(OpenActvCodeFile(&refnum))) {
4028 long count = ActvCodeFileLen;
4029 err = To_tMacErr(FSRead(refnum, &count, p));
4030 (void) FSClose(refnum);
4031 }
4032
4033 return err;
4034}
4035
4036LOCALFUNC tMacErr ActvCodeFileSave(ui3p p)
4037{
4038 tMacErr err;
4039 short refnum;
4040 MyDir_R PrefRef;
4041 MyDir_R GryphelRef;
4042 MyDir_R ActRef;
4043 long count = ActvCodeFileLen;
4044
4045 if (mnvm_noErr == (err = FindPrefFolder(&PrefRef)))
4046 if (mnvm_noErr == (err = FindOrMakeChildDirCStr(&GryphelRef,
4047 &PrefRef, "Gryphel")))
4048 if (mnvm_noErr == (err = FindOrMakeChildDirCStr(&ActRef,
4049 &GryphelRef, "mnvm_act")))
4050 if (mnvm_noErr == (err = MyOpenOverWriteFileCStr(&ActRef,
4051 ActvCodeFileName, &refnum)))
4052 {
4053 err = To_tMacErr(FSWrite(refnum, &count, p));
4054 (void) FSClose(refnum);
4055 }
4056
4057 return err;
4058 /* return mnvm_miscErr; */
4059}
4060
4061#endif /* UseActvFile */
4062
4063#define openOnly 1
4064#define openPrint 2
4065
4066LOCALFUNC blnr GotRequiredParams(AppleEvent *theAppleEvent)
4067{
4068 DescType typeCode;
4069 Size actualSize;
4070 OSErr theErr;
4071
4072 theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
4073 typeWildCard, &typeCode, NULL, 0, &actualSize);
4074 if (errAEDescNotFound == theErr) { /* No more required params. */
4075 return trueblnr;
4076 } else if (noErr == theErr) { /* More required params! */
4077 return /* CheckSysCode(errAEEventNotHandled) */ falseblnr;
4078 } else { /* Unexpected Error! */
4079 return /* CheckSysCode(theErr) */ falseblnr;
4080 }
4081}
4082
4083LOCALFUNC blnr GotRequiredParams0(AppleEvent *theAppleEvent)
4084{
4085 DescType typeCode;
4086 Size actualSize;
4087 OSErr theErr;
4088
4089 theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
4090 typeWildCard, &typeCode, NULL, 0, &actualSize);
4091 if (errAEDescNotFound == theErr) { /* No more required params. */
4092 return trueblnr;
4093 } else if (noErr == theErr) { /* More required params! */
4094 return trueblnr; /* errAEEventNotHandled; */ /*^*/
4095 } else { /* Unexpected Error! */
4096 return /* CheckSysCode(theErr) */ falseblnr;
4097 }
4098}
4099
4100/* call back */ static pascal OSErr OpenOrPrintFiles(
4101 AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
4102{
4103 /*
4104 Adapted from IM VI: AppleEvent Manager:
4105 Handling Required AppleEvents
4106 */
4107 AEDescList docList;
4108
4109 UnusedParam(reply);
4110 UnusedParam(aRefCon);
4111 /* put the direct parameter (a list of descriptors) into docList */
4112 if (noErr == (AEGetParamDesc(theAppleEvent,
4113 keyDirectObject, typeAEList, &docList)))
4114 {
4115 if (GotRequiredParams0(theAppleEvent)) {
4116 /* Check for missing required parameters */
4117 /* printIt = (openPrint == aRefCon) */
4118 ReportStandardOpenDiskError(
4119 InsertDisksFromDocList(&docList));
4120 }
4121 /* vCheckSysCode */ (void) (AEDisposeDesc(&docList));
4122 }
4123 return /* GetASysResultCode() */ 0;
4124}
4125
4126/* call back */ static pascal OSErr DoOpenEvent(
4127 AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
4128/*
4129 This is the alternative to getting an
4130 open document event on startup.
4131*/
4132{
4133 UnusedParam(reply);
4134 UnusedParam(aRefCon);
4135 if (GotRequiredParams0(theAppleEvent)) {
4136 }
4137 return /* GetASysResultCode() */ 0;
4138 /* Make sure there are no additional "required" parameters. */
4139}
4140
4141
4142/* call back */ static pascal OSErr DoQuitEvent(
4143 AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
4144{
4145 UnusedParam(reply);
4146 UnusedParam(aRefCon);
4147 if (GotRequiredParams(theAppleEvent)) {
4148 RequestMacOff = trueblnr;
4149 }
4150
4151 return /* GetASysResultCode() */ 0;
4152}
4153
4154#define MyNewAEEventHandlerUPP NewAEEventHandlerProc
4155
4156LOCALFUNC blnr MyInstallEventHandler(AEEventClass theAEEventClass,
4157 AEEventID theAEEventID, ProcPtr p,
4158 long handlerRefcon, blnr isSysHandler)
4159{
4160 return noErr == (AEInstallEventHandler(theAEEventClass,
4161 theAEEventID,
4162#if /* useUPP */ 1
4163 MyNewAEEventHandlerUPP((AEEventHandlerProcPtr)p),
4164#else
4165 (AEEventHandlerUPP)p,
4166#endif
4167 handlerRefcon, isSysHandler));
4168}
4169
4170LOCALPROC InstallAppleEventHandlers(void)
4171{
4172 if (noErr == AESetInteractionAllowed(kAEInteractWithLocal))
4173 if (MyInstallEventHandler(kCoreEventClass, kAEOpenApplication,
4174 (ProcPtr)DoOpenEvent, 0, falseblnr))
4175 if (MyInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
4176 (ProcPtr)OpenOrPrintFiles, openOnly, falseblnr))
4177 if (MyInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
4178 (ProcPtr)OpenOrPrintFiles, openPrint, falseblnr))
4179 if (MyInstallEventHandler(kCoreEventClass, kAEQuitApplication,
4180 (ProcPtr)DoQuitEvent, 0, falseblnr))
4181 {
4182 }
4183}
4184
4185#if EnableDragDrop
4186static pascal OSErr GlobalTrackingHandler(short message,
4187 WindowRef pWindow, void *handlerRefCon, DragReference theDragRef)
4188{
4189 RgnHandle hilightRgn;
4190 Rect Bounds;
4191
4192 UnusedParam(pWindow);
4193 UnusedParam(handlerRefCon);
4194 if (! ADialogIsUp) {
4195 switch(message) {
4196 case kDragTrackingEnterWindow:
4197 hilightRgn = NewRgn();
4198 if (hilightRgn != NULL) {
4199 SetScrnRectFromCoords(&Bounds,
4200 0, 0, vMacScreenHeight, vMacScreenWidth);
4201 RectRgn(hilightRgn, &Bounds);
4202 ShowDragHilite(theDragRef, hilightRgn, true);
4203 DisposeRgn(hilightRgn);
4204 }
4205 break;
4206 case kDragTrackingLeaveWindow:
4207 HideDragHilite(theDragRef);
4208 break;
4209 }
4210 }
4211
4212 return noErr;
4213}
4214#endif
4215
4216#if EnableDragDrop
4217static DragTrackingHandlerUPP gGlobalTrackingHandler = NULL;
4218#endif
4219
4220#if EnableDragDrop
4221static pascal OSErr GlobalReceiveHandler(WindowRef pWindow,
4222 void *handlerRefCon, DragReference theDragRef)
4223{
4224 unsigned short items;
4225 unsigned short index;
4226 ItemReference theItem;
4227 Size SentSize;
4228 HFSFlavor r;
4229
4230 UnusedParam(pWindow);
4231 UnusedParam(handlerRefCon);
4232 if (! ADialogIsUp)
4233 if (noErr == CountDragItems(theDragRef, &items))
4234 {
4235 for (index = 1; index <= items; ++index) {
4236 if (noErr == GetDragItemReferenceNumber(theDragRef,
4237 index, &theItem))
4238 if (noErr == GetFlavorDataSize(theDragRef,
4239 theItem, flavorTypeHFS, &SentSize))
4240 /*
4241 On very old macs SentSize might only be big enough
4242 to hold the actual file name. Have not seen this
4243 in OS X, but still leave the check
4244 as '<=' instead of '=='.
4245 */
4246 if (SentSize <= sizeof(HFSFlavor))
4247 if (noErr == GetFlavorData(theDragRef, theItem,
4248 flavorTypeHFS, (Ptr)&r, &SentSize, 0))
4249 {
4250 ReportStandardOpenDiskError(
4251 InsertADiskOrAliasFromSpec(&r.fileSpec,
4252 trueblnr, trueblnr));
4253 }
4254 }
4255
4256 if (gTrueBackgroundFlag) {
4257 ProcessSerialNumber currentProcess = {0, kCurrentProcess};
4258
4259 (void) SetFrontProcess(¤tProcess);
4260
4261 WantCmdOptOnReconnect = trueblnr;
4262 }
4263 }
4264
4265 return noErr;
4266}
4267#endif
4268
4269#if EnableDragDrop
4270static DragReceiveHandlerUPP gGlobalReceiveHandler = NULL;
4271#endif
4272
4273#if EnableDragDrop
4274#define MyNewDragTrackingHandlerUPP NewDragTrackingHandlerProc
4275#define MyNewDragReceiveHandlerUPP NewDragReceiveHandlerProc
4276#if ! OPAQUE_UPP_TYPES
4277#define MyDisposeDragReceiveHandlerUPP(userUPP) \
4278 DisposeRoutineDescriptor(userUPP)
4279#define MyDisposeDragTrackingHandlerUPP(userUPP) \
4280 DisposeRoutineDescriptor(userUPP)
4281#else
4282#define MyDisposeDragReceiveHandlerUPP DisposeDragReceiveHandlerUPP
4283#define MyDisposeDragTrackingHandlerUPP DisposeDragTrackingHandlerUPP
4284#endif
4285#endif
4286
4287#if EnableDragDrop
4288LOCALPROC UnPrepareForDragging(void)
4289{
4290 if (NULL != gGlobalReceiveHandler) {
4291 RemoveReceiveHandler(gGlobalReceiveHandler, gMyMainWindow);
4292 MyDisposeDragReceiveHandlerUPP(gGlobalReceiveHandler);
4293 gGlobalReceiveHandler = NULL;
4294 }
4295 if (NULL != gGlobalTrackingHandler) {
4296 RemoveTrackingHandler(gGlobalTrackingHandler, gMyMainWindow);
4297 MyDisposeDragTrackingHandlerUPP(gGlobalTrackingHandler);
4298 gGlobalTrackingHandler = NULL;
4299 }
4300}
4301#endif
4302
4303#if EnableDragDrop
4304LOCALFUNC blnr PrepareForDragging(void)
4305{
4306 blnr IsOk = falseblnr;
4307
4308 gGlobalTrackingHandler = MyNewDragTrackingHandlerUPP(
4309 GlobalTrackingHandler);
4310 if (gGlobalTrackingHandler != NULL) {
4311 gGlobalReceiveHandler = MyNewDragReceiveHandlerUPP(
4312 GlobalReceiveHandler);
4313 if (gGlobalReceiveHandler != NULL) {
4314 if (noErr == InstallTrackingHandler(gGlobalTrackingHandler,
4315 gMyMainWindow, nil))
4316 {
4317 if (noErr == InstallReceiveHandler(
4318 gGlobalReceiveHandler, gMyMainWindow, nil))
4319 {
4320 IsOk = trueblnr;
4321 }
4322 }
4323 }
4324 }
4325
4326 return IsOk;
4327}
4328#endif
4329
4330#if EnableMagnify
4331#define ScaleBuffSzMult (MyWindowScale * MyWindowScale)
4332#endif
4333
4334LOCALFUNC blnr MyCreateNewWindow(Rect *Bounds, WindowPtr *theWindow)
4335{
4336 WindowPtr ResultWin;
4337 blnr IsOk = falseblnr;
4338
4339 ResultWin = NewWindow(
4340 0L, Bounds, LMGetCurApName() /* "\pMini vMac" */, false,
4341 noGrowDocProc, /* Could use kWindowSimpleProc for Full Screen */
4342 (WindowPtr) -1, true, 0);
4343 if (ResultWin != NULL) {
4344 *theWindow = ResultWin;
4345
4346 IsOk = trueblnr;
4347 }
4348
4349 return IsOk;
4350}
4351
4352LOCALPROC ZapMyWState(void)
4353{
4354 gMyMainWindow = NULL;
4355 gGlobalReceiveHandler = NULL;
4356 gGlobalTrackingHandler = NULL;
4357}
4358
4359LOCALPROC CloseMainWindow(void)
4360{
4361#if EnableDragDrop
4362 UnPrepareForDragging();
4363#endif
4364
4365 if (gMyMainWindow != NULL) {
4366 DisposeWindow(gMyMainWindow);
4367 gMyMainWindow = NULL;
4368 }
4369}
4370
4371enum {
4372 kMagStateNormal,
4373#if EnableMagnify
4374 kMagStateMagnifgy,
4375#endif
4376 kNumMagStates
4377};
4378
4379#define kMagStateAuto kNumMagStates
4380
4381#if MayNotFullScreen
4382LOCALVAR int CurWinIndx;
4383LOCALVAR blnr HavePositionWins[kNumMagStates];
4384LOCALVAR Point WinPositionWins[kNumMagStates];
4385#endif
4386
4387LOCALFUNC blnr CreateMainWindow(void)
4388{
4389#if MayNotFullScreen
4390 int WinIndx;
4391#endif
4392 Rect MainScrnBounds;
4393 Rect AllScrnBounds;
4394 Rect NewWinRect;
4395 short leftPos;
4396 short topPos;
4397 short NewWindowHeight = vMacScreenHeight;
4398 short NewWindowWidth = vMacScreenWidth;
4399 blnr IsOk = falseblnr;
4400
4401#if VarFullScreen
4402 if (UseFullScreen) {
4403 My_HideMenuBar();
4404 } else {
4405 My_ShowMenuBar();
4406 }
4407#else
4408#if MayFullScreen
4409 My_HideMenuBar();
4410#endif
4411#endif
4412
4413 MyGetGrayRgnBounds(&AllScrnBounds);
4414 MyGetScreenBitsBounds(&MainScrnBounds);
4415
4416#if EnableMagnify
4417 if (UseMagnify) {
4418 NewWindowHeight *= MyWindowScale;
4419 NewWindowWidth *= MyWindowScale;
4420 }
4421#endif
4422
4423 leftPos = MainScrnBounds.left
4424 + ((MainScrnBounds.right - MainScrnBounds.left)
4425 - NewWindowWidth) / 2;
4426 topPos = MainScrnBounds.top
4427 + ((MainScrnBounds.bottom - MainScrnBounds.top)
4428 - NewWindowHeight) / 2;
4429 if (leftPos < MainScrnBounds.left) {
4430 leftPos = MainScrnBounds.left;
4431 }
4432 if (topPos < MainScrnBounds.top) {
4433 topPos = MainScrnBounds.top;
4434 }
4435
4436#if VarFullScreen
4437 if (UseFullScreen)
4438#endif
4439#if MayFullScreen
4440 {
4441 ViewHSize = MainScrnBounds.right - MainScrnBounds.left;
4442 ViewVSize = MainScrnBounds.bottom - MainScrnBounds.top;
4443#if EnableMagnify
4444 if (UseMagnify) {
4445 ViewHSize /= MyWindowScale;
4446 ViewVSize /= MyWindowScale;
4447 }
4448#endif
4449 if (ViewHSize >= vMacScreenWidth) {
4450 ViewHStart = 0;
4451 ViewHSize = vMacScreenWidth;
4452 } else {
4453 ViewHSize &= ~ 1;
4454 }
4455 if (ViewVSize >= vMacScreenHeight) {
4456 ViewVStart = 0;
4457 ViewVSize = vMacScreenHeight;
4458 } else {
4459 ViewVSize &= ~ 1;
4460 }
4461 }
4462#endif
4463
4464 /* Create window rectangle and centre it on the screen */
4465 SetRect(&MainScrnBounds, 0, 0, NewWindowWidth, NewWindowHeight);
4466 OffsetRect(&MainScrnBounds, leftPos, topPos);
4467
4468#if VarFullScreen
4469 if (UseFullScreen)
4470#endif
4471#if MayFullScreen
4472 {
4473 NewWinRect = AllScrnBounds;
4474 }
4475#endif
4476#if VarFullScreen
4477 else
4478#endif
4479#if MayNotFullScreen
4480 {
4481#if EnableMagnify
4482 if (UseMagnify) {
4483 WinIndx = kMagStateMagnifgy;
4484 } else
4485#endif
4486 {
4487 WinIndx = kMagStateNormal;
4488 }
4489
4490 if (! HavePositionWins[WinIndx]) {
4491 WinPositionWins[WinIndx].h = leftPos;
4492 WinPositionWins[WinIndx].v = topPos;
4493 HavePositionWins[WinIndx] = trueblnr;
4494 NewWinRect = MainScrnBounds;
4495 } else {
4496 SetRect(&NewWinRect, 0, 0, NewWindowWidth, NewWindowHeight);
4497 OffsetRect(&NewWinRect,
4498 WinPositionWins[WinIndx].h, WinPositionWins[WinIndx].v);
4499 }
4500 }
4501#endif
4502
4503#if MayNotFullScreen
4504 CurWinIndx = WinIndx;
4505#endif
4506
4507#if VarFullScreen
4508 if (UseFullScreen)
4509#endif
4510#if MayFullScreen
4511 {
4512 hOffset = MainScrnBounds.left - AllScrnBounds.left;
4513 vOffset = MainScrnBounds.top - AllScrnBounds.top;
4514 }
4515#endif
4516
4517 if (MyCreateNewWindow(&NewWinRect, &gMyMainWindow)) {
4518 ShowWindow(gMyMainWindow);
4519
4520 /* check if window rect valid */
4521#if VarFullScreen
4522 if (! UseFullScreen)
4523#endif
4524#if MayNotFullScreen
4525 {
4526 Rect tr;
4527
4528 if (MyGetWindowTitleBounds(gMyMainWindow, &tr)) {
4529 if (! RectInRgn(&tr, My_GetGrayRgn())) {
4530 MySetMacWindContRect(gMyMainWindow,
4531 &MainScrnBounds);
4532 if (MyGetWindowTitleBounds(gMyMainWindow, &tr)) {
4533 if (! RectInRgn(&tr, My_GetGrayRgn())) {
4534 OffsetRect(&MainScrnBounds,
4535 0, AllScrnBounds.top - tr.top);
4536 MySetMacWindContRect(gMyMainWindow,
4537 &MainScrnBounds);
4538 }
4539 }
4540 }
4541 }
4542 }
4543#endif
4544
4545#if EnableDragDrop
4546 if (HaveDragMgrAvail()) {
4547 (void) PrepareForDragging();
4548 }
4549#endif
4550
4551 IsOk = trueblnr;
4552 }
4553
4554 return IsOk;
4555}
4556
4557struct MyWState {
4558 WindowPtr f_MainWindow;
4559#if MayFullScreen
4560 short f_hOffset;
4561 short f_vOffset;
4562 ui4r f_ViewHSize;
4563 ui4r f_ViewVSize;
4564 ui4r f_ViewHStart;
4565 ui4r f_ViewVStart;
4566#endif
4567#if VarFullScreen
4568 blnr f_UseFullScreen;
4569#endif
4570#if EnableMagnify
4571 blnr f_UseMagnify;
4572#endif
4573#if MayNotFullScreen
4574 int f_CurWinIndx;
4575#endif
4576 DragTrackingHandlerUPP f_gGlobalTrackingHandler;
4577 DragReceiveHandlerUPP f_gGlobalReceiveHandler;
4578};
4579typedef struct MyWState MyWState;
4580
4581LOCALPROC GetMyWState(MyWState *r)
4582{
4583 r->f_MainWindow = gMyMainWindow;
4584#if MayFullScreen
4585 r->f_hOffset = hOffset;
4586 r->f_vOffset = vOffset;
4587 r->f_ViewHSize = ViewHSize;
4588 r->f_ViewVSize = ViewVSize;
4589 r->f_ViewHStart = ViewHStart;
4590 r->f_ViewVStart = ViewVStart;
4591#endif
4592#if VarFullScreen
4593 r->f_UseFullScreen = UseFullScreen;
4594#endif
4595#if EnableMagnify
4596 r->f_UseMagnify = UseMagnify;
4597#endif
4598#if MayNotFullScreen
4599 r->f_CurWinIndx = CurWinIndx;
4600#endif
4601 r->f_gGlobalTrackingHandler = gGlobalTrackingHandler;
4602 r->f_gGlobalReceiveHandler = gGlobalReceiveHandler;
4603}
4604
4605LOCALPROC SetMyWState(MyWState *r)
4606{
4607 gMyMainWindow = r->f_MainWindow;
4608#if MayFullScreen
4609 hOffset = r->f_hOffset;
4610 vOffset = r->f_vOffset;
4611 ViewHSize = r->f_ViewHSize;
4612 ViewVSize = r->f_ViewVSize;
4613 ViewHStart = r->f_ViewHStart;
4614 ViewVStart = r->f_ViewVStart;
4615#endif
4616#if VarFullScreen
4617 UseFullScreen = r->f_UseFullScreen;
4618#endif
4619#if EnableMagnify
4620 UseMagnify = r->f_UseMagnify;
4621#endif
4622#if MayNotFullScreen
4623 CurWinIndx = r->f_CurWinIndx;
4624#endif
4625 gGlobalTrackingHandler = r->f_gGlobalTrackingHandler;
4626 gGlobalReceiveHandler = r->f_gGlobalReceiveHandler;
4627}
4628
4629LOCALFUNC blnr ReCreateMainWindow(void)
4630{
4631 MyWState old_state;
4632 MyWState new_state;
4633
4634#if VarFullScreen
4635 if (! UseFullScreen)
4636#endif
4637#if MayNotFullScreen
4638 {
4639 /* save old position */
4640 if (gMyMainWindow != NULL) {
4641 Rect r;
4642
4643 if (MyGetWindowContBounds(gMyMainWindow, &r)) {
4644 WinPositionWins[CurWinIndx].h = r.left;
4645 WinPositionWins[CurWinIndx].v = r.top;
4646 }
4647 }
4648 }
4649#endif
4650
4651#if MayFullScreen
4652 UngrabMachine();
4653#endif
4654
4655 GetMyWState(&old_state);
4656
4657 ZapMyWState();
4658
4659#if VarFullScreen
4660 UseFullScreen = WantFullScreen;
4661#endif
4662#if EnableMagnify
4663 UseMagnify = WantMagnify;
4664#endif
4665
4666 ColorTransValid = falseblnr;
4667
4668 if (! CreateMainWindow()) {
4669 CloseMainWindow();
4670 SetMyWState(&old_state);
4671
4672#if VarFullScreen
4673 if (UseFullScreen) {
4674 My_HideMenuBar();
4675 } else {
4676 My_ShowMenuBar();
4677 }
4678#endif
4679
4680 /* avoid retry */
4681#if VarFullScreen
4682 WantFullScreen = UseFullScreen;
4683#endif
4684#if EnableMagnify
4685 WantMagnify = UseMagnify;
4686#endif
4687
4688 return falseblnr;
4689 } else {
4690 GetMyWState(&new_state);
4691 SetMyWState(&old_state);
4692 CloseMainWindow();
4693 SetMyWState(&new_state);
4694
4695 if (HaveCursorHidden) {
4696 (void) MyMoveMouse(CurMouseH, CurMouseV);
4697 WantCursorHidden = trueblnr;
4698 }
4699
4700 return trueblnr;
4701 }
4702}
4703
4704#if VarFullScreen && EnableMagnify
4705enum {
4706 kWinStateWindowed,
4707#if EnableMagnify
4708 kWinStateFullScreen,
4709#endif
4710 kNumWinStates
4711};
4712#endif
4713
4714#if VarFullScreen && EnableMagnify
4715LOCALVAR int WinMagStates[kNumWinStates];
4716#endif
4717
4718LOCALPROC ZapWinStateVars(void)
4719{
4720#if MayNotFullScreen
4721 {
4722 int i;
4723
4724 for (i = 0; i < kNumMagStates; ++i) {
4725 HavePositionWins[i] = falseblnr;
4726 }
4727 }
4728#endif
4729#if VarFullScreen && EnableMagnify
4730 {
4731 int i;
4732
4733 for (i = 0; i < kNumWinStates; ++i) {
4734 WinMagStates[i] = kMagStateAuto;
4735 }
4736 }
4737#endif
4738}
4739
4740#if VarFullScreen
4741LOCALPROC ToggleWantFullScreen(void)
4742{
4743 WantFullScreen = ! WantFullScreen;
4744
4745#if EnableMagnify
4746 {
4747 int OldWinState =
4748 UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
4749 int OldMagState =
4750 UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
4751 int NewWinState =
4752 WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
4753 int NewMagState = WinMagStates[NewWinState];
4754
4755 WinMagStates[OldWinState] = OldMagState;
4756 if (kMagStateAuto != NewMagState) {
4757 WantMagnify = (kMagStateMagnifgy == NewMagState);
4758 } else {
4759 WantMagnify = falseblnr;
4760 if (WantFullScreen) {
4761 Rect r;
4762
4763 MyGetScreenBitsBounds(&r);
4764 if (((r.right - r.left)
4765 >= vMacScreenWidth * MyWindowScale)
4766 && ((r.bottom - r.top)
4767 >= vMacScreenHeight * MyWindowScale)
4768 )
4769 {
4770 WantMagnify = trueblnr;
4771 }
4772 }
4773 }
4774 }
4775#endif
4776}
4777#endif
4778
4779LOCALPROC LeaveBackground(void)
4780{
4781#if HogCPU
4782 NoEventsCounter = 0;
4783#endif
4784
4785 SetCursorArrow();
4786 ReconnectKeyCodes3();
4787}
4788
4789LOCALPROC EnterBackground(void)
4790{
4791 DisconnectKeyCodes3();
4792
4793#if VarFullScreen
4794 if (WantFullScreen) {
4795 ToggleWantFullScreen();
4796 }
4797#endif
4798}
4799
4800LOCALPROC LeaveSpeedStopped(void)
4801{
4802#if MySoundEnabled
4803 MySound_Start();
4804#endif
4805
4806 StartUpTimeAdjust();
4807}
4808
4809LOCALPROC EnterSpeedStopped(void)
4810{
4811#if MySoundEnabled
4812 MySound_Stop();
4813#endif
4814}
4815
4816LOCALPROC CheckForSavedTasks(void)
4817{
4818 if (MyEvtQNeedRecover) {
4819 MyEvtQNeedRecover = falseblnr;
4820
4821 /* attempt cleanup, MyEvtQNeedRecover may get set again */
4822 MyEvtQTryRecoverFromFull();
4823 }
4824
4825#if EnableFSMouseMotion
4826 if (HaveMouseMotion) {
4827 MyMouseConstrain();
4828 }
4829#endif
4830
4831 if (RequestMacOff) {
4832 RequestMacOff = falseblnr;
4833 if (AnyDiskInserted()) {
4834 MacMsgOverride(kStrQuitWarningTitle,
4835 kStrQuitWarningMessage);
4836 } else {
4837 ForceMacOff = trueblnr;
4838 }
4839 }
4840
4841 if (ForceMacOff) {
4842 return;
4843 }
4844
4845 if (gTrueBackgroundFlag != gBackgroundFlag) {
4846 gBackgroundFlag = gTrueBackgroundFlag;
4847 if (gTrueBackgroundFlag) {
4848 EnterBackground();
4849 } else {
4850 LeaveBackground();
4851 }
4852 }
4853
4854 if (CurSpeedStopped != (SpeedStopped ||
4855 (gBackgroundFlag && ! RunInBackground
4856#if EnableAutoSlow && 0
4857 && (QuietSubTicks >= 4092)
4858#endif
4859 )))
4860 {
4861 CurSpeedStopped = ! CurSpeedStopped;
4862 if (CurSpeedStopped) {
4863 EnterSpeedStopped();
4864 } else {
4865 LeaveSpeedStopped();
4866 }
4867 }
4868
4869#if EnableRecreateW
4870 if (! (gTrueBackgroundFlag)) {
4871 if (0
4872#if EnableMagnify
4873 || (UseMagnify != WantMagnify)
4874#endif
4875#if VarFullScreen
4876 || (UseFullScreen != WantFullScreen)
4877#endif
4878 )
4879 {
4880 (void) ReCreateMainWindow();
4881#if HogCPU
4882 NoEventsCounter = 0;
4883#endif
4884 }
4885 }
4886#endif
4887
4888#if MayFullScreen
4889 if (GrabMachine != (
4890#if VarFullScreen
4891 UseFullScreen &&
4892#endif
4893 ! (gTrueBackgroundFlag || CurSpeedStopped)))
4894 {
4895 GrabMachine = ! GrabMachine;
4896 AdjustMachineGrab();
4897 }
4898#endif
4899
4900 if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
4901 MacMsgDisplayOn();
4902 }
4903
4904 if (NeedWholeScreenDraw) {
4905 NeedWholeScreenDraw = falseblnr;
4906 ScreenChangedAll();
4907 }
4908
4909 if (gTrueBackgroundFlag) {
4910 /*
4911 dialog during drag and drop hangs if in background
4912 and don't want recursive dialogs
4913 so wait til later to display dialog
4914 */
4915 } else {
4916#if IncludeSonyNew
4917 if (vSonyNewDiskWanted) {
4918#if IncludeSonyNameNew
4919 if (vSonyNewDiskName != NotAPbuf) {
4920 MakeNewDisk(vSonyNewDiskSize,
4921 PbufDat[vSonyNewDiskName]);
4922 PbufDispose(vSonyNewDiskName);
4923 vSonyNewDiskName = NotAPbuf;
4924 } else
4925#endif
4926 {
4927 MakeNewDisk(vSonyNewDiskSize, NULL);
4928 }
4929 vSonyNewDiskWanted = falseblnr;
4930 /* must be done after may have gotten disk */
4931 }
4932#endif
4933 if (RequestInsertDisk) {
4934 RequestInsertDisk = falseblnr;
4935 InsertADisk0();
4936 }
4937 }
4938
4939#if NeedRequestIthDisk
4940 if (0 != RequestIthDisk) {
4941 Sony_InsertIth(RequestIthDisk);
4942 RequestIthDisk = 0;
4943 }
4944#endif
4945
4946 if (HaveCursorHidden != (WantCursorHidden
4947 && ! (gTrueBackgroundFlag || CurSpeedStopped)))
4948 {
4949 HaveCursorHidden = ! HaveCursorHidden;
4950 if (HaveCursorHidden) {
4951 HideCursor();
4952 } else {
4953 ShowCursor();
4954 }
4955 }
4956}
4957
4958GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
4959{
4960 UpdateTrueEmulatedTime();
4961 return TrueEmulatedTime == OnTrueTime;
4962}
4963
4964#define CheckItem CheckMenuItem
4965
4966/* Menu Constants */
4967
4968#define kAppleMenu 128
4969#define kFileMenu 129
4970#define kSpecialMenu 130
4971
4972/* Apple */
4973
4974enum {
4975 kAppleNull,
4976
4977 kAppleAboutItem,
4978 kAppleSep1,
4979
4980 kNumAppleItems
4981};
4982
4983/* File */
4984
4985enum {
4986 kFileNull,
4987
4988 kFileOpenDiskImage,
4989 kFileSep1,
4990 kFileQuitItem,
4991
4992 kNumFileItems
4993};
4994
4995/* Special */
4996
4997enum {
4998 kSpecialNull,
4999
5000 kSpecialMoreCommandsItem,
5001
5002 kNumSpecialItems
5003};
5004
5005LOCALPROC DoOpenDA(short menuItem)
5006{
5007 Str32 name;
5008 GrafPtr savePort;
5009
5010 GetPort(&savePort);
5011 GetMenuItemText(GetMenuHandle(kAppleMenu), menuItem, name);
5012 OpenDeskAcc(name);
5013 SystemTask();
5014 SetPort(savePort);
5015}
5016
5017LOCALPROC MacOS_HandleMenu(short menuID, short menuItem)
5018{
5019 switch (menuID) {
5020 case kAppleMenu:
5021 if (kAppleAboutItem == menuItem) {
5022 DoAboutMsg();
5023 } else {
5024 DoOpenDA(menuItem);
5025 }
5026 break;
5027
5028 case kFileMenu:
5029 switch (menuItem) {
5030 case kFileOpenDiskImage:
5031 RequestInsertDisk = trueblnr;
5032 break;
5033
5034 case kFileQuitItem:
5035 RequestMacOff = trueblnr;
5036 break;
5037 }
5038 break;
5039
5040 case kSpecialMenu:
5041 switch (menuItem) {
5042 case kSpecialMoreCommandsItem:
5043 DoMoreCommandsMsg();
5044 break;
5045 }
5046 break;
5047
5048 default:
5049 /* if 0 == menuID, then no command chosen from menu */
5050 /* do nothing */
5051 break;
5052 }
5053}
5054
5055LOCALPROC HandleMacEvent(EventRecord *theEvent)
5056{
5057 WindowPtr whichWindow;
5058 GrafPtr savePort;
5059
5060 switch(theEvent->what) {
5061 case mouseDown:
5062 switch (FindWindow(theEvent->where, &whichWindow)) {
5063 case inSysWindow:
5064 SystemClick(theEvent, whichWindow);
5065 break;
5066 case inMenuBar:
5067 ForceShowCursor();
5068 {
5069 long menuSelection =
5070 MenuSelect(theEvent->where);
5071 MacOS_HandleMenu(HiWord(menuSelection),
5072 LoWord(menuSelection));
5073 }
5074 HiliteMenu(0);
5075 break;
5076
5077 case inDrag:
5078 {
5079 Rect r;
5080
5081 MyGetScreenBitsBounds(&r);
5082 DragWindow(whichWindow, theEvent->where, &r);
5083 }
5084 break;
5085
5086 case inContent:
5087 if (FrontWindow() != whichWindow) {
5088 SelectWindow(whichWindow);
5089 }
5090 if (whichWindow == gMyMainWindow) {
5091 MousePositionNotifyFromGlobal(theEvent->where);
5092 MyMouseButtonSet(trueblnr);
5093 }
5094 break;
5095
5096 case inGoAway:
5097 if (TrackGoAway(whichWindow, theEvent->where)) {
5098 RequestMacOff = trueblnr;
5099 }
5100 break;
5101
5102 case inZoomIn:
5103 case inZoomOut:
5104 /* Zoom Boxes */
5105 break;
5106 }
5107 break;
5108 case mouseUp:
5109 MousePositionNotifyFromGlobal(theEvent->where);
5110 MyMouseButtonSet(falseblnr);
5111 break;
5112
5113 case updateEvt:
5114 GetPort(&savePort);
5115 BeginUpdate((WindowPtr) theEvent->message);
5116
5117 if ((WindowPtr)theEvent->message == gMyMainWindow) {
5118 Update_Screen();
5119 }
5120
5121 EndUpdate((WindowPtr) theEvent->message);
5122 SetPort(savePort);
5123 break;
5124
5125 case keyDown:
5126 case autoKey:
5127 case keyUp:
5128 /* ignore it */
5129 break;
5130 case osEvt:
5131 if ((theEvent->message >> 24) & suspendResumeMessage) {
5132 if (theEvent->message & 1) {
5133 gTrueBackgroundFlag = falseblnr;
5134 } else {
5135 gTrueBackgroundFlag = trueblnr;
5136 }
5137 }
5138 break;
5139 case kHighLevelEvent:
5140 if (kCoreEventClass == (AEEventClass)theEvent->message) {
5141 if (/* CheckSysCode */ noErr ==
5142 (AEProcessAppleEvent(theEvent)))
5143 {
5144 }
5145 } else {
5146 /* vCheckSysCode(errAENotAppleEvent); */
5147 }
5148 break;
5149 }
5150}
5151
5152LOCALPROC WaitForTheNextEvent(void)
5153{
5154 /*
5155 Wait for the next event
5156 from the operating system, we have nothing better
5157 to do. Call HandleTheEvent and return (only
5158 wait for one event).
5159 */
5160
5161 EventRecord theEvent;
5162
5163 if (
5164#if HaveCPUfamM68K
5165 (! HaveWaitNextEventAvail()) ?
5166 GetNextEvent(everyEvent, &theEvent) :
5167#endif
5168 WaitNextEvent(everyEvent, &theEvent,
5169 (gTrueBackgroundFlag && ! RunInBackground)
5170 ? 5 * 60 * 60
5171 : 5,
5172 /*
5173 still need to check for
5174 control key when SpeedStopped,
5175 don't get event
5176 */
5177 NULL))
5178 {
5179 HandleMacEvent(&theEvent);
5180 }
5181}
5182
5183LOCALPROC DontWaitForEvent(void)
5184{
5185 /* we're busy, but see what system wants */
5186
5187 EventRecord theEvent;
5188 int i = 0;
5189
5190#if 0 /* this seems to cause crashes on some machines */
5191 if (EventAvail(everyEvent, &theEvent)) {
5192 NoEventsCounter = 0;
5193#endif
5194
5195 while ((
5196#if HaveCPUfamM68K
5197 (! HaveWaitNextEventAvail()) ?
5198 GetNextEvent(everyEvent, &theEvent) :
5199#endif
5200 WaitNextEvent(everyEvent, &theEvent, 0, NULL))
5201 && (i < 10))
5202 {
5203 HandleMacEvent(&theEvent);
5204#if HogCPU
5205 NoEventsCounter = 0;
5206#endif
5207 ++i;
5208 }
5209#if 0
5210 }
5211#endif
5212}
5213
5214#define PrivateEventMask \
5215 (mDownMask | mUpMask | keyDownMask | keyUpMask | autoKeyMask)
5216
5217#define IsPowOf2(x) (0 == ((x) & ((x) - 1)))
5218
5219LOCALPROC CheckForSystemEvents(void)
5220{
5221#if HogCPU && MayFullScreen
5222 /*
5223 only hog cpu in full screen mode
5224 */
5225 if (
5226#if VarFullScreen
5227 UseFullScreen &&
5228#endif
5229 ((ui3b) -1 == SpeedValue) && ! CurSpeedStopped)
5230 {
5231 EventRecord theEvent;
5232
5233 if (! OSEventAvail(everyEvent, &theEvent)) {
5234 /*
5235 if no OSEvent now, and not looking for aftermath of
5236 event, assume there is no event of any kind we need
5237 to look at
5238 */
5239 if (NoEventsCounter < 256) {
5240 ++NoEventsCounter;
5241 if (IsPowOf2(NoEventsCounter)) {
5242 DontWaitForEvent();
5243 }
5244 }
5245 } else {
5246 WindowPtr whichWindow;
5247
5248 blnr PrivateEvent = falseblnr;
5249 switch (theEvent.what) {
5250 case keyDown:
5251 case autoKey:
5252 case keyUp:
5253 case mouseUp:
5254 PrivateEvent = trueblnr;
5255 break;
5256 case mouseDown:
5257 if ((inContent ==
5258 FindWindow(theEvent.where, &whichWindow))
5259 && (whichWindow == gMyMainWindow)
5260 && (FrontWindow() == whichWindow))
5261 {
5262 PrivateEvent = trueblnr;
5263 }
5264 break;
5265 }
5266 if (PrivateEvent) {
5267 /*
5268 if event can effect only us, and not looking out
5269 for aftermath of another event, then hog the cpu
5270 */
5271 if (GetOSEvent(PrivateEventMask, &theEvent)) {
5272 HandleMacEvent(&theEvent);
5273 }
5274 } else {
5275 NoEventsCounter = 0;
5276 /*
5277 Have an Event, so reset NoEventsCounter, no matter
5278 what. WaitNextEvent can return false, even if it did
5279 handle an event. Such as a click in the collapse
5280 box. In this case we need to look out for update
5281 events.
5282 */
5283 DontWaitForEvent();
5284 }
5285 }
5286 } else
5287#endif
5288 {
5289 DontWaitForEvent();
5290 }
5291
5292 if (! gBackgroundFlag) {
5293 CheckKeyBoardState();
5294 }
5295}
5296
5297GLOBALOSGLUPROC WaitForNextTick(void)
5298{
5299label_retry:
5300 CheckForSystemEvents();
5301 CheckForSavedTasks();
5302 if (ForceMacOff) {
5303 return;
5304 }
5305
5306 if (CurSpeedStopped) {
5307 DoneWithDrawingForTick();
5308 WaitForTheNextEvent();
5309 goto label_retry;
5310 }
5311
5312 /*
5313 Wait until the end of the current
5314 tick, then emulate the next tick.
5315 */
5316
5317 if (ExtraTimeNotOver()) {
5318#if HaveCPUfamM68K
5319 if (HaveWaitNextEventAvail())
5320#endif
5321 {
5322 EventRecord theEvent;
5323
5324 if (WaitNextEvent(everyEvent, &theEvent, 1, NULL)) {
5325 HandleMacEvent(&theEvent);
5326#if HogCPU
5327 NoEventsCounter = 0;
5328#endif
5329 }
5330 }
5331 goto label_retry;
5332 }
5333
5334 if (CheckDateTime()) {
5335#if MySoundEnabled
5336 MySound_SecondNotify();
5337#endif
5338#if EnableDemoMsg
5339 DemoModeSecondNotify();
5340#endif
5341 }
5342
5343 if (! (gBackgroundFlag)) {
5344 CheckMouseState();
5345 }
5346
5347 OnTrueTime = TrueEmulatedTime;
5348
5349#if dbglog_TimeStuff
5350 dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
5351#endif
5352}
5353
5354#include "PROGMAIN.h"
5355
5356LOCALPROC AppendMenuCStr(MenuHandle menu, char *s)
5357{
5358 Str255 t;
5359
5360 PStrFromCStr(t, s);
5361 AppendMenu(menu, t);
5362}
5363
5364LOCALPROC AppendMenuConvertCStr(MenuHandle menu,
5365 char *s, blnr WantEllipsis)
5366{
5367 Str255 t;
5368
5369 NativeStrFromCStr(t, s, WantEllipsis);
5370 AppendMenu(menu, t);
5371}
5372
5373LOCALPROC AppendMenuSep(MenuHandle menu)
5374{
5375 AppendMenuCStr(menu, "(-");
5376}
5377
5378LOCALFUNC MenuHandle NewMenuFromConvertCStr(short menuID, char *s)
5379{
5380 Str255 r;
5381
5382 NativeStrFromCStr(r, s, falseblnr);
5383 return NewMenu(menuID, r);
5384}
5385
5386LOCALFUNC blnr InstallOurMenus(void)
5387{
5388 MenuHandle menu;
5389 Str255 s;
5390
5391 PStrFromChar(s, (char)20);
5392 menu = NewMenu(kAppleMenu, s);
5393 if (menu != NULL) {
5394 AppendMenuConvertCStr(menu,
5395 kStrMenuItemAbout, trueblnr);
5396 AppendMenuSep(menu);
5397 AppendResMenu(menu, 'DRVR');
5398 InsertMenu(menu, 0);
5399 }
5400
5401 menu = NewMenuFromConvertCStr(kFileMenu, kStrMenuFile);
5402 if (menu != NULL) {
5403 AppendMenuConvertCStr(menu,
5404 kStrMenuItemOpen, trueblnr);
5405 {
5406 AppendMenuSep(menu);
5407 AppendMenuConvertCStr(menu,
5408 kStrMenuItemQuit, falseblnr);
5409 }
5410 InsertMenu(menu, 0);
5411 }
5412
5413 menu = NewMenuFromConvertCStr(kSpecialMenu, kStrMenuSpecial);
5414 if (menu != NULL) {
5415 AppendMenuConvertCStr(menu,
5416 kStrMenuItemMore, trueblnr);
5417 InsertMenu(menu, 0);
5418 }
5419
5420 DrawMenuBar();
5421
5422 return trueblnr;
5423}
5424
5425#if AppearanceAvail
5426LOCALFUNC blnr InstallOurAppearanceClient(void)
5427{
5428 if (HaveAppearanceAvail()) {
5429 RegisterAppearanceClient();
5430 }
5431 return trueblnr;
5432}
5433#endif
5434
5435LOCALFUNC blnr InstallOurEventHandlers(void)
5436{
5437 InitKeyCodes();
5438
5439 if (HaveAppleEvtMgrAvail()) {
5440 InstallAppleEventHandlers();
5441 }
5442 return trueblnr;
5443}
5444
5445LOCALPROC ZapOSGLUVars(void)
5446{
5447 ZapEmKeys();
5448 InitDrives();
5449 ZapWinStateVars();
5450}
5451
5452LOCALPROC ReserveAllocAll(void)
5453{
5454 /* !! must match ChooseTotMemSize in build system !! */
5455
5456#if dbglog_HAVE
5457 dbglog_ReserveAlloc();
5458#endif
5459 ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
5460 ReserveAllocOneBlock(&screencomparebuff,
5461 vMacScreenNumBytes, 5, trueblnr);
5462#if UseControlKeys
5463 ReserveAllocOneBlock(&CntrlDisplayBuff,
5464 vMacScreenNumBytes, 5, falseblnr);
5465#endif
5466#if EnableMagnify
5467 ReserveAllocOneBlock(&ScalingBuff,
5468 vMacScreenNumBytes * (ScaleBuffSzMult), 5, falseblnr);
5469 ReserveAllocOneBlock(&ScalingTabl,
5470 ScalingTablsz, 5, falseblnr);
5471#endif
5472#if MySoundEnabled
5473 ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
5474 dbhBufferSize, 5, falseblnr);
5475#endif
5476
5477 EmulationReserveAlloc();
5478}
5479
5480LOCALFUNC blnr AllocMyMemory(void)
5481{
5482 uimr n;
5483 blnr IsOk = falseblnr;
5484
5485 ReserveAllocOffset = 0;
5486 ReserveAllocBigBlock = nullpr;
5487 ReserveAllocAll();
5488 n = ReserveAllocOffset;
5489 ReserveAllocBigBlock = (ui3p)NewPtr(n);
5490 if (NULL == ReserveAllocBigBlock) {
5491 MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
5492 } else {
5493 ReserveAllocOffset = 0;
5494 ReserveAllocAll();
5495 if (n != ReserveAllocOffset) {
5496 /* oops, program error */
5497 } else {
5498 IsOk = trueblnr;
5499 }
5500 }
5501
5502 return IsOk;
5503}
5504
5505LOCALFUNC blnr InitOSGLU(void)
5506{
5507 if (InitMacManagers())
5508 if (AllocMyMemory())
5509 if (InitMyApplInfo())
5510#if dbglog_HAVE
5511 if (dbglog_open())
5512#endif
5513#if AppearanceAvail
5514 if (InstallOurAppearanceClient())
5515#endif
5516 if (InstallOurEventHandlers())
5517 if (InstallOurMenus())
5518#if MySoundEnabled
5519 if (MySound_Init())
5520#endif
5521 if (ReCreateMainWindow())
5522 if (LoadMacRom())
5523 if (LoadInitialImages())
5524#if UseActvCode
5525 if (ActvCodeInit())
5526#endif
5527 if (InitLocationDat())
5528 if (WaitForRom())
5529 {
5530 return trueblnr;
5531 }
5532 return falseblnr;
5533}
5534
5535LOCALPROC UnInitOSGLU(void)
5536{
5537 if (MacMsgDisplayed) {
5538 MacMsgDisplayOff();
5539 }
5540
5541#if MayFullScreen
5542 UngrabMachine();
5543#endif
5544
5545#if MySoundEnabled
5546 MySound_Stop();
5547#endif
5548
5549 CloseMainWindow();
5550
5551#if MayFullScreen
5552 My_ShowMenuBar();
5553#endif
5554
5555#if IncludePbufs
5556 UnInitPbufs();
5557#endif
5558 UnInitDrives();
5559
5560#if dbglog_HAVE
5561 dbglog_close();
5562#endif
5563
5564 ForceShowCursor();
5565
5566 if (! gTrueBackgroundFlag) {
5567 CheckSavedMacMsg();
5568 }
5569}
5570
5571#ifndef MainReturnsInt
5572#define MainReturnsInt 0
5573#endif
5574
5575#ifndef NeedLongGlue
5576#define NeedLongGlue 0
5577#endif
5578
5579#if NeedLongGlue
5580#define main long_main
5581#endif
5582
5583#if MainReturnsInt
5584int
5585#else
5586void
5587#endif
5588main(void)
5589{
5590 ZapOSGLUVars();
5591 if (InitOSGLU()) {
5592 ProgramMain();
5593 }
5594 UnInitOSGLU();
5595
5596#if MainReturnsInt
5597 return 0;
5598#endif
5599}
5600
5601#endif /* WantOSGLUMAC */