potts@itl.itd.umich.edu (Paul Potts) (06/14/91)
I've been putting together some code to use Gestalt in its new and improved form. Since it has taken me a while to get it going, I thought I would post it to save someone else time. This uses the new method for checking trap availability described in IM-6, chapter 3. I've translated some of that code directly into THINK C. If anyone finds an error, please post a correction. It seems to work fine. ----------- compatibility.h ------------ ---- this is a header file that lists some useful function prototypes and defines for the compatibility.c file ---------------------------- #define GESTALT_NOT_PRESENT -1 /* prototypes */ int NumToolboxTraps (void); TrapType GetTrapType (int theTrap); Boolean TrapAvailable (int theTrap); Boolean WNEAvailable (void); Boolean GestaltAvailable (void); Boolean testAttribute (OSType selector, short attribute, short * error); short GestaltFeature(OSType selector, long * feature); Boolean GestaltPresent(void); --------- compatibility.c -------------- ---- here are some useful functions to work with Gestalt. ------ #include <GestaltEqu.h> #include "Compatibility.h" /* contains prototypes */ int NumToolboxTraps(void) { return ((NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap)) ? 0x200 : 0x400); } TrapType GetTrapType (theTrap) int theTrap; { return ((theTrap & 0x0800) ? ToolTrap : OSTrap); } Boolean TrapAvailable (theTrap) int theTrap; { TrapType tType; tType = GetTrapType (theTrap); if (tType == ToolTrap) { theTrap = (theTrap & 0x07FF); if (theTrap >= NumToolboxTraps()) theTrap = _Unimplemented; } return ((NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap))); } Boolean WNEAvailable(void) { return (TrapAvailable (0xA860)); } Boolean GestaltAvailable (void) { return (TrapAvailable (0xA1Ad /*Gestalt*/ )); } Boolean GestaltPresent() { return GestaltAvailable(); } short GestaltFeature(OSType selector, long * feature) { return Gestalt(selector, feature); } Boolean testAttribute (OSType selector, short attribute, short * error) { long feature; if (GestaltPresent()) { *error = GestaltFeature (gestaltHardwareAttr, &feature); return (BitTst((void*)&feature, 31 - attribute)); } else { * error = -1; } /* my code for Gestalt Not Present */ } ---------------------------------------------------------- ------ Now here is some code that shows how you might ---- ------ call these routines ------------------------------- void HandleGestaltError(short error) { switch (error) { case GESTALT_NOT_PRESENT: error_message (NO_GESTALT); /* do whatever error handling you do */ break; case gestaltUnknownErr: case gestaltUndefSelectorErr: /* could handle these cases separately, but I just return a general message */ default: error_message (GESTALT_ERROR); break; /* NOTE THE FALL-THROUGH which occurs when I have a case without an explicit break */ } /* end of switch */ } /* end of procedure */ ----------- this example function tests for compatibility by ----------- looking to see if an apple sound chip is present, ----------- and returns false if it isn't. Boolean compatible() { Boolean result; short error; result = testAttribute (gestaltHardwareAttr, gestaltHasASC, &error); if (error !=0) /* if Gestalt returned an OS Error or -1 */ { HandleGestaltError(error); return (FALSE); } else /* assume result is correct */ { if (!result) /* sound chip bit was zero */ { error_message (NO_SOUND_CHIP); return (FALSE); } else /* sound chip bit was one */ { return (result); /* return TRUE */ } } /* end of no OS Error returned case */ } /* end of procedure */ --------------- Have fun! let me know if anyone finds errors. ------- Paul Potts potts@itl.itd.umich.edu Paul_Potts@um.cc.umich.edu
keith@Apple.COM (Keith Rollin) (06/17/91)
In article <1991Jun14.160733.14793@terminator.cc.umich.edu> potts@itl.itd.umich.edu (Paul Potts) writes: >I've been putting together some code to use Gestalt in its new and >improved form. Since it has taken me a while to get it going, I thought >I would post it to save someone else time. > >This uses the new method for checking trap availability described in IM-6, >chapter 3. I've translated some of that code directly into THINK C. > >If anyone finds an error, please post a correction. It seems to work fine. In the code that you posted, you check for the existance of the _Gestalt trap. I don't think this is a good idea. Gestalt is both glue and a trap. When you compile a program with a version of MPW or THINK that supports Gestalt, you end up calling the glue. The glue checks to see if the trap is implemented. If so, the trap is called. If not, the rest of the glue provides some emulated behavior. If you check for the trap yourself, you loose out on this emulated behavior. Actually, the above is just a little shy of the truth. It is possible for you to specify that you want your program to be built for 7.0 or later, in which case you end up calling the trap directly. However, in that case, you can safely assume the existance of _Gestalt and not check for it. By the way, in testAttribute(), why do you use: return (BitTst((void*)&feature, 31 - attribute)); instead of return (feature & (1 << attribute)); ? -- ------------------------------------------------------------------------------ Keith Rollin --- Apple Computer, Inc. INTERNET: keith@apple.com UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith "But where the senses fail us, reason must step in." - Galileo