]> git.saurik.com Git - wxWidgets.git/blob - include/wx/unix/private/sockunix.h
make wxSocketImplUnix inherit from wxFDIOHandler as they're used for almost the same...
[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 }
31
32 virtual void Shutdown();
33 virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket);
34
35 int Read(char *buffer, int size);
36 int Write(const char *buffer, int size);
37 //attach or detach from main loop
38 void Notify(bool flag);
39
40 // wxFDIOHandler methods
41 virtual void OnReadWaiting();
42 virtual void OnWriteWaiting();
43 virtual void OnExceptionWaiting();
44
45 private:
46 virtual wxSocketError DoHandleConnect(int ret);
47 virtual void DoClose()
48 {
49 wxSocketManager * const manager = wxSocketManager::Get();
50 if ( manager )
51 {
52 manager->Uninstall_Callback(this, wxSOCKET_INPUT);
53 manager->Uninstall_Callback(this, wxSOCKET_OUTPUT);
54 }
55
56 close(m_fd);
57 }
58
59 virtual void UnblockAndRegisterWithEventLoop()
60 {
61 int trueArg = 1;
62 ioctl(m_fd, FIONBIO, &trueArg);
63
64 EnableEvents();
65 }
66
67 // enable or disable notifications for socket input/output events but only
68 // if m_use_events is true; do nothing otherwise
69 virtual void EnableEvents()
70 {
71 if ( m_use_events )
72 DoEnableEvents(true);
73 }
74
75 void DisableEvents()
76 {
77 if ( m_use_events )
78 DoEnableEvents(false);
79 }
80
81 // really enable or disable socket input/output events, regardless of
82 // m_use_events value
83 void DoEnableEvents(bool enable);
84
85
86 // enable or disable events for the given event if m_use_events; do nothing
87 // otherwise
88 //
89 // notice that these functions also update m_detected: EnableEvent() clears
90 // the corresponding bit in it and DisableEvent() sets it
91 void EnableEvent(wxSocketNotify event);
92 void DisableEvent(wxSocketNotify event);
93
94
95 wxSocketError Input_Timeout();
96 wxSocketError Output_Timeout();
97 int Recv_Stream(char *buffer, int size);
98 int Recv_Dgram(char *buffer, int size);
99 int Send_Stream(const char *buffer, int size);
100 int Send_Dgram(const char *buffer, int size);
101
102 protected:
103 // true if socket should fire events
104 bool m_use_events;
105
106 // descriptors for input and output event notification channels associated
107 // with the socket
108 int m_fds[2];
109
110 private:
111 // notify the associated wxSocket about a change in socket state and shut
112 // down the socket if the event is wxSOCKET_LOST
113 void OnStateChange(wxSocketNotify event);
114
115 // give it access to our m_fds
116 friend class wxSocketFDBasedManager;
117 };
118
119 // A version of wxSocketManager which uses FDs for socket IO
120 class wxSocketFDBasedManager : public wxSocketManager
121 {
122 public:
123 // no special initialization/cleanup needed when using FDs
124 virtual bool OnInit() { return true; }
125 virtual void OnExit() { }
126
127 // allocate/free the storage we need
128 virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket)
129 {
130 return new wxSocketImplUnix(wxsocket);
131 }
132
133 protected:
134 // identifies either input or output direction
135 //
136 // NB: the values of this enum shouldn't change
137 enum SocketDir
138 {
139 FD_INPUT,
140 FD_OUTPUT
141 };
142
143 // get the FD index corresponding to the given wxSocketNotify
144 SocketDir GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event)
145 {
146 switch ( event )
147 {
148 default:
149 wxFAIL_MSG( "unexpected socket event" );
150 // fall through
151
152 case wxSOCKET_LOST:
153 // fall through
154
155 case wxSOCKET_INPUT:
156 return FD_INPUT;
157
158 case wxSOCKET_OUTPUT:
159 return FD_OUTPUT;
160
161 case wxSOCKET_CONNECTION:
162 // FIXME: explain this?
163 return socket->m_server ? FD_INPUT : FD_OUTPUT;
164 }
165 }
166
167 // access the FDs we store
168 int& FD(wxSocketImplUnix *socket, SocketDir d)
169 {
170 return socket->m_fds[d];
171 }
172 };
173
174 // Common base class for all ports using X11-like (and hence implemented in
175 // X11, Motif and GTK) AddInput() and RemoveInput() functions
176 class wxSocketInputBasedManager : public wxSocketFDBasedManager
177 {
178 public:
179 virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event)
180 {
181 wxSocketImplUnix * const
182 socket = static_cast<wxSocketImplUnix *>(socket_);
183
184 wxCHECK_RET( socket->m_fd != -1,
185 "shouldn't be called on invalid socket" );
186
187 const SocketDir d = GetDirForEvent(socket, event);
188
189 int& fd = FD(socket, d);
190 if ( fd != -1 )
191 RemoveInput(fd);
192
193 fd = AddInput(socket, socket->m_fd, d);
194 }
195
196 virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event)
197 {
198 wxSocketImplUnix * const
199 socket = static_cast<wxSocketImplUnix *>(socket_);
200
201 const SocketDir d = GetDirForEvent(socket, event);
202
203 int& fd = FD(socket, d);
204 if ( fd != -1 )
205 {
206 RemoveInput(fd);
207 fd = -1;
208 }
209 }
210
211 private:
212 // these functions map directly to XtAdd/RemoveInput() or
213 // gdk_input_add/remove()
214 virtual int AddInput(wxFDIOHandler *handler, int fd, SocketDir d) = 0;
215 virtual void RemoveInput(int fd) = 0;
216 };
217
218 #endif /* _WX_UNIX_GSOCKUNX_H_ */