emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android fa821ed1863: ; * java/README: More documentation.


From: Po Lu
Subject: feature/android fa821ed1863: ; * java/README: More documentation.
Date: Fri, 16 Jun 2023 23:34:06 -0400 (EDT)

branch: feature/android
commit fa821ed18639aa1b0275c2938af9987c0c71b581
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    ; * java/README: More documentation.
---
 java/README | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/java/README b/java/README
index 96271279c28..a6adb805b9e 100644
--- a/java/README
+++ b/java/README
@@ -906,3 +906,144 @@ of memory.
 Otherwise, it applies the specified window attributes and returns the
 handle of the new window.
 }
+
+
+
+DRAWABLES, CURSORS AND HANDLES
+
+Each widget created by Emacs corresponds to a single ``window'', which
+has its own backing store.  This arrangement is quite similar to X.
+
+C code does not directly refer to the EmacsView widgets that implement
+the UI logic behind windows.  Instead, its handles refer to
+EmacsWindow structures, which contain the state necessary to interact
+with the widgets in an orderly and synchronized manner.
+
+Like X, both pixmaps and windows are drawable resources, and the same
+graphics operations can be applied to both.  Thus, a separate
+EmacsPixmap structure is used to wrap around Android Bitmap resources,
+and the Java-level graphics operation functions are capable of
+operating on them both.
+
+Finally, graphics contexts are maintained on both the C and Java
+levels; the C state recorded in `struct android_gc' is kept in sync
+with the Java state in the GContext handle's corresponding EmacsGC
+structure, and cursors are used through handles that refer to
+EmacsCursor structures that hold system PointerIcons.
+
+In all cases, the interfaces provided are identical to X.
+
+
+
+EVENT LOOP
+
+In a typical Android application, the event loop is managed by the
+operating system, and callbacks (implemented through overriding
+separate functions in widgets) are run by the event loop wherever
+necessary.  The thread which runs the event loop is also the only
+thread capable of creating and manipulating widgets and activities,
+and is referred to as the ``UI thread''.
+
+These callbacks are used by Emacs to write representations of X-like
+events to a separate event queue, which are then read from Emacs's own
+event loop running in a separate thread.  This is accomplished through
+replacing `select' by a function which waits for the event queue to be
+occupied, in addition to any file descriptors that `select' would
+normally wait for.
+
+Conversely, Emacs's event loop sometimes needs to send events to the
+UI thread.  These events are implemented as tiny fragments of code,
+which are run as they are received by the main thread.
+
+A typical example is `displayToast', which is implemented in
+EmacsService.java:
+
+  public void
+  displayToast (final String string)
+  {
+    runOnUiThread (new Runnable () {
+       @Override
+       public void
+       run ()
+       {
+         Toast toast;
+
+         toast = Toast.makeText (getApplicationContext (),
+                                 string, Toast.LENGTH_SHORT);
+         toast.show ();
+       }
+      });
+  }
+
+Here, the variable `string' is used by a nested function.  This nested
+function contains a copy of that variable, and is run on the main
+thread using the function `runOnUiThread', in order to display a short
+status message on the display.
+
+When Emacs needs to wait for the nested function to finish, it uses a
+mechanism implemented in `syncRunnable'.  This mechanism first calls a
+deadlock avoidance mechanism, then runs a nested function on the UI
+thread, which is expected to signal itself as a condition variable
+upon completion.  It is typically used to allocate resources that can
+only be allocated from the UI thread, or to obtain non-thread-safe
+information.  The following function is an example; it returns a new
+EmacsView widget corresponding to the provided window:
+
+  public EmacsView
+  getEmacsView (final EmacsWindow window, final int visibility,
+               final boolean isFocusedByDefault)
+  {
+    Runnable runnable;
+    final EmacsHolder<EmacsView> view;
+
+    view = new EmacsHolder<EmacsView> ();
+
+    runnable = new Runnable () {
+       public void
+       run ()
+       {
+         synchronized (this)
+           {
+             view.thing = new EmacsView (window);
+             view.thing.setVisibility (visibility);
+
+             /* The following function is only present on Android 26
+                or later.  */
+             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+               view.thing.setFocusedByDefault (isFocusedByDefault);
+
+             notify ();
+           }
+       }
+      };
+
+    syncRunnable (runnable);
+    return view.thing;
+  }
+
+As no value can be directly returned from the nested function, a
+separate container object is used to hold the result after the
+function finishes execution.  Note the type name inside the angle
+brackets: this type is substituted into the class definition as it is
+used; a definition such as:
+
+public class Foo<T>
+{
+  T bar;
+};
+
+can not be used alone:
+
+  Foo holder; /* Error! */
+
+but must have a type specified:
+
+  Foo<Object> holder;
+
+in which case the effective definition is:
+
+public class Foo
+{
+  Object bar;
+};
+



reply via email to

[Prev in Thread] Current Thread [Next in Thread]