1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2013 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci#include <gtest/gtest.h>
24bf215546Sopenharmony_ci#include <signal.h>
25bf215546Sopenharmony_ci#include <setjmp.h>
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include "glxclient.h"
28bf215546Sopenharmony_ci#include "glx_error.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ciextern bool GetGLXScreenConfigs_called;
31bf215546Sopenharmony_ciextern struct glx_screen *psc;
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_cistruct attribute_test_vector {
34bf215546Sopenharmony_ci   const char *string;
35bf215546Sopenharmony_ci   int value;
36bf215546Sopenharmony_ci};
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci#define E(x) { # x, x }
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_cistatic bool got_sigsegv;
43bf215546Sopenharmony_cistatic jmp_buf jmp;
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_cistatic void
46bf215546Sopenharmony_cisigsegv_handler(int sig)
47bf215546Sopenharmony_ci{
48bf215546Sopenharmony_ci   (void) sig;
49bf215546Sopenharmony_ci   got_sigsegv = true;
50bf215546Sopenharmony_ci   longjmp(jmp, 1);
51bf215546Sopenharmony_ci}
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_cistatic bool query_renderer_string_called = false;
54bf215546Sopenharmony_cistatic bool query_renderer_integer_called = false;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_cistatic int
57bf215546Sopenharmony_cifake_query_renderer_integer(struct glx_screen *psc, int attribute,
58bf215546Sopenharmony_ci                            unsigned int *value)
59bf215546Sopenharmony_ci{
60bf215546Sopenharmony_ci   (void) psc;
61bf215546Sopenharmony_ci   (void) attribute;
62bf215546Sopenharmony_ci   (void) value;
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci   query_renderer_integer_called = true;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   return -1;
67bf215546Sopenharmony_ci}
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_cistatic int
70bf215546Sopenharmony_cifake_query_renderer_string(struct glx_screen *psc, int attribute,
71bf215546Sopenharmony_ci                           const char **value)
72bf215546Sopenharmony_ci{
73bf215546Sopenharmony_ci   (void) psc;
74bf215546Sopenharmony_ci   (void) attribute;
75bf215546Sopenharmony_ci   (void) value;
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci   query_renderer_string_called = true;
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   return -1;
80bf215546Sopenharmony_ci}
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_cistruct glx_screen_vtable fake_vtable = {
83bf215546Sopenharmony_ci   NULL,
84bf215546Sopenharmony_ci   NULL,
85bf215546Sopenharmony_ci   fake_query_renderer_integer,
86bf215546Sopenharmony_ci   fake_query_renderer_string
87bf215546Sopenharmony_ci};
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ciclass query_renderer_string_test : public ::testing::Test {
90bf215546Sopenharmony_cipublic:
91bf215546Sopenharmony_ci   virtual void SetUp();
92bf215546Sopenharmony_ci   virtual void TearDown();
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   struct glx_screen scr;
95bf215546Sopenharmony_ci   struct sigaction sa;
96bf215546Sopenharmony_ci   struct sigaction old_sa;
97bf215546Sopenharmony_ci   Display dpy;
98bf215546Sopenharmony_ci};
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ciclass query_renderer_integer_test : public query_renderer_string_test {
101bf215546Sopenharmony_ci};
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_civoid query_renderer_string_test::SetUp()
104bf215546Sopenharmony_ci{
105bf215546Sopenharmony_ci   memset(&scr, 0, sizeof(scr));
106bf215546Sopenharmony_ci   scr.vtable = &fake_vtable;
107bf215546Sopenharmony_ci   psc = &scr;
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   got_sigsegv = false;
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci   sa.sa_handler = sigsegv_handler;
112bf215546Sopenharmony_ci   sigemptyset(&sa.sa_mask);
113bf215546Sopenharmony_ci   sa.sa_flags = 0;
114bf215546Sopenharmony_ci   sigaction(SIGSEGV, &sa, &old_sa);
115bf215546Sopenharmony_ci}
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_civoid query_renderer_string_test::TearDown()
118bf215546Sopenharmony_ci{
119bf215546Sopenharmony_ci   sigaction(SIGSEGV, &old_sa, NULL);
120bf215546Sopenharmony_ci}
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci/**
123bf215546Sopenharmony_ci * glXQueryRendererStringMESA will return \c NULL if the query_render_string
124bf215546Sopenharmony_ci * vtable entry is \c NULL.  It will also not segfault.
125bf215546Sopenharmony_ci */
126bf215546Sopenharmony_ciTEST_F(query_renderer_string_test, null_query_render_string)
127bf215546Sopenharmony_ci{
128bf215546Sopenharmony_ci   struct glx_screen_vtable vtable = {
129bf215546Sopenharmony_ci      NULL,
130bf215546Sopenharmony_ci      NULL,
131bf215546Sopenharmony_ci      NULL,
132bf215546Sopenharmony_ci      NULL
133bf215546Sopenharmony_ci   };
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   scr.vtable = &vtable;
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
138bf215546Sopenharmony_ci      const char *str =
139bf215546Sopenharmony_ci         glXQueryRendererStringMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
140bf215546Sopenharmony_ci      EXPECT_EQ((char *)0, str);
141bf215546Sopenharmony_ci   } else {
142bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
143bf215546Sopenharmony_ci   }
144bf215546Sopenharmony_ci}
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci/**
147bf215546Sopenharmony_ci * glXQueryRendererStringMESA will not call the screen query_render_string
148bf215546Sopenharmony_ci * function with an invalid GLX enum value, and it will return NULL.
149bf215546Sopenharmony_ci */
150bf215546Sopenharmony_ciTEST_F(query_renderer_string_test, invalid_attribute)
151bf215546Sopenharmony_ci{
152bf215546Sopenharmony_ci   static const attribute_test_vector invalid_attributes[] = {
153bf215546Sopenharmony_ci      /* These values are just plain invalid for use with this extension.
154bf215546Sopenharmony_ci       */
155bf215546Sopenharmony_ci      E(0),
156bf215546Sopenharmony_ci      E(GLX_VENDOR),
157bf215546Sopenharmony_ci      E(GLX_VERSION),
158bf215546Sopenharmony_ci      E(GLX_EXTENSIONS),
159bf215546Sopenharmony_ci      E(GLX_RENDERER_VENDOR_ID_MESA + 0x10000),
160bf215546Sopenharmony_ci      E(GLX_RENDERER_DEVICE_ID_MESA + 0x10000),
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci      /* These enums are part of the extension, but they are not allowed for
163bf215546Sopenharmony_ci       * the string query.
164bf215546Sopenharmony_ci       */
165bf215546Sopenharmony_ci      E(GLX_RENDERER_VERSION_MESA),
166bf215546Sopenharmony_ci      E(GLX_RENDERER_ACCELERATED_MESA),
167bf215546Sopenharmony_ci      E(GLX_RENDERER_VIDEO_MEMORY_MESA),
168bf215546Sopenharmony_ci      E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA),
169bf215546Sopenharmony_ci      E(GLX_RENDERER_PREFERRED_PROFILE_MESA),
170bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA),
171bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA),
172bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA),
173bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA),
174bf215546Sopenharmony_ci   };
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(invalid_attributes); i++) {
177bf215546Sopenharmony_ci      query_renderer_integer_called = false;
178bf215546Sopenharmony_ci      query_renderer_string_called = false;
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci      const char *str =
181bf215546Sopenharmony_ci         glXQueryRendererStringMESA(&dpy, 0, 0, invalid_attributes[i].value);
182bf215546Sopenharmony_ci      EXPECT_EQ((char *)0, str) << invalid_attributes[i].string;
183bf215546Sopenharmony_ci      EXPECT_FALSE(query_renderer_integer_called)
184bf215546Sopenharmony_ci         << invalid_attributes[i].string;
185bf215546Sopenharmony_ci      EXPECT_FALSE(query_renderer_string_called)
186bf215546Sopenharmony_ci         << invalid_attributes[i].string;
187bf215546Sopenharmony_ci   }
188bf215546Sopenharmony_ci}
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci/**
191bf215546Sopenharmony_ci * glXQueryRendererStringMESA will not call GetGLXScreenConfigs if the display
192bf215546Sopenharmony_ci * pointer is \c NULL.  It will also not segfault.
193bf215546Sopenharmony_ci */
194bf215546Sopenharmony_ciTEST_F(query_renderer_string_test, null_display_pointer)
195bf215546Sopenharmony_ci{
196bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
197bf215546Sopenharmony_ci      GetGLXScreenConfigs_called = false;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci      const char *str =
200bf215546Sopenharmony_ci         glXQueryRendererStringMESA(NULL, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
201bf215546Sopenharmony_ci      EXPECT_EQ((char *)0, str);
202bf215546Sopenharmony_ci      EXPECT_FALSE(GetGLXScreenConfigs_called);
203bf215546Sopenharmony_ci   } else {
204bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
205bf215546Sopenharmony_ci   }
206bf215546Sopenharmony_ci}
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci/**
209bf215546Sopenharmony_ci * glXQueryRendererStringMESA will return error if GetGLXScreenConfigs returns
210bf215546Sopenharmony_ci * NULL.  It will also not segfault.
211bf215546Sopenharmony_ci */
212bf215546Sopenharmony_ciTEST_F(query_renderer_string_test, null_screen_pointer)
213bf215546Sopenharmony_ci{
214bf215546Sopenharmony_ci   psc = NULL;
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
217bf215546Sopenharmony_ci      GetGLXScreenConfigs_called = false;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci      const char *str =
220bf215546Sopenharmony_ci         glXQueryRendererStringMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
221bf215546Sopenharmony_ci      EXPECT_EQ((char *)0, str);
222bf215546Sopenharmony_ci      EXPECT_TRUE(GetGLXScreenConfigs_called);
223bf215546Sopenharmony_ci   } else {
224bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
225bf215546Sopenharmony_ci   }
226bf215546Sopenharmony_ci}
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci/**
229bf215546Sopenharmony_ci * glXQueryRendererStringMESA will not call the screen query_render_string
230bf215546Sopenharmony_ci * function if the renderer is invalid, and it will return NULL.
231bf215546Sopenharmony_ci */
232bf215546Sopenharmony_ciTEST_F(query_renderer_string_test, invalid_renderer_index)
233bf215546Sopenharmony_ci{
234bf215546Sopenharmony_ci   static const int invalid_renderer_indices[] = {
235bf215546Sopenharmony_ci      -1,
236bf215546Sopenharmony_ci      1,
237bf215546Sopenharmony_ci      999,
238bf215546Sopenharmony_ci   };
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
241bf215546Sopenharmony_ci      for (unsigned i = 0; i < ARRAY_SIZE(invalid_renderer_indices); i++) {
242bf215546Sopenharmony_ci         const char *str =
243bf215546Sopenharmony_ci            glXQueryRendererStringMESA(&dpy, 0,
244bf215546Sopenharmony_ci                                       invalid_renderer_indices[i],
245bf215546Sopenharmony_ci                                       GLX_RENDERER_VENDOR_ID_MESA);
246bf215546Sopenharmony_ci         EXPECT_EQ((char *)0, str) << invalid_renderer_indices[i];
247bf215546Sopenharmony_ci         EXPECT_FALSE(query_renderer_integer_called)
248bf215546Sopenharmony_ci            << invalid_renderer_indices[i];
249bf215546Sopenharmony_ci         EXPECT_FALSE(query_renderer_string_called)
250bf215546Sopenharmony_ci            << invalid_renderer_indices[i];
251bf215546Sopenharmony_ci      }
252bf215546Sopenharmony_ci   } else {
253bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
254bf215546Sopenharmony_ci   }
255bf215546Sopenharmony_ci}
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci/**
258bf215546Sopenharmony_ci * glXQueryCurrentRendererStringMESA will return error if there is no context
259bf215546Sopenharmony_ci * current.  It will also not segfault.
260bf215546Sopenharmony_ci */
261bf215546Sopenharmony_ciTEST_F(query_renderer_string_test, no_current_context)
262bf215546Sopenharmony_ci{
263bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
264bf215546Sopenharmony_ci      const char *str =
265bf215546Sopenharmony_ci         glXQueryCurrentRendererStringMESA(GLX_RENDERER_VENDOR_ID_MESA);
266bf215546Sopenharmony_ci      EXPECT_EQ((char *)0, str);
267bf215546Sopenharmony_ci   } else {
268bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
269bf215546Sopenharmony_ci   }
270bf215546Sopenharmony_ci}
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci/**
273bf215546Sopenharmony_ci * glXQueryCurrentRendererIntegerMESA will return \c NULL if the
274bf215546Sopenharmony_ci * query_render_string vtable entry is \c NULL.  It will also not segfault.
275bf215546Sopenharmony_ci */
276bf215546Sopenharmony_ciTEST_F(query_renderer_integer_test, null_query_render_string)
277bf215546Sopenharmony_ci{
278bf215546Sopenharmony_ci   struct glx_screen_vtable vtable = {
279bf215546Sopenharmony_ci      NULL,
280bf215546Sopenharmony_ci      NULL,
281bf215546Sopenharmony_ci      NULL,
282bf215546Sopenharmony_ci      NULL
283bf215546Sopenharmony_ci   };
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci   scr.vtable = &vtable;
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
288bf215546Sopenharmony_ci      unsigned value = 0xDEADBEEF;
289bf215546Sopenharmony_ci      Bool success = glXQueryRendererIntegerMESA(&dpy, 0, 0,
290bf215546Sopenharmony_ci                                                 GLX_RENDERER_VENDOR_ID_MESA,
291bf215546Sopenharmony_ci                                                 &value);
292bf215546Sopenharmony_ci      EXPECT_FALSE(success);
293bf215546Sopenharmony_ci      EXPECT_EQ(0xDEADBEEF, value);
294bf215546Sopenharmony_ci   } else {
295bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
296bf215546Sopenharmony_ci   }
297bf215546Sopenharmony_ci}
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci/**
300bf215546Sopenharmony_ci * glXQueryCurrentRendererIntegerMESA will not call the screen
301bf215546Sopenharmony_ci * query_render_string function with an invalid GLX enum value, and it will
302bf215546Sopenharmony_ci * return NULL.
303bf215546Sopenharmony_ci */
304bf215546Sopenharmony_ciTEST_F(query_renderer_integer_test, invalid_attribute)
305bf215546Sopenharmony_ci{
306bf215546Sopenharmony_ci   static const attribute_test_vector invalid_attributes[] = {
307bf215546Sopenharmony_ci      /* These values are just plain invalid for use with this extension.
308bf215546Sopenharmony_ci       */
309bf215546Sopenharmony_ci      E(0),
310bf215546Sopenharmony_ci      E(GLX_VENDOR),
311bf215546Sopenharmony_ci      E(GLX_VERSION),
312bf215546Sopenharmony_ci      E(GLX_EXTENSIONS),
313bf215546Sopenharmony_ci      E(GLX_RENDERER_VENDOR_ID_MESA + 0x10000),
314bf215546Sopenharmony_ci      E(GLX_RENDERER_DEVICE_ID_MESA + 0x10000),
315bf215546Sopenharmony_ci      E(GLX_RENDERER_VERSION_MESA + 0x10000),
316bf215546Sopenharmony_ci      E(GLX_RENDERER_ACCELERATED_MESA + 0x10000),
317bf215546Sopenharmony_ci      E(GLX_RENDERER_VIDEO_MEMORY_MESA + 0x10000),
318bf215546Sopenharmony_ci      E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA + 0x10000),
319bf215546Sopenharmony_ci      E(GLX_RENDERER_PREFERRED_PROFILE_MESA + 0x10000),
320bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA + 0x10000),
321bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA + 0x10000),
322bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA + 0x10000),
323bf215546Sopenharmony_ci      E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA + 0x10000),
324bf215546Sopenharmony_ci   };
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(invalid_attributes); i++) {
327bf215546Sopenharmony_ci      query_renderer_integer_called = false;
328bf215546Sopenharmony_ci      query_renderer_string_called = false;
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci      unsigned value = 0xDEADBEEF;
331bf215546Sopenharmony_ci      Bool success =
332bf215546Sopenharmony_ci         glXQueryRendererIntegerMESA(&dpy, 0, 0,
333bf215546Sopenharmony_ci                                     invalid_attributes[i].value,
334bf215546Sopenharmony_ci                                     &value);
335bf215546Sopenharmony_ci      EXPECT_FALSE(success) << invalid_attributes[i].string;
336bf215546Sopenharmony_ci      EXPECT_EQ(0xDEADBEEF, value) << invalid_attributes[i].string;
337bf215546Sopenharmony_ci      EXPECT_FALSE(query_renderer_integer_called)
338bf215546Sopenharmony_ci         << invalid_attributes[i].string;
339bf215546Sopenharmony_ci      EXPECT_FALSE(query_renderer_string_called)
340bf215546Sopenharmony_ci         << invalid_attributes[i].string;
341bf215546Sopenharmony_ci   }
342bf215546Sopenharmony_ci}
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci/**
345bf215546Sopenharmony_ci * glXQueryCurrentRendererIntegerMESA will not call GetGLXScreenConfigs if the
346bf215546Sopenharmony_ci * display pointer is \c NULL.  It will also not segfault.
347bf215546Sopenharmony_ci */
348bf215546Sopenharmony_ciTEST_F(query_renderer_integer_test, null_display_pointer)
349bf215546Sopenharmony_ci{
350bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
351bf215546Sopenharmony_ci      GetGLXScreenConfigs_called = false;
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci      unsigned value = 0xDEADBEEF;
354bf215546Sopenharmony_ci      Bool success =
355bf215546Sopenharmony_ci         glXQueryRendererIntegerMESA(NULL, 0, 0, GLX_RENDERER_VENDOR_ID_MESA,
356bf215546Sopenharmony_ci                                     &value);
357bf215546Sopenharmony_ci      EXPECT_FALSE(success);
358bf215546Sopenharmony_ci      EXPECT_EQ(0xDEADBEEF, value);
359bf215546Sopenharmony_ci      EXPECT_FALSE(GetGLXScreenConfigs_called);
360bf215546Sopenharmony_ci   } else {
361bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
362bf215546Sopenharmony_ci   }
363bf215546Sopenharmony_ci}
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci/**
366bf215546Sopenharmony_ci * glXQueryCurrentRendererIntegerMESA will return error if GetGLXScreenConfigs
367bf215546Sopenharmony_ci * returns NULL.  It will also not segfault.
368bf215546Sopenharmony_ci */
369bf215546Sopenharmony_ciTEST_F(query_renderer_integer_test, null_screen_pointer)
370bf215546Sopenharmony_ci{
371bf215546Sopenharmony_ci   psc = NULL;
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
374bf215546Sopenharmony_ci      GetGLXScreenConfigs_called = false;
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci      unsigned value = 0xDEADBEEF;
377bf215546Sopenharmony_ci      Bool success =
378bf215546Sopenharmony_ci         glXQueryRendererIntegerMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA,
379bf215546Sopenharmony_ci            &value);
380bf215546Sopenharmony_ci      EXPECT_FALSE(success);
381bf215546Sopenharmony_ci      EXPECT_EQ(0xDEADBEEF, value);
382bf215546Sopenharmony_ci      EXPECT_TRUE(GetGLXScreenConfigs_called);
383bf215546Sopenharmony_ci   } else {
384bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
385bf215546Sopenharmony_ci   }
386bf215546Sopenharmony_ci}
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci/**
389bf215546Sopenharmony_ci * glXQueryRendererIntegerMESA will not call the screen query_render_integer
390bf215546Sopenharmony_ci * function if the renderer is invalid, and it will return NULL.
391bf215546Sopenharmony_ci */
392bf215546Sopenharmony_ciTEST_F(query_renderer_integer_test, invalid_renderer_index)
393bf215546Sopenharmony_ci{
394bf215546Sopenharmony_ci   static const int invalid_renderer_indices[] = {
395bf215546Sopenharmony_ci      -1,
396bf215546Sopenharmony_ci      1,
397bf215546Sopenharmony_ci      999,
398bf215546Sopenharmony_ci   };
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
401bf215546Sopenharmony_ci      for (unsigned i = 0; i < ARRAY_SIZE(invalid_renderer_indices); i++) {
402bf215546Sopenharmony_ci         unsigned value = 0xDEADBEEF;
403bf215546Sopenharmony_ci         Bool success =
404bf215546Sopenharmony_ci            glXQueryRendererIntegerMESA(&dpy, 0,
405bf215546Sopenharmony_ci                                        invalid_renderer_indices[i],
406bf215546Sopenharmony_ci                                        GLX_RENDERER_VENDOR_ID_MESA,
407bf215546Sopenharmony_ci                                        &value);
408bf215546Sopenharmony_ci         EXPECT_FALSE(success) << invalid_renderer_indices[i];
409bf215546Sopenharmony_ci         EXPECT_EQ(0xDEADBEEF, value) << invalid_renderer_indices[i];
410bf215546Sopenharmony_ci         EXPECT_FALSE(query_renderer_integer_called)
411bf215546Sopenharmony_ci            << invalid_renderer_indices[i];
412bf215546Sopenharmony_ci         EXPECT_FALSE(query_renderer_string_called)
413bf215546Sopenharmony_ci            << invalid_renderer_indices[i];
414bf215546Sopenharmony_ci      }
415bf215546Sopenharmony_ci   } else {
416bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
417bf215546Sopenharmony_ci   }
418bf215546Sopenharmony_ci}
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci/**
421bf215546Sopenharmony_ci * glXQueryCurrentRendererIntegerMESA will return error if there is no context
422bf215546Sopenharmony_ci * current.  It will also not segfault.
423bf215546Sopenharmony_ci */
424bf215546Sopenharmony_ciTEST_F(query_renderer_integer_test, no_current_context)
425bf215546Sopenharmony_ci{
426bf215546Sopenharmony_ci   if (setjmp(jmp) == 0) {
427bf215546Sopenharmony_ci      unsigned value = 0xDEADBEEF;
428bf215546Sopenharmony_ci      Bool success =
429bf215546Sopenharmony_ci         glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VENDOR_ID_MESA,
430bf215546Sopenharmony_ci                                            &value);
431bf215546Sopenharmony_ci      EXPECT_FALSE(success);
432bf215546Sopenharmony_ci      EXPECT_EQ(0xDEADBEEF, value);
433bf215546Sopenharmony_ci   } else {
434bf215546Sopenharmony_ci      EXPECT_FALSE(got_sigsegv);
435bf215546Sopenharmony_ci   }
436bf215546Sopenharmony_ci}
437