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) 
   7 // Copyright:   (c) David Elliott, Ryan Norton 
   8 //              (c) 2013 Rob Bresalier 
   9 // Licence:     wxWindows licence 
  10 // Notes:       This code comes from src/osx/carbon/utilsexc.cpp,1.11 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 #include "wx/wxprec.h" 
  17 #endif //ndef WX_PRECOMP 
  18 #include "wx/stdpaths.h" 
  20 #include "wx/apptrait.h" 
  21 #include "wx/thread.h" 
  22 #include "wx/process.h" 
  24 #include "wx/evtloop.h" 
  25 #include "wx/evtloopsrc.h" 
  26 #include "wx/private/eventloopsourcesmanager.h" 
  30 #include <CoreFoundation/CFSocket.h> 
  32 #if wxUSE_EVENTLOOP_SOURCE 
  39 wx_socket_callback(CFSocketRef 
WXUNUSED(s
), 
  40                    CFSocketCallBackType callbackType
, 
  41                    CFDataRef 
WXUNUSED(address
), 
  42                    void const *WXUNUSED(data
), 
  45     wxLogTrace(wxTRACE_EVT_SOURCE
, 
  46                "CFSocket callback, type=%d", static_cast<int>(callbackType
)); 
  48     wxCFEventLoopSource 
* const 
  49         source 
= static_cast<wxCFEventLoopSource 
*>(ctxData
); 
  51     wxEventLoopSourceHandler 
* const 
  52         handler 
= source
->GetHandler(); 
  54     switch ( callbackType 
) 
  56         case kCFSocketReadCallBack
: 
  57             handler
->OnReadWaiting(); 
  60         case kCFSocketWriteCallBack
: 
  61             handler
->OnWriteWaiting(); 
  65             wxFAIL_MSG( "Unexpected callback type." ); 
  69 } // anonymous namespace 
  71 class wxCFEventLoopSourcesManager 
: public wxEventLoopSourcesManagerBase
 
  75     AddSourceForFD(int fd
, wxEventLoopSourceHandler 
*handler
, int flags
) 
  77         wxCHECK_MSG( fd 
!= -1, NULL
, "can't monitor invalid fd" ); 
  79         wxScopedPtr
<wxCFEventLoopSource
> 
  80             source(new wxCFEventLoopSource(handler
, flags
)); 
  82         CFSocketContext context 
= { 0, source
.get(), NULL
, NULL
, NULL 
}; 
  84         int callbackTypes 
= 0; 
  85         if ( flags 
& wxEVENT_SOURCE_INPUT 
) 
  86             callbackTypes 
|= kCFSocketReadCallBack
; 
  87         if ( flags 
& wxEVENT_SOURCE_OUTPUT 
) 
  88             callbackTypes 
|= kCFSocketWriteCallBack
; 
  91             cfSocket(CFSocketCreateWithNative
 
 102             wxLogError(wxS("Failed to create event loop source socket.")); 
 106         // Adjust the socket options to suit our needs: 
 107         CFOptionFlags sockopt 
= CFSocketGetSocketFlags(cfSocket
); 
 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 
 112         if ( flags 
& wxEVENT_SOURCE_OUTPUT 
) 
 113             sockopt 
|= kCFSocketAutomaticallyReenableWriteCallBack
; 
 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
; 
 119         CFSocketSetSocketFlags(cfSocket
, sockopt
); 
 121         wxCFRef
<CFRunLoopSourceRef
> 
 122             runLoopSource(CFSocketCreateRunLoopSource
 
 126                             0 // Lowest index means highest priority 
 128         if ( !runLoopSource 
) 
 130             wxLogError(wxS("Failed to create low level event loop source.")); 
 131             CFSocketInvalidate(cfSocket
); 
 135         // Save the socket so that we can remove it later if asked to. 
 136         source
->InitSourceSocket(cfSocket
.release()); 
 138         CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource
, kCFRunLoopCommonModes
); 
 140         return source
.release(); 
 144 wxEventLoopSourcesManagerBase
* wxGUIAppTraits::GetEventLoopSourcesManager() 
 146     static wxCFEventLoopSourcesManager s_eventLoopSourcesManager
; 
 148     return &s_eventLoopSourcesManager
; 
 151 #endif // wxUSE_EVENTLOOP_SOURCE 
 153 ///////////////////////////////////////////////////////////////////////////// 
 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. 
 158 wxStandardPaths
& wxGUIAppTraits::GetStandardPaths() 
 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
 
 166         wxStandardPathsDefault() { } 
 169     static wxStandardPathsDefault gs_stdPaths
; 
 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 
 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 
 183 extern WXDLLIMPEXP_BASE wxSocketManager 
*wxOSXSocketManagerCF
; 
 184 wxSocketManager 
*wxGUIAppTraits::GetSocketManager() 
 186     return wxOSXSocketManagerCF 
? wxOSXSocketManagerCF
 
 187                                 : wxGUIAppTraitsBase::GetSocketManager(); 
 190 #endif // wxUSE_SOCKETS