1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Android jni helpers
12 *
13 * By Thomas Fjellstrom.
14 *
15 */
16
17 #include "allegro5/allegro.h"
18 #include "allegro5/internal/aintern_android.h"
19 #include <jni.h>
20 #include <stdarg.h>
21
22 ALLEGRO_DEBUG_CHANNEL("jni")
23
24 #define VERBOSE_DEBUG(a, ...) (void)0
25
26 /* jni helpers */
27
__jni_checkException(JNIEnv * env,const char * file,const char * func,int line)28 void __jni_checkException(JNIEnv *env, const char *file, const char *func, int line)
29 {
30 jthrowable exc;
31
32 exc = (*env)->ExceptionOccurred(env);
33 if (exc) {
34 ALLEGRO_DEBUG("GOT AN EXCEPTION @ %s:%i %s", file, line, func);
35 /* We don't do much with the exception, except that
36 we print a debug message for it, clear it, and
37 throw a new exception. */
38 (*env)->ExceptionDescribe(env);
39 (*env)->ExceptionClear(env);
40 (*env)->FatalError(env, "EXCEPTION");
41 //(*env)->ThrowNew(env, system_data.illegal_argument_exception_class, "thrown from C code");
42 }
43 }
44
_jni_callObjectMethod(JNIEnv * env,jobject object,const char * name,const char * sig)45 jobject _jni_callObjectMethod(JNIEnv *env, jobject object,
46 const char *name, const char *sig)
47 {
48 VERBOSE_DEBUG("%s (%s)", name, sig);
49
50 jclass class_id = _jni_call(env, jclass, GetObjectClass, object);
51 jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, name, sig);
52 jobject ret = _jni_call(env, jobject, CallObjectMethod, object, method_id);
53
54 _jni_callv(env, DeleteLocalRef, class_id);
55
56 return ret;
57 }
58
_jni_callObjectMethodV(JNIEnv * env,jobject object,const char * name,const char * sig,...)59 jobject _jni_callObjectMethodV(JNIEnv *env, jobject object,
60 const char *name, const char *sig, ...)
61 {
62 va_list ap;
63
64 VERBOSE_DEBUG("%s (%s)", name, sig);
65
66 jclass class_id = _jni_call(env, jclass, GetObjectClass, object);
67 jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, name, sig);
68
69 va_start(ap, sig);
70 jobject ret = _jni_call(env, jobject, CallObjectMethodV, object, method_id, ap);
71 va_end(ap);
72
73 _jni_callv(env, DeleteLocalRef, class_id);
74
75 VERBOSE_DEBUG("callObjectMethodV end");
76 return ret;
77 }
78
_jni_getString(JNIEnv * env,jobject object)79 ALLEGRO_USTR *_jni_getString(JNIEnv *env, jobject object)
80 {
81 VERBOSE_DEBUG("GetStringUTFLength");
82 jsize len = _jni_call(env, jsize, GetStringUTFLength, object);
83
84 const char *str = _jni_call(env, const char *, GetStringUTFChars, object, NULL);
85
86 VERBOSE_DEBUG("al_ustr_new_from_buffer");
87 ALLEGRO_USTR *ustr = al_ustr_new_from_buffer(str, len);
88
89 _jni_callv(env, ReleaseStringUTFChars, object, str);
90
91 return ustr;
92 }
93
_jni_callStringMethod(JNIEnv * env,jobject obj,const char * name,const char * sig)94 ALLEGRO_USTR *_jni_callStringMethod(JNIEnv *env, jobject obj,
95 const char *name, const char *sig)
96 {
97 jobject str_obj = _jni_callObjectMethod(env, obj, name, sig);
98 return _jni_getString(env, str_obj);
99 }
100
_jni_callStaticObjectMethodV(JNIEnv * env,jclass cls,const char * name,const char * sig,...)101 jobject _jni_callStaticObjectMethodV(JNIEnv *env, jclass cls,
102 const char *name, const char *sig, ...)
103 {
104 jmethodID mid;
105 jobject ret;
106 va_list ap;
107
108 mid = _jni_call(env, jmethodID, GetStaticMethodID, cls, name, sig);
109
110 va_start(ap, sig);
111 ret = _jni_call(env, jobject, CallStaticObjectMethodV, cls, mid, ap);
112 va_end(ap);
113
114 return ret;
115 }
116
_jni_callStaticIntMethodV(JNIEnv * env,jclass cls,const char * name,const char * sig,...)117 jint _jni_callStaticIntMethodV(JNIEnv *env, jclass cls,
118 const char *name, const char *sig, ...)
119 {
120 jmethodID mid;
121 jint ret;
122 va_list ap;
123
124 mid = _jni_call(env, jmethodID, GetStaticMethodID, cls, name, sig);
125
126 va_start(ap, sig);
127 ret = _jni_call(env, jint, CallStaticIntMethodV, cls, mid, ap);
128 va_end(ap);
129
130 return ret;
131 }
132
133 /* vim: set sts=3 sw=3 et: */
134