mac-rom/Toolbox/MenuMgr/MenuMgr.c
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

250 lines
10 KiB
C

/*
File: MenuMgr.c
Contains: C language portions of Menu Manager
Written by: Kevin MacDonell and David Collins
Copyright: © 1991-1992 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<14> 11/3/92 DTY Strip out unnecessary includes.
<13> 5/29/92 DCL Included TextUtils.h. NBreakTablePtr moved there for the New
Inside Mac.
<12> 4/22/92 DTY #1024445,<KSM>: If at first you donÕt succeedÉ The last change
wasnÕt doing what we wanted it to do. Move the line from the
last checkin up a line so that the script code will be forced to
smRoman a little earlier if weÕre trying to insert 'FONT' 0.
<11> 4/1/92 KSM #1024445,<DTY>: Fix case where a Chicago 'FONT' (family id = 0)
maps to the current system script instead of Roman.
<10> 3/30/92 DC #1025860,<KSM>: Fix IDToScriptCode. Boundary case would cause ID
16384 to map to Roman script.
<9> 3/27/92 DC #1025860,<KSM>: Added InsertIntlResMenu to allow a user to filter a
resource by its associatiation with a script system
<8> 3/20/92 DCL #1025005,<KSM>:
Included Language.h because: For New IM: Moved some declarations
and routines from Packages.[ph] to Language.[ph] #1025005
<7> 2/11/92 DTY #1021194, #1021189: To deal with resource names containing
metacharacters, call InsMenuItem with a space, then SetItem with
the actual menu item string.
<6> 12/30/91 KSM xxx,#1018832: (Bruges fix) AddResMenu must call CalcMenuSize
when finished!
<5> 10/10/91 PKE #1012949, For Cube-E (and Bruges): Use new Font2RealScript
routine (ignores FontForce & script enable status) instead of
Font2Script to determine script of fonts in menus. Need to
include ScriptPriv.h. Also added bug # to previous comment.
<4> 10/7/91 KSM #1012768, For Cube-E (and Bruges): Fix bug where FONT and FOND
names were duplicated.
<3> 9/23/91 DTY Dean finds a better way of making fonts load in the System Heap,
so take out the last change.
<2> 9/19/91 DTY Dean makes a unilateral decision at 1 in the morning to make all
'FOND's and 'FONT's load into the System heap.
<1> 8/22/91 KSM first checked in
To Do:
*/
#include <Types.h>
#include <Memory.h>
#include <Menus.h>
#include <Resources.h>
#include <Script.h>
#include <SysEqu.h>
#include <IntlUtilsPriv.h>
#include <ScriptPriv.h>
#define GetResLoad() (*(Boolean *)ResLoad)
#define GetItmIcon(ip) (*(ip + (*ip + 1)))
#define GetItmCmd(ip) (*(ip + (*ip + 2)))
#define kFirstType 'FOND'
#define kSecondType 'FONT'
/*--------------------------------------------------------------------------------------------------
Purpose: Compares 'rsrcName' with a contiguous subset of the items of the given menu
and determines its internationally correct sort position within that menu.
Inputs: rsrcName - name of item we wish to insert
rsrcScript - the script code of the string (to be internationally correct)
theMenu - the menu in which 'rsrcName' will be inserted
afterItem - the first item to compare against for insertion
addedResources - the number of items to compare against (1st time is always zero)
Outputs: FindInsertIPt - the item number after which rsrcName should be inserted.
*/
short FindInsertIPt(StringPtr rsrcName, short rsrcScript, MenuHandle theMenu, short afterItem, short addedResources)
{
StringPtr itemRecPtr;
short i;
HLock((Handle)theMenu); // we can point into it
SetResLoad(true); // Let IntÕl rsrcs load for IUTextOrderSys
itemRecPtr = (**theMenu).menuData; // Make pointer to menu title
itemRecPtr += *itemRecPtr + 1; // Skip over title
for (i=afterItem-1;i >= 0; --i) // Point to item 'afterItem'
if (*itemRecPtr) // Check to see we havenÕt run off end
itemRecPtr += (*itemRecPtr + 5);
else break;
// Do compares across only the items weÕve added to this menu
for (; *itemRecPtr && (addedResources--); itemRecPtr += (*itemRecPtr + 5))
{
short cmpResult;
// Do the IntÕl correct compare. Must use iuSystemScript and not zero as compare scripts.
// Note that if the itmCmd field is $1c then the itmIcon field contains the script code.
cmpResult = IUTextOrderSys(
rsrcName+1, itemRecPtr+1, *rsrcName, *itemRecPtr, // Strings
rsrcScript,
(GetItmCmd(itemRecPtr) == 0x1c) ? (char)GetItmIcon(itemRecPtr) : (char)iuSystemScript, // Scripts
0, 0 ); // Languages
if (cmpResult <= 0) // true if (rsrcName <= itemName)
{
if (!cmpResult) // if (rsrcName == itemName)
afterItem = -1; // show this is a duplicate
break; // otherwise afterItem is now correct
}
++afterItem; // Insert after this item
}
SetResLoad(false); // Restore ResLoad for caller
HUnlock((Handle)theMenu); // Set it free again
return afterItem;
}
#define romanCieling 16384
short IDToScriptCode(short rsrcID)
{
rsrcID -= romanCieling;
if (rsrcID >= 0)
{
rsrcID >>= 9;
++rsrcID;
}
else
rsrcID = 0;
return rsrcID;
}
/*--------------------------------------------------------------------------------------------------
Purpose: Loops thru each resource ID of the given type and inserts it into the menu.
Empty names, names beginning with '.' or '%' are skipped.
Inputs: theMenu - the menu in which the name of the resources will be inserted
theType - the resource type to add
afterItem - the item number after which rsrc names will be added
fontFondFlag - TRUE if theType is 'FOND' or 'FONT' and we need to use
the Script code in comparing the strings
Outputs: The menu is updated as appropriate.
*/
pascal void __InsertIntlResMenu(MenuHandle theMenu,
ResType theType,
short afterItem,
short scriptFilter)
{
Boolean oldResLoad;
short nRsrcs, currSysScript, addedResources = 0;
Boolean fontFondFlag = ((theType == kSecondType) || (theType == kFirstType));
// If we are adding fonts, we will do a pass to add resources of type kFirstType and
// then come back and do a pass for kSecondType. We interpret the special script filter
// values here and turn them into their functional values.
// Otherwise, the script filter must be set to 'smAllScripts' to avoid sorting problems.
currSysScript = GetEnvirons(smSysScript);
// Interpret special ScriptMgr script values, get real values from pseudo-values
if (scriptFilter == smSystemScript)
scriptFilter = currSysScript;
else if (scriptFilter == smCurrentScript)
scriptFilter = FontScript();
if (fontFondFlag) // Special case?
theType = kFirstType; // Always start with first type
{
short nItems = CountMItems(theMenu); // Find out # items in menu
if (afterItem < 0) afterItem = 0; // Insure reasonableness
if (afterItem > nItems) afterItem = nItems; // Insure min(afterItem,nItems)
}
oldResLoad = GetResLoad();
SetResLoad(false); // Just need the map info
NextFONTPass: // Comes here 2nd time for fonts
if (!(nRsrcs = CountResources(theType))) goto PassDone; // None to add...
do
{
Handle theRsrcH;
theRsrcH = GetIndResource(theType, nRsrcs); // Get each one in turn
if (theRsrcH != NULL)
{
short rsrcID, item;
Str255 rsrcName;
short rsrcScript;
char *fc=&rsrcName[1];
GetResInfo(theRsrcH, &rsrcID, &theType, rsrcName);
if (!(*rsrcName) || (*fc == '.') || (*fc == '%')) continue;
rsrcScript = fontFondFlag ? Font2RealScript(rsrcID) : IDToScriptCode(rsrcID);
if ((rsrcID == 0) && (theType == 'FONT')) // <12> Force Chicago FONT to be in the Roman script system
rsrcScript = smRoman;
if ((scriptFilter != smAllScripts) && (rsrcScript != scriptFilter)) continue;
item = FindInsertIPt(rsrcName, rsrcScript, theMenu, afterItem, addedResources);
if (item >= 0) // negative means duplicate, skip this item
{
InsMenuItem(theMenu, "\p ", item); // <7> Create an empty menu item after ÒitemÓ.
SetItem(theMenu, item + 1, rsrcName); // <7> Now fill the new item with the resource name.
// Only set the script code if fontFondFlag
// and non-system font script to optimize menu drawing speed over this routine
if ((fontFondFlag) && (rsrcScript != currSysScript))
{
SetItemCmd(theMenu, item+1, (char)0x1c); // Show item has a script
SetItemIcon(theMenu, item+1, rsrcScript); // scripts go in icon field
}
++addedResources; // Keep count of items added
}
}
} while (--nRsrcs);
PassDone:
if (fontFondFlag && (theType == kFirstType)) // If doing fonts and only have done kSecondType...
{
theType = kSecondType;
goto NextFONTPass;
}
SetResLoad(oldResLoad);
CalcMenuSize(theMenu);
}
/*--------------------------------------------------------------------------------------------------
Purpose: Set up for calling InsResGuts for FONT/FOND menus.
Inputs: theMenu - the menu in which the name of the resources will be inserted
afterItem - the item number after which rsrc names will be added
scriptFilter- smAllScripts: Adds all the FONT/FONDs to the menu
smSystemScript: Adds those FONT/FONDs for the system script
smCurrentScript: Adds those FONT/FONDs for the current script
otherwise adds only those FONT/FONDs = to that script.
Outputs: The menu is updated as appropriate.
*/
pascal void __InsrtFontResMenu(MenuHandle theMenu, short afterItem, short scriptFilter)
{
InsertIntlResMenu(theMenu, kFirstType, afterItem, scriptFilter); // Do the FONTs and FONDs
}
/*--------------------------------------------------------------------------------------------------
Purpose: Set up for calling InsResGuts.
Note: Special cased for FONT and FOND resources: will do both if either is mentioned.
Inputs: theMenu - the menu in which the name of the resources will be inserted
theType - the resource type to add
afterItem - the item number after which rsrc names will be added
Outputs: The menu is updated as appropriate.
*/
pascal void InsrtResMenu(MenuHandle theMenu, ResType theType, short afterItem)
{
InsertIntlResMenu(theMenu, theType, afterItem, smAllScripts);
}