]> git.saurik.com Git - wxWidgets.git/blame - src/mac/gsockosx.cpp
made wxFFile a bit more safe: don't crash when Tell() and Length() are called on...
[wxWidgets.git] / src / mac / 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
27void Mac_Socket_Callback(CFSocketRef s, CFSocketCallBackType callbackType,
28 CFDataRef address, const void* data, void* info)
29{
30 GSocket* socket = (GSocket*)info;
31 struct MacGSocketData* macdata;
32 macdata = (struct MacGSocketData*)socket->m_gui_dependent;
33 if (!macdata) return;
34 switch (callbackType)
35 {
36 case kCFSocketConnectCallBack:
37 assert(!socket->m_server);
38 socket->m_functions->Detected_Write(socket);
39 break;
40 case kCFSocketReadCallBack:
41 socket->m_functions->Detected_Read(socket);
42 break;
43 case kCFSocketWriteCallBack:
44 socket->m_functions->Detected_Write(socket);
45 break;
46 default:
47 break; /* We shouldn't get here. */
48 }
49}
50
51struct MacGSocketData* _GSocket_Get_Mac_Socket(GSocket *socket)
52{
53 /* If socket is already created, returns a pointer to the data */
54 /* Otherwise, creates socket and returns the pointer */
55 CFSocketContext cont;
56 struct MacGSocketData* data = (struct MacGSocketData*)socket->m_gui_dependent;
57
58 if (data && data->source) return data;
59
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;
64 cont.info = socket;
65
66 CFSocketRef cf = CFSocketCreateWithNative(NULL, socket->m_fd,
67 ALL_CALLBACK_TYPES, Mac_Socket_Callback, &cont);
68 CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, cf, 0);
69 assert(source);
70 socket->m_gui_dependent = (char*)data;
71
72 /* Keep the source and the socket around. */
73 data->source = source;
74 data->socket = cf;
75
76 return data;
77}
78
79int _GSocket_GUI_Init(void)
80{
81 return 1;
82}
83
84void _GSocket_GUI_Cleanup(void)
85{
86}
87
88int _GSocket_GUI_Init_Socket(GSocket *socket)
89{
90 struct MacGSocketData *data = malloc(sizeof(struct MacGSocketData));
91 if (data)
92 {
93 socket->m_gui_dependent = (char*)data;
94 data->socket = NULL;
95 data->source = NULL;
96 return 1;
97 }
98 return 0;
99}
100
101void _GSocket_GUI_Destroy_Socket(GSocket *socket)
102{
103 struct MacGSocketData *data = (struct MacGSocketData*)(socket->m_gui_dependent);
104 if (data)
105 {
106 CFRelease(data->socket);
107 free(data);
108 }
109}
110
111void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
112{
113 int c;
114 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
115 if (!data) return;
116 switch (event)
117 {
118 case GSOCK_CONNECTION:
119 if(socket->m_server)
120 c = kCFSocketReadCallBack;
121 else
122 c = kCFSocketConnectCallBack;
123 break;
124 case GSOCK_LOST:
125 case GSOCK_INPUT:
126 c = kCFSocketReadCallBack;
127 break;
128 case GSOCK_OUTPUT:
129 c = kCFSocketWriteCallBack;
130 break;
131 default:
132 c = 0;
133 }
134 CFSocketEnableCallBacks(data->socket, c);
135}
136
137void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
138{
139 int c;
140 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
141 if (!data) return;
142 switch (event)
143 {
144 case GSOCK_CONNECTION:
145 if(socket->m_server)
146 c = kCFSocketReadCallBack;
147 else
148 c = kCFSocketConnectCallBack;
149 break;
150 case GSOCK_LOST:
151 case GSOCK_INPUT:
152 c = kCFSocketReadCallBack;
153 break;
154 case GSOCK_OUTPUT:
155 c = kCFSocketWriteCallBack;
156 break;
157 default:
158 c = 0;
159 }
160 CFSocketDisableCallBacks(data->socket, c);
161}
162
163void _GSocket_Enable_Events(GSocket *socket)
164{
165 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
166 if (!data) return;
167
168 CFRunLoopAddSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopDefaultMode);
169}
170
171void _GSocket_Disable_Events(GSocket *socket)
172{
173 struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
174 if (!data) return;
175
176 /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */
177 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes);
178 CFSocketInvalidate(data->socket);
179}
180
181#endif // wxUSE_SOCKETS