X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/70988afbb1280a637b78a63b6a8697da3565b4ba..76d81b4d11617b806d6ab9bd60614c39999cdece:/src/msw/gsockmsw.c diff --git a/src/msw/gsockmsw.c b/src/msw/gsockmsw.c index 4d1eaf4111..4ff547fe94 100644 --- a/src/msw/gsockmsw.c +++ b/src/msw/gsockmsw.c @@ -7,12 +7,50 @@ * ------------------------------------------------------------------------- */ +/* + * TODO: for WinCE we need to replace WSAAsyncSelect + * (Windows message-based notification of network events for a socket) + * with another mechanism. + * We may need to have a separate thread that polls for socket events + * using select() and sends a message to the main thread. + */ + /* * PLEASE don't put C++ comments here - this is a C source file. */ +/* including rasasync.h (included from windows.h itself included from + * wx/setup.h and/or winsock.h results in this warning for + * RPCNOTIFICATION_ROUTINE + */ +#ifdef _MSC_VER +# pragma warning(disable:4115) /* named type definition in parentheses */ +#endif + +/* This needs to be before the wx/defs/h inclusion + * for some reason + */ + +#ifdef __WXWINCE__ + /* windows.h results in tons of warnings at max warning level */ +# ifdef _MSC_VER +# pragma warning(push, 1) + /* + "unreferenced inline function has been removed": this is not + suppressed by push above as it is given at the end of the + compilation unit + */ +# pragma warning(disable:4514) +# endif +# include +# ifdef _MSC_VER +# pragma warning(pop) +# endif +#endif + #ifndef __GSOCKET_STANDALONE__ -#include "wx/setup.h" +# include "wx/platform.h" +# include "wx/setup.h" #endif #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) @@ -22,6 +60,7 @@ #include "wx/msw/gsockmsw.h" #include "wx/gsocket.h" +HINSTANCE wxGetInstance(void); #define INSTANCE wxGetInstance() #else @@ -30,23 +69,38 @@ #include "gsocket.h" /* If not using wxWindows, a global var called hInst must - * be available and it must containt the app's instance + * be available and it must contain the app's instance * handle. */ #define INSTANCE hInst #endif /* __GSOCKET_STANDALONE__ */ +#ifndef __WXWINCE__ #include +#else +#define assert(x) +#include +#include "wx/msw/wince/net.h" +#endif + #include #include #include #include #include + #include -#define CLASSNAME "_GSocket_Internal_Window_Class" -#define WINDOWNAME "_GSocket_Internal_Window_Name" +#ifdef _MSC_VER +# pragma warning(default:4115) /* named type definition in parentheses */ +#endif + +#define CLASSNAME TEXT("_GSocket_Internal_Window_Class") + +/* 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 @@ -58,6 +112,7 @@ #error "MAXSOCKETS is too big!" #endif +typedef int (PASCAL *WSAAsyncSelectFunc)(SOCKET,HWND,u_int,long); /* Global variables */ @@ -66,34 +121,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 */ -bool GSocket_Init() +int _GSocket_GUI_Init(void) { - WSADATA wsaData; - 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); @@ -104,26 +145,40 @@ bool GSocket_Init() } firstAvailable = 0; - /* Initialize WinSocket */ - return (WSAStartup((1 << 8) | 1, &wsaData) == 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): */ + 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_Cleanup() +void _GSocket_GUI_Cleanup(void) { /* Destroy internal window */ DestroyWindow(hWin); UnregisterClass(CLASSNAME, INSTANCE); + /* Unlock wsock32.dll */ + if (gs_wsock32dll) + { + FreeLibrary(gs_wsock32dll); + gs_wsock32dll = 0; + } + /* Delete critical section */ DeleteCriticalSection(&critical); - - /* Cleanup WinSocket */ - WSACleanup(); } /* Per-socket GUI initialization / cleanup */ -bool _GSocket_GUI_Init(GSocket *socket) +int _GSocket_GUI_Init_Socket(GSocket *socket) { int i; @@ -150,7 +205,7 @@ bool _GSocket_GUI_Init(GSocket *socket) return TRUE; } -void _GSocket_GUI_Destroy(GSocket *socket) +void _GSocket_GUI_Destroy_Socket(GSocket *socket) { /* Remove the socket from the list */ EnterCriticalSection(&critical); @@ -174,7 +229,7 @@ LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, { EnterCriticalSection(&critical); socket = socketList[(uMsg - WM_USER)]; - event = -1; + event = (GSocketEvent) -1; cback = NULL; data = NULL; @@ -240,8 +295,13 @@ void _GSocket_Enable_Events(GSocket *socket) if (socket->m_fd != INVALID_SOCKET) { - WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, - FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE); + /* We could probably just subscribe to all events regardless + * of the socket type, but MS recommends to do it this way. + */ + long lEvent = socket->m_server? + FD_ACCEPT : (FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE); + + gs_WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, lEvent); } } @@ -254,16 +314,16 @@ 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); } } #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)(); +typedef void (*wxDummy)(); #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */