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