home *** CD-ROM | disk | FTP | other *** search
- #include "go.h"
- #include "display.h"
- #include "xfer.h"
- #include "fontda.h"
- #include <assert.h>
-
- #include "initicons.proto.h"
- #include "sharedtransfer.proto.h"
-
- #include "bndl.h"
-
- icontableentry **icontable[ICONTABLESIZE];
- icn_sharp_hand g_foldericons, g_diskicons;
- applist **sigowners[TEXTEDITORPOS + 1];
-
- /* NOTE: the default doc must be the last item. Its type should really be special
- cased, but it's the default anyway so if a document has a goofy filetype
- it will get the correct information regardless.
- */
-
- typeinfo typearray[] =
- {
- 'ffil', FONTBAND, NOACTION, FONTICONNUM, 0,
- 'FFIL', FONTBAND, NOACTION, FONTSCICONNUM, 0,
- 'tfil', FONTBAND, NOACTION, TTFONTICONNUM, 0,
- 'dfil', DABAND, OPENDA, DAICONNUM, 0,
- 'DFIL', DABAND, OPENDA, DASCICONNUM, 0,
- 'APPL', APPBAND, LAUNCH, DEFAULTAPPLICONNUM, 0,
-
- /* NOTE: TEXT, ttro and PICT are special cased in launch.c */
- 'TEXT', DOCBAND, LAUNCHCREATOR, DEFAULTTEXTICONNUM, 0,
- 'ttro', DOCBAND, LAUNCHCREATOR, DEFAULTTEXTICONNUM, 0,
- 'PICT', DOCBAND, LAUNCHCREATOR, DEFAULTTEXTICONNUM, 0,
-
- '|!@$', DOCBAND, LAUNCHCREATOR, DEFAULTDOCICONNUM, 0,
- };
-
- static long
- get_filenum (short vrefnum, long parid, Str255 s)
- {
- CInfoPBRec cpb;
- Str255 s2;
- OSErr e;
-
- mystr255copy (s2, s);
- cpb.dirInfo.ioNamePtr = s2;
- cpb.dirInfo.ioVRefNum = vrefnum;
- cpb.dirInfo.ioDrDirID = parid;
- cpb.dirInfo.ioFDirIndex = 0;
- e = PBGetCatInfo (&cpb, false);
-
- return e == noErr ? cpb.dirInfo.ioDrDirID : -1;
- }
-
- ControlHandle
- getnewiconcontrol (WindowPtr wp, char **path, long parid,
- short vrefnum, Str255 s, short view)
- {
- item **h;
- Rect r;
- ControlHandle c;
- long filenum;
-
- filenum = get_filenum (vrefnum, parid, s);
-
- SetRect (&r, 0, 0, ICONWIDTHUSED, ICONHEIGHTUSED);
- c = NewControl (wp, &r, s, false, 0, 0, 0, ICONCONTROL, 0);
- h = (item **) NewHandle (sizeof (item));
- (*h)->path = path;
- (*h)->ioparid = parid;
- (*h)->filenum = filenum;
- (*h)->vrefnum = vrefnum;
- (*h)->selected = false;
- (*h)->view = view;
- (*c)->contrlRfCon = 0L;
- (*c)->contrlData = (Handle) h;
- #ifdef THINK_C
- (*c)->contrlAction = (ProcPtr) -1L;
- #else
- (*c)->contrlAction = (ControlActionUPP) -1L;
- #endif
- return c;
- }
-
- #if 0
-
- #define NOTFOUND -1
- short
- localidlookup (short localid, iconentry ** iconarray, short n)
- {
- short i;
-
- for (i = 0; i < n; i++)
- if ((*iconarray)[i].localid == localid)
- /*-->*/ return i;
- return NOTFOUND;
- /* TODO: ALERT */
- }
-
- void
- dobundle (short *spacemade, iconentry *** iconarray, char **h)
- {
- /* todo: get rid of the *h += n stuff and make a datatype */
- short k, pos, numentries;
- ResType type;
- identry *idarray;
- Handle h2;
-
- type = *(OSType *) *h;
- *h += 4;
- numentries = *(short *) *h + 1;
- *h += 2;
- if (*spacemade == 0)
- {
- *iconarray = (iconentry **) NewHandle (numentries * sizeof (iconentry));
- *spacemade = numentries;
- idarray = (identry *) *h;
- if (type == 'ICN#')
- {
- for (k = 0; k < numentries; k++)
- {
- (**iconarray)[k].resid = idarray[k].resid;
- (**iconarray)[k].localid = idarray[k].localid;
- }
- }
- else if (type == 'FREF')
- {
- for (k = 0; k < numentries; k++)
- {
- h2 = (Handle) Get1Resource ('FREF', idarray[k].resid);
- if (h2 && GetHandleSize (h2) >= 7)
- {
- (**iconarray)[k].type = *(OSType *) *h2;
- (**iconarray)[k].localid = *(short *) (*h2 + 4);
- }
- else
- {
- /* What should *REALLY* be done here? */
- (**iconarray)[k].type = 0;
- (**iconarray)[k].localid = -1;
- }
- ReleaseResource (h2);
- }
- }
- else
- {
- /* there shouldn't be any other types */
- assert (0);
- /* ALERT */
- }
- *h += numentries * sizeof (identry);
- }
- else
- {
- #if 0
- /* todo: find out if this assert can ever fail */
- /* It can, but the code should work anyways. This should be looked into further. */
- assert (*spacemade == numentries);
- #endif /* 0 */
- idarray = (identry *) * h;
- if (type == 'ICN#')
- {
- for (k = 0; k < numentries; k++)
- {
- pos = localidlookup (idarray[k].localid, *iconarray, *spacemade);
- if (pos != NOTFOUND)
- (**iconarray)[pos].resid = idarray[k].resid;
- }
- }
- else if (type == 'FREF')
- {
- for (k = 0; k < numentries; k++)
- {
- /*
- * It is my understanding the first two bytes mean nothing. IMVI says they must be
- * unique, but doesn't use them, but keeps them in for backwards compatibility. They
- * are local fref ids
- */
- h2 = (Handle) Get1Resource ('FREF', idarray[k].resid);
- if (h2 && GetHandleSize (h2) >= 7)
- pos = localidlookup (*(short *) (*h2 + 4), *iconarray, *spacemade);
- else
- pos = NOTFOUND;
- if (pos != NOTFOUND)
- (**iconarray)[pos].type = *(ResType *) * h2;
- ReleaseResource (h2);
- }
- }
- else
- /* there shouldn't be any other types */
- assert (0);
- *h += numentries * sizeof (identry);
- }
- }
- #undef NOTFOUND
-
- #endif
-
- typeinfo *
- gettypeinfo (OSType type)
- {
- short i;
-
- for (i = 0; i < NELEM (typearray); i++)
- if (type == typearray[i].filetype)
- return &typearray[i];
- return &typearray[NELEM (typearray) - 1];
- }
-
- #define resCompressed 1
-
- static Handle
- Get1NonCompressedResource (ResType type, INTEGER id)
- {
- Handle retval;
- INTEGER attrs;
-
- retval = Get1Resource (type, id);
-
- /*
- * It's not clear how we're supposed to detect and deal with compressed
- * resources. FIlemakerPro's install disk has an installer whose icl8 icons
- * are listed by ResEdit as being compressed. Those icons also have bit 0
- * turned on, and bit 0 isn't assigned to anything. So I decided that bit 0
- * is now used to denote compression, and perhaps it is. However, an old
- * copy of FoxBASE had some ICN#s with that bit set that clearly weren't
- * compressed. After much head scratching, I've decided to just arbitrarily
- * say that ICN#'s are never compressed. This may be what the Mac does, it
- * may not, but I don't have a good way to test. --ctm 95-07-05
- *
- * Update: it appears that the files which truly have compressed resources
- * also have 'dcmp' resources, so our new test checks to see if there are any
- * 'dcmp's and the comment about ICN# is no longer correct.
- */
-
- attrs = GetResAttrs (retval);
- if ((attrs & resCompressed) && Count1Resources ('dcmp') > 0)
- retval = 0;
- return retval;
- }
-
- icn_sharp_hand
- read_icn_sharp (short id)
- {
- icn_sharp_hand retval;
- Handle h;
- SignedByte state;
-
- #define geticonhandle(field, type) \
- h = (Handle) Get1NonCompressedResource(type, id); \
- HandToHand(&h); \
- (*retval)->field = h;
-
- retval = (icn_sharp_hand) NewHandle (sizeof (**retval));
-
- HLock ((Handle) retval);
- geticonhandle (icnsh, 'ICN#');
- geticonhandle (icssh, 'ics#');
- geticonhandle (icl8, 'icl8');
- geticonhandle (icl4, 'icl4');
- geticonhandle (ics8, 'ics8');
- geticonhandle (ics4, 'ics4');
- HUnlock ((Handle) retval);
-
- if (!((*retval)->icnsh || (*retval)->icl8 || (*retval)->icl4))
- {
- DisposHandle ((Handle) retval);
- retval = 0;
- }
-
- return retval;
- #undef geticonhandle
- }
-
- void
- inithash (void)
- {
- short i;
- icontableentry **node;
-
- g_foldericons = read_icn_sharp (FOLDERICONNUM);
- HLock ((Handle) g_foldericons);
-
- g_diskicons = read_icn_sharp (DISKICONNUM);
- HLock ((Handle) g_diskicons);
-
- for (i = 0; i < ICONTABLESIZE; i++)
- icontable[i] = 0;
- for (i = 0; i < NELEM (typearray); i++)
- {
- typearray[i].iconh = read_icn_sharp (typearray[i].iconid);
- }
- for (i = 0; i < SIGARRAYSIZE; i++)
- sigowners[i] = 0;
- }
-
- #if 0
- icontableentry **
- gethash (OSType type, OSType creator)
- {
- unsigned short hashval;
- icontableentry **np;
-
- hashval = ((unsigned long) type + (unsigned long) creator) % ICONTABLESIZE;
- for (np = icontable[hashval]; np != 0; np = (*np)->next)
- {
- if (((*np)->type == type) && ((*np)->sig == creator))
- return np;
- }
-
- return gettypeinfo (type)->iconh;
- }
-
- static boolean_t
- at_least_one_icon_p (icontableentry **node)
- {
- icontableentry *p;
-
- p = *node;
- return (p->icnsh || p->icl8 || p->icl4);
- /* No need to test these: && (p->icssh || p->ics8 || p->ics4); */
- }
- #endif
-
- void
- hashicons (ControlHandle c)
- {
- /* todo: worry about filenames in FREFs */
- /* get FREF, BNDL, ICN#, ics#, icl8, ics8, icl4, ics4 */
- /* BNDL is:
- 4 bytes of signature
- 2 bytes of 0 [signature resource id?]
- 2 bytes of <number of main entries - 1> (almost always 1)
- numberofmainentries *
- 4 bytes of 'ICN#' or 'FREF'
- 2 bytes of <number of entries - 1>
- numberofentries *
- 2 bytes of localid
- 2 bytes of resid
- */
- /* todo: see what happens with multiple BNDLs */
-
- char *p;
- short i, j, spacemade, nummain, numbndls;
- unsigned short hashval;
- iconentry **iconarray;
- icontableentry **node;
- Handle h;
- OSType signature;
- short refnum, sigid;
- unsigned char state;
- applist **ah;
-
- refnum = openappres (c);
- numbndls = Count1Resources ('BNDL');
- for (i = 1; i <= numbndls; i++)
- {
- bndl_t **bndl;
-
- h = (Handle) Get1IndResource ('BNDL', i);
- bndl = (bndl_t **) h;
- process_bndl (bndl, (*bndl)->owner);
- state = HGetState (h);
- HLock (h);
- p = *h;
- signature = *(OSType *) p;
- p += 4;
- sigid = *(short *) p;
- p += 2;
-
- hashval = (unsigned long) signature % SIGARRAYSIZE;
- #define CONTROLPROBLEMS
- #ifndef CONTROLPROBLEMS
- for (ah = sigowners[hashval]; ah != 0 && (*ah)->sig != signature; ah = (*ah)->next)
- ;
- if (ah == 0)
- {
- #endif /* CONTROLPROBLEMS */
- ah = sigowners[hashval];
- sigowners[hashval] = (applist **) NewHandle (sizeof (applist));
- (*sigowners[hashval])->next = ah;
- (*sigowners[hashval])->parid = (*(item **) (*c)->contrlData)->ioparid;
- (*sigowners[hashval])->vrefnum = (*(item **) (*c)->contrlData)->vrefnum;
- (*sigowners[hashval])->sig = signature;
- mystr255copy ((*sigowners[hashval])->name, (*c)->contrlTitle);
- #ifndef CONTROLPROBLEMS
- }
- #endif /* CONTROLPROBLEMS */
-
- #if 0
- /* todo: find out if nummain must == 2 */
- nummain = *(short *) p + 1;
- p += 2;
-
- spacemade = 0;
- for (j = 0; j < nummain; j++)
- {
- dobundle (&spacemade, &iconarray, &p);
- }
-
- for (j = 0; j < spacemade; j++)
- {
- hashval = ((unsigned long) signature + (unsigned long) (*iconarray)[j].type)
- % ICONTABLESIZE;
- for (node = icontable[hashval]; node != 0 &&
- ((*node)->sig != signature || (*node)->type != (*iconarray)[j].type);
- node = (*node)->next)
- ;
- if (node == 0)
- {
- node = (icontableentry **) NewHandle (sizeof (icontableentry));
- (*node)->sig = signature;
- (*node)->type = (*iconarray)[j].type;
- geticons (node, (*iconarray)[j].resid);
- if (at_least_one_icon_p (node))
- {
- (*node)->next = icontable[hashval];
- icontable[hashval] = node;
- }
- else
- DisposHandle ((Handle) node);
- }
- }
- DisposHandle ((Handle) iconarray);
- HSetState (h, state);
- ReleaseResource (h);
- #endif
- }
- CloseResFile (refnum);
- }
-
- void
- setoneicon (ControlHandle c)
- {
- CInfoPBRec pb;
- item **ih;
- typeinfo *tip;
-
- ih = (item **) (*c)->contrlData;
- pb.hFileInfo.ioFDirIndex = 0;
- pb.hFileInfo.ioVRefNum = (*ih)->vrefnum;
- pb.hFileInfo.ioDirID = (*ih)->ioparid;
- pb.hFileInfo.ioNamePtr = (*c)->contrlTitle;
- PBGetCatInfo (&pb, false);
- if (pb.hFileInfo.ioFlAttrib & DIRBIT)
- {
- (*ih)->iconfam = g_foldericons;
- (*ih)->action = OPENDIR;
- (*ih)->size = 0;
- (*ih)->moddate = pb.dirInfo.ioDrMdDat;
- }
- else
- {
- (*ih)->iconfam = map_type_and_creator (pb.hFileInfo.ioFlFndrInfo.fdType,
- pb.hFileInfo.ioFlFndrInfo.fdCreator);
- if (!(*ih)->iconfam)
- (*ih)->iconfam = (gettypeinfo (pb.hFileInfo.ioFlFndrInfo.fdType))->iconh;
- tip = gettypeinfo (pb.hFileInfo.ioFlFndrInfo.fdType);
- (*ih)->action = tip->action;
- (*ih)->size = pb.hFileInfo.ioFlLgLen + pb.hFileInfo.ioFlRLgLen;
- (*ih)->moddate = pb.hFileInfo.ioFlMdDat;
- (*ih)->sig = pb.hFileInfo.ioFlFndrInfo.fdCreator;
- (*ih)->type = pb.hFileInfo.ioFlFndrInfo.fdType;
- }
- }
-
- void
- seticons (void)
- {
- bandinfo *b;
- short i, j;
-
- b = &bands[VOLBAND];
- for (i = 0; i < b->numitems; i++)
- (*(item **) (*(**b->items)[i])->contrlData)->iconfam = g_diskicons;
- b = &bands[FOLDERBAND];
- for (i = 0; i < b->numitems; i++)
- (*(item **) (*(**b->items)[i])->contrlData)->iconfam = g_foldericons;
- for (i = 0; i < NUMBANDS; i++)
- if (i != VOLBAND && i != FOLDERBAND)
- {
- b = &bands[i];
- for (j = 0; j < b->numitems; j++)
- setoneicon ((**b->items)[j]);
- }
- }
-
- short
- openappres (ControlHandle c)
- {
- /* TODO: check error conditions */
- WDPBRec wdpb;
- short refnum;
- short resloadval;
-
- wdpb.ioVRefNum = (*(item **) (*c)->contrlData)->vrefnum;
- wdpb.ioWDDirID = (*(item **) (*c)->contrlData)->ioparid;
- wdpb.ioWDProcID = 0;
- wdpb.ioNamePtr = 0;
- PBOpenWD (&wdpb, false);
- #ifdef THINK_C
- resloadval = ResLoad;
- #else
- resloadval = LMGetResLoad ();
- #endif
- SetResLoad (false);
- refnum = OpenRFPerm ((*c)->contrlTitle, wdpb.ioVRefNum, fsRdPerm);
- SetResLoad (resloadval);
- PBCloseWD (&wdpb, false);
- if (refnum == -1)
- {
- /* todo: alert */
- }
- return refnum;
- }
-