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