home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 "swMain.h"
- #include "sWindows.h"
-
- struct IntuitionBase *IntuitionBase = NULL;
- extern struct SysBase *SysBase;
-
- static char *program = PROGRAM;
- static char *copyright = COPYRIGHT;
-
- static char *handler = HANDLERCODE; /* the name of the handler file */
- #define HANDLER &(handler[2]) /* handler without the L: */
-
- static struct swHandlerInfo *swHandlerData; /* data shared with the handler */
- static long Segment; /* the loaded handler segment */
-
- static SLISTITEM *ScreenList; /* screen item linked list */
- static WLISTITEM *WindowList; /* window item linked list */
-
-
- /*
- * FreeAllMemory()
- *
- * After the function vectors have been restored, the linked lists are
- * freed. If any tasks are waiting for the close signal before
- * closing their screens, then these tasks are signalled immediately.
- * Allowing the screen to close before the windows are all closed, however,
- * is not a good idea.
- */
-
- void FreeAllMemory()
- {
- SLISTITEM theScreen;
- WLISTITEM theWindow;
-
- Forbid();
- while (*WindowList)
- {
- theWindow = *WindowList;
- *WindowList = theWindow->Next;
- FREE(WindowListItem,theWindow);
- }
- while (*ScreenList)
- {
- theScreen = *ScreenList;
- *ScreenList = theScreen->Next;
- if (theScreen->CloseTask)
- Signal(theScreen->CloseTask,theScreen->CloseSignal);
- FREE(ScreenListItem,theScreen);
- }
- Permit();
- }
-
-
- /*
- * DoExit()
- *
- * General purpose error-exit routine. Print an error message if one was
- * supplied (it can have up to three parameters), and then clean up any
- * memory, libraries, etc. that need to be handled before exiting.
- */
-
- static void DoExit(s,x1,x2,x3)
- char *s, *x1, *x2, *x3;
- {
- long status = EXIT_OK;
-
- if (s != NULL)
- {
- printf(s,x1,x2,x3);
- printf("\n");
- status = EXIT_ERROR;
- }
- FreeAllMemory();
- if (Segment) UnLoadSeg(Segment);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- exit(status);
- }
-
-
- /*
- * CheckLibOpen()
- *
- * Call OpenLibrary() for the specified library, and check that the
- * open succeeded.
- */
-
- static void CheckLibOpen(lib,name,rev)
- APTR *lib;
- char *name;
- int rev;
- {
- extern APTR OpenLibrary();
-
- if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
- DoExit("Can't open %s",name);
- }
-
-
- /*
- * LoadHandler()
- *
- * Try to LoadSeg the handler from the current directory, and if it is not
- * found, try the L: directory. If neither can be loaded, exit with an
- * error message. Once the handler is loaded, call the Setup routine
- * in the handler code and pass the loader version number. The handler will
- * check the version for compatibility and returns NULL if there is a
- * mismatch, or a pointer to the shared data if everything is OK.
- * Check the handler version number, and then store the loader version
- * and the segment list pointer for use in unloading the handler later.
- * The MsgPort is the first item in the swHandler structure. It is used
- * to link the information into the system port list, where we can find it
- * later.
- */
-
- void LoadHandler(thePort)
- struct MsgPort **thePort;
- {
- struct swHandlerInfo *(*Setup)();
-
- if ((Segment = LoadSeg(HANDLER)) == NULL)
- if ((Segment = LoadSeg(handler)) == NULL)
- DoExit("Can't load %s",handler);
- Setup = (struct swHandlerInfo *(*)()) ((Segment << 2) + 4);
-
- swHandlerData = (*Setup)(LOADVERS);
- if (swHandlerData)
- {
- if (var(MajVers) > 1) DoExit("Version mismatch with %s",HANDLER);
- *thePort = &(swHandlerData->swPort);
- } else {
- DoExit("%s reports a version mismatch",HANDLER);
- }
-
- var(Segment) = Segment;
- var(LoadVers) = LOADVERS;
- }
-
-
- /*
- * SetVerctors()
- *
- * Set the Intuition library vectors for the OpenWindow, CloseWindow
- * and CloseScreen to the routines specified by the handler. Save the
- * old routine pointers for later replacement.
- */
-
- void SetVectors()
- {
- VAR(OldOpenWindow) =
- SetFunction(IntuitionBase,&LVOOpenWindow,var(aOpenWindow));
- VAR(OldCloseWindow) =
- SetFunction(IntuitionBase,&LVOCloseWindow,var(aCloseWindow));
- VAR(OldCloseScreen) =
- SetFunction(IntuitionBase,&LVOCloseScreen,var(aCloseScreen));
- }
-
-
- /*
- * UnSetVectors()
- *
- * Replace the old Intuition library vectors, but make sure that no one
- * else has changed them behind our back. If they are not the same as
- * what we set them to originally, then put back the ones that we found,
- * and return an error status.
- */
-
- int UnSetVectors()
- {
- long NewOpenWindow,NewCloseWindow,NewCloseScreen;
- int status = TRUE;
-
- NewOpenWindow =
- SetFunction(IntuitionBase,&LVOOpenWindow,VAR(OldOpenWindow));
- NewCloseWindow =
- SetFunction(IntuitionBase,&LVOCloseWindow,VAR(OldCloseWindow));
- NewCloseScreen =
- SetFunction(IntuitionBase,&LVOCloseScreen,VAR(OldCloseScreen));
-
- if (NewOpenWindow != (long) var(aOpenWindow) ||
- NewCloseWindow != (long) var(aCloseWindow) ||
- NewCloseScreen != (long) var(aCloseScreen))
- {
- SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
- SetFunction(IntuitionBase,&LVOCloseWindow,NewCloseWindow);
- SetFunction(IntuitionBase,&LVOCloseScreen,NewCloseScreen);
- status = FALSE;
- }
- return(status);
- }
-
-
- /*
- * SetVariables()
- *
- * The swHandlerData structure is used to allow the loading program to
- * set up variables needed by the handler (like Intuitionbase, etc.). This
- * keeps the handler code to a minimum. The loader retains pointers to the
- * linked lists, in case it needs to free memory on behalf of the handler.
- */
-
- void SetVariables(thePort)
- struct MsgPort *thePort;
- {
- VAR(IntuitionBase) = IntuitionBase;
- VAR(SysBase) = SysBase;
- ScreenList = var(ScreenList);
- WindowList = var(WindowList);
- }
-
-
- /*
- * GetVariables()
- *
- * Look up the values stored in the swHandlerData structure. The
- * Intuition library already was opened, and we will need to close it.
- * The data in the linked lists may need to be freed.
- */
-
- void GetVariables(thePort)
- struct MsgPort *thePort;
- {
- swHandlerData = (struct swHandlerInfo *) thePort;
- IntuitionBase = VAR(IntuitionBase);
- ScreenList = var(ScreenList);
- WindowList = var(WindowList);
- }
-
-
- /*
- * Main()
- *
- * Look for the sWindows port, which indicates that sWindows already exists.
- * If the port does not exist, then sWindows is not active, so
- * Open Intuition.
- * Load the handler code and check its version.
- * Add the port (supplied by the handler) into the system list so we
- * can find it later.
- * Set the variables needed by the handler.
- * Set the Intuition Library vectors the the handler routines
- * Notify the user that all is ready.
- * else (the port already exists, so sWindows alreay is active)
- * Get the pointer to the swHandlerData structure from the port,
- * and get any variables we need from the structure.
- * Check that the loader versions are compatible.
- * Try to remove the SetFunction calls.
- * If successfull, then
- * Remove the port from the system list.
- * Free any window and screen item memory from the linked lists.
- * Unload the handler segment list.
- * Notify the user that sWindows is deactivated.
- * Close Intuition.
- * else (we could not replace the functions)
- * Inform the user that sWindows can not be removed
- */
-
- void main()
- {
- struct MsgPort *NamedPort;
-
- NamedPort = FindPort(PORTNAME);
- if (NamedPort == NULL)
- {
- CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
- LoadHandler(&NamedPort);
- AddPort(NamedPort);
- SetVariables(NamedPort);
- SetVectors(NamedPort);
- printf("%s v%d.%d.%d Installed\n",program,
- var(MajVers),var(MinVers),var(LoadVers));
- } else {
- GetVariables(NamedPort);
- if (var(LoadVers) > LOADVERS)
- {
- printf("Loader version mismatch\n");
- printf("Current handler was started by a higher-version loader\n");
- printf("%s not removed\n",program);
- } else {
- if (UnSetVectors(NamedPort))
- {
- RemPort(NamedPort);
- FreeAllMemory();
- UnLoadSeg(var(Segment));
- printf("%s removed\n",program);
- CloseLibrary(IntuitionBase);
- } else {
- printf("SetFunction vectors have been changed!\n");
- printf("Cannot remove %s\n",program);
- }
- }
- }
- }
-