home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 532.lha / NLDaemon / Source / NL-Main.c < prev    next >
C/C++ Source or Header  |  1991-07-09  |  14KB  |  478 lines

  1. /*
  2.  *  NL-Daemon   A program to force old programs to use NL gadget imagery.
  3.  *
  4.  *              Copyright 1989 by Davide P. Cervone.
  5.  *  You may use this code, provided this copyright notice is kept intact.
  6.  */
  7.  
  8. #include "NL-Main.h"
  9. #include "NL-Daemon.h"
  10.  
  11. struct IntuitionBase *IntuitionBase = NULL;
  12. extern struct SysBase *SysBase;
  13.  
  14. static char *program   = PROGRAM;
  15. static char *copyright = COPYRIGHT;
  16.  
  17. static char *handler   = HANDLERCODE;       /* the name of the handler file */
  18. #define HANDLER          &(handler[2])      /* handler without the L: */
  19.  
  20. static struct NL_HandlerInfo *NL_HandlerData; /* data shared with the handler */
  21. static long Segment;                        /* the loaded handler segment */
  22.  
  23. /*
  24.  *  DoExit()
  25.  *
  26.  *  General purpose error-exit routine.  Print an error message if one was
  27.  *  supplied (it can have up to three parameters), and then clean up any
  28.  *  memory, libraries, etc. that need to be handled before exiting.
  29.  */
  30.  
  31. static void DoExit(s,x1,x2,x3)
  32. char *s, *x1, *x2, *x3;
  33. {
  34.    long status = EXIT_OK;
  35.    
  36.    if (s != NULL)
  37.    {
  38.       printf(s,x1,x2,x3);
  39.       printf("\n");
  40.       status = EXIT_ERROR;
  41.    }
  42.    if (Segment)       UnLoadSeg(Segment);
  43.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  44.    exit(status);
  45. }
  46.  
  47.  
  48. /*
  49.  *  CheckLibOpen()
  50.  *
  51.  *  Call OpenLibrary() for the specified library, and check that the 
  52.  *  open succeeded.
  53.  */
  54.  
  55. static void CheckLibOpen(lib,name,rev)
  56. APTR *lib;
  57. char *name;
  58. int rev;
  59. {
  60.    extern APTR OpenLibrary();
  61.  
  62.    if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
  63.       DoExit("Can't open %s",name);
  64. }
  65.  
  66.  
  67. /*
  68.  *  LoadHandler()
  69.  *
  70.  *  Try to LoadSeg the handler from the current directory, and if it is not
  71.  *  found, try the L: directory.  If neither can be loaded, exit with an
  72.  *  error message.  Once the handler is loaded, call the Setup routine
  73.  *  in the handler code and pass the loader version number.  The handler will
  74.  *  check the version for compatibility and returns NULL if there is a
  75.  *  mismatch, or a pointer to the shared data if everything is OK.
  76.  *  Check the handler version number, and then store the loader version
  77.  *  and the segment list pointer for use in unloading the handler later.
  78.  *  The MsgPort is the first item in the NL_Handler structure.  It is used
  79.  *  to link the information into the system port list, where we can find it
  80.  *  later.
  81.  */
  82.  
  83. void LoadHandler(thePort)
  84. struct MsgPort **thePort;
  85. {
  86.    struct NL_HandlerInfo *(*Setup)();
  87.    
  88.    if ((Segment = LoadSeg(HANDLER)) == NULL)
  89.       if ((Segment = LoadSeg(handler)) == NULL)
  90.         DoExit("Can't load %s",handler);
  91.    Setup = (struct NL_HandlerInfo *(*)()) ((Segment << 2) + 4);
  92.    
  93.    NL_HandlerData = (*Setup)(LOADVERS);
  94.    if (NL_HandlerData)
  95.    {
  96.       if (var(MajVers) < MINHMAJVERS ||
  97.          (var(MajVers) == MINHMAJVERS && var(MinVers) < MINHMINVERS))
  98.              DoExit("Version mismatch with %s",HANDLER);
  99.       *thePort = &(NL_HandlerData->NL_Port);
  100.    } else {
  101.       DoExit("%s reports a version mismatch",HANDLER);
  102.    }
  103.    
  104.    var(Segment)  = Segment;
  105. }
  106.  
  107.  
  108. /*
  109.  *  InvertImage()
  110.  *
  111.  *  Performs a Logical NOT on all the bits in the Image data, and
  112.  *  XORs the second bitplane in the PlaneOnOff field.  This makes the
  113.  *  standard Intuition Imagery use color 2 as the background and color
  114.  *  three as the forground (rather than 1 and 0).
  115.  */
  116.  
  117. #define IMAGESIZE(i)    ((i)->Depth*(((i)->Width+15)>>4)*(i)->Height)
  118.  
  119. static void InvertImage(theImage)
  120. struct Image *theImage;
  121. {
  122.    short i;
  123.    USHORT *theWord;
  124.    
  125.    if (theImage)
  126.    {
  127.       theWord = theImage->ImageData;
  128.       for (i=IMAGESIZE(theImage); i; i--,theWord++) *theWord = ~(*theWord);
  129.       theImage->PlaneOnOff ^= 0x02;
  130.    }
  131. }
  132.  
  133.  
  134. /*
  135.  *  SetVectors()
  136.  *
  137.  *  Set the Intuition library vectors for the routines specified by the
  138.  *  handler.  Save the old routine pointers for later replacement.
  139.  */
  140.  
  141. void SetVectors()
  142. {
  143.    VAR(OldOpenWindow) =
  144.       SetFunction(IntuitionBase,&LVOOpenWindow,var(aOpenWindow));
  145.    VAR(OldSetMenuStrip) =
  146.       SetFunction(IntuitionBase,&LVOSetMenuStrip,var(aSetMenuStrip));
  147.    VAR(OldOpenScreen) =
  148.       SetFunction(IntuitionBase,&LVOOpenScreen,var(aOpenScreen));
  149. }
  150.  
  151.  
  152. /*
  153.  *  UnSetVectors()
  154.  *
  155.  *  Replace the old Intuition library vectors, but make sure that no one
  156.  *  else has changed them behind our back.  If they are not the same as
  157.  *  what we set them to originally, then put back the ones that we found,
  158.  *  and return an error status.
  159.  */
  160.  
  161. int UnSetVectors()
  162. {
  163.    long NewOpenWindow;
  164.    long NewSetMenuStrip;
  165.    long NewOpenScreen;
  166.    int status = TRUE;
  167.  
  168.    NewOpenWindow = SetFunction(IntuitionBase,&LVOOpenWindow,VAR(OldOpenWindow));
  169.    NewSetMenuStrip =
  170.       SetFunction(IntuitionBase,&LVOSetMenuStrip,VAR(OldSetMenuStrip));
  171.    NewOpenScreen = SetFunction(IntuitionBase,&LVOOpenScreen,VAR(OldOpenScreen));
  172.    if (NewOpenWindow   != (long) var(aOpenWindow) ||
  173.        NewSetMenuStrip != (long) var(aSetMenuStrip) ||
  174.        NewOpenScreen   != (long) var(aOpenScreen))
  175.    {
  176.       SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
  177.       SetFunction(IntuitionBase,&LVOSetMenuStrip,NewSetMenuStrip);
  178.       SetFunction(IntuitionBase,&LVOOpenScreen,NewOpenScreen);
  179.       status = FALSE;
  180.    }
  181.    return(status);
  182. }
  183.  
  184.  
  185. /*
  186.  *  SetVariables()
  187.  *
  188.  *  The NL_HandlerData structure is used to allow the loading program to
  189.  *  set up variables needed by the handler (like Intuitionbase, etc.).  This
  190.  *  keeps the handler code to a minimum.  The loader retains pointers to the
  191.  *  linked lists, in case it needs to free memory on behalf of the handler.
  192.  */
  193.  
  194. void SetVariables(thePort,argc)
  195. struct MsgPort *thePort;
  196. int argc;
  197. {
  198.    VAR(IntuitionBase) = IntuitionBase;
  199.    VAR(SysBase) = SysBase;
  200.  
  201.    if (argc == 1)
  202.    {
  203.       Forbid();
  204.       InvertImage(IntuitionBase->CheckImage[0]);
  205.       InvertImage(IntuitionBase->CheckImage[1]);
  206.       InvertImage(IntuitionBase->AmigaIcon[0]);
  207.       InvertImage(IntuitionBase->AmigaIcon[1]);
  208.       Permit();
  209.       var(Flags) |= INTUITION_CHANGED;
  210.    }
  211. }
  212.  
  213.  
  214. /*
  215.  *  GetVariables()
  216.  *
  217.  *  Look up the values stored in the NL_HandlerData structure.  The 
  218.  *  Intuition library already was opened, and we will need to close it.
  219.  *  The data in the linked lists may need to be freed.
  220.  */
  221.  
  222. void GetVariables(thePort)
  223. struct MsgPort *thePort;
  224. {
  225.    NL_HandlerData = (struct NL_HandlerInfo *)thePort;
  226.    IntuitionBase = VAR(IntuitionBase);
  227. }
  228.  
  229.  
  230. /*
  231.  *  SetupWindows()
  232.  *
  233.  *  Looks through the Intuition screen and windows lists and
  234.  *  calls the Handler's SetupWindow routine to add the imagery to
  235.  *  each pre-existing window.  If the window has a menu strip, remove 
  236.  *  it and then replace it (our SetMenuStrip routine will fix the menu
  237.  *  for us, since it has already be added in via SetFunction).
  238.  *  All of this is done in Forbid() mode so that the list won't change 
  239.  *  while we're looking.
  240.  */
  241.  
  242. static void SetupWindows()
  243. {
  244.    struct Screen *theScreen;
  245.    struct Window *theWindow;
  246.    struct Menu *theMenu;
  247.    
  248.    if (var(SetupWindow) || var(SetupScreen))
  249.    {
  250.       Forbid();
  251.       theScreen = IntuitionBase->FirstScreen;
  252.       while (theScreen)
  253.       {
  254.          if (var(SetupScreen)) VAR(SetupScreen)(theScreen);
  255.          if (var(SetupWindow))
  256.          {
  257.             theWindow = theScreen->FirstWindow;
  258.             while (theWindow)
  259.             {
  260.                VAR(SetupWindow)(theWindow);
  261.                if (theWindow->MenuStrip)
  262.                {
  263.                   theMenu = theWindow->MenuStrip;
  264.                   ClearMenuStrip(theWindow);
  265.                   SetMenuStrip(theWindow,theMenu);
  266.                }
  267.                theWindow = theWindow->NextWindow;
  268.             }
  269.          }
  270.          theScreen = theScreen->NextScreen;
  271.       }
  272.       Permit();
  273.    }
  274. }
  275.  
  276.  
  277. /*
  278.  *  CheckGadget()
  279.  *
  280.  *  Checks to see if a gadget's imagery has been changed.  If so, it
  281.  *  replaces the imagery with the standard Intuition imagery that we saved
  282.  *  when we set up the NL gadget.
  283.  */
  284.  
  285. static int CheckGadget(theGadget,HiResImage,LowResImage)
  286. struct Gadget *theGadget;
  287. APTR HiResImage,LowResImage;
  288. {
  289.    int status = FALSE;
  290.  
  291.    if (theGadget->GadgetRender == HiResImage ||
  292.        theGadget->GadgetRender == LowResImage)
  293.    {
  294.       status = TRUE;
  295.       theGadget->GadgetRender = theGadget->SelectRender;
  296.       theGadget->LeftEdge = ((LONG)theGadget->UserData) >> 16;
  297.       theGadget->Width    = ((LONG)theGadget->UserData) & 0xFFFF;
  298.    }
  299.    return(status);
  300. }
  301.  
  302.  
  303. /*
  304.  *  CheckGadgetList()
  305.  *
  306.  *  Looks through a list of gadgets to see if any of their imagery has been
  307.  *  changed, and replaces their original imagery if they where changed.
  308.  *  Returns TRUE if any changes were made, FALSE otherwise.
  309.  */
  310.  
  311. static int CheckGadgetList(theGadget)
  312. struct Gadget *theGadget;
  313. {
  314.    int Changed = FALSE;
  315.  
  316.    while (theGadget)
  317.    {
  318.       switch(theGadget->GadgetType & ~GADGETTYPE)
  319.       {
  320.          case SIZING:
  321.             Changed |= CheckGadget(theGadget,var(SizeImage),var(LR_SizeImage));
  322.             break;
  323.  
  324.          case WUPFRONT:
  325.          case SUPFRONT:
  326.             Changed |=
  327.                CheckGadget(theGadget,var(UpFrontImage),var(LR_UpFrontImage));
  328.             break;
  329.  
  330.          case WDOWNBACK:
  331.          case SDOWNBACK:
  332.             Changed |=
  333.                CheckGadget(theGadget,var(DownBackImage),var(LR_DownBackImage));
  334.             break;
  335.  
  336.          case CLOSE:
  337.             Changed |=
  338.                CheckGadget(theGadget,var(CloseImage),var(LR_CloseImage));
  339.             break;
  340.  
  341.          case BOOLGADGET:
  342.             Changed |= CheckGadget(theGadget,var(ZoomImage),var(LR_ZoomImage));
  343.             break;
  344.       }
  345.       theGadget = theGadget->NextGadget;
  346.    }
  347.    return(Changed);
  348. }
  349.  
  350.  
  351. /*
  352.  *  CleanUpWindows()
  353.  *
  354.  *  Looks through the intuition Screen and Window lists to see if
  355.  *  any gadgets are still using the NL gadget imagery.  If so, 
  356.  *  replace the old imagery and detail pen, then refresh the window
  357.  *  to show the original gadgets.  Do this all in Forbid() mode, so 
  358.  *  nothing changes while we're looking at the list.
  359.  */
  360.  
  361. static void CleanUpWindows()
  362. {
  363.    struct Screen *theScreen;
  364.    struct Window *theWindow;
  365.    int Changed;
  366.  
  367.    Forbid();
  368.    theScreen = IntuitionBase->FirstScreen;
  369.    while (theScreen)
  370.    {
  371.       theWindow = theScreen->FirstWindow;
  372.       while (theWindow)
  373.       {
  374.          Changed = CheckGadgetList(theWindow->FirstGadget);
  375.          if (theWindow->BlockPen & PENCHANGED)
  376.          {
  377.             theWindow->BlockPen  = STDBLOCKPEN;
  378.             if (theWindow->DetailPen & PENCHANGED)
  379.                theWindow->DetailPen = STDDETAILPEN;
  380.             Changed = TRUE;
  381.          }
  382.          if (Changed) RefreshWindowFrame(theWindow);
  383.          theWindow = theWindow->NextWindow;
  384.       }
  385.  
  386.       Changed = CheckGadgetList(theScreen->FirstGadget);
  387.       if (theScreen->BlockPen & PENCHANGED)
  388.       {
  389.          theScreen->BlockPen  = STDBLOCKPEN;
  390.          if (theScreen->DetailPen & PENCHANGED)
  391.             theScreen->DetailPen = STDDETAILPEN;
  392.          Changed = TRUE;
  393.       }
  394.       if (Changed)
  395.          ShowTitle(theScreen,(theScreen->Flags & SHOWTITLE)? TRUE: FALSE);
  396.       theScreen = theScreen->NextScreen;
  397.    }
  398.  
  399.    if (var(Flags) & INTUITION_CHANGED)
  400.    {
  401.       InvertImage(IntuitionBase->CheckImage[0]);
  402.       InvertImage(IntuitionBase->CheckImage[1]);
  403.       InvertImage(IntuitionBase->AmigaIcon[0]);
  404.       InvertImage(IntuitionBase->AmigaIcon[1]);
  405.       var(Flags) &= ~INTUITION_CHANGED;
  406.    }
  407.    Permit();
  408. }
  409.  
  410.  
  411. /*
  412.  *  Main()
  413.  *
  414.  *  Look for the NL-Daemon port, which indicates that NL-Daemon already exists.
  415.  *  If the port does not exist, then NL-Daemon is not active, so
  416.  *    Open Intuition.
  417.  *    Load the handler code and check its version.
  418.  *    Add the port (supplied by the handler) into the system list so we
  419.  *      can find it later.
  420.  *    Set the variables needed by the handler.
  421.  *    Set the Intuition Library vectors for the handler routines
  422.  *    Retro-fit any existing windows to include the NL gadgets
  423.  *    Notify the user that all is ready.
  424.  *  else (the port already exists, so NL-Daemon alreay is active)
  425.  *    Get the pointer to the NL_HandlerData structure from the port,
  426.  *      and get any variables we need from the structure.
  427.  *    Check that the loader versions are compatible.
  428.  *    Try to remove the SetFunction calls.
  429.  *    If successfull, then
  430.  *      Remove the port from the system list.
  431.  *      Cleanup and windows that are still using the image data
  432.  *      Unload the handler segment list.
  433.  *      Notify the user that NL-Daemon is deactivated.
  434.  *      Close Intuition.
  435.  *    else (we could not replace the functions)
  436.  *      Inform the user that NL-Daemon can not be removed
  437.  */
  438.  
  439. void main(argc,argv)
  440. int argc;
  441. char **argv;
  442. {
  443.    struct MsgPort *NamedPort;
  444.  
  445.    NamedPort = FindPort(PORTNAME);
  446.    if (NamedPort == NULL)
  447.    {
  448.       CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
  449.       LoadHandler(&NamedPort);
  450.       AddPort(NamedPort);
  451.       SetVariables(NamedPort,argc);
  452.       SetVectors(NamedPort);
  453.       SetupWindows();
  454.       printf("%s v%d.%d.%d Installed\n",program,
  455.          var(MajVers),var(MinVers),LOADVERS);
  456.    } else {
  457.       GetVariables(NamedPort);
  458.       if (var(MinLoadVers) > LOADVERS || var(MajVers) < MINHMAJVERS ||
  459.          (var(MajVers) == MINHMAJVERS && var(MinVers) < MINHMINVERS))
  460.       {
  461.          printf("Loader version mismatch\n");
  462.          printf("%s not removed\n",program);
  463.       } else {
  464.          if (UnSetVectors(NamedPort))
  465.          {
  466.             RemPort(NamedPort);
  467.             CleanUpWindows();
  468.             UnLoadSeg(var(Segment));
  469.             printf("%s removed\n",program);
  470.             CloseLibrary(IntuitionBase);
  471.          } else {
  472.             printf("SetFunction vectors have been changed!\n");
  473.             printf("Cannot remove %s\n",program);
  474.          }
  475.       }
  476.    }
  477. }
  478.