]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
fix wxExecute() return code checks and removed not working code to open URLs in new...
[wxWidgets.git] / src / mac / carbon / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utils.cpp
3 // Purpose: Various utilities
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/utils.h"
15 #include "wx/app.h"
16 #include "wx/apptrait.h"
17
18 #if wxUSE_GUI
19 #include "wx/mac/uma.h"
20 #include "wx/font.h"
21 #include "wx/toplevel.h"
22 #else
23 #include "wx/intl.h"
24 #endif
25
26 #include <ctype.h>
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdarg.h>
32
33 #include "MoreFilesX.h"
34
35 #ifndef __DARWIN__
36 #include <Threads.h>
37 #include <Sound.h>
38 #endif
39
40 #if wxUSE_GUI
41 #if TARGET_API_MAC_OSX
42 #include <CoreServices/CoreServices.h>
43 #else
44 #include <DriverServices.h>
45 #include <Multiprocessing.h>
46 #endif
47
48 #ifdef __DARWIN__
49 #include <Carbon/Carbon.h>
50 #else
51 #include <ATSUnicode.h>
52 #include <TextCommon.h>
53 #include <TextEncodingConverter.h>
54 #endif
55 #endif // wxUSE_GUI
56
57 #include "wx/mac/private.h" // includes mac headers
58
59 #if defined(__MWERKS__) && wxUSE_UNICODE
60 #include <wtime.h>
61 #endif
62
63 // ---------------------------------------------------------------------------
64 // code used in both base and GUI compilation
65 // ---------------------------------------------------------------------------
66
67 // our OS version is the same in non GUI and GUI cases
68 static int DoGetOSVersion(int *majorVsn, int *minorVsn)
69 {
70 long theSystem ;
71
72 // are there x-platform conventions ?
73
74 Gestalt(gestaltSystemVersion, &theSystem) ;
75 if (minorVsn != NULL) {
76 *minorVsn = (theSystem & 0xFF ) ;
77 }
78 if (majorVsn != NULL) {
79 *majorVsn = (theSystem >> 8 ) ;
80 }
81 #ifdef __DARWIN__
82 return wxMAC_DARWIN;
83 #else
84 return wxMAC;
85 #endif
86 }
87
88
89 #if wxUSE_BASE
90
91 // ----------------------------------------------------------------------------
92 // debugging support
93 // ----------------------------------------------------------------------------
94
95 #if defined(__WXDEBUG__) && defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
96
97 // MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds...
98
99 #ifndef __MetroNubUtils__
100 #include "MetroNubUtils.h"
101 #endif
102
103 #ifndef __GESTALT__
104 #include <Gestalt.h>
105 #endif
106
107 #if TARGET_API_MAC_CARBON
108
109 #include <CodeFragments.h>
110
111 extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...);
112
113 ProcPtr gCallUniversalProc_Proc = NULL;
114
115 #endif
116
117 static MetroNubUserEntryBlock* gMetroNubEntry = NULL;
118
119 static long fRunOnce = false;
120
121 /* ---------------------------------------------------------------------------
122 IsMetroNubInstalled
123 --------------------------------------------------------------------------- */
124
125 Boolean IsMetroNubInstalled()
126 {
127 if (!fRunOnce)
128 {
129 long result, value;
130
131 fRunOnce = true;
132 gMetroNubEntry = NULL;
133
134 if (Gestalt(gestaltSystemVersion, &value) == noErr && value < 0x1000)
135 {
136 /* look for MetroNub's Gestalt selector */
137 if (Gestalt(kMetroNubUserSignature, &result) == noErr)
138 {
139
140 #if TARGET_API_MAC_CARBON
141 if (gCallUniversalProc_Proc == NULL)
142 {
143 CFragConnectionID connectionID;
144 Ptr mainAddress;
145 Str255 errorString;
146 ProcPtr symbolAddress;
147 OSErr err;
148 CFragSymbolClass symbolClass;
149
150 symbolAddress = NULL;
151 err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
152 &connectionID, &mainAddress, errorString);
153
154 if (err != noErr)
155 {
156 gCallUniversalProc_Proc = NULL;
157 goto end;
158 }
159
160 err = FindSymbol(connectionID, "\pCallUniversalProc",
161 (Ptr *) &gCallUniversalProc_Proc, &symbolClass);
162
163 if (err != noErr)
164 {
165 gCallUniversalProc_Proc = NULL;
166 goto end;
167 }
168 }
169 #endif
170
171 {
172 MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
173
174 /* make sure the version of the API is compatible */
175 if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
176 kMetroNubUserAPIVersion <= block->apiHiVersion)
177 gMetroNubEntry = block; /* success! */
178 }
179
180 }
181 }
182 }
183
184 end:
185
186 #if TARGET_API_MAC_CARBON
187 return (gMetroNubEntry != NULL && gCallUniversalProc_Proc != NULL);
188 #else
189 return (gMetroNubEntry != NULL);
190 #endif
191 }
192
193 /* ---------------------------------------------------------------------------
194 IsMWDebuggerRunning [v1 API]
195 --------------------------------------------------------------------------- */
196
197 Boolean IsMWDebuggerRunning()
198 {
199 if (IsMetroNubInstalled())
200 return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
201 else
202 return false;
203 }
204
205 /* ---------------------------------------------------------------------------
206 AmIBeingMWDebugged [v1 API]
207 --------------------------------------------------------------------------- */
208
209 Boolean AmIBeingMWDebugged()
210 {
211 if (IsMetroNubInstalled())
212 return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
213 else
214 return false;
215 }
216
217 extern bool WXDLLEXPORT wxIsDebuggerRunning()
218 {
219 return IsMWDebuggerRunning() && AmIBeingMWDebugged();
220 }
221
222 #else
223
224 extern bool WXDLLEXPORT wxIsDebuggerRunning()
225 {
226 return false;
227 }
228
229 #endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
230
231
232 #ifndef __DARWIN__
233 // defined in unix/utilsunx.cpp for Mac OS X
234
235 // get full hostname (with domain name if possible)
236 bool wxGetFullHostName(wxChar *buf, int maxSize)
237 {
238 return wxGetHostName(buf, maxSize);
239 }
240
241 // Get hostname only (without domain name)
242 bool wxGetHostName(wxChar *buf, int maxSize)
243 {
244 // Gets Chooser name of user by examining a System resource.
245
246 const short kComputerNameID = -16413;
247
248 short oldResFile = CurResFile() ;
249 UseResFile(0);
250 StringHandle chooserName = (StringHandle)::GetString(kComputerNameID);
251 UseResFile(oldResFile);
252
253 if (chooserName && *chooserName)
254 {
255 HLock( (Handle) chooserName ) ;
256 wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
257 HUnlock( (Handle) chooserName ) ;
258 ReleaseResource( (Handle) chooserName ) ;
259 wxStrncpy( buf , name , maxSize - 1 ) ;
260 }
261 else
262 buf[0] = 0 ;
263
264 return true;
265 }
266
267 // Get user ID e.g. jacs
268 bool wxGetUserId(wxChar *buf, int maxSize)
269 {
270 return wxGetUserName( buf , maxSize ) ;
271 }
272
273 const wxChar* wxGetHomeDir(wxString *pstr)
274 {
275 *pstr = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ;
276 return pstr->c_str() ;
277 }
278
279 // Get user name e.g. Stefan Csomor
280 bool wxGetUserName(wxChar *buf, int maxSize)
281 {
282 // Gets Chooser name of user by examining a System resource.
283
284 const short kChooserNameID = -16096;
285
286 short oldResFile = CurResFile() ;
287 UseResFile(0);
288 StringHandle chooserName = (StringHandle)::GetString(kChooserNameID);
289 UseResFile(oldResFile);
290
291 if (chooserName && *chooserName)
292 {
293 HLock( (Handle) chooserName ) ;
294 wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
295 HUnlock( (Handle) chooserName ) ;
296 ReleaseResource( (Handle) chooserName ) ;
297 wxStrncpy( buf , name , maxSize - 1 ) ;
298 }
299 else
300 buf[0] = 0 ;
301
302 return true;
303 }
304
305 int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
306 {
307 // TODO
308 return 0;
309 }
310
311 WXDLLEXPORT bool wxGetEnv(const wxString& var, wxString *value)
312 {
313 // TODO : under classic there is no environement support, under X yes
314 return false ;
315 }
316
317 // set the env var name to the given value, return true on success
318 WXDLLEXPORT bool wxSetEnv(const wxString& var, const wxChar *value)
319 {
320 // TODO : under classic there is no environement support, under X yes
321 return false ;
322 }
323
324 //
325 // Execute a program in an Interactive Shell
326 //
327 bool wxShell(const wxString& command)
328 {
329 // TODO
330 return false;
331 }
332
333 // Shutdown or reboot the PC
334 bool wxShutdown(wxShutdownFlags wFlags)
335 {
336 // TODO
337 return false;
338 }
339
340 wxPowerType wxGetPowerType()
341 {
342 // TODO
343 return wxPOWER_UNKNOWN;
344 }
345
346 wxBatteryState wxGetBatteryState()
347 {
348 // TODO
349 return wxBATTERY_UNKNOWN_STATE;
350 }
351
352 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
353 wxMemorySize wxGetFreeMemory()
354 {
355 return (wxMemorySize)FreeMem() ;
356 }
357
358 #ifndef __DARWIN__
359
360 void wxMicroSleep(unsigned long microseconds)
361 {
362 AbsoluteTime wakeup = AddDurationToAbsolute( microseconds * durationMicrosecond , UpTime());
363 MPDelayUntil( & wakeup);
364 }
365
366 void wxMilliSleep(unsigned long milliseconds)
367 {
368 AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime());
369 MPDelayUntil( & wakeup);
370 }
371
372 void wxSleep(int nSecs)
373 {
374 wxMilliSleep(1000*nSecs);
375 }
376
377 #endif
378
379 // Consume all events until no more left
380 void wxFlushEvents()
381 {
382 }
383
384 #endif // !__DARWIN__
385
386 // Emit a beeeeeep
387 void wxBell()
388 {
389 SysBeep(30);
390 }
391
392 wxToolkitInfo& wxConsoleAppTraits::GetToolkitInfo()
393 {
394 static wxToolkitInfo info;
395 info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
396 info.name = _T("wxBase");
397 return info;
398 }
399
400 #endif // wxUSE_BASE
401
402 #if wxUSE_GUI
403
404 wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
405 {
406 static wxToolkitInfo info;
407 info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
408 info.shortName = _T("mac");
409 info.name = _T("wxMac");
410 #ifdef __WXUNIVERSAL__
411 info.shortName << _T("univ");
412 info.name << _T("/wxUniversal");
413 #endif
414 return info;
415 }
416
417 // Reading and writing resources (eg WIN.INI, .Xdefaults)
418 #if wxUSE_RESOURCES
419 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
420 {
421 // TODO
422 return false;
423 }
424
425 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
426 {
427 wxString buf;
428 buf.Printf(wxT("%.4f"), value);
429
430 return wxWriteResource(section, entry, buf, file);
431 }
432
433 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
434 {
435 wxString buf;
436 buf.Printf(wxT("%ld"), value);
437
438 return wxWriteResource(section, entry, buf, file);
439 }
440
441 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
442 {
443 wxString buf;
444 buf.Printf(wxT("%d"), value);
445
446 return wxWriteResource(section, entry, buf, file);
447 }
448
449 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
450 {
451 // TODO
452 return false;
453 }
454
455 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
456 {
457 char *s = NULL;
458 bool succ = wxGetResource(section, entry, (char **)&s, file);
459 if (succ)
460 {
461 *value = (float)strtod(s, NULL);
462 delete[] s;
463 return true;
464 }
465 else return false;
466 }
467
468 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
469 {
470 char *s = NULL;
471 bool succ = wxGetResource(section, entry, (char **)&s, file);
472 if (succ)
473 {
474 *value = strtol(s, NULL, 10);
475 delete[] s;
476 return true;
477 }
478 else return false;
479 }
480
481 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
482 {
483 char *s = NULL;
484 bool succ = wxGetResource(section, entry, (char **)&s, file);
485 if (succ)
486 {
487 *value = (int)strtol(s, NULL, 10);
488 delete[] s;
489 return true;
490 }
491 else return false;
492 }
493 #endif // wxUSE_RESOURCES
494
495 int gs_wxBusyCursorCount = 0;
496 extern wxCursor gMacCurrentCursor ;
497 wxCursor gMacStoredActiveCursor ;
498
499 // Set the cursor to the busy cursor for all windows
500 void wxBeginBusyCursor(wxCursor *cursor)
501 {
502 if (gs_wxBusyCursorCount++ == 0)
503 {
504 gMacStoredActiveCursor = gMacCurrentCursor ;
505 cursor->MacInstall() ;
506 }
507 //else: nothing to do, already set
508 }
509
510 // Restore cursor to normal
511 void wxEndBusyCursor()
512 {
513 wxCHECK_RET( gs_wxBusyCursorCount > 0,
514 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
515
516 if (--gs_wxBusyCursorCount == 0)
517 {
518 gMacStoredActiveCursor.MacInstall() ;
519 gMacStoredActiveCursor = wxNullCursor ;
520 }
521 }
522
523 // true if we're between the above two calls
524 bool wxIsBusy()
525 {
526 return (gs_wxBusyCursorCount > 0);
527 }
528
529 #endif // wxUSE_GUI
530
531 #if wxUSE_BASE
532
533 wxString wxMacFindFolder( short vol,
534 OSType folderType,
535 Boolean createFolder)
536 {
537 FSRef fsRef ;
538 wxString strDir ;
539
540 if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr)
541 strDir = wxMacFSRefToPath( &fsRef ) + wxFILE_SEP_PATH ;
542
543 return strDir ;
544 }
545
546 #endif // wxUSE_BASE
547
548 #if wxUSE_GUI
549
550 // Check whether this window wants to process messages, e.g. Stop button
551 // in long calculations.
552 bool wxCheckForInterrupt(wxWindow *wnd)
553 {
554 // TODO
555 return false;
556 }
557
558 void wxGetMousePosition( int* x, int* y )
559 {
560 Point pt ;
561
562 GetMouse( &pt ) ;
563 LocalToGlobal( &pt ) ;
564 *x = pt.h ;
565 *y = pt.v ;
566 };
567
568 // Return true if we have a colour display
569 bool wxColourDisplay()
570 {
571 return true;
572 }
573
574 // Returns depth of screen
575 int wxDisplayDepth()
576 {
577 Rect globRect ;
578 SetRect(&globRect, -32760, -32760, 32760, 32760);
579 GDHandle theMaxDevice;
580
581 int theDepth = 8;
582 theMaxDevice = GetMaxDevice(&globRect);
583 if (theMaxDevice != nil)
584 theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
585
586 return theDepth ;
587 }
588
589 // Get size of display
590 void wxDisplaySize(int *width, int *height)
591 {
592 BitMap screenBits;
593 GetQDGlobalsScreenBits( &screenBits );
594
595 if (width != NULL) {
596 *width = screenBits.bounds.right - screenBits.bounds.left ;
597 }
598 if (height != NULL) {
599 *height = screenBits.bounds.bottom - screenBits.bounds.top ;
600 }
601 }
602
603 void wxDisplaySizeMM(int *width, int *height)
604 {
605 wxDisplaySize(width, height);
606 // on mac 72 is fixed (at least now ;-)
607 float cvPt2Mm = 25.4 / 72;
608
609 if (width != NULL) {
610 *width = int( *width * cvPt2Mm );
611 }
612 if (height != NULL) {
613 *height = int( *height * cvPt2Mm );
614 }
615 }
616
617 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
618 {
619 Rect r ;
620 GetAvailableWindowPositioningBounds( GetMainDevice() , &r ) ;
621 if ( x )
622 *x = r.left ;
623 if ( y )
624 *y = r.top ;
625 if ( width )
626 *width = r.right - r.left ;
627 if ( height )
628 *height = r.bottom - r.top ;
629 }
630
631 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
632 {
633 return wxGenericFindWindowAtPoint(pt);
634 }
635
636 #endif // wxUSE_GUI
637
638 #if wxUSE_BASE
639
640 wxString wxGetOsDescription()
641 {
642 #ifdef WXWIN_OS_DESCRIPTION
643 // use configure generated description if available
644 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
645 #else
646 return wxT("MacOS") ; //TODO:define further
647 #endif
648 }
649
650 #ifndef __DARWIN__
651 wxChar *wxGetUserHome (const wxString& user)
652 {
653 // TODO
654 return NULL;
655 }
656
657 bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree)
658 {
659 if ( path.empty() )
660 return false;
661
662 wxString p = path ;
663 if (p[0u] == ':' ) {
664 p = wxGetCwd() + p ;
665 }
666
667 int pos = p.Find(':') ;
668 if ( pos != wxNOT_FOUND ) {
669 p = p.Mid(1,pos) ;
670 }
671
672 p = p + wxT(":") ;
673
674 OSErr err = noErr ;
675
676 FSRef fsRef ;
677 err = wxMacPathToFSRef( p , &fsRef ) ;
678 if ( noErr == err )
679 {
680 FSVolumeRefNum vRefNum ;
681 err = FSGetVRefNum( &fsRef , &vRefNum ) ;
682 if ( noErr == err )
683 {
684 UInt64 freeBytes , totalBytes ;
685 err = FSGetVInfo( vRefNum , NULL , &freeBytes , &totalBytes ) ;
686 if ( noErr == err )
687 {
688 if ( pTotal )
689 *pTotal = wxLongLong( totalBytes ) ;
690 if ( pFree )
691 *pFree = wxLongLong( freeBytes ) ;
692 }
693 }
694 }
695
696 return err == noErr ;
697 }
698 #endif // !__DARWIN__
699
700 //---------------------------------------------------------------------------
701 // wxMac Specific utility functions
702 //---------------------------------------------------------------------------
703
704 void wxMacStringToPascal( const wxString&from , StringPtr to )
705 {
706 wxCharBuffer buf = from.mb_str( wxConvLocal ) ;
707 int len = strlen(buf) ;
708
709 if ( len > 255 )
710 len = 255 ;
711 to[0] = len ;
712 memcpy( (char*) &to[1] , buf , len ) ;
713 }
714
715 wxString wxMacMakeStringFromPascal( ConstStringPtr from )
716 {
717 return wxString( (char*) &from[1] , wxConvLocal , from[0] ) ;
718 }
719
720
721 // ----------------------------------------------------------------------------
722 // Common Event Support
723 // ----------------------------------------------------------------------------
724
725
726 extern ProcessSerialNumber gAppProcess ;
727
728 void wxMacWakeUp()
729 {
730 ProcessSerialNumber psn ;
731 Boolean isSame ;
732 psn.highLongOfPSN = 0 ;
733 psn.lowLongOfPSN = kCurrentProcess ;
734 SameProcess( &gAppProcess , &psn , &isSame ) ;
735 if ( isSame )
736 {
737 #if TARGET_CARBON
738 static wxMacCarbonEvent s_wakeupEvent ;
739 OSStatus err = noErr ;
740 if ( !s_wakeupEvent.IsValid() )
741 {
742 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
743 kEventAttributeNone ) ;
744 }
745 if ( err == noErr )
746 {
747 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
748 return ;
749 s_wakeupEvent.SetTime(0) ;
750 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
751 kEventPriorityHigh);
752 }
753 #else
754 PostEvent( nullEvent , 0 ) ;
755 #endif
756 }
757 else
758 {
759 WakeUpProcess( &gAppProcess ) ;
760 }
761 }
762
763 #endif // wxUSE_BASE
764
765 #if wxUSE_GUI
766
767 // ----------------------------------------------------------------------------
768 // Native Struct Conversions
769 // ----------------------------------------------------------------------------
770
771
772 void wxMacRectToNative( const wxRect *wx , Rect *n )
773 {
774 n->left = wx->x ;
775 n->top = wx->y ;
776 n->right = wx->x + wx->width ;
777 n->bottom = wx->y + wx->height ;
778 }
779
780 void wxMacNativeToRect( const Rect *n , wxRect* wx )
781 {
782 wx->x = n->left ;
783 wx->y = n->top ;
784 wx->width = n->right - n->left ;
785 wx->height = n->bottom - n->top ;
786 }
787
788 void wxMacPointToNative( const wxPoint* wx , Point *n )
789 {
790 n->h = wx->x ;
791 n->v = wx->y ;
792 }
793
794 void wxMacNativeToPoint( const Point *n , wxPoint* wx )
795 {
796 wx->x = n->h ;
797 wx->y = n->v ;
798 }
799
800 // ----------------------------------------------------------------------------
801 // Carbon Event Support
802 // ----------------------------------------------------------------------------
803
804
805 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
806 {
807 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData ) ;
808 }
809
810 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
811 {
812 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData ) ;
813 }
814
815 // ----------------------------------------------------------------------------
816 // Control Access Support
817 // ----------------------------------------------------------------------------
818
819 wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl )
820 {
821 Init() ;
822 m_peer = peer ;
823 m_isRootControl = isRootControl ;
824 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing() ;
825 }
826
827 wxMacControl::wxMacControl( wxWindow* peer , ControlRef control )
828 {
829 Init() ;
830 m_peer = peer ;
831 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing() ;
832 m_controlRef = control ;
833 }
834
835 wxMacControl::wxMacControl( wxWindow* peer , WXWidget control )
836 {
837 Init() ;
838 m_peer = peer ;
839 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing() ;
840 m_controlRef = (ControlRef) control ;
841 }
842
843 wxMacControl::~wxMacControl()
844 {
845 }
846
847 void wxMacControl::Init()
848 {
849 m_peer = NULL ;
850 m_controlRef = NULL ;
851 m_needsFocusRect = false ;
852 m_isCompositing = false ;
853 m_isRootControl = false ;
854 }
855
856 void wxMacControl::Dispose()
857 {
858 ::DisposeControl( m_controlRef ) ;
859 m_controlRef = NULL ;
860 }
861
862 void wxMacControl::SetReference( SInt32 data )
863 {
864 SetControlReference( m_controlRef , data ) ;
865 }
866
867 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
868 {
869 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize ) ;
870 }
871
872 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
873 {
874 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize ) ;
875 }
876
877 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
878 {
879 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData ) ;
880 }
881
882 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
883 {
884 #if TARGET_API_MAC_OSX
885 return SendEventToEventTargetWithOptions( event,
886 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
887 #else
888 #pragma unused(inOptions)
889 return SendEventToEventTarget(event,GetControlEventTarget( m_controlRef ) ) ;
890 #endif
891 }
892
893 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
894 {
895 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ) ;
896 event.SetParameter<HICommand>(kEventParamDirectObject,command) ;
897 return SendEvent( event , inOptions ) ;
898 }
899
900 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
901 {
902 HICommand command ;
903 memset( &command, 0 , sizeof(command) ) ;
904 command.commandID = commandID ;
905 return SendHICommand( command , inOptions ) ;
906 }
907
908 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
909 {
910 HiliteControl( m_controlRef , part ) ;
911 unsigned long finalTicks ;
912 Delay( ticks , &finalTicks ) ;
913 HiliteControl( m_controlRef , kControlNoPart ) ;
914 }
915
916 SInt32 wxMacControl::GetValue() const
917 {
918 return ::GetControl32BitValue( m_controlRef ) ;
919 }
920
921 SInt32 wxMacControl::GetMaximum() const
922 {
923 return ::GetControl32BitMaximum( m_controlRef ) ;
924 }
925
926 SInt32 wxMacControl::GetMinimum() const
927 {
928 return ::GetControl32BitMinimum( m_controlRef ) ;
929 }
930
931 void wxMacControl::SetValue( SInt32 v )
932 {
933 ::SetControl32BitValue( m_controlRef , v ) ;
934 }
935
936 void wxMacControl::SetMinimum( SInt32 v )
937 {
938 ::SetControl32BitMinimum( m_controlRef , v ) ;
939 }
940
941 void wxMacControl::SetMaximum( SInt32 v )
942 {
943 ::SetControl32BitMaximum( m_controlRef , v ) ;
944 }
945
946 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
947 {
948 ::SetControl32BitMinimum( m_controlRef , minimum ) ;
949 ::SetControl32BitMaximum( m_controlRef , maximum ) ;
950 ::SetControl32BitValue( m_controlRef , value ) ;
951 }
952
953 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
954 {
955 return SetKeyboardFocus( GetControlOwner( m_controlRef ) ,
956 m_controlRef , focusPart ) ;
957 }
958
959 bool wxMacControl::HasFocus() const
960 {
961 ControlRef control ;
962 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
963 return control == m_controlRef ;
964 }
965
966 void wxMacControl::SetNeedsFocusRect( bool needs )
967 {
968 m_needsFocusRect = needs ;
969 }
970
971 bool wxMacControl::NeedsFocusRect() const
972 {
973 return m_needsFocusRect ;
974 }
975
976 void wxMacControl::VisibilityChanged(bool shown)
977 {
978 }
979
980 void wxMacControl::SuperChangedPosition()
981 {
982 }
983
984 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
985 {
986 m_font = font ;
987 ControlFontStyleRec fontStyle;
988 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
989 {
990 switch( font.MacGetThemeFontID() )
991 {
992 case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ;
993 case 109 /*mini font */ : fontStyle.font = -5 ; break ;
994 case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ;
995 default : fontStyle.font = kControlFontBigSystemFont ; break ;
996 }
997 fontStyle.flags = kControlUseFontMask ;
998 }
999 else
1000 {
1001 fontStyle.font = font.MacGetFontNum() ;
1002 fontStyle.style = font.MacGetFontStyle() ;
1003 fontStyle.size = font.MacGetFontSize() ;
1004 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
1005 }
1006
1007 fontStyle.just = teJustLeft ;
1008 fontStyle.flags |= kControlUseJustMask ;
1009 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
1010 fontStyle.just = teJustCenter ;
1011 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
1012 fontStyle.just = teJustRight ;
1013
1014
1015 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1016 // won't get grayed out by the system anymore
1017
1018 if ( foreground != *wxBLACK )
1019 {
1020 fontStyle.foreColor = MAC_WXCOLORREF(foreground.GetPixel() ) ;
1021 fontStyle.flags |= kControlUseForeColorMask ;
1022 }
1023
1024 ::SetControlFontStyle( m_controlRef , &fontStyle );
1025 }
1026
1027 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
1028 {
1029 // TODO
1030 // setting up a color proc is not recommended anymore
1031 }
1032
1033 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
1034 {
1035 ::SetControl32BitMinimum( m_controlRef , minimum ) ;
1036 ::SetControl32BitMaximum( m_controlRef , maximum ) ;
1037 }
1038
1039 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
1040 {
1041 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers ) ;
1042 }
1043
1044 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
1045 {
1046 SetControlAction( m_controlRef , actionProc ) ;
1047 }
1048
1049 void wxMacControl::SetViewSize( SInt32 viewSize )
1050 {
1051 SetControlViewSize(m_controlRef , viewSize ) ;
1052 }
1053
1054 SInt32 wxMacControl::GetViewSize() const
1055 {
1056 return GetControlViewSize( m_controlRef ) ;
1057 }
1058
1059 bool wxMacControl::IsVisible() const
1060 {
1061 return IsControlVisible( m_controlRef ) ;
1062 }
1063
1064 void wxMacControl::SetVisibility( bool visible , bool redraw )
1065 {
1066 SetControlVisibility( m_controlRef , visible , redraw ) ;
1067 }
1068
1069 bool wxMacControl::IsEnabled() const
1070 {
1071 #if TARGET_API_MAC_OSX
1072 return IsControlEnabled( m_controlRef ) ;
1073 #else
1074 return IsControlActive( m_controlRef ) ;
1075 #endif
1076 }
1077
1078 bool wxMacControl::IsActive() const
1079 {
1080 return IsControlActive( m_controlRef ) ;
1081 }
1082
1083 void wxMacControl::Enable( bool enable )
1084 {
1085 #if TARGET_API_MAC_OSX
1086 if ( enable )
1087 EnableControl( m_controlRef ) ;
1088 else
1089 DisableControl( m_controlRef ) ;
1090 #else
1091 if ( enable )
1092 ActivateControl( m_controlRef ) ;
1093 else
1094 DeactivateControl( m_controlRef ) ;
1095 #endif
1096 }
1097
1098 void wxMacControl::SetDrawingEnabled( bool enable )
1099 {
1100 #if TARGET_API_MAC_OSX
1101 HIViewSetDrawingEnabled( m_controlRef , enable ) ;
1102 #endif
1103 }
1104
1105 #if TARGET_API_MAC_OSX
1106 bool wxMacControl::GetNeedsDisplay() const
1107 {
1108 #if TARGET_API_MAC_OSX
1109 if ( m_isCompositing )
1110 {
1111 return HIViewGetNeedsDisplay( m_controlRef ) ;
1112 }
1113 else
1114 #endif
1115 {
1116 if ( !IsVisible() )
1117 return false ;
1118
1119 Rect controlBounds ;
1120 GetControlBounds( m_controlRef, &controlBounds ) ;
1121 RgnHandle rgn = NewRgn() ;
1122 GetWindowRegion ( GetControlOwner( m_controlRef ) , kWindowUpdateRgn , rgn ) ;
1123 Boolean intersect = RectInRgn ( &controlBounds , rgn ) ;
1124 DisposeRgn( rgn ) ;
1125 return intersect ;
1126 }
1127
1128 }
1129 #endif
1130
1131 void wxMacControl::SetNeedsDisplay( RgnHandle where )
1132 {
1133 if ( !IsVisible() )
1134 return ;
1135
1136 #if TARGET_API_MAC_OSX
1137 if ( m_isCompositing )
1138 {
1139 HIViewSetNeedsDisplayInRegion( m_controlRef , where , true ) ;
1140 }
1141 else
1142 #endif
1143 {
1144 Rect controlBounds ;
1145 GetControlBounds( m_controlRef, &controlBounds ) ;
1146 RgnHandle update = NewRgn() ;
1147 CopyRgn( where , update ) ;
1148 OffsetRgn( update , controlBounds.left , controlBounds.top ) ;
1149 InvalWindowRgn( GetControlOwner( m_controlRef) , update ) ;
1150 }
1151 }
1152
1153 void wxMacControl::SetNeedsDisplay( Rect* where )
1154 {
1155 if ( !IsVisible() )
1156 return ;
1157
1158 #if TARGET_API_MAC_OSX
1159 if ( m_isCompositing )
1160 {
1161 if ( where != NULL )
1162 {
1163 RgnHandle update = NewRgn() ;
1164 RectRgn( update , where ) ;
1165 HIViewSetNeedsDisplayInRegion( m_controlRef , update , true ) ;
1166 DisposeRgn( update ) ;
1167 }
1168 else
1169 HIViewSetNeedsDisplay( m_controlRef , true ) ;
1170 }
1171 else
1172 #endif
1173 {
1174 Rect controlBounds ;
1175 GetControlBounds( m_controlRef, &controlBounds ) ;
1176 if ( where )
1177 {
1178 Rect whereLocal = *where ;
1179 OffsetRect( &whereLocal , controlBounds.left , controlBounds.top ) ;
1180 SectRect( &controlBounds , &whereLocal, &controlBounds ) ;
1181 }
1182 InvalWindowRect( GetControlOwner( m_controlRef) , &controlBounds ) ;
1183 }
1184 }
1185
1186 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
1187 {
1188 #if TARGET_API_MAC_OSX
1189 if ( from->m_peer->MacGetTopLevelWindow()->MacUsesCompositing() )
1190 {
1191 HIPoint hiPoint ;
1192 hiPoint.x = pt->x ;
1193 hiPoint.y = pt->y ;
1194 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef ) ;
1195 pt->x = (int)hiPoint.x ;
1196 pt->y = (int)hiPoint.y ;
1197 }
1198 else
1199 #endif
1200 {
1201 Rect fromRect ;
1202 Rect toRect ;
1203 GetControlBounds( from->m_controlRef , &fromRect ) ;
1204 GetControlBounds( to->m_controlRef , &toRect ) ;
1205 if ( from->m_isRootControl )
1206 fromRect.left = fromRect.top = 0 ;
1207 if ( to->m_isRootControl )
1208 toRect.left = toRect.top = 0 ;
1209
1210 pt->x = pt->x + fromRect.left - toRect.left ;
1211 pt->y = pt->y + fromRect.top - toRect.top ;
1212 }
1213 }
1214
1215 void wxMacControl::SetRect( Rect *r )
1216 {
1217 #if TARGET_API_MAC_OSX
1218 if ( m_isCompositing )
1219 {
1220 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1221 //CGPoint and CGSize, which have two floats each
1222 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } } ;
1223 HIViewSetFrame ( m_controlRef , &hir ) ;
1224 // eventuall we might have to do a SetVisibility( false , true ) ;
1225 // before and a SetVisibility( true , true ) ; after
1226 }
1227 else
1228 #endif
1229 {
1230 bool vis = IsVisible() ;
1231 if ( vis )
1232 {
1233 Rect former ;
1234 GetControlBounds( m_controlRef , &former ) ;
1235 InvalWindowRect( GetControlOwner( m_controlRef ) , &former ) ;
1236 }
1237
1238 Rect controlBounds = *r ;
1239
1240 // since the rect passed in is always (even in non-compositing) relative
1241 // to the (native) parent, we have to adjust to window relative here
1242 wxMacControl* parent = m_peer->GetParent()->GetPeer() ;
1243 if( parent->m_isRootControl == false )
1244 {
1245 Rect superRect ;
1246 GetControlBounds( parent->m_controlRef , &superRect ) ;
1247 OffsetRect( &controlBounds , superRect.left , superRect.top ) ;
1248 }
1249
1250 SetControlBounds( m_controlRef , &controlBounds ) ;
1251 if ( vis )
1252 {
1253 InvalWindowRect( GetControlOwner( m_controlRef ) , &controlBounds ) ;
1254 }
1255 }
1256 }
1257
1258 void wxMacControl::GetRect( Rect *r )
1259 {
1260 GetControlBounds( m_controlRef , r ) ;
1261 if ( m_isCompositing == false )
1262 {
1263 // correct the case of the root control
1264 if ( m_isRootControl )
1265 {
1266 WindowRef wr = GetControlOwner( m_controlRef ) ;
1267 GetWindowBounds( wr , kWindowContentRgn , r ) ;
1268 r->right -= r->left ;
1269 r->bottom -= r->top ;
1270 r->left = 0 ;
1271 r->top = 0 ;
1272 }
1273 else
1274 {
1275 wxMacControl* parent = m_peer->GetParent()->GetPeer() ;
1276 if( parent->m_isRootControl == false )
1277 {
1278 Rect superRect ;
1279 GetControlBounds( parent->m_controlRef , &superRect ) ;
1280 OffsetRect( r , -superRect.left , -superRect.top ) ;
1281 }
1282 }
1283 }
1284 }
1285
1286 void wxMacControl::GetRectInWindowCoords( Rect *r )
1287 {
1288 UMAGetControlBoundsInWindowCoords( m_controlRef , r ) ;
1289 }
1290
1291 void wxMacControl::GetBestRect( Rect *r )
1292 {
1293 short baselineoffset ;
1294 GetBestControlRect( m_controlRef , r , &baselineoffset ) ;
1295 }
1296
1297 void wxMacControl::SetTitle( const wxString &title )
1298 {
1299 wxFontEncoding encoding;
1300
1301 if ( m_font.Ok() )
1302 encoding = m_font.GetEncoding();
1303 else
1304 encoding = wxFont::GetDefaultEncoding();
1305
1306 UMASetControlTitle( m_controlRef , title , encoding ) ;
1307 }
1308
1309 void wxMacControl::GetFeatures( UInt32 * features )
1310 {
1311 GetControlFeatures( m_controlRef , features ) ;
1312 }
1313
1314 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
1315 {
1316 OSStatus err = GetControlRegion( m_controlRef , partCode , region ) ;
1317 if ( m_isCompositing == false )
1318 {
1319 if ( !m_isRootControl )
1320 {
1321 Rect r ;
1322 GetControlBounds(m_controlRef, &r ) ;
1323 if ( !EmptyRgn( region ) )
1324 OffsetRgn( region , -r.left , -r.top ) ;
1325 }
1326 }
1327 return err ;
1328 }
1329
1330 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
1331 {
1332 #if TARGET_API_MAC_OSX
1333 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
1334 (other != NULL) ? other->m_controlRef : NULL) ;
1335 #else
1336 return 0 ;
1337 #endif
1338 }
1339
1340
1341 #if TARGET_API_MAC_OSX
1342 // SetNeedsDisplay would not invalidate the children
1343 static void InvalidateControlAndChildren( HIViewRef control )
1344 {
1345 HIViewSetNeedsDisplay( control , true ) ;
1346 UInt16 childrenCount = 0 ;
1347 OSStatus err = CountSubControls( control , &childrenCount ) ;
1348 if ( err == errControlIsNotEmbedder )
1349 return ;
1350 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
1351
1352 for ( UInt16 i = childrenCount ; i >=1 ; --i )
1353 {
1354 HIViewRef child ;
1355 err = GetIndexedSubControl( control , i , & child ) ;
1356 if ( err == errControlIsNotEmbedder )
1357 return ;
1358 InvalidateControlAndChildren( child ) ;
1359 }
1360 }
1361 #endif
1362
1363 void wxMacControl::InvalidateWithChildren()
1364 {
1365 #if TARGET_API_MAC_OSX
1366 InvalidateControlAndChildren( m_controlRef ) ;
1367 #endif
1368 }
1369
1370 void wxMacControl::ScrollRect( wxRect *r , int dx , int dy )
1371 {
1372 wxASSERT( r != NULL ) ;
1373 #if TARGET_API_MAC_OSX
1374 if ( m_isCompositing )
1375 {
1376 HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height) ;
1377 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ) ;
1378 }
1379 else
1380 #endif
1381 {
1382 Rect bounds ;
1383 GetControlBounds( m_controlRef , &bounds ) ;
1384 bounds.left += r->x ;
1385 bounds.top += r->y ;
1386 bounds.bottom = bounds.top + r->height ;
1387 bounds.right = bounds.left + r->width ;
1388 wxMacWindowClipper clip( m_peer ) ;
1389 RgnHandle updateRgn = NewRgn() ;
1390 ::ScrollRect( &bounds , dx , dy , updateRgn ) ;
1391 InvalWindowRgn( GetControlOwner( m_controlRef ) , updateRgn ) ;
1392 }
1393 }
1394
1395
1396 // SetNeedsDisplay would not invalidate the children
1397
1398 //
1399 // Databrowser
1400 //
1401
1402 OSStatus wxMacControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1403 {
1404 return SetDataBrowserSelectionFlags( m_controlRef , options ) ;
1405 }
1406
1407 OSStatus wxMacControl::AddListViewColumn( DataBrowserListViewColumnDesc *columnDesc,
1408 DataBrowserTableViewColumnIndex position )
1409 {
1410 return AddDataBrowserListViewColumn( m_controlRef , columnDesc, position ) ;
1411 }
1412
1413 OSStatus wxMacControl::AutoSizeListViewColumns()
1414 {
1415 return AutoSizeDataBrowserListViewColumns(m_controlRef) ;
1416 }
1417
1418 OSStatus wxMacControl::SetHasScrollBars( bool horiz , bool vert )
1419 {
1420 return SetDataBrowserHasScrollBars( m_controlRef , horiz , vert ) ;
1421 }
1422
1423 OSStatus wxMacControl::SetTableViewHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1424 {
1425 return SetDataBrowserTableViewHiliteStyle( m_controlRef , hiliteStyle ) ;
1426 }
1427
1428 OSStatus wxMacControl::SetListViewHeaderBtnHeight(UInt16 height)
1429 {
1430 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef ,height ) ;
1431 }
1432
1433 OSStatus wxMacControl::SetCallbacks(const DataBrowserCallbacks * callbacks)
1434 {
1435 return SetDataBrowserCallbacks( m_controlRef , callbacks ) ;
1436 }
1437
1438 OSStatus wxMacControl::UpdateItems( DataBrowserItemID container, UInt32 numItems,
1439 const DataBrowserItemID* items,
1440 DataBrowserPropertyID preSortProperty,
1441 DataBrowserPropertyID propertyID )
1442 {
1443 return UpdateDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty, propertyID ) ;
1444 }
1445
1446 bool wxMacControl::IsItemSelected( DataBrowserItemID item )
1447 {
1448 return IsDataBrowserItemSelected( m_controlRef , item ) ;
1449 }
1450
1451 OSStatus wxMacControl::AddItems( DataBrowserItemID container, UInt32 numItems,
1452 const DataBrowserItemID* items,
1453 DataBrowserPropertyID preSortProperty )
1454 {
1455 return AddDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty ) ;
1456 }
1457
1458 OSStatus wxMacControl::RemoveItems( DataBrowserItemID container, UInt32 numItems,
1459 const DataBrowserItemID* items,
1460 DataBrowserPropertyID preSortProperty )
1461 {
1462 return RemoveDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty ) ;
1463 }
1464
1465 OSStatus wxMacControl::RevealItem( DataBrowserItemID item,
1466 DataBrowserPropertyID propertyID,
1467 DataBrowserRevealOptions options )
1468 {
1469 return RevealDataBrowserItem( m_controlRef , item , propertyID , options ) ;
1470 }
1471
1472 OSStatus wxMacControl::SetSelectedItems(UInt32 numItems,
1473 const DataBrowserItemID * items,
1474 DataBrowserSetOption operation )
1475 {
1476 return SetDataBrowserSelectedItems( m_controlRef , numItems , items, operation ) ;
1477 }
1478
1479 OSStatus wxMacControl::GetSelectionAnchor( DataBrowserItemID * first, DataBrowserItemID * last )
1480 {
1481 return GetDataBrowserSelectionAnchor( m_controlRef , first , last ) ;
1482 }
1483
1484 //
1485 // Tab Control
1486 //
1487
1488 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
1489 {
1490 return ::SetTabEnabled( m_controlRef , tabNo , enable ) ;
1491 }
1492
1493 //
1494 // Quartz Support
1495 //
1496
1497 #ifdef __WXMAC_OSX__
1498 // snippets from Sketch Sample from Apple :
1499
1500 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
1501 /*
1502 This function locates, opens, and returns the profile reference for the calibrated
1503 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
1504 with the profile reference this function returns.
1505 */
1506 CMProfileRef wxMacOpenGenericProfile(void)
1507 {
1508 static CMProfileRef cachedRGBProfileRef = NULL;
1509
1510 // we only create the profile reference once
1511 if (cachedRGBProfileRef == NULL)
1512 {
1513 CMProfileLocation loc;
1514
1515 loc.locType = cmPathBasedProfile;
1516 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
1517
1518 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
1519 }
1520
1521 if (cachedRGBProfileRef)
1522 {
1523 // clone the profile reference so that the caller has their own reference, not our cached one
1524 CMCloneProfileRef(cachedRGBProfileRef);
1525 }
1526
1527 return cachedRGBProfileRef;
1528 }
1529
1530 /*
1531 Return the generic RGB color space. This is a 'get' function and the caller should
1532 not release the returned value unless the caller retains it first. Usually callers
1533 of this routine will immediately use the returned colorspace with CoreGraphics
1534 so they typically do not need to retain it themselves.
1535
1536 This function creates the generic RGB color space once and hangs onto it so it can
1537 return it whenever this function is called.
1538 */
1539
1540 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
1541 {
1542 static CGColorSpaceRef genericRGBColorSpace = NULL;
1543
1544 if (genericRGBColorSpace == NULL)
1545 {
1546 CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
1547
1548 if (genericRGBProfile)
1549 {
1550 genericRGBColorSpace = CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile);
1551 wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") ) ;
1552
1553 // we opened the profile so it is up to us to close it
1554 CMCloseProfile(genericRGBProfile);
1555 }
1556 }
1557 return genericRGBColorSpace;
1558 }
1559 #endif
1560
1561 #endif // wxUSE_GUI
1562