Re: gtk2 news



Sorry to take so long to respond, and to get some code up. I'm having
hardware issues with my web server at home, so I wasn't able to get the
source up there.  I hope to have it fixed tonight.

On Tue, 2002-09-10 at 06:17, Christian Borup wrote: 

There is really no difference between Inline::C and XS except for
automatic compilation.

Is it better, then, to use Inline::C?  I've never done more than 
play with it a little.  My understanding was that it wasn't as 
scalable.

* Libraries and header files:

The libraries used to compile C programs using Gtk2 are the ones
we want to wrap with Perl modules.  While certain binutils tools
like nm
can tell us the names of functions in the library directly, we need,
I believe, the header files to get the exact prototype.

On systems with pkg-config installed, getting the list of both
libraries and header files for gtk2 is easy:

  pkg-config gtk+-2.0 --cflags --libs

The libraries include gtk, gdk, pango, atk, glib, and a few
others upon which gtk is dependent.

* After wrapping the libraries:

While basic wrappers for the libraries would be nice,
all we'd be left with is perl code like:

    use libgtk;
    my $winptr = libgtk::gtk_window_new();
    libgtk::gtk_window_set_title($winptr,"My Title");


This would be silly. 
XS will do all the wrapping for you.
You just give the XS compiler a couple of hints, and the methods will
be
placed in the right packages.

The hints in this case would be:
MODULE = Gtk::Window    PACKAGE = Gtk::Window   PREFIX = gtk_window_

Using PREFIX would allow calls to things like Gtk::Window->new to go
straight to whatever is defined in the .xs file.  The question is
whether the additional preprocessing of perl parameters should happen on
the C-side or the Perl-side.

My initial take was to do it on the perl side for simplicity, and then,
as part of refactoring, move the complex part of the parameter
translation into the xs code itself.  It's easier to tweak and debug on
the perl side too.

This makes gtk_window_new() become Gtk::Window->new() in Perl.

The previous wrappers constructed perl classes (packages)
for the various types available in Gtk, and made methods
in the packages which called the real c functions with 
shorter names.  Once the above perl code is possible to execute,
going to this next level should be simple.  All GtkWidget
objects are derived from GObject, and all GObjects have
a GType, for which there are functions in to get 
inheritance information.  In a dynamically typed language
like perl we could pre-build the packages as modules,
or build them on-the-fly at run-time.

As far as I can tell there is no way to introspect methods (please
correct me if I'm wrong - I'd like to be this case).

Unfortunately, I think you're right about introspecting methods. 
I was planning to use the introspection just to figure-out inheritance
and interfaces for each known GType.  Connecting methods with classes
will require matching function prefixes to class names, regardless
of whether the resulting mapping yields a PREFIX in .xs, or is used
by AUTOLOAD, or by an automated package code generator outside of
AUTOLOAD.


The methods which wrap the c-function-equivalents will have
to translate pointers returned from the c library into perl
objects of the correct type (the old version seemed to use
a hashref with a single key/value (_gtk => pointer_value).

Again XS will do this translation for you. This is what typemaps are
for.

When the C function returns a pointer (say with a value of 1234) to a
GtkButton, XS will make something like 

bless({_gtk => 1234},'GtkButton')

And more importantly, after a perl object is created to wrap the
pointer, will it always return that perl object for that perl pointer?

It looks like the old code has a bunch of these for each widget:

#define newSVGtkVBox(x) newSVGtkObjectRef(GTK_OBJECT(x),0)

The newSVGtkObjecRef presumably handles the turning of a pointer
into the blessed hashref.  This is certainly worth digging into.


Using a hashref is actually a pretty neat idea. If the plain C pointer
was used the object would be opaque to the Perl side of things. So
subclasses would have nowhere to put object private data (I do know
about set_data/get_data - but those present other problems).


A great idea, but not mine.  It was in the last set of bindings.

All the bindings I've looked at use .defs file for generating their
stubs. This is not a bad idea as header parsing (which is rather error
prone) and the following handcleaning of the results, can be done just
once.

1. Extend the script to write the actual xs code for each function.

Such a script allready exists in the old binding.
Shouldn't need that many changes.

I noticed the gendefs.pl script, but I found no documentation, and I'm
not certain how the results are parsed.  The parser I wrote writes with
Data::Dumper so I don't have to parse it (perl does it with eval) to
write
scripts which can use the function definitions. That's not to say, that 
the defs method is not better in some way, but that it took me less time
to 
write-around the problem than it seemed it would take to figure it out.


2. Test to make sure we can build the basic perl wrappers for the
libs.
   (like Goran's code but without having to hand-write gtkperl_*
    wrappers)

3. Produce a module which will be directly "used" by the programmer.
   It should:
     . "use" the lib* modules.
     . query the GType system and build a perl inheritance tree.
     . each package generated should know its function prefix
     . AUTOLOAD should create class methods which are wrappers
       for underlyin c functions on the fly.

This is how the python binding do it - at least they did for gtk+ 1.
In Perl it doesn't make sense as XS will do it for you (better and
faster).

That may be true.  I'm shooting for functionality first, and then
tweak the module generation for more speed.

I'll post a link as soon as I have some stuff up.

Scott

========================================
Scott Smith <ssmith watson wustl edu>
Informatics
Genome Sequencing Center
Washington University School of Medicine





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]