Return to JGIR

Overview of Java mapping

JGIR contains hand-written bindings for parts of GLib and GObject. Not all of GLib and GObject are exposed, and some parts that are are done in a custom way, for example properties. But everything above GObject, from Gio on up, is a 100% algorithmic mapping. If you know the C code, you should be able to know where the Java is without referring to docs; completion in your IDE should be enough.

Global functions

All global functions (not associated with a GObject, GInterface, etc.) go into a class named FooGlobals, where Foo is the namespace. Example:

gtk_init_check(int *argc, char ***argv);

is translated to:

class GtkGlobals {...
/* The Pointer here will be changed soon */
  public static final void initCheck(Pointer argc, Pointer argv);
}

GObject subclasses

GObjects are naturally reflected into a corresponding Java class hierarchy. Methods are mapped to Java methods.

Constructors

Every class has the following constructors, equivalent to:

g_object_new (MY_TYPE_GOBJECT, ...)

Is represented with:

class MyGObject extends GObject {
  public MyGObject(Map<String,Object> args) { ... }
  public MyGObject() { this(new HashMap<String,Object>()); }
}

Custom constructors are mapped to Java constructors if they have different signatures:

GtkWidget *gtk_image_new_from_pixmap(GdkPixmap *pixmap, GdkBitmap *bitmap);
GtkWidget *gtk_image_new_from_image(GtkImage *image);

maps to:

public class Image { ...
  public Image(Pixmap pixmap, Bitmap bitmap) { ...}
  public Image(Image image) { ...}
}

However, if two constructors have the same signature, this is resolved by using static methods. Currently if one of the conflicting constructors is named "new", that is used as the default. Example:

GtkLabel * gtk_label_new(char*);
GtkLabel * gtk_label_new_with_mnemonic(char*);

These are translated into:

class Label { ...
  public Label(String) { ... }
  public static Label newWithMnemonic(String) { ... }
}

If none of the constructors is named "new", then all of them become static methods:

GtkWidget* gtk_image_new_from_icon_name (const gchar *icon_name, GtkIconSize size);
GtkWidget* gtk_image_new_from_stock      (const gchar *stock_id, GtkIconSize size);

These are translated into:

class Image { ...
  public static Image newFromIconName(String, IconSize size) { ... }
  public static Image newFromStock(String, IconSize size) { ... }
}

GObject Signals

Signals are mapped to inner interface classes, with an override for the "connect" method for each one. For example, you can connect to Gtk.Widget's "delete-event" like this:

  window.connect(new Widget.DeleteEvent() {
     @Override
     public Boolean onDeleteEvent(Widget w, Event arg0) {
       System.out.println("Deleted!");
     }
  });

GObject Properties

Besides the constructor, the only interface to properties currently is generic "get" and "set" methods on GObject. For example:

  window.set("name", "Hello World App");

Structures

JGIR is based on JNA; effectively, this lets you interface with things like native C structures from Java. JGIR thus maps C structures like this:

struct _GstMessage
{
  GstMiniObject mini_object;

  /*< private > *//* with MESSAGE_LOCK */
  GMutex *lock;                 /* lock and cond for async delivery */
  GCond *cond;

  /*< public > *//* with COW */
  GstMessageType type;
  guint64 timestamp;
  GstObject *src;

 ...
};

into the following. Note that not all GLib types such as "GMutex" are mapped; in this particular case, we'll likely never bother to bind it. But you can use the important fields like "type":

public final class Message extends com.sun.jna.Structure {
  public GstMiniObject mini_object;
  public Pointer lock;
  public Pointer cond;
  
  public int type;
  public long timestamp;
  Object src;
}

For more, see the JNA Structure documentation.

Unions

Yes, you can do C unions too, and the mapping is similar to structures. See the JNA Union documentation.

Enumerations

The C "enum" type can be used in glib's terms as both an "enum" and "flags". A glib enum has only one value at a time. In the second; a bitfield is typically used so multiple values can be passed at once.

GLib Enumeration

The following C:

typedef enum  {
  G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
  G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN,
  G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN
} GDataStreamByteOrder;

maps to:

public enum DataStreamByteOrder {
  BIG_ENDIAN,
  LITTLE_ENDIAN,
  HOST_ENDIAN
}

as you would expect.

GLib Flags

Java has no native concept of "flags", so JGIR maps them to plain "int".

This C:

typedef enum {
  G_APP_INFO_CREATE_NONE = 0,           /*< nick=none >*/
  G_APP_INFO_CREATE_NEEDS_TERMINAL = (1<<0),  /*< nick=needs-terminal >*/
  G_APP_INFO_CREATE_SUPPORTS_URIS = (1<<1)   /*< nick=supports-uris >*/
} GAppInfoCreateFlags;

maps to:

public interface AppInfoCreateFlags {
  public static final int NONE = 0;
  public static final int NEEDS_TERMINAL = 1; 
  public static final int SUPPORTS_URIS = 1 << 1;
}

In method calls, the parameter will just be "int" - you will need to know that the API takes a flags.

Projects/JGIR/Design (last edited 2014-06-19 23:09:52 by DanielEspinosaOrtiz)