]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/sockmsw.cpp
Avoid redraw artifacts from the border after resizing
[wxWidgets.git] / src / msw / sockmsw.cpp
index 75b56980d46a3ad7957e795f037f2e9f9c5fc024..1edcf8d67dfa887dbeea406beecc52f3a65f3b62 100644 (file)
 #endif
 
 #include "wx/private/socket.h"
+#include "wx/msw/private.h"     // for wxGetInstance()
 #include "wx/apptrait.h"
 #include "wx/thread.h"
-
-extern "C" WXDLLIMPEXP_BASE HINSTANCE wxGetInstance();
-#define INSTANCE wxGetInstance()
-
-#include <winsock.h>
-
-#if defined(__CYGWIN__)
-    //CYGWIN gives annoying warning about runtime stuff if we don't do this
-#   define USE_SYS_TYPES_FD_SET
-#   include <sys/types.h>
-#endif
+#include "wx/dynlib.h"
 
 #ifdef __WXWINCE__
 /*
@@ -83,7 +74,7 @@ wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
 #endif
 
 #ifndef __WXWINCE__
-typedef int (PASCAL *WSAAsyncSelectFunc)(SOCKET,HWND,u_int,long);
+typedef int (PASCAL *WSAAsyncSelect_t)(SOCKET,HWND,u_int,long);
 #else
 /* Typedef the needed function prototypes and the WSANETWORKEVENTS structure
 */
@@ -91,10 +82,10 @@ typedef struct _WSANETWORKEVENTS {
        long lNetworkEvents;
        int iErrorCode[10];
 } WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
-typedef HANDLE (PASCAL *WSACreateEventFunc)();
-typedef int (PASCAL *WSAEventSelectFunc)(SOCKET,HANDLE,long);
-typedef int (PASCAL *WSAWaitForMultipleEventsFunc)(long,HANDLE,BOOL,long,BOOL);
-typedef int (PASCAL *WSAEnumNetworkEventsFunc)(SOCKET,HANDLE,LPWSANETWORKEVENTS);
+typedef HANDLE (PASCAL *WSACreateEvent_t)();
+typedef int (PASCAL *WSAEventSelect_t)(SOCKET,HANDLE,long);
+typedef int (PASCAL *WSAWaitForMultipleEvents_t)(long,HANDLE,BOOL,long,BOOL);
+typedef int (PASCAL *WSAEnumNetworkEvents_t)(SOCKET,HANDLE,LPWSANETWORKEVENTS);
 #endif //__WXWINCE__
 
 LRESULT CALLBACK wxSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM);
@@ -107,15 +98,15 @@ static wxSocketImplMSW *socketList[MAXSOCKETS];
 static int firstAvailable;
 
 #ifndef __WXWINCE__
-static WSAAsyncSelectFunc gs_WSAAsyncSelect = NULL;
+static WSAAsyncSelect_t gs_WSAAsyncSelect = NULL;
 #else
 static SocketHash socketHash;
 static unsigned int currSocket;
 HANDLE hThread[MAXSOCKETS];
-static WSACreateEventFunc gs_WSACreateEvent = NULL;
-static WSAEventSelectFunc gs_WSAEventSelect = NULL;
-static WSAWaitForMultipleEventsFunc gs_WSAWaitForMultipleEvents = NULL;
-static WSAEnumNetworkEventsFunc gs_WSAEnumNetworkEvents = NULL;
+static WSACreateEvent_t gs_WSACreateEvent = NULL;
+static WSAEventSelect_t gs_WSAEventSelect = NULL;
+static WSAWaitForMultipleEvents_t gs_WSAWaitForMultipleEvents = NULL;
+static WSAEnumNetworkEvents_t gs_WSAEnumNetworkEvents = NULL;
 /* This structure will be used to pass data on to the thread that handles socket events.
 */
 typedef struct thread_data{
@@ -126,13 +117,11 @@ typedef struct thread_data{
 }thread_data;
 #endif
 
-static HMODULE gs_wsock32dll = 0;
-
-
 #ifdef __WXWINCE__
-/* This thread handles socket events on WinCE using WSAEventSelect() as WSAAsyncSelect is not supported.
-*  When an event occures for the socket, it is checked what kind of event happend and the correct message gets posted
-*  so that the hidden window can handle it as it would in other MSW builds.
+/* This thread handles socket events on WinCE using WSAEventSelect() as
+ * WSAAsyncSelect is not supported. When an event occurs for the socket, it is
+ * checked what kind of event happend and the correct message gets posted so
+ * that the hidden window can handle it as it would in other MSW builds.
 */
 DWORD WINAPI SocketThread(LPVOID data)
 {
@@ -192,8 +181,13 @@ public:
     }
     virtual void Install_Callback(wxSocketImpl *socket, wxSocketNotify event);
     virtual void Uninstall_Callback(wxSocketImpl *socket, wxSocketNotify event);
+
+private:
+    static wxDynamicLibrary gs_wsock32dll;
 };
 
+wxDynamicLibrary wxSocketMSWManager::gs_wsock32dll;
+
 bool wxSocketMSWManager::OnInit()
 {
   static LPCTSTR pclassname = NULL;
@@ -211,45 +205,42 @@ bool wxSocketMSWManager::OnInit()
   }
   firstAvailable = 0;
 
-  /* Load WSAAsyncSelect from wsock32.dll (we don't link against it
-     statically to avoid dependency on wsock32.dll for apps that don't use
-     sockets): */
+  // we don't link with wsock32.dll (or ws2 in CE case) statically to avoid
+  // dependencies on it for all the application using wx even if they don't use
+  // sockets
+#ifdef __WXWINCE__
+    #define WINSOCK_DLL_NAME _T("ws2.dll")
+#else
+    #define WINSOCK_DLL_NAME _T("wsock32.dll")
+#endif
+
+    gs_wsock32dll.Load(WINSOCK_DLL_NAME, wxDL_VERBATIM | wxDL_QUIET);
+    if ( !gs_wsock32dll.IsLoaded() )
+        return false;
+
 #ifndef __WXWINCE__
-  gs_wsock32dll = LoadLibrary(wxT("wsock32.dll"));
-  if (!gs_wsock32dll)
-      return false;
-  gs_WSAAsyncSelect =(WSAAsyncSelectFunc)GetProcAddress(gs_wsock32dll,
-                                                        "WSAAsyncSelect");
-  if (!gs_WSAAsyncSelect)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAAsyncSelect, gs_wsock32dll);
+    if ( !gs_WSAAsyncSelect )
+        return false;
 #else
-/*  On WinCE we load ws2.dll which will provide the needed functions.
-*/
-  gs_wsock32dll = LoadLibrary(wxT("ws2.dll"));
-  if (!gs_wsock32dll)
-      return false;
-  gs_WSAEventSelect =(WSAEventSelectFunc)GetProcAddress(gs_wsock32dll,
-                                                        wxT("WSAEventSelect"));
-  if (!gs_WSAEventSelect)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAEventSelect, gs_wsock32dll);
+    if ( !gs_WSAEventSelect )
+        return false;
 
-  gs_WSACreateEvent =(WSACreateEventFunc)GetProcAddress(gs_wsock32dll,
-                                                        wxT("WSACreateEvent"));
-  if (!gs_WSACreateEvent)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSACreateEvent, gs_wsock32dll);
+    if ( !gs_WSACreateEvent )
+        return false;
 
-  gs_WSAWaitForMultipleEvents =(WSAWaitForMultipleEventsFunc)GetProcAddress(gs_wsock32dll,
-                                                                            wxT("WSAWaitForMultipleEvents"));
-  if (!gs_WSAWaitForMultipleEvents)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAWaitForMultipleEvents, gs_wsock32dll);
+    if ( !gs_WSAWaitForMultipleEvents )
+        return false;
 
-  gs_WSAEnumNetworkEvents =(WSAEnumNetworkEventsFunc)GetProcAddress(gs_wsock32dll,
-                                                                    wxT("WSAEnumNetworkEvents"));
-  if (!gs_WSAEnumNetworkEvents)
-      return false;
+    wxDL_INIT_FUNC(gs_, WSAEnumNetworkEvents, gs_wsock32dll);
+    if ( !gs_WSAEnumNetworkEvents )
+        return false;
 
-  currSocket = 0;
-#endif
+    currSocket = 0;
+#endif // !__WXWINCE__/__WXWINCE__
 
   // finally initialize WinSock
   WSADATA wsaData;
@@ -265,16 +256,11 @@ void wxSocketMSWManager::OnExit()
 #endif
   /* Destroy internal window */
   DestroyWindow(hWin);
-  UnregisterClass(CLASSNAME, INSTANCE);
-
-  /* Unlock wsock32.dll */
-  if (gs_wsock32dll)
-  {
-      FreeLibrary(gs_wsock32dll);
-      gs_wsock32dll = 0;
-  }
+  UnregisterClass(CLASSNAME, wxGetInstance());
 
   WSACleanup();
+
+  gs_wsock32dll.Unload();
 }
 
 /* Per-socket GUI initialization / cleanup */
@@ -502,10 +488,9 @@ wxSocketImpl *wxSocketImplMSW::WaitConnection(wxSocketBase& wxsocket)
   }
 
   /* Wait for a connection (with timeout) */
-  if (Input_Timeout() == wxSOCKET_TIMEDOUT)
+  if ( !BlockForInputWithTimeout() )
   {
     delete connection;
-    /* m_error set by Input_Timeout */
     return NULL;
   }
 
@@ -615,9 +600,8 @@ int wxSocketImplMSW::Read(void *buffer, int size)
   }
 
   /* If the socket is blocking, wait for data (with a timeout) */
-  if (Input_Timeout() == wxSOCKET_TIMEDOUT)
+  if ( !BlockForInputWithTimeout() )
   {
-    m_error = wxSOCKET_TIMEDOUT;
     return -1;
   }
 
@@ -650,7 +634,7 @@ int wxSocketImplMSW::Write(const void *buffer, int size)
   }
 
   /* If the socket is blocking, wait for writability (with a timeout) */
-  if (Output_Timeout() == wxSOCKET_TIMEDOUT)
+  if ( BlockForOutputWithTimeout() )
     return -1;
 
   /* Write the data */
@@ -680,48 +664,6 @@ int wxSocketImplMSW::Write(const void *buffer, int size)
 
 /* Internals (IO) */
 
-/*
- *  For blocking sockets, wait until data is available or
- *  until timeout ellapses.
- */
-wxSocketError wxSocketImplMSW::Input_Timeout()
-{
-  fd_set readfds;
-
-  if (!m_non_blocking)
-  {
-    FD_ZERO(&readfds);
-    FD_SET(m_fd, &readfds);
-    if (select(0, &readfds, NULL, NULL, &m_timeout) == 0)
-    {
-      m_error = wxSOCKET_TIMEDOUT;
-      return wxSOCKET_TIMEDOUT;
-    }
-  }
-  return wxSOCKET_NOERROR;
-}
-
-/*
- *  For blocking sockets, wait until data can be sent without
- *  blocking or until timeout ellapses.
- */
-wxSocketError wxSocketImplMSW::Output_Timeout()
-{
-  fd_set writefds;
-
-  if (!m_non_blocking)
-  {
-    FD_ZERO(&writefds);
-    FD_SET(m_fd, &writefds);
-    if (select(0, NULL, &writefds, NULL, &m_timeout) == 0)
-    {
-      m_error = wxSOCKET_TIMEDOUT;
-      return wxSOCKET_TIMEDOUT;
-    }
-  }
-  return wxSOCKET_NOERROR;
-}
-
 /*
  *  For blocking sockets, wait until the connection is
  *  established or fails, or until timeout ellapses.