Discussion:
[Larceny-users] XQueryTree
Eduardo Cavazos
2009-03-12 00:33:51 UTC
Permalink
Hello,

XQueryTree is a function from xlib:

extern Status XQueryTree(
Display* /* display */,
Window /* w */,
Window* /* root_return */,
Window* /* parent_return */,
Window** /* children_return */,
unsigned int* /* nchildren_return */
);

This is how I'm pulling it into Larceny (using a 'c-function' macro I'm
using for cross-Scheme compatability):

(c-function Status XQueryTree (void* ulong boxed boxed boxed boxed))

Here's an example of how I'm able to call it:

(define root-return (make-bytevector 4))
(define parent-return (make-bytevector 4))
(define children-return (make-bytevector 4))
(define nchildren-return (make-bytevector 4))

(XQueryTree dpy root
root-return
parent-return
children-return
nchildren-return)

Getting at root-return, parent-return, and nchildren-return is simple
since they're passed in as bytevectors. So for example this returns the
root window:

(bytevector-u32-native-ref root-return 0)

So now for 'children-return'. Ideally, we'd end up with the array of
children as a Scheme bytevector.

If you do:

(bytevector-u32-native-ref children-return 0)

you get back an integer which is the pointer to the memory that xlib
allocated for us (may be freed with XFree).

The best I was able to come up with for accessing elements of that
memory is:

(%peek32u (+ addr (* 0 4))) ; first element

(%peek32u (+ addr (* 1 4))) ; second element

(%peek32u (+ addr (* 2 4))) ; third element

...

My question is, is this the best way given the Larceny FFI?

Another question; is there a way to create a Scheme bytevector given an
address of some C array and the size of the array?

For comparison, Ypsilon offers 'make-bytevector-mapping':

http://www.littlewing.co.jp/ypsilon/doc-draft/libref.ypsilon.ffi.html#make-bytevector-mapping

Thanks for any suggestions you might have!

Even if something like 'make-bytevector-mapping' doesn't exist for
Larceny, I should be able to cook something up that will copy the
elements into a fresh bytearray. That would be good anyway since then
the memory xlib allocates can be freed via XFree.

Ed
Eduardo Cavazos
2009-03-13 02:59:30 UTC
Permalink
Post by Eduardo Cavazos
extern Status XQueryTree(
Display* /* display */,
Window /* w */,
Window* /* root_return */,
Window* /* parent_return */,
Window** /* children_return */,
unsigned int* /* nchildren_return */
);
This is how I'm pulling it into Larceny (using a 'c-function' macro I'm
(c-function Status XQueryTree (void* ulong boxed boxed boxed boxed))
(define root-return (make-bytevector 4))
(define parent-return (make-bytevector 4))
(define children-return (make-bytevector 4))
(define nchildren-return (make-bytevector 4))
(XQueryTree dpy root
root-return
parent-return
children-return
nchildren-return)
Getting at root-return, parent-return, and nchildren-return is simple
since they're passed in as bytevectors. So for example this returns the
(bytevector-u32-native-ref root-return 0)
So now for 'children-return'. Ideally, we'd end up with the array of
children as a Scheme bytevector.
(bytevector-u32-native-ref children-return 0)
you get back an integer which is the pointer to the memory that xlib
allocated for us (may be freed with XFree).
The best I was able to come up with for accessing elements of that
(%peek32u (+ addr (* 0 4))) ; first element
(%peek32u (+ addr (* 1 4))) ; second element
(%peek32u (+ addr (* 2 4))) ; third element
...
My question is, is this the best way given the Larceny FFI?
Another question; is there a way to create a Scheme bytevector given an
address of some C array and the size of the array?
http://www.littlewing.co.jp/ypsilon/doc-draft/libref.ypsilon.ffi.html#make-bytevector-mapping
Thanks for any suggestions you might have!
Even if something like 'make-bytevector-mapping' doesn't exist for
Larceny, I should be able to cook something up that will copy the
elements into a fresh bytearray. That would be good anyway since then
the memory xlib allocates can be freed via XFree.
This is how I ended up wrapping XQueryTree in Larceny. The solutions for
Ypsilon and Chicken are very similar. Comments welcome!

(define (x-query-tree dpy win)

(let ((root-return (make-bytevector 4))
(parent-return (make-bytevector 4))
(children-return (make-bytevector sizeof:pointer))
(nchildren-return (make-bytevector 4)))

(XQueryTree dpy
win
root-return
parent-return
children-return
nchildren-return)

(let ((root (bytevector-u32-native-ref root-return 0))
(parent (bytevector-u32-native-ref parent-return 0))
(children-addr (%get-pointer children-return 0))
(nchildren (bytevector-u32-native-ref nchildren-return 0)))

(let ((children (make-vector nchildren)))

(let loop ((i 0))

(cond ((>= i nchildren)
(XFree ((record-constructor void*-rt) children-addr))
children)
(else
(vector-set! children i (%peek32u (+ children-addr (*
i 4))))
(loop (+ i 1)))))

(list root parent children)))))

Loading...