]> git.saurik.com Git - wxWidgets.git/blame - src/mac/corefoundation/gsockosx.cpp
warning cleanup
[wxWidgets.git] / src / mac / corefoundation / gsockosx.cpp
CommitLineData
02dad85e
DE
1/* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsockosx.c
4 * Purpose: GSocket: Mac OS X mach-o part
5 * CVSID: $Id$
6 * Mac code by Brian Victor, February 2002. Email comments to bhv1@psu.edu
7 * ------------------------------------------------------------------------- */
8
9#include "wx/setup.h"
10
11#if wxUSE_SOCKETS
12
13#include <stdlib.h>
14#include "wx/gsocket.h"
15#include "wx/unix/gsockunx.h"
16
17#include <CoreFoundation/CoreFoundation.h>
18
19#define ALL_CALLBACK_TYPES (kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack)
20
21struct MacGSocketData
22{
23 CFSocketRef socket;
24 CFRunLoopSourceRef source;
25};
26
7725dc7c
KH
27// Sockets must use the event loop on the main thread
28// We will store the main loop's reference when Initialize is called
29static CFRunLoopRef s_mainRunLoop = NULL;
30
02dad85e
DE
31void Mac_Socket_Callback(CFSocketRef s, CFSocketCallBackType callbackType,
32 CFDataRef address, const void* data, void* info)
33{
34 GSocket* socket = (GSocket*)info;
35 struct MacGSocketData* macdata;
36 macdata = (struct MacGSocketData*)socket->m_gui_dependent;
37 if (!macdata) return;
38 switch (callbackType)
39 {
40 case kCFSocketConnectCallBack:
41 assert(!socket->m_server);
0a647691 42 socket->Detected_Write();
02dad85e
DE
43 break;
44 case kCFSocketReadCallBack:
0a647691 45 socket->Detected_Read();
02dad85e
DE
46 break;
47 case kCFSocketWriteCallBack:
0a647691 48 socket->Detected_Write();
02dad85e
DE
49 break;
50 default:
51 break; /* We shouldn't get here. */
52 }
53}
54
55struct MacGSocketData* _GSocket_Get_Mac_Socket(GSocket *socket)
56{
57 /* If socket is already created, returns a pointer to the data */
58 /* Otherwise, creates socket and returns the pointer */
59 CFSocketContext cont;
60 struct MacGSocketData* data = (struct MacGSocketData*)socket->m_gui_dependent;
61
62 if (data && data->source) return data;
63
64 /* CFSocket has not been created, create it: */
65 if (socket->m_fd < 0 || !data) return NULL;
66 cont.version = 0; cont.retain = NULL;
67 cont.release = NULL; cont.copyDescription = NULL;
68 cont.info = socket;
69
70 CFSocketRef cf = CFSocketCreateWithNative(NULL, socket->m_fd,
71 ALL_CALLBACK_TYPES, Mac_Socket_Callback, &cont);
72 CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, cf, 0);
73 assert(source);
74 socket->m_gui_dependent = (char*)data;
75
76 /* Keep the source and the socket around. */
77 data->source = source;
78 data->socket = cf;
79
80 return data;
81}
82
0a647691
DE
83bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop()
84{ return true; }
85
86bool GSocketGUIFunctionsTableConcrete::OnInit(void)
02dad85e 87{
7725dc7c
KH
88 // No need to store the main loop again
89 if (s_mainRunLoop != NULL)
90 return true;
91
92 // Get the loop for the main thread so our events will actually fire.
93 // The common socket.cpp code will assert if initialize is called from a
94 // secondary thread, otherwise Mac would have the same problems as MSW
95 s_mainRunLoop = CFRunLoopGetCurrent();
96 CFRetain(s_mainRunLoop);
97
0a647691 98 return true;
02dad85e
DE
99}
100
0a647691 101void GSocketGUIFunctionsTableConcrete::OnExit(void)
02dad85e 102{
7725dc7c
KH
103 // Release the reference count, and set the reference back to NULL
104 CFRelease(s_mainRunLoop);
105 s_mainRunLoop = NULL;
02dad85e
DE
106}
107
0a647691 108bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket)
02dad85e 109{
facd6764 110 struct MacGSocketData *data = (struct MacGSocketData *)malloc(sizeof(struct MacGSocketData));
02dad85e
DE
111 if (data)
112 {
113 socket->m_gui_dependent = (char*)data;
114 data->socket = NULL;
115 data->source = NULL;
116 return 1;
117 }
118 return 0;
119}
120
0a647691 121void GSocketGUIFunctionsTableConcrete::Destroy_Socket(GSocket *socket)
02dad85e
DE
122{
123 struct MacGSocketData *data = (struct MacGSocketData*)(socket->m_gui_dependent);
124 if (data)
125 {
577b58df
SC
126 if ( data->source )
127 CFRelease(data->source);
ee9a28ab
SC
128 if ( data->socket )
129 CFRelease(data->socket);
02dad85e
DE
130 free(data);
131 }
132}
133
0a647691 134void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket, GSocketEvent event)
02dad85e
DE
135{
136 int c;
137 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
138 if (!data) return;
139 switch (event)
140 {
141 case GSOCK_CONNECTION:
142 if(socket->m_server)
143 c = kCFSocketReadCallBack;
144 else
145 c = kCFSocketConnectCallBack;
146 break;
147 case GSOCK_LOST:
148 case GSOCK_INPUT:
149 c = kCFSocketReadCallBack;
150 break;
151 case GSOCK_OUTPUT:
152 c = kCFSocketWriteCallBack;
153 break;
154 default:
155 c = 0;
156 }
157 CFSocketEnableCallBacks(data->socket, c);
158}
159
0a647691 160void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket, GSocketEvent event)
02dad85e
DE
161{
162 int c;
163 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
164 if (!data) return;
165 switch (event)
166 {
167 case GSOCK_CONNECTION:
168 if(socket->m_server)
169 c = kCFSocketReadCallBack;
170 else
171 c = kCFSocketConnectCallBack;
172 break;
173 case GSOCK_LOST:
174 case GSOCK_INPUT:
175 c = kCFSocketReadCallBack;
176 break;
177 case GSOCK_OUTPUT:
178 c = kCFSocketWriteCallBack;
179 break;
180 default:
181 c = 0;
182 }
183 CFSocketDisableCallBacks(data->socket, c);
184}
185
0a647691 186void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket)
02dad85e
DE
187{
188 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
189 if (!data) return;
190
7725dc7c 191 CFRunLoopAddSource(s_mainRunLoop, data->source, kCFRunLoopCommonModes);
02dad85e
DE
192}
193
0a647691 194void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket)
02dad85e
DE
195{
196 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
197 if (!data) return;
198
199 /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */
7725dc7c 200 CFRunLoopRemoveSource(s_mainRunLoop, data->source, kCFRunLoopCommonModes);
02dad85e
DE
201 CFSocketInvalidate(data->socket);
202}
203
204#endif // wxUSE_SOCKETS