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