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