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.
- *
- * wHandler.c The Input Handler and replacement routines for the
- * Intuition functions trapped by SetFunction().
- *
- * 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 "wHandler.h"
- #include "wMenu.h"
- #include <libraries/dosextens.h>
- #include <graphics/gfxbase.h>
-
-
- /*
- * The definition for wIconify BackDrop windows
- * (the IDCMPFlags are added later, since they share a UserPort)
- */
- static struct NewWindow BDWindow =
- {
- 0,0, 0,0, -1,-1, NULL,
- SIMPLE_REFRESH| NOCAREREFRESH| BACKDROP| BORDERLESS| REPORTMOUSE,
- NULL, NULL, NULL, NULL, NULL, 20,20, -1,-1, WBENCHSCREEN
- };
-
- extern struct wMenuItem OpenWindowMenu[];
-
- /*
- * Tells whether a screen is iconified (i.e., pushed off the bottom)
- */
- #define ISICONIFIED(s) ((s)->TopEdge > GfxBase->NormalDisplayRows)
-
-
-
- /*
- * CheckIconifiedScreen()
- *
- * If the front screen is iconified, move it to the back.
- * If there is an active window
- * If its screen is iconified
- * Look for the next uniconified screen
- * (Start over from the front of the list if we hit the end)
- * If we found an uniconified screen and it has a window
- * Activate the window
- * (i.e, try to make sure that windows on iconified screens never become
- * active. Give preference to forward screens rather than backward ones.
- * This may effect the use of some hot-key screen shufflers that activate
- * windows on the new front screen: pushing screens to the back will
- * still work fine, but pulling the back one to the front will fail).
- */
-
- static void CheckIconifiedScreen()
- {
- struct Screen *iScreen;
-
- Forbid();
- iScreen = IntuitionBase->FirstScreen;
- if (ISICONIFIED(iScreen)) ScreenToBack(iScreen);
- if (IntuitionBase->ActiveWindow)
- {
- iScreen = IntuitionBase->ActiveWindow->WScreen;
- if (ISICONIFIED(iScreen))
- {
- while (iScreen && ISICONIFIED(iScreen)) iScreen = iScreen->NextScreen;
- if (iScreen == NULL)
- {
- iScreen = IntuitionBase->FirstScreen;
- while (iScreen && ISICONIFIED(iScreen))
- iScreen = iScreen->NextScreen;
- }
- if (iScreen && iScreen->FirstWindow)
- ActivateWindow(iScreen->FirstWindow);
- }
- }
- Permit();
- }
-
-
- /*
- * wHandler()
- *
- * If we are in the process of ending, just return the list
- * Check for iconified screens
- * While there are events in the list
- * If they are mouse or key events
- * If the event matches the iconify-key specification (up or down)
- * If the event is the key or button up event
- * Get a new message to send to the wIconify process
- * Set up the values to pass to it
- * Send it to the handler process
- * Remove this event from the list
- * (ie, process key-up events, but just remove key-down events)
- * Otherwise, if the event matches the activation-key specification
- * If it's the key up event
- * Get the current active screen
- * Activate its wIconify window, if any
- * Remove this event from the list (as above)
- * If we are removing the event from the list, do so
- * Go on to the next event in the list
- * Return the (modified) list.
- */
-
- struct InputEvent *wHandler(EventList,data)
- struct InputEvent *EventList;
- APTR data;
- {
- struct InputEvent **EventPtr = &EventList;
- struct InputEvent *theEvent;
- struct wIconMessage *theMessage;
- WSCREEN *theScreen;
- int RemoveEvent = FALSE;
-
-
- if (EndSignal) return(EventList);
-
- CheckIconifiedScreen();
- while (theEvent = *EventPtr)
- {
- if (theEvent->ie_Class == IECLASS_RAWMOUSE ||
- theEvent->ie_Class == IECLASS_RAWKEY)
- {
- if ((theEvent->ie_Code | IECODE_UP_PREFIX) == IconifyKey &&
- (theEvent->ie_Qualifier & (IconifyQuals | IconifyDisquals))
- == IconifyQuals)
- {
- if (theEvent->ie_Code == IconifyKey)
- {
- if (NEWSTRUCT(wIconMessage,theMessage))
- {
- theMessage->Window = IntuitionBase->ActiveWindow;
- theMessage->Action = WI_ICONIFY;
- theMessage->Flags = WI_NOREPLY;
- if ((theEvent->ie_Qualifier & IconifyChange) == IconifyChange)
- theMessage->Flags |= WI_CHANGE;
- theMessage->Message.mn_ReplyPort = NULL;
- theMessage->Message.mn_Length = sizeof(struct wIconMessage);
- PutMsg(wIconPort,theMessage);
- }
- }
- RemoveEvent = TRUE;
- } else if ((theEvent->ie_Code | IECODE_UP_PREFIX) == ActivateKey &&
- (theEvent->ie_Qualifier & ActivateQuals) == ActivateQuals) {
- if (theEvent->ie_Code == ActivateKey)
- {
- Forbid();
- theScreen = FindScreen(IntuitionBase->ActiveScreen);
- if (theScreen && theScreen->BackDrop)
- ActivateWindow(theScreen->BackDrop);
- Permit();
- }
- RemoveEvent = TRUE;
- }
- }
- if (RemoveEvent)
- *EventPtr = theEvent->ie_NextEvent;
- else
- EventPtr = &(theEvent->ie_NextEvent);
- RemoveEvent = FALSE;
- }
- return(EventList);
- }
-
-
- #define TOUPPER(c) (((c)>='a'&&(c)<='z')?(c)-'a'+'A':c)
-
-
- /*
- * PrefixMatch()
- *
- * Case-insensitive prefix match. The empty string will match NULL pointers
- * and empty strings, but are not considered prefixes to any string.
- *
- * Return <0 if the first is smaller than the second,
- * =0 if the first is a prefix of the second,
- * >1 if the first is larger than the second.
- */
-
- int PrefixMatch(s1,s2)
- char *s1,*s2;
- {
- int match = -1;
-
- if (*s1)
- {
- if (s2)
- {
- while (TOUPPER(*s1) == TOUPPER(*s2) && *s2 != 0) s1++,s2++;
- if (*s1 == 0) match = 0; else match = *s1 - *s2;
- } else match = 1;
- } else if (s2 == NULL || *s2 == 0) match = 0;
- return(match);
- }
-
-
- /*
- * GetScreen()
- *
- * Find the screen where the window will open via the following rules:
- * If we are supposed to open on the active screen, get the active screen
- * Otherwise, if we are supposed to open on the current WB, get it
- * If we have found a screen
- * If the screen is the real WB, forget it (no changes needed)
- * If the screen is closing or iconified, forget it
- * If the screen we are opening on is not currently active
- * Get the actual screen pointer of the screen we are interested in
- * If it is not active, we should bring it to the front
- * return the WSCREEN we shoulod use (or NULL if no action)
- */
-
- static WSCREEN *GetScreen(BringToFront)
- int *BringToFront;
- {
- WSCREEN *theScreen = NULL;
- struct Screen *chkScreen = NULL;
-
- if (OpenWindowMenu[OW_ACTIVESCRN].Item.Flags & CHECKED)
- theScreen = FindScreen(IntuitionBase->ActiveScreen); else
- if (OpenWindowMenu[OW_CURRENTWB].Item.Flags & CHECKED)
- theScreen = WBScreen;
- if (theScreen)
- {
- if (theScreen == RealWB) theScreen = NULL; else
- if ((theScreen->Flags & WI_CLOSING) ||
- (theScreen->Icon.Icon.Flags & WI_ICONIFIED))
- theScreen = NULL;
- }
- if (theScreen) chkScreen = theScreen->Screen;
- else if (RealWB) chkScreen = RealWB->Screen;
- *BringToFront = (chkScreen != IntuitionBase->ActiveScreen);
- return(theScreen);
- }
-
-
- /*
- * CheckWindowSize()
- *
- * If the window has a drag bar
- * Check if it fits on the screen; if not, move it to a better spot
- * If the window has a sizing gadget or accepts NEWSIZE messages
- * If the window doesn't fint on the screen, shrink it so that it does
- * Return an indication of whether the size was modified
- */
-
- static int CheckWindowSize(newWindow)
- struct NewWindow *newWindow;
- {
- short x = newWindow->LeftEdge;
- short y = newWindow->TopEdge;
- short w = newWindow->Width;
- short h = newWindow->Height;
- short Sw = newWindow->Screen->Width;
- short Sh = newWindow->Screen->Height;
- int Sized = FALSE;
-
- if (newWindow->Flags & WINDOWDRAG)
- {
- if (x+w > Sw) x = newWindow->LeftEdge = (Sw > w)? Sw - w: 0;
- if (y+h > Sh) y = newWindow->TopEdge = (Sh > h)? Sh - h: 0;
- }
- if ((newWindow->Flags & WINDOWSIZING) || (newWindow->IDCMPFlags & NEWSIZE))
- {
- if (x < Sw && x+w > Sw) newWindow->Width = Sw - x, Sized = TRUE;
- if (y < Sh && y+h > Sh) newWindow->Height = Sh - y, Sized = TRUE;
- }
- return(Sized);
- }
-
-
- /*
- * cOpenWindow()
- *
- * If we have a new window and we are not in the process of ending Iconify
- * Get the screen where we should open, and the bring-to-front flag
- * If we have a screen to open on, and the window was opening on the WB
- * Get a new wbWindow structure for it
- * Copy the NewWindow info so we can change it
- * Change the window specification so that it opens on the right screen
- * If we are allowed to resize the window, check if it needs it
- * Try to open the window
- * If successful
- * Link the window into the screen's list of foreign windows
- * Send a resize message if the window was sized
- * Otherwise
- * Free the allocated structure (we won't be needing it)
- * Otherwise (it's not a window we're supposed to change)
- * If the real WB screen is open and this window is the WB backdrop
- * window (ie, LoadWB is trying to start the WB)
- * Copy the NewWindow structure so we can "fix" it
- * Set the width to something smaller
- * Move the window to the right side of the screen
- * Make it a regular non-backdrop window with a border
- * Add the sizing, dragging and depth gadgets
- * Then open the window
- * If the window was not opened yet, open it as a normal window
- * If we are supposed to bring a screen to the front and the window
- * was actually opened, bring the screen to front
- * Return the pointer to the opened window
- */
-
- struct Window *cOpenWindow(newWindow)
- struct NewWindow *newWindow;
- {
- struct Window *theWindow = NOWINDOW;
- struct NewWindow tmpWindow;
- WBWINDOW *WBWindow;
- WSCREEN *theScreen = NULL;
- int BringToFront = FALSE;
- int Sized = FALSE;
-
- if (newWindow && EndSignal == 0)
- {
- Forbid();
- theScreen = GetScreen(&BringToFront);
- if (theScreen && (newWindow->Type & SCREENTYPE) == WBENCHSCREEN)
- {
- if (NEWSTRUCT(wbWindow,WBWindow))
- {
- tmpWindow = *newWindow;
- tmpWindow.Screen = theScreen->Screen;
- tmpWindow.Type = CUSTOMSCREEN;
- if (OpenWindowMenu[OW_AUTORESIZE].Item.Flags & CHECKED)
- Sized = CheckWindowSize(&tmpWindow);
- theWindow = aOldOpenWindow(&tmpWindow);
- if (theWindow)
- {
- WBWindow->Window = theWindow;
- LinkWindow(WBWindow,theScreen);
- if (Sized) SendIntuiMessage(NEWSIZE,theWindow);
- } else {
- FREESTRUCT(wbWindow,WBWindow);
- }
- }
- } else if (RealWB && (newWindow->Flags & WBFLAGS) == WBFLAGS) {
- tmpWindow = *newWindow;
- tmpWindow.Width = WBWIDTH;
- tmpWindow.LeftEdge = RealWB->Screen->Width - WBWIDTH;
- tmpWindow.Flags &= ~(BORDERLESS | BACKDROP);
- tmpWindow.Flags |= WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH;
- theWindow = aOldOpenWindow(&tmpWindow);
- }
- Permit();
- }
- if (theWindow == NOWINDOW) theWindow = aOldOpenWindow(newWindow);
- if (BringToFront && theWindow != NOWINDOW) ScreenToFront(theWindow->WScreen);
- return(theWindow);
- }
-
-
- /*
- * ParentWindow()
- *
- * Get the parent window of the current one
- * If it has one, then
- * Find its icon
- * While the window we are looking at is iconified
- * Go to its parent and get its icon
- * If we did not find a window, use the screen's backdrop window
- * Return the window that we found
- */
-
- static struct Window *ParentWindow(theWindow)
- struct Window *theWindow;
- {
- WICONREF *theIcon;
- WSCREEN *theScreen = NULL;
-
- theWindow = theWindow->Parent;
- if (theWindow)
- {
- theIcon = FindIcon(theWindow,&theScreen);
- while (theIcon && (theIcon->Icon.Flags & WI_ICONIFIED))
- {
- theWindow = theWindow->Parent;
- theIcon = (theWindow)? FindIcon(theWindow,&theScreen): NULL;
- }
- }
- if (theWindow == NULL && theScreen) theWindow = theScreen->BackDrop;
- return(theWindow);
- }
-
-
- /*
- * FinishWindow()
- *
- * Find the icon of the window that is closing
- * If it has one, tell the Iconify process to remove it
- * Find the wbWindow structure of this window (if any)
- * If it has one (ie, it is opened on a foreign screen)
- * Unlink the window from the screen
- * If it was the last one on the screen, let the Iconify process know
- * (it may want to update the menu to include CLOSESCREEN)
- * Free the window structure
- * If the Iconify process was waiting to end, let it try now
- * Find the (first non-iconified) parent of this window
- * Close the window
- * If the screen was waiting to close, signal it that it can
- * Of Iconify wants to hear about this window, signal it
- * If Intuition would attempt to activate an iconified window,
- * Activate the first non-iconified parent window
- */
-
- static void FinishWindow(oldWindow,RemoveWindow)
- struct Window *oldWindow;
- void (*RemoveWindow)();
- {
- WBWINDOW *theWindow;
- APTR ScreenTask = NULL;
- ULONG ScreenSignal;
- ULONG IconSignal = 0;
- WICONREF *theIcon;
- WSCREEN *theScreen;
- struct Window *Parent,*OldParent;
-
- Forbid();
- theIcon = FindIcon(oldWindow,&theScreen);
- if (theIcon) SendIconMessage(WI_REMOVEICON,NULL,theScreen,theIcon);
- theWindow = FindWindow(oldWindow);
- if (theWindow)
- {
- ScreenTask = theWindow->Screen->CloseTask;
- ScreenSignal = theWindow->Screen->CloseSignal;
- UnLinkWindow(theWindow);
- if (theWindow->Screen->Window == NULL) IconSignal = CloseSignal;
- FREESTRUCT(wbWindow,theWindow);
- IconSignal |= EndSignal;
- }
- Parent = ParentWindow(oldWindow); OldParent = oldWindow->Parent;
- Permit();
- (*RemoveWindow)(oldWindow);
- if (ScreenTask) Signal(ScreenTask,ScreenSignal);
- if (IconSignal) Signal(IconTask,IconSignal);
- if (Parent && Parent != OldParent) ActivateWindow(Parent);
- }
-
-
- /*
- * cCloseWindow()
- *
- * We are finished with this window; use the old CloseWindow() routine
- * to remove it from the screen.
- */
-
- void cCloseWindow(oldWindow)
- struct Window *oldWindow;
- {
- extern void aOldCloseWindow();
-
- FinishWindow(oldWindow,&aOldCloseWindow);
- }
-
-
- /*
- * cOpenScreen()
- *
- * If the screen was opened OK, and the Iconify process is not ending
- * Look through the ignore-screen list for this screen
- * If it does not appear in the list
- * Get a new Screen sctructure for this screen
- * Open a BackDrop window of the correct size on this screen
- * Set up the screen's icon
- * If the BackDrop window opened OK
- * Link the screen into the list
- * Set the new window as the current WB window
- * else
- * Free the structure, we won't be needing it
- */
-
- void cOpenScreen(newScreen)
- struct Screen *newScreen;
- {
- WSCREEN *theScreen;
- struct Ignore *igScreen = IgnoreScreen;
- extern struct Window *OpenWindow();
- extern struct Menu wMenu[];
-
- if (newScreen && EndSignal == 0)
- {
- while (igScreen && PrefixMatch(igScreen->Title,newScreen->DefaultTitle))
- igScreen = igScreen->Next;
- if (igScreen == NULL)
- {
- if (NEWSTRUCT(wScreen,theScreen))
- {
- theScreen->Screen = newScreen;
- BDWindow.Screen = newScreen;
- BDWindow.Type = newScreen->Flags & SCREENTYPE;
- BDWindow.Width = newScreen->Width;
- BDWindow.Height = newScreen->Height;
- theScreen->BackDrop = OpenWindow(&BDWindow);
- theScreen->Icon.Icon.Name = newScreen->DefaultTitle;
- theScreen->Icon.Icon.Flags = WI_SCREENICON| DefaultScreenFlags;
- theScreen->Icon.Screen = theScreen;
- theScreen->Icon.Window = theScreen->BackDrop;
- if (theScreen->BackDrop)
- {
- LinkScreen(theScreen);
- NewIconWindow(theScreen);
- } else {
- FREESTRUCT(wScreen,theScreen);
- }
- }
- }
- }
- }
-
-
- /*
- * cCloseScreen()
- *
- * Look to see if the screen is in the list of screens with wIconify windows
- * If so,
- * Mark the screen as closing so we don't allow any more icons on it
- * If the screen is the current WB, clear the current WB
- * If the screen is the real WB screen (should never happen), forget it
- * Restore the screen's icon if it is iconified
- * Tell anyone who's interested that the screen is closing
- * Remove any icons we're allowed to remove
- * Wait for any foreign windows or other icons to be removed
- * If the current task is the wIconify handler process, unlink the screen
- * Otherwise send wIconify the message to remove the screen
- * Close the wIconify backdrop window
- * Close the screen itself and free the screen structure
- * Otherwise
- * Just close the screen
- */
-
- void cCloseScreen(oldScreen)
- struct Screen *oldScreen;
- {
- WSCREEN *theScreen;
-
- Forbid();
- theScreen = FindScreen(oldScreen);
- if (theScreen)
- {
- theScreen->Flags |= WI_CLOSING;
- if (theScreen == WBScreen) NewWBScreen(NULL);
- if (theScreen == RealWB) RealWB = NULL;
- Permit();
- Restore(&(theScreen->Icon),TRUE);
- ReportMulti(WI_REPORTSCREENCLOSE,theScreen->Screen,theScreen);
- RemoveAutoIcons(theScreen);
- WaitForWindows(theScreen);
- if (FindTask(NULL) == IconTask)
- UnLinkScreen(theScreen);
- else
- SendIconMessage(WI_REMSCREEN,NULL,theScreen,NULL);
- CloseIconWindow(theScreen);
- aOldCloseScreen(oldScreen);
- FREESTRUCT(wScreen,theScreen);
- } else {
- Permit();
- aOldCloseScreen(oldScreen);
- }
- }
-
-
- /*
- * cSetWindowTitles()
- *
- * If a window was specified and it is getting a new title
- * Look for the window's icon
- * If found, and if the icon has a gadget (ie, it is iconified)
- * Set the icon's title and center it
- * Tell wIconify to update the screen
- */
-
- void cSetWindowTitles(theWindow,wTitle,sTitle)
- struct Window *theWindow;
- UBYTE *wTitle,*sTitle;
- {
- WICONREF *theIcon;
- WSCREEN *theScreen;
-
- if (theWindow && wTitle != (UBYTE *)-ONE)
- {
- Forbid();
- theIcon = FindIcon(theWindow,&theScreen);
- if (theIcon && theIcon->Gadget)
- {
- theIcon->Gadget->IText.IText = (wTitle)? wTitle: "[No Title]";
- theIcon->Gadget->IText.LeftEdge =
- (((struct Image *)(theIcon->Gadget->Gadget.GadgetRender))->Width -
- IntuiTextLength(&theIcon->Gadget->IText)) / 2;
- SendIconMessage(WI_REDRAW,NULL,theIcon->Screen,NULL);
- }
- Permit();
- }
- }
-
-
- /*
- * cWindowToFront()
- *
- * If a window was specified and it is a BACKDROP window
- * If the current task is not the wIconify handler process
- * Find the icon for this window
- * If it was found and it is iconified, or if its screen was found
- * and the window is the wIconify backdrop window, don't allow the
- * window to be moved
- * Return TRUE if the window can be moved, FLASE otherwise
- */
-
- int cWindowToFront(theWindow)
- struct Window *theWindow;
- {
- int MoveIt = TRUE;
- WICONREF *theIcon;
- WSCREEN *theScreen;
-
- if (theWindow && (theWindow->Flags & BACKDROP))
- {
- if (FindTask(NULL) != IconTask)
- {
- theIcon = FindIcon(theWindow,&theScreen);
- if ((theIcon && (theIcon->Icon.Flags && WI_ICONIFIED)) ||
- (theScreen && theScreen->BackDrop == theWindow)) MoveIt = FALSE;
- }
- }
- return(MoveIt);
- }
-
- /*
- * cWindowToBack()
- *
- * If a window was specified and it is a BACKDROP window
- * If the current task is not the wIconify handler process
- * Find the icon for this window
- * If it was found and it is iconified, or if its screen was found
- * and the window is the wIconify backdrop window, don't allow the
- * window to be moved
- * Otherwise, the window is a BACKDROP window that is being
- * sent to the back, so it will fall behind the wIconify window
- * were the user will not be able to get at it, so iconify it
- * so it can be retrieved.
- * Return TRUE if the window can be moved, FLASE otherwise
- */
-
- int cWindowToBack(theWindow)
- struct Window *theWindow;
- {
- int MoveIt = TRUE;
- WICONREF *theIcon;
- WSCREEN *theScreen;
-
- if (theWindow && (theWindow->Flags & BACKDROP))
- {
- if (FindTask(NULL) != IconTask)
- {
- theIcon = FindIcon(theWindow,&theScreen);
- if ((theIcon && (theIcon->Icon.Flags & WI_ICONIFIED)) ||
- (theScreen && theScreen->BackDrop == theWindow)) MoveIt = FALSE;
- else SendIconMessage(WI_ICONIFY,theWindow,NULL,NULL);
- }
- }
- return(MoveIt);
- }
-
-
- /*
- * cActivateWindow()
- *
- * If a window was specified and it is a BACKDROP window
- * If the current process is not the wIconify process
- * Find the icon for this window
- * If found and it is iconified, don't all the window to be activated
- * Return TRUE if it can be activated, FALSE otherwise
- */
-
- int cActivateWindow(theWindow)
- struct Window *theWindow;
- {
- int Activate = TRUE;
- WICONREF *theIcon;
- WSCREEN *theScreen;
-
- if (theWindow && (theWindow->Flags & BACKDROP))
- {
- if (FindTask(NULL) != IconTask)
- {
- theIcon = FindIcon(theWindow,&theScreen);
- if (theIcon && (theIcon->Icon.Flags & WI_ICONIFIED)) Activate = FALSE;
- }
- }
- return(Activate);
- }
-
-
- /*
- * cBuildSysRequest()
- *
- * If wIconify is stil running
- * If a window was not specified
- * Get the process that is calling BuildSysRequest()
- * If it is really a process and it has an error window, use it
- * If there is still no window
- * Get the screen and bring-to-front flag as for normal windows
- * If it is for a different screen, use it's backdrop window
- * If we have a window to work with
- * If we don't already have a screen, get it
- * If the screen is the real WB, ignore it
- * If we got a screen
- * Allocate a new wbWindow structure
- * If this fails, use the original window (ie, don't switch its screen)
- * Get the system requester on the proper screen
- * If we actually got a window (not TRUE or FALSE)
- * If we have a wbWindow for this window, link it in
- * Bring the screen to the front, if necessary
- * If the process has a name, use it as the window title
- * Otherwise use "System Request" as usual
- * Otherwise, free the wbWindow, if it was allocated
- * Return the window created by the original BuildSysRequest
- */
-
- struct Window *cBuildSysRequest(theWindow,Body,PosText,NegText,Flags,w,h)
- struct Window *theWindow;
- struct IntuiText *Body,*PosText,*NegText;
- ULONG Flags;
- long w,h;
- {
- extern struct Window *aOldBuildSysRequest();
- struct Process *theProc = NULL;
- struct Window *onWindow = theWindow;
- struct Window *newWindow;
- WBWINDOW *WBWindow = NULL;
- WSCREEN *theScreen = NULL;
- int BringToFront = FALSE;
- char *theTitle;
-
- Forbid();
- if (EndSignal == 0)
- {
- if (onWindow == NULL)
- {
- theProc = (struct Process *)FindTask(NULL);
- if (theProc->pr_Task.tc_Node.ln_Type == NT_PROCESS &&
- theProc->pr_WindowPtr != (APTR)-1)
- onWindow = (struct Window *)theProc->pr_WindowPtr;
- if (onWindow == NULL)
- {
- theScreen = GetScreen(&BringToFront);
- if (theScreen) onWindow = theScreen->BackDrop;
- }
- }
- if (onWindow)
- {
- if (theScreen == NULL) theScreen = FindScreen(onWindow->WScreen);
- if (theScreen == RealWB) theScreen = NULL;
- if (theScreen)
- if (NEWSTRUCT(wbWindow,WBWindow) == NULL) onWindow = theWindow;
- }
- }
- newWindow = aOldBuildSysRequest(onWindow,Body,PosText,NegText,Flags,w,h);
- if (newWindow && newWindow != (struct Window *)TRUE)
- {
- if (WBWindow)
- {
- WBWindow->Window = newWindow;
- LinkWindow(WBWindow,theScreen);
- }
- if (BringToFront) ScreenToFront(newWindow->WScreen);
- if (theProc && theProc->pr_Task.tc_Node.ln_Name)
- theTitle = theProc->pr_Task.tc_Node.ln_Name;
- else
- theTitle = "System Request";
- SetWindowTitles(newWindow,theTitle,-1L);
- } else {
- if (WBWindow) FREESTRUCT(wbWindow,WBWindow);
- }
- Permit();
- return(newWindow);
- }
-
-
- /*
- * cFreeSysRequest()
- *
- * We are finished with this requester; use the old FreeSysRequest() routine
- * to remove it from the screen.
- */
-
- void cFreeSysRequest(oldWindow)
- struct Window *oldWindow;
- {
- extern void aOldFreeSysRequest();
-
- FinishWindow(oldWindow,&aOldFreeSysRequest);
- }
-
-
- /*
- * cAutoRequest()
- *
- * Use (the modified) BuildSysRequest() to get a system requester
- * If we got a window (not TRUE or FALSE)
- * Get the signal bit for the window's port
- * While we are not done with the requester
- * While there are more messages in the port
- * Get the message info and reply to the message
- * If the message is one of the positive ones, end with TRUE
- * If it is one of the negative ones, end with FALSE
- * If it is a key event and the left amiga key id down
- * If it is left-amiga-B, cancel the requester
- * If it is left-amiga-V, retry the requester
- * If it is a gadget event
- * If the gadget is the negative one, end with FALSE
- * If it is the positive one, end with TRUE
- * If we are not done yet, Wait() for more messages
- * Finish up the system requester
- * Otherwise return the answer obtained from BuildSysRequest()
- * Return the result (TRUE or FALSE)
- */
-
- int cAutoRequest(theWindow,Body,PosText,NegText,PFlags,NFlags,w,h)
- struct Window *theWindow;
- struct IntuiText *Body,*PosText,*NegText;
- ULONG PFlags,NFlags;
- long w,h;
- {
- struct Window *newWindow;
- struct IntuiMessage *theMessage;
- struct Gadget *theGadget;
- ULONG Signal,Class;
- USHORT Code,Qual;
- int Result = NOTDONE;
- extern struct IntuiMessage *GetMsg();
- extern struct Window *BuildSysRequest();
-
- newWindow = BuildSysRequest(theWindow,Body,PosText,NegText,
- GADGETUP|RAWKEY|PFlags|NFlags,w,h);
- if (newWindow && newWindow != (struct Window *)TRUE)
- {
- Signal = (1 << newWindow->UserPort->mp_SigBit);
- while (Result == NOTDONE)
- {
- while (theMessage = GetMsg(newWindow->UserPort))
- {
- Class = theMessage->Class;
- Code = theMessage->Code;
- Qual = theMessage->Qualifier;
- theGadget = (struct Gadget *)theMessage->IAddress;
- ReplyMsg(theMessage);
- if (Class & PFlags) Result = TRUE; else
- if (Class & NFlags) Result = FALSE; else
- if (Class == RAWKEY && (Qual & AMIGALEFT))
- {
- if (Code == KEYCODE_B) Result = FALSE; else
- if (Code == KEYCODE_V) Result = TRUE;
- } else if (Class == GADGETUP) {
- if (theGadget->GadgetText == NegText) Result = FALSE; else
- if (theGadget->GadgetText == PosText) Result = TRUE;
- }
- }
- if (Result == NOTDONE) Wait(Signal);
- }
- FreeSysRequest(newWindow);
- } else Result = (int) newWindow;
- return(Result);
- }
-
-
-
-
- /*
- * SendIconMessage()
- *
- * Set up the data for the IconMessage
- * If the current task is the wIconify process
- * Call the event routine with the dummy message
- * Otherwise
- * Create a reply port
- * If successful
- * Set the message reply port
- * Send the message to the wIconify process
- * Wait for the reply
- * Remove the port
- */
-
- void SendIconMessage(theAction,theWindow,theScreen,theIcon)
- int theAction;
- struct Window *theWindow;
- WSCREEN *theScreen;
- WICONREF *theIcon;
- {
- struct wIconMessage theMessage;
- struct MsgPort *thePort;
- extern struct wIconMessage *WaitPort();
- extern struct MsgPort *CreatePort();
-
- theMessage.Window = theWindow;
- theMessage.Icon = theIcon;
- theMessage.Action = theAction;
- theMessage.Flags = 0;
- theMessage.Data.wScreen = theScreen;
- if (FindTask(NULL) == IconTask)
- {
- DoIconEvent(&theMessage,TRUE);
- } else {
- thePort = CreatePort(NULL);
- if (thePort)
- {
- theMessage.Message.mn_ReplyPort = thePort;
- theMessage.Message.mn_Length = sizeof(struct wIconMessage);
- PutMsg(wIconPort,&theMessage);
- WaitPort(thePort);
- DeletePort(thePort);
- }
- }
- }
-
-
- /*
- * SendIntuiMessage()
- *
- * If the window has a message port and it accepts this type of message
- * Allocate a new IntuiMessage structure
- * If successful
- * Set the important IntuiMessage fields
- * Use the wIconify UserPort as the reply port (the wIconify process
- * will clean up after us)
- * Send the message to the window
- */
-
- void SendIntuiMessage(theClass,theWindow)
- ULONG theClass;
- struct Window *theWindow;
- {
- struct IntuiMessage *theMessage;
-
- if (theWindow && theWindow->UserPort && (theWindow->IDCMPFlags & theClass))
- {
- if (NEWSTRUCT(IntuiMessage,theMessage))
- {
- theMessage->Class = theClass;
- theMessage->Qualifier = 0;
- theMessage->Code = 0;
- theMessage->MouseX = theMessage->MouseY = 0;
- theMessage->IAddress = NULL;
- theMessage->IDCMPWindow = theWindow;
- theMessage->SpecialLink = NULL;
- theMessage->ExecMessage.mn_ReplyPort = wUserPort;
- theMessage->ExecMessage.mn_Length = sizeof(struct IntuiMessage);
- PutMsg(theWindow->UserPort,theMessage);
- }
- }
- }
-