Browse Source

One more fix from upstream

tags/2020-12-27
falkTX 3 years ago
parent
commit
596686a957
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 144 additions and 49 deletions
  1. +12
    -4
      libs/juce-current/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  2. +103
    -40
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
  3. +29
    -5
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h

+ 12
- 4
libs/juce-current/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -330,11 +330,17 @@ private:
class LinuxRepaintManager : public Timer
{
public:
LinuxRepaintManager (LinuxComponentPeer& p) : peer (p) {}
LinuxRepaintManager (LinuxComponentPeer& p)
: peer (p),
isSemiTransparentWindow ((peer.getStyleFlags() & ComponentPeer::windowIsSemiTransparent) != 0)
{
}
void timerCallback() override
{
if (XWindowSystem::getInstance()->getNumPaintsPending (peer.windowH) > 0)
XWindowSystem::getInstance()->processPendingPaintsForWindow (peer.windowH);
if (XWindowSystem::getInstance()->getNumPaintsPendingForWindow (peer.windowH) > 0)
return;
if (! regionsNeedingRepaint.isEmpty())
@@ -359,7 +365,7 @@ private:
void performAnyPendingRepaintsNow()
{
if (XWindowSystem::getInstance()->getNumPaintsPending (peer.windowH) > 0)
if (XWindowSystem::getInstance()->getNumPaintsPendingForWindow (peer.windowH) > 0)
{
startTimer (repaintTimerPeriod);
return;
@@ -374,7 +380,8 @@ private:
if (image.isNull() || image.getWidth() < totalArea.getWidth()
|| image.getHeight() < totalArea.getHeight())
{
image = XWindowSystem::getInstance()->createImage (totalArea.getWidth(), totalArea.getHeight(),
image = XWindowSystem::getInstance()->createImage (isSemiTransparentWindow,
totalArea.getWidth(), totalArea.getHeight(),
useARGBImagesForRendering);
}
@@ -407,6 +414,7 @@ private:
enum { repaintTimerPeriod = 1000 / 100 };
LinuxComponentPeer& peer;
const bool isSemiTransparentWindow;
Image image;
uint32 lastTimeImageUsed = 0;
RectangleList<int> regionsNeedingRepaint;


+ 103
- 40
libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp View File

@@ -643,16 +643,13 @@ namespace Visuals
}
//================================= X11 - Bitmap ===============================
static std::unordered_map<::Window, int> shmPaintsPendingMap;
class XBitmapImage : public ImagePixelData
{
public:
XBitmapImage (::Display* d, Image::PixelFormat format, int w, int h,
XBitmapImage (Image::PixelFormat format, int w, int h,
bool clearImage, unsigned int imageDepth_, Visual* visual)
: ImagePixelData (format, w, h),
imageDepth (imageDepth_),
display (d)
imageDepth (imageDepth_)
{
jassert (format == Image::RGB || format == Image::ARGB);
@@ -807,6 +804,11 @@ public:
{
XWindowSystemUtilities::ScopedXLock xLock;
#if JUCE_USE_XSHM
if (isUsingXShm())
XWindowSystem::getInstance()->addPendingPaintForWindow (window);
#endif
if (gc == None)
{
XGCValues gcvalues;
@@ -856,10 +858,7 @@ public:
// blit results to screen.
#if JUCE_USE_XSHM
if (isUsingXShm())
{
X11Symbols::getInstance()->xShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, True);
++shmPaintsPendingMap[window];
}
else
#endif
X11Symbols::getInstance()->xPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh);
@@ -878,7 +877,7 @@ private:
int pixelStride, lineStride;
uint8* imageData = nullptr;
GC gc = None;
::Display* display = nullptr;
::Display* display = XWindowSystem::getInstance()->getDisplay();
#if JUCE_USE_XSHM
XShmSegmentInfo segmentInfo;
@@ -1305,6 +1304,13 @@ static int getAllEventsMask (bool ignoresMouseClicks)
XWindowSystemUtilities::ScopedXLock xLock;
auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display));
auto visualAndDepth = displayVisuals->getBestVisualForWindow ((styleFlags & ComponentPeer::windowIsSemiTransparent) != 0);
auto colormap = X11Symbols::getInstance()->xCreateColormap (display, root, visualAndDepth.visual, AllocNone);
X11Symbols::getInstance()->xInstallColormap (display, colormap);
// Set up the window attributes
XSetWindowAttributes swa;
swa.border_pixel = 0;
@@ -1313,11 +1319,9 @@ static int getAllEventsMask (bool ignoresMouseClicks)
swa.override_redirect = ((styleFlags & ComponentPeer::windowIsTemporary) != 0) ? True : False;
swa.event_mask = getAllEventsMask (styleFlags & ComponentPeer::windowIgnoresMouseClicks);
auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display));
auto windowH = X11Symbols::getInstance()->xCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root,
0, 0, 1, 1,
0, depth, InputOutput, visual,
0, visualAndDepth.depth, InputOutput, visualAndDepth.visual,
CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect,
&swa);
@@ -1423,7 +1427,10 @@ void XWindowSystem::destroyWindow (::Window windowH)
&event) == True)
{}
shmPaintsPendingMap.erase (windowH);
#if JUCE_USE_XSHM
if (XSHMHelpers::isShmAvailable (display))
shmPaintsPendingMap.erase (windowH);
#endif
}
//==============================================================================
@@ -1808,16 +1815,18 @@ bool XWindowSystem::canUseARGBImages() const
return canUseARGB;
}
Image XWindowSystem::createImage (int width, int height, bool argb) const
Image XWindowSystem::createImage (bool isSemiTransparent, int width, int height, bool argb) const
{
auto visualAndDepth = displayVisuals->getBestVisualForWindow (isSemiTransparent);
#if JUCE_USE_XSHM
return Image (new XBitmapImage (display, argb ? Image::ARGB : Image::RGB,
return Image (new XBitmapImage (argb ? Image::ARGB : Image::RGB,
#else
return Image (new XBitmapImage (display, Image::RGB,
return Image (new XBitmapImage (Image::RGB,
#endif
(width + 31) & ~31,
(height + 31) & ~31,
false, (unsigned int) depth, visual));
false, (unsigned int) visualAndDepth.depth, visualAndDepth.visual));
}
void XWindowSystem::blitToWindow (::Window windowH, Image image, Rectangle<int> destinationRect, Rectangle<int> totalRect) const
@@ -1833,20 +1842,47 @@ void XWindowSystem::blitToWindow (::Window windowH, Image image, Rectangle<int>
destinationRect.getX() - totalRect.getX(), destinationRect.getY() - totalRect.getY());
}
int XWindowSystem::getNumPaintsPending (::Window windowH) const
void XWindowSystem::processPendingPaintsForWindow (::Window windowH)
{
#if JUCE_USE_XSHM
if (shmPaintsPendingMap[windowH] != 0)
if (! XSHMHelpers::isShmAvailable (display))
return;
if (getNumPaintsPendingForWindow (windowH) > 0)
{
XWindowSystemUtilities::ScopedXLock xLock;
XEvent evt;
while (X11Symbols::getInstance()->xCheckTypedWindowEvent (display, windowH, shmCompletionEvent, &evt))
--shmPaintsPendingMap[windowH];
removePendingPaintForWindow (windowH);
}
#endif
}
int XWindowSystem::getNumPaintsPendingForWindow (::Window windowH)
{
#if JUCE_USE_XSHM
if (XSHMHelpers::isShmAvailable (display))
return shmPaintsPendingMap[windowH];
#endif
return 0;
}
void XWindowSystem::addPendingPaintForWindow (::Window windowH)
{
#if JUCE_USE_XSHM
if (XSHMHelpers::isShmAvailable (display))
++shmPaintsPendingMap[windowH];
#endif
}
return shmPaintsPendingMap[windowH];
void XWindowSystem::removePendingPaintForWindow (::Window windowH)
{
#if JUCE_USE_XSHM
if (XSHMHelpers::isShmAvailable (display))
--shmPaintsPendingMap[windowH];
#endif
}
void XWindowSystem::setScreenSaverEnabled (bool enabled) const
@@ -2710,6 +2746,40 @@ long XWindowSystem::getUserTime (::Window windowH) const
return result;
}
XWindowSystem::DisplayVisuals::DisplayVisuals (::Display* xDisplay)
{
auto findVisualWithDepthOrNull = [&] (int desiredDepth) -> Visual*
{
int matchedDepth = 0;
auto* visual = Visuals::findVisualFormat (xDisplay, desiredDepth, matchedDepth);
if (desiredDepth == matchedDepth)
return visual;
return nullptr;
};
visual16Bit = findVisualWithDepthOrNull (16);
visual24Bit = findVisualWithDepthOrNull (24);
visual32Bit = findVisualWithDepthOrNull (32);
}
XWindowSystem::VisualAndDepth XWindowSystem::DisplayVisuals::getBestVisualForWindow (bool isSemiTransparent) const
{
if (isSemiTransparent && visual32Bit != nullptr)
return { visual32Bit, 32 };
if (visual24Bit != nullptr)
return { visual24Bit, 24 };
return { visual16Bit, 16 };
}
bool XWindowSystem::DisplayVisuals::isValid() const noexcept
{
return (visual32Bit != nullptr || visual24Bit != nullptr || visual16Bit != nullptr);
}
//==============================================================================
bool XWindowSystem::initialiseXDisplay()
{
@@ -2743,7 +2813,8 @@ bool XWindowSystem::initialiseXDisplay()
// Create our message window (this will never be mapped)
auto screen = X11Symbols::getInstance()->xDefaultScreen (display);
juce_messageWindowHandle = X11Symbols::getInstance()->xCreateWindow (display, X11Symbols::getInstance()->xRootWindow (display, screen),
auto root = X11Symbols::getInstance()->xRootWindow (display, screen);
juce_messageWindowHandle = X11Symbols::getInstance()->xCreateWindow (display, root,
0, 0, 1, 1, 0, 0, InputOnly,
X11Symbols::getInstance()->xDefaultVisual (display, screen),
CWEventMask, &swa);
@@ -2752,22 +2823,6 @@ bool XWindowSystem::initialiseXDisplay()
atoms = XWindowSystemUtilities::Atoms (display);
// Get defaults for various properties
auto root = X11Symbols::getInstance()->xRootWindow (display, screen);
// Try to obtain a 32-bit visual or fallback to 24 or 16
visual = Visuals::findVisualFormat (display, 32, depth);
if (visual == nullptr)
{
Logger::outputDebugString ("ERROR: System doesn't support 32, 24 or 16 bit RGB display.\n");
Process::terminate();
}
// Create and install a colormap suitable for our visual
colormap = X11Symbols::getInstance()->xCreateColormap (display, root, visual, AllocNone);
X11Symbols::getInstance()->xInstallColormap (display, colormap);
initialisePointerMap();
updateModifierMappings();
@@ -2776,6 +2831,14 @@ bool XWindowSystem::initialiseXDisplay()
shmCompletionEvent = X11Symbols::getInstance()->xShmGetEventBase (display) + ShmCompletion;
#endif
displayVisuals = std::make_unique<DisplayVisuals> (display);
if (! displayVisuals->isValid())
{
Logger::outputDebugString ("ERROR: System doesn't support 32, 24 or 16 bit RGB display.\n");
Process::terminate();
}
// Setup input event handler
LinuxEventLoop::registerFdCallback (X11Symbols::getInstance()->xConnectionNumber (display),
[this] (int)
@@ -2823,10 +2886,10 @@ void XWindowSystem::destroyXDisplay()
X11Symbols::getInstance()->xSync (display, True);
LinuxEventLoop::unregisterFdCallback (X11Symbols::getInstance()->xConnectionNumber (display));
visual = nullptr;
X11Symbols::getInstance()->xCloseDisplay (display);
display = nullptr;
displayVisuals = nullptr;
}
}
@@ -2905,7 +2968,7 @@ void XWindowSystem::handleWindowMessage (LinuxComponentPeer<::Window>* peer, XEv
XWindowSystemUtilities::ScopedXLock xLock;
if (event.xany.type == shmCompletionEvent)
--shmPaintsPendingMap[(::Window) peer->getNativeHandle()];
XWindowSystem::getInstance()->removePendingPaintForWindow ((::Window) peer->getNativeHandle());
}
#endif
break;


+ 29
- 5
libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h View File

@@ -126,9 +126,12 @@ public:
bool canUseSemiTransparentWindows() const;
bool canUseARGBImages() const;
int getNumPaintsPending (::Window windowH) const;
int getNumPaintsPendingForWindow (::Window windowH);
void processPendingPaintsForWindow (::Window windowH);
void addPendingPaintForWindow (::Window windowH);
void removePendingPaintForWindow (::Window windowH);
Image createImage (int width, int height, bool argb) const;
Image createImage (bool isSemiTransparentWindow, int width, int height, bool argb) const;
void blitToWindow (::Window windowH, Image image, Rectangle<int> destinationRect, Rectangle<int> totalRect) const;
void setScreenSaverEnabled (bool enabled) const;
@@ -171,6 +174,24 @@ private:
~XWindowSystem();
//==============================================================================
struct VisualAndDepth
{
Visual* visual;
int depth;
};
struct DisplayVisuals
{
explicit DisplayVisuals (::Display* d);
VisualAndDepth getBestVisualForWindow (bool isSemiTransparent) const;
bool isValid() const noexcept;
Visual* visual16Bit = nullptr;
Visual* visual24Bit = nullptr;
Visual* visual32Bit = nullptr;
};
bool initialiseXDisplay();
void destroyXDisplay();
@@ -217,10 +238,13 @@ private:
XWindowSystemUtilities::Atoms atoms;
::Display* display = nullptr;
Colormap colormap = {};
Visual* visual = nullptr;
std::unique_ptr<DisplayVisuals> displayVisuals;
#if JUCE_USE_XSHM
std::map<::Window, int> shmPaintsPendingMap;
#endif
int depth = 0, shmCompletionEvent = 0;
int shmCompletionEvent = 0;
int pointerMap[5] = {};
String localClipboardContent;


Loading…
Cancel
Save