1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mac/corefoundation/utilsexc_base.cpp
3 // Purpose: wxMacLaunch
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 /////////////////////////////////////////////////////////////////////////////
14 //===========================================================================
16 //===========================================================================
18 //---------------------------------------------------------------------------
19 // Pre-compiled header stuff
20 //---------------------------------------------------------------------------
22 // For compilers that support precompilation, includes "wx.h".
23 #include "wx/wxprec.h"
27 #include "wx/string.h"
35 #include <CoreFoundation/CoreFoundation.h>
36 #ifndef __WXOSX_IPHONE__
37 #include <ApplicationServices/ApplicationServices.h>
41 #include "wx/filename.h"
42 #include "wx/osx/core/cfstring.h"
43 #include "wx/osx/core/private.h"
46 #define kDefaultPathStyle kCFURLPOSIXPathStyle
48 extern bool WXDLLEXPORT
wxIsDebuggerRunning()
50 // TODO : try to find out ...
54 #if wxOSX_USE_COCOA_OR_CARBON
56 // have a fast version for mac code that returns the version as a return value
58 long UMAGetSystemVersion()
60 static SInt32 sUMASystemVersion
= 0 ;
61 if ( sUMASystemVersion
== 0 )
63 verify_noerr(Gestalt(gestaltSystemVersion
, &sUMASystemVersion
));
65 return sUMASystemVersion
;
68 // our OS version is the same in non GUI and GUI cases
69 wxOperatingSystemId
wxGetOsVersion(int *majorVsn
, int *minorVsn
)
72 Gestalt(gestaltSystemVersion
, &theSystem
);
74 if ( majorVsn
!= NULL
)
75 *majorVsn
= (theSystem
>> 8);
77 if ( minorVsn
!= NULL
)
78 *minorVsn
= (theSystem
& 0xFF);
80 return wxOS_MAC_OSX_DARWIN
;
83 #include <sys/utsname.h>
85 wxString
wxGetOsDescription()
89 return wxString::Format(_T("Mac OS X (%s %s %s)"),
90 wxString::FromAscii(name
.sysname
).c_str(),
91 wxString::FromAscii(name
.release
).c_str(),
92 wxString::FromAscii(name
.machine
).c_str());
95 #endif // wxOSX_USE_COCOA_OR_CARBON
97 //===========================================================================
99 //===========================================================================
101 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
105 // argv is the command line split up, with the application path first
106 // flags are the flags from wxExecute
107 // process is the process passed from wxExecute for pipe streams etc.
108 // returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
109 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
110 bool wxMacLaunch(char **argv
)
112 // Obtains the number of arguments for determining the size of
113 // the CFArray used to hold them
114 CFIndex cfiCount
= 0;
115 for(char** argvcopy
= argv
; *argvcopy
!= NULL
; ++argvcopy
)
120 // If there is not a single argument then there is no application
124 wxLogDebug(wxT("wxMacLaunch No file to launch!"));
129 wxString path
= *argv
++;
131 // Create a CFURL for the application path
132 // Created this way because we are opening a bundle which is a directory
134 CFURLCreateWithFileSystemPath(
138 true); //false == not a directory
140 // Check for error from the CFURL
143 wxLogDebug(wxT("wxMacLaunch Can't open path: %s"), path
.c_str());
147 // Create a CFBundle from the CFURL created earlier
148 CFBundleRef cfbApp
= CFBundleCreate(kCFAllocatorDefault
, cfurlApp
);
150 // Check to see if CFBundleCreate returned an error,
151 // and if it did this was an invalid bundle or not a bundle
152 // at all (maybe a simple directory etc.)
155 wxLogDebug(wxT("wxMacLaunch Bad bundle: %s"), path
.c_str());
160 // Get the bundle type and make sure its an 'APPL' bundle
161 // Otherwise we're dealing with something else here...
162 UInt32 dwBundleType
, dwBundleCreator
;
163 CFBundleGetPackageInfo(cfbApp
, &dwBundleType
, &dwBundleCreator
);
164 if(dwBundleType
!= 'APPL')
166 wxLogDebug(wxT("wxMacLaunch Not an APPL bundle: %s"), path
.c_str());
172 // Create a CFArray for dealing with the command line
173 // arguments to the bundle
174 CFMutableArrayRef cfaFiles
= CFArrayCreateMutable(kCFAllocatorDefault
,
175 cfiCount
-1, &kCFTypeArrayCallBacks
);
176 if(!cfaFiles
) //This should never happen
178 wxLogDebug(wxT("wxMacLaunch Could not create CFMutableArray"));
184 // Loop through command line arguments to the bundle,
185 // turn them into CFURLs and then put them in cfaFiles
186 // For use to launch services call
187 for( ; *argv
!= NULL
; ++argv
)
189 // Check for '<' as this will ring true for
190 // CFURLCreateWithString but is generally not considered
191 // typical on mac but is usually passed here from wxExecute
192 if (wxStrcmp(*argv
, wxT("<")) == 0)
196 CFURLRef cfurlCurrentFile
; // CFURL to hold file path
197 wxFileName
argfn(*argv
); // Filename for path
199 if(argfn
.DirExists())
201 // First, try creating as a directory
202 cfurlCurrentFile
= CFURLCreateWithFileSystemPath(
204 wxCFStringRef(*argv
),
206 true); //true == directory
208 else if(argfn
.FileExists())
210 // And if it isn't a directory try creating it
212 cfurlCurrentFile
= CFURLCreateWithFileSystemPath(
214 wxCFStringRef(*argv
),
216 false); //false == regular file
220 // Argument did not refer to
221 // an entry in the local filesystem,
222 // so try creating it through CFURLCreateWithString
223 cfurlCurrentFile
= CFURLCreateWithString(
225 wxCFStringRef(*argv
),
229 // Continue in the loop if the CFURL could not be created
230 if(!cfurlCurrentFile
)
233 wxT("wxMacLaunch Could not create CFURL for argument:%s"),
238 // Add the valid CFURL to the argument array and then
239 // release it as the CFArray adds a ref count to it
244 CFRelease(cfurlCurrentFile
); // array has retained it
247 // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
248 // Note that there are several flag options (launchFlags) such
249 // as kLSLaunchDontSwitch etc. and maybe we could be more
250 // picky about the flags we choose
251 LSLaunchURLSpec launchspec
;
252 launchspec
.appURL
= cfurlApp
;
253 launchspec
.itemURLs
= cfaFiles
;
254 launchspec
.passThruParams
= NULL
; //AEDesc*
255 launchspec
.launchFlags
= kLSLaunchDefaults
;
256 launchspec
.asyncRefCon
= NULL
;
258 // Finally, call LSOpenFromURL spec with our arguments
259 // 2nd parameter is a pointer to a CFURL that gets
260 // the actual path launched by the function
261 OSStatus status
= LSOpenFromURLSpec(&launchspec
, NULL
);
263 // Cleanup corefoundation references
268 // Check for error from LSOpenFromURLSpec
271 wxLogDebug(wxT("wxMacLaunch LSOpenFromURLSpec Error: %d"),
276 // No error from LSOpenFromURLSpec, so app was launched