1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core 3e5c31af7Sopenharmony_ci * ---------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * Copyright (c) 2016 The Khronos Group Inc. 7e5c31af7Sopenharmony_ci * Copyright (c) 2016 Mun Gwan-gyeong <elongbug@gmail.com> 8e5c31af7Sopenharmony_ci * 9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci * 15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci * limitations under the License. 20e5c31af7Sopenharmony_ci * 21e5c31af7Sopenharmony_ci *//*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief wayland utilities. 24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "tcuLnxWayland.hpp" 27e5c31af7Sopenharmony_ci#include "gluRenderConfig.hpp" 28e5c31af7Sopenharmony_ci#include "deMemory.h" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include <stdio.h> 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_cinamespace tcu 33e5c31af7Sopenharmony_ci{ 34e5c31af7Sopenharmony_cinamespace lnx 35e5c31af7Sopenharmony_ci{ 36e5c31af7Sopenharmony_cinamespace wayland 37e5c31af7Sopenharmony_ci{ 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ciconst struct wl_registry_listener Display::s_registryListener 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci Display::handleGlobal, 42e5c31af7Sopenharmony_ci Display::handleGlobalRemove 43e5c31af7Sopenharmony_ci}; 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ciDisplay::DisplayState Display::s_displayState = Display::DISPLAY_STATE_UNKNOWN; 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_cibool Window::s_addWMBaseListener = true; 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciconst struct xdg_surface_listener Window::s_xdgSurfaceListener 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci Window::handleConfigure 52e5c31af7Sopenharmony_ci}; 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_ciconst struct xdg_wm_base_listener Window::s_wmBaseListener 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci Window::handlePing 57e5c31af7Sopenharmony_ci}; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_civoid Display::handleGlobal (void* data, struct wl_registry* registry, uint32_t id, const char* interface, uint32_t version) 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci Display* _this = static_cast<Display*>(data); 62e5c31af7Sopenharmony_ci DE_UNREF(version); 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ci if (!strcmp(interface, "wl_compositor")) 65e5c31af7Sopenharmony_ci _this->m_compositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, id, &wl_compositor_interface, version > 3 ? version : 3)); 66e5c31af7Sopenharmony_ci if (!strcmp(interface, "xdg_wm_base")) 67e5c31af7Sopenharmony_ci _this->m_shell = static_cast<struct xdg_wm_base*>(wl_registry_bind(registry, id, &xdg_wm_base_interface, 1)); 68e5c31af7Sopenharmony_ci} 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_civoid Display::handleGlobalRemove (void* data, struct wl_registry* registry, uint32_t name) 71e5c31af7Sopenharmony_ci{ 72e5c31af7Sopenharmony_ci DE_UNREF(data); 73e5c31af7Sopenharmony_ci DE_UNREF(registry); 74e5c31af7Sopenharmony_ci DE_UNREF(name); 75e5c31af7Sopenharmony_ci} 76e5c31af7Sopenharmony_ci 77e5c31af7Sopenharmony_cibool Display::hasDisplay (const char* name) 78e5c31af7Sopenharmony_ci{ 79e5c31af7Sopenharmony_ci if (s_displayState == DISPLAY_STATE_UNKNOWN) 80e5c31af7Sopenharmony_ci { 81e5c31af7Sopenharmony_ci struct wl_display *display = wl_display_connect(name); 82e5c31af7Sopenharmony_ci if (display) 83e5c31af7Sopenharmony_ci { 84e5c31af7Sopenharmony_ci s_displayState = DISPLAY_STATE_AVAILABLE; 85e5c31af7Sopenharmony_ci wl_display_disconnect(display); 86e5c31af7Sopenharmony_ci } else 87e5c31af7Sopenharmony_ci s_displayState = DISPLAY_STATE_UNAVAILABLE; 88e5c31af7Sopenharmony_ci } 89e5c31af7Sopenharmony_ci return s_displayState == DISPLAY_STATE_AVAILABLE ? true : false; 90e5c31af7Sopenharmony_ci} 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ciDisplay::Display (EventState& eventState, const char* name) 93e5c31af7Sopenharmony_ci : m_eventState (eventState) 94e5c31af7Sopenharmony_ci , m_display (DE_NULL) 95e5c31af7Sopenharmony_ci , m_registry (DE_NULL) 96e5c31af7Sopenharmony_ci , m_compositor (DE_NULL) 97e5c31af7Sopenharmony_ci , m_shell (DE_NULL) 98e5c31af7Sopenharmony_ci{ 99e5c31af7Sopenharmony_ci try 100e5c31af7Sopenharmony_ci { 101e5c31af7Sopenharmony_ci m_display = wl_display_connect(name); 102e5c31af7Sopenharmony_ci if (!m_display) 103e5c31af7Sopenharmony_ci throw ResourceError("Failed to open display", name, __FILE__, __LINE__); 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci m_registry = wl_display_get_registry(m_display); 106e5c31af7Sopenharmony_ci if (!m_registry) 107e5c31af7Sopenharmony_ci throw ResourceError("Failed to get registry", name, __FILE__, __LINE__); 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci wl_registry_add_listener(m_registry, &s_registryListener, this); 110e5c31af7Sopenharmony_ci wl_display_roundtrip(m_display); 111e5c31af7Sopenharmony_ci if (!m_compositor) 112e5c31af7Sopenharmony_ci throw ResourceError("Failed to bind compositor", name, __FILE__, __LINE__); 113e5c31af7Sopenharmony_ci if (!m_shell) 114e5c31af7Sopenharmony_ci throw ResourceError("Failed to bind shell", name, __FILE__, __LINE__); 115e5c31af7Sopenharmony_ci } 116e5c31af7Sopenharmony_ci catch (...) 117e5c31af7Sopenharmony_ci { 118e5c31af7Sopenharmony_ci if (m_shell) 119e5c31af7Sopenharmony_ci xdg_wm_base_destroy(m_shell); 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci if (m_compositor) 122e5c31af7Sopenharmony_ci wl_compositor_destroy(m_compositor); 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci if (m_registry) 125e5c31af7Sopenharmony_ci wl_registry_destroy(m_registry); 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci if (m_display) 128e5c31af7Sopenharmony_ci wl_display_disconnect(m_display); 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci throw; 131e5c31af7Sopenharmony_ci } 132e5c31af7Sopenharmony_ci} 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ciDisplay::~Display (void) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci if (m_shell) 137e5c31af7Sopenharmony_ci xdg_wm_base_destroy(m_shell); 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ci if (m_compositor) 140e5c31af7Sopenharmony_ci wl_compositor_destroy(m_compositor); 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci if (m_registry) 143e5c31af7Sopenharmony_ci wl_registry_destroy(m_registry); 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_ci if (m_display) 146e5c31af7Sopenharmony_ci wl_display_disconnect(m_display); 147e5c31af7Sopenharmony_ci} 148e5c31af7Sopenharmony_ci 149e5c31af7Sopenharmony_civoid Display::processEvents (void) 150e5c31af7Sopenharmony_ci{ 151e5c31af7Sopenharmony_ci} 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ciWindow::Window (Display& display, int width, int height) 154e5c31af7Sopenharmony_ci : m_display (display) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci try 157e5c31af7Sopenharmony_ci { 158e5c31af7Sopenharmony_ci m_surface = wl_compositor_create_surface(display.getCompositor()); 159e5c31af7Sopenharmony_ci if (!m_surface) 160e5c31af7Sopenharmony_ci throw ResourceError("Failed to create ", "surface", __FILE__, __LINE__); 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci m_xdgSurface = xdg_wm_base_get_xdg_surface(display.getShell(), m_surface); 163e5c31af7Sopenharmony_ci if (!m_xdgSurface) 164e5c31af7Sopenharmony_ci throw ResourceError("Failed to create ", "shell_surface", __FILE__, __LINE__); 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci // add wm base listener once 167e5c31af7Sopenharmony_ci if (s_addWMBaseListener) 168e5c31af7Sopenharmony_ci { 169e5c31af7Sopenharmony_ci xdg_wm_base_add_listener(display.getShell(), &s_wmBaseListener, this); 170e5c31af7Sopenharmony_ci s_addWMBaseListener = false; 171e5c31af7Sopenharmony_ci } 172e5c31af7Sopenharmony_ci xdg_surface_add_listener(m_xdgSurface, &s_xdgSurfaceListener, this); 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci // select xdg surface role 175e5c31af7Sopenharmony_ci m_topLevel = xdg_surface_get_toplevel(m_xdgSurface); 176e5c31af7Sopenharmony_ci xdg_toplevel_set_title(m_topLevel, "CTS for OpenGL (ES)"); 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci // configure xdg surface 179e5c31af7Sopenharmony_ci m_configured = false; 180e5c31af7Sopenharmony_ci wl_surface_commit(m_surface); 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci // wait till xdg surface is configured 183e5c31af7Sopenharmony_ci int dispatchedEvents = 0; 184e5c31af7Sopenharmony_ci while(dispatchedEvents != -1) 185e5c31af7Sopenharmony_ci { 186e5c31af7Sopenharmony_ci dispatchedEvents = wl_display_dispatch(display.getDisplay()); 187e5c31af7Sopenharmony_ci if (m_configured) 188e5c31af7Sopenharmony_ci break; 189e5c31af7Sopenharmony_ci } 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci if (width == glu::RenderConfig::DONT_CARE) 192e5c31af7Sopenharmony_ci width = DEFAULT_WINDOW_WIDTH; 193e5c31af7Sopenharmony_ci if (height == glu::RenderConfig::DONT_CARE) 194e5c31af7Sopenharmony_ci height = DEFAULT_WINDOW_HEIGHT; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci m_window = wl_egl_window_create(m_surface, width, height); 197e5c31af7Sopenharmony_ci if (!m_window) 198e5c31af7Sopenharmony_ci throw ResourceError("Failed to create ", "window", __FILE__, __LINE__); 199e5c31af7Sopenharmony_ci } 200e5c31af7Sopenharmony_ci catch (...) 201e5c31af7Sopenharmony_ci { 202e5c31af7Sopenharmony_ci throw; 203e5c31af7Sopenharmony_ci } 204e5c31af7Sopenharmony_ci TCU_CHECK(m_window); 205e5c31af7Sopenharmony_ci} 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_civoid Window::setVisibility (bool visible) 208e5c31af7Sopenharmony_ci{ 209e5c31af7Sopenharmony_ci m_visible = visible; 210e5c31af7Sopenharmony_ci} 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_civoid Window::getDimensions (int* width, int* height) const 213e5c31af7Sopenharmony_ci{ 214e5c31af7Sopenharmony_ci wl_egl_window_get_attached_size(m_window, width, height); 215e5c31af7Sopenharmony_ci} 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_civoid Window::setDimensions (int width, int height) 218e5c31af7Sopenharmony_ci{ 219e5c31af7Sopenharmony_ci wl_egl_window_resize(m_window, width, height, 0, 0); 220e5c31af7Sopenharmony_ci} 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_civoid Window::processEvents (void) 223e5c31af7Sopenharmony_ci{ 224e5c31af7Sopenharmony_ci} 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_civoid Window::handlePing (void* data, struct xdg_wm_base* shell, uint32_t serial) 227e5c31af7Sopenharmony_ci{ 228e5c31af7Sopenharmony_ci DE_UNREF(data); 229e5c31af7Sopenharmony_ci xdg_wm_base_pong(shell, serial); 230e5c31af7Sopenharmony_ci} 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_civoid Window::handleConfigure (void* data, struct xdg_surface* xdgSurface, uint32_t serial) 233e5c31af7Sopenharmony_ci{ 234e5c31af7Sopenharmony_ci Window* window = reinterpret_cast<Window*>(data); 235e5c31af7Sopenharmony_ci window->m_configured = true; 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci xdg_surface_ack_configure(xdgSurface, serial); 238e5c31af7Sopenharmony_ci} 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ciWindow::~Window (void) 241e5c31af7Sopenharmony_ci{ 242e5c31af7Sopenharmony_ci if (m_window) 243e5c31af7Sopenharmony_ci wl_egl_window_destroy(m_window); 244e5c31af7Sopenharmony_ci if (m_topLevel) 245e5c31af7Sopenharmony_ci xdg_toplevel_destroy(m_topLevel); 246e5c31af7Sopenharmony_ci if (m_xdgSurface) 247e5c31af7Sopenharmony_ci xdg_surface_destroy(m_xdgSurface); 248e5c31af7Sopenharmony_ci if (m_surface) 249e5c31af7Sopenharmony_ci wl_surface_destroy(m_surface); 250e5c31af7Sopenharmony_ci} 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci} // wayland 253e5c31af7Sopenharmony_ci} // lnx 254e5c31af7Sopenharmony_ci} // tcu 255