aboutsummaryrefslogtreecommitdiffstats
path: root/src/androidfns.c
diff options
context:
space:
mode:
authorPo Lu2023-03-10 15:16:05 +0800
committerPo Lu2023-03-10 15:16:05 +0800
commitae5513ede52536df2cd823699d6168985915ce0f (patch)
tree61e38d5c1f5544b03778055af964e4e0289928ac /src/androidfns.c
parenta7c8ae7d675c402923e2ff8359b9cc286792bbb0 (diff)
downloademacs-ae5513ede52536df2cd823699d6168985915ce0f.tar.gz
emacs-ae5513ede52536df2cd823699d6168985915ce0f.zip
Implement mouse cursors on Android 7.0 and later
* java/org/gnu/emacs/EmacsWindow.java (defineCursor): New function. * src/android.c (struct android_emacs_cursor): New struct. (android_init_emacs_cursor): New function. (JNICALL): Call it. (android_create_font_cursor, android_define_cursor) (android_free_cursor): New functions. * src/android.h (enum android_handle_type): Add cursor handle type. * src/androidfns.c (Fx_create_frame, android_create_tip_frame) (enum mouse_cursor, struct mouse_cursor_types, mouse_cursor_types) (struct mouse_cursor_data, android_set_mouse_color) (syms_of_androidfns): * src/androidgui.h (enum android_cursor_shape): * src/androidterm.c (make_invisible_cursor) (android_toggle_invisible_pointer, android_free_frame_resources) (android_define_frame_cursor): * src/androidterm.h (struct android_display_info) (struct android_output): Port mouse cursor code over from X.
Diffstat (limited to 'src/androidfns.c')
-rw-r--r--src/androidfns.c221
1 files changed, 218 insertions, 3 deletions
diff --git a/src/androidfns.c b/src/androidfns.c
index 2724b9595c1..589ae4331cb 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -802,6 +802,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
802 FRAME_BACKGROUND_PIXEL (f) = -1; 802 FRAME_BACKGROUND_PIXEL (f) = -1;
803 f->output_data.android->cursor_pixel = -1; 803 f->output_data.android->cursor_pixel = -1;
804 f->output_data.android->cursor_foreground_pixel = -1; 804 f->output_data.android->cursor_foreground_pixel = -1;
805 f->output_data.android->mouse_pixel = -1;
805 806
806 black = build_string ("black"); 807 black = build_string ("black");
807 FRAME_FOREGROUND_PIXEL (f) 808 FRAME_FOREGROUND_PIXEL (f)
@@ -812,6 +813,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
812 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); 813 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f));
813 f->output_data.android->cursor_foreground_pixel 814 f->output_data.android->cursor_foreground_pixel
814 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); 815 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f));
816 f->output_data.android->mouse_pixel
817 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f));
815 } 818 }
816 819
817 /* Set the name; the functions to which we pass f expect the name to 820 /* Set the name; the functions to which we pass f expect the name to
@@ -1798,6 +1801,7 @@ android_create_tip_frame (struct android_display_info *dpyinfo,
1798 FRAME_BACKGROUND_PIXEL (f) = -1; 1801 FRAME_BACKGROUND_PIXEL (f) = -1;
1799 f->output_data.android->cursor_pixel = -1; 1802 f->output_data.android->cursor_pixel = -1;
1800 f->output_data.android->cursor_foreground_pixel = -1; 1803 f->output_data.android->cursor_foreground_pixel = -1;
1804 f->output_data.android->mouse_pixel = -1;
1801 1805
1802 black = build_string ("black"); 1806 black = build_string ("black");
1803 FRAME_FOREGROUND_PIXEL (f) 1807 FRAME_FOREGROUND_PIXEL (f)
@@ -1808,6 +1812,8 @@ android_create_tip_frame (struct android_display_info *dpyinfo,
1808 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); 1812 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1809 f->output_data.android->cursor_foreground_pixel 1813 f->output_data.android->cursor_foreground_pixel
1810 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f)); 1814 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1815 f->output_data.android->mouse_pixel
1816 = android_decode_color (f, black, BLACK_PIX_DEFAULT (f));
1811 } 1817 }
1812 1818
1813 /* Set the name; the functions to which we pass f expect the name to 1819 /* Set the name; the functions to which we pass f expect the name to
@@ -2632,13 +2638,147 @@ android_set_menu_bar_lines (struct frame *f, Lisp_Object value,
2632 adjust_frame_glyphs (f); 2638 adjust_frame_glyphs (f);
2633} 2639}
2634 2640
2641
2642
2643/* These enums must stay in sync with the mouse_cursor_types array
2644 below! */
2645
2646enum mouse_cursor
2647 {
2648 mouse_cursor_text,
2649 mouse_cursor_nontext,
2650 mouse_cursor_hourglass,
2651 mouse_cursor_mode,
2652 mouse_cursor_hand,
2653 mouse_cursor_horizontal_drag,
2654 mouse_cursor_vertical_drag,
2655 mouse_cursor_left_edge,
2656 mouse_cursor_top_left_corner,
2657 mouse_cursor_top_edge,
2658 mouse_cursor_top_right_corner,
2659 mouse_cursor_right_edge,
2660 mouse_cursor_bottom_right_corner,
2661 mouse_cursor_bottom_edge,
2662 mouse_cursor_bottom_left_corner,
2663 mouse_cursor_max
2664 };
2665
2666struct mouse_cursor_types
2667{
2668 /* Printable name for error messages (optional). */
2669 const char *name;
2670
2671 /* Lisp variable controlling the cursor shape. */
2672 /* FIXME: A couple of these variables are defined in the C code but
2673 are not actually accessible from Lisp. They should probably be
2674 made accessible or removed. */
2675 Lisp_Object *shape_var_ptr;
2676
2677 /* The default shape. */
2678 int default_shape;
2679};
2680
2681/* This array must stay in sync with enum mouse_cursor above! */
2682
2683static const struct mouse_cursor_types mouse_cursor_types[] =
2684 {
2685 {"text", &Vx_pointer_shape, ANDROID_XC_XTERM, },
2686 {"nontext", &Vx_nontext_pointer_shape, ANDROID_XC_LEFT_PTR, },
2687 {"hourglass", &Vx_hourglass_pointer_shape, ANDROID_XC_WATCH, },
2688 {"modeline", &Vx_mode_pointer_shape, ANDROID_XC_XTERM, },
2689 {NULL, &Vx_sensitive_text_pointer_shape, ANDROID_XC_HAND2, },
2690 {NULL, &Vx_window_horizontal_drag_shape, ANDROID_XC_SB_H_DOUBLE_ARROW, },
2691 {NULL, &Vx_window_vertical_drag_shape, ANDROID_XC_SB_V_DOUBLE_ARROW, },
2692 {NULL, &Vx_window_left_edge_shape, ANDROID_XC_LEFT_SIDE, },
2693 {NULL, &Vx_window_top_left_corner_shape, ANDROID_XC_TOP_LEFT_CORNER, },
2694 {NULL, &Vx_window_top_edge_shape, ANDROID_XC_TOP_SIDE, },
2695 {NULL, &Vx_window_top_right_corner_shape, ANDROID_XC_TOP_RIGHT_CORNER, },
2696 {NULL, &Vx_window_right_edge_shape, ANDROID_XC_RIGHT_SIDE, },
2697 {NULL, &Vx_window_bottom_right_corner_shape,
2698 ANDROID_XC_BOTTOM_RIGHT_CORNER, },
2699 {NULL, &Vx_window_bottom_edge_shape, ANDROID_XC_BOTTOM_SIDE, },
2700 {NULL, &Vx_window_bottom_left_corner_shape,
2701 ANDROID_XC_BOTTOM_LEFT_CORNER, },
2702 };
2703
2704struct mouse_cursor_data
2705{
2706 /* Cursor numbers chosen. */
2707 unsigned int cursor_num[mouse_cursor_max];
2708
2709 /* Allocated Cursor values, or zero for failed attempts. */
2710 android_cursor cursor[mouse_cursor_max];
2711};
2712
2713
2714
2635static void 2715static void
2636android_set_mouse_color (struct frame *f, Lisp_Object arg, 2716android_set_mouse_color (struct frame *f, Lisp_Object arg,
2637 Lisp_Object oldval) 2717 Lisp_Object oldval)
2638{ 2718{
2639 /* Changing the mouse color is unsupported under Android, so this is 2719 struct android_output *x = f->output_data.android;
2640 left intact. */ 2720 struct mouse_cursor_data cursor_data = { -1, -1 };
2641 android_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); 2721 unsigned long pixel = android_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
2722 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
2723 int i;
2724
2725 /* Don't let pointers be invisible. */
2726 if (mask_color == pixel)
2727 pixel = FRAME_FOREGROUND_PIXEL (f);
2728
2729 x->mouse_pixel = pixel;
2730
2731 for (i = 0; i < mouse_cursor_max; i++)
2732 {
2733 Lisp_Object shape_var = *mouse_cursor_types[i].shape_var_ptr;
2734 cursor_data.cursor_num[i]
2735 = (!NILP (shape_var)
2736 ? check_uinteger_max (shape_var, UINT_MAX)
2737 : mouse_cursor_types[i].default_shape);
2738 }
2739
2740 block_input ();
2741
2742 for (i = 0; i < mouse_cursor_max; i++)
2743 cursor_data.cursor[i]
2744 = android_create_font_cursor (cursor_data.cursor_num[i]);
2745
2746 if (FRAME_ANDROID_WINDOW (f))
2747 {
2748 f->output_data.android->current_cursor
2749 = cursor_data.cursor[mouse_cursor_text];
2750 android_define_cursor (FRAME_ANDROID_WINDOW (f),
2751 f->output_data.android->current_cursor);
2752 }
2753
2754#define INSTALL_CURSOR(FIELD, SHORT_INDEX) \
2755 eassert (x->FIELD \
2756 != cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX]); \
2757 if (x->FIELD != 0) \
2758 android_free_cursor (x->FIELD); \
2759 x->FIELD = cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX];
2760
2761 INSTALL_CURSOR (text_cursor, text);
2762 INSTALL_CURSOR (nontext_cursor, nontext);
2763 INSTALL_CURSOR (hourglass_cursor, hourglass);
2764 INSTALL_CURSOR (modeline_cursor, mode);
2765 INSTALL_CURSOR (hand_cursor, hand);
2766 INSTALL_CURSOR (horizontal_drag_cursor, horizontal_drag);
2767 INSTALL_CURSOR (vertical_drag_cursor, vertical_drag);
2768 INSTALL_CURSOR (left_edge_cursor, left_edge);
2769 INSTALL_CURSOR (top_left_corner_cursor, top_left_corner);
2770 INSTALL_CURSOR (top_edge_cursor, top_edge);
2771 INSTALL_CURSOR (top_right_corner_cursor, top_right_corner);
2772 INSTALL_CURSOR (right_edge_cursor, right_edge);
2773 INSTALL_CURSOR (bottom_right_corner_cursor, bottom_right_corner);
2774 INSTALL_CURSOR (bottom_edge_cursor, bottom_edge);
2775 INSTALL_CURSOR (bottom_left_corner_cursor, bottom_left_corner);
2776
2777#undef INSTALL_CURSOR
2778
2779 unblock_input ();
2780
2781 update_face_from_frame_parameter (f, Qmouse_color, arg);
2642} 2782}
2643 2783
2644static void 2784static void
@@ -2845,6 +2985,81 @@ syms_of_androidfns (void)
2845 DEFSYM (Qtrue_color, "true-color"); 2985 DEFSYM (Qtrue_color, "true-color");
2846 DEFSYM (Qalways, "always"); 2986 DEFSYM (Qalways, "always");
2847 2987
2988 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
2989 doc: /* SKIP: real text in xfns.c. */);
2990 Vx_pointer_shape = Qnil;
2991
2992#if false /* This doesn't really do anything. */
2993 DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
2994 doc: /* SKIP: real doc in xfns.c. */);
2995#endif
2996 Vx_nontext_pointer_shape = Qnil;
2997
2998 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
2999 doc: /* SKIP: real text in xfns.c. */);
3000 Vx_hourglass_pointer_shape = Qnil;
3001
3002 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
3003 Vx_sensitive_text_pointer_shape,
3004 doc: /* SKIP: real text in xfns.c. */);
3005 Vx_sensitive_text_pointer_shape = Qnil;
3006
3007 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
3008 Vx_window_horizontal_drag_shape,
3009 doc: /* SKIP: real text in xfns.c. */);
3010 Vx_window_horizontal_drag_shape = Qnil;
3011
3012 DEFVAR_LISP ("x-window-vertical-drag-cursor",
3013 Vx_window_vertical_drag_shape,
3014 doc: /* SKIP: real text in xfns.c. */);
3015 Vx_window_vertical_drag_shape = Qnil;
3016
3017 DEFVAR_LISP ("x-window-left-edge-cursor",
3018 Vx_window_left_edge_shape,
3019 doc: /* SKIP: real text in xfns.c. */);
3020 Vx_window_left_edge_shape = Qnil;
3021
3022 DEFVAR_LISP ("x-window-top-left-corner-cursor",
3023 Vx_window_top_left_corner_shape,
3024 doc: /* SKIP: real text in xfns.c. */);
3025 Vx_window_top_left_corner_shape = Qnil;
3026
3027 DEFVAR_LISP ("x-window-top-edge-cursor",
3028 Vx_window_top_edge_shape,
3029 doc: /* SKIP: real text in xfns.c. */);
3030 Vx_window_top_edge_shape = Qnil;
3031
3032 DEFVAR_LISP ("x-window-top-right-corner-cursor",
3033 Vx_window_top_right_corner_shape,
3034 doc: /* SKIP: real text in xfns.c. */);
3035 Vx_window_top_right_corner_shape = Qnil;
3036
3037 DEFVAR_LISP ("x-window-right-edge-cursor",
3038 Vx_window_right_edge_shape,
3039 doc: /* SKIP: real text in xfns.c. */);
3040 Vx_window_right_edge_shape = Qnil;
3041
3042 DEFVAR_LISP ("x-window-bottom-right-corner-cursor",
3043 Vx_window_bottom_right_corner_shape,
3044 doc: /* SKIP: real text in xfns.c. */);
3045 Vx_window_bottom_right_corner_shape = Qnil;
3046
3047 DEFVAR_LISP ("x-window-bottom-edge-cursor",
3048 Vx_window_bottom_edge_shape,
3049 doc: /* SKIP: real text in xfns.c. */);
3050 Vx_window_bottom_edge_shape = Qnil;
3051
3052#if false /* This doesn't really do anything. */
3053 DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
3054 doc: /* SKIP: real doc in xfns.c. */);
3055#endif
3056 Vx_mode_pointer_shape = Qnil;
3057
3058 DEFVAR_LISP ("x-window-bottom-left-corner-cursor",
3059 Vx_window_bottom_left_corner_shape,
3060 doc: /* SKIP: real text in xfns.c. */);
3061 Vx_window_bottom_left_corner_shape = Qnil;
3062
2848 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel, 3063 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
2849 doc: /* SKIP: real doc in xfns.c. */); 3064 doc: /* SKIP: real doc in xfns.c. */);
2850 Vx_cursor_fore_pixel = Qnil; 3065 Vx_cursor_fore_pixel = Qnil;