home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 532.lha / sWindows / Source / swMain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-10  |  8.5 KB  |  300 lines

  1. /*
  2.  *  SWINDOWS    A program to allow you to open windows on any screen by
  3.  *              supplying the screen name in thw window title
  4.  *
  5.  *              Copyright 1989 by Davide P. Cervone.
  6.  *  You may use this code, provided this copywrite notice is kept intact.
  7.  */
  8.  
  9. #include "swMain.h"
  10. #include "sWindows.h"
  11.  
  12. struct IntuitionBase *IntuitionBase = NULL;
  13. extern struct SysBase *SysBase;
  14.  
  15. static char *program   = PROGRAM;
  16. static char *copyright = COPYRIGHT;
  17.  
  18. static char *handler   = HANDLERCODE;       /* the name of the handler file */
  19. #define HANDLER          &(handler[2])      /* handler without the L: */
  20.  
  21. static struct swHandlerInfo *swHandlerData; /* data shared with the handler */
  22. static long Segment;                        /* the loaded handler segment */
  23.  
  24. static SLISTITEM *ScreenList;               /* screen item linked list */
  25. static WLISTITEM *WindowList;               /* window item linked list */
  26.  
  27.  
  28. /*
  29.  *  FreeAllMemory()
  30.  *
  31.  *  After the function vectors have been restored, the linked lists are
  32.  *  freed.  If any tasks are waiting for the close signal before
  33.  *  closing their screens, then these tasks are signalled immediately.
  34.  *  Allowing the screen to close before the windows are all closed, however,
  35.  *  is not a good idea.
  36.  */
  37.  
  38. void FreeAllMemory()
  39. {
  40.    SLISTITEM theScreen;
  41.    WLISTITEM theWindow;
  42.  
  43.    Forbid();
  44.    while (*WindowList)
  45.    {
  46.       theWindow = *WindowList;
  47.       *WindowList = theWindow->Next;
  48.       FREE(WindowListItem,theWindow);
  49.    }
  50.    while (*ScreenList)
  51.    {
  52.       theScreen = *ScreenList;
  53.       *ScreenList = theScreen->Next;
  54.       if (theScreen->CloseTask)
  55.          Signal(theScreen->CloseTask,theScreen->CloseSignal);
  56.       FREE(ScreenListItem,theScreen);
  57.    }
  58.    Permit();
  59. }
  60.  
  61.  
  62. /*
  63.  *  DoExit()
  64.  *
  65.  *  General purpose error-exit routine.  Print an error message if one was
  66.  *  supplied (it can have up to three parameters), and then clean up any
  67.  *  memory, libraries, etc. that need to be handled before exiting.
  68.  */
  69.  
  70. static void DoExit(s,x1,x2,x3)
  71. char *s, *x1, *x2, *x3;
  72. {
  73.    long status = EXIT_OK;
  74.    
  75.    if (s != NULL)
  76.    {
  77.       printf(s,x1,x2,x3);
  78.       printf("\n");
  79.       status = EXIT_ERROR;
  80.    }
  81.    FreeAllMemory();
  82.    if (Segment)       UnLoadSeg(Segment);
  83.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  84.    exit(status);
  85. }
  86.  
  87.  
  88. /*
  89.  *  CheckLibOpen()
  90.  *
  91.  *  Call OpenLibrary() for the specified library, and check that the 
  92.  *  open succeeded.
  93.  */
  94.  
  95. static void CheckLibOpen(lib,name,rev)
  96. APTR *lib;
  97. char *name;
  98. int rev;
  99. {
  100.    extern APTR OpenLibrary();
  101.  
  102.    if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
  103.       DoExit("Can't open %s",name);
  104. }
  105.  
  106.  
  107. /*
  108.  *  LoadHandler()
  109.  *
  110.  *  Try to LoadSeg the handler from the current directory, and if it is not
  111.  *  found, try the L: directory.  If neither can be loaded, exit with an
  112.  *  error message.  Once the handler is loaded, call the Setup routine
  113.  *  in the handler code and pass the loader version number.  The handler will
  114.  *  check the version for compatibility and returns NULL if there is a
  115.  *  mismatch, or a pointer to the shared data if everything is OK.
  116.  *  Check the handler version number, and then store the loader version
  117.  *  and the segment list pointer for use in unloading the handler later.
  118.  *  The MsgPort is the first item in the swHandler structure.  It is used
  119.  *  to link the information into the system port list, where we can find it
  120.  *  later.
  121.  */
  122.  
  123. void LoadHandler(thePort)
  124. struct MsgPort **thePort;
  125. {
  126.    struct swHandlerInfo *(*Setup)();
  127.    
  128.    if ((Segment = LoadSeg(HANDLER)) == NULL)
  129.       if ((Segment = LoadSeg(handler)) == NULL)
  130.         DoExit("Can't load %s",handler);
  131.    Setup = (struct swHandlerInfo *(*)()) ((Segment << 2) + 4);
  132.    
  133.    swHandlerData = (*Setup)(LOADVERS);
  134.    if (swHandlerData)
  135.    {
  136.       if (var(MajVers) > 1) DoExit("Version mismatch with %s",HANDLER);
  137.       *thePort = &(swHandlerData->swPort);
  138.    } else {
  139.       DoExit("%s reports a version mismatch",HANDLER);
  140.    }
  141.    
  142.    var(Segment)  = Segment;
  143.    var(LoadVers) = LOADVERS;
  144. }
  145.  
  146.  
  147. /*
  148.  *  SetVerctors()
  149.  *
  150.  *  Set the Intuition library vectors for the OpenWindow, CloseWindow
  151.  *  and CloseScreen to the routines specified by the handler.  Save the
  152.  *  old routine pointers for later replacement.
  153.  */
  154.  
  155. void SetVectors()
  156. {
  157.    VAR(OldOpenWindow)  =
  158.       SetFunction(IntuitionBase,&LVOOpenWindow,var(aOpenWindow));
  159.    VAR(OldCloseWindow) =
  160.       SetFunction(IntuitionBase,&LVOCloseWindow,var(aCloseWindow));
  161.    VAR(OldCloseScreen) =
  162.       SetFunction(IntuitionBase,&LVOCloseScreen,var(aCloseScreen));
  163. }
  164.  
  165.  
  166. /*
  167.  *  UnSetVectors()
  168.  *
  169.  *  Replace the old Intuition library vectors, but make sure that no one
  170.  *  else has changed them behind our back.  If they are not the same as
  171.  *  what we set them to originally, then put back the ones that we found,
  172.  *  and return an error status.
  173.  */
  174.  
  175. int UnSetVectors()
  176. {
  177.    long NewOpenWindow,NewCloseWindow,NewCloseScreen;
  178.    int status = TRUE;
  179.  
  180.    NewOpenWindow =
  181.       SetFunction(IntuitionBase,&LVOOpenWindow,VAR(OldOpenWindow));
  182.    NewCloseWindow =
  183.       SetFunction(IntuitionBase,&LVOCloseWindow,VAR(OldCloseWindow));
  184.    NewCloseScreen =
  185.       SetFunction(IntuitionBase,&LVOCloseScreen,VAR(OldCloseScreen));
  186.  
  187.    if (NewOpenWindow  != (long) var(aOpenWindow)  ||
  188.        NewCloseWindow != (long) var(aCloseWindow) ||
  189.        NewCloseScreen != (long) var(aCloseScreen))
  190.    {
  191.       SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
  192.       SetFunction(IntuitionBase,&LVOCloseWindow,NewCloseWindow);
  193.       SetFunction(IntuitionBase,&LVOCloseScreen,NewCloseScreen);
  194.       status = FALSE;
  195.    }
  196.    return(status);
  197. }
  198.  
  199.  
  200. /*
  201.  *  SetVariables()
  202.  *
  203.  *  The swHandlerData structure is used to allow the loading program to
  204.  *  set up variables needed by the handler (like Intuitionbase, etc.).  This
  205.  *  keeps the handler code to a minimum.  The loader retains pointers to the
  206.  *  linked lists, in case it needs to free memory on behalf of the handler.
  207.  */
  208.  
  209. void SetVariables(thePort)
  210. struct MsgPort *thePort;
  211. {
  212.    VAR(IntuitionBase) = IntuitionBase;
  213.    VAR(SysBase) = SysBase;
  214.    ScreenList = var(ScreenList);
  215.    WindowList = var(WindowList);
  216. }
  217.  
  218.  
  219. /*
  220.  *  GetVariables()
  221.  *
  222.  *  Look up the values stored in the swHandlerData structure.  The 
  223.  *  Intuition library already was opened, and we will need to close it.
  224.  *  The data in the linked lists may need to be freed.
  225.  */
  226.  
  227. void GetVariables(thePort)
  228. struct MsgPort *thePort;
  229. {
  230.    swHandlerData = (struct swHandlerInfo *) thePort;
  231.    IntuitionBase = VAR(IntuitionBase);
  232.    ScreenList    = var(ScreenList);
  233.    WindowList    = var(WindowList);
  234. }
  235.  
  236.  
  237. /*
  238.  *  Main()
  239.  *
  240.  *  Look for the sWindows port, which indicates that sWindows already exists.
  241.  *  If the port does not exist, then sWindows is not active, so
  242.  *    Open Intuition.
  243.  *    Load the handler code and check its version.
  244.  *    Add the port (supplied by the handler) into the system list so we
  245.  *      can find it later.
  246.  *    Set the variables needed by the handler.
  247.  *    Set the Intuition Library vectors the the handler routines
  248.  *    Notify the user that all is ready.
  249.  *  else (the port already exists, so sWindows alreay is active)
  250.  *    Get the pointer to the swHandlerData structure from the port,
  251.  *      and get any variables we need from the structure.
  252.  *    Check that the loader versions are compatible.
  253.  *    Try to remove the SetFunction calls.
  254.  *    If successfull, then
  255.  *      Remove the port from the system list.
  256.  *      Free any window and screen item memory from the linked lists.
  257.  *      Unload the handler segment list.
  258.  *      Notify the user that sWindows is deactivated.
  259.  *      Close Intuition.
  260.  *    else (we could not replace the functions)
  261.  *      Inform the user that sWindows can not be removed
  262.  */
  263.  
  264. void main()
  265. {
  266.    struct MsgPort *NamedPort;
  267.  
  268.    NamedPort = FindPort(PORTNAME);
  269.    if (NamedPort == NULL)
  270.    {
  271.       CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
  272.       LoadHandler(&NamedPort);
  273.       AddPort(NamedPort);
  274.       SetVariables(NamedPort);
  275.       SetVectors(NamedPort);
  276.       printf("%s v%d.%d.%d Installed\n",program,
  277.          var(MajVers),var(MinVers),var(LoadVers));
  278.    } else {
  279.       GetVariables(NamedPort);
  280.       if (var(LoadVers) > LOADVERS)
  281.       {
  282.          printf("Loader version mismatch\n");
  283.          printf("Current handler was started by a higher-version loader\n");
  284.          printf("%s not removed\n",program);
  285.       } else {
  286.          if (UnSetVectors(NamedPort))
  287.          {
  288.             RemPort(NamedPort);
  289.             FreeAllMemory();
  290.             UnLoadSeg(var(Segment));
  291.             printf("%s removed\n",program);
  292.             CloseLibrary(IntuitionBase);
  293.          } else {
  294.             printf("SetFunction vectors have been changed!\n");
  295.             printf("Cannot remove %s\n",program);
  296.          }
  297.       }
  298.    }
  299. }
  300.