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