1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Linux: Added X11Symbols and WebKitSymbols singletons to dynamically load X11 and WebKit library functions at runtime

This commit is contained in:
ed 2019-09-05 16:45:30 +01:00
parent ffb7b0730d
commit fe61354c21
21 changed files with 1835 additions and 959 deletions

View file

@ -81,8 +81,6 @@ namespace Vst2
#include "pluginterfaces/vst2.x/aeffectx.h"
}
using namespace juce;
JUCE_END_IGNORE_WARNINGS_MSVC
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
@ -92,8 +90,12 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#endif
#define JUCE_VSTINTERFACE_H_INCLUDED 1
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#include "../utility/juce_IncludeModuleHeaders.h"
using namespace juce;
#include "../utility/juce_FakeMouseMoveGenerator.h"
#include "../utility/juce_WindowsHooks.h"
@ -1086,7 +1088,7 @@ public:
#elif JUCE_LINUX
addToDesktop (0, args.ptr);
hostWindow = (Window) args.ptr;
XReparentWindow (display.display, (Window) getWindowHandle(), hostWindow, 0, 0);
X11Symbols::getInstance()->xReparentWindow (display.display, (Window) getWindowHandle(), hostWindow, 0, 0);
#else
hostWindow = attachComponentToWindowRefVST (this, args.ptr, wrapper.useNSView);
#endif
@ -1195,7 +1197,7 @@ public:
if (auto* peer = ed->getPeer())
scale *= (float) peer->getPlatformScaleFactor();
XResizeWindow (display.display, (Window) getWindowHandle(),
X11Symbols::getInstance()->xResizeWindow (display.display, (Window) getWindowHandle(),
static_cast<unsigned int> (roundToInt (pos.getWidth() * scale)),
static_cast<unsigned int> (roundToInt (pos.getHeight() * scale)));
#endif

View file

@ -29,19 +29,10 @@
#ifdef __INTEL_COMPILER
#pragma warning (disable : 1899)
#endif
#elif JUCE_LINUX
#include <float.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#undef Font
#undef KeyPress
#undef Drawable
#undef Time
#elif JUCE_ANDROID
#else
#elif JUCE_MAC || JUCE_IOS
#if ! (defined (JUCE_SUPPORT_CARBON) || defined (__LP64__))
#define JUCE_SUPPORT_CARBON 1
#endif

View file

@ -239,7 +239,7 @@ namespace
{
ScopedXDisplay xDisplay;
XQueryTree (xDisplay.display, windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren);
X11Symbols::getInstance()->xQueryTree (xDisplay.display, windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren);
}
if (numChildren > 0)
@ -2836,8 +2836,9 @@ public:
{
auto clip = g.getClipBounds();
XClearArea (display, pluginWindow, clip.getX(), clip.getY(),
static_cast<unsigned int> (clip.getWidth()), static_cast<unsigned int> (clip.getHeight()), True);
X11Symbols::getInstance()->xClearArea (display, pluginWindow, clip.getX(), clip.getY(),
static_cast<unsigned int> (clip.getWidth()),
static_cast<unsigned int> (clip.getHeight()), True);
}
#endif
}
@ -2875,13 +2876,13 @@ public:
#elif JUCE_LINUX
if (pluginWindow != 0)
{
XMoveResizeWindow (display, pluginWindow,
X11Symbols::getInstance()->xMoveResizeWindow (display, pluginWindow,
pos.getX(), pos.getY(),
static_cast<unsigned int> (roundToInt (getWidth() * nativeScaleFactor)),
static_cast<unsigned int> (roundToInt (getHeight() * nativeScaleFactor)));
XMapRaised (display, pluginWindow);
XFlush (display);
X11Symbols::getInstance()->xMapRaised (display, pluginWindow);
X11Symbols::getInstance()->xFlush (display);
}
#endif
@ -3160,7 +3161,7 @@ private:
}
if (pluginWindow != 0)
XMapRaised (display, pluginWindow);
X11Symbols::getInstance()->xMapRaised (display, pluginWindow);
#endif
w = roundToInt (w / nativeScaleFactor);

View file

@ -27,6 +27,7 @@
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#include "juce_audio_processors.h"
#include <juce_gui_extra/juce_gui_extra.h>

View file

@ -37,7 +37,7 @@
dependencies: juce_events
OSXFrameworks: Cocoa QuartzCore
iOSFrameworks: CoreGraphics CoreImage CoreText QuartzCore
linuxPackages: x11 xinerama xext freetype2
linuxPackages: freetype2
END_JUCE_MODULE_DECLARATION

View file

@ -33,6 +33,7 @@
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#include "juce_gui_basics.h"
@ -79,48 +80,6 @@
#pragma comment (lib, "D2d1.lib")
#endif
#endif
//==============================================================================
#elif JUCE_LINUX
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <X11/cursorfont.h>
#include <unistd.h>
#if JUCE_USE_XRANDR
/* If you're trying to use Xrandr, you'll need to install the "libxrandr-dev" package.. */
#include <X11/extensions/Xrandr.h>
#endif
#if JUCE_USE_XINERAMA
/* If you're trying to use Xinerama, you'll need to install the "libxinerama-dev" package.. */
#include <X11/extensions/Xinerama.h>
#endif
#if JUCE_USE_XSHM
#include <X11/extensions/XShm.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#endif
#if JUCE_USE_XRENDER
// If you're missing these headers, try installing the libxrender-dev and libxcomposite-dev
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xcomposite.h>
#endif
#if JUCE_USE_XCURSOR
// If you're missing this header, try installing the libxcursor-dev package
#include <X11/Xcursor/Xcursor.h>
#endif
#undef SIZEOF
#undef KeyPress
#endif
#include <set>
@ -291,6 +250,7 @@ namespace juce
#include "native/juce_win32_FileChooser.cpp"
#elif JUCE_LINUX
#include "native/juce_linux_X11Symbols.cpp"
#include "native/juce_linux_X11.cpp"
#include "native/juce_linux_X11_Clipboard.cpp"

View file

@ -37,7 +37,6 @@
dependencies: juce_graphics juce_data_structures
OSXFrameworks: Cocoa Carbon QuartzCore
iOSFrameworks: UIKit MobileCoreServices
linuxPackages: x11 xinerama xext
END_JUCE_MODULE_DECLARATION
@ -290,6 +289,51 @@ namespace juce
#if JUCE_LINUX
#include "native/juce_linux_X11.h"
#if JUCE_GUI_BASICS_INCLUDE_XHEADERS
// If you're missing these headers, you need to install the libx11-dev package
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <X11/cursorfont.h>
#include <unistd.h>
#if JUCE_USE_XRANDR
// If you're missing this header, you need to install the libxrandr-dev package
#include <X11/extensions/Xrandr.h>
#endif
#if JUCE_USE_XINERAMA
// If you're missing this header, you need to install the libxinerama-dev package
#include <X11/extensions/Xinerama.h>
#endif
#if JUCE_USE_XSHM
#include <X11/extensions/XShm.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#endif
#if JUCE_USE_XRENDER
// If you're missing these headers, you need to install the libxrender-dev and libxcomposite-dev packages
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xcomposite.h>
#endif
#if JUCE_USE_XCURSOR
// If you're missing this header, you need to install the libxcursor-dev package
#include <X11/Xcursor/Xcursor.h>
#endif
#undef SIZEOF
#undef KeyPress
#include "native/juce_linux_X11Symbols.h"
#endif
#endif
#include "layout/juce_FlexItem.h"

View file

@ -19,10 +19,11 @@
namespace juce
{
typedef void (*WindowMessageReceiveCallback) (XEvent&);
//==============================================================================
using WindowMessageReceiveCallback = void (*) (XEvent&);
WindowMessageReceiveCallback dispatchWindowMessage = nullptr;
typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&);
using SelectionRequestCallback = void (*) (XSelectionRequestEvent&);
SelectionRequestCallback handleSelectionRequest = nullptr;
::Window juce_messageWindowHandle;
@ -55,8 +56,9 @@ namespace X11ErrorHandling
char errorStr[64] = { 0 };
char requestStr[64] = { 0 };
XGetErrorText (display, event->error_code, errorStr, 64);
XGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64);
X11Symbols::getInstance()->xGetErrorText (display, event->error_code, errorStr, 64);
X11Symbols::getInstance()->xGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64);
DBG ("ERROR: X returned " << errorStr << " for operation " << requestStr);
#endif
@ -65,35 +67,37 @@ namespace X11ErrorHandling
void installXErrorHandlers()
{
oldIOErrorHandler = XSetIOErrorHandler (ioErrorHandler);
oldErrorHandler = XSetErrorHandler (errorHandler);
oldIOErrorHandler = X11Symbols::getInstance()->xSetIOErrorHandler (ioErrorHandler);
oldErrorHandler = X11Symbols::getInstance()->xSetErrorHandler (errorHandler);
}
void removeXErrorHandlers()
{
XSetIOErrorHandler (oldIOErrorHandler);
X11Symbols::getInstance()->xSetIOErrorHandler (oldIOErrorHandler);
oldIOErrorHandler = {};
XSetErrorHandler (oldErrorHandler);
X11Symbols::getInstance()->xSetErrorHandler (oldErrorHandler);
oldErrorHandler = {};
}
}
//==============================================================================
XWindowSystem::XWindowSystem() noexcept
{
if (JUCEApplicationBase::isStandaloneApp())
xIsAvailable = X11Symbols::getInstance()->areXFunctionsAvailable();
if (JUCEApplicationBase::isStandaloneApp() && xIsAvailable)
{
// Initialise xlib for multiple thread support
static bool initThreadCalled = false;
if (! initThreadCalled)
{
if (! XInitThreads())
if (! X11Symbols::getInstance()->xInitThreads())
{
// This is fatal! Print error and closedown
Logger::outputDebugString ("Failed to initialise xlib thread support.");
Process::terminate();
return;
}
@ -106,15 +110,18 @@ XWindowSystem::XWindowSystem() noexcept
XWindowSystem::~XWindowSystem() noexcept
{
if (JUCEApplicationBase::isStandaloneApp())
if (JUCEApplicationBase::isStandaloneApp() && xIsAvailable)
{
X11ErrorHandling::removeXErrorHandlers();
X11Symbols::deleteInstance();
}
clearSingletonInstance();
}
::Display* XWindowSystem::displayRef() noexcept
{
if (++displayCount == 1)
if (xIsAvailable && ++displayCount == 1)
{
jassert (display == nullptr);
@ -127,7 +134,7 @@ XWindowSystem::~XWindowSystem() noexcept
// fail the first time, but succeed on a second attempt..
for (int retries = 2; --retries >= 0;)
{
display = XOpenDisplay (displayName.toUTF8());
display = X11Symbols::getInstance()->xOpenDisplay (displayName.toUTF8());
if (display != nullptr)
break;
@ -141,21 +148,26 @@ XWindowSystem::~XWindowSystem() noexcept
::Display* XWindowSystem::displayUnref() noexcept
{
if (xIsAvailable)
{
jassert (display != nullptr);
jassert (displayCount.get() > 0);
if (--displayCount == 0)
{
destroyXDisplay();
XCloseDisplay (display);
X11Symbols::getInstance()->xCloseDisplay (display);
display = nullptr;
}
}
return display;
}
void XWindowSystem::initialiseXDisplay() noexcept
{
if (xIsAvailable)
{
// This is fatal! Print error and closedown
if (display == nullptr)
{
@ -164,25 +176,23 @@ void XWindowSystem::initialiseXDisplay() noexcept
}
// Create a context to store user data associated with Windows we create
windowHandleXContext = XUniqueContext();
windowHandleXContext = (XContext) X11Symbols::getInstance()->xrmUniqueQuark();
// We're only interested in client messages for this window, which are always sent
XSetWindowAttributes swa;
swa.event_mask = NoEventMask;
// Create our message window (this will never be mapped)
const int screen = DefaultScreen (display);
juce_messageWindowHandle = XCreateWindow (display, RootWindow (display, screen),
auto screen = X11Symbols::getInstance()->xDefaultScreen (display);
juce_messageWindowHandle = X11Symbols::getInstance()->xCreateWindow (display, X11Symbols::getInstance()->xRootWindow (display, screen),
0, 0, 1, 1, 0, 0, InputOnly,
DefaultVisual (display, screen),
X11Symbols::getInstance()->xDefaultVisual (display, screen),
CWEventMask, &swa);
XSync (display, False);
X11Symbols::getInstance()->xSync (display, False);
// Setup input event handler
int fd = XConnectionNumber (display);
LinuxEventLoop::registerFdCallback (fd,
LinuxEventLoop::registerFdCallback (X11Symbols::getInstance()->xConnectionNumber (display),
[this](int)
{
do
@ -192,10 +202,10 @@ void XWindowSystem::initialiseXDisplay() noexcept
{
ScopedXLock xlock (display);
if (! XPending (display))
if (! X11Symbols::getInstance()->xPending (display))
return;
XNextEvent (display, &evt);
X11Symbols::getInstance()->xNextEvent (display, &evt);
}
if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle
@ -211,21 +221,28 @@ void XWindowSystem::initialiseXDisplay() noexcept
} while (display != nullptr);
});
}
}
void XWindowSystem::destroyXDisplay() noexcept
{
if (xIsAvailable)
{
ScopedXLock xlock (display);
XDestroyWindow (display, juce_messageWindowHandle);
X11Symbols::getInstance()->xDestroyWindow (display, juce_messageWindowHandle);
juce_messageWindowHandle = 0;
XSync (display, True);
LinuxEventLoop::unregisterFdCallback (XConnectionNumber (display));
X11Symbols::getInstance()->xSync (display, True);
LinuxEventLoop::unregisterFdCallback (X11Symbols::getInstance()->xConnectionNumber (display));
}
}
JUCE_IMPLEMENT_SINGLETON (XWindowSystem)
//==============================================================================
ScopedXDisplay::ScopedXDisplay() : display (XWindowSystem::getInstance()->displayRef())
ScopedXDisplay::ScopedXDisplay()
: display (XWindowSystem::getInstance()->displayRef())
{
}
@ -235,16 +252,17 @@ ScopedXDisplay::~ScopedXDisplay()
}
//==============================================================================
ScopedXLock::ScopedXLock (::Display* d) : display (d)
ScopedXLock::ScopedXLock (::Display* d)
: display (d)
{
if (display != nullptr)
XLockDisplay (display);
X11Symbols::getInstance()->xLockDisplay (display);
}
ScopedXLock::~ScopedXLock()
{
if (display != nullptr)
XUnlockDisplay (display);
X11Symbols::getInstance()->xUnlockDisplay (display);
}
//==============================================================================
@ -292,15 +310,15 @@ Atoms::Atoms (::Display* display)
allowedActions[4] = XdndActionPrivate;
}
Atom Atoms::getIfExists (::Display* display, const char* name) { return XInternAtom (display, name, True); }
Atom Atoms::getCreating (::Display* display, const char* name) { return XInternAtom (display, name, False); }
Atom Atoms::getIfExists (::Display* display, const char* name) { return X11Symbols::getInstance()->xInternAtom (display, name, True); }
Atom Atoms::getCreating (::Display* display, const char* name) { return X11Symbols::getInstance()->xInternAtom (display, name, False); }
String Atoms::getName (::Display* display, const Atom atom)
{
if (atom == None)
return "None";
return String (XGetAtomName (display, atom));
return X11Symbols::getInstance()->xGetAtomName (display, atom);
}
bool Atoms::isMimeTypeFile (::Display* display, const Atom atom)
@ -316,7 +334,7 @@ GetXProperty::GetXProperty (::Display* display, Window window, Atom atom,
long offset, long length, bool shouldDelete,
Atom requestedType)
{
success = (XGetWindowProperty (display, window, atom, offset, length,
success = (X11Symbols::getInstance()->xGetWindowProperty (display, window, atom, offset, length,
(Bool) shouldDelete, requestedType, &actualType,
&actualFormat, &numItems, &bytesLeft, &data) == Success)
&& data != nullptr;
@ -325,7 +343,7 @@ GetXProperty::GetXProperty (::Display* display, Window window, Atom atom,
GetXProperty::~GetXProperty()
{
if (data != nullptr)
XFree (data);
X11Symbols::getInstance()->xFree (data);
}
} // namespace juce

View file

@ -37,6 +37,8 @@ public:
JUCE_DECLARE_SINGLETON (XWindowSystem, false)
private:
bool xIsAvailable = false;
XDisplay display = {};
Atomic<int> displayCount;
@ -80,7 +82,6 @@ public:
~ScopedXLock();
private:
// defined in juce_linux_X11.h
XDisplay display;
};
@ -131,39 +132,4 @@ struct GetXProperty
int actualFormat;
};
//==============================================================================
enum
{
maxXEmbedVersionToSupport = 0
};
enum
{
XEMBED_MAPPED = (1<<0)
};
enum
{
XEMBED_EMBEDDED_NOTIFY = 0,
XEMBED_WINDOW_ACTIVATE = 1,
XEMBED_WINDOW_DEACTIVATE = 2,
XEMBED_REQUEST_FOCUS = 3,
XEMBED_FOCUS_IN = 4,
XEMBED_FOCUS_OUT = 5,
XEMBED_FOCUS_NEXT = 6,
XEMBED_FOCUS_PREV = 7,
XEMBED_MODALITY_ON = 10,
XEMBED_MODALITY_OFF = 11,
XEMBED_REGISTER_ACCELERATOR = 12,
XEMBED_UNREGISTER_ACCELERATOR = 13,
XEMBED_ACTIVATE_ACCELERATOR = 14
};
enum
{
XEMBED_FOCUS_CURRENT = 0,
XEMBED_FOCUS_FIRST = 1,
XEMBED_FOCUS_LAST = 2
};
} // namespace juce

View file

@ -0,0 +1,236 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
namespace X11SymbolHelpers
{
template<typename FuncPtr>
struct SymbolBinding
{
FuncPtr& func;
const char* name;
};
template<typename FuncPtr>
SymbolBinding<FuncPtr> makeSymbolBinding (FuncPtr& func, const char* name)
{
return { func, name };
}
template <typename FuncPtr>
bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding)
{
if (auto* func = lib.getFunction (binding.name))
{
binding.func = reinterpret_cast<FuncPtr> (func);
return true;
}
return false;
}
template<typename FuncPtr, typename... Args>
bool loadSymbols (DynamicLibrary& lib1, DynamicLibrary& lib2, SymbolBinding<FuncPtr> binding)
{
return loadSymbols (lib1, binding) || loadSymbols (lib2, binding);
}
template<typename FuncPtr, typename... Args>
bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding, Args... args)
{
return loadSymbols (lib, binding) && loadSymbols (lib, args...);
}
template<typename FuncPtr, typename... Args>
bool loadSymbols (DynamicLibrary& lib1, DynamicLibrary& lib2, SymbolBinding<FuncPtr> binding, Args... args)
{
return loadSymbols (lib1, lib2, binding) && loadSymbols (lib1, lib2, args...);
}
}
//==============================================================================
bool X11Symbols::loadAllSymbols()
{
using namespace X11SymbolHelpers;
if (! loadSymbols (xLib, xextLib,
makeSymbolBinding (xAllocSizeHints, "XAllocSizeHints"),
makeSymbolBinding (xAllocWMHints, "XAllocWMHints"),
makeSymbolBinding (xBitmapBitOrder, "XBitmapBitOrder"),
makeSymbolBinding (xBitmapUnit, "XBitmapUnit"),
makeSymbolBinding (xChangeActivePointerGrab, "XChangeActivePointerGrab"),
makeSymbolBinding (xChangeProperty, "XChangeProperty"),
makeSymbolBinding (xCheckTypedWindowEvent, "XCheckTypedWindowEvent"),
makeSymbolBinding (xCheckWindowEvent, "XCheckWindowEvent"),
makeSymbolBinding (xClearArea, "XClearArea"),
makeSymbolBinding (xCloseDisplay, "XCloseDisplay"),
makeSymbolBinding (xConnectionNumber, "XConnectionNumber"),
makeSymbolBinding (xConvertSelection, "XConvertSelection"),
makeSymbolBinding (xCreateColormap, "XCreateColormap"),
makeSymbolBinding (xCreateFontCursor, "XCreateFontCursor"),
makeSymbolBinding (xCreateGC, "XCreateGC"),
makeSymbolBinding (xCreateImage, "XCreateImage"),
makeSymbolBinding (xCreatePixmap, "XCreatePixmap"),
makeSymbolBinding (xCreatePixmapCursor, "XCreatePixmapCursor"),
makeSymbolBinding (xCreatePixmapFromBitmapData, "XCreatePixmapFromBitmapData"),
makeSymbolBinding (xCreateWindow, "XCreateWindow"),
makeSymbolBinding (xDefaultRootWindow, "XDefaultRootWindow"),
makeSymbolBinding (xDefaultScreen, "XDefaultScreen"),
makeSymbolBinding (xDefaultScreenOfDisplay, "XDefaultScreenOfDisplay"),
makeSymbolBinding (xDefaultVisual, "XDefaultVisual"),
makeSymbolBinding (xDefineCursor, "XDefineCursor"),
makeSymbolBinding (xDeleteContext, "XDeleteContext"),
makeSymbolBinding (xDeleteProperty, "XDeleteProperty"),
makeSymbolBinding (xDestroyImage, "XDestroyImage"),
makeSymbolBinding (xDestroyWindow, "XDestroyWindow"),
makeSymbolBinding (xDisplayHeight, "XDisplayHeight"),
makeSymbolBinding (xDisplayHeightMM, "XDisplayHeightMM"),
makeSymbolBinding (xDisplayWidth, "XDisplayWidth"),
makeSymbolBinding (xDisplayWidthMM, "XDisplayWidthMM"),
makeSymbolBinding (xEventsQueued, "XEventsQueued"),
makeSymbolBinding (xFindContext, "XFindContext"),
makeSymbolBinding (xFlush, "XFlush"),
makeSymbolBinding (xFree, "XFree"),
makeSymbolBinding (xFreeCursor, "XFreeCursor"),
makeSymbolBinding (xFreeColormap, "XFreeColormap"),
makeSymbolBinding (xFreeGC, "XFreeGC"),
makeSymbolBinding (xFreeModifiermap, "XFreeModifiermap"),
makeSymbolBinding (xFreePixmap, "XFreePixmap"),
makeSymbolBinding (xGetAtomName, "XGetAtomName"),
makeSymbolBinding (xGetErrorDatabaseText, "XGetErrorDatabaseText"),
makeSymbolBinding (xGetErrorText, "XGetErrorText"),
makeSymbolBinding (xGetGeometry, "XGetGeometry"),
makeSymbolBinding (xGetInputFocus, "XGetInputFocus"),
makeSymbolBinding (xGetModifierMapping, "XGetModifierMapping"),
makeSymbolBinding (xGetPointerMapping, "XGetPointerMapping"),
makeSymbolBinding (xGetSelectionOwner, "XGetSelectionOwner"),
makeSymbolBinding (xGetVisualInfo, "XGetVisualInfo"),
makeSymbolBinding (xGetWMHints, "XGetWMHints"),
makeSymbolBinding (xGetWindowAttributes, "XGetWindowAttributes"),
makeSymbolBinding (xGetWindowProperty, "XGetWindowProperty"),
makeSymbolBinding (xGrabPointer, "XGrabPointer"),
makeSymbolBinding (xGrabServer, "XGrabServer"),
makeSymbolBinding (xImageByteOrder, "XImageByteOrder"),
makeSymbolBinding (xInitImage, "XInitImage"),
makeSymbolBinding (xInitThreads, "XInitThreads"),
makeSymbolBinding (xInstallColormap, "XInstallColormap"),
makeSymbolBinding (xInternAtom, "XInternAtom"),
makeSymbolBinding (xkbKeycodeToKeysym, "XkbKeycodeToKeysym"),
makeSymbolBinding (xKeysymToKeycode, "XKeysymToKeycode"),
makeSymbolBinding (xListProperties, "XListProperties"),
makeSymbolBinding (xLockDisplay, "XLockDisplay"),
makeSymbolBinding (xLookupString, "XLookupString"),
makeSymbolBinding (xMapRaised, "XMapRaised"),
makeSymbolBinding (xMapWindow, "XMapWindow"),
makeSymbolBinding (xMoveResizeWindow, "XMoveResizeWindow"),
makeSymbolBinding (xNextEvent, "XNextEvent"),
makeSymbolBinding (xOpenDisplay, "XOpenDisplay"),
makeSymbolBinding (xPeekEvent, "XPeekEvent"),
makeSymbolBinding (xPending, "XPending"),
makeSymbolBinding (xPutImage, "XPutImage"),
makeSymbolBinding (xPutPixel, "XPutPixel"),
makeSymbolBinding (xQueryBestCursor, "XQueryBestCursor"),
makeSymbolBinding (xQueryExtension, "XQueryExtension"),
makeSymbolBinding (xQueryPointer, "XQueryPointer"),
makeSymbolBinding (xQueryTree, "XQueryTree"),
makeSymbolBinding (xRefreshKeyboardMapping, "XRefreshKeyboardMapping"),
makeSymbolBinding (xReparentWindow, "XReparentWindow"),
makeSymbolBinding (xResizeWindow, "XResizeWindow"),
makeSymbolBinding (xRestackWindows, "XRestackWindows"),
makeSymbolBinding (xRootWindow, "XRootWindow"),
makeSymbolBinding (xSaveContext, "XSaveContext"),
makeSymbolBinding (xScreenCount, "XScreenCount"),
makeSymbolBinding (xScreenNumberOfScreen, "XScreenNumberOfScreen"),
makeSymbolBinding (xSelectInput, "XSelectInput"),
makeSymbolBinding (xSendEvent, "XSendEvent"),
makeSymbolBinding (xSetErrorHandler, "XSetErrorHandler"),
makeSymbolBinding (xSetIOErrorHandler, "XSetIOErrorHandler"),
makeSymbolBinding (xSetInputFocus, "XSetInputFocus"),
makeSymbolBinding (xSetSelectionOwner, "XSetSelectionOwner"),
makeSymbolBinding (xSetWMHints, "XSetWMHints"),
makeSymbolBinding (xSetWMIconName, "XSetWMIconName"),
makeSymbolBinding (xSetWMName, "XSetWMName"),
makeSymbolBinding (xSetWMNormalHints, "XSetWMNormalHints"),
makeSymbolBinding (xStringListToTextProperty, "XStringListToTextProperty"),
makeSymbolBinding (xSync, "XSync"),
makeSymbolBinding (xTranslateCoordinates, "XTranslateCoordinates"),
makeSymbolBinding (xrmUniqueQuark, "XrmUniqueQuark"),
makeSymbolBinding (xUngrabPointer, "XUngrabPointer"),
makeSymbolBinding (xUngrabServer, "XUngrabServer"),
makeSymbolBinding (xUnlockDisplay, "XUnlockDisplay"),
makeSymbolBinding (xUnmapWindow, "XUnmapWindow"),
makeSymbolBinding (xWarpPointer, "XWarpPointer")))
return false;
#if JUCE_USE_XCURSOR
loadSymbols (xcursorLib,
makeSymbolBinding (xcursorImageCreate, "XcursorImageCreate"),
makeSymbolBinding (xcursorImageLoadCursor, "XcursorImageLoadCursor"),
makeSymbolBinding (xcursorImageDestroy, "XcursorImageDestroy"));
#endif
#if JUCE_USE_XINERAMA
loadSymbols (xineramaLib,
makeSymbolBinding (xineramaIsActive, "XineramaIsActive"),
makeSymbolBinding (xineramaQueryScreens, "XineramaQueryScreens"));
#endif
#if JUCE_USE_XRENDER
loadSymbols (xrenderLib,
makeSymbolBinding (xRenderQueryVersion, "XRenderQueryVersion"),
makeSymbolBinding (xRenderFindStandardFormat, "XRenderFindStandardFormat"),
makeSymbolBinding (xRenderFindFormat, "XRenderFindFormat"),
makeSymbolBinding (xRenderFindVisualFormat, "XRenderFindVisualFormat"));
#endif
#if JUCE_USE_XRANDR
loadSymbols (xrandrLib,
makeSymbolBinding (xRRGetScreenResources, "XRRGetScreenResources"),
makeSymbolBinding (xRRFreeScreenResources, "XRRFreeScreenResources"),
makeSymbolBinding (xRRGetOutputInfo, "XRRGetOutputInfo"),
makeSymbolBinding (xRRFreeOutputInfo, "XRRFreeOutputInfo"),
makeSymbolBinding (xRRGetCrtcInfo, "XRRGetCrtcInfo"),
makeSymbolBinding (xRRFreeCrtcInfo, "XRRFreeCrtcInfo"),
makeSymbolBinding (xRRGetOutputPrimary, "XRRGetOutputPrimary"));
#endif
#if JUCE_USE_XSHM
loadSymbols (xLib, xextLib,
makeSymbolBinding (xShmAttach, "XShmAttach"),
makeSymbolBinding (xShmCreateImage, "XShmCreateImage"),
makeSymbolBinding (xShmDetach, "XShmDetach"),
makeSymbolBinding (xShmGetEventBase, "XShmGetEventBase"),
makeSymbolBinding (xShmPutImage, "XShmPutImage"),
makeSymbolBinding (xShmQueryVersion, "XShmQueryVersion"));
#endif
return true;
}
//==============================================================================
JUCE_IMPLEMENT_SINGLETON (X11Symbols)
}

View file

@ -0,0 +1,606 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
namespace ReturnHelpers
{
template<typename Type>
Type returnDefaultConstructedAnyType() { return {}; }
template<>
inline void returnDefaultConstructedAnyType<void>() {}
}
#define JUCE_GENERATE_FUNCTION_WITH_DEFAULT(functionName, objectName, args, returnType) \
using functionName = returnType (*) args; \
functionName objectName = [] args -> returnType { return ReturnHelpers::returnDefaultConstructedAnyType<returnType>(); };
//==============================================================================
class JUCE_API X11Symbols : public DeletedAtShutdown
{
public:
//==============================================================================
bool areXFunctionsAvailable() { return functionsAreAvailable; }
//==============================================================================
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XAllocSizeHints, xAllocSizeHints,
(),
XSizeHints*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XAllocWMHints, xAllocWMHints,
(),
XWMHints*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XBitmapBitOrder, xBitmapBitOrder,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XBitmapUnit, xBitmapUnit,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XChangeActivePointerGrab, xChangeActivePointerGrab,
(::Display*, unsigned int, Cursor, ::Time),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XChangeProperty, xChangeProperty,
(::Display*, ::Window, Atom, Atom, int, int, const unsigned char*, int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCheckTypedWindowEvent, xCheckTypedWindowEvent,
(::Display*, ::Window, int, XEvent*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCheckWindowEvent, xCheckWindowEvent,
(::Display*, ::Window, long, XEvent*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XClearArea, xClearArea,
(::Display*, ::Window, int, int, unsigned int, unsigned int, Bool),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCloseDisplay, xCloseDisplay,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XConnectionNumber, xConnectionNumber,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XConvertSelection, xConvertSelection,
(::Display*, Atom, Atom, Atom, ::Window, ::Time),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateColormap, xCreateColormap,
(::Display*, ::Window, Visual*, int),
Colormap)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateFontCursor, xCreateFontCursor,
(::Display*, unsigned int),
Cursor)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateGC, xCreateGC,
(::Display*, ::Drawable, unsigned long, XGCValues*),
GC)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateImage, xCreateImage,
(::Display*, Visual*, unsigned int, int, int, const char*, unsigned int, unsigned int, int, int),
XImage*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreatePixmap, xCreatePixmap,
(::Display*, ::Drawable, unsigned int, unsigned int, unsigned int),
Pixmap)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreatePixmapCursor, xCreatePixmapCursor,
(::Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int),
Cursor)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreatePixmapFromBitmapData, xCreatePixmapFromBitmapData,
(::Display*, ::Drawable, const char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int),
Pixmap)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateWindow, xCreateWindow,
(::Display*, ::Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*),
::Window)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultRootWindow, xDefaultRootWindow,
(::Display*),
::Window)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultScreen, xDefaultScreen,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultScreenOfDisplay, xDefaultScreenOfDisplay,
(::Display*),
Screen*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultVisual, xDefaultVisual,
(::Display*, int),
Visual*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefineCursor, xDefineCursor,
(::Display*, ::Window, Cursor),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDeleteContext, xDeleteContext,
(::Display*, XID, XContext),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDeleteProperty, xDeleteProperty,
(::Display*, Window, Atom),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDestroyImage, xDestroyImage,
(XImage*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDestroyWindow, xDestroyWindow,
(::Display*, ::Window),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayHeight, xDisplayHeight,
(::Display*, int),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayHeightMM, xDisplayHeightMM,
(::Display*, int),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayWidth, xDisplayWidth,
(::Display*, int),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayWidthMM, xDisplayWidthMM,
(::Display*, int),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XEventsQueued, xEventsQueued,
(::Display*, int),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFindContext, xFindContext,
(::Display*, XID, XContext, XPointer*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFlush, xFlush,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFree, xFree,
(void*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeCursor, xFreeCursor,
(::Display*, Cursor),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeColormap ,xFreeColormap,
(::Display*, Colormap),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeGC, xFreeGC,
(::Display*, GC),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeModifiermap, xFreeModifiermap,
(XModifierKeymap*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreePixmap, xFreePixmap,
(::Display*, Pixmap),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetAtomName, xGetAtomName,
(::Display*, Atom),
char*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetErrorDatabaseText, xGetErrorDatabaseText,
(::Display*, char*, const char*, const char*, int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetErrorText, xGetErrorText,
(::Display*, int, const char*, int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetGeometry, xGetGeometry,
(::Display*, ::Drawable, ::Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetInputFocus, xGetInputFocus,
(::Display*, ::Window*, int*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetModifierMapping, xGetModifierMapping,
(::Display*),
XModifierKeymap*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetPointerMapping, xGetPointerMapping,
(::Display*, unsigned char[], int),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetSelectionOwner, xGetSelectionOwner,
(::Display*, Atom),
::Window)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetVisualInfo, xGetVisualInfo,
(::Display*, long, XVisualInfo*, int*),
XVisualInfo*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetWMHints, xGetWMHints,
(::Display*, ::Window),
XWMHints*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetWindowAttributes, xGetWindowAttributes,
(::Display*, ::Window, XWindowAttributes*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetWindowProperty, xGetWindowProperty,
(::Display*, ::Window, Atom, long, long, Bool, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGrabPointer, xGrabPointer,
(::Display*, ::Window, Bool, unsigned int, int, int, ::Window, Cursor, ::Time),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGrabServer, xGrabServer,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XImageByteOrder, xImageByteOrder,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInitImage, xInitImage,
(XImage*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInitThreads, xInitThreads,
(),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInstallColormap, xInstallColormap,
(::Display*, Colormap),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInternAtom, xInternAtom,
(::Display*, const char*, Bool),
Atom)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XkbKeycodeToKeysym, xkbKeycodeToKeysym,
(::Display*, KeyCode, unsigned int, unsigned int),
KeySym)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XKeysymToKeycode, xKeysymToKeycode,
(::Display*, KeySym),
KeyCode)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XListProperties, xListProperties,
(::Display*, Window, int*),
Atom*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XLockDisplay, xLockDisplay,
(::Display*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XLookupString, xLookupString,
(XKeyEvent*, const char*, int, KeySym*, XComposeStatus*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XMapRaised, xMapRaised,
(::Display*, ::Window),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XMapWindow, xMapWindow,
(::Display*, ::Window),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XMoveResizeWindow, xMoveResizeWindow,
(::Display*, ::Window, int, int, unsigned int, unsigned int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XNextEvent, xNextEvent,
(::Display*, XEvent*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XOpenDisplay, xOpenDisplay,
(const char*),
::Display*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPeekEvent, xPeekEvent,
(::Display*, XEvent*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPending, xPending,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPutImage, xPutImage,
(::Display*, ::Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPutPixel, xPutPixel,
(XImage*, int, int, unsigned long),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryBestCursor, xQueryBestCursor,
(::Display*, ::Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryExtension, xQueryExtension,
(::Display*, const char*, int*, int*, int*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryPointer, xQueryPointer,
(::Display*, ::Window, ::Window*, ::Window*, int*, int*, int*, int*, unsigned int*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryTree, xQueryTree,
(::Display*, ::Window, ::Window*, ::Window*, ::Window**, unsigned int*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRefreshKeyboardMapping, xRefreshKeyboardMapping,
(XMappingEvent*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XReparentWindow, xReparentWindow,
(::Display*, ::Window, ::Window, int, int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XResizeWindow, xResizeWindow,
(::Display*, Window, unsigned int, unsigned int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRestackWindows, xRestackWindows,
(::Display*, ::Window[], int),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRootWindow, xRootWindow,
(::Display*, int),
::Window)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSaveContext, xSaveContext,
(::Display*, XID, XContext, XPointer),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XScreenCount, xScreenCount,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XScreenNumberOfScreen, xScreenNumberOfScreen,
(Screen*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSelectInput, xSelectInput,
(::Display*, ::Window, long),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSendEvent, xSendEvent,
(::Display*, ::Window, Bool, long, XEvent*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetErrorHandler, xSetErrorHandler,
(XErrorHandler),
XErrorHandler)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetIOErrorHandler, xSetIOErrorHandler,
(XIOErrorHandler),
XIOErrorHandler)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetInputFocus, xSetInputFocus,
(::Display*, ::Window, int, ::Time),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetSelectionOwner, xSetSelectionOwner,
(::Display*, Atom, ::Window, ::Time),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMHints, xSetWMHints,
(::Display*, ::Window, XWMHints*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMIconName, xSetWMIconName,
(::Display*, ::Window, XTextProperty*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMName, xSetWMName,
(::Display*, ::Window, XTextProperty*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMNormalHints, xSetWMNormalHints,
(::Display*, ::Window, XSizeHints*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XStringListToTextProperty, xStringListToTextProperty,
(char**, int, XTextProperty*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSync, xSync,
(::Display*, Bool),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XTranslateCoordinates, xTranslateCoordinates,
(::Display*, ::Window, ::Window, int, int, int*, int*, ::Window*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XrmUniqueQuark, xrmUniqueQuark,
(),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUngrabPointer, xUngrabPointer,
(::Display*, ::Time),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUngrabServer, xUngrabServer,
(::Display*),
int)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUnlockDisplay, xUnlockDisplay,
(::Display*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUnmapWindow, xUnmapWindow,
(::Display*, ::Window),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XWarpPointer, xWarpPointer,
(::Display*, ::Window, ::Window, int, int, unsigned int, unsigned int, int, int),
void)
#if JUCE_USE_XCURSOR
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XcursorImageCreate, xcursorImageCreate,
(int, int),
XcursorImage*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XcursorImageLoadCursor, xcursorImageLoadCursor,
(::Display*, XcursorImage*),
Cursor)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XcursorImageDestroy, xcursorImageDestroy,
(XcursorImage*),
void)
#endif
#if JUCE_USE_XINERAMA
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XineramaIsActive, xineramaIsActive,
(::Display*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XineramaQueryScreens, xineramaQueryScreens,
(::Display*, int*),
XineramaScreenInfo*)
#endif
#if JUCE_USE_XRENDER
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderQueryVersion, xRenderQueryVersion,
(::Display*, int*, int*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderFindStandardFormat, xRenderFindStandardFormat,
(Display*, int),
XRenderPictFormat*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderFindFormat, xRenderFindFormat,
(Display*, unsigned long, XRenderPictFormat*, int),
XRenderPictFormat*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderFindVisualFormat, xRenderFindVisualFormat,
(Display*, Visual*),
XRenderPictFormat*)
#endif
#if JUCE_USE_XRANDR
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetScreenResources, xRRGetScreenResources,
(::Display*, Window),
XRRScreenResources*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRFreeScreenResources, xRRFreeScreenResources,
(XRRScreenResources*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetOutputInfo, xRRGetOutputInfo,
(::Display*, XRRScreenResources*, RROutput),
XRROutputInfo*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRFreeOutputInfo, xRRFreeOutputInfo,
(XRROutputInfo*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetCrtcInfo, xRRGetCrtcInfo,
(::Display*, XRRScreenResources*, RRCrtc),
XRRCrtcInfo*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRFreeCrtcInfo, xRRFreeCrtcInfo,
(XRRCrtcInfo*),
void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetOutputPrimary, xRRGetOutputPrimary,
(::Display*, ::Window),
RROutput)
#endif
#if JUCE_USE_XSHM
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmAttach, xShmAttach,
(::Display*, XShmSegmentInfo*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmCreateImage, xShmCreateImage,
(::Display*, Visual*, unsigned int, int, const char*, XShmSegmentInfo*, unsigned int, unsigned int),
XImage*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmDetach, xShmDetach,
(::Display*, XShmSegmentInfo*),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmGetEventBase, xShmGetEventBase,
(::Display*),
Status)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmPutImage, xShmPutImage,
(::Display*, ::Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int, bool),
Bool)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmQueryVersion, xShmQueryVersion,
(::Display*, int*, int*, Bool*),
Bool)
#endif
//==============================================================================
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (X11Symbols)
private:
X11Symbols() = default;
~X11Symbols()
{
clearSingletonInstance();
}
//==============================================================================
bool loadAllSymbols();
//==============================================================================
DynamicLibrary xLib { "libX11.so" }, xextLib { "libXext.so" };
#if JUCE_USE_XCURSOR
DynamicLibrary xcursorLib { "libXcursor.so" };
#endif
#if JUCE_USE_XINERAMA
DynamicLibrary xineramaLib { "libXinerama.so" };
#endif
#if JUCE_USE_XRENDER
DynamicLibrary xrenderLib { "libXrender.so" };
#endif
#if JUCE_USE_XRANDR
DynamicLibrary xrandrLib { "libXrandr.so" };
#endif
const bool functionsAreAvailable = loadAllSymbols();
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (X11Symbols)
};
}

View file

@ -57,7 +57,7 @@ namespace ClipboardHelpers
int actualFormat;
unsigned long numItems, bytesLeft;
if (XGetWindowProperty (display, window, prop,
if (X11Symbols::getInstance()->xGetWindowProperty (display, window, prop,
0L /* offset */, 1000000 /* length (max) */, False,
AnyPropertyType /* format */,
&actualType, &actualFormat, &numItems, &bytesLeft,
@ -69,12 +69,12 @@ namespace ClipboardHelpers
returnData = String (clipData, numItems);
if (clipData != nullptr)
XFree (clipData);
X11Symbols::getInstance()->xFree (clipData);
jassert (bytesLeft == 0 || numItems == 1000000);
}
XDeleteProperty (display, window, prop);
X11Symbols::getInstance()->xDeleteProperty (display, window, prop);
}
return returnData;
@ -85,11 +85,11 @@ namespace ClipboardHelpers
static bool requestSelectionContent (::Display* display, String& selectionContent,
Atom selection, Atom requestedFormat)
{
Atom property_name = XInternAtom (display, "JUCE_SEL", false);
auto property_name = X11Symbols::getInstance()->xInternAtom (display, "JUCE_SEL", false);
// The selection owner will be asked to set the JUCE_SEL property on the
// juce_messageWindowHandle with the selection content
XConvertSelection (display, selection, requestedFormat, property_name,
X11Symbols::getInstance()->xConvertSelection (display, selection, requestedFormat, property_name,
juce_messageWindowHandle, CurrentTime);
int count = 50; // will wait at most for 200 ms
@ -98,7 +98,7 @@ namespace ClipboardHelpers
{
XEvent event;
if (XCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event))
if (X11Symbols::getInstance()->xCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event))
{
if (event.xselection.property == property_name)
{
@ -176,7 +176,7 @@ namespace ClipboardHelpers
// for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss
if (evt.property != None && numDataItems < maxReasonableSelectionSize)
{
XChangeProperty (evt.display, evt.requestor,
X11Symbols::getInstance()->xChangeProperty (evt.display, evt.requestor,
evt.property, evt.target,
propertyFormat /* 8 or 32 */, PropModeReplace,
reinterpret_cast<const unsigned char*> (data.getData()), (int) numDataItems);
@ -184,7 +184,7 @@ namespace ClipboardHelpers
}
}
XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply);
X11Symbols::getInstance()->xSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply);
}
}
@ -212,8 +212,8 @@ void SystemClipboard::copyTextToClipboard (const String& clipText)
ClipboardHelpers::initSelectionAtoms (display);
ClipboardHelpers::localClipboardContent = clipText;
XSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime);
XSetSelectionOwner (display, ClipboardHelpers::atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime);
X11Symbols::getInstance()->xSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime);
X11Symbols::getInstance()->xSetSelectionOwner (display, ClipboardHelpers::atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime);
}
}
@ -238,10 +238,10 @@ String SystemClipboard::getTextFromClipboard()
Atom selection = XA_PRIMARY;
Window selectionOwner = None;
if ((selectionOwner = XGetSelectionOwner (display, selection)) == None)
if ((selectionOwner = X11Symbols::getInstance()->xGetSelectionOwner (display, selection)) == None)
{
selection = ClipboardHelpers::atom_CLIPBOARD;
selectionOwner = XGetSelectionOwner (display, selection);
selectionOwner = X11Symbols::getInstance()->xGetSelectionOwner (display, selection);
}
if (selectionOwner != None)

File diff suppressed because it is too large Load diff

View file

@ -4704,10 +4704,12 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT
if (copyCursor == nullptr)
{
static unsigned char copyCursorData[] = { 71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,
128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0, 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,
78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174, 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,
252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };
static unsigned char copyCursorData[] = {
71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0,
21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,78,133,218,215,137,31,82,154,100,200,86,91,202,142,
12,108,212,87,235,174, 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,252,114,147,74,83,
5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0
};
const int copyCursorSize = 119;
copyCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), { 1, 3 }).create();

View file

@ -31,6 +31,7 @@
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#if JUCE_USE_WINRT_WEBVIEW
#define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1
@ -99,28 +100,18 @@
#endif
//==============================================================================
#elif JUCE_LINUX
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#undef SIZEOF
#undef KeyPress
#if JUCE_WEB_BROWSER
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#elif JUCE_LINUX && JUCE_WEB_BROWSER
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant", "-Wparentheses")
// If you're missing this header, you need to install the webkit2gtk-4.0 package
#include <gtk/gtk.h>
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
// If you're missing these headers, you need to install the webkit2gtk-4.0 package
#include <gtk/gtkx.h>
#include <glib-unix.h>
#include <webkit2/webkit2.h>
#endif
#endif
//==============================================================================

View file

@ -50,7 +50,7 @@
//==============================================================================
/** Config: JUCE_WEB_BROWSER
This lets you disable the WebBrowserComponent class (Mac and Windows).
This lets you disable the WebBrowserComponent class (Mac, Windows, and Linux).
If you're not using any embedded web-pages, turning this off may reduce your code size.
*/
#ifndef JUCE_WEB_BROWSER

View file

@ -29,21 +29,21 @@ public:
ScopedXLock xlock (display);
Screen* const screen = XDefaultScreenOfDisplay (display);
const int screenNumber = XScreenNumberOfScreen (screen);
auto* screen = X11Symbols::getInstance()->xDefaultScreenOfDisplay (display);
auto screenNumber = X11Symbols::getInstance()->xScreenNumberOfScreen (screen);
String screenAtom ("_NET_SYSTEM_TRAY_S");
screenAtom << screenNumber;
Atom selectionAtom = Atoms::getCreating (display, screenAtom.toUTF8());
XGrabServer (display);
Window managerWin = XGetSelectionOwner (display, selectionAtom);
X11Symbols::getInstance()->xGrabServer (display);
auto managerWin = X11Symbols::getInstance()->xGetSelectionOwner (display, selectionAtom);
if (managerWin != None)
XSelectInput (display, managerWin, StructureNotifyMask);
X11Symbols::getInstance()->xSelectInput (display, managerWin, StructureNotifyMask);
XUngrabServer (display);
XFlush (display);
X11Symbols::getInstance()->xUngrabServer (display);
X11Symbols::getInstance()->xFlush (display);
if (managerWin != None)
{
@ -58,26 +58,28 @@ public:
ev.xclient.data.l[3] = 0;
ev.xclient.data.l[4] = 0;
XSendEvent (display, managerWin, False, NoEventMask, &ev);
XSync (display, False);
X11Symbols::getInstance()->xSendEvent (display, managerWin, False, NoEventMask, &ev);
X11Symbols::getInstance()->xSync (display, False);
}
// For older KDE's ...
long atomData = 1;
Atom trayAtom = Atoms::getCreating (display, "KWM_DOCKWINDOW");
XChangeProperty (display, windowH, trayAtom, trayAtom, 32, PropModeReplace, (unsigned char*) &atomData, 1);
X11Symbols::getInstance()->xChangeProperty (display, windowH, trayAtom, trayAtom,
32, PropModeReplace, (unsigned char*) &atomData, 1);
// For more recent KDE's...
trayAtom = Atoms::getCreating (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR");
XChangeProperty (display, windowH, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char*) &windowH, 1);
X11Symbols::getInstance()->xChangeProperty (display, windowH, trayAtom, XA_WINDOW,
32, PropModeReplace, (unsigned char*) &windowH, 1);
// A minimum size must be specified for GNOME and Xfce, otherwise the icon is displayed with a width of 1
XSizeHints* hints = XAllocSizeHints();
auto* hints = X11Symbols::getInstance()->xAllocSizeHints();
hints->flags = PMinSize;
hints->min_width = 22;
hints->min_height = 22;
XSetWMNormalHints (display, windowH, hints);
XFree (hints);
X11Symbols::getInstance()->xSetWMNormalHints (display, windowH, hints);
X11Symbols::getInstance()->xFree (hints);
}
Image image;

View file

@ -19,6 +19,186 @@
namespace juce
{
//==============================================================================
class WebKitSymbols : public DeletedAtShutdown
{
public:
//==============================================================================
bool isWebKitAvailable() { return webKitIsAvailable; }
//==============================================================================
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_settings_new, juce_webkit_settings_new,
(), WebKitSettings*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_settings_set_hardware_acceleration_policy, juce_webkit_settings_set_hardware_acceleration_policy,
(WebKitSettings*, int), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_new_with_settings, juce_webkit_web_view_new_with_settings,
(WebKitSettings*), GtkWidget*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_load_uri, juce_webkit_web_view_load_uri,
(WebKitWebView*, const gchar*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_policy_decision_use, juce_webkit_policy_decision_use,
(WebKitPolicyDecision*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_policy_decision_ignore, juce_webkit_policy_decision_ignore,
(WebKitPolicyDecision*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_go_back, juce_webkit_web_view_go_back,
(WebKitWebView*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_go_forward, juce_webkit_web_view_go_forward,
(WebKitWebView*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_reload, juce_webkit_web_view_reload,
(WebKitWebView*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_stop_loading, juce_webkit_web_view_stop_loading,
(WebKitWebView*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_uri_request_get_uri, juce_webkit_uri_request_get_uri,
(WebKitURIRequest*), const gchar*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_navigation_action_get_request, juce_webkit_navigation_action_get_request,
(WebKitNavigationAction*), WebKitURIRequest*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_navigation_policy_decision_get_frame_name, juce_webkit_navigation_policy_decision_get_frame_name,
(WebKitNavigationPolicyDecision*), const gchar*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_navigation_policy_decision_get_navigation_action, juce_webkit_navigation_policy_decision_get_navigation_action,
(WebKitNavigationPolicyDecision*), WebKitNavigationAction*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_get_uri, juce_webkit_web_view_get_uri,
(WebKitWebView*), const gchar*)
//==============================================================================
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_init, juce_gtk_init,
(int*, char***), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_plug_new, juce_gtk_plug_new,
(::Window), GtkWidget*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_scrolled_window_new, juce_gtk_scrolled_window_new,
(GtkAdjustment*, GtkAdjustment*), GtkWidget*)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_container_add, juce_gtk_container_add,
(GtkContainer*, GtkWidget*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_widget_show_all, juce_gtk_widget_show_all,
(GtkWidget*), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_plug_get_id, juce_gtk_plug_get_id,
(GtkPlug*), ::Window)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_main, juce_gtk_main,
(), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_main_quit, juce_gtk_main_quit,
(), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_unix_fd_add, juce_g_unix_fd_add,
(gint, GIOCondition, GUnixFDSourceFunc, gpointer), guint)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_object_ref, juce_g_object_ref,
(gpointer), gpointer)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_object_unref, juce_g_object_unref,
(gpointer), void)
JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_signal_connect_data, juce_g_signal_connect_data,
(gpointer, const gchar*, GCallback, gpointer, GClosureNotify, GConnectFlags), gulong)
//==============================================================================
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (WebKitSymbols)
private:
WebKitSymbols() = default;
~WebKitSymbols()
{
clearSingletonInstance();
}
template<typename FuncPtr>
struct SymbolBinding
{
FuncPtr& func;
const char* name;
};
template<typename FuncPtr>
SymbolBinding<FuncPtr> makeSymbolBinding (FuncPtr& func, const char* name)
{
return { func, name };
}
template <typename FuncPtr>
bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding)
{
if (auto* func = lib.getFunction (binding.name))
{
binding.func = reinterpret_cast<FuncPtr> (func);
return true;
}
return false;
}
template<typename FuncPtr, typename... Args>
bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding, Args... args)
{
return loadSymbols (lib, binding) && loadSymbols (lib, args...);
}
//==============================================================================
bool loadWebkitSymbols()
{
return loadSymbols (webkitLib,
makeSymbolBinding (juce_webkit_settings_new, "webkit_settings_new"),
makeSymbolBinding (juce_webkit_settings_set_hardware_acceleration_policy, "webkit_settings_set_hardware_acceleration_policy"),
makeSymbolBinding (juce_webkit_web_view_new_with_settings, "webkit_web_view_new_with_settings"),
makeSymbolBinding (juce_webkit_policy_decision_use, "webkit_policy_decision_use"),
makeSymbolBinding (juce_webkit_policy_decision_ignore, "webkit_policy_decision_ignore"),
makeSymbolBinding (juce_webkit_web_view_go_back, "webkit_web_view_go_back"),
makeSymbolBinding (juce_webkit_web_view_go_forward, "webkit_web_view_go_forward"),
makeSymbolBinding (juce_webkit_web_view_reload, "webkit_web_view_reload"),
makeSymbolBinding (juce_webkit_web_view_stop_loading, "webkit_web_view_stop_loading"),
makeSymbolBinding (juce_webkit_uri_request_get_uri, "webkit_uri_request_get_uri"),
makeSymbolBinding (juce_webkit_web_view_load_uri, "webkit_web_view_load_uri"),
makeSymbolBinding (juce_webkit_navigation_action_get_request, "webkit_navigation_action_get_request"),
makeSymbolBinding (juce_webkit_navigation_policy_decision_get_frame_name, "webkit_navigation_policy_decision_get_frame_name"),
makeSymbolBinding (juce_webkit_navigation_policy_decision_get_navigation_action, "webkit_navigation_policy_decision_get_navigation_action"),
makeSymbolBinding (juce_webkit_web_view_get_uri, "webkit_web_view_get_uri"));
}
bool loadGtkSymbols()
{
return loadSymbols (gtkLib,
makeSymbolBinding (juce_gtk_init, "gtk_init"),
makeSymbolBinding (juce_gtk_plug_new, "gtk_plug_new"),
makeSymbolBinding (juce_gtk_scrolled_window_new, "gtk_scrolled_window_new"),
makeSymbolBinding (juce_gtk_container_add, "gtk_container_add"),
makeSymbolBinding (juce_gtk_widget_show_all, "gtk_widget_show_all"),
makeSymbolBinding (juce_gtk_plug_get_id, "gtk_plug_get_id"),
makeSymbolBinding (juce_gtk_main, "gtk_main"),
makeSymbolBinding (juce_gtk_main_quit, "gtk_main_quit"),
makeSymbolBinding (juce_g_unix_fd_add, "g_unix_fd_add"),
makeSymbolBinding (juce_g_object_ref, "g_object_ref"),
makeSymbolBinding (juce_g_object_unref, "g_object_unref"),
makeSymbolBinding (juce_g_signal_connect_data, "g_signal_connect_data"));
}
//==============================================================================
DynamicLibrary gtkLib { "libgtk-3.so" }, webkitLib { "libwebkit2gtk-4.0.so" };
const bool webKitIsAvailable = loadWebkitSymbols() && loadGtkSymbols();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebKitSymbols)
};
JUCE_IMPLEMENT_SINGLETON (WebKitSymbols)
//==============================================================================
extern int juce_gtkWebkitMain (int argc, const char* argv[]);
class CommandReceiver
@ -40,7 +220,7 @@ public:
static void setBlocking (int fd, bool shouldBlock)
{
int flags = fcntl (fd, F_GETFL);
auto flags = fcntl (fd, F_GETFL);
fcntl (fd, F_SETFL, (shouldBlock ? (flags & ~O_NONBLOCK)
: (flags | O_NONBLOCK)));
}
@ -51,14 +231,14 @@ public:
{
for (;;)
{
size_t len = (receivingLength ? sizeof (size_t) : bufferLength.len);
auto len = (receivingLength ? sizeof (size_t) : bufferLength.len);
if (! receivingLength)
buffer.realloc (len);
char* dst = (receivingLength ? bufferLength.data : buffer.getData());
auto* dst = (receivingLength ? bufferLength.data : buffer.getData());
ssize_t actual = read (inChannel, &dst[pos], static_cast<size_t> (len - pos));
auto actual = read (inChannel, &dst[pos], static_cast<size_t> (len - pos));
if (actual < 0)
{
@ -94,13 +274,13 @@ public:
if (! params.isVoid())
obj->setProperty (getParamIdentifier(), params);
String json (JSON::toString (var (obj.get())));
auto json = JSON::toString (var (obj.get()));
size_t jsonLength = static_cast<size_t> (json.length());
size_t len = sizeof (size_t) + jsonLength;
auto jsonLength = static_cast<size_t> (json.length());
auto len = sizeof (size_t) + jsonLength;
HeapBlock<char> buffer (len);
char* dst = buffer.getData();
auto* dst = buffer.getData();
memcpy (dst, &jsonLength, sizeof (size_t));
dst += sizeof (size_t);
@ -109,21 +289,24 @@ public:
ssize_t ret;
do
for (;;)
{
ret = write (outChannel, buffer.getData(), len);
} while (ret == -1 && errno == EINTR);
if (ret != -1 || errno != EINTR)
break;
}
}
private:
void parseJSON (const String& json)
{
var object (JSON::fromString (json));
auto object = JSON::fromString (json);
if (! object.isVoid())
{
String cmd (object.getProperty (getCmdIdentifier(), var()).toString());
var params (object.getProperty (getParamIdentifier(), var()));
auto cmd = object.getProperty (getCmdIdentifier(), {}).toString();
auto params = object.getProperty (getParamIdentifier(), {});
if (responder != nullptr)
responder->handleCommand (cmd, params);
@ -133,105 +316,101 @@ private:
static Identifier getCmdIdentifier() { static Identifier Id ("cmd"); return Id; }
static Identifier getParamIdentifier() { static Identifier Id ("params"); return Id; }
Responder* responder;
int inChannel;
Responder* responder = nullptr;
int inChannel = 0;
size_t pos = 0;
bool receivingLength = true;
union { char data [sizeof (size_t)]; size_t len; } bufferLength;
HeapBlock<char> buffer;
};
#define juce_g_signal_connect(instance, detailed_signal, c_handler, data) \
WebKitSymbols::getInstance()->juce_g_signal_connect_data (instance, detailed_signal, c_handler, data, nullptr, (GConnectFlags) 0)
//==============================================================================
class GtkChildProcess : private CommandReceiver::Responder
{
public:
//==============================================================================
GtkChildProcess (int inChannel, int outChannelToUse)
: outChannel (outChannelToUse), receiver (this, inChannel)
: outChannel (outChannelToUse),
receiver (this, inChannel)
{}
typedef void (*SetHardwareAcclPolicyFunctionPtr) (WebKitSettings*, int);
int entry()
{
CommandReceiver::setBlocking (outChannel, true);
gtk_init (nullptr, nullptr);
WebKitSymbols::getInstance()->juce_gtk_init (nullptr, nullptr);
WebKitSettings* settings = webkit_settings_new();
auto* settings = WebKitSymbols::getInstance()->juce_webkit_settings_new();
WebKitSymbols::getInstance()->juce_webkit_settings_set_hardware_acceleration_policy (settings,
/* WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER */ 2);
// webkit_settings_set_hardware_acceleration_policy was only added recently to webkit2
// but is needed when running a WebBrowserComponent in a Parallels VM with 3D acceleration enabled
auto setHardwarePolicy
= reinterpret_cast<SetHardwareAcclPolicyFunctionPtr> (dlsym (RTLD_DEFAULT, "webkit_settings_set_hardware_acceleration_policy"));
auto* plug = WebKitSymbols::getInstance()->juce_gtk_plug_new (0);
auto* container = WebKitSymbols::getInstance()->juce_gtk_scrolled_window_new (nullptr, nullptr);
if (setHardwarePolicy != nullptr)
setHardwarePolicy (settings, 2 /*WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER*/);
auto* webviewWidget = WebKitSymbols::getInstance()->juce_webkit_web_view_new_with_settings (settings);
webview = (WebKitWebView*) webviewWidget;
GtkWidget *plug;
WebKitSymbols::getInstance()->juce_gtk_container_add ((GtkContainer*) container, webviewWidget);
WebKitSymbols::getInstance()->juce_gtk_container_add ((GtkContainer*) plug, container);
plug = gtk_plug_new(0);
GtkWidget* container;
container = gtk_scrolled_window_new (nullptr, nullptr);
WebKitSymbols::getInstance()->juce_webkit_web_view_load_uri (webview, "about:blank");
GtkWidget* webviewWidget = webkit_web_view_new_with_settings (settings);
webview = WEBKIT_WEB_VIEW (webviewWidget);
juce_g_signal_connect (webview, "decide-policy",
(GCallback) decidePolicyCallback, this);
juce_g_signal_connect (webview, "load-changed",
(GCallback) loadChangedCallback, this);
gtk_container_add (GTK_CONTAINER (container), webviewWidget);
gtk_container_add (GTK_CONTAINER (plug), container);
webkit_web_view_load_uri (webview, "about:blank");
g_signal_connect (webview, "decide-policy",
G_CALLBACK (decidePolicyCallback), this);
g_signal_connect (webview, "load-changed",
G_CALLBACK (loadChangedCallback), this);
g_signal_connect (webview, "load-failed",
G_CALLBACK (loadFailedCallback), this);
gtk_widget_show_all (plug);
unsigned long wID = (unsigned long) gtk_plug_get_id (GTK_PLUG (plug));
juce_g_signal_connect (webview, "load-failed",
(GCallback) loadFailedCallback, this);
WebKitSymbols::getInstance()->juce_gtk_widget_show_all (plug);
auto wID = (unsigned long) WebKitSymbols::getInstance()->juce_gtk_plug_get_id ((GtkPlug*) plug);
ssize_t ret;
do {
for (;;)
{
ret = write (outChannel, &wID, sizeof (wID));
} while (ret == -1 && errno == EINTR);
g_unix_fd_add (receiver.getFd(), G_IO_IN, pipeReadyStatic, this);
if (ret != -1 || errno != EINTR)
break;
}
WebKitSymbols::getInstance()->juce_g_unix_fd_add (receiver.getFd(), G_IO_IN, pipeReadyStatic, this);
receiver.tryNextRead();
gtk_main();
WebKitSymbols::getInstance()->juce_gtk_main();
WebKitSymbols::getInstance()->deleteInstance();
return 0;
}
void goToURL (const var& params)
{
static Identifier urlIdentifier ("url");
String url (params.getProperty (urlIdentifier, var()).toString());
auto url = params.getProperty (urlIdentifier, var()).toString();
webkit_web_view_load_uri (webview, url.toRawUTF8());
WebKitSymbols::getInstance()->juce_webkit_web_view_load_uri (webview, url.toRawUTF8());
}
void handleDecisionResponse (const var& params)
{
WebKitPolicyDecision* decision
= (WebKitPolicyDecision*) ((int64) params.getProperty ("decision_id", var (0)));
auto* decision = (WebKitPolicyDecision*) ((int64) params.getProperty ("decision_id", var (0)));
bool allow = params.getProperty ("allow", var (false));
if (decision != nullptr && decisions.contains (decision))
{
if (allow)
webkit_policy_decision_use (decision);
WebKitSymbols::getInstance()->juce_webkit_policy_decision_use (decision);
else
webkit_policy_decision_ignore (decision);
WebKitSymbols::getInstance()->juce_webkit_policy_decision_ignore (decision);
decisions.removeAllInstancesOf (decision);
g_object_unref (decision);
WebKitSymbols::getInstance()->juce_g_object_unref (decision);
}
}
@ -240,10 +419,10 @@ public:
{
if (cmd == "quit") quit();
else if (cmd == "goToURL") goToURL (params);
else if (cmd == "goBack") webkit_web_view_go_back (webview);
else if (cmd == "goForward") webkit_web_view_go_forward (webview);
else if (cmd == "refresh") webkit_web_view_reload (webview);
else if (cmd == "stop") webkit_web_view_stop_loading (webview);
else if (cmd == "goBack") WebKitSymbols::getInstance()->juce_webkit_web_view_go_back (webview);
else if (cmd == "goForward") WebKitSymbols::getInstance()->juce_webkit_web_view_go_forward (webview);
else if (cmd == "refresh") WebKitSymbols::getInstance()->juce_webkit_web_view_reload (webview);
else if (cmd == "stop") WebKitSymbols::getInstance()->juce_webkit_web_view_stop_loading (webview);
else if (cmd == "decision") handleDecisionResponse (params);
}
@ -266,7 +445,13 @@ public:
void quit()
{
gtk_main_quit();
WebKitSymbols::getInstance()->juce_gtk_main_quit();
}
String getURIStringForAction (WebKitNavigationAction* action)
{
auto* request = WebKitSymbols::getInstance()->juce_webkit_navigation_action_get_request (action);
return WebKitSymbols::getInstance()->juce_webkit_uri_request_get_uri (request);
}
bool onNavigation (String frameName,
@ -275,12 +460,12 @@ public:
{
if (decision != nullptr && frameName.isEmpty())
{
g_object_ref (decision);
WebKitSymbols::getInstance()->juce_g_object_ref (decision);
decisions.add (decision);
DynamicObject::Ptr params = new DynamicObject;
params->setProperty ("url", String (webkit_uri_request_get_uri (webkit_navigation_action_get_request (action))));
params->setProperty ("url", getURIStringForAction (action));
params->setProperty ("decision_id", (int64) decision);
CommandReceiver::sendCommand (outChannel, "pageAboutToLoad", var (params.get()));
@ -298,11 +483,11 @@ public:
{
DynamicObject::Ptr params = new DynamicObject;
params->setProperty ("url", String (webkit_uri_request_get_uri (webkit_navigation_action_get_request (action))));
params->setProperty ("url", getURIStringForAction (action));
CommandReceiver::sendCommand (outChannel, "newWindowAttemptingToLoad", var (params.get()));
// never allow new windows
webkit_policy_decision_ignore (decision);
WebKitSymbols::getInstance()->juce_webkit_policy_decision_ignore (decision);
return true;
}
@ -316,7 +501,7 @@ public:
{
DynamicObject::Ptr params = new DynamicObject;
params->setProperty ("url", String (webkit_web_view_get_uri (webview)));
params->setProperty ("url", String (WebKitSymbols::getInstance()->juce_webkit_web_view_get_uri (webview)));
CommandReceiver::sendCommand (outChannel, "pageFinishedLoading", var (params.get()));
}
}
@ -328,31 +513,31 @@ public:
{
case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
{
WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
const char* frameName = webkit_navigation_policy_decision_get_frame_name (navigationDecision);
auto* navigationDecision = (WebKitNavigationPolicyDecision*) decision;
auto* frameName = WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_frame_name (navigationDecision);
return onNavigation (String (frameName != nullptr ? frameName : ""),
webkit_navigation_policy_decision_get_navigation_action (navigationDecision),
WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_navigation_action (navigationDecision),
decision);
}
break;
case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
{
WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
const char* frameName = webkit_navigation_policy_decision_get_frame_name (navigationDecision);
auto* navigationDecision = (WebKitNavigationPolicyDecision*) decision;
auto* frameName = WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_frame_name (navigationDecision);
return onNewWindow (String (frameName != nullptr ? frameName : ""),
webkit_navigation_policy_decision_get_navigation_action (navigationDecision),
WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_navigation_action (navigationDecision),
decision);
}
break;
case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
{
WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision);
auto* response = (WebKitNavigationPolicyDecision*) decision;
// for now just always allow response requests
ignoreUnused (response);
webkit_policy_decision_use (decision);
WebKitSymbols::getInstance()->juce_webkit_policy_decision_use (decision);
return true;
}
break;
@ -382,7 +567,7 @@ private:
WebKitPolicyDecisionType decisionType,
gpointer user)
{
GtkChildProcess& owner = *reinterpret_cast<GtkChildProcess*> (user);
auto& owner = *reinterpret_cast<GtkChildProcess*> (user);
return (owner.onDecidePolicy (decision, decisionType) ? TRUE : FALSE);
}
@ -390,7 +575,7 @@ private:
WebKitLoadEvent loadEvent,
gpointer user)
{
GtkChildProcess& owner = *reinterpret_cast<GtkChildProcess*> (user);
auto& owner = *reinterpret_cast<GtkChildProcess*> (user);
owner.onLoadChanged (loadEvent);
}
@ -400,11 +585,11 @@ private:
GError* error,
gpointer user)
{
GtkChildProcess& owner = *reinterpret_cast<GtkChildProcess*> (user);
auto& owner = *reinterpret_cast<GtkChildProcess*> (user);
owner.onLoadFailed (error);
}
int outChannel;
int outChannel = 0;
CommandReceiver receiver;
WebKitWebView* webview = nullptr;
Array<WebKitPolicyDecision*> decisions;
@ -417,7 +602,9 @@ class WebBrowserComponent::Pimpl : private Thread,
public:
Pimpl (WebBrowserComponent& parent)
: Thread ("Webview"), owner (parent)
{}
{
webKitIsAvailable = WebKitSymbols::getInstance()->isWebKitAvailable();
}
~Pimpl() override
{
@ -427,9 +614,12 @@ public:
//==============================================================================
void init()
{
if (! webKitIsAvailable)
return;
launchChild();
int ret = pipe (threadControl);
auto ret = pipe (threadControl);
ignoreUnused (ret);
jassert (ret == 0);
@ -440,7 +630,7 @@ public:
CommandReceiver::setBlocking (threadControl[1], true);
unsigned long windowHandle;
ssize_t actual = read (inChannel, &windowHandle, sizeof (windowHandle));
auto actual = read (inChannel, &windowHandle, sizeof (windowHandle));
if (actual != (ssize_t) sizeof (windowHandle))
{
@ -461,6 +651,9 @@ public:
void quit()
{
if (! webKitIsAvailable)
return;
if (isThreadRunning())
{
signalThreadShouldExit();
@ -468,10 +661,13 @@ public:
char ignore = 0;
ssize_t ret;
do
for (;;)
{
ret = write (threadControl[1], &ignore, 1);
} while (ret == -1 && errno == EINTR);
if (ret != -1 || errno != EINTR)
break;
}
waitForThreadToExit (-1);
receiver = nullptr;
@ -479,7 +675,7 @@ public:
if (childProcess != 0)
{
CommandReceiver::sendCommand (outChannel, "quit", var());
CommandReceiver::sendCommand (outChannel, "quit", {});
killChild();
}
}
@ -487,6 +683,9 @@ public:
//==============================================================================
void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData)
{
if (! webKitIsAvailable)
return;
DynamicObject::Ptr params = new DynamicObject;
params->setProperty ("url", url);
@ -500,16 +699,17 @@ public:
CommandReceiver::sendCommand (outChannel, "goToURL", var (params.get()));
}
void goBack() { CommandReceiver::sendCommand (outChannel, "goBack", var()); }
void goForward() { CommandReceiver::sendCommand (outChannel, "goForward", var()); }
void refresh() { CommandReceiver::sendCommand (outChannel, "refresh", var()); }
void stop() { CommandReceiver::sendCommand (outChannel, "stop", var()); }
void goBack() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "goBack", {}); }
void goForward() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "goForward", {}); }
void refresh() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "refresh", {}); }
void stop() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "stop", {}); }
void resized()
{
if (xembed != nullptr)
xembed->setBounds (owner.getLocalBounds());
}
private:
//==============================================================================
void killChild()
@ -518,7 +718,7 @@ private:
{
xembed = nullptr;
int status = 0, result;
int status = 0, result = 0;
result = waitpid (childProcess, &status, WNOHANG);
for (int i = 0; i < 15 && (! WIFEXITED(status) || result != childProcess); ++i)
@ -531,11 +731,14 @@ private:
status = 0;
if (! WIFEXITED(status) || result != childProcess)
{
do
for (;;)
{
kill (childProcess, SIGTERM);
waitpid (childProcess, &status, 0);
} while (! WIFEXITED(status));
if (WIFEXITED (status))
break;
}
}
childProcess = 0;
@ -544,16 +747,15 @@ private:
void launchChild()
{
int ret;
int inPipe[2], outPipe[2];
ret = pipe (inPipe);
auto ret = pipe (inPipe);
ignoreUnused (ret); jassert (ret == 0);
ret = pipe (outPipe);
ignoreUnused (ret); jassert (ret == 0);
int pid = fork();
auto pid = fork();
if (pid == 0)
{
close (inPipe[0]);
@ -611,7 +813,7 @@ private:
bool shouldExit()
{
char ignore;
ssize_t result = read (threadControl[0], &ignore, 1);
auto result = read (threadControl[0], &ignore, 1);
return (result != -1 || (errno != EAGAIN && errno != EWOULDBLOCK));
}
@ -619,7 +821,7 @@ private:
//==============================================================================
void handleCommandOnMessageThread (const String& cmd, const var& params)
{
String url (params.getProperty ("url", var()).toString());
auto url = params.getProperty ("url", var()).toString();
if (cmd == "pageAboutToLoad") handlePageAboutToLoad (url, params);
else if (cmd == "pageFinishedLoading") owner.pageFinishedLoading (url);
@ -679,12 +881,13 @@ private:
owner->handleCommandOnMessageThread (cmdToSend, paramsToSend);
}
Pimpl* owner;
Pimpl* owner = nullptr;
String cmdToSend;
var paramsToSend;
};
private:
bool webKitIsAvailable = false;
WebBrowserComponent& owner;
std::unique_ptr<CommandReceiver> receiver;
int childProcess = 0, inChannel = 0, outChannel = 0;
@ -802,11 +1005,12 @@ void WebBrowserComponent::clearCookies()
int juce_gtkWebkitMain (int argc, const char* argv[])
{
if (argc != 4) return -1;
if (argc != 4)
return -1;
GtkChildProcess child (String (argv[2]).getIntValue(),
String (argv[3]).getIntValue());
return child.entry();
}

View file

@ -26,6 +26,41 @@ Window juce_getCurrentFocusWindow (ComponentPeer*);
unsigned long juce_createKeyProxyWindow (ComponentPeer*);
void juce_deleteKeyProxyWindow (ComponentPeer*);
//==============================================================================
enum
{
maxXEmbedVersionToSupport = 0
};
enum
{
XEMBED_MAPPED = (1<<0)
};
enum
{
XEMBED_EMBEDDED_NOTIFY = 0,
XEMBED_WINDOW_ACTIVATE = 1,
XEMBED_WINDOW_DEACTIVATE = 2,
XEMBED_REQUEST_FOCUS = 3,
XEMBED_FOCUS_IN = 4,
XEMBED_FOCUS_OUT = 5,
XEMBED_FOCUS_NEXT = 6,
XEMBED_FOCUS_PREV = 7,
XEMBED_MODALITY_ON = 10,
XEMBED_MODALITY_OFF = 11,
XEMBED_REGISTER_ACCELERATOR = 12,
XEMBED_UNREGISTER_ACCELERATOR = 13,
XEMBED_ACTIVATE_ACCELERATOR = 14
};
enum
{
XEMBED_FOCUS_CURRENT = 0,
XEMBED_FOCUS_FIRST = 1,
XEMBED_FOCUS_LAST = 2
};
//==============================================================================
class XEmbedComponent::Pimpl : private ComponentListener
{
@ -117,16 +152,17 @@ public:
if (host != 0)
{
auto dpy = getDisplay();
XDestroyWindow (dpy, host);
XSync (dpy, false);
const long mask = NoEventMask | KeyPressMask | KeyReleaseMask
X11Symbols::getInstance()->xDestroyWindow (dpy, host);
X11Symbols::getInstance()->xSync (dpy, false);
auto mask = NoEventMask | KeyPressMask | KeyReleaseMask
| EnterWindowMask | LeaveWindowMask | PointerMotionMask
| KeymapStateMask | ExposureMask | StructureNotifyMask
| FocusChangeMask;
XEvent event;
while (XCheckWindowEvent (dpy, host, mask, &event) == True)
while (X11Symbols::getInstance()->xCheckWindowEvent (dpy, host, mask, &event) == True)
{}
host = 0;
@ -155,22 +191,22 @@ public:
else
{
auto newBounds = getX11BoundsFromJuce();
XResizeWindow (dpy, client, static_cast<unsigned int> (newBounds.getWidth()),
X11Symbols::getInstance()->xResizeWindow (dpy, client, static_cast<unsigned int> (newBounds.getWidth()),
static_cast<unsigned int> (newBounds.getHeight()));
}
auto eventMask = StructureNotifyMask | PropertyChangeMask | FocusChangeMask;
XWindowAttributes clientAttr;
XGetWindowAttributes (dpy, client, &clientAttr);
X11Symbols::getInstance()->xGetWindowAttributes (dpy, client, &clientAttr);
if ((eventMask & clientAttr.your_event_mask) != eventMask)
XSelectInput (dpy, client, clientAttr.your_event_mask | eventMask);
X11Symbols::getInstance()->xSelectInput (dpy, client, clientAttr.your_event_mask | eventMask);
getXEmbedMappedFlag();
if (shouldReparent)
XReparentWindow (dpy, client, host, 0, 0);
X11Symbols::getInstance()->xReparentWindow (dpy, client, host, 0, 0);
if (supportsXembed)
sendXEmbedEvent (CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, (long) host, xembedVersion);
@ -242,25 +278,25 @@ private:
auto newBounds = getX11BoundsFromJuce();
XWindowAttributes attr;
if (XGetWindowAttributes (dpy, host, &attr))
if (X11Symbols::getInstance()->xGetWindowAttributes (dpy, host, &attr))
{
Rectangle<int> currentBounds (attr.x, attr.y, attr.width, attr.height);
if (currentBounds != newBounds)
{
XMoveResizeWindow (dpy, host, newBounds.getX(), newBounds.getY(),
X11Symbols::getInstance()->xMoveResizeWindow (dpy, host, newBounds.getX(), newBounds.getY(),
static_cast<unsigned int> (newBounds.getWidth()),
static_cast<unsigned int> (newBounds.getHeight()));
}
}
if (client != 0 && XGetWindowAttributes (dpy, client, &attr))
if (client != 0 && X11Symbols::getInstance()->xGetWindowAttributes (dpy, client, &attr))
{
Rectangle<int> currentBounds (attr.x, attr.y, attr.width, attr.height);
if ((currentBounds.getWidth() != newBounds.getWidth()
|| currentBounds.getHeight() != newBounds.getHeight()))
{
XMoveResizeWindow (dpy, client, 0, 0,
X11Symbols::getInstance()->xMoveResizeWindow (dpy, client, 0, 0,
static_cast<unsigned int> (newBounds.getWidth()),
static_cast<unsigned int> (newBounds.getHeight()));
}
@ -272,8 +308,8 @@ private:
void createHostWindow()
{
auto dpy = getDisplay();
int defaultScreen = XDefaultScreen (dpy);
Window root = RootWindow (dpy, defaultScreen);
int defaultScreen = X11Symbols::getInstance()->xDefaultScreen (dpy);
Window root = X11Symbols::getInstance()->xRootWindow (dpy, defaultScreen);
XSetWindowAttributes swa;
swa.border_pixel = 0;
@ -281,7 +317,7 @@ private:
swa.override_redirect = True;
swa.event_mask = SubstructureNotifyMask | StructureNotifyMask | FocusChangeMask;
host = XCreateWindow (dpy, root, 0, 0, 1, 1, 0, CopyFromParent,
host = X11Symbols::getInstance()->xCreateWindow (dpy, root, 0, 0, 1, 1, 0, CopyFromParent,
InputOutput, CopyFromParent,
CWEventMask | CWBorderPixel | CWBackPixmap | CWOverrideRedirect,
&swa);
@ -292,20 +328,20 @@ private:
if (client != 0)
{
auto dpy = getDisplay();
XSelectInput (dpy, client, 0);
X11Symbols::getInstance()->xSelectInput (dpy, client, 0);
keyWindow = nullptr;
int defaultScreen = XDefaultScreen (dpy);
Window root = RootWindow (dpy, defaultScreen);
int defaultScreen = X11Symbols::getInstance()->xDefaultScreen (dpy);
Window root = X11Symbols::getInstance()->xRootWindow (dpy, defaultScreen);
if (hasBeenMapped)
{
XUnmapWindow (dpy, client);
X11Symbols::getInstance()->xUnmapWindow (dpy, client);
hasBeenMapped = false;
}
XReparentWindow (dpy, client, root, 0, 0);
X11Symbols::getInstance()->xReparentWindow (dpy, client, root, 0, 0);
client = 0;
}
}
@ -321,9 +357,9 @@ private:
hasBeenMapped = shouldBeMapped;
if (shouldBeMapped)
XMapWindow (getDisplay(), client);
X11Symbols::getInstance()->xMapWindow (getDisplay(), client);
else
XUnmapWindow (getDisplay(), client);
X11Symbols::getInstance()->xUnmapWindow (getDisplay(), client);
}
}
}
@ -378,13 +414,13 @@ private:
XWindowAttributes attr;
auto dpy = getDisplay();
if (XGetWindowAttributes (dpy, client, &attr))
if (X11Symbols::getInstance()->xGetWindowAttributes (dpy, client, &attr))
{
XWindowAttributes hostAttr;
if (XGetWindowAttributes (dpy, host, &hostAttr))
if (X11Symbols::getInstance()->xGetWindowAttributes (dpy, host, &hostAttr))
if (attr.width != hostAttr.width || attr.height != hostAttr.height)
XResizeWindow (dpy, host, (unsigned int) attr.width, (unsigned int) attr.height);
X11Symbols::getInstance()->xResizeWindow (dpy, host, (unsigned int) attr.width, (unsigned int) attr.height);
// as the client window is not on any screen yet, we need to guess
// on which screen it might appear to get a scaling factor :-(
@ -420,14 +456,14 @@ private:
keyWindow = nullptr;
auto dpy = getDisplay();
Window rootWindow = RootWindow (dpy, DefaultScreen (dpy));
Window rootWindow = X11Symbols::getInstance()->xRootWindow (dpy, DefaultScreen (dpy));
Rectangle<int> newBounds = getX11BoundsFromJuce();
if (newPeer == nullptr)
XUnmapWindow (dpy, host);
X11Symbols::getInstance()->xUnmapWindow (dpy, host);
Window newParent = (newPeer != nullptr ? getParentX11Window() : rootWindow);
XReparentWindow (dpy, host, newParent, newBounds.getX(), newBounds.getY());
X11Symbols::getInstance()->xReparentWindow (dpy, host, newParent, newBounds.getX(), newBounds.getY());
lastPeer = newPeer;
@ -440,7 +476,7 @@ private:
}
componentMovedOrResized (owner, true, true);
XMapWindow (dpy, host);
X11Symbols::getInstance()->xMapWindow (dpy, host);
broughtToFront();
}
@ -450,7 +486,7 @@ private:
void updateKeyFocus()
{
if (lastPeer != nullptr && lastPeer->isFocused())
XSetInputFocus (getDisplay(), getCurrentFocusWindow (lastPeer), RevertToParent, CurrentTime);
X11Symbols::getInstance()->xSetInputFocus (getDisplay(), getCurrentFocusWindow (lastPeer), RevertToParent, CurrentTime);
}
//==============================================================================
@ -560,8 +596,8 @@ private:
msg.data.l[3] = data1;
msg.data.l[4] = data2;
XSendEvent (dpy, client, False, NoEventMask, (XEvent*) &msg);
XSync (dpy, False);
X11Symbols::getInstance()->xSendEvent (dpy, client, False, NoEventMask, (XEvent*) &msg);
X11Symbols::getInstance()->xSync (dpy, False);
}
Rectangle<int> getX11BoundsFromJuce()

View file

@ -29,6 +29,7 @@
#define JUCE_CORE_INCLUDE_JNI_HELPERS 1
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#include "juce_opengl.h"

View file

@ -58,7 +58,7 @@ public:
display = XWindowSystem::getInstance()->displayRef();
ScopedXLock xlock (display);
XSync (display, False);
X11Symbols::getInstance()->xSync (display, False);
GLint attribs[] =
{
@ -77,7 +77,7 @@ public:
None
};
bestVisual = glXChooseVisual (display, DefaultScreen (display), attribs);
bestVisual = glXChooseVisual (display, X11Symbols::getInstance()->xDefaultScreen (display), attribs);
if (bestVisual == nullptr)
return;
@ -85,7 +85,7 @@ public:
jassert (peer != nullptr);
auto windowH = (Window) peer->getNativeHandle();
auto colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
auto colourMap = X11Symbols::getInstance()->xCreateColormap (display, windowH, bestVisual->visual, AllocNone);
XSetWindowAttributes swa;
swa.colormap = colourMap;
@ -97,7 +97,7 @@ public:
glBounds = juce_LinuxScaledToPhysicalBounds (peer, glBounds);
embeddedWindow = XCreateWindow (display, windowH,
embeddedWindow = X11Symbols::getInstance()->xCreateWindow (display, windowH,
glBounds.getX(), glBounds.getY(),
(unsigned int) jmax (1, glBounds.getWidth()),
(unsigned int) jmax (1, glBounds.getHeight()),
@ -107,12 +107,12 @@ public:
CWBorderPixel | CWColormap | CWEventMask,
&swa);
XSaveContext (display, (XID) embeddedWindow, windowHandleXContext, (XPointer) peer);
X11Symbols::getInstance()->xSaveContext (display, (XID) embeddedWindow, windowHandleXContext, (XPointer) peer);
XMapWindow (display, embeddedWindow);
XFreeColormap (display, colourMap);
X11Symbols::getInstance()->xMapWindow (display, embeddedWindow);
X11Symbols::getInstance()->xFreeColormap (display, colourMap);
XSync (display, False);
X11Symbols::getInstance()->xSync (display, False);
juce_LinuxAddRepaintListener (peer, &dummy);
}
@ -124,12 +124,12 @@ public:
if (embeddedWindow != 0)
{
ScopedXLock xlock (display);
XUnmapWindow (display, embeddedWindow);
XDestroyWindow (display, embeddedWindow);
X11Symbols::getInstance()->xUnmapWindow (display, embeddedWindow);
X11Symbols::getInstance()->xDestroyWindow (display, embeddedWindow);
}
if (bestVisual != nullptr)
XFree (bestVisual);
X11Symbols::getInstance()->xFree (bestVisual);
XWindowSystem::getInstance()->displayUnref();
}
@ -185,7 +185,7 @@ public:
auto physicalBounds = juce_LinuxScaledToPhysicalBounds (component.getPeer(), bounds);
ScopedXLock xlock (display);
XMoveResizeWindow (display, embeddedWindow,
X11Symbols::getInstance()->xMoveResizeWindow (display, embeddedWindow,
physicalBounds.getX(), physicalBounds.getY(),
(unsigned int) jmax (1, physicalBounds.getWidth()),
(unsigned int) jmax (1, physicalBounds.getHeight()));