• 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 
XcbDisplay(EventState & platform,const char * name)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 
~XcbDisplay(void)43 XcbDisplay::~XcbDisplay (void)
44 {
45 	xcb_disconnect (m_connection);
46 }
47 
processEvents(void)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 
XcbWindow(XcbDisplay & display,int width,int height,xcb_visualid_t * visual)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 
~XcbWindow(void)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 
setVisibility(bool visible)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 
processEvents(void)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 
getDimensions(int * width,int * height) const129 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 
setDimensions(int width,int height)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