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 >
C/C++ Source or Header  |  1991-06-06  |  8KB  |  253 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 "swHandler.h"
  10.  
  11. static char *program   = PROGRAM;
  12. static char *copyright = COPYRIGHT;
  13.  
  14. /* don't want to have to include LIB:lc.lib in the linking */
  15.  
  16. #define toupper(c)  (((c)>='a'&&(c)<='z')?(c)+('A'-'a'):(c))
  17.  
  18.  
  19. /*
  20.  *  FindScreen()
  21.  *
  22.  *  FindScreen looks through the IntuitionBase linked list of screens
  23.  *  for a screen whose title matches the one supplied by the user.
  24.  *  If no title was supplied, then the active screen is returned.
  25.  *  A case-insensitive prefix match is performed.  If the screen is
  26.  *  not found, FindScreen returns NULL.
  27.  */
  28.  
  29. static struct Screen *FindScreen(OldTitle,Title)
  30. UBYTE *OldTitle,*Title;
  31. {
  32.    register struct Screen *theScreen = IntuitionBase->ActiveScreen;
  33.    register UBYTE *TName,*SName;
  34.    int NotDone = TRUE;
  35.    ULONG ILock;
  36.    
  37.    if (OldTitle != Title)
  38.    {
  39.       ILock = LockIBase(0L);
  40.       theScreen = IntuitionBase->FirstScreen;
  41.       while (theScreen && NotDone)
  42.       {
  43.          TName = theScreen->Title;
  44.          if (TName)
  45.          {
  46.             SName = OldTitle;
  47.             while (SName < Title && toupper(*TName) == toupper(*SName))
  48.             {
  49.                SName++;
  50.                TName++;
  51.             }
  52.             if (SName == Title) NotDone = FALSE;
  53.          }
  54.          if (NotDone) theScreen = theScreen->NextScreen;
  55.       }
  56.       UnlockIBase(ILock);
  57.    }
  58.    return(theScreen);
  59. }
  60.  
  61.  
  62. /*
  63.  *  OpenOnScreen()
  64.  *
  65.  *  The NewWindow structure is modified temporarily to incorporate the 
  66.  *  correct screen pointer and type.  The title is shortened so that
  67.  *  the screen name and "::" are note included in the window title.
  68.  *  Once the window is opened, the NewWindow structure is restored in case
  69.  *  it needs to be used by the calling program again.
  70.  */
  71.  
  72. static struct Window *OpenOnScreen(theScreen,NewWindow,Title,OldTitle)
  73. struct Screen *theScreen;
  74. struct NewWindow *NewWindow;
  75. UBYTE *Title,*OldTitle;
  76. {
  77.    struct Window *theWindow;
  78.    struct Screen *OldScreen;
  79.    USHORT OldType;
  80.    
  81.    OldScreen = NewWindow->Screen;
  82.    OldType   = NewWindow->Type;
  83.  
  84.    NewWindow->Screen = theScreen;
  85.    NewWindow->Type   = (theScreen->Flags & SCREENTYPE);
  86.    NewWindow->Title  = (*Title)? Title: NULL;
  87.    theWindow = aOldOpenWindow(NewWindow);
  88.  
  89.    NewWindow->Title  = OldTitle;
  90.    NewWindow->Screen = OldScreen;
  91.    NewWindow->Type   = OldType;
  92.  
  93.    return(theWindow);
  94. }
  95.  
  96.  
  97. /*
  98.  *  cOpenWindow()
  99.  *
  100.  *  This is the replacement for OpenWindow.
  101.  *
  102.  *  If a NewWindow structure was supplied and it has a title string, then
  103.  *  Search the title string for "::" (change CHAR1 and CHAR2 if you want to 
  104.  *    use different characters for the separators)
  105.  *  If "::" was found, then
  106.  *     Look for the screen with the given title.
  107.  *     If one was found, then
  108.  *        Get the ScreenlistItem associated with that screen
  109.  *        If one was found (or newly created) then
  110.  *          Make a new WindowListItem for this window
  111.  *          If successfull, then
  112.  *            Save the ScreenItem pointer
  113.  *            Open the window on the specified screen, and
  114.  *            If window opened OK, then add it to the linked list
  115.  *            Otherwise free the WindowListItem, and maybe the ScreenItem too
  116.  *           Otherwise
  117.  *            Free the ScreenItem if it was newly created.
  118.  *  If for any reason, the old OpenWindow was not called, 
  119.  *    Try to open the window without changes to the NewWindow structure.
  120.  *  return the window pointer produced.
  121.  */
  122.  
  123. struct Window *cOpenWindow(NewWindow)
  124. struct NewWindow *NewWindow;
  125. {
  126.    UBYTE *Title,*OldTitle;
  127.    struct Window *theWindow = NOWINDOW;
  128.    struct Screen *theScreen;
  129.    SLISTITEM ScreenItem;
  130.    WLISTITEM WindowItem;
  131.  
  132.    if (NewWindow && NewWindow->Title)
  133.    {
  134.       Title = OldTitle = NewWindow->Title;
  135.       while (*Title && (*Title != CHAR1 || *(Title+1) != CHAR2)) Title++;
  136.       if (*Title)
  137.       {
  138.          theScreen = FindScreen(OldTitle,Title);
  139.          if (theScreen)
  140.          {
  141.             ScreenItem = FindScreenListItem(theScreen);
  142.             if (ScreenItem)
  143.             {
  144.                if (NEW(WindowListItem,WindowItem))
  145.                {
  146.                   WindowItem->Screen = ScreenItem;
  147.                   theWindow = 
  148.                      OpenOnScreen(theScreen,NewWindow,Title+2,OldTitle);
  149.                   if (theWindow)
  150.                   {
  151.                      AddWindowListItem(WindowItem,theWindow);
  152.                   } else {
  153.                      FREE(WindowListItem,WindowItem);
  154.                      UnuseScreenListItem(ScreenItem);
  155.                   }
  156.                } else {
  157.                   UnuseScreenListItem(ScreenItem);
  158.                }
  159.             }
  160.          }
  161.       }
  162.    }
  163.    if (theWindow == NOWINDOW) theWindow = aOldOpenWindow(NewWindow);
  164.    return(theWindow);
  165. }
  166.  
  167.  
  168. /*
  169.  *  cCloseWindow()
  170.  *
  171.  *  This is the replacement for CloseWindow().
  172.  *  (the old CloseWindow is called by the stub before calling this routine)
  173.  *  
  174.  *  Look through the window item list for this window.
  175.  *  If the window was found (i.e., it was opened by sWindows) then
  176.  *    Free the window item and remove it from the list.
  177.  *    Check to see whether the screen can now be closed
  178.  */
  179.  
  180. void cCloseWindow(theWindow)
  181. struct Window *theWindow;
  182. {
  183.    WLISTITEM WindowItem;
  184.    SLISTITEM ScreenItem;
  185.    
  186.    Forbid();
  187.    WindowItem = WindowList;
  188.    while (WindowItem && WindowItem->Window != theWindow)
  189.       WindowItem = WindowItem->Next;
  190.    if (WindowItem)
  191.    {
  192.       ScreenItem = WindowItem->Screen;
  193.       FreeWindowListItem(WindowItem);
  194.       UnuseScreenListItem(ScreenItem);
  195.    }
  196.    Permit();
  197. }
  198.  
  199.  
  200. /*
  201.  *  cCloseScreen()
  202.  *
  203.  *  This is the replacement for CloseScreen().
  204.  *  (the old CloseScreen is called by the stub after this routine returns)
  205.  *
  206.  *  Look through the screen list to for this screen.
  207.  *  If found (i.e., there is a window opened by sWindows open on it), then
  208.  *    Allocate a signal so so that we can wait for all the windows to close
  209.  *    If one could not be allocated, use the default signal.
  210.  *    Clear the close signal.
  211.  *    Save the old task pointer and signal (in case some other task also 
  212.  *       called CloseScreen for this screen).
  213.  *    Set the task pointer and signal in the ScreenItem so that we can get 
  214.  *      signaled when all the windows are closed.
  215.  *    Wait for the close signal to arrive.
  216.  *    (time passes ... finally all the windows are closed)
  217.  *    If there was another task was waiting, signal it.
  218.  *    Free the allocated signal bit.
  219.  */
  220.  
  221. void cCloseScreen(theScreen)
  222. struct Screen *theScreen;
  223. {
  224.    SLISTITEM ScreenItem;
  225.    APTR NextTask;
  226.    ULONG NextSignal,mySignal;
  227.    UBYTE mySigBit;
  228.    extern APTR FindTask();
  229.    extern ULONG AllocSignal();
  230.  
  231.    Forbid();
  232.    ScreenItem = ScreenList;
  233.    while (ScreenItem && ScreenItem->Screen != theScreen)
  234.       ScreenItem = ScreenItem->Next;
  235.    if (ScreenItem)
  236.    {
  237.       mySigBit = AllocSignal(-ONE);
  238.       mySignal = (mySigBit == -ONE)? DEFAULTSIGNAL: (ONE<<mySigBit);
  239.       SetSignal(mySignal,0L);
  240.       NextSignal = ScreenItem->CloseSignal;
  241.       NextTask   = ScreenItem->CloseTask;
  242.       ScreenItem->CloseSignal = mySignal;
  243.       ScreenItem->CloseTask   = FindTask(NULL);
  244.    }
  245.    Permit();
  246.    if (ScreenItem)
  247.    {
  248.       Wait(mySignal);
  249.       if (NextTask) Signal(NextTask,NextSignal);
  250.       if (mySigBit != -ONE) FreeSignal(mySigBit);
  251.    }
  252. }
  253.