From: Václav Slavík Date: Thu, 7 Aug 2003 12:26:17 +0000 (+0000) Subject: fixed wxBase and GUI separation for sockets code X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/38bb138f09688c1575766aafdbf296dfeeee0d7d 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 --- diff --git a/include/wx/apptrait.h b/include/wx/apptrait.h index 164f042bd7..f6750d2bc4 100644 --- a/include/wx/apptrait.h +++ b/include/wx/apptrait.h @@ -24,6 +24,8 @@ class WXDLLIMPEXP_BASE wxMessageOutput; class WXDLLEXPORT wxRendererNative; class WXDLLIMPEXP_BASE wxString; +extern "C" struct GSocketGUIFunctionsTable; + // ---------------------------------------------------------------------------- // toolkit information // ---------------------------------------------------------------------------- @@ -105,6 +107,11 @@ public: // wxBase 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 // that are both contained in wxBase: @@ -154,6 +161,9 @@ 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); @@ -181,6 +191,9 @@ 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); diff --git a/include/wx/gsocket.h b/include/wx/gsocket.h index a03616a9fc..2b626a698e 100644 --- a/include/wx/gsocket.h +++ b/include/wx/gsocket.h @@ -95,8 +95,37 @@ typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event, 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 */ +/* 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 */ int GSocket_Init(void); diff --git a/include/wx/msw/gsockmsw.h b/include/wx/msw/gsockmsw.h index c558049e1f..a000ababea 100644 --- a/include/wx/msw/gsockmsw.h +++ b/include/wx/msw/gsockmsw.h @@ -83,8 +83,10 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size); /* Callbacks */ -int _GSocket_GUI_Init(GSocket *socket); -void _GSocket_GUI_Destroy(GSocket *socket); +int _GSocket_GUI_Init(void); +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); diff --git a/include/wx/unix/gsockunx.h b/include/wx/unix/gsockunx.h index dc0e170716..8f3028568c 100644 --- a/include/wx/unix/gsockunx.h +++ b/include/wx/unix/gsockunx.h @@ -56,6 +56,9 @@ struct _GSocket char *m_data[GSOCK_MAX_EVENT]; char *m_gui_dependent; + + /* Function pointers */ + struct GSocketBaseFunctionsTable *m_functions; }; /* Definition of GAddress */ @@ -81,8 +84,11 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size); /* Callbacks */ -int _GSocket_GUI_Init(GSocket *socket); -void _GSocket_GUI_Destroy(GSocket *socket); +int _GSocket_GUI_Init(void); +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_Disable_Events(GSocket *socket); diff --git a/src/cocoa/gsockcocoa.c b/src/cocoa/gsockcocoa.c index 2a8b2f90b7..1df818b89c 100644 --- a/src/cocoa/gsockcocoa.c +++ b/src/cocoa/gsockcocoa.c @@ -12,12 +12,21 @@ #include #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; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { } diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 2091e12a70..9b7e921da8 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -456,6 +456,13 @@ void wxConsoleAppTraitsBase::RemoveFromPendingDelete(wxObject * WXUNUSED(object) { // nothing to do } + +#if wxUSE_SOCKETS +GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable() +{ + return NULL; +} +#endif // ---------------------------------------------------------------------------- // wxAppTraits diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index f64e6b6bb6..906f2c48d5 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -497,3 +497,35 @@ void wxGUIAppTraitsBase::RemoveFromPendingDelete(wxObject *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 + diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 60bbc1f48d..5816414509 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -126,6 +126,12 @@ bool wxSocketBase::Initialize() { if ( !m_countInit++ ) { + wxAppTraits *traits = wxAppConsole::GetInstance() ? + wxAppConsole::GetInstance()->GetTraits() : NULL; + GSocketGUIFunctionsTable *functions = + traits ? traits->GetSocketGUIFunctionsTable() : NULL; + GSocket_SetGUIFunctions(functions); + if ( !GSocket_Init() ) { m_countInit--; diff --git a/src/gtk/gsockgtk.c b/src/gtk/gsockgtk.c index 6a1a3f5ee7..0115e520db 100644 --- a/src/gtk/gsockgtk.c +++ b/src/gtk/gsockgtk.c @@ -28,12 +28,21 @@ void _GSocket_GDK_Input(gpointer data, GSocket *socket = (GSocket *)data; if (condition & GDK_INPUT_READ) - _GSocket_Detected_Read(socket); + socket->m_functions->Detected_Read(socket); 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; @@ -46,7 +55,7 @@ int _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { free(socket->m_gui_dependent); } diff --git a/src/gtk1/gsockgtk.c b/src/gtk1/gsockgtk.c index 6a1a3f5ee7..0115e520db 100644 --- a/src/gtk1/gsockgtk.c +++ b/src/gtk1/gsockgtk.c @@ -28,12 +28,21 @@ void _GSocket_GDK_Input(gpointer data, GSocket *socket = (GSocket *)data; if (condition & GDK_INPUT_READ) - _GSocket_Detected_Read(socket); + socket->m_functions->Detected_Read(socket); 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; @@ -46,7 +55,7 @@ int _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { free(socket->m_gui_dependent); } diff --git a/src/mac/carbon/gsocket.c b/src/mac/carbon/gsocket.c index 45275d9176..c01b1c4ec1 100644 --- a/src/mac/carbon/gsocket.c +++ b/src/mac/carbon/gsocket.c @@ -196,6 +196,11 @@ static void SetDefaultEndpointModes(EndpointRef ep , void *data ) /* Global initialisers */ +void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *) +{ + // do nothing, wxMac doesn't have wxBase-GUI separation yet +} + int GSocket_Init() { return TRUE; diff --git a/src/mac/gsocket.c b/src/mac/gsocket.c index 45275d9176..c01b1c4ec1 100644 --- a/src/mac/gsocket.c +++ b/src/mac/gsocket.c @@ -196,6 +196,11 @@ static void SetDefaultEndpointModes(EndpointRef ep , void *data ) /* Global initialisers */ +void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *) +{ + // do nothing, wxMac doesn't have wxBase-GUI separation yet +} + int GSocket_Init() { return TRUE; diff --git a/src/motif/gsockmot.c b/src/motif/gsockmot.c index f442a508dc..e4904f6610 100644 --- a/src/motif/gsockmot.c +++ b/src/motif/gsockmot.c @@ -22,7 +22,7 @@ static void _GSocket_Motif_Input(XtPointer data, int *fid, { GSocket *socket = (GSocket *)data; - _GSocket_Detected_Read(socket); + socket->m_functions->Detected_Read(socket); } 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_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; @@ -46,7 +55,7 @@ int _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { free(socket->m_gui_dependent); } diff --git a/src/msw/gsocket.c b/src/msw/gsocket.c index 0a5ad3a4ac..de5bf961c3 100644 --- a/src/msw/gsocket.c +++ b/src/msw/gsocket.c @@ -73,6 +73,62 @@ # define SOCKLEN_T int #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 */ @@ -101,7 +157,7 @@ GSocket *GSocket_new(void) socket->m_establishing = FALSE; /* Per-socket GUI-specific initialization */ - success = _GSocket_GUI_Init(socket); + success = _GSocket_GUI_Init_Socket(socket); if (!success) { free(socket); @@ -123,7 +179,7 @@ void GSocket_destroy(GSocket *socket) assert(socket != NULL); /* Per-socket GUI-specific cleanup */ - _GSocket_GUI_Destroy(socket); + _GSocket_GUI_Destroy_Socket(socket); /* Check that the socket is really shutdowned */ if (socket->m_fd != INVALID_SOCKET) diff --git a/src/msw/gsockmsw.c b/src/msw/gsockmsw.c index 5016995a45..38dd6bd523 100644 --- a/src/msw/gsockmsw.c +++ b/src/msw/gsockmsw.c @@ -106,9 +106,8 @@ static int firstAvailable; /* Global initializers */ -int GSocket_Init(void) +int _GSocket_GUI_Init(void) { - WSADATA wsaData; WNDCLASS winClass; int i; @@ -141,11 +140,10 @@ int GSocket_Init(void) } firstAvailable = 0; - /* Initialize WinSocket */ - return (WSAStartup((1 << 8) | 1, &wsaData) == 0); + return 1; } -void GSocket_Cleanup(void) +void _GSocket_GUI_Cleanup(void) { /* Destroy internal window */ DestroyWindow(hWin); @@ -153,14 +151,11 @@ void GSocket_Cleanup(void) /* Delete critical section */ DeleteCriticalSection(&critical); - - /* Cleanup WinSocket */ - WSACleanup(); } /* Per-socket GUI initialization / cleanup */ -int _GSocket_GUI_Init(GSocket *socket) +int _GSocket_GUI_Init_Socket(GSocket *socket) { int i; @@ -187,7 +182,7 @@ int _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { /* Remove the socket from the list */ EnterCriticalSection(&critical); diff --git a/src/os2/gsocket.c b/src/os2/gsocket.c index 4547bd4151..268b7860c4 100644 --- a/src/os2/gsocket.c +++ b/src/os2/gsocket.c @@ -141,16 +141,6 @@ int _System soclose(int); # include "gsocket.h" #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 */ #ifdef __GSOCKET_DEBUG__ # define GSocket_Debug(args) printf args @@ -158,15 +148,60 @@ int _System soclose(int); # define GSocket_Debug(args) #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 */ +void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc) +{ + gs_gui_functions = guifunc; +} + int GSocket_Init(void) { + if (gs_gui_functions) + { + if ( !gs_gui_functions->GUI_Init() ) + return 0; + } return 1; } void GSocket_Cleanup(void) { + if (gs_gui_functions) + { + gs_gui_functions->GUI_Cleanup(); + } } /* Constructors / Destructors for GSocket */ @@ -198,8 +233,10 @@ GSocket *GSocket_new(void) /* 10 minutes * 60 sec * 1000 millisec */ socket->m_establishing = FALSE; + socket->m_functions = &gs_base_functions; + /* Per-socket GUI-specific initialization */ - success = _GSocket_GUI_Init(socket); + success = _GSocket_GUI_Init_Socket(socket); if (!success) { free(socket); @@ -225,7 +262,7 @@ void GSocket_destroy(GSocket *socket) GSocket_Shutdown(socket); /* Per-socket GUI-specific cleanup */ - _GSocket_GUI_Destroy(socket); + _GSocket_GUI_Destroy_Socket(socket); /* Destroy private addresses */ 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) { -#if defined(wxUSE_GUI) && !wxUSE_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; + if (!USE_GUI()) + { - assert(socket != NULL); + GSocketEventFlags result = 0; + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + struct timeval tv; - 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); + /* Do not use a static struct, Linux can garble it */ + tv.tv_sec = 0; + tv.tv_usec = 0; - /* Check 'sticky' CONNECTION flag first */ - result |= (GSOCK_CONNECTION_FLAG & socket->m_detected); + assert(socket != NULL); - /* 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; + 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); - return (GSOCK_LOST_FLAG & flags); - } + /* Check 'sticky' CONNECTION flag first */ + result |= (GSOCK_CONNECTION_FLAG & socket->m_detected); - /* Try select now */ - if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) - { - /* What to do here? */ - return (result & flags); - } + /* 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; - /* Check for readability */ - if (FD_ISSET(socket->m_fd, &readfds)) - { - char c; + return (GSOCK_LOST_FLAG & flags); + } - if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) + /* Try select now */ + if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) { - result |= GSOCK_INPUT_FLAG; + /* What to do here? */ + return (result & flags); } - else + + /* Check for readability */ + if (FD_ISSET(socket->m_fd, &readfds)) { - if (socket->m_server && socket->m_stream) + char c; + + if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) { - result |= GSOCK_CONNECTION_FLAG; - socket->m_detected |= GSOCK_CONNECTION_FLAG; + result |= GSOCK_INPUT_FLAG; } else { - socket->m_detected = GSOCK_LOST_FLAG; - socket->m_establishing = FALSE; - - /* LOST event: Abort any further processing */ - return (GSOCK_LOST_FLAG & flags); + 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) + /* Check for writability */ + if (FD_ISSET(socket->m_fd, &writefds)) { - int error; - SOCKLEN_T len = sizeof(error); + 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); + getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len); - if (error) - { - socket->m_detected = GSOCK_LOST_FLAG; + if (error) + { + socket->m_detected = GSOCK_LOST_FLAG; - /* LOST event: Abort any further processing */ - return (GSOCK_LOST_FLAG & flags); + /* 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_CONNECTION_FLAG; - socket->m_detected |= GSOCK_CONNECTION_FLAG; + result |= GSOCK_OUTPUT_FLAG; } } - else + + /* Check for exceptions and errors (is this useful in Unices?) */ + if (FD_ISSET(socket->m_fd, &exceptfds)) { - result |= GSOCK_OUTPUT_FLAG; + socket->m_establishing = FALSE; + socket->m_detected = GSOCK_LOST_FLAG; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); } - } - /* Check for exceptions and errors (is this useful in Unices?) */ - if (FD_ISSET(socket->m_fd, &exceptfds)) - { - socket->m_establishing = FALSE; - socket->m_detected = GSOCK_LOST_FLAG; + return (result & flags); - /* LOST event: Abort any further processing */ - return (GSOCK_LOST_FLAG & flags); } + else + { - return (result & flags); - -#else - - assert(socket != NULL); - return flags & socket->m_detected; + assert(socket != NULL); + return flags & socket->m_detected; -#endif /* !wxUSE_GUI */ + } } /* Flags */ diff --git a/src/os2/gsockpm.c b/src/os2/gsockpm.c index 404582c508..9cf4ce0229 100644 --- a/src/os2/gsockpm.c +++ b/src/os2/gsockpm.c @@ -34,7 +34,16 @@ static void _GSocket_PM_Output(void *data) _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; socket->m_gui_dependent = (char *)malloc(sizeof(int)*2); @@ -45,7 +54,7 @@ int _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { free(socket->m_gui_dependent); } diff --git a/src/unix/gsocket.c b/src/unix/gsocket.c index 09924de226..36a2ca622f 100644 --- a/src/unix/gsocket.c +++ b/src/unix/gsocket.c @@ -110,17 +110,6 @@ struct sockaddr_un # include "gsocket.h" #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 */ #ifdef __GSOCKET_DEBUG__ # define GSocket_Debug(args) printf args @@ -128,15 +117,60 @@ struct sockaddr_un # define GSocket_Debug(args) #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 */ +void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc) +{ + gs_gui_functions = guifunc; +} + int GSocket_Init(void) { + if (gs_gui_functions) + { + if ( !gs_gui_functions->GUI_Init() ) + return 0; + } return 1; } void GSocket_Cleanup(void) { + if (gs_gui_functions) + { + gs_gui_functions->GUI_Cleanup(); + } } /* Constructors / Destructors for GSocket */ @@ -168,8 +202,10 @@ GSocket *GSocket_new(void) /* 10 minutes * 60 sec * 1000 millisec */ socket->m_establishing = FALSE; + socket->m_functions = &gs_base_functions; + /* Per-socket GUI-specific initialization */ - success = _GSocket_GUI_Init(socket); + success = _GSocket_GUI_Init_Socket(socket); if (!success) { free(socket); @@ -195,7 +231,7 @@ void GSocket_destroy(GSocket *socket) GSocket_Shutdown(socket); /* Per-socket GUI-specific cleanup */ - _GSocket_GUI_Destroy(socket); + _GSocket_GUI_Destroy_Socket(socket); /* Destroy private addresses */ 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) { -#if defined(wxUSE_GUI) && !wxUSE_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; + if (!USE_GUI()) + { - assert(socket != NULL); + GSocketEventFlags result = 0; + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + struct timeval tv; - 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); + /* Do not use a static struct, Linux can garble it */ + tv.tv_sec = 0; + tv.tv_usec = 0; - /* Check 'sticky' CONNECTION flag first */ - result |= (GSOCK_CONNECTION_FLAG & socket->m_detected); + assert(socket != NULL); - /* 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; + 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); - return (GSOCK_LOST_FLAG & flags); - } + /* Check 'sticky' CONNECTION flag first */ + result |= (GSOCK_CONNECTION_FLAG & socket->m_detected); - /* Try select now */ - if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) - { - /* What to do here? */ - return (result & flags); - } + /* 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; - /* Check for readability */ - if (FD_ISSET(socket->m_fd, &readfds)) - { - char c; + return (GSOCK_LOST_FLAG & flags); + } - if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) + /* Try select now */ + if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) { - result |= GSOCK_INPUT_FLAG; + /* What to do here? */ + return (result & flags); } - else + + /* Check for readability */ + if (FD_ISSET(socket->m_fd, &readfds)) { - if (socket->m_server && socket->m_stream) + char c; + + if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) { - result |= GSOCK_CONNECTION_FLAG; - socket->m_detected |= GSOCK_CONNECTION_FLAG; + result |= GSOCK_INPUT_FLAG; } else { - socket->m_detected = GSOCK_LOST_FLAG; - socket->m_establishing = FALSE; - - /* LOST event: Abort any further processing */ - return (GSOCK_LOST_FLAG & flags); + 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) + /* Check for writability */ + if (FD_ISSET(socket->m_fd, &writefds)) { - int error; - SOCKLEN_T len = sizeof(error); + 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); + getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len); - if (error) - { - socket->m_detected = GSOCK_LOST_FLAG; + if (error) + { + socket->m_detected = GSOCK_LOST_FLAG; - /* LOST event: Abort any further processing */ - return (GSOCK_LOST_FLAG & flags); + /* 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_CONNECTION_FLAG; - socket->m_detected |= GSOCK_CONNECTION_FLAG; + result |= GSOCK_OUTPUT_FLAG; } } - else + + /* Check for exceptions and errors (is this useful in Unices?) */ + if (FD_ISSET(socket->m_fd, &exceptfds)) { - result |= GSOCK_OUTPUT_FLAG; + socket->m_establishing = FALSE; + socket->m_detected = GSOCK_LOST_FLAG; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); } - } - /* Check for exceptions and errors (is this useful in Unices?) */ - if (FD_ISSET(socket->m_fd, &exceptfds)) - { - socket->m_establishing = FALSE; - socket->m_detected = GSOCK_LOST_FLAG; + return (result & flags); - /* LOST event: Abort any further processing */ - return (GSOCK_LOST_FLAG & flags); } + else + { - return (result & flags); - -#else - - assert(socket != NULL); - return flags & socket->m_detected; + assert(socket != NULL); + return flags & socket->m_detected; -#endif /* !wxUSE_GUI */ + } } /* Flags */ diff --git a/src/x11/gsockx11.c b/src/x11/gsockx11.c index d49b6d1c07..ae23842347 100644 --- a/src/x11/gsockx11.c +++ b/src/x11/gsockx11.c @@ -32,17 +32,26 @@ static void _GSocket_X11_Input(int *fid, void* data) { GSocket *socket = (GSocket *)data; - _GSocket_Detected_Read(socket); + socket->m_functions->Detected_Read(socket); } static void _GSocket_X11_Output(int *fid, void* 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; @@ -55,7 +64,7 @@ int _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { free(socket->m_gui_dependent); }