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