mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
; * java/README: More documentation.
This commit is contained in:
parent
6999067034
commit
fa821ed186
1 changed files with 141 additions and 0 deletions
141
java/README
141
java/README
|
|
@ -906,3 +906,144 @@ of memory.
|
||||||
Otherwise, it applies the specified window attributes and returns the
|
Otherwise, it applies the specified window attributes and returns the
|
||||||
handle of the new window.
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue