Status:
I have now been able to compile-ffi the following on my Mac. I’m sure
bugs remain.
(define-ffi-module (cairo cairo)
#:pkg-config "cairo"
#:include '(“cairo.h" "cairo-pdf.h" "cairo-svg.h")
;; the following are bent pipe to scm-module
#:export (make-cairo-unit-matrix)
)
(define (make-cairo-unit-matrix)
(make-cairo_matrix_t #(1.0 0.0 0.0 1.0 0.0 0.0)))
I convert the above “cairo.ffi” file to “cairo.scm” using the following
command
mwette$ guild compile-ffi cairo/cairo.ffi
The above generates 397 FFI declarations in cairo.scm, a file which is
about 6000 lines long, compared to the original “cairo.ffi” which is
less than 10 lines long.
Some generated code:
;; typedef struct _cairo_device cairo_device_t;
(define-fh-pointer-type cairo_device_t*)
;; union _cairo_path_data_t {
;; struct {
;; cairo_path_data_type_t type;
;; int length;
;; } header;
;; struct {
;; double x, y;
;; } point;
;; };
(define cairo_path_data_t-desc
(bs:union
(list `(header
,(bs:struct
(list `(type ,cairo_path_data_type_t-desc)
`(length ,int))))
`(point ,(bs:struct (list `(y ,double) `(x ,double)))))))
(export cairo_path_data_t-desc)
(define-fh-bytestructure-type/p cairo_path_data_t
cairo_path_data_t-desc)
(define union-_cairo_path_data_t cairo_path_data_t)
;; typedef enum _cairo_path_data_type {
;; CAIRO_PATH_MOVE_TO,
;; CAIRO_PATH_LINE_TO,
;; CAIRO_PATH_CURVE_TO,
;; CAIRO_PATH_CLOSE_PATH,
;; } cairo_path_data_type_t;
(define-fh-enum-type cairo_path_data_type_t
'((CAIRO_PATH_MOVE_TO . 0)
(CAIRO_PATH_LINE_TO . 1)
(CAIRO_PATH_CURVE_TO . 2)
(CAIRO_PATH_CLOSE_PATH . 3))
)
;; typedef void (*cairo_destroy_func_t)(void *data);
(define (wrap-cairo_destroy_func_t proc) ;; => pointer
(ffi:procedure->pointer ffi:void proc (list '*))
)
(export wrap-cairo_destroy_func_t)
;; cairo_status_t cairo_device_set_user_data(cairo_device_t *device,
const
;; cairo_user_data_key_t *key, void *user_data,
cairo_destroy_func_t
;; destroy);
(define cairo_device_set_user_data
(let ((~f (ffi:pointer->procedure
ffi:int
(lib-func "cairo_device_set_user_data")
(list '* '* '* '*))))
(lambda (device key user_data destroy)
(let ((~device (unwrap-cairo_device_t* device))
(~key (unwrap-cairo_user_data_key_t* key))
(~user_data (unwrap~pointer user_data))
(~destroy (unwrap-cairo_destroy_func_t destroy)))
(wrap-cairo_status_t
(~f ~device ~key ~user_data ~destroy))))))
(export cairo_device_set_user_data)