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.