13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ---------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief X11 utilities. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuX11.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderConfig.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <X11/Xutil.h> 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace x11 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DEFAULT_WINDOW_WIDTH = 400, 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DEFAULT_WINDOW_HEIGHT = 300 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryEventState::EventState (void) 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_quit(false) 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryEventState::~EventState (void) 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid EventState::setQuitFlag (bool quit) 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::ScopedLock lock(m_mutex); 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_quit = quit; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool EventState::getQuitFlag (void) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::ScopedLock lock(m_mutex); 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_quit; 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDisplay::Display (EventState& eventState, const char* name) 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_eventState (eventState) 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_display (DE_NULL) 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_deleteAtom (DE_NULL) 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_display = XOpenDisplay((char*)name); // Won't modify argument string. 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_display) 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ResourceError("Failed to open display", name, __FILE__, __LINE__); 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_deleteAtom = XInternAtom(m_display, "WM_DELETE_WINDOW", False); 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDisplay::~Display (void) 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XCloseDisplay(m_display); 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Display::processEvents (void) 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XEvent event; 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (XPending(m_display)) 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XNextEvent(m_display, &event); 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2010-10-27 pyry] Handle ConfigureNotify? 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (event.type == ClientMessage && (unsigned)event.xclient.data.l[0] == m_deleteAtom) 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_eventState.setQuitFlag(true); 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Display::getVisualInfo (VisualID visualID, XVisualInfo& dst) 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XVisualInfo query; 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry query.visualid = visualID; 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVisuals = 0; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XVisualInfo* response = XGetVisualInfo(m_display, VisualIDMask, &query, &numVisuals); 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool succ = false; 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (response != DE_NULL) 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numVisuals > 0) // should be 1, but you never know... 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst = response[0]; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry succ = true; 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XFree(response); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return succ; 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry::Visual* Display::getVisual (VisualID visualID) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XVisualInfo info; 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getVisualInfo(visualID, info)) 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return info.visual; 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindow::Window (Display& display, int width, int height, ::Visual* visual) 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_display (display) 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_colormap (None) 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_window (None) 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_visible (false) 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XSetWindowAttributes swa; 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ::Display* dpy = m_display.getXDisplay(); 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ::Window root = DefaultRootWindow(dpy); 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry unsigned long mask = CWBorderPixel | CWEventMask; 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (visual == DE_NULL) 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry visual = CopyFromParent; 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XVisualInfo info = XVisualInfo(); 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool succ = display.getVisualInfo(XVisualIDFromVisual(visual), info); 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK_INTERNAL(succ); 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root = RootWindow(dpy, info.screen); 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_colormap = XCreateColormap(dpy, root, visual, AllocNone); 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swa.colormap = m_colormap; 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mask |= CWColormap; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swa.border_pixel = 0; 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swa.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask; 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mask |= CWOverrideRedirect; 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swa.override_redirect = true; 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (width == glu::RenderConfig::DONT_CARE) 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry width = DEFAULT_WINDOW_WIDTH; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (height == glu::RenderConfig::DONT_CARE) 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry height = DEFAULT_WINDOW_HEIGHT; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_window = XCreateWindow(dpy, root, 0, 0, width, height, 0, 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CopyFromParent, InputOutput, visual, mask, &swa); 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(m_window); 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Atom deleteAtom = m_display.getDeleteAtom(); 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XSetWMProtocols(dpy, m_window, &deleteAtom, 1); 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Window::setVisibility (bool visible) 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ::Display* dpy = m_display.getXDisplay(); 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int eventType = None; 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XEvent event; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (visible == m_visible) 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (visible) 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XMapWindow(dpy, m_window); 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry eventType = MapNotify; 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XUnmapWindow(dpy, m_window); 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry eventType = UnmapNotify; 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We are only interested about exposure/structure notify events, not user input 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XSelectInput(dpy, m_window, ExposureMask | StructureNotifyMask); 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry do 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XNextEvent(dpy, &event); 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } while (event.type != eventType); 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_visible = visible; 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Window::getDimensions (int* width, int* height) const 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int x, y; 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ::Window root; 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry unsigned width_, height_, borderWidth, depth; 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XGetGeometry(m_display.getXDisplay(), m_window, &root, &x, &y, &width_, &height_, &borderWidth, &depth); 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (width != DE_NULL) 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *width = static_cast<int>(width_); 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (height != DE_NULL) 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *height = static_cast<int>(height_); 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Window::setDimensions (int width, int height) 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const unsigned int mask = CWWidth | CWHeight; 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XWindowChanges changes; 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry changes.width = width; 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry changes.height = height; 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XConfigureWindow(m_display.getXDisplay(), m_window, mask, &changes); 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Window::processEvents (void) 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // A bit of a hack, since we don't really handle all the events. 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_display.processEvents(); 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindow::~Window (void) 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XDestroyWindow(m_display.getXDisplay(), m_window); 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_colormap != None) 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XFreeColormap(m_display.getXDisplay(), m_colormap); 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // x11 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu 239