more socket cleanup to allow using wxSocket from both wxBase and wxCore (replaces patch 1756260)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50831 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -30,7 +30,7 @@ class WXDLLIMPEXP_FWD_BASE wxString;
|
||||
class WXDLLIMPEXP_FWD_BASE wxTimer;
|
||||
class WXDLLIMPEXP_FWD_BASE wxTimerImpl;
|
||||
|
||||
class GSocketGUIFunctionsTable;
|
||||
class GSocketManager;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -116,13 +116,9 @@ public:
|
||||
virtual void RemoveFromPendingDelete(wxObject *object) = 0;
|
||||
|
||||
#if wxUSE_SOCKETS
|
||||
// return table of GUI callbacks for GSocket code or NULL in wxBase. This
|
||||
// is needed because networking classes are in their own library and so
|
||||
// they can't directly call GUI functions (the same net library can be
|
||||
// used in both GUI and base apps). To complicate it further, GUI library
|
||||
// ("wxCore") doesn't depend on networking library and so only a functions
|
||||
// table can be passed around
|
||||
virtual GSocketGUIFunctionsTable* GetSocketGUIFunctionsTable() = 0;
|
||||
// return socket manager: this is usually different for console and GUI
|
||||
// applications (although some ports use the same implementation for both)
|
||||
virtual GSocketManager *GetSocketManager() = 0;
|
||||
#endif
|
||||
|
||||
// create a new, port specific, instance of the event loop used by wxApp
|
||||
@@ -220,9 +216,6 @@ public:
|
||||
virtual wxFontMapper *CreateFontMapper();
|
||||
#endif // wxUSE_FONTMAP
|
||||
virtual wxRendererNative *CreateRenderer();
|
||||
#if wxUSE_SOCKETS
|
||||
virtual GSocketGUIFunctionsTable* GetSocketGUIFunctionsTable();
|
||||
#endif
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
virtual bool ShowAssertDialog(const wxString& msg);
|
||||
@@ -264,9 +257,6 @@ public:
|
||||
virtual wxFontMapper *CreateFontMapper();
|
||||
#endif // wxUSE_FONTMAP
|
||||
virtual wxRendererNative *CreateRenderer();
|
||||
#if wxUSE_SOCKETS
|
||||
virtual GSocketGUIFunctionsTable* GetSocketGUIFunctionsTable();
|
||||
#endif
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
virtual bool ShowAssertDialog(const wxString& msg);
|
||||
|
||||
@@ -2,26 +2,24 @@
|
||||
* Project: GSocket (Generic Socket)
|
||||
* Name: gsocket.h
|
||||
* Author: Guilhem Lavaux
|
||||
* Guillermo Rodriguez Garcia <guille@iies.es> (maintainer)
|
||||
* Guillermo Rodriguez Garcia <guille@iies.es>
|
||||
* Copyright: (c) Guilhem Lavaux
|
||||
* (c) 2007 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
* Licence: wxWindows Licence
|
||||
* Purpose: GSocket include file (system independent)
|
||||
* CVSID: $Id$
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __GSOCKET_H
|
||||
#define __GSOCKET_H
|
||||
#ifndef _WX_GSOCKET_H_
|
||||
#define _WX_GSOCKET_H_
|
||||
|
||||
#ifndef __GSOCKET_STANDALONE__
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_SOCKETS
|
||||
|
||||
#include "wx/dlimpexp.h" /* for WXDLLIMPEXP_NET */
|
||||
|
||||
#endif
|
||||
|
||||
#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
@@ -37,27 +35,24 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
class GSocket;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _GAddress GAddress;
|
||||
|
||||
typedef enum {
|
||||
enum GAddressType
|
||||
{
|
||||
GSOCK_NOFAMILY = 0,
|
||||
GSOCK_INET,
|
||||
GSOCK_INET6,
|
||||
GSOCK_UNIX
|
||||
} GAddressType;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GSocketStream
|
||||
{
|
||||
GSOCK_STREAMED,
|
||||
GSOCK_UNSTREAMED
|
||||
} GSocketStream;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GSocketError
|
||||
{
|
||||
GSOCK_NOERROR = 0,
|
||||
GSOCK_INVOP,
|
||||
GSOCK_IOERR,
|
||||
@@ -69,19 +64,21 @@ typedef enum {
|
||||
GSOCK_TIMEDOUT,
|
||||
GSOCK_MEMERR,
|
||||
GSOCK_OPTERR
|
||||
} GSocketError;
|
||||
};
|
||||
|
||||
/* See below for an explanation on how events work.
|
||||
*/
|
||||
typedef enum {
|
||||
enum GSocketEvent
|
||||
{
|
||||
GSOCK_INPUT = 0,
|
||||
GSOCK_OUTPUT = 1,
|
||||
GSOCK_CONNECTION = 2,
|
||||
GSOCK_LOST = 3,
|
||||
GSOCK_MAX_EVENT = 4
|
||||
} GSocketEvent;
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT,
|
||||
GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT,
|
||||
GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION,
|
||||
@@ -90,54 +87,99 @@ enum {
|
||||
|
||||
typedef int GSocketEventFlags;
|
||||
|
||||
class GSocket;
|
||||
|
||||
typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event,
|
||||
char *cdata);
|
||||
|
||||
/*
|
||||
Class providing hooks abstracting the differences between console and GUI
|
||||
applications for socket code.
|
||||
|
||||
/* Functions tables for internal use by GSocket code: */
|
||||
|
||||
/* Actually this is a misnomer now, but reusing this name means I don't
|
||||
have to ifdef app traits or common socket code */
|
||||
class GSocketGUIFunctionsTable
|
||||
We also have different implementations of this class for different platforms
|
||||
allowing us to keep more things in the common code but the main reason for
|
||||
its existence is that we want the same socket code work differently
|
||||
depending on whether it's used from a console or a GUI program. This is
|
||||
achieved by implementing the virtual methods of this class differently in
|
||||
the objects returned by wxConsoleAppTraits::GetSocketFunctionsTable() and
|
||||
the same method in wxGUIAppTraits.
|
||||
*/
|
||||
class GSocketManager
|
||||
{
|
||||
public:
|
||||
// needed since this class declares virtual members
|
||||
virtual ~GSocketGUIFunctionsTable() { }
|
||||
// set the manager to use, we don't take ownership of it
|
||||
//
|
||||
// this should be called before GSocket_Init(), i.e. before the first
|
||||
// wxSocket object is created, otherwise the manager returned by
|
||||
// wxAppTraits::GetSocketManager() will be used
|
||||
static void Set(GSocketManager *manager);
|
||||
|
||||
// return the manager to use
|
||||
//
|
||||
// this initializes the manager at first use
|
||||
static GSocketManager *Get()
|
||||
{
|
||||
if ( !ms_manager )
|
||||
Init();
|
||||
|
||||
return ms_manager;
|
||||
}
|
||||
|
||||
// called before the first wxSocket is created and should do the
|
||||
// initializations needed in order to use the network
|
||||
//
|
||||
// return true if initialized successfully
|
||||
virtual bool OnInit() = 0;
|
||||
|
||||
// undo the initializations of OnInit()
|
||||
virtual void OnExit() = 0;
|
||||
virtual bool CanUseEventLoop() = 0;
|
||||
|
||||
|
||||
// do manager-specific socket initializations (and undo it): this is called
|
||||
// in the beginning/end of the socket initialization/destruction
|
||||
virtual bool Init_Socket(GSocket *socket) = 0;
|
||||
virtual void Destroy_Socket(GSocket *socket) = 0;
|
||||
#ifndef __WINDOWS__
|
||||
|
||||
virtual void Install_Callback(GSocket *socket, GSocketEvent event) = 0;
|
||||
virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event) = 0;
|
||||
#endif
|
||||
|
||||
virtual void Enable_Events(GSocket *socket) = 0;
|
||||
virtual void Disable_Events(GSocket *socket) = 0;
|
||||
|
||||
virtual ~GSocketManager() { }
|
||||
|
||||
private:
|
||||
// get the manager to use if we don't have it yet
|
||||
static void Init();
|
||||
|
||||
static GSocketManager *ms_manager;
|
||||
};
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include "wx/msw/gsockmsw.h"
|
||||
#else
|
||||
#include "wx/unix/gsockunx.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Global initializers */
|
||||
|
||||
/* Sets GUI functions callbacks. Must be called *before* GSocket_Init
|
||||
if the app uses async sockets. */
|
||||
void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable *guifunc);
|
||||
|
||||
/* GSocket_Init() must be called at the beginning */
|
||||
int GSocket_Init(void);
|
||||
/* GSocket_Init() must be called at the beginning (but after calling
|
||||
* GSocketManager::Set() if a custom manager should be used) */
|
||||
bool GSocket_Init();
|
||||
|
||||
/* GSocket_Cleanup() must be called at the end */
|
||||
void GSocket_Cleanup(void);
|
||||
void GSocket_Cleanup();
|
||||
|
||||
|
||||
/* Constructors / Destructors */
|
||||
|
||||
GSocket *GSocket_new(void);
|
||||
GSocket *GSocket_new();
|
||||
|
||||
|
||||
/* GAddress */
|
||||
|
||||
GAddress *GAddress_new(void);
|
||||
GAddress *GAddress_new();
|
||||
GAddress *GAddress_copy(GAddress *address);
|
||||
void GAddress_destroy(GAddress *address);
|
||||
|
||||
@@ -185,16 +227,6 @@ unsigned short GAddress_INET6_GetPort(GAddress *address);
|
||||
GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
|
||||
GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* wxUSE_SOCKETS */
|
||||
|
||||
# if defined(__WINDOWS__)
|
||||
# include "wx/msw/gsockmsw.h"
|
||||
# else
|
||||
# include "wx/unix/gsockunx.h"
|
||||
# endif
|
||||
|
||||
#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
|
||||
|
||||
#endif /* __GSOCKET_H */
|
||||
#endif /* _WX_GSOCKET_H_ */
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#define _WX_PRIVATE_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
#include "X11/Xlib.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <Xm/Xm.h>
|
||||
#include "wx/evtloop.h"
|
||||
|
||||
class WXDLLIMPEXP_FWD_CORE wxFont;
|
||||
|
||||
@@ -45,10 +45,32 @@ public:
|
||||
// the GUI code, WAIT_OBJECT_0 + 1 if a Windows message arrived
|
||||
virtual WXDWORD WaitForThread(WXHANDLE hThread) = 0;
|
||||
|
||||
|
||||
// wxSocket support
|
||||
// ----------------
|
||||
|
||||
#if wxUSE_SOCKETS
|
||||
// this function is used by wxNet library to set the default socket manager
|
||||
// to use: doing it like this allows us to keep all socket-related code in
|
||||
// wxNet instead of having to pull it in wxBase itself as we'd have to do
|
||||
// if we really implemented GSocketManager here
|
||||
//
|
||||
// we don't take ownership of this pointer, it should have a lifetime
|
||||
// greater than that of any socket (e.g. be a pointer to a static object)
|
||||
static void SetDefaultSocketManager(GSocketManager *manager)
|
||||
{
|
||||
ms_manager = manager;
|
||||
}
|
||||
|
||||
virtual GSocketManager *GetSocketManager() { return ms_manager; }
|
||||
#endif // wxUSE_SOCKETS
|
||||
|
||||
protected:
|
||||
// implementation of WaitForThread() for the console applications which is
|
||||
// also used by the GUI code if it doesn't [yet|already} dispatch events
|
||||
WXDWORD DoSimpleWaitForThread(WXHANDLE hThread);
|
||||
|
||||
static GSocketManager *ms_manager;
|
||||
};
|
||||
|
||||
#endif // _WX_MSW_APPTBASE_H_
|
||||
|
||||
@@ -8,20 +8,8 @@
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __GSOCK_MSW_H
|
||||
#define __GSOCK_MSW_H
|
||||
|
||||
#ifndef __GSOCKET_STANDALONE__
|
||||
#include "wx/setup.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
|
||||
|
||||
#ifndef __GSOCKET_STANDALONE__
|
||||
#include "wx/gsocket.h"
|
||||
#else
|
||||
#include "gsocket.h"
|
||||
#endif
|
||||
#ifndef _WX_MSW_GSOCKMSW_H_
|
||||
#define _WX_MSW_GSOCKMSW_H_
|
||||
|
||||
#include "wx/msw/wrapwin.h"
|
||||
|
||||
@@ -35,18 +23,6 @@
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
class GSocketGUIFunctionsTableConcrete: public GSocketGUIFunctionsTable
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual void OnExit();
|
||||
virtual bool CanUseEventLoop();
|
||||
virtual bool Init_Socket(GSocket *socket);
|
||||
virtual void Destroy_Socket(GSocket *socket);
|
||||
virtual void Enable_Events(GSocket *socket);
|
||||
virtual void Disable_Events(GSocket *socket);
|
||||
};
|
||||
|
||||
/* Definition of GSocket */
|
||||
class GSocket
|
||||
{
|
||||
@@ -62,6 +38,8 @@ public:
|
||||
GAddress *GetPeer();
|
||||
GSocketError SetServer();
|
||||
GSocket *WaitConnection();
|
||||
// not used under MSW
|
||||
void Notify(bool) { }
|
||||
bool SetReusable();
|
||||
bool SetBroadcast();
|
||||
bool DontDoBind();
|
||||
@@ -123,10 +101,6 @@ public:
|
||||
int m_msgnumber;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Definition of GAddress */
|
||||
struct _GAddress
|
||||
{
|
||||
@@ -149,10 +123,4 @@ GSocketError _GAddress_translate_to (GAddress *address,
|
||||
GSocketError _GAddress_Init_INET(GAddress *address);
|
||||
GSocketError _GAddress_Init_UNIX(GAddress *address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
|
||||
|
||||
#endif /* __GSOCK_MSW_H */
|
||||
#endif /* _WX_MSW_GSOCKMSW_H_ */
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Name: wx/private/gsocketiohandler.h
|
||||
// Purpose: class for registering GSocket in wxSelectDispatcher
|
||||
// Authors: Lukasz Michalski
|
||||
// Modified by:
|
||||
// Created: December 2006
|
||||
// Copyright: (c) Lukasz Michalski
|
||||
// RCS-ID: $Id$
|
||||
@@ -13,30 +12,34 @@
|
||||
#define _WX_PRIVATE_GSOCKETIOHANDLER_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_SOCKETS && wxUSE_SELECT_DISPATCHER
|
||||
|
||||
#include "wx/private/selectdispatcher.h"
|
||||
#include "wx/gsocket.h"
|
||||
|
||||
#if wxUSE_SOCKETS
|
||||
|
||||
// forward declarations
|
||||
class GSocket;
|
||||
|
||||
class WXDLLIMPEXP_CORE wxGSocketIOHandler : public wxFDIOHandler
|
||||
class WXDLLIMPEXP_BASE wxGSocketIOHandler : public wxFDIOHandler
|
||||
{
|
||||
public:
|
||||
wxGSocketIOHandler(GSocket* socket);
|
||||
int GetFlags() const;
|
||||
void RemoveFlag(wxFDIODispatcherEntryFlags flag);
|
||||
void AddFlag(wxFDIODispatcherEntryFlags flag);
|
||||
wxGSocketIOHandler(GSocket* socket)
|
||||
{
|
||||
m_socket = socket;
|
||||
m_flags = 0;
|
||||
}
|
||||
|
||||
virtual void OnReadWaiting();
|
||||
virtual void OnWriteWaiting();
|
||||
virtual void OnExceptionWaiting();
|
||||
int GetFlags() const { return m_flags; }
|
||||
void RemoveFlag(wxFDIODispatcherEntryFlags flag) { m_flags &= ~flag; }
|
||||
void AddFlag(wxFDIODispatcherEntryFlags flag) { m_flags |= flag; }
|
||||
|
||||
virtual void OnReadWaiting() { m_socket->Detected_Read(); }
|
||||
virtual void OnWriteWaiting() { m_socket->Detected_Write(); }
|
||||
virtual void OnExceptionWaiting() { m_socket->Detected_Read(); }
|
||||
|
||||
private:
|
||||
GSocket* m_socket;
|
||||
int m_flags;
|
||||
};
|
||||
|
||||
#endif // wxUSE_SOCKETS
|
||||
#endif // wxUSE_SOCKETS && wxUSE_SELECT_DISPATCHER
|
||||
|
||||
#endif // _WX_PRIVATE_SOCKETEVTDISPATCH_H_
|
||||
|
||||
@@ -48,6 +48,13 @@ public:
|
||||
// ----------------
|
||||
|
||||
// TODO
|
||||
|
||||
#if wxUSE_SOCKETS
|
||||
// returns the select()-based socket manager for console applications which
|
||||
// is also used by some ports (wxX11, wxDFB) in the GUI build (hence it is
|
||||
// here and not in wxConsoleAppTraits)
|
||||
virtual GSocketManager *GetSocketManager();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // _WX_UNIX_APPTBASE_H_
|
||||
|
||||
@@ -67,6 +67,17 @@ public:
|
||||
#if defined(__WXDEBUG__) && defined(__WXGTK20__)
|
||||
virtual bool ShowAssertDialog(const wxString& msg);
|
||||
#endif
|
||||
|
||||
// GTK+ and Motif integrate sockets directly in their main loop, the other
|
||||
// Unix ports do it at wxEventLoop level
|
||||
//
|
||||
// TODO: Should we use XtAddInput() for wxX11 too? Or, vice versa, if there
|
||||
// is no advantage in doing this compared to the generic way
|
||||
// currently used by wxX11, should we continue to use GTK/Motif-
|
||||
// specific stuff?
|
||||
#if wxUSE_SOCKETS && (defined(__WXGTK__) || defined(__WXMOTIF__))
|
||||
virtual GSocketManager *GetSocketManager();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
@@ -8,37 +8,11 @@
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __GSOCK_UNX_H
|
||||
#define __GSOCK_UNX_H
|
||||
|
||||
#ifndef __GSOCKET_STANDALONE__
|
||||
#include "wx/setup.h"
|
||||
#endif
|
||||
#ifndef _WX_UNIX_GSOCKUNX_H_
|
||||
#define _WX_UNIX_GSOCKUNX_H_
|
||||
|
||||
class wxGSocketIOHandler;
|
||||
|
||||
#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
|
||||
|
||||
#ifndef __GSOCKET_STANDALONE__
|
||||
#include "wx/gsocket.h"
|
||||
#else
|
||||
#include "gsocket.h"
|
||||
#endif
|
||||
|
||||
class GSocketGUIFunctionsTableConcrete : public GSocketGUIFunctionsTable
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual void OnExit();
|
||||
virtual bool CanUseEventLoop();
|
||||
virtual bool Init_Socket(GSocket *socket);
|
||||
virtual void Destroy_Socket(GSocket *socket);
|
||||
virtual void Install_Callback(GSocket *socket, GSocketEvent event);
|
||||
virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event);
|
||||
virtual void Enable_Events(GSocket *socket);
|
||||
virtual void Disable_Events(GSocket *socket);
|
||||
};
|
||||
|
||||
class GSocket
|
||||
{
|
||||
public:
|
||||
@@ -70,6 +44,8 @@ public:
|
||||
GSocketError GetSockOpt(int level, int optname, void *optval, int *optlen);
|
||||
GSocketError SetSockOpt(int level, int optname,
|
||||
const void *optval, int optlen);
|
||||
//attach or detach from main loop
|
||||
void Notify(bool flag);
|
||||
virtual void Detected_Read();
|
||||
virtual void Detected_Write();
|
||||
void SetInitialSocketBuffers(int recv, int send)
|
||||
@@ -79,6 +55,9 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
//enable or disable event callback using gsocket gui callback table
|
||||
void EnableEvents(bool flag = true);
|
||||
void DisableEvents() { EnableEvents(false); }
|
||||
void Enable(GSocketEvent event);
|
||||
void Disable(GSocketEvent event);
|
||||
GSocketError Input_Timeout();
|
||||
@@ -108,18 +87,18 @@ public:
|
||||
bool m_dobind;
|
||||
unsigned long m_timeout;
|
||||
|
||||
// true if socket should fire events
|
||||
bool m_use_events;
|
||||
|
||||
/* Callbacks */
|
||||
GSocketEventFlags m_detected;
|
||||
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
|
||||
char *m_data[GSOCK_MAX_EVENT];
|
||||
|
||||
char *m_gui_dependent;
|
||||
|
||||
// pointer for storing extra (usually GUI-specific) data
|
||||
void *m_gui_dependent;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
/* Definition of GAddress */
|
||||
struct _GAddress
|
||||
{
|
||||
@@ -131,15 +110,6 @@ struct _GAddress
|
||||
|
||||
GSocketError m_error;
|
||||
};
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/* GAddress */
|
||||
|
||||
@@ -150,11 +120,121 @@ GSocketError _GAddress_translate_to (GAddress *address,
|
||||
GSocketError _GAddress_Init_INET(GAddress *address);
|
||||
GSocketError _GAddress_Init_UNIX(GAddress *address);
|
||||
|
||||
// A version of GSocketManager which uses FDs for socket IO
|
||||
//
|
||||
// This class uses GSocket::m_gui_dependent field to store the 2 (for input and
|
||||
// output) FDs associated with the socket.
|
||||
class GSocketFDBasedManager : public GSocketManager
|
||||
{
|
||||
public:
|
||||
// no special initialization/cleanup needed when using FDs
|
||||
virtual bool OnInit() { return true; }
|
||||
virtual void OnExit() { }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
// allocate/free the storage we need
|
||||
virtual bool Init_Socket(GSocket *socket)
|
||||
{
|
||||
socket->m_gui_dependent = malloc(sizeof(int)*2);
|
||||
int * const fds = wx_static_cast(int *, socket->m_gui_dependent);
|
||||
|
||||
#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
|
||||
fds[0] = -1;
|
||||
fds[1] = -1;
|
||||
|
||||
#endif /* __GSOCK_UNX_H */
|
||||
return true;
|
||||
}
|
||||
virtual void Destroy_Socket(GSocket *socket)
|
||||
{
|
||||
free(socket->m_gui_dependent);
|
||||
}
|
||||
|
||||
virtual void Enable_Events(GSocket *socket)
|
||||
{
|
||||
Install_Callback(socket, GSOCK_INPUT);
|
||||
Install_Callback(socket, GSOCK_OUTPUT);
|
||||
}
|
||||
virtual void Disable_Events(GSocket *socket)
|
||||
{
|
||||
Uninstall_Callback(socket, GSOCK_INPUT);
|
||||
Uninstall_Callback(socket, GSOCK_OUTPUT);
|
||||
}
|
||||
|
||||
protected:
|
||||
// identifies either input or output direction
|
||||
//
|
||||
// NB: the values of this enum shouldn't change
|
||||
enum SocketDir
|
||||
{
|
||||
FD_INPUT,
|
||||
FD_OUTPUT
|
||||
};
|
||||
|
||||
// get the FD index corresponding to the given GSocketEvent
|
||||
SocketDir GetDirForEvent(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
default:
|
||||
wxFAIL_MSG( "unexpected socket event" );
|
||||
// fall through
|
||||
|
||||
case GSOCK_LOST:
|
||||
// fall through
|
||||
|
||||
case GSOCK_INPUT:
|
||||
return FD_INPUT;
|
||||
|
||||
case GSOCK_OUTPUT:
|
||||
return FD_OUTPUT;
|
||||
|
||||
case GSOCK_CONNECTION:
|
||||
// FIXME: explain this?
|
||||
return socket->m_server ? FD_INPUT : FD_OUTPUT;
|
||||
}
|
||||
}
|
||||
|
||||
// access the FDs we store
|
||||
int& FD(GSocket *socket, SocketDir d)
|
||||
{
|
||||
return wx_static_cast(int *, socket->m_gui_dependent)[d];
|
||||
}
|
||||
};
|
||||
|
||||
// Common base class for all ports using X11-like (and hence implemented in
|
||||
// X11, Motif and GTK) AddInput() and RemoveInput() functions
|
||||
class GSocketInputBasedManager : public GSocketFDBasedManager
|
||||
{
|
||||
public:
|
||||
virtual void Install_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
wxCHECK_RET( socket->m_fd != -1,
|
||||
"shouldn't be called on invalid socket" );
|
||||
|
||||
const SocketDir d = GetDirForEvent(socket, event);
|
||||
|
||||
int& fd = FD(socket, d);
|
||||
if ( fd != -1 )
|
||||
RemoveInput(fd);
|
||||
|
||||
fd = AddInput(socket, d);
|
||||
}
|
||||
|
||||
virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event)
|
||||
{
|
||||
const SocketDir d = GetDirForEvent(socket, event);
|
||||
|
||||
int& fd = FD(socket, d);
|
||||
if ( fd != -1 )
|
||||
{
|
||||
RemoveInput(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// these functions map directly to XtAdd/RemoveInput() or
|
||||
// gdk_input_add/remove()
|
||||
virtual int AddInput(GSocket *socket, SocketDir d) = 0;
|
||||
virtual void RemoveInput(int fd) = 0;
|
||||
};
|
||||
|
||||
#endif /* _WX_UNIX_GSOCKUNX_H_ */
|
||||
|
||||
Reference in New Issue
Block a user