aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJared Finder2025-01-06 20:52:11 -0800
committerEli Zaretskii2025-01-11 12:47:46 +0200
commitd018a26f9cfb29b166199e88ec6ee84d06733851 (patch)
treec4e7b356e07522dc557937340386c9190aa4cb0a /src
parent2f63dab3ee566f5794fac4139a8f8b8b9e250a00 (diff)
downloademacs-d018a26f9cfb29b166199e88ec6ee84d06733851.tar.gz
emacs-d018a26f9cfb29b166199e88ec6ee84d06733851.zip
Support TTY child frames with GPM mouse
* lisp/frame.el (x-list-fonts): Delete `frame-at', to move to C implementation. * lisp/xt-mouse.el (xterm-mouse-event): Call new `tty-frame-at'. * src/term.c (tty_frame_at, Ftty_frame_at): New C function, replacing `frame-at' only for TTYs. (term_mouse_position): Use last_mouse_frame when it is set. (handle_one_term_event): Call tty_frame_at to get frame under mouse, store it in last_mouse_frame. Alter event coordinates based on mouse frame. (syms_of_term): Add tty-frame-at, last_mouse_frame. * src/termhooks.h: Make Gpm_Event parameter const.
Diffstat (limited to 'src')
-rw-r--r--src/term.c70
-rw-r--r--src/termhooks.h2
2 files changed, 59 insertions, 13 deletions
diff --git a/src/term.c b/src/term.c
index 368e20803e1..10380eba4b9 100644
--- a/src/term.c
+++ b/src/term.c
@@ -141,6 +141,7 @@ static int max_frame_cols;
141struct tty_display_info *gpm_tty = NULL; 141struct tty_display_info *gpm_tty = NULL;
142 142
143/* Last recorded mouse coordinates. */ 143/* Last recorded mouse coordinates. */
144static Lisp_Object last_mouse_frame;
144static int last_mouse_x, last_mouse_y; 145static int last_mouse_x, last_mouse_y;
145#endif /* HAVE_GPM */ 146#endif /* HAVE_GPM */
146 147
@@ -2593,6 +2594,35 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2593 2594
2594#endif 2595#endif
2595 2596
2597static Lisp_Object
2598tty_frame_at (int x, int y)
2599{
2600 for (Lisp_Object frames = Ftty_frame_list_z_order (Qnil); frames != Qnil;
2601 frames = Fcdr (frames))
2602 {
2603 Lisp_Object frame = Fcar (frames);
2604 struct frame *f = XFRAME (frame);
2605
2606 if (f->left_pos <= x && x < f->left_pos + f->pixel_width &&
2607 f->top_pos <= y && y < f->top_pos + f->pixel_height)
2608 return frame;
2609 }
2610
2611 return Qnil;
2612}
2613
2614DEFUN ("tty-frame-at", Ftty_frame_at, Stty_frame_at,
2615 2, 2, 0,
2616 doc: /* Return tty frame containing pixel position X, Y. */)
2617 (Lisp_Object x, Lisp_Object y)
2618{
2619 if (! FIXNUMP (x) || ! FIXNUMP (y))
2620 /* Coordinates this big can not correspond to any frame. */
2621 return Qnil;
2622
2623 return tty_frame_at (XFIXNUM (x), XFIXNUM (y));
2624}
2625
2596#ifdef HAVE_GPM 2626#ifdef HAVE_GPM
2597 2627
2598void 2628void
@@ -2638,7 +2668,12 @@ term_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
2638 enum scroll_bar_part *part, Lisp_Object *x, 2668 enum scroll_bar_part *part, Lisp_Object *x,
2639 Lisp_Object *y, Time *timeptr) 2669 Lisp_Object *y, Time *timeptr)
2640{ 2670{
2641 *fp = SELECTED_FRAME (); 2671 /* If we've gotten no GPM mouse events yet, last_mouse_frame won't be
2672 set. Perhaps `gpm-mouse-mode' was never active. */
2673 if (! FRAMEP (last_mouse_frame))
2674 return;
2675
2676 *fp = XFRAME (last_mouse_frame);
2642 (*fp)->mouse_moved = 0; 2677 (*fp)->mouse_moved = 0;
2643 2678
2644 *bar_window = Qnil; 2679 *bar_window = Qnil;
@@ -2713,9 +2748,14 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
2713} 2748}
2714 2749
2715int 2750int
2716handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event) 2751handle_one_term_event (struct tty_display_info *tty, const Gpm_Event *event_in)
2717{ 2752{
2718 struct frame *f = XFRAME (tty->top_frame); 2753 Lisp_Object frame = tty_frame_at (event_in->x, event_in->y);
2754 struct frame *f = decode_live_frame (frame);
2755 Gpm_Event event = *event_in;
2756 event.x -= f->left_pos;
2757 event.y -= f->top_pos;
2758
2719 struct input_event ie; 2759 struct input_event ie;
2720 int count = 0; 2760 int count = 0;
2721 2761
@@ -2723,30 +2763,34 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
2723 ie.kind = NO_EVENT; 2763 ie.kind = NO_EVENT;
2724 ie.arg = Qnil; 2764 ie.arg = Qnil;
2725 2765
2726 if (event->type & (GPM_MOVE | GPM_DRAG)) 2766 if (event.type & (GPM_MOVE | GPM_DRAG))
2727 { 2767 {
2728 Gpm_DrawPointer (event->x, event->y, fileno (tty->output)); 2768 /* The pointer must be drawn using screen coordinates (x,y), not
2769 frame coordinates. Use event_in which has an unmodified event
2770 directly from GPM. */
2771 Gpm_DrawPointer (event_in->x, event_in->y, fileno (tty->output));
2729 2772
2730 /* Has the mouse moved off the glyph it was on at the last 2773 /* Has the mouse moved off the glyph it was on at the last
2731 sighting? */ 2774 sighting? */
2732 if (event->x != last_mouse_x || event->y != last_mouse_y) 2775 if (event.x != last_mouse_x || event.y != last_mouse_y)
2733 { 2776 {
2734 /* FIXME: These three lines can not be moved into 2777 /* FIXME: These four lines can not be moved into
2735 update_mouse_position unless xterm-mouse gets updated to 2778 update_mouse_position unless xterm-mouse gets updated to
2736 generate mouse events via C code. See 2779 generate mouse events via C code. See
2737 https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00163.html */ 2780 https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00163.html */
2738 last_mouse_x = event->x; 2781 last_mouse_frame = frame;
2739 last_mouse_y = event->y; 2782 last_mouse_x = event.x;
2783 last_mouse_y = event.y;
2740 f->mouse_moved = 1; 2784 f->mouse_moved = 1;
2741 2785
2742 count += update_mouse_position (f, event->x, event->y); 2786 count += update_mouse_position (f, event.x, event.y);
2743 } 2787 }
2744 } 2788 }
2745 else 2789 else
2746 { 2790 {
2747 f->mouse_moved = 0; 2791 f->mouse_moved = 0;
2748 term_mouse_click (&ie, event, f); 2792 term_mouse_click (&ie, &event, f);
2749 ie.arg = tty_handle_tab_bar_click (f, event->x, event->y, 2793 ie.arg = tty_handle_tab_bar_click (f, event.x, event.y,
2750 (ie.modifiers & down_modifier) != 0, &ie); 2794 (ie.modifiers & down_modifier) != 0, &ie);
2751 kbd_buffer_store_event (&ie); 2795 kbd_buffer_store_event (&ie);
2752 count++; 2796 count++;
@@ -4967,9 +5011,11 @@ trigger redisplay. */);
4967 defsubr (&Stty__set_output_buffer_size); 5011 defsubr (&Stty__set_output_buffer_size);
4968 defsubr (&Stty__output_buffer_size); 5012 defsubr (&Stty__output_buffer_size);
4969#endif /* !HAVE_ANDROID */ 5013#endif /* !HAVE_ANDROID */
5014 defsubr (&Stty_frame_at);
4970#ifdef HAVE_GPM 5015#ifdef HAVE_GPM
4971 defsubr (&Sgpm_mouse_start); 5016 defsubr (&Sgpm_mouse_start);
4972 defsubr (&Sgpm_mouse_stop); 5017 defsubr (&Sgpm_mouse_stop);
5018 staticpro (&last_mouse_frame);
4973#endif /* HAVE_GPM */ 5019#endif /* HAVE_GPM */
4974 5020
4975 defsubr (&Stty_frame_geometry); 5021 defsubr (&Stty_frame_geometry);
diff --git a/src/termhooks.h b/src/termhooks.h
index b32804a57b3..0795148f1af 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -458,7 +458,7 @@ enum {
458 458
459#ifdef HAVE_GPM 459#ifdef HAVE_GPM
460#include <gpm.h> 460#include <gpm.h>
461extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *); 461extern int handle_one_term_event (struct tty_display_info *, const Gpm_Event *);
462extern void term_mouse_moveto (int, int); 462extern void term_mouse_moveto (int, int);
463 463
464/* The device for which we have enabled gpm support. */ 464/* The device for which we have enabled gpm support. */