home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 110 / af110sub.adf / DTConvert.lzx / DTConvert / DTConvert.c < prev    next >
C/C++ Source or Header  |  1998-03-11  |  59KB  |  1,860 lines

  1.  
  2. /*
  3. **
  4. **  $VER: DTConvert.c 1.7 (2.3.98)
  5. **  datatypes.library/Examples/DTConvert
  6. **
  7. **  Converts file into another format using datatypes
  8. **
  9. **  Main program and startup code
  10. **
  11. **  Written 1996-1998 by Roland 'Gizzy' Mainz
  12. **
  13. */
  14.  
  15. /* project includes */
  16. #include "DTConvert.h"
  17. #include "gui.h"
  18.  
  19. /* version string */
  20. #include "DTConvert_rev.h"
  21.  
  22. /*****************************************************************************/
  23.  
  24. /* list of datatypes, used in gadtools listview gadget */
  25. struct DTList
  26. {
  27.     struct List dtl_List;
  28.     UWORD       dtl_NumNodes;
  29.     APTR        dtl_Pool;
  30. };
  31.  
  32. /* single dtlist node */
  33. struct DTNode
  34. {
  35.     struct Node dtn_Node;
  36.     STRPTR      dtn_DTName;
  37.     /* dynamic bufferspace follows here */
  38. };
  39.  
  40.  
  41. /*****************************************************************************/
  42. /* shared libraries */
  43.  
  44. struct Library       *UtilityBase    = NULL;
  45. struct GfxBase       *GfxBase        = NULL;
  46. struct IntuitionBase *IntuitionBase  = NULL;
  47. struct Library       *GadToolsBase   = NULL;
  48. struct Library       *DataTypesBase  = NULL;
  49. struct Library       *AslBase        = NULL;
  50. struct Library       *IconBase       = NULL;
  51. struct Library       *WorkbenchBase  = NULL;
  52.  
  53. /*****************************************************************************/
  54.  
  55. /* version_string */
  56. STRPTR versionstring = VERSTAG;
  57.  
  58. /*****************************************************************************/
  59.  
  60. /* local prototypes */
  61. static                 void                 DefaultSettings( void );
  62. static                 void                 ClearRDA( void );
  63. static                 void                 ScanRDA( void );
  64. static                 void                 ScanToolTypes( TEXT ** );
  65. static                 void                 FreeInitProjectResult( void );
  66. static                 void                 ReadENVPrefs( void );
  67.  
  68. static                 BOOL                 CreateBasicResources( void );
  69. static                 void                 DeleteBasicResources( void );
  70.  
  71. static                 BOOL                 OpenLibStuff( void );
  72. static                 void                 CloseLibStuff( void );
  73.  
  74. static                 void                 RunTool( STRPTR );
  75.  
  76. static                 BOOL                 NewProject( STRPTR, STRPTR, BOOL, STRPTR, BOOL, STRPTR );
  77.  
  78. static                 struct DTList       *CreateDTDescrList( BPTR, ULONG );
  79. static                 void                 FreeDTDescrList( struct DTList * );
  80. static                 struct DTNode       *FindDTNodeByName( struct DTList *, STRPTR );
  81.  
  82. static                 void                 LockGUI( void );
  83. static                 void                 UnlockGUI( void );
  84.  
  85. static                 STRPTR               StringSave( STRPTR );
  86. static                 STRPTR               AllocStringBuff( ULONG );
  87. static                 STRPTR               UpdateString( STRPTR *, STRPTR );
  88. static                 void                 FreeString( STRPTR );
  89.  
  90. static                 struct DiskObject   *GetToolDiskObject( STRPTR );
  91.  
  92. static                 ULONG                SumString( STRPTR );
  93.  
  94.  
  95. /*****************************************************************************/
  96.  
  97. long main_retval,
  98.      main_retval2;
  99.  
  100. static struct RDArgs  *startuprda;
  101.  
  102. /* mempool for strings */
  103. static APTR StringPool;
  104.  
  105. /*****************************************************************************/
  106.  
  107. /* template for ReadArgs */
  108. #define STARTUP_TEMPLATE "FROM=NAME=SRCNAME,"          \
  109.                          "DESTDATATYPE=DATATYPE=DTN,"  \
  110.                          "IFF/S,"                      \
  111.                          "TO=DESTNAME,"                \
  112.                          "GUI/S,"                      \
  113.                          "PUBSCREEN/K"
  114.  
  115. #define ENV_TEMPLATE STARTUP_TEMPLATE /* equal because there are no /A switches */
  116.  
  117. static
  118. struct
  119. {
  120.     STRPTR  srcname;
  121.     STRPTR  destdatatype;
  122.     long   *iff;
  123.     STRPTR  destname;
  124.     long   *gui;
  125.     STRPTR  pubscreen;
  126. } result;
  127.  
  128. static
  129. struct
  130. {
  131.     STRPTR  srcname;
  132.     STRPTR  destdatatype;
  133.     BOOL    iff;
  134.     STRPTR  destname;
  135.     BOOL    gui;
  136.     STRPTR  pubscreen;
  137. } project;
  138.  
  139. /*****************************************************************************/
  140.  
  141. /****** DTConvert/DTConvert **************************************************
  142. *
  143. *    NAME
  144. *       DTConvert -- DataTypes-based conversion tool
  145. *
  146. *    FORMAT
  147. *       DTConvert [FROM|NAME|SRCNAME <file>]
  148. *                 [DESTDATATYPE|DATATYPE|DTN <datatype>] [IFF]
  149. *                 [TO|DESTNAME <file>] [GUI] [PUBSCREEN <public screen>]
  150. *
  151. *    TEMPLATE
  152. *       FROM=NAME=SRCNAME,DESTDATATYPE=DATATYPE=DTN,IFF/S,TO=DESTNAME,
  153. *       GUI/S,PUBSCREEN/K
  154. *
  155. *    PURPOSE
  156. *       Convert data from one format into another format using datatypes
  157. *       classes.
  158. *
  159. *    DESCRIPTION
  160. *       DTConvert converts data from one format into another format,
  161. *       e.g. picture -> picture,
  162. *            animation -> anmation,
  163. *            movie -> movie,
  164. *            sound -> sound,
  165. *            text -> text (n/a)
  166. *
  167. *      You simply have to set the souce file name (SRCNAME), the
  168. *      datatype to convert to (DATATYPE) (or the IFF switch if you want to
  169. *      convert into the base-IFF format and the destination file name (TO).
  170. *
  171. *    BUGS
  172. *      - picture.datatype V43 interface not implemented.
  173. *        This causes that any encoder only runs in V42 mode any may
  174. *        only encode 8 bit data.
  175. *
  176. *      - path names are limitted to 1024 chars, larger filenames may cause
  177. *        mailfunctions
  178. *
  179. *      - the IFF switch is incompatible to the GUI switch because the GUI
  180. *        as no IFF checkbox gadget, nor does the GUI check if the IFF
  181. *        switch was set.
  182. *
  183. *      - datatypes.library versions V45.3 and V45.4 have a bug in
  184. *        NewDTObjectA which causes that a descriptor is unlocked too often,
  185. *        which results in an Alert( 3500000 ). V45.5 fixes this.
  186. *
  187. *      - Added an error text in the case that a datatypes class does not
  188. *        support an encoder part...
  189. *
  190. *    NOTES
  191. *      - picture.datatype V43 pixmap interface not supported.
  192. *
  193. *      - text conversion not supported yet.
  194. *
  195. *    TODO
  196. *      - picture.datatype V43 compatibility
  197. *
  198. *      - text conversion (GID_TEXT -> GID_TEXT), e.g. IFF FTXT <-> Ascii
  199. *
  200. *      - document conversion (GID_DOCUMENT -> GID_DOCUMENT), after
  201. *        Stefan Ruppert and I finsished the document.datatype concepts.
  202. *
  203. *    HISTORY
  204. *       V1.1:
  205. *         - First release to dta@amigawolrd.com mailinglist.
  206. *
  207. *       V1.2:
  208. *         - Added support for animation.datatype subclasses
  209. *
  210. *       V1.3:
  211. *         - Minor fixes.
  212. *
  213. *       V1.4
  214. *         - Added support for sound.datatype V40 subclasses, partial support
  215. *           for suggested sound.datatype V41 interface.
  216. *
  217. *         - Added some usefull comments.
  218. *
  219. *         - WriteAnimClass/WriteSoundClass now sets
  220. *           SetIoErr( ERROR_REQUIRED_ARGUMENT_MISSING ); if something goes
  221. *           wrong (this should abort the encoder; only ERROR_OBJECT_NOT_FOUND
  222. *           is accepted here).
  223. *
  224. *         - Fixed some holes in the error handling.
  225. *
  226. *         - GUI added.
  227. *
  228. *         - Added WB support
  229. *
  230. *         - Added ENV variable support; a local or global (ENV) variable
  231. *           "DTConvert" takes the same arguments as the shell template.
  232. *           Variable settings can be overridden by any argument.
  233. *
  234. *         - Project split in seperate sources (e.g. main, GUI, converters)
  235. *
  236. *       V1.5
  237. *         - Added the feature that the datatypes selection requester shows
  238. *           only entries which match the source group IDs
  239. *           (if a source has been already selected).
  240. *
  241. *         - Added kluge which alows the conversion between GID_MOVIE
  242. *           and GID_ANIMATION datatypes (both are based on
  243. *           animation.datatype, here we have the same interface :-)
  244. *
  245. *         - Fixed the bug that ConvertAnimation function did not deal
  246. *           with truecolor bitmaps (e.g. CyberGFX bitmaps for example,
  247. *           truecolor bitmaps are indicated by ADTA_NumColors == 0.
  248. *           Fixed.
  249. *
  250. *       V1.6
  251. *         - Fixed the bug that ObtainDataTypeA was called for each
  252. *           INTUITICK if the datatype selection requester was open.
  253. *           Fixed.
  254. *
  255. *       V1.7
  256. *         - Fixed the bug that a descriptor was unlocked too often
  257. *           in some cases. See BUGS section above about a matching bug
  258. *           in datatypes.library V45.3 and V45.4 (V45.5 fixes this).
  259. *           Fixed (both "datatypes.library" and "DTConvert").
  260. *
  261. *         - The datatypes requester now accepts ESC as "Cancel" and
  262. *           RETURN as OK.
  263. *
  264. *         - The tool can now be aborted by SIGBREAKF_CTRL_C.
  265. *
  266. *         - Fixed the bug that somtimes an error return code
  267. *           was overwritting by the Message() function.
  268. *
  269. *         - Fixed the bu that the IFF comandline switch did not work
  270. *           (the GUI prompted everytimes in this case). But IFF and
  271. *           GUI switches does currently not co-operate :-(
  272. *
  273. *         - Fixed a bug in the WB startup code which caused that a project
  274. *           without an icon wasn't processed. The code now uses
  275. *           GetDiskObjectNew instead of GetDiskObject to fix this.
  276. *           Fixed.
  277. *
  278. *         - If launched from WB, "DTConvert" now opens a console window
  279. *           manually. Previously, the default WB output channel was used
  280. *           (which was NIL:).
  281. *           Same for project childs.
  282. *
  283. *         - Added output which prints a message if a subclass does not
  284. *           implement a local encoder. This was only done to get rid
  285. *           of mails like "your DTConvert has a bug: IFF ILBM -> PNG does
  286. *           not work...". These mails should go to the authors of the
  287. *           datatype classes, not to me. Sorry, but...
  288. *
  289. *         - If more than one project icon is given at WB startup, "DTConvert"
  290. *           now launches the matching number of projects instead
  291. *           of processing the given icons in sequence.
  292. *
  293. *         - Fixed problems with WB project startup and the current directory.
  294. *
  295. *         - The icon now contains the (possible) options and sets the
  296. *           stack size up to 16384 bytes.
  297. *
  298. *    AUTHOR's REQUEST
  299. *        By  releasing  this program I do  not  place any obligations on you,
  300. *        feel free to share this program with your  friends (and enemies).
  301. *
  302. *        If you want to blame me, report any bugs, or wants a new version
  303. *        send your letter to:
  304. *                        Roland Mainz
  305. *                        Hohenstaufenstraße 8
  306. *                        52388 Nörvenich
  307. *                        GERMANY
  308. *
  309. *        Phone: (+49)(0)2426/901568
  310. *        Fax:   (+49)(0)2426/901569
  311. *
  312. *        EMAIL is also available:
  313. *        GISBURN@w-specht.rhein-ruhr.de
  314. *
  315. *        If you want to send me attachments larger than 1MB (up to 5MB,
  316. *        more with my permission):
  317. *        Up to April 1998 I'm reachable using this email address, too:
  318. *        Reinhold.A.Mainz@KBV.DE
  319. *
  320. *        | Please put your name and address in your mails !
  321. *        | German mailers should add their phone numbers.
  322. *        | See BUGS section above when submitting bug reports.
  323. *
  324. *        Sorry, but I can only look once a week for mails.
  325. *        If you don't hear something from me within three weeks, please
  326. *        send your mail again (but watch about new releases) (problems with
  327. *        this email port are caused by reconfigurations, hackers, network
  328. *        problems etc.).
  329. *
  330. *        The  entire  "DTConvert"  package may  be  noncommercially
  331. *        redistributed, provided  that  the package  is always  distributed
  332. *        in it's complete  form (including it's documentation).  A small copy
  333. *        fee for media costs is okay but any kind of commercial distribution
  334. *        is strictly forbidden! Comments  and  suggestions  how  to  improve
  335. *        this program  are generally appreciated!
  336. *
  337. *        Thanks to Matt Dillon for his DICE, David Junod for this datatypes
  338. *        environment and Olaf 'Olsen' Barthel for his help, ideas and some
  339. *        text clips from his documentations.
  340. *
  341. *    SEE ALSO
  342. *
  343. ******************************************************************************
  344. *
  345. */
  346.  
  347.  
  348. #ifdef _DCC
  349. /* disable CTRL_C break support (DICE CTRL_C abort function) */
  350. void chkabort( void )
  351. {
  352. }
  353.  
  354.  
  355. /* DICE workbench entry */
  356. long wbmain( struct WBStartup *wbstartup )
  357. {
  358.     /* Call main like SAS-C */
  359.     return( (int)main( 0L, (STRPTR *)wbstartup ) );
  360. }
  361. #endif /* _DCC */
  362.  
  363.  
  364. int main( int ac, STRPTR *av )
  365. {
  366.     LONG               numArgs,
  367.                        x;
  368.     struct WBStartup  *wbstartup;
  369.     struct WBArg      *wbarg;
  370.     struct DiskObject *tooldobj,
  371.                       *projectdobj;
  372.     BPTR               oldToolLock    = NULL,
  373.                        oldProjectLock = NULL;
  374.     BPTR               oldOutput      = NULL;
  375.  
  376.     main_retval2 = 0L;
  377.     main_retval  = RETURN_OK;
  378.  
  379.     if( CreateBasicResources() )
  380.     {
  381.       DefaultSettings();
  382.  
  383.       /* check if something goes wrong (ENV error etc.) */
  384.       if( main_retval == RETURN_OK )
  385.       {
  386. /* Workbench */
  387.         if( ac == 0L )
  388.         {
  389.           BPTR newOutput;
  390.  
  391.           /* Add "stdout" for Message() function...  */
  392.           if( newOutput = Open( "CON:////" NAME "/auto/wait/close", MODE_READWRITE ) )
  393.           {
  394.             oldOutput = SelectOutput( newOutput );
  395.           }
  396.  
  397.           wbstartup = (struct WBStartup *)av;
  398.  
  399.           numArgs = wbstartup -> sm_NumArgs;
  400.           wbarg   = wbstartup -> sm_ArgList;
  401.  
  402.           if( *(wbarg[ 0 ] . wa_Name) )
  403.           {
  404.             if( wbarg[ 0 ] . wa_Lock )
  405.             {
  406.               oldToolLock = CurrentDir( (wbarg[ 0 ] . wa_Lock) );
  407.             }
  408.  
  409.             if( tooldobj = GetToolDiskObject( (wbarg[ 0 ] . wa_Name) ) )
  410.             {
  411.               /* two possible cases when started from workbench ... */
  412.               if( numArgs < 2L )
  413.               {
  414.                 /* ... first case, only our tool icon is given, create one project here */
  415.  
  416.                 ScanToolTypes( (STRPTR *)(tooldobj -> do_ToolTypes) );
  417.  
  418.                 /* check if something goes wrong (parsing error, etc.) */
  419.                 if( main_retval == RETURN_OK )
  420.                 {
  421.                   RunTool( NULL );
  422.                 }
  423.  
  424.                 FreeInitProjectResult();
  425.               }
  426.               else
  427.               {
  428.                 /* ... second case, a couple of project icons are given, multiple projects will start from here */
  429.                 for( x = 1L ; x < numArgs ; x++ )
  430.                 {
  431.                   if( wbarg[ x ] . wa_Lock )
  432.                   {
  433.                     oldProjectLock = CurrentDir( (wbarg[ x ] . wa_Lock) );
  434.                   }
  435.  
  436.                   if( *(wbarg[ x ] . wa_Name) )
  437.                   {
  438.                     if( projectdobj = GetDiskObjectNew( (wbarg[ x ] . wa_Name) ) )
  439.                     {
  440.                       ScanToolTypes( (STRPTR *)(tooldobj -> do_ToolTypes) );
  441.                       ScanToolTypes( (STRPTR *)(projectdobj -> do_ToolTypes) );
  442.  
  443.                       /* check if something goes wrong (parsing error, etc.) */
  444.                       if( main_retval == RETURN_OK )
  445.                       {
  446.                         NewProject( ((project . srcname)?(project . srcname):((STRPTR)(wbarg[ x ] . wa_Name))),
  447.                                     (project . destdatatype),
  448.                                     (project . iff),
  449.                                     (project . destname),
  450.                                     TRUE,
  451.                                     (project . pubscreen) );
  452.                       }
  453.  
  454.                       FreeInitProjectResult();
  455.                       DefaultSettings();
  456.  
  457.                       FreeDiskObject( projectdobj );
  458.                     }
  459.                   }
  460.  
  461.                   if( wbarg[ x ] . wa_Lock )
  462.                   {
  463.                     CurrentDir( oldProjectLock );
  464.                   }
  465.                 }
  466.               }
  467.  
  468.               FreeDiskObject( tooldobj );
  469.             }
  470.  
  471.             if( wbarg[ 0 ] . wa_Lock )
  472.             {
  473.               CurrentDir( oldToolLock );
  474.             }
  475.           }
  476.         }
  477.         else
  478.         {
  479. /* CLI/Shell */
  480.           if( startuprda = ReadArgs( STARTUP_TEMPLATE, (LONG *)(&result), NULL ) )
  481.           {
  482.             /* did we get a CTRL_C signal ? */
  483.             if( !CheckSignal( SIGBREAKF_CTRL_C ) )
  484.             {
  485.               ScanRDA();
  486.  
  487.               /* check if something goes wrong (parsing error, etc.) */
  488.               if( main_retval == RETURN_OK )
  489.               {
  490.                 RunTool( NULL );
  491.               }
  492.  
  493.               FreeInitProjectResult();
  494.             }
  495.             else
  496.             {
  497.               main_retval2 = ERROR_BREAK;
  498.               main_retval  = RETURN_WARN;
  499.             }
  500.  
  501.             FreeArgs( startuprda );
  502.           }
  503.           else
  504.           {
  505.             main_retval2 = IoErr();
  506.             main_retval  = RETURN_FAIL;
  507.           }
  508.         }
  509.       }
  510.  
  511.       DeleteBasicResources();
  512.     }
  513.  
  514.     PrintFault( main_retval2, NAME );
  515.  
  516.     /* Close WB stdout... */
  517.     if( oldOutput )
  518.     {
  519.       BPTR newOutput;
  520.  
  521.       newOutput = SelectOutput( oldOutput );
  522.  
  523.       (void)Close( newOutput );
  524.     }
  525.  
  526.     SetIoErr( main_retval2 );
  527.  
  528.     return( main_retval );
  529. }
  530.  
  531.  
  532. static
  533. void DefaultSettings( void )
  534. {
  535.     ClearRDA();
  536.  
  537.     memset( (void *)(&project), 0, sizeof( project ) );
  538.  
  539.     ReadENVPrefs();
  540. }
  541.  
  542.  
  543. static
  544. void ReadENVPrefs( void )
  545. {
  546.     struct RDArgs envvarrda =
  547.     {
  548.       NULL,
  549.       256L,
  550.       0L,
  551.       0L,
  552.       NULL,
  553.       0L,
  554.       NULL,
  555.       RDAF_NOPROMPT
  556.     };
  557.  
  558.     TEXT varbuff[ 258 ];
  559.  
  560.     envvarrda . RDA_Source . CS_Buffer = varbuff;
  561.  
  562.     if( GetVar( NAME, varbuff, 256L, 0UL ) != (-1L) )
  563.     {
  564.       strcat( varbuff, "\n" );
  565.  
  566.       if( ReadArgs( ENV_TEMPLATE, (LONG *)(&result), (&envvarrda) ) )
  567.       {
  568.         ScanRDA();
  569.  
  570.         FreeArgs( (&envvarrda) );
  571.       }
  572.       else
  573.       {
  574.         main_retval2 = IoErr();
  575.         main_retval  = RETURN_FAIL;
  576.       }
  577.     }
  578. }
  579.  
  580.  
  581. static
  582. void ClearRDA( void )
  583. {
  584.     memset( (void *)(&result), 0, sizeof( result ) );
  585. }
  586.  
  587.  
  588. static
  589. void ScanRDA( void )
  590. {
  591.     if( result . srcname )
  592.     {
  593.       UpdateString( (&(project . srcname)), (result . srcname) );
  594.     }
  595.  
  596.     if( result . destdatatype )
  597.     {
  598.       UpdateString( (&(project . destdatatype)), (result . destdatatype) );
  599.     }
  600.  
  601.     if( result . iff )
  602.     {
  603.       project . iff = TRUE;
  604.     }
  605.  
  606.     if( result . destname )
  607.     {
  608.       UpdateString( (&(project . destname)), (result . destname) );
  609.     }
  610.  
  611.     if( result . gui )
  612.     {
  613.       project . gui = TRUE;
  614.     }
  615.  
  616.     if( result . pubscreen )
  617.     {
  618.       UpdateString( (&(project . pubscreen)), (result . pubscreen) );
  619.     }
  620.  
  621.     ClearRDA();
  622. }
  623.  
  624.  
  625. static
  626. void ScanToolTypes( TEXT **tt )
  627. {
  628.     STRPTR s;
  629.  
  630.     if( s = FindToolType( tt, "FROM" ) )
  631.       result . srcname = s;
  632.  
  633.     if( s = FindToolType( tt, "NAME" ) )
  634.       result . srcname = s;
  635.  
  636.     if( s = FindToolType( tt, "SRCNAME" ) )
  637.       result . srcname = s;
  638.  
  639.     if( s = FindToolType( tt, "DESTDATATYPE" ) )
  640.       result . destdatatype = s;
  641.  
  642.     if( s = FindToolType( tt, "DATATYPE" ) )
  643.       result . destdatatype = s;
  644.  
  645.     if( s = FindToolType( tt, "DTN" ) )
  646.       result . destdatatype = s;
  647.  
  648.     if( s = FindToolType( tt, "IFF" ) )
  649.       result . iff = (long *)s;
  650.  
  651.     if( s = FindToolType( tt, "TO" ) )
  652.       result . destname = s;
  653.  
  654.     if( s = FindToolType( tt, "DESTNAME" ) )
  655.       result . destname = s;
  656.  
  657.     if( s = FindToolType( tt, "GUI" ) )
  658.       result . gui = (long *)s;
  659.  
  660.     if( s = FindToolType( tt, "PUBSCREEN" ) )
  661.       result . pubscreen = s;
  662.  
  663.     ScanRDA();
  664. }
  665.  
  666.  
  667. static
  668. void FreeInitProjectResult( void )
  669. {
  670.     FreeString( (project . srcname) );
  671.     FreeString( (project . destdatatype) );
  672.     FreeString( (project . destname) );
  673.     FreeString( (project . pubscreen) );
  674. }
  675.  
  676.  
  677. static
  678. BOOL CreateBasicResources( void )
  679. {
  680.     if( OpenLibStuff() )
  681.     {
  682.       if( StringPool = CreatePool( (MEMF_PUBLIC | MEMF_CLEAR), 128UL, 128UL ) )
  683.       {
  684.         return( TRUE );
  685.  
  686. #ifdef COMMENTED_OUT
  687.         DeletePool( StringPool );
  688. #endif /* COMMENTED_OUT */
  689.       }
  690.  
  691.       CloseLibStuff();
  692.     }
  693.  
  694.     return( FALSE );
  695. }
  696.  
  697.  
  698. static
  699. void DeleteBasicResources( void )
  700. {
  701.     DeletePool( StringPool );
  702.     CloseLibStuff();
  703. }
  704.  
  705.  
  706. static
  707. BOOL OpenLibStuff( void )
  708. {
  709.     AttemptOpenLibrary( (&UtilityBase),                          NAME, "utility.library",     39UL );
  710.     AttemptOpenLibrary( (struct Library **)(&(GfxBase)),         NAME, "graphics.library",    39UL );
  711.     AttemptOpenLibrary( (struct Library **)(&(IntuitionBase)),   NAME, "intuition.library",   39UL );
  712.     AttemptOpenLibrary( (&GadToolsBase),                         NAME, "gadtools.library",    39UL );
  713.     AttemptOpenLibrary( (&DataTypesBase),                        NAME, "datatypes.library",   45UL );
  714.     AttemptOpenLibrary( (&IconBase),                             NAME, "icon.library",        39UL );
  715.     AttemptOpenLibrary( (&WorkbenchBase),                        NAME, "workbench.library",   39UL );
  716.     AttemptOpenLibrary( (&AslBase),                              NAME, "asl.library",         38UL );
  717.  
  718.     if( UtilityBase && GfxBase && IntuitionBase && GadToolsBase && DataTypesBase && IconBase && WorkbenchBase && AslBase  )
  719.     {
  720.       return( TRUE );
  721.     }
  722.  
  723.     CloseLibStuff();
  724.  
  725.     return( FALSE );
  726. }
  727.  
  728.  
  729. static
  730. void CloseLibStuff( void )
  731. {
  732.     CloseLibrary( AslBase );
  733.     CloseLibrary( WorkbenchBase );
  734.     CloseLibrary( IconBase );
  735.     CloseLibrary( DataTypesBase );
  736.     CloseLibrary( GadToolsBase );
  737.     CloseLibrary( (&(IntuitionBase -> LibNode)) );
  738.     CloseLibrary( (&(GfxBase -> LibNode)) );
  739.     CloseLibrary( UtilityBase );
  740. }
  741.  
  742.  
  743. static
  744. void RunTool( STRPTR srcname )
  745. {
  746.     STRPTR destname     = project . destname;
  747.     STRPTR datatypename = project . destdatatype;
  748.     BOOL   srcchanged   = FALSE;      /* srcname changed ? */
  749.     ULONG  srcsum       = SumString( srcname );
  750.  
  751.     if( project . srcname )
  752.     {
  753.       srcname = project . srcname;
  754.     }
  755.  
  756.     /* Check if datatype name is valid */
  757.     if( datatypename )
  758.     {
  759.       struct DataType *dtn;
  760.  
  761.       if( dtn = ObtainDataTypeA( DTST_RAM, (APTR)datatypename, NULL ) )
  762.       {
  763.         ReleaseDataType( dtn );
  764.       }
  765.       else
  766.       {
  767.         datatypename = NULL;
  768.       }
  769.     }
  770.  
  771.     /* GUI requested / required ? */
  772.     if( (project . gui) || (srcname == NULL) || (destname == NULL) || ((datatypename == NULL) && ((project . iff) == 0L)) )
  773.     {
  774.       struct MsgPort *appport;
  775.       struct DTList  *dtl;
  776.       struct DTNode  *selecteddt;
  777.  
  778.       if( appport = CreateMsgPort() )
  779.       {
  780.         BPTR srclock = NULL;
  781.  
  782.         if( Strlen( srcname ) )
  783.         {
  784.           srclock = Lock( srcname, SHARED_LOCK );
  785.         }
  786.  
  787.         if( dtl = CreateDTDescrList( srclock, 0UL ) )
  788.         {
  789.           PubScreenName = project . pubscreen; /* set pubscreen name for GadToolsBox's windows */
  790.  
  791.           selecteddt = FindDTNodeByName( dtl, datatypename );
  792.  
  793.           if( !SetupScreen() )
  794.           {
  795.             struct FileRequester *SrcFileReq  = NULL,
  796.                                  *DestFileReq = NULL;
  797.  
  798.             if( !OpenDTConvert_MAINWindow() )
  799.             {
  800.               BOOL                 done             = FALSE;
  801.               struct IntuiMessage *imsg;
  802.               ULONG                sigmask;
  803.               BOOL                 get_source       = FALSE,
  804.                                    get_datatype     = FALSE,
  805.                                    get_destination  = FALSE;
  806.               BOOL                 convert          = FALSE;
  807.               BOOL                 convertable      = Strlen( srcname ) && selecteddt && Strlen( destname );
  808.               struct AppWindow    *appwindow        = NULL;
  809.               struct DiskObject   *appdobj          = NULL;
  810.               struct AppIcon      *appicon          = NULL;
  811.  
  812.               /* Running on WB screen ? */
  813.               if( ((DTConvert_MAINWnd -> WScreen -> Flags) & SCREENTYPE) == WBENCHSCREEN )
  814.               {
  815.                 appwindow = AddAppWindowA( 0UL, 0UL, DTConvert_MAINWnd, appport, NULL );
  816.               }
  817.               else
  818.               {
  819.                 if( appdobj = GetDefDiskObject( WBPROJECT ) )
  820.                 {
  821.                   /* Not running on workbench screen ? - Create AppIcon for wb app support ! */
  822.                   appicon = AddAppIconA( 0UL, 0UL, NAME, appport, NULL, appdobj, NULL );
  823.                 }
  824.               }
  825.  
  826.               GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ],      DTConvert_MAINWnd, NULL, GTST_String, srcname,                                                  TAG_DONE );
  827.               GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DATATYPE ],    DTConvert_MAINWnd, NULL, GTTX_Text,   ((selecteddt)?(selecteddt -> dtn_Node . ln_Name):(NULL)), TAG_DONE );
  828.               GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL, GTST_String, destname,                                                 TAG_DONE );
  829.               GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_CONVERT ],     DTConvert_MAINWnd, NULL, GA_Disabled, (!convertable),                                           TAG_DONE );
  830.  
  831.               /*******************
  832.                * Main event loop *
  833.                *******************/
  834.               while( !done )
  835.               {
  836.                 ULONG sigr;
  837.  
  838.                 sigmask = (1UL << (DTConvert_MAINWnd -> UserPort -> mp_SigBit)) |
  839.                           (1UL << (appport -> mp_SigBit))                       |
  840.                           SIGBREAKF_CTRL_C;
  841.  
  842.                 if( DTConvert_DATATYPEWnd )
  843.                 {
  844.                   sigmask |= (1UL << (DTConvert_DATATYPEWnd -> UserPort -> mp_SigBit));
  845.                 }
  846.  
  847.                 sigr = Wait( sigmask );
  848.  
  849. /* Maiain window */
  850.                 if( sigr & (1UL << (DTConvert_MAINWnd -> UserPort -> mp_SigBit)) )
  851.                 {
  852.                   while( imsg = GT_GetIMsg( (DTConvert_MAINWnd -> UserPort) ) )
  853.                   {
  854.                     switch( imsg -> Class )
  855.                     {
  856.                       case IDCMP_CLOSEWINDOW:
  857.                       {
  858.                           done = TRUE;
  859.                       }
  860.                           break;
  861.  
  862.                       case IDCMP_REFRESHWINDOW:
  863.                       {
  864.                           GT_BeginRefresh( (imsg -> IDCMPWindow) );
  865.                           GT_EndRefresh( (imsg -> IDCMPWindow), TRUE );
  866.                       }
  867.                           break;
  868.  
  869.                       case IDCMP_GADGETUP:
  870.                       {
  871.                           switch( G( (imsg -> IAddress) ) -> GadgetID )
  872.                           {
  873.                             case GD_SOURCE: break;   /* NOP */
  874.  
  875.                             case GD_DATATYPE: break; /* NOP */
  876.  
  877.                             case GD_DESTINATION: break; /* NOP */
  878.  
  879.                             case GD_GET_SOURCE:
  880.                             {
  881.                                 get_source = TRUE;
  882.                             }
  883.                                 break;
  884.  
  885.                             case GD_GET_DATATYPE:
  886.                             {
  887.                                 get_datatype = TRUE;
  888.                             }
  889.                                 break;
  890.  
  891.                             case GD_GET_DESTINATION:
  892.                             {
  893.                                 get_destination = TRUE;
  894.                             }
  895.                                 break;
  896.  
  897.                             case GD_CONVERT:
  898.                             {
  899.                                 convert = TRUE;
  900.                             }
  901.                                 break;
  902.  
  903.                             case GD_CANCEL:
  904.                             {
  905.                                 done = TRUE;
  906.                             }
  907.                                 break;
  908.                           }
  909.                       }
  910.                           break;
  911.  
  912.                       case IDCMP_VANILLAKEY:
  913.                       {
  914.                           switch( imsg -> Code )
  915.                           {
  916.                             case 's': /* Source */
  917.                                 ActivateGadget( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL );
  918.                                 break;
  919.  
  920.                             case 'S': /* Get Source */
  921.                                 get_source = TRUE;
  922.                                 break;
  923.  
  924.                             case 't': /* datatype */
  925.                             case 'T': /* datatype */
  926.                                 get_datatype = TRUE;
  927.                                 break;
  928.  
  929.                             case 'd': /* Destination */
  930.                                 ActivateGadget( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL );
  931.                                 break;
  932.  
  933.                             case 'D': /* Get Destination */
  934.                                 get_destination = TRUE;
  935.                                 break;
  936.  
  937.                             case 'c': /* Convert */
  938.                             case 'C': /* Convert */
  939.                             {
  940.                                 convert = TRUE;
  941.                             }
  942.                                 break;
  943.  
  944.                             case 'a': /* Cancel */
  945.                             case 'A': /* Cancel */
  946.                             {
  947.                                 done = TRUE;
  948.                             }
  949.                                 break;
  950.                           }
  951.                       }
  952.                           break;
  953.                     }
  954.  
  955.                     GT_ReplyIMsg( imsg );
  956.                   }
  957.                 }
  958.  
  959. /* DatataTypes requester */
  960.                 if( DTConvert_DATATYPEWnd )
  961.                 {
  962.                   if( sigr & (1UL << (DTConvert_DATATYPEWnd -> UserPort -> mp_SigBit)) )
  963.                   {
  964.                     BOOL  dtdone = FALSE;
  965.                     BOOL  dtok   = FALSE;
  966.                     LONG  oldselected,
  967.                           selected;
  968.  
  969.                     GT_GetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL,
  970.                                        GTLV_Selected, (&oldselected),
  971.                                        TAG_DONE );
  972.  
  973.                     selected = oldselected;
  974.  
  975.                     while( imsg = GT_GetIMsg( (DTConvert_DATATYPEWnd -> UserPort) ) )
  976.                     {
  977.                       switch( imsg -> Class )
  978.                       {
  979.                         case IDCMP_CLOSEWINDOW:
  980.                         {
  981.                             dtdone = TRUE;
  982.                         }
  983.                             break;
  984.  
  985.                         case IDCMP_REFRESHWINDOW:
  986.                         {
  987.                             GT_BeginRefresh( (imsg -> IDCMPWindow) );
  988.                             GT_EndRefresh( (imsg -> IDCMPWindow), TRUE );
  989.                         }
  990.                             break;
  991.  
  992.                         case IDCMP_GADGETUP:
  993.                         {
  994.                             switch( G( (imsg -> IAddress) ) -> GadgetID )
  995.                             {
  996.                               case GD_DATATYPEDT: break; /* NOP */
  997.  
  998.                               case GD_OKDT:
  999.                               {
  1000.                                   dtdone = dtok = TRUE;
  1001.                               }
  1002.                                   break;
  1003.  
  1004.                               case GD_CANCELDT:
  1005.                               {
  1006.                                   dtdone = TRUE;
  1007.                               }
  1008.                                   break;
  1009.                             }
  1010.                         }
  1011.                             break;
  1012.  
  1013.                         case IDCMP_VANILLAKEY:
  1014.                         {
  1015.                             switch( imsg -> Code )
  1016.                             {
  1017.                               case 'o':  /* Ok */
  1018.                               case 'O':  /* Ok */
  1019.                               case '\r': /* Ok */
  1020.                                   dtdone = dtok = TRUE;
  1021.                                   break;
  1022.  
  1023.                               case 'c': /* Cancel */
  1024.                               case 'C': /* Cancel */
  1025.                               case  27: /* ESC == Cancel */
  1026.                                   dtdone = TRUE;
  1027.                                   break;
  1028.  
  1029.                               case 'd': /* DT Selection down */
  1030.                               {
  1031.                                   selected++;
  1032.                               }
  1033.                                   break;
  1034.  
  1035.                               case 'D': /* DT Selection up */
  1036.                               {
  1037.                                   selected--;
  1038.                               }
  1039.                                   break;
  1040.                             }
  1041.                         }
  1042.                             break;
  1043.  
  1044.                         case IDCMP_RAWKEY:
  1045.                         {
  1046.                             switch( imsg -> Code )
  1047.                             {
  1048.                               case 76: /* up */
  1049.                               {
  1050.                                   if( (imsg -> Qualifier) & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
  1051.                                   {
  1052.                                     selected = 0L; /* top */
  1053.                                   }
  1054.                                   else
  1055.                                   {
  1056.                                     if( (imsg -> Qualifier) & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) )
  1057.                                     {
  1058.                                       selected -= 5L; /* page up */
  1059.                                     }
  1060.                                     else
  1061.                                     {
  1062.                                       selected--; /* previous entry */
  1063.                                     }
  1064.                                   }
  1065.                               }
  1066.                                   break;
  1067.  
  1068.                               case 77: /* down */
  1069.                               {
  1070.                                   if( (imsg -> Qualifier) & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
  1071.                                   {
  1072.                                     selected = dtl -> dtl_NumNodes; /* bottom */
  1073.                                   }
  1074.                                   else
  1075.                                   {
  1076.                                     if( (imsg -> Qualifier) & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) )
  1077.                                     {
  1078.                                       selected += 5L; /* page down */
  1079.                                     }
  1080.                                     else
  1081.                                     {
  1082.                                       selected++; /* next entry */
  1083.                                     }
  1084.                                   }
  1085.                               }
  1086.                                   break;
  1087.                             }
  1088.                         }
  1089.                             break;
  1090.                       }
  1091.  
  1092.                       /* Check bounds */
  1093.                       if( selected < 0L )
  1094.                       {
  1095.                         selected = 0L;
  1096.                       }
  1097.                       else
  1098.                       {
  1099.                         if( selected > (LONG)(dtl -> dtl_NumNodes) )
  1100.                         {
  1101.                           selected = (LONG)(dtl -> dtl_NumNodes);
  1102.                         }
  1103.                       }
  1104.  
  1105.                       GT_ReplyIMsg( imsg );
  1106.                     }
  1107.  
  1108.                     if( selected != oldselected )
  1109.                     {
  1110.                       GT_SetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL,
  1111.                                          GTLV_Selected,    selected,
  1112.                                          GTLV_MakeVisible, selected,
  1113.                                          TAG_DONE );
  1114.                     }
  1115.  
  1116.                     if( dtok )
  1117.                     {
  1118.                       if( selecteddt = (struct DTNode *)GetNumNode( (&(dtl -> dtl_List)), selected ) )
  1119.                       {
  1120.                         GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DATATYPE ], DTConvert_MAINWnd, NULL,
  1121.                                            GTTX_Text, (selecteddt -> dtn_Node . ln_Name),
  1122.                                            TAG_DONE );
  1123.                       }
  1124.                     }
  1125.  
  1126.                     if( dtdone )
  1127.                     {
  1128.                       CloseDTConvert_DATATYPEWindow();
  1129.                     }
  1130.                   }
  1131.                 }
  1132.  
  1133. /* appppwindow / appicon port */
  1134.                 if( sigr & (1UL << (appport -> mp_SigBit)) )
  1135.                 {
  1136.                   struct AppMessage *amsg;
  1137.  
  1138.                   while( amsg = (struct AppMessage *)GetMsg( appport ) )
  1139.                   {
  1140.                     switch( amsg -> am_Type )
  1141.                     {
  1142.                       case AMTYPE_APPWINDOW:
  1143.                       case AMTYPE_APPICON:
  1144.                       {
  1145.                           if( amsg -> am_NumArgs )
  1146.                           {
  1147.                             LockGUI();
  1148.  
  1149.                               if( (amsg -> am_NumArgs) == 1UL )
  1150.                               {
  1151.                                 STRPTR name;
  1152.  
  1153.                                 if( name = GetLockName( (amsg -> am_ArgList[ 0 ] . wa_Lock), (amsg -> am_ArgList[ 0 ] . wa_Name) ) )
  1154.                                 {
  1155.                                   GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL, GTST_String, name, TAG_DONE );
  1156.  
  1157.                                   FreeVec( name );
  1158.                                 }
  1159.                               }
  1160.                               else
  1161.                               {
  1162.                                 ULONG i;
  1163.  
  1164.                                 for( i = 0UL ; i < (amsg -> am_NumArgs) ; i++ )
  1165.                                 {
  1166.                                   BPTR oldProjectLock = NULL;
  1167.  
  1168.                                   if( amsg -> am_ArgList[ i ] . wa_Lock )
  1169.                                   {
  1170.                                     oldProjectLock = CurrentDir( (amsg -> am_ArgList[ i ] . wa_Lock) );
  1171.                                   }
  1172.  
  1173.                                   NewProject( (amsg -> am_ArgList[ 0 ] . wa_Name), ((selecteddt)?(selecteddt -> dtn_DTName):(NULL)), (project . iff), destname, TRUE, (project . pubscreen) );
  1174.  
  1175.                                   if( amsg -> am_ArgList[ i ] . wa_Lock )
  1176.                                   {
  1177.                                     (void)CurrentDir( oldProjectLock );
  1178.                                   }
  1179.                                 }
  1180.                               }
  1181.  
  1182.                             UnlockGUI();
  1183.                           }
  1184.                       }
  1185.                           break;
  1186.                     }
  1187.  
  1188.                     ReplyMsg( (&(amsg -> am_Message)) );
  1189.                   }
  1190.                 }
  1191.  
  1192.                 /* Quit signal ? */
  1193.                 if( sigr & SIGBREAKF_CTRL_C )
  1194.                 {
  1195.                   done = TRUE;
  1196.                 }
  1197.  
  1198. /* prorocess collected events */
  1199.                 if( get_source || get_datatype || get_destination )
  1200.                 {
  1201.                   LockGUI();
  1202.  
  1203.                     if( get_source )
  1204.                     {
  1205.                       if( SrcFileReq == NULL )
  1206.                       {
  1207.                         SrcFileReq = (struct FileRequester *)AllocAslRequestTags( ASL_FileRequest,
  1208.                                                                                   ASLFR_Screen,          (DTConvert_MAINWnd -> WScreen),
  1209.                                                                                   ASLFR_TitleText,       "Open File...",
  1210.                                                                                   ASLFR_InitialLeftEdge, ((DTConvert_MAINWnd -> LeftEdge) + (DTConvert_MAINWnd -> BorderLeft) + 1UL),
  1211.                                                                                   ASLFR_InitialTopEdge,  ((DTConvert_MAINWnd -> TopEdge)  + (DTConvert_MAINWnd -> BorderTop) + 1UL),
  1212.                                                                                   ASLFR_DoPatterns,      TRUE,
  1213.                                                                                   TAG_DONE );
  1214.                       }
  1215.                 
  1216.                       if( SrcFileReq )
  1217.                       {
  1218.                         if( AslRequest( SrcFileReq, NULL ) )
  1219.                         {
  1220.                           ULONG  buffsize;
  1221.                           STRPTR filebuffer;
  1222.                 
  1223.                           buffsize = Strlen( (SrcFileReq -> fr_Drawer) ) + Strlen( (SrcFileReq -> fr_File) ) + 10UL;
  1224.                 
  1225.                           if( filebuffer = (STRPTR)AllocVec( buffsize, MEMF_PUBLIC ) )
  1226.                           {
  1227.                             strcpy( filebuffer, (SrcFileReq -> fr_Drawer) );
  1228.                             AddPart( filebuffer, (SrcFileReq -> fr_File), buffsize );
  1229.                 
  1230.                             GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL, GTST_String, filebuffer, TAG_DONE );
  1231.                 
  1232.                             FreeVec( filebuffer );
  1233.                           }
  1234.                         }
  1235.                       }
  1236.                 
  1237.                       get_source = FALSE;
  1238.                     }
  1239.                 
  1240.                     if( get_datatype )
  1241.                     {
  1242.                       if( DTConvert_DATATYPEWnd == NULL )
  1243.                       {
  1244.                         if( !OpenDTConvert_DATATYPEWindow() )
  1245.                         {
  1246.                           GT_SetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL, GTLV_Labels, dtl, TAG_DONE );
  1247.                         }
  1248.                       }
  1249.                 
  1250.                       get_datatype = FALSE;
  1251.                     }
  1252.                 
  1253.                     if( get_destination )
  1254.                     {
  1255.                       if( DestFileReq == NULL )
  1256.                       {
  1257.                         DestFileReq = (struct FileRequester *)AllocAslRequestTags( ASL_FileRequest,
  1258.                                                                                    ASLFR_Screen,          (DTConvert_MAINWnd -> WScreen),
  1259.                                                                                    ASLFR_TitleText,       "Save File...",
  1260.                                                                                    ASLFR_InitialLeftEdge, ((DTConvert_MAINWnd -> LeftEdge) + (DTConvert_MAINWnd -> BorderLeft) + 1UL),
  1261.                                                                                    ASLFR_InitialTopEdge,  ((DTConvert_MAINWnd -> TopEdge)  + (DTConvert_MAINWnd -> BorderTop) + 1UL),
  1262.                                                                                    ASLFR_DoPatterns,      TRUE,
  1263.                                                                                    ASLFR_DoSaveMode,      TRUE,
  1264.                                                                                    TAG_DONE );
  1265.                       }
  1266.                 
  1267.                       if( DestFileReq )
  1268.                       {
  1269.                         if( AslRequest( DestFileReq, NULL ) )
  1270.                         {
  1271.                           ULONG  buffsize;
  1272.                           STRPTR filebuffer;
  1273.                 
  1274.                           buffsize = Strlen( (DestFileReq -> fr_Drawer) ) + Strlen( (DestFileReq -> fr_File) ) + 10UL;
  1275.                 
  1276.                           if( filebuffer = (STRPTR)AllocVec( buffsize, MEMF_PUBLIC ) )
  1277.                           {
  1278.                             strcpy( filebuffer, (DestFileReq -> fr_Drawer) );
  1279.                             AddPart( filebuffer, (DestFileReq -> fr_File), buffsize );
  1280.                 
  1281.                             GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL, GTST_String, filebuffer, TAG_DONE );
  1282.                 
  1283.                             FreeVec( filebuffer );
  1284.                           }
  1285.                         }
  1286.                       }
  1287.                 
  1288.                       get_destination = FALSE;
  1289.                     }
  1290.  
  1291.                   UnlockGUI();
  1292.                 }
  1293.  
  1294. /* update */
  1295.                 GT_GetGadgetAttrs( DTConvert_MAINGadgets[ GD_SOURCE ], DTConvert_MAINWnd, NULL,
  1296.                                    GTST_String, (&srcname),
  1297.                                    TAG_DONE );
  1298.  
  1299.  
  1300.                 /* My quick hack to check if the src filename has been changed... */
  1301.                 srcchanged = (SumString( srcname ) != srcsum);
  1302.  
  1303.                 /* following block is experimental...  */
  1304.                 if( srcchanged )
  1305.                 {
  1306.                   struct DTList *old_dtl = dtl;
  1307.  
  1308.                   /* Update checksum... */
  1309.                   srcsum = SumString( srcname );
  1310.  
  1311.                   if( srclock )
  1312.                   {
  1313.                     UnLock( srclock );
  1314.                     srclock = NULL;
  1315.                   }
  1316.  
  1317.                   if( Strlen( srcname ) )
  1318.                   {
  1319.                     srclock = Lock( srcname, SHARED_LOCK );
  1320.                   }
  1321.  
  1322.                   dtl = CreateDTDescrList( srclock, 0UL );
  1323.  
  1324.                   if( selecteddt )
  1325.                   {
  1326.                     selecteddt = FindDTNodeByName( dtl, (selecteddt -> dtn_DTName) );
  1327.  
  1328.                     GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_DATATYPE ], DTConvert_MAINWnd, NULL,
  1329.                                        GTTX_Text, ((selecteddt)?(selecteddt -> dtn_Node . ln_Name):("")),
  1330.                                        TAG_DONE );
  1331.                   }
  1332.  
  1333.                   /* update DataTypes selection gadget */
  1334.                   if( DTConvert_DATATYPEWnd )
  1335.                   {
  1336.                     GT_SetGadgetAttrs( DTConvert_DATATYPEGadgets[ GD_DATATYPEDT ], DTConvert_DATATYPEWnd, NULL, GTLV_Labels, dtl, TAG_DONE );
  1337.                   }
  1338.  
  1339.                   FreeDTDescrList( old_dtl );
  1340.                 }
  1341.  
  1342.                 GT_GetGadgetAttrs( DTConvert_MAINGadgets[ GD_DESTINATION ], DTConvert_MAINWnd, NULL,
  1343.                                    GTST_String, (&destname),
  1344.                                    TAG_DONE );
  1345.  
  1346.                 convertable = Strlen( srcname ) && selecteddt && Strlen( destname );
  1347.  
  1348.                 GT_SetGadgetAttrs( DTConvert_MAINGadgets[ GD_CONVERT ], DTConvert_MAINWnd, NULL,
  1349.                                    GA_Disabled, (!convertable),
  1350.                                    TAG_DONE );
  1351.  
  1352. /* run converter ? */
  1353.                 if( convert )
  1354.                 {
  1355.                   if( convertable )
  1356.                   {
  1357.                     LockGUI();
  1358.  
  1359.                       Message( "converting '%s' '%s' '%s'\n", srcname, (selecteddt -> dtn_DTName), destname );
  1360.  
  1361.                       Convert( srcname, (selecteddt -> dtn_DTName), FALSE, destname );
  1362.  
  1363.                     UnlockGUI();
  1364.                   }
  1365.  
  1366.                   convert = FALSE;
  1367.                 }
  1368.               }
  1369.  
  1370.               /**********
  1371.                * Done ! *
  1372.                **********/
  1373.               if( appwindow )
  1374.               {
  1375.                 (void)RemoveAppWindow( appwindow );
  1376.               }
  1377.  
  1378.               if( appdobj )
  1379.               {
  1380.                 FreeDiskObject( appdobj );
  1381.               }
  1382.  
  1383.               if( appicon )
  1384.               {
  1385.                 (void)RemoveAppIcon( appicon );
  1386.               }
  1387.  
  1388.               CloseDTConvert_DATATYPEWindow();
  1389.               CloseDTConvert_MAINWindow();
  1390.             }
  1391.  
  1392.             FreeAslRequest( SrcFileReq );
  1393.             FreeAslRequest( DestFileReq );
  1394.  
  1395.             CloseDownScreen();
  1396.           }
  1397.  
  1398.           FreeDTDescrList( dtl );
  1399.         }
  1400.  
  1401.         if( srclock )
  1402.         {
  1403.           UnLock( srclock );
  1404.         }
  1405.  
  1406.         ClearMsgPort( appport );
  1407.         DeleteMsgPort( appport );
  1408.       }
  1409.     }
  1410.     else
  1411.     {
  1412.       Convert( srcname, datatypename, (project . iff), destname );
  1413.     }
  1414.  
  1415.     if( IoErr() )
  1416.     {
  1417.       main_retval2 = IoErr();
  1418.       main_retval  = RETURN_ERROR;
  1419.     }
  1420. }
  1421.  
  1422.  
  1423. static
  1424. BOOL NewProject( STRPTR from, STRPTR datatype, BOOL iff, STRPTR destname, BOOL gui, STRPTR pubscreen )
  1425. {
  1426.     struct Process              *ThisProc = (struct Process *)FindTask( NULL );
  1427.     BPTR                         olddir    = CurrentDir( (ThisProc -> pr_HomeDir) );
  1428.     BOOL                         success  = FALSE;
  1429.     STRPTR                       buffer;
  1430.     ULONG                        buffersize;
  1431.     struct CommandLineInterface *cli = Cli();
  1432.  
  1433.     if( from = GetLockName( olddir, from ) )
  1434.     {
  1435.       buffersize = Strlen( from ) + Strlen( datatype ) + Strlen( destname ) + Strlen( pubscreen ) + 512UL;
  1436.  
  1437.       if( buffer = (STRPTR)AllocVec( buffersize, MEMF_PUBLIC ) )
  1438.       {
  1439.         STRPTR next = buffer;
  1440.  
  1441.         if( cli )
  1442.         {
  1443.           STRPTR s = (STRPTR)BADDR( (cli -> cli_CommandName) );
  1444.  
  1445.           stccpy( next, (&s[ 1 ]), (int)(s[ 0 ] + 1U) );
  1446.         }
  1447.         else
  1448.         {
  1449.           strcpy( next, (ThisProc -> pr_Task . tc_Node . ln_Name) );
  1450.         }
  1451.  
  1452.         next += strlen( next );
  1453.  
  1454.         if( Strlen( from ) )
  1455.         {
  1456.           mysprintf( next, " FROM=\"%s\"", from );
  1457.           next += strlen( next );
  1458.         }
  1459.  
  1460.         if( Strlen( datatype ) )
  1461.         {
  1462.           mysprintf( next, " DATATYPE=\"%s\"", datatype );
  1463.           next += strlen( next );
  1464.         }
  1465.  
  1466.         if( iff )
  1467.         {
  1468.           mysprintf( next, " IFF" );
  1469.           next += strlen( next );
  1470.         }
  1471.  
  1472.         if( Strlen( destname ) )
  1473.         {
  1474.           mysprintf( next, " TO=\"%s\"", destname );
  1475.           next += strlen( next );
  1476.         }
  1477.  
  1478.         if( gui )
  1479.         {
  1480.           mysprintf( next, " GUI" );
  1481.           next += strlen( next );
  1482.         }
  1483.  
  1484.         if( Strlen( pubscreen ) )
  1485.         {
  1486.           mysprintf( next, " PUBSCREEN=\"%s\"", pubscreen );
  1487.         }
  1488.  
  1489.         if( SystemTags( buffer,
  1490.                         SYS_Input,     Open( "CON:////" NAME "/auto/wait/close", MODE_READWRITE ),
  1491.                         SYS_Asynch,    TRUE,
  1492.                         TAG_DONE ) != (-1L) )
  1493.         {
  1494.           success = TRUE;
  1495.         }
  1496.  
  1497.         FreeVec( buffer );
  1498.       }
  1499.       
  1500.       FreeVec( from );
  1501.     }
  1502.  
  1503.     (void)CurrentDir( olddir );
  1504.  
  1505.     return( success );
  1506. }
  1507.  
  1508.  
  1509. /* GUI locking stuff */
  1510. static ULONG            GUILock                = 0UL;
  1511. static struct Requester MAINBlockReq           = { 0 };
  1512. static BOOL             MAINBlockReqActive     = FALSE;
  1513. static struct Requester DATATYPEBlockReq       = { 0 };
  1514. static BOOL             DATATYPEBlockReqActive = FALSE;
  1515.  
  1516.  
  1517. static
  1518. void LockGUI( void )
  1519. {
  1520.     if( GUILock++ == 0UL )
  1521.     {
  1522.       InitRequester( (&MAINBlockReq) );
  1523.       InitRequester( (&DATATYPEBlockReq) );
  1524.  
  1525.       if( DTConvert_MAINWnd )
  1526.       {
  1527.         SetWindowPointer( DTConvert_MAINWnd, WA_BusyPointer, TRUE, WA_PointerDelay, TRUE, TAG_DONE );
  1528.  
  1529.         if( MAINBlockReqActive == FALSE )
  1530.         {
  1531.           MAINBlockReqActive = Request( (&MAINBlockReq), DTConvert_MAINWnd );
  1532.         }
  1533.       }
  1534.  
  1535.       if( DTConvert_DATATYPEWnd )
  1536.       {
  1537.         SetWindowPointer( DTConvert_DATATYPEWnd, WA_BusyPointer, TRUE,  WA_PointerDelay, TRUE, TAG_DONE );
  1538.  
  1539.         if( DATATYPEBlockReqActive == FALSE )
  1540.         {
  1541.           DATATYPEBlockReqActive = Request( (&DATATYPEBlockReq), DTConvert_DATATYPEWnd );
  1542.         }
  1543.       }
  1544.     }
  1545. }
  1546.  
  1547.  
  1548. static
  1549. void UnlockGUI( void )
  1550. {
  1551.     if( --GUILock == 0UL )
  1552.     {
  1553.       if( DTConvert_MAINWnd )
  1554.       {
  1555.         SetWindowPointer( DTConvert_MAINWnd, WA_BusyPointer, FALSE, TAG_DONE );
  1556.  
  1557.         if( MAINBlockReqActive )
  1558.         {
  1559.           EndRequest( (&MAINBlockReq), DTConvert_MAINWnd );
  1560.           MAINBlockReqActive = FALSE;
  1561.         }
  1562.       }
  1563.  
  1564.       if( DTConvert_DATATYPEWnd )
  1565.       {
  1566.         SetWindowPointer( DTConvert_DATATYPEWnd, WA_BusyPointer, FALSE, TAG_DONE );
  1567.  
  1568.         if( DATATYPEBlockReqActive )
  1569.         {
  1570.           EndRequest( (&DATATYPEBlockReq), DTConvert_DATATYPEWnd );
  1571.           DATATYPEBlockReqActive = FALSE;
  1572.         }
  1573.       }
  1574.     }
  1575. }
  1576.  
  1577.  
  1578. void Message( STRPTR fmt, ... )
  1579. {
  1580.     VPrintf( fmt, (APTR)((&fmt) + 1) );
  1581. }
  1582.  
  1583.  
  1584. static
  1585. struct DTList *CreateDTDescrList( BPTR lock, ULONG groupid )
  1586. {
  1587.     APTR  pool;
  1588. #define NUM_GID_TABLE (32) /* we have much less GID_#? types defined yet (datatypes.library V45), but... */
  1589.     ULONG groupid_table[ NUM_GID_TABLE ] = { 0 };
  1590.  
  1591.     /* If a lock is given, we build here a list of all DT group ids the source file may be of... */
  1592.     if( lock )
  1593.     {
  1594.       struct DataType *dtn,
  1595.                       *prevdtn = NULL;
  1596.  
  1597.       /* Print whole list or determine the DataType of the file */
  1598.       while( dtn = ObtainDataType( DTST_FILE, (APTR)lock, DTA_DataType,                  prevdtn,
  1599.                                                           XTAG( groupid, DTA_GroupID ),  groupid,
  1600.                                                           TAG_DONE ) )
  1601.       {
  1602.         ULONG i,
  1603.               groupid = dtn -> dtn_Header -> dth_GroupID;
  1604.  
  1605.         /* Release previous DataType */
  1606.         ReleaseDataType( prevdtn );
  1607.  
  1608.         /* the follwoing statement assmes that GID_SYSTEM datatypes are not convertable
  1609.          * (and it filters some invalid datatypes which have a 0 group id)
  1610.          */
  1611.         if( (groupid != GID_SYSTEM) && (groupid != 0UL) )
  1612.         {
  1613.           for( i = 0UL ; i < NUM_GID_TABLE ; i++ )
  1614.           {
  1615.             if( !groupid_table[ i ] )
  1616.             {
  1617.               groupid_table[ i ] = groupid;
  1618.               break;
  1619.             }
  1620.           }
  1621.         }
  1622.  
  1623.         prevdtn = dtn;
  1624.       }
  1625.  
  1626.       /* Release last datatype */
  1627.       ReleaseDataType( prevdtn );
  1628.     }
  1629.  
  1630.     if( pool = CreatePool( (MEMF_PUBLIC | MEMF_CLEAR), 1024UL, 1024UL ) )
  1631.     {
  1632.       struct DTList *dtl;
  1633.  
  1634.       if( dtl = (struct DTList *)AllocVecPooled( pool, sizeof( struct DTList ) ) )
  1635.       {
  1636.         struct DataType *dtn,
  1637.                         *prevdtn = NULL;
  1638.         BOOL             error   = FALSE;
  1639.  
  1640.         NewList( (&(dtl -> dtl_List)) );
  1641.         dtl -> dtl_Pool = pool;
  1642.  
  1643.         /* Print whole list or determine the DataType of the file */
  1644.         while( dtn = ObtainDataType( DTST_RAM, NULL, DTA_DataType,                  prevdtn,
  1645.                                                      XTAG( groupid, DTA_GroupID ),  groupid,
  1646.                                                      TAG_DONE ) )
  1647.         {
  1648.           struct DataTypeHeader *dth;          /* datatypes header        */
  1649.           BOOL                   match = TRUE; /* include this datatype ? */
  1650.  
  1651.           /* Release previous DataType */
  1652.           ReleaseDataType( prevdtn );
  1653.  
  1654.           dth = dtn -> dtn_Header; /* Shortcut... */
  1655.  
  1656.           /* If we have a lock given, we previously build a group id table... */
  1657.           if( lock )
  1658.           {
  1659.             ULONG i;
  1660.  
  1661.             match = FALSE;
  1662.  
  1663.             /* ... now check if this datatype node matches any source groupid */
  1664.             for( i = 0UL ; ((i < NUM_GID_TABLE) && groupid_table[ i ]) ; i++ )
  1665.             {
  1666.               /* Match ? */
  1667.               if( groupid_table[ i ] == (dth -> dth_GroupID) )
  1668.               {
  1669.                 match = TRUE;
  1670.                 break;
  1671.               }
  1672.  
  1673.               /* Special kluge that we can convert GID_ANIMATION to GID_MOVIE and backwards
  1674.                * (both are based on animation.datatype, here we have the same interface :-)
  1675.                */
  1676.               if( ((groupid_table[ i ]   == GID_MOVIE) || (groupid_table[ i ]   == GID_ANIMATION)) &&
  1677.                   (((dth -> dth_GroupID) == GID_MOVIE) || ((dth -> dth_GroupID) == GID_ANIMATION)) )
  1678.               {
  1679.                 match = TRUE;
  1680.                 break;
  1681.               }
  1682.             }
  1683.           }
  1684.  
  1685.           /* Include this datatype ? */
  1686.           if( match )
  1687.           {
  1688.             STRPTR         groupid_name; /* short-cut to GID_#? name string    */
  1689.             ULONG          size;         /* size of struct DTNode and contents */
  1690.             struct DTNode *namenode;
  1691.  
  1692.             groupid_name = GetDTString( (dth -> dth_GroupID) );
  1693.  
  1694.             size = sizeof( struct DTNode ) + (strlen( (dth -> dth_Name) ) * 2UL) + Strlen( groupid_name ) + 16UL;
  1695.  
  1696.             /* Alloc and build node... */
  1697.             if( namenode = (struct DTNode *)AllocVecPooled( pool, size ) )
  1698.             {
  1699.               STRPTR s = (STRPTR)(namenode + 1);
  1700.  
  1701.               /* store listview names */
  1702.               mysprintf( s, "%s %s", (dth -> dth_Name), groupid_name );
  1703.               namenode -> dtn_Node . ln_Name = s;
  1704.  
  1705.               s = s + strlen( s ) + 2; /* next free space */
  1706.  
  1707.               /* store datatype name */
  1708.               strcpy( s, (dth -> dth_Name) );
  1709.               namenode -> dtn_DTName = s;
  1710.  
  1711.               /* add node */
  1712.               AddTail( (&(dtl -> dtl_List)), (&(namenode -> dtn_Node)) );
  1713.               dtl -> dtl_NumNodes++;
  1714.             }
  1715.             else
  1716.             {
  1717.               error = TRUE;
  1718.             }
  1719.           }
  1720.  
  1721.           prevdtn = dtn;
  1722.         }
  1723.  
  1724.         /* Release last datatype */
  1725.         ReleaseDataType( prevdtn );
  1726.  
  1727.         /* Success ? */
  1728.         if( !error )
  1729.         {
  1730.           return( dtl );
  1731.         }
  1732.       }
  1733.  
  1734.       DeletePool( pool );
  1735.     }
  1736.  
  1737.     return( NULL );
  1738. }
  1739.  
  1740.  
  1741. static
  1742. void FreeDTDescrList( struct DTList *list )
  1743. {
  1744.    if( list )
  1745.    {
  1746.      DeletePool( (list -> dtl_Pool) );
  1747.    }
  1748. }
  1749.  
  1750.  
  1751. static
  1752. struct DTNode *FindDTNodeByName( struct DTList *list, STRPTR name )
  1753. {
  1754.     struct DTNode *node;
  1755.     struct DTNode *result = NULL;
  1756.  
  1757.     if( list && name )
  1758.     {
  1759.       for( node = (struct DTNode *)(list -> dtl_List . lh_Head) ; node -> dtn_Node . ln_Succ ; node = (struct DTNode *)(node -> dtn_Node . ln_Succ) )
  1760.       {
  1761.         if( !Stricmp( (node -> dtn_DTName), name ) )
  1762.         {
  1763.           result = node;
  1764.           break;
  1765.         }
  1766.       }
  1767.     }
  1768.  
  1769.     return( result );
  1770. }
  1771.  
  1772.  
  1773. static
  1774. STRPTR StringSave( STRPTR s )
  1775. {
  1776.     STRPTR saved;
  1777.  
  1778.     if( s )
  1779.     {
  1780.       if( saved = AllocStringBuff( (ULONG)strlen( s ) ) )
  1781.       {
  1782.         strcpy( saved, s );
  1783.  
  1784.         return( saved );
  1785.       }
  1786.     }
  1787.  
  1788.     return( NULL );
  1789. }
  1790.  
  1791.  
  1792. static
  1793. STRPTR AllocStringBuff( ULONG size )
  1794. {
  1795.     return( (STRPTR)AllocVecPooled( StringPool, (size + 2UL) ) );
  1796. }
  1797.  
  1798.  
  1799. static
  1800. STRPTR UpdateString( STRPTR *storage, STRPTR newstring )
  1801. {
  1802.     STRPTR s;
  1803.  
  1804.     s = NULL;
  1805.  
  1806.     if( storage )
  1807.     {
  1808.       FreeString( (*storage) );
  1809.  
  1810.       s = (*storage) = StringSave( newstring );
  1811.     }
  1812.  
  1813.     return( s );
  1814. }
  1815.  
  1816.  
  1817. static
  1818. void FreeString( STRPTR s )
  1819. {
  1820.     if( s )
  1821.     {
  1822.       FreeVecPooled( StringPool, s );
  1823.     }
  1824. }
  1825.  
  1826.  
  1827. static
  1828. struct DiskObject *GetToolDiskObject( STRPTR name )
  1829. {
  1830.     struct DiskObject *dobj;
  1831.     struct Process    *ThisProc = (struct Process *)FindTask( NULL );
  1832.     BPTR               olddir   = CurrentDir( (ThisProc -> pr_HomeDir) );
  1833.  
  1834.     dobj = GetDiskObjectNew( name );
  1835.  
  1836.     (void)CurrentDir( olddir );
  1837.  
  1838.     return( dobj );
  1839. }
  1840.  
  1841.  
  1842. static
  1843. ULONG SumString( STRPTR s )
  1844. {
  1845.     ULONG sum = 0UL;
  1846.  
  1847.     if( s )
  1848.     {
  1849.       ULONG ch;
  1850.  
  1851.       while( ch = *s++ )
  1852.       {
  1853.         sum = (sum * 7UL) + ch;
  1854.       }
  1855.     }
  1856.  
  1857.     return( sum );
  1858. }
  1859.  
  1860.