Update Android port
* .gitignore: Update with new files. Do not ignore std*.in.h. * INSTALL.android: Explain how to build Emacs with external dependencies. * Makefile.in (xcompile, cross): Rename to `cross'. (clean_dirs): Clean cross, not xcompile. * README: Document new directories. * build-aux/ndk-build-helper-1.mk (build_kind, NDK_SO_NAMES): * build-aux/ndk-build-helper-2.mk (build_kind, NDK_SO_NAMES): * build-aux/ndk-build-helper-3.mk (build_kind): * build-aux/ndk-build-helper-4.mk: * build-aux/ndk-build-helper.mk (NDK_BUILD_DIR, my-dir): * build-aux/ndk-module-extract.awk: New files. * configure.ac: Set up libgif, libwebp, and libpng for ndk-build. * cross/ndk-build/Makefile.in (srcdir, NDK_BUILD_ANDROID_MK): * cross/ndk-build/ndk-build-executable.mk: * cross/ndk-build/ndk-build-shared-library.mk (eq, objname): * cross/ndk-build/ndk-build-static-library.mk (eq, objname): * cross/ndk-build/ndk-build.in (NDK_BUILD_MODULES): * cross/ndk-build/ndk-build.mk.in (NDK_BUILD_MODULES) (NDK_BUILD_SHARED): * cross/ndk-build/ndk-clear-vars.mk: * cross/ndk-build/ndk-prebuilt-shared-library.mk: * cross/ndk-build/ndk-prebuilt-static-library.mk: New files. * doc/emacs/android.texi (Android, Android Environment): Document clipboard support on Android. * doc/emacs/emacs.texi (Top): Update menus. * etc/MACHINES: Document Android. * java/AndroidManifest.xml.in: Respect new `--with-android-debug' option. * java/Makefile.in (CROSS_BINS, CROSS_LIBS): Adjust for rename. Include ndk-build.mk.:(emacs.apk-in): Depend on shared libraries. Then, package shared libraries. * java/org/gnu/emacs/EmacsClipboard.java (EmacsClipboard): New class. * java/org/gnu/emacs/EmacsFontDriver.java: Update comment to say this is unused. * java/org/gnu/emacs/EmacsNative.java (EmacsNative): New function `sendExpose'. * java/org/gnu/emacs/EmacsSdk11Clipboard.java (EmacsSdk11Clipboard): * java/org/gnu/emacs/EmacsSdk8Clipboard.java (EmacsSdk8Clipboard): New classes. * java/org/gnu/emacs/EmacsView.java (EmacsView, handleDirtyBitmap) (onDetachedFromWindow): When window is reattached, expose the frame. * lib/Makefile.in (VPATH): (ALL_CFLAGS): Adjust for rename. * lisp/term/android-win.el (android-clipboard-exists-p) (android-get-clipboard, android-set-clipboard) (android-clipboard-owner-p, android-primary-selection) (android-get-clipboard-1, android-get-primary) (android-selection-bounds, android-encode-select-string) (gui-backend-get-selection, gui-backend-selection-exists-p) (gui-backend-selection-owner-p, gui-backend-set-selection): New functions. * m4/ndk-build.m4: New file. * src/Makefile.in (GIF_CFLAGS, ANDROID_LDFLAGS): New variables. (EMACS_CFLAGS): Add GIF_CFLAGS. Include ndk-build.mk. (libemacs.so): Depend on and link with required libraries. * src/android.c (android_check_compressed_file): New function. (android_open): Work around Android platform bug. (sendExpose): New function. (android_readdir): Set d_type if this is a directory. * src/androidgui.h (enum android_event_type) (struct android_expose_event, union android_event): Add expose events. * src/androidselect.c (struct android_emacs_clipboard) (android_init_emacs_clipboard, Fandroid_clipboard_owner_p) (Fandroid_set_clipboard, Fandroid_get_clipboard) (Fandroid_clipboard_exists_p, init_androidselect) (syms_of_androidselect): New file. * src/androidterm.c (handle_one_android_event): Handle exposures. * src/androidterm.h: Update prototypes. * src/emacs.c (android_emacs_init): Initialize androidselect.
This commit is contained in:
44
java/org/gnu/emacs/EmacsClipboard.java
Normal file
44
java/org/gnu/emacs/EmacsClipboard.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||
|
||||
Copyright (C) 2023 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.os.Build;
|
||||
|
||||
/* This class provides helper code for accessing the clipboard,
|
||||
abstracting between the different interfaces on API 8 and 11. */
|
||||
|
||||
public abstract class EmacsClipboard
|
||||
{
|
||||
public abstract void setClipboard (byte[] bytes);
|
||||
public abstract int ownsClipboard ();
|
||||
public abstract boolean clipboardExists ();
|
||||
public abstract byte[] getClipboard ();
|
||||
|
||||
/* Create the correct kind of clipboard for this system. */
|
||||
|
||||
public static EmacsClipboard
|
||||
makeClipboard ()
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
return new EmacsSdk11Clipboard ();
|
||||
else
|
||||
return new EmacsSdk8Clipboard ();
|
||||
}
|
||||
};
|
||||
@@ -23,6 +23,9 @@ import java.util.List;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
/* This code is mostly unused. See sfntfont-android.c for the code
|
||||
that is actually used. */
|
||||
|
||||
public abstract class EmacsFontDriver
|
||||
{
|
||||
/* Font weights. */
|
||||
|
||||
@@ -132,6 +132,10 @@ public class EmacsNative
|
||||
/* Send an ANDROID_CONTEXT_MENU event. */
|
||||
public static native long sendContextMenu (short window, int menuEventID);
|
||||
|
||||
/* Send an ANDROID_EXPOSE event. */
|
||||
public static native long sendExpose (short window, int x, int y,
|
||||
int width, int height);
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary ("emacs");
|
||||
|
||||
156
java/org/gnu/emacs/EmacsSdk11Clipboard.java
Normal file
156
java/org/gnu/emacs/EmacsSdk11Clipboard.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||
|
||||
Copyright (C) 2023 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.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.ClipData;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/* This class implements EmacsClipboard for Android 3.0 and later
|
||||
systems. */
|
||||
|
||||
public class EmacsSdk11Clipboard extends EmacsClipboard
|
||||
implements ClipboardManager.OnPrimaryClipChangedListener
|
||||
{
|
||||
private static final String TAG = "EmacsSdk11Clipboard";
|
||||
private ClipboardManager manager;
|
||||
private boolean ownsClipboard;
|
||||
private int clipboardChangedCount;
|
||||
private int monitoredClipboardChangedCount;
|
||||
|
||||
public
|
||||
EmacsSdk11Clipboard ()
|
||||
{
|
||||
String what;
|
||||
Context context;
|
||||
|
||||
what = Context.CLIPBOARD_SERVICE;
|
||||
context = EmacsService.SERVICE;
|
||||
manager
|
||||
= (ClipboardManager) context.getSystemService (what);
|
||||
manager.addPrimaryClipChangedListener (this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void
|
||||
onPrimaryClipChanged ()
|
||||
{
|
||||
Log.d (TAG, ("onPrimaryClipChanged: "
|
||||
+ monitoredClipboardChangedCount
|
||||
+ " " + clipboardChangedCount));
|
||||
|
||||
/* Increment monitoredClipboardChangeCount. If it is now greater
|
||||
than clipboardChangedCount, then Emacs no longer owns the
|
||||
clipboard. */
|
||||
monitoredClipboardChangedCount++;
|
||||
|
||||
if (monitoredClipboardChangedCount > clipboardChangedCount)
|
||||
{
|
||||
ownsClipboard = false;
|
||||
|
||||
/* Reset both values back to 0. */
|
||||
monitoredClipboardChangedCount = 0;
|
||||
clipboardChangedCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the clipboard text to CLIPBOARD, a string in UTF-8
|
||||
encoding. */
|
||||
|
||||
@Override
|
||||
public synchronized void
|
||||
setClipboard (byte[] bytes)
|
||||
{
|
||||
ClipData data;
|
||||
String string;
|
||||
|
||||
try
|
||||
{
|
||||
string = new String (bytes, "UTF-8");
|
||||
data = ClipData.newPlainText ("Emacs", string);
|
||||
manager.setPrimaryClip (data);
|
||||
ownsClipboard = true;
|
||||
|
||||
/* onPrimaryClipChanged will be called again. Use this
|
||||
variable to keep track of how many times the clipboard has
|
||||
been changed. */
|
||||
++clipboardChangedCount;
|
||||
}
|
||||
catch (UnsupportedEncodingException exception)
|
||||
{
|
||||
Log.w (TAG, "setClipboard: " + exception);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return whether or not Emacs owns the clipboard. Value is 1 if
|
||||
Emacs does, 0 if Emacs does not, and -1 if that information is
|
||||
unavailable. */
|
||||
|
||||
@Override
|
||||
public synchronized int
|
||||
ownsClipboard ()
|
||||
{
|
||||
return ownsClipboard ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Return whether or not clipboard content currently exists. */
|
||||
|
||||
@Override
|
||||
public boolean
|
||||
clipboardExists ()
|
||||
{
|
||||
return manager.hasPrimaryClip ();
|
||||
}
|
||||
|
||||
/* Return the current content of the clipboard, as plain text, or
|
||||
NULL if no content is available. */
|
||||
|
||||
@Override
|
||||
public byte[]
|
||||
getClipboard ()
|
||||
{
|
||||
ClipData clip;
|
||||
CharSequence text;
|
||||
Context context;
|
||||
|
||||
clip = manager.getPrimaryClip ();
|
||||
|
||||
if (clip == null || clip.getItemCount () < 1)
|
||||
return null;
|
||||
|
||||
context = EmacsService.SERVICE;
|
||||
|
||||
try
|
||||
{
|
||||
text = clip.getItemAt (0).coerceToText (context);
|
||||
return text.toString ().getBytes ("UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException exception)
|
||||
{
|
||||
Log.w (TAG, "getClipboard: " + exception);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
116
java/org/gnu/emacs/EmacsSdk8Clipboard.java
Normal file
116
java/org/gnu/emacs/EmacsSdk8Clipboard.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
||||
|
||||
Copyright (C) 2023 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;
|
||||
|
||||
/* Importing the entire package avoids the deprecation warning. */
|
||||
import android.text.*;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/* This class implements EmacsClipboard for Android 2.2 and other
|
||||
similarly old systems. */
|
||||
|
||||
@SuppressWarnings ("deprecation")
|
||||
public class EmacsSdk8Clipboard extends EmacsClipboard
|
||||
{
|
||||
private static final String TAG = "EmacsSdk8Clipboard";
|
||||
private ClipboardManager manager;
|
||||
|
||||
public
|
||||
EmacsSdk8Clipboard ()
|
||||
{
|
||||
String what;
|
||||
Context context;
|
||||
|
||||
what = Context.CLIPBOARD_SERVICE;
|
||||
context = EmacsService.SERVICE;
|
||||
manager
|
||||
= (ClipboardManager) context.getSystemService (what);
|
||||
}
|
||||
|
||||
/* Set the clipboard text to CLIPBOARD, a string in UTF-8
|
||||
encoding. */
|
||||
|
||||
@Override
|
||||
public void
|
||||
setClipboard (byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
manager.setText (new String (bytes, "UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException exception)
|
||||
{
|
||||
Log.w (TAG, "setClipboard: " + exception);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return whether or not Emacs owns the clipboard. Value is 1 if
|
||||
Emacs does, 0 if Emacs does not, and -1 if that information is
|
||||
unavailable. */
|
||||
|
||||
@Override
|
||||
public int
|
||||
ownsClipboard ()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return whether or not clipboard content currently exists. */
|
||||
|
||||
@Override
|
||||
public boolean
|
||||
clipboardExists ()
|
||||
{
|
||||
return manager.hasText ();
|
||||
}
|
||||
|
||||
/* Return the current content of the clipboard, as plain text, or
|
||||
NULL if no content is available. */
|
||||
|
||||
@Override
|
||||
public byte[]
|
||||
getClipboard ()
|
||||
{
|
||||
String string;
|
||||
CharSequence text;
|
||||
|
||||
text = manager.getText ();
|
||||
|
||||
if (text == null)
|
||||
return null;
|
||||
|
||||
string = text.toString ();
|
||||
|
||||
try
|
||||
{
|
||||
return string.getBytes ("UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException exception)
|
||||
{
|
||||
Log.w (TAG, "getClipboard: " + exception);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -99,6 +99,9 @@ public class EmacsView extends ViewGroup
|
||||
yet responded to. 0 if there is no such outstanding event. */
|
||||
public long pendingConfigure;
|
||||
|
||||
/* Whether or not this view is attached to a window. */
|
||||
public boolean isAttachedToWindow;
|
||||
|
||||
public
|
||||
EmacsView (EmacsWindow window)
|
||||
{
|
||||
@@ -140,6 +143,9 @@ public class EmacsView extends ViewGroup
|
||||
if (measuredWidth == 0 || measuredHeight == 0)
|
||||
return;
|
||||
|
||||
if (!isAttachedToWindow)
|
||||
return;
|
||||
|
||||
/* If bitmap is the same width and height as the measured width
|
||||
and height, there is no need to do anything. Avoid allocating
|
||||
the extra bitmap. */
|
||||
@@ -547,6 +553,8 @@ public class EmacsView extends ViewGroup
|
||||
public synchronized void
|
||||
onDetachedFromWindow ()
|
||||
{
|
||||
isAttachedToWindow = false;
|
||||
|
||||
synchronized (this)
|
||||
{
|
||||
/* Recycle the bitmap and call GC. */
|
||||
@@ -559,6 +567,21 @@ public class EmacsView extends ViewGroup
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void
|
||||
onAttachedToWindow ()
|
||||
{
|
||||
isAttachedToWindow = true;
|
||||
|
||||
/* Dirty the bitmap, as it was destroyed when onDetachedFromWindow
|
||||
was called. */
|
||||
bitmapDirty = true;
|
||||
|
||||
/* Now expose the view contents again. */
|
||||
EmacsNative.sendExpose (this.window.handle, 0, 0,
|
||||
measuredWidth, measuredHeight);
|
||||
}
|
||||
|
||||
public void
|
||||
showOnScreenKeyboard ()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user