]> git.saurik.com Git - wxWidgets.git/blame - src/osx/core/utilsexc_base.cpp
Fix crash in wxColour ctor from NSColor in wxOSX/Cocoa.
[wxWidgets.git] / src / osx / core / utilsexc_base.cpp
CommitLineData
489468fe
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: mac/corefoundation/utilsexc_base.cpp
3// Purpose: wxMacLaunch
4// Author: Ryan Norton
5// Modified by:
6// Created: 2005-06-21
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10// Notes: Source was originally in utilsexc_cf.cpp,1.6 then moved
11// to totally unrelated hid.cpp,1.8.
12/////////////////////////////////////////////////////////////////////////////
13
14//===========================================================================
15// DECLARATIONS
16//===========================================================================
17
18//---------------------------------------------------------------------------
19// Pre-compiled header stuff
20//---------------------------------------------------------------------------
21
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
24
25// WX includes
26#ifndef WX_PRECOMP
27 #include "wx/string.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #include "wx/utils.h"
31 #include "wx/wxcrt.h"
32#endif // WX_PRECOMP
33
34// Mac Includes
35#include <CoreFoundation/CoreFoundation.h>
36#ifndef __WXOSX_IPHONE__
37#include <ApplicationServices/ApplicationServices.h>
38#endif
39
40// More WX Includes
41#include "wx/filename.h"
c8ef3d55 42#include "wx/osx/core/cfstring.h"
b2767951 43#include "wx/osx/core/private.h"
489468fe
SC
44
45// Default path style
46#define kDefaultPathStyle kCFURLPOSIXPathStyle
47
5815e959
VZ
48#if wxUSE_SOCKETS
49// global pointer which lives in the base library, set from the net one (see
50// sockosx.cpp) and used from the GUI code (see utilsexc_cf.cpp) -- ugly but
51// needed hack, see the above-mentioned files for more information
52class wxSocketManager;
53extern WXDLLIMPEXP_BASE wxSocketManager *wxOSXSocketManagerCF;
54wxSocketManager *wxOSXSocketManagerCF = NULL;
55#endif // wxUSE_SOCKETS
56
b2767951
KO
57extern bool WXDLLEXPORT wxIsDebuggerRunning()
58{
59 // TODO : try to find out ...
60 return false;
61}
62
63#if wxOSX_USE_COCOA_OR_CARBON
64
65// have a fast version for mac code that returns the version as a return value
66
03647350
VZ
67long UMAGetSystemVersion()
68{
b2767951
KO
69 static SInt32 sUMASystemVersion = 0 ;
70 if ( sUMASystemVersion == 0 )
71 {
72 verify_noerr(Gestalt(gestaltSystemVersion, &sUMASystemVersion));
73 }
03647350 74 return sUMASystemVersion ;
b2767951
KO
75}
76
77// our OS version is the same in non GUI and GUI cases
78wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn)
79{
80 SInt32 theSystem;
81 Gestalt(gestaltSystemVersion, &theSystem);
82
83 if ( majorVsn != NULL )
84 *majorVsn = (theSystem >> 8);
85
86 if ( minorVsn != NULL )
87 *minorVsn = (theSystem & 0xFF);
88
89 return wxOS_MAC_OSX_DARWIN;
90}
91
92#include <sys/utsname.h>
93
94wxString wxGetOsDescription()
95{
96 struct utsname name;
97 uname(&name);
9a83f860 98 return wxString::Format(wxT("Mac OS X (%s %s %s)"),
b2767951
KO
99 wxString::FromAscii(name.sysname).c_str(),
100 wxString::FromAscii(name.release).c_str(),
101 wxString::FromAscii(name.machine).c_str());
102}
103
489468fe
SC
104//===========================================================================
105// IMPLEMENTATION
106//===========================================================================
107
108//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
109//
110// wxMacLaunch
111//
112// argv is the command line split up, with the application path first
113// flags are the flags from wxExecute
114// process is the process passed from wxExecute for pipe streams etc.
115// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
116//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
117bool wxMacLaunch(char **argv)
118{
119 // Obtains the number of arguments for determining the size of
120 // the CFArray used to hold them
121 CFIndex cfiCount = 0;
122 for(char** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
123 {
124 ++cfiCount;
125 }
126
127 // If there is not a single argument then there is no application
128 // to launch
129 if(cfiCount == 0)
130 {
131 wxLogDebug(wxT("wxMacLaunch No file to launch!"));
132 return false ;
133 }
134
135 // Path to bundle
136 wxString path = *argv++;
137
138 // Create a CFURL for the application path
139 // Created this way because we are opening a bundle which is a directory
140 CFURLRef cfurlApp =
141 CFURLCreateWithFileSystemPath(
142 kCFAllocatorDefault,
143 wxCFStringRef(path),
144 kDefaultPathStyle,
145 true); //false == not a directory
146
147 // Check for error from the CFURL
148 if(!cfurlApp)
149 {
150 wxLogDebug(wxT("wxMacLaunch Can't open path: %s"), path.c_str());
151 return false ;
152 }
153
154 // Create a CFBundle from the CFURL created earlier
155 CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
156
157 // Check to see if CFBundleCreate returned an error,
158 // and if it did this was an invalid bundle or not a bundle
159 // at all (maybe a simple directory etc.)
160 if(!cfbApp)
161 {
162 wxLogDebug(wxT("wxMacLaunch Bad bundle: %s"), path.c_str());
163 CFRelease(cfurlApp);
164 return false ;
165 }
166
167 // Get the bundle type and make sure its an 'APPL' bundle
168 // Otherwise we're dealing with something else here...
169 UInt32 dwBundleType, dwBundleCreator;
170 CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
171 if(dwBundleType != 'APPL')
172 {
173 wxLogDebug(wxT("wxMacLaunch Not an APPL bundle: %s"), path.c_str());
174 CFRelease(cfbApp);
175 CFRelease(cfurlApp);
176 return false ;
177 }
178
179 // Create a CFArray for dealing with the command line
180 // arguments to the bundle
181 CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
182 cfiCount-1, &kCFTypeArrayCallBacks);
183 if(!cfaFiles) //This should never happen
184 {
185 wxLogDebug(wxT("wxMacLaunch Could not create CFMutableArray"));
186 CFRelease(cfbApp);
187 CFRelease(cfurlApp);
188 return false ;
189 }
190
191 // Loop through command line arguments to the bundle,
192 // turn them into CFURLs and then put them in cfaFiles
193 // For use to launch services call
65391c8f
PC
194 for( ; *argv != NULL ; ++argv)
195 {
489468fe
SC
196 // Check for '<' as this will ring true for
197 // CFURLCreateWithString but is generally not considered
198 // typical on mac but is usually passed here from wxExecute
199 if (wxStrcmp(*argv, wxT("<")) == 0)
200 continue;
201
202
203 CFURLRef cfurlCurrentFile; // CFURL to hold file path
204 wxFileName argfn(*argv); // Filename for path
205
206 if(argfn.DirExists())
207 {
208 // First, try creating as a directory
209 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
210 kCFAllocatorDefault,
211 wxCFStringRef(*argv),
212 kDefaultPathStyle,
213 true); //true == directory
214 }
215 else if(argfn.FileExists())
216 {
217 // And if it isn't a directory try creating it
218 // as a regular file
219 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
220 kCFAllocatorDefault,
221 wxCFStringRef(*argv),
222 kDefaultPathStyle,
223 false); //false == regular file
224 }
225 else
226 {
227 // Argument did not refer to
228 // an entry in the local filesystem,
229 // so try creating it through CFURLCreateWithString
230 cfurlCurrentFile = CFURLCreateWithString(
231 kCFAllocatorDefault,
232 wxCFStringRef(*argv),
233 NULL);
234 }
235
236 // Continue in the loop if the CFURL could not be created
237 if(!cfurlCurrentFile)
238 {
239 wxLogDebug(
240 wxT("wxMacLaunch Could not create CFURL for argument:%s"),
241 *argv);
242 continue;
243 }
244
245 // Add the valid CFURL to the argument array and then
246 // release it as the CFArray adds a ref count to it
65391c8f
PC
247 CFArrayAppendValue(
248 cfaFiles,
249 cfurlCurrentFile
250 );
251 CFRelease(cfurlCurrentFile); // array has retained it
252 }
489468fe
SC
253
254 // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
255 // Note that there are several flag options (launchFlags) such
256 // as kLSLaunchDontSwitch etc. and maybe we could be more
257 // picky about the flags we choose
258 LSLaunchURLSpec launchspec;
259 launchspec.appURL = cfurlApp;
260 launchspec.itemURLs = cfaFiles;
261 launchspec.passThruParams = NULL; //AEDesc*
262 launchspec.launchFlags = kLSLaunchDefaults;
263 launchspec.asyncRefCon = NULL;
264
265 // Finally, call LSOpenFromURL spec with our arguments
266 // 2nd parameter is a pointer to a CFURL that gets
267 // the actual path launched by the function
268 OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);
269
270 // Cleanup corefoundation references
271 CFRelease(cfbApp);
272 CFRelease(cfurlApp);
273 CFRelease(cfaFiles);
274
275 // Check for error from LSOpenFromURLSpec
276 if(status != noErr)
277 {
278 wxLogDebug(wxT("wxMacLaunch LSOpenFromURLSpec Error: %d"),
279 (int)status);
280 return false ;
281 }
282
283 // No error from LSOpenFromURLSpec, so app was launched
284 return true ;
285}
286
7c38b3a5 287#endif // wxOSX_USE_COCOA_OR_CARBON