1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/classic/utils.cpp
3// Purpose:     Various utilities
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     1998-01-01
7// RCS-ID:      $Id: utils.cpp 40605 2006-08-13 22:43:30Z VZ $
8// Copyright:   (c) Stefan Csomor
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#include "wx/utils.h"
15
16#ifndef WX_PRECOMP
17    #include "wx/intl.h"
18    #include "wx/app.h"
19    #if wxUSE_GUI
20        #include "wx/font.h"
21    #endif
22#endif
23
24#include "wx/apptrait.h"
25
26#if wxUSE_GUI
27    #include "wx/mac/uma.h"
28#endif
29
30#include <ctype.h>
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <stdarg.h>
36
37#ifdef __DARWIN__
38#  include "MoreFilesX.h"
39#else
40#  include "MoreFiles.h"
41#  include "MoreFilesExtras.h"
42#endif
43
44#ifndef __DARWIN__
45#include <Threads.h>
46#include <Sound.h>
47#endif
48
49#include <ATSUnicode.h>
50#include <TextCommon.h>
51#include <TextEncodingConverter.h>
52
53#include  "wx/mac/private.h"  // includes mac headers
54
55#if defined(__MWERKS__) && wxUSE_UNICODE
56    #include <wtime.h>
57#endif
58
59#if wxUSE_BASE
60
61// our OS version is the same in non GUI and GUI cases
62wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn)
63{
64    long theSystem;
65    Gestalt(gestaltSystemVersion, &theSystem);
66
67    if ( majorVsn != NULL )
68        *majorVsn = (theSystem >> 8);
69
70    if ( minorVsn != NULL )
71        *minorVsn = (theSystem & 0xFF);
72
73
74#if defined( __DARWIN__ )
75    return wxOS_MAC_OSX_DARWIN;
76#else
77    return wxOS_MAC_OS;
78#endif
79}
80
81#ifndef __DARWIN__
82// defined in unix/utilsunx.cpp for Mac OS X
83
84// get full hostname (with domain name if possible)
85bool wxGetFullHostName(wxChar *buf, int maxSize)
86{
87    return wxGetHostName(buf, maxSize);
88}
89
90// Get hostname only (without domain name)
91bool wxGetHostName(wxChar *buf, int maxSize)
92{
93    // Gets Chooser name of user by examining a System resource.
94
95    const short kComputerNameID = -16413;
96
97    short oldResFile = CurResFile() ;
98    UseResFile(0);
99    StringHandle chooserName = (StringHandle)::GetString(kComputerNameID);
100    UseResFile(oldResFile);
101
102    if (chooserName && *chooserName)
103    {
104        HLock( (Handle) chooserName ) ;
105        wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
106        HUnlock( (Handle) chooserName ) ;
107        ReleaseResource( (Handle) chooserName ) ;
108        wxStrncpy( buf , name , maxSize - 1 ) ;
109    }
110    else
111        buf[0] = 0 ;
112
113    return true;
114}
115
116// Get user ID e.g. jacs
117bool wxGetUserId(wxChar *buf, int maxSize)
118{
119  return wxGetUserName( buf , maxSize ) ;
120}
121
122const wxChar* wxGetHomeDir(wxString *pstr)
123{
124    *pstr = wxMacFindFolder(  (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ;
125    return pstr->c_str() ;
126}
127
128// Get user name e.g. Stefan Csomor
129bool wxGetUserName(wxChar *buf, int maxSize)
130{
131    // Gets Chooser name of user by examining a System resource.
132
133    const short kChooserNameID = -16096;
134
135    short oldResFile = CurResFile() ;
136    UseResFile(0);
137    StringHandle chooserName = (StringHandle)::GetString(kChooserNameID);
138    UseResFile(oldResFile);
139
140    if (chooserName && *chooserName)
141    {
142        HLock( (Handle) chooserName ) ;
143        wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
144        HUnlock( (Handle) chooserName ) ;
145        ReleaseResource( (Handle) chooserName ) ;
146        wxStrncpy( buf , name , maxSize - 1 ) ;
147    }
148    else
149        buf[0] = 0 ;
150
151    return true;
152}
153
154int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
155{
156    // TODO
157    return 0;
158}
159
160WXDLLEXPORT bool wxGetEnv(const wxString& var, wxString *value)
161{
162    // TODO : under classic there is no environement support, under X yes
163    return false ;
164}
165
166// set the env var name to the given value, return true on success
167WXDLLEXPORT bool wxSetEnv(const wxString& var, const wxChar *value)
168{
169    // TODO : under classic there is no environement support, under X yes
170    return false ;
171}
172
173//
174// Execute a program in an Interactive Shell
175//
176bool wxShell(const wxString& command)
177{
178    // TODO
179    return false;
180}
181
182// Shutdown or reboot the PC
183bool wxShutdown(wxShutdownFlags wFlags)
184{
185    // TODO
186    return false;
187}
188
189// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
190wxMemorySize wxGetFreeMemory()
191{
192    return (wxMemorySize)FreeMem() ;
193}
194
195void wxUsleep(unsigned long milliseconds)
196{
197    clock_t start = clock() ;
198    do
199    {
200        YieldToAnyThread() ;
201    } while( clock() - start < milliseconds /  1000.0 * CLOCKS_PER_SEC ) ;
202}
203
204void wxSleep(int nSecs)
205{
206    wxUsleep(1000*nSecs);
207}
208
209// Consume all events until no more left
210void wxFlushEvents()
211{
212}
213
214#endif // !__DARWIN__
215
216// Emit a beeeeeep
217void wxBell()
218{
219    SysBeep(30);
220}
221
222#endif // wxUSE_BASE
223
224#if wxUSE_GUI
225
226wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
227{
228    // We suppose that toolkit version is the same as OS version under Mac
229    wxGetOsVersion(verMaj, verMin);
230
231    return wxPORT_MAC;
232}
233
234// Reading and writing resources (eg WIN.INI, .Xdefaults)
235#if wxUSE_RESOURCES
236bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
237{
238    // TODO
239    return false;
240}
241
242bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
243{
244    wxString buf;
245    buf.Printf(wxT("%.4f"), value);
246
247    return wxWriteResource(section, entry, buf, file);
248}
249
250bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
251{
252    wxString buf;
253    buf.Printf(wxT("%ld"), value);
254
255    return wxWriteResource(section, entry, buf, file);
256}
257
258bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
259{
260    wxString buf;
261    buf.Printf(wxT("%d"), value);
262
263    return wxWriteResource(section, entry, buf, file);
264}
265
266bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
267{
268    // TODO
269    return false;
270}
271
272bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
273{
274    char *s = NULL;
275    bool succ = wxGetResource(section, entry, (char **)&s, file);
276    if (succ)
277    {
278        *value = (float)strtod(s, NULL);
279        delete[] s;
280        return true;
281    }
282    else return false;
283}
284
285bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
286{
287    char *s = NULL;
288    bool succ = wxGetResource(section, entry, (char **)&s, file);
289    if (succ)
290    {
291        *value = strtol(s, NULL, 10);
292        delete[] s;
293        return true;
294    }
295    else return false;
296}
297
298bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
299{
300    char *s = NULL;
301    bool succ = wxGetResource(section, entry, (char **)&s, file);
302    if (succ)
303    {
304        *value = (int)strtol(s, NULL, 10);
305        delete[] s;
306        return true;
307    }
308    else return false;
309}
310#endif // wxUSE_RESOURCES
311
312int gs_wxBusyCursorCount = 0;
313extern wxCursor    gMacCurrentCursor ;
314wxCursor        gMacStoredActiveCursor ;
315
316// Set the cursor to the busy cursor for all windows
317void wxBeginBusyCursor(const wxCursor *cursor)
318{
319    if (gs_wxBusyCursorCount++ == 0)
320    {
321        gMacStoredActiveCursor = gMacCurrentCursor ;
322        cursor->MacInstall() ;
323    }
324    //else: nothing to do, already set
325}
326
327// Restore cursor to normal
328void wxEndBusyCursor()
329{
330    wxCHECK_RET( gs_wxBusyCursorCount > 0,
331        wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
332
333    if (--gs_wxBusyCursorCount == 0)
334    {
335        gMacStoredActiveCursor.MacInstall() ;
336        gMacStoredActiveCursor = wxNullCursor ;
337    }
338}
339
340// true if we're between the above two calls
341bool wxIsBusy()
342{
343    return (gs_wxBusyCursorCount > 0);
344}
345
346#endif // wxUSE_GUI
347
348#if wxUSE_BASE
349
350wxString wxMacFindFolderNoSeparator( short        vol,
351              OSType       folderType,
352              Boolean      createFolder)
353{
354    short    vRefNum  ;
355    long     dirID ;
356    wxString strDir ;
357
358    if ( FindFolder( vol, folderType, createFolder, &vRefNum, &dirID) == noErr)
359    {
360        FSSpec file ;
361        if ( FSMakeFSSpec( vRefNum , dirID , "\p" , &file ) == noErr )
362        {
363            strDir = wxMacFSSpec2MacFilename( &file );
364        }
365    }
366    return strDir ;
367}
368
369wxString wxMacFindFolder( short        vol,
370              OSType       folderType,
371              Boolean      createFolder)
372{
373    return wxMacFindFolderNoSeparator(vol, folderType, createFolder) + wxFILE_SEP_PATH;
374}
375
376#endif // wxUSE_BASE
377
378#if wxUSE_GUI
379
380// Check whether this window wants to process messages, e.g. Stop button
381// in long calculations.
382bool wxCheckForInterrupt(wxWindow *wnd)
383{
384    // TODO
385    return false;
386}
387
388void wxGetMousePosition( int* x, int* y )
389{
390    Point pt ;
391
392    GetMouse( &pt ) ;
393    LocalToGlobal( &pt ) ;
394    *x = pt.h ;
395    *y = pt.v ;
396};
397
398// Return true if we have a colour display
399bool wxColourDisplay()
400{
401    return true;
402}
403
404// Returns depth of screen
405int wxDisplayDepth()
406{
407    Rect globRect ;
408    SetRect(&globRect, -32760, -32760, 32760, 32760);
409    GDHandle    theMaxDevice;
410
411    int theDepth = 8;
412    theMaxDevice = GetMaxDevice(&globRect);
413    if (theMaxDevice != nil)
414        theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
415
416    return theDepth ;
417}
418
419// Get size of display
420void wxDisplaySize(int *width, int *height)
421{
422    BitMap screenBits;
423    GetQDGlobalsScreenBits( &screenBits );
424
425    if (width != NULL) {
426        *width = screenBits.bounds.right - screenBits.bounds.left  ;
427    }
428    if (height != NULL) {
429        *height = screenBits.bounds.bottom - screenBits.bounds.top ;
430    }
431}
432
433void wxDisplaySizeMM(int *width, int *height)
434{
435    wxDisplaySize(width, height);
436    // on mac 72 is fixed (at least now ;-)
437    float cvPt2Mm = 25.4 / 72;
438
439    if (width != NULL) {
440        *width = int( *width * cvPt2Mm );
441    }
442    if (height != NULL) {
443        *height = int( *height * cvPt2Mm );
444    }
445}
446
447void wxClientDisplayRect(int *x, int *y, int *width, int *height)
448{
449#if TARGET_CARBON
450    Rect r ;
451    GetAvailableWindowPositioningBounds( GetMainDevice() , &r ) ;
452    if ( x )
453        *x = r.left ;
454    if ( y )
455        *y = r.top ;
456    if ( width )
457        *width = r.right - r.left ;
458    if ( height )
459        *height = r.bottom - r.top ;
460#else
461    BitMap screenBits;
462    GetQDGlobalsScreenBits( &screenBits );
463
464    if (x) *x = 0;
465    if (y) *y = 0;
466
467    if (width != NULL) {
468        *width = screenBits.bounds.right - screenBits.bounds.left  ;
469    }
470    if (height != NULL) {
471        *height = screenBits.bounds.bottom - screenBits.bounds.top ;
472    }
473
474    SInt16 mheight ;
475#if TARGET_CARBON
476    GetThemeMenuBarHeight( &mheight ) ;
477#else
478    mheight = LMGetMBarHeight() ;
479#endif
480    if (height != NULL) {
481        *height -= mheight ;
482    }
483    if (y)
484        *y = mheight ;
485#endif
486}
487
488wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
489{
490    return wxGenericFindWindowAtPoint(pt);
491}
492
493#endif // wxUSE_GUI
494
495#if wxUSE_BASE
496
497wxString wxGetOsDescription()
498{
499#ifdef WXWIN_OS_DESCRIPTION
500    // use configure generated description if available
501    return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
502#else
503    return wxT("MacOS") ; //TODO:define further
504#endif
505}
506
507#ifndef __DARWIN__
508wxChar *wxGetUserHome (const wxString& user)
509{
510    // TODO
511    return NULL;
512}
513
514bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree)
515{
516    if ( path.empty() )
517        return false;
518
519    wxString p = path ;
520    if (p[0u] == ':' ) {
521      p = wxGetCwd() + p ;
522    }
523
524    int pos = p.Find(':') ;
525    if ( pos != wxNOT_FOUND ) {
526      p = p.Mid(1,pos) ;
527    }
528
529    p = p + wxT(":") ;
530
531    Str255 volumeName ;
532    XVolumeParam pb ;
533
534    wxMacStringToPascal( p  , volumeName ) ;
535    OSErr err = XGetVolumeInfoNoName( volumeName , 0 , &pb ) ;
536    if ( err == noErr ) {
537      if ( pTotal ) {
538        (*pTotal) = wxDiskspaceSize_t( pb.ioVTotalBytes ) ;
539      }
540      if ( pFree ) {
541        (*pFree) = wxDiskspaceSize_t( pb.ioVFreeBytes ) ;
542      }
543    }
544
545    return err == noErr ;
546}
547#endif // !__DARWIN__
548
549//---------------------------------------------------------------------------
550// wxMac Specific utility functions
551//---------------------------------------------------------------------------
552
553void wxMacStringToPascal( const wxString&from , StringPtr to )
554{
555    wxCharBuffer buf = from.mb_str( wxConvLocal ) ;
556    int len = strlen(buf) ;
557
558    if ( len > 255 )
559        len = 255 ;
560    to[0] = len ;
561    memcpy( (char*) &to[1] , buf , len ) ;
562}
563
564wxString wxMacMakeStringFromPascal( ConstStringPtr from )
565{
566    return wxString( (char*) &from[1] , wxConvLocal , from[0] ) ;
567}
568
569
570wxUint32 wxMacGetSystemEncFromFontEnc(wxFontEncoding encoding)
571{
572    TextEncodingBase enc = 0 ;
573    if ( encoding == wxFONTENCODING_DEFAULT )
574    {
575#if wxUSE_GUI
576        encoding = wxFont::GetDefaultEncoding() ;
577#else
578        encoding = wxLocale::GetSystemEncoding() ;
579#endif
580    }
581
582    switch( encoding)
583    {
584        case wxFONTENCODING_ISO8859_1 :
585            enc = kTextEncodingISOLatin1 ;
586            break ;
587        case wxFONTENCODING_ISO8859_2 :
588            enc = kTextEncodingISOLatin2;
589            break ;
590        case wxFONTENCODING_ISO8859_3 :
591            enc = kTextEncodingISOLatin3 ;
592            break ;
593        case wxFONTENCODING_ISO8859_4 :
594            enc = kTextEncodingISOLatin4;
595            break ;
596        case wxFONTENCODING_ISO8859_5 :
597            enc = kTextEncodingISOLatinCyrillic;
598            break ;
599        case wxFONTENCODING_ISO8859_6 :
600            enc = kTextEncodingISOLatinArabic;
601            break ;
602        case wxFONTENCODING_ISO8859_7 :
603            enc = kTextEncodingISOLatinGreek;
604            break ;
605        case wxFONTENCODING_ISO8859_8 :
606            enc = kTextEncodingISOLatinHebrew;
607            break ;
608        case wxFONTENCODING_ISO8859_9 :
609            enc = kTextEncodingISOLatin5;
610            break ;
611        case wxFONTENCODING_ISO8859_10 :
612            enc = kTextEncodingISOLatin6;
613            break ;
614        case wxFONTENCODING_ISO8859_13 :
615            enc = kTextEncodingISOLatin7;
616            break ;
617        case wxFONTENCODING_ISO8859_14 :
618            enc = kTextEncodingISOLatin8;
619            break ;
620        case wxFONTENCODING_ISO8859_15 :
621            enc = kTextEncodingISOLatin9;
622            break ;
623
624        case wxFONTENCODING_KOI8 :
625            enc = kTextEncodingKOI8_R;
626            break ;
627        case wxFONTENCODING_ALTERNATIVE : // MS-DOS CP866
628            enc = kTextEncodingDOSRussian;
629            break ;
630/*
631        case wxFONTENCODING_BULGARIAN :
632            enc = ;
633            break ;
634*/
635        case wxFONTENCODING_CP437 :
636            enc =kTextEncodingDOSLatinUS ;
637            break ;
638        case wxFONTENCODING_CP850 :
639            enc = kTextEncodingDOSLatin1;
640            break ;
641        case wxFONTENCODING_CP852 :
642            enc = kTextEncodingDOSLatin2;
643            break ;
644        case wxFONTENCODING_CP855 :
645            enc = kTextEncodingDOSCyrillic;
646            break ;
647        case wxFONTENCODING_CP866 :
648            enc =kTextEncodingDOSRussian ;
649            break ;
650        case wxFONTENCODING_CP874 :
651            enc = kTextEncodingDOSThai;
652            break ;
653        case wxFONTENCODING_CP932 :
654            enc = kTextEncodingDOSJapanese;
655            break ;
656        case wxFONTENCODING_CP936 :
657            enc =kTextEncodingDOSChineseSimplif ;
658            break ;
659        case wxFONTENCODING_CP949 :
660            enc = kTextEncodingDOSKorean;
661            break ;
662        case wxFONTENCODING_CP950 :
663            enc = kTextEncodingDOSChineseTrad;
664            break ;
665
666        case wxFONTENCODING_CP1250 :
667            enc = kTextEncodingWindowsLatin2;
668            break ;
669        case wxFONTENCODING_CP1251 :
670            enc =kTextEncodingWindowsCyrillic ;
671            break ;
672        case wxFONTENCODING_CP1252 :
673            enc =kTextEncodingWindowsLatin1 ;
674            break ;
675        case wxFONTENCODING_CP1253 :
676            enc = kTextEncodingWindowsGreek;
677            break ;
678        case wxFONTENCODING_CP1254 :
679            enc = kTextEncodingWindowsLatin5;
680            break ;
681        case wxFONTENCODING_CP1255 :
682            enc =kTextEncodingWindowsHebrew ;
683            break ;
684        case wxFONTENCODING_CP1256 :
685            enc =kTextEncodingWindowsArabic ;
686            break ;
687        case wxFONTENCODING_CP1257 :
688            enc = kTextEncodingWindowsBalticRim;
689            break ;
690
691        case wxFONTENCODING_UTF7 :
692            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF7Format) ;
693            break ;
694        case wxFONTENCODING_UTF8 :
695            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF8Format) ;
696            break ;
697        case wxFONTENCODING_EUC_JP :
698            enc = kTextEncodingEUC_JP;
699            break ;
700        case wxFONTENCODING_UTF16BE :
701            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
702            break ;
703        case wxFONTENCODING_UTF16LE :
704            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
705            break ;
706        case wxFONTENCODING_UTF32BE :
707            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
708            break ;
709        case wxFONTENCODING_UTF32LE :
710            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
711            break ;
712
713        case wxFONTENCODING_MACROMAN :
714            enc = kTextEncodingMacRoman ;
715            break ;
716        case wxFONTENCODING_MACJAPANESE :
717            enc = kTextEncodingMacJapanese ;
718            break ;
719        case wxFONTENCODING_MACCHINESETRAD :
720            enc = kTextEncodingMacChineseTrad ;
721            break ;
722        case wxFONTENCODING_MACKOREAN :
723            enc = kTextEncodingMacKorean ;
724            break ;
725        case wxFONTENCODING_MACARABIC :
726            enc = kTextEncodingMacArabic ;
727            break ;
728        case wxFONTENCODING_MACHEBREW :
729            enc = kTextEncodingMacHebrew ;
730            break ;
731        case wxFONTENCODING_MACGREEK :
732            enc = kTextEncodingMacGreek ;
733            break ;
734        case wxFONTENCODING_MACCYRILLIC :
735            enc = kTextEncodingMacCyrillic ;
736            break ;
737        case wxFONTENCODING_MACDEVANAGARI :
738            enc = kTextEncodingMacDevanagari ;
739            break ;
740        case wxFONTENCODING_MACGURMUKHI :
741            enc = kTextEncodingMacGurmukhi ;
742            break ;
743        case wxFONTENCODING_MACGUJARATI :
744            enc = kTextEncodingMacGujarati ;
745            break ;
746        case wxFONTENCODING_MACORIYA :
747            enc = kTextEncodingMacOriya ;
748            break ;
749        case wxFONTENCODING_MACBENGALI :
750            enc = kTextEncodingMacBengali ;
751            break ;
752        case wxFONTENCODING_MACTAMIL :
753            enc = kTextEncodingMacTamil ;
754            break ;
755        case wxFONTENCODING_MACTELUGU :
756            enc = kTextEncodingMacTelugu ;
757            break ;
758        case wxFONTENCODING_MACKANNADA :
759            enc = kTextEncodingMacKannada ;
760            break ;
761        case wxFONTENCODING_MACMALAJALAM :
762            enc = kTextEncodingMacMalayalam ;
763            break ;
764        case wxFONTENCODING_MACSINHALESE :
765            enc = kTextEncodingMacSinhalese ;
766            break ;
767        case wxFONTENCODING_MACBURMESE :
768            enc = kTextEncodingMacBurmese ;
769            break ;
770        case wxFONTENCODING_MACKHMER :
771            enc = kTextEncodingMacKhmer ;
772            break ;
773        case wxFONTENCODING_MACTHAI :
774            enc = kTextEncodingMacThai ;
775            break ;
776        case wxFONTENCODING_MACLAOTIAN :
777            enc = kTextEncodingMacLaotian ;
778            break ;
779        case wxFONTENCODING_MACGEORGIAN :
780            enc = kTextEncodingMacGeorgian ;
781            break ;
782        case wxFONTENCODING_MACARMENIAN :
783            enc = kTextEncodingMacArmenian ;
784            break ;
785        case wxFONTENCODING_MACCHINESESIMP :
786            enc = kTextEncodingMacChineseSimp ;
787            break ;
788        case wxFONTENCODING_MACTIBETAN :
789            enc = kTextEncodingMacTibetan ;
790            break ;
791        case wxFONTENCODING_MACMONGOLIAN :
792            enc = kTextEncodingMacMongolian ;
793            break ;
794        case wxFONTENCODING_MACETHIOPIC :
795            enc = kTextEncodingMacEthiopic ;
796            break ;
797        case wxFONTENCODING_MACCENTRALEUR :
798            enc = kTextEncodingMacCentralEurRoman ;
799            break ;
800        case wxFONTENCODING_MACVIATNAMESE :
801            enc = kTextEncodingMacVietnamese ;
802            break ;
803        case wxFONTENCODING_MACARABICEXT :
804            enc = kTextEncodingMacExtArabic ;
805            break ;
806        case wxFONTENCODING_MACSYMBOL :
807            enc = kTextEncodingMacSymbol ;
808            break ;
809        case wxFONTENCODING_MACDINGBATS :
810            enc = kTextEncodingMacDingbats ;
811            break ;
812        case wxFONTENCODING_MACTURKISH :
813            enc = kTextEncodingMacTurkish ;
814            break ;
815        case wxFONTENCODING_MACCROATIAN :
816            enc = kTextEncodingMacCroatian ;
817            break ;
818        case wxFONTENCODING_MACICELANDIC :
819            enc = kTextEncodingMacIcelandic ;
820            break ;
821        case wxFONTENCODING_MACROMANIAN :
822            enc = kTextEncodingMacRomanian ;
823            break ;
824        case wxFONTENCODING_MACCELTIC :
825            enc = kTextEncodingMacCeltic ;
826            break ;
827        case wxFONTENCODING_MACGAELIC :
828            enc = kTextEncodingMacGaelic ;
829            break ;
830        case wxFONTENCODING_MACKEYBOARD :
831            enc = kTextEncodingMacKeyboardGlyphs ;
832            break ;
833        default :
834            // to make gcc happy
835            break ;
836    } ;
837    return enc ;
838}
839
840wxFontEncoding wxMacGetFontEncFromSystemEnc(wxUint32 encoding)
841{
842    wxFontEncoding enc = wxFONTENCODING_DEFAULT ;
843
844    switch( encoding)
845    {
846        case kTextEncodingISOLatin1  :
847            enc = wxFONTENCODING_ISO8859_1 ;
848            break ;
849        case kTextEncodingISOLatin2 :
850            enc = wxFONTENCODING_ISO8859_2;
851            break ;
852        case kTextEncodingISOLatin3 :
853            enc = wxFONTENCODING_ISO8859_3 ;
854            break ;
855        case kTextEncodingISOLatin4 :
856            enc = wxFONTENCODING_ISO8859_4;
857            break ;
858        case kTextEncodingISOLatinCyrillic :
859            enc = wxFONTENCODING_ISO8859_5;
860            break ;
861        case kTextEncodingISOLatinArabic :
862            enc = wxFONTENCODING_ISO8859_6;
863            break ;
864        case kTextEncodingISOLatinGreek :
865            enc = wxFONTENCODING_ISO8859_7;
866            break ;
867        case kTextEncodingISOLatinHebrew :
868            enc = wxFONTENCODING_ISO8859_8;
869            break ;
870        case kTextEncodingISOLatin5 :
871            enc = wxFONTENCODING_ISO8859_9;
872            break ;
873        case kTextEncodingISOLatin6 :
874            enc = wxFONTENCODING_ISO8859_10;
875            break ;
876        case kTextEncodingISOLatin7 :
877            enc = wxFONTENCODING_ISO8859_13;
878            break ;
879        case kTextEncodingISOLatin8 :
880            enc = wxFONTENCODING_ISO8859_14;
881            break ;
882        case kTextEncodingISOLatin9 :
883            enc =wxFONTENCODING_ISO8859_15 ;
884            break ;
885
886        case kTextEncodingKOI8_R :
887            enc = wxFONTENCODING_KOI8;
888            break ;
889/*
890        case  :
891            enc = wxFONTENCODING_BULGARIAN;
892            break ;
893*/
894        case kTextEncodingDOSLatinUS :
895            enc = wxFONTENCODING_CP437;
896            break ;
897        case kTextEncodingDOSLatin1 :
898            enc = wxFONTENCODING_CP850;
899            break ;
900        case kTextEncodingDOSLatin2 :
901            enc =wxFONTENCODING_CP852 ;
902            break ;
903        case kTextEncodingDOSCyrillic :
904            enc = wxFONTENCODING_CP855;
905            break ;
906        case kTextEncodingDOSRussian :
907            enc = wxFONTENCODING_CP866;
908            break ;
909        case kTextEncodingDOSThai :
910            enc =wxFONTENCODING_CP874 ;
911            break ;
912        case kTextEncodingDOSJapanese :
913            enc = wxFONTENCODING_CP932;
914            break ;
915        case kTextEncodingDOSChineseSimplif :
916            enc = wxFONTENCODING_CP936;
917            break ;
918        case kTextEncodingDOSKorean :
919            enc = wxFONTENCODING_CP949;
920            break ;
921        case kTextEncodingDOSChineseTrad :
922            enc = wxFONTENCODING_CP950;
923            break ;
924
925        case kTextEncodingWindowsLatin2 :
926            enc = wxFONTENCODING_CP1250;
927            break ;
928        case kTextEncodingWindowsCyrillic :
929            enc = wxFONTENCODING_CP1251;
930            break ;
931        case kTextEncodingWindowsLatin1 :
932            enc = wxFONTENCODING_CP1252;
933            break ;
934        case kTextEncodingWindowsGreek :
935            enc = wxFONTENCODING_CP1253;
936            break ;
937        case kTextEncodingWindowsLatin5 :
938            enc = wxFONTENCODING_CP1254;
939            break ;
940        case kTextEncodingWindowsHebrew :
941            enc = wxFONTENCODING_CP1255;
942            break ;
943        case kTextEncodingWindowsArabic :
944            enc = wxFONTENCODING_CP1256;
945            break ;
946        case kTextEncodingWindowsBalticRim :
947            enc =wxFONTENCODING_CP1257 ;
948            break ;
949        case kTextEncodingEUC_JP :
950            enc = wxFONTENCODING_EUC_JP;
951            break ;
952            /*
953        case wxFONTENCODING_UTF7 :
954            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF7Format) ;
955            break ;
956        case wxFONTENCODING_UTF8 :
957            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF8Format) ;
958            break ;
959        case wxFONTENCODING_UTF16BE :
960            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
961            break ;
962        case wxFONTENCODING_UTF16LE :
963            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
964            break ;
965        case wxFONTENCODING_UTF32BE :
966            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
967            break ;
968        case wxFONTENCODING_UTF32LE :
969            enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
970            break ;
971        */
972        case kTextEncodingMacRoman :
973            enc = wxFONTENCODING_MACROMAN ;
974            break ;
975        case kTextEncodingMacJapanese :
976            enc = wxFONTENCODING_MACJAPANESE ;
977            break ;
978        case kTextEncodingMacChineseTrad :
979            enc = wxFONTENCODING_MACCHINESETRAD ;
980            break ;
981        case kTextEncodingMacKorean :
982            enc = wxFONTENCODING_MACKOREAN ;
983            break ;
984        case kTextEncodingMacArabic :
985            enc =wxFONTENCODING_MACARABIC ;
986            break ;
987        case kTextEncodingMacHebrew :
988            enc = wxFONTENCODING_MACHEBREW ;
989            break ;
990        case kTextEncodingMacGreek :
991            enc = wxFONTENCODING_MACGREEK ;
992            break ;
993        case kTextEncodingMacCyrillic :
994            enc = wxFONTENCODING_MACCYRILLIC ;
995            break ;
996        case kTextEncodingMacDevanagari :
997            enc = wxFONTENCODING_MACDEVANAGARI ;
998            break ;
999        case kTextEncodingMacGurmukhi :
1000            enc = wxFONTENCODING_MACGURMUKHI ;
1001            break ;
1002        case kTextEncodingMacGujarati :
1003            enc = wxFONTENCODING_MACGUJARATI ;
1004            break ;
1005        case kTextEncodingMacOriya :
1006            enc =wxFONTENCODING_MACORIYA ;
1007            break ;
1008        case kTextEncodingMacBengali :
1009            enc =wxFONTENCODING_MACBENGALI ;
1010            break ;
1011        case kTextEncodingMacTamil :
1012            enc = wxFONTENCODING_MACTAMIL ;
1013            break ;
1014        case kTextEncodingMacTelugu :
1015            enc = wxFONTENCODING_MACTELUGU ;
1016            break ;
1017        case kTextEncodingMacKannada :
1018            enc = wxFONTENCODING_MACKANNADA ;
1019            break ;
1020        case kTextEncodingMacMalayalam :
1021            enc = wxFONTENCODING_MACMALAJALAM ;
1022            break ;
1023        case kTextEncodingMacSinhalese :
1024            enc = wxFONTENCODING_MACSINHALESE ;
1025            break ;
1026        case kTextEncodingMacBurmese :
1027            enc = wxFONTENCODING_MACBURMESE ;
1028            break ;
1029        case kTextEncodingMacKhmer :
1030            enc = wxFONTENCODING_MACKHMER ;
1031            break ;
1032        case kTextEncodingMacThai :
1033            enc = wxFONTENCODING_MACTHAI ;
1034            break ;
1035        case kTextEncodingMacLaotian :
1036            enc = wxFONTENCODING_MACLAOTIAN ;
1037            break ;
1038        case kTextEncodingMacGeorgian :
1039            enc = wxFONTENCODING_MACGEORGIAN ;
1040            break ;
1041        case kTextEncodingMacArmenian :
1042            enc = wxFONTENCODING_MACARMENIAN ;
1043            break ;
1044        case kTextEncodingMacChineseSimp :
1045            enc = wxFONTENCODING_MACCHINESESIMP ;
1046            break ;
1047        case kTextEncodingMacTibetan :
1048            enc = wxFONTENCODING_MACTIBETAN ;
1049            break ;
1050        case kTextEncodingMacMongolian :
1051            enc = wxFONTENCODING_MACMONGOLIAN ;
1052            break ;
1053        case kTextEncodingMacEthiopic :
1054            enc = wxFONTENCODING_MACETHIOPIC ;
1055            break ;
1056        case kTextEncodingMacCentralEurRoman:
1057            enc = wxFONTENCODING_MACCENTRALEUR  ;
1058            break ;
1059        case kTextEncodingMacVietnamese:
1060            enc = wxFONTENCODING_MACVIATNAMESE  ;
1061            break ;
1062        case kTextEncodingMacExtArabic :
1063            enc = wxFONTENCODING_MACARABICEXT ;
1064            break ;
1065        case kTextEncodingMacSymbol :
1066            enc = wxFONTENCODING_MACSYMBOL ;
1067            break ;
1068        case kTextEncodingMacDingbats :
1069            enc = wxFONTENCODING_MACDINGBATS ;
1070            break ;
1071        case kTextEncodingMacTurkish :
1072            enc = wxFONTENCODING_MACTURKISH ;
1073            break ;
1074        case kTextEncodingMacCroatian :
1075            enc = wxFONTENCODING_MACCROATIAN ;
1076            break ;
1077        case kTextEncodingMacIcelandic :
1078            enc = wxFONTENCODING_MACICELANDIC ;
1079            break ;
1080        case kTextEncodingMacRomanian :
1081            enc = wxFONTENCODING_MACROMANIAN ;
1082            break ;
1083        case kTextEncodingMacCeltic :
1084            enc = wxFONTENCODING_MACCELTIC ;
1085            break ;
1086        case kTextEncodingMacGaelic :
1087            enc = wxFONTENCODING_MACGAELIC ;
1088            break ;
1089        case kTextEncodingMacKeyboardGlyphs :
1090            enc = wxFONTENCODING_MACKEYBOARD ;
1091            break ;
1092    } ;
1093    return enc ;
1094}
1095
1096#endif // wxUSE_BASE
1097
1098#if wxUSE_GUI
1099
1100
1101//
1102// CFStringRefs (Carbon only)
1103//
1104
1105#if TARGET_CARBON
1106
1107// converts this string into a carbon foundation string with optional pc 2 mac encoding
1108void wxMacCFStringHolder::Assign( const wxString &st , wxFontEncoding encoding )
1109{
1110    Release() ;
1111
1112    wxString str = st ;
1113    wxMacConvertNewlines13To10( &str ) ;
1114#if wxUSE_UNICODE
1115#if SIZEOF_WCHAR_T == 2
1116    m_cfs = CFStringCreateWithCharacters( kCFAllocatorDefault,
1117            (UniChar*)str.wc_str() , str.Len() );
1118#else
1119    wxMBConvUTF16BE converter ;
1120    size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
1121    UniChar *unibuf = new UniChar[ unicharlen / sizeof(UniChar) + 1 ] ;
1122    converter.WC2MB( (char*)unibuf , str.wc_str() , unicharlen ) ;
1123    m_cfs = CFStringCreateWithCharacters( kCFAllocatorDefault ,
1124        unibuf , unicharlen / sizeof(UniChar) ) ;
1125    delete[] unibuf ;
1126#endif
1127#else // not wxUSE_UNICODE
1128    m_cfs = CFStringCreateWithCString( kCFAllocatorSystemDefault , str.c_str() ,
1129        wxMacGetSystemEncFromFontEnc( encoding ) ) ;
1130#endif
1131    m_release = true ;
1132}
1133
1134wxString wxMacCFStringHolder::AsString(wxFontEncoding encoding)
1135{
1136    Size cflen = CFStringGetLength( m_cfs )  ;
1137    size_t noChars ;
1138    wxChar* buf = NULL ;
1139
1140#if wxUSE_UNICODE
1141#if SIZEOF_WCHAR_T == 2
1142    buf = new wxChar[ cflen + 1 ] ;
1143    CFStringGetCharacters( m_cfs , CFRangeMake( 0 , cflen ) , (UniChar*) buf ) ;
1144    noChars = cflen ;
1145#else
1146    UniChar* unibuf = new UniChar[ cflen + 1 ] ;
1147    CFStringGetCharacters( m_cfs , CFRangeMake( 0 , cflen ) , (UniChar*) unibuf ) ;
1148    unibuf[cflen] = 0 ;
1149    wxMBConvUTF16BE converter ;
1150    noChars = converter.MB2WC( NULL , (const char*)unibuf , 0 ) ;
1151    buf = new wxChar[ noChars + 1 ] ;
1152    converter.MB2WC( buf , (const char*)unibuf , noChars ) ;
1153    delete[] unibuf ;
1154#endif
1155#else
1156    CFIndex cStrLen ;
1157    CFStringGetBytes( m_cfs , CFRangeMake(0, cflen) , wxMacGetSystemEncFromFontEnc( encoding ) ,
1158        '?' , false , NULL , 0 , &cStrLen ) ;
1159    buf = new wxChar[ cStrLen + 1 ] ;
1160    CFStringGetBytes( m_cfs , CFRangeMake(0, cflen) , wxMacGetSystemEncFromFontEnc( encoding ) ,
1161        '?' , false , (unsigned char*) buf , cStrLen , &cStrLen) ;
1162    noChars = cStrLen ;
1163#endif
1164
1165    buf[noChars] = 0 ;
1166    wxMacConvertNewlines10To13( buf ) ;
1167    wxString result(buf) ;
1168    delete[] buf ;
1169    return result ;
1170}
1171
1172#endif //TARGET_CARBON
1173
1174void wxMacConvertNewlines13To10( char * data )
1175{
1176    char * buf = data ;
1177    while( (buf=strchr(buf,0x0d)) != NULL )
1178    {
1179        *buf = 0x0a ;
1180        buf++ ;
1181    }
1182}
1183
1184void wxMacConvertNewlines10To13( char * data )
1185{
1186    char * buf = data ;
1187    while( (buf=strchr(buf,0x0a)) != NULL )
1188    {
1189        *buf = 0x0d ;
1190        buf++ ;
1191    }
1192}
1193
1194void wxMacConvertNewlines13To10( wxString * data )
1195{
1196    size_t len = data->length() ;
1197
1198    if ( len == 0 || wxStrchr(data->c_str(),0x0d)==NULL)
1199        return ;
1200
1201    wxString temp(*data) ;
1202    wxStringBuffer buf(*data,len ) ;
1203    memcpy( buf , temp.c_str() , (len+1)*sizeof(wxChar) ) ;
1204
1205    wxMacConvertNewlines13To10( buf ) ;
1206}
1207
1208void wxMacConvertNewlines10To13( wxString * data )
1209{
1210    size_t len = data->length() ;
1211
1212    if ( data->empty() || wxStrchr(data->c_str(),0x0a)==NULL)
1213        return ;
1214
1215    wxString temp(*data) ;
1216    wxStringBuffer buf(*data,len ) ;
1217    memcpy( buf , temp.c_str() , (len+1)*sizeof(wxChar) ) ;
1218    wxMacConvertNewlines10To13( buf ) ;
1219}
1220
1221
1222#if wxUSE_UNICODE
1223void wxMacConvertNewlines13To10( wxChar * data )
1224{
1225    wxChar * buf = data ;
1226    while( (buf=wxStrchr(buf,0x0d)) != NULL )
1227    {
1228        *buf = 0x0a ;
1229        buf++ ;
1230    }
1231}
1232
1233void wxMacConvertNewlines10To13( wxChar * data )
1234{
1235    wxChar * buf =  data ;
1236    while( (buf=wxStrchr(buf,0x0a)) != NULL )
1237    {
1238        *buf = 0x0d ;
1239        buf++ ;
1240    }
1241}
1242#endif
1243
1244// ----------------------------------------------------------------------------
1245// debugging support
1246// ----------------------------------------------------------------------------
1247
1248#if defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
1249
1250// MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds...
1251
1252#ifndef __MetroNubUtils__
1253#include "MetroNubUtils.h"
1254#endif
1255
1256#ifndef __GESTALT__
1257#include <Gestalt.h>
1258#endif
1259
1260#if TARGET_API_MAC_CARBON
1261
1262    #include <CodeFragments.h>
1263
1264    extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...);
1265
1266    ProcPtr gCallUniversalProc_Proc = NULL;
1267
1268#endif
1269
1270static MetroNubUserEntryBlock*    gMetroNubEntry = NULL;
1271
1272static long fRunOnce = false;
1273
1274/* ---------------------------------------------------------------------------
1275        IsMetroNubInstalled
1276   --------------------------------------------------------------------------- */
1277
1278Boolean IsMetroNubInstalled()
1279{
1280    if (!fRunOnce)
1281    {
1282        long result, value;
1283
1284        fRunOnce = true;
1285        gMetroNubEntry = NULL;
1286
1287        if (Gestalt(gestaltSystemVersion, &value) == noErr && value < 0x1000)
1288        {
1289            /* look for MetroNub's Gestalt selector */
1290            if (Gestalt(kMetroNubUserSignature, &result) == noErr)
1291            {
1292
1293            #if TARGET_API_MAC_CARBON
1294                if (gCallUniversalProc_Proc == NULL)
1295                {
1296                    CFragConnectionID   connectionID;
1297                    Ptr                 mainAddress;
1298                    Str255              errorString;
1299                    ProcPtr             symbolAddress;
1300                    OSErr               err;
1301                    CFragSymbolClass    symbolClass;
1302
1303                    symbolAddress = NULL;
1304                    err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
1305                                           &connectionID, &mainAddress, errorString);
1306
1307                    if (err != noErr)
1308                    {
1309                        gCallUniversalProc_Proc = NULL;
1310                        goto end;
1311                    }
1312
1313                    err = FindSymbol(connectionID, "\pCallUniversalProc",
1314                                    (Ptr *) &gCallUniversalProc_Proc, &symbolClass);
1315
1316                    if (err != noErr)
1317                    {
1318                        gCallUniversalProc_Proc = NULL;
1319                        goto end;
1320                    }
1321                }
1322            #endif
1323
1324                {
1325                    MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
1326
1327                    /* make sure the version of the API is compatible */
1328                    if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
1329                        kMetroNubUserAPIVersion <= block->apiHiVersion)
1330                        gMetroNubEntry = block;        /* success! */
1331                }
1332
1333            }
1334        }
1335    }
1336
1337end:
1338
1339#if TARGET_API_MAC_CARBON
1340    return (gMetroNubEntry != NULL && gCallUniversalProc_Proc != NULL);
1341#else
1342    return (gMetroNubEntry != NULL);
1343#endif
1344}
1345
1346/* ---------------------------------------------------------------------------
1347        IsMWDebuggerRunning                                            [v1 API]
1348   --------------------------------------------------------------------------- */
1349
1350Boolean IsMWDebuggerRunning()
1351{
1352    if (IsMetroNubInstalled())
1353        return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
1354    else
1355        return false;
1356}
1357
1358/* ---------------------------------------------------------------------------
1359        AmIBeingMWDebugged                                            [v1 API]
1360   --------------------------------------------------------------------------- */
1361
1362Boolean AmIBeingMWDebugged()
1363{
1364    if (IsMetroNubInstalled())
1365        return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
1366    else
1367        return false;
1368}
1369
1370extern bool WXDLLEXPORT wxIsDebuggerRunning()
1371{
1372    return IsMWDebuggerRunning() && AmIBeingMWDebugged();
1373}
1374
1375#else
1376
1377extern bool WXDLLEXPORT wxIsDebuggerRunning()
1378{
1379    return false;
1380}
1381
1382#endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
1383
1384#endif // wxUSE_GUI
1385