|
|
1.1 ! root 1: // ThinkMore.m ! 2: // ! 3: // Contains additional methods used in the Thinker class. ! 4: // ! 5: // You may freely copy, distribute, and reuse the code in this example. ! 6: // NeXT disclaims any warranty of any kind, expressed or implied, as to its ! 7: // fitness for any particular use. ! 8: ! 9: #import "Thinker.h" ! 10: #import "SpaceView.h" ! 11: #import "BackView.h" ! 12: #import "SleepView.h" ! 13: #import "BlackView.h" ! 14: #import "Password.h" ! 15: #import "psfuncts.h" ! 16: ! 17: ! 18: #import <appkit/appkit.h> ! 19: #import <objc/NXBundle.h> ! 20: ! 21: ! 22: #define VIEWDIRECTORY "/LocalLibrary/BackSpaceViews" ! 23: ! 24: static char *compiledViewNames[] = { ! 25: "Space", ! 26: "Boink", ! 27: "Black", ! 28: }; ! 29: ! 30: #define COMVIEWCOUNT (sizeof(compiledViewNames)/sizeof(*compiledViewNames)) ! 31: ! 32: @implementation Thinker(thinkMore) ! 33: ! 34: ! 35: //must invoke this before creating window or setting up the views ! 36: - getViewType ! 37: { ! 38: int i; ! 39: id theMatrix; ! 40: char buf[MAXPATHLEN]; ! 41: ModuleInfo *m; ! 42: ! 43: strcpy( buf, NXHomeDirectory()); ! 44: strcat( buf, "/Library/BackSpaceViews"); ! 45: ! 46: moduleList = [[ModuleList alloc] init]; ! 47: ! 48: [self loadViewsFrom:buf]; ! 49: [self loadViewsFrom: [self appDirectory]]; ! 50: [self loadViewsFrom: VIEWDIRECTORY]; ! 51: ! 52: for (i = 0; i < COMVIEWCOUNT; i++) ! 53: { ! 54: m = [[ModuleInfo alloc] ! 55: initWithView:nil name:compiledViewNames[i] path:NULL]; ! 56: [moduleList addObject: m]; ! 57: } ! 58: ! 59: [moduleList sort]; ! 60: [viewSelectionBrowser loadColumnZero]; ! 61: theMatrix = [viewSelectionBrowser matrixInColumn:0]; ! 62: [theMatrix selectCellAt:realViewIndex :0]; ! 63: [theMatrix scrollCellToVisible:realViewIndex :0]; ! 64: ! 65: return self; ! 66: } ! 67: ! 68: ! 69: - selectRealViewIndex:sender ! 70: { ! 71: //sender is the NXBrowser ! 72: int index = [[viewSelectionBrowser matrixInColumn:0] selectedRow]; ! 73: ! 74: if (index == realViewIndex) return self; ! 75: if (index == -1) ! 76: { ! 77: id theMatrix = [viewSelectionBrowser matrixInColumn:0]; ! 78: [theMatrix selectCellAt:realViewIndex :0]; ! 79: [theMatrix scrollCellToVisible:realViewIndex :0]; ! 80: return self; ! 81: } ! 82: ! 83: realViewIndex = index; ! 84: [self setVirtualViewIndexAndIncrement:NO]; ! 85: ! 86: return self; ! 87: } ! 88: ! 89: ! 90: // this method is the actual view setting mechanism, ! 91: // guaranteed to get called to set the view ! 92: ! 93: - setVirtualViewIndexAndIncrement:(BOOL)flag ! 94: { ! 95: id myView; ! 96: id newInspector; ! 97: ! 98: if (realViewIndex) ! 99: { ! 100: virtualViewIndex = realViewIndex-1; ! 101: [self selectScreenSaverViews]; ! 102: } ! 103: ! 104: else ! 105: { ! 106: if (flag) ! 107: { ! 108: virtualViewIndex = random() % [moduleList count]; ! 109: [self selectScreenSaverViews]; ! 110: myView = [self backView]; ! 111: ! 112: while ([myView respondsTo:@selector(isBoringScreenSaver)] ! 113: && [myView isBoringScreenSaver]) ! 114: { ! 115: if (++virtualViewIndex >= [moduleList count]) ! 116: virtualViewIndex = 0; ! 117: ! 118: [self selectScreenSaverViews]; ! 119: myView = [self backView]; ! 120: } ! 121: } ! 122: else [self selectScreenSaverViews]; ! 123: } ! 124: ! 125: ! 126: //--------------------------------------------- ! 127: // now plug in the inspector ! 128: //--------------------------------------------- ! 129: myView = [self backView]; ! 130: ! 131: if ([myView respondsTo:@selector(inspector:)]) ! 132: { ! 133: newInspector = [myView inspector:self]; ! 134: if (!newInspector) newInspector = [self nullInspector]; ! 135: } ! 136: else newInspector = [self nullInspector]; ! 137: ! 138: if (newInspector != currentInspector) ! 139: { ! 140: if ([oldInspectorOwner respondsTo:@selector(inspectorWillBeRemoved)]) ! 141: [oldInspectorOwner inspectorWillBeRemoved]; ! 142: // either myView will be the inspector owner, or it won't care ! 143: oldInspectorOwner = myView; ! 144: ! 145: // don't want it to resize the box. Suboptimal technique... ! 146: [newInspector setFrame:&inspectorFrame]; ! 147: ! 148: [invisibleInspectorBox setContentView: newInspector]; ! 149: currentInspector = newInspector; ! 150: ! 151: if ([myView respondsTo:@selector(inspectorInstalled)]) ! 152: [myView inspectorInstalled]; ! 153: ! 154: [invisibleInspectorBox display]; ! 155: } ! 156: ! 157: return self; ! 158: } ! 159: ! 160: ! 161: - selectScreenSaverViews ! 162: { ! 163: id theView, bigWindow; ! 164: int myBacking; ! 165: ! 166: //need to order out big window if that's the type and buffering changed ! 167: ! 168: theView = [self backView]; ! 169: ! 170: myBacking = [self backingTypeForView:theView]; ! 171: ! 172: [self createBigWindowIfNecessaryForView:theView]; ! 173: ! 174: if (myBacking == NX_BUFFERED) bigWindow = bigBufferedWindow; ! 175: else bigWindow = bigUnbufferedWindow; ! 176: ! 177: if (windowType == BACKWINDOW) ! 178: { ! 179: if (spaceWindow != bigWindow) ! 180: { ! 181: [spaceWindow orderOut:self]; ! 182: [self useBackWindow:globalTier]; ! 183: } ! 184: } ! 185: ! 186: spaceView = theView; ! 187: [self installSpaceViewIntoWindow:spaceWindow]; ! 188: ! 189: if ([spaceView respondsTo:@selector(setImage:)]) ! 190: [spaceView setImage: image]; ! 191: if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow]; ! 192: ! 193: [self setWindowTitle]; ! 194: ! 195: NXWriteDefault([NXApp appName], "viewType", (realViewIndex ? ! 196: ([moduleList nameAt: realViewIndex-1]) : "All")); ! 197: ! 198: ! 199: if (windowType) ! 200: { ! 201: // the unbuffered window looks better if you just display ! 202: // its contents, but for a buffered oneshot window, you must ! 203: // display the window to make sure the window server window exists. ! 204: ! 205: if (myBacking == NX_BUFFERED) ! 206: [spaceWindow display]; ! 207: else ! 208: { ! 209: [spaceView fillBoundsWithBlack]; ! 210: [spaceView display]; ! 211: } ! 212: } ! 213: ! 214: if (normalWindow && (windowType == NORMALWINDOW)) ! 215: { ! 216: if (myBacking == NX_BUFFERED) ! 217: [normalWindow setBackingType:NX_BUFFERED]; ! 218: else[normalWindow setBackingType:NX_RETAINED]; ! 219: } ! 220: ! 221: return self; ! 222: } ! 223: ! 224: - setWindowTitle ! 225: { ! 226: if ([spaceView respondsTo:@selector(windowTitle)]) ! 227: { ! 228: [normalWindow setTitle: NXLocalString([spaceView windowTitle],0,0)]; ! 229: } ! 230: else [normalWindow setTitle: NXLocalString("BackSpace",0,0)]; ! 231: return self; ! 232: } ! 233: ! 234: ! 235: - getScreenLockerSetting ! 236: { ! 237: const char *ptr; ! 238: ! 239: [screenLocker setState:0]; ! 240: ! 241: ptr = NXGetDefaultValue([NXApp appName], "screenLocker"); ! 242: ! 243: if (!ptr || !strcmp(ptr,"Off")) [self setScreenLocker:NO andRemember:NO]; ! 244: else [self setScreenLocker:YES andRemember:NO]; ! 245: ! 246: return self; ! 247: } ! 248: ! 249: - changeScreenLockerSetting:sender ! 250: { ! 251: if (![password checkPassword: ! 252: NXLocalString("Enter password to change screen lock setting:",0,0) ! 253: randomPos:NO checkLock:NO withView:nil]) ! 254: { ! 255: [screenLocker setState:[password isLocked]]; ! 256: return self; ! 257: } ! 258: ! 259: if (![password validPassword] && ![password setPassword:self]) ! 260: { ! 261: [screenLocker setState:[password isLocked]]; ! 262: return self; ! 263: } ! 264: ! 265: [self setScreenLocker:([screenLocker state])andRemember:YES]; ! 266: return self; ! 267: } ! 268: ! 269: - setScreenLocker:(BOOL)val andRemember:(BOOL)rem ! 270: { ! 271: [screenLocker setState:val]; ! 272: [password setLock: val]; ! 273: ! 274: if (rem) ! 275: { ! 276: if (val) NXWriteDefault([NXApp appName], "screenLocker", "On"); ! 277: else NXRemoveDefault([NXApp appName], "screenLocker"); ! 278: } ! 279: ! 280: return self; ! 281: } ! 282: ! 283: ! 284: ! 285: ! 286: //--------------------------------------------------- ! 287: // View manager routines ! 288: //--------------------------------------------------- ! 289: ! 290: - backView ! 291: { ! 292: NXRect aFrame = {{0,0},{200,200}}; ! 293: id theView; ! 294: ! 295: if (![moduleList viewAt:virtualViewIndex]) ! 296: { ! 297: char path[MAXPATHLEN]; ! 298: id myClass; ! 299: const char *name; ! 300: char *filenames[] = {path, NULL}; ! 301: ModuleInfo *mp; ! 302: struct mach_header *header; ! 303: ! 304: mp = [moduleList objectAt: virtualViewIndex]; ! 305: name = [mp viewName]; ! 306: ! 307: // before I loaded all classes at launch time; now classes are ! 308: // loaded only as needed. This idea and some of the code here is ! 309: // from bill bumgarner, thanx! ! 310: ! 311: if ([mp path]) // we have path but no instance, must load class ! 312: { ! 313: long ret; ! 314: do ! 315: { ! 316: sprintf(path, "%s/%sView.BackO", [mp path], name); ! 317: ret = objc_loadModules(filenames, NULL, NULL, &header, NULL); ! 318: ! 319: // objc_loadModules succeeds with a warning if the architecture of the ! 320: // object file is wrong, so we better check if we really got a class ! 321: ! 322: if (!ret) // load succeeded or was wrong architecture ! 323: { ! 324: sprintf(path,"%sView", name); ! 325: myClass = objc_getClass(path); ! 326: if (!myClass) ret = -1; ! 327: } ! 328: ! 329: } while (ret && [mp useNextPath]); ! 330: ! 331: [mp discardAltPaths]; ! 332: ! 333: if (ret) ! 334: { ! 335: // Ugh, failed. Will instantiate a BlackView instead... ! 336: NXRunAlertPanel([NXApp appName], NXLocalString( ! 337: "Could not dynamically load class: %sView",0,0), ! 338: NULL, NULL, NULL, name); ! 339: name = "Black"; ! 340: } ! 341: else ! 342: { ! 343: [mp setHeader:header]; ! 344: } ! 345: } ! 346: ! 347: //at this point we must have a valid name for a loaded class ! 348: ! 349: sprintf(path,"%sView", name); ! 350: myClass = objc_getClass(path); ! 351: ! 352: theView = [[myClass allocFromZone:backZone] initFrame:&aFrame]; ! 353: [[moduleList objectAt:virtualViewIndex] setView:theView]; ! 354: } ! 355: ! 356: theView = [moduleList viewAt:virtualViewIndex]; ! 357: ! 358: return theView; ! 359: } ! 360: ! 361: - showInfoPanel:sender ! 362: { ! 363: if (!infoPanel) ! 364: { ! 365: if (![NXApp loadNibSection:"Info.nib" owner:self withNames:NO fromZone:[self zone]]) ! 366: NXLogError ("Can't find Info.nib!"); ! 367: } ! 368: [infoPanel makeKeyAndOrderFront:sender]; ! 369: return self; ! 370: } ! 371: ! 372: #define SLEEPSIZE (3.0) ! 373: ! 374: - createSleepWindow ! 375: { ! 376: if (!sleepWindow) ! 377: { ! 378: NXRect sleep={{0, 0},{SLEEPSIZE, SLEEPSIZE}}; ! 379: id aView = [[SleepView alloc] initFrame:&sleep]; ! 380: ! 381: sleepWindow = [[Window alloc] ! 382: initContent:&sleep style:NX_TOKENSTYLE ! 383: backing:NX_NONRETAINED buttonMask:0 defer:NO]; ! 384: ! 385: [sleepWindow setEventMask:(NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK)]; ! 386: PSsetwindowlevel(SLEEPTIER, [sleepWindow windowNum]); ! 387: PSWmakeWindowGray([sleepWindow windowNum]); ! 388: [[sleepWindow setContentView: aView] free]; ! 389: ! 390: [sleepWindow setTrackingRect:&sleep inside:YES owner:aView ! 391: tag:3 left:NO right:NO]; ! 392: } ! 393: ! 394: return self; ! 395: } ! 396: ! 397: - setSleepCorner:(int)val ! 398: { ! 399: NXRect screen={{0, 0}}; ! 400: NXCoord x = 0.0, y = 0.0; ! 401: ! 402: if (val) ! 403: { ! 404: [NXApp getScreenSize:&(screen.size)]; ! 405: [self createSleepWindow]; ! 406: if (val == 2 || val == 3) x = screen.size.width - SLEEPSIZE; ! 407: if (val == 3 || val == 4) y = screen.size.height - SLEEPSIZE; ! 408: [sleepWindow moveTo:x :y]; ! 409: [sleepWindow orderFront:self]; ! 410: } ! 411: else [sleepWindow orderOut:self]; ! 412: return self; ! 413: } ! 414: ! 415: - getHotCornerSetting ! 416: { ! 417: const char *ptr; ! 418: int tval, val=0; ! 419: ! 420: ptr = NXGetDefaultValue([NXApp appName], "hotCorner"); ! 421: if (ptr) ! 422: { ! 423: sscanf(ptr,"%d",&tval); ! 424: if (tval >= 0 && tval <= 4) val = tval; ! 425: } ! 426: ! 427: [cornerView setState:val]; ! 428: [self setSleepCorner:val]; ! 429: ! 430: return self; ! 431: } ! 432: ! 433: ! 434: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.