.defs Issues From Java-Gnome



Hi there. I'm one of the developers working on the Java-Gnome project (see
<http://java-gnome.sourceforge.net/> for details if you are unfamiliar with
it). 

I sent a note (attached below, mostly for historical interest) a couple
days ago, and it seems to have gotten lost in "moderation purgatory," so I
took extreme measures, and joined the list so I could post directly.

Right now, I'm the primary developer of the .defs file processing code for
Java-Gnome, and I wanted to let you know about some issues we've had. Since
writing the original note, I did some spelunking through the archives and
found discussions from January and February of this year about redoing the
format for the .defs files, but I was unable to find anything after that,
so I don't really know where things currently stand.

That being said, I wanted to share with you some of the problems we've had
dealing with the current .defs format. (If these concerns have already been
addressed with the new format, then that's great, and I apologize for
wasting your time.)

* Some enums and flags types have "holes" or are otherwise not the obvious
  simple increasing sequence from 0 (or 1 << 0).

The Java code for an enum/flags type ends up being a class which declares
static variables to hold each of the enum/flags constants. For example
(simplifying somewhat for the sake of explanation):

    public class GtkAccelFlags
    {
        static final public int VISIBLE = 1 << 0;
        static final public int SIGNAL_VISIBLE = 1 << 1;
        static final public int LOCKED = 1 << 2;
    }

Right now, if the underlying C type is declared in anything but the same
order as declared in Scheme or if the C type assigns values in something
other than the typical order, then we will get messed up. Since we *must*
be able to have these as manifest constants in Java (to support switch
statements and the like), right now, what I will be forced to do is grovel
over the actual C headers to derive these values, which will be a big pain
in the ass, and seems counter to the whole .defs idea anyway.

* There are inheritence relationships with some things currently classified
  as "boxed types".

I'm thinking in particular of the GDK types GdkDrawable, GdkBitmap,
GdkPixmap, and GdkWindow. There are C-level declarations that make it
look like there should be an inheritence relationship where GdkDrawable
is the superclass of the other three, but this isn't expressable in
the original .defs format. (Java-Gnome has our own extension at this
point, which is covered in the original note, below, but it may not
be applicable now.)

The upshot of this is that it seems that the boxed vs. object distinction
is somewhat dubious.

* We need to deal with read-write structs. 

There are structs like GtkItemFactoryEntry which we need to be usable from
Java. Right now, it looks like (fields ...) forms are meant to imply that
the fields are read-only, so we'd need an extension that allowed one to
declare read-write fields. (We have an extension that supports just that.
Again, given the evolution of the format, it may not be applicable
anymore.)

* Bad constructor return types.

There seem to be a proliferation of declarations like this:

    GtkWidget* gtk_window_new (GtkWindowType type);

That is, the declared return type from a constructor isn't actually the
most-specific type that's returned. Right now there are a few heuristics
used by our processor to determine what constitutes a constructor. In this
case, we use the fact that the name ends with "_new" as the determining
factor and then spit out a warning saying that the return type doesn't
match. However, there are cases of constructors (mostly in Gnome, I think)
that don't have names that fall into any obvious heuristic. In those cases,
we rely on the return type, and in fact have to change the .defs file to
make the processor recognize a constructor as such.

* Argc/argv issues.

Java main()s don't get the program name in argv[0], so in order to make
Gtk.init() (or Gnome.init()) do something reasonable from the Java
perspective, we have to secretly insert a zero-th element to the argv array
on its way into GTK. (And, not that it's your issue per se, but it looks to
me like the Gnome init code assumes that argv[0] can't be freed.) We
currently define two special Scheme types, "argvec" and "argcnt" to handle
the mechanism. (For example, argcnt is just like "int" except that it gets
incremented by 1 on its way to GTK.)

* Lots of missing definitions.

I think we've probably had to double or maybe even triple the size of
the .defs files compared to the ones found in the 1.2.8 distribution.

* Function pointers aren't good enough.

There's no such thing as a function pointer, per se, in Java. The closest
one gets is an interface with a single method. However, there's no easy way
to translate that into a function pointer at the lower level. I noticed
some rumblings on the list about implementing closures. If one could in
fact create a closure (either generate a trampoline or use a special type)
that were usable wherever function pointers are currently used, then life
would be much happier up in Java Land. (Okay, so this isn't really a defs
issue, but I thought it was worth mentioning.)

Thanks for listening, and I look forward to your responses. Since I'm set
up to receive this list in digest form, if you want a quick(er) response,
please reply to me directly.

Take care,

-dan

##########

Hi there. I'm one of the developers working on the Java-Gnome project (see
<http://java-gnome.sourceforge.net/> for details if you are unfamiliar with
it). We are using the .defs (currently from gtk+-1.2.8) files as the basis
for automatically generating wrapper classes, but we are also attempting to
augment the .defs files to make them a more accurate reflection of the full
GTK API. I have recently run into a bit of a situation having to do with
how some stuff is defined at the GDK layer.

I found this tidbit in the GDK docs[*]:

    struct GdkPixmap

    An opaque structure representing an offscreen drawable. Pointers to
    structures of type GdkPixmap, GdkBitmap, and GdkWindow, can often be
    used interchangeably. The type GdkDrawable refers generically to any of
    these types.

What this says to me is that, to a first approximation, these things should
be defined like this:

    (define-object GdkDrawable ())
    (define-object GdkBitmap (GdkDrawable))
    (define-object GdkPixmap (GdkDrawable))
    (define-object GdkWindow (GdkDrawable))

where the empty inheritence would mean to not inherit from *anything*
in-model, including, in particular, GtkObject.

The GDK API seems to be pretty consistent with this supposition. In
particular, there are lots of functions declared to take GdkDrawable which
should work with any of these types, most notably the gdk_draw_* functions,
such as:

    void gdk_draw_point (GdkDrawable *drawable,
                         GdkGC *gc,
                         gint x,
                         gint y);

    void gdk_draw_line (GdkDrawable *drawable,
                        GdkGC *gc,
                        gint x1,
                        gint y1,
                        gint x2,
                        gint y2);

I'd very much like it if these could be defined in a .defs file in the
obvious way and then be usable with the GdkDrawable "subclasses":

    (define-func gdk_draw_point
      none
      ((GdkDrawable drawable)
       (GdkGC gc)
       (int x)
       (int y)))

However, there is then the issue of what to do with the ref/unref functions
declared as part of the (define-boxed) form, which is currently used
to define object-like things at the GDK layer:

    (define-boxed GdkWindow
      gdk_window_ref
      gdk_window_unref)

(Right now, the gtk-boxed.defs file doesn't even mention GdkBitmap,
GdkPixmap, or GdkDrawable at all, and in the Java-Gnome additions to the
file, we typically say GdkWindow even in cases that mandate a GdkPixmap,
etc.) Clearly, I don't want to lose the annotation about how to properly
refcount, but at the same time, I really want the typechecking (at the Java
layer) to know that it's okay to pass a GdkWindow to something declared to
take a GdkDrawable.

Within the Java-Gnome group, I had previously made a suggestion, for other
reasons actually, to compatibly extend the syntax of (define-object ...)
(in particular, to support defining read-write structs for things like
GtkItemFactoryEntry). It looks like an extension may be warranted for this
case, as well. I believe, if we could put the following in a .defs file, it
would fairly accurately describe this particular slice of the API:

    (define-object GdkDrawable ())

    (define-object GdkBitmap (GdkDrawable)
      (copy gdk_bitmap_ref)
      (free gdk_bitmap_unref))

    (define-object GdkPixmap (GdkDrawable)
      (copy gdk_pixmap_ref)
      (free gdk_pixmap_unref))

    (define-object GdkWindow (GdkDrawable)
      (copy gdk_window_ref)
      (free gdk_window_unref))

("copy" and "free" instead of "ref" and "unref" because these annotations
would also be used for non-refcounted structs, and the "copy" operation
really would perform a copy, etc.)

One of the Java-Gnome mandates is to stay as compatible as possible with
the original .defs files, but I can't see how to accurately define the
above without at least *some* syntactic tweak, and this one seemed the most
innocuous, and maximally in-line with the current syntax, to me. (You
wouldn't have to specify the extra attributes, so the old forms would
remain syntactically valid and have the same semantics.) So, I was hoping
to convince (the collective) you that this change would be a Good Thing and
perhaps something we could look forward to coding against when the 1.4
release comes out.

I am not actually on this list, but I will try to follow the archives.
However, if you'd like a quick reply, please email me directly. Thanks
for listening.

-dan

[*] http://developer.gnome.org/doc/API/gdk/gdk-bitmaps-and-pixmaps.html




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