[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