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