/* * Implements * org.freedesktop.bindings.Environment.setenv(String variableName, String value) */ JNIEXPORT void JNICALL Java_org_freedesktop_bindings_Environment_setenv ( JNIEnv *env, jclass cls, jstring _name, jstring _value ) { const gchar* name; const gchar* value; // convert parameter name name = bindings_java_getString(env, _name); if (name == NULL) { return; /* OutOfMemoryError already thrown */ } // convert parameter value value = bindings_java_getString(env, _value); if (value == NULL) { return; /* OutOfMemoryError already thrown */ } // call function if (g_setenv(name, value, 1) == -1) { bindings_java_throw(env, "\nsetenv() failed: Insufficient space in environment"); } // clean up name bindings_java_releaseString(name); // clean up name bindings_java_releaseString(value); }
/** * Implements * org.gnome.glib.GObject.g_signal_connect(long instance, Object handler, String name, boolean after) * called from * org.gnome.glib.Plumbing.connectSignal(Object instance, Signal handler, String name, boolean after) * called from * <generated package scope classes>.connect(Object instance, Signal handler, boolean after) * * This is where the magic to create a GClosure and hook it up to the GSignal * handling mechanisms is taken care of. A reference is created to the passed * Java object which is used as the callback when the signal is fired. */ JNIEXPORT void JNICALL Java_oscats_glib_GObject_g_1signal_1connect ( JNIEnv *env, jclass cls, jlong _instance, jobject _handler, jobject _receiver, jstring _name, jboolean _after ) { GObject* instance; const gchar* name; gboolean after; guint id; GQuark detail = 0; GClosure* closure; gboolean ok; // translate instance instance = (GObject*) _instance; // translate the signal name name = bindings_java_getString(env, _name); // translate after after = (gboolean) _after; /* * Lookup the signal information. We use this rather than g_signal_lookup() because * it allows us to sidestep the issue of detailed signal names. */ ok = g_signal_parse_name(name, G_OBJECT_TYPE(instance), &id, &detail, TRUE); if (!ok) { bindings_java_throw(env, "Unknown signal name %s for object %s", name, G_OBJECT_TYPE_NAME(instance)); return; } closure = bindings_java_closure_new(env, _handler, (jclass) _receiver, name, id); if (closure == NULL) { // and an exception has already been thrown return; } // returns the handler id, but we don't need it. g_signal_connect_closure_by_id(instance, id, detail, closure, after); // cleanup. Not really necessary as will happen automatically in a moment. bindings_java_releaseString(name); }
/** * Implements * org.gnome.glib.GObject.g_object_get_property(long instance, String name) * called from * org.gnome.glib.GObject.getProperty(Object instance, String name) * * The idea of using g_object_class_find_property() to get at an appropriate * GType for the empty GValue we need to pass as an out parameter to * g_object_get_property() is borrowed from java-gnome 2.x's implementation. */ JNIEXPORT jlong JNICALL Java_oscats_glib_GObject_g_1object_1get_1property ( JNIEnv* env, jclass cls, jlong _instance, jstring _name ) { GObject* instance; const gchar* name; GValue* value; GParamSpec* spec; // translate instance instance = (GObject*) _instance; // translate name name = bindings_java_getString(env, _name); if (name == NULL) { return 0L; /* OutOfMemoryError already thrown */ } // initialize value spec = g_object_class_find_property(G_OBJECT_GET_CLASS(instance), name); if (spec == NULL) { bindings_java_throw(env, "GParamSpec for %s was NULL", name); return 0L; } value = g_slice_new0(GValue); g_value_init(value, spec->value_type); // call method g_object_get_property(instance, name, value); // clean up name bindings_java_releaseString(name); /* * we do not need to clean up value; it will eventually be underneath a * Fundamental extends Value extends Proxy which will ultimately call * g_value_free() when it is ready to be disposed. */ return (jlong) value; }
/** * Called from * org.gnome.gtk.GtkTreeModeOverride.gtk_list_store_new(String[]) * called from * org.gnome.gtk.GtkTreeModeOverride.createListStore(Class[]) * called from * org.gnome.gtk.ListStore.<init>(???) * * You should already have established Java side that ther array is bigger * that 0 elements before calling this. */ JNIEXPORT jlong JNICALL Java_org_gnome_gtk_GtkTreeModelOverride_gtk_1list_1store_1new ( JNIEnv* env, jclass cls, jobjectArray _columns ) { GtkListStore* result; gint num_columns; GType* columns; // GType[] gint i; jstring _name; const gchar* name; num_columns = (gint) (*env)->GetArrayLength(env, _columns); columns = g_newa(GType, num_columns); for (i = 0; i < num_columns; i++) { _name = (jstring) (*env)->GetObjectArrayElement(env, _columns, i); name = bindings_java_getString(env, _name); if (name == NULL) { return 0L; // OutOfMemory already thrown } columns[i] = bindings_java_type_lookup(name); if (columns[i] == G_TYPE_INVALID) { bindings_java_throw(env, "Don't know how to map %s into a GType", name); return 0L; } bindings_java_releaseString(name); (*env)->DeleteLocalRef(env, _name); } // call constructor result = gtk_list_store_newv(num_columns, columns); // clean up of columns is automatic // and finally return (jlong) result; }
JNIEXPORT jlong JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1pixbuf ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; GdkPixbuf* pixbuf; // translate value value = (GValue*) _value; if (G_VALUE_TYPE(value) != GDK_TYPE_PIXBUF) { bindings_java_throw(env, "You've asked for the GdkPixbuf within a GValue, but it's not a GDK_TYPE_PIXBUF!"); return 0L; } // call function pixbuf = g_value_get_object(value); // and return return (jlong) pixbuf; }
JNIEXPORT jlong JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1object ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; GObject* object; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_OBJECT(value)) { bindings_java_throw(env, "You've asked for the GObject within a GValue, but it's not a G_TYPE_OBJECT!"); return 0L; } // call function object = g_value_get_object(value); // and return return (jlong) object; }
/** * Implements * org.gnome.glib.GValue.g_value_get_flags(long value) * called from * org.gnome.glib.GValue.getFlags(Value value) * called from * org.gnome.glib.Object.getPropertyFlags(String name) * * Extract the ordinal of an flag stored in a GValue of type G_TYPE_FLAGS. */ JNIEXPORT jint JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1flags ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; guint num; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_FLAGS(value)) { bindings_java_throw(env, "You've asked for the flags ordinal value of a GValue, but it's not a G_TYPE_FLAGS!"); return 0; } // call function num = g_value_get_flags(value); // and return return (jint) num; }
/** * Implements * org.gnome.glib.GValue.g_value_get_string(long value) * called from * org.gnome.glib.GValue.getString(Value value) * called from * org.gnome.glib.Object.getPropertyString(String name) * * Extract the string value from a GValue of G_TYPE_STRING, returning the * primitive (well, String) to be used as such. */ JNIEXPORT jstring JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1string ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; const gchar* str; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_STRING(value)) { bindings_java_throw(env, "You've asked for the string value of a GValue, but it's not a G_TYPE_STRING!"); return NULL; } // call function str = g_value_get_string(value); // and return return bindings_java_newString(env, str); }
JNIEXPORT jboolean JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1boolean ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; gboolean result; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_BOOLEAN(value)) { bindings_java_throw(env, "You've asked for the boolean value of a GValue, but it's not a G_TYPE_BOOLEAN!"); return 0; } // call function result = g_value_get_boolean(value); // and return return (jboolean) result; }
JNIEXPORT jlong JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1long ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; gint64 result; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_INT64(value)) { bindings_java_throw(env, "You've asked for the long value of a GValue, but it's not a G_TYPE_INT64!"); return 0; } // call function result = g_value_get_int64(value); // and return return (jlong) result; }
/** * Implements * org.gnome.glib.GValue.g_value_get_double(long value) * called from * org.gnome.glib.GValue.getDouble(Value value) * called from * org.gnome.glib.Object.getPropertyDouble(String name) * * Extract the gdoulbe value from a GValue of G_TYPE_DOUBLE, returning the * primitive. */ JNIEXPORT jdouble JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1double ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; gdouble result; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_DOUBLE(value)) { bindings_java_throw(env, "You've asked for the double value of a GValue, but it's not a G_TYPE_DOUBLE!"); return 0.0; } // call function result = g_value_get_double(value); // and return return (jdouble) result; }
/** * Implements * org.gnome.glib.GValue.g_value_get_float(long value) * called from * org.gnome.glib.GValue.getFloat(Value value) * called from * org.gnome.glib.Object.getPropertyFloat(String name) * * Extract the gfloat value from a GValue of G_TYPE_FLOAT, returning the * primitive. */ JNIEXPORT jfloat JNICALL Java_org_gnome_glib_GValue_g_1value_1get_1float ( JNIEnv* env, jclass cls, jlong _value ) { GValue* value; gfloat result; // translate value value = (GValue*) _value; if (!G_VALUE_HOLDS_FLOAT(value)) { bindings_java_throw(env, "You've asked for the float value of a GValue, but it's not a G_TYPE_FLOAT!"); return 0.0f; } // call function result = g_value_get_float(value); // and return return (jfloat) result; }
/* * Implements * org.freedesktop.cairo.Plumbing.createPattern(long pointer) */ JNIEXPORT jobject JNICALL Java_org_freedesktop_cairo_Plumbing_createPattern ( JNIEnv* env, jclass cls, jlong _pointer ) { cairo_pattern_t* pattern; jclass found; static jclass SolidPattern = NULL; static jclass SurfacePattern = NULL; static jclass LinearPattern = NULL; static jclass RadialPattern = NULL; jclass type; jmethodID constructor; jobject proxy; // convert pointer pattern = (cairo_pattern_t*) _pointer; // increment reference count cairo_pattern_reference(pattern); // now figure out Proxy class and create switch (cairo_pattern_get_type(pattern)) { case CAIRO_PATTERN_TYPE_SOLID: if (SolidPattern == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/SolidPattern"); SolidPattern = (*env)->NewGlobalRef(env, found); } type = SolidPattern; break; case CAIRO_PATTERN_TYPE_SURFACE: if (SurfacePattern == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/SurfacePattern"); SurfacePattern = (*env)->NewGlobalRef(env, found); } type = SurfacePattern; break; case CAIRO_PATTERN_TYPE_LINEAR: if (LinearPattern == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/LinearPattern"); LinearPattern = (*env)->NewGlobalRef(env, found); } type = LinearPattern; break; case CAIRO_PATTERN_TYPE_RADIAL: if (RadialPattern == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/RadialPattern"); RadialPattern = (*env)->NewGlobalRef(env, found); } type = RadialPattern; break; default: g_critical("Unimplemented pattern type"); return NULL; } if (type == NULL) { bindings_java_throw(env, "FindClass() failed"); return NULL; } constructor = (*env)->GetMethodID(env, type, "<init>", "(J)V"); if (constructor == NULL) { g_error("Constructor methodID not found"); return NULL; } proxy = (*env)->NewObject(env, type, constructor, _pointer); return proxy; }
/* * Implements * org.freedesktop.cairo.Plumbing.createSurface(long pointer) */ JNIEXPORT jobject JNICALL Java_org_freedesktop_cairo_Plumbing_createSurface ( JNIEnv* env, jclass cls, jlong _pointer ) { cairo_surface_t* surface; jclass found; static jclass ImageSurface = NULL; static jclass XlibSurface = NULL; static jclass PdfSurface = NULL; static jclass SvgSurface = NULL; static jclass RecordingSurface = NULL; static jclass UnknownSurface = NULL; jclass type; jmethodID constructor; jobject proxy; // convert pointer surface = (cairo_surface_t*) _pointer; // increment reference count cairo_surface_reference(surface); // now figure out Proxy class and create switch (cairo_surface_get_type(surface)) { case CAIRO_SURFACE_TYPE_IMAGE: if (ImageSurface == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/ImageSurface"); ImageSurface = (*env)->NewGlobalRef(env, found); } type = ImageSurface; break; case CAIRO_SURFACE_TYPE_XLIB: if (XlibSurface == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/XlibSurface"); XlibSurface = (*env)->NewGlobalRef(env, found); } type = XlibSurface; break; case CAIRO_SURFACE_TYPE_PDF: if (PdfSurface == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/PdfSurface"); PdfSurface = (*env)->NewGlobalRef(env, found); } type = PdfSurface; break; case CAIRO_SURFACE_TYPE_SVG: if (SvgSurface == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/SvgSurface"); SvgSurface = (*env)->NewGlobalRef(env, found); } type = SvgSurface; break; case CAIRO_SURFACE_TYPE_RECORDING: if (RecordingSurface == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/RecordingSurface"); RecordingSurface = (*env)->NewGlobalRef(env, found); } type = RecordingSurface; break; default: /* * This is an unusual scenario. Normally in java-gnome if we * don't know the type that's a fatal error (and on purpose; if * we haven't got a concrete Proxy subclass for someone, that's * it). In Cairo, however, there are a number of cases where * internal types are exposed (notably MetaSurface, created if * you call createSimilar() on a vector backend) for which * there is no publicly available identification. So * UnknownSurface it is. This, however, obscures the real error * condition of needing to add a block to this switch statement * for a newly covered type. */ if (UnknownSurface == NULL) { found = (*env)->FindClass(env, "org/freedesktop/cairo/UnknownSurface"); UnknownSurface = (*env)->NewGlobalRef(env, found); } type = UnknownSurface; } if (type == NULL) { bindings_java_throw(env, "FindClass() failed"); return NULL; } constructor = (*env)->GetMethodID(env, type, "<init>", "(J)V"); if (constructor == NULL) { bindings_java_throw(env, "Constructor methodID not found"); return NULL; } proxy = (*env)->NewObject(env, type, constructor, _pointer); return proxy; }
/** * Implements * oscats.glib.GObject.g_object_new(String type, String[] keys, int num, long[] vlaues * called from * oscats.glib.GObject.new_with_params(Class<? extends glib.Object> type, Object... params) */ JNIEXPORT jlong JNICALL Java_oscats_glib_GObject_g_1object_1new ( JNIEnv *env, jclass cls, jstring _name, jint _num, jobjectArray _keys, jlongArray _values ) { jlong *values = NULL; GType type; GObjectClass *klass = NULL; GObject *obj; GParameter *params = NULL; const gchar *name; gint i; // translate name name = bindings_java_getString(env, _name); if (name == NULL) { return; /* OutOfMemoryError already thrown */ } type = g_type_from_name(name); if (!type) { bindings_java_throw(env, "GType not found for %s", name); return 0L; } if (!g_type_is_a(type, G_TYPE_OBJECT)) { bindings_java_throw(env, "Type %s is not a GObject", name); return 0L; } if ((klass = g_type_class_ref(type)) == NULL) { bindings_java_throw(env, "Could not get a reference to %s class", name); return 0L; } values = (jlong*) (*env)->GetLongArrayElements(env, _values, NULL); if (!values) return 0L; params = g_new0(GParameter, _num); for (i=0; i < _num; i++) { GParamSpec *pspec; GValue *value; GType pspec_type; const gchar *param = bindings_java_getString(env, (jstring)(*env)->GetObjectArrayElement(env, _keys, i)); if (param == NULL) { goto bail; /* OutOfMemoryError already thrown */ } pspec = g_object_class_find_property(klass, param); if (!pspec) { bindings_java_throw(env, "%s doesn't have property %s", name, param); bindings_java_releaseString(param); goto bail; } value = (GValue*)values[i]; pspec_type = G_PARAM_SPEC_VALUE_TYPE(pspec); if (!(G_VALUE_HOLDS(value, pspec_type) || (pspec_type == G_TYPE_UCHAR && G_VALUE_HOLDS(value, G_TYPE_CHAR)) || (pspec_type == G_TYPE_UINT && G_VALUE_HOLDS(value, G_TYPE_INT)) || (pspec_type == G_TYPE_ULONG && G_VALUE_HOLDS(value, G_TYPE_LONG)) || (pspec_type == G_TYPE_UINT64 && G_VALUE_HOLDS(value, G_TYPE_INT64)) )) { bindings_java_throw(env, "%s expects %s to be of type %s, not %s", name, param, g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)), g_type_name(G_VALUE_TYPE(value))); bindings_java_releaseString(param); goto bail; } g_value_init(¶ms[i].value, G_VALUE_TYPE(value)); g_value_copy(value, ¶ms[i].value); params[i].name = g_strdup(param); bindings_java_releaseString(param); } obj = g_object_newv(type, _num, params); if (!obj) { bindings_java_throw(env, "Could not create %s object", name); } bail: // No changes made (*env)->ReleaseLongArrayElements(env, _values, values, JNI_ABORT); for (i=0; i < _num; i++) { g_free((gchar*)params[i].name); g_value_unset(¶ms[i].value); } g_free(params); g_type_class_unref(klass); // clean up name bindings_java_releaseString(name); return (jlong)obj; }