Hi Mikael,

This is the solution that seems to work, wrapping it. 

(define cairo-create-surface
  (c-lambda (unsigned-char* int int int int)
            cairo-surface-t* 
            "
            cairo_format_t format;
            switch (___arg2) {
              case -1: format = CAIRO_FORMAT_INVALID; break;
              case 0: format = CAIRO_FORMAT_ARGB32; break;
              case 1: format = CAIRO_FORMAT_RGB24; break;
              case 2: format = CAIRO_FORMAT_A8; break;
              case 3: format = CAIRO_FORMAT_A1; break;
              case 4: format = CAIRO_FORMAT_RGB16_565; break;
              default: format = CAIRO_FORMAT_RGB24; break;
            }
            ___result = cairo_image_surface_create_for_data(___arg1, format, ___arg3, ___arg4, ___arg5);
            "))



It is rather inconvenient, though. I think there should be a better way. Also, this crashes Gambit, just per se:
(define CAIRO_FORMAT_RGB24 ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")))


Best regards,

Álvaro




2012/2/5 Mikael <mikael.rcv@gmail.com>
Hi, do something like this: In cairo-image-surface-create-for-data, do printf("Wnt %i got %i\n",CAIRO_FORMAT_RGB24,___arg2); and rerun your previous tests, do they make more sense now? In case the both values printed are the same, your sigsegvcomes from elsewhere. Brgds

2012/2/5 Álvaro Castro-Castilla <alvaro.castro.castilla@gmail.com>
hi Mikael,

Thanks for your response.
Unfortunately, your solution also breaks. Actually, it is doing more or less the same I did. What you say should be used like this, right?:
(image-surface (cairo-image-surface-create-for-data
                         (SDL::surface-pixels sdl-surface)
                         (CAIRO_FORMAT_RGB24)
                         maxx
                         maxy
                         (SDL::screen-pitch sdl-surface)))

In case you have (define CAIRO_FORMAT_RGB24 ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;"))  already, you should type only  CAIRO_FORMAT_RGB24 here not  (CAIRO_FORMAT_RGB24).
 
What I was proposing just decides the output at runtime (the argument is an int, but passed to a function that converts it into a enum -should convert-):
(image-surface (cairo-image-surface-create-for-data
                         (SDL::surface-pixels sdl-surface)
                         (cairo-format CAIRO_FORMAT_RGB24)
                         maxx
                         maxy
                         (SDL::screen-pitch sdl-surface)))

In the Scheme world I think there should only be the need for one representation/form of the C constant.

But the result is the same: segfault. Using your first solution (returning an int) causes the same problem I got at the beginning: (cairo#cairo-image-surface-create-for-data '#<|unsigned char*| #16 0x7f584104c000> 0 500 500 2000)

To make this one spin, just declare the second argument of this procedure as an int also. Does it work?
 

Thanks for your help.

Best regards



On Sun, Feb 5, 2012 at 6:35 PM, Mikael <mikael.rcv@gmail.com> wrote:
If those are int consts from the C header files of the lib, then import them as is fromt here (define CAIRO_FORMAT_ARGB32 ((c-lambda () int "___result = CAIRO_FORMAT_ARGB32;")) etc. , and any arguments that need them declare as int too.

If they're C enums, maybe you want another datatype declaration of them than int - though I suppose int ought to be generally viable for that too.

The exception in your example below is not so strange, as the second arg is an int while the procedure is declared as cairo-format-t. For it to work, I suppose define CAIRO_FORMAT_RGB24 to ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")) . Works?

2012/2/5 Álvaro Castro-Castilla <alvaro.castro.castilla@gmail.com>
Hi,

I'm using my ffi cairo bindings, that worked fine in the past. However now that I'm using Gambit compiled with C++ support it stopped working.




I got this error:

*** ERROR IN main-sdl#main, "main-sdl.scm"@19.24 -- (Argument 2) Can't convert to C type
(cairo#cairo-image-surface-create-for-data '#<|unsigned char*| #16 0x7f33ba191000> 1 500 500 2000)

On the ffi side, things are declared like this:

(c-define-type cairo-format-t "cairo_format_t")
(define CAIRO_FORMAT_ARGB32 0)
(define CAIRO_FORMAT_RGB24 1)
(define CAIRO_FORMAT_A8 2)
(define CAIRO_FORMAT_A1 3)
(define CAIRO_FORMAT_RGB16_565 4)
(define cairo-image-surface-create-for-data (c-lambda (unsigned-char* cairo-format-t int int int) cairo-surface-t* "cairo_image_surface_create_for_data"))

And used like this:

(cairo-image-surface-create-for-data
                         (SDL::surface-pixels sdl-surface)
                         CAIRO_FORMAT_RGB24
                         maxx
                         maxy
                         (SDL::screen-pitch sdl-surface))

I've tried with this idea:

(define cairo-format
  (c-lambda (int) cairo-format-t
            "
            switch (___arg1) {
              case 0: ___result = CAIRO_FORMAT_ARGB32; break;
              case 1: ___result = CAIRO_FORMAT_RGB24; break; // and so on...
            }
            "))

And then calling on the Scheme side "(cairo-format CAIRO_FORMAT_RGB24)" instead of just using the int directly, but it segfaults.


How should I really handle enums properly?



Best regards,


_______________________________________________
Gambit-list mailing list
Gambit-list@iro.umontreal.ca
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list