/* * SWINDOWS A program to allow you to open windows on any screen by * supplying the screen name in thw window title * * Copyright 1989 by Davide P. Cervone. * You may use this code, provided this copywrite notice is kept intact. */ #include "swHandler.h" static char *program = PROGRAM; static char *copyright = COPYRIGHT; /* don't want to have to include LIB:lc.lib in the linking */ #define toupper(c) (((c)>='a'&&(c)<='z')?(c)+('A'-'a'):(c)) /* * FindScreen() * * FindScreen looks through the IntuitionBase linked list of screens * for a screen whose title matches the one supplied by the user. * If no title was supplied, then the active screen is returned. * A case-insensitive prefix match is performed. If the screen is * not found, FindScreen returns NULL. */ static struct Screen *FindScreen(OldTitle,Title) UBYTE *OldTitle,*Title; { register struct Screen *theScreen = IntuitionBase->ActiveScreen; register UBYTE *TName,*SName; int NotDone = TRUE; ULONG ILock; if (OldTitle != Title) { ILock = LockIBase(0L); theScreen = IntuitionBase->FirstScreen; while (theScreen && NotDone) { TName = theScreen->Title; if (TName) { SName = OldTitle; while (SName < Title && toupper(*TName) == toupper(*SName)) { SName++; TName++; } if (SName == Title) NotDone = FALSE; } if (NotDone) theScreen = theScreen->NextScreen; } UnlockIBase(ILock); } return(theScreen); } /* * OpenOnScreen() * * The NewWindow structure is modified temporarily to incorporate the * correct screen pointer and type. The title is shortened so that * the screen name and "::" are note included in the window title. * Once the window is opened, the NewWindow structure is restored in case * it needs to be used by the calling program again. */ static struct Window *OpenOnScreen(theScreen,NewWindow,Title,OldTitle) struct Screen *theScreen; struct NewWindow *NewWindow; UBYTE *Title,*OldTitle; { struct Window *theWindow; struct Screen *OldScreen; USHORT OldType; OldScreen = NewWindow->Screen; OldType = NewWindow->Type; NewWindow->Screen = theScreen; NewWindow->Type = (theScreen->Flags & SCREENTYPE); NewWindow->Title = (*Title)? Title: NULL; theWindow = aOldOpenWindow(NewWindow); NewWindow->Title = OldTitle; NewWindow->Screen = OldScreen; NewWindow->Type = OldType; return(theWindow); } /* * cOpenWindow() * * This is the replacement for OpenWindow. * * If a NewWindow structure was supplied and it has a title string, then * Search the title string for "::" (change CHAR1 and CHAR2 if you want to * use different characters for the separators) * If "::" was found, then * Look for the screen with the given title. * If one was found, then * Get the ScreenlistItem associated with that screen * If one was found (or newly created) then * Make a new WindowListItem for this window * If successfull, then * Save the ScreenItem pointer * Open the window on the specified screen, and * If window opened OK, then add it to the linked list * Otherwise free the WindowListItem, and maybe the ScreenItem too * Otherwise * Free the ScreenItem if it was newly created. * If for any reason, the old OpenWindow was not called, * Try to open the window without changes to the NewWindow structure. * return the window pointer produced. */ struct Window *cOpenWindow(NewWindow) struct NewWindow *NewWindow; { UBYTE *Title,*OldTitle; struct Window *theWindow = NOWINDOW; struct Screen *theScreen; SLISTITEM ScreenItem; WLISTITEM WindowItem; if (NewWindow && NewWindow->Title) { Title = OldTitle = NewWindow->Title; while (*Title && (*Title != CHAR1 || *(Title+1) != CHAR2)) Title++; if (*Title) { theScreen = FindScreen(OldTitle,Title); if (theScreen) { ScreenItem = FindScreenListItem(theScreen); if (ScreenItem) { if (NEW(WindowListItem,WindowItem)) { WindowItem->Screen = ScreenItem; theWindow = OpenOnScreen(theScreen,NewWindow,Title+2,OldTitle); if (theWindow) { AddWindowListItem(WindowItem,theWindow); } else { FREE(WindowListItem,WindowItem); UnuseScreenListItem(ScreenItem); } } else { UnuseScreenListItem(ScreenItem); } } } } } if (theWindow == NOWINDOW) theWindow = aOldOpenWindow(NewWindow); return(theWindow); } /* * cCloseWindow() * * This is the replacement for CloseWindow(). * (the old CloseWindow is called by the stub before calling this routine) * * Look through the window item list for this window. * If the window was found (i.e., it was opened by sWindows) then * Free the window item and remove it from the list. * Check to see whether the screen can now be closed */ void cCloseWindow(theWindow) struct Window *theWindow; { WLISTITEM WindowItem; SLISTITEM ScreenItem; Forbid(); WindowItem = WindowList; while (WindowItem && WindowItem->Window != theWindow) WindowItem = WindowItem->Next; if (WindowItem) { ScreenItem = WindowItem->Screen; FreeWindowListItem(WindowItem); UnuseScreenListItem(ScreenItem); } Permit(); } /* * cCloseScreen() * * This is the replacement for CloseScreen(). * (the old CloseScreen is called by the stub after this routine returns) * * Look through the screen list to for this screen. * If found (i.e., there is a window opened by sWindows open on it), then * Allocate a signal so so that we can wait for all the windows to close * If one could not be allocated, use the default signal. * Clear the close signal. * Save the old task pointer and signal (in case some other task also * called CloseScreen for this screen). * Set the task pointer and signal in the ScreenItem so that we can get * signaled when all the windows are closed. * Wait for the close signal to arrive. * (time passes ... finally all the windows are closed) * If there was another task was waiting, signal it. * Free the allocated signal bit. */ void cCloseScreen(theScreen) struct Screen *theScreen; { SLISTITEM ScreenItem; APTR NextTask; ULONG NextSignal,mySignal; UBYTE mySigBit; extern APTR FindTask(); extern ULONG AllocSignal(); Forbid(); ScreenItem = ScreenList; while (ScreenItem && ScreenItem->Screen != theScreen) ScreenItem = ScreenItem->Next; if (ScreenItem) { mySigBit = AllocSignal(-ONE); mySignal = (mySigBit == -ONE)? DEFAULTSIGNAL: (ONE<CloseSignal; NextTask = ScreenItem->CloseTask; ScreenItem->CloseSignal = mySignal; ScreenItem->CloseTask = FindTask(NULL); } Permit(); if (ScreenItem) { Wait(mySignal); if (NextTask) Signal(NextTask,NextSignal); if (mySigBit != -ONE) FreeSignal(mySigBit); } }