1+ // Copyright 2021 The golang.design Initiative Authors.
2+ // All rights reserved. Use of this source code is governed
3+ // by a MIT license that can be found in the LICENSE file.
4+ //
5+ // Written by Changkun Ou <changkun.de>
6+
7+ //go:build !linux && android
8+
9+ #include <android/log.h>
10+ #include <jni.h>
11+ #include <stdlib.h>
12+ #include <string.h>
13+
14+ #define LOG_FATAL (...) __android_log_print(ANDROID_LOG_FATAL, \
15+ "GOLANG.DESIGN/X/CLIPBOARD", __VA_ARGS__)
16+
17+ static jmethodID find_method (JNIEnv * env , jclass clazz , const char * name , const char * sig ) {
18+ jmethodID m = (* env )-> GetMethodID (env , clazz , name , sig );
19+ if (m == 0 ) {
20+ (* env )-> ExceptionClear (env );
21+ LOG_FATAL ("cannot find method %s %s" , name , sig );
22+ return 0 ;
23+ }
24+ return m ;
25+ }
26+
27+ jobject get_clipboard (uintptr_t jni_env , uintptr_t ctx ) {
28+ JNIEnv * env = (JNIEnv * )jni_env ;
29+ jclass ctxClass = (* env )-> GetObjectClass (env , (jobject )ctx );
30+ jmethodID getSystemService = find_method (env , ctxClass , "getSystemService" , "(Ljava/lang/String;)Ljava/lang/Object;" );
31+
32+ jstring service = (* env )-> NewStringUTF (env , "clipboard" );
33+ jobject ret = (jobject )(* env )-> CallObjectMethod (env , (jobject )ctx , getSystemService , service );
34+ jthrowable err = (* env )-> ExceptionOccurred (env );
35+
36+ if (err != NULL ) {
37+ LOG_FATAL ("cannot find clipboard" );
38+ (* env )-> ExceptionClear (env );
39+ return NULL ;
40+ }
41+ return ret ;
42+ }
43+
44+ char * clipboard_read_string (uintptr_t java_vm , uintptr_t jni_env , uintptr_t ctx ) {
45+ JNIEnv * env = (JNIEnv * )jni_env ;
46+ jobject mgr = get_clipboard (jni_env , ctx );
47+ if (mgr == NULL ) {
48+ return NULL ;
49+ }
50+
51+ jclass mgrClass = (* env )-> GetObjectClass (env , mgr );
52+ jmethodID getText = find_method (env , mgrClass , "getText" , "()Ljava/lang/CharSequence;" );
53+
54+ jobject content = (jstring )(* env )-> CallObjectMethod (env , mgr , getText );
55+ if (content == NULL ) {
56+ return NULL ;
57+ }
58+
59+ jclass clzCharSequence = (* env )-> GetObjectClass (env , content );
60+ jmethodID toString = (* env )-> GetMethodID (env , clzCharSequence , "toString" , "()Ljava/lang/String;" );
61+ jobject s = (* env )-> CallObjectMethod (env , content , toString );
62+
63+ const char * chars = (* env )-> GetStringUTFChars (env , s , NULL );
64+ char * copy = strdup (chars );
65+ (* env )-> ReleaseStringUTFChars (env , s , chars );
66+ return copy ;
67+ }
68+
69+ void clipboard_write_string (uintptr_t java_vm , uintptr_t jni_env , uintptr_t ctx , char * str ) {
70+ JNIEnv * env = (JNIEnv * )jni_env ;
71+ jobject mgr = get_clipboard (jni_env , ctx );
72+ if (mgr == NULL ) {
73+ return ;
74+ }
75+
76+ jclass mgrClass = (* env )-> GetObjectClass (env , mgr );
77+ jmethodID setText = find_method (env , mgrClass , "setText" , "(Ljava/lang/CharSequence;)V" );
78+
79+ (* env )-> CallVoidMethod (env , mgr , setText , (* env )-> NewStringUTF (env , str ));
80+ }
0 commit comments