]>
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 | |
5e1eac14 VZ |
14 | class wxGSocketIOHandler; |
15 | ||
f0db5d75 | 16 | class GSocket : public GSocketBase |
ba2a81d7 DE |
17 | { |
18 | public: | |
19 | GSocket(); | |
20 | virtual ~GSocket(); | |
09e6e5ec DE |
21 | bool IsOk() { return m_ok; } |
22 | void Close(); | |
23 | void Shutdown(); | |
24 | GSocketError SetLocal(GAddress *address); | |
25 | GSocketError SetPeer(GAddress *address); | |
26 | GAddress *GetLocal(); | |
27 | GAddress *GetPeer(); | |
28 | GSocketError SetServer(); | |
29 | GSocket *WaitConnection(); | |
948c96ef | 30 | bool SetReusable(); |
60edcf45 VZ |
31 | bool SetBroadcast(); |
32 | bool DontDoBind(); | |
09e6e5ec DE |
33 | GSocketError Connect(GSocketStream stream); |
34 | GSocketError SetNonOriented(); | |
35 | int Read(char *buffer, int size); | |
36 | int Write(const char *buffer, int size); | |
948c96ef | 37 | void SetNonBlocking(bool non_block); |
09e6e5ec | 38 | void SetTimeout(unsigned long millisec); |
ba2a81d7 | 39 | GSocketError WXDLLIMPEXP_NET GetError(); |
09e6e5ec DE |
40 | void SetCallback(GSocketEventFlags flags, |
41 | GSocketCallback callback, char *cdata); | |
42 | void UnsetCallback(GSocketEventFlags flags); | |
b082b524 DE |
43 | GSocketError GetSockOpt(int level, int optname, void *optval, int *optlen); |
44 | GSocketError SetSockOpt(int level, int optname, | |
45 | const void *optval, int optlen); | |
2804f77d VZ |
46 | //attach or detach from main loop |
47 | void Notify(bool flag); | |
ba2a81d7 DE |
48 | virtual void Detected_Read(); |
49 | virtual void Detected_Write(); | |
8c029a5b VZ |
50 | void SetInitialSocketBuffers(int recv, int send) |
51 | { | |
52 | m_initialRecvBufferSize = recv; | |
53 | m_initialSendBufferSize = send; | |
54 | } | |
55 | ||
09e6e5ec | 56 | protected: |
2804f77d VZ |
57 | //enable or disable event callback using gsocket gui callback table |
58 | void EnableEvents(bool flag = true); | |
59 | void DisableEvents() { EnableEvents(false); } | |
09e6e5ec DE |
60 | void Enable(GSocketEvent event); |
61 | void Disable(GSocketEvent event); | |
62 | GSocketError Input_Timeout(); | |
63 | GSocketError Output_Timeout(); | |
64 | int Recv_Stream(char *buffer, int size); | |
65 | int Recv_Dgram(char *buffer, int size); | |
66 | int Send_Stream(const char *buffer, int size); | |
67 | int Send_Dgram(const char *buffer, int size); | |
09e6e5ec | 68 | public: |
b6db2e91 SN |
69 | /* DFE: We can't protect these data member until the GUI code is updated */ |
70 | /* protected: */ | |
5e1eac14 | 71 | wxGSocketIOHandler *m_handler; |
a324a7bc | 72 | |
2804f77d VZ |
73 | // true if socket should fire events |
74 | bool m_use_events; | |
75 | ||
2804f77d VZ |
76 | // pointer for storing extra (usually GUI-specific) data |
77 | void *m_gui_dependent; | |
a324a7bc GL |
78 | }; |
79 | ||
2804f77d VZ |
80 | // A version of GSocketManager which uses FDs for socket IO |
81 | // | |
82 | // This class uses GSocket::m_gui_dependent field to store the 2 (for input and | |
83 | // output) FDs associated with the socket. | |
84 | class GSocketFDBasedManager : public GSocketManager | |
85 | { | |
86 | public: | |
87 | // no special initialization/cleanup needed when using FDs | |
88 | virtual bool OnInit() { return true; } | |
89 | virtual void OnExit() { } | |
90 | ||
91 | // allocate/free the storage we need | |
92 | virtual bool Init_Socket(GSocket *socket) | |
93 | { | |
94 | socket->m_gui_dependent = malloc(sizeof(int)*2); | |
5c33522f | 95 | int * const fds = static_cast<int *>(socket->m_gui_dependent); |
2804f77d VZ |
96 | |
97 | fds[0] = -1; | |
98 | fds[1] = -1; | |
9bf10d6b | 99 | |
2804f77d VZ |
100 | return true; |
101 | } | |
102 | virtual void Destroy_Socket(GSocket *socket) | |
103 | { | |
104 | free(socket->m_gui_dependent); | |
105 | } | |
d422d01e | 106 | |
2804f77d VZ |
107 | virtual void Enable_Events(GSocket *socket) |
108 | { | |
109 | Install_Callback(socket, GSOCK_INPUT); | |
110 | Install_Callback(socket, GSOCK_OUTPUT); | |
111 | } | |
112 | virtual void Disable_Events(GSocket *socket) | |
113 | { | |
114 | Uninstall_Callback(socket, GSOCK_INPUT); | |
115 | Uninstall_Callback(socket, GSOCK_OUTPUT); | |
116 | } | |
117 | ||
118 | protected: | |
119 | // identifies either input or output direction | |
120 | // | |
121 | // NB: the values of this enum shouldn't change | |
122 | enum SocketDir | |
123 | { | |
124 | FD_INPUT, | |
125 | FD_OUTPUT | |
126 | }; | |
127 | ||
128 | // get the FD index corresponding to the given GSocketEvent | |
129 | SocketDir GetDirForEvent(GSocket *socket, GSocketEvent event) | |
130 | { | |
131 | switch ( event ) | |
132 | { | |
133 | default: | |
134 | wxFAIL_MSG( "unexpected socket event" ); | |
135 | // fall through | |
136 | ||
137 | case GSOCK_LOST: | |
138 | // fall through | |
139 | ||
140 | case GSOCK_INPUT: | |
141 | return FD_INPUT; | |
142 | ||
143 | case GSOCK_OUTPUT: | |
144 | return FD_OUTPUT; | |
145 | ||
146 | case GSOCK_CONNECTION: | |
147 | // FIXME: explain this? | |
148 | return socket->m_server ? FD_INPUT : FD_OUTPUT; | |
149 | } | |
150 | } | |
151 | ||
152 | // access the FDs we store | |
153 | int& FD(GSocket *socket, SocketDir d) | |
154 | { | |
5c33522f | 155 | return static_cast<int *>(socket->m_gui_dependent)[d]; |
2804f77d VZ |
156 | } |
157 | }; | |
158 | ||
159 | // Common base class for all ports using X11-like (and hence implemented in | |
160 | // X11, Motif and GTK) AddInput() and RemoveInput() functions | |
161 | class GSocketInputBasedManager : public GSocketFDBasedManager | |
162 | { | |
163 | public: | |
164 | virtual void Install_Callback(GSocket *socket, GSocketEvent event) | |
165 | { | |
166 | wxCHECK_RET( socket->m_fd != -1, | |
167 | "shouldn't be called on invalid socket" ); | |
168 | ||
169 | const SocketDir d = GetDirForEvent(socket, event); | |
170 | ||
171 | int& fd = FD(socket, d); | |
172 | if ( fd != -1 ) | |
173 | RemoveInput(fd); | |
174 | ||
175 | fd = AddInput(socket, d); | |
176 | } | |
177 | ||
178 | virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event) | |
179 | { | |
180 | const SocketDir d = GetDirForEvent(socket, event); | |
181 | ||
182 | int& fd = FD(socket, d); | |
183 | if ( fd != -1 ) | |
184 | { | |
185 | RemoveInput(fd); | |
186 | fd = -1; | |
187 | } | |
188 | } | |
189 | ||
190 | private: | |
191 | // these functions map directly to XtAdd/RemoveInput() or | |
192 | // gdk_input_add/remove() | |
193 | virtual int AddInput(GSocket *socket, SocketDir d) = 0; | |
194 | virtual void RemoveInput(int fd) = 0; | |
195 | }; | |
d422d01e | 196 | |
2804f77d | 197 | #endif /* _WX_UNIX_GSOCKUNX_H_ */ |