Пример #1
0
/*
 * Signature is (*cairo_destroy_funct_t) meeting the requirements of the
 * fifth parameter of cairo_surface_set_mime_data() below.
 */
static void
release_image_data
(
	void* pointer
)
{
	ImageCleanup* cleanup;
	JNIEnv* env;
	jbyteArray array;
	jbyte* data;

	cleanup = (ImageCleanup*) pointer;
	array = (jbyteArray) cleanup->array;
	data = (jbyte*) cleanup->data;

	env = bindings_java_getEnv();

	// call function to free image data
	(*env)->ReleaseByteArrayElements(env, array, data, JNI_ABORT);

	// drop reference
 	(*env)->DeleteGlobalRef(env, array);

	// cleanup transfer struct
	g_free(cleanup);
}
Пример #2
0
WebKitWebView*      createWebView                      (WebKitWebView  *web_view,
                                                        gpointer        user_data)
{
  /*   WebKitWebView* newWnd = (WebKitWebView*)user_data;
       return newWnd;
  */
  jlong viewPtr = (long)web_view;
  
  JNIEnv* env = bindings_java_getEnv();
  jclass cls;
  cls = (*env)->FindClass(env, "org/gnome/webKit/WebView");
  if (cls != 0)
    {
      jmethodID mid = mid = (*env)->GetStaticMethodID(env, cls, "JNICreateWebView", "(J)J");
      if(mid !=0)
        {
          // printf("Result of JNICreateWebView: %l\n", view);
          jlong view = (*env)->CallStaticLongMethod(env, cls, mid, viewPtr);
          g_printf("JNICreateWebView method succeded\n");
          return (WebKitWebView*) view;
        }
      else
        {
          g_printf("JNICreateWebView method failed\n");
        }
    }
  else
    {
      puts("Could not find the class");
    }
  return 0;
}
/*
 * Signature the prototype of the generic (*GCallback) prototype, meeting the
 * requirements of the first argument to gdk_threads_set_lock_functions()
 */
void
bindings_java_threads_lock
( 
)
{
	JNIEnv* env;
	
	env = bindings_java_getEnv();

	if ((*env)->MonitorEnter(env, lock) != JNI_OK) {
		g_critical("Error trying to get Java side GDK lock!?!");
	}
}
/*
 * Signature the prototype of the generic (*GCallback) prototype, meeting the
 * requirements of the second argument to gdk_threads_set_lock_functions()
 */
void
bindings_java_threads_unlock
( 
)
{
	JNIEnv* env;

	env = bindings_java_getEnv();

	if ((*env)->MonitorExit(env, lock) != JNI_OK) {
		g_critical("Error trying to release Java side GDK lock?!?");
	}
}
Пример #5
0
/*
 * Meets the signature requirement of (*GBoxedFreeFunc)
 */
static void
bindings_java_reference_free
(
	gpointer _boxed
)
{
	JNIEnv* env;
	jobject reference;
	
	env = bindings_java_getEnv();
	reference = (jobject) _boxed;

	(*env)->DeleteGlobalRef(env, reference);
}
Пример #6
0
/*
 * Meets the signature of (*GBoxedCopyFunc).
 */
static gpointer
bindings_java_reference_copy
(
	gpointer _boxed
)
{
	JNIEnv* env;
	jobject result, reference;

	env = bindings_java_getEnv();
	reference = (jobject) _boxed;

	result = (*env)->NewGlobalRef(env, reference);
 
	return (gpointer) result;
}
Пример #7
0
/*
 * Signature the prototype of (*GClosureNotify), meeting the requirements
 * to be the third argument to g_closure_add_finalize_notifier()
 */
static void
bindings_java_closure_destroy
(
	gpointer data,
	GClosure *closure
)
{
	BindingsJavaClosure* bjc;
	JNIEnv* env;	

 	bjc = (BindingsJavaClosure*) closure;

	if (bjc->handler) {
		env = bindings_java_getEnv();
		(*env)->DeleteWeakGlobalRef(env, bjc->handler);
	}
}
Пример #8
0
/*
 * Signature the prototype of (*GClosureMarshall), meeting the requirements
 * to be the second argument to g_closure_set_marshal()
 */
static void
bindings_java_marshaller
(
	GClosure* closure,
	GValue* return_value,
	guint n_param_values,
	const GValue* param_values,
	gpointer invocation_hint,
	gpointer marshal_data
)
{
 	BindingsJavaClosure* bjc;
 	JNIEnv* env;
 	jvalue* jargs;
	guint i;
	GType type;

	// Return values, as necessary
	jboolean _b;
	gboolean b;
	
	jint _e;
	
	jstring _str;
	gchar* str;
	GObject* obj;
	
	/*
	 * Begin marshaller by downcasting the GClosure we got.
	 */

	bjc = (BindingsJavaClosure*) closure;

	/*
	 * Get the JNIEnv interface pointer
	 */

	env = bindings_java_getEnv();
	if (env == NULL) {
		g_critical("Couldn't get JNIEnv interface, aborting marshal");
		return;
	}
		
	/*
	 * Build the parameters for the callback. The signature of the
	 * handlers on the Java side for a signal "name" would be:
	 *
	 * 	receiveName(Signal handler, type arg0, type arg1, ...)
	 *
	 * Note that arg0 is universally the source object (in otherwords, a
	 * method function where the first argument is always a reference to
	 * self).
	 *
	 * In case you didn't know, JNI's jvalue us a rather complex union
	 * which holds any of the possible things you can send across the
	 * boundary. So we allocate an array of them, then for each parameter
	 * passed to the marshaller, whack them in.
	 */

	jargs = g_newa(jvalue, n_param_values + 1);

	jargs[0].l = bjc->handler;

	for(i = 0; i < n_param_values; i++) {
		type = G_VALUE_TYPE(&param_values[i]);
		switch(G_TYPE_FUNDAMENTAL(type)) {
		case G_TYPE_CHAR:
			jargs[i+1].c = g_value_get_char(&param_values[i]);
      			break;

		case G_TYPE_UCHAR:
			jargs[i+1].c = g_value_get_uchar(&param_values[i]);
      			break;

		case G_TYPE_BOOLEAN:
			b = g_value_get_boolean(&param_values[i]);
			jargs[i+1].z = (b == TRUE) ? JNI_TRUE : JNI_FALSE;
			break;

		case G_TYPE_INT:
			jargs[i+1].i = g_value_get_int(&param_values[i]);
			break;

		case G_TYPE_UINT:
			jargs[i+1].i = g_value_get_uint(&param_values[i]);
			break;

		case G_TYPE_ENUM:
			jargs[i+1].i = g_value_get_enum(&param_values[i]);
			break;

		case G_TYPE_FLAGS:
			jargs[i+1].i = g_value_get_flags(&param_values[i]);
			break;

		case G_TYPE_LONG:
			jargs[i+1].j = g_value_get_long(&param_values[i]);
			break;

		case G_TYPE_ULONG:
			jargs[i+1].j = g_value_get_ulong(&param_values[i]);
			break;

		case G_TYPE_FLOAT:
			jargs[i+1].f = g_value_get_float(&param_values[i]);
			break;

		case G_TYPE_DOUBLE:
			jargs[i+1].d = g_value_get_double(&param_values[i]);
			break;

		case G_TYPE_STRING:
			jargs[i+1].l = bindings_java_newString(env, g_value_get_string(&param_values[i]));
      			break;

		case G_TYPE_OBJECT:
		case G_TYPE_INTERFACE:
			/*
			 * GObjects are just pointers, and so we pass up the
			 * address across the boundary to be looked up and
			 * either an existing Proxy returned or a new Proxy
			 * created.
			 */
			obj = g_value_get_object(&param_values[i]);
			bindings_java_memory_cleanup(obj, FALSE);
			jargs[i+1].j = (jlong) obj;
			break;

		case G_TYPE_BOXED:
			/*
			 * We make a copy of the GBoxed so that we own it and
			 * thus it can (will) survive the duration of the
			 * signal in the event that the developer using this
			 * code keeps a reference to the returned Boxed.
			 */
			jargs[i+1].j = (jlong) g_boxed_copy(type, g_value_get_boxed(&param_values[i]));
			break;

		case G_TYPE_PARAM:
			/*
			 * We're ignoring GParamSpec at the moment. They
			 * normally only show up in 'notify' signals, and we
			 * don't need them.
			 */
		case G_TYPE_POINTER:
			/*
			 * and, we're ignoring something that gets registered
			 * as a gpointer, by definition it has no type
			 * information and there's nothing we can do.
			 */
			jargs[i+1].j = (jlong) NULL;
			break;

		default:
			/*
			 * Unrecognized. Probably means we need to add a clause above.
			 */
			g_printerr("Don't know how to marshal a %s", g_type_name(type));
			jargs[i+1].l = 0;
			break;
		}
	}
	
	/*
	 * And now we invoke the callback on the Java side Signal handler; we have to
	 * select the correct function based on what return type is necessary.
	 */

	switch(bjc->returnType) {
	case 'V':
		/*
		 * void return signals
		 */
		(*env)->CallStaticVoidMethodA(env, bjc->receiver, bjc->method, jargs);
		break;

	case 'Z':
		/*
		 * boolean return signals
		 */
		_b = (*env)->CallStaticBooleanMethodA(env, bjc->receiver, bjc->method, jargs);		
		if (_b == JNI_TRUE) {
			b = TRUE;
		} else if (_b == JNI_FALSE) {
			b = FALSE;
		} else {
			g_critical("How did you manage to return a boolean that's neither TRUE nor FALSE?");
			return;
		}
		
		g_value_set_boolean(return_value, b);
		break;

	case 'I':
		/*
		 * integer return signals
		 */
		_e = (*env)->CallStaticIntMethodA(env, bjc->receiver, bjc->method, jargs);
		
		g_value_set_int(return_value, _e);
		break;

	case 'E':
		/*
		 * enum return signals
		 */
		_e = (*env)->CallStaticIntMethodA(env, bjc->receiver, bjc->method, jargs);		
		
		g_value_set_enum(return_value, _e);
		break;

	case 'L':
		/*
		 * String return signals
		 *
		 * L is actually Object, of course, but the only type we need to
		 * worry about is java.lang.String encode it for now, and so make the
		 * enormous assumption that a string is what we get back.
		 */
		_str = (*env)->CallStaticObjectMethodA(env, bjc->receiver, bjc->method, jargs);
		if (_str == NULL) {
			g_warning("Invoking string handler returned null. That's probably bad");
			break;
		}
		
		str = (gchar*) bindings_java_getString(env, _str);
		if (str == NULL) {
			/* OutOfMemoryError already thrown */
			return;
		}
		
		// according to the API docs, this copies the input...
		g_value_set_string(return_value, str);
		
		// ... so we can release str
		bindings_java_releaseString(str);
		break;

	default:
		/*
		 * If it's not void, boolean or gchar*, then what kind of signal is it?
		 */
		g_critical("Invocation for return type %c not implemented", bjc->returnType);
		break;
	}

	/*
	 * Cleanup
	 */

	for(i = 0; i < n_param_values; i++) {
  		type = G_VALUE_TYPE(&param_values[i]);
		switch(G_TYPE_FUNDAMENTAL(type)) {
		case G_TYPE_STRING:
			(*env)->DeleteLocalRef(env, jargs[i+1].l);
			break;

		default:
			break;
		}
	}
	
	/*
	 * Don't need to free jargs - we alloca()'d it
	 */
	
	/*
	 * Now, check if an exception occurred in the callback. There's a
	 * catch: because we're in native code right now [care of the call to
	 * gtk_main()] the exception gets swallowed until we return from that
	 * native call. So we call the function which causes the main loop to
	 * terminate, with the result that the exception will propegate out
	 * and, yes, probably halt the program.
	 *
	 * This is abrupt, but it is deliberate: we need to force developers
	 * to deal with criticals emitted by the underlying libraries.
	 * Otherwise, the next thing that is likely to happen is a
	 * segmentation fault, and not only does that crash the "program" but
	 * it takes out the Java Virtual Machine running it. People don't
	 * like VM crashes.
	 *
	 * Uncaught exceptions of any kind leaving a signal handler are to be
	 * considered programmer error and will be fatal.
	 */

	if ((*env)->ExceptionOccurred(env)) {
		gtk_main_quit();
	}
}