home *** CD-ROM | disk | FTP | other *** search
- /*
- * WICONIFY A utility that allows you to iconify any Intuition window
- * on any screen, and to open WB windows on any screen.
- *
- * wScreen.c Handles menu and screen functions.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #define INTUITION_PREFERENCES_H /* don't need 'em */
- #include <intuition/intuitionbase.h>
- #include <libraries/dosextens.h>
- #include "wHandler.h"
- #include "wMenu.h"
-
-
- #define SCREENMEM(p) RASSIZE(p.Width,p.Height*p.Depth)
-
- #define RED(i) (((Color[i])>>8)&0x0F)
- #define GREEN(i) (((Color[i])>>4)&0x0F)
- #define BLUE(i) ( (Color[i]) &0x0F)
-
- /*
- * The newScreen structure for wIconify screens
- */
- static struct NewScreen IconScreen =
- {0,0, 640,200,2, 0,1, HIRES,CUSTOMSCREEN, NULL,"wIconify Screen",NULL,NULL};
-
- static struct Window *PreviousWindow;
-
- static char *LockName = "UnLock";
- extern struct wMenuItem OpenWindowMenu[],
- NewScreenMenu[],
- IconMenu[],
- ScreenMenu[];
-
- /*
- * Macros for modifying the menus during menu update
- */
- #define ENABLESCREEN(n) ScreenMenu[n].Item.Flags |= ITEMENABLED
- #define DISABLESCREEN(n) ScreenMenu[n].Item.Flags &= ~ITEMENABLED
- #define ENABLEICON(n) IconMenu[n].Item.Flags |= ITEMENABLED
- #define DISABLEICON(n) IconMenu[n].Item.Flags &= ~ITEMENABLED
- #define CHECKITEM(n) NewScreenMenu[n].Item.Flags |= CHECKED
- #define UNCHECKITEM(n) NewScreenMenu[n].Item.Flags &= ~CHECKED
- #define ISCHECKED(n) (NewScreenMenu[n].Item.Flags & CHECKED)
- #define SETLOCK(n)\
- (((struct IntuiText *)(IconMenu[n].Item.ItemFill))->IText = &LockName[2])
- #define SETUNLOCK(n)\
- (((struct IntuiText *)(IconMenu[n].Item.ItemFill))->IText = LockName)
-
-
- /*
- * SetScreenMenu()
- *
- * Check the correct HIRES/LORES menu
- * Check or uncheck the INTERLACE and HAM menus
- */
-
- void SetScreenMenu(Modes)
- UWORD Modes;
- {
- if (Modes & HIRES)
- {
- CHECKITEM(NS_HIRES);
- UNCHECKITEM(NS_LORES);
- } else {
- CHECKITEM(NS_LORES);
- UNCHECKITEM(NS_HIRES);
- }
- if (Modes & LACE) CHECKITEM(NS_INTERLACE); else UNCHECKITEM(NS_INTERLACE);
- if (Modes & HAM) CHECKITEM(NS_HAM); else UNCHECKITEM(NS_HAM);
- }
-
-
- /*
- * SetActiveMenu()
- *
- * Get the screen from the backdrop window
- * If the screen is the RealWB, don't allow it to be iconified
- * If the screen is the current WB or it is in the process of closing
- * or real WB is the current WB and so is the screen we are using
- * don't allow the MAKEWB menu
- * Don't allow the CLOSESCREEN item, unless...
- * If the screen is a wIconify screen and it has no windows
- * And the only icons on the screen are AUTOREMOVE icons
- * Then allow CLOSESCREEN
- * If the active backdrop window has changed, update the NEWSCREEN menus
- * If there are icons on the screen
- * Enable CLEANUP, ORGANIZE and OPENALL
- * Otherwise disable them
- * Disable the CLOSE item, unless...
- * If there are selected icons
- * Enable OPEN and UNLOCK and disable CLEANUP, unless..
- * While ther eare more selected gadgets
- * If the gadget is allowed to be close, enable CLOSE
- * If the gadget is not locked
- * Set the UNLOCK menu to LOCK
- * If the icon can be organized, enable CLEANUP
- * Go on to the next selected icon
- * Otherwise (no selected icons) disable OPEN and LOCK
- * If the screen can hold the tallest menu, set the menu strip
- */
-
- static void SetActiveMenu(theWindow)
- struct Window *theWindow;
- {
- WSCREEN *theScreen;
- WICONREF *theIcon;
- struct wGadget *theGadget;
-
- Forbid();
- theScreen = (WSCREEN *)theWindow->UserData;
- if (theScreen == RealWB) DISABLESCREEN(SM_ICONIFY);
- else ENABLESCREEN(SM_ICONIFY);
- if (theScreen == WBScreen || (theScreen->Flags & WI_CLOSING) ||
- (WBScreen == NULL && theScreen == RealWB))
- DISABLESCREEN(SM_MAKEWB); else ENABLESCREEN(SM_MAKEWB);
- DISABLESCREEN(SM_CLOSESCREEN);
- if ((theScreen->Flags & WI_WSCREEN) && theScreen->Window == NULL)
- {
- theIcon = theScreen->IconRef;
- while (theIcon && ((theIcon->Icon.Flags & WI_AUTOREMOVE)))
- theIcon = theIcon->Next;
- if (theIcon == NULL) ENABLESCREEN(SM_CLOSESCREEN);
- }
- if (ActiveWindow != PreviousWindow)
- SetScreenMenu(theScreen->Screen->ViewPort.Modes);
-
- if (theScreen->BackDrop->FirstGadget)
- {
- ENABLEICON(IM_CLEANUP);
- ENABLEICON(IM_ORGANIZE);
- ENABLEICON(IM_OPENALL);
- } else {
- DISABLEICON(IM_CLEANUP);
- DISABLEICON(IM_ORGANIZE);
- DISABLEICON(IM_OPENALL);
- }
- DISABLEICON(IM_CLOSE);
- if (theScreen->Selected)
- {
- ENABLEICON(IM_OPEN);
- ENABLEICON(IM_LOCK); SETUNLOCK(IM_LOCK);
- DISABLEICON(IM_CLEANUP);
- theGadget = theScreen->Selected;
- while (theGadget)
- {
- if ((GADGETICON->Icon.Flags & WI_NOCLOSE) == FALSE)
- ENABLEICON(IM_CLOSE);
- if ((GADGETICON->Icon.Flags & WI_LOCKED) == FALSE)
- {
- SETLOCK(IM_LOCK);
- if ((GADGETICON->Icon.Flags & WI_NOORGANIZE) == FALSE)
- ENABLEICON(IM_CLEANUP);
- }
- theGadget = theGadget->NextSelect;
- }
- } else {
- DISABLEICON(IM_OPEN);
- DISABLEICON(IM_LOCK); SETLOCK(IM_LOCK);
- }
- Permit();
- if (theScreen->Screen->Height >= TOTAL_MENUH)
- SetMenuStrip(ActiveWindow,wMenu);
- }
-
-
- /*
- * SetWindowMenu()
- *
- * If a backdrop window is active, remove its menu strip
- * If the OpenOn type has changed
- * Check and uncheck the correct items in the menu
- * If SizeToFit has changed
- * Check or uncheck it
- * If a backdrop window was active, add the menu strip again
- */
-
- void SetWindowMenu(ScreenType,SizeToFit)
- int ScreenType,SizeToFit;
- {
- short i;
-
- if (ActiveWindow) ClearMenuStrip(ActiveWindow);
- Forbid();
- if (ScreenType != NOCHANGE)
- {
- for (i=OW_ACTIVESCRN; i<=OW_REALWB; i++)
- {
- if (i == ScreenType)
- OpenWindowMenu[i].Item.Flags |= CHECKED;
- else
- OpenWindowMenu[i].Item.Flags &= ~CHECKED;
- }
- }
- if (SizeToFit != NOCHANGE)
- {
- if (SizeToFit)
- OpenWindowMenu[OW_AUTORESIZE].Item.Flags |= CHECKED;
- else
- OpenWindowMenu[OW_AUTORESIZE].Item.Flags &= ~CHECKED;
- }
- Permit();
- if (ActiveWindow) SetActiveMenu(ActiveWindow);
- }
-
-
- /*
- * SetActiveWindow()
- *
- * If the window is not already the active one
- * If there is an old active one
- * Get the window's screen
- * If it has icons that are being dragged, cancel the dragging
- * Remove the menu strip
- * Report that the icon window is becoming inactive to anyone who cares
- * Set the new active window
- * If there is a new window
- * Clear any error message from the title
- * Setup the menu strip and add it
- * Record the fact that this was the last window active
- * Report the activation to anyone who wants to know
- */
-
- void SetActiveWindow(theWindow)
- struct Window *theWindow;
- {
- WSCREEN *theScreen;
-
- if (theWindow != ActiveWindow)
- {
- if (ActiveWindow)
- {
- theScreen = (WSCREEN *)ActiveWindow->UserData;
- if (theScreen->Flags & (WI_STARTDRAG| WI_DRAGGING))
- CancelDragging(theScreen);
- ClearMenuStrip(ActiveWindow);
- ReportMulti(WI_REPORTINACTIVE,ActiveWindow,theScreen);
- }
- ActiveWindow = theWindow;
- if (ActiveWindow)
- {
- if (ActiveWindow->ScreenTitle != wIconifyTitle)
- SetWindowTitles(ActiveWindow,-ONE,wIconifyTitle);
- SetActiveMenu(ActiveWindow);
- PreviousWindow = ActiveWindow;
- ReportMulti(WI_REPORTACTIVATE,ActiveWindow,ActiveWindow->UserData);
- }
- }
- }
-
-
- /*
- * UpdateActiveMenu()
- *
- * If there is an active window
- * Remove its menu, then set up and add the menu again
- */
-
- void UpdateActiveMenu()
- {
- if (ActiveWindow)
- {
- ClearMenuStrip(ActiveWindow);
- SetActiveMenu(ActiveWindow);
- }
- }
-
-
- /*
- * SetScreenColors()
- *
- * If the new scren depth is too big, clip it
- * For each color in the map, if no color was specified
- * Get it from the screen's color map (always should be the same)
- * Set the screen's color map to the specified colors
- */
-
- static void SetScreenColors(theScreen)
- struct Screen *theScreen;
- {
- short i;
- struct ViewPort *theVP = &(theScreen->ViewPort);
- short Depth = (1 << theScreen->BitMap.Depth);
-
- if (Depth > 32) Depth = 32;
- for (i=0; i<Depth; i++)
- if (Colors[i] == NOCOLOR) Colors[i] = GetRGB4(theVP->ColorMap,i);
- LoadRGB4(theVP,&Colors[0],Depth);
- }
-
-
- /*
- * DoNewScreen()
- *
- * Set the modes and width from the current screen according to whether
- * the new screen should be HIRES or not
- * Set the modes and height from the current screen according to whether
- * the new screen should be interlaced or not
- * Set the modes and depth for HAM screens
- * If there is enough CHIP memory for the screen plus some extra,
- * Attempt to open the screen
- * If successful
- * Set the new screen's color map
- * If the screen got a wIconify backdrop window (usually should)
- * Set the screen as a wIconify screen and as the new WB screen
- * Otherwise give an error
- */
-
- WSCREEN *DoNewScreen(Depth,oldScreen)
- UWORD Depth;
- struct Screen *oldScreen;
- {
- struct Screen *newScreen;
- WSCREEN *theScreen = NULL;
- UWORD Modes = oldScreen->ViewPort.Modes;
- extern long AvailMem();
-
- if (ISCHECKED(NS_HIRES))
- {
- IconScreen.ViewModes |= HIRES;
- IconScreen.Width = (Modes & HIRES)? oldScreen->Width: oldScreen->Width*2;
- if (Depth > 4) Depth = 4;
- } else {
- IconScreen.ViewModes &= ~HIRES;
- IconScreen.Width = (Modes & HIRES)? oldScreen->Width/2: oldScreen->Width;
- }
- if (ISCHECKED(NS_INTERLACE))
- {
- IconScreen.ViewModes |= LACE;
- IconScreen.Height = (Modes&LACE)? oldScreen->Height: oldScreen->Height*2;
- } else {
- IconScreen.ViewModes &= ~LACE;
- IconScreen.Height = (Modes&LACE)? oldScreen->Height/2: oldScreen->Height;
- }
- if (ISCHECKED(NS_HAM))
- {
- IconScreen.ViewModes |= HAM;
- Depth = 6;
- } else {
- IconScreen.ViewModes &= ~HAM;
- }
- IconScreen.Depth = Depth;
- if (AvailMem(MEMF_CHIP) > 125 * SCREENMEM(IconScreen) / 100)
- {
- newScreen = OpenScreen(&IconScreen);
- if (newScreen)
- {
- SetScreenColors(newScreen);
- if (theScreen = FindScreen(newScreen))
- {
- theScreen->Flags |= WI_WSCREEN;
- NewWBScreen(theScreen);
- }
- } else IconError("Can't open New Screen");
- } else IconError("Too low on memory to open New Screen");
- return(theScreen);
- }
-
-
- /*
- * DoScreenMenu()
- *
- * Do the right thing for each Screen menu item:
- * SCREENTOFRONT:
- * Send the screen to the front and activate it's backdrop
- * SCREENTOBACK:
- * Find the screen following this one
- * Send the screen to the back
- * If the following screen has a backdrop window, activate it
- * WBTOFRONT:
- * Get the current WB screen and bring it to the front
- * Activate its backdrop, if any
- * TOGGLETITLE:
- * Toggle the title for the screen
- * ICONIFY:
- * Set up a bogus message and call the Iconify routine to iconify it
- * MAKEWB:
- * Set the screen as the new WB screen
- * Activate the CurrentWB menu item
- * NEWCLI:
- * Create the NewCLI
- * NEWSCREEN:
- * Get the subcode
- * If it is a depth code
- * Create a new screen of the proper depth
- * If the screen was created and it has a backdrop window, activate it
- * CLOSESCREEN:
- * If the screen is a wIconify screen and it has no windows open on it
- * Report the screen close to those interested in it
- * (some icons may choose to close themselves)
- * Remove the auto-remove icons
- * If there are no icons left close the screen
- */
-
- int DoScreenMenu(theCode,theScreen,EndItAll)
- USHORT theCode;
- WSCREEN *theScreen;
- int EndItAll;
- {
- struct Screen *nextScreen;
- struct wIconMessage tmpMessage;
-
- switch(ITEMNUM(theCode))
- {
- case SM_TOFRONT:
- ScreenToFront(theScreen->Screen);
- ActivateWindow(theScreen->BackDrop);
- break;
-
- case SM_TOBACK:
- Forbid(); nextScreen = IntuitionBase->FirstScreen; Permit();
- if (nextScreen == theScreen->Screen)
- nextScreen = nextScreen->NextScreen;
- ScreenToBack(theScreen->Screen);
- theScreen = FindScreen(nextScreen);
- if (theScreen && theScreen->BackDrop)
- ActivateWindow(theScreen->BackDrop);
- break;
-
- case SM_WBTOFRONT:
- if (WBScreen) theScreen = WBScreen; else theScreen = RealWB;
- ScreenToFront(theScreen->Screen);
- if (theScreen->BackDrop) ActivateWindow(theScreen->BackDrop);
- break;
-
- case SM_TOGGLE:
- if (theScreen->Screen->Flags & SHOWTITLE)
- ShowTitle(theScreen->Screen,FALSE);
- else
- ShowTitle(theScreen->Screen,TRUE);
- break;
-
- case SM_ICONIFY:
- tmpMessage.Action = WI_ICONIFY;
- tmpMessage.Window = theScreen->BackDrop;
- tmpMessage.Flags = 0;
- DoIconify(&tmpMessage);
- break;
-
- case SM_MAKEWB:
- NewWBScreen(theScreen);
- SetWindowMenu(OW_CURRENTWB,NOCHANGE);
- break;
-
- case SM_NEWCLI:
- DoNewCLI(theScreen);
- break;
-
- case SM_NEWSCREEN:
- theCode = SUBNUM(theCode);
- if (theCode >= NS_DEPTH1 && theCode <= NS_DEPTH5)
- {
- theScreen = DoNewScreen(theCode-NS_DEPTH1+1,theScreen->Screen);
- if (theScreen && theScreen->BackDrop)
- ActivateWindow(theScreen->BackDrop);
- }
- break;
-
- case SM_CLOSESCREEN:
- if ((theScreen->Flags & WI_WSCREEN) && theScreen->Window == NULL)
- {
- ReportMulti(WI_REPORTSCREENCLOSE,theScreen->Screen,theScreen);
- RemoveAutoIcons(theScreen);
- if (theScreen->IconRef == NULL) CloseScreen(theScreen->Screen);
- }
- break;
- }
- Permit();
- return(EndItAll);
- }
-