On Sat, 2008-03-15 at 14:23 +0100, Jörn Reder wrote: > > It doesn't use GObject to implement its own objects, so it won't be > > completely fool-proof to write bindings. It's still not really hard, > > and you don't need that much C experience. So just give it a try. Look > > at other bindings. Read some things about Perl's extension language XS. > > Ask questions on this list. > > Ok, so I did and so I'll do ;)
Great! > I wrote a first version binding the elementary stuff, so at least the > test suite produces a black OSD rectangle (wow, I'm a hero :). For now > you can download this well undocumented version here: > > http://www.exit1.org/packages/X11-Aosd/X11-Aosd-0.01.tar.gz > > (any comments are welcome how to do things better) OK, some comments: * Makefile.PL: ExtUtils::Depends allows to specify other ExtUtils::Depens-using modules as dependencies. get_makefile_vars() will then set everything up correctly. So, do: my $package = ExtUtils::Depends->new('X11::Aosd', 'Cairo', 'Gtk2'); * Aosd.xs - I'm surprised to see no PREFIX in the MODULE line. That's usually needed so xsubpp knows how to form the method names. - You expose aosd_destroy. Try to avoid binding memory management related functions. In this case, you can automate releasing the object by writing a DESTROY xsub which calls aosd_destroy: void DESTROY (Aosd *aosd) CODE: aosd_destroy (aosd); DESTROY is automatically called by perl when a variable goes out of scope. - You use newSVnv to convert integers to SVs. newSVnv is for floating point numbers. Use newSViv for signed integers. > But in this state it's quite unusable and I'd appreciate some help. Next > thing is to add the Cairo stuff, which is realized using a callback in > libaosd: > > The callback: > > typedef void (*AosdRenderer)(cairo_t* cr, void* user_data); > > Passing it to the Aosd object: > > void aosd_set_renderer(Aosd* aosd, AosdRenderer renderer, void* user_data); > > My questions are: how do I create such a callback function? How do I > reference to the Cairo Perl objects? Is it just adding a T_PTROBJ entry > for cairo_t in the typemap and passing a Cairo Perl object? When you tell EU::Depends that Cairo is a dependency, you get access to Cairo's typemaps. So cairo_t* is handled automatically in normal methods. Unfortunately, callbacks can't be handled automatically yet. You need to write a C function that has the specified signature. You pass a reference to this C function to aosd_set_renderer. When aosd then invokes the callback, your C function is called. Now the C function needs to invoke a Perl callback somehow. To do that, you put a function and a user data scalar into a struct and pass this struct to aosd_set_renderer as user_data. Your C function receives this struct as the second argument, so you unpack it and use perl's API to invoke the function scalar. To make things easier, you should depend on Gtk2 and thus on Glib. Above the MODULE line, do this: #include <gperl.h> #include <cairo-perl.h> static void perl_aosd_renderer (cairo_t *cr, void *user_data) { GPerlCallback *callback = user_data; dSP; ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2); PUSHs (sv_2mortal (newSVCairoContext (cr))); PUSHs (sv_2mortal (newSVsv (callback->data))); PUTBACK; call_sv (callback->func, G_DISCARD); FREETMPS; LEAVE; } And somewhere below the MODULE line, add this: void aosd_set_renderer (Aosd *aosd, SV *func, SV *data=NULL) PREINIT: CPerlCallback *callback; CODE: callback = gperl_callback_new (func, data, 0, NULL, 0); aosd_set_renderer (aosd, perl_aosd_renderer, callback); Unfortunately, aosd doesn't provide destruction notification here, so the memory used for callback will never be released. The code is untested, so you might have to apply a compilation fix here or there. -- Bye, -Torsten _______________________________________________ gtk-perl-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/gtk-perl-list
