|
|
1.1 ! root 1: // Thinker.m ! 2: // ! 3: // This class is the brains behind the BackSpace app; it is the Application ! 4: // object's delegate, and it watches the system to determine when to ! 5: // initiate the screen saver mode. ! 6: // ! 7: // You may freely copy, distribute, and reuse the code in this example. ! 8: // NeXT disclaims any warranty of any kind, expressed or implied, as to its ! 9: // fitness for any particular use. ! 10: ! 11: ! 12: #import "Thinker.h" ! 13: #import "BackWindow.h" ! 14: #import "BackView.h" ! 15: #import "SpaceView.h" ! 16: #import "MySlider.h" ! 17: #import "Password.h" ! 18: #import "psfuncts.h" ! 19: ! 20: #import <appkit/appkit.h> ! 21: #import <objc/NXBundle.h> ! 22: ! 23: // convert vertical blank time to milliseconds ! 24: #define SEC2MS(x) ((x * 1000) + 20) ! 25: ! 26: //#define SHOWITERATIONSPERSEC ! 27: ! 28: #ifdef SHOWITERATIONSPERSEC ! 29: unsigned iterations; ! 30: BStimeval then, now, targetTime; ! 31: #endif ! 32: ! 33: static id _BSThinker; ! 34: ! 35: id BSThinker() ! 36: { return _BSThinker; ! 37: } ! 38: ! 39: ! 40: @implementation Thinker ! 41: ! 42: - appDidInit:sender ! 43: { ! 44: const char *autoLaunch; ! 45: globalTier = BACKGROUNDTIER; ! 46: openAnother = YES; ! 47: _BSThinker = self; ! 48: ! 49: backZone = NXCreateZone(vm_page_size, vm_page_size, YES); ! 50: ! 51: NXSetRect(&windowRect, 475, 300, 500, 450); ! 52: ! 53: [NXApp getScreens:&screens count:&screenCount]; ! 54: ! 55: [commonImageInspector getFrame: &inspectorFrame]; ! 56: currentInspector = commonImageInspector; ! 57: ! 58: [self getViewType]; ! 59: [self setVirtualViewIndexAndIncrement:NO]; ! 60: [self getWindowType]; ! 61: ! 62: [self getScreenSaverSetting]; ! 63: [self getScreenLockerSetting]; ! 64: [self getPrioritySetting]; ! 65: [self getImageFile]; ! 66: [self getHotCornerSetting]; ! 67: ! 68: autoLaunch = NXGetDefaultValue([NXApp appName], "NXAutoLaunch"); ! 69: if (strcmp(autoLaunch,"YES")) ! 70: { ! 71: [[windMatrix window] makeKeyAndOrderFront:self]; ! 72: windowHasBeenDisplayed = YES; ! 73: } ! 74: else [NXApp hide:self]; ! 75: ! 76: #ifdef SHOWITERATIONSPERSEC ! 77: then = currentTimeInMs(); ! 78: targetTime = then + 10000; ! 79: #endif ! 80: ! 81: srandom(time(0)); ! 82: ! 83: return self; ! 84: } ! 85: ! 86: - appDidHide:sender ! 87: { ! 88: if (windowType != BACKWINDOW) [self removeTimer]; ! 89: return self; ! 90: } ! 91: ! 92: - appDidUnhide:sender ! 93: { ! 94: if (!windowHasBeenDisplayed) ! 95: { ! 96: [[windMatrix window] makeKeyAndOrderFront:self]; ! 97: windowHasBeenDisplayed = YES; ! 98: } ! 99: ! 100: if (windowType != NOWINDOW) [self createTimer]; ! 101: return self; ! 102: } ! 103: ! 104: ! 105: ! 106: // Pretty much a dummy function to invoke the step method. ! 107: ! 108: void timedEntryFunction (DPSTimedEntry timedEntry, double timeNow, void *theObject) ! 109: { [(id)theObject doDistributorLoop]; ! 110: } ! 111: ! 112: - createTimer ! 113: { ! 114: if (!timerValid) ! 115: { ! 116: timerValid = YES; ! 117: timer = DPSAddTimedEntry(0.02, &timedEntryFunction, self, NX_BASETHRESHOLD); ! 118: } ! 119: return self; ! 120: } ! 121: ! 122: - removeTimer ! 123: { ! 124: if (timerValid) DPSRemoveTimedEntry (timer); ! 125: timerValid = NO; ! 126: return self; ! 127: } ! 128: ! 129: - doDistributorLoop ! 130: { ! 131: NXEvent dummyEvent; ! 132: ! 133: keepLooping = YES; ! 134: [spaceView lockFocus]; ! 135: if ([spaceView respondsTo:@selector(didLockFocus)]) [spaceView didLockFocus]; ! 136: ! 137: do { ! 138: [spaceView oneStep]; ! 139: [spaceWindow flushWindow]; ! 140: NXPing (); // Synchronize postscript for smoother animation ! 141: ! 142: [spaceView oneStep]; ! 143: [spaceWindow flushWindow]; ! 144: NXPing (); // Synchronize postscript for smoother animation ! 145: ! 146: #ifdef SHOWITERATIONSPERSEC ! 147: iterations++; ! 148: if ((now = currentTimeInMs()) > targetTime) ! 149: { ! 150: printf("BackSpace: %5.1f its/sec\n", ! 151: (double)iterations*1000.0/(double)(now - then)); ! 152: iterations = 0; ! 153: targetTime = now + 10000; ! 154: then = now; ! 155: } ! 156: #endif ! 157: ! 158: } while (timerValid && keepLooping && ! 159: ([NXApp peekNextEvent:NX_ALLEVENTS into:&dummyEvent ! 160: waitFor:0 threshold:NX_BASETHRESHOLD] == NULL)); ! 161: ! 162: [spaceView unlockFocus]; ! 163: ! 164: return self; ! 165: ! 166: } ! 167: ! 168: - installSpaceViewIntoWindow:w ! 169: { ! 170: NXRect cvrect; ! 171: int i; ! 172: id subviews, contentView; ! 173: ! 174: if (!w) return nil; ! 175: contentView = [w contentView]; ! 176: ! 177: // get size of content view ! 178: [contentView getBounds:&cvrect]; ! 179: ! 180: // remove old subviews, this is overkill really... ! 181: subviews = [contentView subviews]; ! 182: for (i=([subviews count]-1); i>=0; i--) ! 183: { [[subviews objectAt:i] removeFromSuperview]; ! 184: } ! 185: ! 186: // install it into the window's content view ! 187: [contentView addSubview:spaceView]; ! 188: [contentView setAutoresizeSubviews:YES]; ! 189: [spaceView setAutosizing:NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE]; ! 190: ! 191: // size the spaceview ! 192: [spaceView sizeTo:cvrect.size.width :cvrect.size.height]; ! 193: ! 194: return self; ! 195: } ! 196: ! 197: - useNormalWindow ! 198: { ! 199: int myBacking; ! 200: ! 201: spaceView = [self backView]; ! 202: myBacking = [self backingTypeForView:spaceView]; ! 203: ! 204: if (!normalWindow) ! 205: { ! 206: normalWindow = [[Window allocFromZone:backZone] ! 207: initContent:&windowRect style:NX_RESIZEBARSTYLE ! 208: backing:myBacking ! 209: buttonMask:NX_CLOSEBUTTONMASK ! 210: defer:NO]; ! 211: ! 212: [self setWindowTitle]; ! 213: [normalWindow useOptimizedDrawing:YES]; ! 214: [normalWindow setDynamicDepthLimit:YES]; //want window depth to match device! ! 215: [normalWindow setOneShot:YES]; ! 216: [normalWindow setDelegate:self]; ! 217: [normalWindow setBackgroundGray:NX_BLACK]; ! 218: } ! 219: ! 220: spaceWindow = normalWindow; ! 221: [self installSpaceViewIntoWindow:spaceWindow]; ! 222: ! 223: if ([spaceView respondsTo:@selector(setImage:)]) ! 224: [spaceView setImage: image]; ! 225: if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow]; ! 226: [spaceWindow display]; ! 227: ! 228: [spaceWindow makeKeyAndOrderFront:self]; ! 229: ! 230: // need to do this so flushing always works! ! 231: // must do it late because kit does lazy window creation ie the PostScript ! 232: // window might not exist until you actually draw to it ! 233: ! 234: if (myBacking == NX_RETAINED) ! 235: [spaceWindow setBackingType:NX_RETAINED]; ! 236: else [spaceWindow setBackingType:NX_BUFFERED]; ! 237: ! 238: return self; ! 239: } ! 240: ! 241: - (int) backingTypeForView:aView ! 242: { ! 243: if ([aView respondsTo:@selector(useBufferedWindow)] ! 244: && [aView useBufferedWindow]) ! 245: return NX_BUFFERED; ! 246: return NX_RETAINED; ! 247: } ! 248: ! 249: - useBackWindow:(int)tier ! 250: { ! 251: NXRect r={{0, 0}}; ! 252: int myBacking; ! 253: ! 254: [NXApp getScreenSize:&(r.size)]; ! 255: ! 256: spaceView = [self backView]; ! 257: myBacking = [self backingTypeForView:spaceView]; ! 258: ! 259: [self createBigWindowIfNecessaryForView:spaceView]; ! 260: ! 261: if (myBacking == NX_RETAINED) ! 262: { spaceWindow = bigUnbufferedWindow; ! 263: tweakWindow([spaceWindow windowNum], tier); ! 264: } ! 265: else ! 266: { spaceWindow = bigBufferedWindow; ! 267: } ! 268: ! 269: [self installSpaceViewIntoWindow:spaceWindow]; ! 270: ! 271: if ([spaceView respondsTo:@selector(setImage:)]) ! 272: [spaceView setImage: image]; ! 273: ! 274: [spaceWindow placeWindow:&r]; ! 275: if (myBacking == NX_BUFFERED) [spaceWindow display]; ! 276: ! 277: [spaceWindow orderFront:self]; ! 278: if (myBacking == NX_BUFFERED) tweakWindow([spaceWindow windowNum], tier); ! 279: else [spaceWindow display]; ! 280: ! 281: if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow]; ! 282: ! 283: return self; ! 284: } ! 285: ! 286: - createBigWindowIfNecessaryForView:aView ! 287: { ! 288: NXRect r={{0, 0}}; ! 289: int myBacking = [self backingTypeForView:aView]; ! 290: ! 291: [NXApp getScreenSize:&(r.size)]; ! 292: ! 293: if ((myBacking == NX_RETAINED) && !bigUnbufferedWindow) ! 294: { ! 295: ! 296: bigUnbufferedWindow = [[BackWindow allocFromZone:backZone] ! 297: initContent:&r style:NX_TOKENSTYLE ! 298: backing:NX_NONRETAINED buttonMask:0 defer:NO]; ! 299: ! 300: [bigUnbufferedWindow useOptimizedDrawing:YES]; ! 301: ! 302: [bigUnbufferedWindow removeFromEventMask:(NX_LMOUSEDOWNMASK | NX_LMOUSEUPMASK ! 303: | NX_MOUSEMOVEDMASK | NX_LMOUSEDRAGGEDMASK ! 304: | NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK ! 305: | NX_KEYDOWNMASK | NX_KEYUPMASK ! 306: | NX_CURSORUPDATEMASK)]; ! 307: [bigUnbufferedWindow setBackgroundGray:NX_BLACK]; ! 308: } ! 309: ! 310: if ((myBacking == NX_BUFFERED) && !bigBufferedWindow) ! 311: { ! 312: ! 313: bigBufferedWindow = [[BackWindow allocFromZone:backZone] ! 314: initContent:&r style:NX_TOKENSTYLE ! 315: backing:NX_BUFFERED buttonMask:0 defer:NO]; ! 316: ! 317: [bigBufferedWindow useOptimizedDrawing:YES]; ! 318: ! 319: [bigBufferedWindow removeFromEventMask:(NX_LMOUSEDOWNMASK | NX_LMOUSEUPMASK ! 320: | NX_MOUSEMOVEDMASK | NX_LMOUSEDRAGGEDMASK ! 321: | NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK ! 322: | NX_KEYDOWNMASK | NX_KEYUPMASK ! 323: | NX_CURSORUPDATEMASK)]; ! 324: ! 325: [bigBufferedWindow setDynamicDepthLimit:YES]; //want window depth to match device! ! 326: [bigBufferedWindow setOneShot:YES]; ! 327: [bigBufferedWindow setBackgroundGray:NX_BLACK]; ! 328: } ! 329: ! 330: return self; ! 331: } ! 332: ! 333: - changeWindowType:sender ! 334: { ! 335: [self changeWindowTypeAndRemember:YES]; ! 336: return self; ! 337: } ! 338: ! 339: - changeWindowTypeAndRemember:(BOOL)rem ! 340: { ! 341: char str[10]; ! 342: int newWindowType; ! 343: ! 344: newWindowType = [windMatrix selectedRow]; ! 345: if (newWindowType == windowType) return self; ! 346: ! 347: windowType = newWindowType; ! 348: ! 349: if (rem) ! 350: { ! 351: sprintf(str,"%1d", windowType); ! 352: NXWriteDefault([NXApp appName], "windowType", str); ! 353: } ! 354: ! 355: [spaceWindow orderOut:self]; ! 356: ! 357: switch (windowType) ! 358: { ! 359: case NOWINDOW: ! 360: [self removeTimer]; ! 361: break; ! 362: case NORMALWINDOW: ! 363: [self useNormalWindow]; ! 364: [self createTimer]; ! 365: break; ! 366: case BACKWINDOW: ! 367: [self useBackWindow: globalTier]; ! 368: [self createTimer]; ! 369: break; ! 370: } ! 371: ! 372: return self; ! 373: } ! 374: ! 375: - getWindowType ! 376: { ! 377: int tWindowType = NORMALWINDOW; ! 378: const char *ptr; ! 379: int val; ! 380: ! 381: ptr = NXGetDefaultValue([NXApp appName], "windowType"); ! 382: if (ptr) ! 383: { ! 384: sscanf(ptr,"%d",&val); ! 385: if (val >= 0 && val <= 2) tWindowType = val; ! 386: } ! 387: ! 388: [windMatrix selectCellAt:tWindowType :0]; ! 389: [self changeWindowTypeAndRemember:NO]; ! 390: ! 391: return self; ! 392: } ! 393: ! 394: - getScreenSaverSetting ! 395: { ! 396: const char *ptr; ! 397: ! 398: if((evs = NXOpenEventStatus()) == 0) ! 399: { perror("NXOpenEventStatus failed."); ! 400: exit(10); ! 401: } ! 402: ! 403: [self getDimBrightness:&dimBrightness]; ! 404: ! 405: //in case the old dim brightness is somehow invalid, I reset it ! 406: if (dimBrightness > .25) ! 407: { ! 408: dimBrightness = .25; ! 409: [self _setDimBrightness:&dimBrightness]; ! 410: } ! 411: ! 412: [screenSaver setState:0]; ! 413: ! 414: ptr = NXGetDefaultValue([NXApp appName], "screenSaver"); ! 415: ! 416: if (!ptr || !strcmp(ptr,"Off")) [self setScreenSaver:NO andRemember:NO]; ! 417: else [self setScreenSaver:YES andRemember:NO]; ! 418: ! 419: return self; ! 420: } ! 421: ! 422: - changeScreenSaverSetting:sender ! 423: { ! 424: [self setScreenSaver:([screenSaver state])andRemember:YES]; ! 425: return self; ! 426: } ! 427: ! 428: - setScreenSaver:(BOOL)val andRemember:(BOOL)rem ! 429: { ! 430: [screenSaver setState:val]; ! 431: screenSaverVal = val; ! 432: ! 433: if (val) ! 434: { ! 435: // turn it on... ! 436: [self calcDimTime]; ! 437: if (rem) NXWriteDefault([NXApp appName], "screenSaver", "On"); ! 438: } ! 439: else ! 440: { ! 441: // turn it off... ! 442: if (rem) NXRemoveDefault([NXApp appName], "screenSaver"); ! 443: } ! 444: ! 445: return self; ! 446: } ! 447: ! 448: - calcDimTime ! 449: { ! 450: double dimTime; ! 451: [self getDimTime :&dimTime]; ! 452: ! 453: if (dimTime < 0) dimTime = .1; ! 454: ! 455: if (screenSaverVal && !doingSaver) ! 456: { ! 457: // printf("BackSpace calcDimTime: dims in %f seconds\n",dimTime); ! 458: ! 459: [self perform:@selector(maybeDoScreenSaver:) ! 460: with:self ! 461: afterDelay:SEC2MS(dimTime) ! 462: cancelPrevious:YES]; ! 463: } ! 464: ! 465: return self; ! 466: } ! 467: ! 468: - maybeDoScreenSaver:sender ! 469: { ! 470: NXEvent anEvent; ! 471: BOOL autoDimmed; ! 472: ! 473: // in case timed entry fires but user has killed screen saver ! 474: if (!screenSaverVal || doingSaver) return self; ! 475: ! 476: autoDimmed = NXAutoDimState(evs); ! 477: if (!autoDimmed) ! 478: { ! 479: [self calcDimTime]; ! 480: return self; ! 481: } ! 482: ! 483: // The perform:afterDelay: method starts a timed entry to ! 484: // invoke maybeDoScreenSaver, so we are in a timed entry ! 485: // right now. If we just jumped into doScreenSaver:, we ! 486: // would interrupt the doDistributorLoop method while ! 487: // it's still focused on the spaceView. By posting an ! 488: // event, we force that loop to bail out so we can jump ! 489: // into the screen saver cleanly. ! 490: ! 491: keepLooping = NO; // There was a bug related to this at one point. ! 492: // I don't think it's necessary anymore. ! 493: anEvent.type = NX_APPDEFINED; ! 494: anEvent.data.compound.subtype = BSDOSAVER; ! 495: anEvent.ctxt = [NXApp context]; ! 496: DPSPostEvent(&anEvent,0); ! 497: ! 498: return self; ! 499: } ! 500: ! 501: - applicationDefined:(NXEvent *)theEvent ! 502: { ! 503: switch (theEvent->data.compound.subtype) ! 504: { ! 505: case BSDOSAVER: ! 506: [self doScreenSaver:self]; ! 507: [self calcDimTime]; // reset to fire again ! 508: break; ! 509: case BSOPENFILE: ! 510: [self doDelayedOpenFile]; ! 511: break; ! 512: default: ! 513: break; ! 514: } ! 515: return self; ! 516: } ! 517: ! 518: - showFakeScreenSaverAfterPause:sender ! 519: { ! 520: usleep(250000); ! 521: return [self showFakeScreenSaver:sender]; ! 522: } ! 523: ! 524: - showFakeScreenSaver:sender ! 525: { ! 526: [self screenSaverMode]; ! 527: NXSetAutoDimState(evs, YES); ! 528: [self doScreenSaver:self]; ! 529: NXSetAutoDimState(evs, NO); ! 530: [self normalMode]; //usually not necessary ! 531: ! 532: // reset to fire again ! 533: [self calcDimTime]; ! 534: ! 535: return self; ! 536: } ! 537: ! 538: ! 539: - doScreenSaver:sender ! 540: { ! 541: BOOL autoDimmed; ! 542: int oldWindowType; ! 543: BOOL mouseOK, oldTimerValid; ! 544: BOOL ignoreMouseMovement = NO; ! 545: BOOL isHidden; ! 546: NXRect trackingRect; ! 547: NXPoint mouseLoc; ! 548: BOOL passwordOK; ! 549: BOOL stoleActivation = NO; ! 550: int oldActiveApp = 0; ! 551: int iterationCount = 0; ! 552: ! 553: // must be sure we don't enter on timed entry after faking saver ! 554: doingSaver = YES; ! 555: ! 556: isHidden = [NXApp isHidden]; ! 557: if (isHidden) ! 558: { ! 559: [NXApp unhideWithoutActivation:self]; ! 560: } ! 561: ! 562: // force activation here so we get keystrokes if someone ! 563: // just types his password. ! 564: if ([password isLocked]) ! 565: { ! 566: oldActiveApp = [NXApp activateSelf:YES]; ! 567: stoleActivation = YES; ! 568: } ! 569: ! 570: [self setVirtualViewIndexAndIncrement:YES]; ! 571: ! 572: //save old window state ! 573: oldWindowType = [windMatrix selectedRow]; ! 574: ! 575: globalTier = SAVERTIER; ! 576: ! 577: [self blackOutAllScreens]; ! 578: ! 579: //background window on screen ! 580: [windMatrix selectCellAt:BACKWINDOW :0]; ! 581: [self changeWindowTypeAndRemember:NO]; ! 582: ! 583: //nuke timer so timed entry doesn't fire ! 584: oldTimerValid = timerValid; ! 585: [self removeTimer]; ! 586: ! 587: ! 588: //set background window tier to SAVERTIER ! 589: if ([self backingTypeForView:spaceView] == NX_BUFFERED) ! 590: { ! 591: // make sure the one shot buffer really exists ! 592: //[spaceWindow display]; //xxx ! 593: if ([spaceWindow windowNum] <= 0) [spaceWindow display]; ! 594: PSsetwindowlevel(SAVERTIER, [spaceWindow windowNum]); ! 595: } ! 596: else ! 597: { ! 598: PSsetwindowlevel(SAVERTIER, [spaceWindow windowNum]); ! 599: [spaceView fillBoundsWithBlack]; ! 600: [spaceView display]; ! 601: } ! 602: ! 603: NXPing(); ! 604: [self screenSaverMode]; ! 605: ! 606: PSsetwaitcursorenabled(NO); ! 607: ! 608: if ([spaceView respondsTo:@selector(enteredScreenSaverMode)]) ! 609: [spaceView enteredScreenSaverMode]; ! 610: ! 611: do { ! 612: //obscure cursor ! 613: PSobscurecursor(); ! 614: ! 615: [spaceView lockFocus]; ! 616: if ([spaceView respondsTo:@selector(didLockFocus)]) ! 617: [spaceView didLockFocus]; ! 618: ! 619: ! 620: if ([spaceView respondsTo:@selector(ignoreMouseMovement)]) ! 621: ignoreMouseMovement = [spaceView ignoreMouseMovement]; ! 622: ! 623: [spaceWindow getMouseLocation:&mouseLoc]; ! 624: trackingRect.origin.x = mouseLoc.x - 100; ! 625: trackingRect.origin.y = mouseLoc.y - 100; ! 626: trackingRect.size.width = trackingRect.size.height = 200; ! 627: ! 628: do { ! 629: if ((++iterationCount & 0x7f)==0) PSobscurecursor(); ! 630: ! 631: [spaceView oneStep]; ! 632: [spaceWindow flushWindow]; ! 633: NXPing(); // Synchronize postscript for smoother animation ! 634: ! 635: // note: window and view coordinates the same! ! 636: // so I don't have to convert to view coord system ! 637: if (ignoreMouseMovement) mouseOK = YES; ! 638: else ! 639: { ! 640: [spaceWindow getMouseLocation:&mouseLoc]; ! 641: mouseOK = [spaceView mouse:&mouseLoc inRect:&trackingRect]; ! 642: } ! 643: ! 644: [spaceView oneStep]; ! 645: [spaceWindow flushWindow]; ! 646: NXPing(); // Synchronize postscript for smoother animation ! 647: ! 648: autoDimmed = NXAutoDimState(evs); ! 649: } while (autoDimmed && mouseOK); ! 650: ! 651: [spaceView unlockFocus]; ! 652: ! 653: // force activation here in case anyone changed it out ! 654: // from under me. (workspace does this, dog gone it!) ! 655: if ([password isLocked]) ! 656: { ! 657: [NXApp activateSelf:YES]; ! 658: } ! 659: ! 660: passwordOK = [password checkPassword: ! 661: NXLocalString("Screen is locked. Enter password to unlock:",0,0) ! 662: randomPos:YES checkLock:YES withView:spaceView]; ! 663: ! 664: if (!passwordOK) NXSetAutoDimState(evs, YES); ! 665: ! 666: } while (!passwordOK); ! 667: ! 668: if ([spaceView respondsTo:@selector(willExitScreenSaverMode)]) ! 669: [spaceView willExitScreenSaverMode]; ! 670: ! 671: NXSetAutoDimState(evs, NO); ! 672: ! 673: PSsetwaitcursorenabled(YES); ! 674: ! 675: [self normalMode]; ! 676: ! 677: //background window tier to BACKGROUNDTIER ! 678: PSsetwindowlevel(BACKGROUNDTIER, [spaceWindow windowNum]); ! 679: globalTier = BACKGROUNDTIER; ! 680: ! 681: if (([self backingTypeForView:spaceView] != NX_BUFFERED) && ! 682: oldWindowType == BACKWINDOW) ! 683: // this justs fixes a display bug for really lazy nonretained windows ! 684: { ! 685: [spaceView fillBoundsWithBlack]; ! 686: [spaceView display]; ! 687: } ! 688: ! 689: if (oldTimerValid) [self createTimer]; ! 690: ! 691: [self unBlackOutAllScreens]; ! 692: ! 693: //restore old window state ! 694: [windMatrix selectCellAt:oldWindowType :0]; ! 695: [self changeWindowTypeAndRemember:NO]; ! 696: ! 697: if (stoleActivation) ! 698: { ! 699: if (oldActiveApp) [NXApp activate:oldActiveApp]; ! 700: else [NXApp deactivateSelf]; ! 701: } ! 702: ! 703: if (isHidden) ! 704: { ! 705: [NXApp hide:self]; ! 706: } ! 707: ! 708: doingSaver = NO; ! 709: ! 710: return self; ! 711: } ! 712: ! 713: - appWillTerminate:sender ! 714: { ! 715: [self normalMode]; ! 716: return self; ! 717: } ! 718: ! 719: - appDidBecomeActive:sender ! 720: { ! 721: id theMatrix; ! 722: ! 723: theMatrix = [viewSelectionBrowser matrixInColumn:0]; ! 724: [theMatrix scrollCellToVisible:realViewIndex :0]; ! 725: return self; ! 726: } ! 727: ! 728: - app:sender powerOffIn:(int)ms andSave:(int)aFlag ! 729: { ! 730: return [NXApp terminate:self]; ! 731: } ! 732: ! 733: - getPrioritySetting ! 734: { ! 735: const char *ptr; ! 736: int val; ! 737: ! 738: [mySlider setMinValue: 0]; ! 739: [mySlider setMaxValue: 10]; ! 740: ! 741: ptr = NXGetDefaultValue([NXApp appName], "priority"); ! 742: if (ptr) ! 743: { ! 744: sscanf(ptr,"%d",&val); ! 745: if (val >= 0 && val <= 10) priority = val; ! 746: else priority = 4; ! 747: } ! 748: else priority = 4; ! 749: ! 750: [[mySlider cell] setIntValue:priority]; ! 751: [[priorityLevel cell] setIntValue:priority]; ! 752: ! 753: // use mach call rather than unix - mach lets me increase priority! ! 754: // setpriority(PRIO_PROCESS, 0, priority); ! 755: cthread_priority(cthread_self(), priority, FALSE); ! 756: ! 757: return self; ! 758: } ! 759: ! 760: - changeSliderValue:sender ! 761: { ! 762: priority = [[mySlider cell] intValue]; ! 763: [[priorityLevel cell] setIntValue:priority]; ! 764: return self; ! 765: } ! 766: ! 767: - saveSliderValue ! 768: { ! 769: char str[50]; ! 770: // setpriority(PRIO_PROCESS, 0, priority); ! 771: cthread_priority(cthread_self(), priority, FALSE); ! 772: ! 773: sprintf(str,"%d", priority); ! 774: NXWriteDefault([NXApp appName], "priority", str); ! 775: return self; ! 776: } ! 777: ! 778: - windowWillResize:sender toSize:(NXSize *)frameSize ! 779: { ! 780: if (frameSize->width < 100) frameSize->width = 100; ! 781: if (frameSize->height < 100) frameSize->height = 100; ! 782: return self; ! 783: } ! 784: ! 785: - windowWillClose:sender ! 786: { ! 787: [windMatrix selectCellAt:NOWINDOW :0]; ! 788: [self perform:@selector(changeWindowType:) with:self ! 789: afterDelay:1 cancelPrevious:YES]; ! 790: return nil; ! 791: } ! 792: ! 793: BStimeval currentTimeInMs() ! 794: { ! 795: struct timeval curTime; ! 796: gettimeofday (&curTime, NULL); ! 797: return (curTime.tv_sec) * 1000 + curTime.tv_usec / 1000; ! 798: } ! 799: ! 800: // ! 801: // Additional methods to handle a common image object for views. ! 802: // Lennart Lovstrad, Rank Xerox EuroPARC, August 1991. ! 803: // ! 804: ! 805: - setImageFromFile: (const char *) filename ! 806: { ! 807: [image free]; ! 808: ! 809: image = [[NXImage alloc] initFromFile: filename]; ! 810: if (image == nil) ! 811: { ! 812: NXRunAlertPanel([NXApp appName], NXLocalString("Could not open %s",0,0), ! 813: NULL, NULL, NULL, filename); ! 814: image = nil; ! 815: //return nil; //can't return, image is invalid ! 816: } ! 817: ! 818: return [self commonImageInit]; ! 819: } ! 820: ! 821: - setImageFromName: (const char *) name ! 822: { ! 823: [image free]; ! 824: image = [[NXImage alloc] initFromSection: name]; ! 825: ! 826: return [self commonImageInit]; ! 827: } ! 828: ! 829: - commonImageInit ! 830: { ! 831: [imageView setImage: image]; ! 832: [imageView display]; ! 833: ! 834: if ([spaceView respondsTo:@selector(setImage:)]) ! 835: [spaceView setImage: image]; ! 836: ! 837: if ([self backingTypeForView:spaceView] != NX_BUFFERED) ! 838: { ! 839: [spaceView fillBoundsWithBlack]; ! 840: [spaceView display]; ! 841: } ! 842: ! 843: return self; ! 844: } ! 845: ! 846: - getImageFile ! 847: { ! 848: const char *filename; ! 849: ! 850: filename = NXGetDefaultValue([NXApp appName], "imageFile"); ! 851: if (filename) ! 852: [self setImageFromFile: filename]; ! 853: else [self setImageFromName: "defaultImage"]; ! 854: ! 855: return self; ! 856: } ! 857: ! 858: - setImageFileFrom: sender ! 859: { ! 860: id openPanel = [OpenPanel new]; ! 861: const char *fileTypes[] = {"tiff", "eps", NULL}; ! 862: ! 863: if ([openPanel runModalForTypes: fileTypes]) ! 864: { ! 865: [self setImageFromFile: [openPanel filename]]; ! 866: NXWriteDefault([NXApp appName], "imageFile", [openPanel filename]); ! 867: } ! 868: ! 869: [spaceView display]; //don't know why this is necessary... ! 870: ! 871: return self; ! 872: } ! 873: ! 874: // This should return a float between 0 and 1 ! 875: float frandom() ! 876: { ! 877: float val = (random() & 0x7fffffff); ! 878: val /= 0x7fffffff; ! 879: return val; ! 880: } ! 881: ! 882: float randBetween(float a, float b) ! 883: { ! 884: float val, scale, t; ! 885: ! 886: if (a > b) ! 887: { t = a; a = b; b = t; ! 888: } ! 889: ! 890: scale = (b-a); ! 891: val = scale * frandom(); ! 892: return (a + val); ! 893: } ! 894: ! 895: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.