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.
- *
- * wLists.c Handles screen, window, and icon lists.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include "wHandler.h"
- #include <libraries/dos.h>
-
- #define INTUIMESSAGE ((struct IntuiMessage *)theMessage)
-
-
-
- /*
- * FindScreen()
- *
- * Start with the first screen
- * While there are more screens and this one is not the one we want
- * Go on to the next screen
- * Return the scren found or NULL
- */
-
- WSCREEN *FindScreen(theScreen)
- struct Screen *theScreen;
- {
- WSCREEN *ChkScreen;
-
- Forbid();
- ChkScreen = FirstScreen;
- while (ChkScreen && ChkScreen->Screen != theScreen)
- ChkScreen = ChkScreen->Next;
- Permit();
- return(ChkScreen);
- }
-
-
- /*
- * LinkScreen()
- *
- * Link the screen structure into the link list of screens
- */
-
- void LinkScreen(theScreen)
- WSCREEN *theScreen;
- {
- Forbid();
- theScreen->Next = FirstScreen; theScreen->Prev = NULL;
- if (FirstScreen) FirstScreen->Prev = theScreen;
- FirstScreen = theScreen;
- Permit();
- }
-
-
- /*
- * UnLinkScreen()
- *
- * Unlink the screen from the linked list
- * If it is marked for refreshing, remove it from that linked list, too
- */
-
-
- void UnLinkScreen(theScreen)
- WSCREEN *theScreen;
- {
- Forbid();
- if (theScreen->Flags & WI_REFRESH) UnLinkRefresh(theScreen);
- if (theScreen->Next) theScreen->Next->Prev = theScreen->Prev;
- if (theScreen->Prev) theScreen->Prev->Next = theScreen->Next;
- else FirstScreen = theScreen->Next;
- Permit();
- }
-
-
- /*
- * NewWBScreen()
- *
- * Make the specified screen the new WB screen
- */
-
- void NewWBScreen(theScreen)
- WSCREEN *theScreen;
- {
- Forbid();
- if (theScreen == RealWB) WBScreen = NULL; else WBScreen = theScreen;
- Permit();
- }
-
-
- /*
- * WaitForWindows()
- *
- * If the screen has foreign windows or icons on it
- * Get a signal for this screen and clear it
- * Set the Close signal and task for this screen
- * While there are still icons or windows, wait for them to be closed
- * (we will get a signal when they do)
- * Free the signal
- */
-
- void WaitForWindows(theScreen)
- WSCREEN *theScreen;
- {
- ULONG mySignal;
- UBYTE mySigBit;
-
- if (theScreen && (theScreen->Window || theScreen->IconRef))
- {
- mySigBit = AllocSignal(-ONE);
- mySignal = (mySigBit == -ONE)? DEFAULTCLOSESIGNAL: (ONE<<mySigBit);
- SetSignal(mySignal,0L);
-
- Forbid();
- theScreen->CloseSignal = mySignal;
- theScreen->CloseTask = FindTask(NULL);
- Permit();
-
- while (theScreen->Window || theScreen->IconRef) Wait(mySignal);
-
- if (mySigBit != -ONE) FreeSignal(mySigBit);
- }
- }
-
-
- /*
- * StripMessages()
- *
- * Start with the first message in the message port
- * While we are not at the tail of the list
- * If the message belongs to the window we are closing
- * remove it from the port and reply to it
- * Go on to the next message
- */
-
- static void StripMessages(thePort,theWindow)
- struct MsgPort *thePort;
- struct Window *theWindow;
- {
- struct Node *theMessage,*nextMessage;
-
- theMessage = thePort->mp_MsgList.lh_Head;
- while (theMessage->ln_Succ)
- {
- nextMessage = theMessage->ln_Succ;
- if (INTUIMESSAGE->IDCMPWindow == theWindow)
- {
- Remove(theMessage);
- ReplyMsg(theMessage);
- }
- theMessage = nextMessage;
- }
- }
-
-
- /*
- * CloseIconWindow()
- *
- * If we have a screen to work with
- * And it has a backdrop window
- * If the window is active, deactivate it
- * If the window's UserPort is the common one
- * Strip out any messages belonging to this window
- * Clear the UserPort
- * Clear the IDCMP flags so no messages appear while we close it
- * Close the window and clear the screen's backdrop pointer
- */
-
- void CloseIconWindow(theScreen)
- WSCREEN *theScreen;
- {
- if (theScreen)
- {
- Forbid();
- if (theScreen->BackDrop)
- {
- if (theScreen->BackDrop == ActiveWindow) SetActiveWindow(NULL);
- if (theScreen->BackDrop->UserPort == wUserPort)
- {
- StripMessages(theScreen->BackDrop->UserPort,theScreen->BackDrop);
- theScreen->BackDrop->UserPort = NULL;
- ModifyIDCMP(theScreen->BackDrop,0L);
- }
- CloseWindow(theScreen->BackDrop);
- theScreen->BackDrop = NULL;
- }
- Permit();
- }
- }
-
-
- /*
- * FindWindow()
- *
- * If we have a window to look for
- * Find the screen the window is on
- * If the screen was found
- * Look through the window list of the screen for the given window
- * Return the window or NULL
- */
-
- WBWINDOW *FindWindow(theWindow)
- struct Window *theWindow;
- {
- WSCREEN *theScreen;
- WBWINDOW *ChkWindow = NULL;
-
- if (theWindow)
- {
- Forbid();
- theScreen = FindScreen(theWindow->WScreen);
- if (theScreen)
- {
- ChkWindow = theScreen->Window;
- while (ChkWindow && ChkWindow->Window != theWindow)
- ChkWindow = ChkWindow->Next;
- }
- Permit();
- }
- return(ChkWindow);
- }
-
-
- /*
- * LinkWindow()
- *
- * Add the window to the screen's window list
- */
-
- void LinkWindow(theWindow,theScreen)
- WBWINDOW *theWindow;
- WSCREEN *theScreen;
- {
- Forbid();
- theWindow->Screen = theScreen;
- theWindow->Next = theScreen->Window; theWindow->Prev = NULL;
- if (theScreen->Window) theScreen->Window->Prev = theWindow;
- theScreen->Window = theWindow;
- Permit();
- }
-
-
- /*
- * UnLinkWindow()
- *
- * Remove the window from the screen's window list
- */
-
- void UnLinkWindow(theWindow)
- WBWINDOW *theWindow;
- {
- Forbid();
- if (theWindow->Next) theWindow->Next->Prev = theWindow->Prev;
- if (theWindow->Prev) theWindow->Prev->Next = theWindow->Next;
- else theWindow->Screen->Window = theWindow->Next;
- Permit();
- }
-
-
- /*
- * NewIconWindow()
- *
- * If the screen is screen WBENCHSCREEN, then this is the real WB screen
- * Set the backdrop window UserData to point to the screen structure
- * Send the backdro pto the back (in case there are other backdrop windows)
- * If the screen is only one plane deep
- * Get an IntuiText from the menu list
- * If the text pen is the same as the screen's block pen (ie, the text
- * would be the same color as the menu background)
- * Change the backdrop window's detail and block pens so that the menus
- * will sho up OK
- * Add the wIconify title to the backdrop window
- * Show the screen title for this screen
- * Give the backdrop window the common UserPort
- * Set the IDCMP classes for the messages we want to receive
- * Report that a new screen has openned
- */
-
- void NewIconWindow(theScreen)
- WSCREEN *theScreen;
- {
- struct IntuiText *theText;
- extern struct MenuItem IconMenu[];
-
- Forbid();
- if ((theScreen->Screen->Flags & SCREENTYPE) == WBENCHSCREEN)
- RealWB = theScreen;
- Permit();
- theScreen->BackDrop->UserData = (BYTE *)theScreen;
- WindowToBack(theScreen->BackDrop);
- if (theScreen->Screen->BitMap.Depth == 1)
- {
- theText = (struct IntuiText *)IconMenu[0].ItemFill;
- if ((theText->FrontPen & 0x01) == theScreen->BackDrop->BlockPen)
- {
- theScreen->BackDrop->DetailPen = theText->FrontPen & 0x01;
- theScreen->BackDrop->BlockPen = 1 - theScreen->BackDrop->DetailPen;
- }
- }
- SetWindowTitles(theScreen->BackDrop,-1L,wIconifyTitle);
- ShowTitle(theScreen->Screen,TRUE);
- theScreen->BackDrop->UserPort = wUserPort;
- ModifyIDCMP(theScreen->BackDrop,IDCMPFLAGS);
- ReportMulti(WI_REPORTNEWSCREEN,theScreen->Screen,NULL);
- }
-
-
- /*
- * FindIcon()
- *
- * If we have a window to look for
- * Find the window's screen
- * If it was found
- * If the window is not a wIconify backdrop window
- * Search through the icon list for the given icon
- * Otherwise (the window is the backdrop window)
- * Use the screen's icon
- * Return the icon found or NULL
- */
-
- WICONREF *FindIcon(theWindow,theScreen)
- struct Window *theWindow;
- WSCREEN **theScreen;
- {
- WICONREF *theIcon = NULL;
-
- if (theWindow)
- {
- Forbid();
- *theScreen = FindScreen(theWindow->WScreen);
- if (*theScreen)
- {
- if (theWindow != (*theScreen)->BackDrop)
- {
- theIcon = (*theScreen)->IconRef;
- while (theIcon && theIcon->Window != theWindow)
- theIcon = theIcon->Next;
- } else {
- theIcon = &((*theScreen)->Icon);
- }
- }
- Permit();
- } else *theScreen = NULL;
- return(theIcon);
- }
-
-
- /*
- * LinkIcon()
- *
- * Link the Icon into the give screen's icon list
- */
-
- void LinkIcon(theIcon,theScreen)
- WICONREF *theIcon;
- WSCREEN *theScreen;
- {
- Forbid();
- theIcon->Screen = theScreen;
- theIcon->Next = theScreen->IconRef; theIcon->Prev = NULL;
- if (theScreen->IconRef) theScreen->IconRef->Prev = theIcon;
- theScreen->IconRef = theIcon;
- Permit();
- }
-
-
- /*
- * UnLinkIcon()
- *
- * Remove the icon from the screen's icon list
- */
-
- void UnLinkIcon(theIcon)
- WICONREF *theIcon;
- {
- Forbid();
- if (theIcon->Next) theIcon->Next->Prev = theIcon->Prev;
- if (theIcon->Prev) theIcon->Prev->Next = theIcon->Next;
- else theIcon->Screen->IconRef = theIcon->Next;
- Permit();
- }
-
-
- /*
- * RemoveAutoIcons()
- *
- * If a screen was specified
- * Start with the first icon on the screen
- * While there are more icons
- * If the icon is so be removed automatically when the screen closes
- * If the remove event is to be reported, do so
- * If the icon has a window, restore the it
- * Delete the icon from memory
- * Go on to the next icon
- */
-
- void RemoveAutoIcons(theScreen)
- WSCREEN *theScreen;
- {
- WICONREF *theIcon,*nextIcon;
-
- if (theScreen)
- {
- theIcon = theScreen->IconRef;
- while (theIcon)
- {
- nextIcon = theIcon->Next;
- if (theIcon->Icon.Flags & WI_AUTOREMOVE)
- {
- if (theIcon->Icon.Report & WI_REPORTAUTOREMOVE)
- ReportEvent(WI_REPORTAUTOREMOVE,theIcon);
- if (theIcon->Window) Restore(theIcon,TRUE);
- DeleteIcon(theIcon);
- }
- theIcon = nextIcon;
- }
- }
- }
-
-
- /*
- * ClearAllIcons()
- *
- * Remove the icons that can be removed automatically
- * Open all icons that have windows
- * While there are still icons on the screen, delete them
- * (probably not a good idea, but the wIconify window is going
- * to be closed, so the user won't be able to get to them anyway)
- */
-
- static void ClearAllIcons(theScreen)
- WSCREEN *theScreen;
- {
- RemoveAutoIcons(theScreen);
- OpenAllIcons(theScreen);
- while (theScreen->IconRef) DeleteIcon(theScreen->IconRef);
- }
-
-
- /*
- * AttemptQuit()
- *
- * If we have not got an end singal yet
- * Allocate one and clear it
- * Set the current WB screen to NULL so new windows will open on the WB
- * Start with the first screen
- * While there are more screens
- * If the screen has icons, try to clear them
- * Close the wIconify backdrop window
- * If the screen has no more foreign windows or icons
- * Remove the screen from the list
- * If the screen is one that wIconify created, close it
- * Free the screen structure
- * Otherwise (it has windows or icons on it, so can't be closed)
- * Count the number of screens that can't be closed yet
- * Go on to the next screen
- * Return TRUE if all screen's are clear, otherwise return FALSE
- */
-
- int AttemptQuit()
- {
- WSCREEN *theScreen,*nextScreen;
- int ScreenCount = 0;
-
- if (EndSignal == 0)
- {
- EndSigBit = AllocSignal(-ONE);
- EndSignal = (EndSigBit == -ONE)? DEFAULTENDSIGNAL: (ONE<<EndSigBit);
- SetSignal(EndSignal,0L);
- }
- WBScreen = NULL;
-
- Forbid();
- theScreen = FirstScreen;
- while (theScreen)
- {
- nextScreen = theScreen->Next;
- if (theScreen->IconRef) ClearAllIcons(theScreen);
- CloseIconWindow(theScreen);
- if (theScreen->Window == NULL && theScreen->IconRef == NULL)
- {
- UnLinkScreen(theScreen);
- if (theScreen->Flags & WI_WSCREEN) CloseScreen(theScreen->Screen);
- FREESTRUCT(wScreen,theScreen);
- } else ScreenCount++;
- theScreen = nextScreen;
- }
- Permit();
- return(ScreenCount == 0);
- }
-
-
- /*
- * FreeAllLists()
- *
- * While there are more screens to look at
- * While there are more windows on the screen
- * Free the window structure and go on to the next one
- * While there are icons on the screen
- * If the icon was created by wIconify
- * Unlink the icon and cree it
- * Free the screen structure and go on to the next one
- */
-
- void FreeAllLists()
- {
- WSCREEN *theScreen,*tmpScreen;
- WBWINDOW *theWindow,*tmpWindow;
- WICONREF *theIcon,*tmpIcon;
-
- theScreen = FirstScreen;
- while (theScreen)
- {
- theWindow = theScreen->Window;
- while (theWindow)
- {
- tmpWindow = theWindow;
- theWindow = theWindow->Next;
- FREESTRUCT(wbWindow,tmpWindow);
- }
- theIcon = theScreen->IconRef;
- while (theIcon)
- {
- tmpIcon = theIcon;
- theIcon = theIcon->Next;
- if (tmpIcon->Icon.Flags & WI_SYSICON)
- {
- UnLinkIcon(tmpIcon);
- FREESTRUCT(wIconRef,tmpIcon);
- }
- }
- tmpScreen = theScreen;
- theScreen = theScreen->Next;
- FREESTRUCT(wScreen,tmpScreen);
- }
- }
-