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