static void jni_get (void *data_in, void *data_out) { struct jni_params *in_params = (struct jni_params*)data_in; struct jni_out_params_char *out_args = (struct jni_out_params_char*)data_out; char obj_method_name[128]; char obj_method_signature[128]; jclass class_ptr = NULL; jobject obj = NULL; jmethodID giid = NULL; jstring ret_char; snprintf(obj_method_name, sizeof(obj_method_name), "getStringExtra"); snprintf(obj_method_signature, sizeof(obj_method_signature), "(Ljava/lang/String;)Ljava/lang/String;"); GET_OBJECT_CLASS(in_params->env, class_ptr, in_params->class_obj); GET_METHOD_ID(in_params->env, giid, class_ptr, in_params->method_name, in_params->method_signature); CALL_OBJ_METHOD(in_params->env, obj, in_params->class_obj, giid); GET_OBJECT_CLASS(in_params->env, class_ptr, obj); GET_METHOD_ID(in_params->env, giid, class_ptr, obj_method_name, obj_method_signature); CALL_OBJ_METHOD_PARAM(in_params->env, ret_char, obj, giid, (*in_params->env)->NewStringUTF(in_params->env, out_args->in)); if (giid != NULL && ret_char) { const char *test_argv = (*in_params->env)->GetStringUTFChars(in_params->env, ret_char, 0); strncpy(out_args->out, test_argv, out_args->out_sizeof); (*in_params->env)->ReleaseStringUTFChars(in_params->env, ret_char, test_argv); } }
static bool android_gfx_ctx_get_metrics(void *data, enum display_metric_types type, float *value) { jclass metrics_class; jobject metrics; jmethodID getMetrics; struct android_app *android_app = (struct android_app*)g_android; JNIEnv *env = (JNIEnv*)jni_thread_getenv(); GET_METHOD_ID(env, getMetrics, android_app->activity, "getMetrics", "()Landroid/util/DisplayMetrics;"); if (!getMetrics) goto error; CALL_OBJ_STATIC_METHOD(env, metrics, android_app->activity, getMetrics); GET_OBJECT_CLASS(env, metrics_class, metrics); /* Density */ float density = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "density", "F")); float scaled_density = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "scaledDensity", "F")); int density_dpi = (*env)->GetIntField(env, metrics, (*env)->GetFieldID(env, metrics_class, "densityDpi", "I")); /* Size */ int width_pixels = (*env)->GetIntField(env, metrics, (*env)->GetFieldID(env, metrics_class, "widthPixels", "I")); int height_pixels = (*env)->GetIntField(env, metrics, (*env)->GetFieldID(env, metrics_class, "heightPixels", "I")); /* DPI */ /* Apparently xdpi and ydpi can't be trusted to be implemented correctly, so don't try to rely on it... * * https://groups.google.com/forum/#!topic/android-developers/QjUlaRohRPI * * "The xdpi and ydpi are supposed to be the real DPI of the screen... though as you've seen, * many devices don't set it correctly. :( This is our fault, it isn't actually used anywhere * in the platform, so people don't realize they have a bad value, and we haven't had a CTS * test to try to make sure it is sane (it's not clear how that test should work). Worse, we * shipping the original Droid with a graphics driver that reports the wrong value here... * in fact that reported that same damnable 96." * * Unfortunately, I don't have a good solution if you want to get the real exactly screen dots per inch. * One thing you could do is compare xdpi/ydpi with densityDpi and if they are significantly * far apart, assume the values are bad and just fall back on densityDpi as an approximation. * * Be careful on this, because a correctly working device may have densityDpi fairly different * than the real dpi -- for example the Samsung TAB uses high density even though its screen's * really density is a fair amount lower than 240." */ float xdpi = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "xdpi", "F")); float ydpi = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "ydpi", "F")); (void)width_pixels; (void)height_pixels; (void)scaled_density; (void)density; (void)density_dpi; switch (type) { case DISPLAY_METRIC_MM_WIDTH: /* can't guarantee this to be accurate - so return false anyway. */ *value = xdpi; return false; case DISPLAY_METRIC_MM_HEIGHT: /* can't guarantee this to be accurate - so return false anyway. */ *value = ydpi; return false; case DISPLAY_METRIC_DPI: /* just go with quantized DPI. */ *value = density_dpi; break; case DISPLAY_METRIC_NONE: default: *value = 0; return false; } return true; error: return false; }