Fixed bug 1573 - SDL does not support system clipboard on Android.

Philipp Wiesemann 2012-08-18 14:09:47 PDT

there is currently no way in SDL to interact with the system clipboard on
Android.

I attached a patch which tries to implement the three clipboard functions for
Android. It does not add the CLIPBOARDUPDATE event because this seems to
require Android API 11 or polling.
This commit is contained in:
Sam Lantinga 2012-09-26 20:14:37 -07:00
parent 255033689c
commit ef6fa58028
5 changed files with 125 additions and 0 deletions

View file

@ -735,6 +735,84 @@ extern "C" int Android_JNI_FileClose(SDL_RWops* ctx)
return Android_JNI_FileClose(ctx, true);
}
// returns a new global reference which needs to be released later
static jobject Android_JNI_GetSystemServiceObject(const char* name)
{
LocalReferenceHolder refs;
JNIEnv* env = Android_JNI_GetEnv();
if (!refs.init(env)) {
return NULL;
}
jstring service = env->NewStringUTF(name);
jmethodID mid;
mid = env->GetStaticMethodID(mActivityClass, "getContext", "()Landroid/content/Context;");
jobject context = env->CallStaticObjectMethod(mActivityClass, mid);
mid = env->GetMethodID(mActivityClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject manager = env->CallObjectMethod(context, mid, service);
env->DeleteLocalRef(service);
return manager ? env->NewGlobalRef(manager) : NULL;
}
#define SETUP_CLIPBOARD(error) \
LocalReferenceHolder refs; \
JNIEnv* env = Android_JNI_GetEnv(); \
if (!refs.init(env)) { \
return error; \
} \
jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
if (!clipboard) { \
return error; \
}
extern "C" int Android_JNI_SetClipboardText(const char* text)
{
SETUP_CLIPBOARD(-1)
jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "setText", "(Ljava/lang/CharSequence;)V");
jstring string = env->NewStringUTF(text);
env->CallVoidMethod(clipboard, mid, string);
env->DeleteGlobalRef(clipboard);
env->DeleteLocalRef(string);
return 0;
}
extern "C" char* Android_JNI_GetClipboardText()
{
SETUP_CLIPBOARD(SDL_strdup(""))
jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "getText", "()Ljava/lang/CharSequence;");
jobject sequence = env->CallObjectMethod(clipboard, mid);
env->DeleteGlobalRef(clipboard);
if (sequence) {
mid = env->GetMethodID(env->GetObjectClass(sequence), "toString", "()Ljava/lang/String;");
jstring string = reinterpret_cast<jstring>(env->CallObjectMethod(sequence, mid));
const char* utf = env->GetStringUTFChars(string, 0);
if (utf) {
char* text = SDL_strdup(utf);
env->ReleaseStringUTFChars(string, utf);
return text;
}
}
return SDL_strdup("");
}
extern "C" SDL_bool Android_JNI_HasClipboardText()
{
SETUP_CLIPBOARD(SDL_FALSE)
jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "hasText", "()Z");
jboolean has = env->CallBooleanMethod(clipboard, mid);
env->DeleteGlobalRef(clipboard);
return has ? SDL_TRUE : SDL_FALSE;
}
// returns 0 on success or -1 on error (others undefined then)
// returns truthy or falsy value in plugged, charged and battery
// returns the value in seconds and percent or -1 if not available

View file

@ -47,6 +47,11 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t ma
size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, size_t num);
int Android_JNI_FileClose(SDL_RWops* ctx);
/* Clipboard support */
int Android_JNI_SetClipboardText(const char* text);
char* Android_JNI_GetClipboardText();
SDL_bool Android_JNI_HasClipboardText();
/* Power support */
int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent);

View file

@ -0,0 +1,26 @@
#include "SDL_config.h"
#if SDL_VIDEO_DRIVER_ANDROID
#include "SDL_androidvideo.h"
#include "../../core/android/SDL_android.h"
int
Android_SetClipboardText(_THIS, const char *text)
{
return Android_JNI_SetClipboardText(text);
}
char *
Android_GetClipboardText(_THIS)
{
return Android_JNI_GetClipboardText();
}
SDL_bool Android_HasClipboardText(_THIS)
{
return Android_JNI_HasClipboardText();
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View file

@ -0,0 +1,10 @@
#include "SDL_config.h"
#ifndef _SDL_androidclipboard_h
#define _SDL_androidclipboard_h
extern int Android_SetClipboardText(_THIS, const char *text);
extern char *Android_GetClipboardText(_THIS);
extern SDL_bool Android_HasClipboardText(_THIS);
#endif /* _SDL_androidclipboard_h */

View file

@ -33,6 +33,7 @@
#include "../../events/SDL_windowevents_c.h"
#include "SDL_androidvideo.h"
#include "SDL_androidclipboard.h"
#include "SDL_androidevents.h"
#include "SDL_androidkeyboard.h"
#include "SDL_androidwindow.h"
@ -126,6 +127,11 @@ Android_CreateDevice(int devindex)
device->SDL_ToggleScreenKeyboard = Android_ToggleScreenKeyboard;
device->SDL_IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
/* Clipboard */
device->SetClipboardText = Android_SetClipboardText;
device->GetClipboardText = Android_GetClipboardText;
device->HasClipboardText = Android_HasClipboardText;
return device;
}