From a5ae0685a05db49d34d11b6abc26e67c794b49b8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 12 Jan 2018 02:38:00 +0100 Subject: [PATCH 1/6] Fix wxFSVolume compilation with Cygwin in 64 bits Use __LONG32, which is always 32 bits when using Cygwin, unlike long, which is 64 bits there in 64 bit builds, and so can't be used as an argument to InterlockedExchange(). Closes #16746. --- src/msw/volume.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 { From 1261139bcbbcfd9048682cc3116e529582d1f72c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 12 Jan 2018 17:13:35 +0100 Subject: [PATCH 2/6] Fix wxSocket code compilation with Cygwin in 64 bits Use __ms_u_long instead of just u_long with Cygwin to avoid mismatch between (64 bit) Cygwin long and (still 32 bit, even in 64 bit build) Windows API long. --- include/wx/msw/private/sockmsw.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 From ebb06fbeafa0d50581823e3a372a1232b0bc736d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 13 Jan 2018 13:43:28 +0100 Subject: [PATCH 3/6] Use wxTimeVal_t instead of timeval to fix 64 bit Cygwin problems Due to the same problem with sizeof(long) mismatch as in the previous commit, we can't use struct timeval, with its long fields, in 64 bit Cygwin builds, and need to use __ms_timeval instead. Add wxTimeVal_t type to hide this difference and update all code compiled under MSW (there is no need to uglify Unix-only code using timeval, as in wxSelectDispatcher, for example) to use it instead of timeval. --- include/wx/private/socket.h | 13 +++++++++++-- src/common/socket.cpp | 8 ++++---- src/msw/sockmsw.cpp | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) 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/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); From d55d5b1dd76c5d787f6a382cdc2a068afbca11b7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 13 Jan 2018 14:26:00 +0100 Subject: [PATCH 4/6] Use LONG for OLE IAccessible methods parameters This is another fix for 64 bit Cygwin build: LONG is defined as a 32 bit type in it, but not long, which is 64 bits, so use the former instead of the latter. --- src/msw/ole/access.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) 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; From 277937b0c42955707d0136187d357ea3a985ff19 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 13 Jan 2018 15:56:46 +0100 Subject: [PATCH 5/6] Always use stderr for wxMessageOutputBest in the tests Avoid showing message boxes even if we don't have the associated console as this prevents the test from completing on its own if an unknown exception happens. --- tests/test.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/test.cpp b/tests/test.cpp index e8628ac591..09ab1e8f4b 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,36 @@ 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__ + // used by events propagation test virtual int FilterEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event); From 9df5541c537778289028aaa8b006939eaeec2ed4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 13 Jan 2018 18:08:07 +0100 Subject: [PATCH 6/6] Don't show dialogs from OnExceptionInMainLoop() in the tests Similarly to the previous commit, ensure that the tests can run unattended under MSW even if an unhandled exception is thrown during their execution. --- tests/test.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test.cpp b/tests/test.cpp index 09ab1e8f4b..7dbb44fb53 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -219,6 +219,16 @@ public: } #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);