home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d500 / wiconify.lha / wIconify / wIconSetter.lzh / wIconSetter / Source / wIconHandler.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  11KB  |  453 lines

  1. /*
  2.  *  WICONSETTER     A companion utility to wIconify.  wIconSetter allows
  3.  *                  you to specify custom icons for windows ans screens
  4.  *                  that normally use the default icons.
  5.  *
  6.  *  wIconHandler.c      The main Handler code.
  7.  *
  8.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  9.  *  You may use this code, provided this copyright notice is kept intact.
  10.  */
  11.  
  12. #include "wIconHandler.h"
  13.  
  14. /*
  15.  *  Variables and routines needed for traps via SetFunction()
  16.  */
  17.  
  18. long OldOpenWindow;
  19. long OldSetWindowTitles;
  20. long OldOpenScreen;
  21. extern void cOpenWindow();
  22. extern void aOpenWindow();
  23. extern void cSetWindowTitles();
  24. extern void aSetWindowTitles();
  25. extern void cOpenScreen();
  26. extern void aOpenScreen();
  27.  
  28. /*
  29.  *  Routines passed to the loader
  30.  */
  31.  
  32. extern void GetProgramName();
  33. extern int  PrefixMatch();
  34. extern ICONWINDOW *FindIcon(); 
  35.  
  36. extern WICONREF *wIconOf();             /* Part of wIconCalls.o */
  37.  
  38.  
  39. static ICONPROGRAM *FirstProgram;       /* The list of icons */
  40. static ICONPROGRAM *ProgramAny;         /* the special ANY program */
  41. static ICONDEFINE  *FirstDefine;        /* the list of defined icons */
  42.  
  43. struct SysBase *SysBase;
  44.  
  45. static char *IconProcess = ICONPROCNAME;    /* Our process name */
  46. #define NOTICONIFY(p)       (stricmp(p,IconProcess) != 0)
  47.  
  48. #define TOUPPER(c)          (((c)>='a'&&(c)<='z')?(c)-'a'+'A':c)
  49. #define MATCH(n1,n2)        (stricmp(n1,n2))
  50. #define PREFIXMATCH(n1,n2)  ((n1) == NAME_ANY || PrefixMatch(n1,n2) == 0)
  51. #define WPREFIXMATCH(n1,n2)\
  52.    (((n1) == NAME_ANY && (n2) != SCREENICON) || PrefixMatch(n1,n2) == 0)
  53.  
  54.  
  55. /*
  56.  *  IconHandlerData is passed to the loader on startup.
  57.  *  It is used to pass values to the loader and receive initialized
  58.  *  values from the loader.
  59.  */
  60.  
  61. struct IconHandlerInfo IconHandlerData =
  62. {
  63.    {                                            /* the MsgPort is pre-setup */
  64.       {NULL,NULL, NT_MSGPORT, 0, PORTNAME},     /*  to include the name and */
  65.       PA_IGNORE, 0, NULL,                       /*  type so that it can just */
  66.       {NULL,NULL,NULL, 0,0}                     /*  be added to the port list */
  67.    },                                           /*  so it can be found later */
  68.    MAJVERS,MINVERS, MINLOADVERS,            /* version numbers */
  69.    NULL,                                    /* the loaded segment code */
  70.    
  71.    /*
  72.     *  The libraries needed by the handler
  73.     */
  74.  
  75.    &IntuitionBase,
  76.    &SysBase,
  77.    
  78.    /*
  79.     *  The routines and variables trapped by the loader
  80.     */
  81.  
  82.    &aOpenWindow,
  83.    &OldOpenWindow,
  84.    &aSetWindowTitles,
  85.    &OldSetWindowTitles,
  86.    &aOpenScreen,
  87.    &OldOpenScreen,
  88.    
  89.    /*
  90.     *  Data needed by the loader
  91.     */
  92.    &GetProgramName,
  93.    &PrefixMatch,
  94.    &FindIcon,
  95.    &FirstDefine,
  96.    &FirstProgram,
  97.    &ProgramAny,
  98. };
  99.  
  100.  
  101. /*
  102.  *  Setup()
  103.  *
  104.  *  This routine MUST be linked into the wIconSetter-Handler executable 
  105.  *  as the first routine, so that the loader can find it.
  106.  *  It should check the version number for compatibility with the loader,
  107.  *  and should return NULL for an error, or the pointer to the shared
  108.  *  data structure if everything is OK.
  109.  */
  110.  
  111. struct IconHandlerInfo *Setup(version)
  112. int version;
  113. {
  114.    if (version < MINLOADVERS) return(NULL);
  115.    return(&IconHandlerData);
  116. }
  117.  
  118.  
  119. /*
  120.  *  PrefixMatch()
  121.  *
  122.  *  Case-insensitive prefix match.  NULL pointers and empty strings
  123.  *  only match themselves, and are not considered prefixes to any string.
  124.  *  The special SCREENICON value only matches itself.
  125.  *
  126.  *  Return <0 if the first is smaller than the second,
  127.  *         =0 if the first is a prefix of the second,
  128.  *         >1 if the first is larger than the second.
  129.  */
  130.  
  131. int PrefixMatch(s1,s2)
  132. char *s1,*s2;
  133. {
  134.    int match = -1;
  135.    
  136.    if (s1 == SCREENICON || s2 == SCREENICON) match = (s1 == s2)? 0: 1;
  137.    else if (s1)
  138.    {
  139.       if (s2)
  140.       {
  141.          if (*s1)
  142.          {
  143.             while (TOUPPER(*s1) == TOUPPER(*s2) && *s2 != 0) s1++,s2++;
  144.             if (*s1 == 0) match = 0; else match = *s1 - *s2;
  145.          } else if (*s2 == 0) match = 0;
  146.       } else match = 1;
  147.    } else if (s2 == NULL) match = 0;
  148.    return(match);
  149. }
  150.  
  151.  
  152.  
  153. /*
  154.  *  FindIconWindow()
  155.  *
  156.  *  Start with the first window of the given screen
  157.  *  While there are more windows to look at
  158.  *    If the window matches the name, return the window pointer
  159.  *    Otherwise go on to the next one
  160.  *  Return NULL if no match
  161.  */
  162.  
  163. static ICONWINDOW *FindIconWindow(IScreen,Name)
  164. ICONSCREEN *IScreen;
  165. char *Name;
  166. {
  167.    ICONWINDOW *IWindow = IScreen->Window;
  168.  
  169.    while (IWindow)
  170.    {
  171.       if (WPREFIXMATCH(IWindow->Name,Name)) return(IWindow);
  172.       IWindow = IWindow->Next;
  173.    }
  174.    return(NULL);
  175. }
  176.  
  177.  
  178. /*
  179.  *  FindIconScreen()
  180.  *
  181.  *  While there are more screen to look at
  182.  *    If the screen matches the name, return the screen pointer
  183.  *    Otherwise go on to the next one
  184.  *  Return NULL if no match
  185.  */
  186.  
  187. static ICONSCREEN *FindIconScreen(IScreen,Name)
  188. ICONSCREEN *IScreen;
  189. char *Name;
  190. {
  191.    while (IScreen)
  192.    {
  193.       if (PREFIXMATCH(IScreen->Name,Name)) return(IScreen);
  194.       IScreen = IScreen->Next;
  195.    }
  196.    return(NULL);
  197. }
  198.  
  199.  
  200. /*
  201.  *  FindIconProgram()
  202.  *
  203.  *  While there are more programs to look at
  204.  *    If the program name is ANY, always match, otherwise
  205.  *      compare the program against the given name
  206.  *    If there was a match, return the program
  207.  *    Otherwise move down to the next level of the tree
  208.  *  Return ProgramAny if nothing else matched
  209.  */
  210.  
  211. static ICONPROGRAM *FindIconProgram(IProgram,Name)
  212. ICONPROGRAM *IProgram;
  213. char *Name;
  214. {
  215.    int result;
  216.  
  217.    while (IProgram)
  218.    {
  219.       if (IProgram->Name == NAME_ANY) result = 0;
  220.          else result = MATCH(IProgram->Name,Name);
  221.       if (result == 0) return(IProgram); else
  222.       if (result < 0) IProgram = IProgram->Prev; else IProgram = IProgram->Next;
  223.    }
  224.    return(ProgramAny);
  225. }
  226.  
  227.  
  228.  
  229. /*
  230.  *  FindIcon()
  231.  *
  232.  *  Find the program structure for the given program name
  233.  *  If found,
  234.  *    Look through the program's list of screens
  235.  *    While there are more screens to check and we haven't found a window
  236.  *      Find the next matching screen
  237.  *      If found,
  238.  *        Look for the window on that screen and go on to the next screen
  239.  *  return the window (or NULL if none found)
  240.  */
  241.  
  242. ICONWINDOW *FindIcon(Program,theScreen,wTitle)
  243. char *Program;
  244. struct Screen *theScreen;
  245. char *wTitle;
  246. {
  247.    ICONPROGRAM *IProgram;
  248.    ICONSCREEN  *IScreen;
  249.    ICONWINDOW  *IWindow = NULL;
  250.    
  251.    IProgram = FindIconProgram(FirstProgram,Program);
  252.    if (IProgram)
  253.    {
  254.       IScreen = IProgram->Screen;
  255.       while (IScreen && IWindow == NULL)
  256.       {
  257.          IScreen = FindIconScreen(IScreen,theScreen->DefaultTitle);
  258.          if (IScreen)
  259.             IWindow = FindIconWindow(IScreen,wTitle),
  260.             IScreen = IScreen->Next;
  261.       }
  262.    }
  263.    return(IWindow);
  264. }
  265.  
  266.  
  267. /*
  268.  *  StripPath()
  269.  *
  270.  *  Start at the end of the string
  271.  *  While there are more characters to look at,
  272.  *    Get the preceding character
  273.  *    If it is '/' or ':' cancel the loop, otherwise back up a character
  274.  *  Clip the length of the name, if necessary
  275.  *  Terminate the Name string
  276.  *  Copy the name portion of the string into the Name buffer
  277.  */
  278.  
  279. static void StripPath(Name,s,len)
  280. char Name[MAXNAME];
  281. char *s;
  282. short len;
  283. {
  284.    short i = 0;
  285.    char c;
  286.  
  287.    s += len;
  288.    while (len)
  289.    {
  290.       c = *(s-1);
  291.       if (c == '/' || c == ':') len = 0;
  292.          else len--, s--, i++;
  293.    }
  294.    if (i >= MAXNAME) i = MAXNAME-1;
  295.    Name[i] = 0;
  296.    while (i--) Name[i] = s[i];
  297. }
  298.  
  299.  
  300. /*
  301.  *  GetProgramName()
  302.  *
  303.  *  If we have a task to look at,
  304.  *    If the task is a process
  305.  *      If the process has a task number and a CLI structure
  306.  *        Get the CLI structure, and use its current command name and length
  307.  *    If we haven't found the name yet,
  308.  *      Get the name from the task structure, and find its length
  309.  *    Strip the path portion off the name
  310.  *  Otherwise clear the name buffer
  311.  */
  312.  
  313. void GetProgramName(Name,theTask)
  314. char Name[MAXNAME];
  315. struct Process *theTask;
  316. {
  317.    struct CommandLineInterface *theCLI;
  318.    char *s = NULL;
  319.    short len;
  320.  
  321.    if (theTask)
  322.    {
  323.       if (theTask->pr_Task.tc_Node.ln_Type == NT_PROCESS)
  324.       {
  325.          if (theTask->pr_TaskNum && theTask->pr_CLI)
  326.          {
  327.             theCLI = (struct CommandLineInterface *)BADDR(theTask->pr_CLI);
  328.             if (theCLI->cli_CommandName)
  329.                s = (char *)(BADDR(theCLI->cli_CommandName)), len = *s++;
  330.          }
  331.       }
  332.       if (s == NULL)
  333.       {
  334.          s = theTask->pr_Task.tc_Node.ln_Name;
  335.          len = strlen(s);
  336.       }
  337.       StripPath(Name,s,len);
  338.    } else {
  339.       Name[0] = 0;
  340.    }
  341. }
  342.  
  343.  
  344. /*
  345.  *  HandleWindow()
  346.  *
  347.  *  Get the name of the current process
  348.  *  If it is not the wIconify-Handler process
  349.  *    Look through the icon list for the given program/screen/window
  350.  *    If found
  351.  *      Get a copy of the icon (so we can modify it)
  352.  *      Remove the Autoiconify flag, if any (it is wIconSetter private)
  353.  *      Get the current icon position (if it exists)
  354.  *      Set the window to have the (modified) icon
  355.  *      If the original icon had the AUTOICONIFY flag and we are supposed
  356.  *        to do autoiconify, then iconify the window
  357.  */
  358.  
  359. static void HandleWindow(theWindow,DoAuto)
  360. struct Window *theWindow;
  361. int DoAuto;
  362. {
  363.    char Program[MAXNAME];
  364.    ICONWINDOW *theIcon;
  365.    WICON tmpIcon;
  366.  
  367.    GetProgramName(Program,FindTask(NULL));
  368.    if (NOTICONIFY(Program))
  369.    {
  370.       theIcon = FindIcon(Program,theWindow->WScreen,theWindow->Title);
  371.       if (theIcon)
  372.       {
  373.          tmpIcon = theIcon->Icon;
  374.          tmpIcon.Flags &= ~WI_AUTOICONIFY;
  375.          wIconXY(wIconOf(theWindow),&(tmpIcon.x),&(tmpIcon.y));
  376.          wSetIcon(theWindow,&tmpIcon);
  377.          if ((theIcon->Icon.Flags & WI_AUTOICONIFY) && DoAuto)
  378.             wIconify(theWindow);
  379.       }
  380.    }
  381. }
  382.  
  383.  
  384. /*
  385.  *  cOpenWindow()
  386.  *
  387.  *  If the window openned successfully,
  388.  *    Check to see if it needs an icon.
  389.  */
  390.  
  391. void cOpenWindow(theWindow)
  392. struct Window *theWindow;
  393. {
  394.    if (theWindow) HandleWindow(theWindow,TRUE);
  395. }
  396.  
  397.  
  398. /*
  399.  *  cSetWindowTitles()
  400.  *
  401.  *  If a window is specified and it is getting a new title,
  402.  *    Check if the window with the new title should get an icon.
  403.  */
  404.  
  405. void cSetWindowTitles(theWindow,wTitle,sTitle)
  406. struct Window *theWindow;
  407. UBYTE *wTitle,*sTitle;
  408. {
  409.    if (theWindow && wTitle != (UBYTE *)-ONE) HandleWindow(theWindow,FALSE);
  410. }
  411.  
  412.  
  413. /*
  414.  *  cOpenScreen()
  415.  *
  416.  *  If the screen has a window (ie, wIconify added its backdrop window
  417.  *    to it already)
  418.  *    Get the name of the current task
  419.  *    If it is not the wIconify-Handler process itself
  420.  *      Look through the icon list for this program/screen
  421.  *      If it needs an icon
  422.  *        Get a copy of the screen icon for modification
  423.  *        Clear the AUTOICONIFY flag (it is wIconSetter private)
  424.  *        Set the screen to have the given icon
  425.  *        If the original icon has the AUTOICONIFY flag,
  426.  *          Iconify the screen
  427.  */
  428.  
  429. void cOpenScreen(theScreen)
  430. struct Screen *theScreen;
  431. {
  432.    char Program[MAXNAME];
  433.    ICONWINDOW *theIcon;
  434.    WICON tmpIcon;
  435.  
  436.    if (theScreen && theScreen->FirstWindow)
  437.    {
  438.       GetProgramName(Program,FindTask(NULL));
  439.       if (NOTICONIFY(Program))
  440.       {
  441.          theIcon = FindIcon(Program,theScreen,SCREENICON);
  442.          if (theIcon)
  443.          {
  444.             tmpIcon = theIcon->Icon;
  445.             tmpIcon.Flags &= ~WI_AUTOICONIFY;
  446.             wSetScreenIcon(theScreen,&tmpIcon);
  447.             if ((theIcon->Icon.Flags & WI_AUTOICONIFY))
  448.                wIconifyScreen(theScreen);
  449.          }
  450.       }
  451.    }
  452. }
  453.