xref: /aosp_15_r20/external/angle/util/linux/wayland/WaylandWindow.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 #include <cerrno>
11 #include <cstring>
12 
WaylandWindow()13 WaylandWindow::WaylandWindow()
14     : mDisplay{nullptr}, mCompositor{nullptr}, mSurface{nullptr}, mWindow{nullptr}
15 {}
16 
~WaylandWindow()17 WaylandWindow::~WaylandWindow()
18 {
19     destroy();
20 }
21 
RegistryHandleGlobal(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)22 void WaylandWindow::RegistryHandleGlobal(void *data,
23                                          struct wl_registry *registry,
24                                          uint32_t name,
25                                          const char *interface,
26                                          uint32_t version)
27 {
28     WaylandWindow *vc = reinterpret_cast<WaylandWindow *>(data);
29 
30     if (strcmp(interface, "wl_compositor") == 0)
31     {
32         void *compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
33         vc->mCompositor  = reinterpret_cast<wl_compositor *>(compositor);
34     }
35 }
36 
RegistryHandleGlobalRemove(void * data,struct wl_registry * registry,uint32_t name)37 void WaylandWindow::RegistryHandleGlobalRemove(void *data,
38                                                struct wl_registry *registry,
39                                                uint32_t name)
40 {}
41 
42 const struct wl_registry_listener WaylandWindow::registryListener = {
43     WaylandWindow::RegistryHandleGlobal, WaylandWindow::RegistryHandleGlobalRemove};
44 
initializeImpl(const std::string & name,int width,int height)45 bool WaylandWindow::initializeImpl(const std::string &name, int width, int height)
46 {
47     destroy();
48 
49     if (!mDisplay)
50     {
51         mDisplay = wl_display_connect(nullptr);
52         if (!mDisplay)
53         {
54             return false;
55         }
56     }
57 
58     // Not get a window
59     struct wl_registry *registry = wl_display_get_registry(mDisplay);
60     wl_registry_add_listener(registry, &registryListener, this);
61 
62     // Round-trip to get globals
63     wl_display_roundtrip(mDisplay);
64     if (!mCompositor)
65     {
66         return false;
67     }
68 
69     // We don't need this anymore
70     wl_registry_destroy(registry);
71 
72     mSurface = wl_compositor_create_surface(mCompositor);
73     if (!mSurface)
74     {
75         return false;
76     }
77 
78     mWindow = wl_egl_window_create(mSurface, width, height);
79     if (!mWindow)
80     {
81         return false;
82     }
83 
84     fds[0] = {wl_display_get_fd(mDisplay), POLLIN, 0};
85 
86     mY      = 0;
87     mX      = 0;
88     mWidth  = width;
89     mHeight = height;
90 
91     return true;
92 }
93 
disableErrorMessageDialog()94 void WaylandWindow::disableErrorMessageDialog() {}
95 
destroy()96 void WaylandWindow::destroy()
97 {
98     if (mWindow)
99     {
100         wl_egl_window_destroy(mWindow);
101         mWindow = nullptr;
102     }
103 
104     if (mSurface)
105     {
106         wl_surface_destroy(mSurface);
107         mSurface = nullptr;
108     }
109 
110     if (mCompositor)
111     {
112         wl_compositor_destroy(mCompositor);
113         mCompositor = nullptr;
114     }
115 }
116 
resetNativeWindow()117 void WaylandWindow::resetNativeWindow() {}
118 
setNativeDisplay(EGLNativeDisplayType display)119 void WaylandWindow::setNativeDisplay(EGLNativeDisplayType display)
120 {
121     mDisplay = reinterpret_cast<wl_display *>(display);
122 }
123 
getNativeWindow() const124 EGLNativeWindowType WaylandWindow::getNativeWindow() const
125 {
126     return reinterpret_cast<EGLNativeWindowType>(mWindow);
127 }
128 
getNativeDisplay() const129 EGLNativeDisplayType WaylandWindow::getNativeDisplay() const
130 {
131     return reinterpret_cast<EGLNativeDisplayType>(mDisplay);
132 }
133 
messageLoop()134 void WaylandWindow::messageLoop()
135 {
136     while (wl_display_prepare_read(mDisplay) != 0)
137         wl_display_dispatch_pending(mDisplay);
138     if (wl_display_flush(mDisplay) < 0 && errno != EAGAIN)
139     {
140         wl_display_cancel_read(mDisplay);
141         return;
142     }
143     if (poll(fds, 1, 0) > 0)
144     {
145         wl_display_read_events(mDisplay);
146         wl_display_dispatch_pending(mDisplay);
147     }
148     else
149     {
150         wl_display_cancel_read(mDisplay);
151     }
152 }
153 
setMousePosition(int x,int y)154 void WaylandWindow::setMousePosition(int x, int y) {}
155 
setOrientation(int width,int height)156 bool WaylandWindow::setOrientation(int width, int height)
157 {
158     return true;
159 }
160 
setPosition(int x,int y)161 bool WaylandWindow::setPosition(int x, int y)
162 {
163     return true;
164 }
165 
resize(int width,int height)166 bool WaylandWindow::resize(int width, int height)
167 {
168     wl_egl_window_resize(mWindow, width, height, 0, 0);
169 
170     mWidth  = width;
171     mHeight = height;
172 
173     return true;
174 }
175 
setVisible(bool isVisible)176 void WaylandWindow::setVisible(bool isVisible) {}
177 
signalTestEvent()178 void WaylandWindow::signalTestEvent() {}
179 
IsWaylandWindowAvailable()180 bool IsWaylandWindowAvailable()
181 {
182     wl_display *display = wl_display_connect(nullptr);
183     if (!display)
184     {
185         return false;
186     }
187     wl_display_disconnect(display);
188     return true;
189 }
190