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.
- *
- * wEvent.c Main event loop routines.
- *
- * 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 "wMenu.h"
-
- static char *IconAbout = COPYRIGHT; /* ABOUT... message */
-
- static WORD MouseX,MouseY; /* Saved mouse position */
- static WSCREEN *MouseScreen = NULL; /* Screen where mouse move occured */
- static WICONREF *PressedIcon; /* Icon to report a release event to */
-
- static WICON NullIcon = {NULL, NULL,NULL,NULL, 0,0,0, 0,NULL};
- /* an empty icon structure */
-
- extern struct Window *WindowToActivate;
-
-
- /*
- * DoVanillaKey()
- *
- * Then, if the right amiga key was pressed, and no shift is pressed,
- * Attempt to create a new screen of the required depth
- * If successful, activate the wIconify window on the screen
- */
-
- static void DoVanillaKey(Code,Qualifier,theWindow)
- USHORT Code;
- USHORT Qualifier;
- struct Window *theWindow;
- {
- WSCREEN *theScreen;
-
- if (Code >= '1' && Code <= '5')
- {
- if ((Qualifier & (AMIGARIGHT | SHIFTKEYS)) == AMIGARIGHT)
- {
- Code -= '0';
- theScreen = DoNewScreen(Code,theWindow->WScreen);
- if (theScreen && theScreen->BackDrop)
- ActivateWindow(theScreen->BackDrop);
- }
- }
- }
-
-
- /*
- * DoMouseButtons()
- *
- * Do the right thing for each of the event types:
- * SELECTDOWN:
- * Cancel any drag in progress (never should happen)
- * If there are any icons selected, deselect them
- *
- * SELECTUP:
- * If there is an icon to report a release event to, do it
- * Complete any dragging that is in progress
- * If there is a window to activate (due to a double-click), do it
- * (we wait until now so that the window does not get an unexpected
- * SELECTUP message when the mouse is released)
- *
- * MENUDOWN:
- * Cancel any dragging in progress
- *
- * MENUUP:
- * Cancel any dragging and close any selected icons (the only time we will
- * get menu buttons rather than menu events is when an icon is being
- * dragged)
- */
-
- static void DoMouseButtons(theMessage,theScreen)
- struct IntuiMessage *theMessage;
- WSCREEN *theScreen;
- {
- switch(theMessage->Code)
- {
- case SELECTDOWN:
- CancelDragging(theScreen);
- if (theScreen->Selected) DeselectAll(theScreen);
- break;
-
- case SELECTUP:
- if (PressedIcon) ReportEvent(WI_REPORTRELEASE,PressedIcon);
- EndDragging(theScreen,theMessage->MouseX,theMessage->MouseY);
- if (WindowToActivate)
- ActivateWindow(WindowToActivate),
- WindowToActivate = NULL;
- break;
-
- case MENUDOWN:
- CancelDragging(theScreen);
- break;
-
- case MENUUP:
- CancelDragging(theScreen);
- CloseSelected(theScreen);
- break;
- }
- PressedIcon = NULL;
- }
-
-
-
- /*
- * DoMouseMove()
- *
- * If mouse moves have occured,
- * If icons are being dragged on the given screen,
- * Move them to their new location
- * Reset for next move
- */
-
- void DoMouseMove()
- {
- if (MouseScreen)
- {
- if (MouseScreen->Flags & (WI_STARTDRAG| WI_DRAGGING))
- MoveGels(MouseScreen,MouseX,MouseY);
- MouseScreen = NULL;
- }
- }
-
-
- /*
- * EARLIERTIME checks if one time value is earlier than another.
- */
- #define EARLIERTIME(s1,m1,s2,m2) ((s1)<(s2)||((s1)==(s2)&&(m1)<(m2)))
-
-
- /*
- * DoGadgetDown()
- *
- * If the current message time is earlier than the previous time (ie, the
- * clock has been reset), then if the time is not zero (ie, it is not a
- * bogus time stamp from some other input handler) then clear the old times
- * If we have a double click
- * Cancel dragging in progress (never should happen)
- * Open the list of selected gadgets, but wait to activate the windows
- * until we get a mouse up event
- * Otherwise
- * If the gadget wants press events reported,
- * Report the event and save the pressed gadget for a release event
- * Select the pressed gadget
- * If the gadget has been selected, set up for dragging it
- * Record the time for double click checking.
- */
-
- static void DoGadgetDown(theGadget,theScreen,theMessage)
- struct wGadget *theGadget;
- WSCREEN *theScreen;
- struct IntuiMessage *theMessage;
- {
- static long Secs = 0, Mics = 0;
-
- if (EARLIERTIME(theMessage->Seconds,theMessage->Micros,Secs,Mics))
- if (theMessage->Seconds || theMessage->Micros) Secs = Mics = 0;
- if (DoubleClick(Secs,Mics,theMessage->Seconds,theMessage->Micros))
- {
- CancelDragging(theScreen);
- OpenSelected(theScreen,FALSE);
- } else {
- if (GADGETICON->Icon.Report & WI_REPORTPRESS)
- {
- ReportEvent(WI_REPORTPRESS,GADGETICON);
- PressedIcon = GADGETICON;
- }
- SelectIcon(GADGETICON,theMessage->Qualifier & SHIFTKEYS);
- if (theGadget->Gadget.Flags & SELECTED)
- StartDragging(GADGETICON,theMessage->MouseX,theMessage->MouseY);
- Secs = theMessage->Seconds;
- Mics = theMessage->Micros;
- }
- }
-
-
- /*
- * DoIconMenu()
- *
- * Do the right thing for each of the menu items (the routine names are
- * pretty self-explanitory).
- */
-
- static int DoIconMenu(theCode,theScreen,EndItAll)
- USHORT theCode;
- WSCREEN *theScreen;
- int EndItAll;
- {
- switch(ITEMNUM(theCode))
- {
- case IM_OPEN:
- OpenSelected(theScreen,TRUE);
- break;
-
- case IM_CLOSE:
- CloseSelected(theScreen);
- break;
-
- case IM_LOCK:
- LockSelected(theScreen);
- UpdateActiveMenu();
- break;
-
- case IM_CLEANUP:
- CleanUpIcons(theScreen);
- RefreshIcons(theScreen,TRUE);
- break;
-
- case IM_ORGANIZE:
- OrganizeIcons(theScreen);
- RefreshIcons(theScreen,TRUE);
- break;
-
- case IM_OPENALL:
- OpenAllIcons(theScreen);
- break;
-
- case IM_ABOUT:
- if (ActiveWindow)
- {
- SetWindowTitles(ActiveWindow,-ONE,IconAbout);
- ShowTitle(ActiveWindow->WScreen,TRUE);
- }
- break;
-
- case IM_END:
- DoEndIconify();
- break;
- }
- return(EndItAll);
- }
-
-
- /*
- * DoMenu()
- *
- * While there are more menu items to do
- * Get the menu item pointer
- * If it is an ICON menu item, do the ICON menu code
- * Otherwise do the SCREEN menu code
- * Go on to the next item
- */
-
- static int DoMenu(theCode,theScreen,EndItAll)
- USHORT theCode;
- WSCREEN *theScreen;
- int EndItAll;
- {
- struct MenuItem *theItem;
-
- while (theCode != MENUNULL)
- {
- theItem = ItemAddress(wMenu,theCode);
- switch(MENUNUM(theCode))
- {
- case ICON_MENU:
- EndItAll = DoIconMenu(theCode,theScreen,EndItAll);
- break;
-
- case SCREEN_MENU:
- EndItAll = DoScreenMenu(theCode,theScreen,EndItAll);
- break;
- }
- theCode = theItem->NextSelect;
- }
- return(EndItAll);
- }
-
-
- /*
- * DoEvent()
- *
- * Clear the ABOUT or error message from the screen title, if necessary
- * Get the screen of the wIconify window were the message occured
- * If the screen exists
- * If there are pending mouse moves and this is not a mouse move
- * Do the buffered mouse moves
- * Call the correct routine for each class of events
- */
-
- int DoEvent(theMessage,EndItAll)
- struct IntuiMessage *theMessage;
- int EndItAll;
- {
- WSCREEN *theScreen;
-
- if (ActiveWindow && ActiveWindow->ScreenTitle != wIconifyTitle)
- SetWindowTitles(ActiveWindow,-ONE,wIconifyTitle);
- theScreen = (WSCREEN *)theMessage->IDCMPWindow->UserData;
- if (theScreen)
- {
- if (MouseScreen && theMessage->Class != MOUSEMOVE) DoMouseMove();
- switch(theMessage->Class)
- {
- case MOUSEBUTTONS:
- DoMouseButtons(theMessage,theScreen);
- break;
-
- case GADGETDOWN:
- DoGadgetDown(theMessage->IAddress,theScreen,theMessage);
- break;
-
- case MENUPICK:
- CancelDragging(theScreen);
- EndItAll = DoMenu(theMessage->Code,theScreen,EndItAll);
- break;
-
- case MOUSEMOVE:
- MouseX = theMessage->MouseX;
- MouseY = theMessage->MouseY;
- MouseScreen = theScreen;
- break;
-
- case VANILLAKEY:
- DoVanillaKey(theMessage->Code,theMessage->Qualifier,
- theMessage->IDCMPWindow);
- break;
-
- case ACTIVEWINDOW:
- SetActiveWindow(theMessage->IDCMPWindow);
- WindowToActivate = NULL;
- break;
-
- case INACTIVEWINDOW:
- SetActiveWindow(NULL);
- WindowToActivate = NULL;
- break;
- }
- }
- return(EndItAll);
- }
-
-
- /*
- * DoIconify()
- *
- * Get the icon and screen of the given window
- * If the screen was located
- * but there was no icon for the window
- * Create a new icon structure, if possible
- * Make it point to the given window
- * Set its default flags and mark it as system-created
- * And link it into the icon list for its screen
- * If an icon exists or was allocated
- * If the icon is for a screen and dragging is in progress (ie, the
- * left button is down over an icon), and the message is a NOREPLY
- * message (ie, it came from the handler), then
- * Close the selected icons on the screen
- * Otherwise
- * If the icon wants to verify iconifications, report ICONVERIFY
- * Otherwise iconify the window
- */
-
- void DoIconify(theMessage)
- struct wIconMessage *theMessage;
- {
- WICONREF *theIcon;
- WSCREEN *theScreen;
-
- theIcon = FindIcon(theMessage->Window,&theScreen);
- if (theScreen)
- {
- if (theIcon == NULL)
- {
- if (NEWSTRUCT(wIconRef,theIcon))
- {
- theIcon->Window = theMessage->Window;
- theIcon->Icon.Flags |= WI_SYSICON | DefaultFlags;
- LinkIcon(theIcon,theScreen);
- }
- }
- if (theIcon)
- {
- if ((theIcon->Icon.Flags & WI_SCREENICON) &&
- (theIcon->Screen->Flags & (WI_STARTDRAG | WI_DRAGGING)) &&
- (theMessage->Flags & WI_NOREPLY))
- {
- CloseSelected(theIcon->Screen);
- } else {
- if (theIcon->Icon.Report & WI_REPORTICONVERIFY)
- ReportEvent(WI_REPORTICONVERIFY,theIcon);
- else
- Iconify(theIcon,theMessage->Flags & WI_CHANGE);
- }
- }
- }
- }
-
-
- /*
- * UpdateIcon()
- *
- * If there was no icon given, use the blank icon
- * Get the icon's screen and system flags
- * Copy the icon template to the existing icon
- * And replace the system flags from before
- * If the icon is currently iconified (ie, it has a gadget)
- * Get the gadget pointer
- * Remove the gadget temprarily so we can work on it
- * If no new position was given, retrieve the old one
- * Save the SELECTED flag
- * Setup the gadget to use the current icon data
- * If it used to be selected, re-select it
- * Replace the gadget on the screen and refresh the screen's icons
- */
-
- static void UpdateIcon(theIcon,WIcon)
- WICONREF *theIcon;
- WICON *WIcon;
- {
- WSCREEN *theScreen;
- ULONG Flags;
- int pos;
- struct Gadget *theGadget;
-
- if (WIcon == NULL) WIcon = &NullIcon;
- theScreen = theIcon->Screen;
- Flags = theIcon->Icon.Flags & WI_SYSTEMFLAGS;
- theIcon->Icon = *WIcon;
- theIcon->Icon.Flags = (WIcon->Flags & ~WI_SYSTEMFLAGS) | Flags;
- if (theIcon->Gadget)
- {
- theGadget = &(theIcon->Gadget->Gadget);
- if (theScreen->BackDrop)
- pos = RemoveGadget(theScreen->BackDrop,theGadget);
- if (WIcon->x == 0 && WIcon->y == 0)
- theIcon->Icon.x = theGadget->LeftEdge,
- theIcon->Icon.y = theGadget->TopEdge;
- Flags = theGadget->Flags & SELECTED;
- SetupGadget(theIcon);
- if (Flags) MakeSelected(theGadget);
- if (theScreen->BackDrop) AddGadget(theScreen->BackDrop,theGadget,pos);
- RefreshIcons(theScreen,TRUE);
- }
- }
-
-
- /*
- * DoSetIcon()
- *
- * Find the icon and screen of the given window
- * If the icon already exists, update it to the new values,
- * Otherwise, if the screen was found
- * Get a new Icon structure, if possible
- * Link it to the window
- * Copy the data from the template
- * Clear the system flags
- * If no template was given, add the default flags
- * Link the icon to the screen's icon list
- * Return the pointer to the IconRef structure
- */
-
- static void DoSetIcon(theWindow,WIcon,theMessage)
- struct Window *theWindow;
- WICON *WIcon;
- struct wIconMessage *theMessage;
- {
- WICONREF *theIcon;
- WSCREEN *theScreen;
-
- theIcon = FindIcon(theWindow,&theScreen);
- if (theIcon) UpdateIcon(theIcon,WIcon);
- else if (theScreen)
- {
- if (NEWSTRUCT(wIconRef,theIcon))
- {
- theIcon->Window = theWindow;
- theIcon->Icon = (WIcon)? *WIcon: NullIcon;
- theIcon->Icon.Flags &= ~WI_SYSTEMFLAGS;
- if (WIcon == NULL) theIcon->Icon.Flags |= DefaultFlags;
- LinkIcon(theIcon,theScreen);
- }
- }
- theMessage->Icon = theIcon;
- }
-
-
- /*
- * DoUnSetIcon()
- *
- * Find the icon and screen of the given window
- * If the icon was found
- * Restore the icon's window and remove the icon from the screen
- * Delete the icon from memory
- * Return the IconRef (which is no longer valid)
- */
-
- static void DoUnSetIcon(theWindow,theMessage)
- struct Window *theWindow;
- struct wIconMessage *theMessage;
- {
- WICONREF *theIcon;
-
- theIcon = FindIcon(theMessage->Window,&(theMessage->Data.wScreen));
- if (theIcon)
- {
- Restore(theIcon,TRUE);
- DeleteIcon(theIcon);
- }
- theMessage->Icon = theIcon;
- }
-
-
- /*
- * DoAddIcon()
- *
- * If a screen and an icon are given
- * Create a new Icon structure
- * Mark it as having no window associated with it
- * Copy the template icon
- * Clear the system flags
- * Link the icon into the screen's icon list
- * Iconify the icon (ie, make it show up on the screen
- * Return the newly created IconRef
- */
-
- static WICONREF *DoAddIcon(WIcon,theScreen)
- WICON *WIcon;
- WSCREEN *theScreen;
- {
- WICONREF *theIcon = NULL;
-
- if (theScreen && WIcon)
- {
- if (NEWSTRUCT(wIconRef,theIcon))
- {
- theIcon->Window = NULL;
- theIcon->Icon = *WIcon;
- theIcon->Icon.Flags &= ~WI_SYSTEMFLAGS;
- LinkIcon(theIcon,theScreen);
- Iconify(theIcon,FALSE);
- }
- }
- return(theIcon);
- }
-
-
- /*
- * DoSelectNext()
- *
- * If the screen has selected icons, start with the next one,
- * Otherwise start with the first icon on the screen
- * Skip over any non-iconified icons
- * If we hit the end of the list of icons
- * Start over at the begining of the list
- * Skip over any non-iconified icons (until we get back to were we started)
- * If we found a new icon to select, select it
- */
-
- static void DoSelectNext(theScreen)
- WSCREEN *theScreen;
- {
- WICONREF *theIcon,*InitialIcon;
-
- if (theScreen->Selected)
- InitialIcon = ((WICONREF *)(theScreen->Selected->Gadget.UserData))->Next;
- else
- InitialIcon = theScreen->IconRef;
- theIcon = InitialIcon;
- while (theIcon && (theIcon->Icon.Flags & WI_ICONIFIED) == FALSE)
- theIcon = theIcon->Next;
- if (theIcon == NULL)
- {
- theIcon = theScreen->IconRef;
- while (theIcon && (theIcon->Icon.Flags & WI_ICONIFIED) == FALSE &&
- theIcon != InitialIcon) theIcon = theIcon->Next;
- }
- if (theIcon) SelectIcon(theIcon,FALSE);
- }
-
-
- /*
- * DoIconEvent()
- *
- * Do the right thing for each type of message
- * ICONIFY: Do the iconification routine
- * RESTORE: Restore the given icon
- * ICONOF: Find the icon and screen of the given window
- * SETICON: Set the window's icon
- * UNSETICON: Remove the window's icon
- * SELECTICON: Attempt to select the indicated icon
- * UNSELECT: Remove the icon from the selection
- * MOVEICON:
- * If an icon was specified
- * Get the icon's screen
- * If the icon has a gadget and the screen has a wIconify window
- * Remove the gadget from the screen
- * Set the gadget's position to the one given in the message
- * Check the new position for validity
- * Put the gadget back on the screen
- * Refresh the icons on the screen
- * ADDICON: Add the given icon to the indicated screen
- * REMOVEICON: Delete the icon from memory
- * REDRAW: Refresh the icons on the given screen
- * UPDATEICON: Update the given icon with new values
- * BACKDROPOF:
- * Find the screen structure if the given screen
- * If found, return the backdrop window of the screen
- * Otherwise return NULL
- * REMSCREEN: Remove the given screen from the list of screens
- * CLOSEICON: Close the given icon
- * SELECTNEXT: Select the next icon on the given screen
- * NEWSCREEN:
- * If the real WB screen is open (to use as a template)
- * Change the active window (unsetting the menus)
- * Set the NewScreen menu to the given modes
- * Create the new screen and return its pointer
- * MAKEWB:
- * Find the indicated screen
- * If it is found and it has a wIconify window
- * Make this the current WB screen
- * Set the OpenWindow submenu to make CURRENT_WB checked
- * Activate the new WB screen's wIconify backdrop window
- * OPENSELECT: Open the selected icons on the given screen
- * CLOSESELECT: Close the selected icons on the given screen
- * OPENON: Set the OpenOn menu items
- * REPORTVERIFY: (returned ICONVERIFY message)
- * If the message was OKed, iconify the window
- * MAKECONTACT: (Initial message from the loader)
- * Check the loader's version and report OK or BAD
- * ENDICONIFY:
- * Try to end the process
- * Report to any programs that are interested
- * Try to exit when we have cleaned out all message from the ports
- */
-
- int DoIconEvent(theMessage,EndItAll)
- struct wIconMessage *theMessage;
- int EndItAll;
- {
- WSCREEN *theScreen;
- int pos;
-
- switch(theMessage->Action)
- {
- case WI_ICONIFY:
- DoIconify(theMessage);
- break;
-
- case WI_RESTORE:
- Restore(theMessage->Icon,TRUE);
- break;
-
- case WI_ICONOF:
- theMessage->Icon =
- FindIcon(theMessage->Window,&(theMessage->Data.wScreen));
- break;
-
- case WI_SETICON:
- DoSetIcon(theMessage->Window,theMessage->Icon,theMessage);
- break;
-
- case WI_UNSETICON:
- DoUnSetIcon(theMessage->Window,theMessage);
- break;
-
- case WI_SELECTICON:
- SelectIcon(theMessage->Icon,theMessage->Flags & WI_ADDTOSELECT);
- break;
-
- case WI_UNSELECT:
- DeselectIcon(theMessage->Icon);
- break;
-
- case WI_MOVEICON:
- if (theMessage->Icon)
- {
- theScreen = theMessage->Icon->Screen;
- if (theMessage->Icon->Gadget && theScreen->BackDrop)
- {
- pos = RemoveGadget(theScreen->BackDrop,theMessage->Icon->Gadget);
- theMessage->Icon->Gadget->Gadget.LeftEdge =
- theMessage->Data.Position.x;
- theMessage->Icon->Gadget->Gadget.TopEdge =
- theMessage->Data.Position.y;
- InitPosition(theMessage->Icon->Gadget);
- AddGadget(theScreen->BackDrop,theMessage->Icon->Gadget,pos);
- RefreshIcons(theMessage->Icon->Screen,TRUE);
- }
- }
- break;
-
- case WI_ADDICON:
- if (theMessage->Icon) theMessage->Icon =
- DoAddIcon(theMessage->Icon,FindScreen(theMessage->Data.Screen));
- break;
-
- case WI_REMOVEICON:
- if (theMessage->Icon) DeleteIcon(theMessage->Icon);
- break;
-
- case WI_REDRAW:
- RefreshIcons(theMessage->Data.wScreen,TRUE);
- break;
-
- case WI_UPDATEICON:
- if (theMessage->Icon)
- UpdateIcon(theMessage->Icon,theMessage->Data.Icon);
- break;
-
- case WI_BACKDROPOF:
- theScreen = FindScreen(theMessage->Data.Screen);
- if (theScreen)
- theMessage->Window = theScreen->BackDrop;
- else
- theMessage->Window = NULL;
- break;
-
- case WI_REMSCREEN:
- UnLinkScreen(theMessage->Data.wScreen);
- break;
-
- case WI_CLOSEICON:
- CloseIcon(theMessage->Icon);
- break;
-
- case WI_SELECTNEXT:
- theScreen = FindScreen(theMessage->Data.Screen);
- if (theScreen) DoSelectNext(theScreen);
- break;
-
- case WI_NEWSCREEN:
- if (RealWB)
- {
- SetActiveWindow(NULL);
- SetScreenMenu(theMessage->Data.NewScreen.Modes);
- theScreen =
- DoNewScreen(theMessage->Data.NewScreen.Depth,RealWB->Screen);
- theMessage->Data.Screen = theScreen->Screen;
- }
- break;
-
- case WI_MAKEWB:
- theScreen = FindScreen(theMessage->Data.Screen);
- if (theScreen && theScreen->BackDrop)
- {
- NewWBScreen(theScreen);
- SetWindowMenu(OW_CURRENTWB,NOCHANGE);
- ActivateWindow(theScreen->BackDrop);
- }
- break;
-
- case WI_OPENSELECT:
- OpenSelected(FindScreen(theMessage->Data.Screen),TRUE);
- break;
-
- case WI_CLOSESELECT:
- CloseSelected(FindScreen(theMessage->Data.Screen));
- break;
-
- case WI_OPENON:
- SetWindowMenu(theMessage->Data.OpenOn.ScreenType,
- theMessage->Data.OpenOn.SizeToFit);
- break;
-
- case WI_REPORTICONVERIFY:
- if (theMessage->Flags & WI_ICONIFYOK)
- Iconify(theMessage->Icon,theMessage->Flags & WI_CHANGE);
- break;
-
- case WI_MAKECONTACT:
- if (theMessage->Data.Version.Maj > MAJLIBVERS ||
- (theMessage->Data.Version.Maj == MAJLIBVERS &&
- theMessage->Data.Version.Min >= MINLIBVERS))
- {
- theMessage->Action = WI_VERSIONOK;
- theMessage->Data.Version.Maj = MAJVERSION;
- theMessage->Data.Version.Min = MINVERSION;
- } else {
- theMessage->Action = WI_VERSIONBAD;
- }
- break;
-
- case WI_ENDICONIFY:
- AttemptEnd(theMessage);
- ReportMulti(WI_REPORTICONEND,NULL,NULL);
- EndItAll = TRUE;
- break;
- }
- return(EndItAll);
- }
-