diff options
| author | Po Lu | 2023-04-06 09:56:23 +0800 |
|---|---|---|
| committer | Po Lu | 2023-04-06 09:56:23 +0800 |
| commit | 3b07a4b3158d024c6eb19ce0e7c67b799ae0d1fc (patch) | |
| tree | 079cb506217df20375835aa72c4bc52095c8c716 /java | |
| parent | 458c6e5c9171f41f327ef88f4a4999db586f8e91 (diff) | |
| download | emacs-3b07a4b3158d024c6eb19ce0e7c67b799ae0d1fc.tar.gz emacs-3b07a4b3158d024c6eb19ce0e7c67b799ae0d1fc.zip | |
Implement `yank-media' on Android
* doc/emacs/android.texi (Android Windowing): Update selection
restrictions.
* java/org/gnu/emacs/EmacsClipboard.java (EmacsClipboard): New
functions `getClipboardTargets' and `getClipboardData'.
* java/org/gnu/emacs/EmacsSdk11Clipboard.java
(EmacsSdk11Clipboard, getClipboardTargets, getClipboardData):
Implement.
* java/org/gnu/emacs/EmacsSdk8Clipboard.java: Stub out new
functions.
* lisp/term/android-win.el (android-get-clipboard-1): Implement
MIME type targets.
* src/android.c (android_exception_check)
(android_exception_check_1, android_exception_check_2): Fix
punctuation in warning message.
(android_exception_check_nonnull_1): New function.
* src/android.h: Update prototypes.
* src/androidselect.c (struct android_emacs_clipboard): New
methods.
(android_init_emacs_clipboard): Initialize new methods.
(Fandroid_get_clipboard_targets, android_xfree_inside)
(Fandroid_get_clipboard_data): New functions.
(syms_of_androidselect): Define new subrs.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsClipboard.java | 3 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsSdk11Clipboard.java | 130 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsSdk8Clipboard.java | 29 |
3 files changed, 162 insertions, 0 deletions
diff --git a/java/org/gnu/emacs/EmacsClipboard.java b/java/org/gnu/emacs/EmacsClipboard.java index cd6bcebfe0e..5cd48af6e3a 100644 --- a/java/org/gnu/emacs/EmacsClipboard.java +++ b/java/org/gnu/emacs/EmacsClipboard.java | |||
| @@ -31,6 +31,9 @@ public abstract class EmacsClipboard | |||
| 31 | public abstract boolean clipboardExists (); | 31 | public abstract boolean clipboardExists (); |
| 32 | public abstract byte[] getClipboard (); | 32 | public abstract byte[] getClipboard (); |
| 33 | 33 | ||
| 34 | public abstract byte[][] getClipboardTargets (); | ||
| 35 | public abstract long[] getClipboardData (byte[] target); | ||
| 36 | |||
| 34 | /* Create the correct kind of clipboard for this system. */ | 37 | /* Create the correct kind of clipboard for this system. */ |
| 35 | 38 | ||
| 36 | public static EmacsClipboard | 39 | public static EmacsClipboard |
diff --git a/java/org/gnu/emacs/EmacsSdk11Clipboard.java b/java/org/gnu/emacs/EmacsSdk11Clipboard.java index a05184513cd..4959ec36eed 100644 --- a/java/org/gnu/emacs/EmacsSdk11Clipboard.java +++ b/java/org/gnu/emacs/EmacsSdk11Clipboard.java | |||
| @@ -21,12 +21,20 @@ package org.gnu.emacs; | |||
| 21 | 21 | ||
| 22 | import android.content.ClipboardManager; | 22 | import android.content.ClipboardManager; |
| 23 | import android.content.Context; | 23 | import android.content.Context; |
| 24 | import android.content.ContentResolver; | ||
| 24 | import android.content.ClipData; | 25 | import android.content.ClipData; |
| 26 | import android.content.ClipDescription; | ||
| 27 | |||
| 28 | import android.content.res.AssetFileDescriptor; | ||
| 29 | |||
| 30 | import android.net.Uri; | ||
| 25 | 31 | ||
| 26 | import android.util.Log; | 32 | import android.util.Log; |
| 27 | 33 | ||
| 28 | import android.os.Build; | 34 | import android.os.Build; |
| 29 | 35 | ||
| 36 | import java.io.FileNotFoundException; | ||
| 37 | import java.io.IOException; | ||
| 30 | import java.io.UnsupportedEncodingException; | 38 | import java.io.UnsupportedEncodingException; |
| 31 | 39 | ||
| 32 | /* This class implements EmacsClipboard for Android 3.0 and later | 40 | /* This class implements EmacsClipboard for Android 3.0 and later |
| @@ -40,6 +48,7 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard | |||
| 40 | private boolean ownsClipboard; | 48 | private boolean ownsClipboard; |
| 41 | private int clipboardChangedCount; | 49 | private int clipboardChangedCount; |
| 42 | private int monitoredClipboardChangedCount; | 50 | private int monitoredClipboardChangedCount; |
| 51 | private ContentResolver resolver; | ||
| 43 | 52 | ||
| 44 | public | 53 | public |
| 45 | EmacsSdk11Clipboard () | 54 | EmacsSdk11Clipboard () |
| @@ -51,6 +60,11 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard | |||
| 51 | 60 | ||
| 52 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) | 61 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) |
| 53 | manager.addPrimaryClipChangedListener (this); | 62 | manager.addPrimaryClipChangedListener (this); |
| 63 | |||
| 64 | /* Now obtain the content resolver used to open file | ||
| 65 | descriptors. */ | ||
| 66 | |||
| 67 | resolver = EmacsService.SERVICE.getContentResolver (); | ||
| 54 | } | 68 | } |
| 55 | 69 | ||
| 56 | @Override | 70 | @Override |
| @@ -157,4 +171,120 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard | |||
| 157 | 171 | ||
| 158 | return null; | 172 | return null; |
| 159 | } | 173 | } |
| 174 | |||
| 175 | /* Return an array of targets currently provided by the | ||
| 176 | clipboard, or NULL if there are none. */ | ||
| 177 | |||
| 178 | @Override | ||
| 179 | public byte[][] | ||
| 180 | getClipboardTargets () | ||
| 181 | { | ||
| 182 | ClipData clip; | ||
| 183 | ClipDescription description; | ||
| 184 | byte[][] typeArray; | ||
| 185 | int i; | ||
| 186 | |||
| 187 | /* N.B. that Android calls the clipboard the ``primary clip''; it | ||
| 188 | is not related to the X primary selection. */ | ||
| 189 | clip = manager.getPrimaryClip (); | ||
| 190 | description = clip.getDescription (); | ||
| 191 | i = description.getMimeTypeCount (); | ||
| 192 | typeArray = new byte[i][i]; | ||
| 193 | |||
| 194 | try | ||
| 195 | { | ||
| 196 | for (i = 0; i < description.getMimeTypeCount (); ++i) | ||
| 197 | typeArray[i] = description.getMimeType (i).getBytes ("UTF-8"); | ||
| 198 | } | ||
| 199 | catch (UnsupportedEncodingException exception) | ||
| 200 | { | ||
| 201 | return null; | ||
| 202 | } | ||
| 203 | |||
| 204 | return typeArray; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* Return the clipboard data for the given target, or NULL if it | ||
| 208 | does not exist. | ||
| 209 | |||
| 210 | Value is normally an array of three longs: the file descriptor, | ||
| 211 | the start offset of the data, and its length; length may be | ||
| 212 | AssetFileDescriptor.UNKOWN_LENGTH, meaning that the data extends | ||
| 213 | from that offset to the end of the file. | ||
| 214 | |||
| 215 | Do not use this function to open text targets; use `getClipboard' | ||
| 216 | for that instead, as it will handle selection data consisting | ||
| 217 | solely of a URI. */ | ||
| 218 | |||
| 219 | @Override | ||
| 220 | public long[] | ||
| 221 | getClipboardData (byte[] target) | ||
| 222 | { | ||
| 223 | ClipData data; | ||
| 224 | String mimeType; | ||
| 225 | int fd; | ||
| 226 | AssetFileDescriptor assetFd; | ||
| 227 | Uri uri; | ||
| 228 | long[] value; | ||
| 229 | |||
| 230 | /* Decode the target given by Emacs. */ | ||
| 231 | try | ||
| 232 | { | ||
| 233 | mimeType = new String (target, "UTF-8"); | ||
| 234 | } | ||
| 235 | catch (UnsupportedEncodingException exception) | ||
| 236 | { | ||
| 237 | return null; | ||
| 238 | } | ||
| 239 | |||
| 240 | Log.d (TAG, "getClipboardData: "+ mimeType); | ||
| 241 | |||
| 242 | /* Now obtain the clipboard data and the data corresponding to | ||
| 243 | that MIME type. */ | ||
| 244 | |||
| 245 | data = manager.getPrimaryClip (); | ||
| 246 | |||
| 247 | if (data.getItemCount () < 1) | ||
| 248 | return null; | ||
| 249 | |||
| 250 | try | ||
| 251 | { | ||
| 252 | uri = data.getItemAt (0).getUri (); | ||
| 253 | |||
| 254 | if (uri == null) | ||
| 255 | return null; | ||
| 256 | |||
| 257 | Log.d (TAG, "getClipboardData: "+ uri); | ||
| 258 | |||
| 259 | /* Now open the file descriptor. */ | ||
| 260 | assetFd = resolver.openTypedAssetFileDescriptor (uri, mimeType, | ||
| 261 | null); | ||
| 262 | |||
| 263 | /* Duplicate the file descriptor. */ | ||
| 264 | fd = assetFd.getParcelFileDescriptor ().getFd (); | ||
| 265 | fd = EmacsNative.dup (fd); | ||
| 266 | |||
| 267 | /* Return the relevant information. */ | ||
| 268 | value = new long[] { fd, assetFd.getStartOffset (), | ||
| 269 | assetFd.getLength (), }; | ||
| 270 | |||
| 271 | /* Close the original offset. */ | ||
| 272 | assetFd.close (); | ||
| 273 | |||
| 274 | Log.d (TAG, "getClipboardData: "+ value); | ||
| 275 | } | ||
| 276 | catch (FileNotFoundException e) | ||
| 277 | { | ||
| 278 | return null; | ||
| 279 | } | ||
| 280 | catch (IOException e) | ||
| 281 | { | ||
| 282 | return null; | ||
| 283 | } | ||
| 284 | |||
| 285 | /* Don't return value if the file descriptor couldn't be | ||
| 286 | created. */ | ||
| 287 | |||
| 288 | return fd != -1 ? value : null; | ||
| 289 | } | ||
| 160 | }; | 290 | }; |
diff --git a/java/org/gnu/emacs/EmacsSdk8Clipboard.java b/java/org/gnu/emacs/EmacsSdk8Clipboard.java index 5a40128b0ac..9622641810f 100644 --- a/java/org/gnu/emacs/EmacsSdk8Clipboard.java +++ b/java/org/gnu/emacs/EmacsSdk8Clipboard.java | |||
| @@ -115,4 +115,33 @@ public final class EmacsSdk8Clipboard extends EmacsClipboard | |||
| 115 | 115 | ||
| 116 | return null; | 116 | return null; |
| 117 | } | 117 | } |
| 118 | |||
| 119 | /* Return an array of targets currently provided by the | ||
| 120 | clipboard, or NULL if there are none. */ | ||
| 121 | |||
| 122 | @Override | ||
| 123 | public byte[][] | ||
| 124 | getClipboardTargets () | ||
| 125 | { | ||
| 126 | return null; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* Return the clipboard data for the given target, or NULL if it | ||
| 130 | does not exist. | ||
| 131 | |||
| 132 | Value is normally an array of three longs: the file descriptor, | ||
| 133 | the start offset of the data, and its length; length may be | ||
| 134 | AssetFileDescriptor.UNKOWN_LENGTH, meaning that the data extends | ||
| 135 | from that offset to the end of the file. | ||
| 136 | |||
| 137 | Do not use this function to open text targets; use `getClipboard' | ||
| 138 | for that instead, as it will handle selection data consisting | ||
| 139 | solely of a URI. */ | ||
| 140 | |||
| 141 | @Override | ||
| 142 | public long[] | ||
| 143 | getClipboardData (byte[] target) | ||
| 144 | { | ||
| 145 | return null; | ||
| 146 | } | ||
| 118 | }; | 147 | }; |