diff options
| author | Po Lu | 2023-01-14 22:12:16 +0800 |
|---|---|---|
| committer | Po Lu | 2023-01-14 22:12:16 +0800 |
| commit | 2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a (patch) | |
| tree | 3ab31df90bd435009d2d42b636ce3baf33bd2b28 /src/androidfns.c | |
| parent | 28a9baccd4c8e997895d3adb3cfce4a11fa29896 (diff) | |
| download | emacs-2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a.tar.gz emacs-2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a.zip | |
Update Android port
* java/Makefile.in (clean): Fix distclean and bootstrap-clean rules.
* java/debug.sh (jdb_port):
(attach_existing):
(num_pids):
(line): Add new options to upload a gdbserver binary to the device.
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): Make
focusedActivities public.
* java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
New class.
* java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Fix
bounds computation.
* java/org/gnu/emacs/EmacsGC.java (markDirty): Set stroke width
explicitly.
* java/org/gnu/emacs/EmacsService.java (EmacsService)
(getLocationOnScreen, nameKeysym): New functions.
* java/org/gnu/emacs/EmacsView.java (EmacsView): Disable focus
highlight.
(onCreateContextMenu, popupMenu, cancelPopupMenu): New
functions.
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): Implement a
kind of ``override redirect'' window for tooltips.
* src/android.c (struct android_emacs_service): New method
`name_keysym'.
(android_run_select_thread, android_init_events):
(android_select): Release select thread on semaphores instead of
signals to avoid one nasty race on SIGUSR2 delivery.
(android_init_emacs_service): Initialize new method.
(android_create_window): Handle CW_OVERRIDE_REDIRECT.
(android_move_resize_window, android_map_raised)
(android_translate_coordinates, android_get_keysym_name)
(android_build_string, android_exception_check): New functions.
* src/android.h: Update prototypes.
* src/androidfns.c (android_set_parent_frame, Fx_create_frame)
(unwind_create_tip_frame, android_create_tip_frame)
(android_hide_tip, compute_tip_xy, Fx_show_tip, Fx_hide_tip)
(syms_of_androidfns): Implement tooltips and iconification
reporting.
* src/androidgui.h (enum android_window_value_mask): Add
CWOverrideRedirect.
(struct android_set_window_attributes): Add `override_redirect'.
(ANDROID_IS_MODIFIER_KEY): Recognize Caps Lock.
* src/androidmenu.c (struct android_emacs_context_menu): New
struct.
(android_init_emacs_context_menu, android_unwind_local_frame)
(android_push_local_frame, android_menu_show, init_androidmenu):
New functions.
* src/androidterm.c (handle_one_android_event): Fix NULL pointer
dereference.
(android_fullscreen_hook): Handle fullscreen correctly.
(android_draw_box_rect): Fix top line.
(get_keysym_name): Implement function.
(android_create_terminal): Remove scroll bar stubs and add menu
hook.
* src/androidterm.h: Update prototypes.
* src/emacs.c (android_emacs_init): Initialize androidmenu.c.
* xcompile/Makefile.in: Fix clean rules.
Diffstat (limited to 'src/androidfns.c')
| -rw-r--r-- | src/androidfns.c | 677 |
1 files changed, 664 insertions, 13 deletions
diff --git a/src/androidfns.c b/src/androidfns.c index 459e407b901..ab136bc2722 100644 --- a/src/androidfns.c +++ b/src/androidfns.c | |||
| @@ -25,12 +25,36 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 25 | #include "androidterm.h" | 25 | #include "androidterm.h" |
| 26 | #include "blockinput.h" | 26 | #include "blockinput.h" |
| 27 | #include "keyboard.h" | 27 | #include "keyboard.h" |
| 28 | #include "buffer.h" | ||
| 28 | 29 | ||
| 29 | #ifndef ANDROID_STUBIFY | 30 | #ifndef ANDROID_STUBIFY |
| 30 | 31 | ||
| 31 | /* Some kind of reference count for the image cache. */ | 32 | /* Some kind of reference count for the image cache. */ |
| 32 | static ptrdiff_t image_cache_refcount; | 33 | static ptrdiff_t image_cache_refcount; |
| 33 | 34 | ||
| 35 | /* The frame of the currently visible tooltip, or nil if none. */ | ||
| 36 | static Lisp_Object tip_frame; | ||
| 37 | |||
| 38 | /* The window-system window corresponding to the frame of the | ||
| 39 | currently visible tooltip. */ | ||
| 40 | static android_window tip_window; | ||
| 41 | |||
| 42 | /* The X and Y deltas of the last call to `x-show-tip'. */ | ||
| 43 | static Lisp_Object tip_dx, tip_dy; | ||
| 44 | |||
| 45 | /* A timer that hides or deletes the currently visible tooltip when it | ||
| 46 | fires. */ | ||
| 47 | static Lisp_Object tip_timer; | ||
| 48 | |||
| 49 | /* STRING argument of last `x-show-tip' call. */ | ||
| 50 | static Lisp_Object tip_last_string; | ||
| 51 | |||
| 52 | /* Normalized FRAME argument of last `x-show-tip' call. */ | ||
| 53 | static Lisp_Object tip_last_frame; | ||
| 54 | |||
| 55 | /* PARMS argument of last `x-show-tip' call. */ | ||
| 56 | static Lisp_Object tip_last_parms; | ||
| 57 | |||
| 34 | #endif | 58 | #endif |
| 35 | 59 | ||
| 36 | static struct android_display_info * | 60 | static struct android_display_info * |
| @@ -180,6 +204,9 @@ android_set_parent_frame (struct frame *f, Lisp_Object new_value, | |||
| 180 | 204 | ||
| 181 | fset_parent_frame (f, new_value); | 205 | fset_parent_frame (f, new_value); |
| 182 | } | 206 | } |
| 207 | |||
| 208 | /* Update the fullscreen frame parameter as well. */ | ||
| 209 | FRAME_TERMINAL (f)->fullscreen_hook (f); | ||
| 183 | } | 210 | } |
| 184 | 211 | ||
| 185 | void | 212 | void |
| @@ -858,13 +885,13 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 858 | gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), | 885 | gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), |
| 859 | NULL, NULL, RES_TYPE_NUMBER); | 886 | NULL, NULL, RES_TYPE_NUMBER); |
| 860 | 887 | ||
| 861 | /* gui_default_parameter (f, parms, Qvertical_scroll_bars, */ | 888 | gui_default_parameter (f, parms, Qvertical_scroll_bars, |
| 862 | /* Qleft, */ | 889 | Qleft, |
| 863 | /* "verticalScrollBars", "ScrollBars", */ | 890 | "verticalScrollBars", "ScrollBars", |
| 864 | /* RES_TYPE_SYMBOL); */ | 891 | RES_TYPE_SYMBOL); |
| 865 | /* gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil, */ | 892 | gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil, |
| 866 | /* "horizontalScrollBars", "ScrollBars", */ | 893 | "horizontalScrollBars", "ScrollBars", |
| 867 | /* RES_TYPE_SYMBOL); TODO */ | 894 | RES_TYPE_SYMBOL); |
| 868 | 895 | ||
| 869 | /* Also do the stuff which must be set before the window exists. */ | 896 | /* Also do the stuff which must be set before the window exists. */ |
| 870 | gui_default_parameter (f, parms, Qforeground_color, build_string ("black"), | 897 | gui_default_parameter (f, parms, Qforeground_color, build_string ("black"), |
| @@ -893,7 +920,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 893 | android_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background, | 920 | android_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background, |
| 894 | "scrollBarBackground", | 921 | "scrollBarBackground", |
| 895 | "ScrollBarBackground", false); | 922 | "ScrollBarBackground", false); |
| 896 | #endif /* TODO */ | 923 | #endif |
| 897 | 924 | ||
| 898 | /* Init faces before gui_default_parameter is called for the | 925 | /* Init faces before gui_default_parameter is called for the |
| 899 | scroll-bar-width parameter because otherwise we end up in | 926 | scroll-bar-width parameter because otherwise we end up in |
| @@ -974,12 +1001,16 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 974 | "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN); | 1001 | "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN); |
| 975 | gui_default_parameter (f, parms, Qcursor_type, Qbox, | 1002 | gui_default_parameter (f, parms, Qcursor_type, Qbox, |
| 976 | "cursorType", "CursorType", RES_TYPE_SYMBOL); | 1003 | "cursorType", "CursorType", RES_TYPE_SYMBOL); |
| 1004 | /* Scroll bars are not supported on Android, as they are near | ||
| 1005 | useless. */ | ||
| 1006 | #if 0 | ||
| 977 | gui_default_parameter (f, parms, Qscroll_bar_width, Qnil, | 1007 | gui_default_parameter (f, parms, Qscroll_bar_width, Qnil, |
| 978 | "scrollBarWidth", "ScrollBarWidth", | 1008 | "scrollBarWidth", "ScrollBarWidth", |
| 979 | RES_TYPE_NUMBER); | 1009 | RES_TYPE_NUMBER); |
| 980 | gui_default_parameter (f, parms, Qscroll_bar_height, Qnil, | 1010 | gui_default_parameter (f, parms, Qscroll_bar_height, Qnil, |
| 981 | "scrollBarHeight", "ScrollBarHeight", | 1011 | "scrollBarHeight", "ScrollBarHeight", |
| 982 | RES_TYPE_NUMBER); | 1012 | RES_TYPE_NUMBER); |
| 1013 | #endif | ||
| 983 | gui_default_parameter (f, parms, Qalpha, Qnil, | 1014 | gui_default_parameter (f, parms, Qalpha, Qnil, |
| 984 | "alpha", "Alpha", RES_TYPE_NUMBER); | 1015 | "alpha", "Alpha", RES_TYPE_NUMBER); |
| 985 | gui_default_parameter (f, parms, Qalpha_background, Qnil, | 1016 | gui_default_parameter (f, parms, Qalpha_background, Qnil, |
| @@ -1009,8 +1040,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 1009 | 1040 | ||
| 1010 | /* Process fullscreen parameter here in the hope that normalizing a | 1041 | /* Process fullscreen parameter here in the hope that normalizing a |
| 1011 | fullheight/fullwidth frame will produce the size set by the last | 1042 | fullheight/fullwidth frame will produce the size set by the last |
| 1012 | adjust_frame_size call. */ | 1043 | adjust_frame_size call. Note that Android only supports the |
| 1013 | gui_default_parameter (f, parms, Qfullscreen, Qnil, | 1044 | `maximized' state. */ |
| 1045 | gui_default_parameter (f, parms, Qfullscreen, Qmaximized, | ||
| 1014 | "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); | 1046 | "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); |
| 1015 | 1047 | ||
| 1016 | /* When called from `x-create-frame-with-faces' visibility is | 1048 | /* When called from `x-create-frame-with-faces' visibility is |
| @@ -1661,6 +1693,391 @@ DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0, | |||
| 1661 | return result; | 1693 | return result; |
| 1662 | } | 1694 | } |
| 1663 | 1695 | ||
| 1696 | #ifndef ANDROID_STUBIFY | ||
| 1697 | |||
| 1698 | static void | ||
| 1699 | unwind_create_tip_frame (Lisp_Object frame) | ||
| 1700 | { | ||
| 1701 | Lisp_Object deleted; | ||
| 1702 | |||
| 1703 | deleted = unwind_create_frame (frame); | ||
| 1704 | if (EQ (deleted, Qt)) | ||
| 1705 | { | ||
| 1706 | tip_window = ANDROID_NONE; | ||
| 1707 | tip_frame = Qnil; | ||
| 1708 | } | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | static Lisp_Object | ||
| 1712 | android_create_tip_frame (struct android_display_info *dpyinfo, | ||
| 1713 | Lisp_Object parms) | ||
| 1714 | { | ||
| 1715 | struct frame *f; | ||
| 1716 | Lisp_Object frame; | ||
| 1717 | Lisp_Object name; | ||
| 1718 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 1719 | bool face_change_before = face_change; | ||
| 1720 | |||
| 1721 | if (!dpyinfo->terminal->name) | ||
| 1722 | error ("Terminal is not live, can't create new frames on it"); | ||
| 1723 | |||
| 1724 | parms = Fcopy_alist (parms); | ||
| 1725 | |||
| 1726 | /* Get the name of the frame to use for resource lookup. */ | ||
| 1727 | name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name", | ||
| 1728 | RES_TYPE_STRING); | ||
| 1729 | if (!STRINGP (name) | ||
| 1730 | && !BASE_EQ (name, Qunbound) | ||
| 1731 | && !NILP (name)) | ||
| 1732 | error ("Invalid frame name--not a string or nil"); | ||
| 1733 | |||
| 1734 | frame = Qnil; | ||
| 1735 | f = make_frame (false); | ||
| 1736 | f->wants_modeline = false; | ||
| 1737 | XSETFRAME (frame, f); | ||
| 1738 | record_unwind_protect (unwind_create_tip_frame, frame); | ||
| 1739 | |||
| 1740 | f->terminal = dpyinfo->terminal; | ||
| 1741 | |||
| 1742 | /* By setting the output method, we're essentially saying that | ||
| 1743 | the frame is live, as per FRAME_LIVE_P. If we get a signal | ||
| 1744 | from this point on, x_destroy_window might screw up reference | ||
| 1745 | counts etc. */ | ||
| 1746 | f->output_method = output_android; | ||
| 1747 | f->output_data.android = xzalloc (sizeof *f->output_data.android); | ||
| 1748 | FRAME_FONTSET (f) = -1; | ||
| 1749 | f->output_data.android->white_relief.pixel = -1; | ||
| 1750 | f->output_data.android->black_relief.pixel = -1; | ||
| 1751 | |||
| 1752 | f->tooltip = true; | ||
| 1753 | fset_icon_name (f, Qnil); | ||
| 1754 | FRAME_DISPLAY_INFO (f) = dpyinfo; | ||
| 1755 | f->output_data.android->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | ||
| 1756 | |||
| 1757 | /* These colors will be set anyway later, but it's important | ||
| 1758 | to get the color reference counts right, so initialize them! */ | ||
| 1759 | { | ||
| 1760 | Lisp_Object black; | ||
| 1761 | |||
| 1762 | /* Function android_decode_color can signal an error. Make sure | ||
| 1763 | to initialize color slots so that we won't try to free colors | ||
| 1764 | we haven't allocated. */ | ||
| 1765 | FRAME_FOREGROUND_PIXEL (f) = -1; | ||
| 1766 | FRAME_BACKGROUND_PIXEL (f) = -1; | ||
| 1767 | f->output_data.android->cursor_pixel = -1; | ||
| 1768 | f->output_data.android->cursor_foreground_pixel = -1; | ||
| 1769 | |||
| 1770 | black = build_string ("black"); | ||
| 1771 | FRAME_FOREGROUND_PIXEL (f) | ||
| 1772 | = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 1773 | FRAME_BACKGROUND_PIXEL (f) | ||
| 1774 | = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 1775 | f->output_data.android->cursor_pixel | ||
| 1776 | = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 1777 | f->output_data.android->cursor_foreground_pixel | ||
| 1778 | = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | /* Set the name; the functions to which we pass f expect the name to | ||
| 1782 | be set. */ | ||
| 1783 | if (BASE_EQ (name, Qunbound) || NILP (name)) | ||
| 1784 | f->explicit_name = false; | ||
| 1785 | else | ||
| 1786 | { | ||
| 1787 | fset_name (f, name); | ||
| 1788 | f->explicit_name = true; | ||
| 1789 | /* use the frame's title when getting resources for this frame. */ | ||
| 1790 | specbind (Qx_resource_name, name); | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | register_font_driver (&androidfont_driver, f); | ||
| 1794 | register_font_driver (&android_sfntfont_driver, f); | ||
| 1795 | |||
| 1796 | image_cache_refcount | ||
| 1797 | = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 1798 | #ifdef GLYPH_DEBUG | ||
| 1799 | dpyinfo_refcount = dpyinfo->reference_count; | ||
| 1800 | #endif /* GLYPH_DEBUG */ | ||
| 1801 | |||
| 1802 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | ||
| 1803 | "fontBackend", "FontBackend", RES_TYPE_STRING); | ||
| 1804 | |||
| 1805 | /* Extract the window parameters from the supplied values that are | ||
| 1806 | needed to determine window geometry. */ | ||
| 1807 | android_default_font_parameter (f, parms); | ||
| 1808 | |||
| 1809 | gui_default_parameter (f, parms, Qborder_width, make_fixnum (0), | ||
| 1810 | "borderWidth", "BorderWidth", RES_TYPE_NUMBER); | ||
| 1811 | |||
| 1812 | /* This defaults to 1 in order to match xterm. We recognize either | ||
| 1813 | internalBorderWidth or internalBorder (which is what xterm calls | ||
| 1814 | it). */ | ||
| 1815 | if (NILP (Fassq (Qinternal_border_width, parms))) | ||
| 1816 | { | ||
| 1817 | Lisp_Object value; | ||
| 1818 | |||
| 1819 | value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width, | ||
| 1820 | "internalBorder", "internalBorder", | ||
| 1821 | RES_TYPE_NUMBER); | ||
| 1822 | if (! BASE_EQ (value, Qunbound)) | ||
| 1823 | parms = Fcons (Fcons (Qinternal_border_width, value), | ||
| 1824 | parms); | ||
| 1825 | } | ||
| 1826 | |||
| 1827 | gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1), | ||
| 1828 | "internalBorderWidth", "internalBorderWidth", | ||
| 1829 | RES_TYPE_NUMBER); | ||
| 1830 | gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0), | ||
| 1831 | NULL, NULL, RES_TYPE_NUMBER); | ||
| 1832 | gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), | ||
| 1833 | NULL, NULL, RES_TYPE_NUMBER); | ||
| 1834 | |||
| 1835 | /* Also do the stuff which must be set before the window exists. */ | ||
| 1836 | gui_default_parameter (f, parms, Qforeground_color, build_string ("black"), | ||
| 1837 | "foreground", "Foreground", RES_TYPE_STRING); | ||
| 1838 | gui_default_parameter (f, parms, Qbackground_color, build_string ("white"), | ||
| 1839 | "background", "Background", RES_TYPE_STRING); | ||
| 1840 | gui_default_parameter (f, parms, Qmouse_color, build_string ("black"), | ||
| 1841 | "pointerColor", "Foreground", RES_TYPE_STRING); | ||
| 1842 | gui_default_parameter (f, parms, Qcursor_color, build_string ("black"), | ||
| 1843 | "cursorColor", "Foreground", RES_TYPE_STRING); | ||
| 1844 | gui_default_parameter (f, parms, Qborder_color, build_string ("black"), | ||
| 1845 | "borderColor", "BorderColor", RES_TYPE_STRING); | ||
| 1846 | gui_default_parameter (f, parms, Qno_special_glyphs, Qnil, | ||
| 1847 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 1848 | |||
| 1849 | { | ||
| 1850 | struct android_set_window_attributes attrs; | ||
| 1851 | unsigned long mask; | ||
| 1852 | |||
| 1853 | block_input (); | ||
| 1854 | mask = ANDROID_CW_OVERRIDE_REDIRECT; | ||
| 1855 | |||
| 1856 | attrs.override_redirect = true; | ||
| 1857 | tip_window | ||
| 1858 | = FRAME_ANDROID_WINDOW (f) | ||
| 1859 | = android_create_window (FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1860 | /* x, y, width, height, value-mask, | ||
| 1861 | attrs. */ | ||
| 1862 | 0, 0, 1, 1, mask, &attrs); | ||
| 1863 | unblock_input (); | ||
| 1864 | } | ||
| 1865 | |||
| 1866 | /* Init faces before gui_default_parameter is called for the | ||
| 1867 | scroll-bar-width parameter because otherwise we end up in | ||
| 1868 | init_iterator with a null face cache, which should not happen. */ | ||
| 1869 | init_frame_faces (f); | ||
| 1870 | |||
| 1871 | gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil, | ||
| 1872 | "inhibitDoubleBuffering", "InhibitDoubleBuffering", | ||
| 1873 | RES_TYPE_BOOLEAN); | ||
| 1874 | |||
| 1875 | gui_figure_window_size (f, parms, false, false); | ||
| 1876 | |||
| 1877 | f->output_data.android->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | ||
| 1878 | |||
| 1879 | android_make_gc (f); | ||
| 1880 | |||
| 1881 | gui_default_parameter (f, parms, Qauto_raise, Qnil, | ||
| 1882 | "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN); | ||
| 1883 | gui_default_parameter (f, parms, Qauto_lower, Qnil, | ||
| 1884 | "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN); | ||
| 1885 | gui_default_parameter (f, parms, Qcursor_type, Qbox, | ||
| 1886 | "cursorType", "CursorType", RES_TYPE_SYMBOL); | ||
| 1887 | gui_default_parameter (f, parms, Qalpha, Qnil, | ||
| 1888 | "alpha", "Alpha", RES_TYPE_NUMBER); | ||
| 1889 | gui_default_parameter (f, parms, Qalpha_background, Qnil, | ||
| 1890 | "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER); | ||
| 1891 | |||
| 1892 | /* Add `tooltip' frame parameter's default value. */ | ||
| 1893 | if (NILP (Fframe_parameter (frame, Qtooltip))) | ||
| 1894 | { | ||
| 1895 | AUTO_FRAME_ARG (arg, Qtooltip, Qt); | ||
| 1896 | Fmodify_frame_parameters (frame, arg); | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | /* FIXME - can this be done in a similar way to normal frames? | ||
| 1900 | https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */ | ||
| 1901 | |||
| 1902 | /* Set the `display-type' frame parameter before setting up faces. */ | ||
| 1903 | { | ||
| 1904 | Lisp_Object disptype; | ||
| 1905 | |||
| 1906 | disptype = Qcolor; | ||
| 1907 | |||
| 1908 | if (NILP (Fframe_parameter (frame, Qdisplay_type))) | ||
| 1909 | { | ||
| 1910 | AUTO_FRAME_ARG (arg, Qdisplay_type, disptype); | ||
| 1911 | Fmodify_frame_parameters (frame, arg); | ||
| 1912 | } | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | /* Set up faces after all frame parameters are known. This call | ||
| 1916 | also merges in face attributes specified for new frames. */ | ||
| 1917 | { | ||
| 1918 | Lisp_Object bg = Fframe_parameter (frame, Qbackground_color); | ||
| 1919 | |||
| 1920 | call2 (Qface_set_after_frame_default, frame, Qnil); | ||
| 1921 | |||
| 1922 | if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) | ||
| 1923 | { | ||
| 1924 | AUTO_FRAME_ARG (arg, Qbackground_color, bg); | ||
| 1925 | Fmodify_frame_parameters (frame, arg); | ||
| 1926 | } | ||
| 1927 | } | ||
| 1928 | |||
| 1929 | f->no_split = true; | ||
| 1930 | |||
| 1931 | /* Now that the frame will be official, it counts as a reference to | ||
| 1932 | its display and terminal. */ | ||
| 1933 | f->terminal->reference_count++; | ||
| 1934 | |||
| 1935 | /* It is now ok to make the frame official even if we get an error | ||
| 1936 | below. And the frame needs to be on Vframe_list or making it | ||
| 1937 | visible won't work. */ | ||
| 1938 | Vframe_list = Fcons (frame, Vframe_list); | ||
| 1939 | f->can_set_window_size = true; | ||
| 1940 | adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), | ||
| 1941 | 0, true, Qtip_frame); | ||
| 1942 | |||
| 1943 | /* Setting attributes of faces of the tooltip frame from resources | ||
| 1944 | and similar will set face_change, which leads to the clearing of | ||
| 1945 | all current matrices. Since this isn't necessary here, avoid it | ||
| 1946 | by resetting face_change to the value it had before we created | ||
| 1947 | the tip frame. */ | ||
| 1948 | face_change = face_change_before; | ||
| 1949 | |||
| 1950 | /* Discard the unwind_protect. */ | ||
| 1951 | return unbind_to (count, frame); | ||
| 1952 | } | ||
| 1953 | |||
| 1954 | static Lisp_Object | ||
| 1955 | android_hide_tip (bool delete) | ||
| 1956 | { | ||
| 1957 | if (!NILP (tip_timer)) | ||
| 1958 | { | ||
| 1959 | call1 (Qcancel_timer, tip_timer); | ||
| 1960 | tip_timer = Qnil; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | if (NILP (tip_frame) | ||
| 1964 | || (!delete | ||
| 1965 | && !NILP (tip_frame) | ||
| 1966 | && FRAME_LIVE_P (XFRAME (tip_frame)) | ||
| 1967 | && !FRAME_VISIBLE_P (XFRAME (tip_frame)))) | ||
| 1968 | return Qnil; | ||
| 1969 | else | ||
| 1970 | { | ||
| 1971 | Lisp_Object was_open = Qnil; | ||
| 1972 | |||
| 1973 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 1974 | specbind (Qinhibit_redisplay, Qt); | ||
| 1975 | specbind (Qinhibit_quit, Qt); | ||
| 1976 | |||
| 1977 | if (!NILP (tip_frame)) | ||
| 1978 | { | ||
| 1979 | struct frame *f = XFRAME (tip_frame); | ||
| 1980 | |||
| 1981 | if (FRAME_LIVE_P (f)) | ||
| 1982 | { | ||
| 1983 | if (delete) | ||
| 1984 | { | ||
| 1985 | delete_frame (tip_frame, Qnil); | ||
| 1986 | tip_frame = Qnil; | ||
| 1987 | } | ||
| 1988 | else | ||
| 1989 | android_make_frame_invisible (XFRAME (tip_frame)); | ||
| 1990 | |||
| 1991 | was_open = Qt; | ||
| 1992 | } | ||
| 1993 | else | ||
| 1994 | tip_frame = Qnil; | ||
| 1995 | } | ||
| 1996 | else | ||
| 1997 | tip_frame = Qnil; | ||
| 1998 | |||
| 1999 | return unbind_to (count, was_open); | ||
| 2000 | } | ||
| 2001 | } | ||
| 2002 | |||
| 2003 | static void | ||
| 2004 | compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, | ||
| 2005 | Lisp_Object dy, int width, int height, int *root_x, | ||
| 2006 | int *root_y) | ||
| 2007 | { | ||
| 2008 | Lisp_Object left, top, right, bottom; | ||
| 2009 | int min_x, min_y, max_x, max_y = -1; | ||
| 2010 | android_window window; | ||
| 2011 | struct frame *mouse_frame; | ||
| 2012 | |||
| 2013 | /* Initialize these values in case there is no mouse frame. */ | ||
| 2014 | *root_x = 0; | ||
| 2015 | *root_y = 0; | ||
| 2016 | |||
| 2017 | /* User-specified position? */ | ||
| 2018 | left = CDR (Fassq (Qleft, parms)); | ||
| 2019 | top = CDR (Fassq (Qtop, parms)); | ||
| 2020 | right = CDR (Fassq (Qright, parms)); | ||
| 2021 | bottom = CDR (Fassq (Qbottom, parms)); | ||
| 2022 | |||
| 2023 | /* Move the tooltip window where the mouse pointer was last seen. | ||
| 2024 | Resize and show it. */ | ||
| 2025 | if ((!FIXNUMP (left) && !FIXNUMP (right)) | ||
| 2026 | || (!FIXNUMP (top) && !FIXNUMP (bottom))) | ||
| 2027 | { | ||
| 2028 | if (x_display_list->last_mouse_motion_frame) | ||
| 2029 | { | ||
| 2030 | *root_x = x_display_list->last_mouse_motion_x; | ||
| 2031 | *root_y = x_display_list->last_mouse_motion_y; | ||
| 2032 | mouse_frame = x_display_list->last_mouse_motion_frame; | ||
| 2033 | window = FRAME_ANDROID_WINDOW (mouse_frame); | ||
| 2034 | |||
| 2035 | /* Translate the coordinates to the screen. */ | ||
| 2036 | android_translate_coordinates (window, *root_x, *root_y, | ||
| 2037 | root_x, root_y); | ||
| 2038 | } | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | min_x = 0; | ||
| 2042 | min_y = 0; | ||
| 2043 | max_x = android_get_screen_width (); | ||
| 2044 | max_y = android_get_screen_height (); | ||
| 2045 | |||
| 2046 | if (FIXNUMP (top)) | ||
| 2047 | *root_y = XFIXNUM (top); | ||
| 2048 | else if (FIXNUMP (bottom)) | ||
| 2049 | *root_y = XFIXNUM (bottom) - height; | ||
| 2050 | else if (*root_y + XFIXNUM (dy) <= min_y) | ||
| 2051 | *root_y = min_y; /* Can happen for negative dy */ | ||
| 2052 | else if (*root_y + XFIXNUM (dy) + height <= max_y) | ||
| 2053 | /* It fits below the pointer */ | ||
| 2054 | *root_y += XFIXNUM (dy); | ||
| 2055 | else if (height + XFIXNUM (dy) + min_y <= *root_y) | ||
| 2056 | /* It fits above the pointer. */ | ||
| 2057 | *root_y -= height + XFIXNUM (dy); | ||
| 2058 | else | ||
| 2059 | /* Put it on the top. */ | ||
| 2060 | *root_y = min_y; | ||
| 2061 | |||
| 2062 | if (FIXNUMP (left)) | ||
| 2063 | *root_x = XFIXNUM (left); | ||
| 2064 | else if (FIXNUMP (right)) | ||
| 2065 | *root_x = XFIXNUM (right) - width; | ||
| 2066 | else if (*root_x + XFIXNUM (dx) <= min_x) | ||
| 2067 | *root_x = 0; /* Can happen for negative dx */ | ||
| 2068 | else if (*root_x + XFIXNUM (dx) + width <= max_x) | ||
| 2069 | /* It fits to the right of the pointer. */ | ||
| 2070 | *root_x += XFIXNUM (dx); | ||
| 2071 | else if (width + XFIXNUM (dx) + min_x <= *root_x) | ||
| 2072 | /* It fits to the left of the pointer. */ | ||
| 2073 | *root_x -= width + XFIXNUM (dx); | ||
| 2074 | else | ||
| 2075 | /* Put it left justified on the screen -- it ought to fit that way. */ | ||
| 2076 | *root_x = min_x; | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | #endif | ||
| 2080 | |||
| 1664 | DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, | 2081 | DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, |
| 1665 | doc: /* SKIP: real doc in xfns.c. */) | 2082 | doc: /* SKIP: real doc in xfns.c. */) |
| 1666 | (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, | 2083 | (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, |
| @@ -1670,8 +2087,214 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, | |||
| 1670 | error ("Android cross-compilation stub called!"); | 2087 | error ("Android cross-compilation stub called!"); |
| 1671 | return Qnil; | 2088 | return Qnil; |
| 1672 | #else | 2089 | #else |
| 1673 | /* TODO tooltips */ | 2090 | struct frame *f, *tip_f; |
| 1674 | return Qnil; | 2091 | struct window *w; |
| 2092 | int root_x, root_y; | ||
| 2093 | struct buffer *old_buffer; | ||
| 2094 | struct text_pos pos; | ||
| 2095 | int width, height; | ||
| 2096 | int old_windows_or_buffers_changed = windows_or_buffers_changed; | ||
| 2097 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 2098 | Lisp_Object window, size, tip_buf; | ||
| 2099 | bool displayed; | ||
| 2100 | #ifdef ENABLE_CHECKING | ||
| 2101 | struct glyph_row *row, *end; | ||
| 2102 | #endif | ||
| 2103 | AUTO_STRING (tip, " *tip*"); | ||
| 2104 | |||
| 2105 | specbind (Qinhibit_redisplay, Qt); | ||
| 2106 | |||
| 2107 | CHECK_STRING (string); | ||
| 2108 | if (SCHARS (string) == 0) | ||
| 2109 | string = make_unibyte_string (" ", 1); | ||
| 2110 | |||
| 2111 | if (NILP (frame)) | ||
| 2112 | frame = selected_frame; | ||
| 2113 | f = decode_window_system_frame (frame); | ||
| 2114 | |||
| 2115 | if (NILP (timeout)) | ||
| 2116 | timeout = Vx_show_tooltip_timeout; | ||
| 2117 | CHECK_FIXNAT (timeout); | ||
| 2118 | |||
| 2119 | if (NILP (dx)) | ||
| 2120 | dx = make_fixnum (5); | ||
| 2121 | else | ||
| 2122 | CHECK_FIXNUM (dx); | ||
| 2123 | |||
| 2124 | if (NILP (dy)) | ||
| 2125 | dy = make_fixnum (-10); | ||
| 2126 | else | ||
| 2127 | CHECK_FIXNUM (dy); | ||
| 2128 | |||
| 2129 | tip_dx = dx; | ||
| 2130 | tip_dy = dy; | ||
| 2131 | |||
| 2132 | if (!NILP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame))) | ||
| 2133 | { | ||
| 2134 | if (FRAME_VISIBLE_P (XFRAME (tip_frame)) | ||
| 2135 | && !NILP (Fequal_including_properties (tip_last_string, | ||
| 2136 | string)) | ||
| 2137 | && !NILP (Fequal (tip_last_parms, parms))) | ||
| 2138 | { | ||
| 2139 | /* Only DX and DY have changed. */ | ||
| 2140 | tip_f = XFRAME (tip_frame); | ||
| 2141 | if (!NILP (tip_timer)) | ||
| 2142 | { | ||
| 2143 | call1 (Qcancel_timer, tip_timer); | ||
| 2144 | tip_timer = Qnil; | ||
| 2145 | } | ||
| 2146 | |||
| 2147 | block_input (); | ||
| 2148 | compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f), | ||
| 2149 | FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y); | ||
| 2150 | android_move_window (FRAME_ANDROID_WINDOW (tip_f), | ||
| 2151 | root_x, root_y); | ||
| 2152 | unblock_input (); | ||
| 2153 | |||
| 2154 | goto start_timer; | ||
| 2155 | } | ||
| 2156 | else | ||
| 2157 | android_hide_tip (true); | ||
| 2158 | } | ||
| 2159 | else | ||
| 2160 | android_hide_tip (true); | ||
| 2161 | |||
| 2162 | tip_last_frame = frame; | ||
| 2163 | tip_last_string = string; | ||
| 2164 | tip_last_parms = parms; | ||
| 2165 | |||
| 2166 | if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame))) | ||
| 2167 | { | ||
| 2168 | /* Add default values to frame parameters. */ | ||
| 2169 | if (NILP (Fassq (Qname, parms))) | ||
| 2170 | parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); | ||
| 2171 | if (NILP (Fassq (Qinternal_border_width, parms))) | ||
| 2172 | parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), | ||
| 2173 | parms); | ||
| 2174 | if (NILP (Fassq (Qborder_width, parms))) | ||
| 2175 | parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms); | ||
| 2176 | if (NILP (Fassq (Qborder_color, parms))) | ||
| 2177 | parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), | ||
| 2178 | parms); | ||
| 2179 | if (NILP (Fassq (Qbackground_color, parms))) | ||
| 2180 | parms = Fcons (Fcons (Qbackground_color, | ||
| 2181 | build_string ("lightyellow")), | ||
| 2182 | parms); | ||
| 2183 | |||
| 2184 | /* Create a frame for the tooltip, and record it in the global | ||
| 2185 | variable tip_frame. */ | ||
| 2186 | if (NILP (tip_frame = android_create_tip_frame (FRAME_DISPLAY_INFO (f), | ||
| 2187 | parms))) | ||
| 2188 | /* Creating the tip frame failed. */ | ||
| 2189 | return unbind_to (count, Qnil); | ||
| 2190 | } | ||
| 2191 | |||
| 2192 | tip_f = XFRAME (tip_frame); | ||
| 2193 | window = FRAME_ROOT_WINDOW (tip_f); | ||
| 2194 | tip_buf = Fget_buffer_create (tip, Qnil); | ||
| 2195 | /* We will mark the tip window a "pseudo-window" below, and such | ||
| 2196 | windows cannot have display margins. */ | ||
| 2197 | bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0)); | ||
| 2198 | bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0)); | ||
| 2199 | set_window_buffer (window, tip_buf, false, false); | ||
| 2200 | w = XWINDOW (window); | ||
| 2201 | w->pseudo_window_p = true; | ||
| 2202 | /* Try to avoid that `other-window' select us (Bug#47207). */ | ||
| 2203 | Fset_window_parameter (window, Qno_other_window, Qt); | ||
| 2204 | |||
| 2205 | /* Set up the frame's root window. Note: The following code does not | ||
| 2206 | try to size the window or its frame correctly. Its only purpose is | ||
| 2207 | to make the subsequent text size calculations work. The right | ||
| 2208 | sizes should get installed when the toolkit gets back to us. */ | ||
| 2209 | w->left_col = 0; | ||
| 2210 | w->top_line = 0; | ||
| 2211 | w->pixel_left = 0; | ||
| 2212 | w->pixel_top = 0; | ||
| 2213 | |||
| 2214 | if (CONSP (Vx_max_tooltip_size) | ||
| 2215 | && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX) | ||
| 2216 | && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX)) | ||
| 2217 | { | ||
| 2218 | w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size)); | ||
| 2219 | w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size)); | ||
| 2220 | } | ||
| 2221 | else | ||
| 2222 | { | ||
| 2223 | w->total_cols = 80; | ||
| 2224 | w->total_lines = 40; | ||
| 2225 | } | ||
| 2226 | |||
| 2227 | w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f); | ||
| 2228 | w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f); | ||
| 2229 | FRAME_TOTAL_COLS (tip_f) = w->total_cols; | ||
| 2230 | adjust_frame_glyphs (tip_f); | ||
| 2231 | |||
| 2232 | /* Insert STRING into root window's buffer and fit the frame to the | ||
| 2233 | buffer. */ | ||
| 2234 | specpdl_ref count_1 = SPECPDL_INDEX (); | ||
| 2235 | old_buffer = current_buffer; | ||
| 2236 | set_buffer_internal_1 (XBUFFER (w->contents)); | ||
| 2237 | bset_truncate_lines (current_buffer, Qnil); | ||
| 2238 | specbind (Qinhibit_read_only, Qt); | ||
| 2239 | specbind (Qinhibit_modification_hooks, Qt); | ||
| 2240 | specbind (Qinhibit_point_motion_hooks, Qt); | ||
| 2241 | Ferase_buffer (); | ||
| 2242 | Finsert (1, &string); | ||
| 2243 | clear_glyph_matrix (w->desired_matrix); | ||
| 2244 | clear_glyph_matrix (w->current_matrix); | ||
| 2245 | SET_TEXT_POS (pos, BEGV, BEGV_BYTE); | ||
| 2246 | displayed = try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); | ||
| 2247 | |||
| 2248 | if (!displayed && NILP (Vx_max_tooltip_size)) | ||
| 2249 | { | ||
| 2250 | #ifdef ENABLE_CHECKING | ||
| 2251 | row = w->desired_matrix->rows; | ||
| 2252 | end = w->desired_matrix->rows + w->desired_matrix->nrows; | ||
| 2253 | |||
| 2254 | while (row < end) | ||
| 2255 | { | ||
| 2256 | if (!row->displays_text_p | ||
| 2257 | || row->ends_at_zv_p) | ||
| 2258 | break; | ||
| 2259 | ++row; | ||
| 2260 | } | ||
| 2261 | |||
| 2262 | eassert (row < end && row->ends_at_zv_p); | ||
| 2263 | #endif | ||
| 2264 | } | ||
| 2265 | |||
| 2266 | /* Calculate size of tooltip window. */ | ||
| 2267 | size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, | ||
| 2268 | make_fixnum (w->pixel_height), Qnil, | ||
| 2269 | Qnil); | ||
| 2270 | /* Add the frame's internal border to calculated size. */ | ||
| 2271 | width = XFIXNUM (CAR (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); | ||
| 2272 | height = XFIXNUM (CDR (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); | ||
| 2273 | |||
| 2274 | /* Calculate position of tooltip frame. */ | ||
| 2275 | compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y); | ||
| 2276 | |||
| 2277 | /* Show tooltip frame. */ | ||
| 2278 | block_input (); | ||
| 2279 | android_move_resize_window (FRAME_ANDROID_WINDOW (tip_f), | ||
| 2280 | root_x, root_y, width, | ||
| 2281 | height); | ||
| 2282 | android_map_raised (FRAME_ANDROID_WINDOW (tip_f)); | ||
| 2283 | unblock_input (); | ||
| 2284 | |||
| 2285 | w->must_be_updated_p = true; | ||
| 2286 | update_single_window (w); | ||
| 2287 | flush_frame (tip_f); | ||
| 2288 | set_buffer_internal_1 (old_buffer); | ||
| 2289 | unbind_to (count_1, Qnil); | ||
| 2290 | windows_or_buffers_changed = old_windows_or_buffers_changed; | ||
| 2291 | |||
| 2292 | start_timer: | ||
| 2293 | /* Let the tip disappear after timeout seconds. */ | ||
| 2294 | tip_timer = call3 (Qrun_at_time, timeout, Qnil, | ||
| 2295 | Qx_hide_tip); | ||
| 2296 | |||
| 2297 | return unbind_to (count, Qnil); | ||
| 1675 | #endif | 2298 | #endif |
| 1676 | } | 2299 | } |
| 1677 | 2300 | ||
| @@ -1683,7 +2306,7 @@ DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0, | |||
| 1683 | error ("Android cross-compilation stub called!"); | 2306 | error ("Android cross-compilation stub called!"); |
| 1684 | return Qnil; | 2307 | return Qnil; |
| 1685 | #else | 2308 | #else |
| 1686 | return Qnil; | 2309 | return android_hide_tip (true); |
| 1687 | #endif | 2310 | #endif |
| 1688 | } | 2311 | } |
| 1689 | 2312 | ||
| @@ -2112,6 +2735,17 @@ syms_of_androidfns (void) | |||
| 2112 | doc: /* SKIP: real doc in xfns.c. */); | 2735 | doc: /* SKIP: real doc in xfns.c. */); |
| 2113 | Vx_cursor_fore_pixel = Qnil; | 2736 | Vx_cursor_fore_pixel = Qnil; |
| 2114 | 2737 | ||
| 2738 | /* Used by Fx_show_tip. */ | ||
| 2739 | DEFSYM (Qrun_at_time, "run-at-time"); | ||
| 2740 | DEFSYM (Qx_hide_tip, "x-hide-tip"); | ||
| 2741 | DEFSYM (Qcancel_timer, "cancel-timer"); | ||
| 2742 | DEFSYM (Qassq_delete_all, "assq-delete-all"); | ||
| 2743 | DEFSYM (Qcolor, "color"); | ||
| 2744 | |||
| 2745 | DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size, | ||
| 2746 | doc: /* SKIP: real doc in xfns.c. */); | ||
| 2747 | Vx_max_tooltip_size = Qnil; | ||
| 2748 | |||
| 2115 | /* Functions defined. */ | 2749 | /* Functions defined. */ |
| 2116 | defsubr (&Sx_create_frame); | 2750 | defsubr (&Sx_create_frame); |
| 2117 | defsubr (&Sxw_color_defined_p); | 2751 | defsubr (&Sxw_color_defined_p); |
| @@ -2139,4 +2773,21 @@ syms_of_androidfns (void) | |||
| 2139 | defsubr (&Sx_show_tip); | 2773 | defsubr (&Sx_show_tip); |
| 2140 | defsubr (&Sx_hide_tip); | 2774 | defsubr (&Sx_hide_tip); |
| 2141 | defsubr (&Sandroid_detect_mouse); | 2775 | defsubr (&Sandroid_detect_mouse); |
| 2776 | |||
| 2777 | #ifndef ANDROID_STUBIFY | ||
| 2778 | tip_timer = Qnil; | ||
| 2779 | staticpro (&tip_timer); | ||
| 2780 | tip_frame = Qnil; | ||
| 2781 | staticpro (&tip_frame); | ||
| 2782 | tip_last_frame = Qnil; | ||
| 2783 | staticpro (&tip_last_frame); | ||
| 2784 | tip_last_string = Qnil; | ||
| 2785 | staticpro (&tip_last_string); | ||
| 2786 | tip_last_parms = Qnil; | ||
| 2787 | staticpro (&tip_last_parms); | ||
| 2788 | tip_dx = Qnil; | ||
| 2789 | staticpro (&tip_dx); | ||
| 2790 | tip_dy = Qnil; | ||
| 2791 | staticpro (&tip_dy); | ||
| 2792 | #endif | ||
| 2142 | } | 2793 | } |