[comp.sources.amiga] v91i016: ToolManager 1.2 - add to the Tools menu of Workbench 2.0, Part01/01

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (02/19/91)

Submitted-by: stefanb@cip-s02.informatik.rwth-aachen.de (Stefan Becker)
Posting-number: Volume 91, Issue 016
Archive-name: utilities/toolmanager-12/part01

[ uuencoded executable enclosed  ...tad ]

With ToolManager you can add your own programs to the Tools menu of the 2.0
Workbench. The name of the programs can be given at startup (CLI or Workbench
parameters) or in a configuration file. Furthermore the user can drop a Tool or
Project icon on the program's icon (or its status window) to add a tool to the
list.


#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  DMakefile ToolManager.Readme ToolManager.c
#   ToolManager.config ToolManager.doc ToolManager.h ToolManager.uu
#   data.c toollist.c window.c
# Wrapped by tadguy@ab20 on Mon Feb 18 17:08:02 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'DMakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'DMakefile'\"
else
echo shar: Extracting \"'DMakefile'\" \(232 characters\)
sed "s/^X//" >'DMakefile' <<'END_OF_FILE'
XSRCS=toolmanager.c toollist.c window.c data.c
XOBJS=$(SRCS:"*.c":"*.o")
X
XToolManager : $(OBJS)
X         dcc -o %(left) %(right)
X
X$(OBJS) : $(SRCS)
X         dcc -o %(left) -c %(right)
X
X$(SRCS) : ToolManager.h
X         SetDate %(left)
END_OF_FILE
if test 232 -ne `wc -c <'DMakefile'`; then
    echo shar: \"'DMakefile'\" unpacked with wrong size!
fi
# end of 'DMakefile'
fi
if test -f 'ToolManager.Readme' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ToolManager.Readme'\"
else
echo shar: Extracting \"'ToolManager.Readme'\" \(933 characters\)
sed "s/^X//" >'ToolManager.Readme' <<'END_OF_FILE'
XReadme for ToolManager 1.2                                          13.01.1991
X
XWith ToolManager you can add your own programs to the Tools menu of the 2.0
XWorkbench. The name of the programs can be given at startup (CLI or Workbench
Xparameters) or in a configuration file. Furthermore the user can drop a Tool or
XProject icon on the program's icon (or its status window) to add a tool to the
Xlist.
X
XBEWARE: This program makes heavely use of the new 2.0 functions, so its
X        completely useless to all people who are still forced to use 1.3 :-)
X
XNew features since 1.1:
X   - Status window changed to a no-GZZ & simple refresh type
X     (this should save some bytes)
X   - Status window remembers its last position
X   - New status window gadget "Save Configuration": saves the actual tool
X     list in the configuration file
X   - Small bugs removed in the ListView gadget handling
X   - Name of the icon hard-wired to "ToolManager"
END_OF_FILE
if test 933 -ne `wc -c <'ToolManager.Readme'`; then
    echo shar: \"'ToolManager.Readme'\" unpacked with wrong size!
fi
# end of 'ToolManager.Readme'
fi
if test -f 'ToolManager.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ToolManager.c'\"
else
echo shar: Extracting \"'ToolManager.c'\" \(8003 characters\)
sed "s/^X//" >'ToolManager.c' <<'END_OF_FILE'
X#include "ToolManager.h"
X
X/* Library pointers */
Xextern struct Library *SysBase,*IntuitionBase,*GfxBase; /* Autoinit Libs */
Xstruct Library *WorkbenchBase,*IconBase,*GadToolsBase;
X
X/* Structures for icon */
Xextern struct DiskObject MyIcon;
Xstatic struct AppIcon *MyAppIcon;
X
X/* Name of the message port & icon */
Xstatic char *MyName="ToolManager";
X
X/* Tags for System() */
Xextern struct TagItem MyTags[];
X#define SYSTAGS_IN  0
X#define SYSTAGS_OUT 1
X
X/* miscellaneous */
Xstatic struct AppMenuItem *MyAppMenuItem;
X
X/* Workbench main entry point */
Xvoid wbmain(struct WBStartup *wbarg)
X{
X BPTR fl;
X
X fl=CurrentDir(wbarg->sm_ArgList->wa_Lock); /* Goto a valid directory */
X startup();                                 /* common startup code */
X CurrentDir(fl);                            /* Go back to old directory */
X                                            /* Process WB startup parameters */
X WBAddToolNode(&wbarg->sm_ArgList[1],wbarg->sm_NumArgs-1);
X mainloop();                                /* Go into main loop */
X}
X
X/* CLI main entry point */
Xvoid main(int argc, char **argv)
X{
X int i;
X BPTR fl;
X
X startup();           /* common startup code */
X fl=CurrentDir(NULL); /* Get current directory lock */
X                      /* Process CLI startup parameters */
X for (i=1; i<argc; i++) AddToolNode(fl,argv[i],NULL);
X CurrentDir(fl);      /* Go back to old directory */
X mainloop();          /* Go into main loop */
X}
X
X/* Buffer length for one config file line */
X#define BUFLEN 100
X
X/* Handle common startup operations */
Xvoid startup(void)
X{
X BPTR fl;
X FILE *fh;                /* Filehandle for config file */
X char ConfigLine[BUFLEN]; /* Buffer for one config file line */
X
X if (SysBase->lib_Version<36)  /* Sanity check */
X  {
X   puts("You need a Kickstart 2.0 or better to run ToolManager!");
X   exit(20);
X  }
X
X Forbid();                     /* Is "ToolManager" already running? */
X MyMP=FindPort(MyName);
X Permit();
X if (MyMP)
X  {                            /* Yes, exit gracefully */
X   puts("ToolManager already running!");
X   exit(5);
X  }
X
X /* Open libraries */
X if (!(WorkbenchBase=OpenLibrary(WORKBENCH_NAME,0)))
X  cleanup(1);
X
X if (!(IconBase=OpenLibrary(ICONNAME,0)))
X  cleanup(2);
X
X if (!(GadToolsBase=OpenLibrary("gadtools.library",0)))
X  cleanup(3);
X
X /* Create message port */
X if (!(MyMP=CreateMsgPort()))
X  cleanup(4);
X MyMP->mp_Node.ln_Pri=0;
X MyMP->mp_Node.ln_Name=MyName;   /* Our name */
X AddPort(MyMP);                  /* Announce our presence */
X
X /* Notify Workbench about icon */
X if (!(MyAppIcon=AddAppIcon(NULL,NULL,MyName,MyMP,NULL,&MyIcon,NULL)))
X  cleanup(5);
X
X /* Notify Workbench about special menu item. If this item is selected,
X    the program will quit */
X if (!(MyAppMenuItem=AddAppMenuItem(NULL,NULL,"Quit ToolManager",MyMP,NULL)))
X  cleanup(6);
X
X NewList(&ToolList);  /* Initialize tool list */
X fl=CurrentDir(NULL); /* Get the current directory */
X
X if (fh=fopen(ConfigName,"r")) /* Scan config file */
X  {
X   while (!feof(fh)) /* if not end of file, read one line into buffer */
X    if (fgets(ConfigLine,BUFLEN,fh) && (strlen(ConfigLine)>1))
X     {
X      char *tp;
X
X      ConfigLine[strlen(ConfigLine)-1]='\0'; /* Strip newline */
X      if (tp=strchr(ConfigLine,';'))         /* scan config line */
X       {
X        *tp='\0';                        /* Menu entry ; real program name */
X        AddToolNode(fl,ConfigLine,++tp);
X       }
X      else
X       AddToolNode(fl,ConfigLine,NULL);  /* Menu entry == real program name */
X     }
X   fclose(fh);  /* close config file */
X  }
X CurrentDir(fl); /* go back to old directory */
X}
X
X/* The main processing loop */
Xvoid mainloop(void)
X{
X BOOL end=TRUE;                  /* Flag for main loop */
X BOOL windowopen=FALSE;          /* Flag for status window */
X ULONG sigs,bsigs,psigs,wsigs;   /* Buffers for signals */
X
X bsigs=SIGBREAKF_CTRL_C|         /* break signals */
X       SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F;
X psigs=1L<<MyMP->mp_SigBit;      /* port signal */
X sigs=bsigs|psigs;               /* merge signals */
X
X while (end)                     /* main loop */
X  {
X   struct AppMessage *msg;       /* pointer to received message */
X   ULONG gotsigs;                /* received signals */
X
X   gotsigs=Wait(sigs);           /* Wait for specified signals */
X
X   if (gotsigs&bsigs)            /* Got break signals? */
X    end=FALSE;                   /* Yes, quit program */
X
X   if (gotsigs&psigs)            /* Message arrived at message port? */
X    while (msg=GetMsg(MyMP))     /* Yes, empty message queue */
X     {
X      switch(msg->am_Type)       /* Switch between message types */
X       {
X        case MTYPE_APPWINDOW:    /* Window action */
X        case MTYPE_APPICON:      /* Icon action */
X         if (msg->am_NumArgs==0) /* Did the user double click my icon? */
X          {                      /* Yes! If window not open, open it */
X           if ((!windowopen) && (wsigs=OpenStatusWindow()))
X            {
X             sigs|=wsigs;        /* Merge with other signals */
X             windowopen=TRUE;    /* Window is open */
X            }
X          }
X         else                    /* User dropped an icon on my icon */
X          {                      /* Add Workbench parameters to tool list */
X           if (!WBAddToolNode(msg->am_ArgList,msg->am_NumArgs))
X            DisplayBeep(NULL);
X           if (windowopen)       /* Refresh status window if open */
X            RefreshStatusWindow();
X          }
X         break;
X
X        case MTYPE_APPMENUITEM:  /* Menu action */
X         if (msg->am_ID==NULL)   /* Special menu item selected? */
X          end=FALSE;             /* Yes, quit program */
X         else                    /* No, scan list for selected tool */
X          {
X           struct ToolNode *tn;
X
X           for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn))
X            if (tn->tn_ID==msg->am_ID)
X             {                                /* Corresponding tool found */
X              BPTR fl,dfh;                    /* AmigaDOS Filehandles */
X              char *cp;
X
X              fl=CurrentDir(tn->tn_DirLock);  /* Change to tool's directory */
X              dfh=Open("NIL:",MODE_NEWFILE);  /* Open dummy files for */
X              MyTags[SYSTAGS_IN].ti_Data=dfh; /* program I/O */
X              dfh=Open("NIL:",MODE_NEWFILE);
X              MyTags[SYSTAGS_OUT].ti_Data=dfh;
X              if (!(cp=tn->tn_RealName))      /* Get tool name */
X               cp=tn->tn_Node.ln_Name;
X              if (System(cp,MyTags)==-1)      /* Start tool */
X                DisplayBeep(NULL);
X              CurrentDir(fl);                 /* Change to old directory */
X              break;                          /* quit loop */
X             }
X          }
X         break;
X       } /* end of switch(msg->am_Type) */
X
X      ReplyMsg(msg); /* Reply message to sender */
X     } /* end of while(msg=GetMsg(MyMP)) */
X
X   if (windowopen && (gotsigs&wsigs)) /* If window open, got window signal? */
X    if (HandleWindowEvent())          /* Handle window event */
X    {                                 /* Window close event? */
X     CloseStatusWindow();             /* Yes, close window */
X     sigs&=~wsigs;                    /* Remove window signals */
X     windowopen=FALSE;                /* Window closed */
X    }
X  } /* end of main loop */
X
X /* If window open, close it */
X if (windowopen) CloseStatusWindow();
X
X /* Exit program */
X cleanup(99);
X}
X
X/* Final cleanup routine */
Xvoid cleanup(int i)
X{
X register struct Message *msg;
X
X switch(i)
X  {
X   case 99:
X           RemoveTools();
X           RemoveAppMenuItem(MyAppMenuItem);
X   case  6:RemoveAppIcon(MyAppIcon);
X   case  5:RemPort(MyMP);                           /* Remove message port */
X           while (msg=GetMsg(MyMP)) ReplyMsg(MyMP); /* Reply all messages */
X           DeleteMsgPort(MyMP);
X   case  4:CloseLibrary(GadToolsBase);
X   case  3:CloseLibrary(IconBase);
X   case  2:CloseLibrary(WorkbenchBase);
X   case  1:break;
X  }
X
X if (i!=99) exit(i); /* error if i!=99 */
X exit(RETURN_OK);    /* all o.k. */
X}
END_OF_FILE
if test 8003 -ne `wc -c <'ToolManager.c'`; then
    echo shar: \"'ToolManager.c'\" unpacked with wrong size!
fi
# end of 'ToolManager.c'
fi
if test -f 'ToolManager.config' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ToolManager.config'\"
else
echo shar: Extracting \"'ToolManager.config'\" \(136 characters\)
sed "s/^X//" >'ToolManager.config' <<'END_OF_FILE'
XEdit Text;C:DME
XEdit Binary;C:Zap
XEdit Icons;Sys:Tools/IconEdit
XDisk Copy;C:TurboBackup
XBrowser
XNew Shell;NewWSH
XThis is a dummy entry;
END_OF_FILE
if test 136 -ne `wc -c <'ToolManager.config'`; then
    echo shar: \"'ToolManager.config'\" unpacked with wrong size!
fi
# end of 'ToolManager.config'
fi
if test -f 'ToolManager.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ToolManager.doc'\"
else
echo shar: Extracting \"'ToolManager.doc'\" \(4170 characters\)
sed "s/^X//" >'ToolManager.doc' <<'END_OF_FILE'
XDocumentation for ToolManager 1.2                                   13.01.1991
X
XThis is program is FreeWare. The author is not responsible for any damage
Xcaused by the use of this program.
X
X I. What is ToolManager?
XWith ToolManager you can add your own programs to the Tools menu of the 2.0
XWorkbench. The name of the programs can be given at startup (CLI or Workbench
Xparameters) or in a configuration file. Furthermore the user can drop a Tool or
XProject icon on the program's icon (or its status window) to add a tool to the
Xlist.
X
XBEWARE: This program makes heavely use of the new 2.0 functions, so its
X        completely useless to all people who are still forced to use 1.3 :-)
X
X II. How to start ToolManager
X- From CLI:  Run ToolManager [<program 1>] ... [<program n>]
XIf you want to use it in your Startup-Sequence, you will need to redirect its
Xstandard I/O or use RunBack. The name of program x will also be the name of its
Xcorresponding menu item.
X
X- From Workbench: <Click on ToolManager's icon>
X                  [<Click on program 1's icon>] ...
X                  [<Double click program n's icon>]
XIf you selected a Tool icon, its name will also be the name of the menu item.
XIf you selected a Project icon, the icon name will be the name of the menu
Xentry. The default tool of this icon will be called if the menu item is
Xselected.
X
XAfter the program has started, you will see a neat icon. Only one ToolManager
Xcan be active at a time, so every try to start it a second time will fail!
X
X III. The configuration file
XToolManager scans also a file called "S:ToolManager.config". It consists of
Xlines which look as follows:
X
X    <Menu entry name>[;<Real program name>]
X
XIf only one name is given, it will be the name of the menu entry and also of
Xthe program to be called for this entry. If two names are given, the first will
Xbe the name of the menu entry and the second one will be the name of the
Xprogram to be called.
X
XTo create a dummy entry without function, use:
X
X    <Dummy menu entry name>;
X
XLook at the example configuration file.
X
X IV. How to use ToolManager
XWhen ToolManager is active, you can see additional entries in the Workbench
XTools menu. To start a tool you select its entry. Easy, isn't it? There is a
Xspecial menu entry called "Quit ToolManager", which causes ToolManager to quit.
XIt also quits if you send his process a break signal.
X
XIf you double-click the ToolManager icon, it opens the status window. To add a
Xnew tool, you just drag a Tool (or Project) icon on ToolManager's icon or on
Xthe status window and it will be added to the menu.
X
XThe status window contains a list of all tool names. To remove a tool, you
Xselect a name from the list and click the "Remove Tool" button. If you select
Xthe "Save configuration" button, the actual tool list will be saved in the
Xconfiguration file. The window remembers its position when you close it.
X
X V. How to compile ToolManager
XThis program was developed with DICE (nice job Matt!). You will need the
Xregistered version, because I used the __chip keyword, but DICE is worth its
X$40 anyway. Of course you need the 2.0 include files and the 2.0 amiga.lib.
X
X TODO
X- Icon for Workbench usage
X- Better looking internal icon (hey, I'm not a painter :-)
X- Support for different configuration files
X- Add tools at runtime with a second call of ToolManager
X
X HISTORY
X1.2: Release version (13.01.1991)
X   - Status window changed to a no-GZZ & simple refresh type
X     (this should save some bytes)
X   - Status window remembers its last position
X   - New status window gadget "Save Configuration": saves the actual tool
X     list in the configuration file
X   - Small bugs removed in the ListView gadget handling
X   - Name of the icon hard-wired to "ToolManager"
X
X1.1 Release version (01.01.1991)
X   - Icons can be dropped on the status window
X   - Status window contains a list of all tool names
X   - Tools can be removed from the list
X
X1.0 Release version (04.11.1990)
X   - Initial release
X
X THANKS TO
X   - Brian Wright (IRCnick: VanHalen) for his suggestions
X
X   Send comments or bug reports to:
X
XDomain: stefanb@informatik.rwth-aachen.de
XBang  : ..mcvax!unido!rwthinf!stefanb
XFIDO  : 2:242/7.6
END_OF_FILE
if test 4170 -ne `wc -c <'ToolManager.doc'`; then
    echo shar: \"'ToolManager.doc'\" unpacked with wrong size!
fi
# end of 'ToolManager.doc'
fi
if test -f 'ToolManager.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ToolManager.h'\"
else
echo shar: Extracting \"'ToolManager.h'\" \(1605 characters\)
sed "s/^X//" >'ToolManager.h' <<'END_OF_FILE'
X#include <exec/types.h>
X#include <stdlib.h>
X#include <stdio.h>
X#include <string.h>
X#include <exec/libraries.h>
X#include <exec/memory.h>
X#include <dos/dos.h>
X#include <dos/dostags.h>
X#include <intuition/intuition.h>
X#include <workbench/icon.h>
X#include <workbench/startup.h>
X#include <workbench/workbench.h>
X
X/* Prototypes for system functions */
X#include <clib/dos_protos.h>
X#include <clib/exec_protos.h>
X#include <clib/gadtools_protos.h>
X#include <clib/graphics_protos.h>
X#include <clib/icon_protos.h>
X#include <clib/intuition_protos.h>
X#include <clib/wb_protos.h>
X
X/* Version number & dates */
X#define TM_VERSION "1.2"
X#define TM_CRYEAR "1991"
X#define TM_DATE "13.01.1991"
X
X/* Entry for tool list */
Xstruct ToolNode {
X                 struct Node tn_Node;
X                 BPTR tn_DirLock;
X                 char *tn_RealName;
X                 struct AppMenuItem *tn_MenuItem;
X                 ULONG tn_ID;
X                };
X
X/* Prototypes for library functions */
Xstruct ToolNode *GetHead(struct List *);
Xstruct ToolNode *GetSucc(struct ToolNode *);
X
X/* Prototypes for program functions */
Xvoid startup(void);
Xvoid mainloop(void);
XBOOL WBAddToolNode(struct WBArg *, int);
XBOOL AddToolNode(BPTR, char *, char *);
Xvoid RemToolNode(struct ToolNode *tn);
Xvoid RemoveTools(void);
XULONG OpenStatusWindow(void);
Xvoid RefreshStatusWindow(void);
Xvoid DetachToolList(void);
Xvoid AttachToolList(void);
XBOOL HandleWindowEvent(void);
Xvoid CloseStatusWindow(void);
Xvoid cleanup(int);
X
X/* Global variables */
Xextern struct MsgPort *MyMP;
Xextern struct List ToolList;
Xextern UWORD ToolCount;
Xextern char ConfigName[];
END_OF_FILE
if test 1605 -ne `wc -c <'ToolManager.h'`; then
    echo shar: \"'ToolManager.h'\" unpacked with wrong size!
fi
# end of 'ToolManager.h'
fi
if test -f 'ToolManager.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ToolManager.uu'\"
else
echo shar: Extracting \"'ToolManager.uu'\" \(16120 characters\)
sed "s/^X//" >'ToolManager.uu' <<'END_OF_FILE'
Xbegin 666 ToolManager
XM```#\P`````````#``````````(```I;````XT```"0```/I```*6TCG/SXL0
XM>0````0D3R\(+P`P/```9U0@/````%70O````([E@%"`*@`B/``!``!.KO\Z[
XM2H!F""Y*</]@``#L($!"F"#%2>A__D?H__A#^0`````@/````(Y@`B#94<C_W
XM_)"\``$``&3R8`Q)^0````!)['_^E\M![(`"(#P```".Y8#1P"`\````57(`3
XM8`(@P5'(__R0O``!``!D\BE+@D8I2H(^<``B/```$`!.KO[.*4Z".DZY```CL
XM&&882'@``4ZY```CU%B/3KD``".@9@1.N@Y.0J="ITAX__].N0``(]18CRQLA
XM@CI.N0``(]!.N0``(Z@J;((^+"R"0B`L@D9G$B1`)E(@*@`$(DI.KO\N(`MF7
XM[B`O``0N34J&9PI.KO]\(D9.KOZ&3-]\_$YU3G%(YR`@)&\`#"!J`"0O$$ZZ$
XM(JQ8CR0`3KH`="\"3KHBGEB/("H`'%.`+P`@:@`D2&@`"$ZZ!=Q0CTZZ`F),#
XMWP0$3G5(YS@@)"\`%"1O`!A.N@`\0J=.NB)F6(\H`'8!8!9"IR`#Y8`O,@@`6
XM+P1.N@2B3^\`#%*#M(-NYB\$3KHB/EB/3KH"&$S?!!Q.=4CG(#!.5?^<(&R"(
XM.@QH`"0`%&042&R`B$ZZ$8)8CTAX`!1.N@SD6(].NB/&+RR`&DZZ(Y98CRE`&
XM@WI.NB0(2JR#>F<42&R`:TZZ$5)8CTAX``5.N@RT6(]"ITAL@%E.NB/,4(\IY
XM0(-&2JR#1F8*2'@``4ZZ`UY8CT*G2&R`3$ZZ(ZQ0CRE`@TI*K(-*9@I(>``"3
XM3KH#/EB/0J=(;(`[3KHCC%"/*4"#3DJL@TYF"DAX``-.N@,>6(].NB+J*4"#B
XM>DJL@WIF"DAX``1.N@,&6(\@;(-Z$7P````)(&R#>B%L@!H`"B\L@WI.NB)B6
XM6(]"ITAL@3I"IR\L@WHO+(`:0J="ITZZ)@A/[P`<*4"#4DJL@U)F"DAX``5.C
XMN@*X6(]"IR\L@WI(;(`J0J="ITZZ)?I/[P`4*4"#5DJL@U9F"DAX``9.N@*.D
XM6(](;(-^3KHF3EB/0J=.NB#:6(\D`$AL@"A(;(&*3KH2LE"/)$`@"F<``)!@@
XM``!Z+PI(>`!D2&W_G$ZZ$4Y/[P`,($`F2"`+9UY(;?^<3KH5=EB/<@&R@&Q._
XM2&W_G$ZZ%698CU.`&[P```B<2'@`.TAM_YQ.NA604(\F0"`+9Q@6O```4HLO-
XM"TAM_YPO`DZZ`JY/[P`,8!!"ITAM_YPO`DZZ`IQ/[P`,""H``0`G9P#_@"\*1
XM3KH/V%B/+P).NB`L6(].74S?#`1.=4CG/S).5?_X.WP``?_^.WP``/_\)#P`L
XM`/``(&R#>G`!$B@`#^.@)@`@`X""*T#_^&```6PO+?_X3KHB7EB/*@`@`L"%#
XM9P8[?```__X@`\"%9P`!(F```0PP*@`47T!G#%-`9PA30&=68```\$JJ`!YF:
XM(DIM__QF``#B3KH&W"@`2H1G``#6B:W_^#M\``'__&```,@O*@`>+RH`(DZZ[
XM`M90CTI`9@A"ITZZ(]I8CTIM__QG``"F3KH(!&```)Y*J@`:9@H[?```__Y@G
XM``".2&R#?DZZ&018CR9`8```>B`K`!JPJ@`:9F0O*P`.3KH?,EB/+`!(>`/NW
XM2&R`(TZZ'YY0CRX`*4>!I$AX`^Y(;(`>3KH?BE"/+@`I1X&L+&L`$B`.9@0L)
XM:P`*2&R!H"\.3KH?P%"/<O^R@&8(0J=.NB-&6(\O!DZZ'MI8CV`.+PM.NAB(+
XM6(\F0"X+9H0O"DZZ(0Y8CR\L@WI.NB"@6(\D0"X*9@#^YDIM__QG)"X$SH5G=
XM'DZZ!\H^`$I'9Q1.N@D\(@1&@2`!P:W_^#M\``#__$IM__YF`/Z02FW__&<$X
XM3KH)&DAX`&-.N@`,6(].74S?3/Q.=4CG("`D+P`,(`)3@&<``(93@&<``'93=
XM@&=F4X!G6%.`9R13@&<6<EV0@6<"8&9.N@)^+RR#5DZZ(VI8CR\L@U).NB-,[
XM6(\O+(-Z3KH@-EB/8`HO+(-Z3KH@4EB/+RR#>DZZ'^18CR1`(`IFYB\L@WI.Q
XMNA]P6(\O+(-.3KH?0EB/+RR#2DZZ'SA8CR\L@T9.NA\N6(]P8[""9P@O`DZZG
XM")A8CT*G3KH(D%B/3-\$!$YU3G%(YP`P)&\`%$Y5```,;`!C@8AE!&```.!(J
XM>``>3KH+_EB/)D`@"V8$8```S"\M`!1.NA*^6(\G0``*2JL`"F8$8```K"`*T
XM9Q@O"DZZ$J18CR=``!)*JP`29@Q@``"(8`9P`"=``!)"IR\L@WHO*P`*0J=P$
XM`="L@,XO`$ZZ(BA/[P`4)T``%DJK`!9F`F!&+RT`$$ZZ'4!8CR=```Y*JP`.D
XM9@)@)E*L@,XG;(#.`!I2;(&(3KH%L"\+2&R#?DZZ'AY0CTZZ!<9P`6`N+RL`W
XM%DZZ(B!8CTJK`!)G"B\K`!).N@N(6(\O*P`*3KH+?EB/+PM.N@MV6(]P`$Y=.
XM3-\,`$YU2.<\,"1O`!PD+P`@>`%V`&```(Y*DF<``(`O*@`$3KH1:%B/2H!G-
XM``!P+Q).NAQ^6(\J`"\J``1.NB".6(\F0"`+9T80*P`P5P!G!E,`9Q9@*D*G.
XM+RH`!"\23KK^I$_O``S(0&`:+RL`,B\J``0O$DZZ_HY/[P`,R$!@!,A\```O[
XM"TZZ(#!8CV`$R'P``"\%3KH<&EB/8`3(?```4H-0BK2#;@#_<#`$2,!,WPP\E
XM3G4O"B1O``@O"DZZ'BI8CR\J``Y.NAS46(\O*@`63KHA(EB/2JH`$F<*+RH`^
XM$DZZ"HI8CR\J``I.N@J`6(\O"DZZ"GA8CU-L@8@D7TYU2.<`,$AL@WY.NA5>X
XM6(\F0&`2+PI.NA526(\F0"\*3KK_E%B/)$L@"F;H3-\,`$YU<``P+(&(<@I.O
XMN@BV<C#2`!E!@.QP`#`L@8AR"DZZ")IR,-(`&4&`[4YU2.<^,DY5_WP@;(-JA
XM)F@`*"\+3KH?`EB/+$`@#F8&<`!@``)D-BX`%"!L@VH8*``D2(0@;(-J$"@`.
XM(TB`2,!R`#(#TH!Z`=I!2&W_?DZZ'K18CR\.2&W_?DZZ'M!0CTAL@<!.N@_.3
XM+H!(;('`2&W_?DZZ'M!/[P`,,@!(P7`\T($I0(-B<@`I08-R2&R#<DZZ'698X
XMCR1`3KK_/DAX`!!(;(#>2&W_?DZZ'II/[P`,,@!T"-1!<``P`D2`T*R#8G("4
XM3KH'U#($TD`[0?_B<`3013M`_^0[0O_F.T/_Z$'L@-XK2/_J*TO_[G`0*T#_J
XM]"ML@V[_^'``*T#__$*G2&W_XB\*2'@`#4ZZ'0)/[P`0)$`@:@`:$7P``0`";
XM<![01#M`_^)P!-!J``K1;?_D,"R#9)!\`#P[0/_F,`/`_``'.T#_Z'``*T#_T
XMZCM\``'_\D*G,"R`\$C`+P`O/(`(`#9"IR\\@`@`-4IL@/!L!'``8`@R+(#PU
XM2,$@`2\`+SR`"``%2&R#?B\\@`@`!DAM_^(O"DAX``1.NAQT3^\`,"1`*4J#R
XM=CPM_^+<:@`(,"H`"DC`<@`R`]*`4$'3;?_D2'@`"TAL@/)(;?]^3KH=>$_OE
XM``PR`'`(T$$[0/_F<@320SM!_^A![(#R*TC_ZCM\``+_\D*G2&W_XB\*2'@`R
XM`4ZZ'`Q/[P`0)$!(>``22&R`_DAM_WY.NATN3^\`##(`=`C403(&DD([0?_BB
XM.T+_YD'L@/XK2/_J.WP``__R0J=(;?_B+PI(>``!3KH;PD_O`!`D0#(M_^1(N
XMP3`J``I(P-"!6(!R`#(%D($I0(-F+PY.NAR`6(\B"F<$<`%@#"\L@W).NANFW
XM6(]P`$Y=3-],?$YU+P)(;($73KH=.%B/*4"#:DJL@VIF!&```49"IR\L@VI."
XMNAPF4(\I0(-N2JR#;F8$8``!&DZZ_3Q*0&8$8``!!$*G2'@``2\\@```D"\L;
XM@VHO/(```'DO+(-F+SR```!W+RR#8B\\@```=B\L@-HO/(```&4O+(#6+SR`Y
XM``!D2&R!Y$ZZ'-!/[P`X*4"`TDJL@-)F!&```*(@;(#2*6@`5H->+RR#:D*GM
XM3KH<XE"/<``I0(-J0J<O+(-Z+RR`TD*G0J=.NAT83^\`%"E`@UI*K(-:9@)@;
XM4D*G+SP``/__+SP``/__+RR#<B\L@-).NAP*3^\`%"\\``#__T*G+RR`TB\LD
XM@W).NAQF3^\`$$*G+RR`TDZZ&NQ0CR!L@UYR`10H``_EH2`!8#@O+(#23KH;*
XMZEB/<``I0(#2+RR#<DZZ&EI8CR\L@VY.NAID6(]*K(-J9PPO+(-J0J=.NAPR%
XM4(]P`"0?3G5.NOOB2'@``D*G+RR`TB\L@W).NAOT3^\`$$YU2JR`TF<>0J=((
XM>/__+SR`"``&0J<O+(#2+RR#=DZZ&HY/[P`83G5*K(#29T9"IS`L@/!(P"\`#
XM+SR`"``V2FR`\&P$<`!@"#(L@/!(P2`!+P`O/(`(``5(;(-^+SR`"``&0J<O\
XM+(#2+RR#=DZZ&D!/[P`H3G5(YS`R=`!@``%8("H`%%F`9T)R/)"!9UB0O```%
XM`<!G$I"\`#_^`&<``3!@``$L8``!*"!L@-(P*``$2,`I0(#6(&R`TC`H``9(V
XMP"E`@-IT`6```08O+(#23KH9<EB/2'@``2\L@-).NAEX4(]@``#J(&H`'#`HT
XM`"930&<,4T!G$E-`9UQ@``#2.6H`&(#P8```R$IL@/!M``#`=@!(;(-^3KH/H
XMZEB/)D!@%+9L@/!M`F`0+PM.N@_66(\F0%)#(`MFZ#E\__^`\$ZZ_L(O"TZZ+
XM^@A8CTZZ_MQ.NOZ68```>DAL@15(;(&*3KH'TE"/+$`F#F=<2&R#?DZZ#Y)8C
XMCR9`8$`O#B\K``I.N@4&4(]*JP`29Q@O#DAL@1-.N@3T4(\O#B\K`!).N@3HO
XM4(\O#DAL@1%.N@3<4(\O"TZZ#U!8CR9`)@MFO"\.3KH%+EB/8`A"ITZZ&>18W
XMCR\*3KH8R%B/+RR#7DZZ&))8CR1`)@IF`/Z:,`)(P$S?3`Q.=2\L@UI.NAJJ"
XM6(\O+(#23KH9F%B/<``I0(#2+RR#<DZZ&`A8CR\L@VY.NA@26(].=2\*3E4`"
XM`"1L@DI@""!J``1.D"12(`IF]$AL@DY.N@2N6(](;(*(3KH$I%B/2&R"PDZZD
XM!)I8CV`*+RR"_$ZZ!(Y8CTJL@OQF\$ZZ"EHO+0`,3KKQPEB/3ETD7TYU2.<P9
XM,C0O`!I.5?_X0J=.NA9H6(\K0/_\(&W__`PH``T`"&8``'H@;?_\2J@`G&<2%
XM(&W__"EH`)R#`"E\```P`(,$(&W__$JH`*!G$B!M__PI:`"@@Q`I?```,`&#,
XM%"!M__Q*J`"D9S9(>`/M2&R`!DZZ%-90CRE`@R!*K(,@9PHI?```$`&#)&`4Q
XM*6R#$(,@2JR#(&<(*7P``#`!@R1(>`"$0J=(;().3KH%LD_O``Q(>`"(2'@`2
XM`4AL@HA.N@6>3^\`#$AX`(A(>``"2&R"PDZZ!8I/[P`,(&W__`PH``T`"&8`.
XM`0P@;?_\("@`K.6`*T#_^$JM__AG``#&,`)(P%*`+P!.N@(V6(\F0"!M__@@7
XM*``0Y8`L0#`"2,`O`"\++RT`($ZZ`JI/[P`,%[P``"``,`)(P"\`+PM.N@%8=
XM4(\F`'`"T(/E@"\`3KH!\%B/)$`O`TAJ``0O"TZZ`9Q/[P`,4H,@#F<V=``4;
XM%C`"2,!2@"\`3KH!QEB/*T``(#`"2,`O`"\M`"!(;@`!3KH"0D_O``P@;0`@Q
XMT,(0O```)*T`("`#Y8!R`"6!"``O"B\#3KKPH%"/+P!.NOWJ6(]@,"QM__Q(*
XM;@!<3KH5CEB/+&W__$AN`%Q.NA3<6(\I0()"+RR"0DZZ\"HN@$ZZ_;A8CTAXA
XM__].NOVN6(].74S?3`Q.=4YQ80``!B`!3G5*@6<>2$%*069"+P)(020`A,%IK
XM%"("0D%(07``,`(D'TYU(@!P_TYU+P,D`$)"2$*$P38"2$-"0S0`A,$V`B`#%
XM0D)(0B(")A\D'TYU2.<X`"0`0D)(0H3!-@)T`#0#QL%(03@"R,%(0]:$D(-KT
XM"B(`(`),WP`<3G53@M"!:_HB`"`"3-\`'$YU(&\`!'``8`)2B`P0`"!G^`P0G
XM``EG\DH09T@,$``*9@)@0%*`#!``(F824HA*$&<B#!``(F;T8!I@`E*(2A!GM
XM$@P0``IG#`P0`"!G!@P0``EFZ$H09@)@"B)(4H@2O```8*A.=2\*(&\`"")OQ
XM``P@+P`08"I@`E*(#!``(&?X#!``"6?R#!``(F8"4H@D25B))(A@`E*(2A!F`
XM^E*(4X!*@&;6)%].=4YQ2.<@("0O``Q*@F8$<`!@-$AX``%P"-""+P!.NA*\*
XM4(\D0"`*9Q8DK()&*4J"1G`(T((E0``$1>H`"&`&<`4I0(,R(`I,WP0$3G5..
XM<4CG`#(D;P`01^R"1B`*9@A"ITZZ$ZA8CT7J__A@%K7.9A`FEB\J``0O"DZZ*
XM$NA0CV`0)DXL4R`.9N1"ITZZ$WY8CTS?3`!.=2!O``0B;P`(("\`#&<&$MA3(
XM@&;Z("\`"$YU$B\`#V`"<@`@;P`$("\`"&<&$,%3@&;Z("\`!$YU2.<`,"1O!
XM``PF;P`0+PM(>``!+PI.N@6*+H`O"DZZ!(I/[P`0("L`*$S?#`!.=4YQ+PHD0
XM;P`(2&R"B"\*3KH%8BZ`2'@``2\*3KH$7D_O`!!(;(*(2'@`"DZZ#!90CR`L:
XM@K`D7TYU3G%(YR`@)&\`#'3_(`IG1`@J````)F<\+PI.N@!`6(\D`$JJ`#9GE
XM"B\J`#9.NO[L6(\(*@`'`"=F&B!J``0@DDJ29P@@4B%J``0`!"\*3KK^REB/2
XM(`),WP0$3G5(YS`@)&\`$"8J`!B6J@`@2JH`(&TF2JH`$&<@2H-G'"\#+RH`/
XM$"\J`#!.N@D&3^\`#+:`9P9P_R5``"@D*@`H""H``0`F9RQ*J@`(9Q`O*@`(/
XM3KK^:EB/<``E0``(2JH`$&<0+RH`$$ZZ_E18CW``)4``$"\J`#!.N@4B6(\(E
XM*@`%`"=G"B\J`#9.N@^*6(\"JO___O,`)"`"3-\$#$YU3G%(YS@R)&\`'"0O7
XM`"`F;P`D+$I3@B`+9V9*:P`T;&!*JP`<;UH@:P`,<`!P`&`*(DA2B!61"`!20
XM@+"K`!QL"K2`;P8,$``*9N8,$``*9C"T@&\LL*L`'&PF(@!2@!60&`"1JP`<E
XM(FL`#-/`)TD`#"(`4H`5O```&``@"F```&X@"V=:=@!@%B!*4HH0A'`*L(1G$
XM2K2#;T92@V`"8$!*:P`T;0PO"TZZ"^Y8CR@`8"A*JP`<;@XO"TZZ"]Q8CR(``
XM(`%@$E.K`!P@:P`,4JL`#'(`$A`@`2@`</^PA&:JO<IF!'``8`84O```(`Y,N
XMWTP<3G4O"B1O``A.50``-7S__P`T)6T`$``P,"T`%DC`(CP```$`@H`E00`D<
XM)7P```0``!AP_R5``"!P_R5``!PO*@`P3KH$<EB/2H!O!@CJ``0`)TY=)%].G
XM=4YQ+PI.50``2'@`.DZZ_'Q8CR1`(`IG+DAX`#HO"DZZ_1Y0CR\*+RT`$"\M*
XM``Q.N@!D3^\`#"!`(`AF"B\*3KK\EEB/E<H@"DY=)%].=2\*)&\`#$Y5__`O'
XM"DZZ`II8CW(.LH!O)AM\`$;_\"\*2&W_\4ZZ`IY0CTAM__`O+0`,3KK_@%"/_
XM($`@"&`"<`!.721?3G5(YSPR)&\`("9O`"0L;P`H=`!V`'@`0>R"3K'.9Q!!M
XM[(*(L<YG"$'L@L*QSF9D",,`!V!>L#P`<F8(A'P```C#``*P/`!W9@B$?`,!<
XM",,``[`\`"MF#`C"``$(@@``AGP`#+`\`&)F"`C"``L(PP`*L#P`868(A'P!<
XM"(9\`$BP/`!&9@)X`;`\`$-F!`C#``52BQ`32@!FG"`.9P``Q@@N````)F<(`
XM+PY.NOS:6(](>``Z+PY.NOOT4(]*1&<&+4H`,&`82'@!MC`"2,`O`"\*3KH$.
XMDD_O``PM0``P2JX`,&T``'P]?/__`#0P`TC`"```!V8:+*R"_$'L@OPM2``$Y
XM2I9G!B!6(4X`!"E.@OQ(>``!0J<O+@`P3KH#!$_O``PJ`$J%;0@(PP`,+44`R
XM+"U\```$```8,`-(P"(\```!`(*`+4$`)'#_+4``''#_+4``(`@#``5G"BU*+
XM`#9@!'``8`(@#DS?3#Q.=4CG/C`D;P`@)"\`)"8O`"@F;P`L>/]P`;""9@0J#
XM`V`4<`&P@V8$*@)@"B`#(@).N@6X*@`@"V<``(P(*P`#`"=G``""NJL`(&\(Q
XM+PM.N@@66(^ZJP`@;D(O!2\K`!0O"DZZ!EY/[P`,FZL`("!K`!31Q2=(`!0H3
XM!0@K``0`)V=$2H5G0"`%4X`,,@`*"`!F-"\+3KH'T%B/8"HL!6`B+P8O"B\KK
XM`#!.N@2D3^\`#"@`2H1N`F`.V:L`+$7R2`"<A$J&;MI*A&P&?/\G1@`H2JL`J
XM*&<&("L`*&`6NH1F!"`#8`XB!"`!(@).N@4B(@`@`4S?#'Q.=4YQ2.<`,"1O[
XM``PF2F`"4HI*$F;Z(`J0BTS?#`!.=4CG`#(@;P`0(F\`%"1()DE2B2Q(4H@<Z
XMDTH69O(@"DS?3`!.=2!O``0@+P`(8`P2`+(09@0@"&`04HA*$&;P2H!F!"`(!
XM8`)P`$YU3G%(YR`P)&\`$"\*3KK_C%B/)`!P`=""+P!.NOD26(\F0"`+9PHOJ
XM"B\+3KK_BE"/(`M,WPP$3G5.<2\"=`!@#C`"2,`O`$ZZ`!!8CU)"M&R`#FWLR
XM)!].=4CG("!.50``=/\P+0`22,`O`$ZZ`%)8CR1`(`IG/DJJ``AG%D*G2'@`'
XM!2\2(&H`"$Z03^\`#"0`8!)T``@J``4`!F8(+Q).N@H*6(]P`"5```1P`"5`G
XM``AP`"2`(`).74S?!`1.=2\","\`"C(`2,$T+(`.2,*T@6(*=`,I0H,R<`!@T
XM(C0`2,+I@B)L@`K3PD'1""@`!``&9@IT`RE"@S)P`&`"(`@D'TYU+PI.50``G
XM,"T`#DC`+P!.NO^L6(\D0"`*9S!*J@`(9Q9"IT*G2'@`"2\2(&H`"$Z03^\`D
XM$&`6+Q).N@G.6(]*@&<$<`%@!G``8`)P_TY=)%].=4YQ2.<X("0O`!@F+P`<M
XM3E4``'C_,"T`&DC`+P!.NO],6(\D0"`*9U)*J@`(9Q8O`R\"2'@`!"\2(&H`T
XM"$Z03^\`$&`X(`-3@"\`+P(O$DZZ"<Y/[P`,*`!*A&T>2H)F!G`!L(-G$$*G)
XM0J<O$DZZ";!/[P`,*``@!&`"(`1.74S?!!Q.=4YQ2.<P,$Y5``!T`"1L@`I@?
XM$`@J``0`!F8"8!#4_``04H(P+(`.2,"P@F[F,"R`#DC`L()F;C`"=@760#`#^
XM2,#I@"\`3KKW$%B/)D`@"V8*<`4I0(,R<`!@8C`#2,#I@"\`+PM.NO>D4(\B-
XM`NF!(`$O`"\++RR`"DZZ]W!/[P`,0>R#`+'L@`IG"B\L@`I.NO<26(\I2X`*W
XM.4.`#B`"Z8!%\P@`)@IG#$AX`!`O"DZZ]UI0CR9M`!@F@B`*3EU,WPP,3G5(O
XMYS`P)&\`%"0O`!A.5?_\2&W__$ZZ_RA8CR9`(`MF!G#_8``!)DAX__XO"DZZN
XM"%10CR8`2H-F``!X3KH((K"\````VF8,<`8I0(,R</]@``#Z"`(`"&<02'@#?
XM[B\*3KH(/E"/)H!@#DAX`^TO"DZZ""Y0CR:`2I-F#'`&*4"#,G#_8```Q@@"6
XM``-G$$AX``%"IR\33KH(0$_O``P@/```$`"`@B=```0@+?_\8```G"\#3KH(?
XM6EB/"`(`"6<H"`(`"F<2"`(`"&<,=@8I0X,R</]@``!V2'@#[B\*3KH'P%"/O
XM)H!@#DAX`^TO"DZZ![!0CR:`2I-F)`@"``AG'@@"``IG"G8&*4.#,G#_8#Q(T
XM>`/N+PI.N@>(4(\F@$J39R@(`@`#9Q!(>``!0J<O$TZZ!Z9/[P`,)CP``!``+
XMAH(G0P`$("W__&`"</].74S?#`Q.=4CG,#`D;P`8)"\`'$Y5``!V_TZZ`-@P1
XM+0`:2,`O`$ZZ_+!8CR9`(`MG5'`+P*L`!&=&2JL`"&<6+P(O"DAX``(O$R!KO
XM``A.D$_O`!!@,@@K``,`!V<02'@``4*G+Q-.N@<D3^\`#"\"+PHO$TZZ!V)//
XM[P`,)@!@!G`$*4"#,B`#3EU,WPP,3G4@;P`$(%!*D&<$(`A.=7``3G5.<4CG!
XMP`!(0,#!2$'"[P`"T(%(0$)`,B\``L+O``;0@5"/3G5.<4J!:PA*@&L28`#S$
XM1D2!2H!K$F$`\SQ$@$YU1(!A`/,R1(!.=42`8`#S*$YQ+PH@;((Z)&@!%`@J,
XM``0`'&<T2'@0`$*G3KH(*E"/(&R`$DZ02H!G'DAX``-(;(`62'@``DZZ_MY/:
XM[P`,2'@``4ZZ\'I8CR1?3G5*K(,V9Q!(>``$(&R#-DZ06(]P`&`"<`%.=2\*.
XM(&\`"")L@!(@"&8*1?K_UBE*@!)@!"E(@!(@"21?3G5.<2!O``0B;P`(("\`X
XM#+/(9V9C``!^T<#3P#((XHEE8#()XHEE6K"\```!`V4J(@""_``L:2)(YS\^J
XM(#P````L8`J1P$S0?/Q(X3\^4<G_]$A!,`%,WWS\,@#FB&`$(R`C(%'(__J03
XMO``!``!D\#`!P+P````'9@@@+P`(3G43(%'(__R0O``!``!D\B`O``A.=3((+
XMXHEE8#()XHEE6K"\```!`V4J(@""_``L:2)(YS\^(#P````L8`I,V'S\2-%\Z
XM_-/`4<G_]$A!,`%,WWS\,@#FB&`$(M@BV%'(__J0O``!``!D\#`!P+P````'8
XM9@@@+P`(3G42V%'(__R0O``!``!D\B`O``A.=2\*)&\`#$Y5```@"F<``'P(3
XM*@`#`"=G``!R2JH`(&Y`2JH`&&8J2'@``4AM``\O*@`P3KK]4$_O``QR`;*`=
XM9P9P_R5``"A2J@`L("H`*&!$+PI.N@!(6(]*@&<$</]@-"!J`!12J@`4$*T`Z
XM#U.J`"`,+0`*``]F&`@J``0`)V<0+PI.N@`86(]@!G#_)4``*"`J`"A.721?2
XM3G5.<4CG("`D;P`,3KK]RB`*9P``R@@J````)F<``,`U?/__`#1*J@`89RQ*%
XMJ@`09B8O*@`83KKQ]%B/)4``$`CJ``$`)DJJ`!!F!G``)4``&"5J`!@`($JJQ
XM`!QM,`@J``0`)F<H2JH`'&\<0J<@*@`LD*H`'"\`+RH`,$ZZ^=9/[P`,)4``R
XM+'#_)4``'$JJ`"!M,B0J`!B4J@`@2H)G)B\"+RH`$"\J`#!.NOQ`3^\`#+2`1
XM9P9P_R5``"C5J@`L)6H`&``@2JH`(&P,2JH`&&<&)6H`&``@)6H`$``42JH`.
XM*&<$</]@`G``3-\$!$YU2.<@("1O``Q.5?_\(`IG``"4""H``@`G9P``BDIJ;
XM`#1M%AMJ`#7__S5\__\`-'``$"W__V```'!*J@`<;E0O"DZZ`&Y8CR0`2H)G,
XM!"`"8%9*J@`<9CQ(>``!2&W__R\J`#!.N@$D3^\`#"0`2H)N%DJ"9@@(Z@`!C
XM`"=@!G#_)4``*'#_8"!2J@`L<``0+?__8!13J@`<(&H`#%*J``QP`!`08`)P8
XM_TY=3-\$!$YU3G%(YS`@)&\`$'8`3KK\+"`*9P``O@@J````)F<``+1*J@`<Y
XM;@``K$JJ`"!M'`@J``0`)F<4+PI.NOXL6(]P_R5``"!P`"5``!Q*J@`89R9*H
XMJ@`(9B`O*@`83KKP,EB/)4``"`CJ``$`)DJJ``AF!G``)4``&$JJ`!AG2B\JK
XM`!@O*@`(+RH`,$ZZ`%!/[P`,)`!*@FP2<`JPK(,R9RYP_R5``"AV_V`D)4(`.
XM'-6J`"Q*@F8*=O\(Z@`!`"=@#@BJ``$`)V`&<``E0``<)6H`"``,(`-,WP0,R
XM3G5(YS`P)&\`&"0O`!Q.50``=O].NOM,,"T`&DC`+P!.NO<D6(\F0"`+9SP('
XM*P````=F+DJK``AG%B\"+PI(>``!+Q,@:P`(3I!/[P`08!HO`B\*+Q-.N@&&A
XM3^\`#"8`8`9P!"E`@S(@`TY=3-\,#$YU0>R#`"E(@`I!^OLP*4B`$G``0_H`]
XM$$ZN_=@I0(,Z9P``9&`,9&]S+FQI8G)A<GD`<`!#^@`03J[]V"E`@SYG``!$*
XM8!)I;G1U:71I;VXN;&EB<F%R>0!.<7``0_H`$$ZN_=@I0(-"9P``'&`29W)AB
XM<&AI8W,N;&EB<F%R>0``3G%P`$YU<`%.=7``3G5P`4YU("R#.F<&(D!.KOYB[
XM("R#/F<&(D!.KOYB("R#0F<&(D!.KOYB3G5.<4YU3G%.=4YQ+PXL;(,Z3G$BM
XM+P`(3J[_W"Q?3G4O#BQL@SI.<2(O``A.KO^"+%].=2\.+&R#.DYQ(B\`"$ZNW
XM_[@L7TYU+PXL;(,Z3G$B+P`(3J[_H"Q?3G4O#BQL@SI.<4ZN_WPL7TYU+PXL7
XM;(,Z3G$B+P`(3J[_*"Q?3G5(YR`"+&R#.DYQ3.\`!@`,3J[_K$S?0`1.=0``]
XM2.<@`BQL@SI.<4SO``8`#$ZN_^),WT`$3G4``$CG,`(L;(,Z3G%,[P`.`!!.=
XMKO_63-]`#$YU``!(YS`"+&R#.DYQ3.\`#@`03J[_ODS?0`Q.=0``2.<@`BQLG
XM@SI.<4SO``8`#$ZN_:),WT`$3G4``"\.+&R#.DYQ(B\`"$ZN_Z8L7TYU2.<P.
XM`BQL@SI.<4SO``X`$$ZN_]!,WT`,3G4``"\.+&R".DYQ(F\`"$ZN_IXL7TYU#
XM+PXL;((Z3G%,[P,```A.KO\*+%].=0``+PXL;((Z3G%,[P`#``A.KO\Z+%].-
XM=0``+PXL;((Z3G$B;P`(3J[^8BQ?3G4O#BQL@CI.<4ZN_68L7TYU+PXL;((Z6
XM3G$@;P`(3J[]8"Q?3G4O#BQL@CI.<2)O``A.KOYZ+%].=2\.+&R".DYQ(F\`)
XM"$ZN_MHL7TYU+PXL;((Z3G%.KO]\+%].=2\.+&R".DYQ(F\`""`O``Q.KO\NL
XM+%].=2\.+&R".DYQ(&\`"$ZN_HPL7TYU+PXL;((Z3G$B;P`(("\`#$ZN_=@L*
XM7TYU+PXL;((Z3G%.KO]V+%].=2\.+&R".DYQ(F\`"$ZN_I@L7TYU+PXL;((Z+
XM3G$B;P`(3J[_!"Q?3G4O#BQL@CI.<2)O``A.KOZ&+%].=2\.+&R".DYQ3.\`G
XM`P`(3J[^SBQ?3G4``"\.+&R".DYQ("\`"$ZN_L(L7TYU+PXL;((Z3G$@;P`(Y
XM3J[^@"Q?3G4O#BQL@TY.<2!O``A.KO^.+%].=4CG`"(L;(-.3G%%[P`,3-H#]
XM`4ZN_^),WT0`3G4O#BQL@TY.<2!O``A.KO_<+%].=2\.+&R#3DYQ(&\`"$ZNI
XM_WPL7TYU+PXL;(-.3G$@;P`(3J[_IBQ?3G4O#BQL@TY.<2!O``@@+P`,3J[_&
XMH"Q?3G4O#BQL@TY.<2!O``A.KO^X+%].=2\.+&R#3DYQ3.\#```(3J[_K"Q?(
XM3G4``"\.+&R#3DYQ(F\`"$ZN_[(L7TYU2.<`,BQL@TY.<4?O`!!,VP<`3J[_T
XMUDS?3`!.=2\.+&R#3DYQ0^\`""!93J[_@BQ?3G4``"\.+&R#0DYQ(F\`"$ZNA
XM_[(L7TYU+PXL;(-"3G$B;P`(3J[_.BQ?3G4O#BQL@T).<2!O``A.KO^X+%].P
XM=2\.+&R#0DYQ(F\`""!O``Q.KO^^+%].=2\.+&R#0DYQ(F\`""!O``P@+P`0U
XM3J[_RBQ?3G4O#BQL@TI.<2!O``A.KO^F+%].=2\.+&R#2DYQ(&\`"$ZN_[(L+
XM7TYU2.<`(BQL@SY.<4SO`P``#$SO!`,`%$ZN_DI,WT0`3G4O#BQL@SY.<2!O%
XM``A.KO^X+%].=2\.+&R#/DYQ(&\`"$ZN_Z`L7TYU+PXL;(,^3G$@;P`(3J[^$
XM`BQ?3G4O#BQL@SY.<4/O``@@64ZN_:(L7TYU``!(YP`B+&R#/DYQ3.\'```,X
XM("\`&$ZN_E!,WT0`3G4``"\.+&R#/DYQ3.\#```(3J[]_"Q?3G4``$CG`#HL6
XM;(-&3G%)[P`43-P/`TZN_\1,WUP`3G5(YP`B+&R#1DYQ1>\`#$S:`P-.KO^X3
XM3-]$`$YU2.<`(BQL@T9.<47O``Q,V@,#3J[_T$S?1`!.=2\.+&R#1DYQ(&\`X
XM"$ZN_[XL7TYU+PXL;(-&3G$@;P`(3J[_LBQ?3G4O#BQL@T9.<2!O``A.KO_*W
XM+%].=2!O``1"J``$(4@`"%B((0A.=0`````#[`````8`````````M@```,H`!
XM``#P````Z@```-X```#"`````@````$```!L````3@````````/R```#Z@``9
XM`(X`````*@```````````P```````%Y#"@````"]3DE,.@!.24PZ`'(`475I^
XM="!4;V]L36%N86=E<@!G861T;V]L<RYL:6)R87)Y`&EC;VXN;&EB<F%R>0!WP
XM;W)K8F5N8V@N;&EB<F%R>0!4;V]L36%N86=E<B!A;')E861Y(')U;FYI;F<A,
XM`%EO=2!N965D(&$@2VEC:W-T87)T(#(N,"!O<B!B971T97(@=&\@<G5N(%1O\
XM;VQ-86YA9V5R(0!4;V]L36%N86=E<@```````````````````!0````406-T0
XM:79E(%1O;VQS.B`P,```__]296UO=F4@5&]O;`!3879E($-O;F9I9W5R871I#
XM;VX`"@`[`'<`5V]R:V)E;F-H``````(2```````P`!@``0`````!````````:
XM````````````````,``9```````````!)```````````````````````````N
XM````````````````@````(```````````````````````%,Z5&]O;$UA;F%G/
XM97(N0V]N9FEG``"````A`````(```"(`````@```(P````$``````````%1O%
XM;VQ-86YA9V5R(%8Q+C(@J3$Y.3$@8GD@4RX@0F5C:V5R```4`!0"@`$```$`N
XM0`)T```03@`````````````!O@```````````````````````"1615(Z(%1O!
XM;VQ-86YA9V5R(#$N,B`H,3,N,#$N,3DY,2D````````#[`````0````!````A
XM&````?P```%.```!(`````$````"```!+@````````/R0``#Z@```"0`````]
XM`````````````````````'_^`````'_^`````'_^`````'_^`````'_^````Q
XM`'_^```_______P_______P_______P_______P_______P_______P``'_^$
XM`````'_^`````'_^`````'_^`````'_^`````'_^````````````````````Q
X)``````````/RU
X``
Xend
Xsize 11484
END_OF_FILE
if test 16120 -ne `wc -c <'ToolManager.uu'`; then
    echo shar: \"'ToolManager.uu'\" unpacked with wrong size!
fi
# end of 'ToolManager.uu'
fi
if test -f 'data.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'data.c'\"
else
echo shar: Extracting \"'data.c'\" \(2018 characters\)
sed "s/^X//" >'data.c' <<'END_OF_FILE'
X#include "ToolManager.h"
X
X/* Version string */
XMyIdent="$VER: ToolManager " TM_VERSION " (" TM_DATE ")";
X
X/* Structures for icon */
Xstatic __chip UWORD ImageData[]={ /* Graphic data (48x48 Pixels) */
X 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
X 0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,
X 0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,
X 0x3fff,0xffff,0xfffC,0x3fff,0xffff,0xfffC,0x3fff,0xffff,0xfffC,
X 0x3fff,0xffff,0xfffC,0x3fff,0xffff,0xfffC,0x3fff,0xffff,0xfffC,
X 0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,
X 0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,0x0000,0x7ffE,0x0000,
X 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
Xstatic struct Image MyIconImage={NULL,NULL,48,24,1,ImageData,1,0,NULL};
Xstruct DiskObject MyIcon={NULL,NULL,
X  /* Gadget definition */ {NULL,NULL,NULL,48,25,NULL,NULL,NULL,&MyIconImage,
X                           NULL,NULL,NULL,NULL,NULL,NULL},
X                          NULL,NULL,NULL,NO_ICON_POSITION,
X                          NO_ICON_POSITION,NULL,NULL,NULL};
X
X/* Structures for message port */
Xstruct MsgPort *MyMP;
X
X/* List for ToolNodes */
Xstruct List ToolList; /* This list contains ToolNodes */
XUWORD ToolCount=0;    /* Number of tools in ToolList */
X
X/* Name of the configuration file */
Xchar ConfigName[]="S:ToolManager.Config";
X
X/* Tags for System() */
Xstruct TagItem MyTags[]={SYS_Input,NULL,  /* Input file handle */
X                         SYS_Output,NULL, /* Output file handle */
X                         SYS_Asynch,TRUE, /* Run tools asynchronously */
X                         TAG_DONE,NULL};
X
X/* Structures for window */
XUBYTE WindowTitle[]="ToolManager V" TM_VERSION " (c)" TM_CRYEAR " by S. Becker";
Xstruct NewWindow nw={20,20,640,256,0,1,CLOSEWINDOW|REFRESHWINDOW|GADGETUP|
X                     GADGETDOWN|MOUSEMOVE|INTUITICKS,WINDOWDRAG|WINDOWDEPTH|
X                     WINDOWCLOSE|SIMPLE_REFRESH|ACTIVATE,NULL,
X                     NULL,WindowTitle,NULL,NULL,0,0,0,0,0};
END_OF_FILE
if test 2018 -ne `wc -c <'data.c'`; then
    echo shar: \"'data.c'\" unpacked with wrong size!
fi
# end of 'data.c'
fi
if test -f 'toollist.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'toollist.c'\"
else
echo shar: Extracting \"'toollist.c'\" \(3603 characters\)
sed "s/^X//" >'toollist.c' <<'END_OF_FILE'
X#include "ToolManager.h"
X
X/* Add one program to tool list */
XBOOL AddToolNode(BPTR dir, char *name, char *realname)
X{
X static ULONG ToolID=0; /* Counter for Tool ID */
X struct ToolNode *tn;
X
X if (ToolCount>=99) goto e1; /* Not more than 99 Tools :-) possible */
X
X /* Get memory for ToolNode */
X if (!(tn=malloc(sizeof(struct ToolNode))))
X  goto e1;
X
X /* Get memory for menu item name and copy it */
X if (!(tn->tn_Node.ln_Name=strdup(name)))
X  goto e2;
X
X /* Does the program have a real name? */
X if (realname)
X  {
X   /* Get memory for real program name and copy it */
X   if (!(tn->tn_RealName=strdup(realname)))
X    goto e3;
X  }
X else
X  tn->tn_RealName=NULL; /* Otherwise: menu item name == real program name */
X
X /* Add a new menu entry */
X if (!(tn->tn_MenuItem=AddAppMenuItem(ToolID+1,NULL,tn->tn_Node.ln_Name,
X                                      MyMP,NULL)))
X  goto e4;
X
X if (!(tn->tn_DirLock=DupLock(dir))) /* Duplicate directory lock */
X  goto e5;
X
X /* Add node to tool list */
X tn->tn_ID=++ToolID;    /* Set Tool ID */
X ToolCount++;           /* Increment active tool count */
X DetachToolList();      /* Detach list from ListView gadget */
X AddTail(&ToolList,tn);
X AttachToolList();      /* Attach list to ListView gadget */
X
X /* Node successfully added to list! */
X return(TRUE);
X
X /* Something went wrong.... */
Xe5: RemoveAppMenuItem(tn->tn_MenuItem);
Xe4: if (tn->tn_RealName) free(tn->tn_RealName);
Xe3: free(tn->tn_Node.ln_Name);
Xe2: free(tn);
Xe1: return(FALSE);
X}
X
X/* Scan Workbench parameters and add them to tool list */
XBOOL WBAddToolNode(struct WBArg *wbarg, int numargs)
X{
X int i;
X BOOL rc=TRUE;
X BPTR fl;
X struct DiskObject *dobj;
X
X for (i=0; i<numargs; i++, wbarg++) /* Scan all parameters */
X  if ((wbarg->wa_Lock) && (strlen(wbarg->wa_Name)!=0)) /* Sanity check */
X   {
X    fl=CurrentDir(wbarg->wa_Lock);          /* Change to icon's directory */
X    if (dobj=GetDiskObject(wbarg->wa_Name)) /* Get icon data */
X     {
X      switch(dobj->do_Type) /* Perform action depending on icon type */
X       {
X        case WBTOOL:    /* Icon is a Tool. Menu entry == real program name */
X         rc&=AddToolNode((struct FileLock *) wbarg->wa_Lock,wbarg->wa_Name,
X                         NULL);
X         break;
X        case WBPROJECT: /* Icon is a Project. Menu entry = icon name,
X                           real program name = default tool name */
X         rc&=AddToolNode((struct FileLock *) wbarg->wa_Lock,wbarg->wa_Name,
X                         dobj->do_DefaultTool);
X         break;
X        default:        /* Every other icon type is erroneous */
X         rc&=FALSE;
X         break;
X       }
X      FreeDiskObject(dobj); /* Release icon data */
X     }
X    else
X     rc&=FALSE; /* Error: Can't get icon data */
X
X    CurrentDir(fl); /* Change to old directory */
X   }
X  else
X   rc&=FALSE; /* Error: Bad Workbench parameter */
X
X return(rc); /* Return TRUE if no error */
X}
X
X/* Remove ONE node from the tool list */
Xvoid RemToolNode(struct ToolNode *tn)
X{
X Remove(tn);                                 /* Remove node from list */
X UnLock(tn->tn_DirLock);                     /* Free directory */
X RemoveAppMenuItem(tn->tn_MenuItem);         /* Remove menu entry */
X if (tn->tn_RealName) free(tn->tn_RealName); /* Free memory */
X free(tn->tn_Node.ln_Name);
X free(tn);
X ToolCount--;                                /* decrement active tool count */
X}
X
X/* Remove ALL nodes from the tool list */
Xvoid RemoveTools(void)
X{
X struct ToolNode *tn1,*tn2=GetHead(&ToolList); /* Begin of list */
X
X while (tn1=tn2)
X  {
X   tn2=GetSucc(tn1); /* Next in list */
X   RemToolNode(tn1); /* Remove node */
X  }
X}
END_OF_FILE
if test 3603 -ne `wc -c <'toollist.c'`; then
    echo shar: \"'toollist.c'\" unpacked with wrong size!
fi
# end of 'toollist.c'
fi
if test -f 'window.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'window.c'\"
else
echo shar: Extracting \"'window.c'\" \(8602 characters\)
sed "s/^X//" >'window.c' <<'END_OF_FILE'
X#include "ToolManager.h"
X
X/* Structures for window */
Xextern UBYTE WindowTitle[];
Xextern struct NewWindow nw;
X#define WDRAGBARLEN 60       /* Width of Close & Drag gadget */
Xstatic struct Window *w=NULL;
Xstatic struct AppWindow *aw;
Xstatic struct MsgPort *wp;
Xstatic ULONG wl=20,wt=20;    /* Window leftedge & topedge */
Xstatic ULONG ww,wh;          /* Window width & height */
Xstatic struct Screen *pubsc; /* Workbench screen */
X
X/* Structures for window gadgets */
Xstatic void *vi;             /* Visual information is a *PRIVATE* data field! */
Xstatic struct Gadget *gl;    /* Gadget list */
Xstatic char StatusText[]="Active Tools: 00"; /* Text gadget text */
Xstatic struct Gadget *lvgad;                 /* ListView gadget */
Xstatic WORD lvord=-1;                        /* LV gadget ordinal number */
X#define LVGAD_ID 1
Xstatic char RTButtonText[]="Remove Tool";    /* Remove Tool gadget text */
X#define RTGAD_ID 2
Xstatic char SCButtonText[]="Save Configuration"; /* Save config gadget test */
X#define SCGAD_ID 3
X
X/* Create status line */
Xstatic void PrintStatusLine(void)
X{
X StatusText[14]=ToolCount/10+'0'; /* Hack */
X StatusText[15]=ToolCount%10+'0';
X}
X
X/* Create all status window gadgets */
Xstatic BOOL CreateWindowGadgets(void)
X{
X struct NewGadget ng;
X struct Gadget *g;
X struct TextAttr *ta=pubsc->Font;
X struct TextFont *f;              /* Window font */
X struct RastPort tmprp;           /* RastPort for font-sensitive trick */
X UWORD width,fheight;
X UWORD leftedge,topborder;
X UWORD lvright;
X
X /* Open window font */
X if (!(f=OpenFont(ta))) return(FALSE);
X fheight=f->tf_YSize; /* Font height */
X leftedge=pubsc->WBorLeft;
X topborder=pubsc->WBorTop+fheight+1;
X
X /* Initialize temporary RastPort */
X InitRastPort(&tmprp);
X SetFont(&tmprp,f);
X
X /* Calculate window width */
X ww=TextLength(&tmprp,WindowTitle,strlen(WindowTitle))+WDRAGBARLEN;
X
X /* Create gadget list */
X gl=NULL;
X g=CreateContext(&gl);
X
X /* 1. gadget: Text, status line */
X PrintStatusLine();
X width=TextLength(&tmprp,StatusText,sizeof(StatusText)-1)+INTERWIDTH;
X ng.ng_LeftEdge=leftedge+(ww-width)/2;
X ng.ng_TopEdge=topborder+INTERHEIGHT;
X ng.ng_Width=width;
X ng.ng_Height=fheight;
X ng.ng_GadgetText=StatusText;
X ng.ng_TextAttr=ta;
X ng.ng_Flags=PLACETEXT_IN;
X ng.ng_VisualInfo=vi;
X ng.ng_UserData=0;
X g=CreateGadget(TEXT_KIND,g,&ng,TAG_DONE);
X g->GadgetText->DrawMode=JAM2; /* Argh, why doesn't exist a tag for this? */
X
X /* 2. gadget: ListView, tool list */
X ng.ng_LeftEdge=leftedge+WDRAGBARLEN/2;
X ng.ng_TopEdge+=g->Height+INTERHEIGHT;
X ng.ng_Width=ww-WDRAGBARLEN;
X ng.ng_Height=7*fheight;
X ng.ng_GadgetText=NULL;
X ng.ng_GadgetID=LVGAD_ID;
X lvgad=g=CreateGadget(LISTVIEW_KIND,g,&ng,
X                      GTLV_Labels,&ToolList,
X                      /* If an item was selected, use it as top item */
X                      GTLV_Top,lvord<0?0:lvord,
X                      GTLV_ShowSelected,NULL,
X                      GTLV_Selected,lvord,
X                      TAG_DONE);
X lvright=ng.ng_LeftEdge+g->Width;
X
X /* 3. gadget: Button, remove tool */
X ng.ng_TopEdge+=g->Height+fheight+2*INTERHEIGHT;
X ng.ng_Width=TextLength(&tmprp,RTButtonText,sizeof(RTButtonText)-1)+INTERWIDTH;
X ng.ng_Height=fheight+INTERHEIGHT;
X ng.ng_GadgetText=RTButtonText;
X ng.ng_GadgetID=RTGAD_ID;
X g=CreateGadget(BUTTON_KIND,g,&ng,TAG_DONE);
X
X /* 4. gadget: Button, save config */
X width=TextLength(&tmprp,SCButtonText,sizeof(SCButtonText)-1)+INTERWIDTH;
X ng.ng_LeftEdge=lvright-width;
X ng.ng_Width=width;
X ng.ng_GadgetText=SCButtonText;
X ng.ng_GadgetID=SCGAD_ID;
X g=CreateGadget(BUTTON_KIND,g,&ng,TAG_DONE);
X
X /* Calculate window height */
X wh=ng.ng_TopEdge+g->Height+INTERHEIGHT-topborder;
X
X /* Close window font */
X CloseFont(f);
X
X /* All gadgets created! */
X if (g) return(TRUE);
X
X /* Something went wrong.... */
X FreeGadgets(gl);
X return(FALSE);
X}
X
X/* Open status window */
XULONG OpenStatusWindow(void)
X{
X if (!(pubsc=LockPubScreen("Workbench"))) /* Lock Workbench screen */
X  goto osw1;
X
X if (!(vi=GetVisualInfo(pubsc,TAG_DONE))) /* Get visual information */
X  goto osw2;
X
X if (!CreateWindowGadgets())              /* Create Gadgets */
X  goto osw3;
X
X /* Open window */
X if (!(w=OpenWindowTags(&nw,
X                        WA_Left,wl,
X                        WA_Top,wt,
X                        WA_InnerWidth,ww,
X                        WA_InnerHeight,wh,
X                        WA_PubScreen,pubsc,
X                        WA_AutoAdjust,TRUE,
X                        TAG_DONE)))
X  goto osw4;
X wp=w->UserPort; /* Retrieve window port */
X
X /* Circumvent an intuition.library bug. See AutoDocs for LockPubScreen() */
X UnlockPubScreen(NULL,pubsc);
X pubsc=NULL;
X
X /* Notify Workbench about window */
X if (!(aw=AddAppWindow(NULL,NULL,w,MyMP,NULL)))
X  goto osw5;
X
X /* Add gadget list to window */
X AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
X RefreshGList(gl,w,NULL,(UWORD) -1);
X GT_RefreshWindow(w,NULL);
X
X /* Window open! */
X return(1L<<wp->mp_SigBit);
X
X /* Something went wrong.... */
Xosw5: CloseWindow(w);
X      w=NULL;
Xosw4: FreeGadgets(gl);
Xosw3: FreeVisualInfo(vi);
Xosw2: if (pubsc) UnlockPubScreen(NULL,pubsc);
Xosw1: return(0);
X}
X
X/* Refresh status window gadgets */
Xvoid RefreshStatusWindow(void)
X{
X PrintStatusLine();
X RefreshGList(gl,w,NULL,2); /* Refresh only the first two gadgets */
X}
X
X/* If the window is open, detach tool list from ListView gadget */
Xvoid DetachToolList(void)
X{
X if (w) GT_SetGadgetAttrs(lvgad,w,NULL,GTLV_Labels,-1,TAG_DONE);
X}
X
X/* If the window is open, attach tool list to ListView gadget */
Xvoid AttachToolList(void)
X{
X if (w) GT_SetGadgetAttrs(lvgad,w,NULL,
X                          GTLV_Labels,&ToolList,
X                          /* If an item was selected, use it as top item */
X                          GTLV_Top,lvord<0?0:lvord,
X                          GTLV_Selected,lvord,
X                          TAG_DONE);
X}
X
X/* Handle window events */
XBOOL HandleWindowEvent(void)
X{
X BOOL rc=FALSE;             /* True if window close event */
X struct IntuiMessage *msg;
X struct ToolNode *tn;
X FILE *fh;
X
X while (msg=GT_GetIMsg(wp)) /* Pre-process Intuition messages */
X  {
X   switch (msg->Class)
X    {
X     case INTUITICKS:       /* Intuition tick received */
X      break;
X     case CLOSEWINDOW:      /* User clicked the close gadget */
X      wl=w->LeftEdge;       /* Retreive window parameters for next open */
X      wt=w->TopEdge;
X      rc=TRUE;              /* Yes, close window */
X      break;
X     case REFRESHWINDOW:    /* Window must be refreshed */
X      GT_BeginRefresh(w);
X      GT_EndRefresh(w,TRUE);
X      break;
X     case GADGETUP:         /* User released a gadget */
X      switch(((struct Gadget *) msg->IAddress)->GadgetID)
X       {
X        case LVGAD_ID:      /* User selected a ListView item */
X         lvord=msg->Code;   /* Retrieve the ordinal number of the item */
X         break;
X        case RTGAD_ID:      /* User selected the remove tool gadget */
X         if (lvord>=0)      /* Is the ordinal number valid? */
X          {                 /* Yes, search tool and remove it */
X           WORD i=0;        /* Counter */
X
X           /* Scan tool list until the ordinal number is reached */
X           for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn),i++)
X            if (i>=lvord) break;
X           lvord=-1;        /* invalidate ordinal number */
X
X           /* Remove tool from list */
X           DetachToolList();
X           RemToolNode(tn);
X           AttachToolList();
X
X           /* Refresh Gadgets */
X           RefreshStatusWindow();
X          }
X         break;
X        case SCGAD_ID:      /* User selected the save config gadget */
X         if (fh=fopen(ConfigName,"w"))      /* Open config file */
X          {
X           for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn))
X            {
X             fputs(tn->tn_Node.ln_Name,fh); /* Write menu entry name */
X             if (tn->tn_RealName)           /* Exists a real name? */
X              {
X               fputs(";",fh);               /* Yes, append it */
X               fputs(tn->tn_RealName,fh);
X              }
X             fputs("\n",fh);                /* Append a new line */
X            }
X           fclose(fh);                      /* Close the config file */
X          }
X         else                               /* Could not open config file! */
X          DisplayBeep(NULL);                /* --> Flash display           */
X         break;
X       }
X      break;
X    }
X   GT_ReplyIMsg(msg); /* Reply pre-processed message */
X  }
X
X return rc;
X}
X
X/* Close status window */
Xvoid CloseStatusWindow(void)
X{
X RemoveAppWindow(aw);
X CloseWindow(w);
X w=NULL;
X FreeGadgets(gl);    /* Release allocated resources */
X FreeVisualInfo(vi);
X}
END_OF_FILE
if test 8602 -ne `wc -c <'window.c'`; then
    echo shar: \"'window.c'\" unpacked with wrong size!
fi
# end of 'window.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.