src/core/android/SDL_android.c
changeset 11355 6185fb86f046
parent 11292 df399ea01ee5
child 11393 3e57ce45a890
     1.1 --- a/src/core/android/SDL_android.c	Sun Aug 27 18:36:54 2017 -0700
     1.2 +++ b/src/core/android/SDL_android.c	Sun Aug 27 18:43:52 2017 -0700
     1.3 @@ -91,6 +91,14 @@
     1.4          JNIEnv* env, jclass jcls,
     1.5          jint device_id);
     1.6  
     1.7 +JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddHaptic)(
     1.8 +        JNIEnv* env, jclass jcls,
     1.9 +        jint device_id, jstring device_name);
    1.10 +
    1.11 +JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveHaptic)(
    1.12 +        JNIEnv* env, jclass jcls,
    1.13 +        jint device_id);
    1.14 +
    1.15  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
    1.16          JNIEnv* env, jclass jcls);
    1.17  
    1.18 @@ -121,6 +129,9 @@
    1.19          JNIEnv* env, jclass jcls,
    1.20          jfloat x, jfloat y, jfloat z);
    1.21  
    1.22 +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
    1.23 +        JNIEnv* env, jclass jcls);
    1.24 +
    1.25  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
    1.26          JNIEnv* env, jclass cls);
    1.27  
    1.28 @@ -187,7 +198,10 @@
    1.29  static jmethodID midSendMessage;
    1.30  static jmethodID midShowTextInput;
    1.31  static jmethodID midIsScreenKeyboardShown;
    1.32 -static jmethodID midGetSystemServiceFromUiThread;
    1.33 +static jmethodID midClipboardSetText;
    1.34 +static jmethodID midClipboardGetText;
    1.35 +static jmethodID midClipboardHasText;
    1.36 +
    1.37  
    1.38  /* static fields */
    1.39  static jfieldID fidSeparateMouseAndTouch;
    1.40 @@ -269,8 +283,12 @@
    1.41                                  "showTextInput", "(IIII)Z");
    1.42      midIsScreenKeyboardShown = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    1.43                                  "isScreenKeyboardShown","()Z");
    1.44 -    midGetSystemServiceFromUiThread = (*mEnv)->GetMethodID(mEnv, mActivityClass,
    1.45 -                                "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;");
    1.46 +    midClipboardSetText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    1.47 +                                "clipboardSetText", "(Ljava/lang/String;)V");
    1.48 +    midClipboardGetText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    1.49 +                                "clipboardGetText", "()Ljava/lang/String;");
    1.50 +    midClipboardHasText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    1.51 +                                "clipboardHasText", "()Z");
    1.52  
    1.53      bHasNewData = SDL_FALSE;
    1.54  
    1.55 @@ -279,7 +297,8 @@
    1.56         !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose ||
    1.57         !midPollInputDevices || !midPollHapticDevices || !midHapticRun ||
    1.58         !midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds ||
    1.59 -       !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midGetSystemServiceFromUiThread) {
    1.60 +       !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || 
    1.61 +       !midClipboardSetText || !midClipboardGetText || !midClipboardHasText) {
    1.62          __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
    1.63      }
    1.64  
    1.65 @@ -366,7 +385,7 @@
    1.66      return Android_RemoveJoystick(device_id);
    1.67  }
    1.68  
    1.69 -JNIEXPORT jint JNICALL Java_org_libsdl_app_SDLActivity_nativeAddHaptic(
    1.70 +JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddHaptic)(
    1.71      JNIEnv* env, jclass jcls, jint device_id, jstring device_name)
    1.72  {
    1.73      int retval;
    1.74 @@ -379,7 +398,7 @@
    1.75      return retval;
    1.76  }
    1.77  
    1.78 -JNIEXPORT jint JNICALL Java_org_libsdl_app_SDLActivity_nativeRemoveHaptic(
    1.79 +JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveHaptic)(
    1.80      JNIEnv* env, jclass jcls, jint device_id)
    1.81  {
    1.82      return Android_RemoveHaptic(device_id);
    1.83 @@ -492,6 +511,13 @@
    1.84      bHasNewData = SDL_TRUE;
    1.85  }
    1.86  
    1.87 +/* Clipboard */
    1.88 +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
    1.89 +                                    JNIEnv* env, jclass jcls)
    1.90 +{
    1.91 +    SDL_SendClipboardUpdate();
    1.92 +}
    1.93 +
    1.94  /* Low memory */
    1.95  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
    1.96                                      JNIEnv* env, jclass cls)
    1.97 @@ -1363,118 +1389,41 @@
    1.98      return Internal_Android_JNI_FileClose(ctx, SDL_TRUE);
    1.99  }
   1.100  
   1.101 -/* returns a new global reference which needs to be released later */
   1.102 -static jobject Android_JNI_GetSystemServiceObject(const char* name)
   1.103 -{
   1.104 -    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
   1.105 -    JNIEnv* env = Android_JNI_GetEnv();
   1.106 -    jobject retval = NULL;
   1.107 -    jstring service;
   1.108 -    jobject context;
   1.109 -    jobject manager;
   1.110 -
   1.111 -    if (!LocalReferenceHolder_Init(&refs, env)) {
   1.112 -        LocalReferenceHolder_Cleanup(&refs);
   1.113 -        return NULL;
   1.114 -    }
   1.115 -
   1.116 -    service = (*env)->NewStringUTF(env, name);
   1.117 -
   1.118 -    /* context = SDLActivity.getContext(); */
   1.119 -    context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
   1.120 -
   1.121 -    manager = (*env)->CallObjectMethod(env, context, midGetSystemServiceFromUiThread, service);
   1.122 -
   1.123 -    (*env)->DeleteLocalRef(env, service);
   1.124 -
   1.125 -    retval = manager ? (*env)->NewGlobalRef(env, manager) : NULL;
   1.126 -    LocalReferenceHolder_Cleanup(&refs);
   1.127 -    return retval;
   1.128 -}
   1.129 -
   1.130 -#define SETUP_CLIPBOARD(error) \
   1.131 -    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \
   1.132 -    JNIEnv* env = Android_JNI_GetEnv(); \
   1.133 -    jobject clipboard; \
   1.134 -    if (!LocalReferenceHolder_Init(&refs, env)) { \
   1.135 -        LocalReferenceHolder_Cleanup(&refs); \
   1.136 -        return error; \
   1.137 -    } \
   1.138 -    clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
   1.139 -    if (!clipboard) { \
   1.140 -        LocalReferenceHolder_Cleanup(&refs); \
   1.141 -        return error; \
   1.142 -    }
   1.143 -
   1.144 -#define CLEANUP_CLIPBOARD() \
   1.145 -    LocalReferenceHolder_Cleanup(&refs);
   1.146 -
   1.147  int Android_JNI_SetClipboardText(const char* text)
   1.148  {
   1.149 -    /* Watch out for C89 scoping rules because of the macro */
   1.150 -    SETUP_CLIPBOARD(-1)
   1.151 -
   1.152 -    /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
   1.153 -    {
   1.154 -        jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
   1.155 -        jstring string = (*env)->NewStringUTF(env, text);
   1.156 -        (*env)->CallVoidMethod(env, clipboard, mid, string);
   1.157 -        (*env)->DeleteGlobalRef(env, clipboard);
   1.158 -        (*env)->DeleteLocalRef(env, string);
   1.159 -    }
   1.160 -    CLEANUP_CLIPBOARD();
   1.161 -
   1.162 +    JNIEnv* env = Android_JNI_GetEnv();
   1.163 +    jstring string = (*env)->NewStringUTF(env, text);
   1.164 +    (*env)->CallStaticVoidMethod(env, mActivityClass, midClipboardSetText, string);
   1.165 +    (*env)->DeleteLocalRef(env, string);
   1.166      return 0;
   1.167  }
   1.168  
   1.169  char* Android_JNI_GetClipboardText(void)
   1.170  {
   1.171 -    /* Watch out for C89 scoping rules because of the macro */
   1.172 -    SETUP_CLIPBOARD(SDL_strdup(""))
   1.173 -
   1.174 -    /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
   1.175 -    {
   1.176 -        jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
   1.177 -        jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
   1.178 -        (*env)->DeleteGlobalRef(env, clipboard);
   1.179 -        if (sequence) {
   1.180 -            jstring string;
   1.181 -            const char* utf;
   1.182 -            mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
   1.183 -            string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
   1.184 -            utf = (*env)->GetStringUTFChars(env, string, 0);
   1.185 -            if (utf) {
   1.186 -                char* text = SDL_strdup(utf);
   1.187 -                (*env)->ReleaseStringUTFChars(env, string, utf);
   1.188 -
   1.189 -                CLEANUP_CLIPBOARD();
   1.190 -
   1.191 -                return text;
   1.192 -            }
   1.193 +    JNIEnv* env = Android_JNI_GetEnv();
   1.194 +    char* text = NULL;
   1.195 +    jstring string;
   1.196 +    
   1.197 +    string = (*env)->CallStaticObjectMethod(env, mActivityClass, midClipboardGetText);
   1.198 +    if (string) {
   1.199 +        const char* utf = (*env)->GetStringUTFChars(env, string, 0);
   1.200 +        if (utf) {
   1.201 +            text = SDL_strdup(utf);
   1.202 +            (*env)->ReleaseStringUTFChars(env, string, utf);
   1.203          }
   1.204 +        (*env)->DeleteLocalRef(env, string);
   1.205      }
   1.206 -    CLEANUP_CLIPBOARD();
   1.207 -
   1.208 -    return SDL_strdup("");
   1.209 +    
   1.210 +    return (text == NULL) ? SDL_strdup("") : text;
   1.211  }
   1.212  
   1.213  SDL_bool Android_JNI_HasClipboardText(void)
   1.214  {
   1.215 -    jmethodID mid;
   1.216 -    jboolean has;
   1.217 -    /* Watch out for C89 scoping rules because of the macro */
   1.218 -    SETUP_CLIPBOARD(SDL_FALSE)
   1.219 -
   1.220 -    mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
   1.221 -    has = (*env)->CallBooleanMethod(env, clipboard, mid);
   1.222 -    (*env)->DeleteGlobalRef(env, clipboard);
   1.223 -
   1.224 -    CLEANUP_CLIPBOARD();
   1.225 -
   1.226 -    return has ? SDL_TRUE : SDL_FALSE;
   1.227 +    JNIEnv* env = Android_JNI_GetEnv();
   1.228 +    jboolean retval = (*env)->CallStaticBooleanMethod(env, mActivityClass, midClipboardHasText);
   1.229 +    return (retval == JNI_TRUE) ? SDL_TRUE : SDL_FALSE;
   1.230  }
   1.231  
   1.232 -
   1.233  /* returns 0 on success or -1 on error (others undefined then)
   1.234   * returns truthy or falsy value in plugged, charged and battery
   1.235   * returns the value in seconds and percent or -1 if not available