home *** CD-ROM | disk | FTP | other *** search
- /*
- * NL-Daemon A program to force old programs to use NL gadget imagery.
- *
- * Copyright 1989 by Davide P. Cervone.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include "NL-Main.h"
- #include "NL-Daemon.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 NL_HandlerInfo *NL_HandlerData; /* data shared with the handler */
- static long Segment; /* the loaded handler segment */
-
- /*
- * 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;
- }
- 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 NL_Handler 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 NL_HandlerInfo *(*Setup)();
-
- if ((Segment = LoadSeg(HANDLER)) == NULL)
- if ((Segment = LoadSeg(handler)) == NULL)
- DoExit("Can't load %s",handler);
- Setup = (struct NL_HandlerInfo *(*)()) ((Segment << 2) + 4);
-
- NL_HandlerData = (*Setup)(LOADVERS);
- if (NL_HandlerData)
- {
- if (var(MajVers) < MINHMAJVERS ||
- (var(MajVers) == MINHMAJVERS && var(MinVers) < MINHMINVERS))
- DoExit("Version mismatch with %s",HANDLER);
- *thePort = &(NL_HandlerData->NL_Port);
- } else {
- DoExit("%s reports a version mismatch",HANDLER);
- }
-
- var(Segment) = Segment;
- }
-
-
- /*
- * InvertImage()
- *
- * Performs a Logical NOT on all the bits in the Image data, and
- * XORs the second bitplane in the PlaneOnOff field. This makes the
- * standard Intuition Imagery use color 2 as the background and color
- * three as the forground (rather than 1 and 0).
- */
-
- #define IMAGESIZE(i) ((i)->Depth*(((i)->Width+15)>>4)*(i)->Height)
-
- static void InvertImage(theImage)
- struct Image *theImage;
- {
- short i;
- USHORT *theWord;
-
- if (theImage)
- {
- theWord = theImage->ImageData;
- for (i=IMAGESIZE(theImage); i; i--,theWord++) *theWord = ~(*theWord);
- theImage->PlaneOnOff ^= 0x02;
- }
- }
-
-
- /*
- * SetVectors()
- *
- * Set the Intuition library vectors for the routines specified by the
- * handler. Save the old routine pointers for later replacement.
- */
-
- void SetVectors()
- {
- VAR(OldOpenWindow) =
- SetFunction(IntuitionBase,&LVOOpenWindow,var(aOpenWindow));
- VAR(OldSetMenuStrip) =
- SetFunction(IntuitionBase,&LVOSetMenuStrip,var(aSetMenuStrip));
- VAR(OldOpenScreen) =
- SetFunction(IntuitionBase,&LVOOpenScreen,var(aOpenScreen));
- }
-
-
- /*
- * 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;
- long NewSetMenuStrip;
- long NewOpenScreen;
- int status = TRUE;
-
- NewOpenWindow = SetFunction(IntuitionBase,&LVOOpenWindow,VAR(OldOpenWindow));
- NewSetMenuStrip =
- SetFunction(IntuitionBase,&LVOSetMenuStrip,VAR(OldSetMenuStrip));
- NewOpenScreen = SetFunction(IntuitionBase,&LVOOpenScreen,VAR(OldOpenScreen));
- if (NewOpenWindow != (long) var(aOpenWindow) ||
- NewSetMenuStrip != (long) var(aSetMenuStrip) ||
- NewOpenScreen != (long) var(aOpenScreen))
- {
- SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
- SetFunction(IntuitionBase,&LVOSetMenuStrip,NewSetMenuStrip);
- SetFunction(IntuitionBase,&LVOOpenScreen,NewOpenScreen);
- status = FALSE;
- }
- return(status);
- }
-
-
- /*
- * SetVariables()
- *
- * The NL_HandlerData 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,argc)
- struct MsgPort *thePort;
- int argc;
- {
- VAR(IntuitionBase) = IntuitionBase;
- VAR(SysBase) = SysBase;
-
- if (argc == 1)
- {
- Forbid();
- InvertImage(IntuitionBase->CheckImage[0]);
- InvertImage(IntuitionBase->CheckImage[1]);
- InvertImage(IntuitionBase->AmigaIcon[0]);
- InvertImage(IntuitionBase->AmigaIcon[1]);
- Permit();
- var(Flags) |= INTUITION_CHANGED;
- }
- }
-
-
- /*
- * GetVariables()
- *
- * Look up the values stored in the NL_HandlerData 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;
- {
- NL_HandlerData = (struct NL_HandlerInfo *)thePort;
- IntuitionBase = VAR(IntuitionBase);
- }
-
-
- /*
- * SetupWindows()
- *
- * Looks through the Intuition screen and windows lists and
- * calls the Handler's SetupWindow routine to add the imagery to
- * each pre-existing window. If the window has a menu strip, remove
- * it and then replace it (our SetMenuStrip routine will fix the menu
- * for us, since it has already be added in via SetFunction).
- * All of this is done in Forbid() mode so that the list won't change
- * while we're looking.
- */
-
- static void SetupWindows()
- {
- struct Screen *theScreen;
- struct Window *theWindow;
- struct Menu *theMenu;
-
- if (var(SetupWindow) || var(SetupScreen))
- {
- Forbid();
- theScreen = IntuitionBase->FirstScreen;
- while (theScreen)
- {
- if (var(SetupScreen)) VAR(SetupScreen)(theScreen);
- if (var(SetupWindow))
- {
- theWindow = theScreen->FirstWindow;
- while (theWindow)
- {
- VAR(SetupWindow)(theWindow);
- if (theWindow->MenuStrip)
- {
- theMenu = theWindow->MenuStrip;
- ClearMenuStrip(theWindow);
- SetMenuStrip(theWindow,theMenu);
- }
- theWindow = theWindow->NextWindow;
- }
- }
- theScreen = theScreen->NextScreen;
- }
- Permit();
- }
- }
-
-
- /*
- * CheckGadget()
- *
- * Checks to see if a gadget's imagery has been changed. If so, it
- * replaces the imagery with the standard Intuition imagery that we saved
- * when we set up the NL gadget.
- */
-
- static int CheckGadget(theGadget,HiResImage,LowResImage)
- struct Gadget *theGadget;
- APTR HiResImage,LowResImage;
- {
- int status = FALSE;
-
- if (theGadget->GadgetRender == HiResImage ||
- theGadget->GadgetRender == LowResImage)
- {
- status = TRUE;
- theGadget->GadgetRender = theGadget->SelectRender;
- theGadget->LeftEdge = ((LONG)theGadget->UserData) >> 16;
- theGadget->Width = ((LONG)theGadget->UserData) & 0xFFFF;
- }
- return(status);
- }
-
-
- /*
- * CheckGadgetList()
- *
- * Looks through a list of gadgets to see if any of their imagery has been
- * changed, and replaces their original imagery if they where changed.
- * Returns TRUE if any changes were made, FALSE otherwise.
- */
-
- static int CheckGadgetList(theGadget)
- struct Gadget *theGadget;
- {
- int Changed = FALSE;
-
- while (theGadget)
- {
- switch(theGadget->GadgetType & ~GADGETTYPE)
- {
- case SIZING:
- Changed |= CheckGadget(theGadget,var(SizeImage),var(LR_SizeImage));
- break;
-
- case WUPFRONT:
- case SUPFRONT:
- Changed |=
- CheckGadget(theGadget,var(UpFrontImage),var(LR_UpFrontImage));
- break;
-
- case WDOWNBACK:
- case SDOWNBACK:
- Changed |=
- CheckGadget(theGadget,var(DownBackImage),var(LR_DownBackImage));
- break;
-
- case CLOSE:
- Changed |=
- CheckGadget(theGadget,var(CloseImage),var(LR_CloseImage));
- break;
-
- case BOOLGADGET:
- Changed |= CheckGadget(theGadget,var(ZoomImage),var(LR_ZoomImage));
- break;
- }
- theGadget = theGadget->NextGadget;
- }
- return(Changed);
- }
-
-
- /*
- * CleanUpWindows()
- *
- * Looks through the intuition Screen and Window lists to see if
- * any gadgets are still using the NL gadget imagery. If so,
- * replace the old imagery and detail pen, then refresh the window
- * to show the original gadgets. Do this all in Forbid() mode, so
- * nothing changes while we're looking at the list.
- */
-
- static void CleanUpWindows()
- {
- struct Screen *theScreen;
- struct Window *theWindow;
- int Changed;
-
- Forbid();
- theScreen = IntuitionBase->FirstScreen;
- while (theScreen)
- {
- theWindow = theScreen->FirstWindow;
- while (theWindow)
- {
- Changed = CheckGadgetList(theWindow->FirstGadget);
- if (theWindow->BlockPen & PENCHANGED)
- {
- theWindow->BlockPen = STDBLOCKPEN;
- if (theWindow->DetailPen & PENCHANGED)
- theWindow->DetailPen = STDDETAILPEN;
- Changed = TRUE;
- }
- if (Changed) RefreshWindowFrame(theWindow);
- theWindow = theWindow->NextWindow;
- }
-
- Changed = CheckGadgetList(theScreen->FirstGadget);
- if (theScreen->BlockPen & PENCHANGED)
- {
- theScreen->BlockPen = STDBLOCKPEN;
- if (theScreen->DetailPen & PENCHANGED)
- theScreen->DetailPen = STDDETAILPEN;
- Changed = TRUE;
- }
- if (Changed)
- ShowTitle(theScreen,(theScreen->Flags & SHOWTITLE)? TRUE: FALSE);
- theScreen = theScreen->NextScreen;
- }
-
- if (var(Flags) & INTUITION_CHANGED)
- {
- InvertImage(IntuitionBase->CheckImage[0]);
- InvertImage(IntuitionBase->CheckImage[1]);
- InvertImage(IntuitionBase->AmigaIcon[0]);
- InvertImage(IntuitionBase->AmigaIcon[1]);
- var(Flags) &= ~INTUITION_CHANGED;
- }
- Permit();
- }
-
-
- /*
- * Main()
- *
- * Look for the NL-Daemon port, which indicates that NL-Daemon already exists.
- * If the port does not exist, then NL-Daemon 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 for the handler routines
- * Retro-fit any existing windows to include the NL gadgets
- * Notify the user that all is ready.
- * else (the port already exists, so NL-Daemon alreay is active)
- * Get the pointer to the NL_HandlerData 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.
- * Cleanup and windows that are still using the image data
- * Unload the handler segment list.
- * Notify the user that NL-Daemon is deactivated.
- * Close Intuition.
- * else (we could not replace the functions)
- * Inform the user that NL-Daemon can not be removed
- */
-
- void main(argc,argv)
- int argc;
- char **argv;
- {
- struct MsgPort *NamedPort;
-
- NamedPort = FindPort(PORTNAME);
- if (NamedPort == NULL)
- {
- CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
- LoadHandler(&NamedPort);
- AddPort(NamedPort);
- SetVariables(NamedPort,argc);
- SetVectors(NamedPort);
- SetupWindows();
- printf("%s v%d.%d.%d Installed\n",program,
- var(MajVers),var(MinVers),LOADVERS);
- } else {
- GetVariables(NamedPort);
- if (var(MinLoadVers) > LOADVERS || var(MajVers) < MINHMAJVERS ||
- (var(MajVers) == MINHMAJVERS && var(MinVers) < MINHMINVERS))
- {
- printf("Loader version mismatch\n");
- printf("%s not removed\n",program);
- } else {
- if (UnSetVectors(NamedPort))
- {
- RemPort(NamedPort);
- CleanUpWindows();
- UnLoadSeg(var(Segment));
- printf("%s removed\n",program);
- CloseLibrary(IntuitionBase);
- } else {
- printf("SetFunction vectors have been changed!\n");
- printf("Cannot remove %s\n",program);
- }
- }
- }
- }
-