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 "tcuLnxX11Xcb.hpp" 25 #include "deMemory.h" 26 27 namespace tcu 28 { 29 namespace lnx 30 { 31 namespace x11 32 { 33 34 XcbDisplay::XcbDisplay (EventState& platform, const char* name) 35 : DisplayBase (platform) 36 { 37 m_connection = xcb_connect(name, NULL); 38 const xcb_setup_t *setup = xcb_get_setup(m_connection); 39 xcb_screen_iterator_t iterator = xcb_setup_roots_iterator(setup); 40 m_screen = iterator.data; 41 } 42 43 XcbDisplay::~XcbDisplay (void) 44 { 45 xcb_disconnect (m_connection); 46 } 47 48 void XcbDisplay::processEvents (void) 49 { 50 xcb_generic_event_t *ev; 51 while ((ev = xcb_poll_for_event(m_connection))) 52 { 53 deFree(ev); 54 /* Manage your event */ 55 } 56 } 57 58 XcbWindow::XcbWindow (XcbDisplay& display, int width, int height, xcb_visualid_t* visual) 59 : WindowBase () 60 , m_display (display) 61 { 62 xcb_connection_t* connection = m_display.getConnection(); 63 uint32_t values[2]; 64 m_window = xcb_generate_id(connection); 65 m_colormap = xcb_generate_id(connection); 66 67 if (visual == DE_NULL) 68 visual = &m_display.getScreen()->root_visual; 69 70 values[0] = m_display.getScreen()->white_pixel; 71 values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_PROPERTY_CHANGE; 72 73 xcb_create_window ( 74 connection, // Connection 75 XCB_COPY_FROM_PARENT, // depth (same as root) 76 m_window, // window Id 77 display.getScreen()->root, // parent window 78 0, 0, // x, y 79 static_cast<uint16_t >(width), // width 80 static_cast<uint16_t >(height), // height 81 10, // border_width 82 XCB_WINDOW_CLASS_INPUT_OUTPUT, // class 83 *visual, // visual 84 XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, // masks 85 values //not used yet 86 ); 87 88 xcb_create_colormap ( 89 connection, 90 XCB_COLORMAP_ALLOC_NONE, 91 m_colormap, 92 m_window, 93 *visual 94 ); 95 96 xcb_alloc_color_reply_t* rep = xcb_alloc_color_reply(connection, xcb_alloc_color(connection, m_colormap, 65535, 0, 0), NULL); 97 deFree(rep); 98 xcb_flush (connection); 99 } 100 101 XcbWindow::~XcbWindow (void) 102 { 103 xcb_flush (m_display.getConnection()); 104 xcb_free_colormap(m_display.getConnection(), m_colormap); 105 xcb_destroy_window(m_display.getConnection(), m_window); 106 } 107 108 void XcbWindow::setVisibility (bool visible) 109 { 110 if (visible == m_visible) 111 return; 112 113 if (visible) 114 xcb_map_window(m_display.getConnection(), m_window); 115 else 116 xcb_unmap_window(m_display.getConnection(), m_window); 117 118 m_visible = visible; 119 xcb_flush (m_display.getConnection()); 120 121 } 122 123 void XcbWindow::processEvents (void) 124 { 125 // A bit of a hack, since we don't really handle all the events. 126 m_display.processEvents(); 127 } 128 129 void XcbWindow::getDimensions (int* width, int* height) const 130 { 131 xcb_get_geometry_reply_t *geom; 132 geom = xcb_get_geometry_reply(m_display.getConnection(), xcb_get_geometry(m_display.getConnection(), m_window), NULL); 133 *height = static_cast<int>(geom->height); 134 *width = static_cast<int>(geom->width); 135 deFree(geom); 136 } 137 138 void XcbWindow::setDimensions (int width, int height) 139 { 140 const uint32_t values[] = {static_cast<uint32_t >(width), static_cast<uint32_t >(height)}; 141 xcb_void_cookie_t result; 142 xcb_connection_t* display = m_display.getConnection(); 143 result = xcb_configure_window(display, m_window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values); 144 DE_ASSERT(DE_NULL == xcb_request_check(display,result)); 145 xcb_flush (display); 146 147 for(;;) 148 { 149 xcb_generic_event_t* event = xcb_poll_for_event(display); 150 int w, h; 151 if(event != DE_NULL) 152 { 153 if (XCB_PROPERTY_NOTIFY == (event->response_type & ~0x80)) 154 { 155 const xcb_property_notify_event_t* pnEvent = (xcb_property_notify_event_t*)event; 156 if (pnEvent->atom == XCB_ATOM_RESOLUTION) 157 { 158 deFree(event); 159 break; 160 } 161 } 162 deFree(event); 163 } 164 getDimensions (&w,&h); 165 if (h==height || w==width) 166 break; 167 } 168 } 169 170 } // xcb 171 } // lnx 172 } // tcu 173