]> git.saurik.com Git - wxWidgets.git/blame - src/osx/core/utilsexc_cf.cpp
fix wxCHECK_MSG() return value
[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
7// RCS-ID: $Id$
8// Copyright: (c) David Elliott, Ryan Norton
821d856a 9// (c) 2013 Rob Bresalier
489468fe 10// Licence: wxWindows licence
524c47aa 11// Notes: This code comes from src/osx/carbon/utilsexc.cpp,1.11
489468fe
SC
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
489468fe
SC
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
71e9885b
VZ
25#include "wx/evtloop.h"
26#include "wx/evtloopsrc.h"
27#include "wx/private/eventloopsourcesmanager.h"
28
489468fe
SC
29#include <sys/wait.h>
30
31#include <CoreFoundation/CFSocket.h>
32
71e9885b
VZ
33#if wxUSE_EVENTLOOP_SOURCE
34
35namespace
36{
37
a25b76f5 38extern "C"
71e9885b 39void
a25b76f5
VZ
40wx_socket_callback(CFSocketRef WXUNUSED(s),
41 CFSocketCallBackType callbackType,
42 CFDataRef WXUNUSED(address),
43 void const *WXUNUSED(data),
44 void *ctxData)
71e9885b
VZ
45{
46 wxLogTrace(wxTRACE_EVT_SOURCE,
821d856a 47 "CFSocket callback, type=%d", static_cast<int>(callbackType));
71e9885b
VZ
48
49 wxCFEventLoopSource * const
50 source = static_cast<wxCFEventLoopSource *>(ctxData);
51
52 wxEventLoopSourceHandler * const
53 handler = source->GetHandler();
71e9885b 54
a25b76f5
VZ
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 }
71e9885b
VZ
68}
69
70} // anonymous namespace
71
72class wxCFEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
73{
74public:
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
a25b76f5
VZ
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."));
71e9885b 104 return NULL;
a25b76f5
VZ
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);
71e9885b
VZ
121
122 wxCFRef<CFRunLoopSourceRef>
a25b76f5
VZ
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);
71e9885b 133 return NULL;
a25b76f5 134 }
71e9885b 135
a25b76f5
VZ
136 // Save the socket so that we can remove it later if asked to.
137 source->InitSourceSocket(cfSocket.release());
71e9885b 138
a25b76f5 139 CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
71e9885b
VZ
140
141 return source.release();
142 }
143};
144
145wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
146{
147 static wxCFEventLoopSourcesManager s_eventLoopSourcesManager;
148
149 return &s_eventLoopSourcesManager;
150}
151
152#endif // wxUSE_EVENTLOOP_SOURCE
153
489468fe
SC
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
159static wxStandardPathsCF gs_stdPaths;
25f49256 160wxStandardPaths& wxGUIAppTraits::GetStandardPaths()
489468fe
SC
161{
162 return gs_stdPaths;
163}
164#endif
165
5815e959
VZ
166#if wxUSE_SOCKETS
167
168// we need to implement this method in a file of the core library as it should
169// only be used for the GUI applications but we can't use socket stuff from it
170// directly as this would create unwanted dependencies of core on net library
171//
172// so we have this global pointer which is set from sockosx.cpp when it is
173// linked in and we simply return it from here
174extern WXDLLIMPEXP_BASE wxSocketManager *wxOSXSocketManagerCF;
175wxSocketManager *wxGUIAppTraits::GetSocketManager()
176{
177 return wxOSXSocketManagerCF ? wxOSXSocketManagerCF
178 : wxGUIAppTraitsBase::GetSocketManager();
179}
180
181#endif // wxUSE_SOCKETS