]> git.saurik.com Git - wxWidgets.git/blob - include/wx/unix/private/sockunix.h
move Read/Write() to common code, there was almost nothing platform-specific in it
[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_enabledCallbacks = 0;
30 }
31
32 virtual wxSocketError GetLastError() const;
33
34 // wxFDIOHandler methods
35 virtual void OnReadWaiting();
36 virtual void OnWriteWaiting();
37 virtual void OnExceptionWaiting();
38
39 // Unix-specific functions
40 bool HasAnyEnabledCallbacks() const { return m_enabledCallbacks != 0; }
41 void EnableCallback(wxFDIODispatcherEntryFlags flag)
42 { m_enabledCallbacks |= flag; }
43 void DisableCallback(wxFDIODispatcherEntryFlags flag)
44 { m_enabledCallbacks &= ~flag; }
45 int GetEnabledCallbacks() const { return m_enabledCallbacks; }
46
47 private:
48 virtual void DoClose()
49 {
50 DisableEvents();
51
52 close(m_fd);
53 }
54
55 virtual void UnblockAndRegisterWithEventLoop()
56 {
57 int trueArg = 1;
58 ioctl(m_fd, FIONBIO, &trueArg);
59
60 EnableEvents();
61 }
62
63 // enable or disable notifications for socket input/output events
64 void EnableEvents() { DoEnableEvents(true); }
65 void DisableEvents() { DoEnableEvents(false); }
66
67 // really enable or disable socket input/output events
68 void DoEnableEvents(bool enable);
69
70 protected:
71 // descriptors for input and output event notification channels associated
72 // with the socket
73 int m_fds[2];
74
75 // the events which are currently enabled for this socket, combination of
76 // wxFDIO_INPUT and wxFDIO_OUTPUT values
77 int m_enabledCallbacks;
78
79 private:
80 // notify the associated wxSocket about a change in socket state and shut
81 // down the socket if the event is wxSOCKET_LOST
82 void OnStateChange(wxSocketNotify event);
83
84 // give it access to our m_fds
85 friend class wxSocketFDBasedManager;
86 };
87
88 // A version of wxSocketManager which uses FDs for socket IO
89 class wxSocketFDBasedManager : public wxSocketManager
90 {
91 public:
92 // no special initialization/cleanup needed when using FDs
93 virtual bool OnInit() { return true; }
94 virtual void OnExit() { }
95
96 protected:
97 // identifies either input or output direction
98 //
99 // NB: the values of this enum shouldn't change
100 enum SocketDir
101 {
102 FD_INPUT,
103 FD_OUTPUT
104 };
105
106 // get the FD index corresponding to the given wxSocketNotify
107 SocketDir GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event)
108 {
109 switch ( event )
110 {
111 default:
112 wxFAIL_MSG( "unexpected socket event" );
113 // fall through
114
115 case wxSOCKET_LOST:
116 // fall through
117
118 case wxSOCKET_INPUT:
119 return FD_INPUT;
120
121 case wxSOCKET_OUTPUT:
122 return FD_OUTPUT;
123
124 case wxSOCKET_CONNECTION:
125 // FIXME: explain this?
126 return socket->IsServer() ? FD_INPUT : FD_OUTPUT;
127 }
128 }
129
130 // access the FDs we store
131 int& FD(wxSocketImplUnix *socket, SocketDir d)
132 {
133 return socket->m_fds[d];
134 }
135 };
136
137 // Common base class for all ports using X11-like (and hence implemented in
138 // X11, Motif and GTK) AddInput() and RemoveInput() functions
139 class wxSocketInputBasedManager : public wxSocketFDBasedManager
140 {
141 public:
142 virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event)
143 {
144 wxSocketImplUnix * const
145 socket = static_cast<wxSocketImplUnix *>(socket_);
146
147 wxCHECK_RET( socket->m_fd != -1,
148 "shouldn't be called on invalid socket" );
149
150 const SocketDir d = GetDirForEvent(socket, event);
151
152 int& fd = FD(socket, d);
153 if ( fd != -1 )
154 RemoveInput(fd);
155
156 fd = AddInput(socket, socket->m_fd, d);
157 }
158
159 virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event)
160 {
161 wxSocketImplUnix * const
162 socket = static_cast<wxSocketImplUnix *>(socket_);
163
164 const SocketDir d = GetDirForEvent(socket, event);
165
166 int& fd = FD(socket, d);
167 if ( fd != -1 )
168 {
169 RemoveInput(fd);
170 fd = -1;
171 }
172 }
173
174 private:
175 // these functions map directly to XtAdd/RemoveInput() or
176 // gdk_input_add/remove()
177 virtual int AddInput(wxFDIOHandler *handler, int fd, SocketDir d) = 0;
178 virtual void RemoveInput(int fd) = 0;
179 };
180
181 #endif /* _WX_UNIX_GSOCKUNX_H_ */