fixed wxBase and GUI separation for sockets code

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22668 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2003-08-07 12:26:17 +00:00
parent 698ec18272
commit 38bb138f09
19 changed files with 542 additions and 253 deletions

View File

@@ -24,6 +24,8 @@ class WXDLLIMPEXP_BASE wxMessageOutput;
class WXDLLEXPORT wxRendererNative; class WXDLLEXPORT wxRendererNative;
class WXDLLIMPEXP_BASE wxString; class WXDLLIMPEXP_BASE wxString;
extern "C" struct GSocketGUIFunctionsTable;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// toolkit information // toolkit information
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -105,6 +107,11 @@ public:
// wxBase // wxBase
virtual void RemoveFromPendingDelete(wxObject *object) = 0; virtual void RemoveFromPendingDelete(wxObject *object) = 0;
#if wxUSE_SOCKETS
// return table of GUI callbacks for GSocket code or NULL in wxBase
virtual GSocketGUIFunctionsTable* GetSocketGUIFunctionsTable() = 0;
#endif
// return information about what toolkit is running; we need for two things // return information about what toolkit is running; we need for two things
// that are both contained in wxBase: // that are both contained in wxBase:
@@ -154,6 +161,9 @@ public:
virtual wxFontMapper *CreateFontMapper(); virtual wxFontMapper *CreateFontMapper();
#endif // wxUSE_FONTMAP #endif // wxUSE_FONTMAP
virtual wxRendererNative *CreateRenderer(); virtual wxRendererNative *CreateRenderer();
#if wxUSE_SOCKETS
virtual GSocketGUIFunctionsTable* GetSocketGUIFunctionsTable();
#endif
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
virtual bool ShowAssertDialog(const wxString& msg); virtual bool ShowAssertDialog(const wxString& msg);
@@ -181,6 +191,9 @@ public:
virtual wxFontMapper *CreateFontMapper(); virtual wxFontMapper *CreateFontMapper();
#endif // wxUSE_FONTMAP #endif // wxUSE_FONTMAP
virtual wxRendererNative *CreateRenderer(); virtual wxRendererNative *CreateRenderer();
#if wxUSE_SOCKETS
virtual GSocketGUIFunctionsTable* GetSocketGUIFunctionsTable();
#endif
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
virtual bool ShowAssertDialog(const wxString& msg); virtual bool ShowAssertDialog(const wxString& msg);

View File

@@ -95,8 +95,37 @@ typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event,
char *cdata); char *cdata);
/* Functions tables for internal use by GSocket code: */
#ifndef __WINDOWS__
struct GSocketBaseFunctionsTable
{
void (*Detected_Read)(GSocket *socket);
void (*Detected_Write)(GSocket *socket);
};
#endif
struct GSocketGUIFunctionsTable
{
int (*GUI_Init)(void);
void (*GUI_Cleanup)(void);
int (*GUI_Init_Socket)(GSocket *socket);
void (*GUI_Destroy_Socket)(GSocket *socket);
#ifndef __WINDOWS__
void (*Install_Callback)(GSocket *socket, GSocketEvent event);
void (*Uninstall_Callback)(GSocket *socket, GSocketEvent event);
#endif
void (*Enable_Events)(GSocket *socket);
void (*Disable_Events)(GSocket *socket);
};
/* Global initializers */ /* Global initializers */
/* Sets GUI functions callbacks. Must be called *before* GSocket_Init
if the app uses async sockets. */
void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc);
/* GSocket_Init() must be called at the beginning */ /* GSocket_Init() must be called at the beginning */
int GSocket_Init(void); int GSocket_Init(void);

View File

@@ -83,8 +83,10 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
/* Callbacks */ /* Callbacks */
int _GSocket_GUI_Init(GSocket *socket); int _GSocket_GUI_Init(void);
void _GSocket_GUI_Destroy(GSocket *socket); void _GSocket_GUI_Cleanup(void);
int _GSocket_GUI_Init_Socket(GSocket *socket);
void _GSocket_GUI_Destroy_Socket(GSocket *socket);
LRESULT CALLBACK _GSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK _GSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM);

View File

@@ -56,6 +56,9 @@ struct _GSocket
char *m_data[GSOCK_MAX_EVENT]; char *m_data[GSOCK_MAX_EVENT];
char *m_gui_dependent; char *m_gui_dependent;
/* Function pointers */
struct GSocketBaseFunctionsTable *m_functions;
}; };
/* Definition of GAddress */ /* Definition of GAddress */
@@ -81,8 +84,11 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
/* Callbacks */ /* Callbacks */
int _GSocket_GUI_Init(GSocket *socket); int _GSocket_GUI_Init(void);
void _GSocket_GUI_Destroy(GSocket *socket); void _GSocket_GUI_Cleanup(void);
int _GSocket_GUI_Init_Socket(GSocket *socket);
void _GSocket_GUI_Destroy_Socket(GSocket *socket);
void _GSocket_Enable_Events(GSocket *socket); void _GSocket_Enable_Events(GSocket *socket);
void _GSocket_Disable_Events(GSocket *socket); void _GSocket_Disable_Events(GSocket *socket);

View File

@@ -12,12 +12,21 @@
#include <stdlib.h> #include <stdlib.h>
#include "wx/gsocket.h" #include "wx/gsocket.h"
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init(void)
{
return 1;
}
void _GSocket_GUI_Cleanup(void)
{
}
int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
return 0; return 0;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
} }

View File

@@ -456,6 +456,13 @@ void wxConsoleAppTraitsBase::RemoveFromPendingDelete(wxObject * WXUNUSED(object)
{ {
// nothing to do // nothing to do
} }
#if wxUSE_SOCKETS
GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable()
{
return NULL;
}
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxAppTraits // wxAppTraits

View File

@@ -497,3 +497,35 @@ void wxGUIAppTraitsBase::RemoveFromPendingDelete(wxObject *object)
wxPendingDelete.DeleteObject(object); wxPendingDelete.DeleteObject(object);
} }
#if wxUSE_SOCKETS
#if defined(__UNIX__) || defined(__DARWIN__) || defined(__OS2__)
#include "wx/unix/gsockunx.h"
#elif defined(__WINDOWS__)
#include "wx/msw/gsockmsw.h"
#elif defined(__MAC__)
#include "wx/mac/gsockmac.h"
#else
#error "Must include correct GSocket header here"
#endif
GSocketGUIFunctionsTable* wxGUIAppTraitsBase::GetSocketGUIFunctionsTable()
{
static GSocketGUIFunctionsTable table =
{
_GSocket_GUI_Init,
_GSocket_GUI_Cleanup,
_GSocket_GUI_Init_Socket,
_GSocket_GUI_Destroy_Socket,
#ifndef __WINDOWS__
_GSocket_Install_Callback,
_GSocket_Uninstall_Callback,
#endif
_GSocket_Enable_Events,
_GSocket_Disable_Events
};
return &table;
}
#endif

View File

@@ -126,6 +126,12 @@ bool wxSocketBase::Initialize()
{ {
if ( !m_countInit++ ) if ( !m_countInit++ )
{ {
wxAppTraits *traits = wxAppConsole::GetInstance() ?
wxAppConsole::GetInstance()->GetTraits() : NULL;
GSocketGUIFunctionsTable *functions =
traits ? traits->GetSocketGUIFunctionsTable() : NULL;
GSocket_SetGUIFunctions(functions);
if ( !GSocket_Init() ) if ( !GSocket_Init() )
{ {
m_countInit--; m_countInit--;

View File

@@ -28,12 +28,21 @@ void _GSocket_GDK_Input(gpointer data,
GSocket *socket = (GSocket *)data; GSocket *socket = (GSocket *)data;
if (condition & GDK_INPUT_READ) if (condition & GDK_INPUT_READ)
_GSocket_Detected_Read(socket); socket->m_functions->Detected_Read(socket);
if (condition & GDK_INPUT_WRITE) if (condition & GDK_INPUT_WRITE)
_GSocket_Detected_Write(socket); socket->m_functions->Detected_Write(socket);
} }
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init(void)
{
return 1;
}
void _GSocket_GUI_Cleanup(void)
{
}
int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
gint *m_id; gint *m_id;
@@ -46,7 +55,7 @@ int _GSocket_GUI_Init(GSocket *socket)
return TRUE; return TRUE;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
free(socket->m_gui_dependent); free(socket->m_gui_dependent);
} }

View File

@@ -28,12 +28,21 @@ void _GSocket_GDK_Input(gpointer data,
GSocket *socket = (GSocket *)data; GSocket *socket = (GSocket *)data;
if (condition & GDK_INPUT_READ) if (condition & GDK_INPUT_READ)
_GSocket_Detected_Read(socket); socket->m_functions->Detected_Read(socket);
if (condition & GDK_INPUT_WRITE) if (condition & GDK_INPUT_WRITE)
_GSocket_Detected_Write(socket); socket->m_functions->Detected_Write(socket);
} }
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init(void)
{
return 1;
}
void _GSocket_GUI_Cleanup(void)
{
}
int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
gint *m_id; gint *m_id;
@@ -46,7 +55,7 @@ int _GSocket_GUI_Init(GSocket *socket)
return TRUE; return TRUE;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
free(socket->m_gui_dependent); free(socket->m_gui_dependent);
} }

View File

@@ -196,6 +196,11 @@ static void SetDefaultEndpointModes(EndpointRef ep , void *data )
/* Global initialisers */ /* Global initialisers */
void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *)
{
// do nothing, wxMac doesn't have wxBase-GUI separation yet
}
int GSocket_Init() int GSocket_Init()
{ {
return TRUE; return TRUE;

View File

@@ -196,6 +196,11 @@ static void SetDefaultEndpointModes(EndpointRef ep , void *data )
/* Global initialisers */ /* Global initialisers */
void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *)
{
// do nothing, wxMac doesn't have wxBase-GUI separation yet
}
int GSocket_Init() int GSocket_Init()
{ {
return TRUE; return TRUE;

View File

@@ -22,7 +22,7 @@ static void _GSocket_Motif_Input(XtPointer data, int *fid,
{ {
GSocket *socket = (GSocket *)data; GSocket *socket = (GSocket *)data;
_GSocket_Detected_Read(socket); socket->m_functions->Detected_Read(socket);
} }
static void _GSocket_Motif_Output(XtPointer data, int *fid, static void _GSocket_Motif_Output(XtPointer data, int *fid,
@@ -30,10 +30,19 @@ static void _GSocket_Motif_Output(XtPointer data, int *fid,
{ {
GSocket *socket = (GSocket *)data; GSocket *socket = (GSocket *)data;
_GSocket_Detected_Write(socket); socket->m_functions->Detected_Write(socket);
} }
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init(void)
{
return 1;
}
void _GSocket_GUI_Cleanup(void)
{
}
int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
int *m_id; int *m_id;
@@ -46,7 +55,7 @@ int _GSocket_GUI_Init(GSocket *socket)
return TRUE; return TRUE;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
free(socket->m_gui_dependent); free(socket->m_gui_dependent);
} }

View File

@@ -73,6 +73,62 @@
# define SOCKLEN_T int # define SOCKLEN_T int
#endif #endif
/* Table of GUI-related functions. We must call them indirectly because
* of wxBase and GUI separation: */
static struct GSocketGUIFunctionsTable *gs_gui_functions;
#define USE_GUI() (gs_gui_functions != NULL)
/* Define macros to simplify indirection: */
#define _GSocket_GUI_Init() \
if (gs_gui_functions) gs_gui_functions->GUI_Init()
#define _GSocket_GUI_Cleanup() \
if (gs_gui_functions) gs_gui_functions->GUI_Cleanup()
#define _GSocket_GUI_Init_Socket(socket) \
(gs_gui_functions ? gs_gui_functions->GUI_Init_Socket(socket) : 1)
#define _GSocket_GUI_Destroy_Socket(socket) \
if (gs_gui_functions) gs_gui_functions->GUI_Destroy_Socket(socket)
#define _GSocket_Enable_Events(socket) \
if (gs_gui_functions) gs_gui_functions->Enable_Events(socket)
#define _GSocket_Disable_Events(socket) \
if (gs_gui_functions) gs_gui_functions->Disable_Events(socket)
#define _GSocket_Install_Callback(socket, event) \
if (gs_gui_functions) gs_gui_functions->Install_Callback(socket, event)
#define _GSocket_Uninstall_Callback(socket, event) \
if (gs_gui_functions) gs_gui_functions->Uninstall_Callback(socket, event)
/* Global initialisers */
void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc)
{
gs_gui_functions = guifunc;
}
int GSocket_Init(void)
{
WSADATA wsaData;
if (gs_gui_functions)
{
if ( !gs_gui_functions->GUI_Init() )
return 0;
}
/* Initialize WinSocket */
return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
}
void GSocket_Cleanup(void)
{
if (gs_gui_functions)
{
gs_gui_functions->GUI_Cleanup();
}
/* Cleanup WinSocket */
WSACleanup();
}
/* Constructors / Destructors for GSocket */ /* Constructors / Destructors for GSocket */
@@ -101,7 +157,7 @@ GSocket *GSocket_new(void)
socket->m_establishing = FALSE; socket->m_establishing = FALSE;
/* Per-socket GUI-specific initialization */ /* Per-socket GUI-specific initialization */
success = _GSocket_GUI_Init(socket); success = _GSocket_GUI_Init_Socket(socket);
if (!success) if (!success)
{ {
free(socket); free(socket);
@@ -123,7 +179,7 @@ void GSocket_destroy(GSocket *socket)
assert(socket != NULL); assert(socket != NULL);
/* Per-socket GUI-specific cleanup */ /* Per-socket GUI-specific cleanup */
_GSocket_GUI_Destroy(socket); _GSocket_GUI_Destroy_Socket(socket);
/* Check that the socket is really shutdowned */ /* Check that the socket is really shutdowned */
if (socket->m_fd != INVALID_SOCKET) if (socket->m_fd != INVALID_SOCKET)

View File

@@ -106,9 +106,8 @@ static int firstAvailable;
/* Global initializers */ /* Global initializers */
int GSocket_Init(void) int _GSocket_GUI_Init(void)
{ {
WSADATA wsaData;
WNDCLASS winClass; WNDCLASS winClass;
int i; int i;
@@ -141,11 +140,10 @@ int GSocket_Init(void)
} }
firstAvailable = 0; firstAvailable = 0;
/* Initialize WinSocket */ return 1;
return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
} }
void GSocket_Cleanup(void) void _GSocket_GUI_Cleanup(void)
{ {
/* Destroy internal window */ /* Destroy internal window */
DestroyWindow(hWin); DestroyWindow(hWin);
@@ -153,14 +151,11 @@ void GSocket_Cleanup(void)
/* Delete critical section */ /* Delete critical section */
DeleteCriticalSection(&critical); DeleteCriticalSection(&critical);
/* Cleanup WinSocket */
WSACleanup();
} }
/* Per-socket GUI initialization / cleanup */ /* Per-socket GUI initialization / cleanup */
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
int i; int i;
@@ -187,7 +182,7 @@ int _GSocket_GUI_Init(GSocket *socket)
return TRUE; return TRUE;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
/* Remove the socket from the list */ /* Remove the socket from the list */
EnterCriticalSection(&critical); EnterCriticalSection(&critical);

View File

@@ -141,16 +141,6 @@ int _System soclose(int);
# include "gsocket.h" # include "gsocket.h"
#endif /* __GSOCKET_STANDALONE__ */ #endif /* __GSOCKET_STANDALONE__ */
/* redefine some GUI-only functions to do nothing in console mode */
#if defined(wxUSE_GUI) && !wxUSE_GUI
# define _GSocket_GUI_Init(socket) (1)
# define _GSocket_GUI_Destroy(socket)
# define _GSocket_Enable_Events(socket)
# define _GSocket_Disable_Events(socket)
# define _GSocket_Install_Callback(socket, event)
# define _GSocket_Uninstall_Callback(socket, event)
#endif /* wxUSE_GUI */
/* debugging helpers */ /* debugging helpers */
#ifdef __GSOCKET_DEBUG__ #ifdef __GSOCKET_DEBUG__
# define GSocket_Debug(args) printf args # define GSocket_Debug(args) printf args
@@ -158,15 +148,60 @@ int _System soclose(int);
# define GSocket_Debug(args) # define GSocket_Debug(args)
#endif /* __GSOCKET_DEBUG__ */ #endif /* __GSOCKET_DEBUG__ */
/* Table of GUI-related functions. We must call them indirectly because
* of wxBase and GUI separation: */
static struct GSocketGUIFunctionsTable *gs_gui_functions;
#define USE_GUI() (gs_gui_functions != NULL)
/* Define macros to simplify indirection: */
#define _GSocket_GUI_Init() \
if (gs_gui_functions) gs_gui_functions->GUI_Init()
#define _GSocket_GUI_Cleanup() \
if (gs_gui_functions) gs_gui_functions->GUI_Cleanup()
#define _GSocket_GUI_Init_Socket(socket) \
(gs_gui_functions ? gs_gui_functions->GUI_Init_Socket(socket) : 1)
#define _GSocket_GUI_Destroy_Socket(socket) \
if (gs_gui_functions) gs_gui_functions->GUI_Destroy_Socket(socket)
#define _GSocket_Enable_Events(socket) \
if (gs_gui_functions) gs_gui_functions->Enable_Events(socket)
#define _GSocket_Disable_Events(socket) \
if (gs_gui_functions) gs_gui_functions->Disable_Events(socket)
#define _GSocket_Install_Callback(socket, event) \
if (gs_gui_functions) gs_gui_functions->Install_Callback(socket, event)
#define _GSocket_Uninstall_Callback(socket, event) \
if (gs_gui_functions) gs_gui_functions->Uninstall_Callback(socket, event)
static struct GSocketBaseFunctionsTable gs_base_functions =
{
_GSocket_Detected_Read,
_GSocket_Detected_Write
};
/* Global initialisers */ /* Global initialisers */
void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc)
{
gs_gui_functions = guifunc;
}
int GSocket_Init(void) int GSocket_Init(void)
{ {
if (gs_gui_functions)
{
if ( !gs_gui_functions->GUI_Init() )
return 0;
}
return 1; return 1;
} }
void GSocket_Cleanup(void) void GSocket_Cleanup(void)
{ {
if (gs_gui_functions)
{
gs_gui_functions->GUI_Cleanup();
}
} }
/* Constructors / Destructors for GSocket */ /* Constructors / Destructors for GSocket */
@@ -198,8 +233,10 @@ GSocket *GSocket_new(void)
/* 10 minutes * 60 sec * 1000 millisec */ /* 10 minutes * 60 sec * 1000 millisec */
socket->m_establishing = FALSE; socket->m_establishing = FALSE;
socket->m_functions = &gs_base_functions;
/* Per-socket GUI-specific initialization */ /* Per-socket GUI-specific initialization */
success = _GSocket_GUI_Init(socket); success = _GSocket_GUI_Init_Socket(socket);
if (!success) if (!success)
{ {
free(socket); free(socket);
@@ -225,7 +262,7 @@ void GSocket_destroy(GSocket *socket)
GSocket_Shutdown(socket); GSocket_Shutdown(socket);
/* Per-socket GUI-specific cleanup */ /* Per-socket GUI-specific cleanup */
_GSocket_GUI_Destroy(socket); _GSocket_GUI_Destroy_Socket(socket);
/* Destroy private addresses */ /* Destroy private addresses */
if (socket->m_local) if (socket->m_local)
@@ -828,123 +865,126 @@ int GSocket_Write(GSocket *socket, const char *buffer, int size)
*/ */
GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
{ {
#if defined(wxUSE_GUI) && !wxUSE_GUI if (!USE_GUI())
GSocketEventFlags result = 0;
fd_set readfds;
fd_set writefds;
fd_set exceptfds;
struct timeval tv;
/* Do not use a static struct, Linux can garble it */
tv.tv_sec = 0;
tv.tv_usec = 0;
assert(socket != NULL);
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(socket->m_fd, &readfds);
FD_SET(socket->m_fd, &writefds);
FD_SET(socket->m_fd, &exceptfds);
/* Check 'sticky' CONNECTION flag first */
result |= (GSOCK_CONNECTION_FLAG & socket->m_detected);
/* If we have already detected a LOST event, then don't try
* to do any further processing.
*/
if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
{ {
socket->m_establishing = FALSE;
return (GSOCK_LOST_FLAG & flags); GSocketEventFlags result = 0;
} fd_set readfds;
fd_set writefds;
fd_set exceptfds;
struct timeval tv;
/* Try select now */ /* Do not use a static struct, Linux can garble it */
if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) tv.tv_sec = 0;
{ tv.tv_usec = 0;
/* What to do here? */
return (result & flags);
}
/* Check for readability */ assert(socket != NULL);
if (FD_ISSET(socket->m_fd, &readfds))
{
char c;
if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(socket->m_fd, &readfds);
FD_SET(socket->m_fd, &writefds);
FD_SET(socket->m_fd, &exceptfds);
/* Check 'sticky' CONNECTION flag first */
result |= (GSOCK_CONNECTION_FLAG & socket->m_detected);
/* If we have already detected a LOST event, then don't try
* to do any further processing.
*/
if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
{ {
result |= GSOCK_INPUT_FLAG;
}
else
{
if (socket->m_server && socket->m_stream)
{
result |= GSOCK_CONNECTION_FLAG;
socket->m_detected |= GSOCK_CONNECTION_FLAG;
}
else
{
socket->m_detected = GSOCK_LOST_FLAG;
socket->m_establishing = FALSE;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
}
}
/* Check for writability */
if (FD_ISSET(socket->m_fd, &writefds))
{
if (socket->m_establishing && !socket->m_server)
{
int error;
SOCKLEN_T len = sizeof(error);
socket->m_establishing = FALSE; socket->m_establishing = FALSE;
getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len); return (GSOCK_LOST_FLAG & flags);
}
if (error) /* Try select now */
if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
{
/* What to do here? */
return (result & flags);
}
/* Check for readability */
if (FD_ISSET(socket->m_fd, &readfds))
{
char c;
if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
{ {
socket->m_detected = GSOCK_LOST_FLAG; result |= GSOCK_INPUT_FLAG;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
} }
else else
{ {
result |= GSOCK_CONNECTION_FLAG; if (socket->m_server && socket->m_stream)
socket->m_detected |= GSOCK_CONNECTION_FLAG; {
result |= GSOCK_CONNECTION_FLAG;
socket->m_detected |= GSOCK_CONNECTION_FLAG;
}
else
{
socket->m_detected = GSOCK_LOST_FLAG;
socket->m_establishing = FALSE;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
} }
} }
else
/* Check for writability */
if (FD_ISSET(socket->m_fd, &writefds))
{ {
result |= GSOCK_OUTPUT_FLAG; if (socket->m_establishing && !socket->m_server)
{
int error;
SOCKLEN_T len = sizeof(error);
socket->m_establishing = FALSE;
getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
if (error)
{
socket->m_detected = GSOCK_LOST_FLAG;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
else
{
result |= GSOCK_CONNECTION_FLAG;
socket->m_detected |= GSOCK_CONNECTION_FLAG;
}
}
else
{
result |= GSOCK_OUTPUT_FLAG;
}
} }
}
/* Check for exceptions and errors (is this useful in Unices?) */ /* Check for exceptions and errors (is this useful in Unices?) */
if (FD_ISSET(socket->m_fd, &exceptfds)) if (FD_ISSET(socket->m_fd, &exceptfds))
{
socket->m_establishing = FALSE;
socket->m_detected = GSOCK_LOST_FLAG;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
return (result & flags);
}
else
{ {
socket->m_establishing = FALSE;
socket->m_detected = GSOCK_LOST_FLAG;
/* LOST event: Abort any further processing */ assert(socket != NULL);
return (GSOCK_LOST_FLAG & flags); return flags & socket->m_detected;
} }
return (result & flags);
#else
assert(socket != NULL);
return flags & socket->m_detected;
#endif /* !wxUSE_GUI */
} }
/* Flags */ /* Flags */

View File

@@ -34,7 +34,16 @@ static void _GSocket_PM_Output(void *data)
_GSocket_Detected_Write(socket); _GSocket_Detected_Write(socket);
} }
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init(void)
{
return 1;
}
void _GSocket_GUI_Cleanup(void)
{
}
int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
int *m_id; int *m_id;
socket->m_gui_dependent = (char *)malloc(sizeof(int)*2); socket->m_gui_dependent = (char *)malloc(sizeof(int)*2);
@@ -45,7 +54,7 @@ int _GSocket_GUI_Init(GSocket *socket)
return TRUE; return TRUE;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
free(socket->m_gui_dependent); free(socket->m_gui_dependent);
} }

View File

@@ -110,17 +110,6 @@ struct sockaddr_un
# include "gsocket.h" # include "gsocket.h"
#endif /* __GSOCKET_STANDALONE__ */ #endif /* __GSOCKET_STANDALONE__ */
/* redefine some GUI-only functions to do nothing in console mode */
#if 1 //defined(wxUSE_GUI) && !wxUSE_GUI
// FIXME -- temporary measure
# define _GSocket_GUI_Init(socket) (1)
# define _GSocket_GUI_Destroy(socket)
# define _GSocket_Enable_Events(socket)
# define _GSocket_Disable_Events(socket)
# define _GSocket_Install_Callback(socket, event)
# define _GSocket_Uninstall_Callback(socket, event)
#endif /* wxUSE_GUI */
/* debugging helpers */ /* debugging helpers */
#ifdef __GSOCKET_DEBUG__ #ifdef __GSOCKET_DEBUG__
# define GSocket_Debug(args) printf args # define GSocket_Debug(args) printf args
@@ -128,15 +117,60 @@ struct sockaddr_un
# define GSocket_Debug(args) # define GSocket_Debug(args)
#endif /* __GSOCKET_DEBUG__ */ #endif /* __GSOCKET_DEBUG__ */
/* Table of GUI-related functions. We must call them indirectly because
* of wxBase and GUI separation: */
static struct GSocketGUIFunctionsTable *gs_gui_functions;
#define USE_GUI() (gs_gui_functions != NULL)
/* Define macros to simplify indirection: */
#define _GSocket_GUI_Init() \
if (gs_gui_functions) gs_gui_functions->GUI_Init()
#define _GSocket_GUI_Cleanup() \
if (gs_gui_functions) gs_gui_functions->GUI_Cleanup()
#define _GSocket_GUI_Init_Socket(socket) \
(gs_gui_functions ? gs_gui_functions->GUI_Init_Socket(socket) : 1)
#define _GSocket_GUI_Destroy_Socket(socket) \
if (gs_gui_functions) gs_gui_functions->GUI_Destroy_Socket(socket)
#define _GSocket_Enable_Events(socket) \
if (gs_gui_functions) gs_gui_functions->Enable_Events(socket)
#define _GSocket_Disable_Events(socket) \
if (gs_gui_functions) gs_gui_functions->Disable_Events(socket)
#define _GSocket_Install_Callback(socket, event) \
if (gs_gui_functions) gs_gui_functions->Install_Callback(socket, event)
#define _GSocket_Uninstall_Callback(socket, event) \
if (gs_gui_functions) gs_gui_functions->Uninstall_Callback(socket, event)
static struct GSocketBaseFunctionsTable gs_base_functions =
{
_GSocket_Detected_Read,
_GSocket_Detected_Write
};
/* Global initialisers */ /* Global initialisers */
void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc)
{
gs_gui_functions = guifunc;
}
int GSocket_Init(void) int GSocket_Init(void)
{ {
if (gs_gui_functions)
{
if ( !gs_gui_functions->GUI_Init() )
return 0;
}
return 1; return 1;
} }
void GSocket_Cleanup(void) void GSocket_Cleanup(void)
{ {
if (gs_gui_functions)
{
gs_gui_functions->GUI_Cleanup();
}
} }
/* Constructors / Destructors for GSocket */ /* Constructors / Destructors for GSocket */
@@ -168,8 +202,10 @@ GSocket *GSocket_new(void)
/* 10 minutes * 60 sec * 1000 millisec */ /* 10 minutes * 60 sec * 1000 millisec */
socket->m_establishing = FALSE; socket->m_establishing = FALSE;
socket->m_functions = &gs_base_functions;
/* Per-socket GUI-specific initialization */ /* Per-socket GUI-specific initialization */
success = _GSocket_GUI_Init(socket); success = _GSocket_GUI_Init_Socket(socket);
if (!success) if (!success)
{ {
free(socket); free(socket);
@@ -195,7 +231,7 @@ void GSocket_destroy(GSocket *socket)
GSocket_Shutdown(socket); GSocket_Shutdown(socket);
/* Per-socket GUI-specific cleanup */ /* Per-socket GUI-specific cleanup */
_GSocket_GUI_Destroy(socket); _GSocket_GUI_Destroy_Socket(socket);
/* Destroy private addresses */ /* Destroy private addresses */
if (socket->m_local) if (socket->m_local)
@@ -797,123 +833,126 @@ int GSocket_Write(GSocket *socket, const char *buffer, int size)
*/ */
GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
{ {
#if defined(wxUSE_GUI) && !wxUSE_GUI if (!USE_GUI())
GSocketEventFlags result = 0;
fd_set readfds;
fd_set writefds;
fd_set exceptfds;
struct timeval tv;
/* Do not use a static struct, Linux can garble it */
tv.tv_sec = 0;
tv.tv_usec = 0;
assert(socket != NULL);
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(socket->m_fd, &readfds);
FD_SET(socket->m_fd, &writefds);
FD_SET(socket->m_fd, &exceptfds);
/* Check 'sticky' CONNECTION flag first */
result |= (GSOCK_CONNECTION_FLAG & socket->m_detected);
/* If we have already detected a LOST event, then don't try
* to do any further processing.
*/
if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
{ {
socket->m_establishing = FALSE;
return (GSOCK_LOST_FLAG & flags); GSocketEventFlags result = 0;
} fd_set readfds;
fd_set writefds;
fd_set exceptfds;
struct timeval tv;
/* Try select now */ /* Do not use a static struct, Linux can garble it */
if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) tv.tv_sec = 0;
{ tv.tv_usec = 0;
/* What to do here? */
return (result & flags);
}
/* Check for readability */ assert(socket != NULL);
if (FD_ISSET(socket->m_fd, &readfds))
{
char c;
if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(socket->m_fd, &readfds);
FD_SET(socket->m_fd, &writefds);
FD_SET(socket->m_fd, &exceptfds);
/* Check 'sticky' CONNECTION flag first */
result |= (GSOCK_CONNECTION_FLAG & socket->m_detected);
/* If we have already detected a LOST event, then don't try
* to do any further processing.
*/
if ((socket->m_detected & GSOCK_LOST_FLAG) != 0)
{ {
result |= GSOCK_INPUT_FLAG;
}
else
{
if (socket->m_server && socket->m_stream)
{
result |= GSOCK_CONNECTION_FLAG;
socket->m_detected |= GSOCK_CONNECTION_FLAG;
}
else
{
socket->m_detected = GSOCK_LOST_FLAG;
socket->m_establishing = FALSE;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
}
}
/* Check for writability */
if (FD_ISSET(socket->m_fd, &writefds))
{
if (socket->m_establishing && !socket->m_server)
{
int error;
SOCKLEN_T len = sizeof(error);
socket->m_establishing = FALSE; socket->m_establishing = FALSE;
getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len); return (GSOCK_LOST_FLAG & flags);
}
if (error) /* Try select now */
if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
{
/* What to do here? */
return (result & flags);
}
/* Check for readability */
if (FD_ISSET(socket->m_fd, &readfds))
{
char c;
if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
{ {
socket->m_detected = GSOCK_LOST_FLAG; result |= GSOCK_INPUT_FLAG;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
} }
else else
{ {
result |= GSOCK_CONNECTION_FLAG; if (socket->m_server && socket->m_stream)
socket->m_detected |= GSOCK_CONNECTION_FLAG; {
result |= GSOCK_CONNECTION_FLAG;
socket->m_detected |= GSOCK_CONNECTION_FLAG;
}
else
{
socket->m_detected = GSOCK_LOST_FLAG;
socket->m_establishing = FALSE;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
} }
} }
else
/* Check for writability */
if (FD_ISSET(socket->m_fd, &writefds))
{ {
result |= GSOCK_OUTPUT_FLAG; if (socket->m_establishing && !socket->m_server)
{
int error;
SOCKLEN_T len = sizeof(error);
socket->m_establishing = FALSE;
getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
if (error)
{
socket->m_detected = GSOCK_LOST_FLAG;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
else
{
result |= GSOCK_CONNECTION_FLAG;
socket->m_detected |= GSOCK_CONNECTION_FLAG;
}
}
else
{
result |= GSOCK_OUTPUT_FLAG;
}
} }
}
/* Check for exceptions and errors (is this useful in Unices?) */ /* Check for exceptions and errors (is this useful in Unices?) */
if (FD_ISSET(socket->m_fd, &exceptfds)) if (FD_ISSET(socket->m_fd, &exceptfds))
{
socket->m_establishing = FALSE;
socket->m_detected = GSOCK_LOST_FLAG;
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
return (result & flags);
}
else
{ {
socket->m_establishing = FALSE;
socket->m_detected = GSOCK_LOST_FLAG;
/* LOST event: Abort any further processing */ assert(socket != NULL);
return (GSOCK_LOST_FLAG & flags); return flags & socket->m_detected;
} }
return (result & flags);
#else
assert(socket != NULL);
return flags & socket->m_detected;
#endif /* !wxUSE_GUI */
} }
/* Flags */ /* Flags */

View File

@@ -32,17 +32,26 @@ static void _GSocket_X11_Input(int *fid, void* data)
{ {
GSocket *socket = (GSocket *)data; GSocket *socket = (GSocket *)data;
_GSocket_Detected_Read(socket); socket->m_functions->Detected_Read(socket);
} }
static void _GSocket_X11_Output(int *fid, void* data) static void _GSocket_X11_Output(int *fid, void* data)
{ {
GSocket *socket = (GSocket *)data; GSocket *socket = (GSocket *)data;
_GSocket_Detected_Write(socket); socket->m_functions->Detected_Write(socket);
} }
int _GSocket_GUI_Init(GSocket *socket) int _GSocket_GUI_Init(void)
{
return 1;
}
void _GSocket_GUI_Cleanup(void)
{
}
int _GSocket_GUI_Init_Socket(GSocket *socket)
{ {
int *m_id; int *m_id;
@@ -55,7 +64,7 @@ int _GSocket_GUI_Init(GSocket *socket)
return TRUE; return TRUE;
} }
void _GSocket_GUI_Destroy(GSocket *socket) void _GSocket_GUI_Destroy_Socket(GSocket *socket)
{ {
free(socket->m_gui_dependent); free(socket->m_gui_dependent);
} }