1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Various utilities 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 // Note: this is done in utilscmn.cpp now. 
  14 // #pragma implementation "utils.h" 
  20 #include "wx/apptrait.h" 
  23     #include "wx/mac/uma.h" 
  34 #  include "MoreFilesX.h" 
  36 #  include "MoreFiles.h" 
  37 #  include "MoreFilesExtras.h" 
  45 #include "ATSUnicode.h" 
  46 #include "TextCommon.h" 
  47 #include "TextEncodingConverter.h" 
  49 #if defined(__WXMAC__) 
  50   #include  "wx/mac/private.h"  // includes mac headers 
  53 #if defined(__MWERKS__) && wxUSE_UNICODE 
  60 // defined in unix/utilsunx.cpp for Mac OS X 
  62 // get full hostname (with domain name if possible) 
  63 bool wxGetFullHostName(wxChar 
*buf
, int maxSize
) 
  65     return wxGetHostName(buf
, maxSize
); 
  68 // Get hostname only (without domain name) 
  69 bool wxGetHostName(wxChar 
*buf
, int maxSize
) 
  71     // Gets Chooser name of user by examining a System resource. 
  73     const short kComputerNameID 
= -16413; 
  75     short oldResFile 
= CurResFile() ; 
  77     StringHandle chooserName 
= (StringHandle
)::GetString(kComputerNameID
); 
  78     UseResFile(oldResFile
); 
  80     if (chooserName 
&& *chooserName
) 
  82         HLock( (Handle
) chooserName 
) ; 
  83         wxString name 
= wxMacMakeStringFromPascal( *chooserName 
) ; 
  84         HUnlock( (Handle
) chooserName 
) ; 
  85         ReleaseResource( (Handle
) chooserName 
) ; 
  86         wxStrncpy( buf 
, name 
, maxSize 
- 1 ) ; 
  94 // Get user ID e.g. jacs 
  95 bool wxGetUserId(wxChar 
*buf
, int maxSize
) 
  97   return wxGetUserName( buf 
, maxSize 
) ; 
 100 const wxChar
* wxGetHomeDir(wxString 
*pstr
) 
 102     *pstr 
= wxMacFindFolder(  (short) kOnSystemDisk
, kPreferencesFolderType
, kDontCreateFolder 
) ; 
 103     return pstr
->c_str() ; 
 106 // Get user name e.g. Stefan Csomor 
 107 bool wxGetUserName(wxChar 
*buf
, int maxSize
) 
 109     // Gets Chooser name of user by examining a System resource. 
 111     const short kChooserNameID 
= -16096; 
 113     short oldResFile 
= CurResFile() ; 
 115     StringHandle chooserName 
= (StringHandle
)::GetString(kChooserNameID
); 
 116     UseResFile(oldResFile
); 
 118     if (chooserName 
&& *chooserName
) 
 120         HLock( (Handle
) chooserName 
) ; 
 121         wxString name 
= wxMacMakeStringFromPascal( *chooserName 
) ; 
 122         HUnlock( (Handle
) chooserName 
) ; 
 123         ReleaseResource( (Handle
) chooserName 
) ; 
 124         wxStrncpy( buf 
, name 
, maxSize 
- 1 ) ; 
 132 int wxKill(long pid
, wxSignal sig 
, wxKillError 
*rc 
) 
 138 WXDLLEXPORT 
bool wxGetEnv(const wxString
& var
, wxString 
*value
) 
 140     // TODO : under classic there is no environement support, under X yes 
 144 // set the env var name to the given value, return TRUE on success 
 145 WXDLLEXPORT 
bool wxSetEnv(const wxString
& var
, const wxChar 
*value
) 
 147     // TODO : under classic there is no environement support, under X yes 
 152 // Execute a program in an Interactive Shell 
 154 bool wxShell(const wxString
& command
) 
 160 // Shutdown or reboot the PC 
 161 bool wxShutdown(wxShutdownFlags wFlags
) 
 167 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) 
 168 long wxGetFreeMemory() 
 173 void wxUsleep(unsigned long milliseconds
) 
 175     clock_t start 
= clock() ; 
 179     } while( clock() - start 
< milliseconds 
/  1000.0 * CLOCKS_PER_SEC 
) ; 
 182 void wxSleep(int nSecs
) 
 184     wxUsleep(1000*nSecs
); 
 187 // Consume all events until no more left 
 192 #endif // !__DARWIN__ 
 200 // our OS version is the same in non GUI and GUI cases 
 201 static int DoGetOSVersion(int *majorVsn
, int *minorVsn
) 
 205     // are there x-platform conventions ? 
 207     Gestalt(gestaltSystemVersion
, &theSystem
) ; 
 208     if (minorVsn 
!= NULL
) { 
 209         *minorVsn 
= (theSystem 
& 0xFF ) ; 
 211     if (majorVsn 
!= NULL
) { 
 212         *majorVsn 
= (theSystem 
>> 8 ) ; 
 221 int wxConsoleAppTraits::GetOSVersion(int *majorVsn
, int *minorVsn
) 
 223     return DoGetOSVersion(majorVsn
, minorVsn
); 
 230 int wxGUIAppTraits::GetOSVersion(int *majorVsn
, int *minorVsn
) 
 232     return DoGetOSVersion(majorVsn
, minorVsn
); 
 235 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
 237 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
) 
 243 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
) 
 246     buf
.Printf(wxT("%.4f"), value
); 
 248     return wxWriteResource(section
, entry
, buf
, file
); 
 251 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
) 
 254     buf
.Printf(wxT("%ld"), value
); 
 256     return wxWriteResource(section
, entry
, buf
, file
); 
 259 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
) 
 262     buf
.Printf(wxT("%d"), value
); 
 264     return wxWriteResource(section
, entry
, buf
, file
); 
 267 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
) 
 273 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
) 
 276     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 279         *value 
= (float)strtod(s
, NULL
); 
 286 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
) 
 289     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 292         *value 
= strtol(s
, NULL
, 10); 
 299 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
) 
 302     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 305         *value 
= (int)strtol(s
, NULL
, 10); 
 311 #endif // wxUSE_RESOURCES 
 313 int gs_wxBusyCursorCount 
= 0; 
 314 extern wxCursor    gMacCurrentCursor 
; 
 315 wxCursor        gMacStoredActiveCursor 
; 
 317 // Set the cursor to the busy cursor for all windows 
 318 void wxBeginBusyCursor(wxCursor 
*cursor
) 
 320     if (gs_wxBusyCursorCount
++ == 0) 
 322         gMacStoredActiveCursor 
= gMacCurrentCursor 
; 
 323         cursor
->MacInstall() ; 
 325     //else: nothing to do, already set 
 328 // Restore cursor to normal 
 329 void wxEndBusyCursor() 
 331     wxCHECK_RET( gs_wxBusyCursorCount 
> 0, 
 332         wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") ); 
 334     if (--gs_wxBusyCursorCount 
== 0) 
 336         gMacStoredActiveCursor
.MacInstall() ; 
 337         gMacStoredActiveCursor 
= wxNullCursor 
; 
 341 // TRUE if we're between the above two calls 
 344     return (gs_wxBusyCursorCount 
> 0); 
 347 wxString 
wxMacFindFolder( short        vol
, 
 349               Boolean      createFolder
) 
 355     if ( FindFolder( vol
, folderType
, createFolder
, &vRefNum
, &dirID
) == noErr
) 
 358         if ( FSMakeFSSpec( vRefNum 
, dirID 
, "\p" , &file 
) == noErr 
) 
 360             strDir 
= wxMacFSSpec2MacFilename( &file 
) + wxFILE_SEP_PATH 
; 
 366 // Check whether this window wants to process messages, e.g. Stop button 
 367 // in long calculations. 
 368 bool wxCheckForInterrupt(wxWindow 
*wnd
) 
 374 void wxGetMousePosition( int* x
, int* y 
) 
 379     LocalToGlobal( &pt 
) ; 
 384 // Return TRUE if we have a colour display 
 385 bool wxColourDisplay() 
 390 // Returns depth of screen 
 394     SetRect(&globRect
, -32760, -32760, 32760, 32760); 
 395     GDHandle    theMaxDevice
; 
 398     theMaxDevice 
= GetMaxDevice(&globRect
); 
 399     if (theMaxDevice 
!= nil
) 
 400         theDepth 
= (**(**theMaxDevice
).gdPMap
).pixelSize
; 
 405 // Get size of display 
 406 void wxDisplaySize(int *width
, int *height
) 
 409     GetQDGlobalsScreenBits( &screenBits 
); 
 412         *width 
= screenBits
.bounds
.right 
- screenBits
.bounds
.left  
; 
 414     if (height 
!= NULL
) { 
 415         *height 
= screenBits
.bounds
.bottom 
- screenBits
.bounds
.top 
; 
 419 void wxDisplaySizeMM(int *width
, int *height
) 
 421     wxDisplaySize(width
, height
); 
 422     // on mac 72 is fixed (at least now ;-) 
 423     float cvPt2Mm 
= 25.4 / 72; 
 426         *width 
= int( *width 
* cvPt2Mm 
); 
 428     if (height 
!= NULL
) { 
 429         *height 
= int( *height 
* cvPt2Mm 
); 
 433 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 436     GetQDGlobalsScreenBits( &screenBits 
); 
 442         *width 
= screenBits
.bounds
.right 
- screenBits
.bounds
.left  
; 
 444     if (height 
!= NULL
) { 
 445         *height 
= screenBits
.bounds
.bottom 
- screenBits
.bounds
.top 
; 
 450     GetThemeMenuBarHeight( &mheight 
) ; 
 452     mheight 
= LMGetMBarHeight() ; 
 454     if (height 
!= NULL
) { 
 461 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
 463     return wxGenericFindWindowAtPoint(pt
); 
 470 wxString 
wxGetOsDescription() 
 472 #ifdef WXWIN_OS_DESCRIPTION 
 473     // use configure generated description if available 
 474     return wxString("MacOS (") + WXWIN_OS_DESCRIPTION 
+ wxString(")"); 
 476     return wxT("MacOS") ; //TODO:define further 
 481 wxChar 
*wxGetUserHome (const wxString
& user
) 
 487 bool wxGetDiskSpace(const wxString
& path
, wxLongLong 
*pTotal
, wxLongLong 
*pFree
) 
 497     int pos 
= p
.Find(':') ; 
 498     if ( pos 
!= wxNOT_FOUND 
) { 
 507     wxMacStringToPascal( p  
, volumeName 
) ; 
 508     OSErr err 
= XGetVolumeInfoNoName( volumeName 
, 0 , &pb 
) ; 
 509     if ( err 
== noErr 
) { 
 511         (*pTotal
) = wxLongLong( pb
.ioVTotalBytes 
) ; 
 514         (*pFree
) = wxLongLong( pb
.ioVFreeBytes 
) ; 
 518     return err 
== noErr 
; 
 520 #endif // !__DARWIN__ 
 526 //--------------------------------------------------------------------------- 
 527 // wxMac Specific utility functions 
 528 //--------------------------------------------------------------------------- 
 530 char StringMac
[] =  "\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" 
 531                     "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" 
 532                     "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf" 
 533                     "\xb1\xb4\xb5\xb6\xbb\xbc\xbe\xbf" 
 534                     "\xc0\xc1\xc2\xc4\xc7\xc8\xc9\xcb\xcc\xcd\xce\xcf" 
 535                     "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xca\xdb" ; 
 537 char StringANSI
[] = "\x0a\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8" 
 538                     "\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC" 
 539                     "\x86\xBA\xA2\xA3\xA7\x95\xB6\xDF\xAE\xA9\x99\xB4\xA8\xC6\xD8" 
 540                     "\xB1\xA5\xB5\xF0\xAA\xBA\xE6\xF8" 
 541                     "\xBF\xA1\xAC\x83\xAB\xBB\x85\xC0\xC3\xD5\x8C\x9C" 
 542                     "\x96\x97\x93\x94\x91\x92\xF7\xFF\xA0\x80" ; 
 544 void wxMacConvertFromPC( const char *from 
, char *to 
, int len 
) 
 549         for( int i 
= 0 ; i 
< len 
; ++ i 
) 
 551             c 
= strchr( StringANSI 
, *from 
) ; 
 554                 *to 
= StringMac
[ c 
- StringANSI
] ; 
 562         for( int i 
= 0 ; i 
< len 
; ++ i 
) 
 564             c 
= strchr( StringANSI 
, *from 
) ; 
 567                 *to 
= StringMac
[ c 
- StringANSI
] ; 
 579 void wxMacConvertToPC( const char *from 
, char *to 
, int len 
) 
 584         for( int i 
= 0 ; i 
< len 
; ++ i 
) 
 586             c 
= strchr( StringMac 
, *from 
) ; 
 589                 *to 
= StringANSI
[ c 
- StringMac
] ; 
 597         for( int i 
= 0 ; i 
< len 
; ++ i 
) 
 599             c 
= strchr( StringMac 
, *from 
) ; 
 602                 *to 
= StringANSI
[ c 
- StringMac
] ; 
 614 TECObjectRef s_TECNativeCToUnicode 
= NULL 
; 
 615 TECObjectRef s_TECUnicodeToNativeC 
= NULL 
; 
 616 TECObjectRef s_TECPlatformToNativeC 
= NULL 
; 
 617 TECObjectRef s_TECNativeCToPlatform 
= NULL 
; 
 618 void wxMacSetupConverters() 
 620     // if we assume errors are happening here we need low level debugging 
 621     // since the high level assert will use the encoders that are not yet 
 623     const int kEncoding 
= wxApp::s_macDefaultEncodingIsPC
 
 624                             ? (int)kTextEncodingWindowsLatin1
 
 625                             : (int)kTextEncodingMacRoman
; 
 627     OSStatus status 
= noErr 
; 
 628     status 
= TECCreateConverter(&s_TECNativeCToUnicode
, 
 630                                 kTextEncodingUnicodeDefault
); 
 633     status 
= TECCreateConverter(&s_TECUnicodeToNativeC
, 
 634                                 kTextEncodingUnicodeDefault
, 
 637     if ( wxApp::s_macDefaultEncodingIsPC 
) 
 639         status 
= TECCreateConverter(&s_TECPlatformToNativeC
, 
 640                                     kTextEncodingMacRoman
, 
 641                                     kTextEncodingWindowsLatin1
); 
 644         status 
= TECCreateConverter(&s_TECNativeCToPlatform
, 
 645                                     kTextEncodingWindowsLatin1
, 
 646                                     kTextEncodingMacRoman
); 
 650 void wxMacCleanupConverters() 
 652     OSStatus status 
= noErr 
; 
 653     status 
= TECDisposeConverter(s_TECNativeCToUnicode
); 
 655     status 
= TECDisposeConverter(s_TECUnicodeToNativeC
); 
 657     status 
= TECDisposeConverter(s_TECPlatformToNativeC
); 
 659     status 
= TECDisposeConverter(s_TECNativeCToPlatform
); 
 662 wxWCharBuffer 
wxMacStringToWString( const wxString 
&from 
) 
 665     wxWCharBuffer 
result( from
.wc_str() ) ; 
 667     OSStatus status 
= noErr 
; 
 668     ByteCount byteOutLen 
; 
 669     ByteCount byteInLen 
= from
.Length() ; 
 670     ByteCount byteBufferLen 
= byteInLen 
*2 ; 
 671     wxWCharBuffer 
result( from
.Length() ) ; 
 672     status 
= TECConvertText(s_TECNativeCToUnicode
, (ConstTextPtr
)from
.c_str() , byteInLen
, &byteInLen
, 
 673         (TextPtr
)result
.data(), byteBufferLen
, &byteOutLen
); 
 674     result
.data()[byteOutLen
/2] = 0 ; 
 679 wxString 
wxMacMakeStringFromCString( const char * from 
, int len 
) 
 681     OSStatus status 
= noErr 
; 
 683     wxChar
* buf 
= result
.GetWriteBuf( len 
) ; 
 685     ByteCount byteOutLen 
; 
 686     ByteCount byteInLen 
= len 
; 
 687     ByteCount byteBufferLen 
= len 
*2 ; 
 689     status 
= TECConvertText(s_TECNativeCToUnicode
, (ConstTextPtr
)from 
, byteInLen
, &byteInLen
, 
 690         (TextPtr
)buf
, byteBufferLen
, &byteOutLen
); 
 692     if ( !wxApp::s_macDefaultEncodingIsPC 
) 
 693         memcpy( buf 
, from 
, len 
) ; 
 696         ByteCount byteOutLen 
; 
 697         ByteCount byteInLen 
= len 
; 
 698         ByteCount byteBufferLen 
= byteInLen 
; 
 700         status 
= TECConvertText(s_TECPlatformToNativeC
, (ConstTextPtr
)from 
, byteInLen
, &byteInLen
, 
 701             (TextPtr
)buf
, byteBufferLen
, &byteOutLen
); 
 705     result
.UngetWriteBuf() ; 
 709 wxString 
wxMacMakeStringFromCString( const char * from 
) 
 711     return wxMacMakeStringFromCString( from 
, strlen(from
) ) ; 
 714 wxCharBuffer 
wxMacStringToCString( const wxString 
&from 
) 
 717     OSStatus status 
= noErr 
; 
 718     ByteCount byteOutLen 
; 
 719     ByteCount byteInLen 
= from
.Length() * 2 ; 
 720     ByteCount byteBufferLen 
= from
.Length() ; 
 721     wxCharBuffer 
result( from
.Length() ) ; 
 722     status 
= TECConvertText(s_TECUnicodeToNativeC 
, (ConstTextPtr
)from
.wc_str() , byteInLen
, &byteInLen
, 
 723         (TextPtr
)result
.data(), byteBufferLen
, &byteOutLen
); 
 726     if ( !wxApp::s_macDefaultEncodingIsPC 
) 
 727         return wxCharBuffer( from
.c_str() ) ; 
 730         wxCharBuffer 
result( from
.Length() ) ; 
 731         OSStatus status 
= noErr 
; 
 732         ByteCount byteOutLen 
; 
 733         ByteCount byteInLen 
= from
.Length() ; 
 734         ByteCount byteBufferLen 
= byteInLen 
; 
 736         status 
= TECConvertText(s_TECNativeCToPlatform
, (ConstTextPtr
)from
.c_str() , byteInLen
, &byteInLen
, 
 737             (TextPtr
)result
.data(), byteBufferLen
, &byteOutLen
); 
 743 void wxMacStringToPascal( const wxString
&from 
, StringPtr to 
) 
 745     wxCharBuffer buf 
= wxMacStringToCString( from 
) ; 
 746     int len 
= strlen(buf
) ; 
 751     memcpy( (char*) &to
[1] , buf 
, len 
) ; 
 754 wxString 
wxMacMakeStringFromPascal( ConstStringPtr from 
) 
 756     return wxMacMakeStringFromCString( (char*) &from
[1] , from
[0] ) ; 
 760 // CFStringRefs (Carbon only) 
 764 // converts this string into a carbon foundation string with optional pc 2 mac encoding 
 765 void wxMacCFStringHolder::Assign( const wxString 
&str 
) 
 768         m_cfs 
= CFStringCreateWithCharacters( kCFAllocatorDefault
, 
 769                 (const unsigned short*)str
.wc_str(), str
.Len() ); 
 771     m_cfs 
= CFStringCreateWithCString( kCFAllocatorSystemDefault 
, str
.c_str() , 
 772         wxApp::s_macDefaultEncodingIsPC 
? 
 773         kCFStringEncodingWindowsLatin1 
: CFStringGetSystemEncoding() ) ; 
 778 wxString 
wxMacCFStringHolder::AsString() 
 781     Size len 
= CFStringGetLength( m_cfs 
)  ; 
 782     wxChar
* buf 
= result
.GetWriteBuf( len 
) ; 
 784     CFStringGetCharacters( m_cfs 
, CFRangeMake( 0 , len 
) , (UniChar
*) buf 
) ; 
 786     CFStringGetCString( m_cfs 
, buf 
, len
+1 , wxApp::s_macDefaultEncodingIsPC 
? 
 787         kCFStringEncodingWindowsLatin1 
: CFStringGetSystemEncoding() ) ; 
 790     result
.UngetWriteBuf() ; 
 796 wxString 
wxMacMakeMacStringFromPC( const wxChar 
* p 
) 
 799     int len 
= wxStrlen ( p 
) ; 
 802         wxChar
* ptr 
= result
.GetWriteBuf(len
) ; 
 803         wxMacConvertFromPC( p 
, ptr 
, len 
) ; 
 805         result
.UngetWriteBuf( len 
) ; 
 810 wxString 
wxMacMakePCStringFromMac( const wxChar 
* p 
) 
 813     int len 
= wxStrlen ( p 
) ; 
 816         wxChar
* ptr 
= result
.GetWriteBuf(len
) ; 
 817         wxMacConvertToPC( p 
, ptr 
, len 
) ; 
 819         result
.UngetWriteBuf( len 
) ; 
 824 wxString 
wxMacMakeStringFromMacString( const wxChar
* from 
, bool mac2pcEncoding 
) 
 828       return wxMacMakePCStringFromMac( from 
) ; 
 832       return wxString( from 
) ; 
 840 wxString 
wxMacMakeStringFromPascal( ConstStringPtr from 
, bool mac2pcEncoding 
) 
 842       // this is safe since a pascal string can never be larger than 256 bytes 
 844       CopyPascalStringToC( from 
, s 
) ; 
 847       return wxMacMakePCStringFromMac( s 
) ; 
 851       return wxString( s 
) ; 
 855 void wxMacStringToPascal( const wxChar 
* from 
, StringPtr to 
, bool pc2macEncoding 
) 
 859       CopyCStringToPascal( wxMacMakeMacStringFromPC( from 
) , to 
) ; 
 863       CopyCStringToPascal( from 
, to 
) ; 
 869 #endif //TARGET_CARBON 
 871 // ---------------------------------------------------------------------------- 
 873 // ---------------------------------------------------------------------------- 
 875 #if defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400) 
 877 // MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds... 
 879 #ifndef __MetroNubUtils__ 
 880 #include "MetroNubUtils.h" 
 887 #if TARGET_API_MAC_CARBON 
 889     #include <CodeFragments.h> 
 891     extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr
, ProcInfoType procInfo
, ...); 
 893     ProcPtr gCallUniversalProc_Proc 
= NULL
; 
 897 static MetroNubUserEntryBlock
*    gMetroNubEntry 
= NULL
; 
 899 static long fRunOnce 
= false; 
 901 /* --------------------------------------------------------------------------- 
 903    --------------------------------------------------------------------------- */ 
 905 Boolean 
IsMetroNubInstalled() 
 912         gMetroNubEntry 
= NULL
; 
 914         if (Gestalt(gestaltSystemVersion
, &value
) == noErr 
&& value 
< 0x1000) 
 916             /* look for MetroNub's Gestalt selector */ 
 917             if (Gestalt(kMetroNubUserSignature
, &result
) == noErr
) 
 920             #if TARGET_API_MAC_CARBON 
 921                 if (gCallUniversalProc_Proc 
== NULL
) 
 923                     CFragConnectionID   connectionID
; 
 926                     ProcPtr             symbolAddress
; 
 928                     CFragSymbolClass    symbolClass
; 
 930                     symbolAddress 
= NULL
; 
 931                     err 
= GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch
, kFindCFrag
, 
 932                                            &connectionID
, &mainAddress
, errorString
); 
 936                         gCallUniversalProc_Proc 
= NULL
; 
 940                     err 
= FindSymbol(connectionID
, "\pCallUniversalProc", 
 941                                     (Ptr 
*) &gCallUniversalProc_Proc
, &symbolClass
); 
 945                         gCallUniversalProc_Proc 
= NULL
; 
 952                     MetroNubUserEntryBlock
* block 
= (MetroNubUserEntryBlock 
*)result
; 
 954                     /* make sure the version of the API is compatible */ 
 955                     if (block
->apiLowVersion 
<= kMetroNubUserAPIVersion 
&& 
 956                         kMetroNubUserAPIVersion 
<= block
->apiHiVersion
) 
 957                         gMetroNubEntry 
= block
;        /* success! */ 
 966 #if TARGET_API_MAC_CARBON 
 967     return (gMetroNubEntry 
!= NULL 
&& gCallUniversalProc_Proc 
!= NULL
); 
 969     return (gMetroNubEntry 
!= NULL
); 
 973 /* --------------------------------------------------------------------------- 
 974         IsMWDebuggerRunning                                            [v1 API] 
 975    --------------------------------------------------------------------------- */ 
 977 Boolean 
IsMWDebuggerRunning() 
 979     if (IsMetroNubInstalled()) 
 980         return CallIsDebuggerRunningProc(gMetroNubEntry
->isDebuggerRunning
); 
 985 /* --------------------------------------------------------------------------- 
 986         AmIBeingMWDebugged                                            [v1 API] 
 987    --------------------------------------------------------------------------- */ 
 989 Boolean 
AmIBeingMWDebugged() 
 991     if (IsMetroNubInstalled()) 
 992         return CallAmIBeingDebuggedProc(gMetroNubEntry
->amIBeingDebugged
); 
 997 extern bool WXDLLEXPORT 
wxIsDebuggerRunning() 
 999     return IsMWDebuggerRunning() && AmIBeingMWDebugged(); 
1004 extern bool WXDLLEXPORT 
wxIsDebuggerRunning() 
1009 #endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)