summaryrefslogtreecommitdiff
path: root/java/org/gnu/emacs/EmacsNative.java
blob: 654e94b1a7d3f6fc61c16be8e8ef3d99d4f97e56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/* Communication module for Android terminals.  -*- c-file-style: "GNU" -*-

Copyright (C) 2023-2024 Free Software Foundation, Inc.

This file is part of GNU Emacs.

GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */

package org.gnu.emacs;

import android.content.res.AssetManager;

import android.graphics.Bitmap;

import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.SurroundingText;
import android.view.inputmethod.TextAttribute;
import android.view.inputmethod.TextSnapshot;

public final class EmacsNative
{
  /* List of native libraries that must be loaded during class
     initialization.  */
  private static final String[] libraryDeps;


  /* Like `dup' in C.  */
  public static native int dup (int fd);

  /* Like `close' in C.  */
  public static native int close (int fd);

  /* Obtain the fingerprint of this build of Emacs.  The fingerprint
     can be used to determine the dump file name.  */
  public static native String getFingerprint ();

  /* Set certain parameters before initializing Emacs.

     assetManager must be the asset manager associated with the
     context that is loading Emacs.  It is saved and remains for the
     remainder the lifetime of the Emacs process.

     filesDir must be the package's data storage location for the
     current Android user.

     libDir must be the package's data storage location for native
     libraries.  It is used as PATH.

     cacheDir must be the package's cache directory.  It is used as
     the `temporary-file-directory'.

     pixelDensityX and pixelDensityY are the DPI values that will be
     used by Emacs.

     scaledDensity is the DPI value used to translate point sizes to
     pixel sizes when loading fonts.

     classPath must be the classpath of this app_process process, or
     NULL.

     emacsService must be the EmacsService singleton, or NULL.

     apiLevel is the version of Android being run.  */
  public static native void setEmacsParams (AssetManager assetManager,
					    String filesDir,
					    String libDir,
					    String cacheDir,
					    float pixelDensityX,
					    float pixelDensityY,
					    float scaledDensity,
					    String classPath,
					    EmacsService emacsService,
					    int apiLevel);

  /* Initialize Emacs with the argument array ARGV.  Each argument
     must contain a NULL terminated string, or else the behavior is
     undefined.

     DUMPFILE is the dump file to use, or NULL if Emacs is to load
     loadup.el itself.  */
  public static native void initEmacs (String argv[], String dumpFile);

  /* Call shut_down_emacs to auto-save and unlock files in the main
     thread, then return.  */
  public static native void shutDownEmacs ();

  /* Garbage collect and clear each frame's image cache.  */
  public static native void onLowMemory ();

  /* Abort and generate a native core dump.  */
  public static native void emacsAbort ();

  /* Set Vquit_flag to t, resulting in Emacs quitting as soon as
     possible.  */
  public static native void quit ();

  /* Send an ANDROID_CONFIGURE_NOTIFY event.  The values of all the
     functions below are the serials of the events sent.  */
  public static native long sendConfigureNotify (short window, long time,
						 int x, int y, int width,
						 int height);

  /* Send an ANDROID_KEY_PRESS event.  */
  public static native long sendKeyPress (short window, long time, int state,
					  int keyCode, int unicodeChar);

  /* Send an ANDROID_KEY_RELEASE event.  */
  public static native long sendKeyRelease (short window, long time, int state,
					    int keyCode, int unicodeChar);

  /* Send an ANDROID_FOCUS_IN event.  */
  public static native long sendFocusIn (short window, long time);

  /* Send an ANDROID_FOCUS_OUT event.  */
  public static native long sendFocusOut (short window, long time);

  /* Send an ANDROID_WINDOW_ACTION event.  */
  public static native long sendWindowAction (short window, int action);

  /* Send an ANDROID_ENTER_NOTIFY event.  */
  public static native long sendEnterNotify (short window, int x, int y,
					     long time);

  /* Send an ANDROID_LEAVE_NOTIFY event.  */
  public static native long sendLeaveNotify (short window, int x, int y,
					     long time);

  /* Send an ANDROID_MOTION_NOTIFY event.  */
  public static native long sendMotionNotify (short window, int x, int y,
					      long time);

  /* Send an ANDROID_BUTTON_PRESS event.  */
  public static native long sendButtonPress (short window, int x, int y,
					     long time, int state,
					     int button);

  /* Send an ANDROID_BUTTON_RELEASE event.  */
  public static native long sendButtonRelease (short window, int x, int y,
					       long time, int state,
					       int button);

  /* Send an ANDROID_TOUCH_DOWN event.  */
  public static native long sendTouchDown (short window, int x, int y,
					   long time, int pointerID,
					   int flags);

  /* Send an ANDROID_TOUCH_UP event.  */
  public static native long sendTouchUp (short window, int x, int y,
					 long time, int pointerID,
					 int flags);

  /* Send an ANDROID_TOUCH_MOVE event.  */
  public static native long sendTouchMove (short window, int x, int y,
					   long time, int pointerID,
					   int flags);

  /* Send an ANDROID_WHEEL event.  */
  public static native long sendWheel (short window, int x, int y,
				       long time, int state,
				       float xDelta, float yDelta);

  /* Send an ANDROID_ICONIFIED event.  */
  public static native long sendIconified (short window);

  /* Send an ANDROID_DEICONIFIED event.  */
  public static native long sendDeiconified (short window);

  /* Send an ANDROID_CONTEXT_MENU event.  */
  public static native long sendContextMenu (short window, int menuEventID,
					     int menuEventSerial);

  /* Send an ANDROID_EXPOSE event.  */
  public static native long sendExpose (short window, int x, int y,
					int width, int height);

  /* Send an ANDROID_DND_DRAG event.  */
  public static native long sendDndDrag (short window, int x, int y);

  /* Send an ANDROID_DND_URI event.  */
  public static native long sendDndUri (short window, int x, int y,
					String text);

  /* Send an ANDROID_DND_TEXT event.  */
  public static native long sendDndText (short window, int x, int y,
					 String text);

  /* Send an ANDROID_NOTIFICATION_CANCELED event.  */
  public static native void sendNotificationDeleted (String tag);

  /* Send an ANDROID_NOTIFICATION_ACTION event.  */
  public static native void sendNotificationAction (String tag, String action);

  /* Return the file name associated with the specified file
     descriptor, or NULL if there is none.  */
  public static native byte[] getProcName (int fd);

  /* Notice that the Emacs thread will now start waiting for the main
     thread's looper to respond.  */
  public static native void beginSynchronous ();

  /* Notice that the Emacs thread will has finished waiting for the
     main thread's looper to respond.  */
  public static native void endSynchronous ();

  /* Prevent deadlocks while reliably allowing queries from the Emacs
     thread to the main thread to complete by waiting for a query to
     start from the main thread, then answer it; assume that a query
     is certain to start shortly.  */
  public static native void answerQuerySpin ();

  /* Return whether or not KEYCODE_VOLUME_DOWN, KEYCODE_VOLUME_UP and
     KEYCODE_VOLUME_MUTE should be forwarded to Emacs.  */
  public static native boolean shouldForwardMultimediaButtons ();

  /* Return whether KEYCODE_SPACE combined with META_CTRL_MASK should
     be prevented from reaching the system input method.  */
  public static native boolean shouldForwardCtrlSpace ();

  /* Initialize the current thread, by blocking signals that do not
     interest it.  */
  public static native void setupSystemThread ();



  /* Input connection functions.  These mostly correspond to their
     counterparts in Android's InputConnection.  */

  public static native void beginBatchEdit (short window);
  public static native void endBatchEdit (short window);
  public static native void commitCompletion (short window, String text,
					      int position);
  public static native void commitText (short window, String text,
					int position);
  public static native void deleteSurroundingText (short window,
						   int leftLength,
						   int rightLength);
  public static native void finishComposingText (short window);
  public static native void replaceText (short window, int start, int end,
					 String text, int newCursorPosition,
					 TextAttribute attributes);
  public static native String getSelectedText (short window, int flags);
  public static native String getTextAfterCursor (short window, int length,
						  int flags);
  public static native String getTextBeforeCursor (short window, int length,
						   int flags);
  public static native void setComposingText (short window, String text,
					      int newCursorPosition);
  public static native void setComposingRegion (short window, int start,
						int end);
  public static native void setSelection (short window, int start, int end);
  public static native void performEditorAction (short window,
						 int editorAction);
  public static native void performContextMenuAction (short window,
						      int contextMenuAction);
  public static native ExtractedText getExtractedText (short window,
						       ExtractedTextRequest req,
						       int flags);
  public static native void requestSelectionUpdate (short window);
  public static native void requestCursorUpdates (short window, int mode);
  public static native void clearInputFlags (short window);
  public static native SurroundingText getSurroundingText (short window,
							   int left, int right,
							   int flags);
  public static native TextSnapshot takeSnapshot (short window);


  /* Return the current value of the selection, or -1 upon
     failure.  */
  public static native int[] getSelection (short window);


  /* Graphics functions used as replacements for potentially buggy
     Android APIs.  */

  public static native void blitRect (Bitmap src, Bitmap dest, int x1,
				      int y1, int x2, int y2);

  /* Increment the generation ID of the specified BITMAP, forcing its
     texture to be re-uploaded to the GPU.  */
  public static native void notifyPixelsChanged (Bitmap bitmap);


  /* Functions used to synchronize document provider access with the
     main thread.  */

  /* Wait for a call to `safPostRequest' while also reading async
     input.

     If asynchronous input arrives and sets Vquit_flag, return 1.  */
  public static native int safSyncAndReadInput ();

  /* Wait for a call to `safPostRequest'.  */
  public static native void safSync ();

  /* Post the semaphore used to await the completion of SAF
     operations.  */
  public static native void safPostRequest ();

  /* Detect and return FD is writable.  FD may be truncated to 0 bytes
     in the process.  */
  public static native boolean ftruncate (int fd);


  /* Functions that assist in generating content file names.  */

  /* Calculate an 8 digit checksum for the byte array DISPLAYNAME
     suitable for inclusion in a content file name.  */
  public static native String displayNameHash (byte[] displayName);

  static
  {
    /* Older versions of Android cannot link correctly with shared
       libraries that link with other shared libraries built along
       Emacs unless all requisite shared libraries are explicitly
       loaded from Java.

       Every time you add a new shared library dependency to Emacs,
       please add it here as well.  */

    libraryDeps = new String[] { "c++_shared", "gnustl_shared",
				 "stlport_shared", "gabi++_shared",
				 "png_emacs", "selinux_emacs",
				 "crypto_emacs", "pcre_emacs",
				 "packagelistparser_emacs",
				 "gnutls_emacs", "gmp_emacs",
				 "nettle_emacs", "p11-kit_emacs",
				 "tasn1_emacs", "hogweed_emacs",
				 "jansson_emacs", "jpeg_emacs",
				 "tiff_emacs", "xml2_emacs",
				 "icuuc_emacs", "harfbuzz_emacs",
				 "tree-sitter_emacs", };

    for (String dependency : libraryDeps)
      {
	try
	  {
	    System.loadLibrary (dependency);
	  }
	catch (UnsatisfiedLinkError exception)
	  {
	    /* Ignore this exception.  */
	  }
      }

    System.loadLibrary ("emacs");
  };
};