1/*
2 * Copyright © 2011 Intel Corporation
3 *
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:
10 *
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.
14 *
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.
22 */
23#include <gtest/gtest.h>
24#include <string.h>
25
26extern "C" {
27#include "glxclient.h"
28}
29
30#include <xcb/glx.h>
31
32#include "mock_xdisplay.h"
33#include "fake_glx_screen.h"
34
35/**
36 * \name Wrappers around some X structures to make the more usable for tests
37 */
38/*@{*/
39class fake_glx_screen;
40
41class fake_glx_display : public glx_display {
42public:
43   fake_glx_display(mock_XDisplay *dpy, int major, int minor)
44   {
45      this->next = 0;
46      this->dpy = dpy;
47      this->majorOpcode = 0;
48      this->majorVersion = major;
49      this->minorVersion = minor;
50      this->serverGLXvendor = 0;
51      this->serverGLXversion = 0;
52      this->glXDrawHash = 0;
53
54      this->screens = new glx_screen *[dpy->nscreens];
55      memset(this->screens, 0, sizeof(struct glx_screen *) * dpy->nscreens);
56   }
57
58   ~fake_glx_display()
59   {
60      for (int i = 0; i < this->dpy->nscreens; i++) {
61	 if (this->screens[i] != NULL)
62	    delete this->screens[i];
63      }
64
65      delete [] this->screens;
66   }
67
68   void init_screen(int i, const char *ext);
69};
70
71class glX_send_client_info_test : public ::testing::Test {
72public:
73   glX_send_client_info_test();
74   virtual ~glX_send_client_info_test();
75   virtual void SetUp();
76
77   void common_protocol_expected_false_test(unsigned major, unsigned minor,
78					    const char *glx_ext, bool *value);
79
80   void common_protocol_expected_true_test(unsigned major, unsigned minor,
81					   const char *glx_ext, bool *value);
82
83   void create_single_screen_display(unsigned major, unsigned minor,
84				     const char *glx_ext);
85
86   void destroy_display();
87
88protected:
89   fake_glx_display *glx_dpy;
90   mock_XDisplay *display;
91};
92
93void
94fake_glx_display::init_screen(int i, const char *ext)
95{
96   if (this->screens[i] != NULL)
97      delete this->screens[i];
98
99   this->screens[i] = new fake_glx_screen(this, i, ext);
100}
101/*@}*/
102
103static const char ext[] = "GL_XXX_dummy";
104
105static bool ClientInfo_was_sent;
106static bool SetClientInfoARB_was_sent;
107static bool SetClientInfo2ARB_was_sent;
108static xcb_connection_t *connection_used;
109static int gl_ext_length;
110static char *gl_ext_string;
111static int glx_ext_length;
112static char *glx_ext_string;
113static int num_gl_versions;
114static uint32_t *gl_versions;
115static int glx_major;
116static int glx_minor;
117
118extern "C" xcb_connection_t *
119XGetXCBConnection(Display *dpy)
120{
121   return (xcb_connection_t *) 0xdeadbeef;
122}
123
124extern "C" xcb_void_cookie_t
125xcb_glx_client_info(xcb_connection_t *c,
126		    uint32_t major_version,
127		    uint32_t minor_version,
128		    uint32_t str_len,
129		    const char *string)
130{
131   xcb_void_cookie_t cookie;
132
133   ClientInfo_was_sent = true;
134   connection_used = c;
135
136   gl_ext_string = (char *) malloc(str_len);
137   memcpy(gl_ext_string, string, str_len);
138   gl_ext_length = str_len;
139
140   glx_major = major_version;
141   glx_minor = minor_version;
142
143   cookie.sequence = 0;
144   return cookie;
145}
146
147extern "C" xcb_void_cookie_t
148xcb_glx_set_client_info_arb(xcb_connection_t *c,
149			    uint32_t major_version,
150			    uint32_t minor_version,
151			    uint32_t num_versions,
152			    uint32_t gl_str_len,
153			    uint32_t glx_str_len,
154			    const uint32_t *versions,
155			    const char *gl_string,
156			    const char *glx_string)
157{
158   xcb_void_cookie_t cookie;
159
160   SetClientInfoARB_was_sent = true;
161   connection_used = c;
162
163   gl_ext_string = new char[gl_str_len];
164   memcpy(gl_ext_string, gl_string, gl_str_len);
165   gl_ext_length = gl_str_len;
166
167   glx_ext_string = new char[glx_str_len];
168   memcpy(glx_ext_string, glx_string, glx_str_len);
169   glx_ext_length = glx_str_len;
170
171   gl_versions = new uint32_t[num_versions * 2];
172   memcpy(gl_versions, versions, sizeof(uint32_t) * num_versions * 2);
173   num_gl_versions = num_versions;
174
175   glx_major = major_version;
176   glx_minor = minor_version;
177
178   cookie.sequence = 0;
179   return cookie;
180}
181
182extern "C" xcb_void_cookie_t
183xcb_glx_set_client_info_2arb(xcb_connection_t *c,
184			     uint32_t major_version,
185			     uint32_t minor_version,
186			     uint32_t num_versions,
187			     uint32_t gl_str_len,
188			     uint32_t glx_str_len,
189			     const uint32_t *versions,
190			     const char *gl_string,
191			     const char *glx_string)
192{
193   xcb_void_cookie_t cookie;
194
195   SetClientInfo2ARB_was_sent = true;
196   connection_used = c;
197
198   gl_ext_string = new char[gl_str_len];
199   memcpy(gl_ext_string, gl_string, gl_str_len);
200   gl_ext_length = gl_str_len;
201
202   glx_ext_string = new char[glx_str_len];
203   memcpy(glx_ext_string, glx_string, glx_str_len);
204   glx_ext_length = glx_str_len;
205
206   gl_versions = new uint32_t[num_versions * 3];
207   memcpy(gl_versions, versions, sizeof(uint32_t) * num_versions * 3);
208   num_gl_versions = num_versions;
209
210   glx_major = major_version;
211   glx_minor = minor_version;
212
213   cookie.sequence = 0;
214   return cookie;
215}
216
217extern "C" char *
218__glXGetClientGLExtensionString()
219{
220   char *str = (char *) malloc(sizeof(ext));
221
222   memcpy(str, ext, sizeof(ext));
223   return str;
224}
225
226glX_send_client_info_test::glX_send_client_info_test()
227   : glx_dpy(0), display(0)
228{
229   /* empty */
230}
231
232glX_send_client_info_test::~glX_send_client_info_test()
233{
234   if (glx_dpy)
235      delete glx_dpy;
236
237   if (display)
238      delete display;
239}
240
241void
242glX_send_client_info_test::destroy_display()
243{
244   if (this->glx_dpy != NULL) {
245      if (this->glx_dpy->screens != NULL) {
246	 for (int i = 0; i < this->display->nscreens; i++) {
247	    delete [] this->glx_dpy->screens[i]->serverGLXexts;
248	    delete this->glx_dpy->screens[i];
249	 }
250
251	 delete [] this->glx_dpy->screens;
252      }
253
254      delete this->glx_dpy;
255      delete this->display;
256   }
257}
258
259void
260glX_send_client_info_test::SetUp()
261{
262   ClientInfo_was_sent = false;
263   SetClientInfoARB_was_sent = false;
264   SetClientInfo2ARB_was_sent = false;
265   connection_used = (xcb_connection_t *) ~0;
266   gl_ext_length = 0;
267   gl_ext_string = (char *) 0;
268   glx_ext_length = 0;
269   glx_ext_string = (char *) 0;
270   num_gl_versions = 0;
271   gl_versions = (uint32_t *) 0;
272   glx_major = 0;
273   glx_minor = 0;
274}
275
276void
277glX_send_client_info_test::create_single_screen_display(unsigned major,
278							unsigned minor,
279							const char *glx_ext)
280{
281   this->display = new mock_XDisplay(1);
282
283   this->glx_dpy = new fake_glx_display(this->display, major, minor);
284   this->glx_dpy->init_screen(0, glx_ext);
285}
286
287void
288glX_send_client_info_test::common_protocol_expected_false_test(unsigned major,
289							       unsigned minor,
290							       const char *glx_ext,
291							       bool *value)
292{
293   create_single_screen_display(major, minor, glx_ext);
294   __glX_send_client_info(this->glx_dpy);
295   EXPECT_FALSE(*value);
296}
297
298void
299glX_send_client_info_test::common_protocol_expected_true_test(unsigned major,
300							      unsigned minor,
301							      const char *glx_ext,
302							      bool *value)
303{
304   create_single_screen_display(major, minor, glx_ext);
305   __glX_send_client_info(this->glx_dpy);
306   EXPECT_TRUE(*value);
307}
308
309TEST_F(glX_send_client_info_test, doesnt_send_ClientInfo_for_1_0)
310{
311   /* The glXClientInfo protocol was added in GLX 1.1.  Verify that no
312    * glXClientInfo is sent to a GLX server that only has GLX 1.0.
313    */
314   common_protocol_expected_false_test(1, 0, "", &ClientInfo_was_sent);
315}
316
317TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_0)
318{
319   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
320    * GLX_ARB_create_context extension.  Verify that no glXSetClientInfoARB is
321    * sent to a GLX server that only has GLX 1.0 regardless of the extension
322    * setting.
323    */
324   common_protocol_expected_false_test(1, 0,
325				       "GLX_ARB_create_context",
326				       &SetClientInfoARB_was_sent);
327}
328
329TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_1)
330{
331   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
332    * GLX_ARB_create_context extension.  Verify that no glXSetClientInfoARB is
333    * sent to a GLX server that only has GLX 1.0 regardless of the extension
334    * setting.
335    */
336   common_protocol_expected_false_test(1, 1,
337				       "GLX_ARB_create_context",
338				       &SetClientInfoARB_was_sent);
339}
340
341TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_empty_extensions)
342{
343   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
344    * GLX_ARB_create_context extension.  Verify that no glXSetClientInfoARB is
345    * sent to a GLX server that has GLX 1.4 but has an empty extension string
346    * (i.e., no extensions at all).
347    */
348   common_protocol_expected_false_test(1, 4,
349				       "",
350				       &SetClientInfoARB_was_sent);
351}
352
353TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_without_extension)
354{
355   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
356    * GLX_ARB_create_context extension.  Verify that no glXSetClientInfoARB is
357    * sent to a GLX server that has GLX 1.4 but doesn't have the extension.
358    */
359   common_protocol_expected_false_test(1, 4,
360				       "GLX_EXT_texture_from_pixmap",
361				       &SetClientInfoARB_was_sent);
362}
363
364TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_wrong_extension)
365{
366   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
367    * GLX_ARB_create_context extension.  Verify that no glXSetClientInfoARB is
368    * sent to a GLX server that has GLX 1.4 but does not have the extension.
369    *
370    * This test differs from
371    * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
372    * extension exists that looks like the correct extension but isn't.
373    */
374   common_protocol_expected_false_test(1, 4,
375				       "GLX_ARB_create_context2",
376				       &SetClientInfoARB_was_sent);
377}
378
379TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_profile_extension)
380{
381   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
382    * GLX_ARB_create_context extension.  Verify that no glXSetClientInfoARB is
383    * sent to a GLX server that has GLX 1.4 but does not have the extension.
384    *
385    * This test differs from
386    * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
387    * extension exists that looks like the correct extension but isn't.
388    */
389   common_protocol_expected_false_test(1, 4,
390				       "GLX_ARB_create_context_profile",
391				       &SetClientInfoARB_was_sent);
392}
393
394TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_0)
395{
396   /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
397    * GLX_ARB_create_context_profile extension.  Verify that no
398    * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.0
399    * regardless of the extension setting.
400    */
401   common_protocol_expected_false_test(1, 0,
402				       "GLX_ARB_create_context_profile",
403				       &SetClientInfo2ARB_was_sent);
404}
405
406TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_1)
407{
408   /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
409    * GLX_ARB_create_context_profile extension.  Verify that no
410    * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.1
411    * regardless of the extension setting.
412    */
413   common_protocol_expected_false_test(1, 1,
414				       "GLX_ARB_create_context_profile",
415				       &SetClientInfo2ARB_was_sent);
416}
417
418TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_empty_extensions)
419{
420   /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
421    * GLX_ARB_create_context_profile extension.  Verify that no
422    * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but has an
423    * empty extension string (i.e., no extensions at all).
424    */
425   common_protocol_expected_false_test(1, 4,
426				       "",
427				       &SetClientInfo2ARB_was_sent);
428}
429
430TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_without_extension)
431{
432   /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
433    * GLX_ARB_create_context_profile extension.  Verify that no
434    * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but
435    * doesn't have the extension.
436    */
437   common_protocol_expected_false_test(1, 4,
438				       "GLX_EXT_texture_from_pixmap",
439				       &SetClientInfo2ARB_was_sent);
440}
441
442TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_wrong_extension)
443{
444   /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
445    * GLX_ARB_create_context_profile extension.  Verify that no
446    * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but does
447    * not have the extension.
448    *
449    * This test differs from
450    * doesnt_send_SetClientInfo2ARB_for_1_4_without_extension in that an
451    * extension exists that looks like the correct extension but isn't.
452    */
453   common_protocol_expected_false_test(1, 4,
454				       "GLX_ARB_create_context_profile2",
455				       &SetClientInfo2ARB_was_sent);
456}
457
458TEST_F(glX_send_client_info_test, does_send_ClientInfo_for_1_1)
459{
460   /* The glXClientInfo protocol was added in GLX 1.1.  Verify that
461    * glXClientInfo is sent to a GLX server that has GLX 1.1.
462    */
463   common_protocol_expected_true_test(1, 1,
464				      "",
465				      &ClientInfo_was_sent);
466}
467
468TEST_F(glX_send_client_info_test, does_send_SetClientInfoARB_for_1_4_with_extension)
469{
470   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
471    * GLX_ARB_create_context extension.  Verify that glXSetClientInfoARB is
472    * sent to a GLX server that has GLX 1.4 and the extension.
473    */
474   common_protocol_expected_true_test(1, 4,
475				      "GLX_ARB_create_context",
476				      &SetClientInfoARB_was_sent);
477}
478
479TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_just_profile_extension)
480{
481   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
482    * GLX_ARB_create_context extension.  Verify that glXSetClientInfoARB is
483    * sent to a GLX server that has GLX 1.4 and the extension.
484    */
485   common_protocol_expected_true_test(1, 4,
486				      "GLX_ARB_create_context_profile",
487				      &SetClientInfo2ARB_was_sent);
488}
489
490TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions)
491{
492   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
493    * GLX_ARB_create_context extension.  Verify that glXSetClientInfoARB is
494    * sent to a GLX server that has GLX 1.4 and the extension.
495    */
496   common_protocol_expected_true_test(1, 4,
497				      "GLX_ARB_create_context "
498				      "GLX_ARB_create_context_profile",
499				      &SetClientInfo2ARB_was_sent);
500}
501
502TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions_reversed)
503{
504   /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
505    * GLX_ARB_create_context extension.  Verify that glXSetClientInfoARB is
506    * sent to a GLX server that has GLX 1.4 and the extension.
507    */
508   common_protocol_expected_true_test(1, 4,
509				      "GLX_ARB_create_context_profile "
510				      "GLX_ARB_create_context",
511				      &SetClientInfo2ARB_was_sent);
512}
513
514TEST_F(glX_send_client_info_test, uses_correct_connection)
515{
516   create_single_screen_display(1, 1, "");
517   __glX_send_client_info(this->glx_dpy);
518   EXPECT_EQ((xcb_connection_t *) 0xdeadbeef, connection_used);
519}
520
521TEST_F(glX_send_client_info_test, sends_correct_gl_extension_string)
522{
523   create_single_screen_display(1, 1, "");
524   __glX_send_client_info(this->glx_dpy);
525
526   ASSERT_EQ((int) sizeof(ext), gl_ext_length);
527   ASSERT_NE((char *) 0, gl_ext_string);
528   EXPECT_EQ(0, memcmp(gl_ext_string, ext, sizeof(ext)));
529}
530
531TEST_F(glX_send_client_info_test, gl_versions_are_sane)
532{
533   create_single_screen_display(1, 4, "GLX_ARB_create_context");
534   __glX_send_client_info(this->glx_dpy);
535
536   ASSERT_NE(0, num_gl_versions);
537
538   unsigned versions_below_3_0 = 0;
539   for (int i = 0; i < num_gl_versions; i++) {
540      EXPECT_LT(0u, gl_versions[i * 2]);
541      EXPECT_GE(4u, gl_versions[i * 2]);
542
543      /* Verify that the minor version advertised with the major version makes
544       * sense.
545       */
546      switch (gl_versions[i * 2]) {
547      case 1:
548	 EXPECT_GE(5u, gl_versions[i * 2 + 1]);
549	 versions_below_3_0++;
550	 break;
551      case 2:
552	 EXPECT_GE(1u, gl_versions[i * 2 + 1]);
553	 versions_below_3_0++;
554	 break;
555      case 3:
556	 EXPECT_GE(3u, gl_versions[i * 2 + 1]);
557	 break;
558      case 4:
559	 EXPECT_GE(2u, gl_versions[i * 2 + 1]);
560	 break;
561      }
562   }
563
564   /* From the GLX_ARB_create_context spec:
565    *
566    *     "Only the highest supported version below 3.0 should be sent, since
567    *     OpenGL 2.1 is backwards compatible with all earlier versions."
568    */
569   EXPECT_LE(versions_below_3_0, 1u);
570}
571
572TEST_F(glX_send_client_info_test, gl_versions_and_profiles_are_sane)
573{
574   create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
575   __glX_send_client_info(this->glx_dpy);
576
577   ASSERT_NE(0, num_gl_versions);
578
579   const uint32_t all_valid_bits = GLX_CONTEXT_CORE_PROFILE_BIT_ARB
580      | GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
581
582   unsigned versions_below_3_0 = 0;
583
584   for (int i = 0; i < num_gl_versions; i++) {
585      EXPECT_LT(0u, gl_versions[i * 3]);
586      EXPECT_GE(4u, gl_versions[i * 3]);
587
588      /* Verify that the minor version advertised with the major version makes
589       * sense.
590       */
591      switch (gl_versions[i * 3]) {
592      case 1:
593	 EXPECT_GE(5u, gl_versions[i * 3 + 1]);
594	 EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
595	 versions_below_3_0++;
596	 break;
597      case 2:
598	 EXPECT_GE(1u, gl_versions[i * 3 + 1]);
599	 EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
600	 versions_below_3_0++;
601	 break;
602      case 3:
603	 EXPECT_GE(3u, gl_versions[i * 3 + 1]);
604
605	 /* Profiles were not introduced until OpenGL 3.2.
606	  */
607	 if (gl_versions[i * 3 + 1] < 2) {
608	    EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
609	 } else {
610	    EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~all_valid_bits);
611	 }
612	 break;
613      case 4:
614	 EXPECT_GE(2u, gl_versions[i * 3 + 1]);
615	 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~all_valid_bits);
616	 break;
617      }
618   }
619
620   /* From the GLX_ARB_create_context_profile spec:
621    *
622    *     "Only the highest supported version below 3.0 should be sent, since
623    *     OpenGL 2.1 is backwards compatible with all earlier versions."
624    */
625   EXPECT_LE(versions_below_3_0, 1u);
626}
627
628TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_1)
629{
630   create_single_screen_display(1, 1, "");
631   __glX_send_client_info(this->glx_dpy);
632
633   EXPECT_EQ(1, glx_major);
634   EXPECT_EQ(4, glx_minor);
635}
636
637TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4)
638{
639   create_single_screen_display(1, 4, "");
640   __glX_send_client_info(this->glx_dpy);
641
642   EXPECT_EQ(1, glx_major);
643   EXPECT_EQ(4, glx_minor);
644}
645
646TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context)
647{
648   create_single_screen_display(1, 4, "GLX_ARB_create_context");
649   __glX_send_client_info(this->glx_dpy);
650
651   EXPECT_EQ(1, glx_major);
652   EXPECT_EQ(4, glx_minor);
653}
654
655TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context_profile)
656{
657   create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
658   __glX_send_client_info(this->glx_dpy);
659
660   EXPECT_EQ(1, glx_major);
661   EXPECT_EQ(4, glx_minor);
662}
663
664TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_5)
665{
666   create_single_screen_display(1, 5, "");
667   __glX_send_client_info(this->glx_dpy);
668
669   EXPECT_EQ(1, glx_major);
670   EXPECT_EQ(4, glx_minor);
671}
672
673TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context)
674{
675   create_single_screen_display(1, 4, "GLX_ARB_create_context");
676   __glX_send_client_info(this->glx_dpy);
677
678   ASSERT_NE(0, glx_ext_length);
679   ASSERT_NE((char *) 0, glx_ext_string);
680
681   bool found_GLX_ARB_create_context = false;
682   const char *const needle = "GLX_ARB_create_context";
683   const unsigned len = strlen(needle);
684   char *haystack = glx_ext_string;
685   while (haystack != NULL) {
686      char *match = strstr(haystack, needle);
687
688      if (match[len] == '\0' || match[len] == ' ') {
689	 found_GLX_ARB_create_context = true;
690	 break;
691      }
692
693      haystack = match + len;
694   }
695
696   EXPECT_TRUE(found_GLX_ARB_create_context);
697}
698
699TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context_profile)
700{
701   create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
702   __glX_send_client_info(this->glx_dpy);
703
704   ASSERT_NE(0, glx_ext_length);
705   ASSERT_NE((char *) 0, glx_ext_string);
706
707   bool found_GLX_ARB_create_context_profile = false;
708   const char *const needle = "GLX_ARB_create_context_profile";
709   const unsigned len = strlen(needle);
710   char *haystack = glx_ext_string;
711   while (haystack != NULL) {
712      char *match = strstr(haystack, needle);
713
714      if (match[len] == '\0' || match[len] == ' ') {
715	 found_GLX_ARB_create_context_profile = true;
716	 break;
717      }
718
719      haystack = match + len;
720   }
721
722   EXPECT_TRUE(found_GLX_ARB_create_context_profile);
723}
724