|
|
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.