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