Merge branch 'master' into webview-chromium
Merge the changes required by wxWebViewChromium, notably support for the entry hooks and new wxDynamicLibrary::ListLoaded() Unix implementation.
|
|
@ -565,6 +565,7 @@ check_symbol_exists(dlopen dlfcn.h HAVE_DLOPEN)
|
|||
cmake_pop_check_state()
|
||||
if(HAVE_DLOPEN)
|
||||
check_symbol_exists(dladdr dlfcn.h HAVE_DLADDR)
|
||||
check_symbol_exists(dl_iterate_phdr link.h HAVE_DL_ITERATE_PHDR)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
|
|
|
|||
12
configure
vendored
|
|
@ -35494,6 +35494,18 @@ fi
|
|||
|
||||
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
for ac_func in dl_iterate_phdr
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr"
|
||||
if test "x$ac_cv_func_dl_iterate_phdr" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DL_ITERATE_PHDR 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -4843,7 +4843,7 @@ else
|
|||
])
|
||||
])
|
||||
|
||||
dnl check also for dlerror()
|
||||
dnl check also for some optional functions which we may use
|
||||
if test "$HAVE_DL_FUNCS" = 1; then
|
||||
AC_CHECK_FUNCS(dladdr,
|
||||
AC_DEFINE(HAVE_DLADDR),
|
||||
|
|
@ -4855,6 +4855,8 @@ else
|
|||
])
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNCS(dl_iterate_phdr)
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,11 @@ Changes in behaviour which may result in build errors
|
|||
compatible with the previous wxWidgets versions, but now compare values, and
|
||||
not pointers, in their Index() member function.
|
||||
|
||||
- Due to the possibility to construct wxString from std::string_view some
|
||||
previously valid code, such as "wxstr = {"Hello", 2}", is now ambiguous.
|
||||
Please use explicit class name, e.g. "wxstr = wxString{"Hello", 2}" to
|
||||
preserve the previous behaviour.
|
||||
|
||||
- Generic wxSearchCtrl doesn't provide methods that make sense only for
|
||||
multiline text controls any longer, for consistency with the other ports.
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 840 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 954 B After Width: | Height: | Size: 780 B |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 880 B After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 803 B After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 466 B After Width: | Height: | Size: 392 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 715 B After Width: | Height: | Size: 930 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 866 B |
|
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 264 B |
|
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 447 B After Width: | Height: | Size: 779 B |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 669 B After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 972 B After Width: | Height: | Size: 609 B |
|
Before Width: | Height: | Size: 525 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 313 B |
|
Before Width: | Height: | Size: 477 B After Width: | Height: | Size: 306 B |
|
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 533 B |
|
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 665 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 997 B |
|
Before Width: | Height: | Size: 389 B After Width: | Height: | Size: 548 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1,006 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 7.7 KiB |
|
|
@ -2336,10 +2336,10 @@
|
|||
#if wxUSE_MEDIACTRL
|
||||
# if !wxUSE_LONGLONG
|
||||
# ifdef wxABORT_ON_CONFIG_ERROR
|
||||
# error "wxMediaCtrl requires wxUSE_LONLONG"
|
||||
# error "wxMediaCtrl requires wxUSE_LONGLONG"
|
||||
# else
|
||||
# undef wxUSE_LONLONG
|
||||
# define wxUSE_LONLONG 1
|
||||
# undef wxUSE_LONGLONG
|
||||
# define wxUSE_LONGLONG 1
|
||||
# endif
|
||||
# endif
|
||||
#endif /* wxUSE_MEDIACTRL */
|
||||
|
|
@ -2375,10 +2375,10 @@
|
|||
# endif
|
||||
# if !wxUSE_LONGLONG
|
||||
# ifdef wxABORT_ON_CONFIG_ERROR
|
||||
# error "wxRichTextCtrl requires wxUSE_LONLONG"
|
||||
# error "wxRichTextCtrl requires wxUSE_LONGLONG"
|
||||
# else
|
||||
# undef wxUSE_LONLONG
|
||||
# define wxUSE_LONLONG 1
|
||||
# undef wxUSE_LONGLONG
|
||||
# define wxUSE_LONGLONG 1
|
||||
# endif
|
||||
# endif
|
||||
# if !wxUSE_VARIANT
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ public:
|
|||
virtual void SetTitle( const wxString& title) override;
|
||||
virtual wxString GetTitle() const override;
|
||||
|
||||
virtual bool MSWProcessMessage(WXMSG* pMsg) override;
|
||||
|
||||
protected:
|
||||
virtual void DoGetSize(int *width, int *height) const override;
|
||||
virtual void DoGetClientSize(int *width, int *height) const override;
|
||||
|
|
|
|||
58
include/wx/private/init.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/private/init.h
|
||||
// Purpose: Private initialization-related data.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2023-09-02
|
||||
// Copyright: (c) 2023 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_PRIVATE_INIT_H_
|
||||
#define _WX_PRIVATE_INIT_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialization data contains parameters we get from the OS entry function.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct WXDLLIMPEXP_BASE wxInitData
|
||||
{
|
||||
wxInitData() = default;
|
||||
|
||||
// Get the single global object.
|
||||
static wxInitData& Get();
|
||||
|
||||
// Initialize from ANSI command line arguments.
|
||||
void Initialize(int argc, char** argv);
|
||||
|
||||
// This function is used instead of the dtor because the global object can
|
||||
// be initialized multiple times.
|
||||
void Free();
|
||||
|
||||
|
||||
// We always have argc and (Unicode) argv, they're filled by Initialize()
|
||||
// and argv as well as its elements are owned by us, see Free().
|
||||
int argc = 0;
|
||||
wchar_t** argv = nullptr;
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
// Initialize from the implicitly available Unicode command line.
|
||||
void MSWInitialize();
|
||||
|
||||
// This pointer is non-null only if MSWInitialize() was called. In this
|
||||
// case, argv is also set to it and, because this pointer needs to be freed
|
||||
// using MSW-specific function, argv must not be freed at all.
|
||||
//
|
||||
// It's also possible to use Initialize(), even under Windows, in which
|
||||
// case this pointer remains null and argv must be freed as usual.
|
||||
wchar_t** argvMSW = nullptr;
|
||||
#else // !__WINDOWS__
|
||||
// Under other platforms we typically need the original, non-Unicode
|
||||
// command line version, so we keep it too. Unlike argv that we allocate,
|
||||
// this pointer doesn't need to be freed.
|
||||
char** argvA = nullptr;
|
||||
#endif // __WINDOWS__
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxInitData);
|
||||
};
|
||||
|
||||
#endif // _WX_PRIVATE_INIT_H_
|
||||
|
|
@ -500,4 +500,17 @@ public:
|
|||
|
||||
typedef wxScrolled<wxWindow> wxScrolledCanvas;
|
||||
|
||||
namespace wxPrivate
|
||||
{
|
||||
|
||||
// This class is specifically DLL-exported, even though it's trivial, in order
|
||||
// to ensure that there is only a single copy of wxScrolledCanvas in the wx DLL.
|
||||
class WXDLLIMPEXP_CORE wxScrolledCanvasDummySubclass : public wxScrolledCanvas
|
||||
{
|
||||
public:
|
||||
wxScrolledCanvasDummySubclass();
|
||||
};
|
||||
|
||||
} // namespace wxPrivate
|
||||
|
||||
#endif // _WX_SCROLWIN_H_BASE_
|
||||
|
|
|
|||
|
|
@ -1263,7 +1263,7 @@ public:
|
|||
#endif
|
||||
|
||||
#ifdef wxHAS_STD_STRING_VIEW
|
||||
wxString(std::wstring_view view)
|
||||
explicit wxString(std::wstring_view view)
|
||||
{ assign(view.data(), view.length()); }
|
||||
#endif // wxHAS_STD_STRING_VIEW
|
||||
|
||||
|
|
@ -1272,7 +1272,7 @@ public:
|
|||
{ assign(str.c_str(), str.length()); }
|
||||
|
||||
#ifdef wxHAS_STD_STRING_VIEW
|
||||
wxString(std::string_view view)
|
||||
explicit wxString(std::string_view view)
|
||||
{ assign(view.data(), view.length()); }
|
||||
#endif // wxHAS_STD_STRING_VIEW
|
||||
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||
|
|
@ -1883,6 +1883,29 @@ public:
|
|||
{ return assign(s); }
|
||||
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
wxString& operator=(const std::wstring& str) { m_impl = str; return *this; }
|
||||
wxString& operator=(std::wstring&& str) noexcept { m_impl = std::move(str); return *this; }
|
||||
#else // wxUSE_UNICODE_UTF8
|
||||
wxString& operator=(const std::wstring& str)
|
||||
{ return assign(str.c_str(), str.length()); }
|
||||
#endif
|
||||
|
||||
#ifdef wxHAS_STD_STRING_VIEW
|
||||
wxString& operator=(std::wstring_view view)
|
||||
{ return assign(view.data(), view.length()); }
|
||||
#endif // wxHAS_STD_STRING_VIEW
|
||||
|
||||
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||
wxString& operator=(const std::string& str)
|
||||
{ return assign(str.c_str(), str.length()); }
|
||||
|
||||
#ifdef wxHAS_STD_STRING_VIEW
|
||||
wxString& operator=(std::string_view view)
|
||||
{ return assign(view.data(), view.length()); }
|
||||
#endif // wxHAS_STD_STRING_VIEW
|
||||
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||
|
||||
// string concatenation
|
||||
// in place concatenation
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@ public:
|
|||
|
||||
virtual ~wxGLCanvasEGL();
|
||||
|
||||
// Wayland-specific callbacks
|
||||
// --------------------------
|
||||
|
||||
void CreateWaylandSubsurface();
|
||||
void DestroyWaylandSubsurface();
|
||||
|
||||
// implement wxGLCanvasBase methods
|
||||
// --------------------------------
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ public:
|
|||
/**
|
||||
Retrieves the load address and the size of this module.
|
||||
|
||||
Note that under ELF systems (such as Linux) the region defined by the
|
||||
parameters of this function can be discontinuous and contain multiple
|
||||
segments belonging to the module with holes between them.
|
||||
|
||||
@param addr
|
||||
The pointer to the location to return load address in, may be
|
||||
@NULL.
|
||||
|
|
@ -38,6 +42,8 @@ public:
|
|||
/**
|
||||
Returns the base name of this module, e.g.\ @c "kernel32.dll" or
|
||||
@c "libc-2.3.2.so".
|
||||
|
||||
This name is empty for the main program itself.
|
||||
*/
|
||||
wxString GetName() const;
|
||||
|
||||
|
|
@ -217,13 +223,20 @@ public:
|
|||
bool IsLoaded() const;
|
||||
|
||||
/**
|
||||
This static method returns a wxArray containing the details of all
|
||||
modules loaded into the address space of the current project. The array
|
||||
elements are objects of the type: wxDynamicLibraryDetails. The array
|
||||
will be empty if an error occurred.
|
||||
This static method returns a vector-like object containing the details
|
||||
of all modules loaded into the address space of the current project.
|
||||
|
||||
This method is currently implemented only under Win32 and Linux and is
|
||||
useful mostly for diagnostics purposes.
|
||||
The array elements are objects of the type wxDynamicLibraryDetails.
|
||||
Under Unix systems they appear in the order in which they libraries
|
||||
have been loaded, with the module corresponding to the main program
|
||||
itself coming first.
|
||||
|
||||
The returned array will be empty if an error occurred or if the
|
||||
function is not implemented for the current platform.
|
||||
|
||||
This method is currently implemented only under Win32 and Unix systems
|
||||
providing `dl_iterate_phdr()` function (such as Linux) and is useful
|
||||
mostly for diagnostics purposes.
|
||||
*/
|
||||
static wxDynamicLibraryDetailsArray ListLoaded();
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ public:
|
|||
Returns @true if the hyperlink has already been clicked by the user at least
|
||||
one time.
|
||||
*/
|
||||
virtual bool GetVisited() const = 0;
|
||||
virtual bool GetVisited() const;
|
||||
|
||||
/**
|
||||
Returns the colour used to print the label when the mouse is not over the
|
||||
|
|
@ -195,7 +195,7 @@ public:
|
|||
/**
|
||||
Marks the hyperlink as visited (see wxHyperlinkCtrl::SetVisitedColour).
|
||||
*/
|
||||
virtual void SetVisited(bool visited = true) = 0;
|
||||
virtual void SetVisited(bool visited = true);
|
||||
|
||||
/**
|
||||
Sets the colour used to print the label when the mouse is not over the control
|
||||
|
|
|
|||
|
|
@ -3773,6 +3773,9 @@ public:
|
|||
applications (and probably avoid using it under the other
|
||||
platforms without good reason as well).
|
||||
|
||||
@note This function does nothing when using wxGTK with Wayland because
|
||||
Wayland intentionally doesn't provide the required functionality.
|
||||
|
||||
@param x
|
||||
The new x position for the cursor.
|
||||
@param y
|
||||
|
|
|
|||
|
|
@ -937,6 +937,9 @@
|
|||
/* Define if you have the dladdr function. */
|
||||
#undef HAVE_DLADDR
|
||||
|
||||
/* Define if you have the dl_iterate_phdr function. */
|
||||
#undef HAVE_DL_ITERATE_PHDR
|
||||
|
||||
/* Define if you have Posix fnctl() function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#endif // wxCrtSetDbgFlag
|
||||
#endif // __WINDOWS__
|
||||
|
||||
#include "wx/private/init.h"
|
||||
#include "wx/private/localeset.h"
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -121,38 +122,25 @@ static inline void Use(void *) { }
|
|||
// initialization data
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static struct InitData
|
||||
namespace
|
||||
{
|
||||
InitData()
|
||||
: nInitCount(0)
|
||||
{
|
||||
argc = argcOrig = 0;
|
||||
// argv = argvOrig = nullptr; -- not even really needed
|
||||
}
|
||||
|
||||
// number of times wxInitialize() was called minus the number of times
|
||||
// wxUninitialize() was
|
||||
//
|
||||
// it is atomic to allow more than one thread to call wxInitialize() but
|
||||
// only one of them to actually initialize the library
|
||||
wxAtomicInt nInitCount;
|
||||
wxAtomicInt gs_nInitCount{0};
|
||||
|
||||
int argc;
|
||||
} // anonymous namespace
|
||||
|
||||
// if we receive the command line arguments as ASCII and have to convert
|
||||
// them to Unicode ourselves (this is the case under Unix but not Windows,
|
||||
// for example), we remember the converted argv here because we'll have to
|
||||
// free it when doing cleanup to avoid memory leaks
|
||||
wchar_t **argv;
|
||||
/* static */
|
||||
wxInitData& wxInitData::Get()
|
||||
{
|
||||
static wxInitData s_initData;
|
||||
|
||||
// we also need to keep two copies, one passed to other functions, and one
|
||||
// unmodified original; somebody may modify the former, so we need to have
|
||||
// the latter to be able to free everything correctly
|
||||
int argcOrig;
|
||||
wchar_t **argvOrig;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(InitData);
|
||||
} gs_initData;
|
||||
return s_initData;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
|
|
@ -162,18 +150,23 @@ static struct InitData
|
|||
// command line arguments ANSI -> Unicode conversion
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void ConvertArgsToUnicode(int argc, char **argv)
|
||||
void wxInitData::Initialize(int argcIn, char **argvIn)
|
||||
{
|
||||
gs_initData.argvOrig = new wchar_t *[argc + 1];
|
||||
gs_initData.argv = new wchar_t *[argc + 1];
|
||||
wxASSERT_MSG( !argc && !argv, "initializing twice?" );
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
argvA = argvIn;
|
||||
#endif
|
||||
|
||||
argv = new wchar_t *[argcIn + 1];
|
||||
|
||||
int wargc = 0;
|
||||
for ( int i = 0; i < argc; i++ )
|
||||
for ( int i = 0; i < argcIn; i++ )
|
||||
{
|
||||
#ifdef __DARWIN__
|
||||
wxWCharBuffer buf(wxConvFileName->cMB2WX(argv[i]));
|
||||
wxWCharBuffer buf(wxConvFileName->cMB2WX(argvIn[i]));
|
||||
#else
|
||||
wxWCharBuffer buf(wxConvLocal.cMB2WX(argv[i]));
|
||||
wxWCharBuffer buf(wxConvLocal.cMB2WX(argvIn[i]));
|
||||
#endif
|
||||
if ( !buf )
|
||||
{
|
||||
|
|
@ -182,28 +175,58 @@ static void ConvertArgsToUnicode(int argc, char **argv)
|
|||
}
|
||||
else // converted ok
|
||||
{
|
||||
gs_initData.argvOrig[wargc] = gs_initData.argv[wargc] = wxStrdup(buf);
|
||||
argv[wargc] = wxStrdup(buf);
|
||||
wargc++;
|
||||
}
|
||||
}
|
||||
|
||||
gs_initData.argcOrig = gs_initData.argc = wargc;
|
||||
gs_initData.argvOrig[wargc] =gs_initData.argv[wargc] = nullptr;
|
||||
argc = wargc;
|
||||
argv[wargc] = nullptr;
|
||||
}
|
||||
|
||||
static void FreeConvertedArgs()
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
void wxInitData::MSWInitialize()
|
||||
{
|
||||
if ( gs_initData.argvOrig )
|
||||
wxASSERT_MSG( !argc && !argvMSW, "initializing twice?" );
|
||||
|
||||
// Prefer to use the standard function for tokenizing the command line,
|
||||
// instead of our own wxCmdLineParser::ConvertStringToArgs() which might
|
||||
// not use exactly the same logic.
|
||||
|
||||
// This pointer will be freed in Free().
|
||||
argvMSW = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
|
||||
// And this one will be used by the rest of the code. It is separate from
|
||||
// argvMSW because it could be allocated by Initialize() if a custom entry
|
||||
// point is used.
|
||||
argv = argvMSW;
|
||||
}
|
||||
|
||||
#endif // __WINDOWS__
|
||||
|
||||
void wxInitData::Free()
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
if ( argvMSW )
|
||||
{
|
||||
for ( int i = 0; i < gs_initData.argcOrig; i++ )
|
||||
::LocalFree(argvMSW);
|
||||
|
||||
// If argvMSW is non-null, argv must be the same value, so reset it too.
|
||||
argv = argvMSW = nullptr;
|
||||
argc = 0;
|
||||
}
|
||||
#endif // __WINDOWS__
|
||||
|
||||
if ( argc )
|
||||
{
|
||||
for ( int i = 0; i < argc; i++ )
|
||||
{
|
||||
free(gs_initData.argvOrig[i]);
|
||||
// gs_initData.argv[i] normally points to the same data
|
||||
free(argv[i]);
|
||||
}
|
||||
|
||||
wxDELETEA(gs_initData.argvOrig);
|
||||
wxDELETEA(gs_initData.argv);
|
||||
gs_initData.argcOrig = gs_initData.argc = 0;
|
||||
wxDELETEA(argv);
|
||||
argc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,11 +362,12 @@ bool wxEntryStart(int& argc, wxChar **argv)
|
|||
// we provide a wxEntryStart() wrapper taking "char *" pointer too
|
||||
bool wxEntryStart(int& argc, char **argv)
|
||||
{
|
||||
ConvertArgsToUnicode(argc, argv);
|
||||
auto& initData = wxInitData::Get();
|
||||
initData.Initialize(argc, argv);
|
||||
|
||||
if ( !wxEntryStart(gs_initData.argc, gs_initData.argv) )
|
||||
if ( !wxEntryStart(initData.argc, initData.argv) )
|
||||
{
|
||||
FreeConvertedArgs();
|
||||
initData.Free();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -378,7 +402,7 @@ static void DoCommonPostCleanup()
|
|||
|
||||
// we can't do this in wxApp itself because it doesn't know if argv had
|
||||
// been allocated
|
||||
FreeConvertedArgs();
|
||||
wxInitData::Get().Free();
|
||||
|
||||
// use Set(nullptr) and not Get() to avoid creating a message output object on
|
||||
// demand when we just want to delete it
|
||||
|
|
@ -401,12 +425,7 @@ static void DoCommonPostCleanup()
|
|||
#endif // wxUSE_LOG
|
||||
}
|
||||
|
||||
// for MSW the real wxEntryCleanup() is defined in msw/main.cpp
|
||||
#ifndef __WINDOWS__
|
||||
#define wxEntryCleanupReal wxEntryCleanup
|
||||
#endif // !__WINDOWS__
|
||||
|
||||
void wxEntryCleanupReal()
|
||||
void wxEntryCleanup()
|
||||
{
|
||||
DoCommonPreCleanup();
|
||||
|
||||
|
|
@ -478,9 +497,10 @@ int wxEntryReal(int& argc, wxChar **argv)
|
|||
// as with wxEntryStart, we provide an ANSI wrapper
|
||||
int wxEntry(int& argc, char **argv)
|
||||
{
|
||||
ConvertArgsToUnicode(argc, argv);
|
||||
auto& initData = wxInitData::Get();
|
||||
initData.Initialize(argc, argv);
|
||||
|
||||
return wxEntry(gs_initData.argc, gs_initData.argv);
|
||||
return wxEntry(initData.argc, initData.argv);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -495,7 +515,7 @@ bool wxInitialize()
|
|||
|
||||
bool wxInitialize(int& argc, wxChar **argv)
|
||||
{
|
||||
if ( wxAtomicInc(gs_initData.nInitCount) != 1 )
|
||||
if ( wxAtomicInc(gs_nInitCount) != 1 )
|
||||
{
|
||||
// already initialized
|
||||
return true;
|
||||
|
|
@ -506,7 +526,7 @@ bool wxInitialize(int& argc, wxChar **argv)
|
|||
|
||||
bool wxInitialize(int& argc, char **argv)
|
||||
{
|
||||
if ( wxAtomicInc(gs_initData.nInitCount) != 1 )
|
||||
if ( wxAtomicInc(gs_nInitCount) != 1 )
|
||||
{
|
||||
// already initialized
|
||||
return true;
|
||||
|
|
@ -517,7 +537,7 @@ bool wxInitialize(int& argc, char **argv)
|
|||
|
||||
void wxUninitialize()
|
||||
{
|
||||
if ( wxAtomicDec(gs_initData.nInitCount) != 0 )
|
||||
if ( wxAtomicDec(gs_nInitCount) != 0 )
|
||||
return;
|
||||
|
||||
wxEntryCleanup();
|
||||
|
|
|
|||
|
|
@ -1532,3 +1532,10 @@ WXLRESULT wxScrolledT_Helper::FilterMSWWindowProc(WXUINT nMsg, WXLRESULT rc)
|
|||
// NB: skipping wxScrolled<T> in wxRTTI information because being a template,
|
||||
// it doesn't and can't implement wxRTTI support
|
||||
wxIMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel);
|
||||
|
||||
namespace wxPrivate
|
||||
{
|
||||
|
||||
wxScrolledCanvasDummySubclass::wxScrolledCanvasDummySubclass() = default;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include "wx/fontmap.h"
|
||||
#include "wx/msgout.h"
|
||||
|
||||
#include "wx/private/init.h"
|
||||
|
||||
#include "wx/gtk/private.h"
|
||||
#include "wx/gtk/private/log.h"
|
||||
#include "wx/gtk/private/threads.h"
|
||||
|
|
@ -472,19 +474,6 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
|
|||
|
||||
bool init_result;
|
||||
|
||||
int i;
|
||||
|
||||
// gtk_init() wants UTF-8, not wchar_t, so convert
|
||||
char **argvGTK = new char *[argc_ + 1];
|
||||
for ( i = 0; i < argc_; i++ )
|
||||
{
|
||||
argvGTK[i] = wxStrdupA(wxConvUTF8.cWX2MB(argv_[i]));
|
||||
}
|
||||
|
||||
argvGTK[argc_] = nullptr;
|
||||
|
||||
int argcGTK = argc_;
|
||||
|
||||
// Prevent gtk_init_check() from changing the locale automatically for
|
||||
// consistency with the other ports that don't do it. If necessary,
|
||||
// wxApp::SetCLocale() may be explicitly called.
|
||||
|
|
@ -501,36 +490,31 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
|
|||
#if defined(__WXGTK4__)
|
||||
init_result = gtk_init_check() != 0;
|
||||
#else
|
||||
init_result = gtk_init_check( &argcGTK, &argvGTK ) != 0;
|
||||
#endif
|
||||
auto argvA = wxInitData::Get().argvA;
|
||||
|
||||
int argcGTK = argc_;
|
||||
init_result = gtk_init_check( &argcGTK, &argvA ) != 0;
|
||||
|
||||
if ( argcGTK != argc_ )
|
||||
{
|
||||
// we have to drop the parameters which were consumed by GTK+
|
||||
for ( i = 0; i < argcGTK; i++ )
|
||||
for ( int i = 0; i < argcGTK; i++ )
|
||||
{
|
||||
while ( strcmp(wxConvUTF8.cWX2MB(argv_[i]), argvGTK[i]) != 0 )
|
||||
while ( strcmp(wxConvUTF8.cWX2MB(argv_[i]), argvA[i]) != 0 )
|
||||
{
|
||||
free(argv_[i]);
|
||||
memmove(argv_ + i, argv_ + i + 1, (argc_ - i)*sizeof(*argv_));
|
||||
}
|
||||
}
|
||||
|
||||
argc_ = argcGTK;
|
||||
argv_[argc_] = nullptr;
|
||||
|
||||
this->argc = argc_;
|
||||
this->argv.Init(argc_, argv_);
|
||||
}
|
||||
//else: gtk_init() didn't modify our parameters
|
||||
|
||||
// free our copy
|
||||
for ( i = 0; i < argcGTK; i++ )
|
||||
{
|
||||
free(argvGTK[i]);
|
||||
}
|
||||
|
||||
delete [] argvGTK;
|
||||
|
||||
// update internal arg[cv] as GTK+ may have removed processed options:
|
||||
this->argc = argc_;
|
||||
this->argv.Init(argc_, argv_);
|
||||
#endif
|
||||
|
||||
if ( !init_result )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1054,7 +1054,7 @@ bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options)
|
|||
gspell_entry_set_inline_spell_checking(spell, options.IsSpellCheckEnabled());
|
||||
}
|
||||
|
||||
return GetProofCheckOptions().IsSpellCheckEnabled();
|
||||
return GetProofCheckOptions().IsSpellCheckEnabled() == options.IsSpellCheckEnabled();
|
||||
}
|
||||
|
||||
wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const
|
||||
|
|
@ -1065,16 +1065,24 @@ wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const
|
|||
{
|
||||
GtkTextView *textview = GTK_TEXT_VIEW(m_text);
|
||||
|
||||
if ( textview && gspell_text_view_get_from_gtk_text_view(textview) )
|
||||
opts.SpellCheck();
|
||||
if ( textview )
|
||||
{
|
||||
GspellTextView *spell = gspell_text_view_get_from_gtk_text_view (textview);
|
||||
if ( spell && gspell_text_view_get_inline_spell_checking(spell) )
|
||||
opts.SpellCheck();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY(m_text);
|
||||
|
||||
if ( entry && gspell_entry_get_from_gtk_entry(entry) )
|
||||
opts.SpellCheck();
|
||||
if ( entry )
|
||||
{
|
||||
GspellEntry *spell = gspell_entry_get_from_gtk_entry(entry);
|
||||
if ( spell && gspell_entry_get_inline_spell_checking(spell) )
|
||||
opts.SpellCheck();
|
||||
}
|
||||
}
|
||||
|
||||
return opts;
|
||||
|
|
|
|||
|
|
@ -63,32 +63,10 @@ bool wxGUIEventLoop::PreProcessMessage(WXMSG *msg)
|
|||
wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hwnd);
|
||||
wxWindow *wnd;
|
||||
|
||||
// this might happen if we're in a modeless dialog, or if a wx control has
|
||||
// children which themselves were not created by wx (i.e. wxActiveX control children)
|
||||
// this might happen a wx control has children which themselves were not
|
||||
// created by wx (i.e. wxActiveX control children)
|
||||
if ( !wndThis )
|
||||
{
|
||||
while ( hwnd && (::GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD ))
|
||||
{
|
||||
hwnd = ::GetParent(hwnd);
|
||||
|
||||
// If the control has a wx parent, break and give the parent a chance
|
||||
// to process the window message
|
||||
wndThis = wxGetWindowFromHWND((WXHWND)hwnd);
|
||||
if (wndThis != nullptr)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !wndThis )
|
||||
{
|
||||
// this may happen if the event occurred in a standard modeless dialog (the
|
||||
// only example of which I know of is the find/replace dialog) - then call
|
||||
// IsDialogMessage() to make TAB navigation in it work
|
||||
|
||||
// NOTE: IsDialogMessage() just eats all the messages (i.e. returns true for
|
||||
// them) if we call it for the control itself
|
||||
return hwnd && ::IsDialogMessage(hwnd, msg) != 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
if ( !AllowProcessing(wndThis) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@
|
|||
|
||||
#include "wx/fdrepdlg.h"
|
||||
|
||||
// Use functions from src/msw/window.cpp
|
||||
extern void wxRemoveHandleAssociation(wxWindowMSW *win);
|
||||
extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// functions prototypes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -334,6 +338,7 @@ wxFindReplaceDialog::~wxFindReplaceDialog()
|
|||
m_isShown = false;
|
||||
|
||||
// and from destroying our window [again]
|
||||
wxRemoveHandleAssociation(this);
|
||||
m_hWnd = (WXHWND)nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -419,6 +424,7 @@ bool wxFindReplaceDialog::Show(bool show)
|
|||
}
|
||||
|
||||
m_hWnd = (WXHWND)hwnd;
|
||||
wxAssociateWinWithHandle(m_hWnd, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -440,6 +446,19 @@ wxString wxFindReplaceDialog::GetTitle() const
|
|||
return m_title;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxFindReplaceDialog message handling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxFindReplaceDialog::MSWProcessMessage(WXMSG* pMsg)
|
||||
{
|
||||
// The base class MSWProcessMessage() doesn't work for us because we don't
|
||||
// have wxTAB_TRAVERSAL style, but then we don't need it anyhow: as this
|
||||
// dialog only ever contains standard controls, just using the standard
|
||||
// function is enough to make TAB navigation work in it.
|
||||
return m_hWnd && ::IsDialogMessage(m_hWnd, pMsg);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxFindReplaceDialog position/size
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "wx/dynlib.h"
|
||||
|
||||
#include "wx/private/init.h"
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/seh.h"
|
||||
|
||||
|
|
@ -38,7 +40,6 @@
|
|||
|
||||
// defined in common/init.cpp
|
||||
extern int wxEntryReal(int& argc, wxChar **argv);
|
||||
extern void wxEntryCleanupReal();
|
||||
|
||||
// ============================================================================
|
||||
// implementation: various entry points
|
||||
|
|
@ -188,78 +189,6 @@ int wxEntry(int& argc, wxChar **argv)
|
|||
// Windows-specific wxEntry
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Declare the functions used in wxCore to access the command line arguments
|
||||
// data in wxBase.
|
||||
WXDLLIMPEXP_BASE void wxMSWCommandLineInit();
|
||||
WXDLLIMPEXP_BASE void wxMSWCommandLineCleanup();
|
||||
WXDLLIMPEXP_BASE int& wxMSWCommandLineGetArgc();
|
||||
WXDLLIMPEXP_BASE wchar_t** wxMSWCommandLineGetArgv();
|
||||
|
||||
#if wxUSE_BASE
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct wxMSWCommandLineArguments
|
||||
{
|
||||
wxMSWCommandLineArguments() { argc = 0; argv = nullptr; }
|
||||
|
||||
// Initialize this object from the current process command line.
|
||||
//
|
||||
// In Unicode build prefer to use the standard function for tokenizing the
|
||||
// command line, but we can't use it with narrow strings, so use our own
|
||||
// approximation instead then.
|
||||
void Init()
|
||||
{
|
||||
argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
}
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
if ( argc )
|
||||
{
|
||||
::LocalFree(argv);
|
||||
argc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~wxMSWCommandLineArguments()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
int argc;
|
||||
wxChar **argv;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxMSWCommandLineArguments);
|
||||
};
|
||||
|
||||
static wxMSWCommandLineArguments wxArgs;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
WXDLLIMPEXP_BASE void wxMSWCommandLineInit()
|
||||
{
|
||||
wxArgs.Init();
|
||||
}
|
||||
|
||||
WXDLLIMPEXP_BASE void wxMSWCommandLineCleanup()
|
||||
{
|
||||
wxArgs.Cleanup();
|
||||
}
|
||||
|
||||
WXDLLIMPEXP_BASE int& wxMSWCommandLineGetArgc()
|
||||
{
|
||||
return wxArgs.argc;
|
||||
}
|
||||
|
||||
WXDLLIMPEXP_BASE wchar_t** wxMSWCommandLineGetArgv()
|
||||
{
|
||||
return wxArgs.argv;
|
||||
}
|
||||
|
||||
#endif // wxUSE_BASE
|
||||
|
||||
#if wxUSE_GUI
|
||||
|
||||
// common part of wxMSW-specific wxEntryStart() and wxEntry() overloads
|
||||
|
|
@ -274,7 +203,7 @@ wxMSWEntryCommon(HINSTANCE hInstance, int nCmdShow)
|
|||
wxUnusedVar(nCmdShow);
|
||||
#endif
|
||||
|
||||
wxMSWCommandLineInit();
|
||||
wxInitData().Get().MSWInitialize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -287,7 +216,8 @@ WXDLLEXPORT bool wxEntryStart(HINSTANCE hInstance,
|
|||
if ( !wxMSWEntryCommon(hInstance, nCmdShow) )
|
||||
return false;
|
||||
|
||||
return wxEntryStart(wxMSWCommandLineGetArgc(), wxMSWCommandLineGetArgv());
|
||||
auto& initData = wxInitData::Get();
|
||||
return wxEntryStart(initData.argc, initData.argv);
|
||||
}
|
||||
|
||||
WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
|
||||
|
|
@ -298,7 +228,8 @@ WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
|
|||
if ( !wxMSWEntryCommon(hInstance, nCmdShow) )
|
||||
return -1;
|
||||
|
||||
return wxEntry(wxMSWCommandLineGetArgc(), wxMSWCommandLineGetArgv());
|
||||
auto& initData = wxInitData::Get();
|
||||
return wxEntry(initData.argc, initData.argv);
|
||||
}
|
||||
|
||||
#endif // wxUSE_GUI
|
||||
|
|
@ -311,16 +242,10 @@ WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
|
|||
|
||||
int wxEntry()
|
||||
{
|
||||
wxMSWCommandLineInit();
|
||||
wxInitData().Get().MSWInitialize();
|
||||
|
||||
return wxEntry(wxMSWCommandLineGetArgc(), wxMSWCommandLineGetArgv());
|
||||
}
|
||||
|
||||
void wxEntryCleanup()
|
||||
{
|
||||
wxEntryCleanupReal();
|
||||
|
||||
wxMSWCommandLineCleanup();
|
||||
auto& initData = wxInitData::Get();
|
||||
return wxEntry(initData.argc, initData.argv);
|
||||
}
|
||||
|
||||
HINSTANCE wxhInstance = 0;
|
||||
|
|
|
|||
|
|
@ -878,7 +878,7 @@ bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options)
|
|||
|
||||
::SendMessage(GetHwnd(), EM_SETLANGOPTIONS, 0, langOptions);
|
||||
|
||||
return GetProofCheckOptions().IsSpellCheckEnabled();
|
||||
return GetProofCheckOptions().IsSpellCheckEnabled() == options.IsSpellCheckEnabled();
|
||||
}
|
||||
|
||||
wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ void wxTraceMSWMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
#endif // wxDEBUG_LEVEL >= 2
|
||||
|
||||
void wxRemoveHandleAssociation(wxWindowMSW *win);
|
||||
extern void wxRemoveHandleAssociation(wxWindowMSW *win);
|
||||
extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
|
||||
|
||||
// get the text metrics for the current font
|
||||
|
|
@ -7098,44 +7098,31 @@ wxWindow *wxGetActiveWindow()
|
|||
extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
|
||||
{
|
||||
HWND hwnd = (HWND)hWnd;
|
||||
if ( !hwnd )
|
||||
return nullptr;
|
||||
|
||||
// For a radiobutton, we get the radiobox from GWL_USERDATA (which is set
|
||||
// by code in msw/radiobox.cpp), for all the others we just search up the
|
||||
// window hierarchy
|
||||
wxWindow *win = nullptr;
|
||||
if ( hwnd )
|
||||
{
|
||||
win = wxFindWinFromHandle(hwnd);
|
||||
if ( !win )
|
||||
{
|
||||
// spin control text buddy window should be mapped to spin ctrl
|
||||
// itself so try it too
|
||||
wxWindow *win = wxFindWinFromHandle(hwnd);
|
||||
|
||||
// spin control text buddy window should be mapped to spin ctrl
|
||||
// itself so try it too
|
||||
#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
|
||||
if ( !win )
|
||||
{
|
||||
win = wxSpinCtrl::GetSpinForTextCtrl((WXHWND)hwnd);
|
||||
}
|
||||
#endif // wxUSE_SPINCTRL
|
||||
}
|
||||
}
|
||||
|
||||
while ( hwnd && !win )
|
||||
if ( !win )
|
||||
{
|
||||
// this is a really ugly hack needed to avoid mistakenly returning the
|
||||
// parent frame wxWindow for the find/replace modeless dialog HWND -
|
||||
// this, in turn, is needed to call IsDialogMessage() from
|
||||
// wxApp::ProcessMessage() as for this we must return nullptr from here
|
||||
//
|
||||
// FIXME: this is clearly not the best way to do it but I think we'll
|
||||
// need to change HWND <-> wxWindow code more heavily than I can
|
||||
// do it now to fix it
|
||||
win = wxSpinCtrl::GetSpinForTextCtrl((WXHWND)hwnd);
|
||||
}
|
||||
#endif // wxUSE_SPINCTRL
|
||||
|
||||
while ( !win )
|
||||
{
|
||||
// Avoid going beyond the top level window (only they have owner in
|
||||
// Win32) as we could find its owner wxFrame which would be unwanted.
|
||||
if ( ::GetWindow(hwnd, GW_OWNER) )
|
||||
{
|
||||
// it's a dialog box, don't go upwards
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
hwnd = ::GetParent(hwnd);
|
||||
if ( !hwnd )
|
||||
return nullptr;
|
||||
|
||||
win = wxFindWinFromHandle(hwnd);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@
|
|||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DL_ITERATE_PHDR
|
||||
#include <link.h>
|
||||
#endif
|
||||
|
||||
// if some flags are not supported, just ignore them
|
||||
#ifndef RTLD_LAZY
|
||||
#define RTLD_LAZY 0
|
||||
|
|
@ -125,20 +129,38 @@ void wxDynamicLibrary::ReportError(const wxString& message,
|
|||
// listing loaded modules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef HAVE_DL_ITERATE_PHDR
|
||||
|
||||
// wxDynamicLibraryDetails declares this class as its friend, so put the code
|
||||
// initializing new details objects here
|
||||
class wxDynamicLibraryDetailsCreator
|
||||
{
|
||||
public:
|
||||
// create a new wxDynamicLibraryDetails from the given data
|
||||
static wxDynamicLibraryDetails
|
||||
New(void *start, void *end, const wxString& path)
|
||||
static int Callback(dl_phdr_info* info, size_t /* size */, void* data)
|
||||
{
|
||||
const wxString path = wxString::FromUTF8(info->dlpi_name);
|
||||
|
||||
wxDynamicLibraryDetails details;
|
||||
details.m_path = path;
|
||||
details.m_name = path.AfterLast(wxT('/'));
|
||||
details.m_address = start;
|
||||
details.m_length = (char *)end - (char *)start;
|
||||
|
||||
// Find the first and last address belonging to this module.
|
||||
decltype(info->dlpi_addr) start = 0, end = 0;
|
||||
for ( decltype(info->dlpi_phnum) n = 0; n < info->dlpi_phnum; n++ )
|
||||
{
|
||||
const auto& segment = info->dlpi_phdr[n];
|
||||
if ( !segment.p_vaddr || !segment.p_memsz )
|
||||
continue;
|
||||
|
||||
if ( !start || segment.p_vaddr < start )
|
||||
start = segment.p_vaddr;
|
||||
|
||||
if ( !end || segment.p_vaddr + segment.p_memsz > end )
|
||||
end = segment.p_vaddr + segment.p_memsz;
|
||||
}
|
||||
|
||||
details.m_address = wxUIntToPtr(info->dlpi_addr + start);
|
||||
details.m_length = end - start;
|
||||
|
||||
// try to extract the library version from its name
|
||||
const size_t posExt = path.rfind(wxT(".so"));
|
||||
|
|
@ -161,78 +183,24 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
return details;
|
||||
auto dlls = static_cast<wxDynamicLibraryDetailsArray*>(data);
|
||||
dlls->push_back(std::move(details));
|
||||
|
||||
// Return 0 to keep iterating.
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // HAVE_DL_ITERATE_PHDR
|
||||
|
||||
/* static */
|
||||
wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
|
||||
{
|
||||
wxDynamicLibraryDetailsArray dlls;
|
||||
|
||||
#ifdef __LINUX__
|
||||
// examine /proc/self/maps to find out what is loaded in our address space
|
||||
wxFFile file(wxT("/proc/self/maps"));
|
||||
if ( file.IsOpened() )
|
||||
{
|
||||
// details of the module currently being parsed
|
||||
wxString pathCur;
|
||||
void *startCur = nullptr,
|
||||
*endCur = nullptr;
|
||||
|
||||
char path[1024];
|
||||
char buf[1024];
|
||||
while ( fgets(buf, WXSIZEOF(buf), file.fp()) )
|
||||
{
|
||||
// format is: "start-end perm offset maj:min inode path", see proc(5)
|
||||
void *start,
|
||||
*end;
|
||||
switch ( sscanf(buf, "%p-%p %*4s %*p %*02x:%*02x %*d %1023s\n",
|
||||
&start, &end, path) )
|
||||
{
|
||||
case 2:
|
||||
// there may be no path column
|
||||
path[0] = '\0';
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// nothing to do, read everything we wanted
|
||||
break;
|
||||
|
||||
default:
|
||||
// chop '\n'
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
wxLogDebug(wxT("Failed to parse line \"%s\" in /proc/self/maps."),
|
||||
buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
wxASSERT_MSG( start >= endCur,
|
||||
wxT("overlapping regions in /proc/self/maps?") );
|
||||
|
||||
wxString pathNew = wxString::FromAscii(path);
|
||||
if ( pathCur.empty() )
|
||||
{
|
||||
// new module start
|
||||
pathCur = pathNew;
|
||||
startCur = start;
|
||||
endCur = end;
|
||||
}
|
||||
else if ( pathCur == pathNew && endCur == end )
|
||||
{
|
||||
// continuation of the same module in the address space
|
||||
endCur = end;
|
||||
}
|
||||
else // end of the current module
|
||||
{
|
||||
dlls.Add(wxDynamicLibraryDetailsCreator::New(startCur,
|
||||
endCur,
|
||||
pathCur));
|
||||
pathCur.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // __LINUX__
|
||||
#ifdef HAVE_DL_ITERATE_PHDR
|
||||
dl_iterate_phdr(wxDynamicLibraryDetailsCreator::Callback, &dlls);
|
||||
#endif // HAVE_DL_ITERATE_PHDR
|
||||
|
||||
return dlls;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,6 +389,14 @@ EGLDisplay wxGLCanvasEGL::GetDisplay()
|
|||
// Helper declared as friend in the header and so can access m_wlSubsurface.
|
||||
void wxEGLUpdatePosition(wxGLCanvasEGL* win)
|
||||
{
|
||||
if ( !win->m_wlSubsurface )
|
||||
{
|
||||
// In some circumstances such as when reparenting a canvas between two hidden
|
||||
// toplevel windows, GTK will call size-allocate before mapping the canvas
|
||||
// Ignore the call, the position will be fixed when it is mapped
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
gdk_window_get_origin(win->GTKGetDrawingWindow(), &x, &y);
|
||||
wl_subsurface_set_position(win->m_wlSubsurface, x, y);
|
||||
|
|
@ -439,6 +447,17 @@ static const struct wl_callback_listener wl_frame_listener = {
|
|||
wl_frame_callback_handler
|
||||
};
|
||||
|
||||
static gboolean gtk_glcanvas_map_callback(GtkWidget *, GdkEventAny *, wxGLCanvasEGL *win)
|
||||
{
|
||||
win->CreateWaylandSubsurface();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void gtk_glcanvas_unmap_callback(GtkWidget *, wxGLCanvasEGL *win)
|
||||
{
|
||||
win->DestroyWaylandSubsurface();
|
||||
}
|
||||
|
||||
static void gtk_glcanvas_size_callback(GtkWidget *widget,
|
||||
GtkAllocation *,
|
||||
wxGLCanvasEGL *win)
|
||||
|
|
@ -462,16 +481,16 @@ bool wxGLCanvasEGL::CreateSurface()
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( m_surface != EGL_NO_SURFACE )
|
||||
{
|
||||
eglDestroySurface(m_surface, m_display);
|
||||
m_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
GdkWindow *window = GTKGetDrawingWindow();
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (wxGTKImpl::IsX11(window))
|
||||
{
|
||||
if ( m_surface != EGL_NO_SURFACE )
|
||||
{
|
||||
eglDestroySurface(m_surface, m_display);
|
||||
m_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
m_xwindow = GDK_WINDOW_XID(window);
|
||||
m_surface = eglCreatePlatformWindowSurface(m_display, *m_config,
|
||||
&m_xwindow, nullptr);
|
||||
|
|
@ -480,10 +499,16 @@ bool wxGLCanvasEGL::CreateSurface()
|
|||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (wxGTKImpl::IsWayland(window))
|
||||
{
|
||||
if ( m_wlSurface )
|
||||
{
|
||||
// Already created (can happen when the canvas is un-realized then
|
||||
// re-realized, for example, when the canvas is re-parented)
|
||||
return true;
|
||||
}
|
||||
|
||||
int w = gdk_window_get_width(window);
|
||||
int h = gdk_window_get_height(window);
|
||||
struct wl_display *display = gdk_wayland_display_get_wl_display(gdk_window_get_display(window));
|
||||
struct wl_surface *surface = gdk_wayland_window_get_wl_surface(window);
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, &wl_registry_listener, this);
|
||||
wl_display_roundtrip(display);
|
||||
|
|
@ -494,21 +519,25 @@ bool wxGLCanvasEGL::CreateSurface()
|
|||
}
|
||||
m_wlSurface = wl_compositor_create_surface(m_wlCompositor);
|
||||
m_wlRegion = wl_compositor_create_region(m_wlCompositor);
|
||||
m_wlSubsurface = wl_subcompositor_get_subsurface(m_wlSubcompositor,
|
||||
m_wlSurface,
|
||||
surface);
|
||||
wl_surface_set_input_region(m_wlSurface, m_wlRegion);
|
||||
wl_subsurface_set_desync(m_wlSubsurface);
|
||||
wxEGLUpdatePosition(this);
|
||||
int scale = gdk_window_get_scale_factor(window);
|
||||
wl_surface_set_buffer_scale(m_wlSurface, scale);
|
||||
m_wlEGLWindow = wl_egl_window_create(m_wlSurface, w * scale,
|
||||
h * scale);
|
||||
m_surface = eglCreatePlatformWindowSurface(m_display, *m_config,
|
||||
m_wlEGLWindow, nullptr);
|
||||
m_wlFrameCallbackHandler = wl_surface_frame(surface);
|
||||
wl_callback_add_listener(m_wlFrameCallbackHandler,
|
||||
&wl_frame_listener, this);
|
||||
|
||||
// We need to use "map-event" instead of "map" to ensure that the
|
||||
// widget's underlying Wayland surface has been created.
|
||||
// Otherwise, gdk_wayland_window_get_wl_surface may return nullptr,
|
||||
// for example when hiding then showing a window containing a canvas.
|
||||
gtk_widget_add_events(m_widget, GDK_STRUCTURE_MASK);
|
||||
g_signal_connect(m_widget, "map-event",
|
||||
G_CALLBACK(gtk_glcanvas_map_callback), this);
|
||||
// However, note the use of "unmap" instead of the later "unmap-event"
|
||||
// Not unmapping the canvas as soon as possible causes problems when reparenting
|
||||
g_signal_connect(m_widget, "unmap",
|
||||
G_CALLBACK(gtk_glcanvas_unmap_callback), this);
|
||||
g_signal_connect(m_widget, "size-allocate",
|
||||
G_CALLBACK(gtk_glcanvas_size_callback), this);
|
||||
|
||||
|
|
@ -535,9 +564,39 @@ wxGLCanvasEGL::~wxGLCanvasEGL()
|
|||
eglDestroySurface(m_display, m_surface);
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
g_clear_pointer(&m_wlEGLWindow, wl_egl_window_destroy);
|
||||
g_clear_pointer(&m_wlSubsurface, wl_subsurface_destroy);
|
||||
g_clear_pointer(&m_wlSurface, wl_surface_destroy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void wxGLCanvasEGL::CreateWaylandSubsurface()
|
||||
{
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
GdkWindow *window = GTKGetDrawingWindow();
|
||||
struct wl_surface *surface = gdk_wayland_window_get_wl_surface(window);
|
||||
|
||||
m_wlSubsurface = wl_subcompositor_get_subsurface(m_wlSubcompositor,
|
||||
m_wlSurface,
|
||||
surface);
|
||||
wl_subsurface_set_desync(m_wlSubsurface);
|
||||
wxEGLUpdatePosition(this);
|
||||
m_wlFrameCallbackHandler = wl_surface_frame(surface);
|
||||
wl_callback_add_listener(m_wlFrameCallbackHandler,
|
||||
&wl_frame_listener, this);
|
||||
|
||||
if ( m_surface == EGL_NO_SURFACE )
|
||||
{
|
||||
wxFAIL_MSG("Unable to create EGL surface");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void wxGLCanvasEGL::DestroyWaylandSubsurface()
|
||||
{
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
g_clear_pointer(&m_wlSubsurface, wl_subsurface_destroy);
|
||||
g_clear_pointer(&m_wlFrameCallbackHandler, wl_callback_destroy);
|
||||
m_readyToDraw = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -690,5 +690,14 @@ TEST_CASE("StdString::View", "[stdstring]")
|
|||
std::string_view strViewInvalidUTF(strInvalidUTF);
|
||||
|
||||
CHECK( "" == wxString::FromUTF8(strViewInvalidUTF) );
|
||||
|
||||
/* Ensure we don't clobber comparisons on base types */
|
||||
std::string_view view = "abc";
|
||||
const char *str = "abc";
|
||||
CHECK( view == str );
|
||||
|
||||
std::wstring_view wview = L"abc";
|
||||
const wchar_t *wstr = L"abc";
|
||||
CHECK( wview == wstr );
|
||||
}
|
||||
#endif // wxHAS_STD_STRING_VIEW
|
||||
|
|
|
|||