]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
renamed RGBColor setter to avoid former overload being an override
[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
16 #ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #endif
19
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 #endif
28
29 #include <ctype.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35
36 #include "MoreFilesX.h"
37
38 #ifndef __DARWIN__
39 #include <Threads.h>
40 #include <Sound.h>
41 #endif
42
43 #if wxUSE_GUI
44 #if TARGET_API_MAC_OSX
45 #include <CoreServices/CoreServices.h>
46 #else
47 #include <DriverServices.h>
48 #include <Multiprocessing.h>
49 #endif
50
51 #ifdef __DARWIN__
52 #include <Carbon/Carbon.h>
53 #else
54 #include <ATSUnicode.h>
55 #include <TextCommon.h>
56 #include <TextEncodingConverter.h>
57 #endif
58 #endif // wxUSE_GUI
59
60 #include "wx/mac/private.h"
61
62 #if defined(__MWERKS__) && wxUSE_UNICODE
63 #if __MWERKS__ < 0x4100 || !defined(__DARWIN__)
64 #include <wtime.h>
65 #endif
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 Boolean IsMetroNubInstalled()
128 {
129 if (!fRunOnce)
130 {
131 long result, value;
132
133 fRunOnce = true;
134 gMetroNubEntry = NULL;
135
136 if (Gestalt(gestaltSystemVersion, &value) == noErr && value < 0x1000)
137 {
138 // look for MetroNub's Gestalt selector
139 if (Gestalt(kMetroNubUserSignature, &result) == noErr)
140 {
141 #if TARGET_API_MAC_CARBON
142 if (gCallUniversalProc_Proc == NULL)
143 {
144 CFragConnectionID connectionID;
145 Ptr mainAddress;
146 Str255 errorString;
147 ProcPtr symbolAddress;
148 OSErr err;
149 CFragSymbolClass symbolClass;
150
151 symbolAddress = NULL;
152 err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
153 &connectionID, &mainAddress, errorString);
154
155 if (err != noErr)
156 {
157 gCallUniversalProc_Proc = NULL;
158 goto end;
159 }
160
161 err = FindSymbol(connectionID, "\pCallUniversalProc",
162 (Ptr *) &gCallUniversalProc_Proc, &symbolClass);
163
164 if (err != noErr)
165 {
166 gCallUniversalProc_Proc = NULL;
167 goto end;
168 }
169 }
170 #endif
171
172 {
173 MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
174
175 // make sure the version of the API is compatible
176 if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
177 kMetroNubUserAPIVersion <= block->apiHiVersion)
178 {
179 // success!
180 gMetroNubEntry = block;
181 }
182 }
183 }
184 }
185 }
186
187 end:
188
189 #if TARGET_API_MAC_CARBON
190 return (gMetroNubEntry != NULL && gCallUniversalProc_Proc != NULL);
191 #else
192 return (gMetroNubEntry != NULL);
193 #endif
194 }
195
196 Boolean IsMWDebuggerRunning()
197 {
198 if (IsMetroNubInstalled())
199 return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
200
201 return false;
202 }
203
204 Boolean AmIBeingMWDebugged()
205 {
206 if (IsMetroNubInstalled())
207 return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
208
209 return false;
210 }
211
212 extern bool WXDLLEXPORT wxIsDebuggerRunning()
213 {
214 return IsMWDebuggerRunning() && AmIBeingMWDebugged();
215 }
216
217 #else
218
219 extern bool WXDLLEXPORT wxIsDebuggerRunning()
220 {
221 return false;
222 }
223
224 #endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
225
226
227 #ifndef __DARWIN__
228 // defined in unix/utilsunx.cpp for Mac OS X
229
230 // get full hostname (with domain name if possible)
231 bool wxGetFullHostName(wxChar *buf, int maxSize)
232 {
233 return wxGetHostName(buf, maxSize);
234 }
235
236 // Get user ID e.g. jacs
237 bool wxGetUserId(wxChar *buf, int maxSize)
238 {
239 return wxGetUserName( buf , maxSize );
240 }
241
242 const wxChar* wxGetHomeDir(wxString *pstr)
243 {
244 *pstr = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder );
245 return pstr->c_str();
246 }
247
248 // Get hostname only (without domain name)
249 bool wxGetHostName(wxChar *buf, int maxSize)
250 {
251 // Gets Chooser name of user by examining a System resource.
252 buf[0] = 0;
253
254 const short kComputerNameID = -16413;
255
256 short oldResFile = CurResFile();
257 UseResFile(0);
258 StringHandle chooserName = (StringHandle)::GetString(kComputerNameID);
259 UseResFile(oldResFile);
260
261 if (chooserName && *chooserName)
262 {
263 HLock( (Handle) chooserName );
264 wxString name = wxMacMakeStringFromPascal( *chooserName );
265 HUnlock( (Handle) chooserName );
266 ReleaseResource( (Handle) chooserName );
267 wxStrncpy( buf , name , maxSize - 1 );
268 }
269
270 return true;
271 }
272
273 // Get user name e.g. Stefan Csomor
274 bool wxGetUserName(wxChar *buf, int maxSize)
275 {
276 // Gets Chooser name of user by examining a System resource.
277 buf[0] = 0;
278
279 const short kChooserNameID = -16096;
280
281 short oldResFile = CurResFile();
282 UseResFile(0);
283 StringHandle chooserName = (StringHandle)::GetString(kChooserNameID);
284 UseResFile(oldResFile);
285
286 if (chooserName && *chooserName)
287 {
288 HLock( (Handle) chooserName );
289 wxString name = wxMacMakeStringFromPascal( *chooserName );
290 HUnlock( (Handle) chooserName );
291 ReleaseResource( (Handle) chooserName );
292 wxStrncpy( buf , name , maxSize - 1 );
293 }
294
295 return true;
296 }
297
298 int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
299 {
300 // TODO
301 return 0;
302 }
303
304 WXDLLEXPORT bool wxGetEnv(const wxString& var, wxString *value)
305 {
306 // TODO : under classic there is no environement support, under X yes
307 return false;
308 }
309
310 // set the env var name to the given value, return true on success
311 WXDLLEXPORT bool wxSetEnv(const wxString& var, const wxChar *value)
312 {
313 // TODO : under classic there is no environement support, under X yes
314 return false;
315 }
316
317 // Execute a program in an Interactive Shell
318 bool wxShell(const wxString& command)
319 {
320 // TODO
321 return false;
322 }
323
324 // Shutdown or reboot the PC
325 bool wxShutdown(wxShutdownFlags wFlags)
326 {
327 // TODO
328 return false;
329 }
330
331 wxPowerType wxGetPowerType()
332 {
333 // TODO
334 return wxPOWER_UNKNOWN;
335 }
336
337 wxBatteryState wxGetBatteryState()
338 {
339 // TODO
340 return wxBATTERY_UNKNOWN_STATE;
341 }
342
343 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
344 wxMemorySize wxGetFreeMemory()
345 {
346 return (wxMemorySize)FreeMem();
347 }
348
349 #ifndef __DARWIN__
350
351 void wxMicroSleep(unsigned long microseconds)
352 {
353 AbsoluteTime wakeup = AddDurationToAbsolute( microseconds * durationMicrosecond , UpTime());
354 MPDelayUntil( & wakeup);
355 }
356
357 void wxMilliSleep(unsigned long milliseconds)
358 {
359 AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime());
360 MPDelayUntil( & wakeup);
361 }
362
363 void wxSleep(int nSecs)
364 {
365 wxMilliSleep(1000*nSecs);
366 }
367
368 #endif
369
370 // Consume all events until no more left
371 void wxFlushEvents()
372 {
373 }
374
375 #endif // !__DARWIN__
376
377 // Emit a beeeeeep
378 void wxBell()
379 {
380 SysBeep(30);
381 }
382
383 wxToolkitInfo& wxConsoleAppTraits::GetToolkitInfo()
384 {
385 static wxToolkitInfo info;
386
387 info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
388 info.name = _T("wxBase");
389
390 return info;
391 }
392
393 #endif // wxUSE_BASE
394
395 #if wxUSE_GUI
396
397 wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
398 {
399 static wxToolkitInfo info;
400
401 info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
402 info.shortName = _T("mac");
403 info.name = _T("wxMac");
404
405 #ifdef __WXUNIVERSAL__
406 info.shortName << _T("univ");
407 info.name << _T("/wxUniversal");
408 #endif
409
410 return info;
411 }
412
413 // Reading and writing resources (eg WIN.INI, .Xdefaults)
414 #if wxUSE_RESOURCES
415 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
416 {
417 // TODO
418 return false;
419 }
420
421 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
422 {
423 wxString buf;
424 buf.Printf(wxT("%.4f"), value);
425
426 return wxWriteResource(section, entry, buf, file);
427 }
428
429 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
430 {
431 wxString buf;
432 buf.Printf(wxT("%ld"), value);
433
434 return wxWriteResource(section, entry, buf, file);
435 }
436
437 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
438 {
439 wxString buf;
440 buf.Printf(wxT("%d"), value);
441
442 return wxWriteResource(section, entry, buf, file);
443 }
444
445 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
446 {
447 // TODO
448 return false;
449 }
450
451 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
452 {
453 char *s = NULL;
454 bool succ = wxGetResource(section, entry, (char **)&s, file);
455 if (succ)
456 {
457 *value = (float)strtod(s, NULL);
458 delete[] s;
459 }
460
461 return succ;
462 }
463
464 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
465 {
466 char *s = NULL;
467 bool succ = wxGetResource(section, entry, (char **)&s, file);
468 if (succ)
469 {
470 *value = strtol(s, NULL, 10);
471 delete[] s;
472 }
473
474 return succ;
475 }
476
477 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
478 {
479 char *s = NULL;
480 bool succ = wxGetResource(section, entry, (char **)&s, file);
481 if (succ)
482 {
483 *value = (int)strtol(s, NULL, 10);
484 delete[] s;
485 }
486
487 return succ;
488 }
489 #endif // wxUSE_RESOURCES
490
491 int gs_wxBusyCursorCount = 0;
492 extern wxCursor gMacCurrentCursor;
493 wxCursor gMacStoredActiveCursor;
494
495 // Set the cursor to the busy cursor for all windows
496 void wxBeginBusyCursor(const wxCursor *cursor)
497 {
498 if (gs_wxBusyCursorCount++ == 0)
499 {
500 gMacStoredActiveCursor = gMacCurrentCursor;
501 cursor->MacInstall();
502 }
503 //else: nothing to do, already set
504 }
505
506 // Restore cursor to normal
507 void wxEndBusyCursor()
508 {
509 wxCHECK_RET( gs_wxBusyCursorCount > 0,
510 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
511
512 if (--gs_wxBusyCursorCount == 0)
513 {
514 gMacStoredActiveCursor.MacInstall();
515 gMacStoredActiveCursor = wxNullCursor;
516 }
517 }
518
519 // true if we're between the above two calls
520 bool wxIsBusy()
521 {
522 return (gs_wxBusyCursorCount > 0);
523 }
524
525 #endif // wxUSE_GUI
526
527 #if wxUSE_BASE
528
529 wxString wxMacFindFolderNoSeparator( short vol,
530 OSType folderType,
531 Boolean createFolder)
532 {
533 FSRef fsRef;
534 wxString strDir;
535
536 if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr)
537 {
538 strDir = wxMacFSRefToPath( &fsRef );
539 }
540
541 return strDir;
542 }
543
544 wxString wxMacFindFolder( short vol,
545 OSType folderType,
546 Boolean createFolder)
547 {
548 return wxMacFindFolderNoSeparator(vol, folderType, createFolder) + wxFILE_SEP_PATH;
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 != NULL)
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 void wxDisplaySizeMM(int *width, int *height)
608 {
609 wxDisplaySize(width, height);
610 // on mac 72 is fixed (at least now;-)
611 float cvPt2Mm = 25.4 / 72;
612
613 if (width != NULL)
614 *width = int( *width * cvPt2Mm );
615
616 if (height != NULL)
617 *height = int( *height * cvPt2Mm );
618 }
619
620 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
621 {
622 Rect r;
623
624 GetAvailableWindowPositioningBounds( GetMainDevice() , &r );
625 if ( x )
626 *x = r.left;
627 if ( y )
628 *y = r.top;
629 if ( width )
630 *width = r.right - r.left;
631 if ( height )
632 *height = r.bottom - r.top;
633 }
634
635 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
636 {
637 return wxGenericFindWindowAtPoint(pt);
638 }
639
640 #endif // wxUSE_GUI
641
642 #if wxUSE_BASE
643
644 wxString wxGetOsDescription()
645 {
646 #ifdef WXWIN_OS_DESCRIPTION
647 // use configure generated description if available
648 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
649 #else
650 return wxT("MacOS"); //TODO:define further
651 #endif
652 }
653
654 #ifndef __DARWIN__
655 wxChar *wxGetUserHome (const wxString& user)
656 {
657 // TODO
658 return NULL;
659 }
660
661 bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree)
662 {
663 if ( path.empty() )
664 return false;
665
666 wxString p = path;
667 if (p[0u] == ':' )
668 p = wxGetCwd() + p;
669
670 int pos = p.Find(':');
671 if ( pos != wxNOT_FOUND )
672 p = p.Mid(1,pos);
673
674 p = p + wxT(":");
675
676 OSErr err = noErr;
677
678 FSRef fsRef;
679 err = wxMacPathToFSRef( p , &fsRef );
680 if ( noErr == err )
681 {
682 FSVolumeRefNum vRefNum;
683 err = FSGetVRefNum( &fsRef , &vRefNum );
684 if ( noErr == err )
685 {
686 UInt64 freeBytes , totalBytes;
687 err = FSGetVInfo( vRefNum , NULL , &freeBytes , &totalBytes );
688 if ( noErr == err )
689 {
690 if ( pTotal )
691 *pTotal = wxDiskspaceSize_t( totalBytes );
692 if ( pFree )
693 *pFree = wxDiskspaceSize_t( freeBytes );
694 }
695 }
696 }
697
698 return err == noErr;
699 }
700 #endif // !__DARWIN__
701
702 //---------------------------------------------------------------------------
703 // wxMac Specific utility functions
704 //---------------------------------------------------------------------------
705
706 void wxMacStringToPascal( const wxString&from , StringPtr to )
707 {
708 wxCharBuffer buf = from.mb_str( wxConvLocal );
709 int len = strlen(buf);
710
711 if ( len > 255 )
712 len = 255;
713 to[0] = len;
714 memcpy( (char*) &to[1] , buf , len );
715 }
716
717 wxString wxMacMakeStringFromPascal( ConstStringPtr from )
718 {
719 return wxString( (char*) &from[1] , wxConvLocal , from[0] );
720 }
721
722 // ----------------------------------------------------------------------------
723 // Common Event Support
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
740 #if 0
741 // lead sometimes to race conditions, although all calls used should be thread safe ...
742 static wxMacCarbonEvent s_wakeupEvent;
743 if ( !s_wakeupEvent.IsValid() )
744 {
745 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
746 kEventAttributeNone );
747 }
748 if ( err == noErr )
749 {
750
751 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
752 return;
753 s_wakeupEvent.SetCurrentTime();
754 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
755 kEventPriorityHigh );
756 }
757 #else
758 wxMacCarbonEvent wakeupEvent;
759 wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
760 kEventAttributeNone );
761 err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
762 kEventPriorityHigh );
763 #endif
764 #else
765 PostEvent( nullEvent , 0 );
766 #endif
767 }
768 else
769 {
770 WakeUpProcess( &gAppProcess );
771 }
772 }
773
774 #endif // wxUSE_BASE
775
776 #if wxUSE_GUI
777
778 // ----------------------------------------------------------------------------
779 // Native Struct Conversions
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 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
815 {
816 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData );
817 }
818
819 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
820 {
821 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData );
822 }
823
824 // ----------------------------------------------------------------------------
825 // Control Access Support
826 // ----------------------------------------------------------------------------
827
828 wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl )
829 {
830 Init();
831 m_peer = peer;
832 m_isRootControl = isRootControl;
833 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing();
834 }
835
836 wxMacControl::wxMacControl( wxWindow* peer , ControlRef control )
837 {
838 Init();
839 m_peer = peer;
840 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing();
841 m_controlRef = control;
842 }
843
844 wxMacControl::wxMacControl( wxWindow* peer , WXWidget control )
845 {
846 Init();
847 m_peer = peer;
848 m_isCompositing = peer->MacGetTopLevelWindow()->MacUsesCompositing();
849 m_controlRef = (ControlRef) control;
850 }
851
852 wxMacControl::~wxMacControl()
853 {
854 }
855
856 void wxMacControl::Init()
857 {
858 m_peer = NULL;
859 m_controlRef = NULL;
860 m_needsFocusRect = false;
861 m_isCompositing = false;
862 m_isRootControl = false;
863 }
864
865 void wxMacControl::Dispose()
866 {
867 ::DisposeControl( m_controlRef );
868 m_controlRef = NULL;
869 }
870
871 void wxMacControl::SetReference( SInt32 data )
872 {
873 SetControlReference( m_controlRef , data );
874 }
875
876 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
877 {
878 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize );
879 }
880
881 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
882 {
883 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize );
884 }
885
886 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
887 {
888 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData );
889 }
890
891 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
892 {
893 #if TARGET_API_MAC_OSX
894 return SendEventToEventTargetWithOptions( event,
895 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
896 #else
897 #pragma unused(inOptions)
898 return SendEventToEventTarget(event,GetControlEventTarget( m_controlRef ) );
899 #endif
900 }
901
902 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
903 {
904 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
905
906 event.SetParameter<HICommand>(kEventParamDirectObject,command);
907
908 return SendEvent( event , inOptions );
909 }
910
911 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
912 {
913 HICommand command;
914
915 memset( &command, 0 , sizeof(command) );
916 command.commandID = commandID;
917 return SendHICommand( command , inOptions );
918 }
919
920 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
921 {
922 unsigned long finalTicks;
923
924 HiliteControl( m_controlRef , part );
925 Delay( ticks , &finalTicks );
926 HiliteControl( m_controlRef , kControlNoPart );
927 }
928
929 SInt32 wxMacControl::GetValue() const
930 {
931 return ::GetControl32BitValue( m_controlRef );
932 }
933
934 SInt32 wxMacControl::GetMaximum() const
935 {
936 return ::GetControl32BitMaximum( m_controlRef );
937 }
938
939 SInt32 wxMacControl::GetMinimum() const
940 {
941 return ::GetControl32BitMinimum( m_controlRef );
942 }
943
944 void wxMacControl::SetValue( SInt32 v )
945 {
946 ::SetControl32BitValue( m_controlRef , v );
947 }
948
949 void wxMacControl::SetMinimum( SInt32 v )
950 {
951 ::SetControl32BitMinimum( m_controlRef , v );
952 }
953
954 void wxMacControl::SetMaximum( SInt32 v )
955 {
956 ::SetControl32BitMaximum( m_controlRef , v );
957 }
958
959 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
960 {
961 ::SetControl32BitMinimum( m_controlRef , minimum );
962 ::SetControl32BitMaximum( m_controlRef , maximum );
963 ::SetControl32BitValue( m_controlRef , value );
964 }
965
966 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
967 {
968 return SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, focusPart );
969 }
970
971 bool wxMacControl::HasFocus() const
972 {
973 ControlRef control;
974 GetKeyboardFocus( GetUserFocusWindow() , &control );
975 return control == m_controlRef;
976 }
977
978 void wxMacControl::SetNeedsFocusRect( bool needs )
979 {
980 m_needsFocusRect = needs;
981 }
982
983 bool wxMacControl::NeedsFocusRect() const
984 {
985 return m_needsFocusRect;
986 }
987
988 void wxMacControl::VisibilityChanged(bool shown)
989 {
990 }
991
992 void wxMacControl::SuperChangedPosition()
993 {
994 }
995
996 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
997 {
998 m_font = font;
999 ControlFontStyleRec fontStyle;
1000 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
1001 {
1002 switch ( font.MacGetThemeFontID() )
1003 {
1004 case kThemeSmallSystemFont :
1005 fontStyle.font = kControlFontSmallSystemFont;
1006 break;
1007
1008 case 109 : // mini font
1009 fontStyle.font = -5;
1010 break;
1011
1012 case kThemeSystemFont :
1013 fontStyle.font = kControlFontBigSystemFont;
1014 break;
1015
1016 default :
1017 fontStyle.font = kControlFontBigSystemFont;
1018 break;
1019 }
1020
1021 fontStyle.flags = kControlUseFontMask;
1022 }
1023 else
1024 {
1025 fontStyle.font = font.MacGetFontNum();
1026 fontStyle.style = font.MacGetFontStyle();
1027 fontStyle.size = font.MacGetFontSize();
1028 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask;
1029 }
1030
1031 fontStyle.just = teJustLeft;
1032 fontStyle.flags |= kControlUseJustMask;
1033 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
1034 fontStyle.just = teJustCenter;
1035 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
1036 fontStyle.just = teJustRight;
1037
1038
1039 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1040 // won't get grayed out by the system anymore
1041
1042 if ( foreground != *wxBLACK )
1043 {
1044 fontStyle.foreColor = MAC_WXCOLORREF( foreground.GetPixel() );
1045 fontStyle.flags |= kControlUseForeColorMask;
1046 }
1047
1048 ::SetControlFontStyle( m_controlRef , &fontStyle );
1049 }
1050
1051 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
1052 {
1053 // TODO
1054 // setting up a color proc is not recommended anymore
1055 }
1056
1057 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
1058 {
1059 ::SetControl32BitMinimum( m_controlRef , minimum );
1060 ::SetControl32BitMaximum( m_controlRef , maximum );
1061 }
1062
1063 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
1064 {
1065 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers );
1066 }
1067
1068 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
1069 {
1070 SetControlAction( m_controlRef , actionProc );
1071 }
1072
1073 void wxMacControl::SetViewSize( SInt32 viewSize )
1074 {
1075 SetControlViewSize(m_controlRef , viewSize );
1076 }
1077
1078 SInt32 wxMacControl::GetViewSize() const
1079 {
1080 return GetControlViewSize( m_controlRef );
1081 }
1082
1083 bool wxMacControl::IsVisible() const
1084 {
1085 return IsControlVisible( m_controlRef );
1086 }
1087
1088 void wxMacControl::SetVisibility( bool visible , bool redraw )
1089 {
1090 SetControlVisibility( m_controlRef , visible , redraw );
1091 }
1092
1093 bool wxMacControl::IsEnabled() const
1094 {
1095 #if TARGET_API_MAC_OSX
1096 return IsControlEnabled( m_controlRef );
1097 #else
1098 return IsControlActive( m_controlRef );
1099 #endif
1100 }
1101
1102 bool wxMacControl::IsActive() const
1103 {
1104 return IsControlActive( m_controlRef );
1105 }
1106
1107 void wxMacControl::Enable( bool enable )
1108 {
1109 #if TARGET_API_MAC_OSX
1110 if ( enable )
1111 EnableControl( m_controlRef );
1112 else
1113 DisableControl( m_controlRef );
1114 #else
1115 if ( enable )
1116 ActivateControl( m_controlRef );
1117 else
1118 DeactivateControl( m_controlRef );
1119 #endif
1120 }
1121
1122 void wxMacControl::SetDrawingEnabled( bool enable )
1123 {
1124 #if TARGET_API_MAC_OSX
1125 HIViewSetDrawingEnabled( m_controlRef , enable );
1126 #endif
1127 }
1128
1129 #if TARGET_API_MAC_OSX
1130 bool wxMacControl::GetNeedsDisplay() const
1131 {
1132 #if TARGET_API_MAC_OSX
1133 if ( m_isCompositing )
1134 {
1135 return HIViewGetNeedsDisplay( m_controlRef );
1136 }
1137 else
1138 #endif
1139 {
1140 if ( !IsVisible() )
1141 return false;
1142
1143 Rect controlBounds;
1144 GetControlBounds( m_controlRef, &controlBounds );
1145 RgnHandle rgn = NewRgn();
1146 GetWindowRegion ( GetControlOwner( m_controlRef ) , kWindowUpdateRgn , rgn );
1147 Boolean intersect = RectInRgn ( &controlBounds , rgn );
1148 DisposeRgn( rgn );
1149
1150 return intersect;
1151 }
1152 }
1153 #endif
1154
1155 void wxMacControl::SetNeedsDisplay( RgnHandle where )
1156 {
1157 if ( !IsVisible() )
1158 return;
1159
1160 #if TARGET_API_MAC_OSX
1161 if ( m_isCompositing )
1162 {
1163 HIViewSetNeedsDisplayInRegion( m_controlRef , where , true );
1164 }
1165 else
1166 #endif
1167 {
1168 Rect controlBounds;
1169 GetControlBounds( m_controlRef, &controlBounds );
1170 RgnHandle update = NewRgn();
1171 CopyRgn( where , update );
1172 OffsetRgn( update , controlBounds.left , controlBounds.top );
1173 InvalWindowRgn( GetControlOwner( m_controlRef) , update );
1174 }
1175 }
1176
1177 void wxMacControl::SetNeedsDisplay( Rect* where )
1178 {
1179 if ( !IsVisible() )
1180 return;
1181
1182 #if TARGET_API_MAC_OSX
1183 if ( m_isCompositing )
1184 {
1185 if ( where != NULL )
1186 {
1187 RgnHandle update = NewRgn();
1188 RectRgn( update , where );
1189 HIViewSetNeedsDisplayInRegion( m_controlRef , update , true );
1190 DisposeRgn( update );
1191 }
1192 else
1193 HIViewSetNeedsDisplay( m_controlRef , true );
1194 }
1195 else
1196 #endif
1197 {
1198 Rect controlBounds;
1199
1200 GetControlBounds( m_controlRef, &controlBounds );
1201 if ( where )
1202 {
1203 Rect whereLocal = *where;
1204 OffsetRect( &whereLocal , controlBounds.left , controlBounds.top );
1205 SectRect( &controlBounds , &whereLocal, &controlBounds );
1206 }
1207
1208 InvalWindowRect( GetControlOwner( m_controlRef) , &controlBounds );
1209 }
1210 }
1211
1212 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
1213 {
1214 #if TARGET_API_MAC_OSX
1215 if ( from->m_peer->MacGetTopLevelWindow()->MacUsesCompositing() )
1216 {
1217 HIPoint hiPoint;
1218
1219 hiPoint.x = pt->x;
1220 hiPoint.y = pt->y;
1221 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef );
1222 pt->x = (int)hiPoint.x;
1223 pt->y = (int)hiPoint.y;
1224 }
1225 else
1226 #endif
1227 {
1228 Rect fromRect, toRect;
1229
1230 GetControlBounds( from->m_controlRef , &fromRect );
1231 GetControlBounds( to->m_controlRef , &toRect );
1232 if ( from->m_isRootControl )
1233 fromRect.left = fromRect.top = 0;
1234 if ( to->m_isRootControl )
1235 toRect.left = toRect.top = 0;
1236
1237 pt->x = pt->x + fromRect.left - toRect.left;
1238 pt->y = pt->y + fromRect.top - toRect.top;
1239 }
1240 }
1241
1242 void wxMacControl::SetRect( Rect *r )
1243 {
1244 #if TARGET_API_MAC_OSX
1245 if ( m_isCompositing )
1246 {
1247 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1248 //CGPoint and CGSize, which have two floats each
1249 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } };
1250 HIViewSetFrame ( m_controlRef , &hir );
1251 // eventuall we might have to do a SetVisibility( false , true );
1252 // before and a SetVisibility( true , true ); after
1253 }
1254 else
1255 #endif
1256 {
1257 bool vis = IsVisible();
1258 if ( vis )
1259 {
1260 Rect former;
1261 GetControlBounds( m_controlRef , &former );
1262 InvalWindowRect( GetControlOwner( m_controlRef ) , &former );
1263 }
1264
1265 Rect controlBounds = *r;
1266
1267 // since the rect passed in is always (even in non-compositing) relative
1268 // to the (native) parent, we have to adjust to window relative here
1269 wxMacControl* parent = m_peer->GetParent()->GetPeer();
1270 if ( !parent->m_isRootControl )
1271 {
1272 Rect superRect;
1273 GetControlBounds( parent->m_controlRef , &superRect );
1274 OffsetRect( &controlBounds , superRect.left , superRect.top );
1275 }
1276
1277 SetControlBounds( m_controlRef , &controlBounds );
1278 if ( vis )
1279 InvalWindowRect( GetControlOwner( m_controlRef ) , &controlBounds );
1280 }
1281 }
1282
1283 void wxMacControl::GetRect( Rect *r )
1284 {
1285 GetControlBounds( m_controlRef , r );
1286 if ( !m_isCompositing )
1287 {
1288 // correct the case of the root control
1289 if ( m_isRootControl )
1290 {
1291 WindowRef wr = GetControlOwner( m_controlRef );
1292 GetWindowBounds( wr , kWindowContentRgn , r );
1293 r->right -= r->left;
1294 r->bottom -= r->top;
1295 r->left = 0;
1296 r->top = 0;
1297 }
1298 else
1299 {
1300 wxMacControl* parent = m_peer->GetParent()->GetPeer();
1301 if ( !parent->m_isRootControl )
1302 {
1303 Rect superRect;
1304 GetControlBounds( parent->m_controlRef , &superRect );
1305 OffsetRect( r , -superRect.left , -superRect.top );
1306 }
1307 }
1308 }
1309 }
1310
1311 void wxMacControl::GetRectInWindowCoords( Rect *r )
1312 {
1313 UMAGetControlBoundsInWindowCoords( m_controlRef , r );
1314 }
1315
1316 void wxMacControl::GetBestRect( Rect *r )
1317 {
1318 short baselineoffset;
1319
1320 GetBestControlRect( m_controlRef , r , &baselineoffset );
1321 }
1322
1323 void wxMacControl::SetLabel( const wxString &title )
1324 {
1325 wxFontEncoding encoding;
1326
1327 if ( m_font.Ok() )
1328 encoding = m_font.GetEncoding();
1329 else
1330 encoding = wxFont::GetDefaultEncoding();
1331
1332 UMASetControlTitle( m_controlRef , title , encoding );
1333 }
1334
1335 void wxMacControl::GetFeatures( UInt32 * features )
1336 {
1337 GetControlFeatures( m_controlRef , features );
1338 }
1339
1340 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
1341 {
1342 OSStatus err = GetControlRegion( m_controlRef , partCode , region );
1343 if ( !m_isCompositing )
1344 {
1345 if ( !m_isRootControl )
1346 {
1347 Rect r;
1348
1349 GetControlBounds(m_controlRef, &r );
1350 if ( !EmptyRgn( region ) )
1351 OffsetRgn( region , -r.left , -r.top );
1352 }
1353 }
1354
1355 return err;
1356 }
1357
1358 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
1359 {
1360 #if TARGET_API_MAC_OSX
1361 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
1362 (other != NULL) ? other->m_controlRef : NULL);
1363 #else
1364 return 0;
1365 #endif
1366 }
1367
1368 #if TARGET_API_MAC_OSX
1369 // SetNeedsDisplay would not invalidate the children
1370 static void InvalidateControlAndChildren( HIViewRef control )
1371 {
1372 HIViewSetNeedsDisplay( control , true );
1373 UInt16 childrenCount = 0;
1374 OSStatus err = CountSubControls( control , &childrenCount );
1375 if ( err == errControlIsNotEmbedder )
1376 return;
1377
1378 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") );
1379
1380 for ( UInt16 i = childrenCount; i >=1; --i )
1381 {
1382 HIViewRef child;
1383
1384 err = GetIndexedSubControl( control , i , & child );
1385 if ( err == errControlIsNotEmbedder )
1386 return;
1387
1388 InvalidateControlAndChildren( child );
1389 }
1390 }
1391 #endif
1392
1393 void wxMacControl::InvalidateWithChildren()
1394 {
1395 #if TARGET_API_MAC_OSX
1396 InvalidateControlAndChildren( m_controlRef );
1397 #endif
1398 }
1399
1400 void wxMacControl::ScrollRect( wxRect *r , int dx , int dy )
1401 {
1402 wxASSERT( r != NULL );
1403
1404 #if TARGET_API_MAC_OSX
1405 if ( m_isCompositing )
1406 {
1407 HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height);
1408 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy );
1409 }
1410 else
1411 #endif
1412 {
1413 Rect bounds;
1414
1415 GetControlBounds( m_controlRef , &bounds );
1416 bounds.left += r->x;
1417 bounds.top += r->y;
1418 bounds.bottom = bounds.top + r->height;
1419 bounds.right = bounds.left + r->width;
1420 wxMacWindowClipper clip( m_peer );
1421 RgnHandle updateRgn = NewRgn();
1422 ::ScrollRect( &bounds , dx , dy , updateRgn );
1423 InvalWindowRgn( GetControlOwner( m_controlRef ) , updateRgn );
1424 DisposeRgn( updateRgn );
1425 }
1426 }
1427
1428 OSType wxMacCreator = 'WXMC';
1429 OSType wxMacControlProperty = 'MCCT';
1430
1431 void wxMacControl::SetReferenceInNativeControl()
1432 {
1433 void * data = this;
1434 verify_noerr( SetControlProperty ( m_controlRef ,
1435 wxMacCreator,wxMacControlProperty, sizeof(data), &data ) );
1436 }
1437
1438 wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control)
1439 {
1440 wxMacControl* ctl = NULL;
1441 UInt32 actualSize;
1442 if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) ,
1443 &actualSize , &ctl ) == noErr )
1444 {
1445 return ctl;
1446 }
1447 return NULL;
1448 }
1449
1450 // ============================================================================
1451 // DataBrowser Wrapper
1452 // ============================================================================
1453 //
1454 // basing on DataBrowserItemIDs
1455 //
1456
1457 pascal void wxMacDataBrowserControl::DataBrowserItemNotificationProc(
1458 ControlRef browser,
1459 DataBrowserItemID itemID,
1460 DataBrowserItemNotification message,
1461 DataBrowserItemDataRef itemData )
1462 {
1463 wxMacDataBrowserControl* ctl = dynamic_cast<wxMacDataBrowserControl*>( wxMacControl::GetReferenceFromNativeControl( browser ) );
1464 if ( ctl != 0 )
1465 {
1466 ctl->ItemNotification(itemID, message, itemData);
1467 }
1468 }
1469
1470 pascal OSStatus wxMacDataBrowserControl::DataBrowserGetSetItemDataProc(
1471 ControlRef browser,
1472 DataBrowserItemID itemID,
1473 DataBrowserPropertyID property,
1474 DataBrowserItemDataRef itemData,
1475 Boolean changeValue )
1476 {
1477 OSStatus err = errDataBrowserPropertyNotSupported;
1478
1479 wxMacDataBrowserControl* ctl = dynamic_cast<wxMacDataBrowserControl*>( wxMacControl::GetReferenceFromNativeControl( browser ) );
1480 if ( ctl != 0 )
1481 {
1482 err = ctl->GetSetItemData(itemID, property, itemData, changeValue);
1483 }
1484 return err;
1485 }
1486
1487 pascal Boolean wxMacDataBrowserControl::DataBrowserCompareProc(
1488 ControlRef browser,
1489 DataBrowserItemID itemOneID,
1490 DataBrowserItemID itemTwoID,
1491 DataBrowserPropertyID sortProperty)
1492 {
1493 wxMacDataBrowserControl* ctl = dynamic_cast<wxMacDataBrowserControl*>( wxMacControl::GetReferenceFromNativeControl( browser ) );
1494 if ( ctl != 0 )
1495 {
1496 return ctl->CompareItems(itemOneID, itemTwoID, sortProperty);
1497 }
1498 return false;
1499 }
1500
1501 DataBrowserItemDataUPP gDataBrowserItemDataUPP = NULL;
1502 DataBrowserItemNotificationUPP gDataBrowserItemNotificationUPP = NULL;
1503 DataBrowserItemCompareUPP gDataBrowserItemCompareUPP = NULL;
1504
1505 wxMacDataBrowserControl::wxMacDataBrowserControl( wxWindow* peer, const wxPoint& pos, const wxSize& size, long style) : wxMacControl( peer )
1506 {
1507 Rect bounds = wxMacGetBoundsForControl( peer, pos, size );
1508 OSStatus err = ::CreateDataBrowserControl(
1509 MAC_WXHWND(peer->MacGetTopLevelWindowRef()),
1510 &bounds, kDataBrowserListView, &m_controlRef );
1511 SetReferenceInNativeControl();
1512 verify_noerr( err );
1513 if ( gDataBrowserItemCompareUPP == NULL )
1514 gDataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(DataBrowserCompareProc);
1515 if ( gDataBrowserItemDataUPP == NULL )
1516 gDataBrowserItemDataUPP = NewDataBrowserItemDataUPP(DataBrowserGetSetItemDataProc);
1517 if ( gDataBrowserItemNotificationUPP == NULL )
1518 {
1519 gDataBrowserItemNotificationUPP =
1520 #if TARGET_API_MAC_OSX
1521 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc);
1522 #else
1523 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc);
1524 #endif
1525 }
1526
1527 DataBrowserCallbacks callbacks;
1528 InitializeDataBrowserCallbacks( &callbacks, kDataBrowserLatestCallbacks );
1529
1530 callbacks.u.v1.itemDataCallback = gDataBrowserItemDataUPP;
1531 callbacks.u.v1.itemCompareCallback = gDataBrowserItemCompareUPP;
1532 callbacks.u.v1.itemNotificationCallback = gDataBrowserItemNotificationUPP;
1533 SetCallbacks( &callbacks );
1534
1535 }
1536
1537 OSStatus wxMacDataBrowserControl::GetItemCount( DataBrowserItemID container,
1538 Boolean recurse,
1539 DataBrowserItemState state,
1540 UInt32 *numItems) const
1541 {
1542 return GetDataBrowserItemCount( m_controlRef, container, recurse, state, numItems );
1543 }
1544
1545 OSStatus wxMacDataBrowserControl::GetItems( DataBrowserItemID container,
1546 Boolean recurse,
1547 DataBrowserItemState state,
1548 Handle items) const
1549 {
1550 return GetDataBrowserItems( m_controlRef, container, recurse, state, items );
1551 }
1552
1553 OSStatus wxMacDataBrowserControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1554 {
1555 return SetDataBrowserSelectionFlags( m_controlRef, options );
1556 }
1557
1558 OSStatus wxMacDataBrowserControl::AddColumn( DataBrowserListViewColumnDesc *columnDesc,
1559 DataBrowserTableViewColumnIndex position )
1560 {
1561 return AddDataBrowserListViewColumn( m_controlRef, columnDesc, position );
1562 }
1563
1564 OSStatus wxMacDataBrowserControl::AutoSizeColumns()
1565 {
1566 return AutoSizeDataBrowserListViewColumns(m_controlRef);
1567 }
1568
1569 OSStatus wxMacDataBrowserControl::SetHasScrollBars( bool horiz, bool vert )
1570 {
1571 return SetDataBrowserHasScrollBars( m_controlRef, horiz, vert );
1572 }
1573
1574 OSStatus wxMacDataBrowserControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1575 {
1576 return SetDataBrowserTableViewHiliteStyle( m_controlRef, hiliteStyle );
1577 }
1578
1579 OSStatus wxMacDataBrowserControl::SetHeaderButtonHeight(UInt16 height)
1580 {
1581 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1582 }
1583
1584 OSStatus wxMacDataBrowserControl::GetHeaderButtonHeight(UInt16 *height)
1585 {
1586 return GetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1587 }
1588
1589 OSStatus wxMacDataBrowserControl::SetCallbacks(const DataBrowserCallbacks *callbacks)
1590 {
1591 return SetDataBrowserCallbacks( m_controlRef, callbacks );
1592 }
1593
1594 OSStatus wxMacDataBrowserControl::UpdateItems(
1595 DataBrowserItemID container,
1596 UInt32 numItems,
1597 const DataBrowserItemID *items,
1598 DataBrowserPropertyID preSortProperty,
1599 DataBrowserPropertyID propertyID ) const
1600 {
1601 return UpdateDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty, propertyID );
1602 }
1603
1604 bool wxMacDataBrowserControl::IsItemSelected( DataBrowserItemID item ) const
1605 {
1606 return IsDataBrowserItemSelected( m_controlRef, item );
1607 }
1608
1609 OSStatus wxMacDataBrowserControl::AddItems(
1610 DataBrowserItemID container,
1611 UInt32 numItems,
1612 const DataBrowserItemID *items,
1613 DataBrowserPropertyID preSortProperty )
1614 {
1615 return AddDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1616 }
1617
1618 OSStatus wxMacDataBrowserControl::RemoveItems(
1619 DataBrowserItemID container,
1620 UInt32 numItems,
1621 const DataBrowserItemID *items,
1622 DataBrowserPropertyID preSortProperty )
1623 {
1624 return RemoveDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1625 }
1626
1627 OSStatus wxMacDataBrowserControl::RevealItem(
1628 DataBrowserItemID item,
1629 DataBrowserPropertyID propertyID,
1630 DataBrowserRevealOptions options ) const
1631 {
1632 return RevealDataBrowserItem( m_controlRef, item, propertyID, options );
1633 }
1634
1635 OSStatus wxMacDataBrowserControl::SetSelectedItems(
1636 UInt32 numItems,
1637 const DataBrowserItemID *items,
1638 DataBrowserSetOption operation )
1639 {
1640 return SetDataBrowserSelectedItems( m_controlRef, numItems, items, operation );
1641 }
1642
1643 OSStatus wxMacDataBrowserControl::GetSelectionAnchor( DataBrowserItemID *first, DataBrowserItemID *last ) const
1644 {
1645 return GetDataBrowserSelectionAnchor( m_controlRef, first, last );
1646 }
1647
1648 OSStatus wxMacDataBrowserControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
1649 {
1650 return GetDataBrowserTableViewItemID( m_controlRef, row, item );
1651 }
1652
1653 OSStatus wxMacDataBrowserControl::GetItemRow( DataBrowserItemID item, DataBrowserTableViewRowIndex * row ) const
1654 {
1655 return GetDataBrowserTableViewItemRow( m_controlRef, item, row );
1656 }
1657
1658 OSStatus wxMacDataBrowserControl::SetDefaultRowHeight( UInt16 height )
1659 {
1660 return SetDataBrowserTableViewRowHeight( m_controlRef , height );
1661 }
1662
1663 OSStatus wxMacDataBrowserControl::GetDefaultRowHeight( UInt16 * height ) const
1664 {
1665 return GetDataBrowserTableViewRowHeight( m_controlRef, height );
1666 }
1667
1668 OSStatus wxMacDataBrowserControl::SetRowHeight( DataBrowserItemID item , UInt16 height)
1669 {
1670 return SetDataBrowserTableViewItemRowHeight( m_controlRef, item , height );
1671 }
1672
1673 OSStatus wxMacDataBrowserControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const
1674 {
1675 return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height);
1676 }
1677
1678 OSStatus wxMacDataBrowserControl::GetColumnWidth( DataBrowserPropertyID column , UInt16 *width ) const
1679 {
1680 return GetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1681 }
1682
1683 OSStatus wxMacDataBrowserControl::SetColumnWidth( DataBrowserPropertyID column , UInt16 width )
1684 {
1685 return SetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1686 }
1687
1688 OSStatus wxMacDataBrowserControl::GetDefaultColumnWidth( UInt16 *width ) const
1689 {
1690 return GetDataBrowserTableViewColumnWidth( m_controlRef , width );
1691 }
1692
1693 OSStatus wxMacDataBrowserControl::SetDefaultColumnWidth( UInt16 width )
1694 {
1695 return SetDataBrowserTableViewColumnWidth( m_controlRef , width );
1696 }
1697
1698 OSStatus wxMacDataBrowserControl::GetColumnCount(UInt32* numColumns) const
1699 {
1700 return GetDataBrowserTableViewColumnCount( m_controlRef, numColumns);
1701 }
1702
1703 OSStatus wxMacDataBrowserControl::GetColumnPosition( DataBrowserPropertyID column,
1704 UInt32 *position) const
1705 {
1706 return GetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1707 }
1708
1709 OSStatus wxMacDataBrowserControl::SetColumnPosition( DataBrowserPropertyID column, UInt32 position)
1710 {
1711 return SetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1712 }
1713
1714 OSStatus wxMacDataBrowserControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
1715 {
1716 return GetDataBrowserScrollPosition( m_controlRef , top , left );
1717 }
1718
1719 OSStatus wxMacDataBrowserControl::SetScrollPosition( UInt32 top , UInt32 left )
1720 {
1721 return SetDataBrowserScrollPosition( m_controlRef , top , left );
1722 }
1723
1724 OSStatus wxMacDataBrowserControl::GetSortProperty( DataBrowserPropertyID *column ) const
1725 {
1726 return GetDataBrowserSortProperty( m_controlRef , column );
1727 }
1728
1729 OSStatus wxMacDataBrowserControl::SetSortProperty( DataBrowserPropertyID column )
1730 {
1731 return SetDataBrowserSortProperty( m_controlRef , column );
1732 }
1733
1734 OSStatus wxMacDataBrowserControl::GetSortOrder( DataBrowserSortOrder *order ) const
1735 {
1736 return GetDataBrowserSortOrder( m_controlRef , order );
1737 }
1738
1739 OSStatus wxMacDataBrowserControl::SetSortOrder( DataBrowserSortOrder order )
1740 {
1741 return SetDataBrowserSortOrder( m_controlRef , order );
1742 }
1743
1744 OSStatus wxMacDataBrowserControl::GetPropertyFlags( DataBrowserPropertyID property,
1745 DataBrowserPropertyFlags *flags ) const
1746 {
1747 return GetDataBrowserPropertyFlags( m_controlRef , property , flags );
1748 }
1749
1750 OSStatus wxMacDataBrowserControl::SetPropertyFlags( DataBrowserPropertyID property,
1751 DataBrowserPropertyFlags flags )
1752 {
1753 return SetDataBrowserPropertyFlags( m_controlRef , property , flags );
1754 }
1755
1756 OSStatus wxMacDataBrowserControl::GetHeaderDesc( DataBrowserPropertyID property,
1757 DataBrowserListViewHeaderDesc *desc ) const
1758 {
1759 return GetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1760 }
1761
1762 OSStatus wxMacDataBrowserControl::SetHeaderDesc( DataBrowserPropertyID property,
1763 DataBrowserListViewHeaderDesc *desc )
1764 {
1765 return SetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1766 }
1767
1768 OSStatus wxMacDataBrowserControl::SetDisclosureColumn( DataBrowserPropertyID property ,
1769 Boolean expandableRows )
1770 {
1771 return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
1772 }
1773
1774 // ============================================================================
1775 // Higher-level Databrowser
1776 // ============================================================================
1777 //
1778 // basing on data item objects
1779 //
1780
1781 wxMacDataItem::wxMacDataItem()
1782 {
1783 }
1784
1785 wxMacDataItem::~wxMacDataItem()
1786 {
1787 }
1788
1789 bool wxMacDataItem::IsLessThan(wxMacDataItemBrowserControl *owner ,
1790 const wxMacDataItem*,
1791 DataBrowserPropertyID property) const
1792 {
1793 return false;
1794 }
1795
1796 OSStatus wxMacDataItem::GetSetData(wxMacDataItemBrowserControl *owner ,
1797 DataBrowserPropertyID property,
1798 DataBrowserItemDataRef itemData,
1799 bool changeValue )
1800 {
1801 return errDataBrowserPropertyNotSupported;
1802 }
1803
1804 void wxMacDataItem::Notification(wxMacDataItemBrowserControl *owner ,
1805 DataBrowserItemNotification message,
1806 DataBrowserItemDataRef itemData ) const
1807 {
1808 }
1809
1810
1811 wxMacDataItemBrowserControl::wxMacDataItemBrowserControl( wxWindow* peer , const wxPoint& pos, const wxSize& size, long style) :
1812 wxMacDataBrowserControl( peer, pos, size, style )
1813 {
1814 m_suppressSelection = false;
1815 }
1816
1817 wxMacDataItemBrowserSelectionSuppressor::wxMacDataItemBrowserSelectionSuppressor(wxMacDataItemBrowserControl *browser)
1818 {
1819 m_former = browser->SuppressSelection(true);
1820 m_browser = browser;
1821 }
1822
1823 wxMacDataItemBrowserSelectionSuppressor::~wxMacDataItemBrowserSelectionSuppressor()
1824 {
1825 m_browser->SuppressSelection(m_former);
1826 }
1827
1828 bool wxMacDataItemBrowserControl::SuppressSelection( bool suppress )
1829 {
1830 bool former = m_suppressSelection;
1831 m_suppressSelection = suppress;
1832
1833 return former;
1834 }
1835
1836 Boolean wxMacDataItemBrowserControl::CompareItems(DataBrowserItemID itemOneID,
1837 DataBrowserItemID itemTwoID,
1838 DataBrowserPropertyID sortProperty)
1839 {
1840 wxMacDataItem* itemOne = (wxMacDataItem*) itemOneID;
1841 wxMacDataItem* itemTwo = (wxMacDataItem*) itemTwoID;
1842 return CompareItems( itemOne , itemTwo , sortProperty );
1843 }
1844
1845 Boolean wxMacDataItemBrowserControl::CompareItems(const wxMacDataItem* itemOne,
1846 const wxMacDataItem* itemTwo,
1847 DataBrowserPropertyID sortProperty)
1848 {
1849 Boolean retval = false;
1850 if ( itemOne != NULL )
1851 retval = itemOne->IsLessThan( this , itemTwo , sortProperty);
1852 return retval;
1853 }
1854
1855 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1856 DataBrowserItemID itemID,
1857 DataBrowserPropertyID property,
1858 DataBrowserItemDataRef itemData,
1859 Boolean changeValue )
1860 {
1861 wxMacDataItem* item = (wxMacDataItem*) itemID;
1862 return GetSetItemData(item, property, itemData , changeValue );
1863 }
1864
1865 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1866 wxMacDataItem* item,
1867 DataBrowserPropertyID property,
1868 DataBrowserItemDataRef itemData,
1869 Boolean changeValue )
1870 {
1871 OSStatus err = errDataBrowserPropertyNotSupported;
1872 switch( property )
1873 {
1874 case kDataBrowserContainerIsClosableProperty :
1875 case kDataBrowserContainerIsSortableProperty :
1876 case kDataBrowserContainerIsOpenableProperty :
1877 // right now default behaviour on these
1878 break;
1879 default :
1880 if ( item != NULL )
1881 err = item->GetSetData( this, property , itemData , changeValue );
1882 break;
1883
1884 }
1885 return err;
1886 }
1887
1888 void wxMacDataItemBrowserControl::ItemNotification(
1889 DataBrowserItemID itemID,
1890 DataBrowserItemNotification message,
1891 DataBrowserItemDataRef itemData)
1892 {
1893 wxMacDataItem* item = (wxMacDataItem*) itemID;
1894 ItemNotification( item , message, itemData);
1895 }
1896
1897 void wxMacDataItemBrowserControl::ItemNotification(
1898 const wxMacDataItem* item,
1899 DataBrowserItemNotification message,
1900 DataBrowserItemDataRef itemData)
1901 {
1902 if (item != NULL)
1903 item->Notification( this, message, itemData);
1904 }
1905
1906 unsigned int wxMacDataItemBrowserControl::GetItemCount(const wxMacDataItem* container,
1907 bool recurse , DataBrowserItemState state) const
1908 {
1909 UInt32 numItems = 0;
1910 verify_noerr( wxMacDataBrowserControl::GetItemCount( (DataBrowserItemID)container,
1911 recurse, state, &numItems ) );
1912 return numItems;
1913 }
1914
1915 void wxMacDataItemBrowserControl::GetItems(const wxMacDataItem* container,
1916 bool recurse , DataBrowserItemState state, wxArrayMacDataItemPtr &items) const
1917 {
1918 Handle handle = NewHandle(0);
1919 verify_noerr( wxMacDataBrowserControl::GetItems( (DataBrowserItemID)container ,
1920 recurse , state, handle) );
1921
1922 int itemCount = GetHandleSize(handle)/sizeof(DataBrowserItemID);
1923 HLock( handle );
1924 wxMacDataItemPtr* itemsArray = (wxMacDataItemPtr*) *handle;
1925 for ( int i = 0; i < itemCount; ++i)
1926 {
1927 items.Add(itemsArray[i]);
1928 }
1929 HUnlock( handle );
1930 DisposeHandle( handle );
1931 }
1932
1933 unsigned int wxMacDataItemBrowserControl::GetLineFromItem(const wxMacDataItem* item) const
1934 {
1935 DataBrowserTableViewRowIndex row;
1936 OSStatus err = GetItemRow( (DataBrowserItemID) item , &row);
1937 wxASSERT( err == noErr);
1938 return row;
1939 }
1940
1941 wxMacDataItem* wxMacDataItemBrowserControl::GetItemFromLine(unsigned int n) const
1942 {
1943 DataBrowserItemID id;
1944 OSStatus err = GetItemID( (DataBrowserTableViewRowIndex) n , &id);
1945 wxASSERT( err == noErr);
1946 return (wxMacDataItem*) id;
1947 }
1948
1949 void wxMacDataItemBrowserControl::UpdateItem(const wxMacDataItem *container,
1950 const wxMacDataItem *item , DataBrowserPropertyID property) const
1951 {
1952 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, 1,
1953 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty /* notSorted */, property ) );
1954 }
1955
1956 void wxMacDataItemBrowserControl::UpdateItems(const wxMacDataItem *container,
1957 wxArrayMacDataItemPtr &itemArray , DataBrowserPropertyID property) const
1958 {
1959 unsigned int noItems = itemArray.GetCount();
1960 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1961 for ( unsigned int i = 0; i < noItems; ++i )
1962 items[i] = (DataBrowserItemID) itemArray[i];
1963
1964 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, noItems,
1965 items, kDataBrowserItemNoProperty /* notSorted */, property ) );
1966 delete [] items;
1967 }
1968
1969 void wxMacDataItemBrowserControl::AddItem(wxMacDataItem *container, wxMacDataItem *item)
1970 {
1971 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, 1,
1972 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty ) );
1973 }
1974
1975 void wxMacDataItemBrowserControl::AddItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray )
1976 {
1977 unsigned int noItems = itemArray.GetCount();
1978 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1979 for ( unsigned int i = 0; i < noItems; ++i )
1980 items[i] = (DataBrowserItemID) itemArray[i];
1981
1982 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, noItems,
1983 (DataBrowserItemID*) items, kDataBrowserItemNoProperty ) );
1984 delete [] items;
1985 }
1986
1987 void wxMacDataItemBrowserControl::RemoveItem(wxMacDataItem *container, wxMacDataItem* item)
1988 {
1989 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 1,
1990 (UInt32*) &item, kDataBrowserItemNoProperty );
1991 verify_noerr( err );
1992 }
1993
1994 void wxMacDataItemBrowserControl::RemoveItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray)
1995 {
1996 unsigned int noItems = itemArray.GetCount();
1997 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1998 for ( unsigned int i = 0; i < noItems; ++i )
1999 items[i] = (DataBrowserItemID) itemArray[i];
2000
2001 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, noItems,
2002 (UInt32*) items, kDataBrowserItemNoProperty );
2003 verify_noerr( err );
2004 delete [] items;
2005 }
2006
2007 void wxMacDataItemBrowserControl::RemoveAllItems(wxMacDataItem *container)
2008 {
2009 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 0 , NULL , kDataBrowserItemNoProperty );
2010 verify_noerr( err );
2011 }
2012
2013 void wxMacDataItemBrowserControl::SetSelectedItem(wxMacDataItem* item , DataBrowserSetOption option)
2014 {
2015 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 1, (DataBrowserItemID*) &item, option ));
2016 }
2017
2018 void wxMacDataItemBrowserControl::SetSelectedAllItems(DataBrowserSetOption option)
2019 {
2020 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 0 , NULL , option ));
2021 }
2022
2023 void wxMacDataItemBrowserControl::SetSelectedItems(wxArrayMacDataItemPtr &itemArray , DataBrowserSetOption option)
2024 {
2025 unsigned int noItems = itemArray.GetCount();
2026 DataBrowserItemID *items = new DataBrowserItemID[noItems];
2027 for ( unsigned int i = 0; i < noItems; ++i )
2028 items[i] = (DataBrowserItemID) itemArray[i];
2029
2030 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( noItems, (DataBrowserItemID*) items, option ));
2031 delete [] items;
2032 }
2033
2034 Boolean wxMacDataItemBrowserControl::IsItemSelected( const wxMacDataItem* item) const
2035 {
2036 return wxMacDataBrowserControl::IsItemSelected( (DataBrowserItemID) item);
2037 }
2038
2039 void wxMacDataItemBrowserControl::RevealItem( wxMacDataItem* item, DataBrowserRevealOptions options)
2040 {
2041 verify_noerr(wxMacDataBrowserControl::RevealItem( (DataBrowserItemID) item, kDataBrowserNoItem , options ) );
2042 }
2043
2044 void wxMacDataItemBrowserControl::GetSelectionAnchor( wxMacDataItemPtr* first , wxMacDataItemPtr* last) const
2045 {
2046 verify_noerr(wxMacDataBrowserControl::GetSelectionAnchor( (DataBrowserItemID*) first, (DataBrowserItemID*) last) );
2047 }
2048
2049
2050
2051 //
2052 // Tab Control
2053 //
2054
2055 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
2056 {
2057 return ::SetTabEnabled( m_controlRef , tabNo , enable );
2058 }
2059
2060 //
2061 // Quartz Support
2062 //
2063
2064 #ifdef __WXMAC_OSX__
2065 // snippets from Sketch Sample from Apple :
2066
2067 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
2068
2069 /*
2070 This function locates, opens, and returns the profile reference for the calibrated
2071 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
2072 with the profile reference this function returns.
2073 */
2074 CMProfileRef wxMacOpenGenericProfile()
2075 {
2076 static CMProfileRef cachedRGBProfileRef = NULL;
2077
2078 // we only create the profile reference once
2079 if (cachedRGBProfileRef == NULL)
2080 {
2081 CMProfileLocation loc;
2082
2083 loc.locType = cmPathBasedProfile;
2084 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
2085
2086 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
2087 }
2088
2089 // clone the profile reference so that the caller has their own reference, not our cached one
2090 if (cachedRGBProfileRef)
2091 CMCloneProfileRef(cachedRGBProfileRef);
2092
2093 return cachedRGBProfileRef;
2094 }
2095
2096 /*
2097 Return the generic RGB color space. This is a 'get' function and the caller should
2098 not release the returned value unless the caller retains it first. Usually callers
2099 of this routine will immediately use the returned colorspace with CoreGraphics
2100 so they typically do not need to retain it themselves.
2101
2102 This function creates the generic RGB color space once and hangs onto it so it can
2103 return it whenever this function is called.
2104 */
2105
2106 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
2107 {
2108 static wxMacCFRefHolder<CGColorSpaceRef> genericRGBColorSpace;
2109
2110 if (genericRGBColorSpace == NULL)
2111 {
2112 if ( UMAGetSystemVersion() >= 0x1040 )
2113 {
2114 genericRGBColorSpace.Set( CGColorSpaceCreateWithName( CFSTR("kCGColorSpaceGenericRGB") ) );
2115 }
2116 else
2117 {
2118 CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
2119
2120 if (genericRGBProfile)
2121 {
2122 genericRGBColorSpace.Set( CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile) );
2123
2124 wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") );
2125
2126 // we opened the profile so it is up to us to close it
2127 CMCloseProfile(genericRGBProfile);
2128 }
2129 }
2130 }
2131
2132 return genericRGBColorSpace;
2133 }
2134 #endif
2135
2136 wxMacPortSaver::wxMacPortSaver( GrafPtr port )
2137 {
2138 ::GetPort( &m_port );
2139 ::SetPort( port );
2140 }
2141
2142 wxMacPortSaver::~wxMacPortSaver()
2143 {
2144 ::SetPort( m_port );
2145 }
2146
2147 #endif // wxUSE_GUI