+++ /dev/null
-///////////////////////////////////////////////////////////////////////////////
-// Name: src/common/socketevtdispatch.cpp
-// Purpose: implements wxSocketEventDispatcher for platforms with no
-// socket events notification
-// Author: Angel Vidal
-// Modified by:
-// Created: 08.24.06
-// RCS-ID: $Id$
-// Copyright: (c) 2006 Angel vidal
-// License: wxWindows licence
-///////////////////////////////////////////////////////////////////////////////
-
-// ============================================================================
-// declarations
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// headers
-// ----------------------------------------------------------------------------
-
-// for compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
-
-#if wxUSE_SOCKETS
-
-#include "wx/private/socketevtdispatch.h"
-#include "wx/module.h"
-#include "wx/unix/private.h"
-#include "wx/gsocket.h"
-#include "wx/unix/gsockunx.h"
-
-#ifndef WX_PRECOMP
- #include "wx/hash.h"
-#endif
-
-#include <sys/time.h>
-#include <unistd.h>
-
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-// ============================================================================
-// implementation
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// wxSocketEventDispatcherEntry
-// ----------------------------------------------------------------------------
-
-class wxSocketEventDispatcherEntry: public wxObject
-{
- public:
- wxSocketEventDispatcherEntry()
- {
- m_fdInput = -1; m_fdOutput = -1;
- m_socket = NULL;
- }
-
- int m_fdInput;
- int m_fdOutput;
- GSocket* m_socket;
-};
-
-// ----------------------------------------------------------------------------
-// wxSocketEventDispatcher
-// ----------------------------------------------------------------------------
-
-wxSocketEventDispatcher* wxSocketEventDispatcher::ms_instance = NULL;
-
-/* static */
-wxSocketEventDispatcher& wxSocketEventDispatcher::Get()
-{
- if ( !ms_instance )
- ms_instance = new wxSocketEventDispatcher;
- return *ms_instance;
-}
-
-wxSocketEventDispatcherEntry* wxSocketEventDispatcher::FindEntry(int fd)
-{
- wxSocketEventDispatcherEntry* entry =
- (wxSocketEventDispatcherEntry*) wxHashTable::Get(fd);
- return entry;
-}
-
-void
-wxSocketEventDispatcher::RegisterCallback(int fd,
- wxSocketEventDispatcherType socketType,
- GSocket* socket)
-{
- wxSocketEventDispatcherEntry* entry = FindEntry(fd);
- if (!entry)
- {
- entry = new wxSocketEventDispatcherEntry();
- Put(fd, entry);
- }
-
- if (socketType == wxSocketEventDispatcherInput)
- entry->m_fdInput = fd;
- else
- entry->m_fdOutput = fd;
-
- entry->m_socket = socket;
-}
-
-void
-wxSocketEventDispatcher::UnregisterCallback(int fd,
- wxSocketEventDispatcherType socketType)
-{
- wxSocketEventDispatcherEntry* entry = FindEntry(fd);
- if (entry)
- {
- if (socketType == wxSocketEventDispatcherInput)
- entry->m_fdInput = -1;
- else
- entry->m_fdOutput = -1;
-
- if (entry->m_fdInput == -1 && entry->m_fdOutput == -1)
- {
- entry->m_socket = NULL;
- Delete(fd);
- delete entry;
- }
- }
-}
-
-int wxSocketEventDispatcher::FillSets(fd_set* readset, fd_set* writeset)
-{
- int max_fd = 0;
-
- wxFD_ZERO(readset);
- wxFD_ZERO(writeset);
-
- BeginFind();
- wxHashTable::compatibility_iterator node = Next();
- while (node)
- {
- wxSocketEventDispatcherEntry* entry =
- (wxSocketEventDispatcherEntry*) node->GetData();
-
- if (entry->m_fdInput != -1)
- {
- wxFD_SET(entry->m_fdInput, readset);
- if (entry->m_fdInput > max_fd)
- max_fd = entry->m_fdInput;
- }
-
- if (entry->m_fdOutput != -1)
- {
- wxFD_SET(entry->m_fdOutput, writeset);
- if (entry->m_fdOutput > max_fd)
- max_fd = entry->m_fdOutput;
- }
-
- node = Next();
- }
-
- return max_fd;
-}
-
-void wxSocketEventDispatcher::AddEvents(fd_set* readset, fd_set* writeset)
-{
- BeginFind();
- wxHashTable::compatibility_iterator node = Next();
- while (node)
- {
- // We have to store the next node here, because the event processing can
- // destroy the object before we call Next()
-
- wxHashTable::compatibility_iterator next_node = Next();
-
- wxSocketEventDispatcherEntry* entry =
- (wxSocketEventDispatcherEntry*) node->GetData();
-
- wxCHECK_RET(entry->m_socket, wxT("Critical: Processing a NULL socket in wxSocketEventDispatcher"));
-
- if (entry->m_fdInput != -1 && wxFD_ISSET(entry->m_fdInput, readset))
- entry->m_socket->Detected_Read();
-
- if (entry->m_fdOutput != -1 && wxFD_ISSET(entry->m_fdOutput, writeset))
- entry->m_socket->Detected_Write();;
-
- node = next_node;
- }
-}
-
-void wxSocketEventDispatcher::RunLoop(int timeout)
-{
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = timeout;
- fd_set readset;
- fd_set writeset;
-
- int max_fd = FillSets( &readset, &writeset);
- if (select( max_fd+1, &readset, &writeset, NULL, &tv ) == 0)
- {
- // No socket input/output. Don't add events.
- return;
- }
- else
- {
- AddEvents(&readset, &writeset);
- }
-}
-
-// ----------------------------------------------------------------------------
-// wxSocketEventDispatcherModule
-// ----------------------------------------------------------------------------
-
-class wxSocketEventDispatcherModule: public wxModule
-{
-public:
- bool OnInit() { return true; }
- void OnExit() { wxDELETE(wxSocketEventDispatcher::ms_instance); }
-
-private:
- DECLARE_DYNAMIC_CLASS(wxSocketEventDispatcherModule)
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxSocketEventDispatcherModule, wxModule)
-
-
-// ----------------------------------------------------------------------------
-// GSocket interface
-// ----------------------------------------------------------------------------
-
-bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop()
-{
- return true;
-}
-
-bool GSocketGUIFunctionsTableConcrete::OnInit(void)
-{
- return 1;
-}
-
-void GSocketGUIFunctionsTableConcrete::OnExit(void)
-{
-}
-
-bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket)
-{
- int *m_id;
-
- socket->m_gui_dependent = (char *)malloc(sizeof(int)*2);
- m_id = (int *)(socket->m_gui_dependent);
-
- m_id[0] = -1;
- m_id[1] = -1;
-
- return true;
-}
-
-void GSocketGUIFunctionsTableConcrete::Destroy_Socket(GSocket *socket)
-{
- free(socket->m_gui_dependent);
-}
-
-void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket,
- GSocketEvent event)
-{
- int *m_id = (int *)(socket->m_gui_dependent);
- int c;
-
- if (socket->m_fd == -1)
- return;
-
- switch (event)
- {
- case GSOCK_LOST: /* fall-through */
- case GSOCK_INPUT: c = 0; break;
- case GSOCK_OUTPUT: c = 1; break;
- case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break;
- default: return;
- }
-
-#if 0
- if (m_id[c] != -1)
- XtRemoveInput(m_id[c]);
-#endif /* 0 */
-
- if (c == 0)
- {
- m_id[0] = socket->m_fd;
-
- wxSocketEventDispatcher::Get().RegisterCallback(
- socket->m_fd, wxSocketEventDispatcherInput, socket);
- }
- else
- {
- m_id[1] = socket->m_fd;
-
- wxSocketEventDispatcher::Get().RegisterCallback(
- socket->m_fd, wxSocketEventDispatcherOutput, socket);
- }
-}
-
-void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket,
- GSocketEvent event)
-{
- int *m_id = (int *)(socket->m_gui_dependent);
- int c;
-
- switch (event)
- {
- case GSOCK_LOST: /* fall-through */
- case GSOCK_INPUT: c = 0; break;
- case GSOCK_OUTPUT: c = 1; break;
- case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break;
- default: return;
- }
-
- if (m_id[c] != -1)
- {
- if (c == 0)
- wxSocketEventDispatcher::Get().UnregisterCallback(
- m_id[c], wxSocketEventDispatcherInput);
- else
- wxSocketEventDispatcher::Get().UnregisterCallback(
- m_id[c], wxSocketEventDispatcherOutput);
- }
-
- m_id[c] = -1;
-}
-
-void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket)
-{
- Install_Callback(socket, GSOCK_INPUT);
- Install_Callback(socket, GSOCK_OUTPUT);
-}
-
-void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket)
-{
- Uninstall_Callback(socket, GSOCK_INPUT);
- Uninstall_Callback(socket, GSOCK_OUTPUT);
-}
-
-#endif // wxUSE_SOCKETS