PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/wrap_xlib.c

http://github.com/dmsh/ocaml-xlib
C | 6005 lines | 4981 code | 580 blank | 444 comment | 189 complexity | 005a9d9d38f67392377279f7cc79fa41 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /* OCaml bindings for the Xlib library.
  2. * Copyright (C) 2008, 2009, 2010 by Florent Monnier
  3. * Contact: <fmonnier@linux-nantes.org>
  4. *
  5. * OCaml-Xlib is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published
  7. * by the Free Software Foundation, either version 3 of the License,
  8. * or (at your option) any later version.
  9. *
  10. * OCaml-Xlib is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with OCaml-Xlib. If not, see:
  17. * <http://www.gnu.org/licenses/>
  18. */
  19. // {{{ Headers
  20. #include <X11/Xlib.h>
  21. #include <X11/Xutil.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #define CAML_NAME_SPACE 1
  26. #include <caml/mlvalues.h>
  27. #include <caml/memory.h>
  28. #include <caml/alloc.h>
  29. #include <caml/bigarray.h>
  30. #include <caml/custom.h>
  31. #include <caml/fail.h>
  32. #include <caml/callback.h>
  33. // }}}
  34. #include "wrap_xlib.h"
  35. // {{{ caml allocs
  36. custom_ops(XEvent);
  37. custom_ops(XColor);
  38. custom_ops(XGCValues);
  39. custom_ops(XSetWindowAttributes);
  40. custom_ops(XWindowAttributes);
  41. custom_ops(XSizeHints);
  42. custom_ops(XVisualInfo);
  43. custom_ops(XChar2b);
  44. custom_ops_n(XChar2b);
  45. // }}}
  46. // {{{ XID's
  47. #define Drawable_val(v) (XID_val(Drawable,(v)))
  48. #define Val_Drawable(xid) (Val_XID((xid)))
  49. #define Cursor_val(v) (XID_val(Cursor,(v)))
  50. #define Val_Cursor(xid) (Val_XID((xid)))
  51. #define Colormap_val(v) (XID_val(Colormap,(v)))
  52. #define Val_Colormap(xid) (Val_XID((xid)))
  53. #define GContext_val(v) (XID_val(GContext,(v)))
  54. #define Val_GContext(xid) (Val_XID((xid)))
  55. //#define KeySym_val(v) (XID_val(KeySym,(v)))
  56. //#define Val_KeySym(xid) (Val_XID((xid)))
  57. /* Get keysyms values instead of an abstract type */
  58. #define Val_keysym Val_int
  59. #define Keysym_val Long_val
  60. // }}}
  61. // {{{ return status
  62. #define DO_CHECK_RETURN_STATUS 1
  63. #if DO_CHECK_RETURN_STATUS
  64. #define GET_STATUS int status =
  65. #define CHECK_STATUS(fun,st) \
  66. do{ if (status != st) caml_failwith(#fun ": wrong return status"); }while(0)
  67. #else
  68. #define GET_STATUS (void)
  69. #define CHECK_STATUS
  70. #endif
  71. /* Many GET/CHECK STATUS are commented just because in
  72. * the source code of the Xlib implementation I use (XOrg)
  73. * the return status is just static and can only return one
  74. * value, so testing it is meaningless.
  75. * They are kept commented in case they are meaningfull in
  76. * an other implementation.
  77. *
  78. * Sometime the return value meaning a success is 1 and sometime 0,
  79. * even in the commented GET/CHECK_STATUS the value is the good one.
  80. */
  81. // }}}
  82. // {{{ GC
  83. // Handle the finalisation of GC's (other than the default one)
  84. #define GC_val(gc_pair) ((GC) Field((gc_pair),0))
  85. #define Display_of_GC(gc_pair) (Field((gc_pair),1))
  86. void Finalize_GC( value gc )
  87. {
  88. value dpy = Display_of_GC(gc);
  89. if (display_is_open(dpy)) {
  90. GET_STATUS XFreeGC(
  91. Display_val(dpy),
  92. GC_val(gc)
  93. );
  94. CHECK_STATUS(XFreeGC,1);
  95. }
  96. }
  97. CAMLprim value do_finalize_GC( value gc ) {
  98. Finalize_GC( gc );
  99. return Val_unit;
  100. }
  101. /*
  102. static struct custom_operations fgc_custom_ops = {
  103. identifier: "GC handling",
  104. finalize: Finalize_GC,
  105. compare: custom_compare_default,
  106. hash: custom_hash_default,
  107. serialize: custom_serialize_default,
  108. deserialize: custom_deserialize_default
  109. };
  110. */
  111. // The finalised one
  112. static inline value Val_GC_final(GC gc, value dpy)
  113. {
  114. CAMLparam1( dpy );
  115. CAMLlocal1( fgc );
  116. //fgc = caml_alloc_custom( &fgc_custom_ops, 2 * sizeof(value), 0, 1);
  117. // the previous line segfaults
  118. // so the link is done with do_finalize_GC from the ocaml side
  119. fgc = caml_alloc(2, 0);
  120. Store_field( fgc, 0, ((value)(gc)) );
  121. Store_field( fgc, 1, dpy );
  122. CAMLreturn( fgc );
  123. }
  124. // Not finalised (for default gc)
  125. static inline value Val_GC(GC gc, value dpy)
  126. {
  127. CAMLparam1( dpy );
  128. CAMLlocal1( gcp );
  129. gcp = caml_alloc(2, 0);
  130. Store_field( gcp, 0, ((value)(gc)) );
  131. Store_field( gcp, 1, dpy );
  132. CAMLreturn( gcp );
  133. }
  134. // }}}
  135. // {{{ Event-Masks
  136. static const long event_mask_table[] = {
  137. KeyPressMask,
  138. KeyReleaseMask,
  139. ButtonPressMask,
  140. ButtonReleaseMask,
  141. EnterWindowMask,
  142. LeaveWindowMask,
  143. PointerMotionMask,
  144. PointerMotionHintMask,
  145. Button1MotionMask,
  146. Button2MotionMask,
  147. Button3MotionMask,
  148. Button4MotionMask,
  149. Button5MotionMask,
  150. ButtonMotionMask,
  151. KeymapStateMask,
  152. ExposureMask,
  153. VisibilityChangeMask,
  154. StructureNotifyMask,
  155. ResizeRedirectMask,
  156. SubstructureNotifyMask,
  157. SubstructureRedirectMask,
  158. FocusChangeMask,
  159. PropertyChangeMask,
  160. ColormapChangeMask,
  161. OwnerGrabButtonMask,
  162. };
  163. static inline long
  164. Eventmask_val( value em_list )
  165. {
  166. long event_mask = 0;
  167. while ( em_list != Val_emptylist )
  168. {
  169. value head = Field(em_list, 0);
  170. long mask = event_mask_table[Long_val(head)];
  171. event_mask |= mask;
  172. em_list = Field(em_list, 1);
  173. }
  174. return event_mask;
  175. }
  176. // }}}
  177. // {{{ macro/funcs
  178. /* switch this to use the macros or the functions */
  179. //#define XMP(f) X##f // use the functions
  180. #define XMP(f) f // use the macros
  181. #define _xConnectionNumber XMP(ConnectionNumber)
  182. #define _xRootWindow XMP(RootWindow)
  183. #define _xDefaultScreen XMP(DefaultScreen)
  184. #define _xDefaultRootWindow XMP(DefaultRootWindow)
  185. #define _xDefaultVisual XMP(DefaultVisual)
  186. #define _xDefaultGC XMP(DefaultGC)
  187. #define _xBlackPixel XMP(BlackPixel)
  188. #define _xWhitePixel XMP(WhitePixel)
  189. #define _xDisplayWidth XMP(DisplayWidth)
  190. #define _xDisplayHeight XMP(DisplayHeight)
  191. #define _xDisplayPlanes XMP(DisplayPlanes)
  192. #define _xDisplayCells XMP(DisplayCells)
  193. #define _xScreenCount XMP(ScreenCount)
  194. #define _xServerVendor XMP(ServerVendor)
  195. #define _xProtocolVersion XMP(ProtocolVersion)
  196. #define _xProtocolRevision XMP(ProtocolRevision)
  197. #define _xVendorRelease XMP(VendorRelease)
  198. #define _xDisplayString XMP(DisplayString)
  199. #define _xDefaultDepth XMP(DefaultDepth)
  200. #define _xDefaultColormap XMP(DefaultColormap)
  201. #define _xBitmapUnit XMP(BitmapUnit)
  202. #define _xBitmapBitOrder XMP(BitmapBitOrder)
  203. #define _xBitmapPad XMP(BitmapPad)
  204. #define _xImageByteOrder XMP(ImageByteOrder)
  205. #define _xBitmapUnit XMP(BitmapUnit)
  206. #define _xScreenOfDisplay XMP(ScreenOfDisplay)
  207. #define _xDefaultScreenOfDisplay XMP(DefaultScreenOfDisplay)
  208. #define _xDisplayOfScreen XMP(DisplayOfScreen)
  209. #define _xRootWindowOfScreen XMP(RootWindowOfScreen)
  210. #define _xBlackPixelOfScreen XMP(BlackPixelOfScreen)
  211. #define _xWhitePixelOfScreen XMP(WhitePixelOfScreen)
  212. #define _xDefaultColormapOfScreen XMP(DefaultColormapOfScreen)
  213. #define _xDefaultDepthOfScreen XMP(DefaultDepthOfScreen)
  214. #define _xDefaultGCOfScreen XMP(DefaultGCOfScreen)
  215. #define _xDefaultVisualOfScreen XMP(DefaultVisualOfScreen)
  216. #define _xWidthOfScreen XMP(WidthOfScreen)
  217. #define _xHeightOfScreen XMP(HeightOfScreen)
  218. #define _xWidthMMOfScreen XMP(WidthMMOfScreen)
  219. #define _xHeightMMOfScreen XMP(HeightMMOfScreen)
  220. #define _xPlanesOfScreen XMP(PlanesOfScreen)
  221. #define _xCellsOfScreen XMP(CellsOfScreen)
  222. #define _xMinCmapsOfScreen XMP(MinCmapsOfScreen)
  223. #define _xMaxCmapsOfScreen XMP(MaxCmapsOfScreen)
  224. #define _xDoesSaveUnders XMP(DoesSaveUnders)
  225. #define _xDoesBackingStore XMP(DoesBackingStore)
  226. #define _xEventMaskOfScreen XMP(EventMaskOfScreen)
  227. // }}}
  228. // {{{ ints
  229. // wraps unsigned long
  230. #define Pixel_color_val Unsigned_long_val
  231. #define Val_pixel_color Val_long
  232. // type 'Time' defined in X.h (unsigned long / CARD32)
  233. // use int64 instead of int32 because the max value of unsigned is twice
  234. // (ocaml int32 is signed)
  235. #define Val_time caml_copy_int64
  236. #define Time_val(t) ((Time)Int64_val(t))
  237. // same value than Int64.max_int (used to check Time overflow)
  238. // (not used anymore, while CARD32 can not overflow a signed int64)
  239. #define MAX_INT64 9223372036854775807L
  240. // }}}
  241. // {{{ Atom
  242. #define Val_Atom(v) ((value)(v))
  243. #define Atom_val(v) ((Atom)(v))
  244. #define Atom_val_addr(v) ((Atom *)(&v))
  245. // }}}
  246. // {{{ KeyCode
  247. /* There's no real uniformity about the type keycode,
  248. - in structures it is most often (int) and sometimes (unsigned int)
  249. - in functions sometimes there is the NeedWidePrototypes switch
  250. which switches between (unsigned int) and (unsigned char)
  251. - in functions sometimes it is just (int) as parameter
  252. or (int *) if it's a returned value
  253. However as it handles a code for each key of the keyboard, and that generally
  254. keyboards have about 105 keys, it seems that it does not really matter.
  255. */
  256. #define Val_KeyCode Val_long
  257. #define KeyCode_val Long_val
  258. // }}}
  259. // {{{ caml_copy_string_array_n()
  260. // The list provided to caml_copy_string_array() needs to be NULL terminated
  261. static value caml_copy_string_array_n(char **strl, int n)
  262. {
  263. CAMLlocal1(ret);
  264. char const **param;
  265. int i;
  266. param = malloc((n+1) * sizeof(char *));
  267. for (i=0; i<n; i++) {
  268. param[i] = strl[i];
  269. }
  270. param[n] = NULL; // here the point
  271. ret = caml_copy_string_array(param);
  272. free(param);
  273. return ret;
  274. }
  275. // }}}
  276. // TODO: XGetErrorText()
  277. #if 0
  278. int ErrorHandler( Display *dpy, XErrorEvent *event )
  279. {
  280. char buffer[BUFSIZ];
  281. XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
  282. /*
  283. event->request_code;
  284. event->minor_code;
  285. event->resourceid;
  286. event->serial;
  287. */
  288. printf("ERROR: %s\n", buffer);
  289. return 0;
  290. }
  291. CAMLprim value
  292. ml_XSetErrorHandler( value unit )
  293. {
  294. XSetErrorHandler( ErrorHandler );
  295. return Val_unit;
  296. }
  297. #endif
  298. int ErrorHandler_closure( Display *dpy, XErrorEvent *event )
  299. {
  300. CAMLlocal1( ml_event );
  301. static value * closure_f = NULL;
  302. if (closure_f == NULL) {
  303. closure_f = caml_named_value("Error Handler Callback");
  304. }
  305. copy_XEvent( event, ml_event );
  306. caml_callback2( *closure_f, Val_Display(dpy), ml_event );
  307. return 0;
  308. }
  309. CAMLprim value
  310. ml_XSetErrorHandler( value unit ) {
  311. XSetErrorHandler(ErrorHandler_closure);
  312. return Val_unit;
  313. }
  314. CAMLprim value
  315. ml_XlibSpecificationRelease( value unit )
  316. {
  317. return Val_int(XlibSpecificationRelease);
  318. }
  319. CAMLprim value
  320. ml_XOpenDisplay( value display_name )
  321. {
  322. Display *dpy;
  323. dpy = XOpenDisplay( String_val(display_name) );
  324. if (dpy == NULL) {
  325. caml_failwith("Cannot open display");
  326. }
  327. return Val_Display(dpy);
  328. }
  329. CAMLprim value
  330. ml_XCloseDisplay( value dpy )
  331. {
  332. XCloseDisplay( Display_val(dpy) );
  333. display_record_closed(dpy);
  334. return Val_unit;
  335. }
  336. CAMLprim value
  337. ml_XFlush( value dpy )
  338. {
  339. GET_STATUS XFlush( Display_val(dpy) );
  340. CHECK_STATUS(XFlush, 1);
  341. return Val_unit;
  342. }
  343. CAMLprim value
  344. ml_XBell( value dpy, value percent )
  345. {
  346. //GET_STATUS
  347. XBell(
  348. Display_val(dpy),
  349. Int_val(percent)
  350. );
  351. //CHECK_STATUS(XBell,1);
  352. return Val_unit;
  353. }
  354. static const int close_mode_table[] = {
  355. DestroyAll,
  356. RetainPermanent,
  357. RetainTemporary,
  358. };
  359. #define Close_mode_val(i) (close_mode_table[Long_val(i)])
  360. CAMLprim value
  361. ml_XSetCloseDownMode( value dpy, value close_mode )
  362. {
  363. //GET_STATUS
  364. XSetCloseDownMode(
  365. Display_val(dpy),
  366. Close_mode_val(close_mode)
  367. );
  368. //CHECK_STATUS(XSetCloseDownMode,1);
  369. return Val_unit;
  370. }
  371. CAMLprim value
  372. ml_XSync( value dpy, value discard )
  373. {
  374. //GET_STATUS
  375. XSync(
  376. Display_val(dpy),
  377. Bool_val(discard)
  378. );
  379. //CHECK_STATUS(XSync,1);
  380. return Val_unit;
  381. }
  382. CAMLprim value
  383. ml_XGrabServer( value dpy )
  384. {
  385. //GET_STATUS
  386. XGrabServer(
  387. Display_val(dpy)
  388. );
  389. //CHECK_STATUS(XGrabServer,1);
  390. return Val_unit;
  391. }
  392. CAMLprim value
  393. ml_XUngrabServer( value dpy )
  394. {
  395. //GET_STATUS
  396. XUngrabServer(
  397. Display_val(dpy)
  398. );
  399. //CHECK_STATUS(XUngrabServer,1);
  400. return Val_unit;
  401. }
  402. CAMLprim value
  403. ml_XUngrabPointer( value dpy, value time )
  404. {
  405. //GET_STATUS
  406. XUngrabPointer(
  407. Display_val(dpy),
  408. Time_val(time)
  409. );
  410. //CHECK_STATUS(XUngrabPointer,1);
  411. return Val_unit;
  412. }
  413. CAMLprim value
  414. ml_XUngrabKeyboard( value dpy, value time )
  415. {
  416. //GET_STATUS
  417. XUngrabKeyboard(
  418. Display_val(dpy),
  419. Time_val(time)
  420. );
  421. //CHECK_STATUS(XUngrabKeyboard,1);
  422. return Val_unit;
  423. }
  424. CAMLprim value
  425. ml_XConnectionNumber( value dpy )
  426. {
  427. return Val_int( XConnectionNumber( Display_val(dpy) ));
  428. }
  429. CAMLprim value
  430. ml_XDefaultScreen( value dpy )
  431. {
  432. int screen_number = _xDefaultScreen( Display_val(dpy) );
  433. return Val_screenNB(screen_number);
  434. }
  435. CAMLprim value
  436. ml_XScreenCount( value dpy )
  437. {
  438. return Val_int( _xScreenCount( Display_val(dpy) ));
  439. }
  440. CAMLprim value
  441. ml_XDefaultRootWindow( value dpy )
  442. {
  443. return Val_Window( _xDefaultRootWindow( Display_val(dpy) ));
  444. }
  445. CAMLprim value
  446. ml_XDefaultVisual( value dpy, value screen_number )
  447. {
  448. Visual * vis = _xDefaultVisual(
  449. Display_val(dpy),
  450. ScreenNB_val(screen_number) );
  451. return Val_Visual(vis);
  452. }
  453. CAMLprim value ml_Visual_visualid( value visual ) {
  454. return Val_VisualID( Visual_val(visual)->visualid );
  455. }
  456. CAMLprim value ml_Visual_map_entries( value visual ) {
  457. return Val_int( Visual_val(visual)->map_entries );
  458. }
  459. CAMLprim value ml_Visual_bits_per_rgb( value visual ) {
  460. return Val_int( Visual_val(visual)->bits_per_rgb );
  461. }
  462. CAMLprim value ml_Visual_red_mask( value visual ) {
  463. return Val_long( Visual_val(visual)->red_mask );
  464. }
  465. CAMLprim value ml_Visual_green_mask( value visual ) {
  466. return Val_long( Visual_val(visual)->green_mask );
  467. }
  468. CAMLprim value ml_Visual_blue_mask( value visual ) {
  469. return Val_long( Visual_val(visual)->blue_mask );
  470. }
  471. CAMLprim value
  472. ml_XDefaultDepth( value dpy, value screen_number )
  473. {
  474. int depth = _xDefaultDepth(
  475. Display_val(dpy),
  476. ScreenNB_val(screen_number) );
  477. return Val_int(depth);
  478. }
  479. CAMLprim value
  480. ml_XListDepths( value dpy, value screen_number )
  481. {
  482. CAMLparam2(dpy, screen_number);
  483. CAMLlocal1(ml_depths);
  484. int i, count;
  485. int *depths = XListDepths(
  486. Display_val(dpy),
  487. ScreenNB_val(screen_number),
  488. &count
  489. );
  490. ml_depths = caml_alloc(count, 0);
  491. for (i=0; i<count; ++i) {
  492. Store_field( ml_depths, i, Val_int(depths[i]) );
  493. }
  494. XFree(depths);
  495. CAMLreturn(ml_depths);
  496. }
  497. CAMLprim value
  498. ml_XDisplayPlanes( value dpy, value screen_number )
  499. {
  500. int depth = _xDisplayPlanes(
  501. Display_val(dpy),
  502. ScreenNB_val(screen_number) );
  503. return Val_int(depth);
  504. }
  505. CAMLprim value
  506. ml_XDefaultColormap( value dpy, value screen_number )
  507. {
  508. Colormap colormap = _xDefaultColormap(
  509. Display_val(dpy),
  510. ScreenNB_val(screen_number) );
  511. return Val_Colormap(colormap);
  512. }
  513. CAMLprim value
  514. ml_XDisplayCells( value dpy, value screen_number )
  515. {
  516. int cells = _xDisplayCells(
  517. Display_val(dpy),
  518. ScreenNB_val(screen_number) );
  519. return Val_int(cells);
  520. }
  521. CAMLprim value
  522. ml_XBitmapUnit( value dpy )
  523. {
  524. return Val_int( _xBitmapUnit( Display_val(dpy) ));
  525. }
  526. CAMLprim value
  527. ml_XBitmapPad( value dpy )
  528. {
  529. return Val_int( _xBitmapPad( Display_val(dpy) ));
  530. }
  531. CAMLprim value
  532. ml_XProtocolVersion( value dpy )
  533. {
  534. return Val_int( _xProtocolVersion( Display_val(dpy) ));
  535. }
  536. CAMLprim value
  537. ml_XProtocolRevision( value dpy )
  538. {
  539. return Val_int( _xProtocolRevision( Display_val(dpy) ));
  540. }
  541. CAMLprim value
  542. ml_XVendorRelease( value dpy )
  543. {
  544. return Val_int( _xVendorRelease( Display_val(dpy) ));
  545. }
  546. CAMLprim value
  547. ml_XServerVendor( value dpy )
  548. {
  549. char * vendor = _xServerVendor( Display_val(dpy) );
  550. return caml_copy_string(vendor);
  551. }
  552. CAMLprim value
  553. ml_XBlackPixel( value dpy, value screen_number )
  554. {
  555. unsigned long color = _xBlackPixel(
  556. Display_val(dpy),
  557. ScreenNB_val(screen_number) );
  558. return Val_pixel_color(color);
  559. }
  560. CAMLprim value
  561. ml_XWhitePixel( value dpy, value screen_number )
  562. {
  563. unsigned long color = _xWhitePixel(
  564. Display_val(dpy),
  565. ScreenNB_val(screen_number) );
  566. return Val_pixel_color(color);
  567. }
  568. CAMLprim value
  569. ml_XDisplayWidth( value dpy, value screen_number )
  570. {
  571. int width = _xDisplayWidth(
  572. Display_val(dpy),
  573. ScreenNB_val(screen_number) );
  574. return Val_int(width);
  575. }
  576. CAMLprim value
  577. ml_XDisplayHeight( value dpy, value screen_number )
  578. {
  579. int height = _xDisplayHeight(
  580. Display_val(dpy),
  581. ScreenNB_val(screen_number) );
  582. return Val_int(height);
  583. }
  584. CAMLprim value
  585. ml_XRootWindow( value dpy, value screen_number )
  586. {
  587. Window win = _xRootWindow(
  588. Display_val(dpy),
  589. ScreenNB_val(screen_number) );
  590. return Val_Window(win);
  591. }
  592. CAMLprim value
  593. ml_XDefaultGC( value dpy, value screen_number )
  594. {
  595. GC gc = _xDefaultGC(
  596. Display_val(dpy),
  597. ScreenNB_val(screen_number) );
  598. return Val_GC(gc,dpy);
  599. }
  600. /* {{{ XColor */
  601. CAMLprim value
  602. ml_alloc_XColor( value unit )
  603. {
  604. CAMLparam0();
  605. CAMLlocal1(x_color);
  606. alloc_XColor(x_color);
  607. memset(XColor_val(x_color), 0, sizeof(XColor));
  608. CAMLreturn(x_color);
  609. }
  610. CAMLprim value
  611. ml_XAllocNamedColor( value dpy, value colormap, value color_name )
  612. {
  613. CAMLparam3(dpy, colormap, color_name);
  614. CAMLlocal3(xcolor_pair, screen_def, exact_def);
  615. alloc_XColor(screen_def);
  616. alloc_XColor(exact_def);
  617. //GET_STATUS
  618. XAllocNamedColor(
  619. Display_val(dpy),
  620. Colormap_val(colormap),
  621. String_val(color_name),
  622. XColor_val(screen_def),
  623. XColor_val(exact_def)
  624. );
  625. //CHECK_STATUS(XAllocNamedColor,1);
  626. xcolor_pair = caml_alloc(2, 0);
  627. Store_field( xcolor_pair, 0, screen_def );
  628. Store_field( xcolor_pair, 1, exact_def );
  629. CAMLreturn(xcolor_pair);
  630. }
  631. CAMLprim value
  632. ml_XColor_set_red( value x_color, value v )
  633. {
  634. XColor * xcolor = XColor_val(x_color);
  635. xcolor->red = Long_val(v);
  636. return Val_unit;
  637. }
  638. CAMLprim value
  639. ml_XColor_set_green( value x_color, value v )
  640. {
  641. XColor * xcolor = XColor_val(x_color);
  642. xcolor->green = Long_val(v);
  643. return Val_unit;
  644. }
  645. CAMLprim value
  646. ml_XColor_set_blue( value x_color, value v )
  647. {
  648. XColor * xcolor = XColor_val(x_color);
  649. xcolor->blue = Long_val(v);
  650. return Val_unit;
  651. }
  652. CAMLprim value
  653. ml_XColor_set_rgb( value x_color, value r, value g, value b )
  654. {
  655. XColor * xcolor = XColor_val(x_color);
  656. xcolor->red = Long_val(r);
  657. xcolor->green = Long_val(g);
  658. xcolor->blue = Long_val(b);
  659. return Val_unit;
  660. }
  661. static const char color_flags_table[] = {
  662. DoRed,
  663. DoGreen,
  664. DoBlue,
  665. };
  666. CAMLprim value
  667. ml_XColor_set_flags( value x_color, value mask_list )
  668. {
  669. XColor * xcolor = XColor_val(x_color);
  670. while ( mask_list != Val_emptylist )
  671. {
  672. value head = Field(mask_list, 0);
  673. xcolor->flags |= color_flags_table[Long_val(head)];
  674. mask_list = Field(mask_list, 1);
  675. }
  676. return Val_unit;
  677. }
  678. CAMLprim value
  679. ml_XAllocColor( value dpy, value colormap, value x_color )
  680. {
  681. XColor * xcolor = XColor_val(x_color);
  682. XAllocColor( Display_val(dpy), Colormap_val(colormap), xcolor );
  683. return Val_unit;
  684. }
  685. CAMLprim value
  686. ml_XAllocColorCells(
  687. value dpy,
  688. value colormap,
  689. value contig,
  690. value nplanes,
  691. value npixels )
  692. {
  693. CAMLparam5(dpy, colormap, contig, nplanes, npixels);
  694. CAMLlocal3(ret, pixels_arr, plnmsk_arr);
  695. unsigned long *pixels = NULL;
  696. unsigned long *plane_masks = NULL;
  697. long i;
  698. pixels = malloc(UInt_val(npixels) * sizeof(unsigned long));
  699. if (pixels == NULL) {
  700. caml_failwith("xAllocColorCells: out of memory");
  701. }
  702. plane_masks = malloc(UInt_val(nplanes) * sizeof(unsigned long));
  703. if (plane_masks == NULL) {
  704. free(pixels);
  705. caml_failwith("xAllocColorCells: out of memory");
  706. }
  707. Status status = XAllocColorCells(
  708. Display_val(dpy),
  709. Colormap_val(colormap),
  710. Bool_val(contig),
  711. plane_masks,
  712. UInt_val(nplanes),
  713. pixels,
  714. UInt_val(npixels)
  715. );
  716. if (!status) {
  717. free(pixels);
  718. free(plane_masks);
  719. caml_failwith("xAllocColorCells: "
  720. "can't alloc enough colors in the current color map");
  721. }
  722. pixels_arr = caml_alloc(UInt_val(npixels), 0);
  723. for (i=0; i < UInt_val(npixels); ++i)
  724. {
  725. Store_field( pixels_arr, i, Val_ulong(pixels[i]) );
  726. }
  727. free(pixels);
  728. plnmsk_arr = caml_alloc(UInt_val(nplanes), 0);
  729. for (i=0; i < UInt_val(nplanes); ++i)
  730. {
  731. Store_field( plnmsk_arr, i, Val_ulong(plane_masks[i]) );
  732. }
  733. free(plane_masks);
  734. ret = caml_alloc(2, 0);
  735. Store_field(ret, 0, pixels_arr );
  736. Store_field(ret, 1, plnmsk_arr );
  737. CAMLreturn(ret);
  738. }
  739. CAMLprim value
  740. ml_XAllocColorCellsPixels(
  741. value dpy,
  742. value colormap,
  743. value contig,
  744. value npixels )
  745. {
  746. CAMLparam4(dpy, colormap, contig, npixels);
  747. CAMLlocal1(pixels_arr);
  748. unsigned long *pixels = NULL;
  749. long i;
  750. pixels = malloc(UInt_val(npixels) * sizeof(unsigned long));
  751. if (pixels == NULL) caml_failwith("xAllocColorCells: out of memory");
  752. Status status = XAllocColorCells(
  753. Display_val(dpy),
  754. Colormap_val(colormap),
  755. Bool_val(contig),
  756. NULL, 0,
  757. pixels,
  758. UInt_val(npixels)
  759. );
  760. if (!status) {
  761. free(pixels);
  762. caml_failwith("xAllocColorCells: "
  763. "can't alloc enough colors in the current color map");
  764. }
  765. pixels_arr = caml_alloc(UInt_val(npixels), 0);
  766. for (i=0; i < UInt_val(npixels); ++i)
  767. {
  768. Store_field( pixels_arr, i, Val_ulong(pixels[i]) );
  769. }
  770. free(pixels);
  771. CAMLreturn(pixels_arr);
  772. }
  773. CAMLprim value
  774. ml_XColor_pixel( value x_color )
  775. {
  776. XColor * xcolor = XColor_val(x_color);
  777. return Val_pixel_color(xcolor->pixel);
  778. }
  779. CAMLprim value
  780. ml_XColor_set_pixel( value x_color, value pixel_color )
  781. {
  782. XColor * xcolor = XColor_val(x_color);
  783. xcolor->pixel = Pixel_color_val(pixel_color);
  784. return Val_unit;
  785. }
  786. CAMLprim value
  787. ml_XQueryColor( value dpy, value colormap, value x_color )
  788. {
  789. XQueryColor(
  790. Display_val(dpy),
  791. Colormap_val(colormap),
  792. XColor_val(x_color)
  793. );
  794. return Val_unit;
  795. }
  796. CAMLprim value
  797. ml_XColor_get_red( value x_color )
  798. {
  799. XColor * xcolor = XColor_val(x_color);
  800. return Val_long(xcolor->red);
  801. }
  802. CAMLprim value
  803. ml_XColor_get_green( value x_color )
  804. {
  805. XColor * xcolor = XColor_val(x_color);
  806. return Val_long(xcolor->green);
  807. }
  808. CAMLprim value
  809. ml_XColor_get_blue( value x_color )
  810. {
  811. XColor * xcolor = XColor_val(x_color);
  812. return Val_long(xcolor->blue);
  813. }
  814. CAMLprim value
  815. ml_XColor_get_rgb( value x_color )
  816. {
  817. CAMLparam1(x_color);
  818. CAMLlocal1(rgb);
  819. XColor * xcolor = XColor_val(x_color);
  820. rgb = caml_alloc(3, 0);
  821. Store_field( rgb, 0, Val_long(xcolor->red) );
  822. Store_field( rgb, 1, Val_long(xcolor->green) );
  823. Store_field( rgb, 2, Val_long(xcolor->blue) );
  824. CAMLreturn(rgb);
  825. }
  826. /* }}} */
  827. CAMLprim value
  828. ml_XCreateSimpleWindow( value dpy, value parent, value x, value y,
  829. value width, value height, value border_width,
  830. value border, value background)
  831. {
  832. Window win = XCreateSimpleWindow(
  833. Display_val(dpy),
  834. Window_val(parent),
  835. Int_val(x),
  836. Int_val(y),
  837. UInt_val(width),
  838. UInt_val(height),
  839. UInt_val(border_width),
  840. Pixel_color_val(border),
  841. Pixel_color_val(background) );
  842. return Val_Window(win);
  843. }
  844. CAMLprim value
  845. ml_XCreateSimpleWindow_bytecode( value * argv, int argn )
  846. {
  847. return ml_XCreateSimpleWindow( argv[0], argv[1], argv[2], argv[3],
  848. argv[4], argv[5], argv[6], argv[7], argv[8] );
  849. }
  850. CAMLprim value
  851. ml_XDestroyWindow( value dpy, value win )
  852. {
  853. GET_STATUS XDestroyWindow(
  854. Display_val(dpy),
  855. Window_val(win) );
  856. CHECK_STATUS(XDestroyWindow, 1);
  857. return Val_unit;
  858. }
  859. CAMLprim value
  860. caml_get_xid(value xid)
  861. {
  862. return Val_XID(Long_val(xid));
  863. }
  864. CAMLprim value
  865. ml_alloc_XVisualInfo( value unit )
  866. {
  867. CAMLparam0();
  868. CAMLlocal1(visInfo);
  869. alloc_XVisualInfo(visInfo);
  870. memset(XVisualInfo_val(visInfo), 0, sizeof(XVisualInfo));
  871. CAMLreturn(visInfo);
  872. }
  873. static const long vinfo_mask_table[] = {
  874. VisualNoMask,
  875. VisualIDMask,
  876. VisualScreenMask,
  877. VisualDepthMask,
  878. VisualClassMask,
  879. VisualRedMaskMask,
  880. VisualGreenMaskMask,
  881. VisualBlueMaskMask,
  882. VisualColormapSizeMask,
  883. VisualBitsPerRGBMask,
  884. VisualAllMask,
  885. };
  886. static inline long
  887. vinfo_mask_val( value mask_list )
  888. {
  889. long c_mask = 0;
  890. while ( mask_list != Val_emptylist )
  891. {
  892. value head = Field(mask_list, 0);
  893. c_mask |= vinfo_mask_table[Long_val(head)];
  894. mask_list = Field(mask_list, 1);
  895. }
  896. return c_mask;
  897. }
  898. CAMLprim value
  899. ml_XGetVisualInfo( value dpy, value vinfo_mask, value vinfo_template )
  900. {
  901. CAMLparam3(dpy, vinfo_mask, vinfo_template);
  902. CAMLlocal2(via, visual_info);
  903. int i, nitems;
  904. XVisualInfo *visInfo = XGetVisualInfo(
  905. Display_val(dpy),
  906. vinfo_mask_val(vinfo_mask),
  907. XVisualInfo_val(vinfo_template),
  908. &nitems
  909. );
  910. if (!visInfo) caml_failwith("xGetVisualInfo: can't get visual");
  911. via = caml_alloc(nitems, 0);
  912. for (i=0; i<nitems; i++) {
  913. alloc_XVisualInfo(visual_info);
  914. memcpy(XVisualInfo_val(visual_info), &(visInfo[i]), sizeof(XVisualInfo));
  915. //XFree(visInfo[i]);
  916. Store_field(via, i, visual_info);
  917. }
  918. XFree(visInfo);
  919. CAMLreturn(via);
  920. }
  921. static const int color_class_table[] = {
  922. StaticGray,
  923. GrayScale,
  924. StaticColor,
  925. PseudoColor,
  926. TrueColor,
  927. DirectColor,
  928. };
  929. #define Color_class_val(v) (color_class_table[Long_val(v)])
  930. #define XVisualInfo_set_field(Conv_val, field) \
  931. CAMLprim value ml_XVisualInfo_set_##field( value visinfo, value v ) { \
  932. XVisualInfo *vi = XVisualInfo_val(visinfo); \
  933. vi->field = Conv_val(v); \
  934. return Val_unit; \
  935. }
  936. XVisualInfo_set_field( Visual_val, visual )
  937. XVisualInfo_set_field( VisualID_val, visualid )
  938. XVisualInfo_set_field( ScreenNB_val, screen )
  939. XVisualInfo_set_field( Long_val, depth )
  940. XVisualInfo_set_field( Color_class_val, class )
  941. XVisualInfo_set_field( ULong_val, red_mask )
  942. XVisualInfo_set_field( ULong_val, green_mask )
  943. XVisualInfo_set_field( ULong_val, blue_mask )
  944. XVisualInfo_set_field( Long_val, colormap_size )
  945. XVisualInfo_set_field( Long_val, bits_per_rgb )
  946. CAMLprim value
  947. ml_XMatchVisualInfo( value dpy, value screen, value depth, value color_class )
  948. {
  949. CAMLparam4(dpy, screen, depth, color_class);
  950. CAMLlocal1(visual_info);
  951. alloc_XVisualInfo(visual_info);
  952. Status st = XMatchVisualInfo(
  953. Display_val(dpy),
  954. ScreenNB_val(screen),
  955. Int_val(depth),
  956. Color_class_val(color_class),
  957. XVisualInfo_val(visual_info)
  958. );
  959. if (st == False) caml_failwith("xMatchVisualInfo: no visual found");
  960. CAMLreturn(visual_info);
  961. }
  962. CAMLprim value
  963. ml_XVisualInfo_contents( value visual_info )
  964. {
  965. CAMLparam1(visual_info);
  966. CAMLlocal1(dat);
  967. XVisualInfo * vi = XVisualInfo_val(visual_info);
  968. dat = caml_alloc(9, 0);
  969. Store_field( dat, 0, Val_Visual(vi->visual) );
  970. Store_field( dat, 1, Val_VisualID(vi->visualid) );
  971. Store_field( dat, 2, Val_screenNB(vi->screen) );
  972. Store_field( dat, 3, Val_int(vi->depth) );
  973. Store_field( dat, 4, Val_long(vi->red_mask) );
  974. Store_field( dat, 5, Val_long(vi->green_mask) );
  975. Store_field( dat, 6, Val_long(vi->blue_mask) );
  976. Store_field( dat, 7, Val_int(vi->colormap_size) );
  977. Store_field( dat, 8, Val_int(vi->bits_per_rgb) );
  978. CAMLreturn(dat);
  979. }
  980. CAMLprim value
  981. ml_XFree_XVisualInfo( value visual_info )
  982. {
  983. XVisualInfo * vi = XVisualInfo_val(visual_info);
  984. if (vi == NULL) {
  985. caml_invalid_argument("xFree_xVisualInfo: xVisualInfo NULL pointer");
  986. } else {
  987. XFree( vi );
  988. vi = NULL;
  989. }
  990. return Val_unit;
  991. }
  992. CAMLprim value
  993. ml_XCreateColormap( value dpy, value win, value visual, value alloc )
  994. {
  995. Colormap colormap = XCreateColormap(
  996. Display_val(dpy),
  997. Window_val(win),
  998. Visual_val(visual),
  999. ( Int_val(alloc) ? AllocAll : AllocNone)
  1000. );
  1001. return Val_Colormap(colormap);
  1002. }
  1003. CAMLprim value
  1004. ml_XFreeColormap( value dpy, value colormap )
  1005. {
  1006. GET_STATUS XFreeColormap(
  1007. Display_val(dpy),
  1008. Colormap_val(colormap) );
  1009. CHECK_STATUS(XFreeColormap,1);
  1010. return Val_unit;
  1011. }
  1012. CAMLprim value
  1013. ml_XCopyColormapAndFree( value dpy, value colormap )
  1014. {
  1015. Colormap new_colormap = XCopyColormapAndFree(
  1016. Display_val(dpy),
  1017. Colormap_val(colormap) );
  1018. /*
  1019. if ((new_colormap=XCopyColormapAndFree(Display_val(dpy),
  1020. Colormap_val(colormap))) == BadAlloc)
  1021. caml_failwith("Can't Create new colormap");
  1022. */
  1023. return Val_Colormap(new_colormap);
  1024. }
  1025. CAMLprim value
  1026. ml_XSetWindowColormap( value dpy, value win, value colormap )
  1027. {
  1028. GET_STATUS XSetWindowColormap(
  1029. Display_val(dpy),
  1030. Window_val(win),
  1031. Colormap_val(colormap) );
  1032. CHECK_STATUS(XSetWindowColormap,1);
  1033. return Val_unit;
  1034. }
  1035. CAMLprim value
  1036. _ml_XSetWindowAttributes_alloc( value unit )
  1037. {
  1038. CAMLparam0();
  1039. CAMLlocal2(ret, wattr);
  1040. alloc_XSetWindowAttributes(wattr);
  1041. ret = caml_alloc(2, 0);
  1042. Store_field(ret, 0, wattr );
  1043. Store_field(ret, 1, (value) 0 );
  1044. CAMLreturn(ret);
  1045. }
  1046. CAMLprim value
  1047. ml_XSetWindowAttributes_alloc( value unit )
  1048. {
  1049. CAMLparam0();
  1050. CAMLlocal1(wattr);
  1051. alloc_XSetWindowAttributes(wattr);
  1052. CAMLreturn(wattr);
  1053. }
  1054. #define WATTR_SET(field_c_type, attr_field, field_mask, Conv_val, ml_type) \
  1055. \
  1056. CAMLprim value \
  1057. ml_xSetWindowAttributes_set_##attr_field( value ml_wattr, value _##attr_field ) \
  1058. { \
  1059. XSetWindowAttributes * wattr; \
  1060. wattr = XSetWindowAttributes_val(ml_wattr); \
  1061. wattr->attr_field = Conv_val(_##attr_field); \
  1062. return Val_unit; \
  1063. }
  1064. /* setting the fields of the struct XSetWindowAttributes and the associated mask */
  1065. WATTR_SET( Pixmap, background_pixmap, CWBackPixmap, Pixmap_val, pixmap )
  1066. WATTR_SET( unsigned long, background_pixel, CWBackPixel, Pixel_color_val, uint )
  1067. WATTR_SET( Pixmap, border_pixmap, CWBorderPixmap, Pixmap_val, pixmap )
  1068. WATTR_SET( unsigned long, border_pixel, CWBorderPixel, Pixel_color_val, uint )
  1069. WATTR_SET( int, bit_gravity, CWBitGravity, Int_val, int )
  1070. WATTR_SET( int, win_gravity, CWWinGravity, Int_val, int )
  1071. WATTR_SET( int, backing_store, CWBackingStore, Int_val, int )
  1072. WATTR_SET( unsigned long, backing_planes, CWBackingPlanes, ULong_val, uint )//XXX
  1073. WATTR_SET( unsigned long, backing_pixel, CWBackingPixel, ULong_val, uint )//pixel_color?
  1074. WATTR_SET( Bool, save_under, CWSaveUnder, Bool_val, bool )
  1075. WATTR_SET( long, event_mask, CWEventMask, Eventmask_val, event_mask_list )
  1076. WATTR_SET( long, do_not_propagate_mask, CWDontPropagate, Long_val, int )
  1077. WATTR_SET( Bool, override_redirect, CWOverrideRedirect, Bool_val, bool )
  1078. WATTR_SET( Colormap, colormap, CWColormap, Colormap_val, colormap )
  1079. WATTR_SET( Cursor, cursor, CWCursor, Cursor_val, cursor )
  1080. static const unsigned int window_class_table[] = {
  1081. CopyFromParent,
  1082. InputOutput,
  1083. InputOnly,
  1084. };
  1085. static const unsigned long winattr_valuemask_table[] = {
  1086. CWBackPixmap,
  1087. CWBackPixel,
  1088. CWBorderPixmap,
  1089. CWBorderPixel,
  1090. CWBitGravity,
  1091. CWWinGravity,
  1092. CWBackingStore,
  1093. CWBackingPlanes,
  1094. CWBackingPixel,
  1095. CWOverrideRedirect,
  1096. CWSaveUnder,
  1097. CWEventMask,
  1098. CWDontPropagate,
  1099. CWColormap,
  1100. CWCursor,
  1101. };
  1102. static inline unsigned long
  1103. winattr_valuemask_val( value mask_list )
  1104. {
  1105. unsigned long c_mask = 0;
  1106. while ( mask_list != Val_emptylist )
  1107. {
  1108. value head = Field(mask_list, 0);
  1109. c_mask |= winattr_valuemask_table[Long_val(head)];
  1110. mask_list = Field(mask_list, 1);
  1111. }
  1112. return c_mask;
  1113. }
  1114. CAMLprim value
  1115. ml_XGetWindowAttributes( value dpy, value win )
  1116. {
  1117. CAMLparam2(dpy, win);
  1118. CAMLlocal1(wattr);
  1119. alloc_XWindowAttributes(wattr);
  1120. //GET_STATUS
  1121. XGetWindowAttributes(
  1122. Display_val(dpy),
  1123. Window_val(win),
  1124. XWindowAttributes_val(wattr)
  1125. );
  1126. //CHECK_STATUS(XGetWindowAttributes,1);
  1127. CAMLreturn(wattr);
  1128. }
  1129. #define quote(s) #s
  1130. #define WATTR_GET( Val_conv, field_name, ml_type ) \
  1131. \
  1132. CAMLprim value \
  1133. ml_XWindowAttributes_##field_name( value wattr ) { \
  1134. return Val_conv( XWindowAttributes_val(wattr)->field_name ); \
  1135. }
  1136. #define WATTR_GML( Val_conv, field_name, ml_type ) \
  1137. external xWindowAttributes_##field_name: xWindowAttributes -> ml_type = quote(ml_XWindowAttributes_##field_name)
  1138. WATTR_GET( Val_int, x, int )
  1139. WATTR_GET( Val_int, y, int )
  1140. WATTR_GET( Val_int, width, int )
  1141. WATTR_GET( Val_int, height, int )
  1142. WATTR_GET( Val_int, depth, int )
  1143. WATTR_GET( Val_XScreen, screen, xScreen )
  1144. WATTR_GET( Val_int, border_width, int )
  1145. WATTR_GET( Val_Colormap, colormap, colormap )
  1146. WATTR_GET( Val_bool, map_installed, bool )
  1147. CAMLprim value
  1148. ml_XWindowAttributes_all( value dpy, value win )
  1149. {
  1150. CAMLparam2(dpy, win);
  1151. CAMLlocal1(wattrs);
  1152. XWindowAttributes c_wattr;
  1153. //GET_STATUS
  1154. XGetWindowAttributes(
  1155. Display_val(dpy),
  1156. Window_val(win),
  1157. &c_wattr
  1158. );
  1159. //CHECK_STATUS(XGetWindowAttributes,1);
  1160. wattrs = caml_alloc(5, 0);
  1161. Store_field( wattrs, 0, Val_int( c_wattr.x ) );
  1162. Store_field( wattrs, 1, Val_int( c_wattr.y ) );
  1163. Store_field( wattrs, 2, Val_int( c_wattr.width ) );
  1164. Store_field( wattrs, 3, Val_int( c_wattr.height ) );
  1165. Store_field( wattrs, 4, Val_int( c_wattr.depth ) );
  1166. CAMLreturn(wattrs);
  1167. }
  1168. #if 0
  1169. typedef struct {
  1170. int x, y; /* location of window */
  1171. int width, height; /* width and height of window */
  1172. int border_width; /* border width of window */
  1173. int depth; /* depth of window */
  1174. Visual *visual; /* the associated visual structure */
  1175. Window root; /* root of screen containing window */
  1176. #if defined(__cplusplus) || defined(c_plusplus)
  1177. int c_class; /* C++ InputOutput, InputOnly*/
  1178. #else
  1179. int class; /* InputOutput, InputOnly*/
  1180. #endif
  1181. int bit_gravity; /* one of bit gravity values */
  1182. int win_gravity; /* one of the window gravity values */
  1183. int backing_store; /* NotUseful, WhenMapped, Always */
  1184. unsigned long backing_planes;/* planes to be preserved if possible */
  1185. unsigned long backing_pixel;/* value to be used when restoring planes */
  1186. Bool save_under; /* boolean, should bits under be saved? */
  1187. Colormap colormap; /* color map to be associated with window */
  1188. Bool map_installed; /* boolean, is color map currently installed*/
  1189. int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
  1190. long all_event_masks; /* set of events all people have interest in*/
  1191. long your_event_mask; /* my event mask */
  1192. long do_not_propagate_mask; /* set of events that should not propagate */
  1193. Bool override_redirect; /* boolean value for override-redirect */
  1194. Screen *screen; /* back pointer to correct screen */
  1195. } XWindowAttributes;
  1196. #endif
  1197. CAMLprim value
  1198. ml_XCreateWindow(
  1199. value dpy, value parent,
  1200. value x, value y,
  1201. value width, value height,
  1202. value border_width,
  1203. value depth, value class, value visual,
  1204. value valuemask, value attributes )
  1205. {
  1206. Window win = XCreateWindow(
  1207. Display_val(dpy),
  1208. Window_val(parent),
  1209. Int_val(x),
  1210. Int_val(y),
  1211. UInt_val(width),
  1212. UInt_val(height),
  1213. UInt_val(border_width),
  1214. Int_val(depth),
  1215. window_class_table[Long_val(class)],
  1216. Visual_val(visual),
  1217. winattr_valuemask_val(valuemask),
  1218. XSetWindowAttributes_val(attributes)
  1219. );
  1220. if (!win) caml_failwith("XCreateWindow");
  1221. return Val_Window(win);
  1222. }
  1223. CAMLprim value
  1224. ml_XCreateWindow_bytecode( value * argv, int argn )
  1225. {
  1226. return ml_XCreateWindow( argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
  1227. argv[6], argv[7], argv[8], argv[9], argv[10], argv[11] );
  1228. }
  1229. CAMLprim value
  1230. ml_XResizeWindow( value dpy, value win, value width, value height )
  1231. {
  1232. GET_STATUS XResizeWindow(
  1233. Display_val(dpy),
  1234. Window_val(win),
  1235. UInt_val(width),
  1236. UInt_val(height)
  1237. );
  1238. CHECK_STATUS(XResizeWindow,1);
  1239. return Val_unit;
  1240. }
  1241. CAMLprim value
  1242. ml_XMoveWindow( value dpy, value win, value x, value y )
  1243. {
  1244. GET_STATUS XMoveWindow(
  1245. Display_val(dpy),
  1246. Window_val(win),
  1247. Int_val(x),
  1248. Int_val(y)
  1249. );
  1250. CHECK_STATUS(XMoveWindow,1);
  1251. return Val_unit;
  1252. }
  1253. CAMLprim value
  1254. ml_XMoveResizeWindow( value dpy, value win, value x, value y, value width, value height )
  1255. {
  1256. GET_STATUS XMoveResizeWindow(
  1257. Display_val(dpy),
  1258. Window_val(win),
  1259. Int_val(x),
  1260. Int_val(y),
  1261. UInt_val(width),
  1262. UInt_val(height)
  1263. );
  1264. CHECK_STATUS(XMoveResizeWindow,1);
  1265. return Val_unit;
  1266. }
  1267. CAMLprim value
  1268. ml_XMoveResizeWindow_bytecode( value * argv, int argn )
  1269. {
  1270. return ml_XMoveResizeWindow( argv[0], argv[1], argv[2],
  1271. argv[3], argv[4], argv[5] );
  1272. }
  1273. CAMLprim value
  1274. ml_XLowerWindow( value dpy, value win )
  1275. {
  1276. GET_STATUS XLowerWindow(
  1277. Display_val(dpy),
  1278. Window_val(win) );
  1279. CHECK_STATUS(XLowerWindow,1);
  1280. return Val_unit;
  1281. }
  1282. CAMLprim value
  1283. ml_XRaiseWindow( value dpy, value win )
  1284. {
  1285. GET_STATUS XRaiseWindow(
  1286. Display_val(dpy),
  1287. Window_val(win) );
  1288. CHECK_STATUS(XRaiseWindow,1);
  1289. return Val_unit;
  1290. }
  1291. CAMLprim value
  1292. ml_XStoreName( value dpy, value win, value name )
  1293. {
  1294. GET_STATUS XStoreName(
  1295. Display_val(dpy),
  1296. Window_val(win),
  1297. String_val(name) );
  1298. CHECK_STATUS(XStoreName, 1);
  1299. return Val_unit;
  1300. }
  1301. CAMLprim value
  1302. ml_XFetchName( value dpy, value win )
  1303. {
  1304. CAMLlocal1( ml_window_name );
  1305. char * window_name = NULL;
  1306. //GET_STATUS
  1307. XFetchName(
  1308. Display_val(dpy),
  1309. Window_val(win),
  1310. &window_name
  1311. );
  1312. //CHECK_STATUS(XFetchName,1);
  1313. if (window_name != NULL) {
  1314. ml_window_name = caml_copy_string(window_name);
  1315. XFree(window_name);
  1316. } else {
  1317. caml_failwith("xFetchName");
  1318. }
  1319. return ml_window_name;
  1320. }
  1321. CAMLprim value
  1322. ml_XSelectInput( value dpy, value win, value ml_event_mask )
  1323. {
  1324. long event_mask = Eventmask_val( ml_event_mask );
  1325. GET_STATUS XSelectInput(
  1326. Display_val(dpy),
  1327. Window_val(win),
  1328. event_mask );
  1329. CHECK_STATUS(XSelectInput, 1);
  1330. return Val_unit;
  1331. }
  1332. CAMLprim value
  1333. ml_XMapWindow( value dpy, value win )
  1334. {
  1335. GET_STATUS XMapWindow(
  1336. Display_val(dpy),
  1337. Window_val(win) );
  1338. CHECK_STATUS(XMapWindow, 1);
  1339. return Val_unit;
  1340. }
  1341. CAMLprim value
  1342. ml_XMapSubwindows( value dpy, value win )
  1343. {
  1344. GET_STATUS XMapSubwindows(
  1345. Display_val(dpy),
  1346. Window_val(win) );
  1347. CHECK_STATUS(XMapSubwindows, 1);
  1348. return Val_unit;
  1349. }
  1350. CAMLprim value
  1351. ml_XMapRaised( value dpy, value win )
  1352. {
  1353. //GET_STATUS
  1354. XMapRaised(
  1355. Display_val(dpy),
  1356. Window_val(win) );
  1357. //CHECK_STATUS(XMapRaised, 1);
  1358. return Val_unit;
  1359. }
  1360. CAMLprim value
  1361. ml_XUnmapWindow( value dpy, value win )
  1362. {
  1363. //GET_STATUS
  1364. XUnmapWindow(
  1365. Display_val(dpy),
  1366. Window_val(win) );
  1367. //CHECK_STATUS(XUnmapWindow,1);
  1368. return Val_unit;
  1369. }
  1370. CAMLprim value
  1371. ml_XReparentWindow( value dpy, value win, value parent, value x, value y )
  1372. {
  1373. GET_STATUS XReparentWindow(
  1374. Display_val(dpy),
  1375. Window_val(win),
  1376. Window_val(parent),
  1377. Int_val(x),
  1378. Int_val(y)
  1379. );
  1380. CHECK_STATUS(XReparentWindow,1);
  1381. return Val_unit;
  1382. }
  1383. CAMLprim value
  1384. ml_XChangeSaveSet( value dpy, value win, value change_mode )
  1385. {
  1386. //GET_STATUS
  1387. XChangeSaveSet(
  1388. Display_val(dpy),
  1389. Window_val(win),
  1390. (Int_val(change_mode) ? SetModeDelete : SetModeInsert)
  1391. );
  1392. //CHECK_STATUS(XChangeSaveSet,1);
  1393. return Val_unit;
  1394. }
  1395. CAMLprim value
  1396. ml_XAddToSaveSet( value dpy, value win )
  1397. {
  1398. //GET_STATUS
  1399. XAddToSaveSet(
  1400. Display_val(dpy),
  1401. Window_val(win)
  1402. );
  1403. //CHECK_STATUS(XAddToSaveSet,1);
  1404. return Val_unit;
  1405. }
  1406. CAMLprim value
  1407. ml_XRemoveFromSaveSet( value dpy, value win )
  1408. {
  1409. //GET_STATUS
  1410. XRemoveFromSaveSet(
  1411. Display_val(dpy),
  1412. Window_val(win)
  1413. );
  1414. //CHECK_STATUS(XRemoveFromSaveSet,1);
  1415. return Val_unit;
  1416. }
  1417. CAMLprim value
  1418. ml_XQueryTree( value dpy, value win )
  1419. {
  1420. CAMLparam2( dpy, win );
  1421. CAMLlocal2( ret, children_arr );
  1422. Window root_win, parent_win, *children;
  1423. unsigned int nchildren, i;
  1424. children = NULL;
  1425. Status status = XQueryTree(
  1426. Display_val(dpy),
  1427. Window_val(win),
  1428. &root_win,
  1429. &parent_win,
  1430. &children,
  1431. &nchildren
  1432. );
  1433. if (status != 1) {
  1434. if (children != NULL) XFree(children);
  1435. caml_failwith("xQueryTree");
  1436. }
  1437. children_arr = caml_alloc(nchildren, 0);
  1438. for (i=0; i < nchildren; i++) {
  1439. Store_field( children_arr, i, Val_Window(children[i]) );
  1440. }
  1441. XFree(children);
  1442. ret = caml_alloc(3, 0);
  1443. Store_field( ret, 0, Val_Window(root_win) );
  1444. Store_field( ret, 1, Val_Window(parent_win) );
  1445. Store_field( ret, 2, children_arr );
  1446. CAMLreturn( ret );
  1447. }
  1448. CAMLprim value
  1449. ml_XRestackWindows( value dpy, value ml_wins )
  1450. {
  1451. int nwindows, i;
  1452. Window* windows;
  1453. nwindows = Wosize_val(ml_wins);
  1454. windows = malloc(nwindows * sizeof(Window*));
  1455. for (i=0; i < nwindows; i++) {
  1456. windows[i] = Window_val(Field(ml_wins, i));
  1457. }
  1458. //GET_STATUS
  1459. XRestackWindows(
  1460. Display_val(dpy),
  1461. windows,
  1462. nwindows
  1463. );
  1464. free(windows);
  1465. //CHECK_STATUS(XRestackWindows,1);
  1466. return Val_unit;
  1467. }
  1468. static const int circulateSubwinsDir_table[] = {
  1469. RaiseLowest,
  1470. LowerHighest
  1471. };
  1472. #define CirculateSubwinsDir_val(i) (circulateSubwinsDir_table[Long_val(i)])
  1473. CAMLprim value
  1474. ml_XCirculateSubwindows( value dpy, value win, value dir )
  1475. {
  1476. //GET_STATUS
  1477. XCirculateSubwindows(
  1478. Display_val(dpy),
  1479. Window_val(win),
  1480. CirculateSubwinsDir_val(dir)
  1481. );
  1482. //CHECK_STATUS(XCirculateSubwindows,1);
  1483. return Val_unit;
  1484. }
  1485. CAMLprim value
  1486. ml_XCirculateSubwindowsDown( value dpy, value win )
  1487. {
  1488. //GET_STATUS
  1489. XCirculateSubwindowsDown(
  1490. Display_val(dpy),
  1491. Window_val(win)
  1492. );
  1493. //CHECK_STATUS(XCirculateSubwindowsDown,1);
  1494. return Val_unit;
  1495. }
  1496. CAMLprim value
  1497. ml_XCirculateSubwindowsUp( value dpy, value win )
  1498. {
  1499. //GET_STATUS
  1500. XCirculateSubwindowsUp(
  1501. Display_val(dpy),
  1502. Window_val(win)
  1503. );
  1504. //CHECK_STATUS(XCirculateSubwindowsUp,1);
  1505. return Val_unit;
  1506. }
  1507. CAMLprim value
  1508. ml_XGetWindowProperty_string(
  1509. value dpy,
  1510. value win,
  1511. value property,
  1512. value long_offset,
  1513. value long_length,
  1514. value delete,
  1515. value req_type
  1516. )
  1517. {
  1518. CAMLparam5(dpy, win, property, long_offset, long_length);
  1519. CAMLxparam2(delete, req_type);
  1520. CAMLlocal1(ret);
  1521. Atom actual_type;
  1522. int actual_format;
  1523. unsigned long nitems, bytes_after;
  1524. /*unsigned*/ char* prop;
  1525. (void) XGetWindowProperty(
  1526. Display_val(dpy),
  1527. Window_val(win),
  1528. Atom_val(property),
  1529. Long_val(long_offset),
  1530. Long_val(long_length),
  1531. Bool_val(delete),
  1532. AnyPropertyType, // Atom req_type, TODO
  1533. &actual_type,
  1534. &actual_format,
  1535. &nitems,
  1536. &bytes_after,
  1537. (unsigned char**)&prop
  1538. );
  1539. ret = caml_alloc(5, 0);
  1540. Store_field(ret, 0, Val_Atom(actual_type) );
  1541. Store_field(ret, 1, Val_int(actual_format) );
  1542. Store_field(ret, 2, Val_long(nitems) );
  1543. Store_field(ret, 3, Val_long(bytes_after) );
  1544. Store_field(ret, 4, caml_copy_string(prop) );
  1545. XFree(prop);
  1546. CAMLreturn(ret);
  1547. }
  1548. CAMLprim value
  1549. ml_XGetWindowProperty_string_bytecode( value * argv, int argn )
  1550. {
  1551. return ml_XGetWindowProperty_string( argv[0], argv[1], argv[2],
  1552. argv[3], argv[4], argv[5], argv[6] );
  1553. }
  1554. CAMLprim value
  1555. ml_XGetWindowProperty_window(
  1556. value dpy,
  1557. value win,
  1558. value property,
  1559. value long_offset,
  1560. value long_length,
  1561. value delete,
  1562. value req_type
  1563. )
  1564. {
  1565. CAMLparam5(dpy, win, property, long_offset, long_length);
  1566. CAMLxparam2(delete, req_type);
  1567. CAMLlocal1(ret);
  1568. Atom actual_type;
  1569. int actual_format;
  1570. unsigned long nitems, bytes_after;
  1571. Window *prop;
  1572. (void) XGetWindowProperty(
  1573. Display_val(dpy),
  1574. Window_val(win),
  1575. Atom_val(property),
  1576. Long_val(long_offset),
  1577. Long_val(long_length),
  1578. Bool_val(delete),
  1579. AnyPropertyType, // Atom req_type, TODO
  1580. &actual_type,
  1581. &actual_format,
  1582. &nitems,
  1583. &bytes_after,
  1584. (unsigned char**)&prop
  1585. );
  1586. ret = caml_alloc(5, 0);
  1587. Store_field(ret, 0, Val_Atom(actual_type) );
  1588. Store_field(ret, 1, Val_int(actual_format) );
  1589. Store_field(ret, 2, Val_long(nitems) );
  1590. Store_field(ret, 3, Val_long(bytes_after) );
  1591. Store_field(ret, 4, Val_Window(prop[0]) );
  1592. XFree(prop);
  1593. CAMLreturn(ret);
  1594. }
  1595. CAMLprim value
  1596. ml_XGetWindowProperty_window_bytecode( value * argv, int argn )
  1597. {
  1598. return ml_XGetWindowProperty_window( argv[0], argv[1], argv[2],
  1599. argv[3], argv[4], argv[5], argv[6] );
  1600. }
  1601. /* Managing Installed Colormaps */
  1602. CAMLprim value
  1603. ml_XInstallColormap( value dpy, value colormap )
  1604. {
  1605. //GET_STATUS
  1606. XInstallColormap(
  1607. Display_val(dpy),
  1608. Colormap_val(colormap)
  1609. );
  1610. //CHECK_STATUS(XInstallColormap,1);
  1611. return Val_unit;
  1612. }
  1613. CAMLprim value
  1614. ml_XUninstallColormap( value dpy, value colormap )
  1615. {
  1616. //GET_STATUS
  1617. XUninstallColormap(
  1618. Display_val(dpy),
  1619. Colormap_val(colormap)
  1620. );
  1621. //CHECK_STATUS(XUninstallColormap,1);
  1622. return Val_unit;
  1623. }
  1624. CAMLprim value
  1625. ml_XListInstalledColormaps( value dpy, value win )
  1626. {
  1627. CAMLparam2(dpy, win);
  1628. CAMLlocal1(ret);
  1629. int i, num;
  1630. Colormap *colormaps =
  1631. XListInstalledColormaps(
  1632. Display_val(dpy),
  1633. Window_val(win),
  1634. &num
  1635. );
  1636. ret = caml_alloc(num, 0);
  1637. for (i=0; i<num; ++i) {
  1638. Store_field(ret, i, Val_Colormap(colormaps[i]) );
  1639. }
  1640. XFree(colormaps);
  1641. CAMLreturn(ret);
  1642. }
  1643. CAMLprim value
  1644. ml_XKillClient( value dpy, value resource )
  1645. {
  1646. //GET_STATUS
  1647. XKillClient(
  1648. Display_val(dpy),
  1649. (XID) resource
  1650. );
  1651. //CHECK_STATUS(XKillClient,1);
  1652. return Val_unit;
  1653. }
  1654. /* Threads */
  1655. CAMLprim value
  1656. ml_XInitThreads( value unit )
  1657. {
  1658. GET_STATUS XInitThreads();
  1659. CHECK_STATUS(XInitThreads,1);
  1660. return Val_unit;
  1661. }
  1662. CAMLprim value
  1663. ml_XLockDisplay( value dpy )
  1664. {
  1665. XLockDisplay( Display_val(dpy) );
  1666. return Val_unit;
  1667. }
  1668. CAMLprim value
  1669. ml_XUnlockDisplay( value dpy )
  1670. {
  1671. XUnlockDisplay( Display_val(dpy) );
  1672. return Val_unit;
  1673. }
  1674. CAMLprim value
  1675. ml_XSetWMProtocols( value dpy, value win, value protocols, value count )
  1676. {
  1677. Status status = XSetWMProtocols(
  1678. Display_val(dpy),
  1679. Window_val(win),
  1680. Atom_val_addr(protocols),
  1681. Int_val(count) );
  1682. CHECK_STATUS(XSetWMProtocols, 1);
  1683. return Val_unit;
  1684. }
  1685. CAMLprim value
  1686. ml_XInternAtom( value dpy, value atom_name, value only_if_exists )
  1687. {
  1688. Atom a = XInternAtom(
  1689. Display_val(dpy),
  1690. String_val(atom_name),
  1691. Bool_val(only_if_exists) );
  1692. if (a == None)
  1693. caml_raise_not_found();
  1694. // XInternAtom() can generate BadAlloc and BadValue errors.
  1695. return Val_Atom(a);
  1696. }
  1697. CAMLprim value
  1698. ml_XInternAtoms( value dpy, value ml_names, value only_if_exists )
  1699. {
  1700. CAMLparam3(dpy, ml_names, only_if_exists);
  1701. CAMLlocal1(ret);
  1702. int count, i;
  1703. char** names;
  1704. Atom* atoms_return;
  1705. count = Wosize_val(ml_names);
  1706. atoms_return = malloc(count * sizeof(Atom));
  1707. names = malloc(count * sizeof(char *));
  1708. for (i=0; i<count; ++i) {
  1709. names[i] = String_val(Field(ml_names,i));
  1710. }
  1711. Status st = XInternAtoms(
  1712. Display_val(dpy),
  1713. names,
  1714. count,
  1715. Bool_val(only_if_exists),
  1716. atoms_return
  1717. );
  1718. if (st == 0)
  1719. caml_failwith("xInternAtoms: atoms were not returned for all of the names");
  1720. ret = caml_alloc(count, 0);
  1721. for (i=0; i<count; ++i) {
  1722. Store_field( ret, i, Val_Atom(atoms_return[i]) );
  1723. }
  1724. free(atoms_return);
  1725. free(names);
  1726. CAMLreturn(ret);
  1727. }
  1728. CAMLprim value
  1729. ml_XGetAtomName( value dpy, value atom )
  1730. {
  1731. CAMLparam2(dpy, atom);
  1732. CAMLlocal1(ml_atom_name);
  1733. char * atom_name = XGetAtomName(
  1734. Display_val(dpy),
  1735. Atom_val(atom)
  1736. );
  1737. if (atom_name == NULL)
  1738. caml_failwith("xGetAtomName");
  1739. ml_atom_name = caml_copy_string(atom_name);
  1740. XFree((void *)atom_name);
  1741. CAMLreturn(ml_atom_name);
  1742. }
  1743. /* XSizeHints, from <X11/Xutil.h> */
  1744. CAMLprim value
  1745. ml_alloc_XSizeHints( value unit )
  1746. {
  1747. CAMLparam0();
  1748. CAMLlocal1(size_hints);
  1749. alloc_XSizeHints(size_hints);
  1750. memset(XSizeHints_val(size_hints), 0, sizeof(XSizeHints));
  1751. CAMLreturn(size_hints);
  1752. }
  1753. CAMLprim value
  1754. ml_XSizeHints_set_USPosition( value size_hints, value _x, value _y )
  1755. {
  1756. XSizeHints *sh

Large files files are truncated, but you can click here to view the full file