Update Android port

Note that the port currently does not work as of this check-in.

* src/android.c (android_change_gc): Fix situations where clip
rects are cleared.
(android_create_pixmap_from_bitmap_data): Fix bitmap data
iteration.
* src/androidfns.c (Fx_show_tip, Fx_hide_tip): Remove annoying
errors.

* src/androidgui.h (enum android_event_type):
(struct android_crossing_event):
(struct android_motion_event):
(struct android_button_event):
(union android_event): New crossing, motion and button events.

* src/androidterm.c (android_note_mouse_movement)
(mouse_or_wdesc_frame, android_construct_mouse_click)
(handle_one_android_event, android_mouse_position)
(android_wait_for_event, android_set_window_size_1)
(android_bitmap_icon, android_free_frame_resources)
(syms_of_androidterm): New functions.  Handle crossing, motion
and button events.

* src/androidterm.h (struct android_display_info): New field
`last_mouse_movement_time'.
(struct android_output): Remove unused `need_buffer_flip' field.

* src/emacs.c (android_emacs_init): Initialize sfntfont.
* src/frame.c (syms_of_frame): Set frame_inhibit_implied_resize
to some reasonable value.
* src/frame.h (GCALIGNED_STRUCT): Set wait_event_type on
Android.

* src/sfnt.c (eassert):
(TEST_STATIC):
(available):
(enum sfnt_table):
(sfnt_table_names):
(SFNT_ENDOF):
(struct sfnt_table_directory):
(enum sfnt_scaler_type):
(sfnt_coerce_fixed):
(struct sfnt_hhea_table):
(struct sfnt_cmap_table):
(enum sfnt_platform_id):
(enum sfnt_unicode_platform_specific_id):
(enum sfnt_macintosh_platform_specific_id):
(enum sfnt_microsoft_platform_specific_id):
(struct sfnt_cmap_encoding_subtable):
(struct sfnt_cmap_encoding_subtable_data):
(struct sfnt_cmap_format_0):
(struct sfnt_cmap_format_2_subheader):
(struct sfnt_cmap_format_2):
(struct sfnt_cmap_format_4):
(struct sfnt_cmap_format_6):
(struct sfnt_cmap_format_8_or_12_group):
(struct sfnt_cmap_format_8):
(struct sfnt_cmap_format_12):
(struct sfnt_maxp_table):
(struct sfnt_loca_table_short):
(struct sfnt_loca_table_long):
(struct sfnt_glyf_table):
(struct sfnt_simple_glyph):
(struct sfnt_compound_glyph_component):
(struct sfnt_compound_glyph):
(struct sfnt_glyph):
(sfnt_read_table_directory):
(file):
(sfnt_read_cmap_table):
(sfnt_read_head_table):
(success):
(sfnt_read_hhea_table):
(sfnt_read_loca_table_short):
(sfnt_read_loca_table_long):
(sfnt_read_maxp_table):
(sfnt_read_glyf_table):
(sfnt_read_compound_glyph):
(sfnt_read_glyph):
(struct sfnt_point):
(sfnt_expand_compound_glyph_context):
(sfnt_decompose_compound_glyph):
(struct sfnt_glyph_outline):
(enum sfnt_glyph_outline_flags):
(struct sfnt_build_glyph_outline_context):
(sfnt_build_append):
(sfnt_build_glyph_outline):
(struct sfnt_raster):
(struct sfnt_edge):
(sfnt_prepare_raster):
(sfnt_build_outline_edges):
(sfnt_raster_glyph_outline): Move structures to sfnt.h.

(struct sfnt_long_hor_metric):
(struct sfnt_hmtx_table):
(struct sfnt_glyph_metrics):
(sfnt_read_hmtx_table):
(sfnt_lookup_glyph_metrics):
(sfnt_read_name_table):
(sfnt_find_name):
(sfnt_read_meta_table):
(sfnt_find_metadata):
(sfnt_test_edge_ignore): New functions.
(main): Add new tests.
* src/xdisp.c (redisplay_tool_bar):
This commit is contained in:
Po Lu 2023-01-08 15:42:37 +08:00
parent 86fe893128
commit 1584a58efd
10 changed files with 1063 additions and 849 deletions

View file

@ -1254,6 +1254,92 @@ NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
android_write_event (&event);
}
extern JNIEXPORT void JNICALL
NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
jshort window, jint x, jint y,
jlong time)
{
union android_event event;
event.xcrossing.type = ANDROID_ENTER_NOTIFY;
event.xcrossing.window = window;
event.xcrossing.x = x;
event.xcrossing.y = y;
event.xcrossing.time = time;
android_write_event (&event);
}
extern JNIEXPORT void JNICALL
NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
jshort window, jint x, jint y,
jlong time)
{
union android_event event;
event.xcrossing.type = ANDROID_LEAVE_NOTIFY;
event.xcrossing.window = window;
event.xcrossing.x = x;
event.xcrossing.y = y;
event.xcrossing.time = time;
android_write_event (&event);
}
extern JNIEXPORT void JNICALL
NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
jshort window, jint x, jint y,
jlong time)
{
union android_event event;
event.xmotion.type = ANDROID_MOTION_NOTIFY;
event.xmotion.window = window;
event.xmotion.x = x;
event.xmotion.y = y;
event.xmotion.time = time;
android_write_event (&event);
}
extern JNIEXPORT void JNICALL
NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
jshort window, jint x, jint y,
jlong time, jint state,
jint button)
{
union android_event event;
event.xbutton.type = ANDROID_BUTTON_PRESS;
event.xbutton.window = window;
event.xbutton.x = x;
event.xbutton.y = y;
event.xbutton.time = time;
event.xbutton.state = state;
event.xbutton.button = button;
android_write_event (&event);
}
extern JNIEXPORT void JNICALL
NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
jshort window, jint x, jint y,
jlong time, jint state,
jint button)
{
union android_event event;
event.xbutton.type = ANDROID_BUTTON_RELEASE;
event.xbutton.window = window;
event.xbutton.x = x;
event.xbutton.y = y;
event.xbutton.time = time;
event.xbutton.state = state;
event.xbutton.button = button;
android_write_event (&event);
}
#pragma clang diagnostic pop
@ -1747,12 +1833,11 @@ android_change_gc (struct android_gc *gc,
emacs_gc_clip_mask,
what);
/* Clearing GCClipMask also clears the clip rectangles. */
if (!what)
(*android_java_env)->SetObjectField (android_java_env,
gcontext,
emacs_gc_clip_rects,
NULL);
/* Changing GCClipMask also clears the clip rectangles. */
(*android_java_env)->SetObjectField (android_java_env,
gcontext,
emacs_gc_clip_rects,
NULL);
}
if (mask & ANDROID_GC_STIPPLE)
@ -2133,14 +2218,14 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
/* The alpha channels must be set, or otherwise, the
pixmap will be created entirely transparent. */
if (data[y * (width + 7) / 8 + x / 8] & (1 << (x % 8)))
if (data[x / 8] & (1 << (x % 8)))
region[x] = foreground | 0xff000000;
else
region[x] = background | 0xff000000;
}
else
{
if (data[y * (width + 7) / 8 + x / 8] & (1 << (x % 8)))
if (data[x / 8] & (1 << (x % 8)))
region[x] = foreground;
else
region[x] = background;
@ -2151,6 +2236,7 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
colors,
width * y, width,
region);
data += width / 8;
}
/* First, allocate the pixmap handle. */

View file

@ -1347,7 +1347,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
error ("Android cross-compilation stub called!");
return Qnil;
#else
error ("Not implemented");
/* TODO tooltips */
return Qnil;
#endif
}
@ -1360,7 +1360,6 @@ DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
error ("Android cross-compilation stub called!");
return Qnil;
#else
error ("Not implemented");
return Qnil;
#endif
}

View file

@ -204,6 +204,11 @@ enum android_event_type
ANDROID_FOCUS_IN,
ANDROID_FOCUS_OUT,
ANDROID_WINDOW_ACTION,
ANDROID_ENTER_NOTIFY,
ANDROID_LEAVE_NOTIFY,
ANDROID_MOTION_NOTIFY,
ANDROID_BUTTON_PRESS,
ANDROID_BUTTON_RELEASE,
};
struct android_any_event
@ -268,6 +273,32 @@ struct android_window_action_event
unsigned int action;
};
struct android_crossing_event
{
enum android_event_type type;
android_window window;
int x, y;
unsigned long time;
};
struct android_motion_event
{
enum android_event_type type;
android_window window;
int x, y;
unsigned long time;
};
struct android_button_event
{
enum android_event_type type;
android_window window;
int x, y;
unsigned long time;
unsigned int state;
unsigned int button;
};
union android_event
{
enum android_event_type type;
@ -276,6 +307,9 @@ union android_event
struct android_configure_event xconfigure;
struct android_focus_event xfocus;
struct android_window_action_event xaction;
struct android_crossing_event xcrossing;
struct android_motion_event xmotion;
struct android_button_event xbutton;
};
extern int android_pending (void);

View file

@ -41,6 +41,11 @@ struct android_display_info *x_display_list;
#include <android/log.h>
/* Non-zero means that a HELP_EVENT has been generated since Emacs
start. */
static bool any_help_event_p;
enum
{
ANDROID_EVENT_NORMAL,
@ -261,6 +266,94 @@ android_detect_focus_change (struct android_display_info *dpyinfo,
}
}
static bool
android_note_mouse_movement (struct frame *frame,
struct android_motion_event *event)
{
struct android_display_info *dpyinfo;
Emacs_Rectangle *r;
if (!FRAME_ANDROID_OUTPUT (frame))
return false;
dpyinfo = FRAME_DISPLAY_INFO (frame);
dpyinfo->last_mouse_motion_frame = frame;
dpyinfo->last_mouse_motion_x = event->x;
dpyinfo->last_mouse_motion_y = event->y;
dpyinfo->last_mouse_movement_time = event->time;
/* Has the mouse moved off the glyph it was on at the last sighting? */
r = &dpyinfo->last_mouse_glyph;
if (frame != dpyinfo->last_mouse_glyph_frame
|| event->x < r->x || event->x >= r->x + r->width
|| event->y < r->y || event->y >= r->y + r->height)
{
frame->mouse_moved = true;
/* TODO
dpyinfo->last_mouse_scroll_bar = NULL; */
note_mouse_highlight (frame, event->x, event->y);
/* Remember which glyph we're now on. */
remember_mouse_glyph (frame, event->x, event->y, r);
dpyinfo->last_mouse_glyph_frame = frame;
return true;
}
return false;
}
static struct frame *
mouse_or_wdesc_frame (struct android_display_info *dpyinfo, int wdesc)
{
struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
? dpyinfo->last_mouse_frame
: NULL);
if (lm_f && !EQ (track_mouse, Qdropping)
&& !EQ (track_mouse, Qdrag_source))
return lm_f;
else
{
struct frame *w_f = android_window_to_frame (dpyinfo, wdesc);
/* Do not return a tooltip frame. */
if (!w_f || FRAME_TOOLTIP_P (w_f))
return EQ (track_mouse, Qdropping) ? lm_f : NULL;
else
/* When dropping it would be probably nice to raise w_f
here. */
return w_f;
}
}
static Lisp_Object
android_construct_mouse_click (struct input_event *result,
struct android_button_event *event,
struct frame *f)
{
struct android_display_info *dpyinfo;
int x, y;
dpyinfo = FRAME_DISPLAY_INFO (f);
x = event->x;
y = event->y;
/* Make the event type NO_EVENT; we'll change that when we decide
otherwise. */
result->kind = MOUSE_CLICK_EVENT;
result->code = event->button - 1;
result->timestamp = event->time;
result->modifiers = (android_android_to_emacs_modifiers (dpyinfo,
event->state)
| (event->type == ANDROID_BUTTON_RELEASE
? up_modifier : down_modifier));
XSETINT (result->x, x);
XSETINT (result->y, y);
XSETFRAME (result->frame_or_window, f);
result->arg = Qnil;
return Qnil;
}
static int
handle_one_android_event (struct android_display_info *dpyinfo,
union android_event *event, int *finish,
@ -270,17 +363,20 @@ handle_one_android_event (struct android_display_info *dpyinfo,
struct frame *f, *any, *mouse_frame;
Mouse_HLInfo *hlinfo;
union buffered_input_event inev;
int modifiers, count;
int modifiers, count, do_help;
/* It is okay for this to not resemble handle_one_xevent so much.
Differences in event handling code are much less nasty than
stuble differences in the graphics code. */
count = 0;
do_help = count = 0;
hlinfo = &dpyinfo->mouse_highlight;
*finish = ANDROID_EVENT_NORMAL;
any = android_window_to_frame (dpyinfo, event->xany.window);
if (any && any->wait_event_type == event->type)
any->wait_event_type = 0; /* Indicates we got it. */
EVENT_INIT (inev.ie);
switch (event->type)
@ -410,6 +506,213 @@ handle_one_android_event (struct android_display_info *dpyinfo,
/* A new frame must be created. */;
}
case ANDROID_ENTER_NOTIFY:
f = any;
if (f)
android_note_mouse_movement (f, &event->xmotion);
goto OTHER;
case ANDROID_MOTION_NOTIFY:
f = any;
if (f)
{
/* Maybe generate a SELECT_WINDOW_EVENT for
`mouse-autoselect-window' but don't let popup menus
interfere with this (Bug#1261). */
if (!NILP (Vmouse_autoselect_window)
&& !popup_activated ()
/* Don't switch if we're currently in the minibuffer.
This tries to work around problems where the
minibuffer gets unselected unexpectedly, and where
you then have to move your mouse all the way down to
the minibuffer to select it. */
&& !MINI_WINDOW_P (XWINDOW (selected_window))
/* With `focus-follows-mouse' non-nil create an event
also when the target window is on another frame. */
&& (f == XFRAME (selected_frame)
|| !NILP (focus_follows_mouse)))
{
static Lisp_Object last_mouse_window;
Lisp_Object window
= window_from_coordinates (f, event->xmotion.x,
event->xmotion.y, 0,
false, false);
/* A window will be autoselected only when it is not
selected now and the last mouse movement event was
not in it. The remainder of the code is a bit vague
wrt what a "window" is. For immediate autoselection,
the window is usually the entire window but for GTK
where the scroll bars don't count. For delayed
autoselection the window is usually the window's text
area including the margins. */
if (WINDOWP (window)
&& !EQ (window, last_mouse_window)
&& !EQ (window, selected_window))
{
inev.ie.kind = SELECT_WINDOW_EVENT;
inev.ie.frame_or_window = window;
}
/* Remember the last window where we saw the mouse. */
last_mouse_window = window;
}
if (!android_note_mouse_movement (f, &event->xmotion))
help_echo_string = previous_help_echo_string;
}
/* If the contents of the global variable help_echo_string
has changed, generate a HELP_EVENT. */
if (!NILP (help_echo_string)
|| !NILP (previous_help_echo_string))
do_help = 1;
if (f)
android_flush_dirty_back_buffer_on (f);
goto OTHER;
case ANDROID_LEAVE_NOTIFY:
f = any;
if (f)
{
/* Now clear dpyinfo->last_mouse_motion_frame, or
gui_redo_mouse_highlight will end up highlighting the
last known position of the mouse if a tooltip frame is
later unmapped. */
if (f == dpyinfo->last_mouse_motion_frame)
dpyinfo->last_mouse_motion_frame = NULL;
/* Something similar applies to
dpyinfo->last_mouse_glyph_frame. */
if (f == dpyinfo->last_mouse_glyph_frame)
dpyinfo->last_mouse_glyph_frame = NULL;
if (f == hlinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
certainly no longer on any text in the frame. */
clear_mouse_face (hlinfo);
hlinfo->mouse_face_mouse_frame = 0;
android_flush_dirty_back_buffer_on (f);
}
/* Generate a nil HELP_EVENT to cancel a help-echo.
Do it only if there's something to cancel.
Otherwise, the startup message is cleared when
the mouse leaves the frame. */
if (any_help_event_p
/* But never if `mouse-drag-and-drop-region' is in
progress, since that results in the tooltip being
dismissed when the mouse moves on top. */
&& !((EQ (track_mouse, Qdrag_source)
|| EQ (track_mouse, Qdropping))
&& gui_mouse_grabbed (dpyinfo)))
do_help = -1;
}
goto OTHER;
case ANDROID_BUTTON_PRESS:
case ANDROID_BUTTON_RELEASE:
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
f = any;
Lisp_Object tab_bar_arg = Qnil;
bool tab_bar_p = false;
bool tool_bar_p = false;
dpyinfo->last_mouse_glyph_frame = NULL;
f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
if (f)
{
/* Is this in the tab-bar? */
if (WINDOWP (f->tab_bar_window)
&& WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
{
Lisp_Object window;
int x = event->xbutton.x;
int y = event->xbutton.y;
window = window_from_coordinates (f, x, y, 0, true, true);
tab_bar_p = EQ (window, f->tab_bar_window);
if (tab_bar_p)
{
tab_bar_arg = handle_tab_bar_click
(f, x, y, (event->xbutton.type
== ANDROID_BUTTON_PRESS),
android_android_to_emacs_modifiers (dpyinfo,
event->xbutton.state));
android_flush_dirty_back_buffer_on (f);
}
}
/* Is this in the tool-bar? */
if (WINDOWP (f->tool_bar_window)
&& WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
{
Lisp_Object window;
int x = event->xbutton.x;
int y = event->xbutton.y;
window = window_from_coordinates (f, x, y, 0, true, true);
tool_bar_p = (EQ (window, f->tool_bar_window)
&& ((event->xbutton.type
!= ANDROID_BUTTON_RELEASE)
|| f->last_tool_bar_item != -1));
if (tool_bar_p && event->xbutton.button < 4)
{
handle_tool_bar_click
(f, x, y, (event->xbutton.type
== ANDROID_BUTTON_PRESS),
android_android_to_emacs_modifiers (dpyinfo,
event->xbutton.state));
android_flush_dirty_back_buffer_on (f);
}
}
if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
{
android_construct_mouse_click (&inev.ie, &event->xbutton, f);
if (!NILP (tab_bar_arg))
inev.ie.arg = tab_bar_arg;
}
}
else
{
/* TODO: scroll bars */
}
if (event->type == ANDROID_BUTTON_PRESS)
{
dpyinfo->grabbed |= (1 << event->xbutton.button);
dpyinfo->last_mouse_frame = f;
if (f && !tab_bar_p)
f->last_tab_bar_item = -1;
if (f && !tool_bar_p)
f->last_tool_bar_item = -1;
}
else
dpyinfo->grabbed &= ~(1 << event->xbutton.button);
/* Ignore any mouse motion that happened before this event;
any subsequent mouse-movement Emacs events should reflect
only motion after the ButtonPress/Release. */
if (f != 0)
f->mouse_moved = false;
goto OTHER;
default:
@ -423,6 +726,30 @@ handle_one_android_event (struct android_display_info *dpyinfo,
count++;
}
if (do_help
&& !(hold_quit && hold_quit->kind != NO_EVENT))
{
Lisp_Object frame;
if (f)
XSETFRAME (frame, f);
else
frame = Qnil;
if (do_help > 0)
{
any_help_event_p = true;
gen_help_event (help_echo_string, frame, help_echo_window,
help_echo_object, help_echo_pos);
}
else
{
help_echo_string = Qnil;
gen_help_event (Qnil, frame, Qnil, Qnil, 0);
}
count++;
}
return count;
}
@ -562,7 +889,32 @@ android_mouse_position (struct frame **fp, int insist,
enum scroll_bar_part *part, Lisp_Object *x,
Lisp_Object *y, Time *timestamp)
{
/* TODO */
Lisp_Object tail, frame;
struct android_display_info *dpyinfo;
dpyinfo = FRAME_DISPLAY_INFO (*fp);
/* This is the best implementation possible on Android, where the
system doesn't let Emacs obtain any information about the mouse
pointer at all. */
if (dpyinfo->last_mouse_motion_frame)
{
*fp = dpyinfo->last_mouse_motion_frame;
*timestamp = dpyinfo->last_mouse_movement_time;
*x = make_fixnum (dpyinfo->last_mouse_motion_x);
*y = make_fixnum (dpyinfo->last_mouse_motion_y);
*bar_window = Qnil;
*part = scroll_bar_nowhere;
FOR_EACH_FRAME (tail, frame)
{
if (FRAME_ANDROID_P (XFRAME (frame)))
XFRAME (frame)->mouse_moved = false;
}
dpyinfo->last_mouse_motion_frame->mouse_moved = false;
}
}
static Lisp_Object
@ -678,6 +1030,45 @@ android_iconify_frame (struct frame *f)
/* TODO */
}
static void
android_wait_for_event (struct frame *f, int eventtype)
{
if (!FLOATP (Vandroid_wait_for_event_timeout))
return;
int level = interrupt_input_blocked;
struct timespec tmo, tmo_at, time_now;
f->wait_event_type = eventtype;
/* Default timeout is 0.1 second. Hopefully not noticeable. */
double timeout = XFLOAT_DATA (Vandroid_wait_for_event_timeout);
time_t timeout_seconds = (time_t) timeout;
tmo = make_timespec (timeout_seconds,
(long int) ((timeout - timeout_seconds)
* 1000 * 1000 * 1000));
tmo_at = timespec_add (current_timespec (), tmo);
while (f->wait_event_type)
{
pending_signals = true;
totally_unblock_input ();
/* XTread_socket is called after unblock. */
block_input ();
interrupt_input_blocked = level;
time_now = current_timespec ();
if (timespec_cmp (tmo_at, time_now) < 0)
break;
tmo = timespec_sub (tmo_at, time_now);
if (android_select (0, NULL, NULL, NULL, &tmo, NULL) == 0)
break; /* Timeout */
}
f->wait_event_type = 0;
}
static void
android_set_window_size_1 (struct frame *f, bool change_gravity,
int width, int height)
@ -688,11 +1079,29 @@ android_set_window_size_1 (struct frame *f, bool change_gravity,
android_resize_window (FRAME_ANDROID_WINDOW (f), width,
height);
/* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
receive in the ConfigureNotify event; if we get what we asked
for, then the event won't cause the screen to become garbaged, so
we have to make sure to do it here. */
SET_FRAME_GARBAGED (f);
if (FRAME_VISIBLE_P (f))
{
android_wait_for_event (f, ANDROID_CONFIGURE_NOTIFY);
if (CONSP (frame_size_history))
frame_size_history_extra (f, build_string ("set_window_size_1 visible"),
FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
width, height, f->new_width, f->new_height);
}
else
{
if (CONSP (frame_size_history))
frame_size_history_extra (f, build_string ("set_window_size_1 "
"invisible"),
FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
width, height, f->new_width, f->new_height);
adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
5, 0, Qx_set_window_size_1);
}
}
void
@ -792,7 +1201,6 @@ android_new_font (struct frame *f, Lisp_Object font_object, int fontset)
static bool
android_bitmap_icon (struct frame *f, Lisp_Object file)
{
/* TODO */
return false;
}
@ -841,6 +1249,13 @@ android_free_frame_resources (struct frame *f)
if (f == hlinfo->mouse_face_mouse_frame)
reset_mouse_highlight (hlinfo);
/* These two need to be freed now that they are used to compute the
mouse position, I think. */
if (f == dpyinfo->last_mouse_motion_frame)
dpyinfo->last_mouse_motion_frame = NULL;
if (f == dpyinfo->last_mouse_frame)
dpyinfo->last_mouse_frame = NULL;
unblock_input ();
}
@ -3233,6 +3648,18 @@ syms_of_androidterm (void)
{
Fprovide (Qandroid, Qnil);
DEFVAR_LISP ("android-wait-for-event-timeout",
Vandroid_wait_for_event_timeout,
doc: /* How long to wait for Android events.
Emacs will wait up to this many seconds to receive events after
making changes which affect the state of the graphical interface.
Under some situations this can take an indefinite amount of time,
so it is important to limit the wait.
If set to a non-float value, there will be no wait at all. */);
Vandroid_wait_for_event_timeout = make_float (0.1);
DEFVAR_BOOL ("x-use-underline-position-properties",
x_use_underline_position_properties,
doc: /* SKIP: real doc in xterm.c. */);

View file

@ -129,6 +129,9 @@ struct android_display_info
/* Where the mouse was the last time the mouse moved. */
Emacs_Rectangle last_mouse_glyph;
/* The time of the last mouse movement. */
Time last_mouse_movement_time;
};
struct android_output
@ -193,11 +196,6 @@ struct android_output
and inactive states. */
bool_bf alpha_identical_p : 1;
/* Flag that indicates whether we've modified the back buffer and
need to publish our modifications to the front buffer at a
convenient time. */
bool_bf need_buffer_flip : 1;
/* Flag that indicates whether or not the frame contents are
complete and can be safely flushed while handling async
input. */
@ -376,6 +374,11 @@ extern void syms_of_androidfont (void);
extern void android_finalize_font_entity (struct font_entity *);
/* Defined in sfntfont-android.c. */
extern void init_sfntfont_android (void);
extern void syms_of_sfntfont_android (void);
#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))

View file

@ -37,6 +37,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "androidterm.h"
#endif
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
#include "sfntfont.h"
#endif
#ifdef WINDOWSNT
#include <fcntl.h>
#include <sys/socket.h>
@ -2396,6 +2400,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_fontset ();
#if !defined ANDROID_STUBIFY
syms_of_androidfont ();
syms_of_sfntfont ();
syms_of_sfntfont_android ();
#endif /* !ANDROID_STUBIFY */
#endif /* HAVE_ANDROID */
@ -2461,6 +2467,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
init_androidfont ();
init_sfntfont ();
init_sfntfont_android ();
#endif
init_charset ();

View file

@ -6644,7 +6644,7 @@ implicitly when there's no window system support.
Note that when a frame is not large enough to accommodate a change of
any of the parameters listed above, Emacs may try to enlarge the frame
even if this option is non-nil. */);
#if defined (HAVE_WINDOW_SYSTEM)
#if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_ANDROID)
#if defined (USE_GTK) || defined (HAVE_NS)
frame_inhibit_implied_resize = list1 (Qtab_bar_lines);
#else

View file

@ -599,8 +599,9 @@ struct frame
/* List of font-drivers available on the frame. */
struct font_driver_list *font_driver_list;
#if defined (HAVE_X_WINDOWS)
/* Used by x_wait_for_event when watching for an X event on this frame. */
#if defined HAVE_X_WINDOWS || defined HAVE_ANDROID
/* Used by x_wait_for_event when watching for an X event on this
frame. */
int wait_event_type;
#endif

1293
src/sfnt.c

File diff suppressed because it is too large Load diff

View file

@ -15230,6 +15230,15 @@ redisplay_tool_bar (struct frame *f)
/* Always do that now. */
clear_glyph_matrix (w->desired_matrix);
f->fonts_changed = true;
/* Kludge (this applies to the X Windows version as well as
Android): when the tool bar size changes,
adjust_window_size (presumably called by
change_tool_bar_height_hook) does not call through to
resize_frame_windows. Pending further investigation,
just call it here as well. */
resize_frame_windows (f, FRAME_INNER_HEIGHT (f), false);
return true;
}
}