this repo has no description
at main 5669 lines 121 kB view raw
1/* 2 OSGLUOSX.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 OS X 20 21 (uses Carbon API. the more recent 22 OSGLUCCO.m uses the Cocoa API) 23 24 All operating system dependent code for the 25 Macintosh platform should go here. 26 27 This code is descended from Richard F. Bannister's Macintosh 28 port of vMac, by Philip Cummins. 29 30 The main entry point 'main' is at the end of this file. 31*/ 32 33#include "OSGCOMUI.h" 34#include "OSGCOMUD.h" 35 36#ifdef WantOSGLUOSX 37 38 39/* --- adapting to API/ABI version differences --- */ 40 41/* 42 if UsingCarbonLib, instead of native Macho, 43 then some APIs are missing 44*/ 45#ifndef UsingCarbonLib 46#define UsingCarbonLib 0 47#endif 48 49LOCALVAR CFBundleRef AppServBunRef; 50 51LOCALVAR blnr DidApplicationServicesBun = falseblnr; 52 53LOCALFUNC blnr HaveApplicationServicesBun(void) 54{ 55 if (! DidApplicationServicesBun) { 56 AppServBunRef = CFBundleGetBundleWithIdentifier( 57 CFSTR("com.apple.ApplicationServices")); 58 DidApplicationServicesBun = trueblnr; 59 } 60 return (AppServBunRef != NULL); 61} 62 63#if MayFullScreen || UsingCarbonLib 64 65LOCALVAR CFBundleRef HIToolboxBunRef; 66 67LOCALVAR blnr DidHIToolboxBunRef = falseblnr; 68 69LOCALFUNC blnr HaveHIToolboxBunRef(void) 70{ 71 if (! DidHIToolboxBunRef) { 72 HIToolboxBunRef = CFBundleGetBundleWithIdentifier( 73 CFSTR("com.apple.HIToolbox")); 74 DidHIToolboxBunRef = trueblnr; 75 } 76 return (HIToolboxBunRef != NULL); 77} 78 79#endif 80 81LOCALVAR CFBundleRef AGLBunRef; 82 83LOCALVAR blnr DidAGLBunRef = falseblnr; 84 85LOCALFUNC blnr HaveAGLBunRef(void) 86{ 87 if (! DidAGLBunRef) { 88 AGLBunRef = CFBundleGetBundleWithIdentifier( 89 CFSTR("com.apple.agl")); 90 DidAGLBunRef = trueblnr; 91 } 92 return (AGLBunRef != NULL); 93} 94 95 96#if MayFullScreen 97 98/* SetSystemUIModeProcPtr API always not available */ 99 100typedef UInt32 MySystemUIMode; 101typedef OptionBits MySystemUIOptions; 102 103enum { 104 MykUIModeNormal = 0, 105 MykUIModeAllHidden = 3 106}; 107 108enum { 109 MykUIOptionAutoShowMenuBar = 1 << 0, 110 MykUIOptionDisableAppleMenu = 1 << 2, 111 MykUIOptionDisableProcessSwitch = 1 << 3, 112 MykUIOptionDisableForceQuit = 1 << 4, 113 MykUIOptionDisableSessionTerminate = 1 << 5, 114 MykUIOptionDisableHide = 1 << 6 115}; 116 117typedef OSStatus (*SetSystemUIModeProcPtr) 118 (MySystemUIMode inMode, MySystemUIOptions inOptions); 119LOCALVAR SetSystemUIModeProcPtr MySetSystemUIMode = NULL; 120LOCALVAR blnr DidSetSystemUIMode = falseblnr; 121 122LOCALFUNC blnr HaveMySetSystemUIMode(void) 123{ 124 if (! DidSetSystemUIMode) { 125 if (HaveHIToolboxBunRef()) { 126 MySetSystemUIMode = 127 (SetSystemUIModeProcPtr) 128 CFBundleGetFunctionPointerForName( 129 HIToolboxBunRef, CFSTR("SetSystemUIMode")); 130 } 131 DidSetSystemUIMode = trueblnr; 132 } 133 return (MySetSystemUIMode != NULL); 134} 135 136#endif 137 138/* In 10.1 or later */ 139 140typedef OSStatus (*LSCopyDisplayNameForRefProcPtr) 141 (const FSRef *inRef, CFStringRef *outDisplayName); 142LOCALVAR LSCopyDisplayNameForRefProcPtr MyLSCopyDisplayNameForRef 143 = NULL; 144LOCALVAR blnr DidLSCopyDisplayNameForRef = falseblnr; 145 146LOCALFUNC blnr HaveMyLSCopyDisplayNameForRef(void) 147{ 148 if (! DidLSCopyDisplayNameForRef) { 149 if (HaveApplicationServicesBun()) { 150 MyLSCopyDisplayNameForRef = 151 (LSCopyDisplayNameForRefProcPtr) 152 CFBundleGetFunctionPointerForName( 153 AppServBunRef, CFSTR("LSCopyDisplayNameForRef")); 154 } 155 DidLSCopyDisplayNameForRef = trueblnr; 156 } 157 return (MyLSCopyDisplayNameForRef != NULL); 158} 159 160/* In 10.5 or later */ 161 162typedef GLboolean (*aglSetWindowRefProcPtr) 163 (AGLContext ctx, WindowRef window); 164LOCALVAR aglSetWindowRefProcPtr MyaglSetWindowRef = NULL; 165LOCALVAR blnr DidaglSetWindowRef = falseblnr; 166 167LOCALFUNC blnr HaveMyaglSetWindowRef(void) 168{ 169 if (! DidaglSetWindowRef) { 170 if (HaveAGLBunRef()) { 171 MyaglSetWindowRef = 172 (aglSetWindowRefProcPtr) 173 CFBundleGetFunctionPointerForName( 174 AGLBunRef, CFSTR("aglSetWindowRef")); 175 } 176 DidaglSetWindowRef = trueblnr; 177 } 178 return (MyaglSetWindowRef != NULL); 179} 180 181/* Deprecated as of 10.5 */ 182 183typedef CGrafPtr My_AGLDrawable; 184typedef GLboolean (*aglSetDrawableProcPtr) 185 (AGLContext ctx, My_AGLDrawable draw); 186LOCALVAR aglSetDrawableProcPtr MyaglSetDrawable = NULL; 187LOCALVAR blnr DidaglSetDrawable = falseblnr; 188 189LOCALFUNC blnr HaveMyaglSetDrawable(void) 190{ 191 if (! DidaglSetDrawable) { 192 if (HaveAGLBunRef()) { 193 MyaglSetDrawable = 194 (aglSetDrawableProcPtr) 195 CFBundleGetFunctionPointerForName( 196 AGLBunRef, CFSTR("aglSetDrawable")); 197 } 198 DidaglSetDrawable = trueblnr; 199 } 200 return (MyaglSetDrawable != NULL); 201} 202 203/* routines not in carbon lib */ 204 205 206#if UsingCarbonLib 207 208typedef CGDisplayErr 209(*CGGetActiveDisplayListProcPtr) ( 210 CGDisplayCount maxDisplays, 211 CGDirectDisplayID * activeDspys, 212 CGDisplayCount * dspyCnt); 213LOCALVAR CGGetActiveDisplayListProcPtr MyCGGetActiveDisplayList = NULL; 214LOCALVAR blnr DidCGGetActiveDisplayList = falseblnr; 215 216LOCALFUNC blnr HaveMyCGGetActiveDisplayList(void) 217{ 218 if (! DidCGGetActiveDisplayList) { 219 if (HaveApplicationServicesBun()) { 220 MyCGGetActiveDisplayList = 221 (CGGetActiveDisplayListProcPtr) 222 CFBundleGetFunctionPointerForName( 223 AppServBunRef, CFSTR("CGGetActiveDisplayList")); 224 } 225 DidCGGetActiveDisplayList = trueblnr; 226 } 227 return (MyCGGetActiveDisplayList != NULL); 228} 229 230#else 231 232#define HaveMyCGGetActiveDisplayList() trueblnr 233#define MyCGGetActiveDisplayList CGGetActiveDisplayList 234 235#endif /* ! UsingCarbonLib */ 236 237 238#if UsingCarbonLib 239 240typedef CGRect 241(*CGDisplayBoundsProcPtr) (CGDirectDisplayID display); 242LOCALVAR CGDisplayBoundsProcPtr MyCGDisplayBounds = NULL; 243LOCALVAR blnr DidCGDisplayBounds = falseblnr; 244 245LOCALFUNC blnr HaveMyCGDisplayBounds(void) 246{ 247 if (! DidCGDisplayBounds) { 248 if (HaveApplicationServicesBun()) { 249 MyCGDisplayBounds = 250 (CGDisplayBoundsProcPtr) 251 CFBundleGetFunctionPointerForName( 252 AppServBunRef, CFSTR("CGDisplayBounds")); 253 } 254 DidCGDisplayBounds = trueblnr; 255 } 256 return (MyCGDisplayBounds != NULL); 257} 258 259#else 260 261#define HaveMyCGDisplayBounds() trueblnr 262#define MyCGDisplayBounds CGDisplayBounds 263 264#endif /* ! UsingCarbonLib */ 265 266 267#if UsingCarbonLib 268 269typedef size_t 270(*CGDisplayPixelsWideProcPtr) (CGDirectDisplayID display); 271LOCALVAR CGDisplayPixelsWideProcPtr MyCGDisplayPixelsWide = NULL; 272LOCALVAR blnr DidCGDisplayPixelsWide = falseblnr; 273 274LOCALFUNC blnr HaveMyCGDisplayPixelsWide(void) 275{ 276 if (! DidCGDisplayPixelsWide) { 277 if (HaveApplicationServicesBun()) { 278 MyCGDisplayPixelsWide = 279 (CGDisplayPixelsWideProcPtr) 280 CFBundleGetFunctionPointerForName( 281 AppServBunRef, CFSTR("CGDisplayPixelsWide")); 282 } 283 DidCGDisplayPixelsWide = trueblnr; 284 } 285 return (MyCGDisplayPixelsWide != NULL); 286} 287 288#else 289 290#define HaveMyCGDisplayPixelsWide() trueblnr 291#define MyCGDisplayPixelsWide CGDisplayPixelsWide 292 293#endif /* ! UsingCarbonLib */ 294 295 296#if UsingCarbonLib 297 298typedef size_t 299(*CGDisplayPixelsHighProcPtr) (CGDirectDisplayID display); 300LOCALVAR CGDisplayPixelsHighProcPtr MyCGDisplayPixelsHigh = NULL; 301LOCALVAR blnr DidCGDisplayPixelsHigh = falseblnr; 302 303LOCALFUNC blnr HaveMyCGDisplayPixelsHigh(void) 304{ 305 if (! DidCGDisplayPixelsHigh) { 306 if (HaveApplicationServicesBun()) { 307 MyCGDisplayPixelsHigh = 308 (CGDisplayPixelsHighProcPtr) 309 CFBundleGetFunctionPointerForName( 310 AppServBunRef, CFSTR("CGDisplayPixelsHigh")); 311 } 312 DidCGDisplayPixelsHigh = trueblnr; 313 } 314 return (MyCGDisplayPixelsHigh != NULL); 315} 316 317#else 318 319#define HaveMyCGDisplayPixelsHigh() trueblnr 320#define MyCGDisplayPixelsHigh CGDisplayPixelsHigh 321 322#endif /* ! UsingCarbonLib */ 323 324 325#if UsingCarbonLib 326 327typedef CGDisplayErr 328(*CGDisplayHideCursorProcPtr) (CGDirectDisplayID display); 329LOCALVAR CGDisplayHideCursorProcPtr MyCGDisplayHideCursor = NULL; 330LOCALVAR blnr DidCGDisplayHideCursor = falseblnr; 331 332LOCALFUNC blnr HaveMyCGDisplayHideCursor(void) 333{ 334 if (! DidCGDisplayHideCursor) { 335 if (HaveApplicationServicesBun()) { 336 MyCGDisplayHideCursor = 337 (CGDisplayHideCursorProcPtr) 338 CFBundleGetFunctionPointerForName( 339 AppServBunRef, CFSTR("CGDisplayHideCursor")); 340 } 341 DidCGDisplayHideCursor = trueblnr; 342 } 343 return (MyCGDisplayHideCursor != NULL); 344} 345 346#else 347 348#define HaveMyCGDisplayHideCursor() trueblnr 349#define MyCGDisplayHideCursor CGDisplayHideCursor 350 351#endif /* ! UsingCarbonLib */ 352 353 354#if UsingCarbonLib 355 356typedef CGDisplayErr 357(*CGDisplayShowCursorProcPtr) (CGDirectDisplayID display); 358LOCALVAR CGDisplayShowCursorProcPtr MyCGDisplayShowCursor = NULL; 359LOCALVAR blnr DidCGDisplayShowCursor = falseblnr; 360 361LOCALFUNC blnr HaveMyCGDisplayShowCursor(void) 362{ 363 if (! DidCGDisplayShowCursor) { 364 if (HaveApplicationServicesBun()) { 365 MyCGDisplayShowCursor = 366 (CGDisplayShowCursorProcPtr) 367 CFBundleGetFunctionPointerForName( 368 AppServBunRef, CFSTR("CGDisplayShowCursor")); 369 } 370 DidCGDisplayShowCursor = trueblnr; 371 } 372 return (MyCGDisplayShowCursor != NULL); 373} 374 375#else 376 377#define HaveMyCGDisplayShowCursor() trueblnr 378#define MyCGDisplayShowCursor CGDisplayShowCursor 379 380#endif /* ! UsingCarbonLib */ 381 382 383#if 0 384 385typedef CGDisplayErr (*CGDisplayMoveCursorToPointProcPtr) 386 (CGDirectDisplayID display, CGPoint point); 387LOCALVAR CGDisplayMoveCursorToPointProcPtr MyCGDisplayMoveCursorToPoint 388 = NULL; 389LOCALVAR blnr DidCGDisplayMoveCursorToPoint = falseblnr; 390 391LOCALFUNC blnr HaveMyCGDisplayMoveCursorToPoint(void) 392{ 393 if (! DidCGDisplayMoveCursorToPoint) { 394 if (HaveApplicationServicesBun()) { 395 MyCGDisplayMoveCursorToPoint = 396 (CGDisplayMoveCursorToPointProcPtr) 397 CFBundleGetFunctionPointerForName( 398 AppServBunRef, CFSTR("CGDisplayMoveCursorToPoint")); 399 } 400 DidCGDisplayMoveCursorToPoint = trueblnr; 401 } 402 return (MyCGDisplayMoveCursorToPoint != NULL); 403} 404 405#endif /* 0 */ 406 407 408#if UsingCarbonLib 409 410typedef CGEventErr 411(*CGWarpMouseCursorPositionProcPtr) (CGPoint newCursorPosition); 412LOCALVAR CGWarpMouseCursorPositionProcPtr MyCGWarpMouseCursorPosition 413 = NULL; 414LOCALVAR blnr DidCGWarpMouseCursorPosition = falseblnr; 415 416LOCALFUNC blnr HaveMyCGWarpMouseCursorPosition(void) 417{ 418 if (! DidCGWarpMouseCursorPosition) { 419 if (HaveApplicationServicesBun()) { 420 MyCGWarpMouseCursorPosition = 421 (CGWarpMouseCursorPositionProcPtr) 422 CFBundleGetFunctionPointerForName( 423 AppServBunRef, CFSTR("CGWarpMouseCursorPosition")); 424 } 425 DidCGWarpMouseCursorPosition = trueblnr; 426 } 427 return (MyCGWarpMouseCursorPosition != NULL); 428} 429 430#else 431 432#define HaveMyCGWarpMouseCursorPosition() trueblnr 433#define MyCGWarpMouseCursorPosition CGWarpMouseCursorPosition 434 435#endif /* ! UsingCarbonLib */ 436 437 438#if UsingCarbonLib 439 440typedef CGEventErr 441(*CGSetLocalEventsSuppressionIntervalProcPtr) (CFTimeInterval seconds); 442LOCALVAR CGSetLocalEventsSuppressionIntervalProcPtr 443 MyCGSetLocalEventsSuppressionInterval = NULL; 444LOCALVAR blnr DidCGSetLocalEventsSuppressionInterval = falseblnr; 445 446LOCALFUNC blnr HaveMyCGSetLocalEventsSuppressionInterval(void) 447{ 448 if (! DidCGSetLocalEventsSuppressionInterval) { 449 if (HaveApplicationServicesBun()) { 450 MyCGSetLocalEventsSuppressionInterval = 451 (CGSetLocalEventsSuppressionIntervalProcPtr) 452 CFBundleGetFunctionPointerForName( 453 AppServBunRef, 454 CFSTR("CGSetLocalEventsSuppressionInterval")); 455 } 456 DidCGSetLocalEventsSuppressionInterval = trueblnr; 457 } 458 return (MyCGSetLocalEventsSuppressionInterval != NULL); 459} 460 461#else 462 463#define HaveMyCGSetLocalEventsSuppressionInterval() trueblnr 464#define MyCGSetLocalEventsSuppressionInterval \ 465 CGSetLocalEventsSuppressionInterval 466 467#endif /* ! UsingCarbonLib */ 468 469 470#if UsingCarbonLib 471 472typedef OSStatus (*CreateStandardAlertProcPtr) ( 473 AlertType alertType, 474 CFStringRef error, 475 CFStringRef explanation, 476 const AlertStdCFStringAlertParamRec * param, 477 DialogRef * outAlert 478); 479LOCALVAR CreateStandardAlertProcPtr MyCreateStandardAlert = NULL; 480LOCALVAR blnr DidCreateStandardAlert = falseblnr; 481 482LOCALFUNC blnr HaveMyCreateStandardAlert(void) 483{ 484 if (! DidCreateStandardAlert) { 485 if (HaveHIToolboxBunRef()) { 486 MyCreateStandardAlert = 487 (CreateStandardAlertProcPtr) 488 CFBundleGetFunctionPointerForName( 489 HIToolboxBunRef, CFSTR("CreateStandardAlert")); 490 } 491 DidCreateStandardAlert = trueblnr; 492 } 493 return (MyCreateStandardAlert != NULL); 494} 495 496#else 497 498#define HaveMyCreateStandardAlert() trueblnr 499#define MyCreateStandardAlert CreateStandardAlert 500 501#endif /* ! UsingCarbonLib */ 502 503 504#if UsingCarbonLib 505 506typedef OSStatus (*RunStandardAlertProcPtr) ( 507 DialogRef inAlert, 508 ModalFilterUPP filterProc, 509 DialogItemIndex * outItemHit 510); 511LOCALVAR RunStandardAlertProcPtr MyRunStandardAlert = NULL; 512LOCALVAR blnr DidRunStandardAlert = falseblnr; 513 514LOCALFUNC blnr HaveMyRunStandardAlert(void) 515{ 516 if (! DidRunStandardAlert) { 517 if (HaveHIToolboxBunRef()) { 518 MyRunStandardAlert = 519 (RunStandardAlertProcPtr) 520 CFBundleGetFunctionPointerForName( 521 HIToolboxBunRef, CFSTR("RunStandardAlert")); 522 } 523 DidRunStandardAlert = trueblnr; 524 } 525 return (MyRunStandardAlert != NULL); 526} 527 528#else 529 530#define HaveMyRunStandardAlert() trueblnr 531#define MyRunStandardAlert RunStandardAlert 532 533#endif /* ! UsingCarbonLib */ 534 535 536typedef CGDirectDisplayID (*CGMainDisplayIDProcPtr)(void); 537 538LOCALVAR CGMainDisplayIDProcPtr MyCGMainDisplayID = NULL; 539LOCALVAR blnr DidCGMainDisplayID = falseblnr; 540 541LOCALFUNC blnr HaveMyCGMainDisplayID(void) 542{ 543 if (! DidCGMainDisplayID) { 544 if (HaveApplicationServicesBun()) { 545 MyCGMainDisplayID = 546 (CGMainDisplayIDProcPtr) 547 CFBundleGetFunctionPointerForName( 548 AppServBunRef, CFSTR("CGMainDisplayID")); 549 } 550 DidCGMainDisplayID = trueblnr; 551 } 552 return (MyCGMainDisplayID != NULL); 553} 554 555#ifndef kCGNullDirectDisplay /* not in MPW Headers */ 556#define kCGNullDirectDisplay ((CGDirectDisplayID)0) 557#endif 558 559typedef CGError 560(*CGDisplayRegisterReconfigurationCallbackProcPtr) ( 561 CGDisplayReconfigurationCallBack proc, 562 void *userInfo 563 ); 564LOCALVAR CGDisplayRegisterReconfigurationCallbackProcPtr 565 MyCGDisplayRegisterReconfigurationCallback = NULL; 566LOCALVAR blnr DidCGDisplayRegisterReconfigurationCallback = falseblnr; 567 568LOCALFUNC blnr HaveMyCGDisplayRegisterReconfigurationCallback(void) 569{ 570 if (! DidCGDisplayRegisterReconfigurationCallback) { 571 if (HaveApplicationServicesBun()) { 572 MyCGDisplayRegisterReconfigurationCallback = 573 (CGDisplayRegisterReconfigurationCallbackProcPtr) 574 CFBundleGetFunctionPointerForName( 575 AppServBunRef, 576 CFSTR("CGDisplayRegisterReconfigurationCallback")); 577 } 578 DidCGDisplayRegisterReconfigurationCallback = trueblnr; 579 } 580 return (MyCGDisplayRegisterReconfigurationCallback != NULL); 581} 582 583 584typedef CGError 585(*CGDisplayRemoveReconfigurationCallbackProcPtr) ( 586 CGDisplayReconfigurationCallBack proc, 587 void *userInfo 588 ); 589LOCALVAR CGDisplayRemoveReconfigurationCallbackProcPtr 590 MyCGDisplayRemoveReconfigurationCallback = NULL; 591LOCALVAR blnr DidCGDisplayRemoveReconfigurationCallback = falseblnr; 592 593LOCALFUNC blnr HaveMyCGDisplayRemoveReconfigurationCallback(void) 594{ 595 if (! DidCGDisplayRemoveReconfigurationCallback) { 596 if (HaveApplicationServicesBun()) { 597 MyCGDisplayRemoveReconfigurationCallback = 598 (CGDisplayRemoveReconfigurationCallbackProcPtr) 599 CFBundleGetFunctionPointerForName( 600 AppServBunRef, 601 CFSTR("CGDisplayRemoveReconfigurationCallback")); 602 } 603 DidCGDisplayRemoveReconfigurationCallback = trueblnr; 604 } 605 return (MyCGDisplayRemoveReconfigurationCallback != NULL); 606} 607 608 609typedef boolean_t (*CGCursorIsVisibleProcPtr)(void); 610 611LOCALVAR CGCursorIsVisibleProcPtr MyCGCursorIsVisible = NULL; 612LOCALVAR blnr DidCGCursorIsVisible = falseblnr; 613 614LOCALFUNC blnr HaveMyCGCursorIsVisible(void) 615{ 616 if (! DidCGCursorIsVisible) { 617 if (HaveApplicationServicesBun()) { 618 MyCGCursorIsVisible = 619 (CGCursorIsVisibleProcPtr) 620 CFBundleGetFunctionPointerForName( 621 AppServBunRef, CFSTR("CGCursorIsVisible")); 622 } 623 DidCGCursorIsVisible = trueblnr; 624 } 625 return (MyCGCursorIsVisible != NULL); 626} 627 628 629/* --- end of adapting to API/ABI version differences --- */ 630 631/* --- some simple utilities --- */ 632 633GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount) 634{ 635 (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount); 636} 637 638LOCALPROC PStrFromChar(ps3p r, char x) 639{ 640 r[0] = 1; 641 r[1] = (char)x; 642} 643 644/* --- mac style errors --- */ 645 646#define CheckSavetMacErr(result) (mnvm_noErr == (err = (result))) 647 /* 648 where 'err' is a variable of type tMacErr in the function 649 this is used in 650 */ 651 652#define To_tMacErr(result) ((tMacErr)(ui4b)(result)) 653 654#define CheckSaveMacErr(result) (CheckSavetMacErr(To_tMacErr(result))) 655 656 657#define NeedCell2UnicodeMap 1 658#define NeedRequestInsertDisk 1 659#define NeedDoMoreCommandsMsg 1 660#define NeedDoAboutMsg 1 661 662#include "INTLCHAR.h" 663 664LOCALPROC UniCharStrFromSubstCStr(int *L, UniChar *x, char *s) 665{ 666 int i; 667 int L0; 668 ui3b ps[ClStrMaxLength]; 669 670 ClStrFromSubstCStr(&L0, ps, s); 671 672 for (i = 0; i < L0; ++i) { 673 x[i] = Cell2UnicodeMap[ps[i]]; 674 } 675 676 *L = L0; 677} 678 679#define NotAfileRef (-1) 680 681LOCALFUNC tMacErr MyMakeFSRefUniChar(FSRef *ParentRef, 682 UniCharCount fileNameLength, const UniChar *fileName, 683 blnr *isFolder, FSRef *ChildRef) 684{ 685 tMacErr err; 686 Boolean isFolder0; 687 Boolean isAlias; 688 689 if (CheckSaveMacErr(FSMakeFSRefUnicode(ParentRef, 690 fileNameLength, fileName, kTextEncodingUnknown, 691 ChildRef))) 692 if (CheckSaveMacErr(FSResolveAliasFile(ChildRef, 693 TRUE, &isFolder0, &isAlias))) 694 { 695 *isFolder = isFolder0; 696 } 697 698 return err; 699} 700 701LOCALFUNC tMacErr MyMakeFSRefC(FSRef *ParentRef, char *fileName, 702 blnr *isFolder, FSRef *ChildRef) 703{ 704 int L; 705 UniChar x[ClStrMaxLength]; 706 707 UniCharStrFromSubstCStr(&L, x, fileName); 708 return MyMakeFSRefUniChar(ParentRef, L, x, 709 isFolder, ChildRef); 710} 711 712#if UseActvFile 713LOCALFUNC tMacErr OpenNamedFileInFolderRef(FSRef *ParentRef, 714 char *fileName, short *refnum) 715{ 716 tMacErr err; 717 blnr isFolder; 718 FSRef ChildRef; 719 HFSUniStr255 forkName; 720 721 if (CheckSavetMacErr(MyMakeFSRefC(ParentRef, fileName, 722 &isFolder, &ChildRef))) 723 if (CheckSaveMacErr(FSGetDataForkName(&forkName))) 724 if (CheckSaveMacErr(FSOpenFork(&ChildRef, forkName.length, 725 forkName.unicode, fsRdPerm, refnum))) 726 { 727 /* ok */ 728 } 729 730 return err; 731} 732#endif 733 734#if dbglog_HAVE || UseActvFile 735LOCALFUNC tMacErr OpenWriteNamedFileInFolderRef(FSRef *ParentRef, 736 char *fileName, short *refnum) 737{ 738 tMacErr err; 739 blnr isFolder; 740 FSRef ChildRef; 741 HFSUniStr255 forkName; 742 int L; 743 UniChar x[ClStrMaxLength]; 744 745 UniCharStrFromSubstCStr(&L, x, fileName); 746 err = MyMakeFSRefUniChar(ParentRef, L, x, &isFolder, &ChildRef); 747 if (mnvm_fnfErr == err) { 748 err = To_tMacErr(FSCreateFileUnicode(ParentRef, L, x, 0, NULL, 749 &ChildRef, NULL)); 750 } 751 if (mnvm_noErr == err) { 752 if (CheckSaveMacErr(FSGetDataForkName(&forkName))) 753 if (CheckSaveMacErr(FSOpenFork(&ChildRef, forkName.length, 754 forkName.unicode, fsRdWrPerm, refnum))) 755 { 756 /* ok */ 757 } 758 } 759 760 return err; 761} 762#endif 763 764LOCALFUNC tMacErr FindNamedChildRef(FSRef *ParentRef, 765 char *ChildName, FSRef *ChildRef) 766{ 767 tMacErr err; 768 blnr isFolder; 769 770 if (CheckSavetMacErr(MyMakeFSRefC(ParentRef, ChildName, 771 &isFolder, ChildRef))) 772 { 773 if (! isFolder) { 774 err = mnvm_miscErr; 775 } 776 } 777 778 return err; 779} 780 781#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable) 782LOCALFUNC tMacErr FindOrMakeNamedChildRef(FSRef *ParentRef, 783 char *ChildName, FSRef *ChildRef) 784{ 785 tMacErr err; 786 blnr isFolder; 787 int L; 788 UniChar x[ClStrMaxLength]; 789 790 UniCharStrFromSubstCStr(&L, x, ChildName); 791 if (CheckSavetMacErr(MyMakeFSRefUniChar(ParentRef, L, x, 792 &isFolder, ChildRef))) 793 { 794 if (! isFolder) { 795 err = mnvm_miscErr; 796 } 797 } 798 if (mnvm_fnfErr == err) { 799 err = To_tMacErr(FSCreateDirectoryUnicode( 800 ParentRef, L, x, kFSCatInfoNone, NULL, 801 ChildRef, NULL, NULL)); 802 } 803 804 return err; 805} 806#endif 807 808LOCALVAR FSRef MyDatDirRef; 809 810LOCALVAR CFStringRef MyAppName = NULL; 811 812LOCALPROC UnInitMyApplInfo(void) 813{ 814 if (MyAppName != NULL) { 815 CFRelease(MyAppName); 816 } 817} 818 819LOCALFUNC blnr InitMyApplInfo(void) 820{ 821 ProcessSerialNumber currentProcess = {0, kCurrentProcess}; 822 FSRef fsRef; 823 FSRef parentRef; 824 825 if (noErr == GetProcessBundleLocation(&currentProcess, 826 &fsRef)) 827 if (noErr == FSGetCatalogInfo(&fsRef, kFSCatInfoNone, 828 NULL, NULL, NULL, &parentRef)) 829 { 830 FSRef ContentsRef; 831 FSRef DatRef; 832 833 MyDatDirRef = parentRef; 834 if (mnvm_noErr == FindNamedChildRef(&fsRef, "Contents", 835 &ContentsRef)) 836 if (mnvm_noErr == FindNamedChildRef(&ContentsRef, "mnvm_dat", 837 &DatRef)) 838 { 839 MyDatDirRef = DatRef; 840 } 841 842 if (HaveMyLSCopyDisplayNameForRef()) { 843 if (noErr == MyLSCopyDisplayNameForRef(&fsRef, &MyAppName)) 844 { 845 return trueblnr; 846 } 847 } 848 849 if (noErr == CopyProcessName(&currentProcess, &MyAppName)) { 850 return trueblnr; 851 } 852 } 853 return falseblnr; 854} 855 856/* --- sending debugging info to file --- */ 857 858#if dbglog_HAVE 859 860LOCALVAR SInt16 dbglog_File = NotAfileRef; 861 862LOCALFUNC blnr dbglog_open0(void) 863{ 864 tMacErr err; 865 866 err = OpenWriteNamedFileInFolderRef(&MyDatDirRef, 867 "dbglog.txt", &dbglog_File); 868 869 return (mnvm_noErr == err); 870} 871 872LOCALPROC dbglog_write0(char *s, uimr L) 873{ 874 ByteCount actualCount; 875 876 if (dbglog_File != NotAfileRef) { 877 (void) FSWriteFork( 878 dbglog_File, 879 fsFromMark, 880 0, 881 L, 882 s, 883 &actualCount); 884 } 885} 886 887LOCALPROC dbglog_close0(void) 888{ 889 if (dbglog_File != NotAfileRef) { 890 (void) FSSetForkSize(dbglog_File, fsFromMark, 0); 891 (void) FSCloseFork(dbglog_File); 892 dbglog_File = NotAfileRef; 893 } 894} 895 896#endif 897 898#if 1 /* (0 != vMacScreenDepth) && (vMacScreenDepth < 4) */ 899#define WantColorTransValid 1 900#endif 901 902#include "COMOSGLU.h" 903 904/* --- time, date --- */ 905 906/* 907 be sure to avoid getting confused if TickCount 908 overflows and wraps. 909*/ 910 911#define dbglog_TimeStuff (0 && dbglog_HAVE) 912 913LOCALVAR ui5b TrueEmulatedTime = 0; 914 915LOCALVAR EventTime NextTickChangeTime; 916 917#define MyTickDuration (kEventDurationSecond / 60.14742) 918 919LOCALPROC UpdateTrueEmulatedTime(void) 920{ 921 EventTime LatestTime = GetCurrentEventTime(); 922 EventTime TimeDiff = LatestTime - NextTickChangeTime; 923 924 if (TimeDiff >= 0.0) { 925 if (TimeDiff > 16 * MyTickDuration) { 926 /* emulation interrupted, forget it */ 927 ++TrueEmulatedTime; 928 NextTickChangeTime = LatestTime + MyTickDuration; 929 930#if dbglog_TimeStuff 931 dbglog_writelnNum("emulation interrupted", 932 TrueEmulatedTime); 933#endif 934 } else { 935 do { 936 ++TrueEmulatedTime; 937 TimeDiff -= MyTickDuration; 938 NextTickChangeTime += MyTickDuration; 939 } while (TimeDiff >= 0.0); 940 } 941 } 942} 943 944GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void) 945{ 946 UpdateTrueEmulatedTime(); 947 return TrueEmulatedTime == OnTrueTime; 948} 949 950/* LOCALVAR EventTime ETimeBase; */ 951LOCALVAR CFAbsoluteTime ATimeBase; 952LOCALVAR ui5b TimeSecBase; 953 954LOCALFUNC blnr CheckDateTime(void) 955{ 956 ui5b NewMacDateInSecond = TimeSecBase 957 + (ui5b)(CFAbsoluteTimeGetCurrent() - ATimeBase); 958 /* 959 ui5b NewMacDateInSecond = TimeSecBase 960 + (ui5b)(GetCurrentEventTime() - ETimeBase); 961 */ 962 /* 963 ui5b NewMacDateInSecond = ((ui5b)(CFAbsoluteTimeGetCurrent())) 964 + 3061137600UL; 965 */ 966 967 if (CurMacDateInSeconds != NewMacDateInSecond) { 968 CurMacDateInSeconds = NewMacDateInSecond; 969 return trueblnr; 970 } else { 971 return falseblnr; 972 } 973} 974 975/* --- parameter buffers --- */ 976 977#include "PBUFSTDC.h" 978 979/* --- drives --- */ 980 981LOCALVAR SInt16 Drives[NumDrives]; /* open disk image files */ 982 983GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer, 984 tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count, 985 ui5r *Sony_ActCount) 986{ 987 ByteCount actualCount; 988 tMacErr result; 989 990 if (IsWrite) { 991 result = To_tMacErr(FSWriteFork( 992 Drives[Drive_No], 993 fsFromStart, 994 Sony_Start, 995 Sony_Count, 996 Buffer, 997 &actualCount)); 998 } else { 999 result = To_tMacErr(FSReadFork( 1000 Drives[Drive_No], 1001 fsFromStart, 1002 Sony_Start, 1003 Sony_Count, 1004 Buffer, 1005 &actualCount)); 1006 } 1007 1008 if (nullpr != Sony_ActCount) { 1009 *Sony_ActCount = actualCount; 1010 } 1011 1012 return result; 1013} 1014 1015GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count) 1016{ 1017 SInt64 forkSize; 1018 tMacErr err = To_tMacErr( 1019 FSGetForkSize(Drives[Drive_No], &forkSize)); 1020 *Sony_Count = forkSize; 1021 return err; 1022} 1023 1024GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No) 1025{ 1026 SInt16 refnum = Drives[Drive_No]; 1027 Drives[Drive_No] = NotAfileRef; 1028 1029 DiskEjectedNotify(Drive_No); 1030 1031 (void) FSCloseFork(refnum); 1032 1033 return mnvm_noErr; 1034} 1035 1036#if IncludeSonyNew 1037GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No) 1038{ 1039 FSRef ref; 1040 tMacErr err0; 1041 tMacErr err; 1042 1043 err0 = To_tMacErr(FSGetForkCBInfo(Drives[Drive_No], 0, 1044 NULL /* iterator */, 1045 NULL /* actualRefNum */, 1046 NULL /* forkInfo */, 1047 &ref /* ref */, 1048 NULL /* outForkName */)); 1049 err = vSonyEject(Drive_No); 1050 1051 if (mnvm_noErr != err0) { 1052 err = err0; 1053 } else { 1054 (void) FSDeleteObject(&ref); 1055 } 1056 1057 return err; 1058} 1059#endif 1060 1061#if IncludeSonyGetName 1062GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r) 1063{ 1064 FSRef ref; 1065 HFSUniStr255 outName; 1066 CFStringRef DiskName; 1067 tMacErr err; 1068 1069 if (CheckSaveMacErr(FSGetForkCBInfo(Drives[Drive_No], 0, 1070 NULL /* iterator */, 1071 NULL /* actualRefNum */, 1072 NULL /* forkInfo */, 1073 &ref /* ref */, 1074 NULL /* outForkName */))) 1075 if (CheckSaveMacErr(FSGetCatalogInfo(&ref, 1076 kFSCatInfoNone /* whichInfo */, 1077 NULL /* catalogInfo */, 1078 &outName /* outName */, 1079 NULL /* fsSpec */, 1080 NULL /* parentRef */))) 1081 { 1082 DiskName = CFStringCreateWithCharacters( 1083 kCFAllocatorDefault, outName.unicode, 1084 outName.length); 1085 if (NULL != DiskName) { 1086 tPbuf i; 1087 1088 if (CheckSavetMacErr(PbufNew(outName.length, &i))) { 1089 if (CFStringGetBytes(DiskName, 1090 CFRangeMake(0, outName.length), 1091 kCFStringEncodingMacRoman, 1092 '?', false, 1093 PbufDat[i], 1094 outName.length, 1095 NULL) != outName.length) 1096 { 1097 err = mnvm_miscErr; 1098 } 1099 if (mnvm_noErr != err) { 1100 PbufDispose(i); 1101 } else { 1102 *r = i; 1103 } 1104 } 1105 CFRelease(DiskName); 1106 } 1107 } 1108 1109 return err; 1110} 1111#endif 1112 1113#if IncludeHostTextClipExchange 1114GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i) 1115{ 1116 tMacErr err; 1117 ScrapRef scrapRef; 1118 1119 if (CheckSaveMacErr(ClearCurrentScrap())) 1120 if (CheckSaveMacErr(GetCurrentScrap(&scrapRef))) 1121 if (CheckSaveMacErr(PutScrapFlavor( 1122 scrapRef, 1123 FOUR_CHAR_CODE('TEXT'), 1124 kScrapFlavorMaskNone, 1125 PbufSize[i], 1126 PbufDat[i]))) 1127 { 1128 /* ok */ 1129 } 1130 1131 PbufDispose(i); 1132 1133 return err; 1134} 1135#endif 1136 1137#if IncludeHostTextClipExchange 1138GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r) 1139{ 1140 tMacErr err; 1141 ScrapRef scrap; 1142 ScrapFlavorFlags flavorFlags; 1143 Size byteCount; 1144 tPbuf i; 1145 1146 if (CheckSaveMacErr(GetCurrentScrap(&scrap))) 1147 if (CheckSaveMacErr(GetScrapFlavorFlags(scrap, 1148 'TEXT', &flavorFlags))) 1149 if (CheckSaveMacErr(GetScrapFlavorSize(scrap, 1150 'TEXT', &byteCount))) 1151 if (CheckSavetMacErr(PbufNew(byteCount, &i))) 1152 { 1153 Size byteCount2 = byteCount; 1154 if (CheckSaveMacErr(GetScrapFlavorData(scrap, 1155 'TEXT', &byteCount2, 1156 PbufDat[i]))) 1157 { 1158 if (byteCount != byteCount2) { 1159 err = mnvm_miscErr; 1160 } 1161 } 1162 if (mnvm_noErr != err) { 1163 PbufDispose(i); 1164 } else { 1165 *r = i; 1166 } 1167 } 1168 1169 return err; 1170} 1171#endif 1172 1173 1174#if EmLocalTalk 1175LOCALFUNC blnr EntropyGather(void) 1176{ 1177 /* 1178 gather some entropy from several places, just in case 1179 /dev/urandom is not available. 1180 */ 1181 1182 { 1183 EventTime v = GetCurrentEventTime(); 1184 1185 EntropyPoolAddPtr((ui3p)&v, sizeof(v) / sizeof(ui3b)); 1186 } 1187 1188 { 1189 CFAbsoluteTime v = CFAbsoluteTimeGetCurrent(); 1190 1191 EntropyPoolAddPtr((ui3p)&v, sizeof(v) / sizeof(ui3b)); 1192 } 1193 1194 { 1195 Point v; 1196 1197 GetGlobalMouse(&v); 1198 EntropyPoolAddPtr((ui3p)&v, sizeof(v) / sizeof(ui3b)); 1199 } 1200 1201 { 1202 ProcessSerialNumber v; 1203 1204 (void) GetFrontProcess(&v); 1205 EntropyPoolAddPtr((ui3p)&v, sizeof(v) / sizeof(ui3b)); 1206 } 1207 1208 { 1209 ui5b dat[2]; 1210 int fd; 1211 1212 if (-1 == (fd = open("/dev/urandom", O_RDONLY))) { 1213#if dbglog_HAVE 1214 dbglog_writeCStr("open /dev/urandom fails"); 1215 dbglog_writeNum(errno); 1216 dbglog_writeCStr(" ("); 1217 dbglog_writeCStr(strerror(errno)); 1218 dbglog_writeCStr(")"); 1219 dbglog_writeReturn(); 1220#endif 1221 } else { 1222 1223 if (read(fd, &dat, sizeof(dat)) < 0) { 1224#if dbglog_HAVE 1225 dbglog_writeCStr("open /dev/urandom fails"); 1226 dbglog_writeNum(errno); 1227 dbglog_writeCStr(" ("); 1228 dbglog_writeCStr(strerror(errno)); 1229 dbglog_writeCStr(")"); 1230 dbglog_writeReturn(); 1231#endif 1232 } else { 1233 1234#if dbglog_HAVE 1235 dbglog_writeCStr("dat: "); 1236 dbglog_writeHex(dat[0]); 1237 dbglog_writeCStr(" "); 1238 dbglog_writeHex(dat[1]); 1239 dbglog_writeReturn(); 1240#endif 1241 1242 e_p[0] ^= dat[0]; 1243 e_p[1] ^= dat[1]; 1244 /* 1245 if "/dev/urandom" is working correctly, 1246 this should make the previous contents of e_p 1247 irrelevant. if it is completely broken, like 1248 returning 0, this will not make e_p any less 1249 random. 1250 */ 1251 1252#if dbglog_HAVE 1253 dbglog_writeCStr("ep: "); 1254 dbglog_writeHex(e_p[0]); 1255 dbglog_writeCStr(" "); 1256 dbglog_writeHex(e_p[1]); 1257 dbglog_writeReturn(); 1258#endif 1259 } 1260 1261 close(fd); 1262 } 1263 } 1264 1265 return trueblnr; 1266} 1267#endif 1268 1269 1270#if EmLocalTalk 1271 1272#include "LOCALTLK.h" 1273 1274#endif 1275 1276 1277/* --- control mode and internationalization --- */ 1278 1279#define WantKeyboard_RemapMac 1 1280 1281#include "CONTROLM.h" 1282 1283 1284/* --- video out --- */ 1285 1286LOCALVAR WindowPtr gMyMainWindow = NULL; 1287LOCALVAR WindowPtr gMyOldWindow = NULL; 1288 1289#if MayFullScreen 1290LOCALVAR short hOffset; 1291LOCALVAR short vOffset; 1292#endif 1293 1294#if MayFullScreen 1295LOCALVAR blnr GrabMachine = falseblnr; 1296#endif 1297 1298#if VarFullScreen 1299LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0); 1300#endif 1301 1302#if EnableMagnify 1303LOCALVAR blnr UseMagnify = (WantInitMagnify != 0); 1304#endif 1305 1306#if EnableMagnify 1307LOCALPROC MyScaleRect(Rect *r) 1308{ 1309 r->left *= MyWindowScale; 1310 r->right *= MyWindowScale; 1311 r->top *= MyWindowScale; 1312 r->bottom *= MyWindowScale; 1313} 1314#endif 1315 1316LOCALPROC SetScrnRectFromCoords(Rect *r, 1317 si4b top, si4b left, si4b bottom, si4b right) 1318{ 1319 r->left = left; 1320 r->right = right; 1321 r->top = top; 1322 r->bottom = bottom; 1323 1324#if VarFullScreen 1325 if (UseFullScreen) 1326#endif 1327#if MayFullScreen 1328 { 1329 OffsetRect(r, - ViewHStart, - ViewVStart); 1330 } 1331#endif 1332 1333#if EnableMagnify 1334 if (UseMagnify) { 1335 MyScaleRect(r); 1336 } 1337#endif 1338 1339#if VarFullScreen 1340 if (UseFullScreen) 1341#endif 1342#if MayFullScreen 1343 { 1344 OffsetRect(r, hOffset, vOffset); 1345 } 1346#endif 1347} 1348 1349LOCALVAR ui3p ScalingBuff = nullpr; 1350 1351LOCALVAR ui3p CLUT_final; 1352 1353#define CLUT_finalsz1 (256 * 8) 1354 1355#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 1356 1357#define CLUT_finalClrSz (256 << (5 - vMacScreenDepth)) 1358 1359#define CLUT_finalsz ((CLUT_finalClrSz > CLUT_finalsz1) \ 1360 ? CLUT_finalClrSz : CLUT_finalsz1) 1361 1362#else 1363#define CLUT_finalsz CLUT_finalsz1 1364#endif 1365 1366 1367#define ScrnMapr_DoMap UpdateBWLuminanceCopy 1368#define ScrnMapr_Src GetCurDrawBuff() 1369#define ScrnMapr_Dst ScalingBuff 1370#define ScrnMapr_SrcDepth 0 1371#define ScrnMapr_DstDepth 3 1372#define ScrnMapr_Map CLUT_final 1373 1374#include "SCRNMAPR.h" 1375 1376 1377#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 1378 1379#define ScrnMapr_DoMap UpdateMappedColorCopy 1380#define ScrnMapr_Src GetCurDrawBuff() 1381#define ScrnMapr_Dst ScalingBuff 1382#define ScrnMapr_SrcDepth vMacScreenDepth 1383#define ScrnMapr_DstDepth 5 1384#define ScrnMapr_Map CLUT_final 1385 1386#include "SCRNMAPR.h" 1387 1388#endif 1389 1390#if vMacScreenDepth >= 4 1391 1392#define ScrnTrns_DoTrans UpdateTransColorCopy 1393#define ScrnTrns_Src GetCurDrawBuff() 1394#define ScrnTrns_Dst ScalingBuff 1395#define ScrnTrns_SrcDepth vMacScreenDepth 1396#define ScrnTrns_DstDepth 5 1397#define ScrnTrns_DstZLo 1 1398 1399#include "SCRNTRNS.h" 1400 1401#endif 1402 1403LOCALPROC UpdateLuminanceCopy(si4b top, si4b left, 1404 si4b bottom, si4b right) 1405{ 1406 int i; 1407 1408#if 0 != vMacScreenDepth 1409 if (UseColorMode) { 1410 1411#if vMacScreenDepth < 4 1412 1413 if (! ColorTransValid) { 1414 int j; 1415 int k; 1416 ui5p p4; 1417 1418 p4 = (ui5p)CLUT_final; 1419 for (i = 0; i < 256; ++i) { 1420 for (k = 1 << (3 - vMacScreenDepth); --k >= 0; ) { 1421 j = (i >> (k << vMacScreenDepth)) & (CLUT_size - 1); 1422 *p4++ = (((long)CLUT_reds[j] & 0xFF00) << 16) 1423 | (((long)CLUT_greens[j] & 0xFF00) << 8) 1424 | ((long)CLUT_blues[j] & 0xFF00); 1425 } 1426 } 1427 ColorTransValid = trueblnr; 1428 } 1429 1430 UpdateMappedColorCopy(top, left, bottom, right); 1431 1432#else 1433 UpdateTransColorCopy(top, left, bottom, right); 1434#endif 1435 1436 } else 1437#endif 1438 { 1439 if (! ColorTransValid) { 1440 int k; 1441 ui3p p4 = (ui3p)CLUT_final; 1442 1443 for (i = 0; i < 256; ++i) { 1444 for (k = 8; --k >= 0; ) { 1445 *p4++ = ((i >> k) & 0x01) - 1; 1446 } 1447 } 1448 ColorTransValid = trueblnr; 1449 } 1450 1451 UpdateBWLuminanceCopy(top, left, bottom, right); 1452 } 1453} 1454 1455LOCALVAR AGLContext ctx = NULL; 1456LOCALVAR short GLhOffset; 1457LOCALVAR short GLvOffset; 1458 1459#ifndef UseAGLdoublebuff 1460#define UseAGLdoublebuff 0 1461#endif 1462 1463LOCALPROC MyDrawWithOpenGL(ui4r top, ui4r left, ui4r bottom, ui4r right) 1464{ 1465 if (NULL == ctx) { 1466 /* oops */ 1467 } else if (GL_TRUE != aglSetCurrentContext(ctx)) { 1468 /* err = aglReportError() */ 1469 } else { 1470 si4b top2; 1471 si4b left2; 1472 1473#if UseAGLdoublebuff 1474 /* redraw all */ 1475 top = 0; 1476 left = 0; 1477 bottom = vMacScreenHeight; 1478 right = vMacScreenWidth; 1479#endif 1480 1481#if VarFullScreen 1482 if (UseFullScreen) 1483#endif 1484#if MayFullScreen 1485 { 1486 if (top < ViewVStart) { 1487 top = ViewVStart; 1488 } 1489 if (left < ViewHStart) { 1490 left = ViewHStart; 1491 } 1492 if (bottom > ViewVStart + ViewVSize) { 1493 bottom = ViewVStart + ViewVSize; 1494 } 1495 if (right > ViewHStart + ViewHSize) { 1496 right = ViewHStart + ViewHSize; 1497 } 1498 1499 if ((top >= bottom) || (left >= right)) { 1500 goto label_exit; 1501 } 1502 } 1503#endif 1504 1505 top2 = top; 1506 left2 = left; 1507 1508#if VarFullScreen 1509 if (UseFullScreen) 1510#endif 1511#if MayFullScreen 1512 { 1513 left2 -= ViewHStart; 1514 top2 -= ViewVStart; 1515 } 1516#endif 1517 1518#if EnableMagnify 1519 if (UseMagnify) { 1520 top2 *= MyWindowScale; 1521 left2 *= MyWindowScale; 1522 } 1523#endif 1524 1525#if 0 1526 glClear(GL_COLOR_BUFFER_BIT); 1527 glBitmap(vMacScreenWidth, 1528 vMacScreenHeight, 1529 0, 1530 0, 1531 0, 1532 0, 1533 (const GLubyte *)GetCurDrawBuff()); 1534#endif 1535#if 1 1536 UpdateLuminanceCopy(top, left, bottom, right); 1537 glRasterPos2i(GLhOffset + left2, GLvOffset - top2); 1538#if 0 != vMacScreenDepth 1539 if (UseColorMode) { 1540 glDrawPixels(right - left, 1541 bottom - top, 1542 GL_RGBA, 1543 GL_UNSIGNED_INT_8_8_8_8, 1544 ScalingBuff + (left + top * vMacScreenWidth) * 4 1545 ); 1546 } else 1547#endif 1548 { 1549 glDrawPixels(right - left, 1550 bottom - top, 1551 GL_LUMINANCE, 1552 GL_UNSIGNED_BYTE, 1553 ScalingBuff + (left + top * vMacScreenWidth) 1554 ); 1555 } 1556#endif 1557 1558#if 0 /* a very quick and dirty check of where drawing */ 1559 glDrawPixels(right - left, 1560 1, 1561 GL_RED, 1562 GL_UNSIGNED_BYTE, 1563 ScalingBuff + (left + top * vMacScreenWidth) 1564 ); 1565 1566 glDrawPixels(1, 1567 bottom - top, 1568 GL_RED, 1569 GL_UNSIGNED_BYTE, 1570 ScalingBuff + (left + top * vMacScreenWidth) 1571 ); 1572#endif 1573 1574#if UseAGLdoublebuff 1575 aglSwapBuffers(ctx); 1576#else 1577 glFlush(); 1578#endif 1579 } 1580 1581#if MayFullScreen 1582label_exit: 1583 ; 1584#endif 1585} 1586 1587LOCALPROC Update_Screen(void) 1588{ 1589 MyDrawWithOpenGL(0, 0, vMacScreenHeight, vMacScreenWidth); 1590} 1591 1592LOCALPROC MyDrawChangesAndClear(void) 1593{ 1594 if (ScreenChangedBottom > ScreenChangedTop) { 1595 MyDrawWithOpenGL(ScreenChangedTop, ScreenChangedLeft, 1596 ScreenChangedBottom, ScreenChangedRight); 1597 ScreenClearChanges(); 1598 } 1599} 1600 1601 1602LOCALVAR blnr MouseIsOutside = falseblnr; 1603 /* 1604 MouseIsOutside true if sure mouse outside our window. If in 1605 our window, or not sure, set false. 1606 */ 1607 1608LOCALVAR blnr WantCursorHidden = falseblnr; 1609 1610LOCALPROC MousePositionNotify(Point NewMousePos) 1611{ 1612 /* 1613 Not MouseIsOutside includes in the title bar, etc, so have 1614 to check if in content area. 1615 */ 1616 1617 Rect r; 1618 blnr ShouldHaveCursorHidden = ! MouseIsOutside; 1619 1620 GetWindowBounds(gMyMainWindow, kWindowContentRgn, &r); 1621 1622 NewMousePos.h -= r.left; 1623 NewMousePos.v -= r.top; 1624 1625#if VarFullScreen 1626 if (UseFullScreen) 1627#endif 1628#if MayFullScreen 1629 { 1630 NewMousePos.h -= hOffset; 1631 NewMousePos.v -= vOffset; 1632 } 1633#endif 1634 1635#if EnableMagnify 1636 if (UseMagnify) { 1637 NewMousePos.h /= MyWindowScale; 1638 NewMousePos.v /= MyWindowScale; 1639 } 1640#endif 1641 1642#if VarFullScreen 1643 if (UseFullScreen) 1644#endif 1645#if MayFullScreen 1646 { 1647 NewMousePos.h += ViewHStart; 1648 NewMousePos.v += ViewVStart; 1649 } 1650#endif 1651 1652#if EnableFSMouseMotion 1653 if (HaveMouseMotion) { 1654 MyMousePositionSetDelta(NewMousePos.h - SavedMouseH, 1655 NewMousePos.v - SavedMouseV); 1656 SavedMouseH = NewMousePos.h; 1657 SavedMouseV = NewMousePos.v; 1658 } else 1659#endif 1660 { 1661 if (NewMousePos.h < 0) { 1662 NewMousePos.h = 0; 1663 ShouldHaveCursorHidden = falseblnr; 1664 } else if (NewMousePos.h >= vMacScreenWidth) { 1665 NewMousePos.h = vMacScreenWidth - 1; 1666 ShouldHaveCursorHidden = falseblnr; 1667 } 1668 if (NewMousePos.v < 0) { 1669 NewMousePos.v = 0; 1670 ShouldHaveCursorHidden = falseblnr; 1671 } else if (NewMousePos.v >= vMacScreenHeight) { 1672 NewMousePos.v = vMacScreenHeight - 1; 1673 ShouldHaveCursorHidden = falseblnr; 1674 } 1675 1676 /* if (ShouldHaveCursorHidden || CurMouseButton) */ 1677 /* 1678 for a game like arkanoid, would like mouse to still 1679 move even when outside window in one direction 1680 */ 1681 MyMousePositionSet(NewMousePos.h, NewMousePos.v); 1682 } 1683 1684 WantCursorHidden = ShouldHaveCursorHidden; 1685} 1686 1687LOCALPROC CheckMouseState(void) 1688{ 1689 Point NewMousePos; 1690 GetGlobalMouse(&NewMousePos); 1691 /* 1692 Deprecated, but haven't found usable replacement. 1693 Between window deactivate and then reactivate, 1694 mouse can move without getting kEventMouseMoved. 1695 Also no way to get initial position. 1696 (Also don't get kEventMouseMoved after 1697 using menu bar. Or while using menubar, but 1698 that isn't too important.) 1699 */ 1700 MousePositionNotify(NewMousePos); 1701} 1702 1703LOCALVAR blnr gLackFocusFlag = falseblnr; 1704LOCALVAR blnr gWeAreActive = falseblnr; 1705 1706GLOBALOSGLUPROC DoneWithDrawingForTick(void) 1707{ 1708#if EnableFSMouseMotion 1709 if (HaveMouseMotion) { 1710 AutoScrollScreen(); 1711 } 1712#endif 1713 MyDrawChangesAndClear(); 1714} 1715 1716LOCALVAR blnr CurSpeedStopped = trueblnr; 1717 1718/* --- keyboard --- */ 1719 1720LOCALVAR UInt32 SavedModifiers = 0; 1721 1722LOCALPROC MyUpdateKeyboardModifiers(UInt32 theModifiers) 1723{ 1724 UInt32 ChangedModifiers = theModifiers ^ SavedModifiers; 1725 1726 if (0 != ChangedModifiers) { 1727 if (0 != (ChangedModifiers & shiftKey)) { 1728 Keyboard_UpdateKeyMap2(MKC_formac_Shift, 1729 (shiftKey & theModifiers) != 0); 1730 } 1731 if (0 != (ChangedModifiers & cmdKey)) { 1732 Keyboard_UpdateKeyMap2(MKC_formac_Command, 1733 (cmdKey & theModifiers) != 0); 1734 } 1735 if (0 != (ChangedModifiers & alphaLock)) { 1736 Keyboard_UpdateKeyMap2(MKC_formac_CapsLock, 1737 (alphaLock & theModifiers) != 0); 1738 } 1739 if (0 != (ChangedModifiers & optionKey)) { 1740 Keyboard_UpdateKeyMap2(MKC_formac_Option, 1741 (optionKey & theModifiers) != 0); 1742 } 1743 if (0 != (ChangedModifiers & controlKey)) { 1744 Keyboard_UpdateKeyMap2(MKC_formac_Control, 1745 (controlKey & theModifiers) != 0); 1746 } 1747 1748 SavedModifiers = theModifiers; 1749 } 1750} 1751 1752LOCALPROC ReconnectKeyCodes3(void) 1753{ 1754 /* 1755 turn off any modifiers (other than alpha) 1756 that were turned on by drag and drop, 1757 unless still being held down. 1758 */ 1759 1760 UInt32 theModifiers = GetCurrentKeyModifiers(); 1761 1762 MyUpdateKeyboardModifiers(theModifiers 1763 & (SavedModifiers | alphaLock)); 1764 1765 SavedModifiers = theModifiers; 1766} 1767 1768/* --- display utilities --- */ 1769 1770/* DoForEachDisplay adapted from Apple Technical Q&A QA1168 */ 1771 1772typedef void 1773(*ForEachDisplayProcPtr) (CGDirectDisplayID display); 1774 1775LOCALPROC DoForEachDisplay0(CGDisplayCount dspCount, 1776 CGDirectDisplayID *displays, ForEachDisplayProcPtr p) 1777{ 1778 CGDisplayCount i; 1779 1780 if (noErr == MyCGGetActiveDisplayList(dspCount, 1781 displays, &dspCount)) 1782 { 1783 for (i = 0; i < dspCount; ++i) { 1784 p(displays[i]); 1785 } 1786 } 1787} 1788 1789LOCALPROC DoForEachDisplay(ForEachDisplayProcPtr p) 1790{ 1791 CGDisplayCount dspCount = 0; 1792 1793 if (HaveMyCGGetActiveDisplayList() 1794 && (noErr == MyCGGetActiveDisplayList(0, NULL, &dspCount))) 1795 { 1796 if (dspCount <= 2) { 1797 CGDirectDisplayID displays[2]; 1798 DoForEachDisplay0(dspCount, displays, p); 1799 } else { 1800 CGDirectDisplayID *displays = 1801 calloc((size_t)dspCount, sizeof(CGDirectDisplayID)); 1802 if (NULL != displays) { 1803 DoForEachDisplay0(dspCount, displays, p); 1804 free(displays); 1805 } 1806 } 1807 } 1808} 1809 1810LOCALVAR void *datp; 1811 1812LOCALPROC MyMainDisplayIDProc(CGDirectDisplayID display) 1813{ 1814 CGDirectDisplayID *p = (CGDirectDisplayID *)datp; 1815 1816 if (kCGNullDirectDisplay == *p) { 1817 *p = display; 1818 } 1819} 1820 1821LOCALFUNC CGDirectDisplayID MyMainDisplayID(void) 1822{ 1823 if (HaveMyCGMainDisplayID()) { 1824 return MyCGMainDisplayID(); 1825 } else { 1826 /* for before OS X 10.2 */ 1827 CGDirectDisplayID r = kCGNullDirectDisplay; 1828 void *savedatp = datp; 1829 datp = (void *)&r; 1830 DoForEachDisplay(MyMainDisplayIDProc); 1831 datp = savedatp; 1832 return r; 1833 } 1834} 1835 1836/* --- cursor hiding --- */ 1837 1838#if 0 1839LOCALPROC MyShowCursorProc(CGDirectDisplayID display) 1840{ 1841 (void) CGDisplayShowCursor(display); 1842} 1843#endif 1844 1845LOCALPROC MyShowCursor(void) 1846{ 1847#if 0 1848 /* ShowCursor(); deprecated */ 1849 DoForEachDisplay(MyShowCursorProc); 1850#endif 1851 if (HaveMyCGDisplayShowCursor()) { 1852 (void) MyCGDisplayShowCursor(MyMainDisplayID()); 1853 /* documentation now claims argument ignored */ 1854 } 1855} 1856 1857#if 0 1858LOCALPROC MyHideCursorProc(CGDirectDisplayID display) 1859{ 1860 (void) CGDisplayHideCursor(display); 1861} 1862#endif 1863 1864LOCALPROC MyHideCursor(void) 1865{ 1866#if 0 1867 /* HideCursor(); deprecated */ 1868 DoForEachDisplay(MyHideCursorProc); 1869#endif 1870 if (HaveMyCGDisplayHideCursor()) { 1871 (void) MyCGDisplayHideCursor(MyMainDisplayID()); 1872 /* documentation now claims argument ignored */ 1873 } 1874} 1875 1876LOCALVAR blnr HaveCursorHidden = falseblnr; 1877 1878LOCALPROC ForceShowCursor(void) 1879{ 1880 if (HaveCursorHidden) { 1881 HaveCursorHidden = falseblnr; 1882 MyShowCursor(); 1883 } 1884} 1885 1886/* --- cursor moving --- */ 1887 1888LOCALPROC SetCursorArrow(void) 1889{ 1890 SetThemeCursor(kThemeArrowCursor); 1891} 1892 1893#if EnableMoveMouse 1894LOCALFUNC blnr MyMoveMouse(si4b h, si4b v) 1895{ 1896 Point CurMousePos; 1897 Rect r; 1898 1899#if VarFullScreen 1900 if (UseFullScreen) 1901#endif 1902#if MayFullScreen 1903 { 1904 h -= ViewHStart; 1905 v -= ViewVStart; 1906 } 1907#endif 1908 1909#if EnableMagnify 1910 if (UseMagnify) { 1911 h *= MyWindowScale; 1912 v *= MyWindowScale; 1913 } 1914#endif 1915 1916#if VarFullScreen 1917 if (UseFullScreen) 1918#endif 1919#if MayFullScreen 1920 { 1921 h += hOffset; 1922 v += vOffset; 1923 } 1924#endif 1925 1926 GetWindowBounds(gMyMainWindow, kWindowContentRgn, &r); 1927 CurMousePos.h = r.left + h; 1928 CurMousePos.v = r.top + v; 1929 1930 /* 1931 This method from SDL_QuartzWM.m, "Simple DirectMedia Layer", 1932 Copyright (C) 1997-2003 Sam Lantinga 1933 */ 1934 if (HaveMyCGSetLocalEventsSuppressionInterval()) { 1935 if (noErr != MyCGSetLocalEventsSuppressionInterval(0.0)) { 1936 /* don't use MacMsg which can call MyMoveMouse */ 1937 } 1938 } 1939 if (HaveMyCGWarpMouseCursorPosition()) { 1940 CGPoint pt; 1941 pt.x = CurMousePos.h; 1942 pt.y = CurMousePos.v; 1943 if (noErr != MyCGWarpMouseCursorPosition(pt)) { 1944 /* don't use MacMsg which can call MyMoveMouse */ 1945 } 1946 } 1947#if 0 1948 if (HaveMyCGDisplayMoveCursorToPoint()) { 1949 CGPoint pt; 1950 pt.x = CurMousePos.h; 1951 pt.y = CurMousePos.v; 1952 if (noErr != MyCGDisplayMoveCursorToPoint( 1953 MyMainDisplayID(), pt)) 1954 { 1955 /* don't use MacMsg which can call MyMoveMouse */ 1956 } 1957 } 1958#endif 1959 1960 return trueblnr; 1961} 1962#endif 1963 1964#if EnableFSMouseMotion 1965LOCALPROC AdjustMouseMotionGrab(void) 1966{ 1967 if (gMyMainWindow != NULL) { 1968#if MayFullScreen 1969 if (GrabMachine) { 1970 /* 1971 if magnification changes, need to reset, 1972 even if HaveMouseMotion already true 1973 */ 1974 if (MyMoveMouse(ViewHStart + (ViewHSize / 2), 1975 ViewVStart + (ViewVSize / 2))) 1976 { 1977 SavedMouseH = ViewHStart + (ViewHSize / 2); 1978 SavedMouseV = ViewVStart + (ViewVSize / 2); 1979 HaveMouseMotion = trueblnr; 1980 } 1981 } else 1982#endif 1983 { 1984 if (HaveMouseMotion) { 1985 (void) MyMoveMouse(CurMouseH, CurMouseV); 1986 HaveMouseMotion = falseblnr; 1987 } 1988 } 1989 } 1990} 1991#endif 1992 1993#if EnableFSMouseMotion 1994LOCALPROC MyMouseConstrain(void) 1995{ 1996 si4b shiftdh; 1997 si4b shiftdv; 1998 1999 if (SavedMouseH < ViewHStart + (ViewHSize / 4)) { 2000 shiftdh = ViewHSize / 2; 2001 } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) { 2002 shiftdh = - ViewHSize / 2; 2003 } else { 2004 shiftdh = 0; 2005 } 2006 if (SavedMouseV < ViewVStart + (ViewVSize / 4)) { 2007 shiftdv = ViewVSize / 2; 2008 } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) { 2009 shiftdv = - ViewVSize / 2; 2010 } else { 2011 shiftdv = 0; 2012 } 2013 if ((shiftdh != 0) || (shiftdv != 0)) { 2014 SavedMouseH += shiftdh; 2015 SavedMouseV += shiftdv; 2016 if (! MyMoveMouse(SavedMouseH, SavedMouseV)) { 2017 HaveMouseMotion = falseblnr; 2018 } 2019 } 2020} 2021#endif 2022 2023#if 0 2024LOCALFUNC blnr InitMousePosition(void) 2025{ 2026 /* 2027 Since there doesn't seem to be any nondeprecated 2028 way to get initial cursor position, instead 2029 start by moving cursor to known position. 2030 */ 2031 2032#if VarFullScreen 2033 if (! UseFullScreen) 2034#endif 2035#if MayNotFullScreen 2036 { 2037 CurMouseH = 16; 2038 CurMouseV = 16; 2039 WantCursorHidden = trueblnr; 2040 (void) MyMoveMouse(CurMouseH, CurMouseV); 2041 } 2042#endif 2043 2044 return trueblnr; 2045} 2046#endif 2047 2048/* --- time, date, location, part 2 --- */ 2049 2050#include "DATE2SEC.h" 2051 2052LOCALFUNC blnr InitLocationDat(void) 2053{ 2054#if AutoLocation || AutoTimeZone 2055 MachineLocation loc; 2056 2057 ReadLocation(&loc); 2058#if AutoLocation 2059 CurMacLatitude = (ui5b)loc.latitude; 2060 CurMacLongitude = (ui5b)loc.longitude; 2061#endif 2062#if AutoTimeZone 2063 CurMacDelta = (ui5b)loc.u.gmtDelta; 2064#endif 2065#endif 2066 2067 { 2068 CFTimeZoneRef tz = CFTimeZoneCopySystem(); 2069 if (tz) { 2070 /* CFAbsoluteTime */ ATimeBase = CFAbsoluteTimeGetCurrent(); 2071 /* ETimeBase = GetCurrentEventTime(); */ 2072 { 2073 CFGregorianDate d = CFAbsoluteTimeGetGregorianDate( 2074 ATimeBase, tz); 2075 double floorsec = floor(d.second); 2076 ATimeBase -= (d.second - floorsec); 2077 /* ETimeBase -= (d.second - floorsec); */ 2078 TimeSecBase = Date2MacSeconds(floorsec, 2079 d.minute, d.hour, 2080 d.day, d.month, d.year); 2081 2082 (void) CheckDateTime(); 2083 } 2084 CFRelease(tz); 2085 } 2086 } 2087 2088 OnTrueTime = TrueEmulatedTime; 2089 2090 return trueblnr; 2091} 2092 2093LOCALPROC StartUpTimeAdjust(void) 2094{ 2095 NextTickChangeTime = GetCurrentEventTime() + MyTickDuration; 2096} 2097 2098/* --- sound --- */ 2099 2100#if MySoundEnabled 2101 2102#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */ 2103#define kSoundBuffers (1 << kLn2SoundBuffers) 2104#define kSoundBuffMask (kSoundBuffers - 1) 2105 2106#define DesiredMinFilledSoundBuffs 3 2107 /* 2108 if too big then sound lags behind emulation. 2109 if too small then sound will have pauses. 2110 */ 2111 2112#define kLnOneBuffLen 9 2113#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen) 2114#define kOneBuffLen (1UL << kLnOneBuffLen) 2115#define kAllBuffLen (1UL << kLnAllBuffLen) 2116#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3) 2117#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3) 2118#define kOneBuffSz (1UL << kLnOneBuffSz) 2119#define kAllBuffSz (1UL << kLnAllBuffSz) 2120#define kOneBuffMask (kOneBuffLen - 1) 2121#define kAllBuffMask (kAllBuffLen - 1) 2122#define dbhBufferSize (kAllBuffSz + kOneBuffSz) 2123 2124#define dbglog_SoundStuff (0 && dbglog_HAVE) 2125#define dbglog_SoundBuffStats (0 && dbglog_HAVE) 2126 2127LOCALVAR tpSoundSamp TheSoundBuffer = nullpr; 2128volatile static ui4b ThePlayOffset; 2129volatile static ui4b TheFillOffset; 2130volatile static ui4b MinFilledSoundBuffs; 2131#if dbglog_SoundBuffStats 2132LOCALVAR ui4b MaxFilledSoundBuffs; 2133#endif 2134LOCALVAR ui4b TheWriteOffset; 2135 2136LOCALPROC MySound_Start0(void) 2137{ 2138 /* Reset variables */ 2139 ThePlayOffset = 0; 2140 TheFillOffset = 0; 2141 TheWriteOffset = 0; 2142 MinFilledSoundBuffs = kSoundBuffers + 1; 2143#if dbglog_SoundBuffStats 2144 MaxFilledSoundBuffs = 0; 2145#endif 2146} 2147 2148GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL) 2149{ 2150 ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset); 2151 ui4b WriteBuffContig = 2152 kOneBuffLen - (TheWriteOffset & kOneBuffMask); 2153 2154 if (WriteBuffContig < n) { 2155 n = WriteBuffContig; 2156 } 2157 if (ToFillLen < n) { 2158 /* overwrite previous buffer */ 2159#if dbglog_SoundStuff 2160 dbglog_writeln("sound buffer over flow"); 2161#endif 2162 TheWriteOffset -= kOneBuffLen; 2163 } 2164 2165 *actL = n; 2166 return TheSoundBuffer + (TheWriteOffset & kAllBuffMask); 2167} 2168 2169#if 4 == kLn2SoundSampSz 2170LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p) 2171{ 2172 int i; 2173 2174 for (i = kOneBuffLen; --i >= 0; ) { 2175 *p++ -= 0x8000; 2176 } 2177} 2178#else 2179#define ConvertSoundBlockToNative(p) 2180#endif 2181 2182LOCALPROC MySound_WroteABlock(void) 2183{ 2184#if (4 == kLn2SoundSampSz) 2185 ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen; 2186 tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask); 2187#endif 2188 2189#if dbglog_SoundStuff 2190 dbglog_writeln("enter MySound_WroteABlock"); 2191#endif 2192 2193 ConvertSoundBlockToNative(p); 2194 2195 TheFillOffset = TheWriteOffset; 2196 2197#if dbglog_SoundBuffStats 2198 { 2199 ui4b ToPlayLen = TheFillOffset 2200 - ThePlayOffset; 2201 ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen; 2202 2203 if (ToPlayBuffs > MaxFilledSoundBuffs) { 2204 MaxFilledSoundBuffs = ToPlayBuffs; 2205 } 2206 } 2207#endif 2208} 2209 2210LOCALFUNC blnr MySound_EndWrite0(ui4r actL) 2211{ 2212 blnr v; 2213 2214 TheWriteOffset += actL; 2215 2216 if (0 != (TheWriteOffset & kOneBuffMask)) { 2217 v = falseblnr; 2218 } else { 2219 /* just finished a block */ 2220 2221 MySound_WroteABlock(); 2222 2223 v = trueblnr; 2224 } 2225 2226 return v; 2227} 2228 2229LOCALPROC MySound_SecondNotify0(void) 2230{ 2231 if (MinFilledSoundBuffs <= kSoundBuffers) { 2232 if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) { 2233#if dbglog_SoundStuff 2234 dbglog_writeln("MinFilledSoundBuffs too high"); 2235#endif 2236 NextTickChangeTime += MyTickDuration; 2237 } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) { 2238#if dbglog_SoundStuff 2239 dbglog_writeln("MinFilledSoundBuffs too low"); 2240#endif 2241 ++TrueEmulatedTime; 2242 } 2243#if dbglog_SoundBuffStats 2244 dbglog_writelnNum("MinFilledSoundBuffs", 2245 MinFilledSoundBuffs); 2246 dbglog_writelnNum("MaxFilledSoundBuffs", 2247 MaxFilledSoundBuffs); 2248 MaxFilledSoundBuffs = 0; 2249#endif 2250 MinFilledSoundBuffs = kSoundBuffers + 1; 2251 } 2252} 2253 2254LOCALPROC RampSound(tpSoundSamp p, 2255 trSoundSamp BeginVal, trSoundSamp EndVal) 2256{ 2257 int i; 2258 ui5r v = (((ui5r)BeginVal) << kLnOneBuffLen) + (kLnOneBuffLen >> 1); 2259 2260 for (i = kOneBuffLen; --i >= 0; ) { 2261 *p++ = v >> kLnOneBuffLen; 2262 v = v + EndVal - BeginVal; 2263 } 2264} 2265 2266#if 4 == kLn2SoundSampSz 2267#define ConvertSoundSampleFromNative(v) ((v) + 0x8000) 2268#else 2269#define ConvertSoundSampleFromNative(v) (v) 2270#endif 2271 2272struct MySoundR { 2273 tpSoundSamp fTheSoundBuffer; 2274 volatile ui4b (*fPlayOffset); 2275 volatile ui4b (*fFillOffset); 2276 volatile ui4b (*fMinFilledSoundBuffs); 2277 2278 volatile blnr PlayingBuffBlock; 2279 volatile trSoundSamp lastv; 2280 volatile blnr wantplaying; 2281 volatile blnr StartingBlocks; 2282 2283 CmpSoundHeader /* ExtSoundHeader */ soundHeader; 2284}; 2285typedef struct MySoundR MySoundR; 2286 2287 2288/* 2289 Some of this code descended from CarbonSndPlayDB, an 2290 example from Apple, as found being used in vMac for Mac OS. 2291*/ 2292 2293LOCALPROC InsertSndDoCommand(SndChannelPtr chan, SndCommand * newCmd) 2294{ 2295 if (-1 == chan->qHead) { 2296 chan->qHead = chan->qTail; 2297 } 2298 2299 if (1 <= chan->qHead) { 2300 chan->qHead--; 2301 } else { 2302 chan->qHead = chan->qTail; 2303 } 2304 2305 chan->queue[chan->qHead] = *newCmd; 2306} 2307 2308/* call back */ static pascal void 2309MySound_CallBack(SndChannelPtr theChannel, SndCommand * theCallBackCmd) 2310{ 2311 MySoundR *datp = 2312 (MySoundR *)(theCallBackCmd->param2); 2313 blnr wantplaying0 = datp->wantplaying; 2314 trSoundSamp v0 = datp->lastv; 2315 2316#if dbglog_SoundStuff 2317 dbglog_writeln("Enter MySound_CallBack"); 2318#endif 2319 2320 if (datp->PlayingBuffBlock) { 2321 /* finish with last sample */ 2322#if dbglog_SoundStuff 2323 dbglog_writeln("done with sample"); 2324#endif 2325 2326 *datp->fPlayOffset += kOneBuffLen; 2327 datp->PlayingBuffBlock = falseblnr; 2328 } 2329 2330 if ((! wantplaying0) && (kCenterSound == v0)) { 2331#if dbglog_SoundStuff 2332 dbglog_writeln("terminating"); 2333#endif 2334 } else { 2335 SndCommand playCmd; 2336 tpSoundSamp p; 2337 trSoundSamp v1 = v0; 2338 blnr WantRamp = falseblnr; 2339 ui4b CurPlayOffset = *datp->fPlayOffset; 2340 ui4b ToPlayLen = *datp->fFillOffset - CurPlayOffset; 2341 ui4b FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen; 2342 2343 if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) { 2344 *datp->fMinFilledSoundBuffs = FilledSoundBuffs; 2345 } 2346 2347 if (! wantplaying0) { 2348#if dbglog_SoundStuff 2349 dbglog_writeln("playing end transistion"); 2350#endif 2351 v1 = kCenterSound; 2352 2353 WantRamp = trueblnr; 2354 } else 2355 if (datp->StartingBlocks) { 2356#if dbglog_SoundStuff 2357 dbglog_writeln("playing start block"); 2358#endif 2359 2360 if ((ToPlayLen >> kLnOneBuffLen) < 12) { 2361 datp->StartingBlocks = falseblnr; 2362#if dbglog_SoundStuff 2363 dbglog_writeln("have enough samples to start"); 2364#endif 2365 2366 p = datp->fTheSoundBuffer 2367 + (CurPlayOffset & kAllBuffMask); 2368 v1 = ConvertSoundSampleFromNative(*p); 2369 } 2370 2371 WantRamp = trueblnr; 2372 } else 2373 if (0 == FilledSoundBuffs) { 2374#if dbglog_SoundStuff 2375 dbglog_writeln("playing under run"); 2376#endif 2377 2378 WantRamp = trueblnr; 2379 } else 2380 { 2381 /* play next sample */ 2382 p = datp->fTheSoundBuffer 2383 + (CurPlayOffset & kAllBuffMask); 2384 datp->PlayingBuffBlock = trueblnr; 2385 v1 = 2386 ConvertSoundSampleFromNative(*(p + kOneBuffLen - 1)); 2387#if dbglog_SoundStuff 2388 dbglog_writeln("playing sample"); 2389#endif 2390 } 2391 2392 if (WantRamp) { 2393 p = datp->fTheSoundBuffer + kAllBuffLen; 2394 2395#if dbglog_SoundStuff 2396 dbglog_writelnNum("v0", v0); 2397 dbglog_writelnNum("v1", v1); 2398#endif 2399 2400 RampSound(p, v0, v1); 2401 ConvertSoundBlockToNative(p); 2402 } 2403 2404 datp->soundHeader.samplePtr = (Ptr)p; 2405 datp->soundHeader.numFrames = 2406 (unsigned long)kOneBuffLen; 2407 2408 /* Insert our callback command */ 2409 InsertSndDoCommand (theChannel, theCallBackCmd); 2410 2411#if 0 2412 { 2413 int i; 2414 tpSoundSamp pS = 2415 (tpSoundSamp)datp->soundHeader.samplePtr; 2416 2417 for (i = datp->soundHeader.numFrames; --i >= 0; ) 2418 { 2419 fprintf(stderr, "%d\n", *pS++); 2420 } 2421 } 2422#endif 2423 2424 /* Play the next buffer */ 2425 playCmd.cmd = bufferCmd; 2426 playCmd.param1 = 0; 2427 playCmd.param2 = (long)&(datp->soundHeader); 2428 InsertSndDoCommand (theChannel, &playCmd); 2429 2430 datp->lastv = v1; 2431 } 2432} 2433 2434LOCALVAR MySoundR cur_audio; 2435 2436LOCALVAR SndCallBackUPP gCarbonSndPlayDoubleBufferCallBackUPP = NULL; 2437 2438LOCALVAR SndChannelPtr sndChannel = NULL; /* our sound channel */ 2439 2440LOCALPROC MySound_Start(void) 2441{ 2442#if dbglog_SoundStuff 2443 dbglog_writeln("MySound_Start"); 2444#endif 2445 2446 if (NULL == sndChannel) { 2447 SndCommand callBack; 2448 SndChannelPtr chan = NULL; 2449 2450 cur_audio.wantplaying = falseblnr; 2451 cur_audio.StartingBlocks = falseblnr; 2452 2453 MySound_Start0(); 2454 2455 SndNewChannel(&chan, sampledSynth, initMono, nil); 2456 if (NULL != chan) { 2457 sndChannel = chan; 2458 2459 cur_audio.PlayingBuffBlock = falseblnr; 2460 cur_audio.lastv = kCenterSound; 2461 cur_audio.StartingBlocks = trueblnr; 2462 cur_audio.wantplaying = trueblnr; 2463 2464 callBack.cmd = callBackCmd; 2465 callBack.param1 = 0; /* unused */ 2466 callBack.param2 = (long)&cur_audio; 2467 2468 sndChannel->callBack = 2469 gCarbonSndPlayDoubleBufferCallBackUPP; 2470 2471 (void) SndDoCommand (sndChannel, &callBack, true); 2472 } 2473 } 2474} 2475 2476LOCALPROC MySound_Stop(void) 2477{ 2478#if dbglog_SoundStuff 2479 dbglog_writeln("enter MySound_Stop"); 2480#endif 2481 2482 if (NULL != sndChannel) { 2483 ui4r retry_limit = 50; /* half of a second */ 2484 SCStatus r; 2485 2486 cur_audio.wantplaying = falseblnr; 2487#if dbglog_SoundStuff 2488 dbglog_writeln("cleared wantplaying"); 2489#endif 2490 2491label_retry: 2492 r.scChannelBusy = falseblnr; /* what is this for? */ 2493 if (noErr != SndChannelStatus(sndChannel, 2494 sizeof(SCStatus), &r)) 2495 { 2496 /* fail */ 2497 } else 2498 if ((! r.scChannelBusy) && (kCenterSound == cur_audio.lastv)) { 2499 /* done */ 2500 2501 /* 2502 observed reporting not busy unexpectedly, 2503 so also check lastv. 2504 */ 2505 } else 2506 if (0 == --retry_limit) { 2507#if dbglog_SoundStuff 2508 dbglog_writeln("retry limit reached"); 2509#endif 2510 /* 2511 don't trust SndChannelStatus, make 2512 sure don't get in infinite loop. 2513 */ 2514 2515 /* done */ 2516 } else 2517 { 2518 /* 2519 give time back, particularly important 2520 if got here on a suspend event. 2521 */ 2522 struct timespec rqt; 2523 struct timespec rmt; 2524 2525#if dbglog_SoundStuff 2526 dbglog_writeln("busy, so sleep"); 2527#endif 2528 2529 rqt.tv_sec = 0; 2530 rqt.tv_nsec = 10000000; 2531 (void) nanosleep(&rqt, &rmt); 2532 2533 goto label_retry; 2534 } 2535 2536 SndDisposeChannel(sndChannel, true); 2537 sndChannel = NULL; 2538 } 2539 2540#if dbglog_SoundStuff 2541 dbglog_writeln("leave MySound_Stop"); 2542#endif 2543} 2544 2545#define SOUND_SAMPLERATE rate22khz 2546 /* = 0x56EE8BA3 = (7833600 * 2 / 704) << 16 */ 2547 2548LOCALFUNC blnr MySound_Init(void) 2549{ 2550#if dbglog_SoundStuff 2551 dbglog_writeln("enter MySound_Init"); 2552#endif 2553 2554 cur_audio.fTheSoundBuffer = TheSoundBuffer; 2555 2556 cur_audio.fPlayOffset = &ThePlayOffset; 2557 cur_audio.fFillOffset = &TheFillOffset; 2558 cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs; 2559 cur_audio.wantplaying = falseblnr; 2560 2561 /* Init basic per channel information */ 2562 cur_audio.soundHeader.sampleRate = SOUND_SAMPLERATE; 2563 /* sample rate */ 2564 cur_audio.soundHeader.numChannels = 1; /* one channel */ 2565 cur_audio.soundHeader.loopStart = 0; 2566 cur_audio.soundHeader.loopEnd = 0; 2567 cur_audio.soundHeader.encode = cmpSH /* extSH */; 2568 cur_audio.soundHeader.baseFrequency = kMiddleC; 2569 cur_audio.soundHeader.numFrames = 2570 (unsigned long)kOneBuffLen; 2571 /* cur_audio.soundHeader.AIFFSampleRate = 0; */ 2572 /* unused */ 2573 cur_audio.soundHeader.markerChunk = nil; 2574 cur_audio.soundHeader.futureUse2 = 0; 2575 cur_audio.soundHeader.stateVars = nil; 2576 cur_audio.soundHeader.leftOverSamples = nil; 2577 cur_audio.soundHeader.compressionID = 0; 2578 /* no compression */ 2579 cur_audio.soundHeader.packetSize = 0; 2580 /* no compression */ 2581 cur_audio.soundHeader.snthID = 0; 2582 cur_audio.soundHeader.sampleSize = (1 << kLn2SoundSampSz); 2583 /* 8 or 16 bits per sample */ 2584 cur_audio.soundHeader.sampleArea[0] = 0; 2585#if 3 == kLn2SoundSampSz 2586 cur_audio.soundHeader.format = kSoundNotCompressed; 2587#elif 4 == kLn2SoundSampSz 2588 cur_audio.soundHeader.format = k16BitNativeEndianFormat; 2589#else 2590#error "unsupported kLn2SoundSampSz" 2591#endif 2592 cur_audio.soundHeader.samplePtr = (Ptr)TheSoundBuffer; 2593 2594 gCarbonSndPlayDoubleBufferCallBackUPP = 2595 NewSndCallBackUPP(MySound_CallBack); 2596 if (gCarbonSndPlayDoubleBufferCallBackUPP != NULL) { 2597 2598 MySound_Start(); 2599 /* 2600 This should be taken care of by LeaveSpeedStopped, 2601 but since takes a while to get going properly, 2602 start early. 2603 */ 2604 2605 return trueblnr; 2606 } 2607 return falseblnr; 2608} 2609 2610GLOBALOSGLUPROC MySound_EndWrite(ui4r actL) 2611{ 2612 if (MySound_EndWrite0(actL)) { 2613 } 2614} 2615 2616LOCALPROC MySound_SecondNotify(void) 2617{ 2618 if (sndChannel != NULL) { 2619 MySound_SecondNotify0(); 2620 } 2621} 2622 2623#endif 2624 2625 2626LOCALPROC MyAdjustGLforSize(int h, int v) 2627{ 2628 if (GL_TRUE != aglSetCurrentContext(ctx)) { 2629 /* err = aglReportError() */ 2630 } else { 2631 2632 glClearColor (0.0, 0.0, 0.0, 1.0); 2633 2634#if 1 2635 glViewport(0, 0, h, v); 2636 glMatrixMode(GL_PROJECTION); 2637 glLoadIdentity(); 2638 glOrtho(0, h, 0, v, -1.0, 1.0); 2639 glMatrixMode(GL_MODELVIEW); 2640#endif 2641 2642 glColor3f(0.0, 0.0, 0.0); 2643#if EnableMagnify 2644 if (UseMagnify) { 2645 glPixelZoom(MyWindowScale, - MyWindowScale); 2646 } else 2647#endif 2648 { 2649 glPixelZoom(1, -1); 2650 } 2651 glPixelStorei(GL_UNPACK_ROW_LENGTH, vMacScreenWidth); 2652 2653 glClear(GL_COLOR_BUFFER_BIT); 2654 2655 if (GL_TRUE != aglSetCurrentContext(NULL)) { 2656 /* err = aglReportError() */ 2657 } 2658 2659 ScreenChangedAll(); 2660 } 2661} 2662 2663LOCALVAR blnr WantScreensChangedCheck = falseblnr; 2664 2665LOCALPROC MyUpdateOpenGLContext(void) 2666{ 2667 if (NULL == ctx) { 2668 /* oops */ 2669 } else if (GL_TRUE != aglSetCurrentContext(ctx)) { 2670 /* err = aglReportError() */ 2671 } else { 2672 aglUpdateContext(ctx); 2673 } 2674} 2675 2676#if 0 /* some experiments */ 2677LOCALVAR CGrafPtr GrabbedPort = NULL; 2678#endif 2679 2680#if 0 2681LOCALPROC AdjustMainScreenGrab(void) 2682{ 2683 if (GrabMachine) { 2684 if (NULL == GrabbedPort) { 2685 /* CGDisplayCapture(MyMainDisplayID()); */ 2686 CGCaptureAllDisplays(); 2687 /* CGDisplayHideCursor( MyMainDisplayID() ); */ 2688 GrabbedPort = 2689 CreateNewPortForCGDisplayID((UInt32)MyMainDisplayID()); 2690 LockPortBits (GrabbedPort); 2691 } 2692 } else { 2693 if (GrabbedPort != NULL) { 2694 UnlockPortBits (GrabbedPort); 2695 /* CGDisplayShowCursor( MyMainDisplayID() ); */ 2696 /* CGDisplayRelease(MyMainDisplayID()); */ 2697 CGReleaseAllDisplays(); 2698 GrabbedPort = NULL; 2699 } 2700 } 2701} 2702#endif 2703 2704#if 0 2705typedef CGDisplayErr (*CGReleaseAllDisplaysProcPtr) 2706 (void); 2707 2708LOCALPROC MyReleaseAllDisplays(void) 2709{ 2710 if (HaveApplicationServicesBun()) { 2711 CGReleaseAllDisplaysProcPtr ReleaseAllDisplaysProc = 2712 (CGReleaseAllDisplaysProcPtr) 2713 CFBundleGetFunctionPointerForName( 2714 AppServBunRef, CFSTR("CGReleaseAllDisplays")); 2715 if (ReleaseAllDisplaysProc != NULL) { 2716 ReleaseAllDisplaysProc(); 2717 } 2718 } 2719} 2720 2721typedef CGDisplayErr (*CGCaptureAllDisplaysProcPtr) 2722 (void); 2723 2724LOCALPROC MyCaptureAllDisplays(void) 2725{ 2726 if (HaveApplicationServicesBun()) { 2727 CGCaptureAllDisplaysProcPtr CaptureAllDisplaysProc = 2728 (CGCaptureAllDisplaysProcPtr) 2729 CFBundleGetFunctionPointerForName( 2730 AppServBunRef, CFSTR("CGCaptureAllDisplays")); 2731 if (CaptureAllDisplaysProc != NULL) { 2732 CaptureAllDisplaysProc(); 2733 } 2734 } 2735} 2736#endif 2737 2738LOCALVAR AGLPixelFormat window_fmt = NULL; 2739LOCALVAR AGLContext window_ctx = NULL; 2740 2741#ifndef UseAGLfullscreen 2742#define UseAGLfullscreen 0 2743#endif 2744 2745#if UseAGLfullscreen 2746LOCALVAR AGLPixelFormat fullscreen_fmt = NULL; 2747LOCALVAR AGLContext fullscreen_ctx = NULL; 2748#endif 2749 2750#if UseAGLfullscreen 2751LOCALPROC MaybeFullScreen(void) 2752{ 2753 if ( 2754#if VarFullScreen 2755 UseFullScreen && 2756#endif 2757 (NULL == fullscreen_ctx) 2758 && HaveMyCGDisplayPixelsWide() 2759 && HaveMyCGDisplayPixelsHigh()) 2760 { 2761 static const GLint fullscreen_attrib[] = {AGL_RGBA, 2762 AGL_NO_RECOVERY, 2763 AGL_FULLSCREEN, 2764 AGL_SINGLE_RENDERER, AGL_ACCELERATED, 2765#if UseAGLdoublebuff 2766 AGL_DOUBLEBUFFER, 2767#endif 2768 AGL_NONE}; 2769 GDHandle theDevice; 2770 CGDirectDisplayID CurMainDisplayID = MyMainDisplayID(); 2771 2772 DMGetGDeviceByDisplayID( 2773 (DisplayIDType)CurMainDisplayID, &theDevice, false); 2774 fullscreen_fmt = aglChoosePixelFormat( 2775 &theDevice, 1, fullscreen_attrib); 2776 if (NULL == fullscreen_fmt) { 2777 /* err = aglReportError() */ 2778 } else { 2779 fullscreen_ctx = aglCreateContext(fullscreen_fmt, NULL); 2780 if (NULL == fullscreen_ctx) { 2781 /* err = aglReportError() */ 2782 } else { 2783 /* MyCaptureAllDisplays(); */ 2784 if (GL_TRUE != aglSetFullScreen(fullscreen_ctx, 2785 0, 0, 0, 0)) 2786 { 2787 /* err = aglReportError() */ 2788 } else { 2789 Rect r; 2790 2791 int h = MyCGDisplayPixelsWide(CurMainDisplayID); 2792 int v = MyCGDisplayPixelsHigh(CurMainDisplayID); 2793 2794 GetWindowBounds(gMyMainWindow, kWindowContentRgn, 2795 &r); 2796 2797 GLhOffset = r.left + hOffset; 2798 GLvOffset = v - (r.top + vOffset); 2799 2800 ctx = fullscreen_ctx; 2801 MyAdjustGLforSize(h, v); 2802 return; 2803 } 2804 /* MyReleaseAllDisplays(); */ 2805 2806 if (GL_TRUE != aglDestroyContext(fullscreen_ctx)) { 2807 /* err = aglReportError() */ 2808 } 2809 fullscreen_ctx = NULL; 2810 } 2811 2812 aglDestroyPixelFormat (fullscreen_fmt); 2813 fullscreen_fmt = NULL; 2814 } 2815 } 2816} 2817#endif 2818 2819#if UseAGLfullscreen 2820LOCALPROC NoFullScreen(void) 2821{ 2822 if (fullscreen_ctx != NULL) { 2823 Rect r; 2824 int h; 2825 int v; 2826 2827 GetWindowBounds(gMyMainWindow, kWindowContentRgn, &r); 2828 2829 h = r.right - r.left; 2830 v = r.bottom - r.top; 2831 2832 GLhOffset = hOffset; 2833 GLvOffset = v - vOffset; 2834 2835 ctx = window_ctx; 2836 2837 MyAdjustGLforSize(h, v); 2838 2839 Update_Screen(); 2840 2841 if (fullscreen_ctx != NULL) { 2842 if (GL_TRUE != aglDestroyContext(fullscreen_ctx)) { 2843 /* err = aglReportError() */ 2844 } 2845 fullscreen_ctx = NULL; 2846 } 2847 if (fullscreen_fmt != NULL) { 2848 aglDestroyPixelFormat(fullscreen_fmt); 2849 fullscreen_fmt = NULL; 2850 } 2851 } 2852} 2853#endif 2854 2855#if UseAGLfullscreen 2856LOCALPROC AdjustOpenGLGrab(void) 2857{ 2858 if (GrabMachine) { 2859 MaybeFullScreen(); 2860 } else { 2861 NoFullScreen(); 2862 } 2863} 2864#endif 2865 2866#if MayFullScreen 2867LOCALPROC AdjustMachineGrab(void) 2868{ 2869#if EnableFSMouseMotion 2870 AdjustMouseMotionGrab(); 2871#endif 2872#if UseAGLfullscreen 2873 AdjustOpenGLGrab(); 2874#endif 2875#if 0 2876 AdjustMainScreenGrab(); 2877#endif 2878} 2879#endif 2880 2881#if MayFullScreen 2882LOCALPROC UngrabMachine(void) 2883{ 2884 GrabMachine = falseblnr; 2885 AdjustMachineGrab(); 2886} 2887#endif 2888 2889LOCALPROC ClearWeAreActive(void) 2890{ 2891 if (gWeAreActive) { 2892 gWeAreActive = falseblnr; 2893 2894 DisconnectKeyCodes2(); 2895 2896 SavedModifiers &= alphaLock; 2897 2898 MyMouseButtonSet(falseblnr); 2899 2900#if MayFullScreen 2901 UngrabMachine(); 2902#endif 2903 2904 ForceShowCursor(); 2905 } 2906} 2907 2908/* --- basic dialogs --- */ 2909 2910LOCALFUNC CFStringRef CFStringCreateFromSubstCStr(char *s) 2911{ 2912 int L; 2913 UniChar x[ClStrMaxLength]; 2914 2915 UniCharStrFromSubstCStr(&L, x, s); 2916 2917 return CFStringCreateWithCharacters(kCFAllocatorDefault, x, L); 2918} 2919 2920#define kMyStandardAlert 128 2921 2922LOCALPROC CheckSavedMacMsg(void) 2923{ 2924 if (nullpr != SavedBriefMsg) { 2925 if (HaveMyCreateStandardAlert() && HaveMyRunStandardAlert()) { 2926 CFStringRef briefMsgu = CFStringCreateFromSubstCStr( 2927 SavedBriefMsg); 2928 if (NULL != briefMsgu) { 2929 CFStringRef longMsgu = CFStringCreateFromSubstCStr( 2930 SavedLongMsg); 2931 if (NULL != longMsgu) { 2932 DialogRef TheAlert; 2933 OSStatus err = MyCreateStandardAlert( 2934 (SavedFatalMsg) ? kAlertStopAlert 2935 : kAlertCautionAlert, 2936 briefMsgu, longMsgu, NULL, 2937 &TheAlert); 2938 if (noErr == err) { 2939 (void) MyRunStandardAlert(TheAlert, NULL, NULL); 2940 } 2941 CFRelease(longMsgu); 2942 } 2943 CFRelease(briefMsgu); 2944 } 2945 } 2946 2947 SavedBriefMsg = nullpr; 2948 } 2949} 2950 2951LOCALVAR blnr gTrueBackgroundFlag = falseblnr; 2952 2953LOCALPROC MyBeginDialog(void) 2954{ 2955 ClearWeAreActive(); 2956} 2957 2958LOCALPROC MyEndDialog(void) 2959{ 2960} 2961 2962/* --- hide/show menubar --- */ 2963 2964#if MayFullScreen 2965LOCALPROC My_HideMenuBar(void) 2966{ 2967 if (HaveMySetSystemUIMode()) { 2968 (void) MySetSystemUIMode(MykUIModeAllHidden, 2969 MykUIOptionDisableAppleMenu 2970#if GrabKeysFullScreen 2971 | MykUIOptionDisableProcessSwitch 2972#if GrabKeysMaxFullScreen /* dangerous !! */ 2973 | MykUIOptionDisableForceQuit 2974 | MykUIOptionDisableSessionTerminate 2975#endif 2976#endif 2977 ); 2978 } else { 2979 if (IsMenuBarVisible()) { 2980 HideMenuBar(); 2981 } 2982 } 2983} 2984#endif 2985 2986#if MayFullScreen 2987LOCALPROC My_ShowMenuBar(void) 2988{ 2989 if (HaveMySetSystemUIMode()) { 2990 (void) MySetSystemUIMode(MykUIModeNormal, 2991 0); 2992 } else { 2993 if (! IsMenuBarVisible()) { 2994 ShowMenuBar(); 2995 } 2996 } 2997} 2998#endif 2999 3000/* --- drives, part 2 --- */ 3001 3002LOCALPROC InitDrives(void) 3003{ 3004 /* 3005 This isn't really needed, Drives[i] 3006 need not have valid value when not vSonyIsInserted[i]. 3007 */ 3008 tDrive i; 3009 3010 for (i = 0; i < NumDrives; ++i) { 3011 Drives[i] = NotAfileRef; 3012 } 3013} 3014 3015LOCALPROC UnInitDrives(void) 3016{ 3017 tDrive i; 3018 3019 for (i = 0; i < NumDrives; ++i) { 3020 if (vSonyIsInserted(i)) { 3021 (void) vSonyEject(i); 3022 } 3023 } 3024} 3025 3026LOCALFUNC tMacErr Sony_Insert0(SInt16 refnum, blnr locked) 3027{ 3028 tDrive Drive_No; 3029 3030 if (! FirstFreeDisk(&Drive_No)) { 3031 (void) FSCloseFork(refnum); 3032 return mnvm_tmfoErr; 3033 } else { 3034 Drives[Drive_No] = refnum; 3035 DiskInsertNotify(Drive_No, locked); 3036 return mnvm_noErr; 3037 } 3038} 3039 3040LOCALPROC ReportStandardOpenDiskError(tMacErr err) 3041{ 3042 if (mnvm_noErr != err) { 3043 if (mnvm_tmfoErr == err) { 3044 MacMsg(kStrTooManyImagesTitle, 3045 kStrTooManyImagesMessage, falseblnr); 3046 } else if (mnvm_opWrErr == err) { 3047 MacMsg(kStrImageInUseTitle, 3048 kStrImageInUseMessage, falseblnr); 3049 } else { 3050 MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr); 3051 } 3052 } 3053} 3054 3055LOCALFUNC tMacErr InsertADiskFromFSRef(FSRef *theRef) 3056{ 3057 tMacErr err; 3058 HFSUniStr255 forkName; 3059 SInt16 refnum; 3060 blnr locked = falseblnr; 3061 3062 if (CheckSaveMacErr(FSGetDataForkName(&forkName))) { 3063 err = To_tMacErr(FSOpenFork(theRef, forkName.length, 3064 forkName.unicode, fsRdWrPerm, &refnum)); 3065 switch (err) { 3066 case mnvm_permErr: 3067 case mnvm_wrPermErr: 3068 case mnvm_afpAccessDenied: 3069 locked = trueblnr; 3070 err = To_tMacErr(FSOpenFork(theRef, forkName.length, 3071 forkName.unicode, fsRdPerm, &refnum)); 3072 break; 3073 default: 3074 break; 3075 } 3076 if (mnvm_noErr == err) { 3077 err = Sony_Insert0(refnum, locked); 3078 } 3079 } 3080 3081 return err; 3082} 3083 3084LOCALFUNC tMacErr LoadMacRomFromRefNum(SInt16 refnum) 3085{ 3086 tMacErr err; 3087 ByteCount actualCount; 3088 3089 if (mnvm_noErr != (err = To_tMacErr( 3090 FSReadFork(refnum, fsFromStart, 0, 3091 kROM_Size, ROM, &actualCount)))) 3092 { 3093 if (mnvm_eofErr == err) { 3094 MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage); 3095 } else { 3096 MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage); 3097 } 3098 } else 3099 { 3100 err = ROM_IsValid(); 3101 } 3102 3103 return err; 3104} 3105 3106LOCALFUNC tMacErr LoadMacRomFromFSRef(FSRef *theRef) 3107{ 3108 tMacErr err; 3109 HFSUniStr255 forkName; 3110 SInt16 refnum; 3111 3112 if (mnvm_noErr == (err = 3113 To_tMacErr(FSGetDataForkName(&forkName)))) 3114 if (mnvm_noErr == (err = To_tMacErr( 3115 FSOpenFork(theRef, forkName.length, 3116 forkName.unicode, fsRdPerm, &refnum)))) 3117 { 3118 err = LoadMacRomFromRefNum(refnum); 3119 3120 (void) FSCloseFork(refnum); 3121 } 3122 3123 return err; 3124} 3125 3126LOCALFUNC tMacErr InsertADiskFromFSRef1(FSRef *theRef) 3127{ 3128 tMacErr err; 3129 3130 if (! ROM_loaded) { 3131 err = LoadMacRomFromFSRef(theRef); 3132 } else { 3133 err = InsertADiskFromFSRef(theRef); 3134 } 3135 3136 return err; 3137} 3138 3139LOCALFUNC tMacErr InsertDisksFromDocList(AEDescList *docList) 3140{ 3141 tMacErr err = mnvm_noErr; 3142 long itemsInList; 3143 long index; 3144 AEKeyword keyword; 3145 DescType typeCode; 3146 FSRef theRef; 3147 Size actualSize; 3148 3149 if (CheckSaveMacErr(AECountItems(docList, &itemsInList))) { 3150 for (index = 1; index <= itemsInList; ++index) { 3151 if (CheckSaveMacErr(AEGetNthPtr(docList, index, typeFSRef, 3152 &keyword, &typeCode, (Ptr)&theRef, 3153 sizeof(FSRef), &actualSize))) 3154 if (CheckSavetMacErr(InsertADiskFromFSRef1(&theRef))) 3155 { 3156 } 3157 if (mnvm_noErr != err) { 3158 goto label_fail; 3159 } 3160 } 3161 } 3162 3163label_fail: 3164 return err; 3165} 3166 3167LOCALFUNC tMacErr InsertADiskFromNameEtc(FSRef *ParentRef, 3168 char *fileName) 3169{ 3170 tMacErr err; 3171 blnr isFolder; 3172 FSRef ChildRef; 3173 3174 if (CheckSavetMacErr(MyMakeFSRefC(ParentRef, fileName, 3175 &isFolder, &ChildRef))) 3176 { 3177 if (isFolder) { 3178 err = mnvm_miscErr; 3179 } else { 3180 if (CheckSavetMacErr(InsertADiskFromFSRef(&ChildRef))) { 3181 /* ok */ 3182 } 3183 } 3184 } 3185 3186 return err; 3187} 3188 3189#if IncludeSonyNew 3190LOCALFUNC tMacErr WriteZero(SInt16 refnum, ui5b L) 3191{ 3192#define ZeroBufferSize 2048 3193 tMacErr err = mnvm_noErr; 3194 ui5b i; 3195 ui3b buffer[ZeroBufferSize]; 3196 ByteCount actualCount; 3197 ui5b offset = 0; 3198 3199 memset(&buffer, 0, ZeroBufferSize); 3200 3201 while (L > 0) { 3202 i = (L > ZeroBufferSize) ? ZeroBufferSize : L; 3203 if (! CheckSaveMacErr(FSWriteFork(refnum, 3204 fsFromStart, 3205 offset, 3206 i, 3207 buffer, 3208 &actualCount))) 3209 { 3210 goto label_fail; 3211 } 3212 L -= i; 3213 offset += i; 3214 } 3215 3216label_fail: 3217 return err; 3218} 3219#endif 3220 3221#if IncludeSonyNew 3222LOCALFUNC tMacErr MyCreateFileCFStringRef(FSRef *saveFileParent, 3223 CFStringRef saveFileName, FSRef *NewRef) 3224{ 3225 tMacErr err; 3226 UniChar buffer[255]; 3227 3228 CFIndex len = CFStringGetLength(saveFileName); 3229 3230 if (len > 255) { 3231 len = 255; 3232 } 3233 3234 CFStringGetCharacters(saveFileName, CFRangeMake(0, len), buffer); 3235 3236 err = To_tMacErr(FSMakeFSRefUnicode(saveFileParent, len, 3237 buffer, kTextEncodingUnknown, NewRef)); 3238 if (mnvm_fnfErr == err) { /* file is not there yet - create it */ 3239 err = To_tMacErr(FSCreateFileUnicode(saveFileParent, 3240 len, buffer, 0, NULL, NewRef, NULL)); 3241 } 3242 3243 return err; 3244} 3245#endif 3246 3247#if IncludeSonyNew 3248LOCALFUNC tMacErr MakeNewDisk0(FSRef *saveFileParent, 3249 CFStringRef saveFileName, ui5b L) 3250{ 3251 tMacErr err; 3252 FSRef NewRef; 3253 HFSUniStr255 forkName; 3254 SInt16 refnum; 3255 3256 if (CheckSavetMacErr( 3257 MyCreateFileCFStringRef(saveFileParent, saveFileName, &NewRef))) 3258 { 3259 if (CheckSaveMacErr(FSGetDataForkName(&forkName))) 3260 if (CheckSaveMacErr(FSOpenFork(&NewRef, forkName.length, 3261 forkName.unicode, fsRdWrPerm, &refnum))) 3262 { 3263 SInt64 forkSize = L; 3264 if (CheckSaveMacErr( 3265 FSSetForkSize(refnum, fsFromStart, forkSize))) 3266 /* 3267 zero out fork. It looks like this is already done, 3268 but documentation says this isn't guaranteed. 3269 */ 3270 if (CheckSavetMacErr(WriteZero(refnum, L))) 3271 { 3272 err = Sony_Insert0(refnum, falseblnr); 3273 refnum = NotAfileRef; 3274 } 3275 if (NotAfileRef != refnum) { 3276 (void) FSCloseFork(refnum); 3277 } 3278 } 3279 if (mnvm_noErr != err) { 3280 (void) FSDeleteObject(&NewRef); 3281 } 3282 } 3283 3284 return err; 3285} 3286#endif 3287 3288#if IncludeSonyNameNew 3289LOCALFUNC CFStringRef CFStringCreateWithPbuf(tPbuf i) 3290{ 3291 return CFStringCreateWithBytes(NULL, 3292 (UInt8 *)PbufDat[i], PbufSize[i], 3293 kCFStringEncodingMacRoman, false); 3294} 3295#endif 3296 3297pascal Boolean NavigationFilterProc( 3298 AEDesc* theItem, void* info, void* NavCallBackUserData, 3299 NavFilterModes theNavFilterModes); 3300pascal Boolean NavigationFilterProc( 3301 AEDesc* theItem, void* info, void* NavCallBackUserData, 3302 NavFilterModes theNavFilterModes) 3303{ 3304 /* NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info; */ 3305 UnusedParam(theItem); 3306 UnusedParam(info); 3307 UnusedParam(theNavFilterModes); 3308 UnusedParam(NavCallBackUserData); 3309 3310 return true; /* display all items */ 3311} 3312 3313 3314pascal void NavigationEventProc( 3315 NavEventCallbackMessage callBackSelector, 3316 NavCBRecPtr callBackParms, void *NavCallBackUserData); 3317pascal void NavigationEventProc( 3318 NavEventCallbackMessage callBackSelector, 3319 NavCBRecPtr callBackParms, void *NavCallBackUserData) 3320{ 3321 UnusedParam(NavCallBackUserData); 3322 3323 switch (callBackSelector) { 3324 case kNavCBEvent: /* probably not needed in os x */ 3325 switch (callBackParms->eventData.eventDataParms.event->what) 3326 { 3327 case updateEvt: 3328 { 3329 WindowPtr which = 3330 (WindowPtr)callBackParms 3331 ->eventData.eventDataParms.event 3332 ->message; 3333 3334 BeginUpdate(which); 3335 3336 if (which == gMyMainWindow) { 3337 Update_Screen(); 3338 } 3339 3340 EndUpdate(which); 3341 } 3342 break; 3343 } 3344 break; 3345#if 0 3346 case kNavCBUserAction: 3347 { 3348 NavUserAction userAction = NavDialogGetUserAction( 3349 callBackParms->context); 3350 switch (userAction) { 3351 case kNavUserActionOpen: { 3352 /* got something to open */ 3353 break; 3354 } 3355 } 3356 } 3357 break; 3358 case kNavCBTerminate: 3359 break; 3360#endif 3361 } 3362} 3363 3364LOCALPROC InsertADisk0(void) 3365{ 3366 NavDialogRef theOpenDialog; 3367 NavDialogCreationOptions dialogOptions; 3368 NavReplyRecord theReply; 3369 NavTypeListHandle openList = NULL; 3370 NavEventUPP gEventProc = NewNavEventUPP(NavigationEventProc); 3371 NavObjectFilterUPP filterUPP = 3372 NewNavObjectFilterUPP(NavigationFilterProc); 3373 3374 if (noErr == NavGetDefaultDialogCreationOptions(&dialogOptions)) { 3375 dialogOptions.modality = kWindowModalityAppModal; 3376 dialogOptions.optionFlags |= kNavDontAutoTranslate; 3377 dialogOptions.optionFlags &= ~ kNavAllowPreviews; 3378 if (noErr == NavCreateGetFileDialog(&dialogOptions, 3379 (NavTypeListHandle)openList, 3380 gEventProc, NULL, 3381 filterUPP, NULL, &theOpenDialog)) 3382 { 3383 MyBeginDialog(); 3384 (void) NavDialogRun(theOpenDialog); 3385 MyEndDialog(); 3386 if (noErr == NavDialogGetReply(theOpenDialog, 3387 &theReply)) 3388 { 3389 if (theReply.validRecord) { 3390 ReportStandardOpenDiskError( 3391 InsertDisksFromDocList(&theReply.selection)); 3392 } 3393 (void) NavDisposeReply(&theReply); 3394 } 3395 NavDialogDispose(theOpenDialog); 3396 } 3397 } 3398 3399 DisposeNavEventUPP(gEventProc); 3400 DisposeNavObjectFilterUPP(filterUPP); 3401} 3402 3403#if IncludeSonyNew 3404LOCALPROC MakeNewDisk(ui5b L, CFStringRef NewDiskName) 3405{ 3406#if SaveDialogEnable 3407 NavDialogRef theSaveDialog; 3408 NavDialogCreationOptions dialogOptions; 3409 NavReplyRecord theReply; 3410 NavEventUPP gEventProc = NewNavEventUPP(NavigationEventProc); 3411 3412 if (noErr == NavGetDefaultDialogCreationOptions(&dialogOptions)) { 3413 dialogOptions.modality = kWindowModalityAppModal; 3414 dialogOptions.saveFileName = NewDiskName; 3415 if (noErr == NavCreatePutFileDialog(&dialogOptions, 3416 'TEXT', 'MPS ', 3417 gEventProc, NULL, 3418 &theSaveDialog)) 3419 { 3420 MyBeginDialog(); 3421 (void) NavDialogRun(theSaveDialog); 3422 MyEndDialog(); 3423 if (noErr == NavDialogGetReply(theSaveDialog, 3424 &theReply)) 3425 { 3426 if (theReply.validRecord) { 3427 long itemsInList; 3428 AEKeyword keyword; 3429 DescType typeCode; 3430 FSRef theRef; 3431 Size actualSize; 3432 3433 if (noErr == AECountItems( 3434 &theReply.selection, &itemsInList)) 3435 { 3436 if (itemsInList == 1) { 3437 if (noErr == AEGetNthPtr( 3438 &theReply.selection, 1, typeFSRef, 3439 &keyword, &typeCode, (Ptr)&theRef, 3440 sizeof(FSRef), &actualSize)) 3441 { 3442 ReportStandardOpenDiskError( 3443 MakeNewDisk0(&theRef, 3444 theReply.saveFileName, L)); 3445 } 3446 } 3447 } 3448 } 3449 (void) NavDisposeReply(&theReply); 3450 } 3451 NavDialogDispose(theSaveDialog); 3452 } 3453 } 3454 3455 DisposeNavEventUPP(gEventProc); 3456#else /* SaveDialogEnable */ 3457 FSRef OutRef; 3458 3459 if (mnvm_noErr == FindOrMakeNamedChildRef(&MyDatDirRef, 3460 "out", &OutRef)) 3461 { 3462 MakeNewDisk0(&OutRef, NewDiskName, L); 3463 } 3464#endif /* SaveDialogEnable */ 3465} 3466#endif 3467 3468LOCALFUNC tMacErr LoadMacRomFromNameFolder(FSRef *ParentRef, 3469 char *fileName) 3470{ 3471 tMacErr err; 3472 blnr isFolder; 3473 FSRef ChildRef; 3474 3475 if (mnvm_noErr == (err = 3476 MyMakeFSRefC(ParentRef, fileName, &isFolder, &ChildRef))) 3477 if (mnvm_noErr == (err = 3478 LoadMacRomFromFSRef(&ChildRef))) 3479 { 3480 } 3481 3482 return err; 3483} 3484 3485LOCALFUNC tMacErr LoadMacRomFromPrefDir(void) 3486{ 3487 tMacErr err; 3488 FSRef PrefRef; 3489 FSRef GryphelRef; 3490 FSRef ROMsRef; 3491 3492 if (mnvm_noErr == (err = To_tMacErr(FSFindFolder(kUserDomain, 3493 kPreferencesFolderType, kDontCreateFolder, &PrefRef)))) 3494 if (mnvm_noErr == (err = FindNamedChildRef(&PrefRef, 3495 "Gryphel", &GryphelRef))) 3496 if (mnvm_noErr == (err = FindNamedChildRef(&GryphelRef, 3497 "mnvm_rom", &ROMsRef))) 3498 if (mnvm_noErr == (err = LoadMacRomFromNameFolder(&ROMsRef, 3499 RomFileName))) 3500 { 3501 /* ok */ 3502 } 3503 3504 return err; 3505} 3506 3507LOCALFUNC blnr LoadMacRom(void) 3508{ 3509 tMacErr err; 3510 3511 if (mnvm_fnfErr == (err = 3512 LoadMacRomFromNameFolder(&MyDatDirRef, RomFileName))) 3513 if (mnvm_fnfErr == (err = 3514 LoadMacRomFromPrefDir())) 3515 { 3516 } 3517 3518 return trueblnr; /* keep launching Mini vMac, regardless */ 3519} 3520 3521LOCALFUNC blnr Sony_InsertIth(int i) 3522{ 3523 tMacErr err = mnvm_noErr; 3524 3525 if ((i > 9) || ! FirstFreeDisk(nullpr)) { 3526 return falseblnr; 3527 } else { 3528 char s[16] = "disk?.dsk"; 3529 3530 s[4] = '0' + i; 3531 3532 if (! CheckSavetMacErr(InsertADiskFromNameEtc(&MyDatDirRef, s))) 3533 { 3534 if (mnvm_fnfErr != err) { 3535 ReportStandardOpenDiskError(err); 3536 } 3537 /* stop on first error (including file not found) */ 3538 return falseblnr; 3539 } 3540 } 3541 3542 return trueblnr; 3543} 3544 3545LOCALFUNC blnr LoadInitialImages(void) 3546{ 3547 int i; 3548 3549 for (i = 1; Sony_InsertIth(i); ++i) { 3550 /* stop on first error (including file not found) */ 3551 } 3552 3553 return trueblnr; 3554} 3555 3556#if UseActvFile 3557 3558#define ActvCodeFileName "act_1" 3559 3560LOCALFUNC tMacErr OpenActvCodeFile(SInt16 *refnum) 3561{ 3562 tMacErr err; 3563 FSRef PrefRef; 3564 FSRef GryphelRef; 3565 FSRef ActRef; 3566 3567 if (CheckSaveMacErr(FSFindFolder(kUserDomain, 3568 kPreferencesFolderType, kDontCreateFolder, &PrefRef))) 3569 if (CheckSavetMacErr(FindNamedChildRef(&PrefRef, 3570 "Gryphel", &GryphelRef))) 3571 if (CheckSavetMacErr(FindNamedChildRef(&GryphelRef, 3572 "mnvm_act", &ActRef))) 3573 if (CheckSavetMacErr(OpenNamedFileInFolderRef(&ActRef, 3574 ActvCodeFileName, refnum))) 3575 { 3576 /* ok */ 3577 } 3578 3579 return err; 3580} 3581 3582LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p) 3583{ 3584 tMacErr err; 3585 SInt16 refnum; 3586 3587 if (CheckSavetMacErr(OpenActvCodeFile(&refnum))) { 3588 ByteCount actualCount; 3589 err = To_tMacErr(FSReadFork(refnum, fsFromStart, 0, 3590 ActvCodeFileLen, p, &actualCount)); 3591 (void) FSCloseFork(refnum); 3592 } 3593 3594 return err; 3595} 3596 3597LOCALFUNC tMacErr ActvCodeFileSave(ui3p p) 3598{ 3599 tMacErr err; 3600 SInt16 refnum; 3601 FSRef PrefRef; 3602 FSRef GryphelRef; 3603 FSRef ActRef; 3604 ByteCount count = ActvCodeFileLen; 3605 3606 if (CheckSaveMacErr(FSFindFolder(kUserDomain, 3607 kPreferencesFolderType, kDontCreateFolder, &PrefRef))) 3608 if (CheckSavetMacErr(FindOrMakeNamedChildRef(&PrefRef, 3609 "Gryphel", &GryphelRef))) 3610 if (CheckSavetMacErr(FindOrMakeNamedChildRef(&GryphelRef, 3611 "mnvm_act", &ActRef))) 3612 if (CheckSavetMacErr(OpenWriteNamedFileInFolderRef(&ActRef, 3613 ActvCodeFileName, &refnum))) 3614 { 3615 ByteCount actualCount; 3616 err = To_tMacErr(FSWriteFork(refnum, fsFromStart, 0, 3617 count, p, &actualCount)); 3618 (void) FSCloseFork(refnum); 3619 } 3620 3621 return err; 3622} 3623 3624#endif /* UseActvFile */ 3625 3626/* --- utilities for adapting to the environment --- */ 3627 3628LOCALPROC MyGetScreenBitsBounds(Rect *r) 3629{ 3630 if (HaveMyCGDisplayBounds()) { 3631 CGRect cgr = MyCGDisplayBounds(MyMainDisplayID()); 3632 3633 r->left = cgr.origin.x; 3634 r->top = cgr.origin.y; 3635 r->right = cgr.origin.x + cgr.size.width; 3636 r->bottom = cgr.origin.y + cgr.size.height; 3637 } 3638} 3639 3640#if MayNotFullScreen 3641LOCALPROC InvalWholeWindow(WindowRef mw) 3642{ 3643 Rect bounds; 3644 3645 GetWindowPortBounds(mw, &bounds); 3646 InvalWindowRect(mw, &bounds); 3647} 3648#endif 3649 3650#if MayNotFullScreen 3651LOCALPROC MySetMacWindContRect(WindowRef mw, Rect *r) 3652{ 3653 (void) SetWindowBounds (mw, kWindowContentRgn, r); 3654 InvalWholeWindow(mw); 3655} 3656#endif 3657 3658#if MayNotFullScreen 3659LOCALFUNC blnr MyGetWindowTitleBounds(WindowRef mw, Rect *r) 3660{ 3661 return (noErr == GetWindowBounds(mw, kWindowTitleBarRgn, r)); 3662} 3663#endif 3664 3665#if EnableRecreateW && MayNotFullScreen 3666LOCALFUNC blnr MyGetWindowContBounds(WindowRef mw, Rect *r) 3667{ 3668 return (noErr == GetWindowBounds(mw, kWindowContentRgn, r)); 3669} 3670#endif 3671 3672LOCALPROC MyGetGrayRgnBounds(Rect *r) 3673{ 3674 GetRegionBounds(GetGrayRgn(), (Rect *)r); 3675} 3676 3677#define openOnly 1 3678#define openPrint 2 3679 3680LOCALFUNC blnr GotRequiredParams(AppleEvent *theAppleEvent) 3681{ 3682 DescType typeCode; 3683 Size actualSize; 3684 OSErr theErr; 3685 3686 theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, 3687 typeWildCard, &typeCode, NULL, 0, &actualSize); 3688 if (errAEDescNotFound == theErr) { /* No more required params. */ 3689 return trueblnr; 3690 } else if (noErr == theErr) { /* More required params! */ 3691 return /* CheckSysCode(errAEEventNotHandled) */ falseblnr; 3692 } else { /* Unexpected Error! */ 3693 return /* CheckSysCode(theErr) */ falseblnr; 3694 } 3695} 3696 3697LOCALFUNC blnr GotRequiredParams0(AppleEvent *theAppleEvent) 3698{ 3699 DescType typeCode; 3700 Size actualSize; 3701 OSErr theErr; 3702 3703 theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, 3704 typeWildCard, &typeCode, NULL, 0, &actualSize); 3705 if (errAEDescNotFound == theErr) { /* No more required params. */ 3706 return trueblnr; 3707 } else if (noErr == theErr) { /* More required params! */ 3708 return trueblnr; /* errAEEventNotHandled; */ /*^*/ 3709 } else { /* Unexpected Error! */ 3710 return /* CheckSysCode(theErr) */ falseblnr; 3711 } 3712} 3713 3714/* call back */ static pascal OSErr OpenOrPrintFiles( 3715 AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon) 3716{ 3717 /* 3718 Adapted from IM VI: AppleEvent Manager: 3719 Handling Required AppleEvents 3720 */ 3721 AEDescList docList; 3722 3723 UnusedParam(reply); 3724 UnusedParam(aRefCon); 3725 /* put the direct parameter (a list of descriptors) into docList */ 3726 if (noErr == (AEGetParamDesc(theAppleEvent, keyDirectObject, 3727 typeAEList, &docList))) 3728 { 3729 if (GotRequiredParams0(theAppleEvent)) { 3730 /* Check for missing required parameters */ 3731 /* printIt = (openPrint == aRefCon) */ 3732 ReportStandardOpenDiskError( 3733 InsertDisksFromDocList(&docList)); 3734 } 3735 /* vCheckSysCode */ (void) (AEDisposeDesc(&docList)); 3736 } 3737 3738 return /* GetASysResultCode() */ 0; 3739} 3740 3741/* call back */ static pascal OSErr DoOpenEvent( 3742 AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon) 3743/* 3744 This is the alternative to getting an 3745 open document event on startup. 3746*/ 3747{ 3748 UnusedParam(reply); 3749 UnusedParam(aRefCon); 3750 if (GotRequiredParams0(theAppleEvent)) { 3751 } 3752 return /* GetASysResultCode() */ 0; 3753 /* Make sure there are no additional "required" parameters. */ 3754} 3755 3756 3757/* call back */ static pascal OSErr DoQuitEvent( 3758 AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon) 3759{ 3760 UnusedParam(reply); 3761 UnusedParam(aRefCon); 3762 if (GotRequiredParams(theAppleEvent)) { 3763 RequestMacOff = trueblnr; 3764 } 3765 3766 return /* GetASysResultCode() */ 0; 3767} 3768 3769LOCALFUNC blnr MyInstallEventHandler(AEEventClass theAEEventClass, 3770 AEEventID theAEEventID, ProcPtr p, 3771 long handlerRefcon, blnr isSysHandler) 3772{ 3773 return noErr == (AEInstallEventHandler(theAEEventClass, 3774 theAEEventID, NewAEEventHandlerUPP((AEEventHandlerProcPtr)p), 3775 handlerRefcon, isSysHandler)); 3776} 3777 3778LOCALPROC InstallAppleEventHandlers(void) 3779{ 3780 if (noErr == AESetInteractionAllowed(kAEInteractWithLocal)) 3781 if (MyInstallEventHandler(kCoreEventClass, kAEOpenApplication, 3782 (ProcPtr)DoOpenEvent, 0, falseblnr)) 3783 if (MyInstallEventHandler(kCoreEventClass, kAEOpenDocuments, 3784 (ProcPtr)OpenOrPrintFiles, openOnly, falseblnr)) 3785 if (MyInstallEventHandler(kCoreEventClass, kAEPrintDocuments, 3786 (ProcPtr)OpenOrPrintFiles, openPrint, falseblnr)) 3787 if (MyInstallEventHandler(kCoreEventClass, kAEQuitApplication, 3788 (ProcPtr)DoQuitEvent, 0, falseblnr)) 3789 { 3790 } 3791} 3792 3793static pascal OSErr GlobalTrackingHandler(DragTrackingMessage message, 3794 WindowRef theWindow, void *handlerRefCon, DragReference theDragRef) 3795{ 3796 RgnHandle hilightRgn; 3797 Rect Bounds; 3798 3799 UnusedParam(theWindow); 3800 UnusedParam(handlerRefCon); 3801 switch(message) { 3802 case kDragTrackingEnterWindow: 3803 hilightRgn = NewRgn(); 3804 if (hilightRgn != NULL) { 3805 SetScrnRectFromCoords(&Bounds, 3806 0, 0, vMacScreenHeight, vMacScreenWidth); 3807 RectRgn(hilightRgn, &Bounds); 3808 ShowDragHilite(theDragRef, hilightRgn, true); 3809 DisposeRgn(hilightRgn); 3810 } 3811 break; 3812 case kDragTrackingLeaveWindow: 3813 HideDragHilite(theDragRef); 3814 break; 3815 } 3816 3817 return noErr; 3818} 3819 3820LOCALFUNC tMacErr InsertADiskOrAliasFromFSRef(FSRef *theRef) 3821{ 3822 tMacErr err; 3823 Boolean isFolder; 3824 Boolean isAlias; 3825 3826 if (CheckSaveMacErr(FSResolveAliasFile(theRef, true, 3827 &isFolder, &isAlias))) 3828 { 3829 err = InsertADiskFromFSRef1(theRef); 3830 } 3831 3832 return err; 3833} 3834 3835LOCALFUNC tMacErr InsertADiskOrAliasFromSpec(FSSpec *spec) 3836{ 3837 tMacErr err; 3838 FSRef newRef; 3839 3840 if (CheckSaveMacErr(FSpMakeFSRef(spec, &newRef))) 3841 if (CheckSavetMacErr(InsertADiskOrAliasFromFSRef(&newRef))) 3842 { 3843 /* ok */ 3844 } 3845 3846 return err; 3847} 3848 3849static pascal OSErr GlobalReceiveHandler(WindowRef pWindow, 3850 void *handlerRefCon, DragReference theDragRef) 3851{ 3852 SInt16 mouseUpModifiers; 3853 unsigned short items; 3854 unsigned short index; 3855 ItemReference theItem; 3856 Size SentSize; 3857 HFSFlavor r; 3858 3859 UnusedParam(pWindow); 3860 UnusedParam(handlerRefCon); 3861 3862 if (noErr == GetDragModifiers(theDragRef, 3863 NULL, NULL, &mouseUpModifiers)) 3864 { 3865 MyUpdateKeyboardModifiers(mouseUpModifiers); 3866 } 3867 3868 if (noErr == CountDragItems(theDragRef, &items)) { 3869 for (index = 1; index <= items; ++index) { 3870 if (noErr == GetDragItemReferenceNumber(theDragRef, 3871 index, &theItem)) 3872 if (noErr == GetFlavorDataSize(theDragRef, 3873 theItem, flavorTypeHFS, &SentSize)) 3874 /* 3875 On very old macs SentSize might only be big enough 3876 to hold the actual file name. Have not seen this 3877 in OS X, but still leave the check 3878 as '<=' instead of '=='. 3879 */ 3880 if (SentSize <= sizeof(HFSFlavor)) 3881 if (noErr == GetFlavorData(theDragRef, theItem, 3882 flavorTypeHFS, (Ptr)&r, &SentSize, 0)) 3883 { 3884 ReportStandardOpenDiskError( 3885 InsertADiskOrAliasFromSpec(&r.fileSpec)); 3886 } 3887 } 3888 3889#if 1 3890 if (gTrueBackgroundFlag) { 3891 ProcessSerialNumber currentProcess = {0, kCurrentProcess}; 3892 3893 (void) SetFrontProcess(&currentProcess); 3894 } 3895#endif 3896 } 3897 3898 return noErr; 3899} 3900 3901LOCALVAR DragTrackingHandlerUPP gGlobalTrackingHandler = NULL; 3902LOCALVAR DragReceiveHandlerUPP gGlobalReceiveHandler = NULL; 3903 3904LOCALPROC UnPrepareForDragging(void) 3905{ 3906 if (NULL != gGlobalReceiveHandler) { 3907 RemoveReceiveHandler(gGlobalReceiveHandler, gMyMainWindow); 3908 DisposeDragReceiveHandlerUPP(gGlobalReceiveHandler); 3909 gGlobalReceiveHandler = NULL; 3910 } 3911 if (NULL != gGlobalTrackingHandler) { 3912 RemoveTrackingHandler(gGlobalTrackingHandler, gMyMainWindow); 3913 DisposeDragTrackingHandlerUPP(gGlobalTrackingHandler); 3914 gGlobalTrackingHandler = NULL; 3915 } 3916} 3917 3918LOCALFUNC blnr PrepareForDragging(void) 3919{ 3920 blnr IsOk = falseblnr; 3921 3922 gGlobalTrackingHandler = NewDragTrackingHandlerUPP( 3923 GlobalTrackingHandler); 3924 if (gGlobalTrackingHandler != NULL) { 3925 gGlobalReceiveHandler = NewDragReceiveHandlerUPP( 3926 GlobalReceiveHandler); 3927 if (gGlobalReceiveHandler != NULL) { 3928 if (noErr == InstallTrackingHandler(gGlobalTrackingHandler, 3929 gMyMainWindow, nil)) 3930 { 3931 if (noErr == InstallReceiveHandler( 3932 gGlobalReceiveHandler, gMyMainWindow, nil)) 3933 { 3934 IsOk = trueblnr; 3935 } 3936 } 3937 } 3938 } 3939 3940 return IsOk; 3941} 3942 3943LOCALPROC HandleEventLocation(EventRef theEvent) 3944{ 3945 Point NewMousePos; 3946 3947 if (! gWeAreActive) { 3948 return; 3949 } 3950 3951 if (noErr == GetEventParameter(theEvent, 3952 kEventParamMouseLocation, 3953 typeQDPoint, 3954 NULL, 3955 sizeof(NewMousePos), 3956 NULL, 3957 &NewMousePos)) 3958 { 3959 MousePositionNotify(NewMousePos); 3960 } 3961} 3962 3963LOCALPROC HandleEventModifiers(EventRef theEvent) 3964{ 3965 UInt32 theModifiers; 3966 3967 if (gWeAreActive) { 3968 GetEventParameter(theEvent, kEventParamKeyModifiers, 3969 typeUInt32, NULL, sizeof(typeUInt32), NULL, &theModifiers); 3970 3971 MyUpdateKeyboardModifiers(theModifiers); 3972 } 3973} 3974 3975LOCALVAR blnr IsOurMouseMove; 3976 3977static pascal OSStatus windowEventHandler( 3978 EventHandlerCallRef nextHandler, EventRef theEvent, 3979 void* userData) 3980{ 3981 OSStatus result = eventNotHandledErr; 3982 UInt32 eventClass = GetEventClass(theEvent); 3983 UInt32 eventKind = GetEventKind(theEvent); 3984 3985 UnusedParam(nextHandler); 3986 UnusedParam(userData); 3987 switch(eventClass) { 3988 case kEventClassWindow: 3989 switch(eventKind) { 3990 case kEventWindowClose: 3991 RequestMacOff = trueblnr; 3992 result = noErr; 3993 break; 3994 case kEventWindowDrawContent: 3995 Update_Screen(); 3996 result = noErr; 3997 break; 3998 case kEventWindowClickContentRgn: 3999 MouseIsOutside = falseblnr; 4000 HandleEventLocation(theEvent); 4001 HandleEventModifiers(theEvent); 4002 MyMouseButtonSet(trueblnr); 4003 result = noErr; 4004 break; 4005 case kEventWindowFocusAcquired: 4006 gLackFocusFlag = falseblnr; 4007 result = noErr; 4008 break; 4009 case kEventWindowFocusRelinquish: 4010 { 4011 WindowRef window; 4012 4013 (void) GetEventParameter(theEvent, 4014 kEventParamDirectObject, typeWindowRef, 4015 NULL, sizeof(WindowRef), NULL, &window); 4016 if ((window == gMyMainWindow) 4017 && (window != gMyOldWindow)) 4018 { 4019 ClearWeAreActive(); 4020 gLackFocusFlag = trueblnr; 4021 } 4022 } 4023 result = noErr; 4024 break; 4025 } 4026 break; 4027 case kEventClassMouse: 4028 switch(eventKind) { 4029 case kEventMouseMoved: 4030 case kEventMouseDragged: 4031 MouseIsOutside = falseblnr; 4032#if 0 /* don't bother, CheckMouseState will take care of it, better */ 4033 HandleEventLocation(theEvent); 4034 HandleEventModifiers(theEvent); 4035#endif 4036 IsOurMouseMove = trueblnr; 4037 result = noErr; 4038 break; 4039 } 4040 break; 4041 } 4042 4043 return result; 4044} 4045 4046LOCALFUNC blnr MyCreateNewWindow(Rect *Bounds, WindowPtr *theWindow) 4047{ 4048 WindowPtr ResultWin; 4049 blnr IsOk = falseblnr; 4050 4051 if (noErr == CreateNewWindow( 4052 4053#if VarFullScreen 4054 UseFullScreen ? 4055#endif 4056#if MayFullScreen 4057 /* 4058 appears not to work properly with aglSetWindowRef 4059 at least in OS X 10.5.5 4060 also doesn't seem to be needed. maybe dates from when 4061 didn't cover all screens in full screen mode. 4062 */ 4063 /* 4064 Oops, no, kDocumentWindowClass doesn't seem to 4065 work quite right if made immediately after 4066 launch, title bar gets moved onscreen. At least 4067 in Intel 10.5.6, doesn't happen in PowerPC 10.4.11. 4068 Oddly, this problem doesn't happen if icon 4069 already in dock before launch, but perhaps 4070 that is just a timing issue. 4071 So use kPlainWindowClass after all. 4072 */ 4073 kPlainWindowClass 4074#endif 4075#if VarFullScreen 4076 : 4077#endif 4078#if MayNotFullScreen 4079 kDocumentWindowClass 4080#endif 4081 , 4082 4083#if VarFullScreen 4084 UseFullScreen ? 4085#endif 4086#if MayFullScreen 4087 /* kWindowStandardHandlerAttribute */ 0 4088#endif 4089#if VarFullScreen 4090 : 4091#endif 4092#if MayNotFullScreen 4093 kWindowCloseBoxAttribute 4094 | kWindowCollapseBoxAttribute 4095#endif 4096 , 4097 4098 Bounds, &ResultWin 4099 )) 4100 { 4101#if VarFullScreen 4102 if (! UseFullScreen) 4103#endif 4104#if MayNotFullScreen 4105 { 4106 SetWindowTitleWithCFString(ResultWin, 4107 MyAppName /* CFSTR("Mini vMac") */); 4108 } 4109#endif 4110 InstallStandardEventHandler(GetWindowEventTarget(ResultWin)); 4111 { 4112 static const EventTypeSpec windowEvents[] = 4113 { 4114 {kEventClassWindow, kEventWindowClose}, 4115 {kEventClassWindow, kEventWindowDrawContent}, 4116 {kEventClassWindow, kEventWindowClickContentRgn}, 4117 {kEventClassMouse, kEventMouseMoved}, 4118 {kEventClassMouse, kEventMouseDragged}, 4119 {kEventClassWindow, kEventWindowFocusAcquired}, 4120 {kEventClassWindow, kEventWindowFocusRelinquish} 4121 }; 4122 InstallWindowEventHandler(ResultWin, 4123 NewEventHandlerUPP(windowEventHandler), 4124 GetEventTypeCount(windowEvents), 4125 windowEvents, 0, NULL); 4126 } 4127 4128 *theWindow = ResultWin; 4129 4130 IsOk = trueblnr; 4131 } 4132 4133 return IsOk; 4134} 4135 4136LOCALPROC CloseAglCurrentContext(void) 4137{ 4138 if (ctx != NULL) { 4139 /* 4140 Only because MyDrawWithOpenGL doesn't 4141 bother to do this. No one 4142 uses the CurrentContext 4143 without settting it first. 4144 */ 4145 if (GL_TRUE != aglSetCurrentContext(NULL)) { 4146 /* err = aglReportError() */ 4147 } 4148 ctx = NULL; 4149 } 4150} 4151 4152LOCALPROC CloseMainWindow(void) 4153{ 4154 UnPrepareForDragging(); 4155 4156 if (window_ctx != NULL) { 4157 if (GL_TRUE != aglDestroyContext(window_ctx)) { 4158 /* err = aglReportError() */ 4159 } 4160 window_ctx = NULL; 4161 } 4162 4163 if (window_fmt != NULL) { 4164 aglDestroyPixelFormat(window_fmt); 4165 window_fmt = NULL; 4166 } 4167 4168 if (gMyMainWindow != NULL) { 4169 DisposeWindow(gMyMainWindow); 4170 gMyMainWindow = NULL; 4171 } 4172} 4173 4174enum { 4175 kMagStateNormal, 4176#if EnableMagnify 4177 kMagStateMagnifgy, 4178#endif 4179 kNumMagStates 4180}; 4181 4182#define kMagStateAuto kNumMagStates 4183 4184#if MayNotFullScreen 4185LOCALVAR int CurWinIndx; 4186LOCALVAR blnr HavePositionWins[kNumMagStates]; 4187LOCALVAR Point WinPositionWins[kNumMagStates]; 4188#endif 4189 4190LOCALFUNC blnr CreateMainWindow(void) 4191{ 4192#if MayNotFullScreen 4193 int WinIndx; 4194#endif 4195 Rect MainScrnBounds; 4196 Rect AllScrnBounds; 4197 Rect NewWinRect; 4198 short leftPos; 4199 short topPos; 4200 short NewWindowHeight = vMacScreenHeight; 4201 short NewWindowWidth = vMacScreenWidth; 4202 blnr IsOk = falseblnr; 4203 4204#if VarFullScreen 4205 if (UseFullScreen) { 4206 My_HideMenuBar(); 4207 } else { 4208 My_ShowMenuBar(); 4209 } 4210#else 4211#if MayFullScreen 4212 My_HideMenuBar(); 4213#endif 4214#endif 4215 4216 MyGetGrayRgnBounds(&AllScrnBounds); 4217 MyGetScreenBitsBounds(&MainScrnBounds); 4218 4219#if EnableMagnify 4220 if (UseMagnify) { 4221 NewWindowHeight *= MyWindowScale; 4222 NewWindowWidth *= MyWindowScale; 4223 } 4224#endif 4225 4226 leftPos = MainScrnBounds.left 4227 + ((MainScrnBounds.right - MainScrnBounds.left) 4228 - NewWindowWidth) / 2; 4229 topPos = MainScrnBounds.top 4230 + ((MainScrnBounds.bottom - MainScrnBounds.top) 4231 - NewWindowHeight) / 2; 4232 if (leftPos < MainScrnBounds.left) { 4233 leftPos = MainScrnBounds.left; 4234 } 4235 if (topPos < MainScrnBounds.top) { 4236 topPos = MainScrnBounds.top; 4237 } 4238 4239#if VarFullScreen 4240 if (UseFullScreen) 4241#endif 4242#if MayFullScreen 4243 { 4244 ViewHSize = MainScrnBounds.right - MainScrnBounds.left; 4245 ViewVSize = MainScrnBounds.bottom - MainScrnBounds.top; 4246#if EnableMagnify 4247 if (UseMagnify) { 4248 ViewHSize /= MyWindowScale; 4249 ViewVSize /= MyWindowScale; 4250 } 4251#endif 4252 if (ViewHSize >= vMacScreenWidth) { 4253 ViewHStart = 0; 4254 ViewHSize = vMacScreenWidth; 4255 } else { 4256 ViewHSize &= ~ 1; 4257 } 4258 if (ViewVSize >= vMacScreenHeight) { 4259 ViewVStart = 0; 4260 ViewVSize = vMacScreenHeight; 4261 } else { 4262 ViewVSize &= ~ 1; 4263 } 4264 } 4265#endif 4266 4267 /* Create window rectangle and centre it on the screen */ 4268 SetRect(&MainScrnBounds, 0, 0, NewWindowWidth, NewWindowHeight); 4269 OffsetRect(&MainScrnBounds, leftPos, topPos); 4270 4271#if VarFullScreen 4272 if (UseFullScreen) 4273#endif 4274#if MayFullScreen 4275 { 4276 NewWinRect = AllScrnBounds; 4277 } 4278#endif 4279#if VarFullScreen 4280 else 4281#endif 4282#if MayNotFullScreen 4283 { 4284#if EnableMagnify 4285 if (UseMagnify) { 4286 WinIndx = kMagStateMagnifgy; 4287 } else 4288#endif 4289 { 4290 WinIndx = kMagStateNormal; 4291 } 4292 4293 if (! HavePositionWins[WinIndx]) { 4294 WinPositionWins[WinIndx].h = leftPos; 4295 WinPositionWins[WinIndx].v = topPos; 4296 HavePositionWins[WinIndx] = trueblnr; 4297 NewWinRect = MainScrnBounds; 4298 } else { 4299 SetRect(&NewWinRect, 0, 0, NewWindowWidth, NewWindowHeight); 4300 OffsetRect(&NewWinRect, 4301 WinPositionWins[WinIndx].h, WinPositionWins[WinIndx].v); 4302 } 4303 } 4304#endif 4305 4306#if MayNotFullScreen 4307 CurWinIndx = WinIndx; 4308#endif 4309 4310#if VarFullScreen 4311 if (UseFullScreen) 4312#endif 4313#if MayFullScreen 4314 { 4315 hOffset = MainScrnBounds.left - AllScrnBounds.left; 4316 vOffset = MainScrnBounds.top - AllScrnBounds.top; 4317 } 4318#endif 4319 4320 if (MyCreateNewWindow(&NewWinRect, &gMyMainWindow)) { 4321 static const GLint window_attrib[] = {AGL_RGBA, 4322#if UseAGLdoublebuff 4323 AGL_DOUBLEBUFFER, 4324#endif 4325 /* AGL_DEPTH_SIZE, 16, */ 4326 AGL_NONE}; 4327 4328#if 0 != vMacScreenDepth 4329 ColorModeWorks = trueblnr; 4330#endif 4331 4332 window_fmt = aglChoosePixelFormat(NULL, 0, window_attrib); 4333 if (NULL == window_fmt) { 4334 /* err = aglReportError() */ 4335 } else { 4336 window_ctx = aglCreateContext(window_fmt, NULL); 4337 if (NULL == window_ctx) { 4338 /* err = aglReportError() */ 4339 } else { 4340 4341 ShowWindow(gMyMainWindow); 4342 4343 if (GL_TRUE != ( 4344 /* 4345 aglSetDrawable is deprecated, but use it anyway 4346 if at all possible, because aglSetWindowRef 4347 doesn't seeem to work properly on a 4348 kPlainWindowClass window. 4349 Should move to Cocoa. 4350 */ 4351 HaveMyaglSetDrawable() 4352 ? MyaglSetDrawable(window_ctx, 4353 GetWindowPort(gMyMainWindow)) 4354 : 4355 HaveMyaglSetWindowRef() 4356 ? MyaglSetWindowRef(window_ctx, gMyMainWindow) 4357 : 4358 GL_FALSE)) 4359 { 4360 /* err = aglReportError() */ 4361 } else { 4362 ctx = window_ctx; 4363 4364#if VarFullScreen 4365 if (UseFullScreen) 4366#endif 4367#if MayFullScreen 4368 { 4369 int h = NewWinRect.right - NewWinRect.left; 4370 int v = NewWinRect.bottom - NewWinRect.top; 4371 4372 GLhOffset = hOffset; 4373 GLvOffset = v - vOffset; 4374 MyAdjustGLforSize(h, v); 4375 } 4376#endif 4377#if VarFullScreen 4378 else 4379#endif 4380#if MayNotFullScreen 4381 { 4382 GLhOffset = 0; 4383 GLvOffset = NewWindowHeight; 4384 MyAdjustGLforSize(NewWindowWidth, 4385 NewWindowHeight); 4386 } 4387#endif 4388 4389#if UseAGLdoublebuff && 1 4390 { 4391 GLint agSwapInterval = 1; 4392 if (GL_TRUE != aglSetInteger( 4393 window_ctx, AGL_SWAP_INTERVAL, 4394 &agSwapInterval)) 4395 { 4396 MacMsg("oops", "aglSetInteger failed", 4397 falseblnr); 4398 } else { 4399 /* 4400 MacMsg("good", "aglSetInteger ok", 4401 falseblnr); 4402 */ 4403 } 4404 } 4405#endif 4406 4407#if VarFullScreen 4408 if (! UseFullScreen) 4409#endif 4410#if MayNotFullScreen 4411 { 4412 /* check if window rect valid */ 4413 Rect tr; 4414 4415 if (MyGetWindowTitleBounds(gMyMainWindow, &tr)) 4416 { 4417 if (! RectInRgn(&tr, GetGrayRgn())) { 4418 MySetMacWindContRect(gMyMainWindow, 4419 &MainScrnBounds); 4420 if (MyGetWindowTitleBounds( 4421 gMyMainWindow, &tr)) 4422 { 4423 if (! RectInRgn(&tr, GetGrayRgn())) 4424 { 4425 OffsetRect(&MainScrnBounds, 0, 4426 AllScrnBounds.top - tr.top); 4427 MySetMacWindContRect( 4428 gMyMainWindow, 4429 &MainScrnBounds); 4430 } 4431 } 4432 } 4433 } 4434 } 4435#endif 4436 4437 (void) PrepareForDragging(); 4438 4439 IsOk = trueblnr; 4440 } 4441 } 4442 } 4443 } 4444 4445 return IsOk; 4446} 4447 4448#if EnableRecreateW 4449LOCALPROC ZapMyWState(void) 4450{ 4451 gMyMainWindow = NULL; 4452 window_fmt = NULL; 4453 window_ctx = NULL; 4454 gGlobalReceiveHandler = NULL; 4455 gGlobalTrackingHandler = NULL; 4456} 4457#endif 4458 4459#if EnableRecreateW 4460struct MyWState { 4461 WindowPtr f_MainWindow; 4462 AGLPixelFormat f_fmt; 4463 AGLContext f_ctx; 4464#if MayFullScreen 4465 short f_hOffset; 4466 short f_vOffset; 4467 ui4r f_ViewHSize; 4468 ui4r f_ViewVSize; 4469 ui4r f_ViewHStart; 4470 ui4r f_ViewVStart; 4471#endif 4472#if VarFullScreen 4473 blnr f_UseFullScreen; 4474#endif 4475#if EnableMagnify 4476 blnr f_UseMagnify; 4477#endif 4478#if MayNotFullScreen 4479 int f_CurWinIndx; 4480#endif 4481 short f_GLhOffset; 4482 short f_GLvOffset; 4483 DragTrackingHandlerUPP f_gGlobalTrackingHandler; 4484 DragReceiveHandlerUPP f_gGlobalReceiveHandler; 4485}; 4486typedef struct MyWState MyWState; 4487#endif 4488 4489#if EnableRecreateW 4490LOCALPROC GetMyWState(MyWState *r) 4491{ 4492 r->f_MainWindow = gMyMainWindow; 4493 r->f_fmt = window_fmt; 4494 r->f_ctx = window_ctx; 4495#if MayFullScreen 4496 r->f_hOffset = hOffset; 4497 r->f_vOffset = vOffset; 4498 r->f_ViewHSize = ViewHSize; 4499 r->f_ViewVSize = ViewVSize; 4500 r->f_ViewHStart = ViewHStart; 4501 r->f_ViewVStart = ViewVStart; 4502#endif 4503#if VarFullScreen 4504 r->f_UseFullScreen = UseFullScreen; 4505#endif 4506#if EnableMagnify 4507 r->f_UseMagnify = UseMagnify; 4508#endif 4509#if MayNotFullScreen 4510 r->f_CurWinIndx = CurWinIndx; 4511#endif 4512 r->f_GLhOffset = GLhOffset; 4513 r->f_GLvOffset = GLvOffset; 4514 r->f_gGlobalTrackingHandler = gGlobalTrackingHandler; 4515 r->f_gGlobalReceiveHandler = gGlobalReceiveHandler; 4516} 4517#endif 4518 4519#if EnableRecreateW 4520LOCALPROC SetMyWState(MyWState *r) 4521{ 4522 gMyMainWindow = r->f_MainWindow; 4523 window_fmt = r->f_fmt; 4524 window_ctx = r->f_ctx; 4525#if MayFullScreen 4526 hOffset = r->f_hOffset; 4527 vOffset = r->f_vOffset; 4528 ViewHSize = r->f_ViewHSize; 4529 ViewVSize = r->f_ViewVSize; 4530 ViewHStart = r->f_ViewHStart; 4531 ViewVStart = r->f_ViewVStart; 4532#endif 4533#if VarFullScreen 4534 UseFullScreen = r->f_UseFullScreen; 4535#endif 4536#if EnableMagnify 4537 UseMagnify = r->f_UseMagnify; 4538#endif 4539#if MayNotFullScreen 4540 CurWinIndx = r->f_CurWinIndx; 4541#endif 4542 GLhOffset = r->f_GLhOffset; 4543 GLvOffset = r->f_GLvOffset; 4544 gGlobalTrackingHandler = r->f_gGlobalTrackingHandler; 4545 gGlobalReceiveHandler = r->f_gGlobalReceiveHandler; 4546 4547 ctx = window_ctx; 4548} 4549#endif 4550 4551#if EnableRecreateW 4552LOCALFUNC blnr ReCreateMainWindow(void) 4553{ 4554 MyWState old_state; 4555 MyWState new_state; 4556 4557#if VarFullScreen 4558 if (! UseFullScreen) 4559#endif 4560#if MayNotFullScreen 4561 { 4562 /* save old position */ 4563 if (gMyMainWindow != NULL) { 4564 Rect r; 4565 4566 if (MyGetWindowContBounds(gMyMainWindow, &r)) { 4567 WinPositionWins[CurWinIndx].h = r.left; 4568 WinPositionWins[CurWinIndx].v = r.top; 4569 } 4570 } 4571 } 4572#endif 4573 4574#if MayFullScreen 4575 UngrabMachine(); 4576#endif 4577 4578 CloseAglCurrentContext(); 4579 4580 gMyOldWindow = gMyMainWindow; 4581 4582 GetMyWState(&old_state); 4583 4584 ZapMyWState(); 4585 4586#if VarFullScreen 4587 UseFullScreen = WantFullScreen; 4588#endif 4589#if EnableMagnify 4590 UseMagnify = WantMagnify; 4591#endif 4592 4593 if (! CreateMainWindow()) { 4594 gMyOldWindow = NULL; 4595 CloseMainWindow(); 4596 SetMyWState(&old_state); 4597 4598#if VarFullScreen 4599 if (UseFullScreen) { 4600 My_HideMenuBar(); 4601 } else { 4602 My_ShowMenuBar(); 4603 } 4604#endif 4605 4606 /* avoid retry */ 4607#if VarFullScreen 4608 WantFullScreen = UseFullScreen; 4609#endif 4610#if EnableMagnify 4611 WantMagnify = UseMagnify; 4612#endif 4613 4614 return falseblnr; 4615 } else { 4616 GetMyWState(&new_state); 4617 SetMyWState(&old_state); 4618 CloseMainWindow(); 4619 gMyOldWindow = NULL; 4620 SetMyWState(&new_state); 4621 4622 if (HaveCursorHidden) { 4623 (void) MyMoveMouse(CurMouseH, CurMouseV); 4624 WantCursorHidden = trueblnr; 4625 } else { 4626 MouseIsOutside = falseblnr; /* don't know */ 4627 } 4628 4629 return trueblnr; 4630 } 4631} 4632#endif 4633 4634#if VarFullScreen && EnableMagnify 4635enum { 4636 kWinStateWindowed, 4637#if EnableMagnify 4638 kWinStateFullScreen, 4639#endif 4640 kNumWinStates 4641}; 4642#endif 4643 4644#if VarFullScreen && EnableMagnify 4645LOCALVAR int WinMagStates[kNumWinStates]; 4646#endif 4647 4648LOCALPROC ZapWinStateVars(void) 4649{ 4650#if MayNotFullScreen 4651 { 4652 int i; 4653 4654 for (i = 0; i < kNumMagStates; ++i) { 4655 HavePositionWins[i] = falseblnr; 4656 } 4657 } 4658#endif 4659#if VarFullScreen && EnableMagnify 4660 { 4661 int i; 4662 4663 for (i = 0; i < kNumWinStates; ++i) { 4664 WinMagStates[i] = kMagStateAuto; 4665 } 4666 } 4667#endif 4668} 4669 4670#if VarFullScreen 4671LOCALPROC ToggleWantFullScreen(void) 4672{ 4673 WantFullScreen = ! WantFullScreen; 4674 4675#if EnableMagnify 4676 { 4677 int OldWinState = 4678 UseFullScreen ? kWinStateFullScreen : kWinStateWindowed; 4679 int OldMagState = 4680 UseMagnify ? kMagStateMagnifgy : kMagStateNormal; 4681 int NewWinState = 4682 WantFullScreen ? kWinStateFullScreen : kWinStateWindowed; 4683 int NewMagState = WinMagStates[NewWinState]; 4684 4685 WinMagStates[OldWinState] = OldMagState; 4686 if (kMagStateAuto != NewMagState) { 4687 WantMagnify = (kMagStateMagnifgy == NewMagState); 4688 } else { 4689 WantMagnify = falseblnr; 4690 if (WantFullScreen 4691 && HaveMyCGDisplayPixelsWide() 4692 && HaveMyCGDisplayPixelsHigh()) 4693 { 4694 CGDirectDisplayID CurMainDisplayID = MyMainDisplayID(); 4695 4696 if ((MyCGDisplayPixelsWide(CurMainDisplayID) 4697 >= vMacScreenWidth * MyWindowScale) 4698 && (MyCGDisplayPixelsHigh(CurMainDisplayID) 4699 >= vMacScreenHeight * MyWindowScale) 4700 ) 4701 { 4702 WantMagnify = trueblnr; 4703 } 4704 } 4705 } 4706 } 4707#endif 4708} 4709#endif 4710 4711LOCALPROC LeaveSpeedStopped(void) 4712{ 4713#if MySoundEnabled 4714 MySound_Start(); 4715#endif 4716 4717 StartUpTimeAdjust(); 4718} 4719 4720LOCALPROC EnterSpeedStopped(void) 4721{ 4722#if MySoundEnabled 4723 MySound_Stop(); 4724#endif 4725} 4726 4727LOCALPROC DoNotInBackgroundTasks(void) 4728{ 4729#if 0 4730 if (HaveMyCGCursorIsVisible()) { 4731 HaveCursorHidden = ! MyCGCursorIsVisible(); 4732 4733 /* 4734 This shouldn't be needed, but have seen 4735 cursor state get messed up in 10.4. 4736 If the os x hide count gets off, this 4737 should fix it within a few ticks. 4738 4739 oops, no, doesn't seem to be accurate, 4740 and makes things worse. particularly if 4741 cursor in obscured state after typing 4742 into dialog. 4743 */ 4744 /* trying a different approach further below */ 4745 } 4746#endif 4747 4748 if (HaveCursorHidden != ( 4749#if MayNotFullScreen 4750 (WantCursorHidden 4751#if VarFullScreen 4752 || UseFullScreen 4753#endif 4754 ) && 4755#endif 4756 gWeAreActive && ! CurSpeedStopped)) 4757 { 4758 HaveCursorHidden = ! HaveCursorHidden; 4759 if (HaveCursorHidden) { 4760 MyHideCursor(); 4761 } else { 4762 /* 4763 kludge for OS X, where mouse over Dock devider 4764 changes cursor, and never sets it back. 4765 */ 4766 SetCursorArrow(); 4767 4768 MyShowCursor(); 4769 } 4770 } 4771 4772 /* check if actual cursor visibility is what it should be */ 4773 if (HaveMyCGCursorIsVisible()) { 4774 /* but only in OS X 10.3 and later */ 4775 if (MyCGCursorIsVisible()) { 4776 if (HaveCursorHidden) { 4777 MyHideCursor(); 4778 if (MyCGCursorIsVisible()) { 4779 /* 4780 didn't work, attempt undo so that 4781 hide cursor count won't get large 4782 */ 4783 MyShowCursor(); 4784 } 4785 } 4786 } else { 4787 if (! HaveCursorHidden) { 4788 MyShowCursor(); 4789 /* 4790 don't check if worked, assume can't decrement 4791 hide cursor count below 0 4792 */ 4793 } 4794 } 4795 } 4796} 4797 4798LOCALPROC CheckForSavedTasks(void) 4799{ 4800 if (MyEvtQNeedRecover) { 4801 MyEvtQNeedRecover = falseblnr; 4802 4803 /* attempt cleanup, MyEvtQNeedRecover may get set again */ 4804 MyEvtQTryRecoverFromFull(); 4805 } 4806 4807#if EnableFSMouseMotion 4808 if (HaveMouseMotion) { 4809 MyMouseConstrain(); 4810 } 4811#endif 4812 4813 if (RequestMacOff) { 4814 RequestMacOff = falseblnr; 4815 if (AnyDiskInserted()) { 4816 MacMsgOverride(kStrQuitWarningTitle, 4817 kStrQuitWarningMessage); 4818 } else { 4819 ForceMacOff = trueblnr; 4820 } 4821 } 4822 4823 if (! gWeAreActive) { 4824 if (! (gTrueBackgroundFlag || gLackFocusFlag)) { 4825 gWeAreActive = trueblnr; 4826 ReconnectKeyCodes3(); 4827 SetCursorArrow(); 4828 } 4829 } 4830 4831#if VarFullScreen 4832 if (gTrueBackgroundFlag && WantFullScreen) { 4833 ToggleWantFullScreen(); 4834 } 4835#endif 4836 4837 if (CurSpeedStopped != (SpeedStopped || 4838 (gTrueBackgroundFlag && ! RunInBackground 4839#if EnableAutoSlow && 0 4840 && (QuietSubTicks >= 4092) 4841#endif 4842 ))) 4843 { 4844 CurSpeedStopped = ! CurSpeedStopped; 4845 if (CurSpeedStopped) { 4846 EnterSpeedStopped(); 4847 } else { 4848 LeaveSpeedStopped(); 4849 } 4850 } 4851 4852#if EnableRecreateW 4853 if (gWeAreActive) { 4854 if (0 4855#if EnableMagnify 4856 || (UseMagnify != WantMagnify) 4857#endif 4858#if VarFullScreen 4859 || (UseFullScreen != WantFullScreen) 4860#endif 4861 ) 4862 { 4863 (void) ReCreateMainWindow(); 4864 } 4865 } 4866#endif 4867 4868#if MayFullScreen 4869 if (GrabMachine != ( 4870#if VarFullScreen 4871 UseFullScreen && 4872#endif 4873 gWeAreActive && ! CurSpeedStopped)) 4874 { 4875 GrabMachine = ! GrabMachine; 4876 AdjustMachineGrab(); 4877 } 4878#endif 4879 4880 if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) { 4881 MacMsgDisplayOn(); 4882 } 4883 4884 if (WantScreensChangedCheck) { 4885 WantScreensChangedCheck = falseblnr; 4886 MyUpdateOpenGLContext(); 4887 } 4888 4889 if (NeedWholeScreenDraw) { 4890 NeedWholeScreenDraw = falseblnr; 4891 ScreenChangedAll(); 4892 } 4893 4894 if (! gWeAreActive) { 4895 /* 4896 dialog during drag and drop hangs if in background 4897 and don't want recursive dialogs 4898 so wait til later to display dialog 4899 */ 4900 } else { 4901#if IncludeSonyNew 4902 if (vSonyNewDiskWanted) { 4903#if IncludeSonyNameNew 4904 if (vSonyNewDiskName != NotAPbuf) { 4905 CFStringRef NewDiskName = 4906 CFStringCreateWithPbuf(vSonyNewDiskName); 4907 MakeNewDisk(vSonyNewDiskSize, NewDiskName); 4908 if (NewDiskName != NULL) { 4909 CFRelease(NewDiskName); 4910 } 4911 PbufDispose(vSonyNewDiskName); 4912 vSonyNewDiskName = NotAPbuf; 4913 } else 4914#endif 4915 { 4916 MakeNewDisk(vSonyNewDiskSize, NULL); 4917 } 4918 vSonyNewDiskWanted = falseblnr; 4919 /* must be done after may have gotten disk */ 4920 } 4921#endif 4922 if (RequestInsertDisk) { 4923 RequestInsertDisk = falseblnr; 4924 InsertADisk0(); 4925 } 4926 } 4927 4928#if NeedRequestIthDisk 4929 if (0 != RequestIthDisk) { 4930 Sony_InsertIth(RequestIthDisk); 4931 RequestIthDisk = 0; 4932 } 4933#endif 4934 4935 if (gWeAreActive) { 4936 DoNotInBackgroundTasks(); 4937 } 4938} 4939 4940#define CheckItem CheckMenuItem 4941 4942/* Menu Constants */ 4943 4944#define kAppleMenu 128 4945#define kFileMenu 129 4946#define kSpecialMenu 130 4947 4948enum { 4949 kCmdIdNull, 4950 kCmdIdMoreCommands, 4951 4952 kNumCmdIds 4953}; 4954 4955LOCALFUNC OSStatus MyProcessCommand(MenuCommand inCommandID) 4956{ 4957 OSStatus result = noErr; 4958 4959 switch (inCommandID) { 4960 case kHICommandAbout: 4961 DoAboutMsg(); 4962 break; 4963 case kHICommandQuit: 4964 RequestMacOff = trueblnr; 4965 break; 4966 case kHICommandOpen: 4967 RequestInsertDisk = trueblnr; 4968 break; 4969 case kCmdIdMoreCommands: 4970 DoMoreCommandsMsg(); 4971 break; 4972 default: 4973 result = eventNotHandledErr; 4974 break; 4975 } 4976 4977 return result; 4978} 4979 4980LOCALFUNC OSStatus Keyboard_UpdateKeyMap3(EventRef theEvent, blnr down) 4981{ 4982 UInt32 uiKeyCode; 4983 4984 HandleEventModifiers(theEvent); 4985 GetEventParameter(theEvent, kEventParamKeyCode, typeUInt32, NULL, 4986 sizeof(uiKeyCode), NULL, &uiKeyCode); 4987 Keyboard_UpdateKeyMap2(Keyboard_RemapMac(uiKeyCode & 0x000000FF), 4988 down); 4989 return noErr; 4990} 4991 4992static pascal OSStatus MyEventHandler(EventHandlerCallRef nextHandler, 4993 EventRef theEvent, void * userData) 4994{ 4995 OSStatus result = eventNotHandledErr; 4996 UInt32 eventClass = GetEventClass(theEvent); 4997 UInt32 eventKind = GetEventKind(theEvent); 4998 4999 UnusedParam(userData); 5000 5001 switch (eventClass) { 5002 case kEventClassMouse: 5003 switch (eventKind) { 5004 case kEventMouseDown: 5005#if MayFullScreen 5006 if (GrabMachine) { 5007 HandleEventLocation(theEvent); 5008 HandleEventModifiers(theEvent); 5009 MyMouseButtonSet(trueblnr); 5010 result = noErr; 5011 } else 5012#endif 5013 { 5014 result = CallNextEventHandler( 5015 nextHandler, theEvent); 5016 } 5017 break; 5018 case kEventMouseUp: 5019 HandleEventLocation(theEvent); 5020 HandleEventModifiers(theEvent); 5021 MyMouseButtonSet(falseblnr); 5022#if MayFullScreen 5023 if (GrabMachine) { 5024 result = noErr; 5025 } else 5026#endif 5027 { 5028 result = CallNextEventHandler( 5029 nextHandler, theEvent); 5030 } 5031 break; 5032 case kEventMouseMoved: 5033 case kEventMouseDragged: 5034 IsOurMouseMove = falseblnr; 5035 result = CallNextEventHandler( 5036 nextHandler, theEvent); 5037 /* 5038 Actually, mousing over window does't seem 5039 to go through here, it goes directly to 5040 the window routine. But since not documented 5041 either way, leave the check in case this 5042 changes. 5043 */ 5044 if (! IsOurMouseMove) { 5045 MouseIsOutside = trueblnr; 5046#if 0 /* don't bother, CheckMouseState will take care of it, better */ 5047 HandleEventLocation(theEvent); 5048 HandleEventModifiers(theEvent); 5049#endif 5050 } 5051 break; 5052 } 5053 break; 5054 case kEventClassApplication: 5055 switch (eventKind) { 5056 case kEventAppActivated: 5057 gTrueBackgroundFlag = falseblnr; 5058 result = noErr; 5059 break; 5060 case kEventAppDeactivated: 5061 gTrueBackgroundFlag = trueblnr; 5062 result = noErr; 5063 ClearWeAreActive(); 5064 break; 5065 } 5066 break; 5067 case kEventClassCommand: 5068 switch (eventKind) { 5069 case kEventProcessCommand: 5070 { 5071 HICommand hiCommand; 5072 5073 GetEventParameter(theEvent, 5074 kEventParamDirectObject, typeHICommand, 5075 NULL, sizeof(HICommand), NULL, &hiCommand); 5076 result = MyProcessCommand(hiCommand.commandID); 5077 } 5078 break; 5079 } 5080 break; 5081 case kEventClassKeyboard: 5082 if (! gWeAreActive) { 5083 return CallNextEventHandler(nextHandler, theEvent); 5084 } else { 5085 switch (eventKind) { 5086 case kEventRawKeyDown: 5087 result = Keyboard_UpdateKeyMap3( 5088 theEvent, trueblnr); 5089 break; 5090 case kEventRawKeyUp: 5091 result = Keyboard_UpdateKeyMap3( 5092 theEvent, falseblnr); 5093 break; 5094 case kEventRawKeyModifiersChanged: 5095 HandleEventModifiers(theEvent); 5096 result = noErr; 5097 break; 5098 default: 5099 break; 5100 } 5101 } 5102 break; 5103 default: 5104 break; 5105 } 5106 return result; 5107} 5108 5109LOCALPROC AppendMenuConvertCStr( 5110 MenuRef menu, 5111 MenuCommand inCommandID, 5112 char *s) 5113{ 5114 CFStringRef cfStr = CFStringCreateFromSubstCStr(s); 5115 if (NULL != cfStr) { 5116 AppendMenuItemTextWithCFString(menu, cfStr, 5117 0, inCommandID, NULL); 5118 CFRelease(cfStr); 5119 } 5120} 5121 5122LOCALPROC AppendMenuSep(MenuRef menu) 5123{ 5124 AppendMenuItemTextWithCFString(menu, NULL, 5125 kMenuItemAttrSeparator, 0, NULL); 5126} 5127 5128LOCALFUNC MenuRef NewMenuFromConvertCStr(short menuID, char *s) 5129{ 5130 MenuRef menu = NULL; 5131 5132 CFStringRef cfStr = CFStringCreateFromSubstCStr(s); 5133 if (NULL != cfStr) { 5134 OSStatus err = CreateNewMenu(menuID, 0, &menu); 5135 if (err != noErr) { 5136 menu = NULL; 5137 } else { 5138 (void) SetMenuTitleWithCFString(menu, cfStr); 5139 } 5140 CFRelease(cfStr); 5141 } 5142 5143 return menu; 5144} 5145 5146LOCALPROC RemoveCommandKeysInMenu(MenuRef theMenu) 5147{ 5148 MenuRef outHierMenu; 5149 int i; 5150 UInt16 n = CountMenuItems(theMenu); 5151 5152 for (i = 1; i <= n; ++i) { 5153 SetItemCmd(theMenu, i, 0); 5154 if (noErr == GetMenuItemHierarchicalMenu( 5155 theMenu, i, &outHierMenu) 5156 && (NULL != outHierMenu)) 5157 { 5158 RemoveCommandKeysInMenu(outHierMenu); 5159 } 5160 } 5161} 5162 5163LOCALFUNC blnr InstallOurMenus(void) 5164{ 5165 MenuRef menu; 5166 Str255 s; 5167 5168 PStrFromChar(s, (char)20); 5169 menu = NewMenu(kAppleMenu, s); 5170 if (menu != NULL) { 5171 AppendMenuConvertCStr(menu, 5172 kHICommandAbout, 5173 kStrMenuItemAbout); 5174 AppendMenuSep(menu); 5175 InsertMenu(menu, 0); 5176 } 5177 5178 menu = NewMenuFromConvertCStr(kFileMenu, kStrMenuFile); 5179 if (menu != NULL) { 5180 AppendMenuConvertCStr(menu, 5181 kHICommandOpen, 5182 kStrMenuItemOpen ";ll"); 5183 InsertMenu(menu, 0); 5184 } 5185 5186 menu = NewMenuFromConvertCStr(kSpecialMenu, kStrMenuSpecial); 5187 if (menu != NULL) { 5188 AppendMenuConvertCStr(menu, 5189 kCmdIdMoreCommands, 5190 kStrMenuItemMore ";ll"); 5191 InsertMenu(menu, 0); 5192 } 5193 5194 { 5195 MenuRef outMenu; 5196 MenuItemIndex outIndex; 5197 5198 if (noErr == GetIndMenuItemWithCommandID( 5199 NULL, kHICommandQuit, 1, &outMenu, &outIndex)) 5200 { 5201 RemoveCommandKeysInMenu(outMenu); 5202 } 5203 } 5204 5205 DrawMenuBar(); 5206 5207 return trueblnr; 5208} 5209 5210LOCALFUNC blnr InstallOurAppearanceClient(void) 5211{ 5212 RegisterAppearanceClient(); /* maybe not needed ? */ 5213 return trueblnr; 5214} 5215 5216LOCALVAR blnr DisplayRegistrationCallBackSuccessful = falseblnr; 5217 5218static void DisplayRegisterReconfigurationCallback( 5219 CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, 5220 void *userInfo) 5221{ 5222 UnusedParam(display); 5223 UnusedParam(userInfo); 5224 5225 if (0 != (flags & kCGDisplayBeginConfigurationFlag)) { 5226 /* fprintf(stderr, "kCGDisplayBeginConfigurationFlag\n"); */ 5227 } else { 5228#if 0 5229 if (0 != (flags & kCGDisplayMovedFlag)) { 5230 fprintf(stderr, "kCGDisplayMovedFlag\n"); 5231 } 5232 if (0 != (flags & kCGDisplaySetMainFlag)) { 5233 fprintf(stderr, "kCGDisplaySetMainFlag\n"); 5234 } 5235 if (0 != (flags & kCGDisplaySetModeFlag)) { 5236 fprintf(stderr, "kCGDisplaySetModeFlag\n"); 5237 } 5238 5239 if (0 != (flags & kCGDisplayAddFlag)) { 5240 fprintf(stderr, "kCGDisplayAddFlag\n"); 5241 } 5242 if (0 != (flags & kCGDisplayRemoveFlag)) { 5243 fprintf(stderr, "kCGDisplayRemoveFlag\n"); 5244 } 5245 5246 if (0 != (flags & kCGDisplayEnabledFlag)) { 5247 fprintf(stderr, "kCGDisplayEnabledFlag\n"); 5248 } 5249 if (0 != (flags & kCGDisplayDisabledFlag)) { 5250 fprintf(stderr, "kCGDisplayDisabledFlag\n"); 5251 } 5252 5253 if (0 != (flags & kCGDisplayMirrorFlag)) { 5254 fprintf(stderr, "kCGDisplayMirrorFlag\n"); 5255 } 5256 if (0 != (flags & kCGDisplayUnMirrorFlag)) { 5257 fprintf(stderr, "kCGDisplayMirrorFlag\n"); 5258 } 5259#endif 5260 5261 WantScreensChangedCheck = trueblnr; 5262 5263#if VarFullScreen 5264 if (WantFullScreen) { 5265 ToggleWantFullScreen(); 5266 } 5267#endif 5268 } 5269} 5270 5271LOCALFUNC blnr InstallOurEventHandlers(void) 5272{ 5273 EventTypeSpec eventTypes[] = { 5274 {kEventClassMouse, kEventMouseDown}, 5275 {kEventClassMouse, kEventMouseUp}, 5276 {kEventClassMouse, kEventMouseMoved}, 5277 {kEventClassMouse, kEventMouseDragged}, 5278 {kEventClassKeyboard, kEventRawKeyModifiersChanged}, 5279 {kEventClassKeyboard, kEventRawKeyDown}, 5280 {kEventClassKeyboard, kEventRawKeyUp}, 5281 {kEventClassApplication, kEventAppActivated}, 5282 {kEventClassApplication, kEventAppDeactivated}, 5283 {kEventClassCommand, kEventProcessCommand} 5284 }; 5285 5286 InstallApplicationEventHandler( 5287 NewEventHandlerUPP(MyEventHandler), 5288 GetEventTypeCount(eventTypes), 5289 eventTypes, NULL, NULL); 5290 5291 InitKeyCodes(); 5292 5293 InstallAppleEventHandlers(); 5294 5295 if (HaveMyCGDisplayRegisterReconfigurationCallback()) { 5296 if (kCGErrorSuccess == 5297 MyCGDisplayRegisterReconfigurationCallback( 5298 DisplayRegisterReconfigurationCallback, NULL)) 5299 { 5300 DisplayRegistrationCallBackSuccessful = trueblnr; 5301 } 5302 } 5303 5304 /* (void) SetMouseCoalescingEnabled(false, NULL); */ 5305 5306 return trueblnr; 5307} 5308 5309LOCALPROC UnInstallOurEventHandlers(void) 5310{ 5311 if (DisplayRegistrationCallBackSuccessful) { 5312 if (HaveMyCGDisplayRemoveReconfigurationCallback()) { 5313 MyCGDisplayRemoveReconfigurationCallback( 5314 DisplayRegisterReconfigurationCallback, NULL); 5315 } 5316 } 5317} 5318 5319GLOBALOSGLUPROC WaitForNextTick(void) 5320{ 5321 OSStatus err; 5322 EventRef theEvent; 5323 ui3r NumChecks; 5324 EventTimeout inTimeout; 5325 EventTargetRef theTarget = GetEventDispatcherTarget(); 5326 5327 inTimeout = kEventDurationNoWait; 5328 5329label_retry: 5330 NumChecks = 0; 5331 while ((NumChecks < 32) && (noErr == (err = 5332 ReceiveNextEvent(0, NULL, inTimeout, 5333 true, &theEvent)))) 5334 { 5335 (void) SendEventToEventTarget(theEvent, theTarget); 5336 ReleaseEvent(theEvent); 5337 inTimeout = kEventDurationNoWait; 5338 ++NumChecks; 5339 } 5340 5341 CheckForSavedTasks(); 5342 5343 if (ForceMacOff) { 5344 return; 5345 } 5346 5347 if (CurSpeedStopped) { 5348 DoneWithDrawingForTick(); 5349 inTimeout = kEventDurationForever; 5350 goto label_retry; 5351 } 5352 5353 if (ExtraTimeNotOver()) { 5354 inTimeout = 5355 NextTickChangeTime - GetCurrentEventTime(); 5356 if (inTimeout > 0.0) { 5357#if 1 5358 struct timespec rqt; 5359 struct timespec rmt; 5360 5361 rqt.tv_sec = 0; 5362 rqt.tv_nsec = inTimeout / kEventDurationNanosecond; 5363 (void) nanosleep(&rqt, &rmt); 5364 inTimeout = kEventDurationNoWait; 5365 goto label_retry; 5366#elif 1 5367 usleep(inTimeout / kEventDurationMicrosecond); 5368 inTimeout = kEventDurationNoWait; 5369 goto label_retry; 5370#else 5371 /* 5372 This has higher overhead. 5373 */ 5374 goto label_retry; 5375#endif 5376 } 5377 } 5378 5379 if (CheckDateTime()) { 5380#if MySoundEnabled 5381 MySound_SecondNotify(); 5382#endif 5383#if EnableDemoMsg 5384 DemoModeSecondNotify(); 5385#endif 5386 } 5387 5388 if (gWeAreActive) { 5389 CheckMouseState(); 5390 } 5391 5392 OnTrueTime = TrueEmulatedTime; 5393 5394#if dbglog_TimeStuff 5395 dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime); 5396#endif 5397} 5398 5399/* --- platform independent code can be thought of as going here --- */ 5400 5401#include "PROGMAIN.h" 5402 5403LOCALPROC ReserveAllocAll(void) 5404{ 5405#if dbglog_HAVE 5406 dbglog_ReserveAlloc(); 5407#endif 5408 ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr); 5409 ReserveAllocOneBlock(&screencomparebuff, 5410 vMacScreenNumBytes, 5, trueblnr); 5411 ReserveAllocOneBlock(&CntrlDisplayBuff, 5412 vMacScreenNumBytes, 5, falseblnr); 5413 ReserveAllocOneBlock(&ScalingBuff, vMacScreenNumPixels 5414#if 0 != vMacScreenDepth 5415 * 4 5416#endif 5417 , 5, falseblnr); 5418 ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr); 5419#if MySoundEnabled 5420 ReserveAllocOneBlock((ui3p *)&TheSoundBuffer, 5421 dbhBufferSize, 5, falseblnr); 5422#endif 5423 5424 EmulationReserveAlloc(); 5425} 5426 5427LOCALFUNC blnr AllocMyMemory(void) 5428{ 5429 uimr n; 5430 blnr IsOk = falseblnr; 5431 5432 ReserveAllocOffset = 0; 5433 ReserveAllocBigBlock = nullpr; 5434 ReserveAllocAll(); 5435 n = ReserveAllocOffset; 5436 ReserveAllocBigBlock = (ui3p)calloc(1, n); 5437 if (NULL == ReserveAllocBigBlock) { 5438 MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr); 5439 } else { 5440 ReserveAllocOffset = 0; 5441 ReserveAllocAll(); 5442 if (n != ReserveAllocOffset) { 5443 /* oops, program error */ 5444 } else { 5445 IsOk = trueblnr; 5446 } 5447 } 5448 5449 return IsOk; 5450} 5451 5452LOCALFUNC blnr InitOSGLU(void) 5453{ 5454 if (AllocMyMemory()) 5455 if (InitMyApplInfo()) 5456#if dbglog_HAVE 5457 if (dbglog_open()) 5458#endif 5459#if MySoundEnabled 5460 if (MySound_Init()) 5461#endif 5462 if (InstallOurAppearanceClient()) 5463 if (InstallOurEventHandlers()) 5464 if (InstallOurMenus()) 5465 if (CreateMainWindow()) 5466 if (LoadMacRom()) 5467 if (LoadInitialImages()) 5468#if UseActvCode 5469 if (ActvCodeInit()) 5470#endif 5471 if (InitLocationDat()) 5472#if EmLocalTalk 5473 if (EntropyGather()) 5474 if (InitLocalTalk()) 5475#endif 5476 if (WaitForRom()) 5477 { 5478 return trueblnr; 5479 } 5480 return falseblnr; 5481} 5482 5483#if dbglog_HAVE && 0 5484IMPORTPROC DoDumpTable(void); 5485#endif 5486#if dbglog_HAVE && 0 5487IMPORTPROC DumpRTC(void); 5488#endif 5489 5490LOCALPROC UnInitOSGLU(void) 5491{ 5492#if dbglog_HAVE && 0 5493 DoDumpTable(); 5494#endif 5495#if dbglog_HAVE && 0 5496 DumpRTC(); 5497#endif 5498 5499 if (MacMsgDisplayed) { 5500 MacMsgDisplayOff(); 5501 } 5502 5503#if EmLocalTalk 5504 UnInitLocalTalk(); 5505#endif 5506 5507#if MayFullScreen 5508 UngrabMachine(); 5509#endif 5510 5511#if MySoundEnabled 5512 MySound_Stop(); 5513#endif 5514 5515 CloseAglCurrentContext(); 5516 CloseMainWindow(); 5517 5518#if MayFullScreen 5519 My_ShowMenuBar(); 5520#endif 5521 5522#if IncludePbufs 5523 UnInitPbufs(); 5524#endif 5525 UnInitDrives(); 5526 5527 if (! gTrueBackgroundFlag) { 5528 CheckSavedMacMsg(); 5529 } 5530 5531 UnInstallOurEventHandlers(); 5532 5533#if dbglog_HAVE 5534 dbglog_close(); 5535#endif 5536 5537 UnInitMyApplInfo(); 5538 5539 ForceShowCursor(); 5540} 5541 5542LOCALPROC ZapOSGLUVars(void) 5543{ 5544 InitDrives(); 5545 ZapWinStateVars(); 5546} 5547 5548/* adapted from Apple "Technical Q&A QA1061" */ 5549 5550static pascal OSStatus EventLoopEventHandler( 5551 EventHandlerCallRef inHandlerCallRef, EventRef inEvent, 5552 void *inUserData) 5553/* 5554 This code contains the standard Carbon event dispatch loop, 5555 as per "Inside Macintosh: Handling Carbon Events", Listing 3-10, 5556 except: 5557 5558 o this loop supports yielding to cooperative threads based on the 5559 application maintaining the gNumberOfRunningThreads global 5560 variable, and 5561 5562 o it also works around a problem with the Inside Macintosh code 5563 which unexpectedly quits when run on traditional Mac OS 9. 5564 5565 See RunApplicationEventLoopWithCooperativeThreadSupport for 5566 an explanation of why this is inside a Carbon event handler. 5567 5568 The code in Inside Mac has a problem in that it quits the 5569 event loop when ReceiveNextEvent returns an error. This is 5570 wrong because ReceiveNextEvent can return eventLoopQuitErr 5571 when you call WakeUpProcess on traditional Mac OS. So, rather 5572 than relying on an error from ReceiveNextEvent, this routine tracks 5573 whether the application is really quitting by installing a 5574 customer handler for the kEventClassApplication/kEventAppQuit 5575 Carbon event. All the custom handler does is call through 5576 to the previous handler and, if it returns noErr (which indicates 5577 the application is quitting, it sets quitNow so that our event 5578 loop quits. 5579 5580 Note that this approach continues to support 5581 QuitApplicationEventLoop, which is a simple wrapper that just posts 5582 a kEventClassApplication/kEventAppQuit event to the event loop. 5583*/ 5584{ 5585 UnusedParam(inHandlerCallRef); 5586 UnusedParam(inEvent); 5587 UnusedParam(inUserData); 5588 5589 ProgramMain(); 5590 QuitApplicationEventLoop(); 5591 5592 return noErr; 5593} 5594 5595LOCALPROC RunApplicationEventLoopWithCooperativeThreadSupport(void) 5596/* 5597 A reimplementation of RunApplicationEventLoop that supports 5598 yielding time to cooperative threads. 5599*/ 5600{ 5601 static const EventTypeSpec eventSpec = {'KWIN', 'KWIN'}; 5602 EventHandlerUPP theEventLoopEventHandlerUPP = nil; 5603 EventHandlerRef installedHandler = NULL; 5604 EventRef dummyEvent = nil; 5605 5606/* 5607 Install EventLoopEventHandler, create a dummy event and post it, 5608 and then call RunApplicationEventLoop. The rationale for this 5609 is as follows: We want to unravel RunApplicationEventLoop so 5610 that we can can yield to cooperative threads. In fact, the 5611 core code for RunApplicationEventLoop is pretty easy (you 5612 can see it above in EventLoopEventHandler). However, if you 5613 just execute this code you miss out on all the standard event 5614 handlers. These are relatively easy to reproduce (handling 5615 the quit event and so on), but doing so is a pain because 5616 a) it requires a bunch boilerplate code, and b) if Apple 5617 extends the list of standard event handlers, your application 5618 wouldn't benefit. So, we execute our event loop from within 5619 a Carbon event handler that we cause to be executed by 5620 explicitly posting an event to our event loop. Thus, the 5621 standard event handlers are installed while our event loop runs. 5622*/ 5623 if (nil == (theEventLoopEventHandlerUPP 5624 = NewEventHandlerUPP(EventLoopEventHandler))) 5625 { 5626 /* fail */ 5627 } else 5628 if (noErr != InstallEventHandler(GetApplicationEventTarget(), 5629 theEventLoopEventHandlerUPP, 1, &eventSpec, nil, 5630 &installedHandler)) 5631 { 5632 /* fail */ 5633 } else 5634 if (noErr != MacCreateEvent(nil, 'KWIN', 'KWIN', 5635 GetCurrentEventTime(), kEventAttributeNone, 5636 &dummyEvent)) 5637 { 5638 /* fail */ 5639 } else 5640 if (noErr != PostEventToQueue(GetMainEventQueue(), 5641 dummyEvent, kEventPriorityHigh)) 5642 { 5643 /* fail */ 5644 } else 5645 { 5646 RunApplicationEventLoop(); 5647 } 5648 5649 if (nil != dummyEvent) { 5650 ReleaseEvent(dummyEvent); 5651 } 5652 5653 if (NULL != installedHandler) { 5654 (void) RemoveEventHandler(installedHandler); 5655 } 5656} 5657 5658int main(void) 5659{ 5660 ZapOSGLUVars(); 5661 if (InitOSGLU()) { 5662 RunApplicationEventLoopWithCooperativeThreadSupport(); 5663 } 5664 UnInitOSGLU(); 5665 5666 return 0; 5667} 5668 5669#endif /* WantOSGLUOSX */