Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

getprocaddress.c 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. /*
  2. * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
  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 shall be included
  12. * in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  18. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. /*
  22. * Test that glXGetProcAddress works.
  23. */
  24. #define GLX_GLXEXT_PROTOTYPES
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27. #include <GL/gl.h>
  28. #include <GL/glx.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <math.h>
  33. typedef void (*generic_func)();
  34. #define EQUAL(X, Y) (fabs((X) - (Y)) < 0.001)
  35. /**
  36. * The following functions are used to check that the named OpenGL function
  37. * actually does what it's supposed to do.
  38. * The naming of these functions is signficant. The getprocaddress.py script
  39. * scans this file and extracts these function names.
  40. */
  41. static GLboolean
  42. test_ActiveTextureARB(generic_func func)
  43. {
  44. PFNGLACTIVETEXTUREARBPROC activeTexture = (PFNGLACTIVETEXTUREARBPROC) func;
  45. GLint t;
  46. GLboolean pass;
  47. (*activeTexture)(GL_TEXTURE1_ARB);
  48. glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &t);
  49. pass = (t == GL_TEXTURE1_ARB);
  50. (*activeTexture)(GL_TEXTURE0_ARB); /* restore default */
  51. return pass;
  52. }
  53. static GLboolean
  54. test_SecondaryColor3fEXT(generic_func func)
  55. {
  56. PFNGLSECONDARYCOLOR3FEXTPROC secColor3f = (PFNGLSECONDARYCOLOR3FEXTPROC) func;
  57. GLfloat color[4];
  58. GLboolean pass;
  59. (*secColor3f)(1.0, 1.0, 0.0);
  60. glGetFloatv(GL_CURRENT_SECONDARY_COLOR_EXT, color);
  61. pass = (color[0] == 1.0 && color[1] == 1.0 && color[2] == 0.0);
  62. (*secColor3f)(0.0, 0.0, 0.0); /* restore default */
  63. return pass;
  64. }
  65. static GLboolean
  66. test_ActiveStencilFaceEXT(generic_func func)
  67. {
  68. PFNGLACTIVESTENCILFACEEXTPROC activeFace = (PFNGLACTIVESTENCILFACEEXTPROC) func;
  69. GLint face;
  70. GLboolean pass;
  71. (*activeFace)(GL_BACK);
  72. glGetIntegerv(GL_ACTIVE_STENCIL_FACE_EXT, &face);
  73. pass = (face == GL_BACK);
  74. (*activeFace)(GL_FRONT); /* restore default */
  75. return pass;
  76. }
  77. static GLboolean
  78. test_VertexAttrib1fvARB(generic_func func)
  79. {
  80. PFNGLVERTEXATTRIB1FVARBPROC vertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) func;
  81. PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
  82. const GLfloat v[1] = {25.0};
  83. const GLfloat def[1] = {0};
  84. GLfloat res[4];
  85. GLboolean pass;
  86. (*vertexAttrib1fvARB)(6, v);
  87. (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
  88. pass = (res[0] == 25.0 && res[1] == 0.0 && res[2] == 0.0 && res[3] == 1.0);
  89. (*vertexAttrib1fvARB)(6, def);
  90. return pass;
  91. }
  92. static GLboolean
  93. test_VertexAttrib4NubvARB(generic_func func)
  94. {
  95. PFNGLVERTEXATTRIB4NUBVARBPROC vertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) func;
  96. PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
  97. const GLubyte v[4] = {255, 0, 255, 0};
  98. const GLubyte def[4] = {0, 0, 0, 255};
  99. GLfloat res[4];
  100. GLboolean pass;
  101. (*vertexAttrib4NubvARB)(6, v);
  102. (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
  103. pass = (res[0] == 1.0 && res[1] == 0.0 && res[2] == 1.0 && res[3] == 0.0);
  104. (*vertexAttrib4NubvARB)(6, def);
  105. return pass;
  106. }
  107. static GLboolean
  108. test_VertexAttrib4NuivARB(generic_func func)
  109. {
  110. PFNGLVERTEXATTRIB4NUIVARBPROC vertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) func;
  111. PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
  112. const GLuint v[4] = {0xffffffff, 0, 0xffffffff, 0};
  113. const GLuint def[4] = {0, 0, 0, 0xffffffff};
  114. GLfloat res[4];
  115. GLboolean pass;
  116. (*vertexAttrib4NuivARB)(6, v);
  117. (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
  118. pass = (EQUAL(res[0], 1.0) && EQUAL(res[1], 0.0) && EQUAL(res[2], 1.0) && EQUAL(res[3], 0.0));
  119. (*vertexAttrib4NuivARB)(6, def);
  120. return pass;
  121. }
  122. static GLboolean
  123. test_VertexAttrib4ivARB(generic_func func)
  124. {
  125. PFNGLVERTEXATTRIB4IVARBPROC vertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) func;
  126. PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
  127. const GLint v[4] = {1, 2, -3, 4};
  128. const GLint def[4] = {0, 0, 0, 1};
  129. GLfloat res[4];
  130. GLboolean pass;
  131. (*vertexAttrib4ivARB)(6, v);
  132. (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
  133. pass = (EQUAL(res[0], 1.0) && EQUAL(res[1], 2.0) && EQUAL(res[2], -3.0) && EQUAL(res[3], 4.0));
  134. (*vertexAttrib4ivARB)(6, def);
  135. return pass;
  136. }
  137. static GLboolean
  138. test_VertexAttrib4NsvARB(generic_func func)
  139. {
  140. PFNGLVERTEXATTRIB4NSVARBPROC vertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) func;
  141. PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
  142. const GLshort v[4] = {0, 32767, 32767, 0};
  143. const GLshort def[4] = {0, 0, 0, 32767};
  144. GLfloat res[4];
  145. GLboolean pass;
  146. (*vertexAttrib4NsvARB)(6, v);
  147. (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
  148. pass = (EQUAL(res[0], 0.0) && EQUAL(res[1], 1.0) && EQUAL(res[2], 1.0) && EQUAL(res[3], 0.0));
  149. (*vertexAttrib4NsvARB)(6, def);
  150. return pass;
  151. }
  152. static GLboolean
  153. test_VertexAttrib4NusvARB(generic_func func)
  154. {
  155. PFNGLVERTEXATTRIB4NUSVARBPROC vertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) func;
  156. PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
  157. const GLushort v[4] = {0xffff, 0, 0xffff, 0};
  158. const GLushort def[4] = {0, 0, 0, 0xffff};
  159. GLfloat res[4];
  160. GLboolean pass;
  161. (*vertexAttrib4NusvARB)(6, v);
  162. (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
  163. pass = (EQUAL(res[0], 1.0) && EQUAL(res[1], 0.0) && EQUAL(res[2], 1.0) && EQUAL(res[3], 0.0));
  164. (*vertexAttrib4NusvARB)(6, def);
  165. return pass;
  166. }
  167. static GLboolean
  168. test_VertexAttrib4ubNV(generic_func func)
  169. {
  170. PFNGLVERTEXATTRIB4UBNVPROC vertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC) func;
  171. PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
  172. const GLubyte v[4] = {255, 0, 255, 0};
  173. const GLubyte def[4] = {0, 0, 0, 255};
  174. GLfloat res[4];
  175. GLboolean pass;
  176. (*vertexAttrib4ubNV)(6, v[0], v[1], v[2], v[3]);
  177. (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
  178. pass = (res[0] == 1.0 && res[1] == 0.0 && res[2] == 1.0 && res[3] == 0.0);
  179. (*vertexAttrib4ubNV)(6, def[0], def[1], def[2], def[3]);
  180. return pass;
  181. }
  182. static GLboolean
  183. test_VertexAttrib2sNV(generic_func func)
  184. {
  185. PFNGLVERTEXATTRIB2SNVPROC vertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC) func;
  186. PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
  187. const GLshort v[2] = {2, -4,};
  188. const GLshort def[2] = {0, 0};
  189. GLfloat res[4];
  190. GLboolean pass;
  191. (*vertexAttrib2sNV)(6, v[0], v[1]);
  192. (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
  193. pass = (EQUAL(res[0], 2) && EQUAL(res[1], -4) && EQUAL(res[2], 0) && res[3] == 1.0);
  194. (*vertexAttrib2sNV)(6, def[0], def[1]);
  195. return pass;
  196. }
  197. static GLboolean
  198. test_VertexAttrib3fNV(generic_func func)
  199. {
  200. PFNGLVERTEXATTRIB3FNVPROC vertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC) func;
  201. PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
  202. const GLfloat v[3] = {0.2, 0.4, 0.8};
  203. const GLfloat def[3] = {0, 0, 0};
  204. GLfloat res[4];
  205. GLboolean pass;
  206. (*vertexAttrib3fNV)(6, v[0], v[1], v[2]);
  207. (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
  208. pass = (EQUAL(res[0], 0.2) && EQUAL(res[1], 0.4) && EQUAL(res[2], 0.8) && res[3] == 1.0);
  209. (*vertexAttrib3fNV)(6, def[0], def[1], def[2]);
  210. return pass;
  211. }
  212. static GLboolean
  213. test_VertexAttrib4dvNV(generic_func func)
  214. {
  215. PFNGLVERTEXATTRIB4DVNVPROC vertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC) func;
  216. PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
  217. const GLdouble v[4] = {0.2, 0.4, 0.8, 1.2};
  218. const GLdouble def[4] = {0, 0, 0, 1};
  219. GLfloat res[4];
  220. GLboolean pass;
  221. (*vertexAttrib4dvNV)(6, v);
  222. (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
  223. pass = (EQUAL(res[0], 0.2) && EQUAL(res[1], 0.4) && EQUAL(res[2], 0.8) && EQUAL(res[3], 1.2));
  224. (*vertexAttrib4dvNV)(6, def);
  225. return pass;
  226. }
  227. static GLboolean
  228. test_StencilFuncSeparateATI(generic_func func)
  229. {
  230. #ifdef GL_ATI_separate_stencil
  231. PFNGLSTENCILFUNCSEPARATEATIPROC stencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) func;
  232. GLint frontFunc, backFunc;
  233. GLint frontRef, backRef;
  234. GLint frontMask, backMask;
  235. (*stencilFuncSeparateATI)(GL_LESS, GL_GREATER, 2, 0xa);
  236. glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
  237. glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
  238. glGetIntegerv(GL_STENCIL_REF, &frontRef);
  239. glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
  240. glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontMask);
  241. glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backMask);
  242. if (frontFunc != GL_LESS ||
  243. backFunc != GL_GREATER ||
  244. frontRef != 2 ||
  245. backRef != 2 ||
  246. frontMask != 0xa ||
  247. backMask != 0xa)
  248. return GL_FALSE;
  249. #endif
  250. return GL_TRUE;
  251. }
  252. static GLboolean
  253. test_StencilFuncSeparate(generic_func func)
  254. {
  255. #ifdef GL_VERSION_2_0
  256. PFNGLSTENCILFUNCSEPARATEPROC stencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) func;
  257. GLint frontFunc, backFunc;
  258. GLint frontRef, backRef;
  259. GLint frontMask, backMask;
  260. (*stencilFuncSeparate)(GL_BACK, GL_GREATER, 2, 0xa);
  261. glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
  262. glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
  263. glGetIntegerv(GL_STENCIL_REF, &frontRef);
  264. glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
  265. glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontMask);
  266. glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backMask);
  267. if (frontFunc != GL_ALWAYS ||
  268. backFunc != GL_GREATER ||
  269. frontRef != 0 ||
  270. backRef != 2 ||
  271. frontMask == 0xa || /* might be 0xff or ~0 */
  272. backMask != 0xa)
  273. return GL_FALSE;
  274. #endif
  275. return GL_TRUE;
  276. }
  277. static GLboolean
  278. test_StencilOpSeparate(generic_func func)
  279. {
  280. #ifdef GL_VERSION_2_0
  281. PFNGLSTENCILOPSEPARATEPROC stencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) func;
  282. GLint frontFail, backFail;
  283. GLint frontZFail, backZFail;
  284. GLint frontZPass, backZPass;
  285. (*stencilOpSeparate)(GL_BACK, GL_INCR, GL_DECR, GL_INVERT);
  286. glGetIntegerv(GL_STENCIL_FAIL, &frontFail);
  287. glGetIntegerv(GL_STENCIL_BACK_FAIL, &backFail);
  288. glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &frontZFail);
  289. glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &backZFail);
  290. glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &frontZPass);
  291. glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &backZPass);
  292. if (frontFail != GL_KEEP ||
  293. backFail != GL_INCR ||
  294. frontZFail != GL_KEEP ||
  295. backZFail != GL_DECR ||
  296. frontZPass != GL_KEEP ||
  297. backZPass != GL_INVERT)
  298. return GL_FALSE;
  299. #endif
  300. return GL_TRUE;
  301. }
  302. static GLboolean
  303. test_StencilMaskSeparate(generic_func func)
  304. {
  305. #ifdef GL_VERSION_2_0
  306. PFNGLSTENCILMASKSEPARATEPROC stencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) func;
  307. GLint frontMask, backMask;
  308. (*stencilMaskSeparate)(GL_BACK, 0x1b);
  309. glGetIntegerv(GL_STENCIL_WRITEMASK, &frontMask);
  310. glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &backMask);
  311. if (frontMask == 0x1b ||
  312. backMask != 0x1b)
  313. return GL_FALSE;
  314. #endif
  315. return GL_TRUE;
  316. }
  317. /*
  318. * The following file is auto-generated with Python.
  319. */
  320. #include "getproclist.h"
  321. static int
  322. extension_supported(const char *haystack, const char *needle)
  323. {
  324. const char *p = strstr(haystack, needle);
  325. if (p) {
  326. /* found string, make sure next char is space or zero */
  327. const int len = strlen(needle);
  328. if (p[len] == ' ' || p[len] == 0)
  329. return 1;
  330. else
  331. return 0;
  332. }
  333. else
  334. return 0;
  335. }
  336. static void
  337. check_functions( const char *extensions )
  338. {
  339. struct name_test_pair *entry;
  340. int failures = 0, passes = 0;
  341. int totalFail = 0, totalPass = 0;
  342. int doTests;
  343. for (entry = functions; entry->name; entry++) {
  344. if (entry->name[0] == '-') {
  345. const char *version = (const char *) glGetString(GL_VERSION);
  346. if (entry->name[1] == '1') {
  347. /* check GL version 1.x */
  348. if (version[0] == '1' &&
  349. version[1] == '.' &&
  350. version[2] >= entry->name[3])
  351. doTests = 1;
  352. else
  353. doTests = 0;
  354. }
  355. else if (entry->name[1] == '2') {
  356. if (version[0] == '2' &&
  357. version[1] == '.' &&
  358. version[2] >= entry->name[3])
  359. doTests = 1;
  360. else
  361. doTests = 0;
  362. }
  363. else {
  364. /* check if the named extension is available */
  365. doTests = extension_supported(extensions, entry->name+1);
  366. }
  367. if (doTests)
  368. printf("Testing %s functions\n", entry->name + 1);
  369. totalFail += failures;
  370. totalPass += passes;
  371. failures = 0;
  372. passes = 0;
  373. }
  374. else if (doTests) {
  375. generic_func funcPtr = (generic_func) glXGetProcAddressARB((const GLubyte *) entry->name);
  376. if (funcPtr) {
  377. if (entry->test) {
  378. GLboolean b;
  379. printf(" Validating %s:", entry->name);
  380. b = (*entry->test)(funcPtr);
  381. if (b) {
  382. printf(" Pass\n");
  383. passes++;
  384. }
  385. else {
  386. printf(" FAIL!!!\n");
  387. failures++;
  388. }
  389. }
  390. else {
  391. passes++;
  392. }
  393. }
  394. else {
  395. printf(" glXGetProcAddress(%s) failed!\n", entry->name);
  396. failures++;
  397. }
  398. }
  399. if (doTests && (!(entry+1)->name || (entry+1)->name[0] == '-')) {
  400. if (failures > 0) {
  401. printf(" %d failed.\n", failures);
  402. }
  403. if (passes > 0) {
  404. printf(" %d passed.\n", passes);
  405. }
  406. }
  407. }
  408. totalFail += failures;
  409. totalPass += passes;
  410. printf("-----------------------------\n");
  411. printf("Total: %d pass %d fail\n", totalPass, totalFail);
  412. }
  413. static void
  414. print_screen_info(Display *dpy, int scrnum, Bool allowDirect)
  415. {
  416. Window win;
  417. int attribSingle[] = {
  418. GLX_RGBA,
  419. GLX_RED_SIZE, 1,
  420. GLX_GREEN_SIZE, 1,
  421. GLX_BLUE_SIZE, 1,
  422. GLX_STENCIL_SIZE, 1,
  423. None };
  424. int attribDouble[] = {
  425. GLX_RGBA,
  426. GLX_RED_SIZE, 1,
  427. GLX_GREEN_SIZE, 1,
  428. GLX_BLUE_SIZE, 1,
  429. GLX_STENCIL_SIZE, 1,
  430. GLX_DOUBLEBUFFER,
  431. None };
  432. XSetWindowAttributes attr;
  433. unsigned long mask;
  434. Window root;
  435. GLXContext ctx;
  436. XVisualInfo *visinfo;
  437. int width = 100, height = 100;
  438. root = RootWindow(dpy, scrnum);
  439. visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
  440. if (!visinfo) {
  441. visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
  442. if (!visinfo) {
  443. fprintf(stderr, "Error: couldn't find RGB GLX visual\n");
  444. return;
  445. }
  446. }
  447. attr.background_pixel = 0;
  448. attr.border_pixel = 0;
  449. attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
  450. attr.event_mask = StructureNotifyMask | ExposureMask;
  451. mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  452. win = XCreateWindow(dpy, root, 0, 0, width, height,
  453. 0, visinfo->depth, InputOutput,
  454. visinfo->visual, mask, &attr);
  455. ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
  456. if (!ctx) {
  457. fprintf(stderr, "Error: glXCreateContext failed\n");
  458. XDestroyWindow(dpy, win);
  459. return;
  460. }
  461. if (glXMakeCurrent(dpy, win, ctx)) {
  462. check_functions( (const char *) glGetString(GL_EXTENSIONS) );
  463. }
  464. else {
  465. fprintf(stderr, "Error: glXMakeCurrent failed\n");
  466. }
  467. glXDestroyContext(dpy, ctx);
  468. XDestroyWindow(dpy, win);
  469. }
  470. int
  471. main(int argc, char *argv[])
  472. {
  473. char *displayName = NULL;
  474. Display *dpy;
  475. dpy = XOpenDisplay(displayName);
  476. if (!dpy) {
  477. fprintf(stderr, "Error: unable to open display %s\n", displayName);
  478. return -1;
  479. }
  480. print_screen_info(dpy, 0, GL_TRUE);
  481. XCloseDisplay(dpy);
  482. return 0;
  483. }