////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "socket.h"
-// #pragma interface
-// #pragma implementation "socket.cpp"
+#endif
+
+#ifdef __MWERKS__
+typedef int socklen_t ;
#endif
// For compilers that support precompilation, includes "wx.h".
#pragma hdrstop
#endif
+#if wxUSE_SOCKETS
+
/////////////////////////////////////////////////////////////////////////////
// wxWindows headers
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// System specific headers
/////////////////////////////////////////////////////////////////////////////
+#ifdef __WXMAC__
+// in order to avoid problems with our c library and double definitions
+#define close closesocket
+#define ioctl ioctlsocket
+
+#include <wx/mac/macsock.h>
+extern GUSISpinFn GUSISpin;
+#define PROCESS_EVENTS() wxMacProcessEvents()
+const short kwxMacNetEventsMax = 1000 ;
+short wxMacNetEventsTop = 0 ;
+short wxMacNetEventsBottom = 0 ;
+short wxMacNetEventsEvents[kwxMacNetEventsMax] ;
+void *wxMacNetEventsReferences[kwxMacNetEventsMax] ;
+
+#define FD_READ 1
+#define FD_WRITE 2
+#define FD_CLOSE 4
+#define FD_ACCEPT 8
+#define FD_CONNECT 16
+#define FD_READY 32
+
+extern "C" void wxMacSocketHandlerProc( void *refcon , short event ) ; // adds events
+extern "C" void wxMacSocketOnRequestProc( void *refcon , short event ) ; // consumes them
+extern "C" void GUSISetReference( short sock , short eventmask , void * data ) ;
+void wxMacProcessEvents() ;
+#endif
+
#if defined(__WINDOWS__)
-#include <winsock.h>
+ #include <winsock.h>
#endif // __WINDOWS__
#if defined(__UNIX__)
#ifdef VMS
-#include <socket.h>
-#else
-#include <sys/socket.h>
-#endif
+ #include <socket.h>
+#else // !VMS
+ #include <sys/socket.h>
+#endif // VMS/!VMS
+
#include <sys/ioctl.h>
#include <sys/time.h>
#include <unistd.h>
#ifdef sun
-#include <sys/filio.h>
+ #include <sys/filio.h>
#endif
#endif // __UNIX__
#include <signal.h>
#include <errno.h>
-#ifdef _MSC_VER
-#include <io.h>
+#ifdef __VISUALC__
+ #include <io.h>
#endif
#if defined(__WXMOTIF__) || defined(__WXXT__)
-#include <X11/Intrinsic.h>
+ #include <X11/Intrinsic.h>
-/////////////////////////////
-// Needs internal variables
-/////////////////////////////
-#ifdef __WXXT__
-#define Uses_XtIntrinsic
-#endif
-
-#endif
+ /////////////////////////////
+ // Needs internal variables
+ /////////////////////////////
+ #ifdef __WXXT__
+ #define Uses_XtIntrinsic
+ #endif
+#endif // Motif or Xt
#if defined(__WXGTK__)
-#include <gtk/gtk.h>
+ #include <gtk/gtk.h>
#endif
/////////////////////////////////////////////////////////////////////////////
// wxSocket headers
/////////////////////////////////////////////////////////////////////////////
#include "wx/module.h"
+
#define WXSOCK_INTERNAL
+
#include "wx/sckaddr.h"
#include "wx/socket.h"
// implementations (such as PC-NFS) will require you to include this
// or a similar routine (see appendix in WinSock doc or help file).
-#if defined( NEED_WSAFDIsSet ) || defined( _MSC_VER )
+#if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ )
int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
{
- int i = set->fd_count;
+ int i = set->fd_count;
- while (i--)
- {
- if (set->fd_array[i] == fd)
- return 1;
- }
+ while (i--)
+ {
+ if (set->fd_array[i] == fd)
+ return 1;
+ }
- return 0;
+ return 0;
}
#endif
#endif
#if defined(__WINDOWS__)
-#define PROCESS_EVENTS() wxYield()
+ #define PROCESS_EVENTS() wxYield()
#elif defined(__WXXT__) || defined(__WXMOTIF__)
-#define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll)
+ #define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll)
#elif defined(__WXGTK__)
-#define PROCESS_EVENTS() gtk_main_iteration()
+ #define PROCESS_EVENTS() gtk_main_iteration()
#endif
/////////////////////////////////////////////////////////////////////////////
// Some patch ///// END
/////////////////////////////////////////////////////////////////////////////
+#ifdef GetClassInfo
+#undef GetClassInfo
+#endif
+
// --------------------------------------------------------------
// Module
// --------------------------------------------------------------
// ClassInfos
// --------------------------------------------------------------
#if !USE_SHARED_LIBRARY
-IMPLEMENT_CLASS(wxSocketBase, wxObject)
-IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
-IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
-IMPLEMENT_CLASS(wxSocketHandler, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
-IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
+ IMPLEMENT_CLASS(wxSocketBase, wxObject)
+ IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
+ IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
+ IMPLEMENT_CLASS(wxSocketHandler, wxObject)
+ IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
+ IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
#endif
class wxSockWakeUp : public wxTimer
// --------- wxSocketBase CONSTRUCTOR ---------------------------
// --------------------------------------------------------------
wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
- wxSocketBase::wxSockType _type) :
+ wxSocketBase::wxSockType _type) :
wxEvtHandler(),
m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
m_fd(INVALID_SOCKET), m_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1),
wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
{
- m_lcount = GetPushback(buffer, nbytes, FALSE);
+ size_t count;
+
+ count = GetPushback(buffer, nbytes, FALSE);
+ nbytes -= count;
+ buffer += count;
// If we have got the whole needed buffer or if we don't want to
// wait then it returns immediately.
- if (!nbytes || (m_lcount && !(m_flags & WAITALL)) )
+ if (!nbytes || (count && !(m_flags & WAITALL)) ) {
+ m_lcount = count;
return *this;
+ }
+ m_lcount = 0;
WantBuffer(buffer, nbytes, EVT_READ);
+ m_lcount += count;
return *this;
}
wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
{
- size_t nbytes_old = nbytes;
+ size_t count;
- nbytes -= GetPushback(buffer, nbytes, TRUE);
- if (!nbytes)
+ count = GetPushback(buffer, nbytes, TRUE);
+ if (nbytes-count == 0)
{
- m_lcount = nbytes_old;
+ m_lcount = nbytes;
return *this;
}
+ buffer += count;
+ nbytes -= count;
+ m_lcount = 0;
WantBuffer(buffer, nbytes, EVT_PEEK);
+ m_lcount += count;
return *this;
}
{
SockMsg msg;
+ // warning about 'cast truncates constant value'
+#ifdef __VISUALC__
+ #pragma warning(disable: 4310)
+#endif // __VISUALC__
+
msg.sig[0] = (char) 0xad;
msg.sig[1] = (char) 0xde;
msg.sig[2] = (char) 0xed;
Write((char *)&msg, sizeof(msg));
return *this;
+
+#ifdef __VISUALC__
+ #pragma warning(default: 4310)
+#endif // __VISUALC__
}
wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
#undef MAX_BUFSIZE
}
-// If what? Who seems to need unsigned int?
-// BTW uint isn't even defined on wxMSW for VC++ for some reason. Even if it
-// were, getpeername/getsockname don't take unsigned int*, they take int*.
-#if 0
-#define wxSOCKET_INT unsigned int
-#else
-#define wxSOCKET_INT int
-#endif
+// this is normally defined by configure, but if it wasn't try to do it here
+#ifndef SOCKLEN_T
+ #if wxHAVE_GLIBC2
+ typedef socklen_t SOCKLEN_T;
+ #else
+ typedef int SOCKLEN_T;
+ #endif
+#endif // SOCKLEN_T
// --------------------------------------------------------------
// wxSocketBase socket info functions
bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
{
struct sockaddr my_addr;
- wxSOCKET_INT len_addr = sizeof(my_addr);
+ SOCKLEN_T len_addr = (SOCKLEN_T)sizeof(my_addr);
if (m_fd < 0)
return FALSE;
bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
{
struct sockaddr my_addr;
- wxSOCKET_INT len_addr = sizeof(my_addr);
+ SOCKLEN_T len_addr = (SOCKLEN_T)sizeof(my_addr);
if (m_fd < 0)
return FALSE;
if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0)
-
return FALSE;
addr_man.Disassemble(&my_addr, len_addr);
// --------- wxSocketBase callback management -------------------
// --------------------------------------------------------------
+#ifdef __WXGTK__
+void wxPrereadSocket(wxSocketBase *sock)
+{
+ char tmp_buf[1024];
+ int got = 0;
+
+ do {
+ got = recv(sock->m_fd, tmp_buf, 1024, 0);
+ if (got > 0)
+ sock->CreatePushbackAfter(tmp_buf, got);
+ } while (got > 0);
+}
+#endif
+
#if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
#if defined(__WXMOTIF__) || defined(__WXXT__)
static void wx_socket_read(XtPointer client, int *fid,
- XtInputId *WXUNUSED(id))
+ XtInputId *WXUNUSED(id))
#define fd *fid
#else
static void wx_socket_read(gpointer client, gint fd,
{
if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
{
+#ifdef __WXGTK__
+ // We can't exit from the GDK main loop because it doesn't accept
+ // destroying input event while we are in a event dispatch.
+ // So we will preread socket and we put the data in the pushback.
+ wxPrereadSocket(sock);
+ // Then we set the socket as BLOCKING
+ int flag = 0;
+ ioctl(fd, FIONBIO, &flag);
+#endif
return;
}
#if defined(__WXMOTIF__) || defined(__WXXT__)
static void wx_socket_write(XtPointer client, int *WXUNUSED(fid),
- XtInputId *WXUNUSED(id))
+ XtInputId *WXUNUSED(id))
#else
static void wx_socket_write(gpointer client, gint WXUNUSED(fd),
- GdkInputCondition WXUNUSED(cond))
+ GdkInputCondition WXUNUSED(cond))
#endif
{
wxSocketBase *sock = (wxSocketBase *)client;
if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED))
return;
-
#if defined(__WXMOTIF__) || defined(__WXXT__)
if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST))
{
m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
(XtPointer *) XtInputReadMask,
(XtInputCallbackProc) wx_socket_read,
+ (XtPointer) this);
}
}
else
if (!m_internal->my_msg)
m_internal->my_msg = m_handler->NewMessage(this);
WSAAsyncSelect(m_fd, m_handler->GetHWND(), m_internal->my_msg, mask);
+#endif
+#ifdef __WXMAC__
+ short mask = 0;
+
+ if (m_neededreq & REQ_READ)
+ mask |= FD_READ;
+ if (m_neededreq & REQ_WRITE)
+ mask |= FD_WRITE;
+ if (m_neededreq & REQ_LOST)
+ mask |= FD_CLOSE;
+ if (m_neededreq & REQ_ACCEPT)
+ mask |= FD_ACCEPT;
+ if (m_neededreq & REQ_CONNECT)
+ mask |= FD_CONNECT;
+
+ GUSISetReference( m_fd ,mask, this ) ;
+ unsigned long flag = 1;
+ ioctl(m_fd, FIONBIO, &flag);
#endif
m_cbkon = TRUE;
m_processing = FALSE;
#ifdef __WINDOWS__
WSAAsyncSelect(m_fd, m_handler->GetHWND(), 0, 0);
#endif
+#ifdef __WXMAC__
+ GUSISetReference( m_fd , 0 , 0 ) ;
+ int bottom = wxMacNetEventsBottom ;
+ while ( wxMacNetEventsTop != bottom )
+ {
+ // set all events that reference this socket to nil
+ if ( wxMacNetEventsReferences[bottom] == (void*) this )
+ wxMacNetEventsReferences[bottom] = NULL ;
+ bottom++ ;
+ if ( bottom == kwxMacNetEventsMax )
+ bottom = 0 ;
+ }
+ SetFlags( m_flags ) ;
+#endif
}
void wxSocketBase::Notify(bool notify)
{
char *curr_pos;
- m_unread = (char *) realloc(m_unread, m_unrd_size+size);
+ if (m_unread != NULL)
+ m_unread = (char *) realloc(m_unread, m_unrd_size+size);
+ else
+ m_unread = (char *) malloc(size);
curr_pos = m_unread + m_unrd_size;
memcpy(curr_pos, buffer, size);
curr_pos = new_buf + size;
memcpy(new_buf, buffer, size);
- memcpy(curr_pos, m_unread, m_unrd_size);
-
- free(m_unread);
+ if (m_unrd_size != 0) {
+ memcpy(curr_pos, m_unread, m_unrd_size);
+ free(m_unread);
+ }
m_unread = new_buf;
m_unrd_size += size;
}
if (!peek) {
m_unrd_size -= size;
- if (!m_unrd_size) {
+ if (m_unrd_size == 0) {
free(m_unread);
m_unread = NULL;
}
}
void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
- wxRequestEvent evt)
+ wxRequestEvent evt)
{
bool buf_timed_out;
// --------------------------------------------------------------
wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
- wxSockFlags flags) :
+ wxSockFlags flags) :
wxSocketBase(flags, SOCK_SERVER)
{
m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
// --------- wxSocketClient CONSTRUCTOR -------------------------
// --------------------------------------------------------------
wxSocketClient::wxSocketClient(wxSockFlags _flags) :
- wxSocketBase(_flags, SOCK_CLIENT)
+ wxSocketBase(_flags, SOCK_CLIENT)
{
}
// --------------------------------------------------------------
// --------- wxSocketHandler CONSTRUCTOR ------------------------
// --------------------------------------------------------------
+#ifdef __WXMAC__
+
+extern "C" int updatestatus(int s) ;
+
+void wxMacSocketOnRequestProc( void *refcon , short event )
+{
+ if ( refcon )
+ {
+ wxSocketBase *sock = (wxSocketBase *) refcon ;
+
+ wxSocketBase::wxRequestEvent sk_req;
+
+ int canRead ;
+ int canWrite ;
+ int exception ;
+
+ switch (event) {
+ case FD_READ:
+ sk_req = wxSocketBase::EVT_READ;
+ sock->OnRequest(sk_req);
+ break;
+ case FD_WRITE:
+ sk_req = wxSocketBase::EVT_WRITE;
+ sock->OnRequest(sk_req);
+ break;
+ case FD_CLOSE:
+ sk_req = wxSocketBase::EVT_LOST;
+ sock->OnRequest(sk_req);
+ break;
+ case FD_ACCEPT:
+ sk_req = wxSocketBase::EVT_ACCEPT;
+ sock->OnRequest(sk_req);
+ break;
+ case FD_CONNECT:
+ sk_req = wxSocketBase::EVT_CONNECT;
+ sock->OnRequest(sk_req);
+ break;
+ case FD_READY :
+ break ;
+ }
+ updatestatus ( sock->m_fd ) ;
+ }
+}
+
+void wxMacSocketHandlerProc( void *refcon , short event )
+{
+ wxMacNetEventsReferences[wxMacNetEventsTop] = refcon ;
+ wxMacNetEventsEvents[wxMacNetEventsTop] = event ;
+
+ // clumsy construct in order to never have a incorrect wxMacNetEventsTop (above limits)
+
+ if ( wxMacNetEventsTop + 1 == kwxMacNetEventsMax )
+ wxMacNetEventsTop = 0 ;
+ else
+ wxMacNetEventsTop++ ;
+}
+
+#endif
#ifdef __WINDOWS__
extern char wxPanelClassName[];
{
if(message==WM_DESTROY)
{
- ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc);
- return DefWindowProc(hWnd, message, wParam, lParam);
+ ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc);
+ return DefWindowProc(hWnd, message, wParam, lParam);
}
wxSocketHandler *h_sock = (wxSocketHandler *)GetWindowLong(hWnd, GWL_USERDATA);
wxNode *node = h_sock->smsg_list->Find(message);
case FD_CONNECT:
sk_req = wxSocketBase::EVT_CONNECT;
break;
+
+ default:
+ wxFAIL_MSG("invalid socket event");
+ return (LRESULT)0;
}
+
sock->OnRequest(sk_req);
return (LRESULT)0;
}
internal = new wxSockHandlerInternal;
internal->sockWin = ::CreateWindow(wxPanelClassName, NULL, 0,
- 0, 0, 0, 0, NULL, (HMENU) NULL,
- wxhInstance, 0);
+ 0, 0, 0, 0, NULL, (HMENU) NULL,
+ wxhInstance, 0);
// Subclass the window
if (!wxSocketSubClassProc)
// --------- wxSocketHandler "big" wait functions ---------------
// --------------------------------------------------------------
void handler_cbk(wxSocketBase& sock,
- wxSocketBase::wxRequestEvent WXUNUSED(flags),
- char *cdata)
+ wxSocketBase::wxRequestEvent WXUNUSED(flags),
+ char *cdata)
{
int *a_wait = (int *)cdata;
// --------- wxSocketHandler: create and register the socket ----
// --------------------------------------------------------------
wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
- wxSocketBase::wxSockFlags flags)
+ wxSocketBase::wxSockFlags flags)
{
wxSocketServer *serv = new wxSocketServer(addr, flags);
wxSocketHandler::master = NULL;
}
+#ifdef __WXMAC__
+void wxMacProcessSocketEvents() ;
+void wxMacProcessEvents()
+{
+ wxMacProcessSocketEvents() ;
+ (*GUSISpin)(SP_MISC, 0) ;
+}
+
+void wxMacProcessSocketEvents()
+{
+ while ( wxMacNetEventsTop != wxMacNetEventsBottom )
+ {
+ // consume event at wxMacNetEventsBottom
+ wxMacSocketOnRequestProc(wxMacNetEventsReferences[wxMacNetEventsBottom] , wxMacNetEventsEvents[wxMacNetEventsBottom] ) ;
+ wxMacNetEventsBottom++ ;
+ if ( wxMacNetEventsBottom == kwxMacNetEventsMax )
+ wxMacNetEventsBottom = 0 ;
+ }
+}
+#endif
+
#endif
// __WXSTUBS__
+
+#endif
+ // wxUSE_SOCKETS