1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3  */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 #ifndef __MOZ_WAYLAND_DISPLAY_H__
9 #define __MOZ_WAYLAND_DISPLAY_H__
10 
11 #include "DMABufLibWrapper.h"
12 
13 #include "mozilla/widget/mozwayland.h"
14 #include "mozilla/widget/gbm.h"
15 #include "mozilla/widget/gtk-primary-selection-client-protocol.h"
16 #include "mozilla/widget/idle-inhibit-unstable-v1-client-protocol.h"
17 #include "mozilla/widget/relative-pointer-unstable-v1-client-protocol.h"
18 #include "mozilla/widget/pointer-constraints-unstable-v1-client-protocol.h"
19 #include "mozilla/widget/linux-dmabuf-unstable-v1-client-protocol.h"
20 #include "mozilla/widget/primary-selection-unstable-v1-client-protocol.h"
21 #include "mozilla/widget/viewporter-client-protocol.h"
22 
23 namespace mozilla {
24 namespace widget {
25 
26 // Our general connection to Wayland display server,
27 // holds our display connection and runs event loop.
28 // We have a global nsWaylandDisplay object for each thread.
29 class nsWaylandDisplay {
30  public:
31   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsWaylandDisplay)
32 
33   // Create nsWaylandDisplay object on top of native Wayland wl_display
34   // connection. When aLighWrapper is set we don't get wayland registry
35   // objects and only event loop is provided.
36   explicit nsWaylandDisplay(wl_display* aDisplay, bool aLighWrapper = false);
37 
38   bool DispatchEventQueue();
39 
40   void SyncBegin();
41   void QueueSyncBegin();
42   void SyncEnd();
43   void WaitForSyncEnd();
44 
45   bool Matches(wl_display* aDisplay);
46 
GetDisplay()47   wl_display* GetDisplay() { return mDisplay; };
GetEventQueue()48   wl_event_queue* GetEventQueue() { return mEventQueue; };
GetCompositor(void)49   wl_compositor* GetCompositor(void) { return mCompositor; };
GetSubcompositor(void)50   wl_subcompositor* GetSubcompositor(void) { return mSubcompositor; };
GetDataDeviceManager(void)51   wl_data_device_manager* GetDataDeviceManager(void) {
52     return mDataDeviceManager;
53   };
54   wl_seat* GetSeat(void);
GetShm(void)55   wl_shm* GetShm(void) { return mShm; };
GetPrimarySelectionDeviceManagerGtk(void)56   gtk_primary_selection_device_manager* GetPrimarySelectionDeviceManagerGtk(
57       void) {
58     return mPrimarySelectionDeviceManagerGtk;
59   };
60   zwp_primary_selection_device_manager_v1*
GetPrimarySelectionDeviceManagerZwpV1(void)61   GetPrimarySelectionDeviceManagerZwpV1(void) {
62     return mPrimarySelectionDeviceManagerZwpV1;
63   };
GetIdleInhibitManager(void)64   zwp_idle_inhibit_manager_v1* GetIdleInhibitManager(void) {
65     return mIdleInhibitManager;
66   }
GetViewporter(void)67   wp_viewporter* GetViewporter(void) { return mViewporter; };
GetRelativePointerManager(void)68   zwp_relative_pointer_manager_v1* GetRelativePointerManager(void) {
69     return mRelativePointerManager;
70   }
GetPointerConstraints(void)71   zwp_pointer_constraints_v1* GetPointerConstraints(void) {
72     return mPointerConstraints;
73   }
74 
IsMainThreadDisplay()75   bool IsMainThreadDisplay() { return mEventQueue == nullptr; }
76 
77   void SetShm(wl_shm* aShm);
78   void SetCompositor(wl_compositor* aCompositor);
79   void SetSubcompositor(wl_subcompositor* aSubcompositor);
80   void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager);
81   void SetPrimarySelectionDeviceManager(
82       gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager);
83   void SetPrimarySelectionDeviceManager(
84       zwp_primary_selection_device_manager_v1* aPrimarySelectionDeviceManager);
85   void SetIdleInhibitManager(zwp_idle_inhibit_manager_v1* aIdleInhibitManager);
86   void SetViewporter(wp_viewporter* aViewporter);
87   void SetRelativePointerManager(
88       zwp_relative_pointer_manager_v1* aRelativePointerManager);
89   void SetPointerConstraints(zwp_pointer_constraints_v1* aPointerConstraints);
90 
IsExplicitSyncEnabled()91   bool IsExplicitSyncEnabled() { return mExplicitSync; }
92 
93  private:
94   ~nsWaylandDisplay();
95 
96   PRThread* mThreadId;
97   wl_display* mDisplay;
98   wl_event_queue* mEventQueue;
99   wl_data_device_manager* mDataDeviceManager;
100   wl_compositor* mCompositor;
101   wl_subcompositor* mSubcompositor;
102   wl_shm* mShm;
103   wl_callback* mSyncCallback;
104   gtk_primary_selection_device_manager* mPrimarySelectionDeviceManagerGtk;
105   zwp_primary_selection_device_manager_v1* mPrimarySelectionDeviceManagerZwpV1;
106   zwp_idle_inhibit_manager_v1* mIdleInhibitManager;
107   zwp_relative_pointer_manager_v1* mRelativePointerManager;
108   zwp_pointer_constraints_v1* mPointerConstraints;
109   wl_registry* mRegistry;
110   wp_viewporter* mViewporter;
111   bool mExplicitSync;
112 };
113 
114 void WaylandDispatchDisplays();
115 void WaylandDisplayRelease();
116 
117 RefPtr<nsWaylandDisplay> WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr);
118 wl_display* WaylandDisplayGetWLDisplay(GdkDisplay* aGdkDisplay = nullptr);
119 
120 }  // namespace widget
121 }  // namespace mozilla
122 
123 template <class T>
WaylandRegistryBind(struct wl_registry * wl_registry,uint32_t name,const struct wl_interface * interface,uint32_t version)124 static inline T* WaylandRegistryBind(struct wl_registry* wl_registry,
125                                      uint32_t name,
126                                      const struct wl_interface* interface,
127                                      uint32_t version) {
128   struct wl_proxy* id;
129 
130   // When libwayland-client does not provide this symbol, it will be
131   // linked to the fallback in libmozwayland, which returns NULL.
132   id = wl_proxy_marshal_constructor_versioned(
133       (struct wl_proxy*)wl_registry, WL_REGISTRY_BIND, interface, version, name,
134       interface->name, version, nullptr);
135 
136   if (id == nullptr) {
137     id = wl_proxy_marshal_constructor((struct wl_proxy*)wl_registry,
138                                       WL_REGISTRY_BIND, interface, name,
139                                       interface->name, version, nullptr);
140   }
141 
142   return reinterpret_cast<T*>(id);
143 }
144 
145 #endif  // __MOZ_WAYLAND_DISPLAY_H__
146