]> git.saurik.com Git - wxWidgets.git/blame - src/osx/core/utilsexc_base.cpp
Set the menu itself as event object for EVT_MENU_{OPEN,CLOSED} in wxMSW.
[wxWidgets.git] / src / osx / core / utilsexc_base.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/osx/core/utilsexc_base.cpp
489468fe
SC
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
26632ccd 57#if ( !wxUSE_GUI && !wxOSX_USE_IPHONE ) || wxOSX_USE_COCOA_OR_CARBON
b2767951
KO
58
59// have a fast version for mac code that returns the version as a return value
60
03647350
VZ
61long UMAGetSystemVersion()
62{
b2767951
KO
63 static SInt32 sUMASystemVersion = 0 ;
64 if ( sUMASystemVersion == 0 )
65 {
66 verify_noerr(Gestalt(gestaltSystemVersion, &sUMASystemVersion));
67 }
03647350 68 return sUMASystemVersion ;
b2767951
KO
69}
70
71// our OS version is the same in non GUI and GUI cases
72wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn)
73{
5755acd7
JS
74 // This returns 10 and 6 for OS X 10.6, consistent with behaviour on
75 // other platforms.
76 SInt32 maj, min;
77 Gestalt(gestaltSystemVersionMajor, &maj);
78 Gestalt(gestaltSystemVersionMinor, &min);
79
80 if ( majorVsn != NULL )
81 *majorVsn = maj;
82
83 if ( minorVsn != NULL )
84 *minorVsn = min;
85
86#if 0
b2767951
KO
87 SInt32 theSystem;
88 Gestalt(gestaltSystemVersion, &theSystem);
89
90 if ( majorVsn != NULL )
91 *majorVsn = (theSystem >> 8);
92
93 if ( minorVsn != NULL )
94 *minorVsn = (theSystem & 0xFF);
5755acd7 95#endif
b2767951
KO
96 return wxOS_MAC_OSX_DARWIN;
97}
98
99#include <sys/utsname.h>
100
101wxString wxGetOsDescription()
102{
103 struct utsname name;
104 uname(&name);
9a83f860 105 return wxString::Format(wxT("Mac OS X (%s %s %s)"),
b2767951
KO
106 wxString::FromAscii(name.sysname).c_str(),
107 wxString::FromAscii(name.release).c_str(),
108 wxString::FromAscii(name.machine).c_str());
109}
110
489468fe
SC
111//===========================================================================
112// IMPLEMENTATION
113//===========================================================================
114
115//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
116//
117// wxMacLaunch
118//
119// argv is the command line split up, with the application path first
120// flags are the flags from wxExecute
121// process is the process passed from wxExecute for pipe streams etc.
122// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
123//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
124bool wxMacLaunch(char **argv)
125{
126 // Obtains the number of arguments for determining the size of
127 // the CFArray used to hold them
128 CFIndex cfiCount = 0;
129 for(char** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
130 {
131 ++cfiCount;
132 }
133
134 // If there is not a single argument then there is no application
135 // to launch
136 if(cfiCount == 0)
137 {
138 wxLogDebug(wxT("wxMacLaunch No file to launch!"));
139 return false ;
140 }
141
142 // Path to bundle
143 wxString path = *argv++;
144
145 // Create a CFURL for the application path
146 // Created this way because we are opening a bundle which is a directory
147 CFURLRef cfurlApp =
148 CFURLCreateWithFileSystemPath(
149 kCFAllocatorDefault,
150 wxCFStringRef(path),
151 kDefaultPathStyle,
152 true); //false == not a directory
153
154 // Check for error from the CFURL
155 if(!cfurlApp)
156 {
157 wxLogDebug(wxT("wxMacLaunch Can't open path: %s"), path.c_str());
158 return false ;
159 }
160
161 // Create a CFBundle from the CFURL created earlier
162 CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
163
164 // Check to see if CFBundleCreate returned an error,
165 // and if it did this was an invalid bundle or not a bundle
166 // at all (maybe a simple directory etc.)
167 if(!cfbApp)
168 {
169 wxLogDebug(wxT("wxMacLaunch Bad bundle: %s"), path.c_str());
170 CFRelease(cfurlApp);
171 return false ;
172 }
173
174 // Get the bundle type and make sure its an 'APPL' bundle
175 // Otherwise we're dealing with something else here...
176 UInt32 dwBundleType, dwBundleCreator;
177 CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
178 if(dwBundleType != 'APPL')
179 {
180 wxLogDebug(wxT("wxMacLaunch Not an APPL bundle: %s"), path.c_str());
181 CFRelease(cfbApp);
182 CFRelease(cfurlApp);
183 return false ;
184 }
185
186 // Create a CFArray for dealing with the command line
187 // arguments to the bundle
188 CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
189 cfiCount-1, &kCFTypeArrayCallBacks);
190 if(!cfaFiles) //This should never happen
191 {
192 wxLogDebug(wxT("wxMacLaunch Could not create CFMutableArray"));
193 CFRelease(cfbApp);
194 CFRelease(cfurlApp);
195 return false ;
196 }
197
198 // Loop through command line arguments to the bundle,
199 // turn them into CFURLs and then put them in cfaFiles
200 // For use to launch services call
65391c8f
PC
201 for( ; *argv != NULL ; ++argv)
202 {
489468fe
SC
203 // Check for '<' as this will ring true for
204 // CFURLCreateWithString but is generally not considered
205 // typical on mac but is usually passed here from wxExecute
206 if (wxStrcmp(*argv, wxT("<")) == 0)
207 continue;
208
209
210 CFURLRef cfurlCurrentFile; // CFURL to hold file path
211 wxFileName argfn(*argv); // Filename for path
212
213 if(argfn.DirExists())
214 {
215 // First, try creating as a directory
216 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
217 kCFAllocatorDefault,
218 wxCFStringRef(*argv),
219 kDefaultPathStyle,
220 true); //true == directory
221 }
222 else if(argfn.FileExists())
223 {
224 // And if it isn't a directory try creating it
225 // as a regular file
226 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
227 kCFAllocatorDefault,
228 wxCFStringRef(*argv),
229 kDefaultPathStyle,
230 false); //false == regular file
231 }
232 else
233 {
234 // Argument did not refer to
235 // an entry in the local filesystem,
236 // so try creating it through CFURLCreateWithString
237 cfurlCurrentFile = CFURLCreateWithString(
238 kCFAllocatorDefault,
239 wxCFStringRef(*argv),
240 NULL);
241 }
242
243 // Continue in the loop if the CFURL could not be created
244 if(!cfurlCurrentFile)
245 {
246 wxLogDebug(
247 wxT("wxMacLaunch Could not create CFURL for argument:%s"),
248 *argv);
249 continue;
250 }
251
252 // Add the valid CFURL to the argument array and then
253 // release it as the CFArray adds a ref count to it
65391c8f
PC
254 CFArrayAppendValue(
255 cfaFiles,
256 cfurlCurrentFile
257 );
258 CFRelease(cfurlCurrentFile); // array has retained it
259 }
489468fe
SC
260
261 // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
262 // Note that there are several flag options (launchFlags) such
263 // as kLSLaunchDontSwitch etc. and maybe we could be more
264 // picky about the flags we choose
265 LSLaunchURLSpec launchspec;
266 launchspec.appURL = cfurlApp;
267 launchspec.itemURLs = cfaFiles;
268 launchspec.passThruParams = NULL; //AEDesc*
269 launchspec.launchFlags = kLSLaunchDefaults;
270 launchspec.asyncRefCon = NULL;
271
272 // Finally, call LSOpenFromURL spec with our arguments
273 // 2nd parameter is a pointer to a CFURL that gets
274 // the actual path launched by the function
275 OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);
276
277 // Cleanup corefoundation references
278 CFRelease(cfbApp);
279 CFRelease(cfurlApp);
280 CFRelease(cfaFiles);
281
282 // Check for error from LSOpenFromURLSpec
283 if(status != noErr)
284 {
285 wxLogDebug(wxT("wxMacLaunch LSOpenFromURLSpec Error: %d"),
286 (int)status);
287 return false ;
288 }
289
290 // No error from LSOpenFromURLSpec, so app was launched
291 return true ;
292}
293
7c38b3a5 294#endif // wxOSX_USE_COCOA_OR_CARBON