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:
parent
86fe893128
commit
1584a58efd
10 changed files with 1063 additions and 849 deletions
102
src/android.c
102
src/android.c
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
1293
src/sfnt.c
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue