• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // WaylandWindow.cpp: Implementation of OSWindow for Wayland
8 
9 #include "util/linux/wayland/WaylandWindow.h"
10 
WaylandWindow()11 WaylandWindow::WaylandWindow()
12     : mDisplay{nullptr}, mCompositor{nullptr}, mSurface{nullptr}, mWindow{nullptr}
13 {}
14 
~WaylandWindow()15 WaylandWindow::~WaylandWindow()
16 {
17     destroy();
18 }
19 
RegistryHandleGlobal(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)20 void WaylandWindow::RegistryHandleGlobal(void *data,
21                                          struct wl_registry *registry,
22                                          uint32_t name,
23                                          const char *interface,
24                                          uint32_t version)
25 {
26     WaylandWindow *vc = reinterpret_cast<WaylandWindow *>(data);
27 
28     if (strcmp(interface, "wl_compositor") == 0)
29     {
30         void *compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
31         vc->mCompositor  = reinterpret_cast<wl_compositor *>(compositor);
32     }
33 }
34 
RegistryHandleGlobalRemove(void * data,struct wl_registry * registry,uint32_t name)35 void WaylandWindow::RegistryHandleGlobalRemove(void *data,
36                                                struct wl_registry *registry,
37                                                uint32_t name)
38 {}
39 
40 const struct wl_registry_listener WaylandWindow::registryListener = {
41     WaylandWindow::RegistryHandleGlobal, WaylandWindow::RegistryHandleGlobalRemove};
42 
initializeImpl(const std::string & name,int width,int height)43 bool WaylandWindow::initializeImpl(const std::string &name, int width, int height)
44 {
45     destroy();
46 
47     if (!mDisplay)
48     {
49         mDisplay = wl_display_connect(nullptr);
50         if (!mDisplay)
51         {
52             return false;
53         }
54     }
55 
56     // Not get a window
57     struct wl_registry *registry = wl_display_get_registry(mDisplay);
58     wl_registry_add_listener(registry, &registryListener, this);
59 
60     // Round-trip to get globals
61     wl_display_roundtrip(mDisplay);
62     if (!mCompositor)
63     {
64         return false;
65     }
66 
67     // We don't need this anymore
68     wl_registry_destroy(registry);
69 
70     mSurface = wl_compositor_create_surface(mCompositor);
71     if (!mSurface)
72     {
73         return false;
74     }
75 
76     mWindow = wl_egl_window_create(mSurface, width, height);
77     if (!mWindow)
78     {
79         return false;
80     }
81 
82     fds[0] = {wl_display_get_fd(mDisplay), POLLIN, 0};
83 
84     mY      = 0;
85     mX      = 0;
86     mWidth  = width;
87     mHeight = height;
88 
89     return true;
90 }
91 
disableErrorMessageDialog()92 void WaylandWindow::disableErrorMessageDialog() {}
93 
destroy()94 void WaylandWindow::destroy()
95 {
96     if (mWindow)
97     {
98         wl_egl_window_destroy(mWindow);
99         mWindow = nullptr;
100     }
101 
102     if (mSurface)
103     {
104         wl_surface_destroy(mSurface);
105         mSurface = nullptr;
106     }
107 
108     if (mCompositor)
109     {
110         wl_compositor_destroy(mCompositor);
111         mCompositor = nullptr;
112     }
113 }
114 
resetNativeWindow()115 void WaylandWindow::resetNativeWindow() {}
116 
getNativeWindow() const117 EGLNativeWindowType WaylandWindow::getNativeWindow() const
118 {
119     return reinterpret_cast<EGLNativeWindowType>(mWindow);
120 }
121 
getNativeDisplay() const122 EGLNativeDisplayType WaylandWindow::getNativeDisplay() const
123 {
124     return reinterpret_cast<EGLNativeDisplayType>(mDisplay);
125 }
126 
messageLoop()127 void WaylandWindow::messageLoop()
128 {
129     while (wl_display_prepare_read(mDisplay) != 0)
130         wl_display_dispatch_pending(mDisplay);
131     if (wl_display_flush(mDisplay) < 0 && errno != EAGAIN)
132     {
133         wl_display_cancel_read(mDisplay);
134         return;
135     }
136     if (poll(fds, 1, 0) > 0)
137     {
138         wl_display_read_events(mDisplay);
139         wl_display_dispatch_pending(mDisplay);
140     }
141     else
142     {
143         wl_display_cancel_read(mDisplay);
144     }
145 }
146 
setMousePosition(int x,int y)147 void WaylandWindow::setMousePosition(int x, int y) {}
148 
setOrientation(int width,int height)149 bool WaylandWindow::setOrientation(int width, int height)
150 {
151     return true;
152 }
153 
setPosition(int x,int y)154 bool WaylandWindow::setPosition(int x, int y)
155 {
156     return true;
157 }
158 
resize(int width,int height)159 bool WaylandWindow::resize(int width, int height)
160 {
161     wl_egl_window_resize(mWindow, width, height, 0, 0);
162 
163     mWidth  = width;
164     mHeight = height;
165 
166     return true;
167 }
168 
setVisible(bool isVisible)169 void WaylandWindow::setVisible(bool isVisible) {}
170 
signalTestEvent()171 void WaylandWindow::signalTestEvent() {}
172 
IsWaylandWindowAvailable()173 bool IsWaylandWindowAvailable()
174 {
175     wl_display *display = wl_display_connect(nullptr);
176     if (!display)
177     {
178         return false;
179     }
180     wl_display_disconnect(display);
181     return true;
182 }
183