зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1507475 - [Wayland] Implement global wayland registry, r=jhorak
Differential Revision: https://phabricator.services.mozilla.com/D12255 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d8e6ef12af
Коммит
d78c51a229
|
@ -59,9 +59,6 @@ void WindowSurfaceProvider::Initialize(
|
|||
#ifdef MOZ_WAYLAND
|
||||
void WindowSurfaceProvider::Initialize(nsWindow *aWidget)
|
||||
{
|
||||
MOZ_ASSERT(aWidget->GetWaylandDisplay(),
|
||||
"We are supposed to have a Wayland display!");
|
||||
|
||||
mWidget = aWidget;
|
||||
mIsX11Display = false;
|
||||
}
|
||||
|
|
|
@ -4,24 +4,25 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsWaylandDisplay.h"
|
||||
#include "WindowSurfaceWayland.h"
|
||||
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "base/task.h" // for NewRunnableMethod, etc
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Tools.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozcontainer.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozwayland/mozwayland.h"
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "base/task.h" // for NewRunnableMethod, etc
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
/*
|
||||
Wayland multi-thread rendering scheme
|
||||
|
||||
|
@ -131,202 +132,8 @@ handle to wayland compositor by WindowBackBuffer/WindowSurfaceWayland
|
|||
(wl_buffer/wl_surface).
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
#define BUFFER_BPP 4
|
||||
#define MAX_DISPLAY_CONNECTIONS 2
|
||||
|
||||
static nsWaylandDisplay* gWaylandDisplays[MAX_DISPLAY_CONNECTIONS];
|
||||
static StaticMutex gWaylandDisplaysMutex;
|
||||
|
||||
// Each thread which is using wayland connection (wl_display) has to operate
|
||||
// its own wl_event_queue. Main Firefox thread wl_event_queue is handled
|
||||
// by Gtk main loop, other threads/wl_event_queue has to be handled by us.
|
||||
//
|
||||
// nsWaylandDisplay is our interface to wayland compositor. It provides wayland
|
||||
// global objects as we need (wl_display, wl_shm) and operates wl_event_queue on
|
||||
// compositor (not the main) thread.
|
||||
static nsWaylandDisplay* WaylandDisplayGet(wl_display *aDisplay);
|
||||
static void WaylandDisplayRelease(wl_display *aDisplay);
|
||||
static void WaylandDisplayLoop(wl_display *aDisplay);
|
||||
|
||||
// TODO: Bug 1467125 - We need to integrate wl_display_dispatch_queue_pending() with
|
||||
// compositor event loop.
|
||||
#define EVENT_LOOP_DELAY (1000/240)
|
||||
|
||||
// Get WaylandDisplay for given wl_display and actual calling thread.
|
||||
static nsWaylandDisplay*
|
||||
WaylandDisplayGetLocked(wl_display *aDisplay, const StaticMutexAutoLock&)
|
||||
{
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display && display->Matches(aDisplay)) {
|
||||
NS_ADDREF(display);
|
||||
return display;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display == nullptr) {
|
||||
display = new nsWaylandDisplay(aDisplay);
|
||||
NS_ADDREF(display);
|
||||
return display;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_CRASH("There's too many wayland display conections!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nsWaylandDisplay*
|
||||
WaylandDisplayGet(wl_display *aDisplay)
|
||||
{
|
||||
StaticMutexAutoLock lock(gWaylandDisplaysMutex);
|
||||
return WaylandDisplayGetLocked(aDisplay, lock);
|
||||
}
|
||||
|
||||
static bool
|
||||
WaylandDisplayReleaseLocked(wl_display *aDisplay,
|
||||
const StaticMutexAutoLock&)
|
||||
{
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display && display->Matches(aDisplay)) {
|
||||
int rc = display->Release();
|
||||
if (rc == 0) {
|
||||
display = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(false, "Missing nsWaylandDisplay for this thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
WaylandDisplayRelease(wl_display *aDisplay)
|
||||
{
|
||||
StaticMutexAutoLock lock(gWaylandDisplaysMutex);
|
||||
WaylandDisplayReleaseLocked(aDisplay, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
WaylandDisplayLoopLocked(wl_display* aDisplay,
|
||||
const StaticMutexAutoLock&)
|
||||
{
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display && display->Matches(aDisplay)) {
|
||||
if (display->DisplayLoop()) {
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
NewRunnableFunction("WaylandDisplayLoop",
|
||||
&WaylandDisplayLoop,
|
||||
aDisplay),
|
||||
EVENT_LOOP_DELAY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WaylandDisplayLoop(wl_display* aDisplay)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
StaticMutexAutoLock lock(gWaylandDisplaysMutex);
|
||||
WaylandDisplayLoopLocked(aDisplay, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
global_registry_handler(void *data, wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
{
|
||||
if (strcmp(interface, "wl_shm") == 0) {
|
||||
auto interface = reinterpret_cast<nsWaylandDisplay *>(data);
|
||||
auto shm = static_cast<wl_shm*>(
|
||||
wl_registry_bind(registry, id, &wl_shm_interface, 1));
|
||||
wl_proxy_set_queue((struct wl_proxy *)shm, interface->GetEventQueue());
|
||||
interface->SetShm(shm);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
global_registry_remover(void *data, wl_registry *registry, uint32_t id)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
global_registry_handler,
|
||||
global_registry_remover
|
||||
};
|
||||
|
||||
wl_shm*
|
||||
nsWaylandDisplay::GetShm()
|
||||
{
|
||||
MOZ_ASSERT(mThreadId == PR_GetCurrentThread());
|
||||
|
||||
if (!mShm) {
|
||||
// wl_shm is not provided by Gtk so we need to query wayland directly
|
||||
// See weston/simple-shm.c and create_display() for reference.
|
||||
wl_registry* registry = wl_display_get_registry(mDisplay);
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
|
||||
wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue);
|
||||
if (mEventQueue) {
|
||||
wl_display_roundtrip_queue(mDisplay, mEventQueue);
|
||||
} else {
|
||||
wl_display_roundtrip(mDisplay);
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(mShm, "Wayland registry query failed!");
|
||||
}
|
||||
|
||||
return(mShm);
|
||||
}
|
||||
|
||||
bool
|
||||
nsWaylandDisplay::DisplayLoop()
|
||||
{
|
||||
wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWaylandDisplay::Matches(wl_display *aDisplay)
|
||||
{
|
||||
return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsWaylandDisplay, nsISupports);
|
||||
|
||||
nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay)
|
||||
: mThreadId(PR_GetCurrentThread())
|
||||
// gfx::SurfaceFormat::B8G8R8A8 is a basic Wayland format
|
||||
// and is always present.
|
||||
// TODO: Provide also format without alpha (Bug 1470126).
|
||||
, mFormat(gfx::SurfaceFormat::B8G8R8A8)
|
||||
, mShm(nullptr)
|
||||
, mDisplay(aDisplay)
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
// Use default event queue in main thread operated by Gtk+.
|
||||
mEventQueue = nullptr;
|
||||
} else {
|
||||
mEventQueue = wl_display_create_queue(mDisplay);
|
||||
MessageLoop::current()->PostTask(NewRunnableFunction(
|
||||
"WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay));
|
||||
}
|
||||
}
|
||||
|
||||
nsWaylandDisplay::~nsWaylandDisplay()
|
||||
{
|
||||
MOZ_ASSERT(mThreadId == PR_GetCurrentThread());
|
||||
// Owned by Gtk+, we don't need to release
|
||||
mDisplay = nullptr;
|
||||
|
||||
if (mEventQueue) {
|
||||
wl_event_queue_destroy(mEventQueue);
|
||||
mEventQueue = nullptr;
|
||||
}
|
||||
}
|
||||
gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8;
|
||||
|
||||
int
|
||||
WaylandShmPool::CreateTemporaryFile(int aSize)
|
||||
|
@ -544,7 +351,7 @@ WindowBackBuffer::Lock()
|
|||
return gfxPlatform::CreateDrawTargetForData(static_cast<unsigned char*>(mShmPool.GetImageData()),
|
||||
lockSize,
|
||||
BUFFER_BPP * mWidth,
|
||||
mWaylandDisplay->GetSurfaceFormat());
|
||||
mFormat);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -562,7 +369,7 @@ static const struct wl_callback_listener frame_listener = {
|
|||
|
||||
WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow)
|
||||
: mWindow(aWindow)
|
||||
, mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay()))
|
||||
, mWaylandDisplay(WaylandDisplayGet())
|
||||
, mWaylandBuffer(nullptr)
|
||||
, mFrameCallback(nullptr)
|
||||
, mLastCommittedSurface(nullptr)
|
||||
|
@ -610,9 +417,9 @@ WindowSurfaceWayland::~WindowSurfaceWayland()
|
|||
mDisplayThreadMessageLoop->PostTask(
|
||||
NewRunnableFunction("WaylandDisplayRelease",
|
||||
&WaylandDisplayRelease,
|
||||
mWaylandDisplay->GetDisplay()));
|
||||
mWaylandDisplay));
|
||||
} else {
|
||||
WaylandDisplayRelease(mWaylandDisplay->GetDisplay());
|
||||
WaylandDisplayRelease(mWaylandDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,7 +507,7 @@ WindowSurfaceWayland::LockImageSurface(const gfx::IntSize& aLockSize)
|
|||
if (!mImageSurface || mImageSurface->CairoStatus() ||
|
||||
!(aLockSize <= mImageSurface->GetSize())) {
|
||||
mImageSurface = new gfxImageSurface(aLockSize,
|
||||
SurfaceFormatToImageFormat(mWaylandDisplay->GetSurfaceFormat()));
|
||||
SurfaceFormatToImageFormat(WindowBackBuffer::GetSurfaceFormat()));
|
||||
if (mImageSurface->CairoStatus()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -709,7 +516,7 @@ WindowSurfaceWayland::LockImageSurface(const gfx::IntSize& aLockSize)
|
|||
return gfxPlatform::CreateDrawTargetForData(mImageSurface->Data(),
|
||||
mImageSurface->GetSize(),
|
||||
mImageSurface->Stride(),
|
||||
mWaylandDisplay->GetSurfaceFormat());
|
||||
WindowBackBuffer::GetSurfaceFormat());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -9,39 +9,13 @@
|
|||
|
||||
#include <prthread.h>
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "nsWaylandDisplay.h"
|
||||
|
||||
#define BACK_BUFFER_NUM 2
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
// Our general connection to Wayland display server,
|
||||
// holds our display connection and runs event loop.
|
||||
class nsWaylandDisplay : public nsISupports {
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
public:
|
||||
explicit nsWaylandDisplay(wl_display *aDisplay);
|
||||
|
||||
wl_shm* GetShm();
|
||||
void SetShm(wl_shm* aShm) { mShm = aShm; };
|
||||
|
||||
wl_display* GetDisplay() { return mDisplay; };
|
||||
wl_event_queue* GetEventQueue() { return mEventQueue; };
|
||||
gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; };
|
||||
bool DisplayLoop();
|
||||
bool Matches(wl_display *aDisplay);
|
||||
|
||||
private:
|
||||
virtual ~nsWaylandDisplay();
|
||||
|
||||
PRThread* mThreadId;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
wl_shm* mShm;
|
||||
wl_event_queue* mEventQueue;
|
||||
wl_display* mDisplay;
|
||||
};
|
||||
|
||||
// Allocates and owns shared memory for Wayland drawing surface
|
||||
class WaylandShmPool {
|
||||
public:
|
||||
|
@ -88,6 +62,11 @@ public:
|
|||
return aBuffer->mWidth == mWidth && aBuffer->mHeight == mHeight;
|
||||
}
|
||||
|
||||
static gfx::SurfaceFormat GetSurfaceFormat()
|
||||
{
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
private:
|
||||
void Create(int aWidth, int aHeight);
|
||||
void Release();
|
||||
|
@ -102,6 +81,7 @@ private:
|
|||
int mHeight;
|
||||
bool mAttached;
|
||||
nsWaylandDisplay* mWaylandDisplay;
|
||||
static gfx::SurfaceFormat mFormat;
|
||||
};
|
||||
|
||||
// WindowSurfaceWayland is an abstraction for wl_surface
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
// gfxImageSurface pixel format configuration.
|
||||
#define SHAPED_IMAGE_SURFACE_BPP 4
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#ifdef MOZ_X11
|
||||
|
||||
#include <glib.h>
|
||||
#include "WindowSurfaceX11.h"
|
||||
#include "gfxXlibSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
|
|
@ -97,6 +97,7 @@ if CONFIG['MOZ_X11']:
|
|||
if CONFIG['MOZ_WAYLAND']:
|
||||
UNIFIED_SOURCES += [
|
||||
'nsClipboardWayland.cpp',
|
||||
'nsWaylandDisplay.cpp',
|
||||
'WindowSurfaceWayland.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#ifdef MOZ_WAYLAND
|
||||
#include "mozwayland/mozwayland.h"
|
||||
#include "nsWaylandDisplay.h"
|
||||
#include <wayland-egl.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
@ -20,6 +20,9 @@
|
|||
#include "maiRedundantObjectFactory.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
/* init methods */
|
||||
static void moz_container_class_init (MozContainerClass *klass);
|
||||
static void moz_container_init (MozContainer *container);
|
||||
|
@ -168,37 +171,6 @@ moz_container_class_init (MozContainerClass *klass)
|
|||
container_class->add = moz_container_add;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WAYLAND)
|
||||
static void
|
||||
registry_handle_global (void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t name,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
MozContainer *container = MOZ_CONTAINER(data);
|
||||
if(strcmp(interface, "wl_subcompositor") == 0) {
|
||||
container->subcompositor =
|
||||
static_cast<wl_subcompositor*>(wl_registry_bind(registry,
|
||||
name,
|
||||
&wl_subcompositor_interface,
|
||||
1));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
registry_handle_global_remove (void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t name)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
registry_handle_global,
|
||||
registry_handle_global_remove
|
||||
};
|
||||
#endif
|
||||
|
||||
void
|
||||
moz_container_init (MozContainer *container)
|
||||
{
|
||||
|
@ -207,28 +179,11 @@ moz_container_init (MozContainer *container)
|
|||
gtk_widget_set_redraw_on_allocate(GTK_WIDGET(container), FALSE);
|
||||
|
||||
#if defined(MOZ_WAYLAND)
|
||||
{
|
||||
container->subcompositor = nullptr;
|
||||
container->surface = nullptr;
|
||||
container->subsurface = nullptr;
|
||||
container->eglwindow = nullptr;
|
||||
container->parent_surface_committed = false;
|
||||
container->needs_clear = true;
|
||||
|
||||
GdkDisplay *gdk_display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
if (!GDK_IS_X11_DISPLAY(gdk_display)) {
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
|
||||
wl_display* display = sGdkWaylandDisplayGetWlDisplay(gdk_display);
|
||||
wl_registry* registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, container);
|
||||
wl_display_dispatch(display);
|
||||
wl_display_roundtrip(display);
|
||||
}
|
||||
}
|
||||
container->surface = nullptr;
|
||||
container->subsurface = nullptr;
|
||||
container->eglwindow = nullptr;
|
||||
container->parent_surface_committed = false;
|
||||
container->needs_clear = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -284,6 +239,7 @@ moz_container_map_surface(MozContainer *container)
|
|||
}
|
||||
|
||||
if (!container->surface) {
|
||||
// TODO - use nsWaylandDisplay::compositor for compositor thread.
|
||||
struct wl_compositor *compositor;
|
||||
compositor = sGdkWaylandDisplayGetWlCompositor(display);
|
||||
container->surface = wl_compositor_create_surface(compositor);
|
||||
|
@ -298,11 +254,15 @@ moz_container_map_surface(MozContainer *container)
|
|||
// to mContainer.
|
||||
return false;
|
||||
}
|
||||
GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
nsWaylandDisplay* waylandDisplay = WaylandDisplayGet(display);
|
||||
wl_subcompositor* subcompositor = waylandDisplay->GetSubcompositor();
|
||||
container->subsurface =
|
||||
wl_subcompositor_get_subsurface(subcompositor,
|
||||
container->surface,
|
||||
gtk_surface);
|
||||
WaylandDisplayRelease(waylandDisplay);
|
||||
|
||||
container->subsurface =
|
||||
wl_subcompositor_get_subsurface (container->subcompositor,
|
||||
container->surface,
|
||||
gtk_surface);
|
||||
gint x, y;
|
||||
gdk_window_get_position(window, &x, &y);
|
||||
wl_subsurface_set_position(container->subsurface, x, y);
|
||||
|
@ -310,7 +270,6 @@ moz_container_map_surface(MozContainer *container)
|
|||
|
||||
// Route input to parent wl_surface owned by Gtk+ so we get input
|
||||
// events from Gtk+.
|
||||
GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET (container));
|
||||
wl_compositor* compositor = sGdkWaylandDisplayGetWlCompositor(display);
|
||||
wl_region* region = wl_compositor_create_region(compositor);
|
||||
wl_surface_set_input_region(container->surface, region);
|
||||
|
|
|
@ -58,7 +58,6 @@ typedef struct _MozContainerClass MozContainerClass;
|
|||
* present in wayland-devel < 1.12
|
||||
*/
|
||||
#ifdef MOZ_WAYLAND
|
||||
struct wl_subcompositor;
|
||||
struct wl_surface;
|
||||
struct wl_subsurface;
|
||||
#endif
|
||||
|
@ -69,7 +68,6 @@ struct _MozContainer
|
|||
GList *children;
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
struct wl_subcompositor *subcompositor;
|
||||
struct wl_surface *surface;
|
||||
struct wl_subsurface *subsurface;
|
||||
struct wl_egl_window *eglwindow;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsDragService.h"
|
||||
#include "mozwayland/mozwayland.h"
|
||||
#include "nsWaylandDisplay.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
|
||||
|
@ -514,7 +515,7 @@ nsRetrievalContextWayland::AddDragAndDropDataOffer(wl_data_offer *aDropDataOffer
|
|||
NS_ASSERTION(dataOffer, "We're missing drag and drop data offer!");
|
||||
if (dataOffer) {
|
||||
g_hash_table_remove(mActiveOffers, aDropDataOffer);
|
||||
mDragContext = new nsWaylandDragContext(dataOffer, mDisplay);
|
||||
mDragContext = new nsWaylandDragContext(dataOffer, mDisplay->GetDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -704,72 +705,12 @@ gtk_primary_selection_device_listener primary_selection_device_listener = {
|
|||
bool
|
||||
nsRetrievalContextWayland::HasSelectionSupport(void)
|
||||
{
|
||||
return mPrimarySelectionDataDeviceManager != nullptr;
|
||||
return mDisplay->GetPrimarySelectionDeviceManager() != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsRetrievalContextWayland::InitDataDeviceManager(wl_registry *registry,
|
||||
uint32_t id,
|
||||
uint32_t version)
|
||||
{
|
||||
int data_device_manager_version = MIN (version, 3);
|
||||
mDataDeviceManager = (wl_data_device_manager *)wl_registry_bind(registry, id,
|
||||
&wl_data_device_manager_interface, data_device_manager_version);
|
||||
}
|
||||
|
||||
void
|
||||
nsRetrievalContextWayland::InitPrimarySelectionDataDeviceManager(
|
||||
wl_registry *registry, uint32_t id)
|
||||
{
|
||||
mPrimarySelectionDataDeviceManager =
|
||||
(gtk_primary_selection_device_manager *)wl_registry_bind(registry, id,
|
||||
>k_primary_selection_device_manager_interface, 1);
|
||||
}
|
||||
|
||||
void
|
||||
nsRetrievalContextWayland::InitSeat(wl_registry *registry,
|
||||
uint32_t id, uint32_t version,
|
||||
void *data)
|
||||
{
|
||||
mSeat = (wl_seat*)wl_registry_bind(registry, id, &wl_seat_interface, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global(void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
nsRetrievalContextWayland *context =
|
||||
static_cast<nsRetrievalContextWayland*>(data);
|
||||
|
||||
if (strcmp (interface, "wl_data_device_manager") == 0) {
|
||||
context->InitDataDeviceManager(registry, id, version);
|
||||
} else if (strcmp(interface, "wl_seat") == 0) {
|
||||
context->InitSeat(registry, id, version, data);
|
||||
} else if (strcmp (interface, "gtk_primary_selection_device_manager") == 0) {
|
||||
context->InitPrimarySelectionDataDeviceManager(registry, id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global_remove(void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener clipboard_registry_listener = {
|
||||
gdk_registry_handle_global,
|
||||
gdk_registry_handle_global_remove
|
||||
};
|
||||
|
||||
nsRetrievalContextWayland::nsRetrievalContextWayland(void)
|
||||
: mInitialized(false)
|
||||
, mSeat(nullptr)
|
||||
, mDataDeviceManager(nullptr)
|
||||
, mPrimarySelectionDataDeviceManager(nullptr)
|
||||
, mDisplay(WaylandDisplayGet())
|
||||
, mActiveOffers(g_hash_table_new(NULL, NULL))
|
||||
, mClipboardOffer(nullptr)
|
||||
, mPrimaryOffer(nullptr)
|
||||
|
@ -778,38 +719,18 @@ nsRetrievalContextWayland::nsRetrievalContextWayland(void)
|
|||
, mClipboardData(nullptr)
|
||||
, mClipboardDataLength(0)
|
||||
{
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
|
||||
mDisplay = sGdkWaylandDisplayGetWlDisplay(gdk_display_get_default());
|
||||
wl_registry_add_listener(wl_display_get_registry(mDisplay),
|
||||
&clipboard_registry_listener, this);
|
||||
// Call wl_display_roundtrip() twice to make sure all
|
||||
// callbacks are processed.
|
||||
wl_display_roundtrip(mDisplay);
|
||||
wl_display_roundtrip(mDisplay);
|
||||
|
||||
// mSeat/mDataDeviceManager should be set now by
|
||||
// gdk_registry_handle_global() as a response to
|
||||
// wl_registry_add_listener() call.
|
||||
if (!mDataDeviceManager || !mSeat)
|
||||
return;
|
||||
|
||||
wl_data_device *dataDevice =
|
||||
wl_data_device_manager_get_data_device(mDataDeviceManager, mSeat);
|
||||
wl_data_device_manager_get_data_device(mDisplay->GetDataDeviceManager(),
|
||||
mDisplay->GetSeat());
|
||||
wl_data_device_add_listener(dataDevice, &data_device_listener, this);
|
||||
// We have to call wl_display_roundtrip() twice otherwise data_offer_listener
|
||||
// may not be processed because it's called from data_device_data_offer
|
||||
// callback.
|
||||
wl_display_roundtrip(mDisplay);
|
||||
wl_display_roundtrip(mDisplay);
|
||||
|
||||
if (mPrimarySelectionDataDeviceManager) {
|
||||
|
||||
gtk_primary_selection_device_manager* manager =
|
||||
mDisplay->GetPrimarySelectionDeviceManager();
|
||||
if (manager) {
|
||||
gtk_primary_selection_device *primaryDataDevice =
|
||||
gtk_primary_selection_device_manager_get_device(mPrimarySelectionDataDeviceManager,
|
||||
mSeat);
|
||||
gtk_primary_selection_device_manager_get_device(manager,
|
||||
mDisplay->GetSeat());
|
||||
gtk_primary_selection_device_add_listener(primaryDataDevice,
|
||||
&primary_selection_device_listener, this);
|
||||
}
|
||||
|
@ -833,6 +754,7 @@ nsRetrievalContextWayland::~nsRetrievalContextWayland(void)
|
|||
{
|
||||
g_hash_table_foreach_remove(mActiveOffers, offer_hash_remove, nullptr);
|
||||
g_hash_table_destroy(mActiveOffers);
|
||||
WaylandDisplayRelease(mDisplay);
|
||||
}
|
||||
|
||||
GdkAtom*
|
||||
|
@ -925,7 +847,7 @@ nsRetrievalContextWayland::GetClipboardData(const char* aMimeType,
|
|||
mClipboardData = nullptr;
|
||||
mClipboardDataLength = 0;
|
||||
} else {
|
||||
mClipboardData = dataOffer->GetData(mDisplay,
|
||||
mClipboardData = dataOffer->GetData(mDisplay->GetDisplay(),
|
||||
aMimeType, &mClipboardDataLength);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,17 +130,11 @@ public:
|
|||
void TransferFastTrackClipboard(int aClipboardRequestNumber,
|
||||
GtkSelectionData *aSelectionData);
|
||||
|
||||
void InitDataDeviceManager(wl_registry *registry, uint32_t id, uint32_t version);
|
||||
void InitPrimarySelectionDataDeviceManager(wl_registry *registry, uint32_t id);
|
||||
void InitSeat(wl_registry *registry, uint32_t id, uint32_t version, void *data);
|
||||
virtual ~nsRetrievalContextWayland() override;
|
||||
|
||||
private:
|
||||
bool mInitialized;
|
||||
wl_display *mDisplay;
|
||||
wl_seat *mSeat;
|
||||
wl_data_device_manager *mDataDeviceManager;
|
||||
gtk_primary_selection_device_manager *mPrimarySelectionDataDeviceManager;
|
||||
nsWaylandDisplay* mDisplay;
|
||||
|
||||
// Data offers provided by Wayland data device
|
||||
GHashTable* mActiveOffers;
|
||||
|
|
|
@ -584,68 +584,37 @@ static const struct wl_keyboard_listener keyboard_listener = {
|
|||
keyboard_handle_modifiers,
|
||||
};
|
||||
|
||||
static void
|
||||
seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
unsigned int caps)
|
||||
{
|
||||
static wl_keyboard *keyboard = nullptr;
|
||||
|
||||
if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
|
||||
keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(keyboard, &keyboard_listener, nullptr);
|
||||
} else if (keyboard && !(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
|
||||
wl_keyboard_destroy(keyboard);
|
||||
keyboard = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
seat_handle_capabilities,
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global(void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
if (strcmp(interface, "wl_seat") == 0) {
|
||||
wl_seat *seat =
|
||||
(wl_seat*)wl_registry_bind(registry, id, &wl_seat_interface, 1);
|
||||
wl_seat_add_listener(seat, &seat_listener, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global_remove(void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t id)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener keyboard_registry_listener = {
|
||||
gdk_registry_handle_global,
|
||||
gdk_registry_handle_global_remove
|
||||
};
|
||||
|
||||
void
|
||||
KeymapWrapper::InitBySystemSettingsWayland()
|
||||
{
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
GdkDeviceManager* manager =
|
||||
gdk_display_get_device_manager(gdk_display_get_default());
|
||||
GList* devices =
|
||||
gdk_device_manager_list_devices(manager, GDK_DEVICE_TYPE_MASTER);
|
||||
GdkDevice* device = nullptr;
|
||||
|
||||
wl_display *display =
|
||||
sGdkWaylandDisplayGetWlDisplay(gdk_display_get_default());
|
||||
wl_registry_add_listener(wl_display_get_registry(display),
|
||||
&keyboard_registry_listener, this);
|
||||
GList* list = devices;
|
||||
while (devices) {
|
||||
device = static_cast<GdkDevice*>(devices->data);
|
||||
if (gdk_device_get_source(device) == GDK_SOURCE_KEYBOARD) {
|
||||
break;
|
||||
}
|
||||
devices = devices->next;
|
||||
}
|
||||
|
||||
// Call wl_display_roundtrip() twice to make sure all
|
||||
// callbacks are processed.
|
||||
wl_display_roundtrip(display);
|
||||
wl_display_roundtrip(display);
|
||||
if (list) {
|
||||
g_list_free(list);
|
||||
}
|
||||
|
||||
if (device) {
|
||||
// Present in Gtk+ 3.10
|
||||
static auto sGdkWaylandDeviceGetWlKeyboard =
|
||||
(struct wl_keyboard * (*)(GdkDevice *device))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_device_get_wl_keyboard");
|
||||
|
||||
wl_keyboard_add_listener(sGdkWaylandDeviceGetWlKeyboard(device),
|
||||
&keyboard_listener, nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef __nsLookAndFeel
|
||||
#define __nsLookAndFeel
|
||||
|
||||
#include "X11UndefineNone.h"
|
||||
#include "nsXPLookAndFeel.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "gfxFont.h"
|
||||
|
|
|
@ -0,0 +1,267 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsWaylandDisplay.h"
|
||||
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "base/task.h" // for NewRunnableMethod, etc
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
#define MAX_DISPLAY_CONNECTIONS 2
|
||||
|
||||
static nsWaylandDisplay* gWaylandDisplays[MAX_DISPLAY_CONNECTIONS];
|
||||
static StaticMutex gWaylandDisplaysMutex;
|
||||
|
||||
// Each thread which is using wayland connection (wl_display) has to operate
|
||||
// its own wl_event_queue. Main Firefox thread wl_event_queue is handled
|
||||
// by Gtk main loop, other threads/wl_event_queue has to be handled by us.
|
||||
//
|
||||
// nsWaylandDisplay is our interface to wayland compositor. It provides wayland
|
||||
// global objects as we need (wl_display, wl_shm) and operates wl_event_queue on
|
||||
// compositor (not the main) thread.
|
||||
static void WaylandDisplayLoop(wl_display *aDisplay);
|
||||
|
||||
// Get WaylandDisplay for given wl_display and actual calling thread.
|
||||
static nsWaylandDisplay*
|
||||
WaylandDisplayGetLocked(wl_display *aDisplay, const StaticMutexAutoLock&)
|
||||
{
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display && display->Matches(aDisplay)) {
|
||||
NS_ADDREF(display);
|
||||
return display;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display == nullptr) {
|
||||
display = new nsWaylandDisplay(aDisplay);
|
||||
NS_ADDREF(display);
|
||||
return display;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_CRASH("There's too many wayland display conections!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsWaylandDisplay*
|
||||
WaylandDisplayGet(GdkDisplay* aGdkDisplay)
|
||||
{
|
||||
if (!aGdkDisplay) {
|
||||
aGdkDisplay = gdk_display_get_default();
|
||||
}
|
||||
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
|
||||
wl_display *display = sGdkWaylandDisplayGetWlDisplay(aGdkDisplay);
|
||||
|
||||
StaticMutexAutoLock lock(gWaylandDisplaysMutex);
|
||||
return WaylandDisplayGetLocked(display, lock);
|
||||
}
|
||||
|
||||
static bool
|
||||
WaylandDisplayReleaseLocked(nsWaylandDisplay* aDisplay,
|
||||
const StaticMutexAutoLock&)
|
||||
{
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display == aDisplay) {
|
||||
int rc = display->Release();
|
||||
if (rc == 0) {
|
||||
display = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(false, "Missing nsWaylandDisplay for this thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
WaylandDisplayRelease(nsWaylandDisplay* aDisplay)
|
||||
{
|
||||
StaticMutexAutoLock lock(gWaylandDisplaysMutex);
|
||||
WaylandDisplayReleaseLocked(aDisplay, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
WaylandDisplayLoopLocked(wl_display* aDisplay,
|
||||
const StaticMutexAutoLock&)
|
||||
{
|
||||
for (auto& display: gWaylandDisplays) {
|
||||
if (display && display->Matches(aDisplay)) {
|
||||
if (display->DisplayLoop()) {
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
NewRunnableFunction("WaylandDisplayLoop",
|
||||
&WaylandDisplayLoop,
|
||||
aDisplay),
|
||||
EVENT_LOOP_DELAY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WaylandDisplayLoop(wl_display* aDisplay)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
StaticMutexAutoLock lock(gWaylandDisplaysMutex);
|
||||
WaylandDisplayLoopLocked(aDisplay, lock);
|
||||
}
|
||||
|
||||
void
|
||||
nsWaylandDisplay::SetShm(wl_shm* aShm)
|
||||
{
|
||||
mShm = aShm;
|
||||
}
|
||||
|
||||
void
|
||||
nsWaylandDisplay::SetSubcompositor(wl_subcompositor* aSubcompositor)
|
||||
{
|
||||
mSubcompositor = aSubcompositor;
|
||||
}
|
||||
|
||||
void
|
||||
nsWaylandDisplay::SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager)
|
||||
{
|
||||
mDataDeviceManager = aDataDeviceManager;
|
||||
}
|
||||
|
||||
void
|
||||
nsWaylandDisplay::SetSeat(wl_seat* aSeat)
|
||||
{
|
||||
mSeat = aSeat;
|
||||
}
|
||||
|
||||
void
|
||||
nsWaylandDisplay::SetPrimarySelectionDeviceManager(
|
||||
gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager)
|
||||
{
|
||||
mPrimarySelectionDeviceManager = aPrimarySelectionDeviceManager;
|
||||
}
|
||||
|
||||
static void
|
||||
global_registry_handler(void *data, wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
{
|
||||
auto display = reinterpret_cast<nsWaylandDisplay *>(data);
|
||||
|
||||
if (strcmp(interface, "wl_shm") == 0) {
|
||||
auto shm = static_cast<wl_shm*>(
|
||||
wl_registry_bind(registry, id, &wl_shm_interface, 1));
|
||||
wl_proxy_set_queue((struct wl_proxy *)shm,
|
||||
display->GetEventQueue());
|
||||
display->SetShm(shm);
|
||||
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
|
||||
int data_device_manager_version = MIN(version, 3);
|
||||
auto data_device_manager =
|
||||
static_cast<wl_data_device_manager *>(wl_registry_bind(registry, id,
|
||||
&wl_data_device_manager_interface,
|
||||
data_device_manager_version));
|
||||
wl_proxy_set_queue((struct wl_proxy *)data_device_manager,
|
||||
display->GetEventQueue());
|
||||
display->SetDataDeviceManager(data_device_manager);
|
||||
} else if (strcmp(interface, "wl_seat") == 0) {
|
||||
auto seat =
|
||||
static_cast<wl_seat*>(wl_registry_bind(registry, id,
|
||||
&wl_seat_interface, 1));
|
||||
wl_proxy_set_queue((struct wl_proxy *)seat,
|
||||
display->GetEventQueue());
|
||||
display->SetSeat(seat);
|
||||
} else if (strcmp(interface, "gtk_primary_selection_device_manager") == 0) {
|
||||
auto primary_selection_device_manager =
|
||||
static_cast<gtk_primary_selection_device_manager *>(
|
||||
wl_registry_bind(registry, id,
|
||||
>k_primary_selection_device_manager_interface, 1));
|
||||
wl_proxy_set_queue((struct wl_proxy *)primary_selection_device_manager,
|
||||
display->GetEventQueue());
|
||||
display->SetPrimarySelectionDeviceManager(primary_selection_device_manager);
|
||||
} else if(strcmp(interface, "wl_subcompositor") == 0) {
|
||||
auto subcompositor =
|
||||
static_cast<wl_subcompositor*>(wl_registry_bind(registry,
|
||||
id,
|
||||
&wl_subcompositor_interface,
|
||||
1));
|
||||
wl_proxy_set_queue((struct wl_proxy *)subcompositor,
|
||||
display->GetEventQueue());
|
||||
display->SetSubcompositor(subcompositor);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
global_registry_remover(void *data, wl_registry *registry, uint32_t id)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
global_registry_handler,
|
||||
global_registry_remover
|
||||
};
|
||||
|
||||
bool
|
||||
nsWaylandDisplay::DisplayLoop()
|
||||
{
|
||||
wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWaylandDisplay::Matches(wl_display *aDisplay)
|
||||
{
|
||||
return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsWaylandDisplay, nsISupports);
|
||||
|
||||
nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay)
|
||||
: mThreadId(PR_GetCurrentThread())
|
||||
, mDisplay(aDisplay)
|
||||
, mEventQueue(nullptr)
|
||||
, mDataDeviceManager(nullptr)
|
||||
, mSubcompositor(nullptr)
|
||||
, mSeat(nullptr)
|
||||
, mShm(nullptr)
|
||||
, mPrimarySelectionDeviceManager(nullptr)
|
||||
{
|
||||
wl_registry* registry = wl_display_get_registry(mDisplay);
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
// Use default event queue in main thread operated by Gtk+.
|
||||
mEventQueue = nullptr;
|
||||
wl_display_roundtrip(mDisplay);
|
||||
wl_display_roundtrip(mDisplay);
|
||||
} else {
|
||||
mEventQueue = wl_display_create_queue(mDisplay);
|
||||
MessageLoop::current()->PostTask(NewRunnableFunction(
|
||||
"WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay));
|
||||
wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue);
|
||||
wl_display_roundtrip_queue(mDisplay, mEventQueue);
|
||||
wl_display_roundtrip_queue(mDisplay, mEventQueue);
|
||||
}
|
||||
}
|
||||
|
||||
nsWaylandDisplay::~nsWaylandDisplay()
|
||||
{
|
||||
MOZ_ASSERT(mThreadId == PR_GetCurrentThread());
|
||||
// Owned by Gtk+, we don't need to release
|
||||
mDisplay = nullptr;
|
||||
|
||||
if (mEventQueue) {
|
||||
wl_event_queue_destroy(mEventQueue);
|
||||
mEventQueue = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __MOZ_WAYLAND_REGISTRY_H__
|
||||
#define __MOZ_WAYLAND_REGISTRY_H__
|
||||
|
||||
#include "mozwayland/mozwayland.h"
|
||||
#include "wayland/gtk-primary-selection-client-protocol.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
// TODO: Bug 1467125 - We need to integrate wl_display_dispatch_queue_pending() with
|
||||
// compositor event loop.
|
||||
#define EVENT_LOOP_DELAY (1000/240)
|
||||
|
||||
// Our general connection to Wayland display server,
|
||||
// holds our display connection and runs event loop.
|
||||
class nsWaylandDisplay : public nsISupports {
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
public:
|
||||
explicit nsWaylandDisplay(wl_display *aDisplay);
|
||||
|
||||
bool DisplayLoop();
|
||||
bool Matches(wl_display *aDisplay);
|
||||
|
||||
wl_display* GetDisplay() { return mDisplay; };
|
||||
wl_event_queue* GetEventQueue() { return mEventQueue; };
|
||||
wl_subcompositor* GetSubcompositor(void) { return mSubcompositor; };
|
||||
wl_data_device_manager* GetDataDeviceManager(void) { return mDataDeviceManager; };
|
||||
wl_seat* GetSeat(void) { return mSeat; };
|
||||
wl_shm* GetShm(void) { return mShm; };
|
||||
gtk_primary_selection_device_manager*
|
||||
GetPrimarySelectionDeviceManager(void) { return mPrimarySelectionDeviceManager; };
|
||||
|
||||
public:
|
||||
void SetShm(wl_shm* aShm);
|
||||
void SetSubcompositor(wl_subcompositor* aSubcompositor);
|
||||
void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager);
|
||||
void SetSeat(wl_seat* aSeat);
|
||||
void SetPrimarySelectionDeviceManager(
|
||||
gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager);
|
||||
|
||||
private:
|
||||
virtual ~nsWaylandDisplay();
|
||||
|
||||
PRThread* mThreadId;
|
||||
wl_display* mDisplay;
|
||||
wl_event_queue* mEventQueue;
|
||||
wl_data_device_manager* mDataDeviceManager;
|
||||
wl_subcompositor* mSubcompositor;
|
||||
wl_seat* mSeat;
|
||||
wl_shm* mShm;
|
||||
gtk_primary_selection_device_manager* mPrimarySelectionDeviceManager;
|
||||
};
|
||||
|
||||
nsWaylandDisplay* WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr);
|
||||
void WaylandDisplayRelease(nsWaylandDisplay* aDisplay);
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // __MOZ_WAYLAND_REGISTRY_H__
|
|
@ -7303,19 +7303,6 @@ void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInit
|
|||
}
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
wl_display*
|
||||
nsWindow::GetWaylandDisplay()
|
||||
{
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
|
||||
GdkDisplay* gdkDisplay = gdk_display_get_default();
|
||||
return mIsX11Display ? nullptr :
|
||||
sGdkWaylandDisplayGetWlDisplay(gdkDisplay);
|
||||
}
|
||||
|
||||
wl_surface*
|
||||
nsWindow::GetWaylandSurface()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче