]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
unused param warning suppressed
[wxWidgets.git] / src / common / socket.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
5 // Davidson(1995) in wxWeb)
6 // Created: April 1997
7 // Updated: March 1998
8 // Copyright: (C) 1998, 1997, Guilhem Lavaux
9 // RCS_ID: $Id$
10 // License: see wxWindows license
11 ////////////////////////////////////////////////////////////////////////////////
12 #ifdef __GNUG__
13 #pragma implementation "socket.h"
14 #endif
15
16 #ifdef __MWERKS__
17 typedef int socklen_t ;
18 #endif
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 /////////////////////////////////////////////////////////////////////////////
28 // wxWindows headers
29 /////////////////////////////////////////////////////////////////////////////
30 #include <wx/defs.h>
31 #include <wx/object.h>
32 #include <wx/string.h>
33 #include <wx/timer.h>
34 #include <wx/utils.h>
35
36 // Not enough OS behaviour defined for wxStubs
37 #ifndef __WXSTUBS__
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42
43 /////////////////////////////////////////////////////////////////////////////
44 // System specific headers
45 /////////////////////////////////////////////////////////////////////////////
46 #ifdef __WXMAC__
47 // in order to avoid problems with our c library and double definitions
48 #define close closesocket
49 #define ioctl ioctlsocket
50
51 #include <wx/mac/macsock.h>
52 extern GUSISpinFn GUSISpin;
53 #define PROCESS_EVENTS() wxMacProcessEvents()
54 const short kwxMacNetEventsMax = 1000 ;
55 short wxMacNetEventsTop = 0 ;
56 short wxMacNetEventsBottom = 0 ;
57 short wxMacNetEventsEvents[kwxMacNetEventsMax] ;
58 void *wxMacNetEventsReferences[kwxMacNetEventsMax] ;
59
60 #define FD_READ 1
61 #define FD_WRITE 2
62 #define FD_CLOSE 4
63 #define FD_ACCEPT 8
64 #define FD_CONNECT 16
65 #define FD_READY 32
66
67 extern "C" void wxMacSocketHandlerProc( void *refcon , short event ) ; // adds events
68 extern "C" void wxMacSocketOnRequestProc( void *refcon , short event ) ; // consumes them
69 extern "C" void GUSISetReference( short sock , short eventmask , void * data ) ;
70 void wxMacProcessEvents() ;
71 #endif
72
73 #if defined(__WINDOWS__)
74 #include <winsock.h>
75 #endif // __WINDOWS__
76
77 #if defined(__UNIX__)
78
79 #ifdef VMS
80 #include <socket.h>
81 #else
82 #include <sys/socket.h>
83 #endif
84 #include <sys/ioctl.h>
85
86 #include <sys/time.h>
87 #include <unistd.h>
88
89 #ifdef sun
90 #include <sys/filio.h>
91 #endif
92
93 #endif // __UNIX__
94
95 #include <signal.h>
96 #include <errno.h>
97
98 #ifdef __VISUALC__
99 #include <io.h>
100 #endif
101
102 #if defined(__WXMOTIF__) || defined(__WXXT__)
103 #include <X11/Intrinsic.h>
104
105 /////////////////////////////
106 // Needs internal variables
107 /////////////////////////////
108 #ifdef __WXXT__
109 #define Uses_XtIntrinsic
110 #endif
111
112 #endif
113
114 #if defined(__WXGTK__)
115 #include <gtk/gtk.h>
116 #endif
117
118 /////////////////////////////////////////////////////////////////////////////
119 // wxSocket headers
120 /////////////////////////////////////////////////////////////////////////////
121 #include "wx/module.h"
122 #define WXSOCK_INTERNAL
123 #include "wx/sckaddr.h"
124 #include "wx/socket.h"
125
126 /////////////////////////////////////////////////////////////////////////////
127 // Some patch ///// BEGIN
128 /////////////////////////////////////////////////////////////////////////////
129 #ifdef __WINDOWS__
130 #define close closesocket
131 #define ioctl ioctlsocket
132 #ifdef errno
133 #undef errno
134 #endif
135 #define errno WSAGetLastError()
136 #ifdef EWOULDBLOCK
137 #undef EWOULDBLOCK
138 #endif
139 #define EWOULDBLOCK WSAEWOULDBLOCK
140 #define ETIMEDOUT WSAETIMEDOUT
141 #undef EINTR
142 #define EINTR WSAEINTR
143 #endif
144
145 #ifndef __WINDOWS__
146 #define INVALID_SOCKET -1
147 #endif
148
149 #ifdef __WXMOTIF__
150 #define wxAPP_CONTEXT ((XtAppContext)wxTheApp->GetAppContext())
151 #endif
152
153 #ifdef __WINDOWS__
154 // This is an MS TCP/IP routine and is not needed here. Some WinSock
155 // implementations (such as PC-NFS) will require you to include this
156 // or a similar routine (see appendix in WinSock doc or help file).
157
158 #if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ )
159 int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
160 {
161 int i = set->fd_count;
162
163 while (i--)
164 {
165 if (set->fd_array[i] == fd)
166 return 1;
167 }
168
169 return 0;
170 }
171 #endif
172 #endif
173
174 #if defined(__WINDOWS__)
175 #define PROCESS_EVENTS() wxYield()
176 #elif defined(__WXXT__) || defined(__WXMOTIF__)
177 #define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll)
178 #elif defined(__WXGTK__)
179 #define PROCESS_EVENTS() gtk_main_iteration()
180 #endif
181
182 /////////////////////////////////////////////////////////////////////////////
183 // Some patch ///// END
184 /////////////////////////////////////////////////////////////////////////////
185
186 #ifdef GetClassInfo
187 #undef GetClassInfo
188 #endif
189
190 // --------------------------------------------------------------
191 // Module
192 // --------------------------------------------------------------
193 class wxSocketModule: public wxModule
194 {
195 DECLARE_DYNAMIC_CLASS(wxSocketModule)
196 public:
197 wxSocketModule() {}
198 bool OnInit();
199 void OnExit();
200 };
201
202 // --------------------------------------------------------------
203 // ClassInfos
204 // --------------------------------------------------------------
205 #if !USE_SHARED_LIBRARY
206 IMPLEMENT_CLASS(wxSocketBase, wxObject)
207 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
208 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
209 IMPLEMENT_CLASS(wxSocketHandler, wxObject)
210 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
211 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
212 #endif
213
214 class wxSockWakeUp : public wxTimer
215 {
216 public:
217 int *my_id;
218 int n_val;
219 wxSocketBase *sock;
220
221 wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val)
222 {
223 my_id = id; n_val = new_val;
224 sock = _sock;
225 }
226 virtual void Notify()
227 {
228 *my_id = n_val;
229 if (sock) sock->Notify(FALSE);
230 }
231 };
232
233 /// Socket request
234 class SockRequest : public wxObject
235 {
236 public:
237 char *buffer;
238 size_t size, nbytes;
239 bool done;
240 int error;
241 wxSockWakeUp *auto_wakeup;
242 wxSocketBase::wxRequestNotify type;
243 };
244
245
246 /////////////////////////////////////////////////////////////////////////////
247 // Some internal define
248 /////////////////////////////////////////////////////////////////////////////
249
250 // --------------------------------------------------------------
251 // --------- wxSocketBase CONSTRUCTOR ---------------------------
252 // --------------------------------------------------------------
253 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
254 wxSocketBase::wxSockType _type) :
255 wxEvtHandler(),
256 m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
257 m_fd(INVALID_SOCKET), m_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1),
258 m_handler(0),
259 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
260 m_cbkon(FALSE),
261 m_unread(NULL), m_unrd_size(0),
262 m_processing(FALSE),
263 m_timeout(3600), m_wantbuf(0)
264 {
265 m_internal = new wxSockInternal;
266 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
267 m_internal->sock_inputid = 0;
268 m_internal->sock_outputid = 0;
269 m_internal->sock_exceptid = 0;
270 #endif
271 #ifdef __WINDOWS__
272 m_internal->my_msg = 0;
273 #endif
274 }
275
276 wxSocketBase::wxSocketBase() :
277 wxEvtHandler(),
278 m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
279 m_connecting(FALSE), m_fd(INVALID_SOCKET), m_waitflags(0),
280 m_cbk(0), m_cdata(0),
281 m_id(-1), m_handler(0),
282 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
283 m_cbkon(FALSE),
284 m_unread(NULL), m_unrd_size(0),
285 m_processing(FALSE),
286 m_timeout(3600), m_wantbuf(0)
287 {
288 m_internal = new wxSockInternal;
289 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
290 m_internal->sock_inputid = 0;
291 m_internal->sock_outputid = 0;
292 m_internal->sock_exceptid = 0;
293 #endif
294 #ifdef __WINDOWS__
295 m_internal->my_msg = 0;
296 #endif
297 }
298
299 // --------------------------------------------------------------
300 // wxSocketBase
301 // --------------------------------------------------------------
302
303 wxSocketBase::~wxSocketBase()
304 {
305 DestroyCallbacks();
306 Close();
307
308 if (m_unread)
309 free(m_unread);
310 if (m_handler)
311 {
312 #ifdef __WINDOWS__
313 if (m_internal->my_msg)
314 m_handler->DestroyMessage(m_internal->my_msg);
315 #endif
316 m_handler->UnRegister(this);
317 }
318 m_states.DeleteContents(TRUE);
319
320 delete m_internal;
321 }
322
323 bool wxSocketBase::Close()
324 {
325 if (m_fd != INVALID_SOCKET)
326 {
327 for (int i=0;i<3;i++)
328 {
329 wxNode *n, *node = req_list[i].First();
330
331 while (node)
332 {
333 SockRequest *req = (SockRequest *)node->Data();
334 req->done = TRUE;
335
336 n = node->Next();
337 delete node;
338 node = n;
339 }
340 }
341
342 DestroyCallbacks();
343 shutdown(m_fd, 2);
344 close(m_fd);
345 m_fd = INVALID_SOCKET;
346 m_connected = FALSE;
347 }
348
349 return TRUE;
350 }
351
352 // --------------------------------------------------------------
353 // wxSocketBase base IO function
354 // --------------------------------------------------------------
355
356 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
357 {
358 size_t count;
359
360 count = GetPushback(buffer, nbytes, FALSE);
361 nbytes -= count;
362 buffer += count;
363
364 // If we have got the whole needed buffer or if we don't want to
365 // wait then it returns immediately.
366 if (!nbytes || (count && !(m_flags & WAITALL)) ) {
367 m_lcount = count;
368 return *this;
369 }
370
371 m_lcount = 0;
372 WantBuffer(buffer, nbytes, EVT_READ);
373 m_lcount += count;
374
375 return *this;
376 }
377
378 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
379 {
380 size_t count;
381
382 count = GetPushback(buffer, nbytes, TRUE);
383 if (nbytes-count == 0)
384 {
385 m_lcount = nbytes;
386 return *this;
387 }
388 buffer += count;
389 nbytes -= count;
390
391 m_lcount = 0;
392 WantBuffer(buffer, nbytes, EVT_PEEK);
393 m_lcount += count;
394
395 return *this;
396 }
397
398 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
399 {
400 WantBuffer((char *)buffer, nbytes, EVT_WRITE);
401 return *this;
402 }
403
404 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
405 {
406 SockMsg msg;
407 size_t len, len2, sig;
408
409 Read((char *)&msg, sizeof(msg));
410 if (m_lcount != sizeof(msg))
411 return *this;
412
413 sig = msg.sig[0] & 0xff;
414 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
415 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
416 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
417
418 if (sig != 0xfeeddead)
419 return *this;
420 len = msg.len[0] & 0xff;
421 len |= (size_t)(msg.len[1] & 0xff) << 8;
422 len |= (size_t)(msg.len[2] & 0xff) << 16;
423 len |= (size_t)(msg.len[3] & 0xff) << 24;
424 len2 = len;
425 if (len > nbytes)
426 len = nbytes;
427 else
428 len2 = 0;
429
430 if (Read(buffer, len).LastCount() != len)
431 return *this;
432 if (len2 && (Read(NULL, len2).LastCount() != len2))
433 return *this;
434 if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
435 return *this;
436
437 sig = msg.sig[0] & 0xff;
438 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
439 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
440 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
441 // ERROR
442 if (sig != 0xdeadfeed)
443 return *this;
444
445 return *this;
446 }
447
448 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
449 {
450 SockMsg msg;
451
452 // warning about 'cast truncates constant value'
453 #ifdef __VISUALC__
454 #pragma warning(disable: 4310)
455 #endif // __VISUALC__
456
457 msg.sig[0] = (char) 0xad;
458 msg.sig[1] = (char) 0xde;
459 msg.sig[2] = (char) 0xed;
460 msg.sig[3] = (char) 0xfe;
461
462 msg.len[0] = (char) nbytes & 0xff;
463 msg.len[1] = (char) (nbytes >> 8) & 0xff;
464 msg.len[2] = (char) (nbytes >> 16) & 0xff;
465 msg.len[3] = (char) (nbytes >> 24) & 0xff;
466
467 if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
468 return *this;
469 if (Write(buffer, nbytes).LastCount() < nbytes)
470 return *this;
471
472 msg.sig[0] = (char) 0xed;
473 msg.sig[1] = (char) 0xfe;
474 msg.sig[2] = (char) 0xad;
475 msg.sig[3] = (char) 0xde;
476 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
477 Write((char *)&msg, sizeof(msg));
478
479 return *this;
480
481 #ifdef __VISUALC__
482 #pragma warning(default: 4310)
483 #endif // __VISUALC__
484 }
485
486 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
487 {
488 CreatePushbackAfter(buffer, nbytes);
489 return *this;
490 }
491
492 bool wxSocketBase::IsData() const
493 {
494 struct timeval tv;
495 fd_set sock_set;
496
497 if (m_fd < 0)
498 return FALSE;
499 if (m_unrd_size > 0)
500 return TRUE;
501
502 tv.tv_sec = 0;
503 tv.tv_usec = 0;
504 FD_ZERO(&sock_set);
505 FD_SET(m_fd, &sock_set);
506 select(FD_SETSIZE, &sock_set, NULL, NULL, &tv);
507 return (FD_ISSET(m_fd, &sock_set) != 0);
508 }
509
510 // ---------------------------------------------------------------------
511 // --------- wxSocketBase Discard(): deletes all byte in the input queue
512 // ---------------------------------------------------------------------
513 void wxSocketBase::Discard()
514 {
515 #define MAX_BUFSIZE (10*1024)
516 char *my_data = new char[MAX_BUFSIZE];
517 size_t recv_size = MAX_BUFSIZE;
518
519 SaveState();
520 SetFlags((wxSockFlags)(NOWAIT | SPEED));
521
522 while (recv_size == MAX_BUFSIZE)
523 {
524 recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
525 }
526
527 RestoreState();
528 delete [] my_data;
529
530 #undef MAX_BUFSIZE
531 }
532
533 // If what? Who seems to need unsigned int?
534 // BTW uint isn't even defined on wxMSW for VC++ for some reason. Even if it
535 // were, getpeername/getsockname don't take unsigned int*, they take int*.
536 //
537 // Under glibc 2.0.7, socketbits.h declares socklen_t to be unsigned int
538 // and it uses *socklen_t as the 3rd parameter. Robert.
539
540 // JACS - How can we detect this?
541 // Meanwhile, if your compiler complains about socklen_t,
542 // switch lines below.
543
544 #if wxHAVE_GLIBC2
545 # define wxSOCKET_INT socklen_t
546 #else
547 # define wxSOCKET_INT int
548 #endif
549
550 // --------------------------------------------------------------
551 // wxSocketBase socket info functions
552 // --------------------------------------------------------------
553
554 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
555 {
556 struct sockaddr my_addr;
557 wxSOCKET_INT len_addr = sizeof(my_addr);
558
559 if (m_fd < 0)
560 return FALSE;
561
562 if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0)
563 return FALSE;
564
565 addr_man.Disassemble(&my_addr, len_addr);
566 return TRUE;
567 }
568
569 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
570 {
571 struct sockaddr my_addr;
572 wxSOCKET_INT len_addr = sizeof(my_addr);
573
574 if (m_fd < 0)
575 return FALSE;
576
577 if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0)
578
579 return FALSE;
580
581 addr_man.Disassemble(&my_addr, len_addr);
582 return TRUE;
583 }
584
585 // --------------------------------------------------------------
586 // wxSocketBase wait functions
587 // --------------------------------------------------------------
588
589 void wxSocketBase::SaveState()
590 {
591 wxSockState *state = new wxSockState;
592
593 state->cbk_on = m_cbkon;
594 state->cbk_set= m_neededreq;
595 state->cbk = m_cbk;
596 state->cdata = m_cdata;
597 state->flags = m_flags;
598 state->notif = m_notifyme;
599
600 m_states.Append(state);
601 }
602
603 void wxSocketBase::RestoreState()
604 {
605 wxNode *node;
606
607 node = m_states.Last();
608 if (!node)
609 return;
610
611 wxSockState *state = (wxSockState *)node->Data();
612
613 SetFlags(state->flags);
614 m_neededreq = state->cbk_set;
615 m_cbk = state->cbk;
616 m_cdata = state->cdata;
617 m_notifyme = state->notif;
618 if (state->cbk_on)
619 SetupCallbacks();
620 else
621 DestroyCallbacks();
622
623 delete node;
624 delete state;
625 }
626
627 // --------------------------------------------------------------
628 // --------- wxSocketBase wait functions ------------------------
629 // --------------------------------------------------------------
630
631 bool wxSocketBase::_Wait(long seconds, long microseconds, int type)
632 {
633 if ((!m_connected && !m_connecting) || m_fd < 0)
634 return FALSE;
635
636 wxSockWakeUp wakeup(this, &m_waitflags, 0);
637
638 SaveState();
639 SetNotify((wxRequestNotify)type);
640 SetupCallbacks();
641
642 if (seconds != -1)
643 wakeup.Start((int)(seconds*1000 + (microseconds / 1000)), TRUE);
644
645 m_waitflags = 0x80 | type;
646 while (m_waitflags & 0x80)
647 PROCESS_EVENTS();
648
649 RestoreState();
650
651 if (m_waitflags & 0x40)
652 {
653 m_waitflags = 0;
654 return TRUE;
655 }
656 m_waitflags = 0;
657
658 return FALSE;
659 }
660
661 bool wxSocketBase::Wait(long seconds, long microseconds)
662 {
663 return _Wait(seconds, microseconds, REQ_ACCEPT | REQ_CONNECT |
664 REQ_READ | REQ_WRITE | REQ_LOST);
665 }
666
667 bool wxSocketBase::WaitForRead(long seconds, long microseconds)
668 {
669 return _Wait(seconds, microseconds, REQ_READ | REQ_LOST);
670 }
671
672 bool wxSocketBase::WaitForWrite(long seconds, long microseconds)
673 {
674 return _Wait(seconds, microseconds, REQ_WRITE);
675 }
676
677 bool wxSocketBase::WaitForLost(long seconds, long microseconds)
678 {
679 return _Wait(seconds, microseconds, REQ_LOST);
680 }
681
682 // --------------------------------------------------------------
683 // --------- wxSocketBase callback management -------------------
684 // --------------------------------------------------------------
685
686 #ifdef __WXGTK__
687 void wxPrereadSocket(wxSocketBase *sock)
688 {
689 char tmp_buf[1024];
690 int got = 0;
691
692 do {
693 got = recv(sock->m_fd, tmp_buf, 1024, 0);
694 if (got > 0)
695 sock->CreatePushbackAfter(tmp_buf, got);
696 } while (got > 0);
697 }
698 #endif
699
700 #if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
701 #if defined(__WXMOTIF__) || defined(__WXXT__)
702 static void wx_socket_read(XtPointer client, int *fid,
703 XtInputId *WXUNUSED(id))
704 #define fd *fid
705 #else
706 static void wx_socket_read(gpointer client, gint fd,
707 GdkInputCondition WXUNUSED(cond))
708 #define fd fd
709 #endif
710 {
711 wxSocketBase *sock = (wxSocketBase *)client;
712 char c;
713 int i;
714
715 i = recv(fd, &c, 1, MSG_PEEK);
716
717 if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT))
718 {
719 sock->OnRequest(wxSocketBase::EVT_ACCEPT);
720 return;
721 }
722
723 if (i != 0)
724 {
725 if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
726 {
727 #ifdef __WXGTK__
728 // We can't exit from the GDK main loop because it doesn't accept
729 // destroying input event while we are in a event dispatch.
730 // So we will preread socket and we put the data in the pushback.
731 wxPrereadSocket(sock);
732 // Then we set the socket as BLOCKING
733 int flag = 0;
734 ioctl(fd, FIONBIO, &flag);
735 #endif
736 return;
737 }
738
739 sock->OnRequest(wxSocketBase::EVT_READ);
740 }
741 else
742 {
743 if (!(sock->NeededReq() & wxSocketBase::REQ_LOST))
744 {
745 sock->Close();
746 return;
747 }
748
749 sock->OnRequest(wxSocketBase::EVT_LOST);
750 }
751 }
752 #undef fd
753
754 #if defined(__WXMOTIF__) || defined(__WXXT__)
755 static void wx_socket_write(XtPointer client, int *WXUNUSED(fid),
756 XtInputId *WXUNUSED(id))
757 #else
758 static void wx_socket_write(gpointer client, gint WXUNUSED(fd),
759 GdkInputCondition WXUNUSED(cond))
760 #endif
761 {
762 wxSocketBase *sock = (wxSocketBase *)client;
763
764 if (!sock->IsConnected())
765 sock->OnRequest(wxSocketBase::EVT_CONNECT);
766 else
767 sock->OnRequest(wxSocketBase::EVT_WRITE);
768 }
769 #endif
770
771 #ifdef wx_xview
772 Notify_value wx_sock_read_xview (Notify_client client, int fd)
773 {
774 wxSocketBase *sock = (wxSocketBase *)client;
775 char c;
776 int i;
777
778 i = recv(fd, &c, 1, MSG_PEEK);
779
780 if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT))
781 {
782 sock->OnRequest(wxSocketBase::EVT_ACCEPT);
783 return;
784 }
785
786 /* Bytes arrived */
787 if (i != 0)
788 {
789 if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
790 return (Notify_value) FALSE;
791
792 sock->OnRequest(wxSocketBase::EVT_READ);
793 }
794 else
795 {
796 if (!(sock->NeededReq() & wxSocketBase::REQ_LOST))
797 return;
798
799 sock->OnRequest(wxSocketBase::EVT_LOST);
800 }
801
802 return (Notify_value) FALSE;
803 }
804
805 Notify_value wx_sock_write_xview (Notify_client client, int fd)
806 {
807 wxSocketBase *sock = (wxSocketBase *)client;
808
809 if (!sock->IsConnected())
810 sock->OnRequest(wxSocketBase::EVT_CONNECT);
811 else
812 sock->OnRequest(wxSocketBase::EVT_WRITE);
813
814 return (Notify_value) TRUE;
815 }
816 #endif
817
818 wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
819 {
820 switch (evt)
821 {
822 case EVT_READ:
823 return REQ_READ;
824 case EVT_PEEK:
825 return REQ_PEEK;
826 case EVT_WRITE:
827 return REQ_WRITE;
828 case EVT_LOST:
829 return REQ_LOST;
830 case EVT_ACCEPT:
831 return REQ_ACCEPT;
832 case EVT_CONNECT:
833 return REQ_CONNECT;
834 }
835 return 0;
836 }
837
838 void wxSocketBase::SetFlags(wxSockFlags _flags)
839 {
840 m_flags = _flags;
841 if (_flags & SPEED)
842 {
843 unsigned long flag = 0;
844 ioctl(m_fd, FIONBIO, &flag);
845
846 // SPEED and WAITALL are antagonists.
847 m_flags = (wxSockFlags)(m_flags & ~WAITALL);
848
849 Notify(FALSE);
850 }
851 else
852 {
853 unsigned long flag = 1;
854 ioctl(m_fd, FIONBIO, &flag);
855 }
856 }
857
858 void wxSocketBase::SetNotify(wxRequestNotify flags)
859 {
860 wxRequestNotify old_needed_req = m_neededreq;
861 if (flags & REQ_ACCEPT)
862 {
863 /* Check if server */
864 if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer))))
865 flags &= ~REQ_ACCEPT;
866 }
867 m_neededreq = flags;
868
869 /*
870 if (m_cbkon && old_needed_req != flags) seems to be wrong, Robert Roebling
871 SetupCallbacks();
872 */
873
874 if (old_needed_req != flags)
875 SetupCallbacks();
876 }
877
878 void wxSocketBase::SetupCallbacks()
879 {
880 if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED))
881 return;
882
883 #if defined(__WXMOTIF__) || defined(__WXXT__)
884 if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST))
885 {
886 if (m_internal->sock_inputid <= 0)
887 {
888 m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
889 (XtPointer *) XtInputReadMask,
890 (XtInputCallbackProc) wx_socket_read,
891 (XtPointer) this);
892 }
893 }
894 else
895 {
896 if (m_internal->sock_inputid > 0)
897 {
898 XtRemoveInput(m_internal->sock_inputid);
899 m_internal->sock_inputid = 0;
900 }
901 }
902
903 if (m_neededreq & (REQ_CONNECT | REQ_WRITE))
904 {
905 if (m_internal->sock_outputid <= 0)
906 {
907 m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
908 (XtPointer *) XtInputWriteMask,
909 (XtInputCallbackProc) wx_socket_write,
910 (XtPointer) this);
911 }
912 }
913 else
914 {
915 if (m_internal->sock_outputid > 0)
916 {
917 XtRemoveInput(m_internal->sock_outputid);
918 m_internal->sock_outputid = 0;
919 }
920 }
921 #endif
922
923
924 #ifdef __WXGTK__
925 if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST))
926 {
927 if (m_internal->sock_inputid <= 0)
928 {
929 m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ,
930 wx_socket_read, (gpointer)this);
931 }
932 }
933 else
934 {
935 if (m_internal->sock_inputid > 0)
936 {
937 /*
938 gdk_input_remove(m_internal->sock_inputid);
939 m_internal->sock_inputid = 0;
940 */
941 }
942 }
943
944 if (m_neededreq & (REQ_CONNECT | REQ_WRITE))
945 {
946 if (m_internal->sock_outputid <= 0)
947 {
948 m_internal->sock_outputid = gdk_input_add(m_fd, GDK_INPUT_WRITE,
949 wx_socket_write, (gpointer)this);
950 }
951 }
952 else
953 {
954 if (m_internal->sock_outputid > 0)
955 {
956 /*
957 gdk_input_remove(m_internal->sock_outputid);
958 m_internal->sock_outputid = 0;
959 */
960 }
961 }
962 #endif
963
964
965 #ifdef __WXMSW__
966 WORD mask = 0;
967
968 if (m_neededreq & REQ_READ)
969 mask |= FD_READ;
970 if (m_neededreq & REQ_WRITE)
971 mask |= FD_WRITE;
972 if (m_neededreq & REQ_LOST)
973 mask |= FD_CLOSE;
974 if (m_neededreq & REQ_ACCEPT)
975 mask |= FD_ACCEPT;
976 if (m_neededreq & REQ_CONNECT)
977 mask |= FD_CONNECT;
978
979 if (!m_internal->my_msg)
980 m_internal->my_msg = m_handler->NewMessage(this);
981 WSAAsyncSelect(m_fd, m_handler->GetHWND(), m_internal->my_msg, mask);
982 #endif
983 #ifdef __WXMAC__
984 short mask = 0;
985
986 if (m_neededreq & REQ_READ)
987 mask |= FD_READ;
988 if (m_neededreq & REQ_WRITE)
989 mask |= FD_WRITE;
990 if (m_neededreq & REQ_LOST)
991 mask |= FD_CLOSE;
992 if (m_neededreq & REQ_ACCEPT)
993 mask |= FD_ACCEPT;
994 if (m_neededreq & REQ_CONNECT)
995 mask |= FD_CONNECT;
996
997 GUSISetReference( m_fd ,mask, this ) ;
998 unsigned long flag = 1;
999 ioctl(m_fd, FIONBIO, &flag);
1000 #endif
1001 m_cbkon = TRUE;
1002 m_processing = FALSE;
1003 }
1004
1005 void wxSocketBase::DestroyCallbacks()
1006 {
1007 if (!m_cbkon || !m_handler)
1008 return;
1009
1010 m_cbkon = FALSE;
1011 m_processing = FALSE;
1012 #if defined(__WXMOTIF__) || defined(__WXXT__)
1013 if (m_internal->sock_inputid > 0)
1014 XtRemoveInput(m_internal->sock_inputid);
1015 m_internal->sock_inputid = 0;
1016 if (m_internal->sock_outputid > 0)
1017 XtRemoveInput(m_internal->sock_outputid);
1018 m_internal->sock_outputid = 0;
1019 #endif
1020 #ifdef __WXGTK__
1021 if (m_internal->sock_inputid > 0)
1022 gdk_input_remove(m_internal->sock_inputid);
1023 m_internal->sock_inputid = 0;
1024 if (m_internal->sock_outputid > 0)
1025 gdk_input_remove(m_internal->sock_outputid);
1026 m_internal->sock_outputid = 0;
1027 #endif
1028 #ifdef __WINDOWS__
1029 WSAAsyncSelect(m_fd, m_handler->GetHWND(), 0, 0);
1030 #endif
1031 #ifdef __WXMAC__
1032 GUSISetReference( m_fd , 0 , 0 ) ;
1033 int bottom = wxMacNetEventsBottom ;
1034 while ( wxMacNetEventsTop != bottom )
1035 {
1036 // set all events that reference this socket to nil
1037 if ( wxMacNetEventsReferences[bottom] == (void*) this )
1038 wxMacNetEventsReferences[bottom] = NULL ;
1039 bottom++ ;
1040 if ( bottom == kwxMacNetEventsMax )
1041 bottom = 0 ;
1042 }
1043 SetFlags( m_flags ) ;
1044 #endif
1045 }
1046
1047 void wxSocketBase::Notify(bool notify)
1048 {
1049 if (m_notifyme == notify)
1050 return;
1051 if (notify)
1052 SetupCallbacks();
1053 else
1054 DestroyCallbacks();
1055 m_notifyme = notify;
1056 }
1057
1058 void wxSocketBase::OnRequest(wxRequestEvent req_evt)
1059 {
1060 wxRequestNotify req_notif = EventToNotify(req_evt);
1061
1062 // Mask the current event
1063 SetNotify(m_neededreq & ~req_notif);
1064
1065 if (req_evt <= EVT_WRITE && DoRequests(req_evt))
1066 return;
1067
1068 if (m_waitflags & 0xF0)
1069 {
1070 // Wake up
1071 if ((m_waitflags & 0x0F) == req_evt)
1072 {
1073 m_waitflags = 0x80;
1074 #ifndef __WXGTK__
1075 DestroyCallbacks();
1076 #endif
1077 }
1078 return;
1079 }
1080
1081 if (req_evt == EVT_LOST)
1082 {
1083 m_connected = FALSE;
1084 Close();
1085 }
1086 if (m_notifyme)
1087 OldOnNotify(req_evt);
1088
1089 // Unmask
1090 SetNotify(m_neededreq | req_notif);
1091 }
1092
1093 wxSocketEvent::wxSocketEvent(int id)
1094 : wxEvent(id)
1095 {
1096 wxEventType type = (wxEventType)wxEVT_SOCKET;
1097
1098 SetEventType(type);
1099 }
1100
1101 void wxSocketBase::OldOnNotify(wxRequestEvent evt)
1102 {
1103 wxSocketEvent event(m_id);
1104
1105 event.SetEventObject(this);
1106 event.m_skevt = evt;
1107 ProcessEvent(event);
1108
1109 if (m_cbk)
1110 m_cbk(*this, evt, m_cdata);
1111 }
1112
1113 // --------------------------------------------------------------
1114 // --------- wxSocketBase functions [Callback, CallbackData] ----
1115 // --------------------------------------------------------------
1116
1117 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk)
1118 {
1119 wxSockCbk old_cbk = m_cbk;
1120
1121 m_cbk = _cbk;
1122 return old_cbk;
1123 }
1124
1125 char *wxSocketBase::CallbackData(char *cdata_)
1126 {
1127 char *old_cdata = m_cdata;
1128
1129 m_cdata = cdata_;
1130 return old_cdata;
1131 }
1132
1133 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
1134 {
1135 SetNextHandler(&h_evt);
1136 m_id = id;
1137 }
1138
1139 // --------------------------------------------------------------
1140 // --------- wxSocketBase pushback library ----------------------
1141 // --------------------------------------------------------------
1142
1143 void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
1144 {
1145 char *curr_pos;
1146
1147 if (m_unread != NULL)
1148 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
1149 else
1150 m_unread = (char *) malloc(size);
1151 curr_pos = m_unread + m_unrd_size;
1152
1153 memcpy(curr_pos, buffer, size);
1154 m_unrd_size += size;
1155 }
1156
1157 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
1158 {
1159 char *curr_pos, *new_buf;
1160
1161 new_buf = (char *) malloc(m_unrd_size+size);
1162 curr_pos = new_buf + size;
1163
1164 memcpy(new_buf, buffer, size);
1165 if (m_unrd_size != 0) {
1166 memcpy(curr_pos, m_unread, m_unrd_size);
1167 free(m_unread);
1168 }
1169 m_unread = new_buf;
1170 m_unrd_size += size;
1171 }
1172
1173 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
1174 {
1175 if (!m_unrd_size)
1176 return 0;
1177
1178 if (size > m_unrd_size)
1179 size = m_unrd_size;
1180 memcpy(buffer, m_unread, size);
1181
1182 if (!peek) {
1183 m_unrd_size -= size;
1184 if (m_unrd_size == 0) {
1185 free(m_unread);
1186 m_unread = NULL;
1187 }
1188 }
1189
1190 return size;
1191 }
1192
1193 // --------------------------------------------------------------
1194 // --------- wxSocketBase "multi-thread" core -------------------
1195 // --------------------------------------------------------------
1196
1197 bool wxSocketBase::DoRequests(wxRequestEvent req_flag)
1198 {
1199 wxNode *node = req_list[req_flag].First();
1200 size_t len;
1201 int ret;
1202
1203 if (!node)
1204 return FALSE;
1205
1206 SockRequest *req = (SockRequest *)node->Data();
1207
1208 delete node;
1209
1210 switch (req->type)
1211 {
1212 case EVT_READ:
1213 case EVT_PEEK:
1214 ret = recv(m_fd, req->buffer, req->size,
1215 (req->type == EVT_PEEK) ? MSG_PEEK : 0);
1216 if (ret < 0)
1217 {
1218 req->error = errno;
1219 req->done = TRUE;
1220 break;
1221 }
1222 len = ret;
1223 if ((len < req->size) && (m_flags & WAITALL))
1224 {
1225 req->size -= len;
1226 req->nbytes += len;
1227 req->buffer += len;
1228 req->auto_wakeup->Start(m_timeout*1000, TRUE);
1229 req_list[req_flag].Insert(req);
1230 break;
1231 }
1232 req->done = TRUE;
1233 req->nbytes += len;
1234 #ifndef __WXGTK__
1235 DestroyCallbacks();
1236 #endif
1237 break;
1238 case EVT_WRITE:
1239 ret = send(m_fd, req->buffer, req->size, 0);
1240 if (ret < 0)
1241 {
1242 req->error = errno;
1243 req->done = TRUE;
1244 break;
1245 }
1246 len = ret;
1247 if ((len < req->size) && (m_flags & WAITALL))
1248 {
1249 req->size -= len;
1250 req->nbytes += len;
1251 req->buffer += len;
1252 req->auto_wakeup->Start(m_timeout*1000, TRUE);
1253 req_list[req_flag].Insert(req);
1254 break;
1255 }
1256 req->done = TRUE;
1257 req->nbytes += len;
1258 #ifndef __WXGTK__
1259 DestroyCallbacks();
1260 #endif
1261 break;
1262 default:
1263 return FALSE;
1264 }
1265 return TRUE;
1266 }
1267
1268 void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes,
1269 wxRequestEvent evt)
1270 {
1271 int ret = 0;
1272
1273 switch (evt)
1274 {
1275 case EVT_PEEK:
1276 case EVT_READ:
1277 ret = recv(m_fd, buffer, nbytes,
1278 (evt == EVT_PEEK) ? MSG_PEEK : 0);
1279 break;
1280 case EVT_WRITE:
1281 ret = send(m_fd, buffer, nbytes, 0);
1282 break;
1283 }
1284 if (ret < 0)
1285 {
1286 m_lcount = 0;
1287 m_error = errno;
1288 }
1289 else
1290 {
1291 m_lcount = ret;
1292 m_error = 0;
1293 }
1294 }
1295
1296 void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
1297 wxRequestEvent evt)
1298 {
1299 bool buf_timed_out;
1300
1301 if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
1302 return;
1303
1304 if (m_flags & SPEED)
1305 {
1306 WantSpeedBuffer(buffer, nbytes, evt);
1307 return;
1308 }
1309
1310 SockRequest *buf = new SockRequest;
1311 wxSockWakeUp s_wake(NULL, (int *)&buf_timed_out, (int)TRUE);
1312
1313 m_wantbuf++;
1314 req_list[evt].Append(buf);
1315
1316 SaveState();
1317 SetNotify(REQ_LOST | EventToNotify(evt));
1318 SetupCallbacks();
1319 buf->buffer = buffer;
1320 buf->size = nbytes;
1321 buf->done = FALSE;
1322 buf->type = evt;
1323 buf->nbytes = 0;
1324 buf->auto_wakeup = &s_wake;
1325 buf->error = 0;
1326 buf_timed_out = FALSE;
1327
1328 s_wake.Start(m_timeout*1000, TRUE);
1329 if (m_flags & NOWAIT)
1330 {
1331 DoRequests(evt);
1332 }
1333 else
1334 {
1335 while (!buf->done && !buf_timed_out)
1336 PROCESS_EVENTS();
1337 }
1338 m_wantbuf--;
1339 m_lcount = buf->nbytes;
1340 if (buf_timed_out)
1341 m_error = ETIMEDOUT;
1342 else
1343 m_error = buf->error;
1344
1345 delete buf;
1346 RestoreState();
1347 }
1348
1349 // --------------------------------------------------------------
1350 // wxSocketServer
1351 // --------------------------------------------------------------
1352
1353 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1354 wxSockFlags flags) :
1355 wxSocketBase(flags, SOCK_SERVER)
1356 {
1357 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
1358
1359 if (m_fd == INVALID_SOCKET)
1360 return;
1361
1362 int flag = 1;
1363 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
1364
1365 struct sockaddr *myaddr;
1366 size_t len;
1367
1368 addr_man.Build(myaddr, len);
1369 if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0)
1370 return;
1371
1372 if (listen(m_fd, 5) < 0) {
1373 m_fd = INVALID_SOCKET;
1374 return;
1375 }
1376 }
1377
1378 // --------------------------------------------------------------
1379 // wxSocketServer Accept
1380 // --------------------------------------------------------------
1381
1382 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
1383 {
1384 int fd2;
1385
1386 if ((fd2 = accept(m_fd, 0, 0)) < 0)
1387 return FALSE;
1388
1389 struct linger linger;
1390 linger.l_onoff = 0;
1391 linger.l_linger = 1;
1392
1393 setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
1394
1395 int flag = 0;
1396 setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
1397
1398 if (!(sock.m_flags & SPEED))
1399 {
1400 unsigned long flag2 = 1;
1401 ioctl(fd2, FIONBIO, &flag2);
1402 }
1403
1404 sock.m_type = SOCK_INTERNAL;
1405 sock.m_fd = fd2;
1406 sock.m_connected = TRUE;
1407
1408 return TRUE;
1409 }
1410
1411 wxSocketBase *wxSocketServer::Accept()
1412 {
1413 wxSocketBase* sock = new wxSocketBase();
1414
1415 sock->SetFlags((wxSockFlags)m_flags);
1416
1417 if (!AcceptWith(*sock))
1418 return NULL;
1419
1420 if (m_handler)
1421 m_handler->Register(sock);
1422
1423 return sock;
1424 }
1425
1426 // --------------------------------------------------------------
1427 // wxSocketServer callbacks
1428 // --------------------------------------------------------------
1429
1430 void wxSocketServer::OnRequest(wxRequestEvent evt)
1431 {
1432 if (evt == EVT_ACCEPT)
1433 {
1434 OldOnNotify(EVT_ACCEPT);
1435 }
1436 }
1437
1438 // --------------------------------------------------------------
1439 // wxSocketClient
1440 // --------------------------------------------------------------
1441
1442 // --------- wxSocketClient CONSTRUCTOR -------------------------
1443 // --------------------------------------------------------------
1444 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
1445 wxSocketBase(_flags, SOCK_CLIENT)
1446 {
1447 }
1448
1449 // --------------------------------------------------------------
1450 // --------- wxSocketClient DESTRUCTOR --------------------------
1451 // --------------------------------------------------------------
1452 wxSocketClient::~wxSocketClient()
1453 {
1454 }
1455
1456 // --------------------------------------------------------------
1457 // --------- wxSocketClient Connect functions -------------------
1458 // --------------------------------------------------------------
1459 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
1460 {
1461 struct linger linger;
1462
1463 if (IsConnected())
1464 Close();
1465
1466 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
1467
1468 if (m_fd < 0)
1469 return FALSE;
1470
1471 m_connected = FALSE;
1472
1473 linger.l_onoff = 1;
1474 linger.l_linger = 5;
1475 setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
1476
1477 // Stay in touch with the state of things...
1478
1479 unsigned long flag = 1;
1480 setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
1481
1482 // Disable the nagle algorithm, which delays sends till the
1483 // buffer is full (or a certain time period has passed?)...
1484
1485 #if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY))
1486 flag = 1;
1487 setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
1488 #endif
1489
1490 struct sockaddr *remote;
1491 size_t len;
1492
1493 addr_man.Build(remote, len);
1494
1495 if (connect(m_fd, remote, len) != 0)
1496 return FALSE;
1497
1498 if (!(m_flags & SPEED))
1499 {
1500 flag = 1;
1501 ioctl(m_fd, FIONBIO, &flag);
1502 }
1503
1504 Notify(TRUE);
1505
1506 m_connected = TRUE;
1507 return TRUE;
1508 }
1509
1510 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
1511 {
1512 int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST);
1513
1514 if (ret)
1515 m_connected = TRUE;
1516
1517 return m_connected;
1518 }
1519
1520 void wxSocketClient::OnRequest(wxRequestEvent evt)
1521 {
1522 if (evt == EVT_CONNECT)
1523 {
1524 if (m_connected)
1525 {
1526 #ifndef __WXGTK__
1527 SetNotify(m_neededreq & ~REQ_CONNECT);
1528 #endif
1529 return;
1530 }
1531 m_waitflags = 0x40;
1532 m_connected = TRUE;
1533 OldOnNotify(EVT_CONNECT);
1534 #ifndef __WXGTK__
1535 DestroyCallbacks();
1536 #endif
1537 return;
1538 }
1539 wxSocketBase::OnRequest(evt);
1540 }
1541
1542 /////////////////////////////////////////////////////////////////
1543 // wxSocketHandler ///////////////////////////////////////////////
1544 /////////////////////////////////////////////////////////////////
1545
1546 wxSocketHandler *wxSocketHandler::master = NULL;
1547 #if defined(__WINDOWS__)
1548 static int win_initialized = 0;
1549 #endif
1550
1551 // --------------------------------------------------------------
1552 // --------- wxSocketHandler CONSTRUCTOR ------------------------
1553 // --------------------------------------------------------------
1554 #ifdef __WXMAC__
1555
1556 extern "C" int updatestatus(int s) ;
1557
1558 void wxMacSocketOnRequestProc( void *refcon , short event )
1559 {
1560 if ( refcon )
1561 {
1562 wxSocketBase *sock = (wxSocketBase *) refcon ;
1563
1564 wxSocketBase::wxRequestEvent sk_req;
1565
1566 int canRead ;
1567 int canWrite ;
1568 int exception ;
1569
1570 switch (event) {
1571 case FD_READ:
1572 sk_req = wxSocketBase::EVT_READ;
1573 sock->OnRequest(sk_req);
1574 break;
1575 case FD_WRITE:
1576 sk_req = wxSocketBase::EVT_WRITE;
1577 sock->OnRequest(sk_req);
1578 break;
1579 case FD_CLOSE:
1580 sk_req = wxSocketBase::EVT_LOST;
1581 sock->OnRequest(sk_req);
1582 break;
1583 case FD_ACCEPT:
1584 sk_req = wxSocketBase::EVT_ACCEPT;
1585 sock->OnRequest(sk_req);
1586 break;
1587 case FD_CONNECT:
1588 sk_req = wxSocketBase::EVT_CONNECT;
1589 sock->OnRequest(sk_req);
1590 break;
1591 case FD_READY :
1592 break ;
1593 }
1594 updatestatus ( sock->m_fd ) ;
1595 }
1596 }
1597
1598 void wxMacSocketHandlerProc( void *refcon , short event )
1599 {
1600 wxMacNetEventsReferences[wxMacNetEventsTop] = refcon ;
1601 wxMacNetEventsEvents[wxMacNetEventsTop] = event ;
1602
1603 // clumsy construct in order to never have a incorrect wxMacNetEventsTop (above limits)
1604
1605 if ( wxMacNetEventsTop + 1 == kwxMacNetEventsMax )
1606 wxMacNetEventsTop = 0 ;
1607 else
1608 wxMacNetEventsTop++ ;
1609 }
1610
1611 #endif
1612 #ifdef __WINDOWS__
1613
1614 extern char wxPanelClassName[];
1615
1616 LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message,
1617 WPARAM wParam, LPARAM lParam)
1618 {
1619 if(message==WM_DESTROY)
1620 {
1621 ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc);
1622 return DefWindowProc(hWnd, message, wParam, lParam);
1623 }
1624 wxSocketHandler *h_sock = (wxSocketHandler *)GetWindowLong(hWnd, GWL_USERDATA);
1625 wxNode *node = h_sock->smsg_list->Find(message);
1626 wxSocketBase *sock;
1627 wxSocketBase::wxRequestEvent sk_req;
1628 UINT event = WSAGETSELECTEVENT(lParam);
1629
1630 if (!node)
1631 return DefWindowProc(hWnd, message, wParam, lParam);
1632
1633 sock = (wxSocketBase *)node->Data();
1634
1635 switch (event) {
1636 case FD_READ:
1637 sk_req = wxSocketBase::EVT_READ;
1638 break;
1639 case FD_WRITE:
1640 sk_req = wxSocketBase::EVT_WRITE;
1641 break;
1642 case FD_CLOSE:
1643 sk_req = wxSocketBase::EVT_LOST;
1644 break;
1645 case FD_ACCEPT:
1646 sk_req = wxSocketBase::EVT_ACCEPT;
1647 break;
1648 case FD_CONNECT:
1649 sk_req = wxSocketBase::EVT_CONNECT;
1650 break;
1651
1652 default:
1653 wxFAIL_MSG("invalid socket event");
1654 return (LRESULT)0;
1655 }
1656
1657 sock->OnRequest(sk_req);
1658
1659 return (LRESULT)0;
1660 }
1661
1662 FARPROC wxSocketSubClassProc = NULL;
1663
1664 #endif
1665
1666 wxSocketHandler::wxSocketHandler()
1667 {
1668 #if defined(__WINDOWS__)
1669 if (!win_initialized)
1670 {
1671 WSADATA wsaData;
1672
1673 WSAStartup((1 << 8) | 1, &wsaData);
1674 win_initialized = 1;
1675 }
1676 internal = new wxSockHandlerInternal;
1677 internal->sockWin = ::CreateWindow(wxPanelClassName, NULL, 0,
1678 0, 0, 0, 0, NULL, (HMENU) NULL,
1679 wxhInstance, 0);
1680
1681 // Subclass the window
1682 if (!wxSocketSubClassProc)
1683 wxSocketSubClassProc = MakeProcInstance((FARPROC) wxSocketHandlerWndProc, wxhInstance);
1684 ::SetWindowLong(internal->sockWin, GWL_WNDPROC, (LONG) wxSocketSubClassProc);
1685 ::SetWindowLong(internal->sockWin, GWL_USERDATA, (LONG) this);
1686
1687 internal->firstAvailableMsg = 5000;
1688 smsg_list = new wxList(wxKEY_INTEGER);
1689 #endif
1690
1691 socks = new wxList;
1692
1693 #ifndef __WINDOWS__
1694 signal(SIGPIPE, SIG_IGN);
1695 #endif
1696 }
1697
1698 // --------------------------------------------------------------
1699 // --------- wxSocketHandler DESTRUCTOR -------------------------
1700 // --------------------------------------------------------------
1701 wxSocketHandler::~wxSocketHandler()
1702 {
1703 wxNode *next_node, *node = socks->First();
1704
1705 while (node)
1706 {
1707 wxSocketBase* sock = (wxSocketBase*)node->Data();
1708
1709 delete sock;
1710 next_node = node->Next();
1711 delete node;
1712 node = next_node;
1713 }
1714
1715 delete socks;
1716
1717 #ifdef __WINDOWS__
1718 delete smsg_list;
1719
1720 ::DestroyWindow(internal->sockWin);
1721 WSACleanup();
1722 win_initialized = 0;
1723
1724 delete internal;
1725 #endif
1726 }
1727
1728 // --------------------------------------------------------------
1729 // --------- wxSocketHandler registering functions --------------
1730 // --------------------------------------------------------------
1731
1732 void wxSocketHandler::Register(wxSocketBase* sock)
1733 {
1734 wxNode *node;
1735
1736 for (node = socks->First(); node != NULL; node = node->Next())
1737 {
1738 wxSocketBase* s = (wxSocketBase*)node->Data();
1739
1740 if (s == sock)
1741 return;
1742 }
1743
1744 if (sock)
1745 {
1746 socks->Append(sock);
1747 sock->SetHandler(this);
1748 sock->SetupCallbacks();
1749 }
1750 }
1751
1752 void wxSocketHandler::UnRegister(wxSocketBase* sock)
1753 {
1754 wxNode *node;
1755
1756 for (node = socks->First(); node; node = node->Next())
1757 {
1758 wxSocketBase* s = (wxSocketBase*)node->Data();
1759
1760 if (s == sock)
1761 {
1762 delete node;
1763 sock->DestroyCallbacks();
1764 sock->SetHandler(NULL);
1765 return;
1766 }
1767 }
1768 }
1769
1770 unsigned long wxSocketHandler::Count() const
1771 {
1772 return socks->Number();
1773 }
1774
1775 // --------------------------------------------------------------
1776 // --------- wxSocketHandler "big" wait functions ---------------
1777 // --------------------------------------------------------------
1778 void handler_cbk(wxSocketBase& sock,
1779 wxSocketBase::wxRequestEvent WXUNUSED(flags),
1780 char *cdata)
1781 {
1782 int *a_wait = (int *)cdata;
1783
1784 (*a_wait)++;
1785 sock.Notify(FALSE);
1786 }
1787
1788 int wxSocketHandler::Wait(long seconds, long microseconds)
1789 {
1790 int i;
1791 int on_wait;
1792 wxSockWakeUp s_wake(NULL, &on_wait, -2);
1793 wxNode *node;
1794
1795 for (node = socks->First(), i=0; node; node = node->Next(), i++)
1796 {
1797 wxSocketBase *sock = (wxSocketBase *)node->Data();
1798
1799 sock->SaveState();
1800
1801 sock->SetupCallbacks();
1802
1803 sock->Callback(handler_cbk);
1804 sock->CallbackData((char *)&on_wait);
1805 }
1806 on_wait = 0;
1807 if (seconds != -1)
1808 s_wake.Start((seconds*1000) + (microseconds/1000), TRUE);
1809
1810 while (!on_wait)
1811 PROCESS_EVENTS();
1812
1813 for (node = socks->First(), i=0; node; node = node->Next(), i++)
1814 {
1815 wxSocketBase *sock = (wxSocketBase *)node->Data();
1816
1817 sock->RestoreState();
1818 }
1819
1820 if (on_wait == -2)
1821 return 0;
1822
1823 return on_wait;
1824 }
1825
1826 void wxSocketHandler::YieldSock()
1827 {
1828 wxNode *node;
1829
1830 for (node = socks->First(); node; node = node->Next() )
1831 {
1832 wxSocketBase *sock = (wxSocketBase *)node->Data();
1833
1834 sock->SaveState();
1835
1836 sock->SetFlags(wxSocketBase::SPEED);
1837 if (sock->IsData())
1838 sock->DoRequests(wxSocketBase::EVT_READ);
1839 sock->DoRequests(wxSocketBase::EVT_WRITE);
1840
1841 sock->RestoreState();
1842 }
1843 }
1844
1845 // --------------------------------------------------------------
1846 // --------- wxSocketHandler: create and register the socket ----
1847 // --------------------------------------------------------------
1848 wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
1849 wxSocketBase::wxSockFlags flags)
1850 {
1851 wxSocketServer *serv = new wxSocketServer(addr, flags);
1852
1853 Register(serv);
1854 return serv;
1855 }
1856
1857 wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
1858 {
1859 wxSocketClient *client = new wxSocketClient(flags);
1860
1861 Register(client);
1862 return client;
1863 }
1864
1865 #ifdef __WINDOWS__
1866 // --------------------------------------------------------------
1867 // --------- wxSocketHandler: Windows specific methods ----------
1868 // --------------------------------------------------------------
1869
1870 UINT wxSocketHandler::NewMessage(wxSocketBase *sock)
1871 {
1872 internal->firstAvailableMsg++;
1873 smsg_list->Append(internal->firstAvailableMsg, sock);
1874 return internal->firstAvailableMsg;
1875 }
1876
1877 void wxSocketHandler::DestroyMessage(UINT msg)
1878 {
1879 wxNode *node = smsg_list->Find(msg);
1880 delete node;
1881 }
1882
1883 HWND wxSocketHandler::GetHWND() const
1884 {
1885 return internal->sockWin;
1886 }
1887
1888 #endif
1889
1890 bool wxSocketModule::OnInit()
1891 {
1892 wxSocketHandler::master = new wxSocketHandler();
1893 return TRUE;
1894 }
1895
1896 void wxSocketModule::OnExit()
1897 {
1898 delete wxSocketHandler::master;
1899 wxSocketHandler::master = NULL;
1900 }
1901
1902 #ifdef __WXMAC__
1903 void wxMacProcessSocketEvents() ;
1904 void wxMacProcessEvents()
1905 {
1906 wxMacProcessSocketEvents() ;
1907 (*GUSISpin)(SP_MISC, 0) ;
1908 }
1909
1910 void wxMacProcessSocketEvents()
1911 {
1912 while ( wxMacNetEventsTop != wxMacNetEventsBottom )
1913 {
1914 // consume event at wxMacNetEventsBottom
1915 wxMacSocketOnRequestProc(wxMacNetEventsReferences[wxMacNetEventsBottom] , wxMacNetEventsEvents[wxMacNetEventsBottom] ) ;
1916 wxMacNetEventsBottom++ ;
1917 if ( wxMacNetEventsBottom == kwxMacNetEventsMax )
1918 wxMacNetEventsBottom = 0 ;
1919 }
1920 }
1921 #endif
1922
1923 #endif
1924 // __WXSTUBS__