1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/socketevtdispatch.cpp
3 // Purpose: implements wxSocketEventDispatcher for platforms with no
4 // socket events notification
9 // Copyright: (c) 2006 Angel vidal
10 // License: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
13 // ============================================================================
15 // ============================================================================
17 // ----------------------------------------------------------------------------
19 // ----------------------------------------------------------------------------
21 // for compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
26 #include "wx/private/socketevtdispatch.h"
27 #include "wx/module.h"
28 #include "wx/unix/private.h"
29 #include "wx/gsocket.h"
30 #include "wx/unix/gsockunx.h"
39 #ifdef HAVE_SYS_SELECT_H
40 # include <sys/select.h>
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
48 // wxSocketEventDispatcherEntry
49 // ----------------------------------------------------------------------------
51 class wxSocketEventDispatcherEntry
: public wxObject
54 wxSocketEventDispatcherEntry()
56 m_fdInput
= -1; m_fdOutput
= -1;
65 // ----------------------------------------------------------------------------
66 // wxSocketEventDispatcher
67 // ----------------------------------------------------------------------------
69 wxSocketEventDispatcher
* wxSocketEventDispatcher::ms_instance
= NULL
;
72 wxSocketEventDispatcher
& wxSocketEventDispatcher::Get()
75 ms_instance
= new wxSocketEventDispatcher
;
79 wxSocketEventDispatcherEntry
* wxSocketEventDispatcher::FindEntry(int fd
)
81 wxSocketEventDispatcherEntry
* entry
=
82 (wxSocketEventDispatcherEntry
*) wxHashTable::Get(fd
);
87 wxSocketEventDispatcher::RegisterCallback(int fd
,
88 wxSocketEventDispatcherType socketType
,
91 wxSocketEventDispatcherEntry
* entry
= FindEntry(fd
);
94 entry
= new wxSocketEventDispatcherEntry();
98 if (socketType
== wxSocketEventDispatcherInput
)
99 entry
->m_fdInput
= fd
;
101 entry
->m_fdOutput
= fd
;
103 entry
->m_socket
= socket
;
107 wxSocketEventDispatcher::UnregisterCallback(int fd
,
108 wxSocketEventDispatcherType socketType
)
110 wxSocketEventDispatcherEntry
* entry
= FindEntry(fd
);
113 if (socketType
== wxSocketEventDispatcherInput
)
114 entry
->m_fdInput
= -1;
116 entry
->m_fdOutput
= -1;
118 if (entry
->m_fdInput
== -1 && entry
->m_fdOutput
== -1)
120 entry
->m_socket
= NULL
;
127 int wxSocketEventDispatcher::FillSets(fd_set
* readset
, fd_set
* writeset
)
135 wxHashTable::compatibility_iterator node
= Next();
138 wxSocketEventDispatcherEntry
* entry
=
139 (wxSocketEventDispatcherEntry
*) node
->GetData();
141 if (entry
->m_fdInput
!= -1)
143 wxFD_SET(entry
->m_fdInput
, readset
);
144 if (entry
->m_fdInput
> max_fd
)
145 max_fd
= entry
->m_fdInput
;
148 if (entry
->m_fdOutput
!= -1)
150 wxFD_SET(entry
->m_fdOutput
, writeset
);
151 if (entry
->m_fdOutput
> max_fd
)
152 max_fd
= entry
->m_fdOutput
;
161 void wxSocketEventDispatcher::AddEvents(fd_set
* readset
, fd_set
* writeset
)
164 wxHashTable::compatibility_iterator node
= Next();
167 // We have to store the next node here, because the event processing can
168 // destroy the object before we call Next()
170 wxHashTable::compatibility_iterator next_node
= Next();
172 wxSocketEventDispatcherEntry
* entry
=
173 (wxSocketEventDispatcherEntry
*) node
->GetData();
175 wxCHECK_RET(entry
->m_socket
, wxT("Critical: Processing a NULL socket in wxSocketEventDispatcher"));
177 if (entry
->m_fdInput
!= -1 && wxFD_ISSET(entry
->m_fdInput
, readset
))
178 entry
->m_socket
->Detected_Read();
180 if (entry
->m_fdOutput
!= -1 && wxFD_ISSET(entry
->m_fdOutput
, writeset
))
181 entry
->m_socket
->Detected_Write();;
187 void wxSocketEventDispatcher::RunLoop(int timeout
)
191 tv
.tv_usec
= timeout
;
195 int max_fd
= FillSets( &readset
, &writeset
);
196 if (select( max_fd
+1, &readset
, &writeset
, NULL
, &tv
) == 0)
198 // No socket input/output. Don't add events.
203 AddEvents(&readset
, &writeset
);
207 // ----------------------------------------------------------------------------
208 // wxSocketEventDispatcherModule
209 // ----------------------------------------------------------------------------
211 class wxSocketEventDispatcherModule
: public wxModule
214 bool OnInit() { return true; }
215 void OnExit() { wxDELETE(wxSocketEventDispatcher::ms_instance
); }
218 DECLARE_DYNAMIC_CLASS(wxSocketEventDispatcherModule
)
221 IMPLEMENT_DYNAMIC_CLASS(wxSocketEventDispatcherModule
, wxModule
)
224 // ----------------------------------------------------------------------------
226 // ----------------------------------------------------------------------------
228 bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop()
233 bool GSocketGUIFunctionsTableConcrete::OnInit(void)
238 void GSocketGUIFunctionsTableConcrete::OnExit(void)
242 bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket
*socket
)
246 socket
->m_gui_dependent
= (char *)malloc(sizeof(int)*2);
247 m_id
= (int *)(socket
->m_gui_dependent
);
255 void GSocketGUIFunctionsTableConcrete::Destroy_Socket(GSocket
*socket
)
257 free(socket
->m_gui_dependent
);
260 void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket
*socket
,
263 int *m_id
= (int *)(socket
->m_gui_dependent
);
266 if (socket
->m_fd
== -1)
271 case GSOCK_LOST
: /* fall-through */
272 case GSOCK_INPUT
: c
= 0; break;
273 case GSOCK_OUTPUT
: c
= 1; break;
274 case GSOCK_CONNECTION
: c
= ((socket
->m_server
) ? 0 : 1); break;
280 XtRemoveInput(m_id
[c
]);
285 m_id
[0] = socket
->m_fd
;
287 wxSocketEventDispatcher::Get().RegisterCallback(
288 socket
->m_fd
, wxSocketEventDispatcherInput
, socket
);
292 m_id
[1] = socket
->m_fd
;
294 wxSocketEventDispatcher::Get().RegisterCallback(
295 socket
->m_fd
, wxSocketEventDispatcherOutput
, socket
);
299 void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket
*socket
,
302 int *m_id
= (int *)(socket
->m_gui_dependent
);
307 case GSOCK_LOST
: /* fall-through */
308 case GSOCK_INPUT
: c
= 0; break;
309 case GSOCK_OUTPUT
: c
= 1; break;
310 case GSOCK_CONNECTION
: c
= ((socket
->m_server
) ? 0 : 1); break;
317 wxSocketEventDispatcher::Get().UnregisterCallback(
318 m_id
[c
], wxSocketEventDispatcherInput
);
320 wxSocketEventDispatcher::Get().UnregisterCallback(
321 m_id
[c
], wxSocketEventDispatcherOutput
);
327 void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket
*socket
)
329 Install_Callback(socket
, GSOCK_INPUT
);
330 Install_Callback(socket
, GSOCK_OUTPUT
);
333 void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket
*socket
)
335 Uninstall_Callback(socket
, GSOCK_INPUT
);
336 Uninstall_Callback(socket
, GSOCK_OUTPUT
);
339 #endif // wxUSE_SOCKETS