X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a3cf8dca335f4a364a84c6144d4747c2429575a4..34b4899df5053a53482f18d8c97a2b1913019d30:/src/msw/gsockmsw.cpp diff --git a/src/msw/gsockmsw.cpp b/src/msw/gsockmsw.cpp index 489feff570..4215428a26 100644 --- a/src/msw/gsockmsw.cpp +++ b/src/msw/gsockmsw.cpp @@ -1,13 +1,15 @@ -/* ------------------------------------------------------------------------- - * Project: GSocket (Generic Socket) - * Name: src/msw/gsockmsw.cpp - * Copyright: (c) Guilhem Lavaux - * Licence: wxWindows Licence - * Author: Guillermo Rodriguez Garcia - * Purpose: GSocket GUI-specific MSW code - * CVSID: $Id$ - * ------------------------------------------------------------------------- - */ +///////////////////////////////////////////////////////////////////////////// +// Name: src/msw/gsockmsw.cpp +// Purpose: MSW-specific socket support +// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia +// Created: April 1997 +// Copyright: (C) 1999-1997, Guilhem Lavaux +// (C) 1999-2000, Guillermo Rodriguez Garcia +// (C) 2008 Vadim Zeitlin +// RCS_ID: $Id$ +// License: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -36,7 +38,7 @@ # pragma warning(disable:4115) /* named type definition in parentheses */ #endif -#include "wx/gsocket.h" +#include "wx/private/socket.h" #include "wx/apptrait.h" #include "wx/link.h" @@ -64,13 +66,13 @@ WX_DECLARE_HASH_MAP(int,bool,wxIntegerHash,wxIntegerEqual,SocketHash); # pragma warning(default:4115) /* named type definition in parentheses */ #endif -#define CLASSNAME TEXT("_GSocket_Internal_Window_Class") +#define CLASSNAME TEXT("_wxSocket_Internal_Window_Class") /* implemented in utils.cpp */ extern "C" WXDLLIMPEXP_BASE HWND wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc); -/* Maximum number of different GSocket objects at a given time. +/* Maximum number of different wxSocket objects at a given time. * This value can be modified at will, but it CANNOT be greater * than (0x7FFF - WM_USER + 1) */ @@ -95,13 +97,13 @@ typedef int (PASCAL *WSAWaitForMultipleEventsFunc)(long,HANDLE,BOOL,long,BOOL); typedef int (PASCAL *WSAEnumNetworkEventsFunc)(SOCKET,HANDLE,LPWSANETWORKEVENTS); #endif //__WXWINCE__ -LRESULT CALLBACK _GSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK wxSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM); /* Global variables */ static HWND hWin; static CRITICAL_SECTION critical; -static GSocket* socketList[MAXSOCKETS]; +static wxSocketImplMSW *socketList[MAXSOCKETS]; static int firstAvailable; #ifndef __WXWINCE__ @@ -175,34 +177,32 @@ DWORD WINAPI SocketThread(LPVOID data) #endif // ---------------------------------------------------------------------------- -// MSW implementation of GSocketManager +// MSW implementation of wxSocketManager // ---------------------------------------------------------------------------- -class GSocketMSWManager : public GSocketManager +class wxSocketMSWManager : public wxSocketManager { public: virtual bool OnInit(); virtual void OnExit(); - virtual bool Init_Socket(GSocket *socket); - virtual void Destroy_Socket(GSocket *socket); - - virtual void Install_Callback(GSocket *socket, GSocketEvent event); - virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event); - - virtual void Enable_Events(GSocket *socket); - virtual void Disable_Events(GSocket *socket); + virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket) + { + return new wxSocketImplMSW(wxsocket); + } + virtual void Install_Callback(wxSocketImpl *socket, wxSocketNotify event); + virtual void Uninstall_Callback(wxSocketImpl *socket, wxSocketNotify event); }; /* Global initializers */ -bool GSocketMSWManager::OnInit() +bool wxSocketMSWManager::OnInit() { static LPCTSTR pclassname = NULL; int i; /* Create internal window for event notifications */ - hWin = wxCreateHiddenWindow(&pclassname, CLASSNAME, _GSocket_Internal_WinProc); + hWin = wxCreateHiddenWindow(&pclassname, CLASSNAME, wxSocket_Internal_WinProc); if (!hWin) return false; @@ -255,10 +255,12 @@ bool GSocketMSWManager::OnInit() currSocket = 0; #endif - return true; + // finally initialize WinSock + WSADATA wsaData; + return WSAStartup((1 << 8) | 1, &wsaData) == 0; } -void GSocketMSWManager::OnExit() +void wxSocketMSWManager::OnExit() { #ifdef __WXWINCE__ /* Delete the threads here */ @@ -278,18 +280,19 @@ void GSocketMSWManager::OnExit() /* Delete critical section */ DeleteCriticalSection(&critical); + + WSACleanup(); } /* Per-socket GUI initialization / cleanup */ -bool GSocketMSWManager::Init_Socket(GSocket *socket) +wxSocketImplMSW::wxSocketImplMSW(wxSocketBase& wxsocket) + : wxSocketImpl(wxsocket) { - int i; - /* Allocate a new message number for this socket */ EnterCriticalSection(&critical); - i = firstAvailable; + int i = firstAvailable; while (socketList[i] != NULL) { i = (i + 1) % MAXSOCKETS; @@ -297,115 +300,89 @@ bool GSocketMSWManager::Init_Socket(GSocket *socket) if (i == firstAvailable) /* abort! */ { LeaveCriticalSection(&critical); - return false; + m_msgnumber = 0; // invalid + return; } } - socketList[i] = socket; + socketList[i] = this; firstAvailable = (i + 1) % MAXSOCKETS; - socket->m_msgnumber = (i + WM_USER); + m_msgnumber = (i + WM_USER); LeaveCriticalSection(&critical); - - return true; } -void GSocketMSWManager::Destroy_Socket(GSocket *socket) +wxSocketImplMSW::~wxSocketImplMSW() { /* Remove the socket from the list */ EnterCriticalSection(&critical); - if ( socket->IsOk() ) - { - const int msgnum = socket->m_msgnumber; + if ( m_msgnumber ) + { // we need to remove any pending messages for this socket to avoid having // them sent to a new socket which could reuse the same message number as // soon as we destroy this one MSG msg; - while ( ::PeekMessage(&msg, hWin, msgnum, msgnum, PM_REMOVE) ) + while ( ::PeekMessage(&msg, hWin, m_msgnumber, m_msgnumber, PM_REMOVE) ) ; - socketList[msgnum - WM_USER] = NULL; + socketList[m_msgnumber - WM_USER] = NULL; } + //else: the socket has never been created successfully LeaveCriticalSection(&critical); } -void GSocketMSWManager::Install_Callback(GSocket * WXUNUSED(socket), - GSocketEvent WXUNUSED(event)) -{ - wxFAIL_MSG( _T("not used under MSW") ); -} - -void GSocketMSWManager::Uninstall_Callback(GSocket * WXUNUSED(socket), - GSocketEvent WXUNUSED(event)) -{ - wxFAIL_MSG( _T("not used under MSW") ); -} - /* Windows proc for asynchronous event handling */ -LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, +LRESULT CALLBACK wxSocket_Internal_WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - GSocket *socket; - GSocketEvent event; - GSocketCallback cback; - char *data; + wxSocketImplMSW *socket; + wxSocketNotify event; if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1)) { EnterCriticalSection(&critical); socket = socketList[(uMsg - WM_USER)]; - event = (GSocketEvent) -1; - cback = NULL; - data = NULL; + event = (wxSocketNotify) -1; /* Check that the socket still exists (it has not been * destroyed) and for safety, check that the m_fd field * is what we expect it to be. */ - if ((socket != NULL) && (socket->m_fd == wParam)) + if ((socket != NULL) && ((WPARAM)socket->m_fd == wParam)) { switch WSAGETSELECTEVENT(lParam) { - case FD_READ: event = GSOCK_INPUT; break; - case FD_WRITE: event = GSOCK_OUTPUT; break; - case FD_ACCEPT: event = GSOCK_CONNECTION; break; + case FD_READ: event = wxSOCKET_INPUT; break; + case FD_WRITE: event = wxSOCKET_OUTPUT; break; + case FD_ACCEPT: event = wxSOCKET_CONNECTION; break; case FD_CONNECT: { if (WSAGETSELECTERROR(lParam) != 0) - event = GSOCK_LOST; + event = wxSOCKET_LOST; else - event = GSOCK_CONNECTION; + event = wxSOCKET_CONNECTION; break; } - case FD_CLOSE: event = GSOCK_LOST; break; + case FD_CLOSE: event = wxSOCKET_LOST; break; } if (event != -1) { - cback = socket->m_cbacks[event]; - data = socket->m_data[event]; - - if (event == GSOCK_LOST) - socket->m_detected = GSOCK_LOST_FLAG; + if (event == wxSOCKET_LOST) + socket->m_detected = wxSOCKET_LOST_FLAG; else socket->m_detected |= (1 << event); } } - /* OK, we can now leave the critical section because we have - * already obtained the callback address (we make no further - * accesses to socket->whatever). However, the app should - * be prepared to handle events from a socket that has just - * been closed! - */ LeaveCriticalSection(&critical); - if (cback != NULL) - (cback)(socket, event, data); + if ( socket ) + socket->NotifyOnStateChange(event); return (LRESULT) 0; } @@ -413,13 +390,16 @@ LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, return DefWindowProc(hWnd, uMsg, wParam, lParam); } -/* _GSocket_Enable_Events: +/* * Enable all event notifications; we need to be notified of all * events for internal processing, but we will only notify users - * when an appropiate callback function has been installed. + * when an appropriate callback function has been installed. */ -void GSocketMSWManager::Enable_Events(GSocket *socket) +void wxSocketMSWManager::Install_Callback(wxSocketImpl *socket_, + wxSocketNotify WXUNUSED(event)) { + wxSocketImplMSW * const socket = static_cast(socket_); + if (socket->m_fd != INVALID_SOCKET) { /* We could probably just subscribe to all events regardless @@ -446,11 +426,14 @@ void GSocketMSWManager::Enable_Events(GSocket *socket) } } -/* _GSocket_Disable_Events: - * Disable event notifications (when shutdowning the socket) +/* + * Disable event notifications (used when shutting down the socket) */ -void GSocketMSWManager::Disable_Events(GSocket *socket) +void wxSocketMSWManager::Uninstall_Callback(wxSocketImpl *socket_, + wxSocketNotify WXUNUSED(event)) { + wxSocketImplMSW * const socket = static_cast(socket_); + if (socket->m_fd != INVALID_SOCKET) { #ifndef __WXWINCE__ @@ -462,15 +445,15 @@ void GSocketMSWManager::Disable_Events(GSocket *socket) } } -// set the wxBase variable to point to our GSocketManager implementation +// set the wxBase variable to point to our wxSocketManager implementation // -// see comments in wx/msw/apptbase.h for the explanation of why do we do it +// see comments in wx/apptrait.h for the explanation of why do we do it // like this static struct ManagerSetter { ManagerSetter() { - static GSocketMSWManager s_manager; + static wxSocketMSWManager s_manager; wxAppTraits::SetDefaultSocketManager(&s_manager); } } gs_managerSetter;