[Larceny-users] XQueryTree
Eduardo Cavazos
wayo.cavazos at gmail.com
Thu Mar 12 22:59:30 EDT 2009
Eduardo Cavazos wrote:
> 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.
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)))))
More information about the Larceny-users
mailing list