/*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" 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*/ int recScrWidth = VSCRWIDTH; /*Video screen size*/ int recScrHeight = VSCRHEIGHT; 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*/ Bool hasOverDraw; /*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*/ #ifdef WINNOCLOSE #define MAXCACHEDWINDOWS 100 long cachedWindows[MAXCACHEDWINDOWS]; int nCachedWindows = 0; #endif int drawingQuality = DQ_FULL; /*The current drawing quality*/ long fontSubMenu; long *styleSubMenus = 0; int nStyleSubMenus = 0; /*Number of style submenus*/ long sizeSubMenu; long alignSubMenu; int STAGX, STAGY; #define STAGSTEP 40 /*Step for staggering*/ #define STAGMAX 200 /*Maximum staggering*/ int stagger = 0; /*Current staggering amount*/ int textSizes[] = { 9, 10, 12, 14, 18, 24, 36, 48, 72 }; /*Names of all the main level menus*/ char *menuName[NMENUS] = { "File", "Network", "Datasets", "Object", "Color", "Text", "Deus", "Window Location", "Window", "Arrange", "Special Effects", "Color Model" }; 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 PROTO 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 PROTO 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 PROTO void SelWindow(WinInfoPtr w) #else void SelWindow(w) WinInfoPtr w; #endif /*Procedure version of SelectWindow, useful for debugging*/ { selWinInfo = w; if (w && ((WinInfoPtr) w) -> id) {winset(((WinInfoPtr) w) -> id); curDisplayMode = getdisplaymode(); rgbp = (curDisplayMode == DMSINGLE || curDisplayMode == DMDOUBLE) ? false : true;} } #endif #ifdef PROTO 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 winposition((long) l, (long) r - 1, (long) b, (long) t - 1); #endif #endif } #ifdef PROTO 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 PROTO 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 } 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 { winInfo -> id = NewOpenedWindow(winInfo -> winTitle, winInfo -> minWidth, winInfo -> minHeight, winInfo -> maxWidth, winInfo -> maxHeight, winInfo -> flags); SetMode(winInfo); ImInvalid((ObjPtr) winInfo); } } #ifdef PROTO void CloseWindow(WinInfoPtr window) #else void CloseWindow(window) WinInfoPtr window; #endif /*Closes window*/ { ObjPtr var; 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 ScrSaveFailed(void) /*Alerts the user that a screen save failed*/ { WinInfoPtr errWindow; errWindow = AlertUser(UISEVEREALERT, (WinInfoPtr) 0, "The attempt to save the screen failed.", 0, 0, ""); SetVar((ObjPtr) errWindow, HELPSTRING, NewString("The attempt to save the screen failed. This is probably \ because the current directory is a directory to which you don't have write \ access. It may also be that the disk is full.")); } void DrawWindowInfo(theWindow) WinInfoPtr theWindow; /*Draws the window based on WinInfoPtr theWindow into the current set window. This is the fundamental window drawing routine.*/ { #ifdef GRAPHICS shademodel(FLAT); concave(TRUE); backface(FALSE); if (hasDithering) { #ifdef DT_OFF dither(DT_OFF); #endif } #endif DrawObject((ObjPtr) theWindow); } void SaveScreen(window, flags) WinInfoPtr window; int flags; /*Saves a screen*/ { #ifdef GRAPHICS long l, r, b, t; int k; #ifndef RELEASE if (GetPrefInteger(PREF_SAVESCREEN)) { for (k = 0; ; ++k) { sprintf(tempStr, "screen%d.eps", k); if (drawFile = fopen(tempStr, "r")) { fclose(drawFile); } else { int left, right, bottom, top; drawFile = fopen(tempStr, "w"); drawingMode = DRAW_POSTSCRIPT; SetDrawingWindow(window); GetWindowBounds(&left, &right, &bottom, &top); BeginDrawing(window -> winTitle, left, right, bottom, top); DrawWindowInfo(window); EndDrawing(); RestoreDrawingWindow(); drawingMode = DRAW_SCREEN; fclose(drawFile); printf("Screen saved in screen%d.eps\n", k); return; } } } else #endif { if (flags & F_OPTIONDOWN) { l = b = 0; r = SCRWIDTH; t = SCRHEIGHT; } else { long sx, sy; getorigin(&l, &b); getsize(&sx, &sy); r = l + sx - 1; t = b + sy - 1; if (!(flags & F_SHIFTDOWN || ((WinInfoPtr) window) -> flags & WINNOFRAME)) { l -= WINBL; r += WINBR; b -= WINBB; t += WINBT; } } for (k = 0; ; ++k) { FILE *test; sprintf(tempStr, "screen%d.rgb", k); if (test = fopen(tempStr, "r")) { fclose(test); } else { sprintf(tempStr, "scrsave screen%d.rgb %d %d %d %d", k, l, r, b, t); if (system(tempStr)) { DoTask(ScrSaveFailed); } else { printf("Screen saved in screen%d.rgb\n", k); } return; } } } #endif } void DeleteMenus(winInfo) WinInfoPtr winInfo; /*Deletes the menus in winInfo*/ { #ifdef GRAPHICS #ifdef MENUS4D int k; if (winInfo -> mainMenu) { freepup(winInfo -> mainMenu); winInfo -> mainMenu = 0; } for (k = 0; k < NMENUS; ++k) { if (winInfo -> subMenus[k]) { freepup(winInfo -> subMenus[k]); winInfo -> subMenus[k] = 0; } } #endif #endif } void SetFont(object, f) ObjPtr object; char *f; /*Sets object to have font f*/ { if (object) { if (logging) { char cmd[256]; char *s; sprintf(cmd, "set font "); s = &(cmd[0]); while (*s) ++s; MakeObjectName(s, object); while (*s) ++s; *s++ = ' '; strcpy(s, f); while (*s) ++s; *s++ = '\n'; *s = 0; Log(cmd); } SetTextFont(object, f); } } static char *globalFont; static ObjPtr SetGlobalFont(object) ObjPtr object; /*Sets the object's font to globalFont*/ { #ifdef GRAPHICS SetFont(object, globalFont); return ObjTrue; #endif } void MenuSetFont(n) int n; /*Sets font n*/ { #ifdef GRAPHICS globalFont = fonts[n]; ForAllSelectedObjects(SetGlobalFont); #endif } void SetSize(object, size) ObjPtr object; int size; /*Sets object to have font size size*/ { if (object) { if (logging) { char cmd[256]; char *s; sprintf(cmd, "set size "); s = &(cmd[0]); while (*s) ++s; MakeObjectName(s, object); while (*s) ++s; *s++ = ' '; sprintf(s, "%d", size); while (*s) ++s; *s++ = '\n'; *s = 0; Log(cmd); } { SetTextSize(object, size); } } } static int globalSize; static ObjPtr SetGlobalSize(object) ObjPtr object; /*Sets the object's font to globalFont*/ { SetSize(object, globalSize); return ObjTrue; } void MenuSetSize(n) int n; /*Sets size n*/ { globalSize = n; ForAllSelectedObjects(SetGlobalSize); } void SetAlignment(object, alignment) ObjPtr object; int alignment; /*Sets object to have alignment*/ { if (object) { if (logging) { char cmd[256]; char *s; sprintf(cmd, "set alignment "); s = &(cmd[0]); while (*s) ++s; MakeObjectName(s, object); while (*s) ++s; *s++ = ' '; sprintf(s, "%d", alignment); while (*s) ++s; *s++ = '\n'; *s = 0; Log(cmd); } { SetTextAlign(object, alignment); } } } static int globalAlignment; static ObjPtr SetGlobalAlignment(object) ObjPtr object; /*Sets the object's font to globalFont*/ { SetAlignment(object, globalAlignment); return ObjTrue; } void MenuSetAlignment(n) int n; /*Sets alignment of text to n, n is ALIGNLEFT, ALIGNRIGHT, or ALIGNCENTER*/ { globalAlignment = n; ForAllSelectedObjects(SetGlobalAlignment); } 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 CutText(void) /*Cuts text*/ { if (selWinInfo) { ObjPtr current; current = GetVar((ObjPtr) selWinInfo, CURRENT); if (current) { FuncTyp method; method = GetMethod(current, CUT); if (method) { ObjPtr value; value = (*method)(current); if (value) { ObjPtr *elements; elements = ELEMENTS(clipboard); elements[0] = value; } } } } } void CopyText(void) /*Cuts text*/ { if (selWinInfo) { ObjPtr current; current = GetVar((ObjPtr) selWinInfo, CURRENT); if (current) { FuncTyp method; method = GetMethod(current, COPY); if (method) { ObjPtr value; value = (*method)(current); if (value) { ObjPtr *elements; elements = ELEMENTS(clipboard); elements[0] = value; } } } } } void PasteText(void) /*Cuts text*/ { if (selWinInfo) { ObjPtr current; current = GetVar((ObjPtr) selWinInfo, CURRENT); if (current) { FuncTyp method; method = GetMethod(current, PASTE); if (method) { ObjPtr value; ObjPtr *elements; elements = ELEMENTS(clipboard); value = elements[0]; (*method)(current, value); } } } } 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 BuildMenu(winInfo) WinInfoPtr winInfo; /*Builds a menu in winInfo*/ { #ifdef GRAPHICS #ifdef MENUS4D long mainMenu; /*Main menu*/ int k; Bool textMenu = false; /*Text menu has been added*/ /*Make the initial menus null*/ DeleteMenus(winInfo); for (k = 0; k < NMENUS; ++k) { winInfo -> subMenus[k] = 0; } /*Give the window a WINDOW menu*/ if (!winInfo -> subMenus[WINDOWSMENU]); { winInfo -> subMenus[WINDOWSMENU] = newpup(); } /*Do the function menus*/ AddFunctionMenus(winInfo); /*Set up the prefix parts of the menus*/ /*Size menu*/ if ((winInfo -> flags & WINFIXEDSIZE) == 0) { /*It can move; give it moving items*/ winInfo -> subMenus[WINSIZEMENU] = newpup(); addtopup(winInfo -> subMenus[WINSIZEMENU], "Full Screen%f", DoMaxScreen); addtopup(winInfo -> subMenus[WINSIZEMENU], "Video Screen%f", DoVideoScreen); addtopup(winInfo -> subMenus[WINSIZEMENU], "Double Video Screen%f", Do2VideoScreen); addtopup(winInfo -> subMenus[WINSIZEMENU], "Previous Location%f", DoUndoReshape); } /*File menu*/ if (!winInfo -> subMenus[FILEMENU]) { winInfo -> subMenus[FILEMENU] = newpup(); } addtopup(winInfo -> subMenus[FILEMENU], "New File Window%f", DoNewFileWindow); #ifdef SOCKETS #ifndef RELEASE if (!winInfo -> subMenus[NETWORKMENU]) { winInfo -> subMenus[NETWORKMENU] = newpup(); } addtopup(winInfo -> subMenus[NETWORKMENU], "Connect To Computer...%f", DoConnectToComputer); #endif #endif /*Go through the defined menu items*/ for (k = 0; k < winInfo -> nMenuItems; ++k) { int whichMenu; whichMenu = winInfo -> menuItems[k] . menu; if (!winInfo -> subMenus[whichMenu]) { winInfo -> subMenus[whichMenu] = newpup(); } if ((whichMenu == TEXTMENU) && !textMenu) { textMenu = true; addtopup(winInfo -> subMenus[TEXTMENU], "Cut Text%f", CutText); addtopup(winInfo -> subMenus[TEXTMENU], "Copy Text%f", CopyText); addtopup(winInfo -> subMenus[TEXTMENU], "Paste Text%f", PasteText); if (fontSubMenu) { addtopup(winInfo -> subMenus[TEXTMENU], "Text Font%m", fontSubMenu); } if (sizeSubMenu) { addtopup(winInfo -> subMenus[TEXTMENU], "Text Size%m", sizeSubMenu); } if (alignSubMenu) { addtopup(winInfo -> subMenus[TEXTMENU], "Text Alignment%m", alignSubMenu); } if (strlen(winInfo -> menuItems[k] . name)) { addtopup(winInfo -> subMenus[TEXTMENU], "-"); } } if (strlen(winInfo -> menuItems[k] . name)) { sprintf(tempStr, "%s%%f", winInfo -> menuItems[k] . name); addtopup(winInfo -> subMenus[whichMenu], tempStr, winInfo -> menuItems[k] . action); } } /*Put arrange menu in window menu*/ if ((winInfo -> flags & WINFIXEDSIZE) == 0) { sprintf(tempStr, "%s%%m", menuName[WINSIZEMENU]); addtopup(winInfo -> subMenus[WINDOWSMENU], tempStr, winInfo -> subMenus[WINSIZEMENU]); } /*Set up the postfix parts of the menus*/ if (GetPredicate((ObjPtr) winInfo, HIDEPANEL)) { if (GetPredicate((ObjPtr) winInfo, PANELHIDDEN)) { addtopup(winInfo -> subMenus[WINDOWSMENU], "Show Control Panel%f", DoShowPanel); } else { addtopup(winInfo -> subMenus[WINDOWSMENU], "Hide Control Panel%f", DoHidePanel); } } #ifndef NOHIDEFRAME if (winInfo -> flags & WINNOFRAME) { addtopup(winInfo -> subMenus[WINDOWSMENU], "Show Window Frame%f", DoShowFrame); } else { addtopup(winInfo -> subMenus[WINDOWSMENU], "Hide Window Frame%f", DoHideFrame); } #endif addtopup(winInfo -> subMenus[WINDOWSMENU], "Close%f", DoClose); addtopup(winInfo -> subMenus[FILEMENU], "Show File Readers%f", PopFileReadersWindow); /*Now create the main menu*/ sprintf(tempStr, "%s%%t", "SciAn"); mainMenu = defpup(tempStr); addtopup(mainMenu, "Help%f", DoShowHelp); addtopup(mainMenu, "Preferences%f", DoShowPreferences); if (winInfo -> subMenus[COLORMENU] && winInfo -> subMenus[COLORMODELMENU]) { /*Put color model menu in color menu*/ sprintf(tempStr, "%s%%m", menuName[COLORMODELMENU]); addtopup(winInfo -> subMenus[COLORMENU], tempStr, winInfo -> subMenus[COLORMODELMENU]); } if (winInfo -> subMenus[COLORMENU] && winInfo -> subMenus[EFFECTSMENU]) { /*Put effects menu in color menu*/ sprintf(tempStr, "%s%%m", menuName[EFFECTSMENU]); addtopup(winInfo -> subMenus[COLORMENU], tempStr, winInfo -> subMenus[EFFECTSMENU]); } /*Add in the little menus*/ for (k = 0; k < NMENUS; ++k) { if ((winInfo -> subMenus[k]) && (k != WINSIZEMENU) && (k != ARRANGEMENU) && (k != EFFECTSMENU) && (k != COLORMODELMENU)) { sprintf(tempStr, "%s%%m", menuName[k]); addtopup(mainMenu, tempStr, winInfo -> subMenus[k]); } } /*Add the quit*/ addtopup(mainMenu, "Quit SciAn%f", MaybeQuit); winInfo -> mainMenu = mainMenu; #endif #endif } void DefineMenuItem(window, menu, name, action) ObjPtr window; int menu; char *name; void (*action)(); /*Defines a menu item in window under menu with name and action*/ { int nMenuItems; /*Add it to the window's list of menu items*/ nMenuItems = ((WinInfoPtr) window) -> nMenuItems; ((WinInfoPtr) window) -> menuItems[nMenuItems] . menu = menu; strcpy(((WinInfoPtr) window) -> menuItems[nMenuItems] . name, name); ((WinInfoPtr) window) -> menuItems[nMenuItems] . action = action; ((WinInfoPtr) window) -> nMenuItems = nMenuItems + 1; } 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 } WindowID NewOpenedWindow(title, minWidth, minHeight, maxWidth, maxHeight, flags) char *title; int minWidth, minHeight, maxWidth, maxHeight; long flags; /*Creates a new opened 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; int stagX, stagY; #ifdef GRAPHICS #ifdef WINDOWS4D #ifndef NOHIDEFRAME if (flags & WINNOFRAME) { noborder(); } #endif #endif #endif if (flags & WINFIXEDLOC) { /*Fixed location. Use max as origin instead*/ prefposition(maxWidth, minWidth + maxWidth - 1, maxHeight, minHeight + maxHeight - 1); } else if (flags & WINCENTERED) { ox = SCRWIDTH / 2 - minWidth / 2; oy = SCRHEIGHT / 2 - minHeight / 2; #ifdef GRAPHICS #ifdef WINDOWS4D prefposition(ox, ox + minWidth - 1, oy, oy + minHeight - 1); #endif #endif } else #ifndef WINNOCLOSE if (runningScript || runningRemote || GetPrefTruth(PREF_NEWWINPLACE)) #endif { #ifdef GRAPHICS #ifdef WINDOWS4D prefposition(stagX = STAGX + stagger, STAGX + stagger + minWidth - 1, stagY = STAGY - stagger - minHeight + 1, STAGY - stagger); #endif #endif stagger += STAGSTEP; if (stagger > STAGMAX) stagger = 0; } else { #ifdef GRAPHICS #ifdef WINDOWS4D minsize(minWidth, minHeight); maxsize(maxWidth, maxHeight); #endif #endif } #ifdef GRAPHICS #ifdef WINDOWS4D #ifdef WINNOCLOSE if (nCachedWindows) { --nCachedWindows; retVal = cachedWindows[nCachedWindows]; winset(retVal); if (flags & WINCENTERED) { ox = SCRWIDTH / 2 - minWidth / 2; oy = SCRHEIGHT / 2 - minHeight / 2; winposition(ox, ox + minWidth - 1, oy, oy + minHeight - 1); } else { winposition(stagX, stagX + minWidth - 1, stagY, stagY + minHeight - 1); } } else #endif retVal = winopen(title); wintitle(title); if (flags & WINFIXEDLOC) { /*Fixed location. Use max as origin instead*/ prefposition(maxWidth, minWidth + maxWidth - 1, maxHeight, minHeight + maxHeight - 1); } else { minsize(minWidth, minHeight); maxsize(maxWidth, maxHeight); } #ifndef NOHIDEFRAME if (flags & WINNOFRAME) { noborder(); } #endif winconstraints(); winset(retVal); #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 (hasOverDraw && pupForOverDraw == false) { overlay(1); } gconfig(); #endif #endif InitStuff(); return retVal; } void SetMinSize(winInfo, mw, mh) WinInfoPtr winInfo; int mw, mh; /*Sets the minimum size of window winInfo to mw, mh*/ { #ifdef WINDOWS4D SelWindow(winInfo); minsize(mw, mh); winconstraints(); #endif } void SetMode(curWinInfo) WinInfoPtr curWinInfo; /*Sets the mode of the current window according to the flags*/ { 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*/ { #ifdef GRAPHICS #ifdef WINDOWS4D SetWindowPosition(0, recScrWidth, 0, recScrHeight); #endif #endif phsco = false; } void Do2VideoScreen() /*Makes the current window go to twice the video screen*/ { #ifdef GRAPHICS #ifdef WINDOWS4D SetWindowPosition(0, 2 * recScrWidth, 0, 2 * recScrHeight); #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*/ { } static Bool TrueBool() /*Boolean routine that returns true*/ { } 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*/ #if 0 singlebuffer(); cmode(); zbuffer(FALSE); gconfig(); #endif 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 -> mainMenu = 0; for (k = 0; k < NMENUS; ++k) { newInfo -> subMenus[k] = 0; } newInfo -> nMenuItems = 0; newInfo -> minWidth = minWidth; newInfo -> maxWidth = maxWidth; newInfo -> minHeight = minHeight; newInfo -> maxHeight = maxHeight; if (windowID) { /*Set to the current window and set the graphics state*/ SetMode(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 /*Return the new info*/ return newInfo; } else { /*Failed to allocate info. Return NIL*/ OMErr(); return (WinInfoPtr) 0; } } void SetWindowTitle(win, title) ObjPtr win; char *title; /*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 } #ifdef PROTO void ContentsExpectWindowSize(WinInfoPtr window, int sizeX, int sizeY) #else void ContentsExpectWindowSize(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); } } 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; } 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.*/ if (logging) { Log("close\n"); } /*First check for hide routine*/ closeRoutine = GetMethod((ObjPtr) *runner, HIDE); if (closeRoutine && IsTrue((*closeRoutine)(*runner))) { #ifdef GRAPHICS #ifdef WINDOWS4D #ifdef WINNOCLOSE cachedWindows[nCachedWindows] = (*runner) -> id; ++nCachedWindows; SelWindow(*runner); minsize(100, 100); maxsize(1280, 1024); winconstraints(); winposition(-200, -100, -200, -100); #else winclose((*runner) -> id); #endif #endif #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 GRAPHICS #ifdef WINDOWS4D #ifdef WINNOCLOSE cachedWindows[nCachedWindows] = (*runner) -> id; ++nCachedWindows; minsize(100, 100); maxsize(1280, 1024); winconstraints(); winposition(-200, -100, -200, -100); #else winclose((*runner) -> id); #endif #endif #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; } #ifdef WINNOCLOSE cachedWindows[nCachedWindows] = allWindows -> id; ++nCachedWindows; SelWindow(allWindows); #ifdef GRAPHICS #ifdef WINDOWS4D minsize(100, 100); maxsize(1280, 1024); winconstraints(); winposition(-200, -100, -200, -100); #else if (allWindows -> id) { winclose(allWindows -> id); allWindows -> id = 0; } #endif #endif #endif 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; } } 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; int prefDrawMoving; oldWindow = selWinInfo; ++updateBatch; prefDrawMoving = GetPrefInteger(PREF_DRAWMOVING); for (curWindow = allWindows; curWindow; curWindow = curWindow -> next) { FuncTyp method; if (curWindow -> id == 0) continue; if (AltDown() && (curWindow != inputWindow)) { continue; } method = GetMethod((ObjPtr) curWindow, MAKEDRAWN); if (method) { struct tms buffer; long beginDraw; if (GetVar((ObjPtr) curWindow, SPACE)) { /*It's a space, maybe move the skeleton*/ if (interactiveMoving) { if (prefDrawMoving == DM_SKELETON) { SetVar((ObjPtr) curWindow, MOVESKELETON, ObjTrue); drawingQuality = DQ_SKELETON; } else if (prefDrawMoving == DM_FULL) { SetVar((ObjPtr) curWindow, MOVESKELETON, ObjFalse); drawingQuality = DQ_FULL; } else if (prefDrawMoving == DM_AUTO) { beginDraw = times(&buffer); drawingQuality = GetPredicate((ObjPtr) curWindow, MOVESKELETON) ? DQ_SKELETON : DQ_FULL; } } else { SetVar((ObjPtr) curWindow, MOVESKELETON, ObjFalse); drawingQuality = DQ_FULL; } } if (IsTrue((*method)(curWindow))) { retVal = true; if (IsDoubleBuf(curWindow)) { SelWindow(curWindow); swapbuffers(); } } if (interactiveMoving) { if (prefDrawMoving == DM_AUTO && drawingQuality == DQ_FULL) { if (times(&buffer) > beginDraw + MAXMOVETIME) { /*Back off on drawing quality*/ SetVar((ObjPtr) curWindow, MOVESKELETON, ObjTrue); } else { SetVar((ObjPtr) curWindow, MOVESKELETON, ObjFalse); } } } } } if (oldWindow && (oldWindow != selWinInfo)) { SelWindow(oldWindow); } #endif return retVal; } 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; } /*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 < 9) { /*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 < 9) { 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_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; } hasOverDraw = false; pupForOverDraw = false; #ifdef GD_BITS_OVER_SNG_CMODE if (getgdesc(GD_BITS_OVER_SNG_CMODE)) { hasOverDraw = true; pupForOverDraw = false; if (showConfig) { printf("There are overlay planes.\n"); } } #endif #ifdef GD_BITS_PUP_SNG_CMODE if (!hasOverDraw && (getgdesc(GD_BITS_PUP_SNG_CMODE))) { hasOverDraw = true; pupForOverDraw = true; if (showConfig) { printf("There are popup planes.\n"); } } #endif #ifdef GD_BITS_OVERLAY if (!hasOverDraw && (getgdesc(GD_BITS_OVERLAY) > 0)) { hasOverDraw = true; pupForOverDraw = false; if (showConfig) { printf("There are overlay planes.\n"); } } #endif if ((!hasOverDraw) && showConfig) { printf("There are no overlay planes.\n"); } if (getenv("SCIAN_VETO_OVERLAY")) { if (showConfig) { printf("Overlay planes vetoed.\n"); } hasOverDraw = false; } if (getenv("SCIAN_FORCE_OVERLAY")) { if (showConfig) { printf("Overlay planes forced.\n"); } hasOverDraw = true; } #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); SetMode(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); SetMode(window); ImInvalid((ObjPtr) window); } else { /*Do nothing*/ } return ObjTrue; } void InitWindows() /*Initializes the window system*/ { long dim; STAGX = 100; STAGY = SCRHEIGHT - 200; 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); #ifdef GRAPHICS if (nFonts) { int k; Bool subMenuP; char mainFontName[300]; char *s, *d, *f; /*Make the fonts submenu*/ strcpy(mainFontName, ""); subMenuP = false; fontSubMenu = newpup(); for (k = 0; k < nFonts; ++k) { Bool matches; f = strrchr(fonts[k], '-'); /*See if this one matches what's in the old name*/ if (mainFontName[0]) { s = mainFontName; d = fonts[k]; while (*s == *d) { ++s; ++d; } if (d == f || *d == 0) { matches = true; } else { matches = false; } } else { matches = false; } /*See if we need to finish up old font*/ if (mainFontName[0] && !matches) { if (subMenuP) { sprintf(tempStr, "%s%%m", mainFontName); addtopup(fontSubMenu, tempStr, styleSubMenus[nStyleSubMenus - 1]); } else { /*Just alone*/ sprintf(tempStr, "%s%%f%%x%d", fonts[k - 1], k - 1); addtopup(fontSubMenu, tempStr, MenuSetFont); } mainFontName[0] = 0; subMenuP = 0; } if (!mainFontName[0]) { /*It's a new main font name. Copy it in*/ s = fonts[k]; d = mainFontName; if (f) { while (s < f) { *d++ = *s++; } } else { while (*s) { *d++ = *s++; } } *d = 0; matches = true; if (f) { /*We know there are more than one; make a new submenu*/ if (nStyleSubMenus) { ++nStyleSubMenus; styleSubMenus = (long *) realloc(styleSubMenus, nStyleSubMenus * sizeof(long)); } else { nStyleSubMenus = 1; styleSubMenus = (long *) malloc(nStyleSubMenus * sizeof(long)); } styleSubMenus[nStyleSubMenus - 1] = newpup(); subMenuP = true; sprintf(tempStr, "%s%%f%%x%d", f + 1, k); addtopup(styleSubMenus[nStyleSubMenus - 1], tempStr, MenuSetFont); } else { /*This may be the only one. Don't make a submenu*/ } } else { /*It matches a current main font.*/ if (!subMenuP) { /*Create a submenu if it's not there, with Plain*/ if (nStyleSubMenus) { ++nStyleSubMenus; styleSubMenus = (long *) realloc(styleSubMenus, nStyleSubMenus * sizeof(long)); } else { nStyleSubMenus = 1; styleSubMenus = (long *) malloc(nStyleSubMenus * sizeof(long)); } styleSubMenus[nStyleSubMenus - 1] = newpup(); subMenuP = true; sprintf(tempStr, "Plain%%f%%x%d", k - 1); addtopup(styleSubMenus[nStyleSubMenus - 1], tempStr, MenuSetFont); } /*Now add us*/ sprintf(tempStr, "%s%%f%%x%d", f ? (f + 1) : "Plain", k); addtopup(styleSubMenus[nStyleSubMenus - 1], tempStr, MenuSetFont); } } /*See if we need to finish up old font*/ if (mainFontName[0]) { if (subMenuP) { sprintf(tempStr, "%s%%m", mainFontName); addtopup(fontSubMenu, tempStr, styleSubMenus[nStyleSubMenus - 1]); } else { /*Just alone*/ sprintf(tempStr, "%s%%f%%x%d", fonts[k - 1], k - 1); addtopup(fontSubMenu, tempStr, MenuSetFont); } mainFontName[0] = 0; } sizeSubMenu = newpup(); for (k = 0; k < (sizeof(textSizes) / sizeof(int)); ++k) { sprintf(tempStr, "%d%%f%%x%d", textSizes[k], textSizes[k]); addtopup(sizeSubMenu, tempStr, MenuSetSize); } } alignSubMenu = newpup(); sprintf(tempStr, "Align Left%%f%%x%d", LEFTALIGN); addtopup(alignSubMenu, tempStr, MenuSetAlignment); sprintf(tempStr, "Align Center%%f%%x%d", CENTERALIGN); addtopup(alignSubMenu, tempStr, MenuSetAlignment); sprintf(tempStr, "Align Right%%f%%x%d", RIGHTALIGN); addtopup(alignSubMenu, tempStr, MenuSetAlignment); #endif /*Create the clipboard*/ dim = 1; clipboard = NewArray(AT_OBJECT, 1, &dim); AddToReferenceList(clipboard); } void KillWindows() /*Kills the window system*/ { #ifdef GRAPHICS freepup(fontSubMenu); if (styleSubMenus) { free(styleSubMenus); } #endif DeleteThing(clipboard); DeleteThing(windowClass); }