|
|
1.1 ! root 1: // Thinspector.m ! 2: // ! 3: // contains more routines for the Thinker class, mostly related to ! 4: // BackSpace's inspectors. ! 5: // ! 6: // You may freely copy, distribute, and reuse the code in this example. ! 7: // NeXT disclaims any warranty of any kind, expressed or implied, as to its ! 8: // fitness for any particular use. ! 9: ! 10: #import "Thinker.h" ! 11: #import "BackWindow.h" ! 12: #import "BackView.h" ! 13: #import "SpaceView.h" ! 14: #import "MySlider.h" ! 15: #import "Password.h" ! 16: #import "psfuncts.h" ! 17: #import "ModuleList.h" ! 18: ! 19: ! 20: #import <appkit/appkit.h> ! 21: #import <objc/NXBundle.h> ! 22: #import <sys/dir.h> /* for opendir(), etc. */ ! 23: ! 24: ! 25: @implementation Thinker(inspector) ! 26: ! 27: - commonImageInspector ! 28: { ! 29: return commonImageInspector; ! 30: } ! 31: ! 32: - nullInspector ! 33: { ! 34: return nullInspector; ! 35: } ! 36: ! 37: - spaceInspector ! 38: { ! 39: return spaceInspector; ! 40: } ! 41: ! 42: - boinkInspector ! 43: { ! 44: return boinkInspector; ! 45: } ! 46: ! 47: - revertToDefaultImage:sender ! 48: { ! 49: [self setImageFromName: "defaultImage"]; ! 50: NXRemoveDefault([NXApp appName], "imageFile"); ! 51: return self; ! 52: } ! 53: ! 54: - (BOOL)browser:sender columnIsValid:(int)column ! 55: { ! 56: return browserValid; ! 57: } ! 58: ! 59: - addCellWithString:(const char *)str at:(int)row toMatrix:matrix ! 60: { ! 61: id theCell; ! 62: ! 63: [matrix insertRowAt:row]; ! 64: theCell = [matrix cellAt:row :0]; ! 65: [theCell setStringValue:str]; ! 66: [theCell setLoaded:YES]; ! 67: [theCell setLeaf:YES]; ! 68: return self; ! 69: } ! 70: ! 71: - (int)browser:sender fillMatrix:matrix inColumn:(int)column ! 72: { ! 73: const char *ptr; ! 74: int i; ! 75: ! 76: // this shouldn't happen... ! 77: if (browserValid) return [matrix cellCount]; ! 78: ! 79: [self addCellWithString:NXLocalString("All", 0, 0) ! 80: at:0 toMatrix:matrix]; ! 81: ! 82: for (i = 0; i < [moduleList count]; i++) ! 83: [self addCellWithString:NXLocalString([moduleList nameAt: i], 0, 0) ! 84: at:(i+1) toMatrix:matrix]; ! 85: ! 86: realViewIndex = 0; ! 87: ! 88: ptr = NXGetDefaultValue([NXApp appName], "viewType"); ! 89: if (ptr) ! 90: { ! 91: for (i = 0; i < [moduleList count]; i++) ! 92: if (strcmp(ptr, [moduleList nameAt: i]) == 0) ! 93: { ! 94: realViewIndex = i+1; ! 95: break; ! 96: } ! 97: } ! 98: ! 99: browserValid = YES; ! 100: return [matrix cellCount]; ! 101: } ! 102: ! 103: ! 104: // Dynamically load all object files found in the specified directory ! 105: // if we find a module in several places, we save the additional paths ! 106: // in case they point to modules for different architectures ! 107: ! 108: - loadViewsFrom: (const char *) dirname ! 109: { ! 110: DIR *dir; ! 111: struct direct *de; ! 112: char path[MAXPATHLEN]; ! 113: char name[60]; ! 114: char *iptr; ! 115: ModuleInfo *m; ! 116: BOOL validName, filePackage; ! 117: ! 118: ! 119: dir = opendir(dirname); ! 120: if (dir == NULL) { ! 121: //perror(dirname); ! 122: return self; ! 123: } ! 124: ! 125: while ((de = readdir(dir)) != NULL) ! 126: { ! 127: int i, numstrings; ! 128: ! 129: // Ignore '.'-files (not really necessary, I guess) ! 130: if (de->d_name[0] == '.') ! 131: continue; ! 132: ! 133: filePackage = validName = NO; ! 134: if (de->d_namlen > 10 && ! 135: !strcmp(&de->d_name[de->d_namlen-10], "View.BackO")) ! 136: { ! 137: validName = YES; ! 138: filePackage = NO; ! 139: } ! 140: else if (de->d_namlen > 15 && ! 141: !strcmp(&de->d_name[de->d_namlen-15], "View.BackModule")) ! 142: { ! 143: validName = YES; ! 144: filePackage = YES; ! 145: } ! 146: ! 147: if (!validName) continue; ! 148: ! 149: ! 150: // refuse to load if the name matches a module already loaded ! 151: numstrings = [moduleList count]; ! 152: strcpy(name, de->d_name); ! 153: ! 154: // Smash out the 'V' in "FooView.BackO" ! 155: if (iptr = rindex(name, 'V')) ! 156: *iptr = '\0'; ! 157: ! 158: for (i=0; i< numstrings; i++) ! 159: { ! 160: if (!strcmp(name, [moduleList nameAt:i])) ! 161: { ! 162: // we already have a module with this name, but will save the path anyway ! 163: validName = NO; ! 164: if (filePackage) sprintf(path,"%s/%sView.BackModule",dirname,name); ! 165: else strcpy(path, dirname); ! 166: [[moduleList objectAt:i] appendPath:path]; ! 167: break; ! 168: } ! 169: } ! 170: if (!validName) continue; ! 171: ! 172: // I used to load the class at this time; this got horribly ! 173: // inefficient. I now wait until I'm about to instantiate ! 174: // a view before doing this (thanx bbum!) ! 175: ! 176: if (filePackage) sprintf(path,"%s/%sView.BackModule",dirname,name); ! 177: else strcpy(path, dirname); ! 178: ! 179: m = [[ModuleInfo alloc] ! 180: initWithView:NULL name:name path:path]; ! 181: [moduleList addObject: m]; ! 182: } ! 183: ! 184: closedir(dir); ! 185: ! 186: return self; ! 187: } ! 188: ! 189: - (BOOL)appAcceptsAnotherFile:sender ! 190: { ! 191: // return openAnother; ! 192: // if I just return openAnother, I fail to open the module if ! 193: // I get launched to do it. Punt until I think of a better solution. ! 194: return YES; ! 195: } ! 196: ! 197: - (int)app:sender openFile:(const char *)filename type:(const char *)aType ! 198: { ! 199: // Here we have caught BackSpace off guard; Speaker says open a file, ! 200: // but BackSpace is already locked on a view because it doesn't unlock ! 201: // focus or bail out of the event loop unless there's an event. ! 202: // This is good for performance but it means it handles openfile badly; ! 203: // it must post an event telling it to bail out of the event loop and ! 204: // open the file later; multi file opens are therefore broken, and ! 205: // the return value here is bogus... ! 206: ! 207: char path[MAXPATHLEN]; ! 208: NXEvent anEvent; ! 209: char *iptr; ! 210: ! 211: if (fileToOpen) ! 212: { free(fileToOpen); ! 213: fileToOpen = NULL; ! 214: } ! 215: ! 216: strcpy(path,filename); ! 217: ! 218: if (!strcmp(aType,"BackModule")) ! 219: { ! 220: iptr = rindex(filename, '/'); ! 221: strcat(path,iptr); // /xxx/fooView.BackModule/fooView.BackModule ! 222: iptr = rindex(path, 'M'); ! 223: strcat(iptr,"O"); // /xxx/fooView.BackModule/fooView.BackO ! 224: } ! 225: ! 226: fileToOpen = NXCopyStringBuffer(path); ! 227: openAnother = NO; ! 228: ! 229: anEvent.type = NX_APPDEFINED; ! 230: anEvent.data.compound.subtype = BSOPENFILE; ! 231: anEvent.ctxt = [NXApp context]; ! 232: DPSPostEvent(&anEvent,0); ! 233: return YES; ! 234: } ! 235: ! 236: - doDelayedOpenFile ! 237: { ! 238: int i, numstrings; ! 239: int ret = YES; ! 240: char path[MAXPATHLEN]; ! 241: id theMatrix; ! 242: char *name; ! 243: char *iptr; ! 244: ModuleInfo *m; ! 245: ! 246: numstrings = [moduleList count]; ! 247: strcpy(path, fileToOpen); ! 248: ! 249: if ((name = rindex(path, '/')) != NULL) ! 250: *name = '\0'; ! 251: name++; ! 252: ! 253: // Smash out the 'V' in "FooView.BackO" ! 254: if ((iptr = rindex(name, 'V')) != NULL) ! 255: *iptr = '\0'; ! 256: ! 257: for (i=0; i< numstrings; i++) ! 258: { ! 259: if (!strcmp(name, [moduleList nameAt:i])) ! 260: { ret = NO; ! 261: break; ! 262: } ! 263: } ! 264: ! 265: if (ret) ! 266: { ! 267: m = [[ModuleInfo alloc] ! 268: initWithView:NULL name:name path:path]; ! 269: [moduleList addObject: m]; ! 270: ! 271: browserValid = NO; ! 272: [moduleList sort]; ! 273: ! 274: [viewSelectionBrowser loadColumnZero]; ! 275: } ! 276: ! 277: theMatrix = [viewSelectionBrowser matrixInColumn:0]; ! 278: numstrings = [moduleList count]; ! 279: for (i=0; i< numstrings; i++) ! 280: { ! 281: if (!strcmp(name, [moduleList nameAt:i])) ! 282: break; ! 283: } ! 284: realViewIndex = i+1; ! 285: ! 286: [theMatrix selectCellAt:realViewIndex :0]; ! 287: [theMatrix scrollCellToVisible:realViewIndex :0]; ! 288: [viewSelectionBrowser display]; ! 289: ! 290: [self setVirtualViewIndexAndIncrement:NO]; ! 291: ! 292: free(fileToOpen); ! 293: fileToOpen = NULL; ! 294: openAnother = YES; ! 295: ! 296: return self; ! 297: } ! 298: ! 299: ! 300: extern const char *appDirectory(); ! 301: - (const char *) appDirectory ! 302: { ! 303: return appDirectory(); ! 304: } ! 305: ! 306: - (const char *) moduleDirectory:(const char *)name ! 307: { ! 308: int i, numstrings; ! 309: ! 310: numstrings = [moduleList count]; ! 311: for (i=0; i< numstrings; i++) ! 312: { ! 313: if (!strcmp(name, [moduleList nameAt:i])) ! 314: return [[moduleList objectAt:i] path]; ! 315: } ! 316: return NULL; ! 317: } ! 318: ! 319: - (struct mach_header *) headerForModule:(const char *)name ! 320: { ! 321: int i, numstrings; ! 322: ! 323: numstrings = [moduleList count]; ! 324: for (i=0; i< numstrings; i++) ! 325: { ! 326: if (!strcmp(name, [moduleList nameAt:i])) ! 327: return [[moduleList objectAt:i] header]; ! 328: } ! 329: return NULL; ! 330: } ! 331: ! 332: ! 333: ! 334: ! 335: static char *launchDir = NULL; /* if this is NULL, it will be calculated */ ! 336: ! 337: /** ! 338: ** which-dir -- find the path for the named exectuable file ! 339: ** Returns malloc'd string if it finds it, or NULL if it can't ! 340: ** ! 341: ** borrowed from Lennart, munged by sam ! 342: **/ ! 343: ! 344: const char *which_dir(const char *file) ! 345: { ! 346: char buf[MAXPATHLEN]; ! 347: char *paths, *p, *q; ! 348: char *ret; ! 349: int dirlen; ! 350: ! 351: paths = getenv("PATH"); ! 352: if (paths == NULL) return NULL; ! 353: ! 354: for (p = q = paths; *q != '\0'; p = q + 1) ! 355: { ! 356: q = index(p, ':'); ! 357: if (q == NULL) q = p + strlen(p); ! 358: ! 359: dirlen = q - p; ! 360: ! 361: sprintf(buf, "%.*s/%s", dirlen, p, file); ! 362: if (access(buf, X_OK) != 0) continue; ! 363: ! 364: buf[dirlen] = '\0'; ! 365: ret = malloc((dirlen+1)*sizeof(char)); ! 366: strcpy(ret,buf); ! 367: return ret; ! 368: } ! 369: return NULL; ! 370: } ! 371: ! 372: const char *appDirectory() ! 373: { ! 374: char buf[MAXPATHLEN]; ! 375: char *suffix, *path; ! 376: ! 377: if (launchDir) return launchDir; ! 378: ! 379: strcpy (buf,NXArgv[0]); ! 380: suffix = rindex(buf,'/'); ! 381: if (suffix != NULL) // explicit path ! 382: { ! 383: *suffix = '\0'; // remove executable name ! 384: } ! 385: else ! 386: { ! 387: path = (char *)which_dir([NXApp appName]); ! 388: if (path != NULL) ! 389: { ! 390: launchDir = path; ! 391: return launchDir; ! 392: } ! 393: else ! 394: { ! 395: // Don't know where we came from -- arbitrarily ! 396: // presume "." and continue (it's better than breaking) ! 397: strcpy(buf, "."); ! 398: } ! 399: } ! 400: ! 401: launchDir = malloc((strlen(buf)+1)*sizeof(char)); ! 402: strcpy(launchDir,buf); ! 403: return launchDir; ! 404: } ! 405: ! 406: @end ! 407:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.