aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2023-06-17 11:24:54 +0800
committerPo Lu2023-06-17 11:24:54 +0800
commitfa821ed18639aa1b0275c2938af9987c0c71b581 (patch)
tree48348b6de19ca0989f598354e818d5df326088de /java
parent6999067034b7e2e79326db7c2243150831f0fe99 (diff)
downloademacs-fa821ed18639aa1b0275c2938af9987c0c71b581.tar.gz
emacs-fa821ed18639aa1b0275c2938af9987c0c71b581.zip
; * java/README: More documentation.
Diffstat (limited to 'java')
-rw-r--r--java/README141
1 files changed, 141 insertions, 0 deletions
diff --git a/java/README b/java/README
index 96271279c28..a6adb805b9e 100644
--- a/java/README
+++ b/java/README
@@ -906,3 +906,144 @@ of memory.
906Otherwise, it applies the specified window attributes and returns the 906Otherwise, it applies the specified window attributes and returns the
907handle of the new window. 907handle of the new window.
908} 908}
909
910
911
912DRAWABLES, CURSORS AND HANDLES
913
914Each widget created by Emacs corresponds to a single ``window'', which
915has its own backing store. This arrangement is quite similar to X.
916
917C code does not directly refer to the EmacsView widgets that implement
918the UI logic behind windows. Instead, its handles refer to
919EmacsWindow structures, which contain the state necessary to interact
920with the widgets in an orderly and synchronized manner.
921
922Like X, both pixmaps and windows are drawable resources, and the same
923graphics operations can be applied to both. Thus, a separate
924EmacsPixmap structure is used to wrap around Android Bitmap resources,
925and the Java-level graphics operation functions are capable of
926operating on them both.
927
928Finally, graphics contexts are maintained on both the C and Java
929levels; the C state recorded in `struct android_gc' is kept in sync
930with the Java state in the GContext handle's corresponding EmacsGC
931structure, and cursors are used through handles that refer to
932EmacsCursor structures that hold system PointerIcons.
933
934In all cases, the interfaces provided are identical to X.
935
936
937
938EVENT LOOP
939
940In a typical Android application, the event loop is managed by the
941operating system, and callbacks (implemented through overriding
942separate functions in widgets) are run by the event loop wherever
943necessary. The thread which runs the event loop is also the only
944thread capable of creating and manipulating widgets and activities,
945and is referred to as the ``UI thread''.
946
947These callbacks are used by Emacs to write representations of X-like
948events to a separate event queue, which are then read from Emacs's own
949event loop running in a separate thread. This is accomplished through
950replacing `select' by a function which waits for the event queue to be
951occupied, in addition to any file descriptors that `select' would
952normally wait for.
953
954Conversely, Emacs's event loop sometimes needs to send events to the
955UI thread. These events are implemented as tiny fragments of code,
956which are run as they are received by the main thread.
957
958A typical example is `displayToast', which is implemented in
959EmacsService.java:
960
961 public void
962 displayToast (final String string)
963 {
964 runOnUiThread (new Runnable () {
965 @Override
966 public void
967 run ()
968 {
969 Toast toast;
970
971 toast = Toast.makeText (getApplicationContext (),
972 string, Toast.LENGTH_SHORT);
973 toast.show ();
974 }
975 });
976 }
977
978Here, the variable `string' is used by a nested function. This nested
979function contains a copy of that variable, and is run on the main
980thread using the function `runOnUiThread', in order to display a short
981status message on the display.
982
983When Emacs needs to wait for the nested function to finish, it uses a
984mechanism implemented in `syncRunnable'. This mechanism first calls a
985deadlock avoidance mechanism, then runs a nested function on the UI
986thread, which is expected to signal itself as a condition variable
987upon completion. It is typically used to allocate resources that can
988only be allocated from the UI thread, or to obtain non-thread-safe
989information. The following function is an example; it returns a new
990EmacsView widget corresponding to the provided window:
991
992 public EmacsView
993 getEmacsView (final EmacsWindow window, final int visibility,
994 final boolean isFocusedByDefault)
995 {
996 Runnable runnable;
997 final EmacsHolder<EmacsView> view;
998
999 view = new EmacsHolder<EmacsView> ();
1000
1001 runnable = new Runnable () {
1002 public void
1003 run ()
1004 {
1005 synchronized (this)
1006 {
1007 view.thing = new EmacsView (window);
1008 view.thing.setVisibility (visibility);
1009
1010 /* The following function is only present on Android 26
1011 or later. */
1012 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
1013 view.thing.setFocusedByDefault (isFocusedByDefault);
1014
1015 notify ();
1016 }
1017 }
1018 };
1019
1020 syncRunnable (runnable);
1021 return view.thing;
1022 }
1023
1024As no value can be directly returned from the nested function, a
1025separate container object is used to hold the result after the
1026function finishes execution. Note the type name inside the angle
1027brackets: this type is substituted into the class definition as it is
1028used; a definition such as:
1029
1030public class Foo<T>
1031{
1032 T bar;
1033};
1034
1035can not be used alone:
1036
1037 Foo holder; /* Error! */
1038
1039but must have a type specified:
1040
1041 Foo<Object> holder;
1042
1043in which case the effective definition is:
1044
1045public class Foo
1046{
1047 Object bar;
1048};
1049