]> git.saurik.com Git - wxWidgets.git/commitdiff
Added gsockmsw which now contains all GUI-specific code for the MSW version
authorGuillermo Rodriguez Garcia <guille@iies.es>
Tue, 14 Mar 2000 04:43:58 +0000 (04:43 +0000)
committerGuillermo Rodriguez Garcia <guille@iies.es>
Tue, 14 Mar 2000 04:43:58 +0000 (04:43 +0000)
of gsocket - a step towards wxBase

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6671 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/gsockmsw.h
src/msw/gsocket.c
src/msw/gsockmsw.c [new file with mode: 0644]

index e7aa1147cd8aea9c753ff8a828ef2083494d7825..16fec0812df11dc1af3aab53cd54374613fa335f 100644 (file)
@@ -62,7 +62,6 @@ struct _GAddress
   GSocketError m_error;
 };
 
-
 /* Input / output */
 
 GSocketError _GSocket_Input_Timeout(GSocket *socket);
@@ -75,9 +74,13 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
 
 /* Callbacks */
 
+bool _GSocket_GUI_Init(GSocket *socket);
+void _GSocket_GUI_Destroy(GSocket *socket);
+
+LRESULT CALLBACK _GSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM);
+
 void _GSocket_Enable_Events(GSocket *socket);
 void _GSocket_Disable_Events(GSocket *socket);
-LRESULT CALLBACK _GSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM);
 
 /* GAddress */
 
index b43d45bc6a20ad357ae8b81e9542647c83de6d80..00e5d32ace9988c498406b5ade1dac52c3c91a4b 100644 (file)
 #include "wx/msw/gsockmsw.h"
 #include "wx/gsocket.h"
 
-#define INSTANCE wxGetInstance()
-
 #else
 
 #include "gsockmsw.h"
 #include "gsocket.h"
 
-/* If not using wxWindows, a global var called hInst must
- * be available and it must containt the app's instance
- * handle.
- */
-#define INSTANCE hInst
-
 #endif /* __GSOCKET_STANDALONE__ */
 
 #include <assert.h>
     #pragma warning(disable:4127) /* conditional expression is constant */
 #endif /* Visual C++ */
 
-#define CLASSNAME  "_GSocket_Internal_Window_Class"
-#define WINDOWNAME "_GSocket_Internal_Window_Name"
-
-/* Maximum number of different GSocket objects at a given time.
- * This value can be modified at will, but it CANNOT be greater
- * than (0x7FFF - WM_USER + 1)
- */
-#define MAXSOCKETS 1024
-
-#if (MAXSOCKETS > (0x7FFF - WM_USER + 1))
-#error "MAXSOCKETS is too big!"
-#endif
-
-
-/* Global variables */
-
-extern HINSTANCE INSTANCE;
-static HWND hWin;
-static CRITICAL_SECTION critical;
-static GSocket* socketList[MAXSOCKETS];
-static int firstAvailable;
-
-/* Global initializers */
-
-bool GSocket_Init()
-{
-  WSADATA wsaData;
-  WNDCLASS winClass;
-  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;
-
-  /* Initialize socket list */
-  InitializeCriticalSection(&critical);
-
-  for (i = 0; i < MAXSOCKETS; i++)
-  {
-    socketList[i] = NULL;
-  }
-  firstAvailable = 0;
-
-  /* Initialize WinSocket */
-  return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
-}
-
-void GSocket_Cleanup()
-{
-  /* Destroy internal window */
-  DestroyWindow(hWin);
-  UnregisterClass(CLASSNAME, INSTANCE);
-
-  /* Delete critical section */
-  DeleteCriticalSection(&critical);
-
-  /* Cleanup WinSocket */
-  WSACleanup();
-}
 
 /* Constructors / Destructors for GSocket */
 
@@ -156,26 +73,12 @@ GSocket *GSocket_new()
   socket->m_timeout.tv_usec = 0;
   socket->m_detected        = 0;
 
-  /* Allocate a new message number for this socket */
-  EnterCriticalSection(&critical);
-
-  i = firstAvailable;
-  while (socketList[i] != NULL)
+  /* Per-socket GUI-specific initialization */
+  if (!_GSocket_GUI_Init(socket))
   {
-    i = (i + 1) % MAXSOCKETS;
-
-    if (i == firstAvailable)    /* abort! */
-    {
-      free(socket);
-      LeaveCriticalSection(&critical);
-      return NULL;
-    }
+    free(socket);
+    return NULL;
   }
-  socketList[i] = socket;
-  firstAvailable = (i + 1) % MAXSOCKETS;
-  socket->m_msgnumber = (i + WM_USER);
-
-  LeaveCriticalSection(&critical);
 
   return socket;
 }
@@ -184,10 +87,8 @@ void GSocket_destroy(GSocket *socket)
 {
   assert(socket != NULL);
 
-  /* Remove the socket from the list */
-  EnterCriticalSection(&critical);
-  socketList[(socket->m_msgnumber - WM_USER)] = NULL;
-  LeaveCriticalSection(&critical);
+  /* Per-socket GUI-specific cleanup */
+  _GSocket_GUI_Destroy(socket);
 
   /* Check that the socket is really shutdowned */
   if (socket->m_fd != INVALID_SOCKET)
@@ -683,7 +584,6 @@ GSocketError GSocket_SetNonOriented(GSocket *sck)
   return GSOCK_NOERROR;
 }
 
-
 /* Generic IO */
 
 /* Like recv(), send(), ... */
@@ -816,7 +716,6 @@ GSocketError GSocket_GetError(GSocket *socket)
   return socket->m_error;
 }
 
-
 /* Callbacks */
 
 /* GSOCK_INPUT:
@@ -884,108 +783,7 @@ void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
   }
 }
 
-
-/* Internals */
-
-/* _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.
- */
-void _GSocket_Enable_Events(GSocket *socket)
-{
-  assert (socket != NULL);
-
-  if (socket->m_fd != INVALID_SOCKET)
-  {
-    WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber,
-                   FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
-  }
-}
-
-/* _GSocket_Disable_Events:
- *  Disable event notifications (when shutdowning the socket)
- */
-void _GSocket_Disable_Events(GSocket *socket)
-{
-  assert (socket != NULL);
-
-  if (socket->m_fd != INVALID_SOCKET)
-  {
-    WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
-  }
-}
-
-
-LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd,
-                                           UINT uMsg,
-                                           WPARAM wParam,
-                                           LPARAM lParam)
-{
-  GSocket *socket;
-  GSocketEvent event;
-  GSocketCallback cback;
-  char *data;
-
-  if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1))
-  {
-    EnterCriticalSection(&critical);
-    socket = socketList[(uMsg - WM_USER)];
-    event = -1;
-    cback = NULL;
-    data = NULL;
-
-    /* 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))
-    {
-      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_CONNECT:
-        {
-          if (WSAGETSELECTERROR(lParam) != 0)
-            event = GSOCK_LOST;
-          else
-            event = GSOCK_CONNECTION;
-          break;
-        }
-        case FD_CLOSE:   event = GSOCK_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;
-        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);
-
-    return (LRESULT) 0;
-  }
-  else
-    return DefWindowProc(hWnd, uMsg, wParam, lParam);
-}
-
+/* Internals (IO) */
 
 /* _GSocket_Input_Timeout:
  *  For blocking sockets, wait until data is available or
diff --git a/src/msw/gsockmsw.c b/src/msw/gsockmsw.c
new file mode 100644 (file)
index 0000000..4d1eaf4
--- /dev/null
@@ -0,0 +1,269 @@
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket)
+ * Name:    gsockmsw.c
+ * Author:  Guillermo Rodriguez Garcia <guille@iies.es>
+ * Purpose: GSocket GUI-specific MSW code
+ * CVSID:   $Id$
+ * -------------------------------------------------------------------------
+ */
+
+/*
+ * PLEASE don't put C++ comments here - this is a C source file.
+ */
+
+#ifndef __GSOCKET_STANDALONE__
+#include "wx/setup.h"
+#endif
+
+#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
+
+#ifndef __GSOCKET_STANDALONE__
+
+#include "wx/msw/gsockmsw.h"
+#include "wx/gsocket.h"
+
+#define INSTANCE wxGetInstance()
+
+#else
+
+#include "gsockmsw.h"
+#include "gsocket.h"
+
+/* If not using wxWindows, a global var called hInst must
+ * be available and it must containt the app's instance
+ * handle.
+ */
+#define INSTANCE hInst
+
+#endif /* __GSOCKET_STANDALONE__ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <winsock.h>
+
+#define CLASSNAME  "_GSocket_Internal_Window_Class"
+#define WINDOWNAME "_GSocket_Internal_Window_Name"
+
+/* Maximum number of different GSocket objects at a given time.
+ * This value can be modified at will, but it CANNOT be greater
+ * than (0x7FFF - WM_USER + 1)
+ */
+#define MAXSOCKETS 1024
+
+#if (MAXSOCKETS > (0x7FFF - WM_USER + 1))
+#error "MAXSOCKETS is too big!"
+#endif
+
+
+/* Global variables */
+
+extern HINSTANCE INSTANCE;
+static HWND hWin;
+static CRITICAL_SECTION critical;
+static GSocket* socketList[MAXSOCKETS];
+static int firstAvailable;
+
+/* Global initializers */
+
+bool GSocket_Init()
+{
+  WSADATA wsaData;
+  WNDCLASS winClass;
+  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;
+
+  /* Initialize socket list */
+  InitializeCriticalSection(&critical);
+
+  for (i = 0; i < MAXSOCKETS; i++)
+  {
+    socketList[i] = NULL;
+  }
+  firstAvailable = 0;
+
+  /* Initialize WinSocket */
+  return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
+}
+
+void GSocket_Cleanup()
+{
+  /* Destroy internal window */
+  DestroyWindow(hWin);
+  UnregisterClass(CLASSNAME, INSTANCE);
+
+  /* Delete critical section */
+  DeleteCriticalSection(&critical);
+
+  /* Cleanup WinSocket */
+  WSACleanup();
+}
+
+/* Per-socket GUI initialization / cleanup */
+
+bool _GSocket_GUI_Init(GSocket *socket)
+{
+  int i;
+
+  /* Allocate a new message number for this socket */
+  EnterCriticalSection(&critical);
+
+  i = firstAvailable;
+  while (socketList[i] != NULL)
+  {
+    i = (i + 1) % MAXSOCKETS;
+
+    if (i == firstAvailable)    /* abort! */
+    {
+      LeaveCriticalSection(&critical);
+      return FALSE;
+    }
+  }
+  socketList[i] = socket;
+  firstAvailable = (i + 1) % MAXSOCKETS;
+  socket->m_msgnumber = (i + WM_USER);
+
+  LeaveCriticalSection(&critical);
+
+  return TRUE;
+}
+
+void _GSocket_GUI_Destroy(GSocket *socket)
+{
+  /* Remove the socket from the list */
+  EnterCriticalSection(&critical);
+  socketList[(socket->m_msgnumber - WM_USER)] = NULL;
+  LeaveCriticalSection(&critical);
+}
+
+/* Windows proc for asynchronous event handling */
+
+LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd,
+                                           UINT uMsg,
+                                           WPARAM wParam,
+                                           LPARAM lParam)
+{
+  GSocket *socket;
+  GSocketEvent event;
+  GSocketCallback cback;
+  char *data;
+
+  if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1))
+  {
+    EnterCriticalSection(&critical);
+    socket = socketList[(uMsg - WM_USER)];
+    event = -1;
+    cback = NULL;
+    data = NULL;
+
+    /* 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))
+    {
+      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_CONNECT:
+        {
+          if (WSAGETSELECTERROR(lParam) != 0)
+            event = GSOCK_LOST;
+          else
+            event = GSOCK_CONNECTION;
+          break;
+        }
+        case FD_CLOSE:   event = GSOCK_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;
+        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);
+
+    return (LRESULT) 0;
+  }
+  else
+    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.
+ */
+void _GSocket_Enable_Events(GSocket *socket)
+{
+  assert (socket != NULL);
+
+  if (socket->m_fd != INVALID_SOCKET)
+  {
+    WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber,
+                   FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
+  }
+}
+
+/* _GSocket_Disable_Events:
+ *  Disable event notifications (when shutdowning the socket)
+ */
+void _GSocket_Disable_Events(GSocket *socket)
+{
+  assert (socket != NULL);
+
+  if (socket->m_fd != INVALID_SOCKET)
+  {
+    WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
+  }
+}
+
+#else /* !wxUSE_SOCKETS */
+
+/* 
+ * Translation unit shouldn't be empty, so include this typedef to make the
+ * compiler (VC++ 6.0, for example) happy
+ */
+typedef (*wxDummy)();
+
+#endif  /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */