1 /* ------------------------------------------------------------------------- 
   2  * Project: GSocket (Generic Socket) for WX 
   4  * Purpose: GSocket: Mac OS X mach-o part 
   6  * Mac code by Brian Victor, February 2002.  Email comments to bhv1@psu.edu 
   7  * ------------------------------------------------------------------------- */ 
  14 #include "wx/gsocket.h" 
  15 #include "wx/unix/gsockunx.h" 
  17 #include <CoreFoundation/CoreFoundation.h> 
  19 #define ALL_CALLBACK_TYPES (kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack) 
  24   CFRunLoopSourceRef source
; 
  27 void Mac_Socket_Callback(CFSocketRef s
, CFSocketCallBackType callbackType
, 
  28                          CFDataRef address
, const void* data
, void* info
) 
  30   GSocket
* socket 
= (GSocket
*)info
; 
  31   struct MacGSocketData
* macdata
; 
  32   macdata 
= (struct MacGSocketData
*)socket
->m_gui_dependent
; 
  36     case kCFSocketConnectCallBack
: 
  37       assert(!socket
->m_server
); 
  38       socket
->m_functions
->Detected_Write(socket
); 
  40     case kCFSocketReadCallBack
: 
  41       socket
->m_functions
->Detected_Read(socket
); 
  43     case kCFSocketWriteCallBack
: 
  44       socket
->m_functions
->Detected_Write(socket
); 
  47       break;  /* We shouldn't get here. */ 
  51 struct MacGSocketData
* _GSocket_Get_Mac_Socket(GSocket 
*socket
) 
  53   /* If socket is already created, returns a pointer to the data */ 
  54   /* Otherwise, creates socket and returns the pointer */ 
  56   struct MacGSocketData
* data 
= (struct MacGSocketData
*)socket
->m_gui_dependent
; 
  58   if (data 
&& data
->source
) return data
; 
  60   /* CFSocket has not been created, create it: */ 
  61   if (socket
->m_fd 
< 0 || !data
) return NULL
; 
  62   cont
.version 
= 0; cont
.retain 
= NULL
; 
  63   cont
.release 
= NULL
; cont
.copyDescription 
= NULL
; 
  66   CFSocketRef cf 
= CFSocketCreateWithNative(NULL
, socket
->m_fd
, 
  67                         ALL_CALLBACK_TYPES
, Mac_Socket_Callback
, &cont
); 
  68   CFRunLoopSourceRef source 
= CFSocketCreateRunLoopSource(NULL
, cf
, 0); 
  70   socket
->m_gui_dependent 
= (char*)data
; 
  72   /* Keep the source and the socket around. */ 
  73   data
->source 
= source
; 
  79 int _GSocket_GUI_Init(void) 
  84 void _GSocket_GUI_Cleanup(void) 
  88 int _GSocket_GUI_Init_Socket(GSocket 
*socket
) 
  90     struct MacGSocketData 
*data 
= malloc(sizeof(struct MacGSocketData
)); 
  93         socket
->m_gui_dependent 
= (char*)data
; 
 101 void _GSocket_GUI_Destroy_Socket(GSocket 
*socket
) 
 103     struct MacGSocketData 
*data 
= (struct MacGSocketData
*)(socket
->m_gui_dependent
); 
 106         CFRelease(data
->socket
); 
 111 void _GSocket_Install_Callback(GSocket 
*socket
, GSocketEvent event
) 
 114     struct MacGSocketData
* data 
= _GSocket_Get_Mac_Socket(socket
); 
 118      case GSOCK_CONNECTION
: 
 120             c 
= kCFSocketReadCallBack
; 
 122             c 
= kCFSocketConnectCallBack
; 
 126          c 
= kCFSocketReadCallBack
; 
 129          c 
= kCFSocketWriteCallBack
; 
 134     CFSocketEnableCallBacks(data
->socket
, c
); 
 137 void _GSocket_Uninstall_Callback(GSocket 
*socket
, GSocketEvent event
) 
 140     struct MacGSocketData
* data 
= _GSocket_Get_Mac_Socket(socket
); 
 144      case GSOCK_CONNECTION
: 
 146             c 
= kCFSocketReadCallBack
; 
 148             c 
= kCFSocketConnectCallBack
; 
 152          c 
= kCFSocketReadCallBack
; 
 155          c 
= kCFSocketWriteCallBack
; 
 160     CFSocketDisableCallBacks(data
->socket
, c
); 
 163 void _GSocket_Enable_Events(GSocket 
*socket
) 
 165     struct MacGSocketData
* data 
= _GSocket_Get_Mac_Socket(socket
); 
 168     CFRunLoopAddSource(CFRunLoopGetCurrent(), data
->source
, kCFRunLoopDefaultMode
); 
 171 void _GSocket_Disable_Events(GSocket 
*socket
) 
 173     struct MacGSocketData
* data 
= _GSocket_Get_Mac_Socket(socket
); 
 176     /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */ 
 177     CFRunLoopRemoveSource(CFRunLoopGetCurrent(), data
->source
, kCFRunLoopCommonModes
); 
 178     CFSocketInvalidate(data
->socket
); 
 181 #endif // wxUSE_SOCKETS