]> git.saurik.com Git - wxWidgets.git/blame - src/osx/core/utilsexc_cf.cpp
follow up parent chain to properly support modal dialog parents, see #15383
[wxWidgets.git] / src / osx / core / utilsexc_cf.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/osx/core/utilsexc_cf.cpp
489468fe
SC
3// Purpose: Execution-related utilities for Darwin
4// Author: David Elliott, Ryan Norton (wxMacExecute)
5// Modified by: Stefan Csomor (added necessary wxT for unicode builds)
6// Created: 2004-11-04
489468fe 7// Copyright: (c) David Elliott, Ryan Norton
821d856a 8// (c) 2013 Rob Bresalier
489468fe 9// Licence: wxWindows licence
524c47aa 10// Notes: This code comes from src/osx/carbon/utilsexc.cpp,1.11
489468fe
SC
11/////////////////////////////////////////////////////////////////////////////
12
13#include "wx/wxprec.h"
14#ifndef WX_PRECOMP
15 #include "wx/log.h"
16 #include "wx/utils.h"
17#endif //ndef WX_PRECOMP
489468fe
SC
18#include "wx/stdpaths.h"
19#include "wx/app.h"
20#include "wx/apptrait.h"
21#include "wx/thread.h"
22#include "wx/process.h"
23
71e9885b
VZ
24#include "wx/evtloop.h"
25#include "wx/evtloopsrc.h"
26#include "wx/private/eventloopsourcesmanager.h"
27
489468fe
SC
28#include <sys/wait.h>
29
30#include <CoreFoundation/CFSocket.h>
31
71e9885b
VZ
32#if wxUSE_EVENTLOOP_SOURCE
33
34namespace
35{
36
a25b76f5 37extern "C"
71e9885b 38void
a25b76f5
VZ
39wx_socket_callback(CFSocketRef WXUNUSED(s),
40 CFSocketCallBackType callbackType,
41 CFDataRef WXUNUSED(address),
42 void const *WXUNUSED(data),
43 void *ctxData)
71e9885b
VZ
44{
45 wxLogTrace(wxTRACE_EVT_SOURCE,
821d856a 46 "CFSocket callback, type=%d", static_cast<int>(callbackType));
71e9885b
VZ
47
48 wxCFEventLoopSource * const
49 source = static_cast<wxCFEventLoopSource *>(ctxData);
50
51 wxEventLoopSourceHandler * const
52 handler = source->GetHandler();
71e9885b 53
a25b76f5
VZ
54 switch ( callbackType )
55 {
56 case kCFSocketReadCallBack:
57 handler->OnReadWaiting();
58 break;
59
60 case kCFSocketWriteCallBack:
61 handler->OnWriteWaiting();
62 break;
63
64 default:
65 wxFAIL_MSG( "Unexpected callback type." );
66 }
71e9885b
VZ
67}
68
69} // anonymous namespace
70
71class wxCFEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
72{
73public:
74 wxEventLoopSource *
75 AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags)
76 {
77 wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
78
79 wxScopedPtr<wxCFEventLoopSource>
80 source(new wxCFEventLoopSource(handler, flags));
81
a25b76f5
VZ
82 CFSocketContext context = { 0, source.get(), NULL, NULL, NULL };
83
84 int callbackTypes = 0;
85 if ( flags & wxEVENT_SOURCE_INPUT )
86 callbackTypes |= kCFSocketReadCallBack;
87 if ( flags & wxEVENT_SOURCE_OUTPUT )
88 callbackTypes |= kCFSocketWriteCallBack;
89
90 wxCFRef<CFSocketRef>
91 cfSocket(CFSocketCreateWithNative
92 (
93 kCFAllocatorDefault,
94 fd,
95 callbackTypes,
96 &wx_socket_callback,
97 &context
98 ));
99
100 if ( !cfSocket )
101 {
102 wxLogError(wxS("Failed to create event loop source socket."));
71e9885b 103 return NULL;
a25b76f5
VZ
104 }
105
106 // Adjust the socket options to suit our needs:
107 CFOptionFlags sockopt = CFSocketGetSocketFlags(cfSocket);
108
109 // First, by default, write callback is not called repeatedly when data
110 // can be written to the socket but we need this behaviour so request
111 // it explicitly.
112 if ( flags & wxEVENT_SOURCE_OUTPUT )
113 sockopt |= kCFSocketAutomaticallyReenableWriteCallBack;
114
115 // Second, we use the socket to monitor the FD but it doesn't own it,
116 // so prevent the FD from being closed when the socket is invalidated.
117 sockopt &= ~kCFSocketCloseOnInvalidate;
118
119 CFSocketSetSocketFlags(cfSocket, sockopt);
71e9885b
VZ
120
121 wxCFRef<CFRunLoopSourceRef>
a25b76f5
VZ
122 runLoopSource(CFSocketCreateRunLoopSource
123 (
124 kCFAllocatorDefault,
125 cfSocket,
126 0 // Lowest index means highest priority
127 ));
128 if ( !runLoopSource )
129 {
130 wxLogError(wxS("Failed to create low level event loop source."));
131 CFSocketInvalidate(cfSocket);
71e9885b 132 return NULL;
a25b76f5 133 }
71e9885b 134
a25b76f5
VZ
135 // Save the socket so that we can remove it later if asked to.
136 source->InitSourceSocket(cfSocket.release());
71e9885b 137
a25b76f5 138 CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
71e9885b
VZ
139
140 return source.release();
141 }
142};
143
144wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
145{
146 static wxCFEventLoopSourcesManager s_eventLoopSourcesManager;
147
148 return &s_eventLoopSourcesManager;
149}
150
151#endif // wxUSE_EVENTLOOP_SOURCE
152
489468fe
SC
153/////////////////////////////////////////////////////////////////////////////
154
155// NOTE: This doesn't really belong here but this was a handy file to
156// put it in because it's already compiled for wxCocoa and wxMac GUI lib.
157#if wxUSE_STDPATHS
25f49256 158wxStandardPaths& wxGUIAppTraits::GetStandardPaths()
489468fe 159{
38aae140
VZ
160 // Derive a class just to be able to create it: wxStandardPaths ctor is
161 // protected to prevent its misuse, but it also means we can't create an
162 // object of this class directly.
163 class wxStandardPathsDefault : public wxStandardPathsCF
164 {
165 public:
166 wxStandardPathsDefault() { }
167 };
168
169 static wxStandardPathsDefault gs_stdPaths;
170
489468fe
SC
171 return gs_stdPaths;
172}
173#endif
174
5815e959
VZ
175#if wxUSE_SOCKETS
176
177// we need to implement this method in a file of the core library as it should
178// only be used for the GUI applications but we can't use socket stuff from it
179// directly as this would create unwanted dependencies of core on net library
180//
181// so we have this global pointer which is set from sockosx.cpp when it is
182// linked in and we simply return it from here
183extern WXDLLIMPEXP_BASE wxSocketManager *wxOSXSocketManagerCF;
184wxSocketManager *wxGUIAppTraits::GetSocketManager()
185{
186 return wxOSXSocketManagerCF ? wxOSXSocketManagerCF
187 : wxGUIAppTraitsBase::GetSocketManager();
188}
189
190#endif // wxUSE_SOCKETS