home *** CD-ROM | disk | FTP | other *** search
- /*
- HASUtilities.c from Hsoi's App Shell © 1995-1997 John C. Daub. All rights reserved.
-
- This file contains various utility functions to deal with things. It's
- kind of a "catch all" file for things that don't really fit anywhere else
- cause they have the potential to be so generally used...either that or
- i just didn't know where else to put them :)
-
- There are other HASUtilxxx.c files...these are also utility type functions, but
- do tend to have more specific usage.
- */
-
- #pragma mark ••• #includes •••
-
- #ifndef __FP__
- #include <fp.h>
- #endif
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
- #ifndef _WASTE_
- #include "WASTE.h"
- #endif
- #include "HASGlobals.h"
- #ifndef __HSOIS_APP_SHELL__
- #include "HASMain.h"
- #endif
- #include "HASDialogs.h"
- #include "HASMiscEvents.h"
- #include "HASUtilities.h"
- #ifndef __MARCO_MOVABLEMODALLIB__
- #include "HASMovableModal.h"
- #endif
-
- #include "WASTE_Objects.h"
-
- #if HAS_DEBUG
- #include "HASUtilTest.h"
- #endif
-
- #pragma mark -
- #pragma mark ••• Floats & Strings •••
-
- /* the following functions, HsoiStringToExtended() and HsoiExtendedToString()
- are based upon a selection from the April 1995 issue of "develop" magazine's
- Q&A section. They're basically "smarter" versions of StringToExtended() and
- ExtendedToString. Here's the original question:
-
- To make my application localizable, I want to use ExtendedToString and
- StringToExtended to convert floats to strings and strings to floats.
- These routines, though, use the SANE extended format, which is quite
- archaic. What's the best way to convert a float to an extended to pass
- to ExtendedToString? It should compile on both 680x0 and PowerPC
- machines with MPW, Metrowerks, and THINK C.
-
- and the answer:
-
- A On PowerPC machines, extended80 and extended96 do not exist, except as
- structures. There are a number of (PowerPC-only) conversion routines in
- fp.h, like x80told. Your formatting code can be written as follows:
-
- (and the listed code from "develop" is the fuction, HsoiStringToExtended().
- in the article, the function was called, LongDoubleToString())
-
- the article continues with more reasoning:
-
- Note that long double is equivalent to extended80 or extended96 on
- 680x0, and 128-bit double-double on PowerPC. If you want to format a
- double, just pass it in and the compiler will take care of converting
- double to long double or double to extended.
-
- SANE.h is being replaced by fp.h, for both 680x0 and PowerPC. This
- issue's CD contains the libraries and interfaces for this new numerics
- package, which implements the Floating-Point C Extensions (FPCE)
- proposed technical draft of the Numerical C Extensions Group's
- requirements (NCEG/X3J11.1).
-
- For more information on how to convert a SANE program to PowerPC, see
- Inside Macintosh: PowerPC Numerics, Appendix A. In principle, you should
- replace all use of extended with double_t. The double_t type maps back
- to long double for 680x0, which is the same as extended; for PowerPC, it
- maps to 64-bit double, which is the fastest floating-point format. Only
- when you read or write 80- or 96-bit SANE numbers to files, or when you
- want to use any of the Toolbox routines that take an 80-bit extended
- parameter, do you need to use conversion routines.
-
- Incidentally, i found this stuff on Apple's Developer web site:
- <http://dev.info.apple.com/> (that's valid as of this writing, 02 Jan 1996).
- I just did a search with the keyword "stringtoextended" and got this.
-
- Oh, and since you're using an ANSI Library in this HAS project file, be
- sure that depending on the compiler settings to add the right ANSI lib
- in. (and it might even be easy to do this with some pragmas at the top
- of this file, like #if defined (powerc) #include <ANSI (2i).C.68k.Lib #endif
- and that might work, y'know)?
-
- what i'd consider doing would be like this: (and this is using the CW7
- ANSI library naming convention, or close enough to it).
-
-
- void HsoiExtendedToString( long double ld, const NumFormatString *myCanonical,
- const NumberParts *partsTable, Str255 outString )
- {
- #if defined(powerc) || defined (__powerc)
- #include <ANSI (2i) C.PPC.lib>
- extended80 x;
-
- ldtox80(&ld, &x);
- ExtendedToString(&x, myCanonical, partsTable, outString);
- #else
- #ifdef mc68881
- #include <ANSI (2i/F) C.68k.lib>
- extended80 x;
-
- x96tox80(&ld, &x);
- ExtendedToString(&x, myCanonical, partsTable, outString);
- #else
- #include <ANSI (2i) C.68k.Lib>
- ExtendedToString(&ld, myCanonical, partsTable, outString);
- #endif
- #endif
- }
-
- wonder if that might be a recommded way to do this or not....or if it's even
- necessary.
-
- -------------
-
- Also, check out the function HsoiGetDoubleItem() in HAS Preferences.c. There's
- more explanation about these routines and my ways of getting around them.
- */
-
- void HsoiExtendedToString( long double ld, const NumFormatString *myCanonical,
- const NumberParts *partsTable, Str255 outString )
- {
- #if defined(powerc) || defined (__powerc)
- extended80 x;
-
- ldtox80(&ld, &x);
- ExtendedToString(&x, myCanonical, partsTable, outString);
- #else
- #ifdef mc68881
- extended80 x;
-
- x96tox80(&ld, &x);
- ExtendedToString(&x, myCanonical, partsTable, outString);
- #else
- ExtendedToString(&ld, myCanonical, partsTable, outString);
- #endif
- #endif
- }
-
- void HsoiStringToExtended( ConstStr255Param source, const NumFormatString *myCanonical,
- const NumberParts *partsTable, long double *x )
- {
- #if defined(powerc) || defined (__powerc)
- extended80 y;
-
- StringToExtended( source, myCanonical, partsTable, &y );
- x80told( &y, x );
-
- #else
- #ifdef mc68881
- extended80 y;
-
- StringToExtended( source, myCanonical, partsTable, &y );
- x80tox96( &y, x );
- #else
- StringToExtended( source, myCanonical, partsTable, x );
-
- #endif
- #endif
- }
-
-
- #pragma mark -
- #pragma mark ••• Memory Utils •••
-
-
- /*
- * This is just a nifty little way of disposing of Handles
- */
-
- void HsoiForgetHandle( Handle *h )
- {
- Handle theHandle;
-
- theHandle = *h;
-
- if ( theHandle != nil )
- {
- *h = nil;
- DisposeHandle( theHandle );
- }
-
- return;
- }
-
- // same thing here as with ForgetHandle() in regards to the argument list, but this is
- // for resources instead.
-
- void HsoiForgetResource( Handle *h )
- {
- Handle theHandle;
-
- theHandle = *h;
-
- if ( theHandle != nil )
- {
- *h = nil;
- ReleaseResource( theHandle );
- }
-
- return;
- }
-
- // the following 2 functions are "better" ways of allocating space for a New Handle.
- // they both do the same thing: first try to tap temporary memory for space to
- // allocate the handle. if that fails, try to allocate in the app's heap. the
- // only difference between the 2 functions is that the 2nd (Clear) calls NewHandleClear
- // instead. (note, there is note TempNewHandleClear() function.)
-
-
- OSErr HsoiNewHandleTemp( Size blockSize, Handle *h )
- {
- OSErr err;
-
- // allocate a new relocatable block from temporary memory, or
- // if that fails, from the current heap
-
- // first try tapping temporary memory
-
- *h = TempNewHandle( blockSize, &err );
-
- // in case of failure, try with current heap
-
- if ( *h == nil )
- {
- *h = NewHandle( blockSize );
- err = MemError();
- }
-
- return err;
- }
-
-
- OSErr HsoiNewHandleTempClear( Size blockSize, Handle *h )
- {
- OSErr err;
-
- // allocate a new relocateable block from temporary memory,
- // or if that fails, from the current heap
-
- // first, try tapping temp memory
-
- *h = TempNewHandle( blockSize, &err );
-
- // in case of failure, try with current heap
-
- if ( *h == nil )
- {
- *h = NewHandleClear( blockSize );
- err = MemError();
- }
-
- return err;
- }
-
-
- #pragma mark -
- #pragma mark ••• Window Utils •••
-
- // given a window, return a handle to the DocumentRecord (stored in the window's refCon)
-
- // this function only returns something (i.e. !nil) for window types that ALWAYS have
- // a DocumentRecord** and/or a WASTE instance attached to the window. That means, only
- // "regular" windows and the clipboard window will return something; DialogRef's passed
- // to this function will return nil.
- // if in the future you (or I) add dialogs with WASTE instances attached to them, this
- // function will have to be modified.
-
- DocumentHandle HsoiGetWindowDocument( WindowRef window )
- {
- // make sure the window is not NIL and is one of our windows
-
- if ( window == nil )
- return nil;
-
- if ( (GetWindowKind(window) != kDocumentKind) && (GetWindowKind(window) != kClipboardKind) )
- return nil;
-
- // a handle to the document structure is kept in the window refCon
- return (DocumentHandle)GetWRefCon(window);
- }
-
- // a handy function: given a window, return it's associated WASTE instance. note the
- // function returns nil for non WASTE windows (i.e. not document nor clipboard windows)
-
- WEReference HsoiGetWindowWE( WindowRef window )
- {
- if ( window == nil )
- return nil;
-
- else if ( GetWindowKind(window) == dialogKind )
- return nil;
-
- else if ( (GetWindowKind(window) == kDocumentKind) || (GetWindowKind(window) == kClipboardKind) ||
- (GetWindowKind(window) == userKind) )
- return (*HsoiGetWindowDocument(window))->we;
- else
- return nil;
- }
-
- // takes a window as an argument and returns true if and only if the window is
- // a window belonging to the app (any window (text or clipboarad), dialog)
- // the windowKind's of userKind (value: 8) and dialogKind (value: 2) are defined
- // in Windows.h, and my own windowKind of kClipboardKind (value: 10) is defined
- // in HASMain.h
- // returns false if of another type (e.g. no window at all, a DA window).
-
- // if you need to know exactly what kind of window it is (e.g. if a dialog and only
- // a dialog, if the clipboard window and not a regular document window), use one
- // of the functions following this one.
-
- Boolean HsoiIsAppWindow( WindowRef window )
- {
- short windowKind;
-
- if ( window == nil )
- return false;
-
- else
- {
- windowKind = GetWindowKind( window );
- return ( (windowKind == dialogKind) || (windowKind == userKind) ||
- (windowKind == kClipboardKind) || (windowKind == kDocumentKind)
- #if HAS_DEBUG
- || ( windowKind == kTestWindowKind )
- #endif
- );
- }
- }
-
- // returns true only if the window belongs to a DA
-
- Boolean HsoiIsDAWindow( WindowRef window )
- {
- if ( window == nil )
- return false;
-
- else
- return( GetWindowKind(window) < 0 );
- }
-
- // returns true only if the window is a dialog
-
- Boolean HsoiIsDialogWindow( WindowRef window )
- {
- if ( window == nil )
- return false;
-
- else
- return ( (GetWindowKind(window) == dialogKind) );
- }
-
- // returns true only if the window is the clipboard window
-
- Boolean HsoiIsClipboardWindow( WindowRef window )
- {
- if ( window == nil )
- return false;
-
- else
- return ( GetWindowKind(window) == kClipboardKind );
- }
-
- // returns true only if the window is a "regular" document window
- // NOTE: the window must be BOTH be of type userKind AND have a WASTE
- // instance attached to it.
-
- Boolean HsoiIsDocumentWindow( WindowRef window )
- {
- if ( window == nil )
- return false;
-
- else
- return ( (GetWindowKind(window) == kDocumentKind) ||
- (GetWindowKind(window) == userKind) );
- }
-
- #pragma mark -
- #pragma mark ••• Trap/OS Utils •••
-
- /* Checking for System 7.0 (at least... )
-
- Hsoi's App Shell can only run on Macs with at least System 7. This is due
- to the many toolbox calls that are exclusive to system 7, plus the fact
- that the text engine (WASTE) requires System 7
- */
-
- /* Call System7Available to determine whether the system software version is
- 7 or higher... */
-
- Boolean HsoiSystem7Available( void )
- {
- long sysVersion;
-
- if ( !HsoiTrapAvailable( _Gestalt ) )
- return( false );
-
- if ( !Gestalt( gestaltSystemVersion, &sysVersion ) )
- {
- if ( sysVersion >= 0x0700 )
- return( true );
- }
-
- return( false );
- }
-
- Boolean HsoiTrapAvailable( short theTrap )
- {
- TrapType tType;
-
- tType = HsoiGetTrapType( theTrap );
-
- if ( tType == ToolTrap )
- {
- theTrap = ( theTrap & 0x07FF );
-
- if ( theTrap >= HsoiNumToolboxTraps() )
- theTrap = _Unimplemented;
- }
-
- return ( NGetTrapAddress( theTrap, tType ) != NGetTrapAddress( _Unimplemented, ToolTrap ) );
- }
-
-
- TrapType HsoiGetTrapType( short theTrap )
- {
- if ( ( theTrap & 0x0800 ) > 0 )
- {
- return ( ToolTrap );
- }
- else
- {
- return( OSTrap );
- }
- }
-
-
- short HsoiNumToolboxTraps( void )
- {
- if ( NGetTrapAddress( _InitGraf, ToolTrap ) == NGetTrapAddress( 0xAA6E, ToolTrap ) )
- {
- return ( 0x200 );
- }
- else
- {
- return ( 0x0400 );
- }
- }
-
- #pragma mark -
- #pragma mark ••• Error Handling •••
-
- /*
- DoError() takes care of all the error displaying stuff.
-
- s0, s1, s2, and s3 are strings which correspond to the ^0, ^1, etc "wildcards"
- in the error ALRT resources. If you do not use all the strings, be sure to
- pass NIL_STRING as an argument.
-
- the errNum is an error number, usually the return result of a function that
- returns an OSErr or the like...you can just pass the error/return result to
- DoError straight, and we'll take care of NumToString here.
-
- errType is the type of error alert to be displayed:
-
- kErrGeneric is just a sort of general "warning" error, but things can continue.
- it's the most flexible of the error displays.
-
- kErrDeath is a death alert...it's the same as calling kErrGeneric, but after
- the user dismisses the alert, ExitToShell() is called...usually best to
- be used in fatal conditions, like startup stuff.
-
- kErrWASTE is for WASTE routines...it takes only 1 string, and the errNum
- (all others should be nil or NIL_STRING). The one string argument is the
- name of the function that was just called, and the errNum is the return
- code that is the result of the error.
-
- See the various used of DoError around the code for "examples"
-
-
- *******
-
- Man, this is cruddy...I did this late at night (as usual) and changed it
- around a lot as I wrote it. I need to totally rewrite the error handlers
- to make it work better...
-
-
- */
-
-
- void HsoiDoError( short resID, short index, OSErr errNum, short errType )
- {
- Str255 errString = NIL_STRING,
- numString = NIL_STRING;
- short itemHit;
-
- if ( SoundIsPlaying() )
- StopCurrentSound();
-
- SetCursor( &qd.arrow );
-
- GetIndString( errString, resID, index );
-
- NumToString( errNum, numString );
-
- ParamText( errString, numString, NIL_STRING, NIL_STRING );
-
- switch ( errType )
- {
- case kErrNote:
- case kErrGeneric:
- {
- itemHit = NoteAlert( rGenericErrorAlert, HsoiGetMyStandardDialogFilter() );
- }
- break;
-
- case kErrCaution:
- {
- itemHit = CautionAlert( rGenericErrorAlert, HsoiGetMyStandardDialogFilter() );
- }
- break;
-
- case kErrStop:
- case kErrDeath:
- {
- itemHit = StopAlert( rGenericErrorAlert, HsoiGetMyStandardDialogFilter() );
-
- if ( errType == kErrDeath )
- ExitToShell();
- }
- break;
-
- } // end: switch( errType )
-
- return;
- }
-
-
- #pragma mark -
- #pragma mark ••• Font Utils •••
-
- // given a name of a font, return the font's ID number on the current system
-
- Boolean HsoiGetFontNumber(ConstStr255Param fontName, short *fontNum)
- {
- Str255 systemFontName;
-
- GetFNum(fontName, fontNum);
-
- if (*fontNum == 0)
- {
- //Either we didn't find the font, or we were looking for the system font.
-
- GetFontName(0, systemFontName);
-
- return EqualString(fontName, systemFontName, false, false);
- }
- else
- {
- return true;
- }
- }
-