]> git.saurik.com Git - wxWidgets.git/blob - include/wx/unix/private/sockunix.h
move enabled callbacks flag down to wxSocketImplUnix from wxSocketImplFDIO, this...
[wxWidgets.git] / include / wx / unix / private / sockunix.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/unix/private/sockunix.h
3 // Purpose: wxSocketImpl implementation for Unix systems
4 // Authors: Guilhem Lavaux, Vadim Zeitlin
5 // Created: April 1997
6 // RCS-ID: $Id$
7 // Copyright: (c) 1997 Guilhem Lavaux
8 // (c) 2008 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_UNIX_GSOCKUNX_H_
13 #define _WX_UNIX_GSOCKUNX_H_
14
15 #include <unistd.h>
16 #include <sys/ioctl.h>
17 #include "wx/private/fdiodispatcher.h"
18
19 class wxSocketImplUnix : public wxSocketImpl,
20 public wxFDIOHandler
21 {
22 public:
23 wxSocketImplUnix(wxSocketBase& wxsocket)
24 : wxSocketImpl(wxsocket)
25 {
26 m_fds[0] =
27 m_fds[1] = -1;
28
29 m_use_events = false;
30 m_enabledCallbacks = 0;
31 }
32
33 virtual void Shutdown();
34 virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket);
35
36 int Read(char *buffer, int size);
37 int Write(const char *buffer, int size);
38 //attach or detach from main loop
39 void Notify(bool flag);
40
41 // wxFDIOHandler methods
42 virtual void OnReadWaiting();
43 virtual void OnWriteWaiting();
44 virtual void OnExceptionWaiting();
45
46 // Unix-specific functions
47 bool HasAnyEnabledCallbacks() const { return m_enabledCallbacks != 0; }
48 void EnableCallback(wxFDIODispatcherEntryFlags flag)
49 { m_enabledCallbacks |= flag; }
50 void DisableCallback(wxFDIODispatcherEntryFlags flag)
51 { m_enabledCallbacks &= ~flag; }
52 int GetEnabledCallbacks() const { return m_enabledCallbacks; }
53
54 private:
55 virtual wxSocketError DoHandleConnect(int ret);
56 virtual void DoClose()
57 {
58 wxSocketManager * const manager = wxSocketManager::Get();
59 if ( manager )
60 {
61 manager->Uninstall_Callback(this, wxSOCKET_INPUT);
62 manager->Uninstall_Callback(this, wxSOCKET_OUTPUT);
63 }
64
65 close(m_fd);
66 }
67
68 virtual void UnblockAndRegisterWithEventLoop()
69 {
70 int trueArg = 1;
71 ioctl(m_fd, FIONBIO, &trueArg);
72
73 EnableEvents();
74 }
75
76 // enable or disable notifications for socket input/output events but only
77 // if m_use_events is true; do nothing otherwise
78 virtual void EnableEvents()
79 {
80 if ( m_use_events )
81 DoEnableEvents(true);
82 }
83
84 void DisableEvents()
85 {
86 if ( m_use_events )
87 DoEnableEvents(false);
88 }
89
90 // really enable or disable socket input/output events, regardless of
91 // m_use_events value
92 void DoEnableEvents(bool enable);
93
94
95 // enable or disable events for the given event if m_use_events; do nothing
96 // otherwise
97 //
98 // notice that these functions also update m_detected: EnableEvent() clears
99 // the corresponding bit in it and DisableEvent() sets it
100 void EnableEvent(wxSocketNotify event);
101 void DisableEvent(wxSocketNotify event);
102
103
104 wxSocketError Input_Timeout();
105 wxSocketError Output_Timeout();
106 int Recv_Stream(char *buffer, int size);
107 int Recv_Dgram(char *buffer, int size);
108 int Send_Stream(const char *buffer, int size);
109 int Send_Dgram(const char *buffer, int size);
110
111
112 protected:
113 // true if socket should fire events
114 bool m_use_events;
115
116 // descriptors for input and output event notification channels associated
117 // with the socket
118 int m_fds[2];
119
120 // the events which are currently enabled for this socket, combination of
121 // wxFDIO_INPUT and wxFDIO_OUTPUT values
122 //
123 // TODO: this overlaps with m_detected but the semantics of the latter are
124 // very unclear so I don't dare to remove it right now
125 int m_enabledCallbacks;
126
127 private:
128 // notify the associated wxSocket about a change in socket state and shut
129 // down the socket if the event is wxSOCKET_LOST
130 void OnStateChange(wxSocketNotify event);
131
132 // give it access to our m_fds
133 friend class wxSocketFDBasedManager;
134 };
135
136 // A version of wxSocketManager which uses FDs for socket IO
137 class wxSocketFDBasedManager : public wxSocketManager
138 {
139 public:
140 // no special initialization/cleanup needed when using FDs
141 virtual bool OnInit() { return true; }
142 virtual void OnExit() { }
143
144 // allocate/free the storage we need
145 virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket)
146 {
147 return new wxSocketImplUnix(wxsocket);
148 }
149
150 protected:
151 // identifies either input or output direction
152 //
153 // NB: the values of this enum shouldn't change
154 enum SocketDir
155 {
156 FD_INPUT,
157 FD_OUTPUT
158 };
159
160 // get the FD index corresponding to the given wxSocketNotify
161 SocketDir GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event)
162 {
163 switch ( event )
164 {
165 default:
166 wxFAIL_MSG( "unexpected socket event" );
167 // fall through
168
169 case wxSOCKET_LOST:
170 // fall through
171
172 case wxSOCKET_INPUT:
173 return FD_INPUT;
174
175 case wxSOCKET_OUTPUT:
176 return FD_OUTPUT;
177
178 case wxSOCKET_CONNECTION:
179 // FIXME: explain this?
180 return socket->m_server ? FD_INPUT : FD_OUTPUT;
181 }
182 }
183
184 // access the FDs we store
185 int& FD(wxSocketImplUnix *socket, SocketDir d)
186 {
187 return socket->m_fds[d];
188 }
189 };
190
191 // Common base class for all ports using X11-like (and hence implemented in
192 // X11, Motif and GTK) AddInput() and RemoveInput() functions
193 class wxSocketInputBasedManager : public wxSocketFDBasedManager
194 {
195 public:
196 virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event)
197 {
198 wxSocketImplUnix * const
199 socket = static_cast<wxSocketImplUnix *>(socket_);
200
201 wxCHECK_RET( socket->m_fd != -1,
202 "shouldn't be called on invalid socket" );
203
204 const SocketDir d = GetDirForEvent(socket, event);
205
206 int& fd = FD(socket, d);
207 if ( fd != -1 )
208 RemoveInput(fd);
209
210 fd = AddInput(socket, socket->m_fd, d);
211 }
212
213 virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event)
214 {
215 wxSocketImplUnix * const
216 socket = static_cast<wxSocketImplUnix *>(socket_);
217
218 const SocketDir d = GetDirForEvent(socket, event);
219
220 int& fd = FD(socket, d);
221 if ( fd != -1 )
222 {
223 RemoveInput(fd);
224 fd = -1;
225 }
226 }
227
228 private:
229 // these functions map directly to XtAdd/RemoveInput() or
230 // gdk_input_add/remove()
231 virtual int AddInput(wxFDIOHandler *handler, int fd, SocketDir d) = 0;
232 virtual void RemoveInput(int fd) = 0;
233 };
234
235 #endif /* _WX_UNIX_GSOCKUNX_H_ */