1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Tester Core 3 * ---------------------------------------- 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief X11 using XCB utilities. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "tcuX11Xcb.hpp" 25 #include "deMemory.h" 26 27 namespace tcu 28 { 29 namespace x11 30 { 31 32 XcbDisplay::XcbDisplay (EventState& platform, const char* name) 33 : DisplayBase (platform) 34 { 35 m_connection = xcb_connect(name, NULL); 36 const xcb_setup_t *setup = xcb_get_setup(m_connection); 37 xcb_screen_iterator_t iterator = xcb_setup_roots_iterator(setup); 38 m_screen = iterator.data; 39 } 40 41 XcbDisplay::~XcbDisplay (void) 42 { 43 xcb_disconnect (m_connection); 44 } 45 46 void XcbDisplay::processEvents (void) 47 { 48 xcb_generic_event_t *ev; 49 while ((ev = xcb_poll_for_event(m_connection))) 50 { 51 deFree(ev); 52 /* Manage your event */ 53 } 54 } 55 56 XcbWindow::XcbWindow (XcbDisplay& display, int width, int height, xcb_visualid_t* visual) 57 : WindowBase () 58 , m_display (display) 59 { 60 xcb_connection_t* connection = m_display.getConnection(); 61 uint32_t values[2]; 62 m_window = xcb_generate_id(connection); 63 m_colormap = xcb_generate_id(connection); 64 65 if (visual == DE_NULL) 66 visual = &m_display.getScreen()->root_visual; 67 68 values[0] = m_display.getScreen()->white_pixel; 69 values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_PROPERTY_CHANGE; 70 71 xcb_create_window ( 72 connection, // Connection 73 XCB_COPY_FROM_PARENT, // depth (same as root) 74 m_window, // window Id 75 display.getScreen()->root, // parent window 76 0, 0, // x, y 77 static_cast<uint16_t >(width), // width 78 static_cast<uint16_t >(height), // height 79 10, // border_width 80 XCB_WINDOW_CLASS_INPUT_OUTPUT, // class 81 *visual, // visual 82 XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, // masks 83 values //not used yet 84 ); 85 86 xcb_create_colormap ( 87 connection, 88 XCB_COLORMAP_ALLOC_NONE, 89 m_colormap, 90 m_window, 91 *visual 92 ); 93 94 xcb_alloc_color_reply_t* rep = xcb_alloc_color_reply(connection, xcb_alloc_color(connection, m_colormap, 65535, 0, 0), NULL); 95 deFree(rep); 96 xcb_flush (connection); 97 } 98 99 XcbWindow::~XcbWindow (void) 100 { 101 xcb_flush (m_display.getConnection()); 102 xcb_free_colormap(m_display.getConnection(), m_colormap); 103 xcb_destroy_window(m_display.getConnection(), m_window); 104 } 105 106 void XcbWindow::setVisibility (bool visible) 107 { 108 if (visible == m_visible) 109 return; 110 111 if (visible) 112 xcb_map_window(m_display.getConnection(), m_window); 113 else 114 xcb_unmap_window(m_display.getConnection(), m_window); 115 116 m_visible = visible; 117 xcb_flush (m_display.getConnection()); 118 119 } 120 121 void XcbWindow::processEvents (void) 122 { 123 // A bit of a hack, since we don't really handle all the events. 124 m_display.processEvents(); 125 } 126 127 void XcbWindow::getDimensions (int* width, int* height) const 128 { 129 xcb_get_geometry_reply_t *geom; 130 geom = xcb_get_geometry_reply(m_display.getConnection(), xcb_get_geometry(m_display.getConnection(), m_window), NULL); 131 *height = static_cast<int>(geom->height); 132 *width = static_cast<int>(geom->width); 133 deFree(geom); 134 } 135 136 void XcbWindow::setDimensions (int width, int height) 137 { 138 const uint32_t values[] = {static_cast<uint32_t >(width), static_cast<uint32_t >(height)}; 139 xcb_void_cookie_t result; 140 xcb_connection_t* display = m_display.getConnection(); 141 result = xcb_configure_window(display, m_window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values); 142 DE_ASSERT(DE_NULL == xcb_request_check(display,result)); 143 xcb_flush (display); 144 145 for(;;) 146 { 147 xcb_generic_event_t* event = xcb_poll_for_event(display); 148 int w, h; 149 if(event != DE_NULL) 150 { 151 if (XCB_PROPERTY_NOTIFY == (event->response_type & ~0x80)) 152 { 153 const xcb_property_notify_event_t* pnEvent = (xcb_property_notify_event_t*)event; 154 if (pnEvent->atom == XCB_ATOM_RESOLUTION) 155 { 156 deFree(event); 157 break; 158 } 159 } 160 deFree(event); 161 } 162 getDimensions (&w,&h); 163 if (h==height || w==width) 164 break; 165 } 166 } 167 168 } // xcb 169 } // tcu 170