Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Fixed bug 1573 - SDL does not support system clipboard on Android.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
slouken committed Sep 27, 2012
1 parent 30a09c9 commit 4b4de5a
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/core/android/SDL_android.cpp
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/core/android/SDL_android.h
Expand Up @@ -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);

Expand Down
26 changes: 26 additions & 0 deletions src/video/android/SDL_androidclipboard.c
@@ -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 */
10 changes: 10 additions & 0 deletions src/video/android/SDL_androidclipboard.h
@@ -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 */
6 changes: 6 additions & 0 deletions src/video/android/SDL_androidvideo.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 4b4de5a

Please sign in to comment.