diff --git a/docs/changes.txt b/docs/changes.txt index f4e42fb2d1..3867505ef1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -201,6 +201,7 @@ wxMSW: - Add support for building with Microsoft Visual Studio 2017 (Tobias Taschner). - Allow loading icons from resources in wxIconBundle (PB). - Enable wxStackWalker in MinGW64 builds. +- Fix build under Cygwin in 64 bits. - Fix crash when using wxCHMHelpController() in 64 bit builds (Xlord2). - Fix wxSpinCtrl appearance: show arrows inside the control (Catalin Raceanu). - Fix MDI menu display after failure to create a child frame (troelsk). diff --git a/include/wx/msw/private/sockmsw.h b/include/wx/msw/private/sockmsw.h index bbcad77bca..91dbbede2a 100644 --- a/include/wx/msw/private/sockmsw.h +++ b/include/wx/msw/private/sockmsw.h @@ -23,6 +23,15 @@ #if defined(__CYGWIN__) #include + #ifdef __LP64__ + // We can't use long in this case because it is 64 bits with Cygwin, so + // use their special type used for working around this instead. + #define wxIoctlSocketArg_t __ms_u_long + #endif +#endif + +#ifndef wxIoctlSocketArg_t + #define wxIoctlSocketArg_t u_long #endif // ---------------------------------------------------------------------------- @@ -61,7 +70,7 @@ private: // just useless) as they would be dispatched by the main thread // while this blocking socket can be used from a worker one, so it // would result in data races and other unpleasantness. - unsigned long trueArg = 1; + wxIoctlSocketArg_t trueArg = 1; ioctlsocket(m_fd, FIONBIO, &trueArg); } else diff --git a/include/wx/private/socket.h b/include/wx/private/socket.h index 906c20c659..56a3cef528 100644 --- a/include/wx/private/socket.h +++ b/include/wx/private/socket.h @@ -62,6 +62,15 @@ #include // for timeval #endif +// 64 bit Cygwin can't use the standard struct timeval because it has long +// fields, which are supposed to be 32 bits in Win64 API, but long is 64 bits +// in 64 bit Cygwin, so we need to use its special __ms_timeval instead. +#if defined(__CYGWIN__) && defined(__LP64__) + typedef __ms_timeval wxTimeVal_t; +#else + typedef timeval wxTimeVal_t; +#endif + // these definitions are for MSW when we don't use configure, otherwise these // symbols are defined by configure #ifndef WX_SOCKLEN_T @@ -254,7 +263,7 @@ public: // flags defines what kind of conditions we're interested in, the return // value is composed of a (possibly empty) subset of the bits set in flags wxSocketEventFlags Select(wxSocketEventFlags flags, - const timeval *timeout = NULL); + wxTimeVal_t *timeout = NULL); // convenient wrapper calling Select() with our default timeout wxSocketEventFlags SelectWithTimeout(wxSocketEventFlags flags) @@ -299,7 +308,7 @@ public: bool m_broadcast; bool m_dobind; - struct timeval m_timeout; + wxTimeVal_t m_timeout; protected: wxSocketImpl(wxSocketBase& wxsocket); diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 5fb8c291ae..207b3c9751 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -135,7 +135,7 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent); namespace { -void SetTimeValFromMS(timeval& tv, unsigned long ms) +void SetTimeValFromMS(wxTimeVal_t& tv, unsigned long ms) { tv.tv_sec = (ms / 1000); tv.tv_usec = (ms % 1000) * 1000; @@ -1304,12 +1304,12 @@ wxSocketBase& wxSocketBase::Discard() and it will return a mask indicating which operations can be performed. */ wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags, - const timeval *timeout) + wxTimeVal_t *timeout) { if ( m_fd == INVALID_SOCKET ) return (wxSOCKET_LOST_FLAG & flags); - struct timeval tv; + wxTimeVal_t tv; if ( timeout ) tv = *timeout; else @@ -1502,7 +1502,7 @@ wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags) else // no event loop or waiting in another thread { // as explained below, we should always check for wxSOCKET_LOST_FLAG - timeval tv; + wxTimeVal_t tv; SetTimeValFromMS(tv, timeLeft); events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv); } diff --git a/src/msw/ole/access.cpp b/src/msw/ole/access.cpp index 6dd3a7baa5..6620f74e6e 100644 --- a/src/msw/ole/access.cpp +++ b/src/msw/ole/access.cpp @@ -47,7 +47,7 @@ int wxConvertToWindowsRole(wxAccRole wxrole); // Convert to Windows state -long wxConvertToWindowsState(long wxstate); +LONG wxConvertToWindowsState(long wxstate); // Convert to Windows selection flag int wxConvertToWindowsSelFlag(wxAccSelectionFlags sel); @@ -191,17 +191,17 @@ public: // Retrieves the child element or child object at a given point on the screen. // All visual objects support this method; sound objects do not support it. - STDMETHODIMP accHitTest(long xLeft, long yLeft, VARIANT* pVarID); + STDMETHODIMP accHitTest(LONG xLeft, LONG yLeft, VARIANT* pVarID); // Retrieves the specified object's current screen location. All visual objects must // support this method; sound objects do not support it. - STDMETHODIMP accLocation ( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varID); + STDMETHODIMP accLocation ( LONG* pxLeft, LONG* pyTop, LONG* pcxWidth, LONG* pcyHeight, VARIANT varID); // Traverses to another user interface element within a container and retrieves the object. // All visual objects must support this method. - STDMETHODIMP accNavigate ( long navDir, VARIANT varStart, VARIANT* pVarEnd); + STDMETHODIMP accNavigate ( LONG navDir, VARIANT varStart, VARIANT* pVarEnd); // Retrieves the address of an IDispatch interface for the specified child. // All objects must support this property. @@ -211,7 +211,7 @@ public: // Retrieves the number of children that belong to this object. // All objects must support this property. - STDMETHODIMP get_accChildCount ( long* pCountChildren); + STDMETHODIMP get_accChildCount ( LONG* pCountChildren); // Retrieves the IDispatch interface of the object's parent. // All objects support this property. @@ -244,7 +244,7 @@ public: // object and the identifier of the appropriate topic within that file. // Not all objects support this property. - STDMETHODIMP get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, long* pidTopic); + STDMETHODIMP get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, LONG* pidTopic); // Retrieves the specified object's shortcut key or access key, also known as // the mnemonic. All objects that have a shortcut key or access key support @@ -278,7 +278,7 @@ public: // specified object. All objects that select or receive the // keyboard focus must support this method. - STDMETHODIMP accSelect ( long flagsSelect, VARIANT varID ); + STDMETHODIMP accSelect ( LONG flagsSelect, VARIANT varID ); // Retrieves the object that has the keyboard focus. All objects // that receive the keyboard focus must support this property. @@ -368,7 +368,7 @@ void wxIAccessible::Quiesce() // Retrieves the child element or child object at a given point on the screen. // All visual objects support this method; sound objects do not support it. -STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID) +STDMETHODIMP wxIAccessible::accHitTest(LONG xLeft, LONG yLeft, VARIANT* pVarID) { wxLogTrace(wxT("access"), wxT("accHitTest")); wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) ); @@ -441,7 +441,7 @@ STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID) // Retrieves the specified object's current screen location. All visual objects must // support this method; sound objects do not support it. -STDMETHODIMP wxIAccessible::accLocation ( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varID) +STDMETHODIMP wxIAccessible::accLocation ( LONG* pxLeft, LONG* pyTop, LONG* pcxWidth, LONG* pcyHeight, VARIANT varID) { wxLogTrace(wxT("access"), wxT("accLocation")); wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) ); @@ -492,7 +492,7 @@ STDMETHODIMP wxIAccessible::accLocation ( long* pxLeft, long* pyTop, long* pcxWi // Traverses to another user interface element within a container and retrieves the object. // All visual objects must support this method. -STDMETHODIMP wxIAccessible::accNavigate ( long navDir, VARIANT varStart, VARIANT* pVarEnd) +STDMETHODIMP wxIAccessible::accNavigate ( LONG navDir, VARIANT varStart, VARIANT* pVarEnd) { wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) ); if (!m_pAccessible) @@ -727,7 +727,7 @@ STDMETHODIMP wxIAccessible::get_accChild ( VARIANT varChildID, IDispatch** ppDis // Retrieves the number of children that belong to this object. // All objects must support this property. -STDMETHODIMP wxIAccessible::get_accChildCount ( long* pCountChildren) +STDMETHODIMP wxIAccessible::get_accChildCount ( LONG* pCountChildren) { wxLogTrace(wxT("access"), wxT("get_accChildCount")); wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) ); @@ -757,7 +757,7 @@ STDMETHODIMP wxIAccessible::get_accChildCount ( long* pCountChildren) } else { - * pCountChildren = (long) childCount; + * pCountChildren = (LONG) childCount; return S_OK; } @@ -1071,7 +1071,7 @@ STDMETHODIMP wxIAccessible::get_accHelp ( VARIANT varID, BSTR* pszHelp) // NOTE: not supported by wxWidgets at this time. Use // GetHelpText instead. -STDMETHODIMP wxIAccessible::get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, long* pidTopic) +STDMETHODIMP wxIAccessible::get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, LONG* pidTopic) { wxLogTrace(wxT("access"), wxT("get_accHelpTopic")); wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) ); @@ -1346,7 +1346,7 @@ STDMETHODIMP wxIAccessible::get_accState ( VARIANT varID, VARIANT* pVarState) } else { - long state = wxConvertToWindowsState(wxstate); + LONG state = wxConvertToWindowsState(wxstate); pVarState->lVal = state; pVarState->vt = VT_I4; return S_OK; @@ -1422,7 +1422,7 @@ STDMETHODIMP wxIAccessible::get_accValue ( VARIANT varID, BSTR* pszValue) // specified object. All objects that select or receive the // keyboard focus must support this method. -STDMETHODIMP wxIAccessible::accSelect ( long flagsSelect, VARIANT varID ) +STDMETHODIMP wxIAccessible::accSelect ( LONG flagsSelect, VARIANT varID ) { wxLogTrace(wxT("access"), wxT("get_accSelect")); wxASSERT( ( m_pAccessible != NULL ) || ( m_bQuiescing == true ) ); @@ -1693,13 +1693,13 @@ IAccessible* wxIAccessible::GetChildStdAccessible(int id) #if 0 { // Loop until we find the right id - long nChildren = 0; + LONG nChildren = 0; this->get_accChildCount(& nChildren); int i; for (i = 0; i < nChildren; i++) { - long obtained = 0; + LONG obtained = 0; VARIANT var; VariantInit(& var); var.vt = VT_I4; @@ -1983,9 +1983,9 @@ int wxConvertToWindowsRole(wxAccRole wxrole) } // Convert to Windows state -long wxConvertToWindowsState(long wxstate) +LONG wxConvertToWindowsState(long wxstate) { - long state = 0; + LONG state = 0; if (wxstate & wxACC_STATE_SYSTEM_ALERT_HIGH) state |= STATE_SYSTEM_ALERT_HIGH; diff --git a/src/msw/sockmsw.cpp b/src/msw/sockmsw.cpp index 791f18a49b..2a66c8eda4 100644 --- a/src/msw/sockmsw.cpp +++ b/src/msw/sockmsw.cpp @@ -217,7 +217,7 @@ LRESULT CALLBACK wxSocket_Internal_WinProc(HWND hWnd, // only then). Ignore such dummy notifications. { fd_set fds; - timeval tv = { 0, 0 }; + wxTimeVal_t tv = { 0, 0 }; wxFD_ZERO(&fds); wxFD_SET(socket->m_fd, &fds); diff --git a/src/msw/volume.cpp b/src/msw/volume.cpp index a2932bf3d4..32e62b4980 100644 --- a/src/msw/volume.cpp +++ b/src/msw/volume.cpp @@ -68,7 +68,18 @@ static WNetCloseEnumPtr s_pWNetCloseEnum; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Globals/Statics //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static long s_cancelSearch = FALSE; + +#if defined(__CYGWIN__) && defined(__LP64__) + // We can't use long in 64 bit Cygwin build because Cygwin uses LP64 model + // (unlike all the other MSW compilers) and long is 64 bits, while + // InterlockedExchange(), with which this variable is used, requires a 32 + // bit-sized value, so use Cygwin-specific type with the right size. + typedef __LONG32 wxInterlockedArg_t; +#else + typedef long wxInterlockedArg_t; +#endif + +static wxInterlockedArg_t s_cancelSearch = FALSE; struct FileInfo { diff --git a/tests/test.cpp b/tests/test.cpp index e8628ac591..7dbb44fb53 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -46,6 +46,7 @@ std::string wxTheCurrentTestClass, wxTheCurrentTestMethod; #include "wx/wx.h" #endif +#include "wx/apptrait.h" #include "wx/cmdline.h" #include #include @@ -171,8 +172,10 @@ CATCH_TRANSLATE_EXCEPTION(TestAssertFailure& e) #if wxUSE_GUI typedef wxApp TestAppBase; + typedef wxGUIAppTraits TestAppTraitsBase; #else typedef wxAppConsole TestAppBase; + typedef wxConsoleAppTraits TestAppTraitsBase; #endif // The application class @@ -186,6 +189,46 @@ public: virtual bool OnInit(); virtual int OnExit(); +#ifdef __WIN32__ + virtual wxAppTraits *CreateTraits() + { + // Define a new class just to customize CanUseStderr() behaviour. + class TestAppTraits : public TestAppTraitsBase + { + public: + // We want to always use stderr, tests are also run unattended and + // in this case we really don't want to show any message boxes, as + // wxMessageOutputBest, used e.g. from the default implementation + // of wxApp::OnUnhandledException(), would do by default. + virtual bool CanUseStderr() { return true; } + + // Overriding CanUseStderr() is not enough, we also need to + // override this one to avoid returning false from it. + virtual bool WriteToStderr(const wxString& text) + { + wxFputs(text, stderr); + fflush(stderr); + + // Intentionally ignore any errors, we really don't want to + // show any message boxes in any case. + return true; + } + }; + + return new TestAppTraits; + } +#endif // __WIN32__ + + // Also override this method to avoid showing any dialogs from here -- and + // show some details about the exception along the way. + virtual bool OnExceptionInMainLoop() + { + wxFprintf(stderr, "Unhandled exception in the main loop: %s\n", + Catch::translateActiveException()); + + throw; + } + // used by events propagation test virtual int FilterEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event);