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