X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f4ada568223b79c8a5769cc351c36a8e2ccd7841..6c905cb7fdc856317f1e1db9c6d6aaa93c67920c:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index f880c2d6e5..186a49a22c 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -9,10 +9,21 @@ // RCS_ID: $Id$ // License: see wxWindows license //////////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#ifdef __GNUG__ #pragma implementation "socket.h" -#pragma interface -#pragma implementation "socket.cpp" +// #pragma interface +// #pragma implementation "socket.cpp" +#endif + +#ifdef __MWERKS__ +typedef int socklen_t ; +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop #endif ///////////////////////////////////////////////////////////////////////////// @@ -24,6 +35,9 @@ #include #include +// Not enough OS behaviour defined for wxStubs +#ifndef __WXSTUBS__ + #include #include #include @@ -31,6 +45,33 @@ ///////////////////////////////////////////////////////////////////////////// // System specific headers ///////////////////////////////////////////////////////////////////////////// +#ifdef __WXMAC__ +// in order to avoid problems with our c library and double definitions +#define close closesocket +#define ioctl ioctlsocket + +#include +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 #endif // __WINDOWS__ @@ -47,11 +88,19 @@ #include #include +#ifdef sun +#include +#endif + #endif // __UNIX__ #include #include +#ifdef _MSC_VER +#include +#endif + #if defined(__WXMOTIF__) || defined(__WXXT__) #include @@ -71,20 +120,20 @@ ///////////////////////////////////////////////////////////////////////////// // wxSocket headers ///////////////////////////////////////////////////////////////////////////// +#include "wx/module.h" #define WXSOCK_INTERNAL #include "wx/sckaddr.h" #include "wx/socket.h" -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - ///////////////////////////////////////////////////////////////////////////// // Some patch ///// BEGIN ///////////////////////////////////////////////////////////////////////////// #ifdef __WINDOWS__ #define close closesocket #define ioctl ioctlsocket +#ifdef errno +#undef errno +#endif #define errno WSAGetLastError() #ifdef EWOULDBLOCK #undef EWOULDBLOCK @@ -100,7 +149,7 @@ #endif #ifdef __WXMOTIF__ -#define wxAPP_CONTEXT wxTheApp->appContext +#define wxAPP_CONTEXT ((XtAppContext)wxTheApp->GetAppContext()) #endif #ifdef __WINDOWS__ @@ -111,15 +160,15 @@ #if defined( NEED_WSAFDIsSet ) || defined( _MSC_VER ) 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 @@ -136,6 +185,18 @@ int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) // Some patch ///// END ///////////////////////////////////////////////////////////////////////////// +// -------------------------------------------------------------- +// Module +// -------------------------------------------------------------- +class wxSocketModule: public wxModule +{ + DECLARE_DYNAMIC_CLASS(wxSocketModule) +public: + wxSocketModule() {} + bool OnInit(); + void OnExit(); +}; + // -------------------------------------------------------------- // ClassInfos // -------------------------------------------------------------- @@ -145,26 +206,31 @@ 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 { +class wxSockWakeUp : public wxTimer +{ public: int *my_id; int n_val; wxSocketBase *sock; - wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val) { + wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val) + { my_id = id; n_val = new_val; sock = _sock; } - virtual void Notify() { + virtual void Notify() + { *my_id = n_val; if (sock) sock->Notify(FALSE); } }; /// Socket request -class SockRequest : public wxObject { +class SockRequest : public wxObject +{ public: char *buffer; size_t size, nbytes; @@ -173,7 +239,7 @@ public: wxSockWakeUp *auto_wakeup; wxSocketBase::wxRequestNotify type; }; - + ///////////////////////////////////////////////////////////////////////////// // Some internal define @@ -183,7 +249,7 @@ public: // --------- 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), @@ -229,8 +295,9 @@ wxSocketBase::wxSocketBase() : } // -------------------------------------------------------------- -// --------- wxSocketBase CONSTRUCTOR --------------------------- +// wxSocketBase // -------------------------------------------------------------- + wxSocketBase::~wxSocketBase() { DestroyCallbacks(); @@ -238,7 +305,8 @@ wxSocketBase::~wxSocketBase() if (m_unread) free(m_unread); - if (m_handler) { + if (m_handler) + { #ifdef __WINDOWS__ if (m_internal->my_msg) m_handler->DestroyMessage(m_internal->my_msg); @@ -252,14 +320,17 @@ wxSocketBase::~wxSocketBase() bool wxSocketBase::Close() { - if (m_fd != INVALID_SOCKET) { - for (int i=0;i<3;i++) { + if (m_fd != INVALID_SOCKET) + { + for (int i=0;i<3;i++) + { wxNode *n, *node = req_list[i].First(); - while (node) { + while (node) + { SockRequest *req = (SockRequest *)node->Data(); req->done = TRUE; - + n = node->Next(); delete node; node = n; @@ -277,8 +348,9 @@ bool wxSocketBase::Close() } // -------------------------------------------------------------- -// --------- wxSocketBase base IO functions --------------------- +// wxSocketBase base IO function // -------------------------------------------------------------- + wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) { m_lcount = GetPushback(buffer, nbytes, FALSE); @@ -298,7 +370,8 @@ wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) size_t nbytes_old = nbytes; nbytes -= GetPushback(buffer, nbytes, TRUE); - if (!nbytes) { + if (!nbytes) + { m_lcount = nbytes_old; return *this; } @@ -318,7 +391,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) { SockMsg msg; size_t len, len2, sig; - + Read((char *)&msg, sizeof(msg)); if (m_lcount != sizeof(msg)) return *this; @@ -361,27 +434,27 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) { SockMsg msg; - - msg.sig[0] = 0xad; - msg.sig[1] = 0xde; - msg.sig[2] = 0xed; - msg.sig[3] = 0xfe; - msg.len[0] = nbytes & 0xff; - msg.len[1] = (nbytes >> 8) & 0xff; - msg.len[2] = (nbytes >> 16) & 0xff; - msg.len[3] = (nbytes >> 24) & 0xff; + msg.sig[0] = (char) 0xad; + msg.sig[1] = (char) 0xde; + msg.sig[2] = (char) 0xed; + msg.sig[3] = (char) 0xfe; + + msg.len[0] = (char) nbytes & 0xff; + msg.len[1] = (char) (nbytes >> 8) & 0xff; + msg.len[2] = (char) (nbytes >> 16) & 0xff; + msg.len[3] = (char) (nbytes >> 24) & 0xff; if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg)) return *this; if (Write(buffer, nbytes).LastCount() < nbytes) - return *this; + return *this; - msg.sig[0] = 0xed; - msg.sig[1] = 0xfe; - msg.sig[2] = 0xad; - msg.sig[3] = 0xde; - msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = 0; + msg.sig[0] = (char) 0xed; + msg.sig[1] = (char) 0xfe; + msg.sig[2] = (char) 0xad; + msg.sig[3] = (char) 0xde; + msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0; Write((char *)&msg, sizeof(msg)); return *this; @@ -408,7 +481,7 @@ bool wxSocketBase::IsData() const FD_ZERO(&sock_set); FD_SET(m_fd, &sock_set); select(FD_SETSIZE, &sock_set, NULL, NULL, &tv); - return FD_ISSET(m_fd, &sock_set); + return (FD_ISSET(m_fd, &sock_set) != 0); } // --------------------------------------------------------------------- @@ -422,8 +495,9 @@ void wxSocketBase::Discard() SaveState(); SetFlags((wxSockFlags)(NOWAIT | SPEED)); - - while (recv_size == MAX_BUFSIZE) { + + while (recv_size == MAX_BUFSIZE) + { recv_size = Read(my_data, MAX_BUFSIZE).LastCount(); } @@ -433,23 +507,29 @@ void wxSocketBase::Discard() #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 + // -------------------------------------------------------------- -// --------- wxSocketBase socket info functions ----------------- +// wxSocketBase socket info functions // -------------------------------------------------------------- + bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const { struct sockaddr my_addr; - size_t len_addr = sizeof(my_addr); + wxSOCKET_INT len_addr = sizeof(my_addr); if (m_fd < 0) return FALSE; -#ifdef __WINDOWS__ - if (getpeername(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0) -#else - if (getpeername(m_fd, (struct sockaddr *)&my_addr, (unsigned int *)&len_addr) < 0) -#endif - return FALSE; + if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) + return FALSE; addr_man.Disassemble(&my_addr, len_addr); return TRUE; @@ -458,16 +538,13 @@ bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const { struct sockaddr my_addr; - size_t len_addr = sizeof(my_addr); + wxSOCKET_INT len_addr = sizeof(my_addr); if (m_fd < 0) return FALSE; -#ifdef __WINDOWS__ - if (getsockname(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0) -#else - if (getsockname(m_fd, (struct sockaddr *)&my_addr, (unsigned int *)&len_addr) < 0) -#endif + if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) + return FALSE; addr_man.Disassemble(&my_addr, len_addr); @@ -475,8 +552,9 @@ bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const } // -------------------------------------------------------------- -// --------- wxSocketBase wait functions ------------------------ +// wxSocketBase wait functions // -------------------------------------------------------------- + void wxSocketBase::SaveState() { wxSockState *state = new wxSockState; @@ -500,7 +578,7 @@ void wxSocketBase::RestoreState() return; wxSockState *state = (wxSockState *)node->Data(); - + SetFlags(state->flags); m_neededreq = state->cbk_set; m_cbk = state->cbk; @@ -518,7 +596,7 @@ void wxSocketBase::RestoreState() // -------------------------------------------------------------- // --------- wxSocketBase wait functions ------------------------ // -------------------------------------------------------------- -// + bool wxSocketBase::_Wait(long seconds, long microseconds, int type) { if ((!m_connected && !m_connecting) || m_fd < 0) @@ -532,14 +610,15 @@ bool wxSocketBase::_Wait(long seconds, long microseconds, int type) if (seconds != -1) wakeup.Start((int)(seconds*1000 + (microseconds / 1000)), TRUE); - + m_waitflags = 0x80 | type; while (m_waitflags & 0x80) PROCESS_EVENTS(); RestoreState(); - if (m_waitflags & 0x40) { + if (m_waitflags & 0x40) + { m_waitflags = 0; return TRUE; } @@ -576,7 +655,7 @@ bool wxSocketBase::WaitForLost(long seconds, long microseconds) #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, @@ -590,18 +669,25 @@ static void wx_socket_read(gpointer client, gint fd, i = recv(fd, &c, 1, MSG_PEEK); - if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) { + if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) + { sock->OnRequest(wxSocketBase::EVT_ACCEPT); return; } - if (i != 0) { + if (i != 0) + { if (!(sock->NeededReq() & wxSocketBase::REQ_READ)) + { return; + } sock->OnRequest(wxSocketBase::EVT_READ); - } else { - if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) { + } + else + { + if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) + { sock->Close(); return; } @@ -613,10 +699,10 @@ static void wx_socket_read(gpointer client, gint fd, #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; @@ -637,18 +723,22 @@ Notify_value wx_sock_read_xview (Notify_client client, int fd) i = recv(fd, &c, 1, MSG_PEEK); - if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) { + if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) + { sock->OnRequest(wxSocketBase::EVT_ACCEPT); return; } /* Bytes arrived */ - if (i != 0) { + if (i != 0) + { if (!(sock->NeededReq() & wxSocketBase::REQ_READ)) return (Notify_value) FALSE; sock->OnRequest(wxSocketBase::EVT_READ); - } else { + } + else + { if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) return; @@ -673,7 +763,8 @@ Notify_value wx_sock_write_xview (Notify_client client, int fd) wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt) { - switch (evt) { + switch (evt) + { case EVT_READ: return REQ_READ; case EVT_PEEK: @@ -693,7 +784,8 @@ wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt) void wxSocketBase::SetFlags(wxSockFlags _flags) { m_flags = _flags; - if (_flags & SPEED) { + if (_flags & SPEED) + { unsigned long flag = 0; ioctl(m_fd, FIONBIO, &flag); @@ -701,7 +793,9 @@ void wxSocketBase::SetFlags(wxSockFlags _flags) m_flags = (wxSockFlags)(m_flags & ~WAITALL); Notify(FALSE); - } else { + } + else + { unsigned long flag = 1; ioctl(m_fd, FIONBIO, &flag); } @@ -710,13 +804,20 @@ void wxSocketBase::SetFlags(wxSockFlags _flags) void wxSocketBase::SetNotify(wxRequestNotify flags) { wxRequestNotify old_needed_req = m_neededreq; - if (flags & REQ_ACCEPT) { + if (flags & REQ_ACCEPT) + { /* Check if server */ if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer)))) flags &= ~REQ_ACCEPT; } m_neededreq = flags; - if (m_cbkon && old_needed_req != flags) + +/* + if (m_cbkon && old_needed_req != flags) seems to be wrong, Robert Roebling + SetupCallbacks(); +*/ + + if (old_needed_req != flags) SetupCallbacks(); } @@ -725,33 +826,89 @@ void wxSocketBase::SetupCallbacks() if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED)) return; -#if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__) - if (m_cbkon) - DestroyCallbacks(); - if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) { -#ifdef __WXGTK__ - m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ, - wx_socket_read, (gpointer)this); -#else - m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, +#if defined(__WXMOTIF__) || defined(__WXXT__) + if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) + { + if (m_internal->sock_inputid <= 0) + { + m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, (XtPointer *) XtInputReadMask, (XtInputCallbackProc) wx_socket_read, (XtPointer) this); -#endif + } } - if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) { -#ifdef __WXGTK__ - m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_WRITE, - wx_socket_write, (gpointer)this); -#else - m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, + else + { + if (m_internal->sock_inputid > 0) + { + XtRemoveInput(m_internal->sock_inputid); + m_internal->sock_inputid = 0; + } + } + + if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) + { + if (m_internal->sock_outputid <= 0) + { + m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd, (XtPointer *) XtInputWriteMask, (XtInputCallbackProc) wx_socket_write, (XtPointer) this); + } + } + else + { + if (m_internal->sock_outputid > 0) + { + XtRemoveInput(m_internal->sock_outputid); + m_internal->sock_outputid = 0; + } + } #endif + + +#ifdef __WXGTK__ + if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) + { + if (m_internal->sock_inputid <= 0) + { + m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ, + wx_socket_read, (gpointer)this); + } + } + else + { + if (m_internal->sock_inputid > 0) + { +/* + gdk_input_remove(m_internal->sock_inputid); + m_internal->sock_inputid = 0; +*/ + } + } + + if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) + { + if (m_internal->sock_outputid <= 0) + { + m_internal->sock_outputid = gdk_input_add(m_fd, GDK_INPUT_WRITE, + wx_socket_write, (gpointer)this); + } + } + else + { + if (m_internal->sock_outputid > 0) + { +/* + gdk_input_remove(m_internal->sock_outputid); + m_internal->sock_outputid = 0; +*/ + } } #endif -#ifdef __WINDOWS__ + + +#ifdef __WXMSW__ WORD mask = 0; if (m_neededreq & REQ_READ) @@ -768,6 +925,24 @@ void wxSocketBase::SetupCallbacks() 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; @@ -777,6 +952,7 @@ void wxSocketBase::DestroyCallbacks() { if (!m_cbkon || !m_handler) return; + m_cbkon = FALSE; m_processing = FALSE; #if defined(__WXMOTIF__) || defined(__WXXT__) @@ -798,6 +974,20 @@ void wxSocketBase::DestroyCallbacks() #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) @@ -816,23 +1006,26 @@ void wxSocketBase::OnRequest(wxRequestEvent req_evt) wxRequestNotify req_notif = EventToNotify(req_evt); // Mask the current event - SetNotify(m_neededreq & ~req_notif); - + SetNotify(m_neededreq & ~req_notif); + if (req_evt <= EVT_WRITE && DoRequests(req_evt)) return; - if (m_waitflags & 0xF0) { + if (m_waitflags & 0xF0) + { // Wake up - if ((m_waitflags & 0x0F) == req_evt) { + if ((m_waitflags & 0x0F) == req_evt) + { m_waitflags = 0x80; #ifndef __WXGTK__ - DestroyCallbacks(); // I disable it to prevent infinite loop on X11. + DestroyCallbacks(); #endif } return; } - if (req_evt == EVT_LOST) { + if (req_evt == EVT_LOST) + { m_connected = FALSE; Close(); } @@ -866,6 +1059,7 @@ void wxSocketBase::OldOnNotify(wxRequestEvent evt) // -------------------------------------------------------------- // --------- wxSocketBase functions [Callback, CallbackData] ---- // -------------------------------------------------------------- + wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk) { wxSockCbk old_cbk = m_cbk; @@ -891,6 +1085,7 @@ void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id) // -------------------------------------------------------------- // --------- wxSocketBase pushback library ---------------------- // -------------------------------------------------------------- + void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) { char *curr_pos; @@ -954,18 +1149,21 @@ bool wxSocketBase::DoRequests(wxRequestEvent req_flag) delete node; - switch (req->type) { + switch (req->type) + { case EVT_READ: case EVT_PEEK: ret = recv(m_fd, req->buffer, req->size, (req->type == EVT_PEEK) ? MSG_PEEK : 0); - if (ret < 0) { + if (ret < 0) + { req->error = errno; req->done = TRUE; break; } len = ret; - if ((len < req->size) && (m_flags & WAITALL)) { + if ((len < req->size) && (m_flags & WAITALL)) + { req->size -= len; req->nbytes += len; req->buffer += len; @@ -981,13 +1179,15 @@ bool wxSocketBase::DoRequests(wxRequestEvent req_flag) break; case EVT_WRITE: ret = send(m_fd, req->buffer, req->size, 0); - if (ret < 0) { + if (ret < 0) + { req->error = errno; req->done = TRUE; break; } len = ret; - if ((len < req->size) && (m_flags & WAITALL)) { + if ((len < req->size) && (m_flags & WAITALL)) + { req->size -= len; req->nbytes += len; req->buffer += len; @@ -1010,40 +1210,48 @@ bool wxSocketBase::DoRequests(wxRequestEvent req_flag) void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes, wxRequestEvent evt) { - int ret; + int ret = 0; - switch (evt) { + switch (evt) + { case EVT_PEEK: case EVT_READ: - ret = read(m_fd, buffer, nbytes); + ret = recv(m_fd, buffer, nbytes, + (evt == EVT_PEEK) ? MSG_PEEK : 0); break; case EVT_WRITE: - ret = write(m_fd, buffer, nbytes); + ret = send(m_fd, buffer, nbytes, 0); break; } - if (ret < 0) { + if (ret < 0) + { m_lcount = 0; m_error = errno; - } else + } + else + { m_lcount = ret; + m_error = 0; + } } void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, - wxRequestEvent evt) + wxRequestEvent evt) { bool buf_timed_out; if (m_fd == INVALID_SOCKET || !m_handler || !m_connected) return; - if (m_flags & SPEED) { + if (m_flags & SPEED) + { WantSpeedBuffer(buffer, nbytes, evt); return; } SockRequest *buf = new SockRequest; wxSockWakeUp s_wake(NULL, (int *)&buf_timed_out, (int)TRUE); - + m_wantbuf++; req_list[evt].Append(buf); @@ -1060,9 +1268,12 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, buf_timed_out = FALSE; s_wake.Start(m_timeout*1000, TRUE); - if (m_flags & NOWAIT) { + if (m_flags & NOWAIT) + { DoRequests(evt); - } else { + } + else + { while (!buf->done && !buf_timed_out) PROCESS_EVENTS(); } @@ -1078,31 +1289,28 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes, } // -------------------------------------------------------------- -// wxSocketServer /////////////////////////////////////////////// +// wxSocketServer // -------------------------------------------------------------- -// -------------------------------------------------------------- -// --------- wxSocketServer CONSTRUCTOR ------------------------- -// -------------------------------------------------------------- wxSocketServer::wxSocketServer(wxSockAddress& addr_man, - wxSockFlags flags) : + wxSockFlags flags) : wxSocketBase(flags, SOCK_SERVER) { m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0); if (m_fd == INVALID_SOCKET) return; - + int flag = 1; setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int)); - + struct sockaddr *myaddr; size_t len; - + addr_man.Build(myaddr, len); if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0) return; - + if (listen(m_fd, 5) < 0) { m_fd = INVALID_SOCKET; return; @@ -1110,29 +1318,31 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man, } // -------------------------------------------------------------- -// --------- wxSocketServer Accept ------------------------------ +// wxSocketServer Accept // -------------------------------------------------------------- + bool wxSocketServer::AcceptWith(wxSocketBase& sock) { int fd2; - + if ((fd2 = accept(m_fd, 0, 0)) < 0) return FALSE; struct linger linger; linger.l_onoff = 0; linger.l_linger = 1; - + setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); - + int flag = 0; setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int)); - - if (!(sock.m_flags & SPEED)) { + + if (!(sock.m_flags & SPEED)) + { unsigned long flag2 = 1; ioctl(fd2, FIONBIO, &flag2); } - + sock.m_type = SOCK_INTERNAL; sock.m_fd = fd2; sock.m_connected = TRUE; @@ -1156,23 +1366,25 @@ wxSocketBase *wxSocketServer::Accept() } // -------------------------------------------------------------- -// --------- wxSocketServer callbacks --------------------------- +// wxSocketServer callbacks // -------------------------------------------------------------- + void wxSocketServer::OnRequest(wxRequestEvent evt) { - if (evt == EVT_ACCEPT) { + if (evt == EVT_ACCEPT) + { OldOnNotify(EVT_ACCEPT); } } // -------------------------------------------------------------- -// wxSocketClient /////////////////////////////////////////////// +// wxSocketClient // -------------------------------------------------------------- // --------- wxSocketClient CONSTRUCTOR ------------------------- // -------------------------------------------------------------- wxSocketClient::wxSocketClient(wxSockFlags _flags) : - wxSocketBase(_flags, SOCK_CLIENT) + wxSocketBase(_flags, SOCK_CLIENT) { } @@ -1186,7 +1398,7 @@ wxSocketClient::~wxSocketClient() // -------------------------------------------------------------- // --------- wxSocketClient Connect functions ------------------- // -------------------------------------------------------------- -bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) +bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) ) { struct linger linger; @@ -1194,21 +1406,21 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) Close(); m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0); - + if (m_fd < 0) return FALSE; - + m_connected = FALSE; linger.l_onoff = 1; - linger.l_linger = 5; + linger.l_linger = 5; setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); - + // Stay in touch with the state of things... - + unsigned long flag = 1; setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int)); - + // Disable the nagle algorithm, which delays sends till the // buffer is full (or a certain time period has passed?)... @@ -1216,7 +1428,7 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) flag = 1; setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); #endif - + struct sockaddr *remote; size_t len; @@ -1225,38 +1437,45 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) if (connect(m_fd, remote, len) != 0) return FALSE; - if (!(m_flags & SPEED)) { + if (!(m_flags & SPEED)) + { flag = 1; ioctl(m_fd, FIONBIO, &flag); } - + Notify(TRUE); m_connected = TRUE; return TRUE; } -bool wxSocketClient::WaitOnConnect(long seconds) +bool wxSocketClient::WaitOnConnect(long seconds, long microseconds) { - int ret = _Wait(seconds, 0, REQ_CONNECT | REQ_LOST); - + int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST); + if (ret) m_connected = TRUE; - - return m_connected; + + return m_connected; } void wxSocketClient::OnRequest(wxRequestEvent evt) { - if (evt == EVT_CONNECT) { - if (m_connected) { + if (evt == EVT_CONNECT) + { + if (m_connected) + { +#ifndef __WXGTK__ SetNotify(m_neededreq & ~REQ_CONNECT); +#endif return; } m_waitflags = 0x40; - m_connected = TRUE; + m_connected = TRUE; OldOnNotify(EVT_CONNECT); +#ifndef __WXGTK__ DestroyCallbacks(); +#endif return; } wxSocketBase::OnRequest(evt); @@ -1274,6 +1493,64 @@ static int win_initialized = 0; // -------------------------------------------------------------- // --------- 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[]; @@ -1281,6 +1558,11 @@ extern char wxPanelClassName[]; LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + if(message==WM_DESTROY) + { + ::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); wxSocketBase *sock; @@ -1321,7 +1603,8 @@ FARPROC wxSocketSubClassProc = NULL; wxSocketHandler::wxSocketHandler() { #if defined(__WINDOWS__) - if (!win_initialized) { + if (!win_initialized) + { WSADATA wsaData; WSAStartup((1 << 8) | 1, &wsaData); @@ -1329,8 +1612,8 @@ wxSocketHandler::wxSocketHandler() } 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) @@ -1356,7 +1639,8 @@ wxSocketHandler::~wxSocketHandler() { wxNode *next_node, *node = socks->First(); - while (node) { + while (node) + { wxSocketBase* sock = (wxSocketBase*)node->Data(); delete sock; @@ -1381,18 +1665,21 @@ wxSocketHandler::~wxSocketHandler() // -------------------------------------------------------------- // --------- wxSocketHandler registering functions -------------- // -------------------------------------------------------------- + void wxSocketHandler::Register(wxSocketBase* sock) { wxNode *node; - for (node = socks->First(); node != NULL; node = node->Next()) { + for (node = socks->First(); node != NULL; node = node->Next()) + { wxSocketBase* s = (wxSocketBase*)node->Data(); if (s == sock) return; } - if (sock) { + if (sock) + { socks->Append(sock); sock->SetHandler(this); sock->SetupCallbacks(); @@ -1403,10 +1690,12 @@ void wxSocketHandler::UnRegister(wxSocketBase* sock) { wxNode *node; - for (node = socks->First(); node; node = node->Next()) { + for (node = socks->First(); node; node = node->Next()) + { wxSocketBase* s = (wxSocketBase*)node->Data(); - - if (s == sock) { + + if (s == sock) + { delete node; sock->DestroyCallbacks(); sock->SetHandler(NULL); @@ -1424,8 +1713,8 @@ unsigned long wxSocketHandler::Count() const // --------- 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; @@ -1440,7 +1729,8 @@ int wxSocketHandler::Wait(long seconds, long microseconds) wxSockWakeUp s_wake(NULL, &on_wait, -2); wxNode *node; - for (node = socks->First(), i=0; node; node = node->Next(), i++) { + for (node = socks->First(), i=0; node; node = node->Next(), i++) + { wxSocketBase *sock = (wxSocketBase *)node->Data(); sock->SaveState(); @@ -1457,7 +1747,8 @@ int wxSocketHandler::Wait(long seconds, long microseconds) while (!on_wait) PROCESS_EVENTS(); - for (node = socks->First(), i=0; node; node = node->Next(), i++) { + for (node = socks->First(), i=0; node; node = node->Next(), i++) + { wxSocketBase *sock = (wxSocketBase *)node->Data(); sock->RestoreState(); @@ -1473,7 +1764,8 @@ void wxSocketHandler::YieldSock() { wxNode *node; - for (node = socks->First(); node; node = node->Next() ) { + for (node = socks->First(); node; node = node->Next() ) + { wxSocketBase *sock = (wxSocketBase *)node->Data(); sock->SaveState(); @@ -1491,7 +1783,7 @@ void wxSocketHandler::YieldSock() // --------- wxSocketHandler: create and register the socket ---- // -------------------------------------------------------------- wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr, - wxSocketBase::wxSockFlags flags) + wxSocketBase::wxSockFlags flags) { wxSocketServer *serv = new wxSocketServer(addr, flags); @@ -1511,6 +1803,7 @@ wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags) // -------------------------------------------------------------- // --------- wxSocketHandler: Windows specific methods ---------- // -------------------------------------------------------------- + UINT wxSocketHandler::NewMessage(wxSocketBase *sock) { internal->firstAvailableMsg++; @@ -1530,3 +1823,39 @@ HWND wxSocketHandler::GetHWND() const } #endif + +bool wxSocketModule::OnInit() +{ + wxSocketHandler::master = new wxSocketHandler(); + return TRUE; +} + +void wxSocketModule::OnExit() +{ + delete wxSocketHandler::master; + 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__