diff options
| author | Po Lu | 2023-01-24 10:34:40 +0800 |
|---|---|---|
| committer | Po Lu | 2023-01-24 10:34:40 +0800 |
| commit | 4de6b187933479ce93b6079f42a485e5868f01a5 (patch) | |
| tree | db3e4cbeb5487a8397e686e9a242fdeb90fad43a /src/androidselect.c | |
| parent | 9d3aacedf0c217af207d39e390f376914160396b (diff) | |
| download | emacs-4de6b187933479ce93b6079f42a485e5868f01a5.tar.gz emacs-4de6b187933479ce93b6079f42a485e5868f01a5.zip | |
Update Android port
* .gitignore: Update with new files. Do not ignore std*.in.h.
* INSTALL.android: Explain how to build Emacs with external
dependencies.
* Makefile.in (xcompile, cross): Rename to `cross'.
(clean_dirs): Clean cross, not xcompile.
* README: Document new directories.
* build-aux/ndk-build-helper-1.mk (build_kind, NDK_SO_NAMES):
* build-aux/ndk-build-helper-2.mk (build_kind, NDK_SO_NAMES):
* build-aux/ndk-build-helper-3.mk (build_kind):
* build-aux/ndk-build-helper-4.mk:
* build-aux/ndk-build-helper.mk (NDK_BUILD_DIR, my-dir):
* build-aux/ndk-module-extract.awk: New files.
* configure.ac: Set up libgif, libwebp, and libpng for
ndk-build.
* cross/ndk-build/Makefile.in (srcdir, NDK_BUILD_ANDROID_MK):
* cross/ndk-build/ndk-build-executable.mk:
* cross/ndk-build/ndk-build-shared-library.mk (eq, objname):
* cross/ndk-build/ndk-build-static-library.mk (eq, objname):
* cross/ndk-build/ndk-build.in (NDK_BUILD_MODULES):
* cross/ndk-build/ndk-build.mk.in (NDK_BUILD_MODULES)
(NDK_BUILD_SHARED):
* cross/ndk-build/ndk-clear-vars.mk:
* cross/ndk-build/ndk-prebuilt-shared-library.mk:
* cross/ndk-build/ndk-prebuilt-static-library.mk: New files.
* doc/emacs/android.texi (Android, Android Environment):
Document clipboard support on Android.
* doc/emacs/emacs.texi (Top): Update menus.
* etc/MACHINES: Document Android.
* java/AndroidManifest.xml.in: Respect new
`--with-android-debug' option.
* java/Makefile.in (CROSS_BINS, CROSS_LIBS): Adjust for rename.
Include ndk-build.mk.:(emacs.apk-in): Depend on shared
libraries. Then, package shared libraries.
* java/org/gnu/emacs/EmacsClipboard.java (EmacsClipboard): New
class.
* java/org/gnu/emacs/EmacsFontDriver.java: Update comment to say
this is unused.
* java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
function `sendExpose'.
* java/org/gnu/emacs/EmacsSdk11Clipboard.java
(EmacsSdk11Clipboard):
* java/org/gnu/emacs/EmacsSdk8Clipboard.java
(EmacsSdk8Clipboard): New classes.
* java/org/gnu/emacs/EmacsView.java (EmacsView, handleDirtyBitmap)
(onDetachedFromWindow): When window is reattached, expose the
frame.
* lib/Makefile.in (VPATH):
(ALL_CFLAGS): Adjust for rename.
* lisp/term/android-win.el (android-clipboard-exists-p)
(android-get-clipboard, android-set-clipboard)
(android-clipboard-owner-p, android-primary-selection)
(android-get-clipboard-1, android-get-primary)
(android-selection-bounds, android-encode-select-string)
(gui-backend-get-selection, gui-backend-selection-exists-p)
(gui-backend-selection-owner-p, gui-backend-set-selection): New
functions.
* m4/ndk-build.m4: New file.
* src/Makefile.in (GIF_CFLAGS, ANDROID_LDFLAGS): New variables.
(EMACS_CFLAGS): Add GIF_CFLAGS. Include
ndk-build.mk.
(libemacs.so): Depend on and link with required
libraries.
* src/android.c (android_check_compressed_file): New function.
(android_open): Work around Android platform bug.
(sendExpose): New function.
(android_readdir): Set d_type if this is a directory.
* src/androidgui.h (enum android_event_type)
(struct android_expose_event, union android_event): Add expose
events.
* src/androidselect.c (struct android_emacs_clipboard)
(android_init_emacs_clipboard, Fandroid_clipboard_owner_p)
(Fandroid_set_clipboard, Fandroid_get_clipboard)
(Fandroid_clipboard_exists_p, init_androidselect)
(syms_of_androidselect): New file.
* src/androidterm.c (handle_one_android_event): Handle
exposures.
* src/androidterm.h: Update prototypes.
* src/emacs.c (android_emacs_init): Initialize androidselect.
Diffstat (limited to 'src/androidselect.c')
| -rw-r--r-- | src/androidselect.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/androidselect.c b/src/androidselect.c new file mode 100644 index 00000000000..4a71b376e28 --- /dev/null +++ b/src/androidselect.c | |||
| @@ -0,0 +1,249 @@ | |||
| 1 | /* Communication module for Android terminals. | ||
| 2 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | #include <assert.h> | ||
| 22 | |||
| 23 | #include "lisp.h" | ||
| 24 | #include "blockinput.h" | ||
| 25 | #include "coding.h" | ||
| 26 | #include "android.h" | ||
| 27 | #include "androidterm.h" | ||
| 28 | |||
| 29 | /* Selection support on Android is confined to copying and pasting of | ||
| 30 | plain text from the clipboard. There is no primary selection. | ||
| 31 | |||
| 32 | While newer versions of Android are supposed to have the necessary | ||
| 33 | interfaces for transferring other kinds of selection data, doing so | ||
| 34 | is too complicated, and involves registering ``content providers'' | ||
| 35 | and all kinds of other stuff. */ | ||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | /* Structure describing the EmacsClipboard class. */ | ||
| 40 | |||
| 41 | struct android_emacs_clipboard | ||
| 42 | { | ||
| 43 | jclass class; | ||
| 44 | jmethodID set_clipboard; | ||
| 45 | jmethodID owns_clipboard; | ||
| 46 | jmethodID clipboard_exists; | ||
| 47 | jmethodID get_clipboard; | ||
| 48 | jmethodID make_clipboard; | ||
| 49 | }; | ||
| 50 | |||
| 51 | /* Methods associated with the EmacsClipboard class. */ | ||
| 52 | static struct android_emacs_clipboard clipboard_class; | ||
| 53 | |||
| 54 | /* Reference to the EmacsClipboard object. */ | ||
| 55 | static jobject clipboard; | ||
| 56 | |||
| 57 | |||
| 58 | |||
| 59 | static void | ||
| 60 | android_init_emacs_clipboard (void) | ||
| 61 | { | ||
| 62 | jclass old; | ||
| 63 | |||
| 64 | clipboard_class.class | ||
| 65 | = (*android_java_env)->FindClass (android_java_env, | ||
| 66 | "org/gnu/emacs/EmacsClipboard"); | ||
| 67 | eassert (clipboard_class.class); | ||
| 68 | |||
| 69 | old = clipboard_class.class; | ||
| 70 | clipboard_class.class | ||
| 71 | = (jclass) (*android_java_env)->NewGlobalRef (android_java_env, | ||
| 72 | old); | ||
| 73 | ANDROID_DELETE_LOCAL_REF (old); | ||
| 74 | |||
| 75 | if (!clipboard_class.class) | ||
| 76 | emacs_abort (); | ||
| 77 | |||
| 78 | #define FIND_METHOD(c_name, name, signature) \ | ||
| 79 | clipboard_class.c_name \ | ||
| 80 | = (*android_java_env)->GetMethodID (android_java_env, \ | ||
| 81 | clipboard_class.class, \ | ||
| 82 | name, signature); \ | ||
| 83 | assert (clipboard_class.c_name); | ||
| 84 | |||
| 85 | FIND_METHOD (set_clipboard, "setClipboard", "([B)V"); | ||
| 86 | FIND_METHOD (owns_clipboard, "ownsClipboard", "()I"); | ||
| 87 | FIND_METHOD (clipboard_exists, "clipboardExists", "()Z"); | ||
| 88 | FIND_METHOD (get_clipboard, "getClipboard", "()[B"); | ||
| 89 | |||
| 90 | clipboard_class.make_clipboard | ||
| 91 | = (*android_java_env)->GetStaticMethodID (android_java_env, | ||
| 92 | clipboard_class.class, | ||
| 93 | "makeClipboard", | ||
| 94 | "()Lorg/gnu/emacs/" | ||
| 95 | "EmacsClipboard;"); | ||
| 96 | assert (clipboard_class.make_clipboard); | ||
| 97 | |||
| 98 | #undef FIND_METHOD | ||
| 99 | } | ||
| 100 | |||
| 101 | |||
| 102 | |||
| 103 | |||
| 104 | DEFUN ("android-clipboard-owner-p", Fandroid_clipboard_owner_p, | ||
| 105 | Sandroid_clipboard_owner_p, 0, 0, 0, | ||
| 106 | doc: /* Return whether or not Emacs owns the clipboard. | ||
| 107 | Alternatively, return the symbol `lambda' if that could not be | ||
| 108 | determined. */) | ||
| 109 | (void) | ||
| 110 | { | ||
| 111 | jint rc; | ||
| 112 | |||
| 113 | block_input (); | ||
| 114 | rc = (*android_java_env)->CallIntMethod (android_java_env, | ||
| 115 | clipboard, | ||
| 116 | clipboard_class.owns_clipboard); | ||
| 117 | android_exception_check (); | ||
| 118 | unblock_input (); | ||
| 119 | |||
| 120 | /* If rc is 0 or 1, then Emacs knows whether or not it owns the | ||
| 121 | clipboard. If rc is -1, then Emacs does not. */ | ||
| 122 | |||
| 123 | if (rc < 0) | ||
| 124 | return Qlambda; | ||
| 125 | |||
| 126 | return rc ? Qt : Qnil; | ||
| 127 | } | ||
| 128 | |||
| 129 | DEFUN ("android-set-clipboard", Fandroid_set_clipboard, | ||
| 130 | Sandroid_set_clipboard, 1, 1, 0, | ||
| 131 | doc: /* Set the clipboard text to STRING. */) | ||
| 132 | (Lisp_Object string) | ||
| 133 | { | ||
| 134 | jarray bytes; | ||
| 135 | |||
| 136 | CHECK_STRING (string); | ||
| 137 | string = ENCODE_UTF_8 (string); | ||
| 138 | |||
| 139 | bytes = (*android_java_env)->NewByteArray (android_java_env, | ||
| 140 | SBYTES (string)); | ||
| 141 | android_exception_check (); | ||
| 142 | |||
| 143 | (*android_java_env)->SetByteArrayRegion (android_java_env, bytes, | ||
| 144 | 0, SBYTES (string), | ||
| 145 | (jbyte *) SDATA (string)); | ||
| 146 | (*android_java_env)->CallVoidMethod (android_java_env, | ||
| 147 | clipboard, | ||
| 148 | clipboard_class.set_clipboard, | ||
| 149 | bytes); | ||
| 150 | android_exception_check (); | ||
| 151 | |||
| 152 | ANDROID_DELETE_LOCAL_REF (bytes); | ||
| 153 | return Qnil; | ||
| 154 | } | ||
| 155 | |||
| 156 | DEFUN ("android-get-clipboard", Fandroid_get_clipboard, | ||
| 157 | Sandroid_get_clipboard, 0, 0, 0, | ||
| 158 | doc: /* Return the current contents of the clipboard. | ||
| 159 | Value is a multibyte string containing decoded clipboard | ||
| 160 | text. | ||
| 161 | Alternatively, return nil if the clipboard is empty. */) | ||
| 162 | (void) | ||
| 163 | { | ||
| 164 | Lisp_Object string; | ||
| 165 | jarray bytes; | ||
| 166 | jmethodID method; | ||
| 167 | size_t length; | ||
| 168 | jbyte *data; | ||
| 169 | |||
| 170 | method = clipboard_class.get_clipboard; | ||
| 171 | bytes | ||
| 172 | = (*android_java_env)->CallObjectMethod (android_java_env, | ||
| 173 | clipboard, | ||
| 174 | method); | ||
| 175 | |||
| 176 | if (!bytes) | ||
| 177 | { | ||
| 178 | android_exception_check (); | ||
| 179 | return Qnil; | ||
| 180 | } | ||
| 181 | |||
| 182 | length = (*android_java_env)->GetArrayLength (android_java_env, | ||
| 183 | bytes); | ||
| 184 | data = (*android_java_env)->GetByteArrayElements (android_java_env, | ||
| 185 | bytes, NULL); | ||
| 186 | android_exception_check (); | ||
| 187 | |||
| 188 | string = make_unibyte_string ((char *) data, length); | ||
| 189 | |||
| 190 | (*android_java_env)->ReleaseByteArrayElements (android_java_env, | ||
| 191 | bytes, data, | ||
| 192 | JNI_ABORT); | ||
| 193 | ANDROID_DELETE_LOCAL_REF (bytes); | ||
| 194 | |||
| 195 | /* Now decode the resulting string. */ | ||
| 196 | return code_convert_string_norecord (string, Qutf_8, Qnil); | ||
| 197 | } | ||
| 198 | |||
| 199 | DEFUN ("android-clipboard-exists-p", Fandroid_clipboard_exists_p, | ||
| 200 | Sandroid_clipboard_exists_p, 0, 0, 0, | ||
| 201 | doc: /* Return whether or not clipboard contents exist. */) | ||
| 202 | (void) | ||
| 203 | { | ||
| 204 | jboolean rc; | ||
| 205 | jmethodID method; | ||
| 206 | |||
| 207 | method = clipboard_class.clipboard_exists; | ||
| 208 | rc = (*android_java_env)->CallBooleanMethod (android_java_env, | ||
| 209 | clipboard, | ||
| 210 | method); | ||
| 211 | android_exception_check (); | ||
| 212 | |||
| 213 | return rc ? Qt : Qnil; | ||
| 214 | } | ||
| 215 | |||
| 216 | |||
| 217 | |||
| 218 | void | ||
| 219 | init_androidselect (void) | ||
| 220 | { | ||
| 221 | jobject tem; | ||
| 222 | jmethodID make_clipboard; | ||
| 223 | |||
| 224 | android_init_emacs_clipboard (); | ||
| 225 | |||
| 226 | make_clipboard = clipboard_class.make_clipboard; | ||
| 227 | tem | ||
| 228 | = (*android_java_env)->CallStaticObjectMethod (android_java_env, | ||
| 229 | clipboard_class.class, | ||
| 230 | make_clipboard); | ||
| 231 | if (!tem) | ||
| 232 | emacs_abort (); | ||
| 233 | |||
| 234 | clipboard = (*android_java_env)->NewGlobalRef (android_java_env, tem); | ||
| 235 | |||
| 236 | if (!clipboard) | ||
| 237 | emacs_abort (); | ||
| 238 | |||
| 239 | ANDROID_DELETE_LOCAL_REF (tem); | ||
| 240 | } | ||
| 241 | |||
| 242 | void | ||
| 243 | syms_of_androidselect (void) | ||
| 244 | { | ||
| 245 | defsubr (&Sandroid_clipboard_owner_p); | ||
| 246 | defsubr (&Sandroid_set_clipboard); | ||
| 247 | defsubr (&Sandroid_get_clipboard); | ||
| 248 | defsubr (&Sandroid_clipboard_exists_p); | ||
| 249 | } | ||