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