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