PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/wrap_glx.c

http://github.com/dmsh/ocaml-xlib
C | 1220 lines | 778 code | 167 blank | 275 comment | 71 complexity | 4972ba638a5a1debf5779ccc4efeb1ad MD5 | raw file
  1. /* OCaml bindings for the GLX library (as part of OCaml-Xlib).
  2. * Copyright (C) 2008, 2009 by Florent Monnier <fmonnier@linux-nantes.org>
  3. *
  4. * OCaml-Xlib is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published
  6. * by the Free Software Foundation, either version 3 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * OCaml-Xlib is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with OCaml-Xlib. If not, see:
  16. * <http://www.gnu.org/licenses/>
  17. */
  18. #define GL_GLEXT_PROTOTYPES
  19. #define GLX_GLXEXT_PROTOTYPES
  20. #include <GL/gl.h>
  21. #include <GL/glx.h>
  22. #define CAML_NAME_SPACE 1
  23. #include <caml/mlvalues.h>
  24. #include <caml/memory.h>
  25. #include <caml/alloc.h>
  26. #include <caml/custom.h>
  27. #include <caml/fail.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include "wrap_xlib.h"
  32. #include "wrap_glx.h"
  33. custom_ops(XVisualInfo); // caml alloc
  34. CAMLprim value
  35. ml_glXQueryExtension( value dpy )
  36. {
  37. int error_base, event_base;
  38. if (!glXQueryExtension( Display_val(dpy), &error_base, &event_base )) {
  39. do_warn2("glXQueryExtension: error_base: %d; event_base: %d\n",
  40. error_base, event_base);
  41. caml_failwith("GLX extension not supported by the X server");
  42. }
  43. return Val_unit;
  44. }
  45. CAMLprim value
  46. ml_glXQueryVersion( value dpy )
  47. {
  48. CAMLparam1(dpy);
  49. CAMLlocal1(tpl);
  50. int major, minor;
  51. if (!glXQueryVersion( Display_val(dpy), &major, &minor ))
  52. caml_failwith("glXQueryVersion");
  53. tpl = caml_alloc(2, 0);
  54. Store_field( tpl, 0, Val_int(major) );
  55. Store_field( tpl, 1, Val_int(minor) );
  56. CAMLreturn(tpl);
  57. }
  58. CAMLprim value
  59. ml_glXQueryExtensionsString( value dpy, value screen )
  60. {
  61. return caml_copy_string( glXQueryExtensionsString( Display_val(dpy), ScreenNB_val(screen) ) );
  62. }
  63. static const int name_table[] = {
  64. GLX_VENDOR,
  65. GLX_VERSION,
  66. GLX_EXTENSIONS
  67. };
  68. CAMLprim value
  69. ml_glXQueryServerString( value dpy, value screen, value name )
  70. {
  71. return caml_copy_string( glXQueryServerString( Display_val(dpy), ScreenNB_val(screen),
  72. name_table[Long_val(name)] ) );
  73. }
  74. CAMLprim value
  75. ml_glXGetClientString( value dpy, value name )
  76. {
  77. const char *str = glXGetClientString( Display_val(dpy), name_table[Long_val(name)] );
  78. return caml_copy_string(str);
  79. }
  80. CAMLprim value
  81. ml_glXCreateWindow( value dpy, value config, value win )
  82. {
  83. int attrib_list[] = { None }; // the man says: currently unused
  84. GLXWindow glx_win = glXCreateWindow( Display_val(dpy), GLXFBConfig_val(config),
  85. Window_val(win), attrib_list );
  86. return Val_GLXWindow(glx_win);
  87. }
  88. CAMLprim value
  89. ml_glXDestroyWindow( value dpy, value win )
  90. {
  91. glXDestroyWindow( Display_val(dpy), GLXWindow_val(win) );
  92. return Val_unit;
  93. }
  94. CAMLprim value
  95. ml_glXSwapBuffers( value dpy, value drawable )
  96. {
  97. glXSwapBuffers( Display_val(dpy), GLXDrawable_val(drawable) );
  98. return Val_unit;
  99. }
  100. CAMLprim value
  101. ml_glXUseXFont( value font, value first, value count, value list )
  102. {
  103. glXUseXFont( Font_val(font), Int_val(first), Int_val(count), Int_val(list) );
  104. return Val_unit;
  105. }
  106. CAMLprim value
  107. ml_glXWaitGL(value unit)
  108. {
  109. glXWaitGL();
  110. return Val_unit;
  111. }
  112. CAMLprim value
  113. ml_glXWaitX(value unit)
  114. {
  115. glXWaitX();
  116. return Val_unit;
  117. }
  118. static inline int
  119. visual_attrib( value v, int *p1, int *p2 )
  120. {
  121. if (Is_long(v))
  122. {
  123. switch (Int_val(v))
  124. {
  125. case 0: *p1 = GLX_USE_GL; break;
  126. case 1: *p1 = GLX_RGBA; break;
  127. case 2: *p1 = GLX_DOUBLEBUFFER; break;
  128. case 3: *p1 = GLX_STEREO; break;
  129. default: caml_failwith("visual_attrib handling bug");
  130. }
  131. return 1;
  132. }
  133. else // (Is_block(v))
  134. {
  135. switch (Tag_val(v))
  136. {
  137. case 0: *p1 = GLX_BUFFER_SIZE; *p2 = UInt_val(Field(v,0)); break;
  138. case 1: *p1 = GLX_LEVEL; *p2 = Int_val(Field(v,0)); break;
  139. case 2: *p1 = GLX_AUX_BUFFERS; *p2 = UInt_val(Field(v,0)); break;
  140. case 3: *p1 = GLX_RED_SIZE; *p2 = UInt_val(Field(v,0)); break;
  141. case 4: *p1 = GLX_GREEN_SIZE; *p2 = UInt_val(Field(v,0)); break;
  142. case 5: *p1 = GLX_BLUE_SIZE; *p2 = UInt_val(Field(v,0)); break;
  143. case 6: *p1 = GLX_ALPHA_SIZE; *p2 = UInt_val(Field(v,0)); break;
  144. case 7: *p1 = GLX_DEPTH_SIZE; *p2 = UInt_val(Field(v,0)); break;
  145. case 8: *p1 = GLX_STENCIL_SIZE; *p2 = UInt_val(Field(v,0)); break;
  146. case 9: *p1 = GLX_ACCUM_RED_SIZE; *p2 = UInt_val(Field(v,0)); break;
  147. case 10: *p1 = GLX_ACCUM_GREEN_SIZE; *p2 = UInt_val(Field(v,0)); break;
  148. case 11: *p1 = GLX_ACCUM_BLUE_SIZE; *p2 = UInt_val(Field(v,0)); break;
  149. case 12: *p1 = GLX_ACCUM_ALPHA_SIZE; *p2 = Int_val(Field(v,0)); break;
  150. default: caml_failwith("visual_attrib handling bug");
  151. }
  152. return 2;
  153. }
  154. }
  155. CAMLprim value
  156. ml_glXChooseVisual( value dpy, value screen, value ml_attribList )
  157. {
  158. CAMLparam3(dpy, screen, ml_attribList);
  159. CAMLlocal1(visual_info);
  160. #define MAX_ATTRIBS 31
  161. int attribList[MAX_ATTRIBS];
  162. XVisualInfo *visinfo = NULL;
  163. int i = 0;
  164. while ( ml_attribList != Val_emptylist )
  165. {
  166. int n, p1, p2;
  167. value attrib = Field(ml_attribList, 0);
  168. n = visual_attrib( attrib, &p1, &p2 );
  169. if (n == 1) {
  170. if (i > MAX_ATTRIBS - 2) // i max = 29
  171. caml_invalid_argument("glXChooseVisual: Visual.attrib list: too much elements");
  172. attribList[i] = p1;
  173. ++i;
  174. } else {
  175. if (i > MAX_ATTRIBS - 3) // i max = 28
  176. caml_invalid_argument("glXChooseVisual: Visual.attrib list: too much elements");
  177. attribList[i] = p1;
  178. attribList[i+1] = p2;
  179. i += 2;
  180. }
  181. ml_attribList = Field(ml_attribList, 1);
  182. }
  183. attribList[i] = None; // i max = 30
  184. visinfo = glXChooseVisual( Display_val(dpy), ScreenNB_val(screen), attribList );
  185. if (!visinfo) caml_failwith("glXChooseVisual");
  186. alloc_XVisualInfo(visual_info);
  187. memcpy(XVisualInfo_val(visual_info), visinfo, sizeof(XVisualInfo));
  188. XFree(visinfo);
  189. CAMLreturn(visual_info);
  190. }
  191. #undef MAX_ATTRIBS
  192. static inline void
  193. fbconfig_attrib( value v, int *p1, int *p2 )
  194. {
  195. if (Is_long(v))
  196. caml_failwith("visual_attrib handling bug");
  197. // (Is_block(v))
  198. {
  199. switch (Tag_val(v))
  200. {
  201. #define attrib_case(n, attrib_name, attrib_param_conv) \
  202. case n: *p1 = attrib_name; *p2 = attrib_param_conv(Field(v,0)); break;
  203. attrib_case(0, GLX_FBCONFIG_ID, GLXFBConfigID_val )
  204. attrib_case(1, GLX_BUFFER_SIZE, UInt_val )
  205. attrib_case(2, GLX_LEVEL, Int_val )
  206. attrib_case(3, GLX_DOUBLEBUFFER, Bool_val )
  207. attrib_case(4, GLX_STEREO, Bool_val )
  208. attrib_case(5, GLX_AUX_BUFFERS, UInt_val )
  209. attrib_case(6, GLX_RED_SIZE, UInt_val )
  210. attrib_case(7, GLX_GREEN_SIZE, UInt_val )
  211. attrib_case(8, GLX_BLUE_SIZE, UInt_val )
  212. attrib_case(9, GLX_ALPHA_SIZE, UInt_val )
  213. attrib_case(10, GLX_DEPTH_SIZE, UInt_val )
  214. attrib_case(11, GLX_STENCIL_SIZE, UInt_val )
  215. attrib_case(12, GLX_ACCUM_RED_SIZE, UInt_val )
  216. attrib_case(13, GLX_ACCUM_GREEN_SIZE, UInt_val )
  217. attrib_case(14, GLX_ACCUM_BLUE_SIZE, UInt_val )
  218. attrib_case(15, GLX_ACCUM_ALPHA_SIZE, Int_val )
  219. //attrib_case(16, GLX_RENDER_TYPE, GLX.opengl_rendering_modes list ) TODO
  220. //attrib_case(17, GLX_DRAWABLE_TYPE, GLX.glx_drawable_types list ) TODO
  221. attrib_case(18, GLX_X_RENDERABLE, Bool_val )
  222. //attrib_case(19, GLX_X_VISUAL_TYPE, GLX.x_visual_type ) TODO
  223. //attrib_case(20, GLX_CONFIG_CAVEAT, GLX.config_caveat ) TODO
  224. //attrib_case(21, GLX_TRANSPARENT_TYPE, GLX.transparent_type ) TODO
  225. attrib_case(22, GLX_TRANSPARENT_INDEX_VALUE, Int_val )
  226. attrib_case(23, GLX_TRANSPARENT_RED_VALUE, Int_val )
  227. attrib_case(24, GLX_TRANSPARENT_GREEN_VALUE, Int_val )
  228. attrib_case(25, GLX_TRANSPARENT_BLUE_VALUE, Int_val )
  229. attrib_case(26, GLX_TRANSPARENT_ALPHA_VALUE, Int_val )
  230. #undef attrib_case
  231. default: caml_failwith("fbconfig_attrib handling bug");
  232. }
  233. }
  234. }
  235. CAMLprim value
  236. ml_glXChooseFBConfig( value dpy, value screen, value ml_attribList )
  237. {
  238. CAMLparam3(dpy, screen, ml_attribList);
  239. CAMLlocal1(ml_configs);
  240. #define MAX_ATTRIBS 55
  241. int attribList[MAX_ATTRIBS];
  242. GLXFBConfig *configs;
  243. int i, nitems;
  244. i = 0;
  245. while ( ml_attribList != Val_emptylist )
  246. {
  247. value attrib = Field(ml_attribList, 0);
  248. if (i > MAX_ATTRIBS - 3) // i max = 52
  249. caml_invalid_argument("glXChooseFBConfig: "
  250. "FBConfig.attrib list: too much elements");
  251. fbconfig_attrib( attrib, &(attribList[i]), &(attribList[i+1]) );
  252. i += 2;
  253. ml_attribList = Field(ml_attribList, 1);
  254. }
  255. attribList[i] = None; // i max = 54
  256. configs = glXChooseFBConfig( Display_val(dpy), ScreenNB_val(screen), attribList, &nitems );
  257. ml_configs = caml_alloc(nitems, 0);
  258. for (i=0; i < nitems; ++i)
  259. {
  260. Store_field( ml_configs, i, Val_GLXFBConfig(configs[i]) );
  261. }
  262. CAMLreturn(ml_configs);
  263. }
  264. #undef MAX_ATTRIBS
  265. CAMLprim value
  266. ml_glXGetFBConfigs( value dpy, value screen )
  267. {
  268. CAMLparam2(dpy, screen);
  269. CAMLlocal1(ml_configs);
  270. GLXFBConfig *configs;
  271. int i, nelements;
  272. configs = glXGetFBConfigs( Display_val(dpy), ScreenNB_val(screen), &nelements );
  273. ml_configs = caml_alloc(nelements, 0);
  274. for (i=0; i < nelements; ++i)
  275. {
  276. Store_field( ml_configs, i, Val_GLXFBConfig(configs[i]) );
  277. }
  278. CAMLreturn(ml_configs);
  279. }
  280. CAMLprim value
  281. ml_XFree_glXFBConfig( value configs )
  282. {
  283. CAMLlocal1(head);
  284. GLXFBConfig config_head;
  285. if (configs == Val_emptylist)
  286. caml_invalid_argument("xFree_glXFBConfig");
  287. head = Field(configs, 0);
  288. config_head = GLXFBConfig_val(head);
  289. XFree( &config_head );
  290. return Val_unit;
  291. }
  292. CAMLprim value
  293. ml_glXGetVisualFromFBConfig( value dpy, value config )
  294. {
  295. CAMLparam2(dpy, config);
  296. CAMLlocal1(visual_info);
  297. XVisualInfo *visinfo = NULL;
  298. visinfo = glXGetVisualFromFBConfig( Display_val(dpy), GLXFBConfig_val(config) );
  299. if (!visinfo) caml_failwith("glXGetVisualFromFBConfig");
  300. alloc_XVisualInfo(visual_info);
  301. memcpy(XVisualInfo_val(visual_info), visinfo, sizeof(XVisualInfo));
  302. XFree(visinfo); /* XXX */
  303. CAMLreturn(visual_info);
  304. }
  305. CAMLprim value
  306. ml_glXCreatePixmap( value dpy, value config, value pixmap, value attrib_list )
  307. {
  308. const int attrs[] = { None };
  309. if ( attrib_list != Val_emptylist ) {
  310. caml_invalid_argument(
  311. "GLX.glXCreatePixmap: the attribs parameter should be an empty list,"
  312. " in GLX 1.4 this parameter is ignored."
  313. " but there are additional parameters with extensions,"
  314. " for instance see GLX_P2T.glXCreatePixmapEXT");
  315. }
  316. GLXPixmap glXPixmap =
  317. glXCreatePixmap( Display_val(dpy), GLXFBConfig_val(config),
  318. Pixmap_val(pixmap), attrs /* NULL */ );
  319. return Val_GLXPixmap(glXPixmap);
  320. }
  321. CAMLprim value
  322. ml_glXDestroyPixmap( value dpy, value pixmap )
  323. {
  324. glXDestroyPixmap( Display_val(dpy), GLXPixmap_val(pixmap) );
  325. return Val_unit;
  326. }
  327. CAMLprim value
  328. ml_glXCreateContext( value dpy, value vis, value share_list, value direct )
  329. {
  330. GLXContext shareList =
  331. ( (share_list == Val_int(0)) ?
  332. NULL : // None
  333. GLXContext_val( Field(share_list,0) ) // Some v
  334. );
  335. GLXContext ctx = glXCreateContext( Display_val(dpy), XVisualInfo_val(vis),
  336. shareList, Bool_val(direct) );
  337. if (!ctx) caml_failwith("glXCreateContext");
  338. return Val_GLXContext(ctx);
  339. }
  340. CAMLprim value
  341. ml_glXCreateNewContext( value dpy, value config, value render_type, value share_list, value direct )
  342. {
  343. GLXContext shareList =
  344. ( (share_list == Val_int(0)) ?
  345. NULL : // None
  346. GLXContext_val( Field(share_list,0) ) // Some v
  347. );
  348. GLXContext ctx = glXCreateNewContext(
  349. Display_val(dpy),
  350. GLXFBConfig_val(config),
  351. ( (render_type == Val_int(0)) ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE ),
  352. shareList,
  353. Bool_val(direct) );
  354. if (!ctx) caml_failwith("glXCreateNewContext");
  355. return Val_GLXContext(ctx);
  356. }
  357. static const unsigned long conv_attrib_bit_table[] = {
  358. GL_ACCUM_BUFFER_BIT,
  359. GL_COLOR_BUFFER_BIT,
  360. GL_CURRENT_BIT,
  361. GL_DEPTH_BUFFER_BIT,
  362. GL_ENABLE_BIT,
  363. GL_EVAL_BIT,
  364. GL_FOG_BIT,
  365. GL_HINT_BIT,
  366. GL_LIGHTING_BIT,
  367. GL_LINE_BIT,
  368. GL_LIST_BIT,
  369. GL_MULTISAMPLE_BIT,
  370. GL_PIXEL_MODE_BIT,
  371. GL_POINT_BIT,
  372. GL_POLYGON_BIT,
  373. GL_POLYGON_STIPPLE_BIT,
  374. GL_SCISSOR_BIT,
  375. GL_STENCIL_BUFFER_BIT,
  376. GL_TEXTURE_BIT,
  377. GL_TRANSFORM_BIT,
  378. GL_VIEWPORT_BIT,
  379. };
  380. CAMLprim value
  381. ml_glXCopyContext( value dpy, value src, value mask_list )
  382. {
  383. GLXContext dst = NULL;
  384. unsigned long attrib_bit = 0;
  385. while ( mask_list != Val_emptylist )
  386. {
  387. value head = Field(mask_list, 0);
  388. attrib_bit |= conv_attrib_bit_table[Long_val(head)];
  389. mask_list = Field(mask_list, 1);
  390. }
  391. glXCopyContext( Display_val(dpy), GLXContext_val(src), dst, attrib_bit );
  392. if (!dst) caml_failwith("glXCopyContext");
  393. return Val_GLXContext(dst);
  394. }
  395. CAMLprim value
  396. ml_glXDestroyContext( value dpy, value ctx )
  397. {
  398. glXDestroyContext( Display_val(dpy), GLXContext_val(ctx) );
  399. return Val_unit;
  400. }
  401. CAMLprim value
  402. ml_glXMakeContextCurrent( value dpy, value draw, value read, value ctx )
  403. {
  404. if (!glXMakeContextCurrent( Display_val(dpy), GLXDrawable_val(draw), GLXDrawable_val(read), GLXContext_val(ctx) ))
  405. caml_failwith("glXMakeContextCurrent");
  406. return Val_unit;
  407. }
  408. CAMLprim value
  409. ml_glXMakeContextCurrent_release( value dpy )
  410. {
  411. if (!glXMakeContextCurrent( Display_val(dpy), None, None, NULL ))
  412. caml_failwith("glXMakeContextCurrent_release");
  413. return Val_unit;
  414. }
  415. CAMLprim value
  416. ml_glXMakeCurrent( value dpy, value drawable, value ctx )
  417. {
  418. if (!glXMakeCurrent( Display_val(dpy), GLXDrawable_val(drawable), GLXContext_val(ctx) ))
  419. caml_failwith("glXMakeCurrent");
  420. return Val_unit;
  421. }
  422. CAMLprim value
  423. ml_glXMakeCurrent_none( value dpy )
  424. {
  425. if (!glXMakeCurrent( Display_val(dpy), None, NULL ))
  426. caml_failwith("glXMakeCurrentNone");
  427. return Val_unit;
  428. }
  429. CAMLprim value
  430. ml_glXIsDirect( value dpy, value ctx )
  431. {
  432. Bool b = glXIsDirect( Display_val(dpy), GLXContext_val(ctx) );
  433. return Val_bool(b);
  434. }
  435. CAMLprim value
  436. ml_glXCreatePbuffer( value dpy, value config, value attrib_list )
  437. {
  438. int attrs[20]; // TODO: is this thread safe ? or should we do a malloc ?
  439. int i = 0;
  440. while ( attrib_list != Val_emptylist )
  441. {
  442. value attrib = Field(attrib_list, 0);
  443. //if (Is_long(attrib)) {
  444. // caml_failwith("variant handling bug");
  445. //} else
  446. //if (Is_block(attrib))
  447. {
  448. switch (Tag_val(attrib))
  449. {
  450. case 0: attrs[i++] = GLX_PBUFFER_WIDTH; break;
  451. case 1: attrs[i++] = GLX_PBUFFER_HEIGHT; break;
  452. case 2: attrs[i++] = GLX_LARGEST_PBUFFER; break;
  453. case 3: attrs[i++] = GLX_PRESERVED_CONTENTS; break;
  454. default: caml_failwith("variant handling bug");
  455. }
  456. attrs[i++] = Int_val(Field(attrib,0));
  457. }
  458. attrib_list = Field(attrib_list,1);
  459. if (i >= 19) break;
  460. }
  461. attrs[i] = None;
  462. GLXPbuffer pbuf = glXCreatePbuffer( Display_val(dpy), GLXFBConfig_val(config), attrs );
  463. return Val_GLXPbuffer(pbuf);
  464. }
  465. CAMLprim value
  466. ml_glXDestroyPbuffer( value dpy, value pbuf )
  467. {
  468. glXDestroyPbuffer( Display_val(dpy), GLXPbuffer_val(pbuf) );
  469. return Val_unit;
  470. }
  471. #define push_glx_drawable_type(bit_mask,n) \
  472. if (c_mask & bit_mask) { \
  473. cons = caml_alloc(2, 0); \
  474. Store_field( cons, 0, Val_int(n) ); \
  475. Store_field( cons, 1, li ); \
  476. li = cons; \
  477. }
  478. static value
  479. Val_GLX_RENDER_TYPE( int c_mask )
  480. {
  481. CAMLparam0();
  482. CAMLlocal2(li, cons);
  483. li = Val_emptylist;
  484. push_glx_drawable_type( GLX_RGBA_BIT, 0 )
  485. push_glx_drawable_type( GLX_COLOR_INDEX_BIT, 1 )
  486. CAMLreturn(li);
  487. }
  488. static value
  489. Val_GLX_DRAWABLE_TYPE( int c_mask )
  490. {
  491. CAMLparam0();
  492. CAMLlocal2(li, cons);
  493. li = Val_emptylist;
  494. push_glx_drawable_type( GLX_WINDOW_BIT, 0 )
  495. push_glx_drawable_type( GLX_PIXMAP_BIT, 1 )
  496. push_glx_drawable_type( GLX_PBUFFER_BIT, 2 )
  497. CAMLreturn(li);
  498. }
  499. static value
  500. Val_x_visual_type( int v )
  501. {
  502. switch (v)
  503. {
  504. case GLX_TRUE_COLOR : return Val_some( Val_int(0) );
  505. case GLX_DIRECT_COLOR: return Val_some( Val_int(1) );
  506. case GLX_PSEUDO_COLOR: return Val_some( Val_int(2) );
  507. case GLX_STATIC_COLOR: return Val_some( Val_int(3) );
  508. case GLX_GRAY_SCALE : return Val_some( Val_int(4) );
  509. case GLX_STATIC_GRAY : return Val_some( Val_int(5) );
  510. case GLX_NONE : return Val_none;
  511. }
  512. caml_failwith("glXGetFBConfigAttrib with GLX_X_VISUAL_TYPE");
  513. return Val_int(0);
  514. }
  515. static value
  516. Val_config_caveat( int c_mask )
  517. {
  518. CAMLparam0();
  519. CAMLlocal2(li, cons);
  520. li = Val_emptylist;
  521. push_glx_drawable_type( GLX_NONE, 0 )
  522. push_glx_drawable_type( GLX_SLOW_CONFIG, 1 )
  523. push_glx_drawable_type( GLX_NON_CONFORMANT_CONFIG, 2 )
  524. CAMLreturn(li);
  525. }
  526. static value
  527. Val_transparent_type( int c_mask )
  528. {
  529. CAMLparam0();
  530. CAMLlocal2(li, cons);
  531. li = Val_emptylist;
  532. push_glx_drawable_type( GLX_NONE, 0 )
  533. push_glx_drawable_type( GLX_TRANSPARENT_RGB, 1 )
  534. push_glx_drawable_type( GLX_TRANSPARENT_INDEX, 2 )
  535. CAMLreturn(li);
  536. }
  537. static value
  538. Val_GLX_BIND_TO_TEXTURE_TARGETS_EXT( int c_mask )
  539. {
  540. CAMLparam0();
  541. CAMLlocal2(li, cons);
  542. li = Val_emptylist;
  543. push_glx_drawable_type( GLX_TEXTURE_1D_BIT_EXT, 0 )
  544. push_glx_drawable_type( GLX_TEXTURE_2D_BIT_EXT, 1 )
  545. push_glx_drawable_type( GLX_TEXTURE_RECTANGLE_BIT_EXT, 2 )
  546. CAMLreturn(li);
  547. }
  548. #undef push_glx_drawable_type
  549. static value
  550. Val_GLX_VISUAL_ID( int v )
  551. {
  552. if (v == 0) return Val_none;
  553. else return Val_some( Val_VisualID(v) );
  554. }
  555. CAMLprim value
  556. ml_glXGetFBConfigAttrib( value dpy, value config, value attribute )
  557. {
  558. int rvalue;
  559. #define case_fbconfig_attrib(n,attrib,Val_conv) \
  560. case n: \
  561. { int ret = glXGetFBConfigAttrib( Display_val(dpy), GLXFBConfig_val(config), attrib, &rvalue); \
  562. if (ret == Success) return Val_conv(rvalue); else return Val_emptylist; \
  563. } break;
  564. switch (Int_val(attribute))
  565. {
  566. case_fbconfig_attrib( 0, GLX_FBCONFIG_ID, Val_GLXFBConfigID )
  567. case_fbconfig_attrib( 1, GLX_BUFFER_SIZE, Val_bool )
  568. case_fbconfig_attrib( 2, GLX_LEVEL, Val_int )
  569. case_fbconfig_attrib( 3, GLX_DOUBLEBUFFER, Val_bool )
  570. case_fbconfig_attrib( 4, GLX_STEREO, Val_bool )
  571. case_fbconfig_attrib( 5, GLX_AUX_BUFFERS, Val_uint )
  572. case_fbconfig_attrib( 6, GLX_RED_SIZE, Val_uint )
  573. case_fbconfig_attrib( 7, GLX_GREEN_SIZE, Val_uint )
  574. case_fbconfig_attrib( 8, GLX_BLUE_SIZE, Val_uint )
  575. case_fbconfig_attrib( 9, GLX_ALPHA_SIZE, Val_uint )
  576. case_fbconfig_attrib( 10, GLX_DEPTH_SIZE, Val_uint )
  577. case_fbconfig_attrib( 11, GLX_STENCIL_SIZE, Val_uint )
  578. case_fbconfig_attrib( 12, GLX_ACCUM_RED_SIZE, Val_uint )
  579. case_fbconfig_attrib( 13, GLX_ACCUM_GREEN_SIZE, Val_uint )
  580. case_fbconfig_attrib( 14, GLX_ACCUM_BLUE_SIZE, Val_uint )
  581. case_fbconfig_attrib( 15, GLX_ACCUM_ALPHA_SIZE, Val_int )
  582. case_fbconfig_attrib( 16, GLX_RENDER_TYPE, Val_GLX_RENDER_TYPE )
  583. case_fbconfig_attrib( 17, GLX_DRAWABLE_TYPE, Val_GLX_DRAWABLE_TYPE )
  584. case_fbconfig_attrib( 18, GLX_X_RENDERABLE, Val_bool )
  585. case_fbconfig_attrib( 19, GLX_VISUAL_ID, Val_GLX_VISUAL_ID )
  586. case_fbconfig_attrib( 20, GLX_X_VISUAL_TYPE, Val_x_visual_type )
  587. case_fbconfig_attrib( 21, GLX_CONFIG_CAVEAT, Val_config_caveat )
  588. case_fbconfig_attrib( 22, GLX_TRANSPARENT_TYPE, Val_transparent_type )
  589. case_fbconfig_attrib( 23, GLX_TRANSPARENT_INDEX_VALUE, Val_int )
  590. case_fbconfig_attrib( 24, GLX_TRANSPARENT_RED_VALUE, Val_int )
  591. case_fbconfig_attrib( 25, GLX_TRANSPARENT_GREEN_VALUE, Val_int )
  592. case_fbconfig_attrib( 26, GLX_TRANSPARENT_BLUE_VALUE, Val_int )
  593. case_fbconfig_attrib( 27, GLX_TRANSPARENT_ALPHA_VALUE, Val_int )
  594. case_fbconfig_attrib( 28, GLX_MAX_PBUFFER_WIDTH, Val_uint )
  595. case_fbconfig_attrib( 29, GLX_MAX_PBUFFER_HEIGHT, Val_uint )
  596. case_fbconfig_attrib( 30, GLX_MAX_PBUFFER_PIXELS, Val_uint )
  597. /* extension: GLX_EXT_texture_from_pixmap */
  598. case_fbconfig_attrib( 31, GLX_BIND_TO_TEXTURE_TARGETS_EXT, Val_GLX_BIND_TO_TEXTURE_TARGETS_EXT )
  599. case_fbconfig_attrib( 32, GLX_BIND_TO_TEXTURE_RGBA_EXT, Val_bool )
  600. case_fbconfig_attrib( 33, GLX_BIND_TO_TEXTURE_RGB_EXT, Val_bool )
  601. case_fbconfig_attrib( 34, GLX_Y_INVERTED_EXT, Val_bool )
  602. }
  603. #undef case_fbconfig_attrib
  604. caml_failwith("bug in function glXGetFBConfigAttrib");
  605. return Val_int(0);
  606. }
  607. /* {{{
  608. | GLX_FBCONFIG_ID of GLX.glXFBConfigID
  609. | GLX_BUFFER_SIZE of GLX.uint
  610. | GLX_LEVEL of int
  611. | GLX_DOUBLEBUFFER of bool
  612. | GLX_STEREO of bool
  613. | GLX_AUX_BUFFERS of GLX.uint
  614. | GLX_RED_SIZE of GLX.uint
  615. | GLX_GREEN_SIZE of GLX.uint
  616. | GLX_BLUE_SIZE of GLX.uint
  617. | GLX_ALPHA_SIZE of GLX.uint
  618. | GLX_DEPTH_SIZE of GLX.uint
  619. | GLX_STENCIL_SIZE of GLX.uint
  620. | GLX_ACCUM_RED_SIZE of GLX.uint
  621. | GLX_ACCUM_GREEN_SIZE of GLX.uint
  622. | GLX_ACCUM_BLUE_SIZE of GLX.uint
  623. | GLX_ACCUM_ALPHA_SIZE of int
  624. | GLX_RENDER_TYPE of GLX.opengl_rendering_modes list
  625. | GLX_DRAWABLE_TYPE of GLX.glx_drawable_types list
  626. | GLX_X_RENDERABLE of bool
  627. GLX_VISUAL_ID ***
  628. XID of the corresponding visual, or zero if there is no associated visual
  629. (i.e., if GLX_X_RENDERABLE is False or GLX_DRAWABLE_TYPE does not have the GLX_WINDOW_BIT bit set).
  630. | GLX_X_VISUAL_TYPE of GLX.x_visual_type
  631. | GLX_CONFIG_CAVEAT of GLX.config_caveat
  632. | GLX_TRANSPARENT_TYPE of GLX.transparent_type
  633. | GLX_TRANSPARENT_INDEX_VALUE of int
  634. | GLX_TRANSPARENT_RED_VALUE of int
  635. | GLX_TRANSPARENT_GREEN_VALUE of int
  636. | GLX_TRANSPARENT_BLUE_VALUE of int
  637. | GLX_TRANSPARENT_ALPHA_VALUE of int
  638. (* TODO *)
  639. | GLX_MAX_PBUFFER_WIDTH of uint
  640. | GLX_MAX_PBUFFER_HEIGHT of uint
  641. | GLX_MAX_PBUFFER_PIXELS of uint
  642. }}} */
  643. /* {{{ funcs to be wrapped
  644. #ifdef GLX_VERSION_1_1
  645. #endif
  646. #ifdef GLX_VERSION_1_2
  647. #endif
  648. #ifdef GLX_VERSION_1_3
  649. #endif
  650. #ifdef GLX_VERSION_1_4
  651. #endif
  652. // Tokens for glXChooseVisual and glXGetConfig:
  653. #define GLX_USE_GL 1
  654. #define GLX_BUFFER_SIZE 2
  655. #define GLX_LEVEL 3
  656. #define GLX_RGBA 4
  657. #define GLX_DOUBLEBUFFER 5
  658. #define GLX_STEREO 6
  659. #define GLX_AUX_BUFFERS 7
  660. #define GLX_RED_SIZE 8
  661. #define GLX_GREEN_SIZE 9
  662. #define GLX_BLUE_SIZE 10
  663. #define GLX_ALPHA_SIZE 11
  664. #define GLX_DEPTH_SIZE 12
  665. #define GLX_STENCIL_SIZE 13
  666. #define GLX_ACCUM_RED_SIZE 14
  667. #define GLX_ACCUM_GREEN_SIZE 15
  668. #define GLX_ACCUM_BLUE_SIZE 16
  669. #define GLX_ACCUM_ALPHA_SIZE 17
  670. // Error codes returned by glXGetConfig:
  671. #define GLX_BAD_SCREEN 1
  672. #define GLX_BAD_ATTRIBUTE 2
  673. #define GLX_NO_EXTENSION 3
  674. #define GLX_BAD_VISUAL 4
  675. #define GLX_BAD_CONTEXT 5
  676. #define GLX_BAD_VALUE 6
  677. #define GLX_BAD_ENUM 7
  678. // GLX 1.1 and later:
  679. #define GLX_VENDOR 1
  680. #define GLX_VERSION 2
  681. #define GLX_EXTENSIONS 3
  682. // GLX 1.3 and later:
  683. #define GLX_CONFIG_CAVEAT 0x20
  684. #define GLX_DONT_CARE 0xFFFFFFFF
  685. #define GLX_X_VISUAL_TYPE 0x22
  686. #define GLX_TRANSPARENT_TYPE 0x23
  687. #define GLX_TRANSPARENT_INDEX_VALUE 0x24
  688. #define GLX_TRANSPARENT_RED_VALUE 0x25
  689. #define GLX_TRANSPARENT_GREEN_VALUE 0x26
  690. #define GLX_TRANSPARENT_BLUE_VALUE 0x27
  691. #define GLX_TRANSPARENT_ALPHA_VALUE 0x28
  692. #define GLX_WINDOW_BIT 0x00000001
  693. #define GLX_PIXMAP_BIT 0x00000002
  694. #define GLX_PBUFFER_BIT 0x00000004
  695. #define GLX_AUX_BUFFERS_BIT 0x00000010
  696. #define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
  697. #define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
  698. #define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
  699. #define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
  700. #define GLX_DEPTH_BUFFER_BIT 0x00000020
  701. #define GLX_STENCIL_BUFFER_BIT 0x00000040
  702. #define GLX_ACCUM_BUFFER_BIT 0x00000080
  703. #define GLX_NONE 0x8000
  704. #define GLX_SLOW_CONFIG 0x8001
  705. #define GLX_TRUE_COLOR 0x8002
  706. #define GLX_DIRECT_COLOR 0x8003
  707. #define GLX_PSEUDO_COLOR 0x8004
  708. #define GLX_STATIC_COLOR 0x8005
  709. #define GLX_GRAY_SCALE 0x8006
  710. #define GLX_STATIC_GRAY 0x8007
  711. #define GLX_TRANSPARENT_RGB 0x8008
  712. #define GLX_TRANSPARENT_INDEX 0x8009
  713. #define GLX_VISUAL_ID 0x800B
  714. #define GLX_SCREEN 0x800C
  715. #define GLX_NON_CONFORMANT_CONFIG 0x800D
  716. #define GLX_DRAWABLE_TYPE 0x8010
  717. #define GLX_RENDER_TYPE 0x8011
  718. #define GLX_X_RENDERABLE 0x8012
  719. #define GLX_FBCONFIG_ID 0x8013
  720. #define GLX_RGBA_TYPE 0x8014
  721. #define GLX_COLOR_INDEX_TYPE 0x8015
  722. #define GLX_MAX_PBUFFER_WIDTH 0x8016
  723. #define GLX_MAX_PBUFFER_HEIGHT 0x8017
  724. #define GLX_MAX_PBUFFER_PIXELS 0x8018
  725. #define GLX_PRESERVED_CONTENTS 0x801B
  726. #define GLX_LARGEST_PBUFFER 0x801C
  727. #define GLX_WIDTH 0x801D
  728. #define GLX_HEIGHT 0x801E
  729. #define GLX_EVENT_MASK 0x801F
  730. #define GLX_DAMAGED 0x8020
  731. #define GLX_SAVED 0x8021
  732. #define GLX_WINDOW 0x8022
  733. #define GLX_PBUFFER 0x8023
  734. #define GLX_PBUFFER_HEIGHT 0x8040
  735. #define GLX_PBUFFER_WIDTH 0x8041
  736. #define GLX_RGBA_BIT 0x00000001
  737. #define GLX_COLOR_INDEX_BIT 0x00000002
  738. #define GLX_PBUFFER_CLOBBER_MASK 0x08000000
  739. // GLX 1.4 and later:
  740. #define GLX_SAMPLE_BUFFERS 0x186a0
  741. #define GLX_SAMPLES 0x186a1
  742. GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visual, Pixmap pixmap );
  743. void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap );
  744. int glXGetConfig( Display *dpy, XVisualInfo *visual, int attrib, int *value );
  745. GLXContext glXGetCurrentContext( void );
  746. GLXDrawable glXGetCurrentDrawable( void );
  747. void glXUseXFont( Font font, int first, int count, int list );
  748. // GLX 1.1 and later
  749. const char *glXQueryExtensionsString( Display *dpy, int screen );
  750. const char *glXQueryServerString( Display *dpy, int screen, int name );
  751. // GLX 1.2 and later
  752. Display *glXGetCurrentDisplay( void );
  753. // GLX 1.3 and later
  754. #ifdef GLX_VERSION_1_3
  755. void glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, unsigned int *value );
  756. GLXContext glXCreateNewContext( Display *dpy, GLXFBConfig config,
  757. int renderType, GLXContext shareList,
  758. Bool direct );
  759. Bool glXMakeContextCurrent( Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx );
  760. GLXDrawable glXGetCurrentReadDrawable( void );
  761. int glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value );
  762. void glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask );
  763. void glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, unsigned long *mask );
  764. #endif
  765. // GLX 1.4 and later
  766. void (*glXGetProcAddress(const GLubyte *procname))( void );
  767. }}} */
  768. // {{{
  769. #if 0
  770. #ifndef GLX_GLXEXT_LEGACY
  771. #include <GL/glxext.h>
  772. #else
  773. // ARB 2. GLX_ARB_get_proc_address
  774. #ifndef GLX_ARB_get_proc_address
  775. #define GLX_ARB_get_proc_address 1
  776. typedef void (*__GLXextFuncPtr)(void);
  777. __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *);
  778. #endif // GLX_ARB_get_proc_address
  779. #endif // GLX_GLXEXT_LEGACY
  780. ///
  781. /// The following aren't in glxext.h yet.
  782. ///
  783. // ???. GLX_NV_vertex_array_range
  784. #ifndef GLX_NV_vertex_array_range
  785. #define GLX_NV_vertex_array_range
  786. void *glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
  787. void glXFreeMemoryNV(GLvoid *pointer);
  788. typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
  789. typedef void ( * PFNGLXFREEMEMORYNVPROC) (GLvoid *pointer);
  790. #endif // GLX_NV_vertex_array_range
  791. // ???. GLX_MESA_allocate_memory
  792. #ifndef GLX_MESA_allocate_memory
  793. #define GLX_MESA_allocate_memory 1
  794. void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority);
  795. void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer);
  796. GLuint glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer);
  797. typedef void * ( * PFNGLXALLOCATEMEMORYMESAPROC) (Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority);
  798. typedef void ( * PFNGLXFREEMEMORYMESAPROC) (Display *dpy, int scrn, void *pointer);
  799. typedef GLuint (* PFNGLXGETMEMORYOFFSETMESAPROC) (Display *dpy, int scrn, const void *pointer);
  800. #endif // GLX_MESA_allocate_memory
  801. //
  802. // ARB ?. GLX_ARB_render_texture
  803. // XXX This was never finalized!
  804. //
  805. #ifndef GLX_ARB_render_texture
  806. #define GLX_ARB_render_texture 1
  807. Bool glXBindTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer);
  808. Bool glXReleaseTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer);
  809. Bool glXDrawableAttribARB(Display *dpy, GLXDrawable draw, const int *attribList);
  810. #endif // GLX_ARB_render_texture
  811. /*
  812. * Remove this when glxext.h is updated.
  813. */
  814. #ifndef GLX_NV_float_buffer
  815. #define GLX_NV_float_buffer 1
  816. #define GLX_FLOAT_COMPONENTS_NV 0x20B0
  817. #endif /* GLX_NV_float_buffer */
  818. /* GLX_MESA_swap_frame_usage */
  819. #ifndef GLX_MESA_swap_frame_usage
  820. #define GLX_MESA_swap_frame_usage 1
  821. int glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, float *usage);
  822. int glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable);
  823. int glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable);
  824. int glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, int64_t *swapCount, int64_t *missedFrames, float *lastMissedUsage);
  825. typedef int (*PFNGLXGETFRAMEUSAGEMESAPROC) (Display *dpy, GLXDrawable drawable, float *usage);
  826. typedef int (*PFNGLXBEGINFRAMETRACKINGMESAPROC)(Display *dpy, GLXDrawable drawable);
  827. typedef int (*PFNGLXENDFRAMETRACKINGMESAPROC)(Display *dpy, GLXDrawable drawable);
  828. typedef int (*PFNGLXQUERYFRAMETRACKINGMESAPROC)(Display *dpy, GLXDrawable drawable, int64_t *swapCount, int64_t *missedFrames, float *lastMissedUsage);
  829. #endif /* GLX_MESA_swap_frame_usage */
  830. /* GLX_MESA_swap_control */
  831. #ifndef GLX_MESA_swap_control
  832. #define GLX_MESA_swap_control 1
  833. int glXSwapIntervalMESA(unsigned int interval);
  834. int glXGetSwapIntervalMESA(void);
  835. typedef int (*PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval);
  836. typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void);
  837. #endif /* GLX_MESA_swap_control */
  838. #endif
  839. // }}}
  840. #if 0
  841. /*
  842. ** GLX Events
  843. */
  844. typedef struct {
  845. int event_type; /* GLX_DAMAGED or GLX_SAVED */
  846. int draw_type; /* GLX_WINDOW or GLX_PBUFFER */
  847. unsigned long serial; /* # of last request processed by server */
  848. Bool send_event; /* true if this came for SendEvent request */
  849. Display *display; /* display the event was read from */
  850. GLXDrawable drawable; /* XID of Drawable */
  851. unsigned int buffer_mask; /* mask indicating which buffers are affected */
  852. unsigned int aux_buffer; /* which aux buffer was affected */
  853. int x, y;
  854. int width, height;
  855. int count; /* if nonzero, at least this many more */
  856. } GLXPbufferClobberEvent;
  857. typedef union __GLXEvent {
  858. GLXPbufferClobberEvent glxpbufferclobber;
  859. long pad[24];
  860. } GLXEvent;
  861. #endif
  862. /*** DEBUG ***/
  863. CAMLprim value
  864. ml_glXGetFBConfigs2( value dpy, value screen )
  865. {
  866. CAMLparam2( dpy, screen );
  867. CAMLlocal1( ml_fbconfigs );
  868. int i, nfbconfigs;
  869. GLXFBConfig *fbconfigs; /* XXX here probably a memory leek */
  870. fbconfigs = glXGetFBConfigs(
  871. Display_val(dpy),
  872. ScreenNB_val(screen),
  873. &nfbconfigs );
  874. ml_fbconfigs = caml_alloc(nfbconfigs, 0);
  875. for (i = 0; i < nfbconfigs; i++)
  876. {
  877. Store_field( ml_fbconfigs, i, Val_GLXFBConfig( fbconfigs[i] ) );
  878. }
  879. CAMLreturn( ml_fbconfigs );
  880. }
  881. static const int drawable_type_table[] = {
  882. GLX_WINDOW_BIT,
  883. GLX_PIXMAP_BIT,
  884. GLX_PBUFFER_BIT
  885. };
  886. #define Drawable_type_val(v) drawable_type_table[Long_val(v)]
  887. static const int bind_to_tex_target_table[] = {
  888. GLX_TEXTURE_1D_BIT_EXT,
  889. GLX_TEXTURE_2D_BIT_EXT,
  890. GLX_TEXTURE_RECTANGLE_BIT_EXT
  891. };
  892. #define Bind_to_tex_target_val(v) bind_to_tex_target_table[Long_val(v)]
  893. /*
  894. type attribute_and_value =
  895. | D_GLX_DRAWABLE_TYPE of drawable_type
  896. | D_GLX_BIND_TO_TEXTURE_TARGETS_EXT of bind_to_tex_target
  897. | D_GLX_BIND_TO_TEXTURE_RGBA_EXT of bool
  898. | D_GLX_BIND_TO_TEXTURE_RGB_EXT of bool
  899. | D_GLX_Y_INVERTED_EXT of bool
  900. */
  901. CAMLprim value
  902. ml_glXHasFBConfigAttrib( value dpy, value fbconfig, value attr_n_val )
  903. {
  904. value v = attr_n_val;
  905. int _value;
  906. int attrib;
  907. int test_value;
  908. test_value = -1;
  909. if (Is_block(v))
  910. {
  911. switch (Tag_val(v))
  912. {
  913. case 0: /* GLX_DRAWABLE_TYPE of drawable_type */
  914. attrib = GLX_DRAWABLE_TYPE;
  915. test_value = Drawable_type_val(Field(v,0));
  916. break;
  917. case 1: /* GLX_BIND_TO_TEXTURE_TARGETS_EXT of bind_to_tex_target */
  918. attrib = GLX_BIND_TO_TEXTURE_TARGETS_EXT;
  919. test_value = Bind_to_tex_target_val(Field(v,0));
  920. break;
  921. case 2: /* GLX_BIND_TO_TEXTURE_RGBA_EXT of bool */
  922. attrib = GLX_BIND_TO_TEXTURE_RGBA_EXT;
  923. test_value = Bool_val(Field(v,0));
  924. break;
  925. case 3: /* GLX_BIND_TO_TEXTURE_RGB_EXT of bool */
  926. attrib = GLX_BIND_TO_TEXTURE_RGB_EXT;
  927. test_value = Bool_val(Field(v,0));
  928. break;
  929. case 4: /* GLX_Y_INVERTED_EXT of bool */
  930. attrib = GLX_Y_INVERTED_EXT;
  931. test_value = Bool_val(Field(v,0));
  932. break;
  933. default: caml_failwith("glXHasFBConfigAttrib: variant handling bug");
  934. }
  935. }
  936. else {caml_failwith("glXHasFBConfigAttrib: variant bug");}
  937. if (test_value == -1) caml_failwith("glXHasFBConfigAttrib: enum bug");
  938. glXGetFBConfigAttrib(
  939. Display_val(dpy),
  940. GLXFBConfig_val(fbconfig),
  941. attrib,
  942. &_value
  943. );
  944. if (_value & test_value) {
  945. return Val_true;
  946. } else {
  947. return Val_false;
  948. }
  949. }
  950. /* TODO */
  951. #if 1
  952. CAMLprim value
  953. /* static GLXFBConfig */
  954. ml_ChoosePixmapFBConfig( value dpy )
  955. {
  956. CAMLparam1( dpy );
  957. CAMLlocal1( res );
  958. Display *display = Display_val(dpy);
  959. int screen = DefaultScreen(display);
  960. GLXFBConfig *fbconfigs;
  961. int i, nfbconfigs, val;
  962. float top, bottom;
  963. fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs);
  964. for (i = 0; i < nfbconfigs; i++) {
  965. glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &val);
  966. if (!(val & GLX_PIXMAP_BIT))
  967. continue;
  968. glXGetFBConfigAttrib(display, fbconfigs[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val);
  969. if (!(val & GLX_TEXTURE_2D_BIT_EXT))
  970. continue;
  971. glXGetFBConfigAttrib(display, fbconfigs[i], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
  972. if (val == False) {
  973. glXGetFBConfigAttrib(display, fbconfigs[i], GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
  974. if (val == False)
  975. continue;
  976. }
  977. glXGetFBConfigAttrib(display, fbconfigs[i], GLX_Y_INVERTED_EXT, &val);
  978. if (val == True) {
  979. top = 0.0f;
  980. bottom = 1.0f;
  981. }
  982. else {
  983. top = 1.0f;
  984. bottom = 0.0f;
  985. }
  986. break;
  987. }
  988. if (i == nfbconfigs) {
  989. printf("Unable to find FBconfig for texturing\n");
  990. exit(1);
  991. }
  992. res = caml_alloc(3, 0);
  993. Store_field( res, 0, Val_GLXFBConfig( fbconfigs[i] ) );
  994. Store_field( res, 1, caml_copy_double( top ) );
  995. Store_field( res, 2, caml_copy_double( bottom ) );
  996. CAMLreturn( res );
  997. }
  998. #endif
  999. // vim: sw=4 sts=4 ts=4 et fdm=marker