CCL Home Page
Up Directory CCL ScianWindows
/*ScianWindows.c
  Eric Pepke
  March 8, 1990
  Window handling routines in Scian
*/

#include "Scian.h"
#include "ScianTypes.h"
#include "ScianWindows.h"
#include "ScianVisWindows.h"
#include "ScianLists.h"
#include "ScianEvents.h"
#include "ScianColors.h"
#include "ScianErrors.h"
#include "ScianIDs.h"
#include "ScianScripts.h"
#include "ScianTextBoxes.h"
#include "ScianFileSystem.h"
#include "ScianPreferences.h"
#include "ScianDatasets.h"
#include "ScianHelp.h"
#include "ScianDialogs.h"
#include "ScianArrays.h"
#include "ScianFiles.h"
#include "ScianFontSystem.h"
#include "ScianSockets.h"
#include "ScianDraw.h"
#include "ScianObjFunctions.h"
#include "ScianStyle.h"
#include "ScianErrors.h"
#include "ScianRecorders.h"
#include "ScianAnimation.h"
#include "ScianSymbols.h"
#include "ScianDatabase.h"

#define MINCMAPBITPLANES 9

int windowSystem = 0;			/*Window system currently in use*/
int updateBatch = 0;			/*Current batch of updates*/
WinInfoPtr allWindows = 0;		/*Window info on all windows*/
static short firstTime = 1;		/*First time a new window is made*/
int curDisplayMode;			/*Current display mode*/
Bool rgbp;				/*True iff in rgb mode*/
extern Bool phsco;			/*Phscologram mode*/
WinInfoPtr selWinInfo;			/*Info for currently selected window*/
ObjPtr windowClass = 0;			/*Window class*/
short curCursor = 0;			/*Current cursor*/
ObjPtr clipboard;			/*Clipboard*/
WinInfoPtr inputWindow = 0;		/*Current window for input or 0*/

Bool hasRGB;				/*True iff has RGB*/
Bool hasCmap;				/*True iff has color map mode*/
Bool hasRGBDouble;			/*True iff has RGB double buffer mode*/
Bool hasCmapDouble;			/*True iff has RGB double buffer mode*/
Bool hasZbuf;				/*True iff has z buffer mode*/
Bool hasTransparency;			/*True iff has transparency*/
Bool hasTwoSided;			/*True iff has two-sided hardware lighting*/
int nOverDrawPlanes;			/*True iff has overdraw planes*/
Bool pupForOverDraw;			/*True iff popup planes used for over draw*/
Bool rgbGoodForUI;			/*True iff rgb mode is good for UI*/
int scrWidth = 1280, scrHeight = 1024;	/*Width and height of screen, changed by GetConfiguration*/
int cmapBitPlanes = 0;			/*# color map bit planes*/
int rBitPlanes = 0, gBitPlanes = 0, bBitPlanes = 0;
					/*r, g, b bit planes*/
Bool scavengeColors;			/*True iff scavenge colors*/
Bool showConfig;			/*True iff want to show configuration*/
Bool hasDithering;			/*True iff has dithering*/
Bool hasAntialiasedLines;		/*True iff has anti-aliased lines*/
Bool hasAntialiasedPoints;		/*True iff has anti-aliased points*/
Bool hasDepthCue;			/*True iff system has depth cueing*/
Bool hasStereo;				/*True iff system has stereo*/

int drawingQuality = DQ_FULL;   	/*The current drawing quality*/

#define STAGOVERX	100		/*X over for staggering*/
#define STAGDOWNY	100		/*Y down for staggering*/
#define STAGSTEP	40		/*Step for staggering*/
#define STAGMAX		200		/*Maximum staggering*/

int stagger = 0;			/*Current staggering amount*/

WinInfoPtr WhichWindow(x, y)
int x, y;
/*Returns which window x, y is in.  Messes up selected window*/
{
    WinInfoPtr retVal = 0;
#ifdef INTERACTIVE
#ifdef WINDOWS4D
    long minDepth;
    Bool first = true;
    WinInfoPtr curWindow;

    curWindow = allWindows;
    while (curWindow)
    {
	if (curWindow -> id && (0 == (curWindow -> flags & WINICONIFIED)))
	{
	    long depth;

	    /*It's a valid candidate*/
	    depth = windepth(curWindow -> id);
	    if (first || (depth < minDepth))
	    {
		long ox, oy, sx, sy;

		SelWindow(curWindow);
		getorigin(&ox, &oy);
		getsize(&sx, &sy);

		if (x >= ox && x <= ox + sx &&
		    y >= oy && y <= oy + sy)
		{
		    /*Hey, it's in there!*/
		    retVal = curWindow;
		    minDepth = depth;
		    first = false;
		}
	    }
	}
	curWindow = curWindow -> next;
    }
#endif
#endif
    return retVal;
}

WinInfoPtr TopWindow()
/*Returns the top window.*/
{
    WinInfoPtr retVal = 0;
#ifdef INTERACTIVE
#ifdef WINDOWS4D
    long minDepth;
    Bool first = true;
    WinInfoPtr curWindow;

    curWindow = allWindows;
    while (curWindow)
    {
	if (curWindow -> id)
	{
	    long depth;

	    /*It's a valid candidate*/
	    depth = windepth(curWindow -> id);
	    if (first || (depth < minDepth))
	    {
		retVal = curWindow;
		minDepth = depth;
		first = false;
	    }
	}
	curWindow = curWindow -> next;
    }
#endif
#endif
    return retVal;
}

WinInfoPtr BottomWindow()
/*Returns the bottom window.*/
{
    WinInfoPtr retVal = 0;
#ifdef INTERACTIVE
#ifdef WINDOWS4D
    long maxDepth;
    Bool first = true;
    WinInfoPtr curWindow;

    curWindow = allWindows;
    while (curWindow)
    {
	if (curWindow -> id)
	{
	    long depth;

	    /*It's a valid candidate*/
	    depth = windepth(curWindow -> id);
	    if (first || (depth > maxDepth))
	    {
		retVal = curWindow;
		maxDepth = depth;
		first = false;
	    }
	}
	curWindow = curWindow -> next;
    }
#endif
#endif
    return retVal;
}

#ifdef HAVE_PROTOTYPES
Bool BelowAllBut(WinInfoPtr window1, WinInfoPtr window2)
#else
Bool BelowAllBut(window1, window2)
WinInfoPtr window1, window2;
#endif
/*Returns true iff window1 is below all windows but window2 excluding
  subwindows.*/
{
#ifdef INTERACTIVE
#ifdef WINDOWS4D
    int targetDepth;
    WinInfoPtr curWindow;

    /*Get target depth of window1*/
    if (!window1 -> id) return false;
    targetDepth = windepth(window1 -> id);

    /*Go through all windows*/
    curWindow = allWindows;
    while (curWindow)
    {
	if (curWindow -> id && !(GetVar((ObjPtr) curWindow, SUPERWINDOW))
	    && curWindow != window2)
	{
	    long depth;

	    /*It's a valid candidate*/
	    depth = windepth(curWindow -> id);
	    if (depth > targetDepth)
	    {
		return false;
	    }
	}
	curWindow = curWindow -> next;
    }
    return true;

#endif
#else
    return false;
#endif
}

#ifdef HAVE_PROTOTYPES
Bool AboveAllMainWindows(WinInfoPtr window1)
#else
Bool AboveAllMainWindows(window1)
WinInfoPtr window1;
#endif
/*Returns true iff window1 is above all windows excluding
  subwindows.*/
{
#ifdef INTERACTIVE
#ifdef WINDOWS4D
    int targetDepth;
    WinInfoPtr curWindow;

    /*Get target depth of window1*/
    if (!window1 -> id) return false;
    targetDepth = windepth(window1 -> id);

    /*Go through all windows*/
    curWindow = allWindows;
    while (curWindow)
    {
	if (curWindow -> id && !(GetVar((ObjPtr) curWindow, SUPERWINDOW)))
	{
	    long depth;

	    /*It's a valid candidate*/
	    depth = windepth(curWindow -> id);
	    if (depth < targetDepth)
	    {
		return false;
	    }
	}
	curWindow = curWindow -> next;
    }
    return true;

#endif
#else
    return false;
#endif
}

#ifndef SelWindow
#ifdef HAVE_PROTOTYPES
void SelWindow(WinInfoPtr w)
#else
void SelWindow(w)
WinInfoPtr w;
#endif
/*Procedure version of SelWindow, useful for debugging*/
{
#if 0
    if (w) 
	printf("SelWindow %s\n", w -> winTitle); 
    else printf("SelWindow null\n");
#endif
    selWinInfo = w; 
    if (w && ((WinInfoPtr) w) -> id) {winset(((WinInfoPtr) w) -> id);\
		curDisplayMode = getdisplaymode();\
		rgbp = (curDisplayMode == DMSINGLE || curDisplayMode == DMDOUBLE) ? false : true;}
}
#endif

#ifdef HAVE_PROTOTYPES
void SetWindowPosition(int l, int r, int b, int t)
#else
void SetWindowPosition(l, r, b, t)
int l, r, b, t;
#endif
/*Sets the position of the selected window to l, r, b, t in
  between pixel coordinates*/
{
#ifdef INTERACTIVE
#ifdef WINDOWS4D
    if (selWinInfo -> flags & WINFIXEDSIZE)
    {
	minsize((long) r - l, (long) t - b);
	maxsize((long) r - l, (long) t - b);
	winconstraints();
    }
    winposition((long) l, (long) r - 1, (long) b, (long) t - 1);
#endif
#endif
}

#ifdef HAVE_PROTOTYPES
void GetWindowBounds(int *l, int *r, int *b, int *t)
#else
void GetWindowBounds(l, r, b, t)
int *l, *r, *b, *t;
#endif
/*Gets the bounds of the current window into l, r, b, t.
  These are "between the pixels" coordinates*/
{
#ifdef WINDOWS4D
    long w, h;
    getsize(&w, &h);
    *l = 0;
    *r = w;
    *b = 0;
    *t = h;
#else
    *l = 0;
    *r = 10;
    *b = 0;
    *t = 10;
#endif
}

void PrintWindowBounds()
{
    int l, r, b, t;
    GetWindowBounds(&l, &r, &b, &t);
    printf("%d %d %d %d\n", l, r, b, t);
}

#ifdef HAVE_PROTOTYPES
void GetWindowOrigin(int *x, int *y)
#else
void GetWindowOrigin(x, y)
int *x, *y;
#endif
/*Gets the origin of the current window*/
{
#ifdef WINDOWS4D
    long lx, ly;
    if (fullScreen)
    {
	*x = 0;
	*y = 0;
    }
    else
    {
	getorigin(&lx, &ly);
	*x = lx;
	*y = ly;
    }
#else
    *x = 0;
    *y = 0;
#endif
}

static ObjPtr OpenWindowManually(window)
WinInfoPtr window;
/*Asks the user to open the window manually*/
{
    WinInfoPtr alertWindow;
    char message[400];

    sprintf(message, "Window '%s' has been turned into an icon.  To continue, first \
dismiss this dialog and then click on the window icon with the left mouse button.", window -> winTitle);

    alertWindow = AlertUser(UIERRORALERT, (WinInfoPtr) 0, message,
	    0, 0, "OK");
    SetVar((ObjPtr) alertWindow, INHIBITLOGGING, ObjTrue);
}

void PushWindow(winInfo)
WinInfoPtr winInfo;
/*Pushes winInfo*/
{
#ifdef GRAPHICS
#ifdef WINDOWS4D
    if (winInfo -> id)
    {
	SelWindow(winInfo);
	winpush();
	Log("pushwindow\n");
    }
#endif
#endif
}

#ifdef HAVE_PROTOTYPES
void CEWS(WinInfoPtr window, int sizeX, int sizeY)
#else
void CEWS(window, sizeX, sizeY)
WinInfoPtr window; int sizeX; int sizeY;
#endif
/*Says to a newly created window that the contents expect a certain window
  size*/
{
    Event event;

    if (window -> nr != window -> nl + sizeX ||
	window -> nt != window -> nb + sizeY)
    {
	event . type = ET_RESHAPE_WINDOW;
	event . flags = 0;
	event . data . window = window;
	window -> nr = window -> nl + sizeX;
	window -> nt = window -> nb + sizeY;
	PostEvent(&event);
    }
}

void PopWindow(winInfo)
WinInfoPtr winInfo;
/*Pops winInfo*/
{
    if (winInfo -> id)
    {
#ifdef GRAPHICS
#ifdef WINDOWS4D
	SelWindow(winInfo);
	winpop();
	if (winInfo -> flags & WINICONIFIED)
	{
	    DeferMessage((ObjPtr) winInfo, OPENMANUALLY);
	}
#endif
#endif
    }
    else
    {
#ifdef WINDOWS4D
	if (windowSystem == WS_GLWINDOWS)
	{
	    winInfo -> id = NewGLWindow(winInfo -> winTitle,
					winInfo -> minWidth,
					winInfo -> minHeight,
					winInfo -> maxWidth,
					winInfo -> maxHeight,
					winInfo -> flags);
	}
	else
#endif
	{
	    winInfo -> id = 0;
	}
	CEWS(winInfo, winInfo -> minWidth, winInfo -> minHeight);
	SetWindowMode(winInfo);
	ImInvalid((ObjPtr) winInfo);
    }
}

#ifdef HAVE_PROTOTYPES
void CloseWindow(WinInfoPtr window)
#else
void CloseWindow(window)
WinInfoPtr window;
#endif
/*Closes window*/
{
    ObjPtr var;

    SelWindow(window);

    Log("close\n");

    while (var = GetVar((ObjPtr) window, SUPERWINDOW))
    {
	window = (WinInfoPtr) var;
    }

    DeferMessage((ObjPtr) window, DISPOSE);
    var = GetVar((ObjPtr) window, SUBWINDOWS);
    if (var)
    {
	ThingListPtr runner;
	runner = LISTOF(var);
	while (runner)
	{
	    DeferMessage(runner -> thing, DISPOSE);
	    runner = runner -> next;
	}
    }
}

void DoShowFrame()
/*Shows the window frame*/
{
#ifndef NOHIDEFRAME
    if (selWinInfo)
    {
	DeferMessage((ObjPtr) selWinInfo, SHOWFRAME);
    }
#endif
}

void DoHideFrame()
/*Hides the window frame*/
{
#ifndef NOHIDEFRAME
    if (selWinInfo)
    {
	DeferMessage((ObjPtr) selWinInfo, HIDEFRAME);
    }
#endif
}

void DrawWindowInfo(theWindow)
WinInfoPtr theWindow;
/*Draws the window based on WinInfoPtr theWindow into the current set window.
  This is the fundamental window drawing routine.*/
{
    OptimizeSharpness();

    DrawObject((ObjPtr) theWindow);
}

void SaveScreen(window, flags)
WinInfoPtr window;
int flags;
/*Saves a screen*/
{
#ifdef GRAPHICS
    long l, r, b, t;
    int k;
    ObjPtr allRecorders, keyList, var;

    keyList = NewList();
    PostfixList(keyList, NewSymbol(CLASSID));
    PostfixList(keyList, NewInt(CLASS_RECORDER));
    PostfixList(keyList, NewSymbol(NAME));
    if (GetPrefInteger(PREF_SAVESCREEN))
    {
	PostfixList(keyList, NewString("PostScript"));
    }
    else
    {
	PostfixList(keyList, NewString("scrsave"));
    }

    allRecorders = SearchDatabase(keyList);
    if (allRecorders && LISTOF(allRecorders))
    {
	/*There is a recorder to save*/
	ObjPtr recorder, lastRecorder;
	Bool oldRecordEnabled;

	recorder = LISTOF(allRecorders) -> thing;

	if (flags & F_OPTIONDOWN)
	{
	    /*Save entire screen*/
	    SetVar(recorder, FRAMEOX, NewInt(0));
	    SetVar(recorder, FRAMEOY, NewInt(0));
	    SetVar(recorder, FRAMEWIDTH, NewInt(SCRWIDTH));
	    SetVar(recorder, FRAMEHEIGHT, NewInt(SCRHEIGHT));
	}
	else if (flags & F_SHIFTDOWN)
	{
	    /*Save with window border*/
	    SetVar(recorder, SAVEWINDOWFRAME, ObjTrue);
	    AdjustToCurWindow(recorder);
	}
	else
	{
	    /*Normal save of window interior*/
	    AdjustToCurWindow(recorder);
	}

	/*Now do it*/
	lastRecorder = curRecorder;
	oldRecordEnabled = recordEnabled;
	recordEnabled = true;
	curRecorder = recorder;
	if (ConnectRecorder())
	{
	    if (PrepareToRecord(1))
	    {
		SnapOneFrame();
		StopRecording();
		DisconnectRecorder();

		var = GetVar(recorder, FILENAME);
		if (var)
		{
		    WinInfoPtr alert;

		    sprintf(tempStr, "The image was saved in file %s", GetString(var));

		    alert = AlertUser(UIINFOALERT, (WinInfoPtr) 0, tempStr,
				(FuncTyp) 0, 0);
		    SetVar((ObjPtr) alert, INHIBITLOGGING, ObjTrue);
		}
	    }
	    else
	    {
		WarnUser(CW_SCREENSAVEERROR);
	    }
	}
	else
	{
	    WarnUser(CW_SCREENSAVEERROR);
	}
	curRecorder = lastRecorder;
	recordEnabled = oldRecordEnabled;

	SetVar(recorder, SAVEWINDOWFRAME, ObjFalse);
    }
    else
    {
	WarnUser(CW_NOSCREENSAVER);
    }
#endif
}

void PopDatasetsWindow(void)
{
    Log("show datasets\n");
    InhibitLogging(true);
    PopWindow(DatasetsWindow());
    InhibitLogging(false);
}

void PopFileReadersWindow(void)
{
    Log("show filereaders\n");
    InhibitLogging(true);
    PopWindow(FileReadersWindow());
    InhibitLogging(false);
}

void PopRecorderDriversWindow(void)
{
    Log("show recorders\n");
    InhibitLogging(true);
    PopWindow(RecorderDriversWindow());
    InhibitLogging(false);
}

#ifdef HAVE_PROTOTYPES
void ToClipboard(ObjPtr object)
#else
void ToClipboard(object)
ObjPtr object;
#endif
/*Move object to the clipboard*/
{
    ObjPtr *elements;
    elements = ELEMENTS(clipboard);
    elements[0] = object;
}

#ifdef HAVE_PROTOTYPES
ObjPtr FromClipboard(void)
#else
ObjPtr FromClipboard()
#endif
/*Return object from the clipboard*/
{
    ObjPtr *elements;
    elements = ELEMENTS(clipboard);
    return elements[0];
}

#ifdef HAVE_PROTOTYPES
void CutText(void)
#else
void CutText()
#endif
/*Cuts text*/
{
    if (selWinInfo)
    {
	ObjPtr current;
	current = GetVar((ObjPtr) selWinInfo, CURRENT);
	if (current)
	{
	    FuncTyp method;
	    method = GetMethod(current, CUT);
	    if (method)
	    {
		(*method)(current);
	    }
	}
    }
}

void CopyText(void)
/*Cuts text*/
{
    if (selWinInfo)
    {
	ObjPtr current;
	current = GetVar((ObjPtr) selWinInfo, CURRENT);
	if (current)
	{
	    FuncTyp method;
	    method = GetMethod(current, COPY);
	    if (method)
	    {
		(*method)(current);
	    }
	}
    }
}

#ifdef HAVE_PROTOTYPES
void PasteError(ObjPtr object, ObjPtr value)
#else
void PasteError(object, value)
ObjPtr object;
ObjPtr value;
#endif
/*Makes an error pasting*/
{
#ifdef GRAPHICS
    ringbell();
#endif
}

void PasteText(void)
/*Cuts text*/
{
    if (selWinInfo)
    {
	ObjPtr current;
	current = GetVar((ObjPtr) selWinInfo, CURRENT);
	if (current)
	{
	    FuncTyp method;
	    method = GetMethod(current, PASTE);
	    if (method)
	    {
		(*method)(current);
	    }
	}
    }
}

void DoUndoReshape()
/*Undoes a reshape of the window*/
{
#ifdef GRAPHICS
#ifdef WINDOWS4D
    if (selWinInfo)
    {
	SetWindowPosition(selWinInfo -> ol, selWinInfo -> or, selWinInfo -> ob, selWinInfo -> ot);
    }
#endif
#endif
}

void DoClose()
/*Closes the current window*/
{
    if (selWinInfo && selWinInfo -> id)
    {
	CloseWindow(selWinInfo);
    }
}

void DoSaveScreen()
/*Saves the entire screen*/
{
    SaveScreen(selWinInfo, F_OPTIONDOWN);
}

void DoSaveWindow()
/*Saves just a window*/
{
    SaveScreen(selWinInfo, 0);
}

static ObjPtr SaveFullScreen(win)
ObjPtr win;
/*Saves the entire screen*/
{
    SaveScreen(selWinInfo, F_OPTIONDOWN);
    return ObjTrue;
}

static ObjPtr SaveWindow()
/*Saves just a window*/
{
    SaveScreen(selWinInfo, 0);
    return ObjTrue;
}

static ObjPtr SaveFWindow()
/*Saves just a window*/
{
    SaveScreen(selWinInfo, F_SHIFTDOWN);
    return ObjTrue;
}

void DropCursorInWindows()
/*Drops the cursor in all the windows*/
{
#ifdef GRAPHICS
#ifdef CURSORS4D
	WinInfoPtr curWindow;

	curWindow = allWindows;
	while (curWindow)
	{
	    if (curWindow -> id)
	    {
		SetDrawingWindow(curWindow);

		if (curCursor < 0)
		{
		    cursoff();
		}
		else
		{
		    curson();
		    setcursor(curCursor, (Colorindex) 1, (Colorindex) 0);
		}
		RestoreDrawingWindow();
	    }
	    curWindow = curWindow -> next;
	}
#endif
#endif
}

void MySetCursor(cursorNumber)
int cursorNumber;
/*Sets the cursor to cursorNumber*/
{
#ifdef GRAPHICS
    if (cursorNumber != curCursor)
    {
	curCursor = cursorNumber;

	DropCursorInWindows();
    }
#endif
}

#ifdef WINDOWS4D
#ifdef HAVE_PROTOTYPES
WindowID NewGLWindow(char *title, int minWidth, int minHeight, int maxWidth, int maxHeight, long flags)
#else
WindowID NewGLWindow(title, minWidth, minHeight, maxWidth, maxHeight, flags)
char *title;
int minWidth, minHeight, maxWidth, maxHeight;
long flags;
#endif
/*Creates a new GL window with title, and size determined by minWidth,
  minHeight, maxWidth, and maxHeight and returns a window ID which will
  differ from machine to machine.*/
{
    WindowID retVal = 0;
    long ox, oy;
    Bool gottaSetMinMax = false;

    /*Set up initial parameters for window*/

    if (windowSystem == WS_GLWINDOWS)
    {
	/*No border if it can be done and the window wants it*/
#ifndef NOHIDEFRAME
	if (flags & WINNOFRAME)
	{
	    noborder();
	}
#endif
    
	/*Set its position, etc.*/
	if (flags & WINCENTERED)
	{
	    /*Center using minimum size around center of screen*/
	    ox = scrWidth / 2 - minWidth / 2;
	    oy = scrHeight / 2 - minHeight / 2;
	    prefposition(ox, ox + minWidth - 1, oy, oy + minHeight - 1);
	}
	else if (flags & WINFIXEDLOC)
	{
	    /*Fixed location.  Use max as origin*/
	    prefposition(maxWidth, minWidth + maxWidth - 1,
			 maxHeight, minHeight + maxHeight - 1);
	}
	else
	{
	    /*Free window*/
	    if (runningScript || runningRemote || GetPrefTruth(PREF_NEWWINPLACE))
	    {
		/*Place in fixed position*/
		ox = STAGOVERX + stagger;
		oy = scrHeight - STAGDOWNY - stagger;
		prefposition(ox, ox + minWidth - 1, oy - minHeight + 1, oy);
		stagger += STAGSTEP;
		if (stagger > STAGMAX) stagger = 0;
		gottaSetMinMax = true;
	    }
	    else
	    {
#ifdef INTERACTIVE
		/*Wait for mouse to come up*/
		while (getbutton(MOUSE1) || getbutton(MOUSE2) || getbutton(MOUSE3));
#endif
		minsize(minWidth, minHeight);
		maxsize(maxWidth, maxHeight);
	    }
	}
    
	/*Create the window*/
	retVal = winopen(title);
	wintitle(title);
    
	/*Set up the default characteristics*/
	winset(retVal);
    
	if (gottaSetMinMax)
	{
	    minsize(minWidth, minHeight);
	    maxsize(maxWidth, maxHeight);
	    winconstraints();
	}
    
#ifdef GL4D
#ifdef GLC_OLDPOLYGON
	glcompat(GLC_OLDPOLYGON, FALSE);
#endif
#ifdef GLC_ZRANGEMAP
	glcompat(GLC_ZRANGEMAP, TRUE);
#endif
#endif
	if (AreFlagsDoubleBuf(flags))
	{
	    doublebuffer();
	}
	else
	{
	    singlebuffer();
	}
	if (nOverDrawPlanes && pupForOverDraw == false)
	{
	    overlay(2);
	}
#if 0
	zbsize(24);
#endif
	gconfig();
    
	/*Now that we've made the first window, it's safe to initialize the rest*/
	InitStuff();
    
	return retVal;
    }
    else
    {
	return 0;
    }
}
#endif

void SetMinSize(winInfo, mw, mh)
WinInfoPtr winInfo;
int mw, mh;
/*Sets the minimum size of window winInfo to mw, mh*/
{
#ifdef WINDOWS4D
    SelWindow(winInfo);
    winInfo -> minWidth = mw;
    winInfo -> minHeight = mh;
    minsize(mw, mh);
    winconstraints();
#endif
}

void SetWindowMode(curWinInfo)
WinInfoPtr curWinInfo;
/*Sets the mode of the current window according to the flags*/
{
    if (curWinInfo -> id)
    {
	SelWindow(curWinInfo);
#ifdef WINDOWS4D
	if (curWinInfo -> flags & WINRGB)
	{
	    if (hasRGB)
	    {
		RGBmode();
	    }
	    else
	    {
		cmode();
	    }
	}
	else
	{
	    if (hasCmap)
	    {
		cmode();
	    }
	    else
	    {
		RGBmode();
	    }
	}
	if (IsDoubleBuf(curWinInfo))
	{
	    doublebuffer();
	}
	else
	{
	    singlebuffer();
	}
	gconfig();
#endif
    }
}

void DoMaxScreen()
/*Makes the current window go to the max screen*/
{
#ifdef GRAPHICS
#ifdef WINDOWS4D
    SetWindowPosition(0, SCRWIDTH, 0, SCRHEIGHT);
#endif
#endif
    phsco = false;
}


void DoVideoScreen()
/*Makes the current window go to the video screen*/
{
    int x, y;
#ifdef GRAPHICS
#ifdef WINDOWS4D
    GetScreenSize(&x, &y);
    SetWindowPosition(0, x, 0, y);
#endif
#endif
    phsco = false;
}

void Do2VideoScreen()
/*Makes the current window go to twice the video screen*/
{
    int x, y;
#ifdef GRAPHICS
#ifdef WINDOWS4D
    GetScreenSize(&x, &y);
    SetWindowPosition(0, 2 * x, 0, 2 * y);
#endif
#endif
    phsco = false;
}

void LocateWindow(l, r, b, t)
int l, r, b, t;
/*Locates current window at l, r, b, t*/
{
#ifdef GRAPHICS
#ifdef WINDOWS4D
    SetWindowPosition(l, r, b, t);
#endif
#endif
    phsco = false;
}

void DoPhscoScreen()
/*Makes the current window go to the phscologram screen*/
{
#ifdef GRAPHICS
#ifdef WINDOWS4D
    SetWindowPosition(0, 1100, 0, 615);
#endif
#endif
    phsco = true;
}

static void NullAndVoid()
/*Default do-nothing void routine*/
{
}

ObjPtr WinFullScreen(ObjPtr win)
/*Sets win (which is also current) to the full screen*/
{
    SetWindowPosition(0, SCRWIDTH, 0, SCRHEIGHT);
    phsco = false;
    return ObjTrue;
}

ObjPtr WinVideoScreen(ObjPtr win)
/*Sets win (which is also current) to the video screen*/
{
    int x, y;

    GetScreenSize(&x, &y);
    SetWindowPosition(0, x, 0, y);

    phsco = false;
    return ObjTrue;
}

ObjPtr WinDoubleVidScreen(ObjPtr win)
/*Sets win (which is also current) to double the video screen*/
{
    int x, y;

    GetScreenSize(&x, &y);
    SetWindowPosition(0, 2 * x, 0, 2 * y);

    phsco = false;
    return ObjTrue;
}

ObjPtr WinPrevScreen(ObjPtr win)
/*Undoes a reshape of the window*/
{
    if (selWinInfo)
    {
	SetWindowPosition(selWinInfo -> ol, selWinInfo -> or, selWinInfo -> ob, selWinInfo -> ot);
    }
}

WinInfoPtr NewWinInfo(superClass, windowID, flags, title, 
		minWidth, minHeight, maxWidth, maxHeight)
ObjPtr superClass;
long windowID;
long flags;
char *title;
int minWidth, minHeight, maxWidth, maxHeight;
/*Creates a new window information record associated with windowID 
  and returns it, or NIL if it couldn't 
  allocate one.  Sets everything to the default.  Sets the superclass to
  superClass so that it can inherit*/
{
    WinInfoPtr newInfo;

#ifdef GRAPHICS
    if (windowID)
    {
	winset(windowID);
    }
#endif

    if (firstTime)
    {
#ifdef GRAPHICS
	/*Finish the initialization that we couldn't do until the 1st window*/
	firstTime = 0;
#endif
    }

    if (superClass == 0)
    {
	superClass = windowClass;
    }

    newInfo = (WinInfoPtr) NewObject(superClass, sizeof(WinInfo) - sizeof(Thing));
    if (newInfo)
    {
	int k;
	WinInfoPtr *runner;
	long ox, oy, sx, sy;

	/*Set up the new info to point to this window*/
	newInfo -> id = windowID;

	/*Link the new info into the list*/
	runner = &(allWindows);
	while (*runner)
	{
	    runner = &((*runner) -> next);
	}
	*runner = newInfo;
	newInfo -> next = 0;

	/*Initialize values to defaults*/
        SETOBJTYPE(newInfo -> thing . flags, WINDOW);
	AddToReferenceList((ObjPtr) newInfo);
        
	newInfo -> flags = flags;
	ImInvalid((ObjPtr) newInfo);

	newInfo -> minWidth = minWidth;
	newInfo -> maxWidth = maxWidth;
	newInfo -> minHeight = minHeight;
	newInfo -> maxHeight = maxHeight;

	if (windowID)
	{
	    /*Set to the current window and set the graphics state*/
	    SetWindowMode(newInfo);
	}
	
	/*Save the title*/
	strcpy(newInfo -> winTitle, title);
	SetVar((ObjPtr) newInfo, NAME, NewString(title));

	/*Select the new window*/
	SelWindow(newInfo);

	/*Stuff ol, or, ob, ot*/
#ifdef WINDOWS4D
#ifdef GRAPHICS
	if (windowID)
	{
	    getorigin(&ox, &oy);
	    getsize(&sx, &sy);
	}
	else
	{
	    ox = SCRWIDTH / 2 - minWidth / 2;
	    oy = SCRHEIGHT / 2 - minHeight / 2;
	    sx = minWidth;
	    sy = minHeight;
	}
	newInfo -> nl = ox;
	newInfo -> nr = ox + sx;
	newInfo -> nb = oy;
	newInfo -> nt = oy + sy;
	newInfo -> ol = ox;
	newInfo -> or = ox + sx;
	newInfo -> ob = oy;
	newInfo -> ot = oy + sy;
#endif
#endif

	/*Set some methods*/

	if (!((flags & WINFIXEDLOC) || (flags & WINFIXEDSIZE)))
	{
	    SetMethod((ObjPtr) newInfo, FULLSCREEN, WinFullScreen);
	    SetMethod((ObjPtr) newInfo, VIDEOSCREEN, WinVideoScreen);
	    SetMethod((ObjPtr) newInfo, DOUBLEVIDSCREEN, WinDoubleVidScreen);
	    SetMethod((ObjPtr) newInfo, PREVSCREEN, WinPrevScreen);
	}
	SetMethod((ObjPtr) newInfo, SAVEWINDOW, SaveWindow);
	SetMethod((ObjPtr) newInfo, SAVEFWINDOW, SaveFWindow);
	SetMethod((ObjPtr) newInfo, SAVESCREEN, SaveFullScreen);

	/*Return the new info*/
	return newInfo;
    }
    else
    {
	/*Failed to allocate info.  Return NIL*/
	OMErr();
	return (WinInfoPtr) 0;
    }
}

#ifdef HAVE_PROTOTYPES
void SetWindowTitle(ObjPtr win, char *title)
#else
void SetWindowTitle(win, title)
ObjPtr win;
char *title;
#endif
/*Sets window title to title*/
{
    strcpy(((WinInfoPtr) win) -> winTitle, title);
    SetVar((ObjPtr) win, NAME, NewString(title));
#ifdef GRAPHICS
#ifdef WINDOWS4D
    if (!(win -> flags & WINNOFRAME))
    {
	wintitle(title);
    }
#endif
#endif
}

Bool IsValidWindow(window)
WinInfoPtr window;
/*Returns true iff window is a valid window*/
{
    register WinInfoPtr runner;

    runner = allWindows;
    while (runner)
    {
	if (runner == window)
	{
	    return true;
	}
	runner = runner -> next;
    }
    return false;
}

WinInfoPtr GetWinInfo(winID)
long winID;
/*Gets the winInfo record associated with winID or returns NIL*/
{
    register WinInfoPtr runner;
    if (winID == 0) return 0;

    runner = allWindows;
    while (runner)
    {
	if (runner -> id == winID)
	{
	    return runner;
	}
	runner = runner -> next;
    }
    return (WinInfoPtr) 0;
}

int strcmp2(s1, s2)
char s1[], s2[];
/*Compares s1 and s2 without regard to case*/
{
    int k;

    for (k = 0; s1[k]; ++k)
    {
	if (toupper(s1[k]) < toupper(s2[k])) return -k - 1;
	if (toupper(s1[k]) > toupper(s2[k])) return k + 1;
    }
    return s2[k] ? -k - 1 : 0;
}

int strcmp3(s1, s2)
char s1[], s2[];
/*Compares s1 and s2 without regard to case, AND s2 can be longer*/
{
    int k;

    for (k = 0; s1[k]; ++k)
    {
	if (toupper(s1[k]) < toupper(s2[k])) return -k - 1;
	if (toupper(s1[k]) > toupper(s2[k])) return k + 1;
    }
    return 0;
}

#ifdef HAVE_PROTOTYPES
Bool ObjectNameMatches(char *pattern, char *candidate)
#else
Bool ObjectNameMatches(pattern, candidate)
char *pattern;
char *candidate;
#endif
/*Returns true if object name candidate matches pattern up until pattern
  stops.  There may be more stuff after the end of pattern.  For example, 
  pattern "foo" matches candidate "foobar"*/
{
    return strcmp3(pattern, candidate) ? false : true;
}

WinInfoPtr GetWinFromTitle(title)
char *title;
/*Gets the winInfo record associated with title.  If there is none or there
  is more than one, returns nil*/
{
    register WinInfoPtr runner;
    runner = allWindows;
    while (runner)
    {
	if (!strcmp2(runner -> winTitle, title))
	{
	    if (!GetVar((ObjPtr) runner, SUPERWINDOW))
	    {
		/*Only return if not a subwindow*/
		return runner;
	    }
	}
	runner = runner -> next;
    }
    return (WinInfoPtr) 0;
}

ObjPtr DisposeWindow(window)
WinInfoPtr window;
/*Disposes of the given window and closes the window.*/
{
    WinInfoPtr *runner;
    runner = &allWindows;
    while (*runner)
    {
	if ((*runner) == window)
	{
	    WinInfoPtr next;
	    FuncTyp closeRoutine;
	    
	    /*Found it.  Close it.*/
	    SelWindow(window);
	    MakeMeCurrent(NULLOBJ);

	    /*First check for hide routine*/
	    closeRoutine = GetMethod((ObjPtr) *runner, HIDE);
	    if (closeRoutine && IsTrue((*closeRoutine)(*runner)))
	    {
#ifdef WINDOWS4D
		winclose((*runner) -> id);
#endif
		if ((*runner) == inputWindow)
		{
		    inputWindow = 0;
		}
		(*runner) -> id = 0;
		SelWindow((WinInfoPtr) 0);

		/*Just advance*/
		runner = &((*runner) -> next);
	    }
	    else
	    {
		closeRoutine = GetMethod((ObjPtr) *runner, CLOSE);
		if (closeRoutine && !IsTrue((*closeRoutine)(*runner)))
		{
		    return ObjFalse;
		}
		SelWindow(*runner);

#ifdef WINDOWS4D
		winclose((*runner) -> id);
#endif
		if ((*runner) == inputWindow)
		{
		    inputWindow = 0;
		}
		SelWindow(0);
		next = (*runner) -> next;
		(*runner) -> id = 0;
		DeleteThing((ObjPtr) *runner);
		*runner = next;
	    }
	}
	else
	{
	    /*Not found.  Just advance.*/
	    runner = &((*runner) -> next);
	}
    }
    if (!allWindows)
    {
	DoQuit();
    }
    return ObjTrue;
}

Bool DisposeAllWindows()
/*Disposes of all the windows.  Returns true iff successful.*/
{
    while (allWindows)
    {
	WinInfoPtr next;
	FuncTyp closeRoutine;

	closeRoutine = GetMethod((ObjPtr) allWindows, CLOSE);
	if (closeRoutine && !IsTrue((*closeRoutine)(allWindows)))
	{
	    return false;
	}
	if (allWindows -> id)
	{
#ifdef WINDOWS4D
	    winclose(allWindows -> id);
#endif
	    allWindows -> id = 0;
	}

	next = allWindows -> next;
	DeleteThing((ObjPtr) allWindows);
	allWindows = next;
    }
    inputWindow = 0;
    return true;
}

int ReshapeWindow(window)
ObjPtr window;
/*Reshapes a window to a new viewport.*/
{
    if (selWinInfo)
    {
	FuncTyp reshapeMethod;
	reshapeMethod = GetMethod(window, RESHAPE);
	if (reshapeMethod)
	{
	    (*reshapeMethod)(window, 
		((WinInfoPtr) selWinInfo) -> ol,
		((WinInfoPtr) selWinInfo) -> or,
		((WinInfoPtr) selWinInfo) -> ob,
		((WinInfoPtr) selWinInfo) -> ot,
		((WinInfoPtr) selWinInfo) -> nl,
		((WinInfoPtr) selWinInfo) -> nr,
		((WinInfoPtr) selWinInfo) -> nb,
		((WinInfoPtr) selWinInfo) -> nt
		);
	}
    }
    return true;
}

void ForAllWindows(routine)
void (*routine)();
/*Performs (*routine)(window) on all windows*/
{
    WinInfoPtr curWindow;
    curWindow = allWindows;
    while (curWindow)
    {
	(*routine)(curWindow);
	curWindow = curWindow -> next;
    }
}

#ifdef HAVE_PROTOTYPES
Bool IdleOneWindow(WinInfoPtr curWindow)
#else
Bool IdleOneWindow(curWindow)
WinInfoPtr curWindow;
#endif
/*Idles one window.  Side effect--may select a window*/
{
    FuncTyp method;
    Bool retVal;

    retVal = false;

    if (curWindow -> id == 0) return false;

#ifdef GRAPHICS
    SetDrawingWindow(curWindow);
    MakeVar(curWindow, NAME);

    method = GetMethod((ObjPtr) curWindow, MAKEDRAWN);
    if (method)
    {
	{
	    if (IsTrue((*method)(curWindow)))
	    {
		/*Window was drawn*/

		retVal = true;

#ifdef WINDOWS4D
		if (windowSystem == WS_GLWINDOWS)
		{
		    if (IsDoubleBuf(curWindow))
		    {
			swapbuffers();
		    }
		}
#endif
	    }
	}
    }

   RestoreDrawingWindow();
   return retVal;
#endif
	
}

Bool IdleAllWindows()
/*Idles all the windows, redrawing double-buffered ones.  Returns true
  iff any redrawing was done*/
{
    Bool retVal = false;
#ifdef GRAPHICS
    WinInfoPtr curWindow;
    WinInfoPtr oldWindow;
    int dummy;

    oldWindow = selWinInfo;
    ++updateBatch;

    if (inputWindow && IsValidWindow(inputWindow))
    {
	if (IdleOneWindow(inputWindow))
	{
	    retVal = true;
	}
    }

    if (!AltDown() && !inhibitOtherWindows)
    {
	for (curWindow = allWindows; curWindow; curWindow = curWindow -> next)
	{
	    if (curWindow -> id == 0) continue;

	    if (curWindow == inputWindow) continue;

	    if (IdleOneWindow(curWindow))
	    {
		retVal = true;
	    }
	}
    }

    if (oldWindow && (oldWindow != selWinInfo))
    {
	SelWindow(oldWindow);
    }
#endif
    return retVal;
}

void IdleCaveWindows()
/*Idles the cave windows*/
{
#ifdef GRAPHICS
    float clr[3];
    WinInfoPtr curWindow;

    clr[0] = clr[1] = clr[2] = 0.0;
    c3f(clr);
    clear();
    zclear();
    rgbp = true;

    ++updateBatch;

    for (curWindow = allWindows; curWindow; curWindow = curWindow -> next)
    {
	DrawWindowInfo(curWindow);
    }
#endif
}

void DeferClose()
/*Does a close as a deferred task*/
{
    if (selWinInfo)
    {
	CloseWindow(selWinInfo);
    }
}

void GetConfiguration()
/*Gets the configuration of the system*/
{
    Bool tryRGB = true, tryCmap = true;
    Bool tryDouble = true;

    if (getenv("SCIAN_SHOW_CONFIG"))
    {
	showConfig = true;
    }
    else
    {
	showConfig = false;
    }

    if (showConfig)
    {
	printf("Calculating machine parameters\n");
    }

    if (getenv("SCIAN_VETO_DOUBLE"))
    {
	if (showConfig)
	{
	    printf("Double buffer mode vetoed.\n");
	}
	tryDouble = false;
    }
    else
    {
	tryDouble = true;
    }

    if (getenv("SCIAN_VETO_RGB"))
    {
	if (showConfig)
	{
	    printf("RGB mode vetoed.\n");
	}
	tryRGB = false;
    }
    else
    {
	tryRGB = true;
    }

    if (getenv("SCIAN_VETO_CMAP"))
    {
	if (showConfig)
	{
	    printf("Color map mode vetoed.\n");
	}
	tryCmap = false;
    }
    else
    {
	tryCmap = true;
    }

#ifdef GRAPHICS
    /*Find out the size of the screen*/
#ifdef GD_XPMAX
    scrWidth = getgdesc(GD_XPMAX);
#else
    scrWidth = CSCRWIDTH;
#endif
#ifdef GD_YPMAX
    scrHeight = getgdesc(GD_YPMAX);
#else
    scrHeight = CSCRHEIGHT;
#endif

    if (showConfig)
    {
	printf("Screen size: %d by %d\n", scrWidth, scrHeight);
    }

    /*See about the colors*/
    if (tryRGB)
    {
    /*Test RGB*/
    hasRGB = true;
    rgbGoodForUI = false;

    if (tryDouble)
    {
	/*Try double buffer RGB*/
	hasRGBDouble = true;

	/*See all bit planes for IBM version*/
#ifdef GD_BITS_NORM_DBL_RGB
	rBitPlanes = getgdesc(GD_BITS_NORM_DBL_RGB);
	gBitPlanes = getgdesc(GD_BITS_NORM_DBL_RGB);
	bBitPlanes = getgdesc(GD_BITS_NORM_DBL_RGB);
#endif

	/*Now individual bit planes for IRIS version*/
#ifdef GD_BITS_NORM_DBL_RED
	rBitPlanes = getgdesc(GD_BITS_NORM_DBL_RED);
#endif
#ifdef GD_BITS_NORM_DBL_GREEN
	gBitPlanes = getgdesc(GD_BITS_NORM_DBL_GREEN);
#endif
#ifdef GD_BITS_NORM_DBL_BLUE
	bBitPlanes = getgdesc(GD_BITS_NORM_DBL_BLUE);
#endif

	/*If not enough bit planes, shoot for single buffer*/
	if (rBitPlanes >= 4 && gBitPlanes >= 4 && bBitPlanes >= 4)
	{
	    if (showConfig)
	    {
		printf("RGB double buffer mode is allowed.\n");
	    }

	    /*KLUDGE heuristic which assumes stuff about IRIS implementation*/
	    if (rBitPlanes == gBitPlanes && gBitPlanes == bBitPlanes)
	    {
		if (showConfig)
		{
		    printf("RGB mode will work for user interface colors.\n");
		}
		rgbGoodForUI = true;
	    }
	    else
	    {
		if (showConfig)
		{
		    printf("RGB mode will NOT work for user interface colors.\n");
		}
		rgbGoodForUI = false;
	    }
	}
	else
	{
	    if (showConfig)
	    {
		printf("There are not enough bit planes for double buffer RGB.\n");
	    }
	    hasRGBDouble = false;
	}
    }
    else
    {
	hasRGBDouble = false;
	if (showConfig)
	{
	    printf("RGB double buffer vetoed\n");
	}
    }

    /*If not enough bit planes, shoot for single buffer*/
    if (!hasRGBDouble)
    {
	/*Try single buffer RGB*/

	/*See all bit planes for IBM version*/
#ifdef GD_BITS_NORM_DBL_RGB
	rBitPlanes = getgdesc(GD_BITS_NORM_SNG_RGB);
	gBitPlanes = getgdesc(GD_BITS_NORM_SNG_RGB);
	bBitPlanes = getgdesc(GD_BITS_NORM_SNG_RGB);
#endif

	/*Now individual bit planes for IRIS version*/
#ifdef GD_BITS_NORM_SNG_RED
	rBitPlanes = getgdesc(GD_BITS_NORM_SNG_RED);
#endif
#ifdef GD_BITS_NORM_SNG_GREEN
	gBitPlanes = getgdesc(GD_BITS_NORM_SNG_GREEN);
#endif
#ifdef GD_BITS_NORM_SNG_BLUE
	bBitPlanes = getgdesc(GD_BITS_NORM_SNG_BLUE);
#endif

	/*If not enough bit planes, shoot for single buffer*/
	if (rBitPlanes && gBitPlanes && bBitPlanes)
	{
	    if (showConfig)
	    {
		printf("RGB single buffer mode is allowed.\n");
	    }

	    /*KLUDGE heuristic which assumes stuff about IRIS implementation*/
	    if (rBitPlanes == gBitPlanes && gBitPlanes == bBitPlanes)
	    {
		if (showConfig)
		{
		    printf("RGB mode will work for user interface colors.\n");
		}
		rgbGoodForUI = true;
	    }
	    else
	    {
		if (showConfig)
		{
		    printf("RGB mode will NOT work for user interface colors.\n");
		}
		rgbGoodForUI = false;
	    }
	}
	else
	{
	    if (showConfig)
	    {
		printf("There are not enough bit planes for single buffer RGB.\n");
	    }
	    hasRGB = false;
	}
    }
    }
    else
    {
	hasRGB = false;
    }

    if (getenv("SCIAN_VETO_RGB_GOOD_FOR_UI"))
    {
	if (showConfig)
	{
	    printf("RGB for user interface vetoed\n");
	}
	rgbGoodForUI = false;
    }
    else if (getenv("SCIAN_FORCE_RGB_GOOD_FOR_UI"))
    {
	if (showConfig)
	{
	    printf("RGB for user interface forced\n");
	}
	rgbGoodForUI = true;
    }

    /*See if depth cueing is appropriate*/
    if (rBitPlanes < 3 || gBitPlanes < 3 || bBitPlanes < 3)
    {
	if (showConfig)
	{
	    printf("Depth cueing is not practical with this number of bitplanes.\n");
	}
	hasDepthCue = false;
    }
    else
    {
	if (showConfig)
	{
	    printf("There is depth cueing.\n");
	}
	hasDepthCue = true;
    }

    /*Now check double buffer color map mode*/
    if (tryCmap)
    {
	hasCmap = true;
	if (tryDouble)
	{
	    hasCmapDouble = true;
	    cmapBitPlanes = getgdesc(GD_BITS_NORM_DBL_CMODE);

	    if (showConfig)
	    {
		printf("%d double buffer color map bitplanes.\n", cmapBitPlanes);
	    }

	    if (cmapBitPlanes < MINCMAPBITPLANES)
	    {
		/*Not enough bit planes for cmap*/
		if (showConfig)
		{
		    printf("Not enough bit planes for double buffer color map mode (%d).\n", cmapBitPlanes);
		}
		hasCmapDouble = false;
	    }
	}

	if (!hasCmapDouble)
	{
	    /*Try single buffer*/

	    cmapBitPlanes = getgdesc(GD_BITS_NORM_SNG_CMODE);
	    if (showConfig)
	    {
		printf("%d single buffer color map bitplanes.\n", cmapBitPlanes);
	    }
	    if (cmapBitPlanes < MINCMAPBITPLANES)
	    {
		if (showConfig)
		{
		    printf("Not enough bit planes for single buffer color map mode (%d).\n", cmapBitPlanes);
		}
		hasCmap = false;
	    }
	}
    }

    if ((!hasCmap) && (!hasRGB))
    {
	printf("This computer does not have enough color bit planes to run SciAn.  SciAn\n");
	printf("requires at least nine color map bit planes or some RGB bit planes in\n");
	printf("order to work properly.\n");
	exit(-1);
    }

    /*Use RGB mode for user interface anyway*/
    rgbGoodForUI = true;

#ifdef GD_DITHER
    if (getgdesc(GD_DITHER))
    {
	if (showConfig)
	{
	    printf("There is dithering.\n");
	}
	hasDithering = true;
    }
    else
    {
	if (showConfig)
	{
	    printf("There is no dithering.\n");
	}
	hasDithering = false;
    }
#else
    if (showConfig)
    {
	printf("There is no dithering.\n");
	hasDithering = false;
    }
#endif

    scavengeColors = false;

    if (hasCmap && getenv("SCIAN_SCAVENGE_COLORS"))
    {
	scavengeColors = true;
    }

#ifdef GD_BLEND
    if (getgdesc(GD_BLEND))
    {
	hasTransparency = true;
	if (showConfig)
	{
	    printf("There is blending transparency.\n");
	}
    }
    else
#endif
    {
	hasTransparency = false;
	if (showConfig)
	{
	    printf("There is no blending transparency.\n");
	}
    }

#ifdef GD_LINESMOOTH_RGB
    if (getgdesc(GD_LINESMOOTH_RGB))
    {
	hasAntialiasedLines = true;
	if (showConfig)
	{
	    printf("There is line anti-aliasing.\n");
	}
    }
    else
#endif
    {
	hasAntialiasedLines = false;
	if (showConfig)
	{
	    printf("There is no line anti-aliasing.\n");
	}
    }

#ifdef GD_PNTSMOOTH_RGB
    if (getgdesc(GD_PNTSMOOTH_RGB))
    {
	hasAntialiasedPoints = true;
	if (showConfig)
	{
	    printf("There is point anti-aliasing.\n");
	}
    }
    else
#endif
    {
	hasAntialiasedPoints = false;
	if (showConfig)
	{
	    printf("There is no point anti-aliasing.\n");
	}
    }

#ifdef GD_LIGHTING_TWOSIDE
    if (getgdesc(GD_LIGHTING_TWOSIDE))
    {
	hasTwoSided = true;
	if (showConfig)
	{
	    printf("There is hardware two-sided lighting available.\n");
	}
    }
    else
#endif
    {
	hasTwoSided = false;
	if (showConfig)
	{
	    printf("There is no hardware two-sided lighting.\n");
	}
    }

#ifdef GD_BITS_ZBUFFER
    if (getgdesc(GD_BITS_ZBUFFER) > 0)
#else
#ifdef GD_BITS_NORM_ZBUFFER
    if (getgdesc(GD_BITS_NORM_ZBUFFER) > 0)
#else
!! No Z-buffer constant defined
#endif
#endif
    {
	hasZbuf = true;
	if (showConfig)
	{
	    printf("There is a Z-buffer.\n");
	}
    }
    else
    {
	hasZbuf = false;
	if (showConfig)
	{
	    printf("There is no Z-buffer.\n");
	}
    }

    if (getenv("SCIAN_VETO_ZBUFFER"))
    {
	if (showConfig)
	{
	    printf("Z-buffer vetoed.\n");
	}
	hasZbuf = false;
    }

    if (getenv("SCIAN_FORCE_ZBUFFER"))
    {
	if (showConfig)
	{
	    printf("Z-buffer forced.\n");
	}
	hasZbuf = true;
    }

    nOverDrawPlanes = 0;
    pupForOverDraw = false;

#ifdef GD_BITS_OVER_SNG_CMODE
    if (nOverDrawPlanes = getgdesc(GD_BITS_OVER_SNG_CMODE))
    {
	pupForOverDraw = false;
	if (showConfig)
	{
	    printf("There are %d overlay planes.\n", nOverDrawPlanes);
	}
    }
#endif
#ifdef GD_BITS_PUP_SNG_CMODE
    if (!nOverDrawPlanes && (nOverDrawPlanes = getgdesc(GD_BITS_PUP_SNG_CMODE)))
    {
	pupForOverDraw = true;
	if (showConfig)
	{
	    printf("There are %d popup planes.\n", nOverDrawPlanes);
	}
    }
#endif

#ifdef GD_BITS_OVERLAY
    if (!nOverDrawPlanes && ((nOverDrawPlanes = getgdesc(GD_BITS_OVERLAY)) > 0))
    {
	pupForOverDraw = false;
	if (showConfig)
	{
	    printf("There are %d overlay planes.\n", nOverDrawPlanes);
	}
    }
#endif

    if ((!nOverDrawPlanes) && showConfig)
    {
	printf("There are no overlay planes.\n");
    }

    if (getenv("SCIAN_VETO_OVERLAY"))
    {
	if (showConfig)
	{
	    printf("Overlay planes vetoed.\n");
	}
	nOverDrawPlanes = 0;
    }

    if (getenv("SCIAN_FORCE_OVERLAY"))
    {
	if (showConfig)
	{
	    printf("Overlay planes forced.\n");
	}
	nOverDrawPlanes = 2;
    }

    if (getenv("SCIAN_FORCE_STEREO"))
    {
	if (showConfig)
	{
	    printf("Stereo forced.\n");
	}
	hasStereo = true;
    }
    else
    {
#ifdef GD_STEREO
	hasStereo = getgdesc(GD_STEREO) ? true : false;
#else
	hasStereo = false;
#endif
	if (showConfig)
	{
	    printf(hasStereo ? "Stereo mode is available.\n" :
			"Stereo mode is not available.\n");
	}
    }

#endif
}

ObjPtr SetWindowToRGB(window)
WinInfoPtr window;
/*Method to set a window to RGB mode*/
{
		    if (window -> flags & WINRGB)
		    {
			/*Do nothing*/
		    }
		    else
		    {
			window -> flags |= WINRGB;
			SelWindow(window);
			SetWindowMode(window);
			ImInvalid((ObjPtr) window);
		    }
    return ObjTrue;
}

ObjPtr SetWindowToCmap(window)
WinInfoPtr window;
/*Method to set a window to Cmap mode*/
{
		    if (window -> flags & WINRGB)
		    {
			window -> flags &= ~WINRGB;
			SelWindow(window);
			SetWindowMode(window);
			ImInvalid((ObjPtr) window);
		    }
		    else
		    {
			/*Do nothing*/
		    }
    return ObjTrue;
}

void InitWindows()
/*Initializes the window system*/
{
    long dim;

    windowClass = NewObject(NULLOBJ, 0);
    SetMethod(windowClass, DISPOSE, DisposeWindow);
    SetVar(windowClass, TYPESTRING, NewString("window"));
    SetMethod(windowClass, SETTORGBMODE, SetWindowToRGB);
    SetMethod(windowClass, SETTOCMAPMODE, SetWindowToCmap);
    SetMethod(windowClass, OPENMANUALLY, OpenWindowManually);
    AddToReferenceList(windowClass);

    /*Create the clipboard*/
    dim = 1;
    clipboard = NewArray(AT_OBJECT, 1, &dim);
    AddToReferenceList(clipboard);
}

void KillWindows()
/*Kills the window system*/
{
    DeleteThing(clipboard);
    DeleteThing(windowClass);
}

Modified: Sun Nov 17 17:00:00 1996 GMT
Page accessed 2309 times since Sat Apr 17 21:55:09 1999 GMT