mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-30 02:50:05 +00:00
Linux: Fixed a use-after-free in XWindowSystem::findDisplays()
This commit is contained in:
parent
8070fa0ec4
commit
09ecc0ebef
1 changed files with 44 additions and 30 deletions
|
|
@ -2168,24 +2168,39 @@ ModifierKeys XWindowSystem::getNativeRealtimeModifiers() const
|
|||
return ModifierKeys::currentModifiers;
|
||||
}
|
||||
|
||||
static bool hasWorkAreaData (const XWindowSystemUtilities::GetXProperty& prop)
|
||||
{
|
||||
return prop.success
|
||||
&& prop.actualType == XA_CARDINAL
|
||||
&& prop.actualFormat == 32
|
||||
&& prop.numItems == 4
|
||||
&& prop.data != nullptr;
|
||||
}
|
||||
|
||||
static Rectangle<int> getWorkArea (const XWindowSystemUtilities::GetXProperty& prop)
|
||||
{
|
||||
if (hasWorkAreaData (prop))
|
||||
{
|
||||
auto* positionData = prop.data;
|
||||
std::array<long, 4> position;
|
||||
|
||||
for (auto& p : position)
|
||||
{
|
||||
memcpy (&p, positionData, sizeof (long));
|
||||
positionData += sizeof (long);
|
||||
}
|
||||
|
||||
return { (int) position[0], (int) position[1],
|
||||
(int) position[2], (int) position[3] };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Array<Displays::Display> XWindowSystem::findDisplays (float masterScale) const
|
||||
{
|
||||
Array<Displays::Display> displays;
|
||||
|
||||
Atom hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WORKAREA");
|
||||
|
||||
auto getWorkAreaPropertyData = [&] (int screenNum) -> unsigned char*
|
||||
{
|
||||
if (hints != None)
|
||||
{
|
||||
XWindowSystemUtilities::GetXProperty prop (X11Symbols::getInstance()->xRootWindow (display, screenNum), hints, 0, 4, false, XA_CARDINAL);
|
||||
|
||||
if (prop.success && prop.actualType == XA_CARDINAL && prop.actualFormat == 32 && prop.numItems == 4)
|
||||
return prop.data;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
auto workAreaHints = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WORKAREA");
|
||||
|
||||
#if JUCE_USE_XRANDR
|
||||
{
|
||||
|
|
@ -2198,11 +2213,13 @@ Array<Displays::Display> XWindowSystem::findDisplays (float masterScale) const
|
|||
|
||||
for (int i = 0; i < numMonitors; ++i)
|
||||
{
|
||||
if (getWorkAreaPropertyData (i) == nullptr)
|
||||
auto rootWindow = X11Symbols::getInstance()->xRootWindow (display, i);
|
||||
XWindowSystemUtilities::GetXProperty prop (rootWindow, workAreaHints, 0, 4, false, XA_CARDINAL);
|
||||
|
||||
if (! hasWorkAreaData (prop))
|
||||
continue;
|
||||
|
||||
if (auto* screens = X11Symbols::getInstance()->xRRGetScreenResources (display,
|
||||
X11Symbols::getInstance()->xRootWindow (display, i)))
|
||||
if (auto* screens = X11Symbols::getInstance()->xRRGetScreenResources (display, rootWindow))
|
||||
{
|
||||
for (int j = 0; j < screens->noutput; ++j)
|
||||
{
|
||||
|
|
@ -2286,25 +2303,22 @@ Array<Displays::Display> XWindowSystem::findDisplays (float masterScale) const
|
|||
if (displays.isEmpty())
|
||||
#endif
|
||||
{
|
||||
if (hints != None)
|
||||
if (workAreaHints != None)
|
||||
{
|
||||
auto numMonitors = X11Symbols::getInstance()->xScreenCount (display);
|
||||
|
||||
for (int i = 0; i < numMonitors; ++i)
|
||||
{
|
||||
if (auto* positionData = getWorkAreaPropertyData (i))
|
||||
XWindowSystemUtilities::GetXProperty prop (X11Symbols::getInstance()->xRootWindow (display, i),
|
||||
workAreaHints, 0, 4, false, XA_CARDINAL);
|
||||
|
||||
auto workArea = getWorkArea (prop);
|
||||
|
||||
if (! workArea.isEmpty())
|
||||
{
|
||||
std::array<long, 4> position;
|
||||
|
||||
for (auto& p : position)
|
||||
{
|
||||
memcpy (&p, positionData, sizeof (long));
|
||||
positionData += sizeof (long);
|
||||
}
|
||||
|
||||
Displays::Display d;
|
||||
d.totalArea = { (int) position[0], (int) position[1],
|
||||
(int) position[2], (int) position[3] };
|
||||
|
||||
d.totalArea = workArea;
|
||||
d.isMain = displays.isEmpty();
|
||||
d.scale = masterScale;
|
||||
d.dpi = DisplayHelpers::getDisplayDPI (display, i);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue