Discussion:
[Larceny-users] preliminary xlib bindings for Larceny
Eduardo Cavazos
2009-03-01 02:52:31 UTC
Permalink
Hello,

http://proteus.freeshell.org/_xlib-larceny-a.sch

The coverage of the api is near complete, but the typedefs need to be
corrected. I.e. a bunch are simply "void*" which is incorrect. Some
should be aliased to "bytevector" (Larceny's boxed).

Note that the binding code itself is "Scheme agnostic", relying on
macros at the head to work with Larceny's names. So hopefully others can
reuse these.

Anywho, they're good enough to run the test program below.

Ed

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(load "/src/larceny_src/lib/xlib.fasl")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define dpy (XOpenDisplay #f))

(define root (XDefaultRootWindow dpy))

(define win (XCreateSimpleWindow dpy root 100 100 200 200 0 0 0))

(XMapWindow dpy win)

(XFlush dpy)

(XSelectInput dpy win (bitwise-ior ExposureMask ButtonPressMask))

(define ev (make-XEvent))

(let ((root-return (make-bytevector 4))
(child-return (make-bytevector 4))
(root-x-return (make-bytevector 4))
(root-y-return (make-bytevector 4))
(win-x-return (make-bytevector 4))
(win-y-return (make-bytevector 4))
(mask-return (make-bytevector 4)))

(let loop ()

(XNextEvent dpy ev)

(display (XAnyEvent-type ev))
(newline)

(XQueryPointer dpy win root-return child-return
root-x-return root-y-return
win-x-return win-y-return
mask-return)

(display (list (bytevector-u32-native-ref win-x-return 0)
(bytevector-u32-native-ref win-y-return 0)))
(newline)

(loop)))
Felix Klock
2009-03-03 19:16:42 UTC
Permalink
Ed-
Post by Eduardo Cavazos
Anywho, they're good enough to run the test program below.
Fantastic. I was able to run your test program on my Mac OS X laptop
after I changed the X11 library code path to refer to
(foreign-file "/usr/X11R6/lib/libX11.dylib")

I may play around with the interface a bit more; for example, it might
be convenient for XQueryResult to return multiple values. Or maybe
I'll leave that alone.

Thanks for sharing this with us!

-Felix
Eduardo Cavazos
2009-03-03 19:44:56 UTC
Permalink
Post by Felix Klock
Post by Eduardo Cavazos
Anywho, they're good enough to run the test program below.
Fantastic. I was able to run your test program on my Mac OS X laptop
after I changed the X11 library code path to refer to
(foreign-file "/usr/X11R6/lib/libX11.dylib")
Excellent! Thanks for testing it!

I've converted the code into an R6RS library for Ypsilon:

http://proteus.freeshell.org/xlib.sls

Yoshikatsu Fujita (Ypsilon implementor) provided this compat file:

http://proteus.freeshell.org/xlib-compat.sls

So hopefully a similar approach can be taken for Larceny. I.e. the
'xlib.sls' body can remain the same accross implementations. I say
"body" because of course the imports will vary.
Post by Felix Klock
I may play around with the interface a bit more; for example, it might
be convenient for XQueryResult to return multiple values. Or maybe I'll
leave that alone.
Feel free, but I have a suggestion. This applies to our handling of
OpenGL api's as well.

When it comes to interfacing to C libraries, I recommend this general
approach. Make a library which is a one-to-one mapping onto the C
library. This library is helpful for folks who know the C library and
need to "naively" port some C code to Scheme for their pointy haired
manager (or advisor...).

Next, layer a library on top of that which provides an idiomatic
interface to the library.

Do not mix the two steps. :-)

Just my advice.

For an example, take a look at how Jazz Scheme provides it's OpenGL library.

The library 'jazz.graphic.opengl.foreign.gl' has definitions like this:

(define glClearColor (c-function (GLclampf GLclampf GLclampf GLclampf)
void "glClearColor"))

And the idiomatic interface is in 'jazz.graphic.opengl' which provies:

(definition (gl-clear-color red green blue alpha)
(with-gl-error 'gl-clear-color
(function ()
(glClearColor red green blue alpha))))

I'm also involved with the Factor programming language project. This is
general strategy we take there also.

So in other words, I'm all for making a "scheme-ish" interface to Xlib.
But let's share a common substrate across all the implementations and
build the idiomatic library on top (which can also be shared). Same for
OpenGL.

So for example, for Larceny's case I'd offer a (opengl ffi) library
which is the low level one ported from Ypsilon. Then layer your
high-level one on top of that and call is (opengl). That's where we
stick all the nice combinators and macros to make opengl more convenient
to use. Same for xlib, i.e. (xlib ffi) and (xlib).

Ed
Felix Klock
2009-03-03 22:22:36 UTC
Permalink
Ed (cc'ing larceny-users)-
Post by Eduardo Cavazos
Post by Felix Klock
I may play around with the interface a bit more; for example, it
might be convenient for XQueryResult to return multiple values. Or
maybe I'll leave that alone.
Feel free, but I have a suggestion. This applies to our handling of
OpenGL api's as well.
When it comes to interfacing to C libraries, I recommend this general
approach. Make a library which is a one-to-one mapping onto the C
library. This library is helpful for folks who know the C library and
need to "naively" port some C code to Scheme for their pointy haired
manager (or advisor...).
Next, layer a library on top of that which provides an idiomatic
interface to the library.
Do not mix the two steps. :-)
Just my advice.
But good advice. It is often a good strategy to follow.

(A possible exception I can think of are times when a Scheme library
designer wants to try to wall off the C interface so that the Scheme
library can enforce library internal invariants that could be broken
if the underlying C code were exposed. But I don't think we're doing
anything so clever in the cases you are discussing here.)

-Felix

Loading...