Respond to display configuration updates on Android
* java/org/gnu/emacs/EmacsNative.java (sendConfigurationChanged): Declare function. * java/org/gnu/emacs/EmacsSdk7FontDriver.java (Sdk7FontEntity) (Sdk7FontObject): Do not access `metrics' field deleted from `EmacsService'. * java/org/gnu/emacs/EmacsService.java (EmacsService) <metrics, resources>: Delete fields. <dpiX, dpiY, dpiScaled>: New fields. (onCreate): Adjust accordingly. Record current display metrics for subsequent comparison. (onConfigurationChanged): New function. * lisp/dynamic-setting.el (font-setting-change-default-font): Enable on systems where font-get-system-font is not defined if invoked with SET-FONT nil. * src/android.c (sendConfigurationChanged): New function. * src/androidgui.h (ANDROID_CONFIGURATION_CHANGED): New enumerator. (struct android_configuration_changed): New structure. (union android_event): Add `config' member. * src/androidterm.c (handle_one_android_event): Handle ANDROID_CONFIGURATION_CHANGED events. (syms_of_androidterm): Define Qfont_render, and Qdynamic_setting. Provide the latter.
This commit is contained in:
parent
cb339ad8f4
commit
884ede7c95
7 changed files with 132 additions and 17 deletions
|
@ -196,6 +196,10 @@ public static native long sendDndText (long window, int x, int y,
|
|||
/* Send an ANDROID_NOTIFICATION_ACTION event. */
|
||||
public static native void sendNotificationAction (String tag, String action);
|
||||
|
||||
/* Send an ANDROID_CONFIGURATION_CHANGED event. */
|
||||
public static native void sendConfigurationChanged (float dpiX, float dpiY,
|
||||
float dpiScaled);
|
||||
|
||||
/* Return the file name associated with the specified file
|
||||
descriptor, or NULL if there is none. */
|
||||
public static native byte[] getProcName (int fd);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
import android.graphics.Typeface;
|
||||
import android.graphics.Canvas;
|
||||
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
|
@ -103,6 +104,8 @@ protected static final class Sdk7FontEntity extends FontEntity
|
|||
public
|
||||
Sdk7FontEntity (Sdk7Typeface typeface)
|
||||
{
|
||||
DisplayMetrics metrics;
|
||||
|
||||
foundry = "Google";
|
||||
family = typeface.familyName;
|
||||
adstyle = null;
|
||||
|
@ -110,7 +113,8 @@ protected static final class Sdk7FontEntity extends FontEntity
|
|||
slant = typeface.slant;
|
||||
spacing = typeface.spacing;
|
||||
width = typeface.width;
|
||||
dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f);
|
||||
metrics = EmacsService.SERVICE.getResources ().getDisplayMetrics ();
|
||||
dpi = Math.round (metrics.scaledDensity * 160f);
|
||||
|
||||
this.typeface = typeface;
|
||||
}
|
||||
|
@ -127,6 +131,7 @@ protected final class Sdk7FontObject extends FontObject
|
|||
{
|
||||
float totalWidth;
|
||||
String testWidth, testString;
|
||||
DisplayMetrics metrics;
|
||||
|
||||
this.typeface = typeface;
|
||||
this.pixelSize = pixelSize;
|
||||
|
@ -137,7 +142,8 @@ protected final class Sdk7FontObject extends FontObject
|
|||
slant = typeface.slant;
|
||||
spacing = typeface.spacing;
|
||||
width = typeface.width;
|
||||
dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f);
|
||||
metrics = EmacsService.SERVICE.getResources ().getDisplayMetrics ();
|
||||
dpi = Math.round (metrics.scaledDensity * 160f);
|
||||
|
||||
/* Compute the ascent and descent. */
|
||||
typeface.typefacePaint.setTextSize (pixelSize);
|
||||
|
|
|
@ -123,9 +123,6 @@ public final class EmacsService extends Service
|
|||
public static final int IC_MODE_TEXT = 2;
|
||||
public static final int IC_MODE_PASSWORD = 3;
|
||||
|
||||
/* Display metrics used by font backends. */
|
||||
public DisplayMetrics metrics;
|
||||
|
||||
/* Flag that says whether or not to print verbose debugging
|
||||
information when responding to an input method. */
|
||||
public static final boolean DEBUG_IC = false;
|
||||
|
@ -149,8 +146,9 @@ public final class EmacsService extends Service
|
|||
thread. */
|
||||
private Thread mainThread;
|
||||
|
||||
/* "Resources" object required by GContext bookkeeping. */
|
||||
public static Resources resources;
|
||||
/* The display's horizontal and vertical density and that which is
|
||||
consulted for font scaling. */
|
||||
private double dpiX, dpiY, dpiScaled;
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -236,10 +234,12 @@ public final class EmacsService extends Service
|
|||
final AssetManager manager;
|
||||
Context app_context;
|
||||
final String filesDir, libDir, cacheDir, classPath;
|
||||
final double pixelDensityX;
|
||||
final double pixelDensityY;
|
||||
final double scaledDensity;
|
||||
double tempScaledDensity;
|
||||
final float pixelDensityX;
|
||||
final float pixelDensityY;
|
||||
final float scaledDensity;
|
||||
float tempScaledDensity;
|
||||
Resources resources;
|
||||
DisplayMetrics metrics;
|
||||
|
||||
super.onCreate ();
|
||||
|
||||
|
@ -265,13 +265,18 @@ public final class EmacsService extends Service
|
|||
corresponds to 1 pixel, not 72 or 96 as used elsewhere. This
|
||||
difference is codified in PT_PER_INCH defined in font.h. */
|
||||
|
||||
if (tempScaledDensity < 160)
|
||||
tempScaledDensity = 160;
|
||||
if (tempScaledDensity < 160.0f)
|
||||
tempScaledDensity = 160.0f;
|
||||
|
||||
/* scaledDensity is const as required to refer to it from within
|
||||
the nested function below. */
|
||||
scaledDensity = tempScaledDensity;
|
||||
|
||||
/* Save these fields for future reference. */
|
||||
dpiX = pixelDensityX;
|
||||
dpiY = pixelDensityY;
|
||||
dpiScaled = scaledDensity;
|
||||
|
||||
/* Remove all tasks from previous Emacs sessions but the task
|
||||
created by the system at startup. */
|
||||
EmacsWindowManager.MANAGER.removeOldTasks (this);
|
||||
|
@ -304,9 +309,8 @@ invocation of app_process (through android-emacs) can
|
|||
run ()
|
||||
{
|
||||
EmacsNative.setEmacsParams (manager, filesDir, libDir,
|
||||
cacheDir, (float) pixelDensityX,
|
||||
(float) pixelDensityY,
|
||||
(float) scaledDensity,
|
||||
cacheDir, pixelDensityX,
|
||||
pixelDensityY, scaledDensity,
|
||||
classPath, EmacsService.this,
|
||||
Build.VERSION.SDK_INT);
|
||||
}
|
||||
|
@ -344,6 +348,40 @@ invocation of app_process (through android-emacs) can
|
|||
super.onLowMemory ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void
|
||||
onConfigurationChanged (Configuration newConfig)
|
||||
{
|
||||
DisplayMetrics metrics;
|
||||
float pixelDensityX, pixelDensityY, scaledDensity;
|
||||
|
||||
metrics = getResources ().getDisplayMetrics ();
|
||||
|
||||
/* The display configuration may have been altered. Retrieve the
|
||||
revised display density and deliver an event if so. */
|
||||
pixelDensityX = metrics.xdpi;
|
||||
pixelDensityY = metrics.ydpi;
|
||||
scaledDensity = ((getScaledDensity (metrics)
|
||||
/ metrics.density) * pixelDensityX);
|
||||
|
||||
/* A density below 160 probably indicates a system bug. See
|
||||
onCreate for more commentary. */
|
||||
if (scaledDensity < 160.0f)
|
||||
scaledDensity = 160.0f;
|
||||
|
||||
if (pixelDensityX != dpiX || pixelDensityY != dpiY
|
||||
|| scaledDensity != dpiScaled)
|
||||
{
|
||||
dpiX = pixelDensityX;
|
||||
dpiY = pixelDensityY;
|
||||
dpiScaled = scaledDensity;
|
||||
EmacsNative.sendConfigurationChanged (pixelDensityX, pixelDensityY,
|
||||
scaledDensity);
|
||||
}
|
||||
|
||||
super.onConfigurationChanged (newConfig);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Functions from here on must only be called from the Emacs
|
||||
|
|
|
@ -46,7 +46,8 @@ the current form for the frame (i.e. hinting or somesuch changed)."
|
|||
(let ((new-font (and (fboundp 'font-get-system-font)
|
||||
(font-get-system-font)))
|
||||
(frame-list (frames-on-display-list display-or-frame)))
|
||||
(when (and new-font (display-graphic-p display-or-frame))
|
||||
(when (and (or (not set-font) new-font)
|
||||
(display-graphic-p display-or-frame))
|
||||
(clear-font-cache)
|
||||
(if set-font
|
||||
;; Set the font on all current and future frames, as though
|
||||
|
|
|
@ -2819,6 +2819,25 @@ NATIVE_NAME (sendNotificationAction) (JNIEnv *env, jobject object,
|
|||
return event_serial;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
NATIVE_NAME (sendConfigurationChanged) (JNIEnv *env, jobject object,
|
||||
jfloat dpi_x, jfloat dpi_y,
|
||||
jfloat dpi_scaled)
|
||||
{
|
||||
JNI_STACK_ALIGNMENT_PROLOGUE;
|
||||
|
||||
union android_event event;
|
||||
|
||||
event.config.type = ANDROID_CONFIGURATION_CHANGED;
|
||||
event.config.serial = ++event_serial;
|
||||
event.config.window = ANDROID_NONE;
|
||||
event.config.dpi_x = dpi_x;
|
||||
event.config.dpi_y = dpi_y;
|
||||
event.config.dpi_scaled = dpi_scaled;
|
||||
android_write_event (&event);
|
||||
return event_serial;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env,
|
||||
jobject object)
|
||||
|
|
|
@ -288,6 +288,7 @@ enum android_event_type
|
|||
ANDROID_DND_TEXT_EVENT,
|
||||
ANDROID_NOTIFICATION_DELETED,
|
||||
ANDROID_NOTIFICATION_ACTION,
|
||||
ANDROID_CONFIGURATION_CHANGED,
|
||||
};
|
||||
|
||||
struct android_any_event
|
||||
|
@ -595,6 +596,26 @@ struct android_notification_event
|
|||
size_t length;
|
||||
};
|
||||
|
||||
struct android_configuration_changed_event
|
||||
{
|
||||
/* Type of the event. */
|
||||
enum android_event_type type;
|
||||
|
||||
/* The event serial. */
|
||||
unsigned long serial;
|
||||
|
||||
/* The window that gave rise to the event (None). */
|
||||
android_window window;
|
||||
|
||||
/* The density of the display along the horizontal and vertical
|
||||
axes. */
|
||||
double dpi_x, dpi_y;
|
||||
|
||||
/* The density to take into account when converting between point and
|
||||
pixel dimensions. */
|
||||
double dpi_scaled;
|
||||
};
|
||||
|
||||
union android_event
|
||||
{
|
||||
enum android_event_type type;
|
||||
|
@ -635,6 +656,11 @@ union android_event
|
|||
/* X provides no equivalent interface for displaying
|
||||
notifications. */
|
||||
struct android_notification_event notification;
|
||||
|
||||
/* The equivalent under X is provided through XSettings, which is a
|
||||
byzantine protocol that extends client messages and is therefore
|
||||
not worthwhile to emulate. */
|
||||
struct android_configuration_changed_event config;
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -1824,6 +1824,22 @@ handle_one_android_event (struct android_display_info *dpyinfo,
|
|||
free (event->notification.action);
|
||||
goto OTHER;
|
||||
|
||||
case ANDROID_CONFIGURATION_CHANGED:
|
||||
/* Update the display configuration from the event. */
|
||||
dpyinfo->resx = event->config.dpi_x;
|
||||
dpyinfo->resy = event->config.dpi_y;
|
||||
dpyinfo->font_resolution = event->config.dpi_scaled;
|
||||
#ifdef notdef
|
||||
__android_log_print (ANDROID_LOG_VERBOSE, __func__,
|
||||
"New display configuration: "
|
||||
"resx = %.2f resy = %.2f font_resolution = %.2f",
|
||||
dpyinfo->resx, dpyinfo->resy, dpyinfo->font_resolution);
|
||||
#endif /* notdef */
|
||||
inev.ie.kind = CONFIG_CHANGED_EVENT;
|
||||
inev.ie.frame_or_window = XCAR (dpyinfo->name_list_element);
|
||||
inev.ie.arg = Qfont_render;
|
||||
goto OTHER;
|
||||
|
||||
default:
|
||||
goto OTHER;
|
||||
}
|
||||
|
@ -7014,6 +7030,11 @@ for instance, `early-init.el', or they will be of no effect. */);
|
|||
/* Key symbols. */
|
||||
DEFSYM (Qselect, "select");
|
||||
DEFSYM (Qreturn, "return");
|
||||
|
||||
/* Display configuration updates. */
|
||||
DEFSYM (Qfont_render, "font-render");
|
||||
DEFSYM (Qdynamic_setting, "dynamic-setting");
|
||||
Fprovide (Qdynamic_setting, Qnil);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Reference in a new issue