/*-------------------------------------------------------------------------
* drawElements Quality Program Tester Core
* ----------------------------------------
*
* Copyright (c) 2016 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief X11 using XCB utilities.
*//*--------------------------------------------------------------------*/
#include "tcuX11Xcb.hpp"
#include "deMemory.h"
namespace tcu
{
namespace x11
{
XcbDisplay::XcbDisplay (EventState& platform, const char* name)
: DisplayBase (platform)
{
m_connection = xcb_connect(name, NULL);
const xcb_setup_t *setup = xcb_get_setup(m_connection);
xcb_screen_iterator_t iterator = xcb_setup_roots_iterator(setup);
m_screen = iterator.data;
}
XcbDisplay::~XcbDisplay (void)
{
xcb_disconnect (m_connection);
}
void XcbDisplay::processEvents (void)
{
xcb_generic_event_t *ev;
while ((ev = xcb_poll_for_event(m_connection)))
{
deFree(ev);
/* Manage your event */
}
}
XcbWindow::XcbWindow (XcbDisplay& display, int width, int height, xcb_visualid_t* visual)
: WindowBase ()
, m_display (display)
{
xcb_connection_t* connection = m_display.getConnection();
uint32_t values[2];
m_window = xcb_generate_id(connection);
m_colormap = xcb_generate_id(connection);
if (visual == DE_NULL)
visual = &m_display.getScreen()->root_visual;
values[0] = m_display.getScreen()->white_pixel;
values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_create_window (
connection, // Connection
XCB_COPY_FROM_PARENT, // depth (same as root)
m_window, // window Id
display.getScreen()->root, // parent window
0, 0, // x, y
static_cast<uint16_t >(width), // width
static_cast<uint16_t >(height), // height
10, // border_width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
*visual, // visual
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, // masks
values //not used yet
);
xcb_create_colormap (
connection,
XCB_COLORMAP_ALLOC_NONE,
m_colormap,
m_window,
*visual
);
xcb_alloc_color_reply_t* rep = xcb_alloc_color_reply(connection, xcb_alloc_color(connection, m_colormap, 65535, 0, 0), NULL);
deFree(rep);
xcb_flush (connection);
}
XcbWindow::~XcbWindow (void)
{
xcb_flush (m_display.getConnection());
xcb_free_colormap(m_display.getConnection(), m_colormap);
xcb_destroy_window(m_display.getConnection(), m_window);
}
void XcbWindow::setVisibility (bool visible)
{
if (visible == m_visible)
return;
if (visible)
xcb_map_window(m_display.getConnection(), m_window);
else
xcb_unmap_window(m_display.getConnection(), m_window);
m_visible = visible;
xcb_flush (m_display.getConnection());
}
void XcbWindow::processEvents (void)
{
// A bit of a hack, since we don't really handle all the events.
m_display.processEvents();
}
void XcbWindow::getDimensions (int* width, int* height) const
{
xcb_get_geometry_reply_t *geom;
geom = xcb_get_geometry_reply(m_display.getConnection(), xcb_get_geometry(m_display.getConnection(), m_window), NULL);
*height = static_cast<int>(geom->height);
*width = static_cast<int>(geom->width);
deFree(geom);
}
void XcbWindow::setDimensions (int width, int height)
{
const uint32_t values[] = {static_cast<uint32_t >(width), static_cast<uint32_t >(height)};
xcb_void_cookie_t result;
xcb_connection_t* display = m_display.getConnection();
result = xcb_configure_window(display, m_window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
DE_ASSERT(DE_NULL == xcb_request_check(display,result));
xcb_flush (display);
for(;;)
{
xcb_generic_event_t* event = xcb_poll_for_event(display);
int w, h;
if(event != DE_NULL)
{
if (XCB_PROPERTY_NOTIFY == (event->response_type & ~0x80))
{
const xcb_property_notify_event_t* pnEvent = (xcb_property_notify_event_t*)event;
if (pnEvent->atom == XCB_ATOM_RESOLUTION)
{
deFree(event);
break;
}
}
deFree(event);
}
getDimensions (&w,&h);
if (h==height || w==width)
break;
}
}
} // xcb
} // tcu