home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / Triton / Source / src / triton.c < prev   
C/C++ Source or Header  |  1998-05-23  |  131KB  |  4,062 lines

  1. /*
  2.  *  OpenTriton -- A free release of the triton.library source code
  3.  *  Copyright (C) 1993-1998  Stefan Zeiger
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  triton.c - Shared library source
  20.  *
  21.  */
  22.  
  23.  
  24. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  25. //////////////////////////////////////////////////////////////////////////////////////// Include our stuff //
  26. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27.  
  28. #define INTUI_V36_NAMES_ONLY
  29. #define TR_NOSUPPORT
  30. #define TR_THIS_IS_TRITON
  31. #define TR_THIS_IS_REALLY_TRITON
  32.  
  33. #include <exec/exec.h>
  34. #include <intuition/intuition.h>
  35. #include <intuition/gadgetclass.h>
  36. #include <intuition/imageclass.h>
  37. #include <graphics/gfx.h>
  38. #include <graphics/gfxbase.h>
  39. #include <graphics/gfxmacros.h>
  40. #include <libraries/gadtools.h>
  41. #include <libraries/diskfont.h>
  42. #include <devices/keymap.h>
  43. #include <devices/inputevent.h>
  44.  
  45. #include <clib/exec_protos.h>
  46. #include <clib/dos_protos.h>
  47. #include <clib/keymap_protos.h>
  48. #include <clib/wb_protos.h>
  49. #include <clib/alib_protos.h>
  50. #include <pragmas/exec_pragmas.h>
  51. #include <pragmas/dos_pragmas.h>
  52. #include <pragmas/keymap_pragmas.h>
  53. #include <pragmas/wb_pragmas.h>
  54.  
  55. #include <stdlib.h>
  56. #include <ctype.h>
  57.  
  58. #include "include/libraries/triton.h"
  59. #include "include/clib/triton_protos.h"
  60. #include "prefs/Triton.h"
  61. #include "/internal.h"
  62.  
  63. #include "parts/define_classes.h"
  64.  
  65.  
  66. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. ////////////////////////////////////////////////////////////////////////////////////////////////// Version //
  68. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69.  
  70. const UBYTE versionstring[]="\0$VER: triton.library " SVERSION "." SREVISION " " __AMIGADATE__;
  71. const UBYTE cooper[]="/THE/OWLS/ARE/NOT/WHAT/THEY/SEEM/";
  72.  
  73.  
  74. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. //////////////////////////////////////////////////////////////////////////////////////////// Library bases //
  76. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  77.  
  78. struct IntuitionBase *IntuitionBase;
  79. struct GfxBase *GfxBase;
  80. struct Library *GadToolsBase;
  81. struct Library *UtilityBase;
  82. struct Library *DiskfontBase;
  83. struct Library *KeymapBase;
  84. struct Library *SysBase;
  85. struct Library *DOSBase;
  86. struct Library *WorkbenchBase;
  87. struct Library *LocaleBase;
  88.  
  89.  
  90. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  91. /////////////////////////////////////////////////////////////////////////////////////////// Locale support //
  92. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93.  
  94. #define CATCOMP_NUMBERS
  95. #define LOCSTR(num) GetString(&li,num)
  96. #include <libraries/locale.h>
  97. #include <proto/locale.h>
  98. #include "catalogs/triton.h"
  99. struct LocaleInfo li;
  100.  
  101.  
  102. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. ////////////////////////////////////////////////////////////////// Amiga.lib, sc.lib replacement functions //
  104. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  105.  
  106. VOID GT_SetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, ULONG tags,...)
  107. {
  108.   GT_SetGadgetAttrsA(g,w,r,(struct TagItem *)&tags);
  109. }
  110.  
  111. LONG GT_GetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, ULONG tags,...)
  112. {
  113.   return GT_GetGadgetAttrsA(g,w,r,(struct TagItem *)&tags);
  114. }
  115.  
  116. struct Menu * __inline CreateMenus(struct NewMenu *n, ULONG tags,...)
  117. {
  118.   return CreateMenusA(n,(struct TagItem *)&tags);
  119. }
  120.  
  121. BOOL __inline LayoutMenus(struct Menu *m, APTR v, ULONG tags,...)
  122. {
  123.   return LayoutMenusA(m,v,(struct TagItem *)&tags);
  124. }
  125.  
  126. VOID __inline SetWindowPointer(struct Window *w, ULONG tags,...)
  127. {
  128.   SetWindowPointerA(w,(struct TagItem *)&tags);
  129. }
  130.  
  131. APTR NewObject(struct IClass *i, UBYTE *c, ULONG tags,...)
  132. {
  133.   return NewObjectA(i,c,(struct TagItem *)&tags);
  134. }
  135.  
  136. struct Screen * __inline OpenScreenTags(struct NewScreen *ns, ULONG tags,...)
  137. {
  138.   return OpenScreenTagList(ns,(struct TagItem *)&tags);
  139. }
  140.  
  141.  
  142. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  143. //////////////////////////////////////////////////////////// Pool support for all system software versions //
  144. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  145.  
  146. #ifdef TR_OS39
  147.  
  148. #define TR_CreatePool(a,b,c)  CreatePool(a,b,c)
  149. #define TR_DeletePool(a)      DeletePool(a)
  150. #define TR_AllocPooled(a,b)   AllocPooled(a,b)
  151. #define TR_FreePooled(a,b,c)  FreePooled(a,b,c)
  152.  
  153. #else
  154.  
  155. struct TR_MemPoolList
  156. {
  157.   struct MinList list;
  158.   ULONG flags;
  159. };
  160.  
  161. struct TR_MemPoolNode
  162. {
  163.   struct Node node;
  164.   ULONG size;
  165.   void *memory;
  166. };
  167.  
  168. void *TR_CreatePool(ULONG memFlags, ULONG puddleSize, ULONG threshSize)
  169. {
  170.   struct TR_MemPoolList *list;
  171.  
  172.   /* Use Exec pool functions on v39+ */
  173.   if(SysBase->lib_Version>=39) return CreatePool(memFlags,puddleSize,threshSize);
  174.  
  175.   if(!(list=(struct TR_MemPoolList *)AllocMem(sizeof(struct TR_MemPoolList),MEMF_ANY|MEMF_CLEAR)))
  176.     return NULL;
  177.   NewList((struct List *)list);
  178.   list->flags=memFlags;
  179.   return (void *)list;
  180. }
  181.  
  182. void TR_DeletePool(void *poolHeader)
  183. {
  184.   struct TR_MemPoolNode *worknode,*nextnode;
  185.  
  186.   /* Use Exec pool functions on v39+ */
  187.   if(SysBase->lib_Version>=39) {DeletePool(poolHeader); return;}
  188.  
  189.   /* Free all entries */
  190.   worknode=(struct TR_MemPoolNode *)(((struct List *)poolHeader)->lh_Head);
  191.   while(nextnode=(struct TR_MemPoolNode *)(worknode->node.ln_Succ))
  192.   {
  193.     FreeMem((APTR)worknode,(ULONG)(worknode->size)+(ULONG)(sizeof(struct TR_MemPoolNode)));
  194.     worknode=nextnode;
  195.   }
  196.  
  197.   /* Free list header */
  198.   FreeMem(poolHeader,sizeof(struct TR_MemPoolList));
  199. }
  200.  
  201. void *TR_AllocPooled(void *poolHeader, ULONG memSize)
  202. {
  203.   struct TR_MemPoolList *list;
  204.   struct TR_MemPoolNode *node;
  205.  
  206.   /* Use Exec pool functions on v39+ */
  207.   if(SysBase->lib_Version>=39) return AllocPooled(poolHeader,memSize);
  208.  
  209.   list=(struct TR_MemPoolList *)poolHeader;
  210.   if(!(node=(struct TR_MemPoolNode *)AllocMem(sizeof(struct TR_MemPoolNode)+memSize,list->flags)))
  211.     return NULL;
  212.   node->memory=(void *)((ULONG)node+(ULONG)sizeof(struct TR_MemPoolNode));
  213.   node->size=memSize;
  214.   AddTail((struct List *)list,(struct Node *)node);
  215.   return node->memory;
  216. }
  217.  
  218. void TR_FreePooled(void *poolHeader, void *memory, ULONG memSize)
  219. {
  220.   struct TR_MemPoolNode *node;
  221.  
  222.   /* Use Exec pool functions on v39+ */
  223.   if(SysBase->lib_Version>=39) {FreePooled(poolHeader,memory,memSize); return;}
  224.  
  225.   node=(struct TR_MemPoolNode *)((ULONG)(memory)-(ULONG)(sizeof(struct TR_MemPoolNode)));
  226.   Remove((struct TR_MemPoolNode *)node);
  227.   FreeMem((APTR)node,sizeof(struct TR_MemPoolNode)+memSize);
  228. }
  229.  
  230. #endif
  231.  
  232.  
  233. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  234. ///////////////////////////////////////////////////////////////////////////////////////// Global variables //
  235. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  236.  
  237. struct TR_Global TR_Global;
  238. struct TextAttr topaz8attr={"topaz.font",8,NULL,FPF_ROMFONT};
  239.  
  240.  
  241. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  242. //////////////////////////////////////////////////////////////////////////////////// The ID list structure //
  243. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  244.  
  245. struct TR_IDNode
  246. {
  247.   struct MinNode        tri_Node;
  248.   ULONG                 tri_ID;
  249.   struct TROD_Object *  tri_Object;
  250. };
  251.  
  252.  
  253. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  254. ///////////////////////////////////////////////////////////////////// Prototypes for our private functions //
  255. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  256.  
  257. ULONG             __regargs TR_CreateMenus(struct TR_Project *project, struct TagItem *tags, ULONG items);
  258. VOID              __regargs TR_DoBackfill(struct TR_Project *project);
  259.  
  260. VOID              __regargs TR_RefreshProject(struct TR_Project *project);
  261.  
  262. VOID              __regargs TR_GetWindowDimensions(struct TR_Project *project);
  263. BYTE              __regargs TR_StrCmp(STRPTR s1,STRPTR s2);
  264.  
  265. VOID              __regargs TR_LockWindow(struct TR_Project *project);
  266. VOID              __regargs TR_UnlockWindow(struct TR_Project *project);
  267.  
  268. VOID              __regargs TR_DisposeClasses(struct MinList *list);
  269.  
  270. VOID              __regargs TR_SaveAppInfos(struct TR_App *app);
  271. VOID              __regargs TR_LoadTritonPrefs(struct TR_App *app);
  272. VOID              __regargs TR_SaveWindowDimensions(struct TR_Project *project);
  273. VOID              __regargs TR_LoadWindowDimensions(struct TR_Project *project);
  274.  
  275. struct Screen *   __regargs TR_OpenScreen(struct TR_ScreenNode *sn);
  276. struct Screen *   __regargs TR_LockPubScreen(STRPTR name);
  277. BOOL              __regargs TR_CloseScreen(struct TR_ScreenNode *sn);
  278. VOID              __regargs TR_RemoveScreens(VOID);
  279. VOID              __regargs TR_UnlockPubScreen(struct Screen *scr);
  280.  
  281.  
  282. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  283. //////////////////////////////////////////////////////////////////////////////////////// The backfill hook //
  284. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  285.  
  286. /****** triton.library/TR_AreaFill ******
  287. *
  288. *   NAME    
  289. *    TR_AreaFill -- Draw a background pattern
  290. *
  291. *   SYNOPSIS
  292. *    TR_AreaFill(Project, RastPort, Left, Top, Right, Bottom,
  293. *                A0       A1        D0    D1   D2     D3
  294. *                Type, Dummy)
  295. *                D4    A2
  296. *
  297. *    VOID TR_AreaFill(struct TR_Project *, struct RastPort *,
  298. *                     ULONG, ULONG, ULONG, ULONG, ULONG, VOID *);
  299. *
  300. *   FUNCTION
  301. *    Fill an area with one of Triton's default backfill patterns.
  302. *    The "Type" argument is a code from the TR_Images enumeration.
  303. *    "Dummy" is currently unused and should be set to NULL. If
  304. *    the RastPort is not specified (NULL) the project's default
  305. *    RastPort will be used.
  306. *
  307. ******/
  308.  
  309. struct BackFillPacket
  310. {
  311.   struct Layer *                layer;
  312.   struct Rectangle              bounds;
  313.   WORD                          offsetx;
  314.   WORD                          offsety;
  315. };
  316.  
  317.  
  318. VOID __regargs TR_InternalAreaFill(struct TR_Project *project, struct RastPort *rp, ULONG left, ULONG top, ULONG right, ULONG bottom, ULONG type)
  319. {
  320.   ULONG frontpen,backpen,bftype;
  321.   static UWORD TR_Planepattern[]={0x5555,0xAAAA};
  322.   static const struct TR_PenArray {ULONG pen,paper;} penarray[]=
  323.   {
  324.     BACKGROUNDPEN,  BACKGROUNDPEN,
  325.     SHINEPEN,       SHINEPEN,
  326.     SHINEPEN,       SHADOWPEN,
  327.     SHINEPEN,       FILLPEN,
  328.     SHINEPEN,       BACKGROUNDPEN,
  329.     SHADOWPEN,      SHADOWPEN,
  330.     SHADOWPEN,      FILLPEN,
  331.     SHADOWPEN,      BACKGROUNDPEN,
  332.     FILLPEN,        FILLPEN,
  333.     FILLPEN,        BACKGROUNDPEN
  334.   };
  335.  
  336.   if(!rp) rp=project->trp_Window->RPort;
  337.  
  338.   if((type<=1)||(type>100))
  339.     {
  340.       if(type>100) type=(type&(~0x00010000));
  341.  
  342.       if(((struct TR_AppPrefs *)(project->trp_App->tra_Prefs))->imgtype[type]==TRIT_BFPATTERN)
  343.     {
  344.       bftype=((struct TR_AppPrefs *)(project->trp_App->tra_Prefs))->imgdata[type]-2;
  345.       backpen=project->trp_DrawInfo->dri_Pens[((penarray[bftype]).paper)];
  346.       frontpen=project->trp_DrawInfo->dri_Pens[((penarray[bftype]).pen)];
  347.     }
  348.       /*-- else... add more image types here */
  349.     }
  350.   else
  351.     {
  352.       frontpen=project->trp_DrawInfo->dri_Pens[((penarray[type-2]).pen)];
  353.       backpen=project->trp_DrawInfo->dri_Pens[((penarray[type-2]).paper)];
  354.     }
  355.  
  356.   SetDrMd(rp,JAM2);
  357.   SetAPen(rp,frontpen);
  358.   SetBPen(rp,backpen);
  359.   SetAfPt(rp,TR_Planepattern,1);
  360.   RectFill(rp,left,top,right,bottom);
  361.   SetAfPt(rp,NULL,-1);
  362. }
  363.  
  364. VOID __saveds __asm TR_AreaFill(register __a0 struct TR_Project *project, register __a1 struct RastPort *rp,
  365.                 register __d0 ULONG left, register __d1 ULONG top, register __d2 ULONG right,
  366.                 register __d3 ULONG bottom, register __d4 ULONG type,
  367.                 register __a2 VOID *dummy)
  368. {
  369.   TR_InternalAreaFill(project,rp,left,top,right,bottom,type);
  370. }
  371.  
  372. ULONG __saveds __asm TR_BackfillFunc(register __a0 struct Hook *hook,register __a2 struct RastPort *rp,
  373.                      register __a1 struct BackFillPacket *bfp)
  374. {
  375.   struct TR_Project *project=(struct TR_Project *)(hook->h_Data);
  376.  
  377.   if(!(((bfp->bounds.MinX)>(bfp->bounds.MaxX))||((bfp->bounds.MinY)>(bfp->bounds.MaxY))))
  378.     TR_InternalAreaFill(project,NULL, bfp->bounds.MinX, bfp->bounds.MinY, bfp->bounds.MaxX, bfp->bounds.MaxY,
  379.             project->trp_BackfillType);
  380.   return NULL;
  381. }
  382.  
  383.  
  384. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  385. ///////////////////////////////////////////////////////////////////////// Open and close the global things //
  386. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  387.  
  388. int __saveds __asm __UserLibInit(VOID);
  389. VOID __saveds __UserLibCleanup(VOID);
  390.  
  391.  
  392. int __saveds __asm __UserLibInit(VOID)
  393. {
  394.   ULONG ch1,ch2;
  395.  
  396.   SysBase=*((void **)4);
  397. #ifndef TR_OS39
  398.   if((((struct Library *)(SysBase))->lib_Version)<37) return 1;
  399. #endif
  400.  
  401. #ifdef TR_OS39
  402.   /*-- Let's hope the compiler didn't generate an 68020+ instruction upto this point ;-) */
  403.   if(!((((struct ExecBase *)(SysBase))->AttnFlags)&AFF_68020)) return 1;
  404.   if((((struct Library *)(SysBase))->lib_Version)<39) return 1;
  405. #endif
  406.  
  407.   NewList((struct List *)&(TR_Global.trg_ClassList));
  408.   NewList((struct List *)&(TR_Global.trg_ScreenList));
  409.  
  410.   if(!(DOSBase=OpenLibrary("dos.library",37L))) goto failed;
  411.   if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))) goto failed;
  412.   if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))) goto failed;
  413.   if(!(GadToolsBase=OpenLibrary("gadtools.library",37L))) goto failed;
  414.   if(!(UtilityBase=OpenLibrary("utility.library",37L))) goto failed;
  415.   if(!(DiskfontBase=OpenLibrary("diskfont.library",36L))) goto failed;
  416.   if(!(KeymapBase=OpenLibrary("keymap.library",37L))) goto failed;
  417.   if(!(WorkbenchBase=OpenLibrary("workbench.library",37L))) goto failed;
  418.  
  419.   if(LocaleBase=OpenLibrary("locale.library",38L))
  420.     {
  421.       li.li_LocaleBase=LocaleBase;
  422.       li.li_Catalog=OpenCatalogA(NULL,"triton.catalog",NULL);
  423.     }
  424.  
  425.   if(!(TR_Global.trg_ClassListPool=
  426.        TR_CreatePool(MEMF_ANY|MEMF_CLEAR,20*sizeof(struct TR_Class),sizeof(struct TR_Class)+1))) goto failed;
  427.   if(!(TR_Global.trg_ScreenListPool=
  428.        TR_CreatePool(MEMF_ANY,4*sizeof(struct TR_ScreenNode),sizeof(struct TR_ScreenNode)))) goto failed;
  429.  
  430.   TR_Global.trg_OSVersion=((struct Library *)(IntuitionBase))->lib_Version;
  431.  
  432. #include "parts/install_classes.h"
  433.  
  434.   if(!(TR_AddClass(NULL,TRMN_Title,TROB_Object,NULL,0,TAG_END))) goto failed;
  435.   if(!(TR_AddClass(NULL,TRMN_Item,TROB_Object,NULL,0,TAG_END))) goto failed;
  436.   if(!(TR_AddClass(NULL,TRMN_Sub,TROB_Object,NULL,0,TAG_END))) goto failed;
  437.  
  438.   return 0;
  439.  
  440. failed:
  441.   __UserLibCleanup();
  442.   return 1;
  443. }
  444.  
  445.  
  446. VOID __saveds __UserLibCleanup(VOID)
  447. {
  448.   TR_RemoveScreens();
  449.   TR_DisposeClasses(&(TR_Global.trg_ClassList));
  450.   if(TR_Global.trg_ClassListPool) TR_DeletePool(TR_Global.trg_ClassListPool);
  451.   if(LocaleBase)
  452.     {
  453.       CloseCatalog(li.li_Catalog);
  454.       CloseLibrary(LocaleBase);
  455.     }
  456.   CloseLibrary(WorkbenchBase);
  457.   CloseLibrary(KeymapBase);
  458.   CloseLibrary(DiskfontBase);
  459.   CloseLibrary(UtilityBase);
  460.   CloseLibrary(GadToolsBase);
  461.   CloseLibrary((struct Library *)GfxBase);
  462.   CloseLibrary((struct Library *)IntuitionBase);
  463. }
  464.  
  465.  
  466. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  467. ////////////////////////////////////////////////////////////////////////// Open and close a window/project //
  468. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  469.  
  470. /****** triton.library/TR_CloseProject ******
  471. *
  472. *   NAME    
  473. *    TR_CloseProject -- Closes a project/window.
  474. *
  475. *   SYNOPSIS
  476. *    TR_CloseProject(Project)
  477. *                    A0
  478. *
  479. *    VOID TR_CloseProject(struct TR_Project *);
  480. *
  481. *   FUNCTION
  482. *    Closes a Triton project.
  483. *
  484. *   SEE ALSO
  485. *    TR_OpenProject()
  486. *
  487. ******/
  488.  
  489. VOID __saveds __asm TR_CloseProject(register __a0 struct TR_Project *project)
  490. {
  491.   if(!project) return;
  492.  
  493.   project->trp_TicksPassed=0;
  494.   TR_UpdateQuickHelp(project,0,0,TRUE);
  495.  
  496.   if(project->trp_NewGadget) FreeMem((VOID *)(project->trp_NewGadget),sizeof(struct NewGadget));
  497.   if(project->trp_GadToolsGadgetList)
  498.     {
  499.       if(project->trp_Window) RemoveGList(project->trp_Window,project->trp_GadToolsGadgetList,-1);
  500.       FreeGadgets(project->trp_GadToolsGadgetList);
  501.     }
  502.   if(project->trp_RootObject)
  503.     {
  504.       if(project->trp_Window)
  505.     TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_REMOVE,NULL);
  506.       TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_DISPOSE,NULL);
  507.     }
  508.   if(project->trp_Window)
  509.     {
  510.       TR_GetWindowDimensions(project);
  511.       TR_SaveWindowDimensions(project);
  512.       if(project->trp_UserDimensions)
  513.     CopyMem((APTR)(project->trp_Dimensions),(APTR)(project->trp_UserDimensions),
  514.         sizeof(struct TR_Dimensions));
  515.       if(project->trp_Window->MenuStrip) ClearMenuStrip(project->trp_Window);
  516.       TR_CloseWindowSafely(project->trp_Window);
  517.       if(project->trp_AppWindow) RemoveAppWindow(project->trp_AppWindow);
  518.     }
  519.   if(project->trp_Menu) FreeMenus(project->trp_Menu);
  520.   if(project->trp_NewMenu) FreeMem((VOID *)(project->trp_NewMenu),project->trp_NewMenuSize);
  521.   if((project->trp_OpenedPropFont)&&(project->trp_PropFont)) CloseFont(project->trp_PropFont);
  522.   if((project->trp_OpenedFixedWidthFont)&&(project->trp_FixedWidthFont))
  523.     CloseFont(project->trp_FixedWidthFont);
  524.   if(project->trp_VisualInfo) FreeVisualInfo(project->trp_VisualInfo);
  525.   if(project->trp_DrawInfo) FreeScreenDrawInfo(project->trp_Screen, project->trp_DrawInfo);
  526.   if(project->trp_LockedPubScreen) TR_UnlockPubScreen(project->trp_LockedPubScreen);
  527.   if(project->trp_MemPool) TR_DeletePool(project->trp_MemPool);
  528.   FreeMem((VOID *)(project),sizeof(struct TR_Project));
  529. }
  530.  
  531.  
  532. /****** triton.library/TR_OpenProject ******
  533. *
  534. *   NAME    
  535. *    TR_OpenProject -- Opens a project/window.
  536. *    TR_OpenProjectTags -- Varargs stub for TR_OpenProject.
  537. *
  538. *   SYNOPSIS
  539. *    Project = TR_OpenProject(App, TagItems)
  540. *    D0                       A1   A0
  541. *
  542. *    struct TR_Project *TR_OpenProject(struct TR_App *,
  543. *                                      struct TagItem *);
  544. *
  545. *    Project = TR_OpenProjectTags(App, Tag1,...)
  546. *
  547. *    struct TR_Project *TR_OpenProjectTags(struct TR_App *,
  548. *                                          ULONG,...);
  549. *
  550. *   FUNCTION
  551. *    Opens a Triton project. The supplied taglist may contain
  552. *    window tags, menu tags and object tags (in that order).
  553. *    Mutually exclusive menus are not yet supported. When creating
  554. *    a menu item with an ID, TRAT_ID must be the *last* tag.
  555. *    A valid application pointer must be supplied.
  556. *
  557. *   INPUTS
  558. *    App = Valid application pointer
  559. *    TagItems = List of tags describing the project
  560. *
  561. *   TAGS
  562. *    The taglist may contain window tags, menu tags and object tags
  563. *    (in that order!). The following list shows the window and menu
  564. *    tags. See the class descriptions for the object tags.
  565. *
  566. *    TRWI_Title (STRPTR) - The window title (changeable)
  567. *
  568. *    TRWI_ScreenTitle (STRPTR) - The screen title (changeable) (V2)
  569. *
  570. *    TRWI_Flags (ULONG) - The Triton window flags:
  571. *    - TRWF_BACKDROP        : Create a backdrop borderless window
  572. *                             in full screen size
  573. *    - TRWF_NODRAGBAR       : No dragging bar
  574. *    - TRWF_NODEPTHGADGET   : No depth arranging gadget
  575. *    - TRWF_NOCLOSEGADGET   : No close gadget
  576. *    - TRWF_NOACTIVATE      : Don't activate window
  577. *    - TRWF_NOESCCLOSE      : Don't send TRMS_CLOSEWINDOW when
  578. *                             Esc is pressed
  579. *    - TRWF_NOPSCRFALLBACK  : Don't fall back onto default PubScreen
  580. *    - TRWF_NOZIPGADGET     : No zip/zoom gadget
  581. *    - TRWF_ZIPCENTERTOP    : Center zipped window on screen title bar
  582. *    - TRWF_NOMINTEXTWIDTH  : Window title text length doesn't count
  583. *                             for window size calculation
  584. *    - TRWF_NOSIZEGADGET    : No size gadget
  585. *    - TRWF_NOFONTFALLBACK  : Don't fall back to topaz/8
  586. *    - TRWF_NODELZIP        : Don't zip the window when Del is pressed
  587. *    - TRWF_SIMPLEREFRESH   : Use simple instead of smart refresh. (V1)
  588. *                             This flag is *obsolete* in V3+!
  589. *                             The refresh type is now set by the user.
  590. *    - TRWF_ZIPTOCURRENTPOS : Zip the window without changing its
  591. *                             position. Requires OS3.0 or higher.
  592. *    - TRWF_APPWINDOW       : Create an AppWindow even if no object
  593. *                             reacts on dropped icons
  594. *    - TRWF_ACTIVATESTRGAD  : Activate the first string gadget after
  595. *                             opening the window
  596. *    - TRWF_HELP            : When the user presses <Help> over a menu
  597. *                             item or a display object, a TRMS_HELP
  598. *                             message will be sent (V2)
  599. *    - TRWF_SYSTEMACTION    : When a system action IDCMP message arrives,
  600. *                             a corresponding Triton message will be
  601. *                             generated. These are currently
  602. *                             TRMS_DISKINSERTED and TRMS_DISKREMOVED.
  603. *                             (V4)
  604. *
  605. *    TRWI_Underscore (UBYTE *) - The underscore for menu and gadget
  606. *        shortcuts. The default is "_".
  607. *
  608. *    TRWI_Position (ULONG) - The window position:
  609. *    - TRWP_DEFAULT         : Let Triton choose a good position for
  610. *                             the window (default; preferred)
  611. *    - TRWP_BELOWTITLEBAR   : Left side of screen; below the title bar
  612. *    - TRWP_CENTERTOP       : Top of screen; centered on the title bar
  613. *    - TRWP_TOPLEFTSCREEN   : Top left corner of screen
  614. *    - TRWP_CENTERSCREEN    : Centered on the screen
  615. *    - TRWP_CENTERDISPLAY   : Centered on the currently displayed clip
  616. *    - TRWP_MOUSEPOINTER    : Centered under the mouse pointer
  617. *
  618. *    TRWI_CustomScreen (struct Screen *) - A custom screen on which
  619. *        the window will be opened
  620. *
  621. *    TRWI_PubScreen (struct Screen *) - A public screen on which the
  622. *        window will be opened. The screen *must* have been locked.
  623. *
  624. *    TRWI_PubScreenName (STRPTR) - A public screen on which the window
  625. *        will be opened. Triton will try to lock the screen with the
  626. *        specified name. It will fall back onto the default public
  627. *        screen in case the screen can't be found/locked if you don't
  628. *        specify TRWF_NOPSCRFALLBACK.
  629. *
  630. *    TRWI_PropFontAttr (struct TextAttr *) - The proportional font. If
  631. *        Triton can't open the font or the window would become too big
  632. *        for the screen with this font and you didn't specify
  633. *        TRWF_NOFONTFALLBACK, Triton will try to use topaz/8 instead.
  634. *
  635. *    TRWI_FixedWidthFontAttr (struct TextAttr *) - The fixed-width
  636. *        font. If Triton can't open the font or the window would
  637. *        become too big for the screen with this font and you didn't
  638. *        specify TRWF_NOFONTFALLBACK, Triton will try to use topaz/8
  639. *        instead.
  640. *
  641. *    TRWI_Backfill (ULONG) - The backfill type:
  642. *    - TRBF_WINDOWBACK        : Default window background; Can be
  643. *                               changed by the user in the Triton
  644. *                               Preferences editor
  645. *    - TRBF_REQUESTERBACK     : Default requester background; Can be
  646. *                               changed by the user in the Triton
  647. *                               Preferences editor
  648. *    - TRBF_NONE              : No backfill (i.e. fill with
  649. *                               BACKGROUNDPEN)
  650. *    - TRBF_SHINE             : Fill with SHINEPEN
  651. *    - TRBF_SHADOW            : Fill with SHADOWPEN
  652. *    - TRBF_FILL              : Fill with FILLPEN
  653. *    - TRBF_SHINE_SHADOW      : Fill with a pattern composed of
  654. *                               SHINEPEN and SHADOWPEN
  655. *    - TRBF_SHINE_FILL        : ~ SHINEPEN and FILLPEN
  656. *    - TRBF_SHINE_BACKGROUND  : ~ SHINEPEN and BACKGROUNDPEN
  657. *    - TRBF_SHADOW_FILL       : ~ SHADOWPEN and FILLPEN
  658. *    - TRBF_SHADOW_BACKGROUND : ~ SHADOWPEN and BACKGROUNDPEN
  659. *    - TRBF_FILL_BACKGROUND   : ~ FILLPEN and BACKGROUNDPEN
  660. *
  661. *    TRWI_ID (ULONG) - An ID for the window. Identical windows (e.g.
  662. *        several identical data editor windows) should share the same
  663. *        ID, otherwise application-wide unique IDs should be used.
  664. *
  665. *    TRWI_Dimensions (struct TR_Dimensions *) - A window dimension
  666. *        structure. The user program must supply a structure on its
  667. *        own if it wants to use this feature. Triton will *not*
  668. *        allocate it. If you use a dimensions structure, Triton will
  669. *        copy the window dimensions into it when you close the window.
  670. *        If you supply a filled-in dimension structure, Triton will try
  671. *        to open the window with these dimensions. Supply a cleared
  672. *        structure if you want Triton to use the default dimensions (the
  673. *        position may then be specified with TRWI_Position) and fill
  674. *        in the structure for later use.
  675. *
  676. *    TRWI_QuickHelp (BOOL) - When this flag is set, QuickHelp windows
  677. *        will pop up for those objects which have QuickHelp strings
  678. *        assigned to them. (changeable) (V4)
  679. *
  680. *    TRMN_Title (STRPTR) - A menu label
  681. *
  682. *    TRMN_Item (STRPTR) - A menu item label. You may attach a
  683. *        keyboard shortcut to a menu by starting the label string
  684. *        with the shortcut followed by the project's underscore
  685. *        character and then the actual label. You may also use
  686. *        extended menu shortcuts composed of more than one character.
  687. *        Extended shortcuts can be specified with an underscore at
  688. *        the beginning, then the shortcut, again an underscore and
  689. *        the label. You may specify TRMN_BARLABEL instead of a string
  690. *        to create a separator bar in the menu.
  691. *
  692. *    TRMN_Sub (STRPTR) - A sub-menu item label. See TRMN_Item.
  693. *
  694. *    TRMN_Flags (ULONG) - Flags for a menu item:
  695. *    - TRMF_CHECKIT         : The menu item may be checked.
  696. *    - TRMF_CHECKED         : The menu item is checked. You may, but
  697. *                             you do not need to specify TRMF_CHECKIT
  698. *                             in addition.
  699. *    - TRMF_DISABLED        : The menu / (sub) item will be ghosted.
  700. *
  701. *   RESULT
  702. *    Project - The pointer to the TR_Project structure
  703. *
  704. *   SEE ALSO
  705. *    TR_CloseProject()
  706. *
  707. ******/
  708.  
  709. struct TR_Project * __saveds __asm TR_OpenProject(register __a1 struct TR_App *app, register __a0 struct TagItem *tags)
  710. {
  711.   ULONG i=0, menuitems=0;
  712.   struct TR_Project *project;
  713.   struct Window *window;
  714.   struct TROM_NewData newdata,realnewdata;
  715.   struct TROM_InstallData installdata;
  716.   struct TagItem *firstobjitem=NULL, *firstmenuitem=NULL;
  717.   STRPTR wintitle;
  718.   ULONG positioning=TRWP_DEFAULT;
  719.   BOOL zipcentertop=FALSE, mintextwidth=TRUE;
  720.   ULONG screenmodeID;
  721.   struct Rectangle displayrect;
  722.   ULONG displayleft,displaytop,displaywidth,displayheight;
  723.   BOOL centeronscreen=FALSE;
  724.   ULONG globalobject;
  725.   BOOL iszoomgadget,isclosegadget=TRUE,isdepthgadget=TRUE;
  726.   BOOL dozip=TRUE,dozoom=TRUE;
  727.   LONG topgadgetswidth=0;
  728.   ULONG closewidth,toprightwidth,bottomgadgetheight,maxborderwidth,maxborderheight;
  729.   struct DimensionInfo diminfo;
  730.   ULONG minwidth,minheight;
  731.   ULONG tagData;
  732.   BOOL hasObjects=FALSE;
  733.  
  734.   /* The default window tags */
  735.  
  736.   struct TagItem winTags[]=
  737.   {
  738.     /*  0 */  WA_Flags,         WFLG_ACTIVATE|
  739.                                 WFLG_CLOSEGADGET|
  740.                                 WFLG_DEPTHGADGET|
  741.                                 WFLG_SIZEGADGET|
  742.                                 WFLG_DRAGBAR|
  743.                                 WFLG_RMBTRAP|
  744.                                 WFLG_NEWLOOKMENUS|
  745.                                 WFLG_SMART_REFRESH|
  746.                                 WFLG_SIZEBBOTTOM,
  747.     /*  1 */  WA_IDCMP,         NULL,
  748.     /*  2 */  WA_Title,         NULL,
  749.     /*  3 */  WA_PubScreenName, NULL, /* This tag can be replaced later on */
  750.     /*  4 */  WA_Width,         NULL,
  751.     /*  5 */  WA_Height,        NULL,
  752.     /*  6 */  WA_Zoom,          NULL,
  753.     /*  7 */  WA_Left,          NULL,
  754.     /*  8 */  WA_Top,           NULL,
  755.     /*  9 */  WA_MaxWidth,      ~0,
  756.     /* 10 */  WA_MaxHeight,     ~0,
  757.     /* 11 */  WA_MinWidth,      0,
  758.     /* 12 */  WA_MinHeight,     0,
  759.     /* 13 */  WA_MenuHelp,      FALSE,
  760.               TAG_END
  761.   };
  762.  
  763.   /* Allocate the Project structure and attached structures */
  764.  
  765.   if(!(project=(struct TR_Project *)AllocMem(sizeof(struct TR_Project),MEMF_ANY|MEMF_CLEAR)))
  766.   {
  767.     app->tra_LastError=TRER_ALLOCMEM;
  768.     return NULL;
  769.   }
  770.  
  771.   if(!(project->trp_MemPool=TR_CreatePool(MEMF_ANY|MEMF_CLEAR,1024,512)))
  772.   {
  773.     app->tra_LastError=TRER_ALLOCMEM;
  774.     TR_CloseProject(project);
  775.     return NULL;
  776.   }
  777.  
  778.   if(!(project->trp_Dimensions=(struct TR_Dimensions *)TR_AllocPooled(project->trp_MemPool,sizeof(struct TR_Dimensions))))
  779.   {
  780.     app->tra_LastError=TRER_ALLOCMEM;
  781.     TR_CloseProject(project);
  782.     return NULL;
  783.   }
  784.  
  785.   /* Set basic IDCMP flags */
  786.  
  787.   project->trp_IDCMPFlags=
  788.     IDCMP_CLOSEWINDOW|
  789.     IDCMP_REFRESHWINDOW|
  790.     IDCMP_CHANGEWINDOW|
  791.     IDCMP_ACTIVEWINDOW|
  792.     IDCMP_INACTIVEWINDOW|
  793.     IDCMP_MENUPICK|
  794.     IDCMP_RAWKEY;
  795.  
  796.   /* Prepare the object and menu lists */
  797.  
  798.   NewList((struct List *)&(project->trp_MenuList));
  799.   NewList((struct List *)&(project->trp_IDList));
  800.  
  801.   /* Fill in the defaults */
  802.  
  803.   project->trp_App=app;
  804.   project->trp_EscClose=TRUE;
  805.   project->trp_DelZip=TRUE;
  806.   project->trp_Underscore='_';
  807.   project->trp_PubScreenFallBack=TRUE;
  808.   project->trp_FontFallBack=TRUE;
  809.  
  810.   if((((struct TR_AppPrefs *)(app->tra_Prefs))->flags)&TRPF_SIMPLEREFRESH) {winTags[0].ti_Data&=(~WFLG_SMART_REFRESH); winTags[0].ti_Data|=WFLG_SIMPLE_REFRESH;}
  811.  
  812.   realnewdata.project=project;
  813.  
  814.   /* Install the backfill hook */
  815.  
  816.   if(!(project->trp_BackfillHook=(struct Hook *)TR_AllocPooled(project->trp_MemPool,sizeof(struct Hook))))
  817.   {
  818.     app->tra_LastError=TRER_ALLOCMEM;
  819.     TR_CloseProject(project);
  820.     return NULL;
  821.   }
  822.   project->trp_BackfillHook->h_Entry=(ULONG (* )())TR_BackfillFunc;
  823.   project->trp_BackfillHook->h_Data=(APTR)project;
  824.   project->trp_BackfillType=TRBF_WINDOWBACK;
  825.  
  826.   /* Process the tags */
  827.  
  828.   for(;;)
  829.   {
  830.     if((tags[i].ti_Tag)==TAG_END) break;
  831.     tagData=tags[i].ti_Data;
  832.     switch(tags[i].ti_Tag)
  833.     {
  834.       case TAG_IGNORE:
  835.         break;
  836.  
  837.       case TRWI_Title:
  838.         winTags[2].ti_Data=tagData;
  839.         break;
  840.  
  841.       case TRWI_ScreenTitle:
  842.         project->trp_ScreenTitle=(STRPTR)tagData;
  843.         break;
  844.  
  845.       case TRWI_Flags:
  846.         project->trp_Flags|=tagData;
  847.         if(tagData&TRWF_BACKDROP)
  848.         {
  849.           winTags[0].ti_Data|=(WFLG_BACKDROP|WFLG_BORDERLESS);
  850.           winTags[0].ti_Data&=(~(WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SIZEGADGET));
  851.           winTags[6].ti_Tag=TAG_IGNORE;
  852.           isdepthgadget=FALSE;
  853.           isclosegadget=FALSE;
  854.           dozoom=FALSE;
  855.           dozip=FALSE;
  856.         }
  857.         if(tagData&TRWF_NODRAGBAR) winTags[0].ti_Data&=(~WFLG_DRAGBAR);
  858.         if(tagData&TRWF_NODEPTHGADGET) { winTags[0].ti_Data&=(~WFLG_DEPTHGADGET); isdepthgadget=FALSE; }
  859.         if(tagData&TRWF_NOCLOSEGADGET) { winTags[0].ti_Data&=(~WFLG_CLOSEGADGET); isclosegadget=FALSE; }
  860.         if(tagData&TRWF_NOZIPGADGET) { winTags[6].ti_Tag=TAG_IGNORE; dozip=FALSE; }
  861.         if(tagData&TRWF_NOACTIVATE) winTags[0].ti_Data&=(~WFLG_ACTIVATE);
  862.         if(tagData&TRWF_NOESCCLOSE) project->trp_EscClose=FALSE;
  863.         if(tagData&TRWF_NODELZIP) project->trp_DelZip=FALSE;
  864.         if(tagData&TRWF_NOPSCRFALLBACK) project->trp_PubScreenFallBack=FALSE;
  865.         if(tagData&TRWF_ZIPCENTERTOP) zipcentertop=TRUE;
  866.         if(tagData&TRWF_NOMINTEXTWIDTH) mintextwidth=FALSE;
  867.         if(tagData&TRWF_NOSIZEGADGET) { winTags[0].ti_Data&=(~WFLG_SIZEGADGET); dozoom=FALSE; }
  868.         if(tagData&TRWF_NOFONTFALLBACK) project->trp_FontFallBack=FALSE;
  869.         if(tagData&TRWF_HELP) { winTags[13].ti_Data=TRUE; project->trp_IDCMPFlags|=IDCMP_MENUHELP; }
  870.         if(tagData&TRWF_SYSTEMACTION) project->trp_IDCMPFlags|=(IDCMP_DISKINSERTED|IDCMP_DISKREMOVED);
  871.         break;
  872.  
  873.       case TRWI_CustomScreen:
  874.         winTags[3].ti_Tag=WA_CustomScreen;
  875.         winTags[3].ti_Data=tagData;
  876.         break;
  877.  
  878.       case TRWI_PubScreen:
  879.         winTags[3].ti_Tag=WA_PubScreen;
  880.         winTags[3].ti_Data=tagData;
  881.         break;
  882.  
  883.       case TRWI_PubScreenName:
  884.         winTags[3].ti_Data=tagData;
  885.         break;
  886.  
  887.       case TRWI_Underscore:
  888.         project->trp_Underscore=((UBYTE *)tagData)[0];
  889.         break;
  890.  
  891.       case TRWI_Position:
  892.         positioning=tagData;
  893.         break;
  894.  
  895.       case TRWI_PropFontAttr:
  896.         project->trp_PropAttr=(struct TextAttr *)tagData;
  897.         break;
  898.  
  899.       case TRWI_FixedWidthFontAttr:
  900.         project->trp_FixedWidthAttr=(struct TextAttr *)tagData;
  901.         break;
  902.  
  903.       case TRWI_Backfill:
  904.         project->trp_BackfillType=tagData;
  905.         break;
  906.  
  907.       case TRWI_QuickHelp:
  908.         if(tagData) project->trp_Flags|=TRWF_QUICKHELP;
  909.     else project->trp_Flags&=(~TRWF_QUICKHELP);
  910.         break;
  911.  
  912.       case TRWI_ID:
  913.         project->trp_ID=tagData;
  914.         break;
  915.  
  916.       case TRWI_Dimensions:
  917.         project->trp_UserDimensions=(struct TR_Dimensions *)tagData;
  918.         project->trp_UserDimensions->trd_Zoomed=FALSE;
  919.         CopyMem((APTR)(project->trp_UserDimensions),(APTR)(project->trp_Dimensions),sizeof(struct TR_Dimensions));
  920.         break;
  921.  
  922.       case TRMN_Title:
  923.         if(!firstmenuitem) firstmenuitem=&tags[i];
  924.         menuitems++;
  925.         break;
  926.  
  927.       case TRMN_Item:
  928.         menuitems++;
  929.         break;
  930.  
  931.       case TRMN_Sub:
  932.         menuitems++;
  933.         break;
  934.  
  935.       default:
  936.         if(TR_GetTagType(tags[i].ti_Tag)==TRTG_CLS)
  937.         {
  938.           if(firstobjitem) break;
  939.           realnewdata.firstitem=&(tags[i+1]);
  940.           realnewdata.itemdata=tagData;
  941.           realnewdata.parseargs=TRUE;
  942.           firstobjitem=&(tags[i]);
  943.           globalobject=tags[i].ti_Tag;
  944.           hasObjects=TRUE;
  945.         }
  946.         break;
  947.     }
  948.     i++;
  949.   }
  950.  
  951.   /* Load the window dimensions */
  952.  
  953.   TR_LoadWindowDimensions(project);
  954.  
  955.   /* Clear RMBTRAP if a menu is to be created */
  956.  
  957.   if(menuitems) winTags[0].ti_Data&=(~WFLG_RMBTRAP);
  958.  
  959.   /* Apply screen manager changes to screen specification */
  960.  
  961.   if(winTags[3].ti_Tag!=WA_CustomScreen)
  962.   {
  963.     switch(((struct TR_AppPrefs *)(app->tra_Prefs))->pubscreen[0])
  964.     {
  965.       case 1: /* Program default */
  966.         break;
  967.  
  968.       case 2: /* Default */
  969.         winTags[3].ti_Tag=WA_PubScreenName;
  970.         winTags[3].ti_Data=NULL;
  971.         break;
  972.  
  973.       case 3: /* Workbench */
  974.         winTags[3].ti_Tag=WA_PubScreenName;
  975.         winTags[3].ti_Data=(ULONG)("Workbench");
  976.         break;
  977.  
  978.       default: /* Specified screen */
  979.         winTags[3].ti_Tag=WA_PubScreenName;
  980.         winTags[3].ti_Data=(ULONG)(((struct TR_AppPrefs *)(app->tra_Prefs))->pubscreen);
  981.         break;
  982.     }
  983.   }
  984.  
  985.   /* Lock public screen */
  986.  
  987.   if(winTags[3].ti_Tag==WA_PubScreenName)
  988.   {
  989.     if(!(project->trp_LockedPubScreen=TR_LockPubScreen((STRPTR)(winTags[3].ti_Data))))
  990.     {
  991.       if(project->trp_PubScreenFallBack) project->trp_LockedPubScreen=LockPubScreen(NULL);
  992.     }
  993.     if(!(project->trp_LockedPubScreen))
  994.     {
  995.       TR_CloseProject(project);
  996.       app->tra_LastError=TRER_NOLOCKPUBSCREEN;
  997.       return NULL;
  998.     }
  999.     winTags[3].ti_Tag=WA_PubScreen;
  1000.     winTags[3].ti_Data=(ULONG)(project->trp_LockedPubScreen);
  1001.   }
  1002.  
  1003.   /* Get window title */
  1004.  
  1005.   wintitle=(STRPTR)(winTags[2].ti_Data);
  1006.  
  1007.   /* Get screen related data */
  1008.  
  1009.   project->trp_Screen=(struct Screen *)(winTags[3].ti_Data);
  1010.   project->trp_ScreenType=winTags[3].ti_Tag;
  1011.  
  1012.   if(!(project->trp_DrawInfo=GetScreenDrawInfo(project->trp_Screen)))
  1013.   {
  1014.     TR_CloseProject(project);
  1015.     app->tra_LastError=TRER_DRAWINFO;
  1016.     return NULL;
  1017.   }
  1018.  
  1019.   if(project->trp_Screen->Flags&SCREENHIRES)
  1020.   {
  1021.     closewidth=20;
  1022.     toprightwidth=24;
  1023.     bottomgadgetheight=TR_GetBottomBorderHeight(project->trp_Screen);
  1024.   }
  1025.   else
  1026.   {
  1027.     closewidth=15;
  1028.     toprightwidth=18;
  1029.     bottomgadgetheight=11;
  1030.   }
  1031.  
  1032.   /* Prepare fonts */
  1033.  
  1034.   if(!project->trp_PropAttr) project->trp_PropAttr=project->trp_Screen->Font;
  1035.   project->trp_PropFont=OpenDiskFont(project->trp_PropAttr);
  1036.  
  1037.   if(project->trp_PropFont) project->trp_OpenedPropFont=TRUE;
  1038.   else /* Fall back */
  1039.   {
  1040.     project->trp_PropAttr=&topaz8attr;
  1041.     project->trp_PropFont=OpenDiskFont(project->trp_PropAttr);
  1042.     if(project->trp_PropFont) project->trp_OpenedPropFont=TRUE;
  1043.     else
  1044.     {
  1045.       TR_CloseProject(project);
  1046.       app->tra_LastError=TRER_OPENFONT;
  1047.       return NULL;
  1048.     }
  1049.   }
  1050.  
  1051.   if(!project->trp_FixedWidthAttr)
  1052.   {
  1053.     project->trp_FixedWidthFont=GfxBase->DefaultFont;
  1054.     if(!(project->trp_FixedWidthAttr=(struct TextAttr *)TR_AllocPooled(project->trp_MemPool,sizeof(struct TextAttr))))
  1055.     {
  1056.       TR_CloseProject(project);
  1057.       app->tra_LastError=TRER_ALLOCMEM;
  1058.       return NULL;
  1059.     }
  1060.     project->trp_FixedWidthAttr->ta_Name=project->trp_FixedWidthFont->tf_Message.mn_Node.ln_Name;
  1061.     project->trp_FixedWidthAttr->ta_Flags=project->trp_FixedWidthFont->tf_Flags;
  1062.     project->trp_FixedWidthAttr->ta_Style=project->trp_FixedWidthFont->tf_Style;
  1063.     project->trp_FixedWidthAttr->ta_YSize=project->trp_FixedWidthFont->tf_YSize;
  1064.   }
  1065.   else
  1066.   {
  1067.     if(project->trp_FixedWidthFont=OpenDiskFont(project->trp_FixedWidthAttr)) project->trp_OpenedFixedWidthFont=TRUE; /* Yes, we've opened it ourselves */
  1068.   }
  1069.  
  1070.   if(!project->trp_FixedWidthFont) /* Fall back */
  1071.     {
  1072.       project->trp_FixedWidthAttr=&topaz8attr;
  1073.       project->trp_FixedWidthFont=OpenDiskFont(project->trp_FixedWidthAttr);
  1074.       if(project->trp_FixedWidthFont)
  1075.     project->trp_OpenedFixedWidthFont=TRUE; /* Yes, we've opened it ourselves */
  1076.       else
  1077.     {
  1078.       TR_CloseProject(project);
  1079.       app->tra_LastError=TRER_OPENFONT;
  1080.       return NULL;
  1081.     }
  1082.     }
  1083.  
  1084.   project->trp_TotalPropFontHeight=max(project->trp_PropFont->tf_YSize,project->trp_PropFont->tf_Baseline+1);
  1085.  
  1086.   /* Precalculate maximum border sizes */
  1087.  
  1088.   maxborderheight=project->trp_Screen->WBorTop+(project->trp_Screen->Font->ta_YSize+1)+bottomgadgetheight;
  1089.   maxborderwidth=project->trp_Screen->WBorLeft+project->trp_Screen->WBorRight;
  1090.  
  1091.   /* Get screenmode data */
  1092.  
  1093.   screenmodeID=GetVPModeID(&project->trp_Screen->ViewPort);
  1094.   if(screenmodeID!=INVALID_ID) if(TR_GetDisplayInfoData((UBYTE *)&diminfo,sizeof(struct DimensionInfo),DTAG_DIMS,screenmodeID)>0)
  1095.   {
  1096.     if((diminfo.Nominal.MaxX-diminfo.Nominal.MinX==1023)&&(diminfo.Nominal.MaxY-diminfo.Nominal.MinY==1023))
  1097.       project->trp_AspectFixing=16;
  1098.     else project->trp_AspectFixing=(((diminfo.Nominal.MaxX-diminfo.Nominal.MinX+1)/320)*16)/((diminfo.Nominal.MaxY-diminfo.Nominal.MinY+1)/200);
  1099.     if(!(project->trp_AspectFixing)) project->trp_AspectFixing=16;
  1100.   }
  1101.  
  1102.   /* Create all objects */
  1103.  
  1104.   realnewdata.objecttype=globalobject;
  1105.   realnewdata.project=project;
  1106.   realnewdata.backfilltype=project->trp_BackfillType;
  1107.  
  1108.   if(hasObjects)
  1109.   {
  1110.     if(!(CreateContext(&(project->trp_GadToolsGadgetList))))
  1111.     {
  1112.       TR_CloseProject(project);
  1113.       app->tra_LastError=TRER_GT_CREATECONTEXT;
  1114.       return NULL;
  1115.     }
  1116.     CopyMem((APTR)(&realnewdata),(APTR)(&newdata),sizeof(struct TROM_NewData));
  1117.     if(!(project->trp_RootObject=(struct TROD_DisplayObject *)TR_DoMethod(NULL,TROM_NEW,(APTR)(&newdata))))
  1118.     {
  1119.       TR_CloseProject(project);
  1120.       return NULL;
  1121.     }
  1122.     if((project->trp_RootObject->MinWidth+maxborderwidth>project->trp_Screen->Width)
  1123.        ||(project->trp_RootObject->MinHeight+maxborderheight>project->trp_Screen->Height))
  1124.     {
  1125.       if(project->trp_FontFallBack)
  1126.       {
  1127.         /* Fall back to topaz.8... */
  1128.         project->trp_PropAttr=&topaz8attr;
  1129.         project->trp_PropFont=OpenDiskFont(project->trp_PropAttr);
  1130.         if(project->trp_PropFont) project->trp_OpenedPropFont=TRUE;
  1131.         else
  1132.         {
  1133.           TR_CloseProject(project);
  1134.           app->tra_LastError=TRER_OPENFONT;
  1135.           return NULL;
  1136.         }
  1137.         project->trp_FixedWidthAttr=&topaz8attr;
  1138.         project->trp_FixedWidthFont=OpenDiskFont(project->trp_FixedWidthAttr);
  1139.         if(project->trp_FixedWidthFont) project->trp_OpenedFixedWidthFont=TRUE;
  1140.         else
  1141.         {
  1142.           TR_CloseProject(project);
  1143.           app->tra_LastError=TRER_OPENFONT;
  1144.           return NULL;
  1145.         }
  1146.         project->trp_TotalPropFontHeight=max(project->trp_PropFont->tf_YSize,project->trp_PropFont->tf_Baseline+1);
  1147.         /* ...and try again */
  1148.         TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_DISPOSE,NULL);
  1149.         NewList((struct List *)&(project->trp_IDList));
  1150.         CopyMem((APTR)(&realnewdata),(APTR)(&newdata),sizeof(struct TROM_NewData));
  1151.         project->trp_RootObject=(struct TROD_DisplayObject *)TR_DoMethod(NULL,TROM_NEW,(APTR)(&newdata));
  1152.     if((project->trp_RootObject->MinWidth+maxborderwidth>project->trp_Screen->Width)
  1153.        ||(project->trp_RootObject->MinHeight+maxborderheight>project->trp_Screen->Height))
  1154.         {
  1155.           TR_CloseProject(project);
  1156.           app->tra_LastError=TRER_WINDOWTOOBIG;
  1157.           return NULL;
  1158.         }
  1159.       }
  1160.       else
  1161.       {
  1162.         TR_CloseProject(project);
  1163.         app->tra_LastError=TRER_WINDOWTOOBIG;
  1164.         return NULL;
  1165.       }
  1166.     }
  1167.  
  1168.     if(project->trp_RootObject->XResize==FALSE) winTags[9].ti_Data=0;
  1169.     if(project->trp_RootObject->YResize==FALSE) winTags[10].ti_Data=0;
  1170.   }
  1171.  
  1172.   if((!hasObjects) || ((!project->trp_RootObject->XResize) && (!project->trp_RootObject->YResize)))
  1173.   {
  1174.     winTags[0].ti_Data&=(~WFLG_SIZEGADGET);
  1175.     dozoom=FALSE;
  1176.   }
  1177.  
  1178.   /* Calculate top border gadget width */
  1179.  
  1180.   if(!hasObjects) { dozoom=FALSE; dozip=FALSE; }
  1181.   if(dozoom||dozip) iszoomgadget=TRUE; else iszoomgadget=FALSE;
  1182.   if(isclosegadget) topgadgetswidth+=closewidth;
  1183.  
  1184.   if(iszoomgadget) topgadgetswidth+=(2*toprightwidth)-2;
  1185.   else if(isdepthgadget) topgadgetswidth+=toprightwidth-1;
  1186.  
  1187.   /* Precalculate border dimensions */
  1188.  
  1189.   project->trp_TopBorder=project->trp_Screen->WBorTop;
  1190.   project->trp_BottomBorder=project->trp_Screen->WBorBottom;
  1191.   project->trp_LeftBorder=project->trp_Screen->WBorLeft;
  1192.   project->trp_RightBorder=project->trp_Screen->WBorRight;
  1193.   if((winTags[2].ti_Data)||
  1194.     ((winTags[0].ti_Data)&(WFLG_DRAGBAR))||
  1195.     iszoomgadget||isdepthgadget||isclosegadget)
  1196.     project->trp_TopBorder+=(project->trp_Screen->Font->ta_YSize+1);
  1197.   if(dozoom) project->trp_BottomBorder=bottomgadgetheight;
  1198.  
  1199.   /* Calculate minimum window size */
  1200.  
  1201.   if(hasObjects)
  1202.   {
  1203.     minwidth  = project->trp_LeftBorder+project->trp_RightBorder + project->trp_RootObject->MinWidth;
  1204.     minheight = project->trp_TopBorder+project->trp_BottomBorder + project->trp_RootObject->MinHeight;
  1205.  
  1206.     if(mintextwidth)
  1207.     {
  1208.       if(((ULONG)TextLength(&(project->trp_Screen->RastPort),wintitle,TR_FirstOccurance(0L,wintitle))+21+topgadgetswidth)>minwidth)
  1209.         minwidth=(ULONG)TextLength(&(project->trp_Screen->RastPort),wintitle,TR_FirstOccurance(0L,wintitle))+21+topgadgetswidth;
  1210.     }
  1211.   }
  1212.   else /* No objects */
  1213.   {
  1214.     minwidth=(ULONG)TextLength(&(project->trp_Screen->RastPort),wintitle,TR_FirstOccurance(0L,wintitle))+21+topgadgetswidth;
  1215.     minheight=project->trp_TopBorder;
  1216.     winTags[6].ti_Tag=TAG_IGNORE;              /* Don't allow zipping       */
  1217.     winTags[0].ti_Data&=(~WFLG_SIZEGADGET);    /* Remove size & zoom gadget */
  1218.   }
  1219.  
  1220.   /* Set real window size */
  1221.  
  1222.   winTags[4].ti_Data = minwidth; /* Normal */
  1223.   winTags[5].ti_Data = minheight;
  1224.  
  1225.   winTags[11].ti_Data = minwidth; /* Minimum */
  1226.   winTags[12].ti_Data = minheight;
  1227.  
  1228.   if(winTags[0].ti_Data&WFLG_BACKDROP)
  1229.   {
  1230.     winTags[4].ti_Data=project->trp_Screen->Width;
  1231.     winTags[5].ti_Data=project->trp_Screen->Height-project->trp_Screen->Font->ta_YSize-3;
  1232.     positioning=TRWP_BELOWTITLEBAR;
  1233.   }
  1234.  
  1235.   /* Correct window size according to dimensions structure */
  1236.  
  1237.   if(hasObjects)
  1238.   {
  1239.     if((project->trp_Dimensions->trd_Width>winTags[4].ti_Data)
  1240.       &&(project->trp_Dimensions->trd_Width<=project->trp_Screen->Width)
  1241.       &&(project->trp_RootObject->XResize))
  1242.       winTags[4].ti_Data=project->trp_Dimensions->trd_Width;
  1243.     if((project->trp_Dimensions->trd_Height>winTags[5].ti_Data)
  1244.       &&(project->trp_Dimensions->trd_Height<=project->trp_Screen->Height)
  1245.       &&(project->trp_RootObject->YResize))
  1246.       winTags[5].ti_Data=project->trp_Dimensions->trd_Height;
  1247.   }
  1248.  
  1249.   /* Set various window parameters */
  1250.  
  1251.   project->trp_WindowStdHeight=minheight; /* winTags[5].ti_Data; */
  1252.   if(!iszoomgadget) project->trp_DelZip=FALSE;
  1253.  
  1254.   /* Set the window position */
  1255.  
  1256.   switch(positioning)
  1257.   {
  1258.     case TRWP_BELOWTITLEBAR:
  1259.       winTags[8].ti_Data=project->trp_Screen->Font->ta_YSize+3;
  1260.       break;
  1261.     case TRWP_CENTERTOP:
  1262.       if((project->trp_Screen->Width)>=(winTags[4].ti_Data)) winTags[7].ti_Data=((project->trp_Screen->Width)-(winTags[4].ti_Data))/2;
  1263.       break;
  1264.     case TRWP_TOPLEFTSCREEN:
  1265.       break;
  1266.     case TRWP_CENTERDISPLAY:
  1267.       if(screenmodeID!=INVALID_ID)
  1268.       {
  1269.         if(QueryOverscan(screenmodeID,&displayrect,OSCAN_TEXT))
  1270.         {
  1271.           displayleft=max(0,-project->trp_Screen->LeftEdge);
  1272.           displaytop=max(0,-project->trp_Screen->TopEdge);
  1273.           displaywidth=displayrect.MaxX-displayrect.MinX+1;
  1274.           displayheight=displayrect.MaxY-displayrect.MinY+1;
  1275.           if(project->trp_Screen->TopEdge>0) displayheight-=project->trp_Screen->TopEdge;
  1276.           displayheight=min(displayheight,project->trp_Screen->Height);
  1277.           displaywidth=min(displaywidth,project->trp_Screen->Width);
  1278.           if((displaywidth)>=(winTags[4].ti_Data)) winTags[7].ti_Data=(((displaywidth)-(winTags[4].ti_Data))/2)+displayleft;
  1279.           else centeronscreen=TRUE;
  1280.           if((displayheight)>=(winTags[5].ti_Data)) winTags[8].ti_Data=(((displayheight)-(winTags[5].ti_Data))/2)+displaytop;
  1281.           else centeronscreen=TRUE;
  1282.         }
  1283.         else centeronscreen=TRUE;
  1284.       }
  1285.       else centeronscreen=TRUE;
  1286.       if(!centeronscreen) break;
  1287.     case TRWP_CENTERSCREEN:
  1288.       if((project->trp_Screen->Width)>=(winTags[4].ti_Data)) winTags[7].ti_Data=((project->trp_Screen->Width)-(winTags[4].ti_Data))/2;
  1289.       if((project->trp_Screen->Height)>=(winTags[5].ti_Data)) winTags[8].ti_Data=((project->trp_Screen->Height)-(winTags[5].ti_Data))/2;
  1290.       break;
  1291.     case TRWP_MOUSEPOINTER:
  1292.       winTags[7].ti_Data=max((LONG)((project->trp_Screen->MouseX)-((winTags[4].ti_Data)/2)),0);
  1293.       winTags[8].ti_Data=max((LONG)((project->trp_Screen->MouseY)-((winTags[5].ti_Data)/2)),0);
  1294.       break;
  1295.     default:
  1296.       if(hasObjects) winTags[8].ti_Data=project->trp_Screen->Font->ta_YSize+3; /* BELOWTITLEBAR */
  1297.       else if((project->trp_Screen->Width)>=(winTags[4].ti_Data)) winTags[7].ti_Data=((project->trp_Screen->Width)-(winTags[4].ti_Data))/2; /* CENTERTOP */
  1298.       break;
  1299.   }
  1300.  
  1301.   /* Correct window position according to dimensions structure */
  1302.  
  1303.   if(project->trp_Dimensions->trd_Width) winTags[7].ti_Data=project->trp_Dimensions->trd_Left;
  1304.   if(project->trp_Dimensions->trd_Height) winTags[8].ti_Data=project->trp_Dimensions->trd_Top;
  1305.  
  1306.   /* Calculate the zip dimensions */
  1307.  
  1308.   #ifndef TR_OS39
  1309.   if(TR_Global.trg_OSVersion<39) project->trp_Flags&=(~TRWF_ZIPTOCURRENTPOS);
  1310.   #endif
  1311.  
  1312.   if(winTags[6].ti_Tag==WA_Zoom) /* Zoom */
  1313.   {
  1314.     winTags[6].ti_Data=(ULONG)(project->trp_ZipDimensions);
  1315.     project->trp_ZipDimensions[2]=TextLength(&(project->trp_Screen->RastPort),wintitle,TR_FirstOccurance(0L,wintitle))+21+topgadgetswidth; /* Width */
  1316.     project->trp_ZipDimensions[3]=project->trp_TopBorder; /* Height */
  1317.     if(zipcentertop)
  1318.     {
  1319.       if((project->trp_Screen->Width)>=(project->trp_ZipDimensions[2])) project->trp_ZipDimensions[0]=(WORD)(((project->trp_Screen->Width)-(project->trp_ZipDimensions[2]))/2); /* Left */
  1320.       project->trp_ZipDimensions[1]=0; /* Top */
  1321.     }
  1322.     else
  1323.     {
  1324.       project->trp_ZipDimensions[0]=(WORD)(winTags[7].ti_Data); /* Left */
  1325.       project->trp_ZipDimensions[1]=(WORD)(winTags[8].ti_Data); /* Top */
  1326.     }
  1327.   }
  1328.   if((winTags[0].ti_Data)&(WFLG_SIZEGADGET)) /* Resize */
  1329.   {
  1330.     winTags[6].ti_Tag=WA_Zoom;
  1331.     winTags[6].ti_Data=(ULONG)(project->trp_ZipDimensions);
  1332.     project->trp_ZipDimensions[2]=winTags[4].ti_Data*3/2;
  1333.     project->trp_ZipDimensions[3]=winTags[5].ti_Data*3/2;
  1334.  
  1335.     if(positioning>=TRWP_MAGIC)
  1336.     {
  1337.       if(project->trp_RootObject->XResize)
  1338.     project->trp_ZipDimensions[0]=max((WORD)(winTags[7].ti_Data)-((WORD)(winTags[4].ti_Data/4)),0);
  1339.       if(project->trp_RootObject->YResize)
  1340.     project->trp_ZipDimensions[1]=max((WORD)(winTags[8].ti_Data)-((WORD)(winTags[5].ti_Data/4)),0);
  1341.     }
  1342.     else
  1343.     {
  1344.       project->trp_ZipDimensions[0]=(WORD)(winTags[7].ti_Data); /* Left */
  1345.       project->trp_ZipDimensions[1]=(WORD)(winTags[8].ti_Data); /* Top */
  1346.     }
  1347.   }
  1348.  
  1349.   /* Correct alternate dimensions according to dimensions structure */
  1350.  
  1351.   if(hasObjects)
  1352.   {
  1353.     /* Size */
  1354.     if((project->trp_Dimensions->trd_Width2>=minwidth)
  1355.       &&(project->trp_Dimensions->trd_Width2<=project->trp_Screen->Width)
  1356.       &&(project->trp_RootObject->XResize))
  1357.       project->trp_ZipDimensions[2]=project->trp_Dimensions->trd_Width2;
  1358.     if((project->trp_Dimensions->trd_Height2>=minheight)
  1359.       &&(project->trp_Dimensions->trd_Height2<=project->trp_Screen->Height)
  1360.       &&(project->trp_RootObject->YResize))
  1361.       project->trp_ZipDimensions[3]=project->trp_Dimensions->trd_Height2;
  1362.  
  1363.     /* Position */
  1364.     if((project->trp_Dimensions->trd_Width2))
  1365.       project->trp_ZipDimensions[0]=project->trp_Dimensions->trd_Left2;
  1366.     if((project->trp_Dimensions->trd_Height2))
  1367.       project->trp_ZipDimensions[1]=project->trp_Dimensions->trd_Top2;
  1368.   }
  1369.  
  1370.   if(project->trp_Flags&TRWF_ZIPTOCURRENTPOS)
  1371.   {
  1372.     project->trp_ZipDimensions[0]=(WORD)(~0);
  1373.     project->trp_ZipDimensions[1]=(WORD)(~0);
  1374.   }
  1375.  
  1376.   /* Get the inner coordinates of the window */
  1377.  
  1378.   project->trp_InnerWidth=winTags[4].ti_Data-project->trp_LeftBorder-project->trp_RightBorder;
  1379.   project->trp_InnerHeight=winTags[5].ti_Data-project->trp_TopBorder-project->trp_BottomBorder;
  1380.  
  1381.   /* Open the window */
  1382.  
  1383.   if(!(window=OpenWindowTagList(NULL,winTags)))
  1384.   {
  1385.     TR_CloseProject(project);
  1386.     app->tra_LastError=TRER_OPENWINDOW;
  1387.     return NULL;
  1388.   }
  1389.   window->UserData=(APTR)project;
  1390.   project->trp_Window=window;
  1391.  
  1392.   /* Install the global message port in the window */
  1393.  
  1394.   window->UserPort=app->tra_IDCMPPort;
  1395.   if(project->trp_Flags&TRWF_QUICKHELP)
  1396.   {
  1397.     project->trp_IDCMPFlags|=(IDCMP_MOUSEMOVE|IDCMP_INTUITICKS|IDCMP_MOUSEBUTTONS);
  1398.     project->trp_Window->Flags|=WFLG_REPORTMOUSE;
  1399.   }
  1400.   ModifyIDCMP(window,project->trp_IDCMPFlags);
  1401.  
  1402.   /* Set screen title */
  1403.   if(project->trp_ScreenTitle) SetWindowTitles(window,(STRPTR)(-1),project->trp_ScreenTitle);
  1404.  
  1405.   /* Make window an application window */
  1406.   if(project->trp_Flags&TRWF_APPWINDOW)
  1407.   {
  1408.     if(!(app->tra_AppPort))
  1409.     {
  1410.       if(!(app->tra_AppPort=CreateMsgPort()))
  1411.       {
  1412.         TR_CloseProject(project);
  1413.         app->tra_LastError=TRER_CREATEMSGPORT;
  1414.         return NULL;
  1415.       }
  1416.       app->tra_BitMask|=1<<app->tra_AppPort->mp_SigBit;
  1417.     }
  1418.     project->trp_AppWindow=AddAppWindowA((ULONG)project,NULL,window,app->tra_AppPort,NULL);
  1419.   }
  1420.  
  1421.   /* Get the visual info */
  1422.  
  1423.   if(!(project->trp_VisualInfo=GetVisualInfoA(project->trp_Window->WScreen,NULL)))
  1424.   {
  1425.     TR_CloseProject(project);
  1426.     app->tra_LastError=TRER_NOLOCKPUBSCREEN;
  1427.     return NULL;
  1428.   }
  1429.  
  1430.   /* Draw the backfill pattern */
  1431.  
  1432.   TR_DoBackfill(project);
  1433.  
  1434.   /* Create the menus */
  1435.  
  1436.   if(menuitems!=0)
  1437.   {
  1438.     if(app->tra_LastError=TR_CreateMenus(project,firstmenuitem,menuitems))
  1439.     {
  1440.       TR_CloseProject(project);
  1441.       return NULL;
  1442.     }
  1443.   }
  1444.  
  1445.   /* Get current window dimensions */
  1446.  
  1447.   project->trp_OldWidth=project->trp_Window->Width;
  1448.   project->trp_OldHeight=project->trp_Window->Height;
  1449.   TR_GetWindowDimensions(project);
  1450.  
  1451.   /* Install the display objects */
  1452.  
  1453.   if(hasObjects)
  1454.   {
  1455.     /* Allocate NewGadget structure */
  1456.     if(!(project->trp_NewGadget=(struct NewGadget *)AllocMem(sizeof(struct NewGadget),MEMF_ANY|MEMF_CLEAR)))
  1457.     {
  1458.       app->tra_LastError=TRER_ALLOCMEM;
  1459.       TR_CloseProject(project);
  1460.       return NULL;
  1461.     }
  1462.     project->trp_NewGadget->ng_VisualInfo=project->trp_VisualInfo;
  1463.     project->trp_NewGadget->ng_TextAttr=project->trp_PropAttr;
  1464.  
  1465.     project->trp_PrevGadget=project->trp_GadToolsGadgetList;
  1466.  
  1467.     installdata.left=project->trp_LeftBorder;
  1468.     installdata.top=project->trp_TopBorder;
  1469.     installdata.width=project->trp_InnerWidth;
  1470.     installdata.height=project->trp_InnerHeight;
  1471.  
  1472.     if(!TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_INSTALL,(APTR)(&installdata)))
  1473.     {
  1474.       TR_CloseProject(project);
  1475.       app->tra_LastError=TRER_INSTALLOBJECT;
  1476.       return NULL;
  1477.     }
  1478.  
  1479.     AddGList(project->trp_Window,project->trp_GadToolsGadgetList,-1,-1,NULL);
  1480.     RefreshGList((struct Gadget *)(project->trp_Window->FirstGadget),project->trp_Window,NULL,-1);
  1481.     GT_RefreshWindow(project->trp_Window,NULL);
  1482.  
  1483.     if(project->trp_Flags&TRWF_ACTIVATESTRGAD) TR_DoShortcut(project, 9, TR_SHORTCUT_KEYDOWN, NULL);
  1484.   }
  1485.  
  1486.   return project;
  1487. }
  1488.  
  1489.  
  1490. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1491. ///////////////////////////////////////////////////////////////////////////////////////// Create the menus //
  1492. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1493.  
  1494. struct TROD_MenuItem
  1495. {
  1496.   struct TROD_DisplayObject DO;
  1497.   ULONG                     MenuNumber;
  1498. };
  1499.  
  1500. #define MENUITEM ((struct TROD_MenuItem *)object)
  1501.  
  1502.  
  1503. ULONG __regargs TR_CreateMenus(struct TR_Project *project, struct TagItem *tags, ULONG items)
  1504. {
  1505.   struct NewMenu *newmenu;
  1506.   ULONG i=0,errorcode=0,strl;
  1507.   LONG menunumber=-1;
  1508.   STRPTR rmtxt;
  1509.   UWORD sepnum;
  1510.   struct TROD_MenuItem *object;
  1511.   BOOL broken;
  1512.   UWORD menun=NOMENU,itemn=NOITEM,subn=NOSUB;
  1513.   ULONG tagData;
  1514.  
  1515.   /* Allocate the NewMenu structure */
  1516.  
  1517.   if(!(newmenu=(struct NewMenu *)
  1518.     AllocMem((sizeof(struct NewMenu))*(items+1),MEMF_ANY|MEMF_CLEAR)))
  1519.     return TRER_ALLOCMEM;
  1520.  
  1521.   /* Fill in the NewMenu structure */
  1522.  
  1523.   for(broken=FALSE;broken==FALSE;)
  1524.   {
  1525.     tagData=tags[i].ti_Data;
  1526.     switch(tags[i].ti_Tag)
  1527.     {
  1528.       case TRMN_Title:
  1529.         if(menun==NOMENU) menun=0; else menun++;
  1530.         itemn=NOITEM;
  1531.         subn=NOSUB;
  1532.         newmenu[++menunumber].nm_Type=NM_TITLE;
  1533.         strl=TR_FirstOccurance(0,(STRPTR)tagData)+1;
  1534.         if(!(rmtxt=(STRPTR)TR_AllocPooled(project->trp_MemPool,strl))) return TRER_ALLOCMEM;
  1535.         CopyMem((APTR)tagData,(APTR)rmtxt,strl);
  1536.         newmenu[menunumber].nm_Label=rmtxt;
  1537.         break;
  1538.  
  1539.       case TRMN_Item:
  1540.         if(itemn==NOITEM) itemn=0; else itemn++;
  1541.         subn=NOSUB;
  1542.         newmenu[++menunumber].nm_Type=NM_ITEM;
  1543.         if((STRPTR)tagData==NM_BARLABEL) newmenu[menunumber].nm_Label=NM_BARLABEL;
  1544.         else
  1545.         {
  1546.           strl=TR_FirstOccurance(0,(STRPTR)tagData)+1;
  1547.           if(!(rmtxt=(STRPTR)TR_AllocPooled(project->trp_MemPool,strl))) return TRER_ALLOCMEM;
  1548.           CopyMem((APTR)tagData,(APTR)rmtxt,strl);
  1549.           if(rmtxt[0]==project->trp_Underscore)
  1550.           {
  1551.             sepnum=TR_FirstOccurance(project->trp_Underscore,&rmtxt[2])+2;
  1552.             rmtxt[sepnum]=0;
  1553.             newmenu[menunumber].nm_Label=&rmtxt[sepnum+1];
  1554.             #ifndef TR_OS39
  1555.             if(TR_Global.trg_OSVersion>=39)
  1556.             {
  1557.             #endif
  1558.               newmenu[menunumber].nm_Flags|=NM_COMMANDSTRING;
  1559.               newmenu[menunumber].nm_CommKey=&rmtxt[1];
  1560.             #ifndef TR_OS39
  1561.             }
  1562.             #endif
  1563.           }
  1564.           else if(rmtxt[1]==project->trp_Underscore)
  1565.           {
  1566.             newmenu[menunumber].nm_CommKey=&rmtxt[0];
  1567.             newmenu[menunumber].nm_Label=&rmtxt[2];
  1568.           }
  1569.           else
  1570.           {
  1571.             newmenu[menunumber].nm_Label=rmtxt;
  1572.           }
  1573.         }
  1574.         break;
  1575.  
  1576.       case TRMN_Sub:
  1577.         if(subn==NOSUB) subn=0; else subn++;
  1578.         newmenu[++menunumber].nm_Type=NM_SUB;
  1579.         if((STRPTR)tagData==NM_BARLABEL) newmenu[menunumber].nm_Label=NM_BARLABEL;
  1580.         else
  1581.         {
  1582.           strl=TR_FirstOccurance(0,(STRPTR)tagData)+1;
  1583.           if(!(rmtxt=(STRPTR)TR_AllocPooled(project->trp_MemPool,strl))) return TRER_ALLOCMEM;
  1584.           CopyMem((APTR)tagData,(APTR)rmtxt,strl);
  1585.           if(rmtxt[0]==project->trp_Underscore)
  1586.           {
  1587.             sepnum=TR_FirstOccurance(project->trp_Underscore,&rmtxt[2])+2;
  1588.             rmtxt[sepnum]=0;
  1589.             newmenu[menunumber].nm_Label=&rmtxt[sepnum+1];
  1590.             #ifdef TR_OS39
  1591.             if(TR_Global.trg_OSVersion>=39)
  1592.             {
  1593.             #endif
  1594.               newmenu[menunumber].nm_Flags|=NM_COMMANDSTRING;
  1595.               newmenu[menunumber].nm_CommKey=&rmtxt[1];
  1596.             #ifdef TR_OS39
  1597.             }
  1598.             #endif
  1599.           }
  1600.           else if(rmtxt[1]==project->trp_Underscore)
  1601.           {
  1602.             newmenu[menunumber].nm_CommKey=&rmtxt[0];
  1603.             newmenu[menunumber].nm_Label=&rmtxt[2];
  1604.           }
  1605.           else
  1606.           {
  1607.             newmenu[menunumber].nm_Label=rmtxt;
  1608.           }
  1609.         }
  1610.         break;
  1611.  
  1612.       case TRMN_Flags:
  1613.         if(tagData&TRMF_CHECKIT) newmenu[menunumber].nm_Flags|=(CHECKIT|MENUTOGGLE);
  1614.         if(tagData&TRMF_CHECKED) newmenu[menunumber].nm_Flags|=(CHECKIT|MENUTOGGLE|CHECKED);
  1615.         if(tagData&TRMF_DISABLED)
  1616.         {
  1617.           if(newmenu[menunumber].nm_Type==NM_TITLE) newmenu[menunumber].nm_Flags|=NM_MENUDISABLED;
  1618.           else newmenu[menunumber].nm_Flags|=NM_ITEMDISABLED;
  1619.         }
  1620.         break;
  1621.  
  1622.       case TRAT_ID:
  1623.         if(!(object=(struct TROD_MenuItem *)TR_AllocPooled(project->trp_MemPool,sizeof(struct TROD_MenuItem)))) return TRER_ALLOCMEM;
  1624.         newmenu[menunumber].nm_UserData=(APTR)tagData;
  1625.         object->DO.ID=tagData;
  1626.         object->MenuNumber=FULLMENUNUM(menun,itemn,subn);
  1627.         if(newmenu[menunumber].nm_Type==NM_TITLE)
  1628.       object->DO.O.Class=TR_FindClass(project->trp_App,TRMN_Title);
  1629.         else if(newmenu[menunumber].nm_Type==NM_ITEM)
  1630.       object->DO.O.Class=TR_FindClass(project->trp_App,TRMN_Item);
  1631.         else if(newmenu[menunumber].nm_Type==NM_SUB)
  1632.       object->DO.O.Class=TR_FindClass(project->trp_App,TRMN_Sub);
  1633.         if(!TR_AddObjectToIDList(project,(struct TROD_Object *)object)) return TRER_ALLOCMEM;
  1634.         AddTail((struct List *)(&project->trp_MenuList),(struct Node *)object);
  1635.         break;
  1636.  
  1637.       default:
  1638.         broken=TRUE;
  1639.         break;
  1640.     }
  1641.     i++;
  1642.   }
  1643.   newmenu[++menunumber].nm_Type=NM_END;
  1644.  
  1645.   /* Create the menus */
  1646.  
  1647.   if(!(project->trp_Menu=CreateMenus(newmenu,GTMN_FrontPen,0,GTMN_SecondaryError,&errorcode,TAG_DONE)))
  1648.   {
  1649.     if(errorcode==GTMENU_NOMEM) return TRER_ALLOCMEM;
  1650.     else return TRER_CREATEMENUS;
  1651.   }
  1652.  
  1653.   /* Layout the menus */
  1654.  
  1655.   if(!LayoutMenus(project->trp_Menu,project->trp_VisualInfo,GTMN_NewLookMenus,TRUE,TAG_DONE)) return TRER_CREATEMENUS;
  1656.  
  1657.   /* Apply the menus */
  1658.  
  1659.   SetMenuStrip(project->trp_Window,project->trp_Menu);
  1660.   project->trp_NewMenu=newmenu;
  1661.   project->trp_NewMenuSize=(sizeof(struct NewMenu))*(items+1);
  1662.  
  1663.   return TRER_OK;
  1664. }
  1665.  
  1666.  
  1667. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1668. /////////////////////////////////////////////////////////////////////////////// Refresh or resize a window //
  1669. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1670.  
  1671. VOID __regargs TR_DoBackfill(struct TR_Project *project)
  1672. {
  1673.   struct BackFillPacket bfp;
  1674.   struct Window *window;
  1675.  
  1676.   window=project->trp_Window;
  1677.  
  1678.   bfp.layer=window->WLayer;
  1679.   bfp.bounds.MinX=window->BorderLeft;
  1680.   bfp.bounds.MinY=window->BorderTop;
  1681.   bfp.bounds.MaxX=window->Width-window->BorderRight-1;
  1682.   bfp.bounds.MaxY=window->Height-window->BorderBottom-1;
  1683.   bfp.offsetx=bfp.bounds.MinX;
  1684.   bfp.offsety=bfp.bounds.MinY;
  1685.  
  1686.   TR_BackfillFunc(project->trp_BackfillHook, window->RPort, &bfp);
  1687. }
  1688.  
  1689.  
  1690. VOID __regargs TR_RefreshProject(struct TR_Project *project)
  1691. {
  1692.   struct Window *window;
  1693.  
  1694.   window=project->trp_Window;
  1695.  
  1696.   GT_BeginRefresh(window);
  1697.   if(project->trp_RootObject)
  1698.   {
  1699.     if(window->Height>=project->trp_WindowStdHeight)
  1700.     {
  1701.       TR_DoBackfill(project);
  1702.       TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_REFRESH,NULL);
  1703.     }
  1704.   }
  1705.   /* Next 2 lines needed only for simple refresh */
  1706.   RefreshGList((struct Gadget *)(project->trp_Window->FirstGadget),project->trp_Window,NULL,-1);
  1707.   GT_RefreshWindow(project->trp_Window,NULL);
  1708.   GT_EndRefresh(window,TRUE);
  1709. }
  1710.  
  1711.  
  1712. BOOL __inline TR_ResizeProject(struct TR_Project *project)
  1713. {
  1714.   struct TROM_InstallData installdata;
  1715.   struct Window *window;
  1716.   BOOL retval=TRUE;
  1717.  
  1718.   window=project->trp_Window;
  1719.  
  1720.   if((project->trp_RootObject)&&(window->Height>=project->trp_WindowStdHeight))
  1721.   {
  1722.     if(!project->trp_IsUserLocked) TR_LockWindow(project);
  1723.  
  1724.     GT_BeginRefresh(window);
  1725.     GT_EndRefresh(window,TRUE);
  1726.  
  1727.     TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_PREGTREMOVE,NULL);
  1728.     RemoveGList(project->trp_Window,project->trp_GadToolsGadgetList,-1);
  1729.     if(project->trp_GadToolsGadgetList->NextGadget) FreeGadgets(project->trp_GadToolsGadgetList->NextGadget);
  1730.     project->trp_PrevGadget=project->trp_GadToolsGadgetList;
  1731.     TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_REMOVE,NULL);
  1732.  
  1733.     TR_DoBackfill(project);
  1734.  
  1735.     installdata.left=project->trp_LeftBorder;
  1736.     installdata.top=project->trp_TopBorder;
  1737.     installdata.width=project->trp_InnerWidth;
  1738.     installdata.height=project->trp_InnerHeight;
  1739.  
  1740.     if(!TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_INSTALL,(APTR)(&installdata)))
  1741.       retval=FALSE;
  1742.  
  1743.     AddGList(project->trp_Window,project->trp_GadToolsGadgetList,-1,-1,NULL);
  1744.  
  1745.     /* TR_DoBackfill(project); */
  1746.     /* TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_REFRESH,NULL); */
  1747.  
  1748.     GT_RefreshWindow(project->trp_Window,NULL); /* Required for GadTools Listview refresh */
  1749.     RefreshWindowFrame(window);
  1750.     if(!project->trp_IsUserLocked) TR_UnlockWindow(project);
  1751.   }
  1752.   else
  1753.   {
  1754.     GT_BeginRefresh(window);
  1755.     GT_EndRefresh(window,TRUE);
  1756.   }
  1757.  
  1758.   return retval;
  1759. }
  1760.  
  1761.  
  1762. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1763. /////////////////////////////////////////////////////////////////////////////////// Some helping functions //
  1764. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1765.  
  1766. ULONG __regargs TR_GetDisplayInfoData(UBYTE *buf, ULONG size, ULONG tagID, ULONG displayID)
  1767. {
  1768.   return GetDisplayInfoData(FindDisplayInfo(displayID), buf, size, tagID, displayID);
  1769. }
  1770.  
  1771.  
  1772. ULONG __regargs TR_GetBottomBorderHeight(struct Screen *scr)
  1773. {
  1774.   struct DrawInfo *dri;
  1775.   APTR obj;
  1776.   ULONG h=10;
  1777.  
  1778.   if(dri=GetScreenDrawInfo(scr))
  1779.   {
  1780.     if(obj=NewObject(NULL,"sysiclass",
  1781.                      SYSIA_DrawInfo,dri, SYSIA_Size,SYSISIZE_MEDRES, SYSIA_Which,SIZEIMAGE,
  1782.                      TAG_DONE))
  1783.     {
  1784.       GetAttr(IA_Height,obj,&h);
  1785.       DisposeObject(obj);
  1786.     }
  1787.     FreeScreenDrawInfo(scr,dri);
  1788.   }
  1789.   return h;
  1790. }
  1791.  
  1792.  
  1793. /****** triton.library/TR_FirstOccurance ******
  1794. *
  1795. *   NAME    
  1796. *    TR_FirstOccurance -- Finds a character in a string.
  1797. *
  1798. *   SYNOPSIS
  1799. *    Position = TR_FirstOccurance(Character, String)
  1800. *    D0                           D0         A0
  1801. *
  1802. *    LONG TR_FirstOccurance(UBYTE, STRPTR);
  1803. *
  1804. *   FUNCTION
  1805. *    Finds the specified character in the string.
  1806. *
  1807. *   RESULT
  1808. *    Position - The position of the first occurance of the
  1809. *    character in the string or -1 if the character couldn't
  1810. *    be found in the string.
  1811. *
  1812. ******/
  1813.  
  1814. LONG __saveds __asm TR_FirstOccurance(register __d0 UBYTE ch, register __a0 STRPTR str)
  1815. {
  1816.   register LONG i=0;
  1817.  
  1818.   if(!str) return 0;
  1819.  
  1820.   for(;;)
  1821.   {
  1822.     if(str[i]==ch) return i;
  1823.     if(str[i]==0) return (-1);
  1824.     i++;
  1825.   }
  1826. }
  1827.  
  1828.  
  1829. /****** triton.library/TR_NumOccurances ******
  1830. *
  1831. *   NAME    
  1832. *    TR_NumOccurances -- Counts a character in a string.
  1833. *
  1834. *   SYNOPSIS
  1835. *    Number = TR_NumOccurances(Character, String)
  1836. *    D0                        D0         A0
  1837. *
  1838. *    LONG TR_NumOccurances(UBYTE, STRPTR);
  1839. *
  1840. *   FUNCTION
  1841. *    Counts the number of occurances of the character in the string.
  1842. *
  1843. *   RESULT
  1844. *    Number - The number of matching characters found.
  1845. *
  1846. ******/
  1847.  
  1848. LONG __saveds __asm TR_NumOccurances(register __d0 UBYTE ch, register __a0 STRPTR str)
  1849. {
  1850.   LONG i=0,num=0;
  1851.   while(str[i]) if(str[i++]==ch) num++;
  1852.   return num;
  1853. }
  1854.  
  1855.  
  1856. VOID __regargs TR_GetWindowDimensions(struct TR_Project *project)
  1857. {
  1858.   project->trp_LeftBorder = project->trp_Window->BorderLeft;
  1859.   project->trp_TopBorder  = project->trp_Window->BorderTop;
  1860.   project->trp_InnerWidth = project->trp_Window->Width
  1861.                           - project->trp_Window->BorderLeft
  1862.                           - project->trp_Window->BorderRight;
  1863.   project->trp_InnerHeight= project->trp_Window->Height
  1864.                           - project->trp_Window->BorderTop
  1865.                           - project->trp_Window->BorderBottom;
  1866.  
  1867.   if(((project->trp_Window->Flags&WFLG_ZOOMED)&&(!(project->trp_Dimensions->trd_Zoomed)))
  1868.     ||((!(project->trp_Window->Flags&WFLG_ZOOMED))&&(project->trp_Dimensions->trd_Zoomed)))
  1869.   {
  1870.     project->trp_Dimensions->trd_Zoomed  = (project->trp_Window->Flags&WFLG_ZOOMED)?TRUE:FALSE;
  1871.     project->trp_Dimensions->trd_Left2   = project->trp_Dimensions->trd_Left;
  1872.     project->trp_Dimensions->trd_Top2    = project->trp_Dimensions->trd_Top;
  1873.     project->trp_Dimensions->trd_Width2  = project->trp_Dimensions->trd_Width;
  1874.     project->trp_Dimensions->trd_Height2 = project->trp_Dimensions->trd_Height;
  1875.   }
  1876.   project->trp_Dimensions->trd_Left    = project->trp_Window->LeftEdge;
  1877.   project->trp_Dimensions->trd_Top     = project->trp_Window->TopEdge;
  1878.   project->trp_Dimensions->trd_Width   = project->trp_Window->Width;
  1879.   project->trp_Dimensions->trd_Height  = project->trp_Window->Height;
  1880. }
  1881.  
  1882.  
  1883. /****** triton.library/TR_GetErrorString ******
  1884. *
  1885. *   NAME    
  1886. *    TR_GetErrorString -- Creates an error message
  1887. *
  1888. *   SYNOPSIS
  1889. *    Message = TR_GetErrorString(Number)
  1890. *    D0                          D0
  1891. *
  1892. *    STRPTR TR_GetErrorString(UWORD);
  1893. *
  1894. *   FUNCTION
  1895. *    Creates an error message which matches the supplied
  1896. *    Triton error code.
  1897. *
  1898. *   INPUTS
  1899. *    Number - Triton error code. In most cases you will
  1900. *             get this with TR_GetLastError().
  1901. *
  1902. *   RESULT
  1903. *    Message - Pointer to a user-readable error message
  1904. *              or an empty string ("") if none available.
  1905. *
  1906. *   BUGS
  1907. *    In older Triton versions, TR_GetErrorString() did
  1908. *    return NULL instead of an empty string. This is
  1909. *    fixed in V4.
  1910. *
  1911. *   SEE ALSO
  1912. *    TR_GetLastError()
  1913. *
  1914. ******/
  1915.  
  1916. STRPTR __saveds __asm TR_GetErrorString(register __d0 UWORD num)
  1917. {
  1918.   ULONG locnum;
  1919.   static const char *emptyString="";
  1920.   STRPTR errorString;
  1921.  
  1922.   switch(num)
  1923.   {
  1924.     case TRER_OK:
  1925.       return emptyString;
  1926.     case TRER_ALLOCMEM:
  1927.       locnum=MSG_ERROR_ALLOCMEM;
  1928.       break;
  1929.     case TRER_OPENWINDOW:
  1930.       locnum=MSG_ERROR_OPENWINDOW;
  1931.       break;
  1932.     case TRER_WINDOWTOOBIG:
  1933.       locnum=MSG_ERROR_WINDOWTOOBIG;
  1934.       break;
  1935.     case TRER_DRAWINFO:
  1936.       locnum=MSG_ERROR_DRAWINFO;
  1937.       break;
  1938.     case TRER_OPENFONT:
  1939.       locnum=MSG_ERROR_OPENFONT;
  1940.       break;
  1941.     case TRER_CREATEMSGPORT:
  1942.       locnum=MSG_ERROR_CREATEMSGPORT;
  1943.       break;
  1944.     case TRER_INSTALLOBJECT:
  1945.       locnum=MSG_ERROR_INSTALLOBJECT;
  1946.       break;
  1947.     case TRER_CREATECLASS:
  1948.       locnum=MSG_ERROR_CREATECLASS;
  1949.       break;
  1950.     case TRER_NOLOCKPUBSCREEN:
  1951.       locnum=MSG_ERROR_NOLOCKPUBSCREEN;
  1952.       break;
  1953.     case TRER_CREATEMENUS:
  1954.       locnum=MSG_ERROR_CREATEMENUS;
  1955.       break;
  1956.     case TRER_GT_CREATECONTEXT:
  1957.       locnum=MSG_ERROR_GADGETCONTEXT;
  1958.       break;
  1959.     default:
  1960.       locnum=MSG_ERROR_UNKNOWN;
  1961.   }
  1962.  
  1963.   if(errorString=LOCSTR(locnum)) return errorString;
  1964.   else return emptyString;
  1965. }
  1966.  
  1967.  
  1968. /****** triton.library/TR_GetLastError ******
  1969. *
  1970. *   NAME    
  1971. *    TR_GetLastError -- Gets the last error code
  1972. *
  1973. *   SYNOPSIS
  1974. *    Number = TR_GetLastError(App)
  1975. *    D0                       A1
  1976. *
  1977. *    UWORD TR_GetLastError(struct TR_App *);
  1978. *
  1979. *   FUNCTION
  1980. *    Returns the TRER code of the last error which occured
  1981. *    in the application and sets the internal tra_LastError
  1982. *    back to TRER_OK.
  1983. *
  1984. *   INPUTS
  1985. *    App - Pointer to a Triton Application
  1986. *
  1987. *   RESULT
  1988. *    Number - TRER error code
  1989. *
  1990. *   SEE ALSO
  1991. *    TR_GetErrorString()
  1992. *
  1993. ******/
  1994.  
  1995. UWORD __saveds __asm TR_GetLastError(register __a1 struct TR_App *app)
  1996. {
  1997.   UWORD error;
  1998.  
  1999.   error=app->tra_LastError;
  2000.   app->tra_LastError=0;
  2001.  
  2002.   return error;
  2003. }
  2004.  
  2005.  
  2006. VOID __stdargs TR_SPrintF (STRPTR buf, STRPTR format, ...)
  2007. {
  2008.   RawDoFmt(format, &format+1, (void (*))"\x16\xC0\x4E\x75", buf);
  2009. }
  2010.  
  2011.  
  2012. ULONG __regargs TR_CountListEntries(struct List *list)
  2013. {
  2014.   struct Node *worknode, *nextnode;
  2015.   ULONG numlines=0;
  2016.  
  2017.   if(!list) return NULL;
  2018.   if((ULONG)list==~0) return NULL;
  2019.  
  2020.   worknode=(struct Node *)(list->lh_Head);
  2021.   while(nextnode=(struct Node *)(worknode->ln_Succ))
  2022.   {
  2023.     numlines++;
  2024.     worknode=nextnode;
  2025.   }
  2026.   return numlines;
  2027. }
  2028.  
  2029.  
  2030. BYTE __regargs TR_StrCmp(STRPTR s1,STRPTR s2)
  2031. {
  2032.   ULONG i;
  2033.  
  2034.   for(i=0;TRUE;i++)
  2035.   {
  2036.     if(s1[i]!=s2[i]) return 1;
  2037.     else if((s1[i]==0)&&(s2[i]==0)) return 0;
  2038.   }
  2039. }
  2040.  
  2041.  
  2042. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2043. //////////////////////////////////////////////////////////////////// Global message port support functions //
  2044. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2045.  
  2046. VOID __regargs __inline TR_StripIntuiMessages(struct MsgPort *mp, struct Window *win)
  2047. {
  2048.   struct IntuiMessage *msg;
  2049.   struct Node *succ;
  2050.  
  2051.   msg=(struct IntuiMessage *)mp->mp_MsgList.lh_Head;
  2052.   while(succ=msg->ExecMessage.mn_Node.ln_Succ)
  2053.   {
  2054.     if(msg->IDCMPWindow==win)
  2055.     {
  2056.       Remove((struct Node *)msg);
  2057.       ReplyMsg((struct Message *)msg);
  2058.     }
  2059.     msg=(struct IntuiMessage *)succ;
  2060.   }
  2061. }
  2062.  
  2063.  
  2064. /****** triton.library/TR_CloseWindowSafely ******
  2065. *
  2066. *   NAME    
  2067. *    TR_CloseWindowSafely -- Closes as window with a shared IDCMP port.
  2068. *
  2069. *   SYNOPSIS
  2070. *    TR_CloseWindowSafely(Window)
  2071. *                         A0
  2072. *
  2073. *    VOID TR_CloseWindowSafely(struct Window *);
  2074. *
  2075. *   FUNCTION
  2076. *    Closes a window which shares its IDCMP port with another window.
  2077. *    All the pending messages (concerning this window) on the port
  2078. *    will be removed and the window will be closed.
  2079. *    
  2080. *    Do *NOT* use this function to close windows which have an IDCMP
  2081. *    port set up by Intuition. If you do the port will be left in memory!
  2082. *    
  2083. *    If you intend to open a lot of windows all sharing the same IDCMP
  2084. *    port it is easiest if you create a port yourself and open all
  2085. *    windows with newwin.IDCMPFlags set to 0 (this tells Intuition NOT to
  2086. *    set up an IDCMP port). After opening the window set win->UserPort
  2087. *    to your message port and call ModifyIDCMP() to set your IDCMP flags.
  2088. *    
  2089. *    When you then receive messages from Intuition check their
  2090. *    imsg->IDCMPWindow field to find out what window they came from
  2091. *    and act upon them.
  2092. *    
  2093. *    When closing your windows call TR_CloseWindowSafely() for all of
  2094. *    them and delete your message port.
  2095. *
  2096. *   INPUTS
  2097. *    Window - pointer to the window to be closed.
  2098. *
  2099. *   NOTE
  2100. *    This function is for the advanced Triton user.
  2101. *
  2102. *   SEE ALSO
  2103. *    intuition.library/CloseWindow()
  2104. *
  2105. ******/
  2106.  
  2107. VOID __saveds __asm TR_CloseWindowSafely(register __a0 struct Window *win)
  2108. {
  2109.   Forbid();
  2110.   TR_StripIntuiMessages(win->UserPort,win);
  2111.   win->UserPort=NULL;
  2112.   ModifyIDCMP(win,NULL);
  2113.   Permit();
  2114.   CloseWindow(win);
  2115. }
  2116.  
  2117.  
  2118. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2119. ///////////////////////////////////////////////////////////////////////////////////////// Class management //
  2120. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2121.  
  2122. /****** triton.library/TR_AddClass ******
  2123. *
  2124. *   NAME    
  2125. *    TR_AddClass -- Add a class to Triton's class management. (V6)
  2126. *
  2127. *   SYNOPSIS
  2128. *    Success = TR_AddClass(Application, Tag, SuperTag,
  2129. *                          A1           D0   D1
  2130. *                          DefaultMethod, DataSize, Tags)
  2131. *                          A2             D2        A0
  2132. *
  2133. *    BOOL TR_AddClass(struct TR_App *, ULONG, ULONG, TR_Method,
  2134. *                     struct TR_Class *, struct TagItem *);
  2135. *
  2136. *   FUNCTION
  2137. *    Add a class to Triton's class management. Objects of the class
  2138. *    may then be used in TR_OpenProject(). You don't have to remove
  2139. *    the classes. This is done automatically when the application
  2140. *    is deleted.
  2141. *
  2142. *   RESULT
  2143. *    Success - FALSE if the class couldn't be initialized.
  2144. *
  2145. ******/
  2146.  
  2147. BOOL __saveds __asm TR_AddClass(register __a1 struct TR_App *app, register __d0 ULONG tag,
  2148.                 register __d1 ULONG superTag, register __a2 TR_Method defaultMethod,
  2149.                 register __d2 ULONG datasize, register __a0 struct TagItem *tags)
  2150. {
  2151.   ULONG i;
  2152.   struct TR_Class *classnode;
  2153.   TR_Method method;
  2154.  
  2155.   if(app)
  2156.     {
  2157.       if(!(classnode=TR_AllocPooled(app->tra_MemPool,sizeof(struct TR_Class)))) return FALSE;
  2158.     }
  2159.   else if(!(classnode=TR_AllocPooled(TR_Global.trg_ClassListPool,sizeof(struct TR_Class)))) return FALSE;
  2160.  
  2161.   classnode->trc_Tag=tag;
  2162.   classnode->trc_Dispatcher[0]=defaultMethod;
  2163.   classnode->trc_SizeOfClassData=datasize;
  2164.   classnode->trc_SuperClass=TR_FindClass(NULL,superTag);
  2165.  
  2166.   if((!defaultMethod)&&classnode->trc_SuperClass) for(i=1;i<24;i++)
  2167.   {
  2168.     classnode->trc_Dispatcher[i]=classnode->trc_SuperClass->trc_Dispatcher[i];
  2169.     classnode->trc_MetaClass[i]=classnode->trc_SuperClass->trc_MetaClass[i];
  2170.   }
  2171.  
  2172.   if(tags) for(i=0;tags[i].ti_Tag;i++)
  2173.   {
  2174.     classnode->trc_Dispatcher[tags[i].ti_Tag]=(TR_Method)(tags[i].ti_Data);
  2175.     classnode->trc_MetaClass[tags[i].ti_Tag]=classnode;
  2176.   }
  2177.  
  2178.   if(app) AddTail((struct List *)&(app->tra_ClassList),(struct Node *)classnode);
  2179.   else AddTail((struct List *)&(TR_Global.trg_ClassList),(struct Node *)classnode);
  2180.  
  2181.   if(!(method=classnode->trc_Dispatcher[TROM_CREATECLASS]))
  2182.     method=defaultMethod;
  2183.   if(method) if((*method)(NULL,TROM_CREATECLASS,NULL,classnode)) return FALSE;
  2184.  
  2185.   return TRUE;
  2186. }
  2187.  
  2188.  
  2189. VOID __regargs __inline TR_DisposeClasses(struct MinList *list)
  2190. {
  2191.   TR_Method method;
  2192.   struct TR_Class *classnode;
  2193.  
  2194.   for(classnode=(struct TR_Class *)(list->mlh_Head);
  2195.       classnode->trc_Node.mln_Succ;
  2196.       classnode=(struct TR_Class *)(classnode->trc_Node.mln_Succ))
  2197.   {
  2198.     if(!(method=classnode->trc_Dispatcher[TROM_DISPOSECLASS]))
  2199.       method=classnode->trc_Dispatcher[0];
  2200.     if(method) (*method)(NULL,TROM_DISPOSECLASS,NULL,classnode);
  2201.   }
  2202. }
  2203.  
  2204.  
  2205. /****i* triton.library/TR_FindClass ******
  2206. *
  2207. *   NAME    
  2208. *    TR_FindClass -- Get a class pointer from a class ID
  2209. *
  2210. *   SYNOPSIS
  2211. *    Class = TR_FindClass(App, ID)
  2212. *
  2213. *    struct TR_Class *TR_FindClass(struct TR_App *, ULONG);
  2214. *
  2215. *   FUNCTION
  2216. *    Find a class given by a class ID (i.e. a project tag). Set App
  2217. *    to NULL if you only want the global class list to be searched.
  2218. *
  2219. *   RESULT
  2220. *    Class - A class pointer or NULL if the class doesn't exist.
  2221. *
  2222. ******/
  2223.  
  2224. struct TR_Class * __regargs TR_FindClass(struct TR_App *app, ULONG tag)
  2225. {
  2226.   struct TR_Class *classnode;
  2227.  
  2228.   for(classnode=(struct TR_Class *)(TR_Global.trg_ClassList.mlh_Head);
  2229.       classnode->trc_Node.mln_Succ;
  2230.       classnode=(struct TR_Class *)(classnode->trc_Node.mln_Succ))
  2231.     if(classnode->trc_Tag==tag) return classnode;
  2232.  
  2233.   if(app)
  2234.     for(classnode=(struct TR_Class *)(app->tra_ClassList.mlh_Head);
  2235.     classnode->trc_Node.mln_Succ;
  2236.     classnode=(struct TR_Class *)(classnode->trc_Node.mln_Succ))
  2237.       if(classnode->trc_Tag==tag) return classnode;
  2238.  
  2239.   return NULL;
  2240. }
  2241.  
  2242.  
  2243. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2244. //////////////////////////////////////////////////////////////////////////////////////// Object management //
  2245. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2246.  
  2247. /****** triton.library/TR_DoMethodClass ******
  2248. *
  2249. *   NAME    
  2250. *    TR_DoMethodClass -- Dispatch a method through a meta-class. (V6)
  2251. *
  2252. *   SYNOPSIS
  2253. *    Result = TR_DoMethodClass(Object, MessageID, Data, Class)
  2254. *                              A0      D0         A1    A2
  2255. *
  2256. *    ULONG TR_DoMethodClass(struct TROD_Object *, ULONG, APTR,
  2257. *                           struct TR_Class *);
  2258. *
  2259. *   FUNCTION
  2260. *    Dispatch a method to an object as if the object was of the
  2261. *    specified class.
  2262. *
  2263. *   RESULT
  2264. *    Depends on the class and method being called.
  2265. *
  2266. *   SEE ALSO
  2267. *    TR_DoMethod()
  2268. *
  2269. ******/
  2270.  
  2271. ULONG __saveds __asm TR_DoMethodClass(register __a0 struct TROD_Object *object,
  2272.                       register __d0 ULONG messageid, register __a1 APTR data,
  2273.                       register __a2 struct TR_Class *cl)
  2274. {
  2275.   TR_Method method;
  2276.   struct TR_Class *metaclass;
  2277.  
  2278.   if(method=cl->trc_Dispatcher[messageid]) metaclass=cl->trc_MetaClass[messageid];
  2279.   else
  2280.   {
  2281.     if(!(method=cl->trc_Dispatcher[0])) return 0;
  2282.     metaclass=cl;
  2283.   }
  2284.   return (*method)(object,messageid,data,metaclass);
  2285. }
  2286.  
  2287.  
  2288. /****** triton.library/TR_DoMethod ******
  2289. *
  2290. *   NAME    
  2291. *    TR_DoMethod -- Dispatch a method. (V6)
  2292. *
  2293. *   SYNOPSIS
  2294. *    Result = TR_DoMethod(Object, MessageID, Data)
  2295. *                         A0      D0         A1
  2296. *
  2297. *    ULONG TR_DoMethod(struct TROD_Object *, ULONG, APTR);
  2298. *
  2299. *   FUNCTION
  2300. *    Dispatch a method to an object.
  2301. *
  2302. *   RESULT
  2303. *    Depends on the class and method being called.
  2304. *
  2305. *   SEE ALSO
  2306. *    TR_DoMethodClass()
  2307. *
  2308. ******/
  2309.  
  2310. ULONG __saveds __asm TR_DoMethod(register __a0 struct TROD_Object *object,
  2311.                  register __d0 ULONG messageid, register __a1 APTR data)
  2312. {
  2313.   struct TR_Class *cl;
  2314.  
  2315.   if(messageid==TROM_NEW)
  2316.   {
  2317.     if(!(cl=TR_FindClass(((struct TROM_NewData *)data)->project->trp_App,
  2318.              ((struct TROM_NewData *)data)->objecttype))) return 0;
  2319.     if(!(object=TR_AllocPooled(((struct TROM_NewData *)data)->project->trp_MemPool,
  2320.                    cl->trc_SizeOfClassData))) return 0;
  2321.     object->Class=cl;
  2322.   }
  2323.   else cl=object->Class;
  2324.  
  2325.   return TR_DoMethodClass(object,messageid,data,cl);
  2326. }
  2327.  
  2328.  
  2329. VOID __regargs TR_DoMethodID(struct TR_Project *project, ULONG objectid, ULONG method, APTR data)
  2330. {
  2331.   struct TR_IDNode *idnode;
  2332.  
  2333.   for(idnode=(struct TR_IDNode *)(project->trp_IDList.mlh_Head);
  2334.       idnode->tri_Node.mln_Succ;
  2335.       idnode=(struct TR_IDNode *)(idnode->tri_Node.mln_Succ))
  2336.     {
  2337.       if(idnode->tri_ID==objectid)
  2338.     if(TR_GetTagType(idnode->tri_Object->Class->trc_Tag)==TRTG_CLS)
  2339.       if(!(((struct TROD_DisplayObject *)(idnode->tri_Object))->Flags&TROB_DISPLAYOBJECT_DISABLED))
  2340.         TR_DoMethod(idnode->tri_Object,method,data);
  2341.     }
  2342. }
  2343.  
  2344.  
  2345. /****** triton.library/TR_SendMessage ******
  2346. *
  2347. *   NAME    
  2348. *    TR_SendMessage -- Send a message to one or more objects. (V4)
  2349. *
  2350. *   SYNOPSIS
  2351. *    TR_SendMessage(Project, ID, MessageID, MessageData)
  2352. *                   A0       D0  D1         A1
  2353. *
  2354. *    ULONG TR_SendMessage(struct TR_Project *, ULONG,
  2355. *                         ULONG, void *);
  2356. *
  2357. *   FUNCTION
  2358. *    Sends an object message, specified by its ID (TROM_...)
  2359. *    and the message data to one or more objects of a project
  2360. *    which share the specified ID. By specifying an ID of NULL,
  2361. *    you can send a message to the project itself.
  2362. *
  2363. *   SEE ALSO
  2364. *    Class descriptions, TR_SetAttribute, TR_GetAttribute()
  2365. *
  2366. ******/
  2367.  
  2368. ULONG __saveds __asm TR_SendMessage(register __a0 struct TR_Project *project, register __d0 ULONG objectid, register __d1 ULONG messageid, register __a1 void *messagedata)
  2369. {
  2370.   struct TR_IDNode *idnode;
  2371.   struct TROD_DisplayObject *object;
  2372.   ULONG retval=0;
  2373.  
  2374.   /*-- if(!objectid) return 0; No window messages available at the moment */
  2375.  
  2376.   for(idnode=(struct TR_IDNode *)(project->trp_IDList.mlh_Head);
  2377.       idnode->tri_Node.mln_Succ;
  2378.       idnode=(struct TR_IDNode *)(idnode->tri_Node.mln_Succ))
  2379.   {
  2380.     if(idnode->tri_ID==objectid)
  2381.     {
  2382.       object=(struct TROD_DisplayObject *)(idnode->tri_Object);
  2383.       if(!((object->O.Class->trc_Tag>=TRMN_Title)
  2384.        &&(object->O.Class->trc_Tag<=TRMN_Sub))) /* No menu */
  2385.     retval=TR_DoMethod(object,messageid,(APTR)messagedata);
  2386.     }
  2387.   }
  2388.  
  2389.   return retval;
  2390. }
  2391.  
  2392.  
  2393. /****** triton.library/TR_SetAttribute ******
  2394. *
  2395. *   NAME    
  2396. *    TR_SetAttribute -- Sets an attribute of an object.
  2397. *
  2398. *   SYNOPSIS
  2399. *    TR_SetAttribute(Project, ID, Attribute, Value)
  2400. *                    A0       D0  D1         D2
  2401. *
  2402. *    VOID TR_SetAttribute(struct TR_Project *, ULONG,
  2403. *                         ULONG, ULONG);
  2404. *
  2405. *   FUNCTION
  2406. *    Sets an attribute of a Triton object. Only attributes
  2407. *    of objects with an ID can be changed. You can change the
  2408. *    default attribute of an object by specifying 0 as
  2409. *    the attribute to change. By specifying an ID of 0, you
  2410. *    can change those attributes of a Triton project which are
  2411. *    marked with '(changeable)' in the TR_OpenProject docs.
  2412. *
  2413. *   SEE ALSO
  2414. *    Class descriptions, TR_GetAttribute(), TR_OpenProject()
  2415. *
  2416. ******/
  2417.  
  2418. VOID __saveds __asm TR_SetAttribute(register __a0 struct TR_Project *project, register __d0 ULONG objectid, register __d1 ULONG attribute, register __d2 ULONG value)
  2419. {
  2420.   struct TROM_SetAttributeData sadata;
  2421.   struct TR_IDNode *idnode;
  2422.   struct TROD_DisplayObject *object;
  2423.   UWORD menun,itemn,subn,i;
  2424.   struct Menu *currentmenu;
  2425.   struct MenuItem *currentitem;
  2426.  
  2427.   if(!objectid)
  2428.   {
  2429.     switch(attribute)
  2430.     {
  2431.       case TRWI_Title:
  2432.         SetWindowTitles(project->trp_Window,(STRPTR)value,(STRPTR)(-1));
  2433.         break;
  2434.       case TRWI_ScreenTitle:
  2435.         project->trp_ScreenTitle=(STRPTR)value;
  2436.         SetWindowTitles(project->trp_Window,(STRPTR)(-1),(STRPTR)value);
  2437.         break;
  2438.       case TRWI_QuickHelp:
  2439.         if(value)
  2440.     {
  2441.       project->trp_Flags|=TRWF_QUICKHELP;
  2442.       project->trp_IDCMPFlags|=(IDCMP_MOUSEMOVE|IDCMP_INTUITICKS|IDCMP_MOUSEBUTTONS);
  2443.           project->trp_Window->Flags|=WFLG_REPORTMOUSE;
  2444.       ModifyIDCMP(project->trp_Window,project->trp_IDCMPFlags);
  2445.     }
  2446.     else
  2447.     {
  2448.       project->trp_Flags&=~TRWF_QUICKHELP;
  2449.           project->trp_Window->Flags&=~WFLG_REPORTMOUSE;
  2450.     }
  2451.         TR_UpdateQuickHelp(project,0,0,TRUE);
  2452.         break;
  2453.     }
  2454.     return;
  2455.   }
  2456.  
  2457.   sadata.attribute=attribute;
  2458.   sadata.value=value;
  2459.  
  2460.   for(idnode=(struct TR_IDNode *)(project->trp_IDList.mlh_Head);
  2461.       idnode->tri_Node.mln_Succ;
  2462.       idnode=(struct TR_IDNode *)(idnode->tri_Node.mln_Succ))
  2463.   {
  2464.     if(idnode->tri_ID==objectid)
  2465.     {
  2466.       object=(struct TROD_DisplayObject *)(idnode->tri_Object);
  2467.       if((object->O.Class->trc_Tag>=TRMN_Title)&&(object->O.Class->trc_Tag<=TRMN_Sub))
  2468.       {
  2469.         if(attribute==TRAT_Disabled)
  2470.         {
  2471.           if(value) OffMenu(project->trp_Window,MENUITEM->MenuNumber);
  2472.           else OnMenu(project->trp_Window,MENUITEM->MenuNumber);
  2473.         }
  2474.         else
  2475.         {
  2476.           /* Get menu number */
  2477.           menun=MENUNUM(MENUITEM->MenuNumber);
  2478.           itemn=ITEMNUM(MENUITEM->MenuNumber);
  2479.           subn=SUBNUM(MENUITEM->MenuNumber);
  2480.           /* Get pointer to menu item */
  2481.           currentmenu=project->trp_Menu;
  2482.           for(i=0;i<menun;i++) currentmenu=currentmenu->NextMenu;
  2483.           currentitem=currentmenu->FirstItem;
  2484.           for(i=0;i<itemn;i++) currentitem=currentitem->NextItem;
  2485.           if(subn!=NOSUB)
  2486.           {
  2487.             currentitem=currentitem->SubItem;
  2488.             for(i=0;i<subn;i++) currentitem=currentitem->NextItem;
  2489.           }
  2490.           /* Set attribute */
  2491.           ClearMenuStrip(project->trp_Window);
  2492.           if(value) currentitem->Flags|=CHECKED;
  2493.           else currentitem->Flags&=(~CHECKED);
  2494.           ResetMenuStrip(project->trp_Window,project->trp_Menu);
  2495.         }
  2496.       }
  2497.       else TR_DoMethod(object,TROM_SETATTRIBUTE,(APTR)(&sadata));
  2498.     }
  2499.   }
  2500. }
  2501.  
  2502.  
  2503. /****** triton.library/TR_GetAttribute ******
  2504. *
  2505. *   NAME    
  2506. *    TR_GetAttribute -- Gets an attribute of an object.
  2507. *
  2508. *   SYNOPSIS
  2509. *    value = TR_GetAttribute(Project, ID, Attribute)
  2510. *    D0                      A0       D0  D1
  2511. *
  2512. *    ULONG TR_GetAttribute(struct TR_Project *, ULONG,
  2513. *                          ULONG);
  2514. *
  2515. *   FUNCTION
  2516. *    Gets an attribute of a Triton object. Only attributes
  2517. *    of objects with an ID can be queried.
  2518. *
  2519. *   RESULT
  2520. *    value - Value of the specified attribute. Depends
  2521. *            on specific class and attribute.
  2522. *
  2523. *   SEE ALSO
  2524. *    Class descriptions, TR_SetAttribute()
  2525. *
  2526. ******/
  2527.  
  2528. ULONG __saveds __asm TR_GetAttribute(register __a0 struct TR_Project *project, register __d0 ULONG objectid, register __d1 ULONG attribute)
  2529. {
  2530.   struct TR_IDNode *idnode;
  2531.   ULONG attval=NULL;
  2532.   struct TROD_DisplayObject *object;
  2533.   UWORD menun,itemn,subn,i;
  2534.   struct Menu *currentmenu;
  2535.   struct MenuItem *currentitem;
  2536.  
  2537.   for(idnode=(struct TR_IDNode *)(project->trp_IDList.mlh_Head);
  2538.       idnode->tri_Node.mln_Succ;
  2539.       idnode=(struct TR_IDNode *)(idnode->tri_Node.mln_Succ))
  2540.   {
  2541.     if(idnode->tri_ID==objectid)
  2542.     {
  2543.       object=(struct TROD_DisplayObject *)(idnode->tri_Object);
  2544.       if((object->O.Class->trc_Tag>=TRMN_Title)&&(object->O.Class->trc_Tag<=TRMN_Sub))
  2545.       {
  2546.         /* Get menu number */
  2547.         menun=MENUNUM(MENUITEM->MenuNumber);
  2548.         itemn=ITEMNUM(MENUITEM->MenuNumber);
  2549.         subn=SUBNUM(MENUITEM->MenuNumber);
  2550.         /* Get pointer to menu item */
  2551.         currentmenu=project->trp_Menu;
  2552.         for(i=0;i<menun;i++) currentmenu=currentmenu->NextMenu;
  2553.         currentitem=currentmenu->FirstItem;
  2554.         for(i=0;i<itemn;i++) currentitem=currentitem->NextItem;
  2555.         if(subn!=NOSUB)
  2556.         {
  2557.           currentitem=currentitem->SubItem;
  2558.           for(i=0;i<subn;i++) currentitem=currentitem->NextItem;
  2559.         }
  2560.         /* Get attribute */
  2561.         if(attribute==TRAT_Disabled) attval=(currentitem->Flags&ITEMENABLED)?FALSE:TRUE;
  2562.         else if(attribute==TRAT_Value) attval=(currentitem->Flags&CHECKED)?TRUE:FALSE;
  2563.       }
  2564.       else attval=TR_DoMethod(object,TROM_GETATTRIBUTE,(APTR)attribute);
  2565.     }
  2566.     if(attval) break;
  2567.   }
  2568.  
  2569.   return attval;
  2570. }
  2571.  
  2572. struct TROD_DisplayObject * __regargs TR_ObjectFromPlace(struct TR_Project *project, UWORD x, UWORD y)
  2573. {
  2574.   struct TROM_HitData hitdata;
  2575.  
  2576.   if(!project->trp_RootObject) return 0L;
  2577.   hitdata.x=x;
  2578.   hitdata.y=y;
  2579.   hitdata.object=NULL;
  2580.   TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_HIT,(APTR)(&hitdata));
  2581.  
  2582.   return hitdata.object;
  2583. }
  2584.  
  2585.  
  2586. ULONG __regargs TR_IdFromPlace(struct TR_Project *project, UWORD x, UWORD y)
  2587. {
  2588.   struct TROD_DisplayObject *object=TR_ObjectFromPlace(project,x,y);
  2589.   return object ? object->ID : 0;
  2590. }
  2591.  
  2592.  
  2593. ULONG __regargs TR_GetTagType(ULONG tag)
  2594. {
  2595.   tag&=~(TRTG_SER(0xFFFF)|TAG_USER);
  2596.   if(tag&0x400) return TRTG_OAT;
  2597.   if(tag&0x300) return TRTG_CLS;
  2598.   if(tag==201) return TRTG_CLS; /* TRGR_Horiz */
  2599.   if(tag==202) return TRTG_CLS; /* TRGR_Vert  */
  2600.   if(tag&0x80) return TRTG_OAT;
  2601.   return TRTG_PAT;
  2602. }
  2603.  
  2604.  
  2605. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2606. /////////////////////////////////////////////////////////////////////////////////// Object list management //
  2607. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2608.  
  2609. struct TROD_Object * __regargs TR_AddObjectToIDList(struct TR_Project *project, struct TROD_Object *object)
  2610. {
  2611.   struct TR_IDNode *idnode;
  2612.  
  2613.   if(((struct TROD_DisplayObject *)(object))->ID)
  2614.   {
  2615.     idnode=(struct TR_IDNode *)TR_AllocPooled(project->trp_MemPool,sizeof(struct TR_IDNode));
  2616.     if(!idnode)
  2617.     {
  2618.       project->trp_App->tra_LastError=TRER_ALLOCMEM;
  2619.       return NULL;
  2620.     }
  2621.     idnode->tri_ID=((struct TROD_DisplayObject *)(object))->ID;
  2622.     idnode->tri_Object=object;
  2623.     AddTail((struct List *)(&(project->trp_IDList)),(struct Node *)idnode);
  2624.   }
  2625.  
  2626.   return object;
  2627. }
  2628.  
  2629.  
  2630. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2631. ///////////////////////////////////////////////////////////////////////////////////////// GadTools support //
  2632. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2633.  
  2634. struct Gadget * __regargs TR_CreateGadget(struct TR_Project *project, struct TROD_Object *object, ULONG kind, ULONG left, ULONG top, ULONG width, ULONG height, struct TagItem *tags)
  2635. {
  2636.   struct Gadget *gad;
  2637.  
  2638.   project->trp_NewGadget->ng_LeftEdge=left;
  2639.   project->trp_NewGadget->ng_TopEdge=top;
  2640.   project->trp_NewGadget->ng_Width=width;
  2641.   project->trp_NewGadget->ng_Height=height;
  2642.   project->trp_NewGadget->ng_UserData=(APTR)object;
  2643.  
  2644.   if(gad=CreateGadgetA(kind,project->trp_PrevGadget,project->trp_NewGadget,tags))
  2645.     project->trp_PrevGadget=gad;
  2646.  
  2647.   return gad;
  2648. }
  2649.  
  2650.  
  2651. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2652. /////////////////////////////////////////////////////////////////////////////////// Window blocking system //
  2653. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2654.  
  2655. #ifndef TR_OS39
  2656. static const UWORD chip TR_BusyPointerData[]=
  2657. {
  2658.   0x0000,0x0000,0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,
  2659.   0x0000,0x07E0,0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,
  2660.   0x3FF8,0x7FBE,0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,
  2661.   0x3FF8,0x7FFE,0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,
  2662.   0x0000,0x07E0,0x0000,0x0000
  2663. };
  2664. #endif
  2665.  
  2666.  
  2667. VOID __regargs TR_LockWindow(struct TR_Project *project)
  2668. {
  2669.   if(project->trp_InvisibleRequest) return;
  2670.   project->trp_InvisibleRequest=(struct Requester *)AllocMem(sizeof(struct Requester),MEMF_CLEAR);
  2671.   if(project->trp_InvisibleRequest) Request(project->trp_InvisibleRequest,project->trp_Window);
  2672. }
  2673.  
  2674.  
  2675. VOID __regargs TR_UnlockWindow(struct TR_Project *project)
  2676. {
  2677.   if(project->trp_InvisibleRequest)
  2678.   {
  2679.     EndRequest(project->trp_InvisibleRequest,project->trp_Window);
  2680.     FreeMem((void *)(project->trp_InvisibleRequest),sizeof(struct Requester));
  2681.     project->trp_InvisibleRequest=NULL;
  2682.   }
  2683. }
  2684.  
  2685.  
  2686. /****** triton.library/TR_LockProject ******
  2687. *
  2688. *   NAME    
  2689. *    TR_LockProject -- Locks a Triton project.
  2690. *
  2691. *   SYNOPSIS
  2692. *    TR_LockProject(Project)
  2693. *                   A0
  2694. *
  2695. *    VOID TR_LockProject(struct TR_Project *);
  2696. *
  2697. *   FUNCTION
  2698. *    Locks a Triton project. Only window resizing will
  2699. *    still work in a locked project. All other kinds of
  2700. *    input (i.e. all input which requires interaction
  2701. *    by your program and not only by Triton) are not
  2702. *    possible.
  2703. *
  2704. *   SEE ALSO
  2705. *    TR_UnlockProject()
  2706. *
  2707. ******/
  2708.  
  2709. VOID __saveds __asm TR_LockProject(register __a0 struct TR_Project *project)
  2710. {
  2711.   project->trp_IsUserLocked=TRUE;
  2712.   TR_LockWindow(project);
  2713.   #ifndef TR_OS39
  2714.   if(TR_Global.trg_OSVersion>=39)
  2715.   #endif
  2716.     SetWindowPointer(project->trp_Window,WA_BusyPointer,TRUE,WA_PointerDelay,TRUE,TAG_END);
  2717.   #ifndef TR_OS39
  2718.   else SetPointer(project->trp_Window,(UWORD *)TR_BusyPointerData,16,16,-6,0);
  2719.   #endif
  2720. }
  2721.  
  2722.  
  2723. /****** triton.library/TR_UnlockProject ******
  2724. *
  2725. *   NAME    
  2726. *    TR_UnlockProject -- Unlocks a Triton project.
  2727. *
  2728. *   SYNOPSIS
  2729. *    TR_UnlockProject(Project)
  2730. *                     A0
  2731. *
  2732. *    VOID TR_UnlockProject(struct TR_Project *);
  2733. *
  2734. *   FUNCTION
  2735. *    Unlocks a Triton project previously locked by
  2736. *    TR_LockProject().
  2737. *
  2738. *   SEE ALSO
  2739. *    TR_LockProject()
  2740. *
  2741. ******/
  2742.  
  2743. VOID __saveds __asm TR_UnlockProject(register __a0 struct TR_Project *project)
  2744. {
  2745.   TR_UnlockWindow(project);
  2746.   project->trp_IsUserLocked=FALSE;
  2747.   ClearPointer(project->trp_Window);
  2748. }
  2749.  
  2750.  
  2751. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2752. ////////////////////////////////////////////////////////////////////////////////// Window locking protocol //
  2753. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2754.  
  2755. /****** triton.library/TR_ObtainWindow ******
  2756. *
  2757. *   NAME    
  2758. *    TR_ObtainWindow -- Get a project's window. (V3)
  2759. *
  2760. *   SYNOPSIS
  2761. *    window = TR_ObtainWindow(Project)
  2762. *    D0                       A0
  2763. *
  2764. *    struct Window * TR_ObtainWindow(struct TR_Project *);
  2765. *
  2766. *   FUNCTION
  2767. *    Lock the window of a Triton project for non-Triton window
  2768. *    operations (e.g. activating a window or bringing it to the
  2769. *    front). Do not manipulate the contents of Triton windows!
  2770. *    Locked windows must be freed again with TR_UnlockWindow().
  2771. *    Locking/unlocking calls are nested.
  2772. *
  2773. *   RESULT
  2774. *    window - Pointer to the project's Window. A value of NULL should
  2775. *             be quietly ignored. NULL simply indicates that there is
  2776. *             currently no window available.
  2777. *
  2778. *   SEE ALSO
  2779. *    TR_UnlockWindow()
  2780. *
  2781. ******/
  2782.  
  2783. struct Window * __asm __saveds TR_ObtainWindow(register __a0 struct TR_Project *project)
  2784. {
  2785.   return project->trp_Window;
  2786. }
  2787.  
  2788.  
  2789. /****** triton.library/TR_ReleaseWindow ******
  2790. *
  2791. *   NAME    
  2792. *    TR_ReleaseWindow -- Release a project's window. (V3)
  2793. *
  2794. *   SYNOPSIS
  2795. *    TR_ReleaseWindow(Window)
  2796. *                    A0
  2797. *
  2798. *    VOID TR_ReleaseWindow(struct Window *);
  2799. *
  2800. *   FUNCTION
  2801. *    Unlock a window which has been locked by TR_ObtainWindow(). All
  2802. *    locked windows must be unlocked! Locking/unlocking calls are
  2803. *    nested.
  2804. *
  2805. *   SEE ALSO
  2806. *    TR_ObtainWindow()
  2807. *
  2808. ******/
  2809.  
  2810. VOID __asm __saveds TR_ReleaseWindow(register __a0 struct Window *screen)
  2811. {
  2812. }
  2813.  
  2814.  
  2815. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2816. /////////////////////////////////////////////////////////////////////////////////// Application management //
  2817. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2818.  
  2819. /****** triton.library/TR_CreateApp ******
  2820. *
  2821. *   NAME    
  2822. *    TR_CreateApp -- Creates a Triton application.
  2823. *    TR_CreateAppTags -- Varargs stub for TR_CreateApp.
  2824. *
  2825. *   SYNOPSIS
  2826. *    app = TR_CreateApp(TagList)
  2827. *    D0                 A1
  2828. *
  2829. *    struct TR_App * TR_CreateApp(struct TagItem *);
  2830. *
  2831. *    app = TR_CreateAppTags(Tag1,...)
  2832. *
  2833. *    struct TR_App * TR_CreateApp(ULONG,...);
  2834. *
  2835. *   FUNCTION
  2836. *    Creates an application. An application is required
  2837. *    for opening windows and polling messages. All projects
  2838. *    of an application will share one IDCMP port and one
  2839. *    memory pool.
  2840. *
  2841. *   TAGS
  2842. *    TRCA_Name        - (STRPTR)
  2843. *                       Unique name for the application. Must not be
  2844. *                       longer than 20 characters. Case-insensitive.
  2845. *                       ' ', '/', '.' and ':' are not allowed.
  2846. *    TRCA_LongName    - (STRPTR)
  2847. *                       A user-readable name for the application.
  2848. *                       Up to 60 characters allowed.
  2849. *    TRCA_Info        - (STRPTR)
  2850. *                       Information about the application. Should not
  2851. *                       be more than 2 lines with 60 characters each.
  2852. *    TRCA_Version     - (STRPTR)
  2853. *                       Internal version of the application.
  2854. *    TRCA_Release     - (STRPTR)
  2855. *                       Release number of the application.
  2856. *    TRCA_Date        - (STRPTR)
  2857. *                       Creation/compilation date. Should be given
  2858. *                       in standard version string format.
  2859. *    
  2860. *    Example:
  2861. *      Name        : DilloCreate
  2862. *      LongName    : Armadillo Creator
  2863. *      Info        : Part of the Armadillo Management System.
  2864. *                    © 1994 by DilloWorks Enterprises.
  2865. *      Version     : 42.135
  2866. *      Release     : 2.1bß3
  2867. *      Date        : 17.6.94
  2868. *
  2869. *   RESULT
  2870. *    app - A pointer to the created application structure.
  2871. *          NULL indicates failure.
  2872. *
  2873. *   SEE ALSO
  2874. *    TR_DeleteApp()
  2875. *
  2876. ******/
  2877.  
  2878. struct TR_App * __saveds __asm TR_CreateApp(register __a1 struct TagItem *apptags)
  2879. {
  2880.   struct TR_App *app;
  2881.   void *pool;
  2882.   struct TagItem *tstate,*tag;
  2883.   ULONG strsize;
  2884.  
  2885.   /* Allocate structure */
  2886.  
  2887.   if(!(pool=TR_CreatePool(MEMF_ANY|MEMF_CLEAR,1024,512))) return NULL;
  2888.   if(!(app=(struct TR_App *)TR_AllocPooled(pool,sizeof(struct TR_App)))) {TR_DeletePool(pool); return NULL;}
  2889.   app->tra_MemPool=pool;
  2890.  
  2891.   /* Create some stuff */
  2892.  
  2893.   NewList((struct List *)&(app->tra_ClassList));
  2894.   NewList((struct List *)&(app->tra_MsgList));
  2895.   if(!(app->tra_IDCMPPort=CreateMsgPort())) goto cleanup;
  2896.   if(!(app->tra_InputEvent=(struct InputEvent *)AllocVec(sizeof(struct InputEvent),MEMF_ANY|MEMF_CLEAR))) goto cleanup;
  2897.  
  2898.   /* Set IDCMP signal bit */
  2899.  
  2900.   app->tra_BitMask=1<<app->tra_IDCMPPort->mp_SigBit;
  2901.  
  2902.   /* Go through tags and allocate other entries via the pool */
  2903.  
  2904.   tstate=apptags;
  2905.   while(tag=NextTagItem(&tstate))
  2906.   {
  2907.     switch(tag->ti_Tag)
  2908.     {
  2909.       case TRCA_Name:
  2910.         strsize=TR_FirstOccurance(0L,(STRPTR)(tag->ti_Data))+1;
  2911.         if(!(app->tra_Name=(STRPTR)TR_AllocPooled(pool,strsize))) goto cleanup;
  2912.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_Name),strsize);
  2913.         break;
  2914.       case TRCA_LongName:
  2915.         strsize=TR_FirstOccurance(0L,(STRPTR)(tag->ti_Data))+1;
  2916.         if(!(app->tra_LongName=(STRPTR)TR_AllocPooled(pool,strsize))) goto cleanup;
  2917.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_LongName),strsize);
  2918.         break;
  2919.       case TRCA_Info:
  2920.         strsize=TR_FirstOccurance(0L,(STRPTR)(tag->ti_Data))+1;
  2921.         if(!(app->tra_Info=(STRPTR)TR_AllocPooled(pool,strsize))) goto cleanup;
  2922.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_Info),strsize);
  2923.         break;
  2924.       case TRCA_Version:
  2925.         strsize=TR_FirstOccurance(0L,(STRPTR)(tag->ti_Data))+1;
  2926.         if(!(app->tra_Version=(STRPTR)TR_AllocPooled(pool,strsize))) goto cleanup;
  2927.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_Version),strsize);
  2928.         break;
  2929.       case TRCA_Release:
  2930.         strsize=TR_FirstOccurance(0L,(STRPTR)(tag->ti_Data))+1;
  2931.         if(!(app->tra_Release=(STRPTR)TR_AllocPooled(pool,strsize))) goto cleanup;
  2932.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_Release),strsize);
  2933.         break;
  2934.       case TRCA_Date:
  2935.         strsize=TR_FirstOccurance(0L,(STRPTR)(tag->ti_Data))+1;
  2936.         if(!(app->tra_Date=(STRPTR)TR_AllocPooled(pool,strsize))) goto cleanup;
  2937.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_Date),strsize);
  2938.         break;
  2939.       case TRCA_MagicPrefs:
  2940.         if(!(app->tra_Prefs=TR_AllocPooled(app->tra_MemPool,sizeof(struct TR_AppPrefs)))) goto cleanup;
  2941.         CopyMem((APTR)(tag->ti_Data),(APTR)(app->tra_Prefs),sizeof(struct TR_AppPrefs));
  2942.         break;
  2943.       default:
  2944.         break;
  2945.     }
  2946.   }
  2947.  
  2948.   TR_SaveAppInfos(app);
  2949.   if(!app->tra_Prefs) TR_LoadTritonPrefs(app);
  2950.  
  2951.   return app;
  2952.  
  2953.   cleanup:
  2954.     TR_DeleteApp(app);
  2955.     return NULL;
  2956. }
  2957.  
  2958.  
  2959. /****** triton.library/TR_DeleteApp ******
  2960. *
  2961. *   NAME    
  2962. *    TR_DeleteApp -- Deletes a Triton application.
  2963. *
  2964. *   SYNOPSIS
  2965. *    TR_DeleteApp(App)
  2966. *                 A1
  2967. *
  2968. *    VOID TR_DeleteApp(struct TR_App *);
  2969. *
  2970. *   FUNCTION
  2971. *    Deletes an application created by TR_CreateApp().
  2972. *
  2973. *   NOTES
  2974. *    All windows have to be closed before deleting the
  2975. *    corresponding application!
  2976. *
  2977. *   SEE ALSO
  2978. *    TR_CreateApp()
  2979. *
  2980. ******/
  2981.  
  2982. VOID __saveds __asm TR_DeleteApp(register __a1 struct TR_App *app)
  2983. {
  2984.   struct Message *msg;
  2985.  
  2986.   if(app)
  2987.   {
  2988.     TR_DisposeClasses(&(app->tra_ClassList));
  2989.     if(app->tra_IDCMPPort)
  2990.     {
  2991.       while(msg=GetMsg(app->tra_IDCMPPort)) ReplyMsg(msg);
  2992.       DeleteMsgPort(app->tra_IDCMPPort);
  2993.     }
  2994.     if(app->tra_AppPort)
  2995.     {
  2996.       while(msg=GetMsg(app->tra_AppPort)) ReplyMsg(msg);
  2997.       DeleteMsgPort(app->tra_AppPort);
  2998.     }
  2999.     if(app->tra_InputEvent) FreeVec(app->tra_InputEvent);
  3000.     TR_DeletePool(app->tra_MemPool);
  3001.   }
  3002. }
  3003.  
  3004.  
  3005. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3006. ////////////////////////////////////////////////////////////////////////////////////// Broadcasting system //
  3007. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3008.  
  3009. /****** triton.library/TR_CreateMsg ******
  3010. *
  3011. *   NAME    
  3012. *    TR_CreateMsg -- Create an application message. (V6)
  3013. *
  3014. *   SYNOPSIS
  3015. *    message = TR_CreateMsg(App)
  3016. *    D0                     A1
  3017. *
  3018. *    struct TR_Message * TR_CreateMsg(struct TR_App *);
  3019. *
  3020. *   FUNCTION
  3021. *    Creates an empty message to be filled in by a custom
  3022. *    class which wants to send a user message. The message
  3023. *    is automatically added to the application's message
  3024. *    queue (which is emptied by user-level calls to
  3025. *    TR_GetMsg()). The trm_App field of the message is
  3026. *    initialized to the supplied app. When called within
  3027. *    a method which is invoked by TR_GetMsg() (i.e. an
  3028. *    event-handling method) trm_Project, trm_Seconds,
  3029. *    trm_Micros and trm_Qualifier are also initialized.
  3030. *
  3031. *   SEE ALSO
  3032. *    TR_GetMsg(), TR_ReplyMsg()
  3033. *
  3034. ******/
  3035.  
  3036. struct TR_Message * __saveds __asm TR_CreateMsg(register __a1 struct TR_App *app)
  3037. {
  3038.   struct TR_Message *m;
  3039.  
  3040.   if(m=TR_AllocPooled(app->tra_MemPool,sizeof(struct TR_Message)))
  3041.     {
  3042.       m->trm_App=app;
  3043.       if(app->tra_CurProject)
  3044.     {
  3045.       m->trm_Project=app->tra_CurProject;
  3046.       m->trm_Seconds=app->tra_CurSecs;
  3047.       m->trm_Micros=app->tra_CurMicros;
  3048.       m->trm_Qualifier=app->tra_CurQual;
  3049.     }
  3050.       AddTail((struct List *)&(app->tra_MsgList),(struct Node *)(&(m->trm_Node)));
  3051.     }
  3052.   else DisplayBeep(NULL); /* We're out of memory. That's the best we can do... */
  3053.   return m;
  3054. }
  3055.  
  3056.  
  3057. /****** triton.library/TR_GetMsg ******
  3058. *
  3059. *   NAME    
  3060. *    TR_GetMsg -- Gets a Triton message.
  3061. *
  3062. *   SYNOPSIS
  3063. *    message = TR_GetMsg(App)
  3064. *    D0                  A1
  3065. *
  3066. *    struct TR_Message * TR_GetMsg(struct TR_App *);
  3067. *
  3068. *   FUNCTION
  3069. *    Gets a message from a Triton application created
  3070. *    by TR_CreateApp(). You may first want to wait for
  3071. *    a message with TR_Wait().
  3072. *
  3073. *   NOTES
  3074. *    Please reply all messages as quickly as possible
  3075. *    with TR_ReplyMsg(). Shutting down an application
  3076. *    does not free unreplied messages and resources
  3077. *    which are attached to them (like AppMessages).
  3078. *
  3079. *   SEE ALSO
  3080. *    TR_ReplyMsg(), TR_Wait(), TR_CreateMsg()
  3081. *
  3082. ******/
  3083.  
  3084. struct TR_Message * __saveds __asm TR_GetMsg(register __a1 struct TR_App *app)
  3085. {
  3086.   struct IntuiMessage *imsg, ownimsg;
  3087.   struct AppMessage *amsg;
  3088.   struct TROM_EventData edata;
  3089.   BOOL keydown;
  3090.   struct TR_Project *project;
  3091.   UBYTE buffer, lowerbuffer;
  3092.   struct MenuItem *menuitem;
  3093.   ULONG menuid,realcode=NULL;
  3094.   struct TR_Message *message=NULL;
  3095.   struct Node *node;
  3096.   UWORD selitem;
  3097.  
  3098.   if(node=RemHead((struct List *)&(app->tra_MsgList))) goto finished;
  3099.  
  3100.   edata.imsg=&ownimsg;
  3101.  
  3102.   while(imsg=GT_GetIMsg(app->tra_IDCMPPort))
  3103.   {
  3104.     project=(struct TR_Project *)(imsg->IDCMPWindow->UserData);
  3105.     CopyMem((APTR)imsg,(APTR)(&ownimsg),sizeof(struct IntuiMessage));
  3106.     GT_ReplyIMsg(imsg);
  3107.     app->tra_CurProject=project;
  3108.     app->tra_CurSecs=imsg->Seconds;
  3109.     app->tra_CurMicros=imsg->Micros;
  3110.     app->tra_CurQual=imsg->Qualifier;
  3111.  
  3112.     if(project->trp_Flags&TRWF_QUICKHELP)
  3113.     {
  3114.       if(ownimsg.Class==IDCMP_INTUITICKS) project->trp_TicksPassed++;
  3115.       else project->trp_TicksPassed=0;
  3116.       TR_UpdateQuickHelp(project,ownimsg.MouseX,ownimsg.MouseY,
  3117.              (ownimsg.Class==IDCMP_MOUSEMOVE || ownimsg.Class==IDCMP_INTUITICKS)?FALSE:TRUE);
  3118.     }
  3119.  
  3120.     switch(ownimsg.Class)
  3121.     {
  3122.       case IDCMP_INTUITICKS:
  3123.         break;
  3124.  
  3125.       case IDCMP_CLOSEWINDOW:
  3126.     if(message=TR_CreateMsg(app)) message->trm_Class=TRMS_CLOSEWINDOW;
  3127.         break;
  3128.  
  3129.       case IDCMP_DISKINSERTED:
  3130.     if(message=TR_CreateMsg(app)) message->trm_Class=TRMS_DISKINSERTED;
  3131.         break;
  3132.  
  3133.       case IDCMP_DISKREMOVED:
  3134.     if(message=TR_CreateMsg(app)) message->trm_Class=TRMS_DISKREMOVED;
  3135.         break;
  3136.  
  3137.       case IDCMP_REFRESHWINDOW:
  3138.         TR_RefreshProject(project);
  3139.         break;
  3140.  
  3141.       case IDCMP_CHANGEWINDOW:
  3142.         TR_GetWindowDimensions(project);
  3143.         if((project->trp_Window->Width!=project->trp_OldWidth)||(project->trp_Window->Height!=project->trp_OldHeight))
  3144.         {
  3145.           project->trp_OldWidth=project->trp_Window->Width;
  3146.           project->trp_OldHeight=project->trp_Window->Height;
  3147.           if(!(TR_ResizeProject(project))) if(message=TR_CreateMsg(app))
  3148.           {
  3149.             message->trm_Class=TRMS_ERROR;
  3150.             message->trm_Data=TRER_INSTALLOBJECT;
  3151.           }
  3152.           TR_DoShortcut(project, 0, TR_SHORTCUT_CANCELLED, &edata);
  3153.         }
  3154.         break;
  3155.  
  3156.       case IDCMP_MENUPICK:
  3157.     for(selitem=ownimsg.Code;selitem!=MENUNULL;selitem=menuitem->NextSelect)
  3158.       {
  3159.         menuitem=ItemAddress(project->trp_Menu,selitem);
  3160.         menuid=(ULONG)(GTMENUITEM_USERDATA(menuitem));
  3161.         if(menuid) if(message=TR_CreateMsg(app))
  3162.           {
  3163.         message->trm_Project=project;
  3164.         message->trm_ID=menuid;
  3165.         if(menuitem->Flags&CHECKIT)
  3166.           {
  3167.             message->trm_Class=TRMS_NEWVALUE;
  3168.             message->trm_Data=(menuitem->Flags&CHECKED)? TRUE:FALSE;
  3169.           }
  3170.         else message->trm_Class=TRMS_ACTION;
  3171.           }
  3172.       }
  3173.     break;
  3174.  
  3175.       case IDCMP_ACTIVEWINDOW:
  3176.       case IDCMP_INACTIVEWINDOW:
  3177.         TR_DoShortcut(project, 0, TR_SHORTCUT_CANCELLED, &edata);
  3178.         break;
  3179.  
  3180.       case IDCMP_MENUHELP:
  3181.         if(ITEMNUM(ownimsg.Code)!=NOITEM) if(message=TR_CreateMsg(app))
  3182.         {
  3183.           menuitem=ItemAddress(project->trp_Menu,ownimsg.Code);
  3184.           message->trm_Class=TRMS_HELP;
  3185.           message->trm_ID=(ULONG)(GTMENUITEM_USERDATA(menuitem));
  3186.         }
  3187.         break;
  3188.  
  3189.       case IDCMP_RAWKEY:
  3190.         app->tra_InputEvent->ie_Class        = IECLASS_RAWKEY;
  3191.         app->tra_InputEvent->ie_Code         = ownimsg.Code;
  3192.         app->tra_InputEvent->ie_Qualifier    = ownimsg.Qualifier;
  3193.         app->tra_InputEvent->ie_EventAddress = (APTR *) *((ULONG *)ownimsg.IAddress);
  3194.  
  3195.         if(app->tra_InputEvent->ie_Code&IECODE_UP_PREFIX)
  3196.         {
  3197.           app->tra_InputEvent->ie_Code&=~(IECODE_UP_PREFIX);
  3198.           keydown=FALSE;
  3199.         }
  3200.         else keydown=TRUE;
  3201.  
  3202.         buffer=0;
  3203.         if(MapRawKey(app->tra_InputEvent,&buffer,1,NULL)==1)
  3204.         {
  3205.           lowerbuffer=tolower(buffer);
  3206.           realcode=edata.imsg->Code;
  3207.           if(lowerbuffer==buffer) edata.imsg->Code=FALSE; /* unshifted */
  3208.           else edata.imsg->Code=TRUE;                     /* shifted   */
  3209.           if(keydown)
  3210.           {
  3211.             if((buffer==27)&&(project->trp_EscClose)) /* Escape */
  3212.             {
  3213.               if(message=TR_CreateMsg(app)) message->trm_Class=TRMS_CLOSEWINDOW;
  3214.             }
  3215.             else if(buffer==127)
  3216.             {
  3217.               if(project->trp_DelZip) ZipWindow(imsg->IDCMPWindow);
  3218.             }
  3219.             else TR_DoShortcut(project, lowerbuffer, TR_SHORTCUT_KEYDOWN, &edata);
  3220.           }
  3221.           else TR_DoShortcut(project, lowerbuffer, TR_SHORTCUT_KEYUP, &edata);
  3222.         }
  3223.         else if((app->tra_InputEvent->ie_Code==96)||(app->tra_InputEvent->ie_Code==97))
  3224.         {
  3225.           if(app->tra_InputEvent->ie_Qualifier&3)
  3226.             TR_DoShortcut(project, 0, TR_SHORTCUT_CANCELLED, &edata);
  3227.       /* else project->trp_IsCancelDown=FALSE; */
  3228.         }
  3229.         else if(app->tra_InputEvent->ie_Code==95 && project->trp_Flags&TRWF_HELP && keydown)
  3230.         {
  3231.       if(message=TR_CreateMsg(app))
  3232.             {
  3233.               message->trm_Class=TRMS_HELP;
  3234.               message->trm_ID=TR_IdFromPlace(project,imsg->MouseX,imsg->MouseY);
  3235.             }
  3236.     }
  3237.  
  3238.     if(node=RemHead((struct List *)&(app->tra_MsgList))) goto finished;
  3239.  
  3240.     if(realcode) edata.imsg->Code=realcode;
  3241.     if(project->trp_RootObject)
  3242.       TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_EVENT,(APTR)(&edata));
  3243.  
  3244.     if(node=RemHead((struct List *)&(app->tra_MsgList))) goto finished;
  3245.  
  3246.     if(message=TR_CreateMsg(app))
  3247.           {
  3248.             message->trm_Class     = TRMS_KEYPRESSED;
  3249.             message->trm_Data      = (ULONG)buffer;
  3250.             message->trm_Code      = (ULONG)(ownimsg.Code);
  3251.             message->trm_Qualifier = (ULONG)(ownimsg.Qualifier);
  3252.           }
  3253.         break;
  3254.  
  3255.       default:
  3256.         if(project->trp_RootObject)
  3257.       TR_DoMethod((struct TROD_Object *)(project->trp_RootObject),TROM_EVENT,(APTR)(&edata));
  3258.     }
  3259.  
  3260.     if(node=RemHead((struct List *)&(app->tra_MsgList))) goto finished;
  3261.   }
  3262.  
  3263.   if(app->tra_AppPort)
  3264.     if(amsg=(struct AppMessage *)GetMsg(app->tra_AppPort))
  3265.       if(message=TR_CreateMsg(app))
  3266.     {
  3267.       project=(struct TR_Project *)(amsg->am_ID);
  3268.       message->trm_Project=project;
  3269.       message->trm_ID=TR_IdFromPlace(project,amsg->am_MouseX,amsg->am_MouseY);
  3270.       message->trm_Class=TRMS_ICONDROPPED;
  3271.       message->trm_Data=(ULONG)amsg;
  3272.       message->trm_Seconds=amsg->am_Seconds;
  3273.       message->trm_Micros=amsg->am_Micros;
  3274.     }
  3275.  
  3276.   if(!(node=RemHead((struct List *)&(app->tra_MsgList))))
  3277.     {
  3278.       app->tra_CurProject=NULL;
  3279.       return NULL;
  3280.     }
  3281.  
  3282. finished:
  3283.   app->tra_CurProject=NULL;
  3284.   return TR_NODE2MSG(node);
  3285. }
  3286.  
  3287.  
  3288. /****** triton.library/TR_ReplyMsg ******
  3289. *
  3290. *   NAME    
  3291. *    TR_ReplyMsg -- Replies a Triton message.
  3292. *
  3293. *   SYNOPSIS
  3294. *    TR_ReplyMsg(Message)
  3295. *                A1
  3296. *
  3297. *    VOID TR_ReplyMsg(struct TR_Message *);
  3298. *
  3299. *   FUNCTION
  3300. *    Replies a message received by TR_GetMsg().
  3301. *
  3302. *   SEE ALSO
  3303. *    TR_GetMsg(), TR_Wait()
  3304. *
  3305. ******/
  3306.  
  3307. VOID __saveds __asm TR_ReplyMsg(register __a1 struct TR_Message *message)
  3308. {
  3309.   if(message)
  3310.   {
  3311.     if(message->trm_Class==TRMS_ICONDROPPED) ReplyMsg((struct Message *)(message->trm_Data));
  3312.     TR_FreePooled(message->trm_App->tra_MemPool,(void *)message,sizeof(struct TR_Message));
  3313.   }
  3314. }
  3315.  
  3316.  
  3317. /****** triton.library/TR_Wait ******
  3318. *
  3319. *   NAME    
  3320. *    TR_Wait -- Waits for exec signals.
  3321. *
  3322. *   SYNOPSIS
  3323. *    Signals = TR_Wait(App, OtherBits)
  3324. *            A1   D0
  3325. *
  3326. *    ULONG TR_Wait(struct TR_App *, ULONG);
  3327. *
  3328. *   FUNCTION
  3329. *    Waits until a signal of the specified application
  3330. *    or one of the other signal bits is set.
  3331. *
  3332. *   RESULT
  3333. *    Signals - The mask of set signals
  3334. *
  3335. *   SEE ALSO
  3336. *    TR_GetMsg(), TR_ReplyMsg()
  3337. *
  3338. ******/
  3339.  
  3340. ULONG __saveds __asm TR_Wait(register __a1 struct TR_App *app, register __d0 ULONG otherbits)
  3341. {
  3342.   return Wait((app->tra_BitMask)|otherbits);
  3343. }
  3344.  
  3345.  
  3346. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3347. /////////////////////////////////////////////////////////////////////////////////// Text support functions //
  3348. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3349.  
  3350. VOID __regargs TR_DoShortcut(struct TR_Project *project, UBYTE shortcut, UWORD code, struct TROM_EventData *edata)
  3351. {
  3352.   struct TR_IDNode *idnode;
  3353.   struct TROD_DisplayObject *object;
  3354.   BOOL isshortcut,oldscdown;
  3355.  
  3356.   for(idnode=(struct TR_IDNode *)(project->trp_IDList.mlh_Head);
  3357.       idnode->tri_Node.mln_Succ;
  3358.       idnode=(struct TR_IDNode *)(idnode->tri_Node.mln_Succ))
  3359.   {
  3360.     object=(struct TROD_DisplayObject *)(idnode->tri_Object);
  3361.     if(TR_GetTagType(object->O.Class->trc_Tag)==TRTG_CLS)
  3362.     {
  3363.       isshortcut=FALSE;
  3364.       if((object->Shortcut==shortcut)||
  3365.      ( (object->O.Class->trc_Tag==TROB_Button) && /*-- Kludge! */
  3366.        ( ((object->Flags&TROB_DISPLAYOBJECT_RETURNOK)&&(shortcut==13))||
  3367.          ((object->Flags&TROB_DISPLAYOBJECT_ESCOK)&&(shortcut==27)) )
  3368.      )||
  3369.      ( (object->O.Class->trc_Tag==TROB_String) && /*-- Kludge! */
  3370.        ((object->Flags&TROB_DISPLAYOBJECT_TABOK)&&(shortcut==9))
  3371.      )
  3372.     ) isshortcut=TRUE;
  3373.  
  3374.       switch(code)
  3375.       {
  3376.         case TR_SHORTCUT_KEYDOWN:
  3377.           if(isshortcut)
  3378.           {
  3379.             if((project->trp_CurrentID)&&(project->trp_CurrentID!=idnode->tri_ID)) TR_DoMethodID(project, project->trp_CurrentID, TROM_KEYCANCELLED, (APTR)(edata));
  3380.             project->trp_CurrentID=idnode->tri_ID;
  3381.             oldscdown=project->trp_IsShortcutDown;
  3382.             project->trp_IsShortcutDown=TRUE;
  3383.             if(oldscdown) TR_DoMethodID(project, idnode->tri_ID, TROM_REPEATEDKEYDOWN, (APTR)(edata));
  3384.             else TR_DoMethodID(project, idnode->tri_ID, TROM_KEYDOWN, (APTR)(edata));
  3385.             return;
  3386.           }
  3387.           break;
  3388.         case TR_SHORTCUT_KEYUP:
  3389.           if(isshortcut)
  3390.           {
  3391.             project->trp_CurrentID=NULL;
  3392.             TR_DoMethodID(project, idnode->tri_ID, TROM_KEYUP, (APTR)(edata));
  3393.             project->trp_IsShortcutDown=FALSE;
  3394.             return;
  3395.           }
  3396.           break;
  3397.         case TR_SHORTCUT_CANCELLED:
  3398.           TR_DoMethodID(project, project->trp_CurrentID, TROM_KEYCANCELLED, (APTR)(edata));
  3399.           project->trp_CurrentID=0;
  3400.           /* project->trp_IsCancelDown=TRUE; */
  3401.           return;
  3402.           break;
  3403.       }
  3404.     }
  3405.   }
  3406. }
  3407.  
  3408.  
  3409. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3410. ///////////////////////////////////////////////////////////////////////////////// Gadget support functions //
  3411. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3412.  
  3413. VOID __regargs TR_SelectGadget(struct TR_Project *project, struct Gadget *gad, BOOL selected)
  3414. {
  3415.   if(selected) gad->Flags |= GFLG_SELECTED;
  3416.     else gad->Flags &= ~(GFLG_SELECTED);
  3417.   RefreshGList (gad, project->trp_Window, NULL, 1);
  3418. }
  3419.  
  3420.  
  3421. VOID __regargs TR_DisableGadget(struct TR_Project *project, struct Gadget *gad, BOOL disabled)
  3422. {
  3423.   if(disabled) gad->Flags |= GFLG_DISABLED;
  3424.     else gad->Flags &= ~(GFLG_DISABLED);
  3425.   RefreshGList (gad, project->trp_Window, NULL, 1);
  3426. }
  3427.  
  3428.  
  3429. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3430. ////////////////////////////////////////////////////////////////////////////////////// Requester functions //
  3431. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3432.  
  3433. /****** triton.library/TR_AutoRequest ******
  3434. *
  3435. *   NAME    
  3436. *    TR_AutoRequest -- A (relatively ;-) low-level requester function.
  3437. *
  3438. *   SYNOPSIS
  3439. *    selection = TR_AutoRequest(App, Project, TagList)
  3440. *    D0                         A1   A0       A2
  3441. *
  3442. *    ULONG TR_AutoRequest(struct TR_App *, struct TR_Project *,
  3443. *                         struct AppItem *);
  3444. *
  3445. *    selection = TR_AutoRequestTags(App, Project, Tag,...)
  3446. *    D0
  3447. *
  3448. *    ULONG TR_AutoRequestTags(struct TR_App *, struct TR_Project *,
  3449. *                         struct AppItem *);
  3450. *
  3451. *   FUNCTION
  3452. *    Pops up a requester which is described by the supplied tag list.
  3453. *    As soon as a TRMS_ACTION message is sent by one of the objects,
  3454. *    the requester will close. If a project is supplied, it will be
  3455. *    locked when opening the requester and unlocked when closing it.
  3456. *
  3457. *   RESULT
  3458. *    selection - The ID of the object which triggered the action,
  3459. *                0 for an error, (ULONG)(-1) for the close gadget.
  3460. *
  3461. *   NOTES
  3462. *    Simple requesters with just text and buttons can be done easier
  3463. *    with TR_EasyRequest(). If you need more complex requesters, you
  3464. *    have to use your own message polling loop instead of
  3465. *    TR_AutoRequest(). You may still use the requester macros though.
  3466. *
  3467. *   SEE ALSO
  3468. *    TR_EasyRequest()
  3469. *
  3470. ******/
  3471.  
  3472. ULONG __saveds __asm TR_AutoRequest(register __a1 struct TR_App *app, register __a0 struct TR_Project *lockproject, register __a2 struct TagItem *request_trwintags)
  3473. {
  3474.   struct TR_Project *request_project;
  3475.   struct TR_Message *trmsg;
  3476.   ULONG id=0;
  3477.  
  3478.   if(!(request_project=TR_OpenProject(app,request_trwintags))) return 0;
  3479.   if(lockproject) TR_LockProject(lockproject);
  3480.  
  3481.   while(!id)
  3482.   {
  3483.     TR_Wait(app,0);
  3484.     while(trmsg=TR_GetMsg(app))
  3485.     {
  3486.       if(trmsg->trm_Project==request_project)
  3487.       {
  3488.         if(trmsg->trm_Class==TRMS_ACTION) id=trmsg->trm_ID;
  3489.         else if(trmsg->trm_Class==TRMS_CLOSEWINDOW) id=(ULONG)(-1);
  3490.       }
  3491.       TR_ReplyMsg(trmsg);
  3492.     }
  3493.   }
  3494.  
  3495.   if(lockproject) TR_UnlockProject(lockproject);
  3496.   TR_CloseProject(request_project);
  3497.  
  3498.   return id;
  3499. }
  3500.  
  3501.  
  3502. /****** triton.library/TR_EasyRequest ******
  3503. *
  3504. *   NAME    
  3505. *    TR_EasyRequest -- A high-level requester function.
  3506. *
  3507. *   SYNOPSIS
  3508. *    selection = TR_EasyRequest(App, BodyFmt, GadFmt, TagList)
  3509. *    D0                         A1   A2       A3      A0
  3510. *
  3511. *    ULONG TR_EasyRequest(struct TR_App *, STRPTR, STRPTR, struct TagItem *);
  3512. *
  3513. *    selection = TR_EasyRequestTags(App, BodyFmt, GadFmt, Tag,...)
  3514. *    D0
  3515. *
  3516. *    ULONG TR_EasyRequestTags(struct TR_App *, STRPTR, STRPTR, ULONG,...);
  3517. *
  3518. *   FUNCTION
  3519. *    Pops up a requester and waits for the user to select a gadget.
  3520. *
  3521. *   INPUTS
  3522. *    App       - A valid Triton application.
  3523. *    BodyFmt   - A multi-line text which will be displayed in the
  3524. *                requester body. See TR_PrintText() autodoc clip
  3525. *                for details about the formatting sequences.
  3526. *    GadFmt    - The gadget texts, separated by '|'.
  3527. *    TagList   - Pointer to a TagItem array.
  3528. *
  3529. *   TAGS
  3530. *    TREZ_ReqPos (ULONG) - The requester's position (TRWP_...).
  3531. *        The default is TRWP_MOUSEPOINTER.
  3532. *
  3533. *    TREZ_LockProject (struct TR_Project *) - This project will be
  3534. *        locked while the requester is displayed. Information about
  3535. *        screen and activity state of the requester are taken from
  3536. *        this project.
  3537. *
  3538. *    TREZ_Return (ULONG) - Number of the default gadget which can be
  3539. *        activated by <RETURN>. Defaults to 1 (0 in a single-gadget
  3540. *        requester).
  3541. *
  3542. *    TREZ_Title (STRPTR) - Requester window title. Default is "System
  3543. *        request" (or a localized version under OS2.1 and higher).
  3544. *
  3545. *    TREZ_Activate (BOOL) - If this tag is supplied, the activity
  3546. *        state of the requester window will be taken from this tag's
  3547. *        argument instead of being inherited from the locked project
  3548. *        (if applicable).
  3549. *
  3550. *    TRWI_PubScreen (struct Screen *) - A public screen on which the
  3551. *        window will be opened. The screen *must* have been locked.
  3552. *
  3553. *    TRWI_PubScreenName (STRPTR) - A public screen on which the window
  3554. *        will be opened. Triton will try to lock the screen with the
  3555. *        specified name. It will fall back onto the default public
  3556. *        screen in case the screen can't be found/locked.
  3557. *
  3558. *   RESULT
  3559. *    selection - The number of the selected gadget. The gadgets are
  3560. *                numbered from left to right beginning with 1. The
  3561. *                rightmost gadget (or the only gadget in a 1-gadget
  3562. *                requester) has got number 0. (ULONG)(-1) is returned
  3563. *                for indicating an error.
  3564. *
  3565. *   SEE ALSO
  3566. *    TR_AutoRequest(), TR_PrintText()
  3567. *
  3568. ******/
  3569.  
  3570. ULONG __saveds __asm TR_EasyRequest(register __a1 struct TR_App *app, register __a2 STRPTR bodyfmt, register __a3 STRPTR gadfmt, register __a0 struct TagItem *taglist)
  3571. {
  3572.   ULONG defid=1, retval=(ULONG)(-1), numgads;
  3573.   ULONG currentpos=26,gstrsize,wintagslen;
  3574.   struct TR_Project *lockproject=NULL;
  3575.   struct TagItem *tstate,*tag,*wintags;
  3576.   STRPTR copygadfmt=NULL;
  3577.   ULONG i,oldi,buttonnumber;
  3578.   BOOL activate=TRUE;
  3579.   BOOL ownactivate=FALSE;
  3580.   BOOL finished=FALSE;
  3581.   ULONG scrtype=TAG_IGNORE, scrdata;
  3582.  
  3583.   struct TagItem deftags[]=
  3584.   {
  3585.     /* Beginning */
  3586.     TRWI_Title, 0, // 0
  3587.     TRWI_Position, TRWP_MOUSEPOINTER, // 1
  3588.     TRWI_Flags, TRWF_NOZIPGADGET|TRWF_NOSIZEGADGET|TRWF_NOCLOSEGADGET|TRWF_NODELZIP|TRWF_NOESCCLOSE, // 2
  3589.     TRWI_Backfill, TRBF_REQUESTERBACK, // 3
  3590.     0,0, // 4
  3591.     TRGR_Vert, TRGR_ALIGN,
  3592.     TROB_Space, TRST_NORMAL,
  3593.     TRGR_Horiz, TRGR_ALIGN,
  3594.     TROB_Space, TRST_NORMAL,
  3595.     TROB_FrameBox, 0,
  3596.     TRAT_Backfill, TRBF_NONE,
  3597.     TRGR_Vert, TRGR_ALIGN,
  3598.     TROB_Space, TRST_NORMAL,
  3599.     /* Text */
  3600.     TRGR_Horiz, TRGR_PROPSPACES|TRGR_CENTER,
  3601.     TROB_Space, TRST_NORMAL,
  3602.     TROB_Text, 0,
  3603.     TRAT_Text, 0, // 16
  3604.     TRAT_Flags, TRTX_NOUNDERSCORE|TRTX_MULTILINE|TRTX_CENTER,
  3605.     TROB_Space, TRST_NORMAL,
  3606.     TRGR_End, 0,
  3607.     /* Intermediate */
  3608.     TROB_Space, TRST_NORMAL,
  3609.     TRGR_End, 0,
  3610.     TROB_Space, TRST_NORMAL,
  3611.     TRGR_End, 0,
  3612.     TROB_Space, TRST_NORMAL,
  3613.     TRGR_Horiz, TRGR_PROPSPACES|TRGR_CENTER
  3614.   };
  3615.  
  3616.   /* Calculate TagList length */
  3617.  
  3618.   numgads = TR_NumOccurances('|',gadfmt) + 1;
  3619.  
  3620.   /* Initialize TagList */
  3621.  
  3622.   wintagslen  = (35 + 5*numgads)*sizeof(struct TagItem);
  3623.   if(!(wintags=(struct TagItem *)TR_AllocPooled(app->tra_MemPool,wintagslen))) goto cleanup;
  3624.   CopyMem((APTR)(deftags),(APTR)(wintags),26*sizeof(struct TagItem));
  3625.   wintags[0].ti_Data = (ULONG)LOCSTR(MSG_SYSTEMREQUEST_TITLE);
  3626.   wintags[16].ti_Data = (ULONG)bodyfmt;
  3627.  
  3628.   /* Go through tags */
  3629.  
  3630.   if(taglist)
  3631.   {
  3632.     tstate=taglist;
  3633.     while(tag=NextTagItem(&tstate))
  3634.     {
  3635.       switch(tag->ti_Tag)
  3636.       {
  3637.         case TREZ_ReqPos:
  3638.       wintags[1].ti_Data = tag->ti_Data;
  3639.           break;
  3640.         case TREZ_LockProject:
  3641.           lockproject=(struct TR_Project *)(tag->ti_Data);
  3642.           break;
  3643.         case TREZ_Return:
  3644.           defid=tag->ti_Data;
  3645.           break;
  3646.         case TREZ_Activate:
  3647.           ownactivate=TRUE;
  3648.           activate=tag->ti_Data;
  3649.           break;
  3650.         case TREZ_Title:
  3651.       wintags[0].ti_Data = tag->ti_Data;
  3652.           break;
  3653.         case TRWI_PubScreen:
  3654.           scrtype=TRWI_PubScreen;
  3655.           scrdata=(ULONG)(tag->ti_Data);
  3656.           break;
  3657.         case TRWI_PubScreenName:
  3658.           scrtype=TRWI_PubScreenName;
  3659.           scrdata=(ULONG)(tag->ti_Data);
  3660.       }
  3661.     }
  3662.   }
  3663.  
  3664.   if(lockproject)
  3665.   {
  3666.     if(scrtype==TAG_IGNORE)
  3667.       {
  3668.     scrtype=TRWI_CustomScreen;
  3669.     scrdata=(ULONG)(lockproject->trp_Window->WScreen);
  3670.       }
  3671.     if(!ownactivate) if(!(lockproject->trp_Window->Flags&WFLG_WINDOWACTIVE)) activate=FALSE;
  3672.   }
  3673.  
  3674.   /* Make a copy of the gadget format string */
  3675.  
  3676.   gstrsize=TR_FirstOccurance(0L,gadfmt)+1;
  3677.   if(!(copygadfmt=(STRPTR)TR_AllocPooled(app->tra_MemPool,gstrsize))) goto cleanup;
  3678.   CopyMem((APTR)(gadfmt),(APTR)(copygadfmt),gstrsize);
  3679.  
  3680.   /* Fill in the tag list */
  3681.  
  3682.   if(!activate) wintags[2].ti_Data |= TRWF_NOACTIVATE;
  3683.   wintags[4].ti_Tag    = scrtype;
  3684.   wintags[4].ti_Data = scrdata;
  3685.  
  3686.   /* Build tag list: Gadgets */
  3687.  
  3688.   if(numgads>1)
  3689.   {
  3690.     wintags[currentpos].ti_Tag    = TRGR_Horiz;
  3691.     wintags[currentpos++].ti_Data = TRGR_FIXHORIZ;
  3692.   }
  3693.  
  3694.   wintags[currentpos].ti_Tag    = TROB_Space;
  3695.   wintags[currentpos++].ti_Data = TRST_NORMAL;
  3696.  
  3697.   if(numgads>1) wintags[currentpos++].ti_Tag    = TRGR_End;
  3698.  
  3699.   if(!defid) defid=numgads;
  3700.   for(i=0,buttonnumber=1;;buttonnumber++)
  3701.   {
  3702.     wintags[currentpos++].ti_Tag  = TROB_Button;
  3703.     wintags[currentpos].ti_Tag    = TRAT_Flags;
  3704.     if(buttonnumber==numgads) wintags[currentpos].ti_Data |= TRBU_ESCOK;
  3705.     if(buttonnumber==defid) wintags[currentpos].ti_Data |= TRBU_RETURNOK;
  3706.     currentpos++;
  3707.     wintags[currentpos].ti_Tag    = TRAT_Text;
  3708.     wintags[currentpos++].ti_Data = (ULONG)(&(copygadfmt[i]));
  3709.     wintags[currentpos].ti_Tag    = TRAT_ID;
  3710.     wintags[currentpos++].ti_Data = buttonnumber;
  3711.  
  3712.     oldi=i;
  3713.     if((i=TR_FirstOccurance('|',©gadfmt[i]))==(ULONG)(-1))
  3714.       {
  3715.     finished=TRUE;
  3716.     if(numgads>1)
  3717.       {
  3718.         wintags[currentpos].ti_Tag    = TRGR_Horiz;
  3719.         wintags[currentpos++].ti_Data = TRGR_FIXHORIZ;
  3720.       }
  3721.       }
  3722.  
  3723.     wintags[currentpos].ti_Tag    = TROB_Space;
  3724.     wintags[currentpos++].ti_Data = TRST_NORMAL;
  3725.  
  3726.     if(numgads>1) if(finished) wintags[currentpos++].ti_Tag = TRGR_End;
  3727.  
  3728.     if(finished) break;
  3729.     i+=oldi;
  3730.     copygadfmt[i++]=0;
  3731.   }
  3732.  
  3733.   /* Build tag list: End */
  3734.  
  3735.   wintags[currentpos++].ti_Tag  = TRGR_End;
  3736.   wintags[currentpos].ti_Tag    = TROB_Space;
  3737.   wintags[currentpos++].ti_Data = TRST_NORMAL;
  3738.   wintags[currentpos++].ti_Tag  = TRGR_End;
  3739.   wintags[currentpos].ti_Tag    = TAG_END;
  3740.  
  3741.   /* The best, the rest, the rare */
  3742.  
  3743.   retval=TR_AutoRequest(app, lockproject, wintags);
  3744.  
  3745. cleanup:
  3746.   if(copygadfmt) TR_FreePooled(app->tra_MemPool,(void *)copygadfmt,gstrsize);
  3747.   if(wintags) TR_FreePooled(app->tra_MemPool,(void *)wintags,wintagslen);
  3748.  
  3749.   if(retval==numgads) return 0;
  3750.   else if(retval==0) return (ULONG)(-1);
  3751.   else return retval;
  3752. }
  3753.  
  3754.  
  3755. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3756. ///////////////////////////////////////////////////////////////////////////////////////// Prefs management //
  3757. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3758.  
  3759. VOID __regargs __inline TR_SaveAppInfos(struct TR_App *app)
  3760. {
  3761.   BPTR lock;
  3762.   ULONG val;
  3763.   UBYTE filename[40];
  3764.  
  3765.   /* Abort if env:Triton doesn't exist or if the application is unnamed */
  3766.   if((!(app->tra_Name))||(!(*(app->tra_Name)))) return;
  3767.   if(lock=Lock("env:Triton",ACCESS_READ)) UnLock(lock); else return;
  3768.  
  3769.   TR_SPrintF(filename,"env:Triton/%s.app",app->tra_Name);
  3770.  
  3771.   if(!(lock=Open(filename,MODE_NEWFILE))) {DisplayBeep(NULL); return;}
  3772.  
  3773.   val=TR_FirstOccurance(0,app->tra_Name);
  3774.   FWrite(lock,(STRPTR)(&val),4,1);
  3775.   FWrite(lock,app->tra_Name,val,1);
  3776.  
  3777.   val=TR_FirstOccurance(0,app->tra_LongName);
  3778.   FWrite(lock,(STRPTR)(&val),4,1);
  3779.   if(val) FWrite(lock,app->tra_LongName,val,1);
  3780.  
  3781.   val=TR_FirstOccurance(0,app->tra_Info);
  3782.   FWrite(lock,(STRPTR)(&val),4,1);
  3783.   if(val) FWrite(lock,app->tra_Info,val,1);
  3784.  
  3785.   val=TR_FirstOccurance(0,app->tra_Version);
  3786.   FWrite(lock,(STRPTR)(&val),4,1);
  3787.   if(val) FWrite(lock,app->tra_Version,val,1);
  3788.  
  3789.   val=TR_FirstOccurance(0,app->tra_Release);
  3790.   FWrite(lock,(STRPTR)(&val),4,1);
  3791.   if(val) FWrite(lock,app->tra_Release,val,1);
  3792.  
  3793.   val=TR_FirstOccurance(0,app->tra_Date);
  3794.   FWrite(lock,(STRPTR)(&val),4,1);
  3795.   if(val) FWrite(lock,app->tra_Date,val,1);
  3796.  
  3797.   Close(lock);
  3798. }
  3799.  
  3800.  
  3801. VOID __regargs __inline TR_LoadTritonPrefs(struct TR_App *app)
  3802. {
  3803.   BPTR lock;
  3804.   UBYTE filename[40];
  3805.   struct TR_AppPrefs loadedprefs;
  3806.  
  3807.   if((!(app->tra_Name))||(!(*(app->tra_Name)))) return;
  3808.  
  3809.   if(!(app->tra_Prefs=TR_AllocPooled(app->tra_MemPool,sizeof(struct TR_AppPrefs))))
  3810.   {
  3811.     DisplayBeep(NULL);
  3812.     return;
  3813.   }
  3814.  
  3815.   CopyMem(&TR_DefaultAppPrefs,app->tra_Prefs,sizeof(struct TR_AppPrefs));
  3816.   ((struct TR_AppPrefs *)(app->tra_Prefs))->pubscreen[0]=1;
  3817.   ((struct TR_AppPrefs *)(app->tra_Prefs))->pubscreen[1]=0;
  3818.  
  3819.   TR_SPrintF(filename,"env:Triton/%s.tri",app->tra_Name);
  3820.   if(!(lock=Open(filename,MODE_OLDFILE))) lock=Open("env:Triton/__GLOBAL__.tri",MODE_OLDFILE);
  3821.   if(lock)
  3822.   {
  3823.     if(FRead(lock,(STRPTR)(&loadedprefs),sizeof(struct TR_AppPrefs),1))
  3824.     {
  3825.       CopyMem((void *)(&loadedprefs),
  3826.           (void *)(app->tra_Prefs),sizeof(struct TR_AppPrefs));
  3827.     }
  3828.     Close(lock);
  3829.   }
  3830. }
  3831.  
  3832.  
  3833. VOID __regargs __inline TR_SaveWindowDimensions(struct TR_Project *project)
  3834. {
  3835.   BPTR lock;
  3836.   ULONG val;
  3837.   UBYTE filename[46];
  3838.  
  3839.   if(!(project->trp_ID)) return;
  3840.   if((!(project->trp_App->tra_Name))||(!(*(project->trp_App->tra_Name)))) return;
  3841.   if(lock=Lock("env:Triton",ACCESS_READ)) UnLock(lock); else return;
  3842.  
  3843.   TR_SPrintF(filename,"env:Triton/%s.win.%ld",project->trp_App->tra_Name,project->trp_ID);
  3844.  
  3845.   if(!(lock=Open(filename,MODE_NEWFILE))) return;
  3846.   FWrite(lock,(STRPTR)(project->trp_Dimensions),sizeof(struct TR_Dimensions),1);
  3847.  
  3848.   if(project->trp_Window->Title)
  3849.   {
  3850.     val=TR_FirstOccurance(0,project->trp_Window->Title);
  3851.     FWrite(lock,(STRPTR)(&val),4,1);
  3852.     FWrite(lock,project->trp_Window->Title,val,1);
  3853.   }
  3854.   else { val=0; FWrite(lock,(STRPTR)(&val),4,1); }
  3855.  
  3856.   Close(lock);
  3857. }
  3858.  
  3859.  
  3860. VOID __regargs __inline TR_LoadWindowDimensions(struct TR_Project *project)
  3861. {
  3862.   BPTR lock;
  3863.   UBYTE filename[46];
  3864.  
  3865.   if(!(project->trp_ID)) return;
  3866.   if((!(project->trp_App->tra_Name))||(!(*(project->trp_App->tra_Name)))) return;
  3867.   if(lock=Lock("env:Triton",ACCESS_READ)) UnLock(lock); else return;
  3868.  
  3869.   TR_SPrintF(filename,"env:Triton/%s.win.%ld",project->trp_App->tra_Name,project->trp_ID);
  3870.  
  3871.   if(!(lock=Open(filename,MODE_OLDFILE))) return;
  3872.   FRead(lock,(STRPTR)(project->trp_Dimensions),sizeof(struct TR_Dimensions),1);
  3873.   Close(lock);
  3874. }
  3875.  
  3876.  
  3877. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3878. //////////////////////////////////////////////////////////////////////////////////// Public screen support //
  3879. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3880.  
  3881. struct Screen * __regargs __inline TR_OpenScreen(struct TR_ScreenNode *sn)
  3882. {
  3883.   UWORD pens[]={(UWORD)(~0)};
  3884.   struct Screen *scr;
  3885.  
  3886.   if(scr=OpenScreenTags(NULL,
  3887.     SA_LikeWorkbench, TRUE,
  3888.     SA_Title,         sn->title,
  3889.     SA_Depth,         sn->depth,
  3890.     SA_Type,          PUBLICSCREEN,
  3891.     SA_DisplayID,     sn->screenmode,
  3892.     SA_PubName,       sn->pubname,
  3893.     SA_AutoScroll,    TRUE,
  3894.     SA_Pens,          pens,
  3895.     SA_FullPalette,   TRUE,
  3896.     TAG_DONE))
  3897.   {
  3898.     PubScreenStatus(scr,0);
  3899.     sn->screen=scr;
  3900.     Forbid();
  3901.     AddTail((struct List *)&(TR_Global.trg_ScreenList),(struct Node *)sn);
  3902.     Permit();
  3903.   }
  3904.  
  3905.   return scr;
  3906. }
  3907.  
  3908.  
  3909. struct Screen * __regargs __inline TR_LockPubScreen(STRPTR name)
  3910. {
  3911.   struct Screen *scr,*openedscreen=NULL;
  3912.   BPTR lock;
  3913.   struct TR_ScreenNode *node;
  3914.   ULONG dummy;
  3915.   BOOL got_one;
  3916.  
  3917.   if(scr=LockPubScreen(name)) return scr;
  3918.  
  3919.   if(node=(struct TR_ScreenNode *)AllocPooled(TR_Global.trg_ScreenListPool,sizeof(struct TR_ScreenNode)))
  3920.   {
  3921.     if(lock=Open("env:Triton/Screens.trc",MODE_OLDFILE))
  3922.     {
  3923.       FRead(lock,(STRPTR)(&dummy),4,1);
  3924.       while(got_one=(BOOL)FRead(lock,(STRPTR)(node),sizeof(struct TR_ScreenNode),1))
  3925.       {
  3926.         if(!TR_StrCmp(name,node->pubname)) break;
  3927.       }
  3928.       Close(lock);
  3929.       if(got_one)
  3930.       {
  3931.         openedscreen=TR_OpenScreen(node);
  3932.         if(!(scr=LockPubScreen(node->pubname)))
  3933.     {
  3934.       CloseScreen(openedscreen);
  3935.       openedscreen=NULL;
  3936.     }
  3937.       }
  3938.       if(!openedscreen) TR_FreePooled(TR_Global.trg_ScreenListPool,(void *)node,sizeof(struct TR_ScreenNode));
  3939.     }
  3940.   }
  3941.  
  3942.   return scr;
  3943. }
  3944.  
  3945.  
  3946. VOID __regargs __inline TR_UnlockPubScreen(struct Screen *scr)
  3947. {
  3948.   struct TR_ScreenNode *screennode;
  3949.  
  3950.   UnlockPubScreen(NULL,scr);
  3951.  
  3952.   for(screennode=(struct TR_ScreenNode *)(TR_Global.trg_ScreenList.mlh_Head);
  3953.       screennode->node.ln_Succ;
  3954.       screennode=(struct TR_ScreenNode *)(screennode->node.ln_Succ))
  3955.   {
  3956.     if(scr==screennode->screen)
  3957.     {
  3958.       TR_CloseScreen(screennode);
  3959.       return;
  3960.     }
  3961.   }
  3962. }
  3963.  
  3964.  
  3965. BOOL __regargs TR_CloseScreen(struct TR_ScreenNode *sn)
  3966. {
  3967.   struct Screen *screen;
  3968.  
  3969.   if(screen=LockPubScreen(sn->pubname))
  3970.   {
  3971.     UnlockPubScreen(NULL,screen);
  3972.     if(PubScreenStatus(screen,PSNF_PRIVATE)&1) /*-- Only needed because of a bug in KCommodity */
  3973.     {
  3974.       if(CloseScreen(screen))
  3975.       {
  3976.         Forbid();
  3977.         Remove((struct Node *)sn);
  3978.         Permit();
  3979.         TR_FreePooled(TR_Global.trg_ScreenListPool,(void *)sn,sizeof(struct TR_ScreenNode));
  3980.         return TRUE;
  3981.       }
  3982.     }
  3983.   }
  3984.   return FALSE;
  3985. }
  3986.  
  3987.  
  3988. VOID __regargs __inline TR_RemoveScreens(VOID)
  3989. {
  3990.   struct TR_ScreenNode *screennode;
  3991.  
  3992.   /* This function is only called during library expunge. Thus it is not necessary
  3993.      to protect access to the screen list by disabling the multi-tasking scheduler. */
  3994.  
  3995.   for(screennode=(struct TR_ScreenNode *)(TR_Global.trg_ScreenList.mlh_Head);
  3996.       screennode->node.ln_Succ;
  3997.       screennode=(struct TR_ScreenNode *)(screennode->node.ln_Succ))
  3998.     TR_CloseScreen(screennode);
  3999.  
  4000.   if(TR_Global.trg_ScreenListPool) TR_DeletePool(TR_Global.trg_ScreenListPool);
  4001. }
  4002.  
  4003.  
  4004. /****** triton.library/TR_LockScreen ******
  4005. *
  4006. *   NAME    
  4007. *    TR_LockScreen -- Get a project's screen
  4008. *
  4009. *   SYNOPSIS
  4010. *    screen = TR_LockScreen(Project)
  4011. *    D0                     A0
  4012. *
  4013. *    struct Screen * TR_LockScreen(struct TR_Project *);
  4014. *
  4015. *   FUNCTION
  4016. *    Lock the screen of a Triton project for use with non-Triton
  4017. *    windows (e.g. for opening a file requester on the screen of a
  4018. *    Triton application). The screen must be unlocked later with
  4019. *    TR_UnlockScreen(). Locking/unlocking calls are nested.
  4020. *
  4021. *   RESULT
  4022. *    screen - Pointer to the project's screen or NULL to indicate an
  4023. *             error. In this case the application should *not* abort,
  4024. *             but *quietly* use another screen (preferably the
  4025. *             Workbench screen) instead.
  4026. *
  4027. *   SEE ALSO
  4028. *    TR_UnlockScreen()
  4029. *
  4030. ******/
  4031.  
  4032. struct Screen * __asm __saveds TR_LockScreen(register __a0 struct TR_Project *project)
  4033. {
  4034.   return project->trp_Screen;
  4035. }
  4036.  
  4037.  
  4038. /****** triton.library/TR_UnlockScreen ******
  4039. *
  4040. *   NAME    
  4041. *    TR_UnlockScreen -- Release a project's screen
  4042. *
  4043. *   SYNOPSIS
  4044. *    TR_UnlockScreen(Screen)
  4045. *                    A0
  4046. *
  4047. *    VOID TR_UnlockScreen(struct Screen *);
  4048. *
  4049. *   FUNCTION
  4050. *    Unlock a screen which has been locked by TR_LockScreen(). All
  4051. *    locked screens must be unlocked! Locking/unlocking calls are
  4052. *    nested.
  4053. *
  4054. *   SEE ALSO
  4055. *    TR_LockScreen()
  4056. *
  4057. ******/
  4058.  
  4059. VOID __asm __saveds TR_UnlockScreen(register __a0 struct Screen *screen)
  4060. {
  4061. }
  4062.