glx: don't call XMapWindow redundantly
[piglit.git] / tests / glx / glx-query-drawable.c
blob49f02e717e4a9663a514ecb5fd261fe3a54fa54c
1 /*
2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 /**
25 * @file glx-query-drawable.c
27 * Test the behavior of glXQueryDrawable(). See GLX 1.4 spec, Section 3.3.6
28 * Querying Attributes.
30 * For usage information, see usage_error();
33 #include "piglit-util-gl.h"
34 #include "piglit-glx-util.h"
36 int piglit_width = 137;
37 int piglit_height = 119;
38 GLXFBConfig config = None;
40 enum _drawable_type {
41 WINDOW,
42 GLXWINDOW,
43 GLXPIXMAP,
44 GLXPBUFFER,
47 int drawable_type /* = WINDOW */;
49 void
50 usage_error()
52 const char *message =
53 "usage:\n"
54 " glx-query-drawable --bad-drawable\n"
55 " Call glXQueryDrawable(drawable=0) and expect that error\n"
56 " GLXBadDrawable is generated.\n"
57 "\n"
58 " glx-query-drawable --attr=GLX_WIDTH\n"
59 " glx-query-drawable --attr=GLX_HEIGHT\n"
60 " glx-query-drawable --attr=GLX_FBCONFIG_ID\n"
61 " glx-query-drawable --attr=GLX_PRESERVED_CONTENTS (pbuffer only)\n"
62 " Call glXQueryDrawable() with the given attribute.\n"
63 "\n"
64 " Options:\n"
65 " -auto"
66 " --type={GLX{WINDOW,PIXMAP,PBUFFER},WINDOW}\n"
67 " Default is: not -auto, WINDOW\n";
68 printf("%s", message);
69 piglit_report_result(PIGLIT_FAIL);
72 /***************************************************************************/
74 /**
75 * @name X Error Handlers
76 * @{
79 bool found_error_glxbaddrawable = false;
81 static int
82 expect_no_error(Display *display, XErrorEvent *error)
84 static char buf[256];
85 XGetErrorText(display, error->error_code, buf, 256);
86 fprintf(stderr, "error: unexpected X error: %s\n", buf);
87 piglit_report_result(PIGLIT_FAIL);
88 return 0;
91 static int
92 expect_glxbaddrawable(Display *display, XErrorEvent *error)
94 if (piglit_glx_get_error(display, error) == GLXBadDrawable) {
95 found_error_glxbaddrawable = true;
96 } else {
97 static char buf[256];
98 XGetErrorText(display, error->error_code, buf, 256);
99 fprintf(stderr, "error: unexpected X error: %s\n", buf);
100 piglit_report_result(PIGLIT_FAIL);
102 return 0;
105 /***************************************************************************/
108 * @}
109 * @name Test Functions
110 * @{
113 static void query_width(Display *display, GLXDrawable draw) {
114 unsigned int width = 0;
116 XSetErrorHandler(expect_no_error);
117 glXQueryDrawable(display, draw, GLX_WIDTH, &width);
119 /* Sync before checking width in order to catch X errors. */
120 XSync(display, 0);
122 if (width != piglit_width) {
123 fprintf(stderr,
124 "error: width=%d but glXQueryDrawable returned %d\n",
125 piglit_width, width);
126 piglit_report_result(PIGLIT_FAIL);
129 piglit_report_result(PIGLIT_PASS);
132 static void query_height(Display *display, GLXDrawable draw) {
133 unsigned int height = 0;
135 XSetErrorHandler(expect_no_error);
136 glXQueryDrawable(display, draw, GLX_HEIGHT, &height);
138 /* Sync before checking height in order to catch X errors. */
139 XSync(display, 0);
141 if (height != piglit_height) {
142 fprintf(stderr,
143 "error: height=%d but glXQueryDrawable returned %d\n",
144 piglit_height, height);
145 piglit_report_result(PIGLIT_FAIL);
148 piglit_report_result(PIGLIT_PASS);
151 static void query_fbconfig_id(Display *display, GLXDrawable draw) {
152 unsigned int id = 0;
153 int piglit_id = 0;
154 enum piglit_result result = PIGLIT_PASS;
156 XSetErrorHandler(expect_no_error);
157 glXQueryDrawable(display, draw, GLX_FBCONFIG_ID, &id);
158 glXGetFBConfigAttrib(display, config, GLX_FBCONFIG_ID, &piglit_id);
160 /* Sync before checking in order to catch X errors. */
161 XSync(display, 0);
163 if (id == 0) {
164 fprintf(stderr, "error: no fbconfig id returned\n");
165 result = PIGLIT_FAIL;
168 if (id != piglit_id) {
169 if (!(drawable_type == WINDOW && id == None)) {
170 fprintf(stderr, "error: id=%d but should be %d\n",
171 id, piglit_id);
172 result = PIGLIT_FAIL;
176 piglit_report_result(result);
179 static void query_preserved_contents(Display *display, GLXDrawable draw) {
180 unsigned int contents = 42;
181 enum piglit_result result = PIGLIT_PASS;
183 if ((contents == True) || (contents == False)) {
184 fprintf(stderr, "This is a very strange dojo\n");
185 piglit_report_result(PIGLIT_SKIP);
186 return;
189 XSetErrorHandler(expect_no_error);
190 glXQueryDrawable(display, draw, GLX_PRESERVED_CONTENTS, &contents);
192 /* Sync before checking in order to catch X errors. */
193 XSync(display, 0);
195 if ((contents != True) && (contents != False)) {
196 fprintf(stderr, "error: Unexpected value %d\n", contents);
197 result = PIGLIT_FAIL;
200 piglit_report_result(result);
203 static void query_bad_drawable(Display *display, GLXDrawable draw) {
204 unsigned int width;
205 (void) draw;
207 XSetErrorHandler(expect_glxbaddrawable);
208 glXQueryDrawable(display, 0, GLX_WIDTH, &width);
209 XSync(display, 0);
211 if (!found_error_glxbaddrawable) {
212 fprintf(stderr,
213 "error: glXQueryDrawable(draw=0) did not generate "
214 "GLXBadDrawable\n");
215 piglit_report_result(PIGLIT_FAIL);
218 piglit_report_result(PIGLIT_PASS);
221 /** @} */
223 /***************************************************************************/
225 static void
226 parse_args(int argc, char **argv,
227 void (**test_func)(Display*, GLXDrawable))
229 int i;
231 /* Count of parsed args, excluding -auto. */
232 int num_parsed_args = 0;
234 for (i = 1; i < argc; ++i) {
235 const char *arg = argv[i];
236 if (!strncmp(arg, "-auto", 5)) {
237 piglit_automatic = 1;
238 } else if (!strncmp(arg, "--bad-drawable", 14)) {
239 ++num_parsed_args;
240 *test_func = query_bad_drawable;
241 } else if (!strncmp(arg, "--attr=GLX_WIDTH", 16)) {
242 ++num_parsed_args;
243 *test_func = query_width;
244 } else if (!strncmp(arg, "--attr=GLX_HEIGHT", 17)) {
245 ++num_parsed_args;
246 *test_func = query_height;
247 } else if (!strncmp(arg, "--attr=GLX_FBCONFIG_ID", 22)) {
248 ++num_parsed_args;
249 *test_func = query_fbconfig_id;
250 } else if (!strncmp(arg, "--attr=GLX_PRESERVED_CONTENTS", 29)) {
251 ++num_parsed_args;
252 *test_func = query_preserved_contents;
253 } else if (!strncmp(arg, "--type=GLXWINDOW", 16)) {
254 ++num_parsed_args;
255 drawable_type = GLXWINDOW;
256 } else if (!strncmp(arg, "--type=GLXPIXMAP", 16)) {
257 ++num_parsed_args;
258 drawable_type = GLXPIXMAP;
259 } else if (!strncmp(arg, "--type=GLXPBUFFER", 17)) {
260 ++num_parsed_args;
261 drawable_type = GLXPBUFFER;
262 } else if (!strncmp(arg, "--type=WINDOW", 13)) {
263 ++num_parsed_args;
264 drawable_type = WINDOW;
265 } else {
266 /* Unrecognized argument. */
267 usage_error();
271 if (*test_func == query_preserved_contents)
272 if (drawable_type != GLXPBUFFER)
273 usage_error();
275 if (num_parsed_args < 1) {
276 usage_error();
280 int main(int argc, char **argv) {
281 Display *display;
282 XVisualInfo *visual;
283 GLXDrawable draw;
284 GLXContext ctx;
285 void (*test_func)(Display*, GLXDrawable);
287 parse_args(argc, argv, &test_func);
289 display = piglit_get_glx_display();
290 piglit_require_glx_version(display, 1, 3);
292 visual = piglit_get_glx_visual(display);
293 config = piglit_glx_get_fbconfig_for_visinfo(display, visual);
294 ctx = piglit_get_glx_context(display, visual);
296 switch (drawable_type) {
297 case GLXWINDOW:
298 draw = glXCreateWindow(display, config,
299 piglit_get_glx_window(display, visual),
300 NULL);
301 break;
302 case GLXPIXMAP:
303 draw = glXCreatePixmap(display, config,
304 XCreatePixmap(display,
305 DefaultRootWindow(display),
306 piglit_width, piglit_height,
307 visual->depth),
308 NULL);
309 break;
310 case GLXPBUFFER: {
311 int attribs[] = { GLX_PBUFFER_WIDTH, piglit_width,
312 GLX_PBUFFER_HEIGHT, piglit_height,
313 None };
314 draw = glXCreatePbuffer(display, config, attribs);
315 break;
317 case WINDOW:
318 draw = piglit_get_glx_window(display, visual);
319 break;
320 default:
321 assert(0);
322 draw = 0;
325 glXMakeCurrent(display, draw, ctx);
327 /* Must initialize static variables of this function. */
328 piglit_glx_get_error(display, NULL);
330 test_func(display, draw);
332 return 0;