This is ThinkMore.m in view mode; [Download] [Up]
#import "Thinker.h" #import "SpaceView.h" #import "BezierViewPart.h" #import "BackView.h" #import "BlackView.h" #import "Password.h" #import "psfuncts.h" #import "Localization.h" #import <appkit/NXColorWell.h> #import <appkit/Matrix.h> #import <appkit/graphics.h> #import <appkit/color.h> #import <appkit/defaults.h> #import <appkit/PopUpList.h> #import <appkit/MenuCell.h> #import <dpsclient/wraps.h> #import <objc/objc-runtime.h> #import <nextdev/evsio.h> #import <libc.h> #import <objc/List.h> #import <streams/streams.h> #import <objc/objc-load.h> #import "StringStorage.h" #import <sys/types.h> #import <stdlib.h> /* for getenv() */ #import <strings.h> /* for index() */ #import <sys/file.h> /* for access() */ #import <sys/param.h> /* for MAXPATHLEN */ #import <sys/dir.h> /* for opendir(), etc. */ #define VIEWDIRECTORY "/LocalLibrary/BackSpaceViews" StringStorage *viewNames; static char *compiledViewNames[] = { "Space", "Boink", "BoinkSpace", "Bezier", "Black", "FadingImage", "SlidingImage", "Sperm", }; #define COMVIEWCOUNT (sizeof(compiledViewNames)/sizeof(*compiledViewNames)) @implementation Thinker(thinkMore) - getBackgroundColor { float r, g, b; const char *ptr; NXColor theColor; ptr = NXGetDefaultValue([NXApp appName], "backgroundColor"); if (!ptr) { theColor = NXConvertGrayToColor(NX_DKGRAY); [myColorWell setColor:theColor]; return self; } sscanf(ptr,"%f %f %f",&r, &g, &b); if (r<0. || g<0. || b<0. || r>1. || g>1. || b>1.) return self; theColor = NXConvertRGBAToColor(r,g,b,1); [myColorWell setColor:theColor]; PSWorkspaceColor(r,g,b); return self; } - setBackgroundColor:sender; { float r,g,b; char str[120]; NXColor theColor = [sender color]; r = NXRedComponent(theColor); g = NXGreenComponent(theColor); b = NXBlueComponent(theColor); PSWorkspaceColor(r,g,b); sprintf(str,"%7.5f %7.5f %7.5f ", r,g,b); NXWriteDefault([NXApp appName], "backgroundColor", str); return self; } /** ** which-bin -- find the path for the named exectuable files ** ** Lennart <Lovstrand@EuroPARC.Xerox.COM>, September 1, 1991. ** slightly modified by sam 910902 **/ char * which_bin(const char *file) { DIR *dir; struct direct *de; static char buf[MAXPATHLEN]; char *paths, *p, *q; int filelen, dirlen; paths = getenv("PATH"); if (paths == NULL) return NULL; filelen = strlen(file); for (p = q = paths; *q != '\0'; p = q + 1) { q = index(p, ':'); if (q == NULL) q = p + strlen(p); dirlen = q - p; strncpy(buf, p, dirlen); buf[dirlen] = '\0'; dir = opendir(buf); if (dir == NULL) continue; buf[dirlen] = '/'; dirlen++; while ((de = readdir(dir)) != NULL) { if (de->d_namlen != filelen || strcmp(de->d_name, file) != 0) continue; strcpy(buf + dirlen, file); if (access(buf, X_OK) != 0) continue; closedir(dir); return buf; } closedir(dir); } return NULL; } void getAppDirectory (char *appDirectory) { char *suffix, *path; strcpy (appDirectory,NXArgv[0]); suffix = rindex(appDirectory,'/'); if (suffix != NULL) // explicit path { *suffix = '\0'; // remove executable name } else { path = which_bin([NXApp appName]); if (path != NULL) strcpy(appDirectory, path); else // Don't know where we came from -- arbitrarily // presume "." and continue (it's better than breaking) strcpy(appDirectory, "."); } } - getViewType { //must invoke this before creating window or setting up the views int i; const char *ptr; char launchdir[256]; viewNames = [[StringStorage alloc] init]; getAppDirectory (&launchdir[0]); [self loadViewsFrom: &launchdir[0]]; [self loadViewsFrom: VIEWDIRECTORY]; for (i = 0; i < COMVIEWCOUNT; i++) [viewNames addElement: compiledViewNames[i]]; [viewNames sort]; for (i = 0; i < [viewNames count]; i++) // could use addItem:, note that it adds items always at end [[viewSelectionButton target] insertItem: LocalString([viewNames elementAt: i], 0, 0) at: (i+1)]; [[viewSelectionButton target] setTarget:self]; [[viewSelectionButton target] setAction:@selector(selectRealViewIndex:)]; realViewIndex = 0; ptr = NXGetDefaultValue([NXApp appName], "viewType"); if (ptr) { for (i = 0; i < [viewNames count]; i++) if (strcmp(ptr, [viewNames elementAt: i]) == 0) { realViewIndex = i+1; break; } } [viewSelectionButton setTitle: (realViewIndex ? LocalString([viewNames elementAt: realViewIndex-1], 0, 0) : LocalString("All", 0, 0))]; return self; } - selectRealViewIndex:sender { //sender is the PopUpList's matrix int index = [sender selectedRow]; if (index == realViewIndex) return self; realViewIndex = index; [self setVirtualViewIndexAndIncrement:NO]; return self; } - setVirtualViewIndexAndIncrement:(BOOL)flag { id myView; if (realViewIndex) { virtualViewIndex = realViewIndex-1; [self selectScreenSaverViews]; } else { if (flag) { do { /* if (++virtualViewIndex >= [viewNames count]) virtualViewIndex = 0; */ /* NEW */ virtualViewIndex = random()%[viewNames count]; [self selectScreenSaverViews]; myView = [self bigView]; } while ([myView respondsTo:@selector(isBoringScreenSaver)] && [myView isBoringScreenSaver]); } else [self selectScreenSaverViews]; } return self; } - selectScreenSaverViews { id tnormalView; id bigWindow, tbigView; int myBacking; //need to order out big window if that's the type and buffering changed tnormalView = [self normalView]; tbigView = [self bigView]; myBacking = [self backingTypeForView:tnormalView]; [self createBigWindowIfNecessaryForView:tbigView]; if (myBacking == NX_BUFFERED) bigWindow = bigBufferedWindow; else bigWindow = bigUnbufferedWindow; [bigWindow setContentView:tbigView]; if (windowType == BACKWINDOW) { if (spaceWindow != bigWindow) { [spaceWindow orderOut:self]; [self useBackWindow:globalTier]; } } [normalWindow setContentView:tnormalView]; spaceView = [spaceWindow contentView]; if ([spaceView respondsTo:@selector(setImage:)]) [spaceView setImage: image]; if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow]; [self setWindowTitle]; NXWriteDefault([NXApp appName], "viewType", (realViewIndex ? ([viewNames elementAt: realViewIndex-1]) : "All")); if (windowType) { // the unbuffered window looks better if you just display // its contents, but for a buffered oneshot window, you must // display the window to make sure the window server window exists. if (myBacking == NX_BUFFERED) [spaceWindow display]; else { [spaceView fillBoundsWithBlack]; [spaceView display]; } } if (normalWindow && (windowType == NORMALWINDOW)) { if (myBacking == NX_BUFFERED) convertToBuffered([normalWindow windowNum]); else convertToRetained([normalWindow windowNum]); } return self; } - setWindowTitle { if ([spaceView respondsTo:@selector(windowTitle)]) { [normalWindow setTitle: LocalString([spaceView windowTitle],0,0)]; } else [normalWindow setTitle: LocalString("BackSpace",0,0)]; return self; } - getScreenLockerSetting { const char *ptr; [screenLocker setState:0]; ptr = NXGetDefaultValue([NXApp appName], "screenLocker"); if (!ptr || !strcmp(ptr,"Off")) [self setScreenLocker:NO andRemember:NO]; else [self setScreenLocker:YES andRemember:NO]; return self; } - changeScreenLockerSetting:sender { if (![password checkPassword: LocalString("Enter password to change screen lock setting:",0,0) randomPos:NO checkLock:NO withView:nil]) { [screenLocker setState:[password isLocked]]; return self; } if (![password validPassword] && ![password setPassword:self]) { [screenLocker setState:[password isLocked]]; return self; } [self setScreenLocker:([screenLocker state])andRemember:YES]; return self; } - setScreenLocker:(BOOL)val andRemember:(BOOL)rem { [screenLocker setState:val]; [password setLock: val]; if (rem) { if (val) NXWriteDefault([NXApp appName], "screenLocker", "On"); else NXRemoveDefault([NXApp appName], "screenLocker"); } return self; } //--------------------------------------------------- // View manager routines // This code uses List in kind of a gross way, // prefilling the List with self as a null entry // to indicate that instances of the View classes // haven't been created. // By the way, List and Storage both refuse to accept // nil as entry's - List won't store it and Storage // attempts to dereference it... //--------------------------------------------------- - createViewLists { int i; normalViewList = [[List allocFromZone:[self zone]] init]; bigViewList = [[List allocFromZone:[self zone]] init]; for (i=0; i< [viewNames count]; i++) { //this is ugly! Prime the Lists. wish I could store nil. [normalViewList insertObject:self at:i]; [bigViewList insertObject:self at:i]; } return self; } - normalView { return [self accessViewList:normalViewList]; } - bigView { return [self accessViewList:bigViewList]; } - accessViewList: (id) whichList { id theView; if ([whichList objectAt:virtualViewIndex] == self) { id myClass; char str[50]; const char *ptr; ptr = [viewNames elementAt: virtualViewIndex]; sprintf(str,"%sView", ptr); myClass = objc_getClass(str); theView = [[myClass allocFromZone:backZone] init]; if (theView) [whichList replaceObjectAt:(virtualViewIndex) with:theView]; } theView = [whichList objectAt:(virtualViewIndex)]; if (theView == self) theView = nil; return theView; } // // Dynamically load all object files found in the specified directory // // MEMO: Must make sure this doesn't screw up when it finds a new // object file with a class that's already loaded!!!! - loadViewsFrom: (const char *) dirname { DIR *dir; struct direct *de; NXStream *nxstderr; char path[MAXPATHLEN]; char *filenames[] = {path, NULL}; nxstderr = NXOpenFile(2, NX_WRITEONLY); dir = opendir(dirname); if (dir == NULL) { //perror(dirname); return self; } while ((de = readdir(dir)) != NULL) { int i, numstrings; BOOL ok; // Ignore '.'-files (not really necessary, I guess) if (de->d_name[0] == '.') continue; // Check that the file has the right extension if (de->d_namlen < 3 || strcmp(&de->d_name[de->d_namlen-2], ".o") != 0) continue; // refuse to load if the name matches a module already loaded numstrings = [viewNames count]; ok = YES; strcpy(path, de->d_name); *(rindex(path, 'V')) = '\0'; for (i=0; i< numstrings; i++) { if (!strcmp(path, [viewNames elementAt:i])) { ok = NO; break; } } if (!ok) continue; // OK, all is well -- go load the little bugger sprintf(path, "%s/%s", dirname, de->d_name); if (objc_loadModules(filenames, nxstderr, NULL, NULL, NULL) == 1) // Ugh, failed. Continue as usual. continue; // Smash out the 'V' in ".../FooView.o" *(rindex(path, 'V')) = '\0'; [viewNames addElement: rindex(path, '/') + 1]; } closedir(dir); NXClose(nxstderr); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.