home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d500
/
swindows.lha
/
sWindows
/
Source
/
swHandler.c
next >
Wrap
C/C++ Source or Header
|
1991-06-06
|
8KB
|
253 lines
/*
* 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<<mySigBit);
SetSignal(mySignal,0L);
NextSignal = ScreenItem->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);
}
}