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