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