1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-28 08:11:05 -08:00

Update Android port

* Makefile.in (java): Depend on info.
(MAKEFILE_NAME):
(config.status): Remove unneeded changes.
* configure.ac (BUILD_DETAILS, ANDROID_STUBIFY): Don't require a
C++ compiler on Android.
* java/AndroidManifest.xml: <EmacsActivity>: Set launchMode
appropriately.  <EmacsMultitaskActivity>: New activity.
* java/Makefile.in (CROSS_BINS): Add EmacsClient.
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity)
(onCreate): Use the window attachment manager.
* java/org/gnu/emacs/EmacsCopyArea.java (EmacsCopyArea)
(paintTo): Implement clip masks correctly.
* java/org/gnu/emacs/EmacsDrawRectangle.java (getRect, paintTo):
Fix damage tracking rectangles.
* java/org/gnu/emacs/EmacsFontDriver.java (FontSpec, toString):
New function.
(FontMetrics, EmacsFontDriver): Fix signature of textExtents.
* java/org/gnu/emacs/EmacsMultitaskActivity.java
(EmacsMultitaskActivity): New file.
* java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
functions sendFocusIn, sendFocusOut, sendWindowAction.
* java/org/gnu/emacs/EmacsPaintQueue.java (run): Fix clipping
handling.
* java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): Add
constructor for mutable pixmaps.
* java/org/gnu/emacs/EmacsSdk23FontDriver.java
(EmacsSdk23FontDriver): New file.
* java/org/gnu/emacs/EmacsSdk7FontDriver.java
(EmacsSdk7FontDriver, Sdk7Typeface, Sdk7FontEntity, Sdk7FontObject)
(checkMatch, hasChar, encodeChar): Implement text display and
fix font metrics semantics.

* java/org/gnu/emacs/EmacsService.java (EmacsService): Remove
availableChildren.
(getLibraryDirectory, onCreate): Pass pixel density to Emacs.
(clearArea): Fix arguments.  Switch to using the window
attachment manager.
* java/org/gnu/emacs/EmacsSurfaceView.java (surfaceChanged)
(surfaceCreated): Flip buffers on surface attachment.
* java/org/gnu/emacs/EmacsView.java (EmacsView, swapBuffers):
New argument FORCE.  Always swap if it is true.
(onKeyMultiple, onFocusChanged): New functions.

* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, destroyHandle)
(run): Switch to using the window attachment manager.
* java/org/gnu/emacs/EmacsWindowAttachmentManager.java
(EmacsWindowAttachmentManager): New file.

* lisp/cus-edit.el (custom-button, custom-button-mouse)
(custom-button-pressed):
* lisp/faces.el (tool-bar): Define faces correctly on Android.
* src/android.c (struct android_emacs_pixmap): Add mutable
constructor.
(struct android_emacs_drawable): New structure.
(android_write_event): Check if event queue hasn't yet been
initialized.
(android_select): Set errno to EINTR if pselect fails.
(android_close): Remove unused debugging code.
(android_get_home_directory): New function.
(Java_org_gnu_emacs_EmacsNative_setEmacsParams): Set pixel
density and compute game path.
(android_init_emacs_drawable): New function.
(Java_org_gnu_emacs_EmacsNative_sendKeyPress): New argument
`unicode_char'.  Pass it in events.
(Java_org_gnu_emacs_EmacsNative_sendKeyRelease): Likewise.
(Java_org_gnu_emacs_EmacsNative_sendFocusIn)
(Java_org_gnu_emacs_EmacsNative_sendFocusOut)
(Java_org_gnu_emacs_EmacsNative_sendWindowAction): New
functions.
(android_resolve_handle): Export function.
(android_change_gc): Clear clip rects under the right
circumstances.  Set right clip mask field.
(android_create_pixmap_from_bitmap_data): Use correct alpha
channels.
(android_create_pixmap): Create mutable pixmap and avoid
redundant color array allocation.
(android_create_bitmap_from_data, android_create_image)
(android_destroy_image, android_put_pixel, android_get_pixel)
(android_get_image, android_put_image, faccessat): New
functions.

* src/android.h: Update prototypes.

* src/androidfns.c (android_default_font_parameter): Prefer
monospace to Droid Sans Mono.
* src/androidfont.c (struct android_emacs_font_driver): New
method `draw'.
(struct android_emacs_font_spec): New field `dpi'.
(struct androidfont_info): Add font metrics cache.
(android_init_font_driver, android_init_font_spec): Adjust
accordingly.
(androidfont_from_lisp, androidfont_from_java): Handle new
fields.
(androidfont_draw): Implement function.
(androidfont_open_font): Set pixel size correctly.
(androidfont_close_font): Free metrics cache.
(androidfont_cache_text_extents)
(androidfont_check_cached_extents): New functions.
(androidfont_text_extents): Cache glyph metrics somewhere for
future use.
(androidfont_list_family): Implement function.

* src/androidgui.h (enum android_event_type): New focus and
window action events.
(enum android_modifier_mask): New masks.
(struct android_key_event): New field `unicode_char'.
(ANDROID_IS_MODIFIER_KEY): Newmacro.
(struct android_focus_event, struct
android_window_action_event): New structs.
(union android_event): Add new fields.
(enum android_image_format, struct android_image): New enums and
structs.

* src/androidterm.c (android_android_to_emacs_modifiers)
(android_emacs_to_android_modifiers, android_lower_frame)
(android_raise_frame, android_new_focus_frame)
(android_focus_changed, android_detect_focus_change): New
functions.
(handle_one_android_event): Implement focus and key event
handling.
(android_frame_rehighlight): New function.
(android_frame_raise_lower): Implement accordingly.
(android_make_frame_invisible): Clear highlight_frame if
required.
(android_free_frame_resources): Clear x_focus_event_frame if
required.
(android_draw_fringe_bitmap, android_draw_image_foreground)
(android_draw_image_foreground_1)
(android_draw_image_glyph_string): Remove unnecessary code.
(android_create_terminal, android_term_init): Set the baud rate
to something sensible.
* src/androidterm.h (struct android_bitmap_record): Make
structure the same as on X.
(struct android_display_info): New focus tracking fields.
(struct android_output): Likewise.
* src/dispextern.h (struct image): Add ximg and mask_img on
Android.

* src/emacs.c (android_emacs_init): Fix argc sorting iteration.

* src/fileio.c (user_homedir):
(get_homedir): Implement correctly on Android.

* src/font.h (PT_PER_INCH): Define correctly on Android.

* src/fringe.c (X, swap_nibble, init_fringe_bitmap): Swap fringe
bitmaps correctly on Android.

* src/image.c (GET_PIXEL, image_create_bitmap_from_data)
(image_create_bitmap_from_file, free_bitmap_record)
(image_unget_x_image_or_dc, struct image_type)
(prepare_image_for_display, image_clear_image_1)
(image_size_in_bytes, x_check_image_size)
(x_create_x_image_and_pixmap, x_destroy_x_image)
(image_check_image_size, image_create_x_image_and_pixmap_1)
(image_destroy_x_image, gui_put_x_image, image_put_x_image)
(image_get_x_image, image_unget_x_image)
(Create_Pixmap_From_Bitmap_Data, image_pixmap_draw_cross)
(MaskForeground, image_types, syms_of_image): Implement all of
the above on Android in terms of an API very similar to X.

* src/keyboard.c (FUNCTION_KEY_OFFSET, lispy_function_keys):
Define on Android to something sensible.

* src/lread.c (build_load_history): Fix problem.
This commit is contained in:
Po Lu 2023-01-02 21:38:19 +08:00
parent fd074f3133
commit a32963e11f
36 changed files with 2435 additions and 693 deletions

View file

@ -32,65 +32,114 @@ import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
public class EmacsActivity extends Activity
implements EmacsWindowAttachmentManager.WindowConsumer
{
public static final String TAG = "EmacsActivity";
/* List of all activities that do not have an associated
EmacsWindow. */
public static List<EmacsActivity> availableActivities;
/* The currently attached EmacsWindow, or null if none. */
private EmacsWindow window;
/* The frame layout associated with the activity. */
private FrameLayout layout;
/* List of activities with focus. */
private static List<EmacsActivity> focusedActivities;
/* The currently focused window. */
public static EmacsWindow focusedWindow;
static
{
/* Set up the list of available activities. */
availableActivities = new ArrayList<EmacsActivity> ();
focusedActivities = new ArrayList<EmacsActivity> ();
};
public static void
invalidateFocus1 (EmacsWindow window)
{
if (window.view.isFocused ())
focusedWindow = window;
for (EmacsWindow child : window.children)
invalidateFocus1 (window);
}
public static void
invalidateFocus ()
{
EmacsWindow oldFocus;
/* Walk through each focused activity and assign the window focus
to the bottom-most focused window within. Record the old focus
as well. */
oldFocus = focusedWindow;
focusedWindow = null;
for (EmacsActivity activity : focusedActivities)
{
if (activity.window != null)
invalidateFocus1 (activity.window);
}
/* Send focus in- and out- events to the previous and current
focus. */
if (oldFocus != null)
EmacsNative.sendFocusOut (oldFocus.handle,
System.currentTimeMillis ());
if (focusedWindow != null)
EmacsNative.sendFocusIn (focusedWindow.handle,
System.currentTimeMillis ());
}
@Override
public void
attachChild (EmacsWindow child)
detachWindow ()
{
if (window == null)
Log.w (TAG, "detachWindow called, but there is no window");
else
{
/* Clear the window's pointer to this activity and remove the
window's view. */
window.setConsumer (null);
layout.removeView (window.view);
window = null;
invalidateFocus ();
}
}
@Override
public void
attachWindow (EmacsWindow child)
{
if (window != null)
throw new IllegalStateException ("trying to attach window when one"
+ " already exists");
/* Record and attach the view. */
window = child;
layout.addView (window.view);
child.setConsumer (this);
/* Remove the objects from the lists of what is available. */
EmacsService.availableChildren.remove (child);
availableActivities.remove (this);
/* Now set child->activity. */
child.setActivity (this);
/* Invalidate the focus. */
invalidateFocus ();
}
/* Make this activity available for future windows to attach
again. */
@Override
public void
makeAvailable ()
destroy ()
{
window = null;
finish ();
}
for (EmacsWindow iterWindow
: EmacsService.availableChildren)
{
synchronized (iterWindow)
{
if (!iterWindow.isDestroyed ())
attachChild (iterWindow);
return;
}
}
availableActivities.add (this);
@Override
public EmacsWindow
getAttachedWindow ()
{
return window;
}
@Override
@ -109,38 +158,38 @@ public class EmacsActivity extends Activity
/* Set it as the content view. */
setContentView (layout);
/* Make the activity available before starting the
service. */
makeAvailable ();
if (EmacsService.SERVICE == null)
/* Start the Emacs service now. */
startService (new Intent (this, EmacsService.class));
/* Add this activity to the list of available activities. */
EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this);
super.onCreate (savedInstanceState);
}
@Override
public void
onStop ()
onDestroy ()
{
/* The activity is no longer visible. If there is a window
attached, detach it. */
/* The activity will die shortly hereafter. If there is a window
attached, close it now. */
Log.d (TAG, "onDestroy " + this);
EmacsWindowAttachmentManager.MANAGER.removeWindowConsumer (this);
focusedActivities.remove (this);
invalidateFocus ();
super.onDestroy ();
}
if (window != null)
{
layout.removeView (window.view);
@Override
public void
onWindowFocusChanged (boolean isFocused)
{
if (isFocused && !focusedActivities.contains (this))
focusedActivities.add (this);
else
focusedActivities.remove (this);
/* Notice that the window is already available too. But do
not call noticeAvailableChild; that might assign it to some
other activity, which behaves badly. */
EmacsService.availableChildren.add (window);
window = null;
}
/* Finally, remove this activity from the list of available
activities. */
availableActivities.remove (this);
super.onStop ();
invalidateFocus ();
}
};