home *** CD-ROM | disk | FTP | other *** search
/ Executor 2.0 / executorv2.0.iso / pc / dos / extra / source / browser / browser.hqx / Browser / initicons.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-06  |  12.9 KB  |  516 lines

  1. #include "go.h"
  2. #include "display.h"
  3. #include "xfer.h"
  4. #include "fontda.h"
  5. #include <assert.h>
  6.  
  7. #include "initicons.proto.h"
  8. #include "sharedtransfer.proto.h"
  9.  
  10. #include "bndl.h"
  11.  
  12. icontableentry **icontable[ICONTABLESIZE];
  13. icn_sharp_hand g_foldericons, g_diskicons;
  14. applist **sigowners[TEXTEDITORPOS + 1];
  15.  
  16. /* NOTE: the default doc must be the last item.  Its type should really be special
  17.    cased, but it's the default anyway so if a document has a goofy filetype
  18.    it will get the correct information regardless.
  19.  */
  20.  
  21. typeinfo typearray[] =
  22. {
  23.   'ffil', FONTBAND, NOACTION, FONTICONNUM, 0,
  24.   'FFIL', FONTBAND, NOACTION, FONTSCICONNUM, 0,
  25.   'tfil', FONTBAND, NOACTION, TTFONTICONNUM, 0,
  26.   'dfil', DABAND, OPENDA, DAICONNUM, 0,
  27.   'DFIL', DABAND, OPENDA, DASCICONNUM, 0,
  28.   'APPL', APPBAND, LAUNCH, DEFAULTAPPLICONNUM, 0,
  29.   
  30.   /* NOTE: TEXT, ttro and PICT are special cased in launch.c */
  31.   'TEXT', DOCBAND, LAUNCHCREATOR, DEFAULTTEXTICONNUM, 0,
  32.   'ttro', DOCBAND, LAUNCHCREATOR, DEFAULTTEXTICONNUM, 0,
  33.   'PICT', DOCBAND, LAUNCHCREATOR, DEFAULTTEXTICONNUM, 0,
  34.  
  35.   '|!@$', DOCBAND, LAUNCHCREATOR, DEFAULTDOCICONNUM, 0,
  36. };
  37.  
  38. static long
  39. get_filenum (short vrefnum, long parid, Str255 s)
  40. {
  41.   CInfoPBRec cpb;
  42.   Str255 s2;
  43.   OSErr e;
  44.   
  45.   mystr255copy (s2, s);
  46.   cpb.dirInfo.ioNamePtr = s2;
  47.   cpb.dirInfo.ioVRefNum = vrefnum;
  48.   cpb.dirInfo.ioDrDirID = parid;
  49.   cpb.dirInfo.ioFDirIndex = 0;
  50.   e = PBGetCatInfo (&cpb, false);
  51.   
  52.   return e == noErr ? cpb.dirInfo.ioDrDirID : -1;
  53. }
  54.  
  55. ControlHandle
  56. getnewiconcontrol (WindowPtr wp, char **path, long parid,
  57.            short vrefnum, Str255 s, short view)
  58. {
  59.   item **h;
  60.   Rect r;
  61.   ControlHandle c;
  62.   long filenum;
  63.   
  64.   filenum = get_filenum (vrefnum, parid, s);
  65.  
  66.   SetRect (&r, 0, 0, ICONWIDTHUSED, ICONHEIGHTUSED);
  67.   c = NewControl (wp, &r, s, false, 0, 0, 0, ICONCONTROL, 0);
  68.   h = (item **) NewHandle (sizeof (item));
  69.   (*h)->path = path;
  70.   (*h)->ioparid = parid;
  71.   (*h)->filenum = filenum;
  72.   (*h)->vrefnum = vrefnum;
  73.   (*h)->selected = false;
  74.   (*h)->view = view;
  75.   (*c)->contrlRfCon = 0L;
  76.   (*c)->contrlData = (Handle) h;
  77. #ifdef THINK_C
  78.   (*c)->contrlAction = (ProcPtr) -1L;
  79. #else
  80.   (*c)->contrlAction = (ControlActionUPP) -1L;
  81. #endif
  82.   return c;
  83. }
  84.  
  85. #if 0
  86.  
  87. #define NOTFOUND    -1
  88. short
  89. localidlookup (short localid, iconentry ** iconarray, short n)
  90. {
  91.   short i;
  92.  
  93.   for (i = 0; i < n; i++)
  94.     if ((*iconarray)[i].localid == localid)
  95. /*-->*/ return i;
  96.   return NOTFOUND;
  97. /* TODO: ALERT */
  98. }
  99.  
  100. void
  101. dobundle (short *spacemade, iconentry *** iconarray, char **h)
  102. {
  103. /* todo: get rid of the *h += n stuff and make a datatype */
  104.   short k, pos, numentries;
  105.   ResType type;
  106.   identry *idarray;
  107.   Handle h2;
  108.  
  109.   type = *(OSType *) *h;
  110.   *h += 4;
  111.   numentries = *(short *) *h + 1;
  112.   *h += 2;
  113.   if (*spacemade == 0)
  114.     {
  115.       *iconarray = (iconentry **) NewHandle (numentries * sizeof (iconentry));
  116.       *spacemade = numentries;
  117.       idarray = (identry *) *h;
  118.       if (type == 'ICN#')
  119.     {
  120.       for (k = 0; k < numentries; k++)
  121.         {
  122.           (**iconarray)[k].resid = idarray[k].resid;
  123.           (**iconarray)[k].localid = idarray[k].localid;
  124.         }
  125.     }
  126.       else if (type == 'FREF')
  127.     {
  128.       for (k = 0; k < numentries; k++)
  129.         {
  130.           h2 = (Handle) Get1Resource ('FREF', idarray[k].resid);
  131.           if (h2 && GetHandleSize (h2) >= 7)
  132.             {
  133.           (**iconarray)[k].type = *(OSType *) *h2;
  134.           (**iconarray)[k].localid = *(short *) (*h2 + 4);
  135.         }
  136.           else
  137.             {
  138.               /* What should *REALLY* be done here? */
  139.           (**iconarray)[k].type = 0;
  140.           (**iconarray)[k].localid = -1;
  141.             }
  142.           ReleaseResource (h2);
  143.         }
  144.     }
  145.       else
  146.     {
  147. /* there shouldn't be any other types */
  148.       assert (0);
  149.       /* ALERT */
  150.     }
  151.       *h += numentries * sizeof (identry);
  152.     }
  153.   else
  154.     {
  155. #if 0
  156. /* todo: find out if this assert can ever fail */
  157. /* It can, but the code should work anyways.  This should be looked into further. */
  158.       assert (*spacemade == numentries);
  159. #endif /* 0 */
  160.       idarray = (identry *) * h;
  161.       if (type == 'ICN#')
  162.     {
  163.       for (k = 0; k < numentries; k++)
  164.         {
  165.           pos = localidlookup (idarray[k].localid, *iconarray, *spacemade);
  166.           if (pos != NOTFOUND)
  167.         (**iconarray)[pos].resid = idarray[k].resid;
  168.         }
  169.     }
  170.       else if (type == 'FREF')
  171.     {
  172.       for (k = 0; k < numentries; k++)
  173.         {
  174. /*
  175.  * It is my understanding the first two bytes mean nothing.  IMVI says they must be
  176.  * unique, but doesn't use them, but keeps them in for backwards compatibility.  They
  177.  * are local fref ids
  178.  */
  179.           h2 = (Handle) Get1Resource ('FREF', idarray[k].resid);
  180.           if (h2 && GetHandleSize (h2) >= 7)
  181.             pos = localidlookup (*(short *) (*h2 + 4), *iconarray, *spacemade);
  182.           else
  183.             pos = NOTFOUND;
  184.           if (pos != NOTFOUND)
  185.         (**iconarray)[pos].type = *(ResType *) * h2;
  186.           ReleaseResource (h2);
  187.         }
  188.     }
  189.       else
  190. /* there shouldn't be any other types */
  191.     assert (0);
  192.       *h += numentries * sizeof (identry);
  193.     }
  194. }
  195. #undef NOTFOUND
  196.  
  197. #endif
  198.  
  199. typeinfo *
  200. gettypeinfo (OSType type)
  201. {
  202.   short i;
  203.  
  204.   for (i = 0; i < NELEM (typearray); i++)
  205.     if (type == typearray[i].filetype)
  206.       return &typearray[i];
  207.   return &typearray[NELEM (typearray) - 1];
  208. }
  209.  
  210. #define resCompressed 1
  211.  
  212. static Handle
  213. Get1NonCompressedResource (ResType type, INTEGER id)
  214. {
  215.   Handle retval;
  216.   INTEGER attrs;
  217.   
  218.   retval = Get1Resource (type, id);
  219.  
  220. /*
  221.  * It's not clear how we're supposed to detect and deal with compressed
  222.  * resources.  FIlemakerPro's install disk has an installer whose icl8 icons
  223.  * are listed by ResEdit as being compressed.  Those icons also have bit 0
  224.  * turned on, and bit 0 isn't assigned to anything.  So I decided that bit 0
  225.  * is now used to denote compression, and perhaps it is.  However, an old
  226.  * copy of FoxBASE had some ICN#s with that bit set that clearly weren't
  227.  * compressed.  After much head scratching, I've decided to just arbitrarily
  228.  * say that ICN#'s are never compressed.  This may be what the Mac does, it
  229.  * may not, but I don't have a good way to test.  --ctm 95-07-05
  230.  *
  231.  * Update: it appears that the files which truly have compressed resources
  232.  * also have 'dcmp' resources, so our new test checks to see if there are any
  233.  * 'dcmp's and the comment about ICN# is no longer correct.
  234.  */
  235.  
  236.   attrs = GetResAttrs (retval);
  237.   if ((attrs & resCompressed) && Count1Resources ('dcmp') > 0)
  238.     retval = 0;
  239.   return retval;
  240. }
  241.  
  242. icn_sharp_hand
  243. read_icn_sharp (short id)
  244. {
  245.   icn_sharp_hand retval;
  246.   Handle h;
  247.   SignedByte state;
  248.  
  249. #define geticonhandle(field, type)        \
  250.     h = (Handle) Get1NonCompressedResource(type, id);    \
  251.     HandToHand(&h);                \
  252.     (*retval)->field = h;
  253.     
  254.   retval = (icn_sharp_hand) NewHandle (sizeof (**retval));
  255.  
  256.   HLock ((Handle) retval);
  257.   geticonhandle (icnsh, 'ICN#');
  258.   geticonhandle (icssh, 'ics#');
  259.   geticonhandle (icl8, 'icl8');
  260.   geticonhandle (icl4, 'icl4');
  261.   geticonhandle (ics8, 'ics8');
  262.   geticonhandle (ics4, 'ics4');
  263.   HUnlock ((Handle) retval);
  264.  
  265.   if (!((*retval)->icnsh || (*retval)->icl8 || (*retval)->icl4))
  266.     {
  267.       DisposHandle ((Handle) retval);
  268.       retval = 0;
  269.     }
  270.  
  271.   return retval;
  272. #undef    geticonhandle
  273. }
  274.  
  275. void
  276. inithash (void)
  277. {
  278.   short i;
  279.   icontableentry **node;
  280.  
  281.   g_foldericons = read_icn_sharp (FOLDERICONNUM);
  282.   HLock ((Handle) g_foldericons);
  283.  
  284.   g_diskicons = read_icn_sharp (DISKICONNUM);
  285.   HLock ((Handle) g_diskicons);
  286.  
  287.   for (i = 0; i < ICONTABLESIZE; i++)
  288.     icontable[i] = 0;
  289.   for (i = 0; i < NELEM (typearray); i++)
  290.     {
  291.       typearray[i].iconh = read_icn_sharp (typearray[i].iconid);
  292.     }
  293.   for (i = 0; i < SIGARRAYSIZE; i++)
  294.     sigowners[i] = 0;
  295. }
  296.  
  297. #if 0
  298. icontableentry **
  299. gethash (OSType type, OSType creator)
  300. {
  301.   unsigned short hashval;
  302.   icontableentry **np;
  303.  
  304.   hashval = ((unsigned long) type + (unsigned long) creator) % ICONTABLESIZE;
  305.   for (np = icontable[hashval]; np != 0; np = (*np)->next)
  306.     {
  307.       if (((*np)->type == type) && ((*np)->sig == creator))
  308.     return np;
  309.     }
  310.  
  311.   return gettypeinfo (type)->iconh;
  312. }
  313.  
  314. static boolean_t
  315. at_least_one_icon_p (icontableentry **node)
  316. {
  317.   icontableentry *p;
  318.   
  319.   p = *node;
  320.   return (p->icnsh || p->icl8 || p->icl4);
  321.       /* No need to test these: && (p->icssh || p->ics8 || p->ics4); */
  322. }
  323. #endif
  324.  
  325. void
  326. hashicons (ControlHandle c)
  327. {
  328. /* todo: worry about filenames in FREFs */
  329.   /* get FREF, BNDL, ICN#, ics#, icl8, ics8, icl4, ics4 */
  330.   /* BNDL is:
  331.      4 bytes of signature
  332.      2 bytes of 0 [signature resource id?]
  333.      2 bytes of <number of main entries - 1> (almost always 1)
  334.      numberofmainentries *
  335.      4 bytes of 'ICN#' or 'FREF'
  336.      2 bytes of <number of entries - 1>
  337.      numberofentries *
  338.      2 bytes of localid
  339.      2 bytes of resid
  340.    */
  341. /* todo: see what happens with multiple BNDLs */
  342.  
  343.   char *p;
  344.   short i, j, spacemade, nummain, numbndls;
  345.   unsigned short hashval;
  346.   iconentry **iconarray;
  347.   icontableentry **node;
  348.   Handle h;
  349.   OSType signature;
  350.   short refnum, sigid;
  351.   unsigned char state;
  352.   applist **ah;
  353.  
  354.   refnum = openappres (c);
  355.   numbndls = Count1Resources ('BNDL');
  356.   for (i = 1; i <= numbndls; i++)
  357.     {
  358.       bndl_t **bndl;
  359.       
  360.       h = (Handle) Get1IndResource ('BNDL', i);
  361.       bndl = (bndl_t **) h;
  362.       process_bndl (bndl, (*bndl)->owner);
  363.       state = HGetState (h);
  364.       HLock (h);
  365.       p = *h;
  366.       signature = *(OSType *) p;
  367.       p += 4;
  368.       sigid = *(short *) p;
  369.       p += 2;
  370.  
  371.       hashval = (unsigned long) signature % SIGARRAYSIZE;
  372. #define CONTROLPROBLEMS
  373. #ifndef CONTROLPROBLEMS
  374.       for (ah = sigowners[hashval]; ah != 0 && (*ah)->sig != signature; ah = (*ah)->next)
  375.     ;
  376.       if (ah == 0)
  377.     {
  378. #endif /* CONTROLPROBLEMS */
  379.       ah = sigowners[hashval];
  380.       sigowners[hashval] = (applist **) NewHandle (sizeof (applist));
  381.       (*sigowners[hashval])->next = ah;
  382.       (*sigowners[hashval])->parid = (*(item **) (*c)->contrlData)->ioparid;
  383.       (*sigowners[hashval])->vrefnum = (*(item **) (*c)->contrlData)->vrefnum;
  384.       (*sigowners[hashval])->sig = signature;
  385.       mystr255copy ((*sigowners[hashval])->name, (*c)->contrlTitle);
  386. #ifndef CONTROLPROBLEMS
  387.     }
  388. #endif /* CONTROLPROBLEMS */
  389.  
  390. #if 0
  391. /* todo: find out if nummain must == 2 */
  392.       nummain = *(short *) p + 1;
  393.       p += 2;
  394.  
  395.       spacemade = 0;
  396.       for (j = 0; j < nummain; j++)
  397.     {
  398.       dobundle (&spacemade, &iconarray, &p);
  399.     }
  400.  
  401.       for (j = 0; j < spacemade; j++)
  402.     {
  403.       hashval = ((unsigned long) signature + (unsigned long) (*iconarray)[j].type)
  404.         % ICONTABLESIZE;
  405.       for (node = icontable[hashval]; node != 0 &&
  406.            ((*node)->sig != signature || (*node)->type != (*iconarray)[j].type);
  407.            node = (*node)->next)
  408.         ;
  409.       if (node == 0)
  410.         {
  411.           node = (icontableentry **) NewHandle (sizeof (icontableentry));
  412.           (*node)->sig = signature;
  413.           (*node)->type = (*iconarray)[j].type;
  414.           geticons (node, (*iconarray)[j].resid);
  415.           if (at_least_one_icon_p (node))
  416.             {
  417.               (*node)->next = icontable[hashval];
  418.               icontable[hashval] = node;
  419.             }
  420.           else
  421.             DisposHandle ((Handle) node);
  422.         }
  423.     }
  424.       DisposHandle ((Handle) iconarray);
  425.       HSetState (h, state);
  426.       ReleaseResource (h);
  427. #endif
  428.     }
  429.   CloseResFile (refnum);
  430. }
  431.  
  432. void
  433. setoneicon (ControlHandle c)
  434. {
  435.   CInfoPBRec pb;
  436.   item **ih;
  437.   typeinfo *tip;
  438.  
  439.   ih = (item **) (*c)->contrlData;
  440.   pb.hFileInfo.ioFDirIndex = 0;
  441.   pb.hFileInfo.ioVRefNum = (*ih)->vrefnum;
  442.   pb.hFileInfo.ioDirID = (*ih)->ioparid;
  443.   pb.hFileInfo.ioNamePtr = (*c)->contrlTitle;
  444.   PBGetCatInfo (&pb, false);
  445.   if (pb.hFileInfo.ioFlAttrib & DIRBIT)
  446.     {
  447.       (*ih)->iconfam = g_foldericons;
  448.       (*ih)->action = OPENDIR;
  449.       (*ih)->size = 0;
  450.       (*ih)->moddate = pb.dirInfo.ioDrMdDat;
  451.     }
  452.   else
  453.     {
  454.       (*ih)->iconfam = map_type_and_creator (pb.hFileInfo.ioFlFndrInfo.fdType,
  455.                 pb.hFileInfo.ioFlFndrInfo.fdCreator);
  456.       if (!(*ih)->iconfam)
  457.         (*ih)->iconfam = (gettypeinfo (pb.hFileInfo.ioFlFndrInfo.fdType))->iconh;
  458.       tip = gettypeinfo (pb.hFileInfo.ioFlFndrInfo.fdType);
  459.       (*ih)->action = tip->action;
  460.       (*ih)->size = pb.hFileInfo.ioFlLgLen + pb.hFileInfo.ioFlRLgLen;
  461.       (*ih)->moddate = pb.hFileInfo.ioFlMdDat;
  462.       (*ih)->sig = pb.hFileInfo.ioFlFndrInfo.fdCreator;
  463.       (*ih)->type = pb.hFileInfo.ioFlFndrInfo.fdType;
  464.     }
  465. }
  466.  
  467. void
  468. seticons (void)
  469. {
  470.   bandinfo *b;
  471.   short i, j;
  472.  
  473.   b = &bands[VOLBAND];
  474.   for (i = 0; i < b->numitems; i++)
  475.     (*(item **) (*(**b->items)[i])->contrlData)->iconfam = g_diskicons;
  476.   b = &bands[FOLDERBAND];
  477.   for (i = 0; i < b->numitems; i++)
  478.     (*(item **) (*(**b->items)[i])->contrlData)->iconfam = g_foldericons;
  479.   for (i = 0; i < NUMBANDS; i++)
  480.     if (i != VOLBAND && i != FOLDERBAND)
  481.       {
  482.     b = &bands[i];
  483.     for (j = 0; j < b->numitems; j++)
  484.       setoneicon ((**b->items)[j]);
  485.       }
  486. }
  487.  
  488. short
  489. openappres (ControlHandle c)
  490. {
  491. /* TODO: check error conditions */
  492.   WDPBRec wdpb;
  493.   short refnum;
  494.   short resloadval;
  495.  
  496.   wdpb.ioVRefNum = (*(item **) (*c)->contrlData)->vrefnum;
  497.   wdpb.ioWDDirID = (*(item **) (*c)->contrlData)->ioparid;
  498.   wdpb.ioWDProcID = 0;
  499.   wdpb.ioNamePtr = 0;
  500.   PBOpenWD (&wdpb, false);
  501. #ifdef THINK_C
  502.   resloadval = ResLoad;
  503. #else
  504.   resloadval = LMGetResLoad ();
  505. #endif
  506.   SetResLoad (false);
  507.   refnum = OpenRFPerm ((*c)->contrlTitle, wdpb.ioVRefNum, fsRdPerm);
  508.   SetResLoad (resloadval);
  509.   PBCloseWD (&wdpb, false);
  510.   if (refnum == -1)
  511.     {
  512.       /* todo: alert */
  513.     }
  514.   return refnum;
  515. }
  516.