]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
applied patch #1356901 "Yet another removal of extra semicolons", also fixed remainin...
[wxWidgets.git] / src / mac / carbon / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/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 OSStatus err = noErr ;
739 #if 0
740 // lead sometimes to race conditions, although all calls used should be thread safe ...
741 static wxMacCarbonEvent s_wakeupEvent ;
742 if ( !s_wakeupEvent.IsValid() )
743 {
744 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
745 kEventAttributeNone ) ;
746 }
747 if ( err == noErr )
748 {
749
750 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
751 return ;
752 s_wakeupEvent.SetCurrentTime() ;
753 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
754 kEventPriorityHigh );
755 }
756 #else
757 wxMacCarbonEvent wakeupEvent ;
758 wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
759 kEventAttributeNone ) ;
760 err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
761 kEventPriorityHigh );
762 #endif
763 #else
764 PostEvent( nullEvent , 0 ) ;
765 #endif
766 }
767 else
768 {
769 WakeUpProcess( &gAppProcess ) ;
770 }
771 }
772
773 #endif // wxUSE_BASE
774
775 #if wxUSE_GUI
776
777 // ----------------------------------------------------------------------------
778 // Native Struct Conversions
779 // ----------------------------------------------------------------------------
780
781
782 void wxMacRectToNative( const wxRect *wx , Rect *n )
783 {
784 n->left = wx->x ;
785 n->top = wx->y ;
786 n->right = wx->x + wx->width ;
787 n->bottom = wx->y + wx->height ;
788 }
789
790 void wxMacNativeToRect( const Rect *n , wxRect* wx )
791 {
792 wx->x = n->left ;
793 wx->y = n->top ;
794 wx->width = n->right - n->left ;
795 wx->height = n->bottom - n->top ;
796 }
797
798 void wxMacPointToNative( const wxPoint* wx , Point *n )
799 {
800 n->h = wx->x ;
801 n->v = wx->y ;
802 }
803
804 void wxMacNativeToPoint( const Point *n , wxPoint* wx )
805 {
806 wx->x = n->h ;
807 wx->y = n->v ;
808 }
809
810 // ----------------------------------------------------------------------------
811 // Carbon Event Support
812 // ----------------------------------------------------------------------------
813
814
815 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
816 {
817 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData ) ;
818 }
819
820 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
821 {
822 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData ) ;
823 }
824
825 // ----------------------------------------------------------------------------
826 // Control Access Support
827 // ----------------------------------------------------------------------------
828
829 wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl )
830 {
831 Init() ;
832 m_peer = peer ;
833 m_isRootControl = isRootControl ;
834 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing() ;
835 }
836
837 wxMacControl::wxMacControl( wxWindow* peer , ControlRef control )
838 {
839 Init() ;
840 m_peer = peer ;
841 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing() ;
842 m_controlRef = control ;
843 }
844
845 wxMacControl::wxMacControl( wxWindow* peer , WXWidget control )
846 {
847 Init() ;
848 m_peer = peer ;
849 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing() ;
850 m_controlRef = (ControlRef) control ;
851 }
852
853 wxMacControl::~wxMacControl()
854 {
855 }
856
857 void wxMacControl::Init()
858 {
859 m_peer = NULL ;
860 m_controlRef = NULL ;
861 m_needsFocusRect = false ;
862 m_isCompositing = false ;
863 m_isRootControl = false ;
864 }
865
866 void wxMacControl::Dispose()
867 {
868 ::DisposeControl( m_controlRef ) ;
869 m_controlRef = NULL ;
870 }
871
872 void wxMacControl::SetReference( SInt32 data )
873 {
874 SetControlReference( m_controlRef , data ) ;
875 }
876
877 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
878 {
879 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize ) ;
880 }
881
882 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
883 {
884 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize ) ;
885 }
886
887 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
888 {
889 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData ) ;
890 }
891
892 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
893 {
894 #if TARGET_API_MAC_OSX
895 return SendEventToEventTargetWithOptions( event,
896 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
897 #else
898 #pragma unused(inOptions)
899 return SendEventToEventTarget(event,GetControlEventTarget( m_controlRef ) ) ;
900 #endif
901 }
902
903 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
904 {
905 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ) ;
906 event.SetParameter<HICommand>(kEventParamDirectObject,command) ;
907 return SendEvent( event , inOptions ) ;
908 }
909
910 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
911 {
912 HICommand command ;
913 memset( &command, 0 , sizeof(command) ) ;
914 command.commandID = commandID ;
915 return SendHICommand( command , inOptions ) ;
916 }
917
918 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
919 {
920 HiliteControl( m_controlRef , part ) ;
921 unsigned long finalTicks ;
922 Delay( ticks , &finalTicks ) ;
923 HiliteControl( m_controlRef , kControlNoPart ) ;
924 }
925
926 SInt32 wxMacControl::GetValue() const
927 {
928 return ::GetControl32BitValue( m_controlRef ) ;
929 }
930
931 SInt32 wxMacControl::GetMaximum() const
932 {
933 return ::GetControl32BitMaximum( m_controlRef ) ;
934 }
935
936 SInt32 wxMacControl::GetMinimum() const
937 {
938 return ::GetControl32BitMinimum( m_controlRef ) ;
939 }
940
941 void wxMacControl::SetValue( SInt32 v )
942 {
943 ::SetControl32BitValue( m_controlRef , v ) ;
944 }
945
946 void wxMacControl::SetMinimum( SInt32 v )
947 {
948 ::SetControl32BitMinimum( m_controlRef , v ) ;
949 }
950
951 void wxMacControl::SetMaximum( SInt32 v )
952 {
953 ::SetControl32BitMaximum( m_controlRef , v ) ;
954 }
955
956 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
957 {
958 ::SetControl32BitMinimum( m_controlRef , minimum ) ;
959 ::SetControl32BitMaximum( m_controlRef , maximum ) ;
960 ::SetControl32BitValue( m_controlRef , value ) ;
961 }
962
963 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
964 {
965 return SetKeyboardFocus( GetControlOwner( m_controlRef ) ,
966 m_controlRef , focusPart ) ;
967 }
968
969 bool wxMacControl::HasFocus() const
970 {
971 ControlRef control ;
972 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
973 return control == m_controlRef ;
974 }
975
976 void wxMacControl::SetNeedsFocusRect( bool needs )
977 {
978 m_needsFocusRect = needs ;
979 }
980
981 bool wxMacControl::NeedsFocusRect() const
982 {
983 return m_needsFocusRect ;
984 }
985
986 void wxMacControl::VisibilityChanged(bool shown)
987 {
988 }
989
990 void wxMacControl::SuperChangedPosition()
991 {
992 }
993
994 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
995 {
996 m_font = font ;
997 ControlFontStyleRec fontStyle;
998 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
999 {
1000 switch( font.MacGetThemeFontID() )
1001 {
1002 case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ;
1003 case 109 /*mini font */ : fontStyle.font = -5 ; break ;
1004 case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ;
1005 default : fontStyle.font = kControlFontBigSystemFont ; break ;
1006 }
1007 fontStyle.flags = kControlUseFontMask ;
1008 }
1009 else
1010 {
1011 fontStyle.font = font.MacGetFontNum() ;
1012 fontStyle.style = font.MacGetFontStyle() ;
1013 fontStyle.size = font.MacGetFontSize() ;
1014 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
1015 }
1016
1017 fontStyle.just = teJustLeft ;
1018 fontStyle.flags |= kControlUseJustMask ;
1019 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
1020 fontStyle.just = teJustCenter ;
1021 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
1022 fontStyle.just = teJustRight ;
1023
1024
1025 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1026 // won't get grayed out by the system anymore
1027
1028 if ( foreground != *wxBLACK )
1029 {
1030 fontStyle.foreColor = MAC_WXCOLORREF(foreground.GetPixel() ) ;
1031 fontStyle.flags |= kControlUseForeColorMask ;
1032 }
1033
1034 ::SetControlFontStyle( m_controlRef , &fontStyle );
1035 }
1036
1037 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
1038 {
1039 // TODO
1040 // setting up a color proc is not recommended anymore
1041 }
1042
1043 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
1044 {
1045 ::SetControl32BitMinimum( m_controlRef , minimum ) ;
1046 ::SetControl32BitMaximum( m_controlRef , maximum ) ;
1047 }
1048
1049 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
1050 {
1051 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers ) ;
1052 }
1053
1054 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
1055 {
1056 SetControlAction( m_controlRef , actionProc ) ;
1057 }
1058
1059 void wxMacControl::SetViewSize( SInt32 viewSize )
1060 {
1061 SetControlViewSize(m_controlRef , viewSize ) ;
1062 }
1063
1064 SInt32 wxMacControl::GetViewSize() const
1065 {
1066 return GetControlViewSize( m_controlRef ) ;
1067 }
1068
1069 bool wxMacControl::IsVisible() const
1070 {
1071 return IsControlVisible( m_controlRef ) ;
1072 }
1073
1074 void wxMacControl::SetVisibility( bool visible , bool redraw )
1075 {
1076 SetControlVisibility( m_controlRef , visible , redraw ) ;
1077 }
1078
1079 bool wxMacControl::IsEnabled() const
1080 {
1081 #if TARGET_API_MAC_OSX
1082 return IsControlEnabled( m_controlRef ) ;
1083 #else
1084 return IsControlActive( m_controlRef ) ;
1085 #endif
1086 }
1087
1088 bool wxMacControl::IsActive() const
1089 {
1090 return IsControlActive( m_controlRef ) ;
1091 }
1092
1093 void wxMacControl::Enable( bool enable )
1094 {
1095 #if TARGET_API_MAC_OSX
1096 if ( enable )
1097 EnableControl( m_controlRef ) ;
1098 else
1099 DisableControl( m_controlRef ) ;
1100 #else
1101 if ( enable )
1102 ActivateControl( m_controlRef ) ;
1103 else
1104 DeactivateControl( m_controlRef ) ;
1105 #endif
1106 }
1107
1108 void wxMacControl::SetDrawingEnabled( bool enable )
1109 {
1110 #if TARGET_API_MAC_OSX
1111 HIViewSetDrawingEnabled( m_controlRef , enable ) ;
1112 #endif
1113 }
1114
1115 #if TARGET_API_MAC_OSX
1116 bool wxMacControl::GetNeedsDisplay() const
1117 {
1118 #if TARGET_API_MAC_OSX
1119 if ( m_isCompositing )
1120 {
1121 return HIViewGetNeedsDisplay( m_controlRef ) ;
1122 }
1123 else
1124 #endif
1125 {
1126 if ( !IsVisible() )
1127 return false ;
1128
1129 Rect controlBounds ;
1130 GetControlBounds( m_controlRef, &controlBounds ) ;
1131 RgnHandle rgn = NewRgn() ;
1132 GetWindowRegion ( GetControlOwner( m_controlRef ) , kWindowUpdateRgn , rgn ) ;
1133 Boolean intersect = RectInRgn ( &controlBounds , rgn ) ;
1134 DisposeRgn( rgn ) ;
1135 return intersect ;
1136 }
1137
1138 }
1139 #endif
1140
1141 void wxMacControl::SetNeedsDisplay( RgnHandle where )
1142 {
1143 if ( !IsVisible() )
1144 return ;
1145
1146 #if TARGET_API_MAC_OSX
1147 if ( m_isCompositing )
1148 {
1149 HIViewSetNeedsDisplayInRegion( m_controlRef , where , true ) ;
1150 }
1151 else
1152 #endif
1153 {
1154 Rect controlBounds ;
1155 GetControlBounds( m_controlRef, &controlBounds ) ;
1156 RgnHandle update = NewRgn() ;
1157 CopyRgn( where , update ) ;
1158 OffsetRgn( update , controlBounds.left , controlBounds.top ) ;
1159 InvalWindowRgn( GetControlOwner( m_controlRef) , update ) ;
1160 }
1161 }
1162
1163 void wxMacControl::SetNeedsDisplay( Rect* where )
1164 {
1165 if ( !IsVisible() )
1166 return ;
1167
1168 #if TARGET_API_MAC_OSX
1169 if ( m_isCompositing )
1170 {
1171 if ( where != NULL )
1172 {
1173 RgnHandle update = NewRgn() ;
1174 RectRgn( update , where ) ;
1175 HIViewSetNeedsDisplayInRegion( m_controlRef , update , true ) ;
1176 DisposeRgn( update ) ;
1177 }
1178 else
1179 HIViewSetNeedsDisplay( m_controlRef , true ) ;
1180 }
1181 else
1182 #endif
1183 {
1184 Rect controlBounds ;
1185 GetControlBounds( m_controlRef, &controlBounds ) ;
1186 if ( where )
1187 {
1188 Rect whereLocal = *where ;
1189 OffsetRect( &whereLocal , controlBounds.left , controlBounds.top ) ;
1190 SectRect( &controlBounds , &whereLocal, &controlBounds ) ;
1191 }
1192 InvalWindowRect( GetControlOwner( m_controlRef) , &controlBounds ) ;
1193 }
1194 }
1195
1196 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
1197 {
1198 #if TARGET_API_MAC_OSX
1199 if ( from->m_peer->MacGetTopLevelWindow()->MacUsesCompositing() )
1200 {
1201 HIPoint hiPoint ;
1202 hiPoint.x = pt->x ;
1203 hiPoint.y = pt->y ;
1204 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef ) ;
1205 pt->x = (int)hiPoint.x ;
1206 pt->y = (int)hiPoint.y ;
1207 }
1208 else
1209 #endif
1210 {
1211 Rect fromRect ;
1212 Rect toRect ;
1213 GetControlBounds( from->m_controlRef , &fromRect ) ;
1214 GetControlBounds( to->m_controlRef , &toRect ) ;
1215 if ( from->m_isRootControl )
1216 fromRect.left = fromRect.top = 0 ;
1217 if ( to->m_isRootControl )
1218 toRect.left = toRect.top = 0 ;
1219
1220 pt->x = pt->x + fromRect.left - toRect.left ;
1221 pt->y = pt->y + fromRect.top - toRect.top ;
1222 }
1223 }
1224
1225 void wxMacControl::SetRect( Rect *r )
1226 {
1227 #if TARGET_API_MAC_OSX
1228 if ( m_isCompositing )
1229 {
1230 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1231 //CGPoint and CGSize, which have two floats each
1232 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } } ;
1233 HIViewSetFrame ( m_controlRef , &hir ) ;
1234 // eventuall we might have to do a SetVisibility( false , true ) ;
1235 // before and a SetVisibility( true , true ) ; after
1236 }
1237 else
1238 #endif
1239 {
1240 bool vis = IsVisible() ;
1241 if ( vis )
1242 {
1243 Rect former ;
1244 GetControlBounds( m_controlRef , &former ) ;
1245 InvalWindowRect( GetControlOwner( m_controlRef ) , &former ) ;
1246 }
1247
1248 Rect controlBounds = *r ;
1249
1250 // since the rect passed in is always (even in non-compositing) relative
1251 // to the (native) parent, we have to adjust to window relative here
1252 wxMacControl* parent = m_peer->GetParent()->GetPeer() ;
1253 if( parent->m_isRootControl == false )
1254 {
1255 Rect superRect ;
1256 GetControlBounds( parent->m_controlRef , &superRect ) ;
1257 OffsetRect( &controlBounds , superRect.left , superRect.top ) ;
1258 }
1259
1260 SetControlBounds( m_controlRef , &controlBounds ) ;
1261 if ( vis )
1262 {
1263 InvalWindowRect( GetControlOwner( m_controlRef ) , &controlBounds ) ;
1264 }
1265 }
1266 }
1267
1268 void wxMacControl::GetRect( Rect *r )
1269 {
1270 GetControlBounds( m_controlRef , r ) ;
1271 if ( m_isCompositing == false )
1272 {
1273 // correct the case of the root control
1274 if ( m_isRootControl )
1275 {
1276 WindowRef wr = GetControlOwner( m_controlRef ) ;
1277 GetWindowBounds( wr , kWindowContentRgn , r ) ;
1278 r->right -= r->left ;
1279 r->bottom -= r->top ;
1280 r->left = 0 ;
1281 r->top = 0 ;
1282 }
1283 else
1284 {
1285 wxMacControl* parent = m_peer->GetParent()->GetPeer() ;
1286 if( parent->m_isRootControl == false )
1287 {
1288 Rect superRect ;
1289 GetControlBounds( parent->m_controlRef , &superRect ) ;
1290 OffsetRect( r , -superRect.left , -superRect.top ) ;
1291 }
1292 }
1293 }
1294 }
1295
1296 void wxMacControl::GetRectInWindowCoords( Rect *r )
1297 {
1298 UMAGetControlBoundsInWindowCoords( m_controlRef , r ) ;
1299 }
1300
1301 void wxMacControl::GetBestRect( Rect *r )
1302 {
1303 short baselineoffset ;
1304 GetBestControlRect( m_controlRef , r , &baselineoffset ) ;
1305 }
1306
1307 void wxMacControl::SetLabel( const wxString &title )
1308 {
1309 wxFontEncoding encoding;
1310
1311 if ( m_font.Ok() )
1312 encoding = m_font.GetEncoding();
1313 else
1314 encoding = wxFont::GetDefaultEncoding();
1315
1316 UMASetControlTitle( m_controlRef , title , encoding ) ;
1317 }
1318
1319 void wxMacControl::GetFeatures( UInt32 * features )
1320 {
1321 GetControlFeatures( m_controlRef , features ) ;
1322 }
1323
1324 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
1325 {
1326 OSStatus err = GetControlRegion( m_controlRef , partCode , region ) ;
1327 if ( m_isCompositing == false )
1328 {
1329 if ( !m_isRootControl )
1330 {
1331 Rect r ;
1332 GetControlBounds(m_controlRef, &r ) ;
1333 if ( !EmptyRgn( region ) )
1334 OffsetRgn( region , -r.left , -r.top ) ;
1335 }
1336 }
1337 return err ;
1338 }
1339
1340 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
1341 {
1342 #if TARGET_API_MAC_OSX
1343 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
1344 (other != NULL) ? other->m_controlRef : NULL) ;
1345 #else
1346 return 0 ;
1347 #endif
1348 }
1349
1350
1351 #if TARGET_API_MAC_OSX
1352 // SetNeedsDisplay would not invalidate the children
1353 static void InvalidateControlAndChildren( HIViewRef control )
1354 {
1355 HIViewSetNeedsDisplay( control , true ) ;
1356 UInt16 childrenCount = 0 ;
1357 OSStatus err = CountSubControls( control , &childrenCount ) ;
1358 if ( err == errControlIsNotEmbedder )
1359 return ;
1360 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
1361
1362 for ( UInt16 i = childrenCount ; i >=1 ; --i )
1363 {
1364 HIViewRef child ;
1365 err = GetIndexedSubControl( control , i , & child ) ;
1366 if ( err == errControlIsNotEmbedder )
1367 return ;
1368 InvalidateControlAndChildren( child ) ;
1369 }
1370 }
1371 #endif
1372
1373 void wxMacControl::InvalidateWithChildren()
1374 {
1375 #if TARGET_API_MAC_OSX
1376 InvalidateControlAndChildren( m_controlRef ) ;
1377 #endif
1378 }
1379
1380 void wxMacControl::ScrollRect( wxRect *r , int dx , int dy )
1381 {
1382 wxASSERT( r != NULL ) ;
1383 #if TARGET_API_MAC_OSX
1384 if ( m_isCompositing )
1385 {
1386 HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height) ;
1387 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ) ;
1388 }
1389 else
1390 #endif
1391 {
1392 Rect bounds ;
1393 GetControlBounds( m_controlRef , &bounds ) ;
1394 bounds.left += r->x ;
1395 bounds.top += r->y ;
1396 bounds.bottom = bounds.top + r->height ;
1397 bounds.right = bounds.left + r->width ;
1398 wxMacWindowClipper clip( m_peer ) ;
1399 RgnHandle updateRgn = NewRgn() ;
1400 ::ScrollRect( &bounds , dx , dy , updateRgn ) ;
1401 InvalWindowRgn( GetControlOwner( m_controlRef ) , updateRgn ) ;
1402 }
1403 }
1404
1405
1406 // SetNeedsDisplay would not invalidate the children
1407
1408 //
1409 // Databrowser
1410 //
1411
1412 OSStatus wxMacControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1413 {
1414 return SetDataBrowserSelectionFlags( m_controlRef , options ) ;
1415 }
1416
1417 OSStatus wxMacControl::AddListViewColumn( DataBrowserListViewColumnDesc *columnDesc,
1418 DataBrowserTableViewColumnIndex position )
1419 {
1420 return AddDataBrowserListViewColumn( m_controlRef , columnDesc, position ) ;
1421 }
1422
1423 OSStatus wxMacControl::AutoSizeListViewColumns()
1424 {
1425 return AutoSizeDataBrowserListViewColumns(m_controlRef) ;
1426 }
1427
1428 OSStatus wxMacControl::SetHasScrollBars( bool horiz , bool vert )
1429 {
1430 return SetDataBrowserHasScrollBars( m_controlRef , horiz , vert ) ;
1431 }
1432
1433 OSStatus wxMacControl::SetTableViewHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1434 {
1435 return SetDataBrowserTableViewHiliteStyle( m_controlRef , hiliteStyle ) ;
1436 }
1437
1438 OSStatus wxMacControl::SetListViewHeaderBtnHeight(UInt16 height)
1439 {
1440 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef ,height ) ;
1441 }
1442
1443 OSStatus wxMacControl::SetCallbacks(const DataBrowserCallbacks * callbacks)
1444 {
1445 return SetDataBrowserCallbacks( m_controlRef , callbacks ) ;
1446 }
1447
1448 OSStatus wxMacControl::UpdateItems( DataBrowserItemID container, UInt32 numItems,
1449 const DataBrowserItemID* items,
1450 DataBrowserPropertyID preSortProperty,
1451 DataBrowserPropertyID propertyID )
1452 {
1453 return UpdateDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty, propertyID ) ;
1454 }
1455
1456 bool wxMacControl::IsItemSelected( DataBrowserItemID item )
1457 {
1458 return IsDataBrowserItemSelected( m_controlRef , item ) ;
1459 }
1460
1461 OSStatus wxMacControl::AddItems( DataBrowserItemID container, UInt32 numItems,
1462 const DataBrowserItemID* items,
1463 DataBrowserPropertyID preSortProperty )
1464 {
1465 return AddDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty ) ;
1466 }
1467
1468 OSStatus wxMacControl::RemoveItems( DataBrowserItemID container, UInt32 numItems,
1469 const DataBrowserItemID* items,
1470 DataBrowserPropertyID preSortProperty )
1471 {
1472 return RemoveDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty ) ;
1473 }
1474
1475 OSStatus wxMacControl::RevealItem( DataBrowserItemID item,
1476 DataBrowserPropertyID propertyID,
1477 DataBrowserRevealOptions options )
1478 {
1479 return RevealDataBrowserItem( m_controlRef , item , propertyID , options ) ;
1480 }
1481
1482 OSStatus wxMacControl::SetSelectedItems(UInt32 numItems,
1483 const DataBrowserItemID * items,
1484 DataBrowserSetOption operation )
1485 {
1486 return SetDataBrowserSelectedItems( m_controlRef , numItems , items, operation ) ;
1487 }
1488
1489 OSStatus wxMacControl::GetSelectionAnchor( DataBrowserItemID * first, DataBrowserItemID * last )
1490 {
1491 return GetDataBrowserSelectionAnchor( m_controlRef , first , last ) ;
1492 }
1493
1494 //
1495 // Tab Control
1496 //
1497
1498 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
1499 {
1500 return ::SetTabEnabled( m_controlRef , tabNo , enable ) ;
1501 }
1502
1503 //
1504 // Quartz Support
1505 //
1506
1507 #ifdef __WXMAC_OSX__
1508 // snippets from Sketch Sample from Apple :
1509
1510 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
1511 /*
1512 This function locates, opens, and returns the profile reference for the calibrated
1513 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
1514 with the profile reference this function returns.
1515 */
1516 CMProfileRef wxMacOpenGenericProfile(void)
1517 {
1518 static CMProfileRef cachedRGBProfileRef = NULL;
1519
1520 // we only create the profile reference once
1521 if (cachedRGBProfileRef == NULL)
1522 {
1523 CMProfileLocation loc;
1524
1525 loc.locType = cmPathBasedProfile;
1526 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
1527
1528 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
1529 }
1530
1531 if (cachedRGBProfileRef)
1532 {
1533 // clone the profile reference so that the caller has their own reference, not our cached one
1534 CMCloneProfileRef(cachedRGBProfileRef);
1535 }
1536
1537 return cachedRGBProfileRef;
1538 }
1539
1540 /*
1541 Return the generic RGB color space. This is a 'get' function and the caller should
1542 not release the returned value unless the caller retains it first. Usually callers
1543 of this routine will immediately use the returned colorspace with CoreGraphics
1544 so they typically do not need to retain it themselves.
1545
1546 This function creates the generic RGB color space once and hangs onto it so it can
1547 return it whenever this function is called.
1548 */
1549
1550 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
1551 #define kCGColorSpaceGenericRGB CFSTR("kCGColorSpaceGenericRGB")
1552 #endif
1553
1554 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
1555 {
1556 static wxMacCFRefHolder<CGColorSpaceRef> genericRGBColorSpace ;
1557
1558 if (genericRGBColorSpace == NULL)
1559 {
1560 if ( UMAGetSystemVersion() >= 0x1040 )
1561 {
1562 genericRGBColorSpace.Set( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) ) ;
1563 }
1564 else
1565 {
1566 CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
1567
1568 if (genericRGBProfile)
1569 {
1570 genericRGBColorSpace.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile) ) ;
1571 wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") ) ;
1572
1573 // we opened the profile so it is up to us to close it
1574 CMCloseProfile(genericRGBProfile);
1575 }
1576 }
1577 }
1578 return genericRGBColorSpace;
1579 }
1580 #endif
1581
1582 #endif // wxUSE_GUI