avoiding reentrancy problems and congestion
[wxWidgets.git] / src / osx / utils_osx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/utils_osx.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
13 #include "wx/wxprec.h"
14
15 #include "wx/utils.h"
16
17 #ifndef WX_PRECOMP
18 #include "wx/intl.h"
19 #include "wx/app.h"
20 #include "wx/log.h"
21 #if wxUSE_GUI
22 #include "wx/toplevel.h"
23 #include "wx/font.h"
24 #endif
25 #endif
26
27 #include "wx/apptrait.h"
28
29 #include <ctype.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35
36 // #include "MoreFilesX.h"
37
38 #include <AudioToolbox/AudioServices.h>
39
40 #include "wx/osx/private.h"
41 #include "wx/osx/private/timer.h"
42
43 #include "wx/evtloop.h"
44
45 // Check whether this window wants to process messages, e.g. Stop button
46 // in long calculations.
47 bool wxCheckForInterrupt(wxWindow *WXUNUSED(wnd))
48 {
49 // TODO
50 return false;
51 }
52
53 // Return true if we have a colour display
54 bool wxColourDisplay()
55 {
56 // always the case on OS X
57 return true;
58 }
59
60
61 #if wxOSX_USE_COCOA_OR_CARBON
62
63 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1070) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
64 // bring back declaration so that we can support deployment targets < 10_6
65 CG_EXTERN size_t CGDisplayBitsPerPixel(CGDirectDisplayID display)
66 CG_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6,
67 __IPHONE_NA, __IPHONE_NA);
68 #endif
69
70 // Returns depth of screen
71 int wxDisplayDepth()
72 {
73 int theDepth = 0;
74
75 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
76 if ( UMAGetSystemVersion() >= 0x1060 )
77 {
78 CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
79 CFStringRef encoding = CGDisplayModeCopyPixelEncoding(currentMode);
80
81 if(CFStringCompare(encoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
82 theDepth = 32;
83 else if(CFStringCompare(encoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
84 theDepth = 16;
85 else if(CFStringCompare(encoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
86 theDepth = 8;
87 else
88 theDepth = 32; // some reasonable default
89
90 CFRelease(encoding);
91 CGDisplayModeRelease(currentMode);
92 }
93 else
94 #endif
95 {
96 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
97 theDepth = (int) CGDisplayBitsPerPixel(CGMainDisplayID());
98 #endif
99 }
100 return theDepth;
101 }
102
103 // Get size of display
104 void wxDisplaySize(int *width, int *height)
105 {
106 // TODO adapt for multi-displays
107 CGRect bounds = CGDisplayBounds(CGMainDisplayID());
108 if ( width )
109 *width = (int)bounds.size.width ;
110 if ( height )
111 *height = (int)bounds.size.height;
112 }
113
114 #if wxUSE_GUI
115
116 // ----------------------------------------------------------------------------
117 // Launch document with default app
118 // ----------------------------------------------------------------------------
119
120 bool wxLaunchDefaultApplication(const wxString& document, int flags)
121 {
122 wxUnusedVar(flags);
123
124 wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(document)));
125 CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
126 wxCFRef<CFURLRef> curl(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
127 OSStatus err = LSOpenCFURLRef( curl , NULL );
128
129 if (err == noErr)
130 {
131 return true;
132 }
133 else
134 {
135 wxLogDebug(wxT("Default Application Launch error %d"), (int) err);
136 return false;
137 }
138 }
139
140 // ----------------------------------------------------------------------------
141 // Launch default browser
142 // ----------------------------------------------------------------------------
143
144 bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
145 {
146 wxUnusedVar(flags);
147 wxCFRef< CFURLRef > curl( CFURLCreateWithString( kCFAllocatorDefault,
148 wxCFStringRef( url ), NULL ) );
149 OSStatus err = LSOpenCFURLRef( curl , NULL );
150
151 if (err == noErr)
152 {
153 return true;
154 }
155 else
156 {
157 wxLogDebug(wxT("Browser Launch error %d"), (int) err);
158 return false;
159 }
160 }
161
162 #endif // wxUSE_GUI
163
164 #endif
165
166 void wxDisplaySizeMM(int *width, int *height)
167 {
168 wxDisplaySize(width, height);
169 // on mac 72 is fixed (at least now;-)
170 double cvPt2Mm = 25.4 / 72;
171
172 if (width != NULL)
173 *width = int( *width * cvPt2Mm );
174
175 if (height != NULL)
176 *height = int( *height * cvPt2Mm );
177 }
178
179
180 wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
181 {
182 // We suppose that toolkit version is the same as OS version under Mac
183 wxGetOsVersion(verMaj, verMin);
184
185 return wxPORT_OSX;
186 }
187
188 wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
189 {
190 return new wxEventLoop;
191 }
192
193 wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt);
194
195 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
196 {
197 #if wxOSX_USE_CARBON
198
199 Point screenPoint = { pt.y , pt.x };
200 WindowRef windowRef;
201
202 if ( FindWindow( screenPoint , &windowRef ) )
203 {
204 wxNonOwnedWindow *nonOwned = wxNonOwnedWindow::GetFromWXWindow( windowRef );
205
206 if ( nonOwned )
207 return wxFindWindowAtPoint( nonOwned , pt );
208 }
209
210 return NULL;
211
212 #else
213
214 return wxGenericFindWindowAtPoint( pt );
215
216 #endif
217 }
218
219 /*
220 Return the generic RGB color space. This is a 'get' function and the caller should
221 not release the returned value unless the caller retains it first. Usually callers
222 of this routine will immediately use the returned colorspace with CoreGraphics
223 so they typically do not need to retain it themselves.
224
225 This function creates the generic RGB color space once and hangs onto it so it can
226 return it whenever this function is called.
227 */
228
229 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
230 {
231 static wxCFRef<CGColorSpaceRef> genericRGBColorSpace;
232
233 if (genericRGBColorSpace == NULL)
234 {
235 #if wxOSX_USE_IPHONE
236 genericRGBColorSpace.reset( CGColorSpaceCreateDeviceRGB() );
237 #else
238 genericRGBColorSpace.reset( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) );
239 #endif
240 }
241
242 return genericRGBColorSpace;
243 }
244
245 #if wxOSX_USE_COCOA_OR_CARBON
246
247 CGColorRef wxMacCreateCGColorFromHITheme( ThemeBrush brush )
248 {
249 const int maxcachedbrush = 58+5; // negative indices are for metabrushes, cache down to -5)
250 int brushindex = brush+5;
251 if ( brushindex < 0 || brushindex > maxcachedbrush )
252 {
253 CGColorRef color ;
254 HIThemeBrushCreateCGColor( brush, &color );
255 return color;
256 }
257 else
258 {
259 static bool inited = false;
260 static CGColorRef themecolors[maxcachedbrush+1];
261 if ( !inited )
262 {
263 for ( int i = 0 ; i <= maxcachedbrush ; ++i )
264 HIThemeBrushCreateCGColor( i-5, &themecolors[i] );
265 inited = true;
266 }
267 return CGColorRetain(themecolors[brushindex ]);
268 }
269 }
270
271 //---------------------------------------------------------------------------
272 // Mac Specific string utility functions
273 //---------------------------------------------------------------------------
274
275 void wxMacStringToPascal( const wxString&from , unsigned char * to )
276 {
277 wxCharBuffer buf = from.mb_str( wxConvLocal );
278 int len = strlen(buf);
279
280 if ( len > 255 )
281 len = 255;
282 to[0] = len;
283 memcpy( (char*) &to[1] , buf , len );
284 }
285
286 wxString wxMacMakeStringFromPascal( const unsigned char * from )
287 {
288 return wxString( (char*) &from[1] , wxConvLocal , from[0] );
289 }
290
291 #endif // wxOSX_USE_COCOA_OR_CARBON