]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
new MLTE implementation, using our own scrolling
[wxWidgets.git] / src / mac / carbon / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utils.cpp
3 // Purpose: Various utilities
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 // Note: this is done in utilscmn.cpp now.
14 // #pragma implementation "utils.h"
15 #endif
16
17 #include "wx/wxprec.h"
18
19 #include "wx/utils.h"
20 #include "wx/app.h"
21 #include "wx/apptrait.h"
22
23 #if wxUSE_GUI
24 #include "wx/mac/uma.h"
25 #include "wx/font.h"
26 #else
27 #include "wx/intl.h"
28 #endif
29
30 #include <ctype.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdarg.h>
36
37 #include "MoreFilesX.h"
38
39 #ifndef __DARWIN__
40 #include <Threads.h>
41 #include <Sound.h>
42 #endif
43
44 #if wxUSE_GUI
45 #if TARGET_API_MAC_OSX
46 #include <CoreServices/CoreServices.h>
47 #else
48 #include <DriverServices.h>
49 #include <Multiprocessing.h>
50 #endif
51
52 #include <ATSUnicode.h>
53 #include <TextCommon.h>
54 #include <TextEncodingConverter.h>
55 #endif // wxUSE_GUI
56
57 #include "wx/mac/private.h" // includes mac headers
58
59 #if defined(__MWERKS__) && wxUSE_UNICODE
60 #include <wtime.h>
61 #endif
62
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
68 static int DoGetOSVersion(int *majorVsn, int *minorVsn)
69 {
70 long theSystem ;
71
72 // are there x-platform conventions ?
73
74 Gestalt(gestaltSystemVersion, &theSystem) ;
75 if (minorVsn != NULL) {
76 *minorVsn = (theSystem & 0xFF ) ;
77 }
78 if (majorVsn != NULL) {
79 *majorVsn = (theSystem >> 8 ) ;
80 }
81 #ifdef __DARWIN__
82 return wxMAC_DARWIN;
83 #else
84 return wxMAC;
85 #endif
86 }
87
88
89 #if wxUSE_BASE
90
91 // ----------------------------------------------------------------------------
92 // debugging support
93 // ----------------------------------------------------------------------------
94
95 #if defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
96
97 // MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds...
98
99 #ifndef __MetroNubUtils__
100 #include "MetroNubUtils.h"
101 #endif
102
103 #ifndef __GESTALT__
104 #include <Gestalt.h>
105 #endif
106
107 #if TARGET_API_MAC_CARBON
108
109 #include <CodeFragments.h>
110
111 extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...);
112
113 ProcPtr gCallUniversalProc_Proc = NULL;
114
115 #endif
116
117 static MetroNubUserEntryBlock* gMetroNubEntry = NULL;
118
119 static long fRunOnce = false;
120
121 /* ---------------------------------------------------------------------------
122 IsMetroNubInstalled
123 --------------------------------------------------------------------------- */
124
125 Boolean IsMetroNubInstalled()
126 {
127 if (!fRunOnce)
128 {
129 long result, value;
130
131 fRunOnce = true;
132 gMetroNubEntry = NULL;
133
134 if (Gestalt(gestaltSystemVersion, &value) == noErr && value < 0x1000)
135 {
136 /* look for MetroNub's Gestalt selector */
137 if (Gestalt(kMetroNubUserSignature, &result) == noErr)
138 {
139
140 #if TARGET_API_MAC_CARBON
141 if (gCallUniversalProc_Proc == NULL)
142 {
143 CFragConnectionID connectionID;
144 Ptr mainAddress;
145 Str255 errorString;
146 ProcPtr symbolAddress;
147 OSErr err;
148 CFragSymbolClass symbolClass;
149
150 symbolAddress = NULL;
151 err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
152 &connectionID, &mainAddress, errorString);
153
154 if (err != noErr)
155 {
156 gCallUniversalProc_Proc = NULL;
157 goto end;
158 }
159
160 err = FindSymbol(connectionID, "\pCallUniversalProc",
161 (Ptr *) &gCallUniversalProc_Proc, &symbolClass);
162
163 if (err != noErr)
164 {
165 gCallUniversalProc_Proc = NULL;
166 goto end;
167 }
168 }
169 #endif
170
171 {
172 MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
173
174 /* make sure the version of the API is compatible */
175 if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
176 kMetroNubUserAPIVersion <= block->apiHiVersion)
177 gMetroNubEntry = block; /* success! */
178 }
179
180 }
181 }
182 }
183
184 end:
185
186 #if TARGET_API_MAC_CARBON
187 return (gMetroNubEntry != NULL && gCallUniversalProc_Proc != NULL);
188 #else
189 return (gMetroNubEntry != NULL);
190 #endif
191 }
192
193 /* ---------------------------------------------------------------------------
194 IsMWDebuggerRunning [v1 API]
195 --------------------------------------------------------------------------- */
196
197 Boolean IsMWDebuggerRunning()
198 {
199 if (IsMetroNubInstalled())
200 return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
201 else
202 return false;
203 }
204
205 /* ---------------------------------------------------------------------------
206 AmIBeingMWDebugged [v1 API]
207 --------------------------------------------------------------------------- */
208
209 Boolean AmIBeingMWDebugged()
210 {
211 if (IsMetroNubInstalled())
212 return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
213 else
214 return false;
215 }
216
217 extern bool WXDLLEXPORT wxIsDebuggerRunning()
218 {
219 return IsMWDebuggerRunning() && AmIBeingMWDebugged();
220 }
221
222 #else
223
224 extern bool WXDLLEXPORT wxIsDebuggerRunning()
225 {
226 return false;
227 }
228
229 #endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
230
231
232 #ifndef __DARWIN__
233 // defined in unix/utilsunx.cpp for Mac OS X
234
235 // get full hostname (with domain name if possible)
236 bool wxGetFullHostName(wxChar *buf, int maxSize)
237 {
238 return wxGetHostName(buf, maxSize);
239 }
240
241 // Get hostname only (without domain name)
242 bool wxGetHostName(wxChar *buf, int maxSize)
243 {
244 // Gets Chooser name of user by examining a System resource.
245
246 const short kComputerNameID = -16413;
247
248 short oldResFile = CurResFile() ;
249 UseResFile(0);
250 StringHandle chooserName = (StringHandle)::GetString(kComputerNameID);
251 UseResFile(oldResFile);
252
253 if (chooserName && *chooserName)
254 {
255 HLock( (Handle) chooserName ) ;
256 wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
257 HUnlock( (Handle) chooserName ) ;
258 ReleaseResource( (Handle) chooserName ) ;
259 wxStrncpy( buf , name , maxSize - 1 ) ;
260 }
261 else
262 buf[0] = 0 ;
263
264 return true;
265 }
266
267 // Get user ID e.g. jacs
268 bool wxGetUserId(wxChar *buf, int maxSize)
269 {
270 return wxGetUserName( buf , maxSize ) ;
271 }
272
273 const wxChar* wxGetHomeDir(wxString *pstr)
274 {
275 *pstr = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ;
276 return pstr->c_str() ;
277 }
278
279 // Get user name e.g. Stefan Csomor
280 bool wxGetUserName(wxChar *buf, int maxSize)
281 {
282 // Gets Chooser name of user by examining a System resource.
283
284 const short kChooserNameID = -16096;
285
286 short oldResFile = CurResFile() ;
287 UseResFile(0);
288 StringHandle chooserName = (StringHandle)::GetString(kChooserNameID);
289 UseResFile(oldResFile);
290
291 if (chooserName && *chooserName)
292 {
293 HLock( (Handle) chooserName ) ;
294 wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
295 HUnlock( (Handle) chooserName ) ;
296 ReleaseResource( (Handle) chooserName ) ;
297 wxStrncpy( buf , name , maxSize - 1 ) ;
298 }
299 else
300 buf[0] = 0 ;
301
302 return true;
303 }
304
305 int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
306 {
307 // TODO
308 return 0;
309 }
310
311 WXDLLEXPORT bool wxGetEnv(const wxString& var, wxString *value)
312 {
313 // TODO : under classic there is no environement support, under X yes
314 return false ;
315 }
316
317 // set the env var name to the given value, return true on success
318 WXDLLEXPORT bool wxSetEnv(const wxString& var, const wxChar *value)
319 {
320 // TODO : under classic there is no environement support, under X yes
321 return false ;
322 }
323
324 //
325 // Execute a program in an Interactive Shell
326 //
327 bool wxShell(const wxString& command)
328 {
329 // TODO
330 return false;
331 }
332
333 // Shutdown or reboot the PC
334 bool wxShutdown(wxShutdownFlags wFlags)
335 {
336 // TODO
337 return false;
338 }
339
340 wxPowerType wxGetPowerType()
341 {
342 // TODO
343 return wxPOWER_UNKNOWN;
344 }
345
346 wxBatteryState wxGetBatteryState()
347 {
348 // TODO
349 return wxBATTERY_UNKNOWN_STATE;
350 }
351
352 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
353 wxMemorySize wxGetFreeMemory()
354 {
355 return (wxMemorySize)FreeMem() ;
356 }
357
358 #ifndef __DARWIN__
359
360 void wxMicroSleep(unsigned long microseconds)
361 {
362 AbsoluteTime wakeup = AddDurationToAbsolute( microseconds * durationMicrosecond , UpTime());
363 MPDelayUntil( & wakeup);
364 }
365
366 void wxMilliSleep(unsigned long milliseconds)
367 {
368 AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime());
369 MPDelayUntil( & wakeup);
370 }
371
372 void wxSleep(int nSecs)
373 {
374 wxMilliSleep(1000*nSecs);
375 }
376
377 #endif
378
379 // Consume all events until no more left
380 void wxFlushEvents()
381 {
382 }
383
384 #endif // !__DARWIN__
385
386 // Emit a beeeeeep
387 void wxBell()
388 {
389 SysBeep(30);
390 }
391
392 wxToolkitInfo& wxConsoleAppTraits::GetToolkitInfo()
393 {
394 static wxToolkitInfo info;
395 info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
396 info.name = _T("wxBase");
397 return info;
398 }
399
400 #endif // wxUSE_BASE
401
402 #if wxUSE_GUI
403
404 wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
405 {
406 static wxToolkitInfo info;
407 info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
408 info.shortName = _T("mac");
409 info.name = _T("wxMac");
410 #ifdef __WXUNIVERSAL__
411 info.shortName << _T("univ");
412 info.name << _T("/wxUniversal");
413 #endif
414 return info;
415 }
416
417 // Reading and writing resources (eg WIN.INI, .Xdefaults)
418 #if wxUSE_RESOURCES
419 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
420 {
421 // TODO
422 return false;
423 }
424
425 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
426 {
427 wxString buf;
428 buf.Printf(wxT("%.4f"), value);
429
430 return wxWriteResource(section, entry, buf, file);
431 }
432
433 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
434 {
435 wxString buf;
436 buf.Printf(wxT("%ld"), value);
437
438 return wxWriteResource(section, entry, buf, file);
439 }
440
441 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
442 {
443 wxString buf;
444 buf.Printf(wxT("%d"), value);
445
446 return wxWriteResource(section, entry, buf, file);
447 }
448
449 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
450 {
451 // TODO
452 return false;
453 }
454
455 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
456 {
457 char *s = NULL;
458 bool succ = wxGetResource(section, entry, (char **)&s, file);
459 if (succ)
460 {
461 *value = (float)strtod(s, NULL);
462 delete[] s;
463 return true;
464 }
465 else return false;
466 }
467
468 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
469 {
470 char *s = NULL;
471 bool succ = wxGetResource(section, entry, (char **)&s, file);
472 if (succ)
473 {
474 *value = strtol(s, NULL, 10);
475 delete[] s;
476 return true;
477 }
478 else return false;
479 }
480
481 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
482 {
483 char *s = NULL;
484 bool succ = wxGetResource(section, entry, (char **)&s, file);
485 if (succ)
486 {
487 *value = (int)strtol(s, NULL, 10);
488 delete[] s;
489 return true;
490 }
491 else return false;
492 }
493 #endif // wxUSE_RESOURCES
494
495 int gs_wxBusyCursorCount = 0;
496 extern wxCursor gMacCurrentCursor ;
497 wxCursor gMacStoredActiveCursor ;
498
499 // Set the cursor to the busy cursor for all windows
500 void wxBeginBusyCursor(wxCursor *cursor)
501 {
502 if (gs_wxBusyCursorCount++ == 0)
503 {
504 gMacStoredActiveCursor = gMacCurrentCursor ;
505 cursor->MacInstall() ;
506 }
507 //else: nothing to do, already set
508 }
509
510 // Restore cursor to normal
511 void wxEndBusyCursor()
512 {
513 wxCHECK_RET( gs_wxBusyCursorCount > 0,
514 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
515
516 if (--gs_wxBusyCursorCount == 0)
517 {
518 gMacStoredActiveCursor.MacInstall() ;
519 gMacStoredActiveCursor = wxNullCursor ;
520 }
521 }
522
523 // true if we're between the above two calls
524 bool wxIsBusy()
525 {
526 return (gs_wxBusyCursorCount > 0);
527 }
528
529 #endif // wxUSE_GUI
530
531 #if wxUSE_BASE
532
533 wxString wxMacFindFolder( short vol,
534 OSType folderType,
535 Boolean createFolder)
536 {
537 FSRef fsRef ;
538 wxString strDir ;
539
540 if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr)
541 strDir = wxMacFSRefToPath( &fsRef ) + wxFILE_SEP_PATH ;
542
543 return strDir ;
544 }
545
546 #endif // wxUSE_BASE
547
548 #if wxUSE_GUI
549
550 // Check whether this window wants to process messages, e.g. Stop button
551 // in long calculations.
552 bool wxCheckForInterrupt(wxWindow *wnd)
553 {
554 // TODO
555 return false;
556 }
557
558 void wxGetMousePosition( int* x, int* y )
559 {
560 Point pt ;
561
562 GetMouse( &pt ) ;
563 LocalToGlobal( &pt ) ;
564 *x = pt.h ;
565 *y = pt.v ;
566 };
567
568 // Return true if we have a colour display
569 bool wxColourDisplay()
570 {
571 return true;
572 }
573
574 // Returns depth of screen
575 int wxDisplayDepth()
576 {
577 Rect globRect ;
578 SetRect(&globRect, -32760, -32760, 32760, 32760);
579 GDHandle theMaxDevice;
580
581 int theDepth = 8;
582 theMaxDevice = GetMaxDevice(&globRect);
583 if (theMaxDevice != nil)
584 theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
585
586 return theDepth ;
587 }
588
589 // Get size of display
590 void wxDisplaySize(int *width, int *height)
591 {
592 BitMap screenBits;
593 GetQDGlobalsScreenBits( &screenBits );
594
595 if (width != NULL) {
596 *width = screenBits.bounds.right - screenBits.bounds.left ;
597 }
598 if (height != NULL) {
599 *height = screenBits.bounds.bottom - screenBits.bounds.top ;
600 }
601 }
602
603 void wxDisplaySizeMM(int *width, int *height)
604 {
605 wxDisplaySize(width, height);
606 // on mac 72 is fixed (at least now ;-)
607 float cvPt2Mm = 25.4 / 72;
608
609 if (width != NULL) {
610 *width = int( *width * cvPt2Mm );
611 }
612 if (height != NULL) {
613 *height = int( *height * cvPt2Mm );
614 }
615 }
616
617 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
618 {
619 Rect r ;
620 GetAvailableWindowPositioningBounds( GetMainDevice() , &r ) ;
621 if ( x )
622 *x = r.left ;
623 if ( y )
624 *y = r.top ;
625 if ( width )
626 *width = r.right - r.left ;
627 if ( height )
628 *height = r.bottom - r.top ;
629 }
630
631 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
632 {
633 return wxGenericFindWindowAtPoint(pt);
634 }
635
636 #endif // wxUSE_GUI
637
638 #if wxUSE_BASE
639
640 wxString wxGetOsDescription()
641 {
642 #ifdef WXWIN_OS_DESCRIPTION
643 // use configure generated description if available
644 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
645 #else
646 return wxT("MacOS") ; //TODO:define further
647 #endif
648 }
649
650 #ifndef __DARWIN__
651 wxChar *wxGetUserHome (const wxString& user)
652 {
653 // TODO
654 return NULL;
655 }
656
657 bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree)
658 {
659 if ( path.empty() )
660 return false;
661
662 wxString p = path ;
663 if (p[0u] == ':' ) {
664 p = wxGetCwd() + p ;
665 }
666
667 int pos = p.Find(':') ;
668 if ( pos != wxNOT_FOUND ) {
669 p = p.Mid(1,pos) ;
670 }
671
672 p = p + wxT(":") ;
673
674 OSErr err = noErr ;
675
676 FSRef fsRef ;
677 err = wxMacPathToFSRef( p , &fsRef ) ;
678 if ( noErr == err )
679 {
680 FSVolumeRefNum vRefNum ;
681 err = FSGetVRefNum( &fsRef , &vRefNum ) ;
682 if ( noErr == err )
683 {
684 UInt64 freeBytes , totalBytes ;
685 err = FSGetVInfo( vRefNum , NULL , &freeBytes , &totalBytes ) ;
686 if ( noErr == err )
687 {
688 if ( pTotal )
689 *pTotal = wxLongLong( totalBytes ) ;
690 if ( pFree )
691 *pFree = wxLongLong( freeBytes ) ;
692 }
693 }
694 }
695
696 return err == noErr ;
697 }
698 #endif // !__DARWIN__
699
700 //---------------------------------------------------------------------------
701 // wxMac Specific utility functions
702 //---------------------------------------------------------------------------
703
704 void wxMacStringToPascal( const wxString&from , StringPtr to )
705 {
706 wxCharBuffer buf = from.mb_str( wxConvLocal ) ;
707 int len = strlen(buf) ;
708
709 if ( len > 255 )
710 len = 255 ;
711 to[0] = len ;
712 memcpy( (char*) &to[1] , buf , len ) ;
713 }
714
715 wxString wxMacMakeStringFromPascal( ConstStringPtr from )
716 {
717 return wxString( (char*) &from[1] , wxConvLocal , from[0] ) ;
718 }
719
720
721 // ----------------------------------------------------------------------------
722 // Common Event Support
723 // ----------------------------------------------------------------------------
724
725
726 extern ProcessSerialNumber gAppProcess ;
727
728 void wxMacWakeUp()
729 {
730 ProcessSerialNumber psn ;
731 Boolean isSame ;
732 psn.highLongOfPSN = 0 ;
733 psn.lowLongOfPSN = kCurrentProcess ;
734 SameProcess( &gAppProcess , &psn , &isSame ) ;
735 if ( isSame )
736 {
737 #if TARGET_CARBON
738 static wxMacCarbonEvent s_wakeupEvent ;
739 OSStatus err = noErr ;
740 if ( !s_wakeupEvent.IsValid() )
741 {
742 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
743 kEventAttributeNone ) ;
744 }
745 if ( err == noErr )
746 {
747 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
748 return ;
749 s_wakeupEvent.SetTime(0) ;
750 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
751 kEventPriorityHigh);
752 }
753 #else
754 PostEvent( nullEvent , 0 ) ;
755 #endif
756 }
757 else
758 {
759 WakeUpProcess( &gAppProcess ) ;
760 }
761 }
762
763 #endif // wxUSE_BASE
764
765 #if wxUSE_GUI
766
767
768 // ----------------------------------------------------------------------------
769 // Carbon Event Support
770 // ----------------------------------------------------------------------------
771
772
773 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
774 {
775 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData ) ;
776 }
777
778 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
779 {
780 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData ) ;
781 }
782
783 // ----------------------------------------------------------------------------
784 // Control Access Support
785 // ----------------------------------------------------------------------------
786
787 void wxMacControl::Dispose()
788 {
789 ::DisposeControl( m_controlRef ) ;
790 m_controlRef = NULL ;
791 }
792
793 void wxMacControl::SetReference( SInt32 data )
794 {
795 SetControlReference( m_controlRef , data ) ;
796 }
797
798 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
799 {
800 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize ) ;
801 }
802
803 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
804 {
805 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize ) ;
806 }
807
808 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
809 {
810 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData ) ;
811 }
812
813 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
814 {
815 #if TARGET_API_MAC_OSX
816 return SendEventToEventTargetWithOptions( event,
817 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
818 #else
819 #pragma unused(inOptions)
820 return SendEventToEventTarget(event,GetControlEventTarget( m_controlRef ) ) ;
821 #endif
822 }
823
824 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
825 {
826 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ) ;
827 event.SetParameter<HICommand>(kEventParamDirectObject,command) ;
828 return SendEvent( event , inOptions ) ;
829 }
830
831 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
832 {
833 HICommand command ;
834 memset( &command, 0 , sizeof(command) ) ;
835 command.commandID = commandID ;
836 return SendHICommand( command , inOptions ) ;
837 }
838
839 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
840 {
841 HiliteControl( m_controlRef , part ) ;
842 unsigned long finalTicks ;
843 Delay( ticks , &finalTicks ) ;
844 HiliteControl( m_controlRef , kControlNoPart ) ;
845 }
846
847 SInt32 wxMacControl::GetValue() const
848 {
849 return ::GetControl32BitValue( m_controlRef ) ;
850 }
851
852 SInt32 wxMacControl::GetMaximum() const
853 {
854 return ::GetControl32BitMaximum( m_controlRef ) ;
855 }
856
857 SInt32 wxMacControl::GetMinimum() const
858 {
859 return ::GetControl32BitMinimum( m_controlRef ) ;
860 }
861
862 void wxMacControl::SetValue( SInt32 v )
863 {
864 ::SetControl32BitValue( m_controlRef , v ) ;
865 }
866
867 void wxMacControl::SetMinimum( SInt32 v )
868 {
869 ::SetControl32BitMinimum( m_controlRef , v ) ;
870 }
871
872 void wxMacControl::SetMaximum( SInt32 v )
873 {
874 ::SetControl32BitMaximum( m_controlRef , v ) ;
875 }
876
877 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
878 {
879 ::SetControl32BitMinimum( m_controlRef , minimum ) ;
880 ::SetControl32BitMaximum( m_controlRef , maximum ) ;
881 ::SetControl32BitValue( m_controlRef , value ) ;
882 }
883
884 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
885 {
886 return SetKeyboardFocus( GetControlOwner( m_controlRef ) ,
887 m_controlRef , focusPart ) ;
888 }
889
890 bool wxMacControl::HasFocus() const
891 {
892 ControlRef control ;
893 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
894 return control == m_controlRef ;
895 }
896
897 bool wxMacControl::NeedsFocusRect() const
898 {
899 return false ;
900 }
901
902 void wxMacControl::VisibilityChanged(bool shown)
903 {
904 }
905
906 void wxMacControl::SuperChangedPosition()
907 {
908 }
909
910 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
911 {
912 m_font = font ;
913 ControlFontStyleRec fontStyle;
914 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
915 {
916 switch( font.MacGetThemeFontID() )
917 {
918 case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ;
919 case 109 /*mini font */ : fontStyle.font = -5 ; break ;
920 case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ;
921 default : fontStyle.font = kControlFontBigSystemFont ; break ;
922 }
923 fontStyle.flags = kControlUseFontMask ;
924 }
925 else
926 {
927 fontStyle.font = font.MacGetFontNum() ;
928 fontStyle.style = font.MacGetFontStyle() ;
929 fontStyle.size = font.MacGetFontSize() ;
930 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
931 }
932
933 fontStyle.just = teJustLeft ;
934 fontStyle.flags |= kControlUseJustMask ;
935 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
936 fontStyle.just = teJustCenter ;
937 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
938 fontStyle.just = teJustRight ;
939
940
941 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
942 // won't get grayed out by the system anymore
943
944 if ( foreground != *wxBLACK )
945 {
946 fontStyle.foreColor = MAC_WXCOLORREF(foreground.GetPixel() ) ;
947 fontStyle.flags |= kControlUseForeColorMask ;
948 }
949
950 ::SetControlFontStyle( m_controlRef , &fontStyle );
951 }
952
953 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
954 {
955 // TODO
956 // setting up a color proc is not recommended anymore
957 }
958
959 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
960 {
961 ::SetControl32BitMinimum( m_controlRef , minimum ) ;
962 ::SetControl32BitMaximum( m_controlRef , maximum ) ;
963 }
964
965 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
966 {
967 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers ) ;
968 }
969
970 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
971 {
972 SetControlAction( m_controlRef , actionProc ) ;
973 }
974
975 void wxMacControl::SetViewSize( SInt32 viewSize )
976 {
977 SetControlViewSize(m_controlRef , viewSize ) ;
978 }
979
980 SInt32 wxMacControl::GetViewSize() const
981 {
982 return GetControlViewSize( m_controlRef ) ;
983 }
984
985 bool wxMacControl::IsVisible() const
986 {
987 return IsControlVisible( m_controlRef ) ;
988 }
989
990 void wxMacControl::SetVisibility( bool visible , bool redraw )
991 {
992 SetControlVisibility( m_controlRef , visible , redraw ) ;
993 }
994
995 bool wxMacControl::IsEnabled() const
996 {
997 #if TARGET_API_MAC_OSX
998 return IsControlEnabled( m_controlRef ) ;
999 #else
1000 return IsControlActive( m_controlRef ) ;
1001 #endif
1002 }
1003
1004 bool wxMacControl::IsActive() const
1005 {
1006 return IsControlActive( m_controlRef ) ;
1007 }
1008
1009 void wxMacControl::Enable( bool enable )
1010 {
1011 #if TARGET_API_MAC_OSX
1012 if ( enable )
1013 EnableControl( m_controlRef ) ;
1014 else
1015 DisableControl( m_controlRef ) ;
1016 #else
1017 if ( enable )
1018 ActivateControl( m_controlRef ) ;
1019 else
1020 DeactivateControl( m_controlRef ) ;
1021 #endif
1022 }
1023
1024 void wxMacControl::SetDrawingEnabled( bool enable )
1025 {
1026 #if TARGET_API_MAC_OSX
1027 HIViewSetDrawingEnabled( m_controlRef , enable ) ;
1028 #endif
1029 }
1030
1031 #if TARGET_API_MAC_OSX
1032 bool wxMacControl::GetNeedsDisplay() const
1033 {
1034 #if TARGET_API_MAC_OSX
1035 return HIViewGetNeedsDisplay( m_controlRef ) ;
1036 #else
1037 return false ;
1038 #endif
1039 }
1040
1041 void wxMacControl::SetNeedsDisplay( bool needsDisplay , RgnHandle where )
1042 {
1043 #if TARGET_API_MAC_OSX
1044 if ( where != NULL )
1045 HIViewSetNeedsDisplayInRegion( m_controlRef , where , needsDisplay ) ;
1046 else
1047 HIViewSetNeedsDisplay( m_controlRef , needsDisplay ) ;
1048 #endif
1049 }
1050 #endif
1051
1052 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
1053 {
1054 #if TARGET_API_MAC_OSX
1055 HIPoint hiPoint ;
1056 hiPoint.x = pt->x ;
1057 hiPoint.y = pt->y ;
1058 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef ) ;
1059 pt->x = (int)hiPoint.x ;
1060 pt->y = (int)hiPoint.y ;
1061 #else
1062 Rect fromRect ;
1063 Rect toRect ;
1064 from->GetRect( &fromRect ) ;
1065 to->GetRect( &toRect ) ;
1066
1067 // correct the case of the root control
1068 if ( fromRect.left == -32768 && fromRect.top == -32768 && fromRect.bottom == 32767 && fromRect.right == 32767)
1069 fromRect.left = fromRect.top = 0 ;
1070
1071 if ( toRect.left == -32768 && toRect.top == -32768 && toRect.bottom == 32767 && toRect.right == 32767 )
1072 toRect.left = toRect.top = 0 ;
1073
1074 pt->x = pt->x + fromRect.left - toRect.left ;
1075 pt->y = pt->y + fromRect.top - toRect.top ;
1076 #endif
1077 }
1078
1079 void wxMacControl::SetRect( Rect *r )
1080 {
1081 #if TARGET_API_MAC_OSX
1082 //A HIRect is actually a CGRect on OSX - which consists of two structures -
1083 //CGPoint and CGSize, which have two floats each
1084 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } } ;
1085 HIViewSetFrame ( m_controlRef , &hir ) ;
1086 #else
1087 SetControlBounds( m_controlRef , r ) ;
1088 #endif
1089
1090 }
1091
1092 void wxMacControl::GetRect( Rect *r )
1093 {
1094 GetControlBounds( m_controlRef , r ) ;
1095 }
1096
1097 void wxMacControl::GetRectInWindowCoords( Rect *r )
1098 {
1099 UMAGetControlBoundsInWindowCoords( m_controlRef , r ) ;
1100 }
1101
1102 void wxMacControl::GetBestRect( Rect *r )
1103 {
1104 short baselineoffset ;
1105 GetBestControlRect( m_controlRef , r , &baselineoffset ) ;
1106 }
1107
1108 void wxMacControl::SetTitle( const wxString &title )
1109 {
1110 wxFontEncoding encoding;
1111
1112 if ( m_font.Ok() )
1113 encoding = m_font.GetEncoding();
1114 else
1115 encoding = wxFont::GetDefaultEncoding();
1116
1117 UMASetControlTitle( m_controlRef , title , encoding ) ;
1118 }
1119
1120 void wxMacControl::GetFeatures( UInt32 * features )
1121 {
1122 GetControlFeatures( m_controlRef , features ) ;
1123 }
1124
1125 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
1126 {
1127 return GetControlRegion( m_controlRef , partCode , region ) ;
1128 }
1129
1130 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
1131 {
1132 #if TARGET_API_MAC_OSX
1133 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
1134 (other != NULL) ? other->m_controlRef : NULL) ;
1135 #else
1136 return 0 ;
1137 #endif
1138 }
1139
1140
1141 #if TARGET_API_MAC_OSX
1142 // SetNeedsDisplay would not invalidate the children
1143 static void InvalidateControlAndChildren( HIViewRef control )
1144 {
1145 HIViewSetNeedsDisplay( control , true ) ;
1146 UInt16 childrenCount = 0 ;
1147 OSStatus err = CountSubControls( control , &childrenCount ) ;
1148 if ( err == errControlIsNotEmbedder )
1149 return ;
1150 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
1151
1152 for ( UInt16 i = childrenCount ; i >=1 ; --i )
1153 {
1154 HIViewRef child ;
1155 err = GetIndexedSubControl( control , i , & child ) ;
1156 if ( err == errControlIsNotEmbedder )
1157 return ;
1158 InvalidateControlAndChildren( child ) ;
1159 }
1160 }
1161 #endif
1162
1163 void wxMacControl::InvalidateWithChildren()
1164 {
1165 #if TARGET_API_MAC_OSX
1166 InvalidateControlAndChildren( m_controlRef ) ;
1167 #endif
1168 }
1169
1170 void wxMacControl::ScrollRect( const wxRect &r , int dx , int dy )
1171 {
1172 #if TARGET_API_MAC_OSX
1173 HIRect scrollarea = CGRectMake( r.x , r.y , r.width , r.height) ;
1174 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ) ;
1175 #endif
1176 }
1177
1178
1179 // SetNeedsDisplay would not invalidate the children
1180
1181 //
1182 // Databrowser
1183 //
1184
1185 OSStatus wxMacControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1186 {
1187 return SetDataBrowserSelectionFlags( m_controlRef , options ) ;
1188 }
1189
1190 OSStatus wxMacControl::AddListViewColumn( DataBrowserListViewColumnDesc *columnDesc,
1191 DataBrowserTableViewColumnIndex position )
1192 {
1193 return AddDataBrowserListViewColumn( m_controlRef , columnDesc, position ) ;
1194 }
1195
1196 OSStatus wxMacControl::AutoSizeListViewColumns()
1197 {
1198 return AutoSizeDataBrowserListViewColumns(m_controlRef) ;
1199 }
1200
1201 OSStatus wxMacControl::SetHasScrollBars( bool horiz , bool vert )
1202 {
1203 return SetDataBrowserHasScrollBars( m_controlRef , horiz , vert ) ;
1204 }
1205
1206 OSStatus wxMacControl::SetTableViewHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1207 {
1208 return SetDataBrowserTableViewHiliteStyle( m_controlRef , hiliteStyle ) ;
1209 }
1210
1211 OSStatus wxMacControl::SetListViewHeaderBtnHeight(UInt16 height)
1212 {
1213 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef ,height ) ;
1214 }
1215
1216 OSStatus wxMacControl::SetCallbacks(const DataBrowserCallbacks * callbacks)
1217 {
1218 return SetDataBrowserCallbacks( m_controlRef , callbacks ) ;
1219 }
1220
1221 OSStatus wxMacControl::UpdateItems( DataBrowserItemID container, UInt32 numItems,
1222 const DataBrowserItemID* items,
1223 DataBrowserPropertyID preSortProperty,
1224 DataBrowserPropertyID propertyID )
1225 {
1226 return UpdateDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty, propertyID ) ;
1227 }
1228
1229 bool wxMacControl::IsItemSelected( DataBrowserItemID item )
1230 {
1231 return IsDataBrowserItemSelected( m_controlRef , item ) ;
1232 }
1233
1234 OSStatus wxMacControl::AddItems( DataBrowserItemID container, UInt32 numItems,
1235 const DataBrowserItemID* items,
1236 DataBrowserPropertyID preSortProperty )
1237 {
1238 return AddDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty ) ;
1239 }
1240
1241 OSStatus wxMacControl::RemoveItems( DataBrowserItemID container, UInt32 numItems,
1242 const DataBrowserItemID* items,
1243 DataBrowserPropertyID preSortProperty )
1244 {
1245 return RemoveDataBrowserItems( m_controlRef , container, numItems, items, preSortProperty ) ;
1246 }
1247
1248 OSStatus wxMacControl::RevealItem( DataBrowserItemID item,
1249 DataBrowserPropertyID propertyID,
1250 DataBrowserRevealOptions options )
1251 {
1252 return RevealDataBrowserItem( m_controlRef , item , propertyID , options ) ;
1253 }
1254
1255 OSStatus wxMacControl::SetSelectedItems(UInt32 numItems,
1256 const DataBrowserItemID * items,
1257 DataBrowserSetOption operation )
1258 {
1259 return SetDataBrowserSelectedItems( m_controlRef , numItems , items, operation ) ;
1260 }
1261
1262 OSStatus wxMacControl::GetSelectionAnchor( DataBrowserItemID * first, DataBrowserItemID * last )
1263 {
1264 return GetDataBrowserSelectionAnchor( m_controlRef , first , last ) ;
1265 }
1266
1267 //
1268 // Tab Control
1269 //
1270
1271 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
1272 {
1273 return ::SetTabEnabled( m_controlRef , tabNo , enable ) ;
1274 }
1275
1276 #endif // wxUSE_GUI
1277