]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/gsockmsw.c
workaround for blocking behaviour under carbon when running in classic
[wxWidgets.git] / src / msw / gsockmsw.c
index 7bc845bed020ced2ace1c191aa6a0db6faf47808..246ae71c82b3f0066a621dc1156e160734f0ce8d 100644 (file)
@@ -36,8 +36,8 @@
 #endif
 
 #ifndef __GSOCKET_STANDALONE__
-#include "wx/defs.h"
-#include "wx/setup.h"
+#   include "wx/platform.h"
+#   include "wx/setup.h"
 #endif
 
 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
@@ -84,7 +84,10 @@ HINSTANCE wxGetInstance(void);
 #endif
 
 #define CLASSNAME  TEXT("_GSocket_Internal_Window_Class")
-#define WINDOWNAME TEXT("_GSocket_Internal_Window_Name")
+
+/* implemented in utils.cpp */
+extern WXDLLIMPEXP_BASE HWND
+wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
 
 /* Maximum number of different GSocket objects at a given time.
  * This value can be modified at will, but it CANNOT be greater
@@ -96,6 +99,7 @@ HINSTANCE wxGetInstance(void);
 #error "MAXSOCKETS is too big!"
 #endif
 
+typedef int (PASCAL *WSAAsyncSelectFunc)(SOCKET,HWND,u_int,long);
 
 /* Global variables */
 
@@ -104,33 +108,20 @@ static HWND hWin;
 static CRITICAL_SECTION critical;
 static GSocket* socketList[MAXSOCKETS];
 static int firstAvailable;
+static WSAAsyncSelectFunc gs_WSAAsyncSelect = NULL;
+static HMODULE gs_wsock32dll = 0;
 
 /* Global initializers */
 
 int _GSocket_GUI_Init(void)
 {
-  WNDCLASS winClass;
+  static LPCTSTR pclassname = NULL;
   int i;
 
   /* Create internal window for event notifications */
-  winClass.style         = 0;
-  winClass.lpfnWndProc   = _GSocket_Internal_WinProc;
-  winClass.cbClsExtra    = 0;
-  winClass.cbWndExtra    = 0;
-  winClass.hInstance     = INSTANCE;
-  winClass.hIcon         = (HICON) NULL;
-  winClass.hCursor       = (HCURSOR) NULL;
-  winClass.hbrBackground = (HBRUSH) NULL;
-  winClass.lpszMenuName  = (LPCTSTR) NULL;
-  winClass.lpszClassName = CLASSNAME;
-
-  RegisterClass(&winClass);
-  hWin = CreateWindow(CLASSNAME,
-                      WINDOWNAME,
-                      0, 0, 0, 0, 0,
-                      (HWND) NULL, (HMENU) NULL, INSTANCE, (LPVOID) NULL);
-
-  if (!hWin) return FALSE;
+  hWin = wxCreateHiddenWindow(&pclassname, CLASSNAME, _GSocket_Internal_WinProc);
+  if (!hWin)
+      return FALSE;
 
   /* Initialize socket list */
   InitializeCriticalSection(&critical);
@@ -141,7 +132,18 @@ int _GSocket_GUI_Init(void)
   }
   firstAvailable = 0;
 
-  return 1;
+  /* 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): */
+  gs_wsock32dll = LoadLibraryA("wsock32.dll");
+  if (!gs_wsock32dll)
+      return FALSE;
+  gs_WSAAsyncSelect =(WSAAsyncSelectFunc)GetProcAddress(gs_wsock32dll,
+                                                        "WSAAsyncSelect");
+  if (!gs_WSAAsyncSelect)
+      return FALSE;
+
+  return TRUE;
 }
 
 void _GSocket_GUI_Cleanup(void)
@@ -150,6 +152,13 @@ void _GSocket_GUI_Cleanup(void)
   DestroyWindow(hWin);
   UnregisterClass(CLASSNAME, INSTANCE);
 
+  /* Unlock wsock32.dll */
+  if (gs_wsock32dll)
+  {
+      FreeLibrary(gs_wsock32dll);
+      gs_wsock32dll = 0;
+  }
+
   /* Delete critical section */
   DeleteCriticalSection(&critical);
 }
@@ -279,7 +288,7 @@ void _GSocket_Enable_Events(GSocket *socket)
     long lEvent = socket->m_server?
                   FD_ACCEPT : (FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);
 
-    WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, lEvent);
+    gs_WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, lEvent);
   }
 }
 
@@ -292,7 +301,7 @@ void _GSocket_Disable_Events(GSocket *socket)
 
   if (socket->m_fd != INVALID_SOCKET)
   {
-    WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
+    gs_WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
   }
 }