home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Frameworks / Hsoi's App Shell 1.0a4 / Hsoi's App Shell Source / HASUtilities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-28  |  14.9 KB  |  576 lines  |  [TEXT/CWIE]

  1. /*
  2.     HASUtilities.c from Hsoi's App Shell © 1995-1997 John C. Daub.  All rights reserved.
  3.     
  4.     This file contains various utility functions to deal with things.  It's
  5.     kind of a "catch all" file for things that don't really fit anywhere else
  6.     cause they have the potential to be so generally used...either that or
  7.     i just didn't know where else to put them :)
  8.  
  9.     There are other HASUtilxxx.c files...these are also utility type functions, but
  10.     do tend to have more specific usage.
  11. */
  12.  
  13. #pragma mark ••• #includes •••
  14.  
  15. #ifndef __FP__
  16. #include <fp.h>
  17. #endif
  18. #ifndef __TEXTUTILS__
  19. #include <TextUtils.h>
  20. #endif
  21. #ifndef _WASTE_
  22. #include "WASTE.h"
  23. #endif
  24. #include "HASGlobals.h"
  25. #ifndef __HSOIS_APP_SHELL__
  26. #include "HASMain.h"
  27. #endif
  28. #include "HASDialogs.h"
  29. #include "HASMiscEvents.h"
  30. #include "HASUtilities.h"
  31. #ifndef __MARCO_MOVABLEMODALLIB__
  32. #include "HASMovableModal.h"
  33. #endif
  34.  
  35. #include "WASTE_Objects.h"
  36.  
  37. #if HAS_DEBUG
  38. #include "HASUtilTest.h"
  39. #endif
  40.  
  41. #pragma mark -
  42. #pragma mark ••• Floats & Strings •••
  43.  
  44. /*    the following functions, HsoiStringToExtended() and HsoiExtendedToString()
  45.     are based upon a selection from the April 1995 issue of "develop" magazine's
  46.     Q&A section.  They're basically "smarter" versions of StringToExtended() and
  47.     ExtendedToString.  Here's the original question:
  48.     
  49.         To make my application localizable, I want to use ExtendedToString and
  50.         StringToExtended to convert floats to strings and strings to floats.
  51.         These routines, though, use the SANE extended format, which is quite
  52.         archaic. What's the best way to convert a float to an extended to pass
  53.         to ExtendedToString? It should compile on both 680x0 and PowerPC
  54.         machines with MPW, Metrowerks, and THINK C.
  55.     
  56.     and the answer:
  57.     
  58.         A On PowerPC machines, extended80 and extended96 do not exist, except as
  59.         structures. There are a number of (PowerPC-only) conversion routines in
  60.         fp.h, like x80told. Your formatting code can be written as follows:
  61.     
  62.     (and the listed code from "develop" is the fuction, HsoiStringToExtended().
  63.     in the article, the function was called, LongDoubleToString())
  64.     
  65.     the article continues with more reasoning:
  66.     
  67.         Note that long double is equivalent to extended80 or extended96 on
  68.         680x0, and 128-bit double-double on PowerPC. If you want to format a
  69.         double, just pass it in and the compiler will take care of converting
  70.         double to long double or double to extended.
  71.         
  72.         SANE.h is being replaced by fp.h, for both 680x0 and PowerPC. This
  73.         issue's CD contains the libraries and interfaces for this new numerics
  74.         package, which implements the Floating-Point C Extensions (FPCE)
  75.         proposed technical draft of the Numerical C Extensions Group's
  76.         requirements (NCEG/X3J11.1).
  77.         
  78.         For more information on how to convert a SANE program to PowerPC, see
  79.         Inside Macintosh: PowerPC Numerics, Appendix A. In principle, you should
  80.         replace all use of extended with double_t. The double_t type maps back
  81.         to long double for 680x0, which is the same as extended; for PowerPC, it
  82.         maps to 64-bit double, which is the fastest floating-point format. Only
  83.         when you read or write 80- or 96-bit SANE numbers to files, or when you
  84.         want to use any of the Toolbox routines that take an 80-bit extended
  85.         parameter, do you need to use conversion routines.
  86.  
  87.     Incidentally, i found this stuff on Apple's Developer web site:
  88.     <http://dev.info.apple.com/> (that's valid as of this writing, 02 Jan 1996).
  89.     I just did a search with the keyword "stringtoextended" and got this.
  90.     
  91.     Oh, and since you're using an ANSI Library in this HAS project file, be
  92.     sure that depending on the compiler settings to add the right ANSI lib
  93.     in.  (and it might even be easy to do this with some pragmas at the top
  94.     of this file, like #if defined (powerc) #include <ANSI (2i).C.68k.Lib #endif
  95.     and that might work, y'know)?
  96.     
  97.     what i'd consider doing would be like this: (and this is using the CW7
  98.     ANSI library naming convention, or close enough to it).
  99.     
  100.     
  101.     void    HsoiExtendedToString( long double ld, const NumFormatString *myCanonical,
  102.                                                     const NumberParts *partsTable, Str255 outString )
  103.     {
  104.     #if defined(powerc) || defined (__powerc)
  105.         #include <ANSI (2i) C.PPC.lib>
  106.        extended80   x;
  107.     
  108.        ldtox80(&ld, &x);
  109.        ExtendedToString(&x, myCanonical, partsTable, outString);
  110.     #else
  111.        #ifdef mc68881
  112.                #include <ANSI (2i/F) C.68k.lib>
  113.           extended80   x;
  114.     
  115.           x96tox80(&ld, &x);
  116.           ExtendedToString(&x, myCanonical, partsTable, outString);
  117.        #else
  118.            #include <ANSI (2i) C.68k.Lib>
  119.           ExtendedToString(&ld, myCanonical, partsTable, outString);
  120.        #endif
  121.     #endif
  122.     }
  123.     
  124.     wonder if that might be a recommded way to do this or not....or if it's even
  125.     necessary.
  126.     
  127.     -------------
  128.     
  129.     Also, check out the function HsoiGetDoubleItem() in HAS Preferences.c.  There's
  130.     more explanation about these routines and my ways of getting around them.
  131. */
  132.  
  133. void    HsoiExtendedToString( long double ld, const NumFormatString *myCanonical,
  134.                                                 const NumberParts *partsTable, Str255 outString )
  135. {
  136. #if defined(powerc) || defined (__powerc)
  137.    extended80   x;
  138.  
  139.    ldtox80(&ld, &x);
  140.    ExtendedToString(&x, myCanonical, partsTable, outString);
  141. #else
  142.    #ifdef mc68881
  143.       extended80   x;
  144.  
  145.       x96tox80(&ld, &x);
  146.       ExtendedToString(&x, myCanonical, partsTable, outString);
  147.    #else
  148.       ExtendedToString(&ld, myCanonical, partsTable, outString);
  149.    #endif
  150. #endif
  151. }
  152.  
  153. void    HsoiStringToExtended( ConstStr255Param source, const NumFormatString *myCanonical,
  154.                                                 const NumberParts *partsTable, long double *x )
  155. {
  156. #if defined(powerc) || defined (__powerc)
  157.     extended80    y;
  158.     
  159.     StringToExtended( source, myCanonical, partsTable, &y );
  160.     x80told( &y, x );
  161.     
  162. #else
  163.     #ifdef mc68881
  164.         extended80 y;
  165.     
  166.         StringToExtended( source, myCanonical, partsTable, &y );
  167.         x80tox96( &y, x );
  168.     #else
  169.         StringToExtended( source, myCanonical, partsTable, x );
  170.     
  171.     #endif
  172. #endif
  173. }
  174.  
  175.  
  176. #pragma mark -
  177. #pragma mark ••• Memory Utils •••
  178.  
  179.  
  180. /*
  181.  *    This is just a nifty little way of disposing of Handles
  182.  */
  183.  
  184. void    HsoiForgetHandle( Handle *h )
  185. {
  186.     Handle    theHandle;
  187.     
  188.     theHandle = *h;
  189.     
  190.     if ( theHandle != nil )
  191.     {
  192.         *h = nil;
  193.         DisposeHandle( theHandle );
  194.     }
  195.  
  196.     return;
  197. }
  198.  
  199. // same thing here as with ForgetHandle() in regards to the argument list, but this is
  200. // for resources instead.
  201.  
  202. void    HsoiForgetResource( Handle *h )
  203. {
  204.     Handle        theHandle;
  205.     
  206.     theHandle = *h;
  207.     
  208.     if ( theHandle != nil )
  209.     {
  210.         *h = nil;
  211.         ReleaseResource( theHandle );
  212.     }
  213.     
  214.     return;
  215. }
  216.  
  217. // the following 2 functions are "better" ways of allocating space for a New Handle.
  218. // they both do the same thing:  first try to tap temporary memory for space to
  219. // allocate the handle.  if that fails, try to allocate in the app's heap.  the
  220. // only difference between the 2 functions is that the 2nd (Clear) calls NewHandleClear
  221. // instead. (note, there is note TempNewHandleClear() function.)
  222.  
  223.  
  224. OSErr    HsoiNewHandleTemp( Size blockSize, Handle *h )
  225. {
  226.     OSErr        err;
  227.     
  228.     // allocate a new relocatable block from temporary memory, or
  229.     // if that fails, from the current heap
  230.     
  231.     // first try tapping temporary memory
  232.     
  233.     *h = TempNewHandle( blockSize, &err );
  234.     
  235.     // in case of failure, try with current heap
  236.     
  237.     if ( *h == nil )
  238.     {
  239.         *h = NewHandle( blockSize );
  240.         err = MemError();
  241.     }
  242.     
  243.     return err;
  244. }
  245.  
  246.  
  247. OSErr    HsoiNewHandleTempClear( Size blockSize, Handle *h )
  248. {
  249.     OSErr    err;
  250.     
  251.     // allocate a new relocateable block from temporary memory,
  252.     // or if that fails, from the current heap
  253.     
  254.     // first, try tapping temp memory
  255.     
  256.     *h = TempNewHandle( blockSize, &err );
  257.     
  258.     // in case of failure, try with current heap
  259.     
  260.     if ( *h == nil )
  261.     {
  262.         *h = NewHandleClear( blockSize );
  263.         err = MemError();
  264.     }
  265.     
  266.     return err;
  267. }
  268.  
  269.  
  270. #pragma mark -
  271. #pragma mark ••• Window Utils •••
  272.  
  273. // given a window, return a handle to the DocumentRecord (stored in the window's refCon)
  274.  
  275. // this function only returns something (i.e. !nil) for window types that ALWAYS have
  276. // a DocumentRecord** and/or a WASTE instance attached to the window.  That means, only
  277. // "regular" windows and the clipboard window will return something; DialogRef's passed
  278. // to this function will return nil.
  279. // if in the future you (or I) add dialogs with WASTE instances attached to them, this
  280. // function will have to be modified.
  281.  
  282. DocumentHandle    HsoiGetWindowDocument( WindowRef window )
  283. {
  284.     // make sure the window is not NIL and is one of our windows
  285.  
  286.     if ( window == nil )
  287.         return nil;
  288.     
  289.     if ( (GetWindowKind(window) != kDocumentKind) && (GetWindowKind(window) != kClipboardKind) )
  290.         return nil;
  291.             
  292.     // a handle to the document structure is kept in the window refCon
  293.     return (DocumentHandle)GetWRefCon(window);
  294. }
  295.  
  296. // a handy function:  given a window, return it's associated WASTE instance.  note the
  297. // function returns nil for non WASTE windows (i.e. not document nor clipboard windows)
  298.  
  299. WEReference    HsoiGetWindowWE( WindowRef window )
  300. {    
  301.     if ( window == nil )
  302.         return nil;
  303.     
  304.     else if ( GetWindowKind(window) == dialogKind )
  305.         return nil;
  306.     
  307.     else if ( (GetWindowKind(window) == kDocumentKind) || (GetWindowKind(window) == kClipboardKind) ||
  308.                 (GetWindowKind(window) == userKind) )
  309.          return (*HsoiGetWindowDocument(window))->we;
  310.     else
  311.         return nil;
  312. }
  313.  
  314. // takes a window as an argument and returns true if and only if the window is
  315. // a window belonging to the app (any window (text or clipboarad), dialog)
  316. // the windowKind's of userKind (value: 8) and dialogKind (value: 2) are defined
  317. // in Windows.h, and my own windowKind of kClipboardKind (value: 10) is defined
  318. // in HASMain.h
  319. // returns false if of another type (e.g. no window at all, a DA window).
  320.  
  321. // if you need to know exactly what kind of window it is (e.g. if a dialog and only
  322. // a dialog, if the clipboard window and not a regular document window), use one
  323. // of the functions following this one.
  324.  
  325. Boolean    HsoiIsAppWindow( WindowRef window )
  326. {
  327.     short    windowKind;
  328.     
  329.     if ( window == nil )
  330.         return false;
  331.     
  332.     else
  333.     {
  334.         windowKind = GetWindowKind( window );
  335.         return ( (windowKind == dialogKind) || (windowKind == userKind) || 
  336.                 (windowKind == kClipboardKind) || (windowKind == kDocumentKind)
  337. #if HAS_DEBUG
  338.                 || ( windowKind == kTestWindowKind )                
  339. #endif
  340.                  );
  341.     }
  342. }
  343.  
  344. // returns true only if the window belongs to a DA
  345.  
  346. Boolean    HsoiIsDAWindow( WindowRef window )
  347. {
  348.     if ( window == nil )
  349.         return false;
  350.     
  351.     else
  352.         return( GetWindowKind(window) < 0 );
  353. }
  354.  
  355. // returns true only if the window is a dialog
  356.  
  357. Boolean    HsoiIsDialogWindow( WindowRef window )
  358. {
  359.     if ( window == nil )
  360.         return false;
  361.     
  362.     else
  363.         return ( (GetWindowKind(window) == dialogKind) );
  364. }
  365.  
  366. // returns true only if the window is the clipboard window
  367.  
  368. Boolean    HsoiIsClipboardWindow( WindowRef window )
  369. {
  370.     if ( window == nil )
  371.         return false;
  372.     
  373.     else
  374.         return ( GetWindowKind(window) == kClipboardKind );
  375. }
  376.  
  377. // returns true only if the window is a "regular" document window
  378. // NOTE: the window must be BOTH be of type userKind AND have a WASTE
  379. // instance attached to it.
  380.  
  381. Boolean HsoiIsDocumentWindow( WindowRef window )
  382. {    
  383.     if ( window == nil )
  384.         return false;
  385.     
  386.     else
  387.         return ( (GetWindowKind(window) == kDocumentKind) ||
  388.                 (GetWindowKind(window) == userKind) );
  389. }
  390.  
  391. #pragma mark -
  392. #pragma mark ••• Trap/OS Utils •••
  393.  
  394. /*    Checking for System 7.0 (at least... )
  395.  
  396.     Hsoi's App Shell can only run on Macs with at least System 7.  This is due
  397.     to the many toolbox calls that are exclusive to system 7, plus the fact
  398.     that the text engine (WASTE) requires System 7
  399.  */
  400.  
  401. /*    Call System7Available to determine whether the system software version is
  402.     7 or higher... */
  403.     
  404. Boolean    HsoiSystem7Available( void )
  405. {
  406.     long    sysVersion;
  407.     
  408.     if ( !HsoiTrapAvailable( _Gestalt ) )
  409.         return( false );
  410.     
  411.     if ( !Gestalt( gestaltSystemVersion, &sysVersion ) )
  412.     {
  413.         if ( sysVersion >= 0x0700 )
  414.             return( true );
  415.     }
  416.     
  417.     return( false );
  418. }
  419.  
  420. Boolean    HsoiTrapAvailable( short theTrap )
  421. {
  422.     TrapType        tType;
  423.     
  424.     tType = HsoiGetTrapType( theTrap );
  425.     
  426.     if ( tType == ToolTrap )
  427.     {
  428.         theTrap = ( theTrap & 0x07FF );
  429.         
  430.         if ( theTrap >= HsoiNumToolboxTraps() )
  431.             theTrap = _Unimplemented;
  432.     }
  433.     
  434.     return ( NGetTrapAddress( theTrap, tType ) != NGetTrapAddress( _Unimplemented, ToolTrap ) );
  435. }
  436.  
  437.  
  438. TrapType HsoiGetTrapType( short theTrap )
  439. {
  440.     if ( ( theTrap & 0x0800 ) > 0 )
  441.     {
  442.         return ( ToolTrap );
  443.     }
  444.     else
  445.     {
  446.         return( OSTrap );
  447.     }
  448. }
  449.  
  450.  
  451. short    HsoiNumToolboxTraps( void )
  452. {
  453.     if ( NGetTrapAddress( _InitGraf, ToolTrap ) == NGetTrapAddress( 0xAA6E, ToolTrap ) )
  454.     {
  455.         return ( 0x200 );
  456.     }
  457.     else
  458.     {
  459.         return ( 0x0400 );
  460.     }
  461. }
  462.  
  463. #pragma mark -
  464. #pragma mark ••• Error Handling •••
  465.  
  466. /*
  467.     DoError() takes care of all the error displaying stuff.
  468.     
  469.     s0, s1, s2, and s3 are strings which correspond to the ^0, ^1, etc "wildcards"
  470.     in the error ALRT resources.  If you do not use all the strings, be sure to
  471.     pass NIL_STRING as an argument.
  472.  
  473.     the errNum is an error number, usually the return result of a function that
  474.     returns an OSErr or the like...you can just pass the error/return result to
  475.     DoError straight, and we'll take care of NumToString here.
  476.     
  477.     errType is the type of error alert to be displayed:
  478.     
  479.     kErrGeneric is just a sort of general "warning" error, but things can continue.
  480.     it's the most flexible of the error displays.
  481.     
  482.     kErrDeath is a death alert...it's the same as calling kErrGeneric, but after
  483.     the user dismisses the alert, ExitToShell() is called...usually best to
  484.     be used in fatal conditions, like startup stuff.
  485.     
  486.     kErrWASTE is for WASTE routines...it takes only 1 string, and the errNum
  487.     (all others should be nil or NIL_STRING).  The one string argument is the
  488.     name of the function that was just called, and the errNum is the return
  489.     code that is the result of the error.
  490.     
  491.     See the various used of DoError around the code for "examples"
  492.     
  493.     
  494.     *******
  495.     
  496.     Man, this is cruddy...I did this late at night (as usual) and changed it
  497.     around a lot as I wrote it.  I need to totally rewrite the error handlers
  498.     to make it work better...
  499.     
  500.     
  501. */    
  502.  
  503.  
  504. void    HsoiDoError( short resID, short index, OSErr errNum, short errType )
  505. {
  506.     Str255            errString = NIL_STRING,
  507.                     numString = NIL_STRING;
  508.     short            itemHit;
  509.     
  510.     if ( SoundIsPlaying() )
  511.         StopCurrentSound();
  512.     
  513.     SetCursor( &qd.arrow );
  514.     
  515.     GetIndString( errString, resID, index );
  516.     
  517.     NumToString( errNum, numString );
  518.     
  519.     ParamText( errString, numString, NIL_STRING, NIL_STRING );
  520.     
  521.     switch ( errType )
  522.     {
  523.         case kErrNote:
  524.         case kErrGeneric:
  525.         {
  526.             itemHit = NoteAlert( rGenericErrorAlert, HsoiGetMyStandardDialogFilter() );
  527.         }
  528.         break;
  529.         
  530.         case kErrCaution:
  531.         {
  532.             itemHit = CautionAlert( rGenericErrorAlert, HsoiGetMyStandardDialogFilter() );
  533.         }
  534.         break;
  535.         
  536.         case kErrStop:
  537.         case kErrDeath:
  538.         {
  539.             itemHit = StopAlert( rGenericErrorAlert, HsoiGetMyStandardDialogFilter() );
  540.             
  541.             if ( errType == kErrDeath )
  542.                 ExitToShell();
  543.         }
  544.         break;
  545.     
  546.     } // end:  switch( errType )
  547.  
  548.     return;
  549. }
  550.  
  551.  
  552. #pragma mark -
  553. #pragma mark ••• Font Utils •••
  554.  
  555. // given a name of a font, return the font's ID number on the current system
  556.  
  557. Boolean        HsoiGetFontNumber(ConstStr255Param fontName, short *fontNum)
  558. {
  559.     Str255        systemFontName;
  560.  
  561.     GetFNum(fontName, fontNum);
  562.  
  563.     if (*fontNum == 0)
  564.     {
  565.         //Either we didn't find the font, or we were looking for the system font. 
  566.         
  567.         GetFontName(0, systemFontName);
  568.         
  569.         return EqualString(fontName, systemFontName, false, false);
  570.     } 
  571.     else
  572.     {
  573.         return true;
  574.     }
  575. }
  576.