]>
Commit | Line | Data |
---|---|---|
dbd300df | 1 | /* ------------------------------------------------------------------------- |
99d80019 JS |
2 | * Project: GSocket (Generic Socket) for WX |
3 | * Name: gsockunx.h | |
4 | * Copyright: (c) Guilhem Lavaux | |
5 | * Licence: wxWindows Licence | |
6 | * Purpose: GSocket Unix header | |
7 | * CVSID: $Id$ | |
dbd300df GL |
8 | * ------------------------------------------------------------------------- |
9 | */ | |
483249fc | 10 | |
2804f77d VZ |
11 | #ifndef _WX_UNIX_GSOCKUNX_H_ |
12 | #define _WX_UNIX_GSOCKUNX_H_ | |
d422d01e | 13 | |
36b6a928 VZ |
14 | #include <unistd.h> |
15 | ||
5e1eac14 VZ |
16 | class wxGSocketIOHandler; |
17 | ||
f0db5d75 | 18 | class GSocket : public GSocketBase |
ba2a81d7 DE |
19 | { |
20 | public: | |
53a161e1 VZ |
21 | GSocket(wxSocketBase& wxsocket); |
22 | virtual ~GSocket(); | |
23 | ||
eb97543d | 24 | virtual void Shutdown(); |
53a161e1 VZ |
25 | virtual GSocket *WaitConnection(wxSocketBase& wxsocket); |
26 | ||
09e6e5ec | 27 | GSocketError SetServer(); |
948c96ef | 28 | bool SetReusable(); |
60edcf45 VZ |
29 | bool SetBroadcast(); |
30 | bool DontDoBind(); | |
09e6e5ec DE |
31 | GSocketError Connect(GSocketStream stream); |
32 | GSocketError SetNonOriented(); | |
33 | int Read(char *buffer, int size); | |
34 | int Write(const char *buffer, int size); | |
948c96ef | 35 | void SetNonBlocking(bool non_block); |
ba2a81d7 | 36 | GSocketError WXDLLIMPEXP_NET GetError(); |
b082b524 DE |
37 | GSocketError GetSockOpt(int level, int optname, void *optval, int *optlen); |
38 | GSocketError SetSockOpt(int level, int optname, | |
39 | const void *optval, int optlen); | |
2804f77d VZ |
40 | //attach or detach from main loop |
41 | void Notify(bool flag); | |
eb97543d VZ |
42 | void Detected_Read(); |
43 | void Detected_Write(); | |
8c029a5b | 44 | |
f0fbbe23 VZ |
45 | private: |
46 | // enable or disable notifications for socket input/output events but only | |
47 | // if m_use_events is true; do nothing otherwise | |
48 | void EnableEvents() | |
49 | { | |
50 | if ( m_use_events ) | |
51 | DoEnableEvents(true); | |
52 | } | |
53 | ||
54 | void DisableEvents() | |
55 | { | |
56 | if ( m_use_events ) | |
57 | DoEnableEvents(false); | |
58 | } | |
59 | ||
60 | // really enable or disable socket input/output events, regardless of | |
61 | // m_use_events value | |
62 | void DoEnableEvents(bool enable); | |
63 | ||
64 | ||
65 | // enable or disable events for the given event if m_use_events; do nothing | |
66 | // otherwise | |
67 | // | |
68 | // notice that these functions also update m_detected: EnableEvent() clears | |
69 | // the corresponding bit in it and DisableEvent() sets it | |
70 | void EnableEvent(GSocketEvent event); | |
71 | void DisableEvent(GSocketEvent event); | |
72 | ||
73 | ||
09e6e5ec DE |
74 | GSocketError Input_Timeout(); |
75 | GSocketError Output_Timeout(); | |
76 | int Recv_Stream(char *buffer, int size); | |
77 | int Recv_Dgram(char *buffer, int size); | |
78 | int Send_Stream(const char *buffer, int size); | |
79 | int Send_Dgram(const char *buffer, int size); | |
09e6e5ec | 80 | public: |
b6db2e91 SN |
81 | /* DFE: We can't protect these data member until the GUI code is updated */ |
82 | /* protected: */ | |
5e1eac14 | 83 | wxGSocketIOHandler *m_handler; |
a324a7bc | 84 | |
2804f77d VZ |
85 | // true if socket should fire events |
86 | bool m_use_events; | |
87 | ||
2804f77d VZ |
88 | // pointer for storing extra (usually GUI-specific) data |
89 | void *m_gui_dependent; | |
53a161e1 VZ |
90 | |
91 | private: | |
92 | // notify the associated wxSocket about a change in socket state and shut | |
93 | // down the socket if the event is GSOCK_LOST | |
94 | void OnStateChange(GSocketEvent event); | |
a324a7bc GL |
95 | }; |
96 | ||
2804f77d VZ |
97 | // A version of GSocketManager which uses FDs for socket IO |
98 | // | |
99 | // This class uses GSocket::m_gui_dependent field to store the 2 (for input and | |
100 | // output) FDs associated with the socket. | |
101 | class GSocketFDBasedManager : public GSocketManager | |
102 | { | |
103 | public: | |
104 | // no special initialization/cleanup needed when using FDs | |
105 | virtual bool OnInit() { return true; } | |
106 | virtual void OnExit() { } | |
107 | ||
108 | // allocate/free the storage we need | |
109 | virtual bool Init_Socket(GSocket *socket) | |
110 | { | |
111 | socket->m_gui_dependent = malloc(sizeof(int)*2); | |
5c33522f | 112 | int * const fds = static_cast<int *>(socket->m_gui_dependent); |
2804f77d VZ |
113 | |
114 | fds[0] = -1; | |
115 | fds[1] = -1; | |
9bf10d6b | 116 | |
2804f77d VZ |
117 | return true; |
118 | } | |
d422d01e | 119 | |
f0fbbe23 | 120 | virtual void Close_Socket(GSocket *socket) |
2804f77d VZ |
121 | { |
122 | Uninstall_Callback(socket, GSOCK_INPUT); | |
123 | Uninstall_Callback(socket, GSOCK_OUTPUT); | |
f0fbbe23 VZ |
124 | |
125 | close(socket->m_fd); | |
126 | } | |
127 | ||
128 | virtual void Destroy_Socket(GSocket *socket) | |
129 | { | |
130 | free(socket->m_gui_dependent); | |
2804f77d VZ |
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 GSocketEvent | |
144 | SocketDir GetDirForEvent(GSocket *socket, GSocketEvent event) | |
145 | { | |
146 | switch ( event ) | |
147 | { | |
148 | default: | |
149 | wxFAIL_MSG( "unexpected socket event" ); | |
150 | // fall through | |
151 | ||
152 | case GSOCK_LOST: | |
153 | // fall through | |
154 | ||
155 | case GSOCK_INPUT: | |
156 | return FD_INPUT; | |
157 | ||
158 | case GSOCK_OUTPUT: | |
159 | return FD_OUTPUT; | |
160 | ||
161 | case GSOCK_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(GSocket *socket, SocketDir d) | |
169 | { | |
5c33522f | 170 | return static_cast<int *>(socket->m_gui_dependent)[d]; |
2804f77d VZ |
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 GSocketInputBasedManager : public GSocketFDBasedManager | |
177 | { | |
178 | public: | |
179 | virtual void Install_Callback(GSocket *socket, GSocketEvent event) | |
180 | { | |
181 | wxCHECK_RET( socket->m_fd != -1, | |
182 | "shouldn't be called on invalid socket" ); | |
183 | ||
184 | const SocketDir d = GetDirForEvent(socket, event); | |
185 | ||
186 | int& fd = FD(socket, d); | |
187 | if ( fd != -1 ) | |
188 | RemoveInput(fd); | |
189 | ||
190 | fd = AddInput(socket, d); | |
191 | } | |
192 | ||
193 | virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event) | |
194 | { | |
195 | const SocketDir d = GetDirForEvent(socket, event); | |
196 | ||
197 | int& fd = FD(socket, d); | |
198 | if ( fd != -1 ) | |
199 | { | |
200 | RemoveInput(fd); | |
201 | fd = -1; | |
202 | } | |
203 | } | |
204 | ||
205 | private: | |
206 | // these functions map directly to XtAdd/RemoveInput() or | |
207 | // gdk_input_add/remove() | |
208 | virtual int AddInput(GSocket *socket, SocketDir d) = 0; | |
209 | virtual void RemoveInput(int fd) = 0; | |
210 | }; | |
d422d01e | 211 | |
2804f77d | 212 | #endif /* _WX_UNIX_GSOCKUNX_H_ */ |