aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.c
diff options
context:
space:
mode:
authorMiles Bader2007-05-24 21:31:10 +0000
committerMiles Bader2007-05-24 21:31:10 +0000
commit262be72a9aaa800d38cd25b12acb8c9b7b21d5d6 (patch)
tree0940ebc7acd6379243e7194446acbd4f062be4f3 /src/term.c
parent5e1d0c0a38c22adc02d1b77bdc1d620fab26e52d (diff)
parenta02a3c235e3ec24acaf2014e6c60c0b4138ff86f (diff)
downloademacs-262be72a9aaa800d38cd25b12acb8c9b7b21d5d6.tar.gz
emacs-262be72a9aaa800d38cd25b12acb8c9b7b21d5d6.zip
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 751-770) - Update from CVS - Merge from emacs--rel--22 - Update from CVS: lisp/textmodes/sgml-mode.el: Revert last change. - Merge from gnus--rel--5.10 * emacs--rel--22 (patch 18-25) * gnus--rel--5.10 (patch 222-223) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-208
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c770
1 files changed, 751 insertions, 19 deletions
diff --git a/src/term.c b/src/term.c
index 1fcda1abb77..6df6ef08918 100644
--- a/src/term.c
+++ b/src/term.c
@@ -147,25 +147,6 @@ int (*read_socket_hook) P_ ((int, int, struct input_event *));
147 147
148void (*frame_up_to_date_hook) P_ ((struct frame *)); 148void (*frame_up_to_date_hook) P_ ((struct frame *));
149 149
150/* Return the current position of the mouse.
151
152 Set *f to the frame the mouse is in, or zero if the mouse is in no
153 Emacs frame. If it is set to zero, all the other arguments are
154 garbage.
155
156 If the motion started in a scroll bar, set *bar_window to the
157 scroll bar's window, *part to the part the mouse is currently over,
158 *x to the position of the mouse along the scroll bar, and *y to the
159 overall length of the scroll bar.
160
161 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
162 row of the character cell the mouse is over.
163
164 Set *time to the time the mouse was at the returned position.
165
166 This should clear mouse_moved until the next motion
167 event arrives. */
168
169void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist, 150void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
170 Lisp_Object *bar_window, 151 Lisp_Object *bar_window,
171 enum scroll_bar_part *part, 152 enum scroll_bar_part *part,
@@ -416,6 +397,9 @@ static int tty_cursor_hidden;
416char *tparam (); 397char *tparam ();
417 398
418extern char *tgetstr (); 399extern char *tgetstr ();
400
401static void term_clear_mouse_face ();
402static void term_mouse_highlight (struct frame *f, int x, int y);
419 403
420 404
421#ifdef WINDOWSNT 405#ifdef WINDOWSNT
@@ -429,6 +413,33 @@ extern char *tgetstr ();
429#define FRAME_TERMCAP_P(_f_) 0 413#define FRAME_TERMCAP_P(_f_) 0
430#endif /* WINDOWSNT */ 414#endif /* WINDOWSNT */
431 415
416#ifdef HAVE_GPM
417#include <sys/fcntl.h>
418#include "buffer.h"
419
420/* Nonzero means mouse is enabled on Linux console. */
421int term_gpm = 0;
422
423/* These variables describe the range of text currently shown in its
424 mouse-face, together with the window they apply to. As long as
425 the mouse stays within this range, we need not redraw anything on
426 its account. Rows and columns are glyph matrix positions in
427 MOUSE_FACE_WINDOW. */
428static int mouse_face_beg_row, mouse_face_beg_col;
429static int mouse_face_end_row, mouse_face_end_col;
430static int mouse_face_past_end;
431static Lisp_Object mouse_face_window;
432static int mouse_face_face_id;
433
434/* FRAME and X, Y position of mouse when last checked for
435 highlighting. X and Y can be negative or out of range for the frame. */
436struct frame *mouse_face_mouse_frame;
437int mouse_face_mouse_x, mouse_face_mouse_y;
438
439static int pos_x, pos_y;
440static int last_mouse_x, last_mouse_y;
441#endif /* HAVE_GPM */
442
432void 443void
433ring_bell () 444ring_bell ()
434{ 445{
@@ -1077,6 +1088,65 @@ write_glyphs (string, len)
1077 cmcheckmagic (); 1088 cmcheckmagic ();
1078} 1089}
1079 1090
1091void
1092write_glyphs_with_face (string, len, face_id)
1093 register struct glyph *string;
1094 register int len, face_id;
1095{
1096 struct frame *sf = XFRAME (selected_frame);
1097 struct frame *f = updating_frame ? updating_frame : sf;
1098 unsigned char *conversion_buffer;
1099 struct coding_system *coding;
1100
1101 turn_off_insert ();
1102 tty_hide_cursor ();
1103
1104 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1105 since that would scroll the whole frame on some terminals. */
1106
1107 if (AutoWrap
1108 && curY + 1 == FRAME_LINES (sf)
1109 && (curX + len) == FRAME_COLS (sf))
1110 len --;
1111 if (len <= 0)
1112 return;
1113
1114 cmplus (len);
1115
1116 /* If terminal_coding does any conversion, use it, otherwise use
1117 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1118 because it always return 1 if the member src_multibyte is 1. */
1119 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
1120 ? &terminal_coding : &safe_terminal_coding);
1121 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1122 the tail. */
1123 coding->mode &= ~CODING_MODE_LAST_BLOCK;
1124
1125
1126 /* Turn appearance modes of the face. */
1127 highlight_if_desired ();
1128 turn_on_face (f, face_id);
1129
1130 coding->mode |= CODING_MODE_LAST_BLOCK;
1131 conversion_buffer = encode_terminal_code (string, len, coding);
1132 if (coding->produced > 0)
1133 {
1134 BLOCK_INPUT;
1135 fwrite (conversion_buffer, 1, coding->produced, stdout);
1136 if (ferror (stdout))
1137 clearerr (stdout);
1138 if (termscript)
1139 fwrite (conversion_buffer, 1, coding->produced, termscript);
1140 UNBLOCK_INPUT;
1141 }
1142
1143 /* Turn appearance modes off. */
1144 turn_off_face (f, face_id);
1145 turn_off_highlight ();
1146
1147 cmcheckmagic ();
1148}
1149
1080/* If start is zero, insert blanks instead of a string at start */ 1150/* If start is zero, insert blanks instead of a string at start */
1081 1151
1082void 1152void
@@ -2421,6 +2491,656 @@ set_tty_color_mode (f, val)
2421 2491
2422 2492
2423/*********************************************************************** 2493/***********************************************************************
2494 Mouse
2495 ***********************************************************************/
2496
2497#ifdef HAVE_GPM
2498static void
2499term_show_mouse_face (enum draw_glyphs_face draw)
2500{
2501 struct window *w = XWINDOW (mouse_face_window);
2502 int save_x, save_y;
2503 int i, j;
2504
2505 if (/* If window is in the process of being destroyed, don't bother
2506 to do anything. */
2507 w->current_matrix != NULL
2508 /* Recognize when we are called to operate on rows that don't exist
2509 anymore. This can happen when a window is split. */
2510 && mouse_face_end_row < w->current_matrix->nrows)
2511 {
2512 /* write_glyphs writes at cursor position, so we need to
2513 temporarily move cursor coordinates to the beginning of
2514 the highlight region. */
2515
2516 /* Save current cursor co-ordinates */
2517 save_y = curY;
2518 save_x = curX;
2519
2520 /* Note that mouse_face_beg_row etc. are window relative. */
2521 for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
2522 {
2523 int start_hpos, end_hpos, nglyphs;
2524 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
2525
2526 /* Don't do anything if row doesn't have valid contents. */
2527 if (!row->enabled_p)
2528 continue;
2529
2530 /* For all but the first row, the highlight starts at column 0. */
2531 if (i == mouse_face_beg_row)
2532 start_hpos = mouse_face_beg_col;
2533 else
2534 start_hpos = 0;
2535
2536 if (i == mouse_face_end_row)
2537 end_hpos = mouse_face_end_col;
2538 else
2539 {
2540 end_hpos = row->used[TEXT_AREA];
2541 if (draw == DRAW_NORMAL_TEXT)
2542 row->fill_line_p = 1; /* Clear to end of line */
2543 }
2544
2545 if (end_hpos <= start_hpos)
2546 continue;
2547 /* Record that some glyphs of this row are displayed in
2548 mouse-face. */
2549 row->mouse_face_p = draw > 0;
2550
2551 nglyphs = end_hpos - start_hpos;
2552
2553 if (end_hpos >= row->used[TEXT_AREA])
2554 nglyphs = row->used[TEXT_AREA] - start_hpos;
2555
2556 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2557 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
2558 + WINDOW_LEFT_EDGE_X (w);
2559
2560 cursor_to (pos_y, pos_x);
2561
2562 if (draw == DRAW_MOUSE_FACE)
2563 {
2564 write_glyphs_with_face (row->glyphs[TEXT_AREA] + start_hpos,
2565 nglyphs, mouse_face_face_id);
2566 }
2567 else /* draw == DRAW_NORMAL_TEXT */
2568 write_glyphs (row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2569 }
2570 cursor_to (save_y, save_x);
2571 }
2572}
2573
2574static void
2575term_clear_mouse_face ()
2576{
2577 if (!NILP (mouse_face_window))
2578 term_show_mouse_face (DRAW_NORMAL_TEXT);
2579
2580 mouse_face_beg_row = mouse_face_beg_col = -1;
2581 mouse_face_end_row = mouse_face_end_col = -1;
2582 mouse_face_window = Qnil;
2583}
2584
2585/* Find the glyph matrix position of buffer position POS in window W.
2586 *HPOS and *VPOS are set to the positions found. W's current glyphs
2587 must be up to date. If POS is above window start return (0, 0).
2588 If POS is after end of W, return end of last line in W.
2589 - taken from msdos.c */
2590static int
2591fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
2592{
2593 int i, lastcol, line_start_position, maybe_next_line_p = 0;
2594 int yb = window_text_bottom_y (w);
2595 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
2596
2597 while (row->y < yb)
2598 {
2599 if (row->used[TEXT_AREA])
2600 line_start_position = row->glyphs[TEXT_AREA]->charpos;
2601 else
2602 line_start_position = 0;
2603
2604 if (line_start_position > pos)
2605 break;
2606 /* If the position sought is the end of the buffer,
2607 don't include the blank lines at the bottom of the window. */
2608 else if (line_start_position == pos
2609 && pos == BUF_ZV (XBUFFER (w->buffer)))
2610 {
2611 maybe_next_line_p = 1;
2612 break;
2613 }
2614 else if (line_start_position > 0)
2615 best_row = row;
2616
2617 /* Don't overstep the last matrix row, lest we get into the
2618 never-never land... */
2619 if (row->y + 1 >= yb)
2620 break;
2621
2622 ++row;
2623 }
2624
2625 /* Find the right column within BEST_ROW. */
2626 lastcol = 0;
2627 row = best_row;
2628 for (i = 0; i < row->used[TEXT_AREA]; i++)
2629 {
2630 struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
2631 int charpos;
2632
2633 charpos = glyph->charpos;
2634 if (charpos == pos)
2635 {
2636 *hpos = i;
2637 *vpos = row->y;
2638 return 1;
2639 }
2640 else if (charpos > pos)
2641 break;
2642 else if (charpos > 0)
2643 lastcol = i;
2644 }
2645
2646 /* If we're looking for the end of the buffer,
2647 and we didn't find it in the line we scanned,
2648 use the start of the following line. */
2649 if (maybe_next_line_p)
2650 {
2651 ++row;
2652 lastcol = 0;
2653 }
2654
2655 *vpos = row->y;
2656 *hpos = lastcol + 1;
2657 return 0;
2658}
2659
2660static void
2661term_mouse_highlight (struct frame *f, int x, int y)
2662{
2663 enum window_part part;
2664 Lisp_Object window;
2665 struct window *w;
2666 struct buffer *b;
2667
2668 if (NILP (Vmouse_highlight)
2669 || !f->glyphs_initialized_p)
2670 return;
2671
2672 mouse_face_mouse_x = x;
2673 mouse_face_mouse_y = y;
2674 mouse_face_mouse_frame = f;
2675
2676 /* Which window is that in? */
2677 window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
2678
2679 /* Not on a window -> return. */
2680 if (!WINDOWP (window))
2681 return;
2682
2683 if (!EQ (window, mouse_face_window))
2684 term_clear_mouse_face ();
2685
2686 w = XWINDOW (window);
2687
2688 /* Are we in a window whose display is up to date?
2689 And verify the buffer's text has not changed. */
2690 b = XBUFFER (w->buffer);
2691 if (part == ON_TEXT
2692 && EQ (w->window_end_valid, w->buffer)
2693 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
2694 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
2695 {
2696 int pos, i, nrows = w->current_matrix->nrows;
2697 struct glyph_row *row;
2698 struct glyph *glyph;
2699
2700 /* Find the glyph under X/Y. */
2701 glyph = NULL;
2702 if (y >= 0 && y < nrows)
2703 {
2704 row = MATRIX_ROW (w->current_matrix, y);
2705 /* Give up if some row before the one we are looking for is
2706 not enabled. */
2707 for (i = 0; i <= y; i++)
2708 if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
2709 break;
2710 if (i > y /* all rows upto and including the one at Y are enabled */
2711 && row->displays_text_p
2712 && x < window_box_width (w, TEXT_AREA))
2713 {
2714 glyph = row->glyphs[TEXT_AREA];
2715 if (x >= row->used[TEXT_AREA])
2716 glyph = NULL;
2717 else
2718 {
2719 glyph += x;
2720 if (!BUFFERP (glyph->object))
2721 glyph = NULL;
2722 }
2723 }
2724 }
2725
2726 /* Clear mouse face if X/Y not over text. */
2727 if (glyph == NULL)
2728 {
2729 term_clear_mouse_face ();
2730 return;
2731 }
2732
2733 if (!BUFFERP (glyph->object))
2734 abort ();
2735 pos = glyph->charpos;
2736
2737 /* Check for mouse-face. */
2738 {
2739 extern Lisp_Object Qmouse_face;
2740 Lisp_Object mouse_face, overlay, position, *overlay_vec;
2741 int noverlays, obegv, ozv;;
2742 struct buffer *obuf;
2743
2744 /* If we get an out-of-range value, return now; avoid an error. */
2745 if (pos > BUF_Z (b))
2746 return;
2747
2748 /* Make the window's buffer temporarily current for
2749 overlays_at and compute_char_face. */
2750 obuf = current_buffer;
2751 current_buffer = b;
2752 obegv = BEGV;
2753 ozv = ZV;
2754 BEGV = BEG;
2755 ZV = Z;
2756
2757 /* Is this char mouse-active? */
2758 XSETINT (position, pos);
2759
2760 /* Put all the overlays we want in a vector in overlay_vec. */
2761 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
2762 /* Sort overlays into increasing priority order. */
2763 noverlays = sort_overlays (overlay_vec, noverlays, w);
2764
2765 /* Check mouse-face highlighting. */
2766 if (!(EQ (window, mouse_face_window)
2767 && y >= mouse_face_beg_row
2768 && y <= mouse_face_end_row
2769 && (y > mouse_face_beg_row
2770 || x >= mouse_face_beg_col)
2771 && (y < mouse_face_end_row
2772 || x < mouse_face_end_col
2773 || mouse_face_past_end)))
2774 {
2775 /* Clear the display of the old active region, if any. */
2776 term_clear_mouse_face ();
2777
2778 /* Find the highest priority overlay that has a mouse-face
2779 property. */
2780 overlay = Qnil;
2781 for (i = noverlays - 1; i >= 0; --i)
2782 {
2783 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
2784 if (!NILP (mouse_face))
2785 {
2786 overlay = overlay_vec[i];
2787 break;
2788 }
2789 }
2790
2791 /* If no overlay applies, get a text property. */
2792 if (NILP (overlay))
2793 mouse_face = Fget_text_property (position, Qmouse_face,
2794 w->buffer);
2795
2796 /* Handle the overlay case. */
2797 if (!NILP (overlay))
2798 {
2799 /* Find the range of text around this char that
2800 should be active. */
2801 Lisp_Object before, after;
2802 int ignore;
2803
2804
2805 before = Foverlay_start (overlay);
2806 after = Foverlay_end (overlay);
2807 /* Record this as the current active region. */
2808 fast_find_position (w, XFASTINT (before),
2809 &mouse_face_beg_col,
2810 &mouse_face_beg_row);
2811
2812 mouse_face_past_end
2813 = !fast_find_position (w, XFASTINT (after),
2814 &mouse_face_end_col,
2815 &mouse_face_end_row);
2816 mouse_face_window = window;
2817
2818 mouse_face_face_id
2819 = face_at_buffer_position (w, pos, 0, 0,
2820 &ignore, pos + 1, 1);
2821
2822 /* Display it as active. */
2823 term_show_mouse_face (DRAW_MOUSE_FACE);
2824 }
2825 /* Handle the text property case. */
2826 else if (!NILP (mouse_face))
2827 {
2828 /* Find the range of text around this char that
2829 should be active. */
2830 Lisp_Object before, after, beginning, end;
2831 int ignore;
2832
2833 beginning = Fmarker_position (w->start);
2834 XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos)));
2835 before
2836 = Fprevious_single_property_change (make_number (pos + 1),
2837 Qmouse_face,
2838 w->buffer, beginning);
2839 after
2840 = Fnext_single_property_change (position, Qmouse_face,
2841 w->buffer, end);
2842
2843 /* Record this as the current active region. */
2844 fast_find_position (w, XFASTINT (before),
2845 &mouse_face_beg_col,
2846 &mouse_face_beg_row);
2847 mouse_face_past_end
2848 = !fast_find_position (w, XFASTINT (after),
2849 &mouse_face_end_col,
2850 &mouse_face_end_row);
2851 mouse_face_window = window;
2852
2853 mouse_face_face_id
2854 = face_at_buffer_position (w, pos, 0, 0,
2855 &ignore, pos + 1, 1);
2856
2857 /* Display it as active. */
2858 term_show_mouse_face (DRAW_MOUSE_FACE);
2859 }
2860 }
2861
2862 /* Look for a `help-echo' property. */
2863 {
2864 Lisp_Object help;
2865 extern Lisp_Object Qhelp_echo;
2866
2867 /* Check overlays first. */
2868 help = Qnil;
2869 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
2870 {
2871 overlay = overlay_vec[i];
2872 help = Foverlay_get (overlay, Qhelp_echo);
2873 }
2874
2875 if (!NILP (help))
2876 {
2877 help_echo_string = help;
2878 help_echo_window = window;
2879 help_echo_object = overlay;
2880 help_echo_pos = pos;
2881 }
2882 /* Try text properties. */
2883 else if (NILP (help)
2884 && ((STRINGP (glyph->object)
2885 && glyph->charpos >= 0
2886 && glyph->charpos < SCHARS (glyph->object))
2887 || (BUFFERP (glyph->object)
2888 && glyph->charpos >= BEGV
2889 && glyph->charpos < ZV)))
2890 {
2891 help = Fget_text_property (make_number (glyph->charpos),
2892 Qhelp_echo, glyph->object);
2893 if (!NILP (help))
2894 {
2895 help_echo_string = help;
2896 help_echo_window = window;
2897 help_echo_object = glyph->object;
2898 help_echo_pos = glyph->charpos;
2899 }
2900 }
2901 }
2902
2903 BEGV = obegv;
2904 ZV = ozv;
2905 current_buffer = obuf;
2906 }
2907 }
2908}
2909
2910static int
2911term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2912{
2913 /* Has the mouse moved off the glyph it was on at the last sighting? */
2914 if (event->x != last_mouse_x || event->y != last_mouse_y)
2915 {
2916 frame->mouse_moved = 1;
2917 term_mouse_highlight (frame, event->x - 1, event->y - 1);
2918 /* Remember which glyph we're now on. */
2919 last_mouse_x = event->x;
2920 last_mouse_y = event->y;
2921 return 1;
2922 }
2923 return 0;
2924}
2925
2926/* Return the current position of the mouse.
2927
2928 Set *f to the frame the mouse is in, or zero if the mouse is in no
2929 Emacs frame. If it is set to zero, all the other arguments are
2930 garbage.
2931
2932 Set *bar_window to Qnil, and *x and *y to the column and
2933 row of the character cell the mouse is over.
2934
2935 Set *time to the time the mouse was at the returned position.
2936
2937 This should clear mouse_moved until the next motion
2938 event arrives.
2939
2940 NOT CURRENTLY INVOKED: see mouse_position_hook below. */
2941static void
2942term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
2943 enum scroll_bar_part *part, Lisp_Object *x,
2944 Lisp_Object *y, unsigned long *time)
2945{
2946 Gpm_Event event;
2947 struct timeval now;
2948 int i;
2949
2950 BLOCK_INPUT;
2951
2952 *fp = SELECTED_FRAME ();
2953
2954 *bar_window = Qnil;
2955 *part = 0;
2956
2957 i = Gpm_GetSnapshot (&event);
2958
2959 XSETINT (*x, event.x);
2960 XSETINT (*y, event.y);
2961 gettimeofday(&now, 0);
2962 *time = (now.tv_sec * 1000) + (now.tv_usec / 1000);
2963
2964 UNBLOCK_INPUT;
2965}
2966
2967/* Prepare a mouse-event in *RESULT for placement in the input queue.
2968
2969 If the event is a button press, then note that we have grabbed
2970 the mouse. */
2971
2972static Lisp_Object
2973term_mouse_click (struct input_event *result, Gpm_Event *event,
2974 struct frame *f)
2975{
2976 struct timeval now;
2977 int i, j;
2978
2979 result->kind = GPM_CLICK_EVENT;
2980 for (i = 0, j = GPM_B_LEFT; i < 3; i++, j >>= 1 )
2981 {
2982 if (event->buttons & j) {
2983 result->code = i; /* button number */
2984 break;
2985 }
2986 }
2987 gettimeofday(&now, 0);
2988 result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000);
2989
2990 if (event->type & GPM_UP)
2991 result->modifiers = up_modifier;
2992 else if (event->type & GPM_DOWN)
2993 result->modifiers = down_modifier;
2994 else
2995 result->modifiers = 0;
2996
2997 if (event->type & GPM_SINGLE)
2998 result->modifiers |= click_modifier;
2999
3000 if (event->type & GPM_DOUBLE)
3001 result->modifiers |= double_modifier;
3002
3003 if (event->type & GPM_TRIPLE)
3004 result->modifiers |= triple_modifier;
3005
3006 if (event->type & GPM_DRAG)
3007 result->modifiers |= drag_modifier;
3008
3009 if (!(event->type & (GPM_MOVE|GPM_DRAG))) {
3010
3011 /* 1 << KG_SHIFT */
3012 if (event->modifiers & (1 << 0))
3013 result->modifiers |= shift_modifier;
3014
3015 /* 1 << KG_CTRL */
3016 if (event->modifiers & (1 << 2))
3017 result->modifiers |= ctrl_modifier;
3018
3019 /* 1 << KG_ALT || KG_ALTGR */
3020 if (event->modifiers & (1 << 3)
3021 || event->modifiers & (1 << 1))
3022 result->modifiers |= meta_modifier;
3023 }
3024
3025 XSETINT (result->x, event->x - 1);
3026 XSETINT (result->y, event->y - 1);
3027 XSETFRAME (result->frame_or_window, f);
3028 result->arg = Qnil;
3029 return Qnil;
3030}
3031
3032int
3033handle_one_term_event (Gpm_Event *event, struct input_event* hold_quit)
3034{
3035 struct frame *f = SELECTED_FRAME ();
3036 int i, j, fd;
3037 struct input_event ie;
3038 int do_help = 0;
3039 int count = 0;
3040
3041 EVENT_INIT (ie);
3042 ie.kind = NO_EVENT;
3043 ie.arg = Qnil;
3044
3045 if (event->type & GPM_MOVE) {
3046 unsigned char buf[6 * sizeof (short)];
3047 unsigned short *arg = (unsigned short *) buf + 1;
3048 const char *name;
3049
3050 previous_help_echo_string = help_echo_string;
3051 help_echo_string = Qnil;
3052
3053 /* Display mouse pointer */
3054 buf[sizeof(short) - 1] = 2; /* set selection */
3055
3056 arg[0] = arg[2] = (unsigned short) event->x;
3057 arg[1] = arg[3] = (unsigned short) event->y;
3058 arg[4] = (unsigned short) 3;
3059
3060 name = (const char *) ttyname (0);
3061 fd = open (name, O_WRONLY);
3062 ioctl (fd, TIOCLINUX, buf + sizeof (short) - 1);
3063 close(fd);
3064
3065 term_mouse_movement (f, event);
3066
3067 /* If the contents of the global variable help_echo_string
3068 has changed, generate a HELP_EVENT. */
3069 if (!NILP (help_echo_string)
3070 || !NILP (previous_help_echo_string))
3071 do_help = 1;
3072
3073 goto done;
3074 }
3075 else {
3076 f->mouse_moved = 0;
3077 term_mouse_click (&ie, event, f);
3078 //kbd_buffer_store_event_hold (&ie, hold_quit);
3079 }
3080
3081 done:
3082 if (ie.kind != NO_EVENT)
3083 {
3084 kbd_buffer_store_event_hold (&ie, hold_quit);
3085 count++;
3086 }
3087
3088 if (do_help
3089 && !(hold_quit && hold_quit->kind != NO_EVENT))
3090 {
3091 Lisp_Object frame;
3092
3093 if (f)
3094 XSETFRAME (frame, f);
3095 else
3096 frame = Qnil;
3097
3098 gen_help_event (help_echo_string, frame, help_echo_window,
3099 help_echo_object, help_echo_pos);
3100 count++;
3101 }
3102
3103 return count;
3104}
3105
3106DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
3107 0, 0, 0,
3108 doc: /* Open a connection to Gpm. */)
3109 ()
3110{
3111 Gpm_Connect connection;
3112
3113 connection.eventMask = ~0;
3114 connection.defaultMask = ~GPM_HARD;
3115 connection.maxMod = ~0;
3116 connection.minMod = 0;
3117
3118 if (Gpm_Open (&connection, 0) < 0)
3119 return Qnil;
3120 else
3121 {
3122 term_gpm = 1;
3123 reset_sys_modes ();
3124 init_sys_modes ();
3125 add_gpm_wait_descriptor (gpm_fd);
3126 return Qt;
3127 }
3128}
3129
3130DEFUN ("term-close-connection", Fterm_close_connection, Sterm_close_connection,
3131 0, 0, 0,
3132 doc: /* Close a connection to Gpm. */)
3133 ()
3134{
3135 delete_gpm_wait_descriptor (gpm_fd);
3136 while (Gpm_Close()); /* close all the stack */
3137 term_gpm = 0;
3138 return Qnil;
3139}
3140#endif /* HAVE_GPM */
3141
3142
3143/***********************************************************************
2424 Initialization 3144 Initialization
2425 ***********************************************************************/ 3145 ***********************************************************************/
2426 3146
@@ -2439,6 +3159,14 @@ term_init (terminal_type)
2439 encode_terminal_src_size = 0; 3159 encode_terminal_src_size = 0;
2440 encode_terminal_dst_size = 0; 3160 encode_terminal_dst_size = 0;
2441 3161
3162#ifdef HAVE_GPM
3163 /* TODO: Can't get Gpm_Snapshot in term_mouse_position to work: test with
3164 (mouse-position). Also set-mouse-position won't work as is. */
3165 /* mouse_position_hook = term_mouse_position; */
3166
3167 mouse_face_window = Qnil;
3168#endif
3169
2442#ifdef WINDOWSNT 3170#ifdef WINDOWSNT
2443 initialize_w32_display (); 3171 initialize_w32_display ();
2444 3172
@@ -2886,6 +3614,10 @@ bigger, or it may make it blink, or it may do nothing at all. */);
2886 defsubr (&Stty_display_color_p); 3614 defsubr (&Stty_display_color_p);
2887 defsubr (&Stty_display_color_cells); 3615 defsubr (&Stty_display_color_cells);
2888 defsubr (&Stty_no_underline); 3616 defsubr (&Stty_no_underline);
3617#ifdef HAVE_GPM
3618 defsubr (&Sterm_open_connection);
3619 defsubr (&Sterm_close_connection);
3620#endif /* HAVE_GPM */
2889 3621
2890 fullscreen_hook = NULL; 3622 fullscreen_hook = NULL;
2891} 3623}