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