]> git.saurik.com Git - wxWidgets.git/blame - src/mac/corefoundation/utilsexc_base.cpp
Removed redundant iostream inclusion
[wxWidgets.git] / src / mac / corefoundation / utilsexc_base.cpp
CommitLineData
1ccb7433
DE
1/////////////////////////////////////////////////////////////////////////////
2// Name: mac/corefoundation/utilsexc_base.cpp
3// Purpose: wxMacExecute
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
7db33dd7
SC
14//===========================================================================
15// DECLARATIONS
16//===========================================================================
17
18//---------------------------------------------------------------------------
19// Pre-compiled header stuff
20//---------------------------------------------------------------------------
21
1ccb7433
DE
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
7db33dd7
SC
24
25// WX includes
1ccb7433
DE
26#ifndef WX_PRECOMP
27 #include "wx/string.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #include "wx/utils.h"
cdfc78b8 31 #include "wx/wxcrt.h"
1ccb7433
DE
32#endif // WX_PRECOMP
33
7db33dd7 34// Mac Includes
1ccb7433
DE
35#include <CoreFoundation/CoreFoundation.h>
36#include <ApplicationServices/ApplicationServices.h>
37
7db33dd7
SC
38// More WX Includes
39#include "wx/filename.h"
1ccb7433
DE
40#include "wx/mac/corefoundation/cfstring.h"
41
7db33dd7
SC
42// Default path style
43#ifdef __WXMAC_OSX__
44#define kDefaultPathStyle kCFURLPOSIXPathStyle
45#else
46#define kDefaultPathStyle kCFURLHFSPathStyle
47#endif
48
49//===========================================================================
50// IMPLEMENTATION
51//===========================================================================
52
53//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54//
a8d69700 55// wxMacExecute
7db33dd7
SC
56//
57// argv is the command line split up, with the application path first
a8d69700 58// flags are the flags from wxExecute
7db33dd7
SC
59// process is the process passed from wxExecute for pipe streams etc.
60// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
61//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1ccb7433
DE
62long wxMacExecute(wxChar **argv,
63 int flags,
0a81a01a 64 wxProcess *WXUNUSED(process))
1ccb7433 65{
7db33dd7 66 // Semi-macros used for return value of wxMacExecute
a8d69700
VZ
67 const long errorCode = ((flags & wxEXEC_SYNC) ? -1 : 0);
68 const long successCode = ((flags & wxEXEC_SYNC) ? 0 : -1); // fake PID
1ccb7433 69
7db33dd7
SC
70 // Obtains the number of arguments for determining the size of
71 // the CFArray used to hold them
1ccb7433 72 CFIndex cfiCount = 0;
1ccb7433
DE
73 for(wxChar** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
74 {
75 ++cfiCount;
76 }
77
7db33dd7
SC
78 // If there is not a single argument then there is no application
79 // to launch
80 if(cfiCount == 0)
1ccb7433
DE
81 {
82 wxLogDebug(wxT("wxMacExecute No file to launch!"));
83 return errorCode ;
84 }
a8d69700 85
7db33dd7
SC
86 // Path to bundle
87 wxString path = *argv++;
88
89 // Create a CFURL for the application path
90 // Created this way because we are opening a bundle which is a directory
a8d69700 91 CFURLRef cfurlApp =
7db33dd7 92 CFURLCreateWithFileSystemPath(
1ccb7433 93 kCFAllocatorDefault,
a8d69700
VZ
94 wxMacCFStringHolder(path),
95 kDefaultPathStyle,
7db33dd7 96 true); //false == not a directory
1ccb7433 97
7db33dd7
SC
98 // Check for error from the CFURL
99 if(!cfurlApp)
100 {
101 wxLogDebug(wxT("wxMacExecute Can't open path: %s"), path.c_str());
102 return errorCode ;
103 }
104
105 // Create a CFBundle from the CFURL created earlier
1ccb7433 106 CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
7db33dd7
SC
107
108 // Check to see if CFBundleCreate returned an error,
109 // and if it did this was an invalid bundle or not a bundle
110 // at all (maybe a simple directory etc.)
1ccb7433
DE
111 if(!cfbApp)
112 {
7db33dd7 113 wxLogDebug(wxT("wxMacExecute Bad bundle: %s"), path.c_str());
1ccb7433
DE
114 CFRelease(cfurlApp);
115 return errorCode ;
116 }
a8d69700 117
7db33dd7
SC
118 // Get the bundle type and make sure its an 'APPL' bundle
119 // Otherwise we're dealing with something else here...
1ccb7433
DE
120 UInt32 dwBundleType, dwBundleCreator;
121 CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
1ccb7433
DE
122 if(dwBundleType != 'APPL')
123 {
7db33dd7
SC
124 wxLogDebug(wxT("wxMacExecute Not an APPL bundle: %s"), path.c_str());
125 CFRelease(cfbApp);
1ccb7433
DE
126 CFRelease(cfurlApp);
127 return errorCode ;
128 }
a8d69700 129
7db33dd7
SC
130 // Create a CFArray for dealing with the command line
131 // arguments to the bundle
a8d69700 132 CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
7db33dd7
SC
133 cfiCount-1, &kCFTypeArrayCallBacks);
134 if(!cfaFiles) //This should never happen
1ccb7433 135 {
a8d69700 136 wxLogDebug(wxT("wxMacExecute Could not create CFMutableArray"));
7db33dd7
SC
137 CFRelease(cfbApp);
138 CFRelease(cfurlApp);
139 return errorCode ;
140 }
a8d69700 141
7db33dd7
SC
142 // Loop through command line arguments to the bundle,
143 // turn them into CFURLs and then put them in cfaFiles
144 // For use to launch services call
1ccb7433
DE
145 for( ; *argv != NULL ; ++argv)
146 {
a8d69700 147 // Check for '<' as this will ring true for
7db33dd7
SC
148 // CFURLCreateWithString but is generally not considered
149 // typical on mac but is usually passed here from wxExecute
150 if (wxStrcmp(*argv, wxT("<")) == 0)
151 continue;
a8d69700
VZ
152
153
154 CFURLRef cfurlCurrentFile; // CFURL to hold file path
155 wxFileName argfn(*argv); // Filename for path
156
7db33dd7
SC
157 if(argfn.DirExists())
158 {
159 // First, try creating as a directory
160 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
161 kCFAllocatorDefault,
a8d69700
VZ
162 wxMacCFStringHolder(*argv),
163 kDefaultPathStyle,
7db33dd7
SC
164 true); //true == directory
165 }
166 else if(argfn.FileExists())
167 {
168 // And if it isn't a directory try creating it
169 // as a regular file
170 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
171 kCFAllocatorDefault,
a8d69700
VZ
172 wxMacCFStringHolder(*argv),
173 kDefaultPathStyle,
7db33dd7 174 false); //false == regular file
a8d69700 175 }
7db33dd7
SC
176 else
177 {
178 // Argument did not refer to
179 // an entry in the local filesystem,
180 // so try creating it through CFURLCreateWithString
181 cfurlCurrentFile = CFURLCreateWithString(
a8d69700
VZ
182 kCFAllocatorDefault,
183 wxMacCFStringHolder(*argv),
184 NULL);
7db33dd7 185 }
a8d69700 186
7db33dd7
SC
187 // Continue in the loop if the CFURL could not be created
188 if(!cfurlCurrentFile)
189 {
190 wxLogDebug(
a8d69700 191 wxT("wxMacExecute Could not create CFURL for argument:%s"),
7db33dd7
SC
192 *argv);
193 continue;
194 }
1ccb7433 195
7db33dd7
SC
196 // Add the valid CFURL to the argument array and then
197 // release it as the CFArray adds a ref count to it
1ccb7433
DE
198 CFArrayAppendValue(
199 cfaFiles,
200 cfurlCurrentFile
201 );
202 CFRelease(cfurlCurrentFile); // array has retained it
203 }
a8d69700 204
7db33dd7
SC
205 // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
206 // Note that there are several flag options (launchFlags) such
207 // as kLSLaunchDontSwitch etc. and maybe we could be more
208 // picky about the flags we choose
1ccb7433
DE
209 LSLaunchURLSpec launchspec;
210 launchspec.appURL = cfurlApp;
211 launchspec.itemURLs = cfaFiles;
a8d69700
VZ
212 launchspec.passThruParams = NULL; //AEDesc*
213 launchspec.launchFlags = kLSLaunchDefaults;
1ccb7433 214 launchspec.asyncRefCon = NULL;
a8d69700 215
7db33dd7
SC
216 // Finally, call LSOpenFromURL spec with our arguments
217 // 2nd parameter is a pointer to a CFURL that gets
218 // the actual path launched by the function
219 OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);
1ccb7433 220
7db33dd7
SC
221 // Cleanup corefoundation references
222 CFRelease(cfbApp);
1ccb7433
DE
223 CFRelease(cfurlApp);
224 CFRelease(cfaFiles);
a8d69700 225
7db33dd7 226 // Check for error from LSOpenFromURLSpec
1ccb7433
DE
227 if(status != noErr)
228 {
a8d69700 229 wxLogDebug(wxT("wxMacExecute LSOpenFromURLSpec Error: %d"),
7db33dd7 230 (int)status);
1ccb7433
DE
231 return errorCode ;
232 }
a8d69700 233
7db33dd7 234 // No error from LSOpenFromURLSpec, so app was launched
a8d69700 235 return successCode;
1ccb7433
DE
236}
237