boot3/Toolbox/CommToolbox/CommToolboxUtilities/CommToolboxUtilityRoutines.c
Elliot Nunn 5b0f0cc134 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 10:02:57 +08:00

581 lines
15 KiB
C

/*
File: CommToolboxUtilityRoutines.c
Contains: Various routines
Written by: Byron Han
Alex Kazim
Copyright: © 1990, 1992 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<16> 11/13/92 JDR Updated QuickDraw.h to not use the dangerous pattern type.
<15> 5/29/92 DCL Included TextUtils.h and Script.h. EqualString and GetScript
moved for the New Inside Mac.
<14> 2/8/91 JNG kaz,#82584:Getflst needs to make sure the system file is in the
resource chain before calling GetIndFlst.
<13> 8/19/90 kaz Fixed gray OK outline to check for ColorQD and a color port.
<12> 8/15/90 kaz Added PlaceWindow() routine to perform 2/3rds centering.
<11> 8/6/90 kaz Added grayOutline button routine, HaveColorQD() macro.
<10> 7/2/90 kaz GetIndflst will compensate for odd font names.
<9> 5/24/90 kaz Combined GetIndfinf & GetIndflst; Added Getflst()
<8> 5/22/90 kaz Renamed Parse_finf, Parse_flst. Using new TextState data struct.
Adding GetTextState, SetTextState
<7> 4/18/90 kaz DoTheIcon() now uses only 1 BitMap
<6> 4/11/90 kaz Added International CmdPeriod() from TechNotes
<5> 3/20/90 kaz Merging utility routines from 1.0
- Fetch QD Globals
- Get just the DITL ItemRect
- Set the UserItem Proc
- PCopyString instead of Pascal aStr := bStr
<4> 3/16/90 BBH added MIN and MAX routines
<3> 3/16/90 BBH change GetDitem to GetDItem
<2> 3/16/90 BBH added DoTheIcon, parse_finf, parse_flst, FindMenuItem,
GoodDrawOutlineButton
<1> 3/14/90 BBH first checked in
To Do:
*/
// These are utility routines used by CommToolboxCore.c and the various managers
// this routine returns the first resource of the given type from the
// tool with the procID specified. This makes no assumptions about the
// tool already being in the resource chain
#include <Menus.h>
#include <Dialogs.h>
#include <QuickDraw.h>
#include <Fonts.h>
#include <SysEqu.h>
#include <TextUtils.h>
#include <Script.h>
#include "CTBUtilities.h"
#include "CommResources.h"
#include "CommToolboxPriv.h"
/* For CmdPeriod() */
#define kMaskModifiers 0xFE00 // strip the cmd key
#define kMaskVirtualKey 0x0000FF00 // virtual key from event
#define kUpKeyMask 0x0080
#define kShiftWord 8 // virtual key -> keycode
#define kMaskASCII1 0x00FF0000 // getting the key
#define kMaskASCII2 0x000000FF
#define kPeriod 0x2E // ascii for a '.'
#define HaveCQD() ((*(unsigned short *) ROM85) <= 0x3FFF)
pascal long MIN(a, b)
long a, b;
{
return( a < b ? a : b);
}
pascal long MAX(a, b)
long a, b;
{
return( a > b ? a : b);
}
pascal Handle CRMGetAResource(theType, procID)
ResType theType;
short procID;
{
CRMToolContext theContext;
short cur;
Handle theHandle;
CRMToolPreflight(procID, &theContext);
cur = CurResFile();
UseResFile(procID);
theHandle = CRMGet1IndResource(theType, 1);
UseResFile(cur);
CRMToolPostflight(&theContext);
return(theHandle);
}
pascal void DoTheIcon(theIcon, destRect, selected)
Ptr theIcon;
const Rect *destRect;
Boolean selected;
{
#define ICONSIZE 32
typedef struct IconsRecord {
long icon[ICONSIZE];
long mask[ICONSIZE];
} IconsRecord, *IconsRecordPtr;
BitMap mBitMap;
GrafPtr myPort;
IconsRecordPtr iP;
GetPort(&myPort);
SetRect(&mBitMap.bounds, 0, 0, ICONSIZE, ICONSIZE);
mBitMap.rowBytes = 4;
iP = (IconsRecordPtr) theIcon;
mBitMap.baseAddr = (Ptr) &iP->mask;
CopyBits(&mBitMap, &myPort->portBits, &mBitMap.bounds, destRect, selected ? srcOr : srcBic, nil);
mBitMap.baseAddr = (Ptr) &iP->icon;
CopyBits(&mBitMap, &myPort->portBits, &mBitMap.bounds, destRect, srcXor, nil);
}
/*************************************************************
DoSolidOutline - Draws a solid outline
Used for default buttons.
pDialog - Where we are
theItem - The DITL item #
**************************************************************/
pascal void DoSolidOutline(DialogPtr pDialog, short theItem)
{
Rect itemRect;
PenState ps;
GetPenState(&ps);
PenNormal();
PenSize(3,3);
GetItemRect(pDialog, theItem, &itemRect);
FrameRoundRect(&itemRect, 16, 16);
SetPenState(&ps);
}
/*************************************************************
DoGrayOutline - Draws a gray outline
Used for default buttons.
pDialog - Where we are
theItem - The DITL item #
**************************************************************/
pascal void DoGrayOutline(DialogPtr pDialog, short theItem)
{
Rect itemRect;
PenState ps;
GrafWorldPtr qdWorld;
PixPatHandle myPix = nil;
RGBColor oldFore,
oldAft;
GetPenState(&ps);
PenNormal();
PenSize(3,3);
GetItemRect(pDialog, theItem, &itemRect);
if (HaveCQD())
if (((CGrafPtr) pDialog)->portVersion & 0xC000) {
GetForeColor(&oldFore);
GetBackColor(&oldAft);
// gimme average RGB. Why does MenuMgr do a ROXR instead of an ASR??
oldFore.red = (oldFore.red + oldAft.red) >> 1;
oldFore.green = (oldFore.green + oldAft.green) >> 1;
oldFore.blue = (oldFore.blue + oldAft.blue) >> 1;
myPix = NewPixPat();
if (myPix != nil) {
MakeRGBPat(myPix,&oldFore);
PenPixPat(myPix);
}
}
if (myPix == nil) {
qdWorld = GetQDGlobals();
PenPat((ConstPatternParam)&(qdWorld->gray));
}
FrameRoundRect(&itemRect, 16, 16);
if (myPix != nil)
DisposPixPat(myPix);
SetPenState(&ps);
}
/*************************************************************
GetIndflst - Walks the font info template ('finf' or
'flst' and tries to get the request
hInfo - A handle to the data from GetResource
oldStyle - True if a 'finf', else 'flst'
index - Which font info do you want
finfInfo - Info to return
returns - -1 if it didn't work
**************************************************************/
pascal OSErr GetIndflst(hInfo, oldStyle, index, finfInfo)
Handle hInfo;
Boolean oldStyle;
short index;
TextState *finfInfo;
{
short numEntries;
long offset;
Str255 fontName;
short i;
short aFont;
finfInfo->theFont = 0; // resort to defaults
finfInfo->theSize = 0;
finfInfo->theFace = 0;
finfInfo->theMode = srcOr;
numEntries = *((short *) (*hInfo));
offset = (long) (*hInfo) + sizeof(numEntries);
/* Have to walk this 'cuz 'flst' is variable length */
for (i = 1; i <= numEntries; i++) {
if (oldStyle) {
aFont = *((short *) offset);
offset += sizeof(short);
}
else {
BlockMove((Ptr) offset, fontName, *((unsigned char *) offset) + 1);
offset += Length(fontName) + 1; // add length + length-byte
if (offset & 0x0001) // even it out
offset++;
}
/* Grab the rest of the data */
if (i == index) {
if (oldStyle)
finfInfo->theFont = aFont;
else
GetFNum(fontName, &finfInfo->theFont);
finfInfo->theFace = *((short *) offset);
offset += sizeof(short);
finfInfo->theSize = *((short *) offset);
offset += sizeof(short);
if (! oldStyle) // mode does not exist in 'finf'
finfInfo->theMode = *((short *) offset);
return(noErr);
}
offset += sizeof(short); // face
offset += sizeof(short); // size
if (! oldStyle)
offset += sizeof(short); // mode
}
return(-1);
}
/*************************************************************
Getflst - Tries to get the 'flst' resource from the
specified file, then tries to get a 'finf',
finally resorts to System 'flst'. Assumes that
the resource will exist in the System.
procID - The file to get it from
resourceID - yes
finfIndex - Index to get
finfInfo - Info to return
**************************************************************/
#define toolFINF 1
#define sysFLST 2
pascal void Getflst(procID, resourceID, finfIndex, finfInfo)
short procID;
short resourceID;
short finfIndex;
TextState *finfInfo;
{
short savedResRef;
Handle theResource;
short tries;
ResType theType;
savedResRef = CurResFile();
for (tries = 0; tries < 3; tries++) {
theType = 'flst';
if (tries == toolFINF) // we try the 'finf' to maintain compatibility
theType = 'finf';
if (tries == sysFLST)
UseResFile(0);
else
UseResFile(procID);
theResource = Get1Resource(theType, resourceID);
if (theResource == nil)
continue;
UseResFile(0); // Needs to be the system so GetIndflst can find font names
if (GetIndflst(theResource, (tries == toolFINF), finfIndex, finfInfo) == noErr)
break;
}
UseResFile(savedResRef);
}
/*************************************************************
GetTextState - Loads the current grafport text info
txState - Like penState
**************************************************************/
pascal void GetTextState(TextState *txState)
{
GrafPtr thePort;
GetPort(&thePort);
txState->theFont = thePort->txFont;
txState->theFace = thePort->txFace;
txState->theSize = thePort->txSize;
txState->theMode = thePort->txMode;
}
/*************************************************************
SetTextState - Sets the current grafport text info
txState - Like penState
**************************************************************/
pascal void SetTextState(TextState *txState)
{
TextFont(txState->theFont);
TextSize(txState->theSize);
TextFace(txState->theFace);
TextMode(txState->theMode);
}
pascal short FindMenuItem(hMenu, theItem)
MenuHandle hMenu;
const Str255 theItem;
{
short i;
Str255 theString;
short limit;
limit = CountMItems(hMenu);
for (i = 1; i <= limit; i++) {
GetItem(hMenu, i, &theString);
if (EqualString(theString, theItem, false, true) )
return(i);
}
return(0);
}
/*************************************************************
GetQDGlobals - Gets a pointer to the start of
the QD Globals given that A5 is valid
oneWorld - The stuff we need
**************************************************************/
pascal GrafWorldPtr GetQDGlobals()
{
GrafWorldPtr oneWorld;
/* A5 points to thePort of QD Global structure, so we add */
/* the GrafPtr to make oneWorld point past the bottom */
/* Then we make oneWorld point to the top */
oneWorld = (GrafWorldPtr) ((**((long **) CurrentA5)) + sizeof(GrafPtr));
return(--oneWorld);
}
/*************************************************************
GetItemRect - Gets a rectangle for a dialog item
so I don't have to pass all those damn
parameters all the time.
theDialog - The place
theItem - The DITL number
theRect - Thar she blows
**************************************************************/
pascal void GetItemRect(DialogPtr theDialog, short theItem, Rect *theRect)
{
short itemKind;
Handle itemHandle;
GetDItem(theDialog, theItem, &itemKind, &itemHandle, theRect);
}
/*************************************************************
SetUserItemProc - Sets the DITL user Item Proc
theDialog - The place
theItem - The DITL number
theProc - What to set it to
**************************************************************/
pascal void SetUserItemProc(DialogPtr theDialog, short theItem, ProcPtr theProc)
{
short itemKind;
Handle itemHandle;
Rect itemRect;
GetDItem(theDialog, theItem, &itemKind, &itemHandle, &itemRect);
SetDItem(theDialog, theItem, itemKind, (Handle) theProc, &itemRect);
}
/*************************************************************
PCopyString - Copies the Pascal string using
BlockMove src -> dest
srcStr - The source & scourge
destStr - Unsuspecting bystander
**************************************************************/
pascal void PCopyString(Str255 srcStr, Str255 destStr)
{
BlockMove((Ptr) srcStr,(Ptr) destStr,Length(srcStr) + 1);
}
/*************************************************************
CmdPeriod - Determines if the cmd-. was hit in an
international friendly way
theEvent - what to look at; not a VAR param
**************************************************************/
pascal Boolean CmdPeriod(EventRecord *theEvent)
{
Boolean fTimeToQuit;
short keyCode;
long virtualKey, keyInfo, lowChar,
highChar, state, keyCId;
Handle hKCHR;
fTimeToQuit = false;
if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
/* If CmdKey is down, get the ascii equiv of the keydown */
if (theEvent->modifiers & cmdKey) {
virtualKey = (theEvent->message & kMaskVirtualKey) >> kShiftWord;
/* get rid of the cmd key and add the virtual */
keyCode = (theEvent->modifiers & kMaskModifiers) | virtualKey;
state = 0;
keyCId = GetScript(GetEnvirons(smKeyScript), smScriptKeys);
hKCHR = GetResource('KCHR', keyCId);
if (hKCHR != nil) {
keyInfo = KeyTrans(*hKCHR, keyCode, &state);
ReleaseResource(hKCHR);
}
else
keyInfo = theEvent->message;
lowChar = keyInfo & kMaskASCII2;
highChar = (keyInfo & kMaskASCII1) >> 16;
if ((lowChar == kPeriod) || (highChar == kPeriod))
fTimeToQuit = true;
} // cmdKey down
} // keyEvent
return(fTimeToQuit);
}
/****************************************************************************
* PlaceWindow - Determines where to put the topLeft corner
* of a window given a relative window
*
* Inputs:
* theParent - place the child relative to it
* childHeight - the size of the child window. We use a rect 'cuz the
* childWidth - dialog may be opened/closed by a ROM routine (SFGetFile)
******************************************************************************/
pascal Point PlaceWindow(WindowPtr theParent,short childHeight,short childWidth)
{
GDHandle theScreen,
maxScreen; // How many faces
RgnHandle screenRgn;
long areaTaken,
maxAreaTaken = 0; // The amt the parent occupies per screen
Point offset; // Relative to the GDevice
Rect screenRect;
Boolean addMenu = false;
Point returnVal;
if (! HaveCQD()) { // old fashioned way
screenRect = (**(GetGrayRgn())).rgnBBox;
goto setLoc;
}
if (theParent == nil) { // Put it on the main screen
screenRect = (**(GetMainDevice())).gdRect;
addMenu = true;
goto setLoc;
}
// Put it on that screen
screenRgn = NewRgn();
/* We will walk the screen list to decide which one */
/* the parent window is most on. */
theScreen = GetDeviceList(); // Scan thru the GDevices
maxScreen = theScreen;
maxAreaTaken = 0;
while (theScreen != nil) {
RectRgn(screenRgn,&(**theScreen).gdRect);
SectRgn(screenRgn,((WindowPeek) theParent)->contRgn,screenRgn);
screenRect = (**screenRgn).rgnBBox;
areaTaken = (screenRect.right - screenRect.left) *
(screenRect.bottom - screenRect.top);
if (areaTaken > maxAreaTaken) { // This be the big one
maxScreen = theScreen;
maxAreaTaken = areaTaken;
}
theScreen = GetNextDevice(theScreen); // NeXT, please
} // in the list
DisposeRgn(screenRgn);
screenRect = (**maxScreen).gdRect;
addMenu = (maxScreen == GetMainDevice());
setLoc:
offset.h = ((screenRect.right - screenRect.left) - childWidth) >> 1;
offset.v = ((screenRect.bottom - screenRect.top) - childHeight) / 3;
SetPt(&returnVal, screenRect.left + offset.h, screenRect.top + offset.v);
if (addMenu)
returnVal.v += (GetMBarHeight() << 1) / 3;
return(returnVal);
}