aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2007-05-20 23:29:14 +0000
committerMiles Bader2007-05-20 23:29:14 +0000
commit7be1c21aedb2f8e7b7831d494e065a31afe13146 (patch)
treea998f949002bf05307fe6b59969e6ebfb0c88b8d /src
parent3c28868aeb2d445830019837294e96f432456754 (diff)
parent26114bc08f03789f30f0acca925955f2139df690 (diff)
downloademacs-7be1c21aedb2f8e7b7831d494e065a31afe13146.tar.gz
emacs-7be1c21aedb2f8e7b7831d494e065a31afe13146.zip
Merged from emacs--devo--0
Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-744 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-745 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-746 Merge from emacs--rel--22 * emacs@sv.gnu.org/emacs--devo--0--patch-747 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-748 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-749 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-750 Merge from emacs--rel--22 * emacs@sv.gnu.org/emacs--devo--0--patch-751 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-752 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-753 Merge from emacs--rel--22 * emacs@sv.gnu.org/emacs--devo--0--patch-754 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-755 Merge from emacs--rel--22 * emacs@sv.gnu.org/emacs--devo--0--patch-756 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-757 Update from CVS: lisp/textmodes/sgml-mode.el: Revert last change. * emacs@sv.gnu.org/emacs--devo--0--patch-758 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-759 Merge from emacs--rel--22 * emacs@sv.gnu.org/emacs--devo--0--patch-760 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-761 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-14 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-15 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-16 Update from CVS: src/xterm.c (XTread_socket): Revert last change. * emacs@sv.gnu.org/emacs--rel--22--patch-17 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-18 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-19 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-20 Update from CVS * emacs@sv.gnu.org/emacs--rel--22--patch-21 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-221 Update from CVS Revision: emacs@sv.gnu.org/emacs--multi-tty--0--patch-12 Creator: Karoly Lorentey <karoly@lorentey.hu>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog100
-rw-r--r--src/Makefile.in11
-rw-r--r--src/config.in3
-rw-r--r--src/image.c18
-rw-r--r--src/keyboard.c108
-rw-r--r--src/lisp.h2
-rw-r--r--src/m/alpha.h4
-rw-r--r--src/m/macppc.h4
-rw-r--r--src/macterm.c19
-rw-r--r--src/process.c49
-rw-r--r--src/syntax.c2
-rw-r--r--src/sysdep.c8
-rw-r--r--src/term.c761
-rw-r--r--src/termhooks.h17
-rw-r--r--src/xdisp.c50
15 files changed, 1086 insertions, 70 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 59a0af5e2c8..67f6bd282c2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,103 @@
12007-05-20 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * Makefile.in: Move GPM check outside HAVE_X_WINDOWS.
4
52007-05-20 Nick Roberts <nickrob@snap.net.nz>
6
7 * config.in, keyboard.c, Makefile.in, sysdep.c, term.c,
8 * termhooks.h: Use HAVE_GPM instead of HAVE_GPM_H.
9
102007-05-20 Nick Roberts <nickrob@snap.net.nz>
11
12 * keyboard.c (make_lispy_event): Make case GPM_CLICK_EVENT
13 conditional on [HAVE_GPM_H].
14
152007-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
16
17 * syntax.c (skip_chars): Update syntax-table only after we checked that
18 the new location is valid.
19
202007-05-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
21
22 * macterm.c (x_calc_absolute_position): Add BLOCK_INPUT around
23 mac_get_window_bounds.
24
252007-05-20 Nick Roberts <nickrob@snap.net.nz>
26
27 * Makefile.in (LIBGPM): Allow it to be set from configure.
28 If set then link Emacs with it.
29
30 * config.in: Regenerate.
31
32 * lisp.h (add_gpm_wait_descriptor, delete_gpm_wait_descriptor):
33 New externs.
34
35 * termhooks.h [HAVE_GPM_H] (enum event_kind): Add GPM_CLICK_EVENT.
36 Include gpm.h.
37 (handle_one_term_event, term_gpm) New externs.
38
39 * sysdep.c [HAVE_GPM_H] (init_sys_modes): Make gpm_fd nonblocking
40 and allow it to be interrupted by SIGIO.
41
42 * process.c (gpm_wait_mask, max_gpm_desc): New variables.
43 (wait_reading_process_output): Wait on gpm_fd too.
44 (add_gpm_wait_descriptor, delete_gpm_wait_descriptor)): New functions.
45 (add_gpm_wait_descriptor_called_flag): New variable.
46 (delete_keyboard_wait_descriptor): Check gpm_wait_mask.
47
48 * keyboard.c [HAVE_GPM_H] (Qmouse_fixup_help_message)
49 (make_lispy_movement, tracking_off, Ftrack_mouse, some_mouse_moved)
50 (show_help_echo, readable_events, kbd_buffer_get_event, init_keyboard):
51 Extend HAVE_MOUSE ifdefs to HAVE_GPM_H.
52 (make_lispy_event): Add case GPM_CLICK_EVENT.
53 (read_avail_input): Handle mouse input.
54
55 * term.c (write_glyphs_with_face): New function.
56 [HAVE_GPM_H]: Include buffer.h, sys/fcntl.h.
57 (mouse_face_beg_row, mouse_face_beg_col, mouse_face_end_row)
58 (mouse_face_end_col, mouse_face_past_end, mouse_face_window)
59 (mouse_face_face_id, term_gpm, pos_x, pos_y)
60 (last_mouse_x, last_mouse_y): New variables.
61 (term_show_mouse_face, term_clear_mouse_face, fast_find_position)
62 (term_mouse_highlight, term_mouse_movement, term_mouse_position)
63 (term_mouse_click, handle_one_term_event, Fterm_open_connection)
64 (Fterm_close_connection): New functions.
65 (term_init): Initialise mouse_face_window.
66
672007-05-19 Chong Yidong <cyd@stupidchicken.com>
68
69 * xdisp.c (redisplay_window): If first window line is a
70 continuation line, recompute the new window start instead of
71 recentering.
72
732007-05-18 Glenn Morris <rgm@gnu.org>
74
75 * m/alpha.h (ORDINARY_LINK): No longer define on OpenBSD.
76 Suggested by Alfred M. Szmidt <ams@gnu.org>.
77
782007-05-17 Glenn Morris <rgm@gnu.org>
79
80 * m/macppc.h (ORDINARY_LINK): No longer define on OpenBSD.
81
822007-05-16 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
83
84 * macterm.c [USE_CARBON_EVENTS] (mac_convert_event_ref): Also convert
85 dead key repeat and up events.
86
872007-05-14 Chong Yidong <cyd@stupidchicken.com>
88
89 * image.c (pbm_load): Check image size for monochrome pbm.
90
912007-05-13 Chong Yidong <cyd@stupidchicken.com>
92
93 * xterm.c (XTread_socket): Revert last change.
94
952007-05-12 Chong Yidong <cyd@stupidchicken.com>
96
97 * image.c (pbm_load): Correctly check image size for greyscale pbm.
98
99 * xterm.c (XTread_socket): Yet Another Uncaught X Error Crash (YAUXEC).
100
12007-05-07 Stefan Monnier <monnier@iro.umontreal.ca> 1012007-05-07 Stefan Monnier <monnier@iro.umontreal.ca>
2 102
3 * editfns.c (Ftranspose_regions): Yet another int/Lisp_Object mixup (YAILOM) 103 * editfns.c (Ftranspose_regions): Yet another int/Lisp_Object mixup (YAILOM)
diff --git a/src/Makefile.in b/src/Makefile.in
index 31fc7b5c23e..c8db387328d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -457,6 +457,15 @@ LIBX= $(LIBXMENU) LD_SWITCH_X_SITE -lX10 LIBX10_MACHINE LIBX10_SYSTEM
457#else /* not HAVE_X_WINDOWS */ 457#else /* not HAVE_X_WINDOWS */
458#endif /* not HAVE_X_WINDOWS */ 458#endif /* not HAVE_X_WINDOWS */
459 459
460#if HAVE_GPM
461#ifndef LIBGPM
462#define LIBGPM -lgpm
463#endif /* not defined LIBGPM */
464#else /* not HAVE_GPM */
465#define LIBGPM
466#endif /* not HAVE_GPM */
467
468
460LIBSOUND= @LIBSOUND@ 469LIBSOUND= @LIBSOUND@
461CFLAGS_SOUND= @CFLAGS_SOUND@ 470CFLAGS_SOUND= @CFLAGS_SOUND@
462 471
@@ -939,7 +948,7 @@ SOME_MACHINE_LISP = ${dotdot}/lisp/mouse.elc \
939 Note that SunOS needs -lm to come before -lc; otherwise, you get 948 Note that SunOS needs -lm to come before -lc; otherwise, you get
940 duplicated symbols. If the standard libraries were compiled 949 duplicated symbols. If the standard libraries were compiled
941 with GCC, we might need gnulib again after them. */ 950 with GCC, we might need gnulib again after them. */
942LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) \ 951LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) LIBGPM \
943 LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ 952 LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
944 LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \ 953 LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \
945 $(GNULIB_VAR) 954 $(GNULIB_VAR)
diff --git a/src/config.in b/src/config.in
index 71b4af0c839..6d945d4bfdc 100644
--- a/src/config.in
+++ b/src/config.in
@@ -231,6 +231,9 @@ Boston, MA 02110-1301, USA. */
231/* Define to 1 if you have the ungif library (-lungif). */ 231/* Define to 1 if you have the ungif library (-lungif). */
232#undef HAVE_GIF 232#undef HAVE_GIF
233 233
234/* Define to 1 if you have the gpm library (-lgpm). */
235#undef HAVE_GPM
236
234/* Define to 1 if you have the `grantpt' function. */ 237/* Define to 1 if you have the `grantpt' function. */
235#undef HAVE_GRANTPT 238#undef HAVE_GRANTPT
236 239
diff --git a/src/image.c b/src/image.c
index 198ffaf4651..5243778526e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -5732,7 +5732,17 @@ pbm_load (f, img)
5732 if (raw_p) 5732 if (raw_p)
5733 { 5733 {
5734 if ((x & 7) == 0) 5734 if ((x & 7) == 0)
5735 c = *p++; 5735 {
5736 if (p >= end)
5737 {
5738 x_destroy_x_image (ximg);
5739 x_clear_image (f, img);
5740 image_error ("Invalid image size in image `%s'",
5741 img->spec, Qnil);
5742 goto error;
5743 }
5744 c = *p++;
5745 }
5736 g = c & 0x80; 5746 g = c & 0x80;
5737 c <<= 1; 5747 c <<= 1;
5738 } 5748 }
@@ -5744,9 +5754,13 @@ pbm_load (f, img)
5744 } 5754 }
5745 else 5755 else
5746 { 5756 {
5747 if (raw_p && (p + 3 * height * width > end)) 5757 if (raw_p
5758 && ((type == PBM_GRAY)
5759 ? (p + height * width > end)
5760 : (p + 3 * height * width > end)))
5748 { 5761 {
5749 x_destroy_x_image (ximg); 5762 x_destroy_x_image (ximg);
5763 x_clear_image (f, img);
5750 image_error ("Invalid image size in image `%s'", 5764 image_error ("Invalid image size in image `%s'",
5751 img->spec, Qnil); 5765 img->spec, Qnil);
5752 goto error; 5766 goto error;
diff --git a/src/keyboard.c b/src/keyboard.c
index 50c1d5a43b8..4658fdcca51 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -508,7 +508,7 @@ Lisp_Object Qmake_frame_visible;
508Lisp_Object Qselect_window; 508Lisp_Object Qselect_window;
509Lisp_Object Qhelp_echo; 509Lisp_Object Qhelp_echo;
510 510
511#ifdef HAVE_MOUSE 511#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
512Lisp_Object Qmouse_fixup_help_message; 512Lisp_Object Qmouse_fixup_help_message;
513#endif 513#endif
514 514
@@ -661,7 +661,7 @@ static Lisp_Object read_char_x_menu_prompt ();
661static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int, 661static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int,
662 Lisp_Object *)); 662 Lisp_Object *));
663static Lisp_Object make_lispy_event P_ ((struct input_event *)); 663static Lisp_Object make_lispy_event P_ ((struct input_event *));
664#ifdef HAVE_MOUSE 664#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
665static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object, 665static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object,
666 enum scroll_bar_part, 666 enum scroll_bar_part,
667 Lisp_Object, Lisp_Object, 667 Lisp_Object, Lisp_Object,
@@ -1466,7 +1466,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
1466 return Qnil; 1466 return Qnil;
1467} 1467}
1468 1468
1469#ifdef HAVE_MOUSE 1469#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1470 1470
1471/* Restore mouse tracking enablement. See Ftrack_mouse for the only use 1471/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
1472 of this function. */ 1472 of this function. */
@@ -1542,7 +1542,7 @@ some_mouse_moved ()
1542 return 0; 1542 return 0;
1543} 1543}
1544 1544
1545#endif /* HAVE_MOUSE */ 1545#endif /* HAVE_MOUSE || HAVE_GPM */
1546 1546
1547/* This is the actual command reading loop, 1547/* This is the actual command reading loop,
1548 sans error-handling encapsulation. */ 1548 sans error-handling encapsulation. */
@@ -2476,7 +2476,7 @@ show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo)
2476 return; 2476 return;
2477 } 2477 }
2478 2478
2479#ifdef HAVE_MOUSE 2479#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
2480 if (!noninteractive && STRINGP (help)) 2480 if (!noninteractive && STRINGP (help))
2481 { 2481 {
2482 /* The mouse-fixup-help-message Lisp function can call 2482 /* The mouse-fixup-help-message Lisp function can call
@@ -3753,7 +3753,7 @@ readable_events (flags)
3753 return 1; 3753 return 1;
3754 } 3754 }
3755 3755
3756#ifdef HAVE_MOUSE 3756#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
3757 if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) 3757 if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
3758 && !NILP (do_mouse_tracking) && some_mouse_moved ()) 3758 && !NILP (do_mouse_tracking) && some_mouse_moved ())
3759 return 1; 3759 return 1;
@@ -4103,7 +4103,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4103 { 4103 {
4104 if (kbd_fetch_ptr != kbd_store_ptr) 4104 if (kbd_fetch_ptr != kbd_store_ptr)
4105 break; 4105 break;
4106#ifdef HAVE_MOUSE 4106#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
4107 if (!NILP (do_mouse_tracking) && some_mouse_moved ()) 4107 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
4108 break; 4108 break;
4109#endif 4109#endif
@@ -4125,7 +4125,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4125#endif /* SIGIO */ 4125#endif /* SIGIO */
4126 if (kbd_fetch_ptr != kbd_store_ptr) 4126 if (kbd_fetch_ptr != kbd_store_ptr)
4127 break; 4127 break;
4128#ifdef HAVE_MOUSE 4128#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
4129 if (!NILP (do_mouse_tracking) && some_mouse_moved ()) 4129 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
4130 break; 4130 break;
4131#endif 4131#endif
@@ -4361,7 +4361,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4361 } 4361 }
4362 } 4362 }
4363 } 4363 }
4364#ifdef HAVE_MOUSE 4364#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
4365 /* Try generating a mouse motion event. */ 4365 /* Try generating a mouse motion event. */
4366 else if (!NILP (do_mouse_tracking) && some_mouse_moved ()) 4366 else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
4367 { 4367 {
@@ -4406,7 +4406,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4406 if (!NILP (x) && NILP (obj)) 4406 if (!NILP (x) && NILP (obj))
4407 obj = make_lispy_movement (f, bar_window, part, x, y, time); 4407 obj = make_lispy_movement (f, bar_window, part, x, y, time);
4408 } 4408 }
4409#endif /* HAVE_MOUSE */ 4409#endif /* HAVE_MOUSE || HAVE GPM */
4410 else 4410 else
4411 /* We were promised by the above while loop that there was 4411 /* We were promised by the above while loop that there was
4412 something for us to read! */ 4412 something for us to read! */
@@ -6123,6 +6123,66 @@ make_lispy_event (event)
6123 } 6123 }
6124#endif 6124#endif
6125 6125
6126#ifdef HAVE_GPM
6127 case GPM_CLICK_EVENT:
6128 {
6129 FRAME_PTR f = XFRAME (event->frame_or_window);
6130 Lisp_Object head, position;
6131 Lisp_Object *start_pos_ptr;
6132 Lisp_Object start_pos;
6133 int button = event->code;
6134
6135 if (button >= ASIZE (button_down_location))
6136 {
6137 button_down_location = larger_vector (button_down_location,
6138 button + 1, Qnil);
6139 mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
6140 }
6141
6142 start_pos_ptr = &AREF (button_down_location, button);
6143 start_pos = *start_pos_ptr;
6144
6145 position = make_lispy_position (f, &event->x, &event->y,
6146 event->timestamp);
6147
6148 if (event->modifiers & down_modifier)
6149 *start_pos_ptr = Fcopy_alist (position);
6150 else if (event->modifiers & (up_modifier | drag_modifier))
6151 {
6152 if (!CONSP (start_pos))
6153 return Qnil;
6154 event->modifiers &= ~up_modifier;
6155 }
6156
6157 head = modify_event_symbol (button,
6158 event->modifiers,
6159 Qmouse_click, Vlispy_mouse_stem,
6160 NULL,
6161 &mouse_syms,
6162 XVECTOR (mouse_syms)->size);
6163
6164 if (event->modifiers & drag_modifier)
6165 return Fcons (head,
6166 Fcons (start_pos,
6167 Fcons (position,
6168 Qnil)));
6169 else if (event->modifiers & double_modifier)
6170 return Fcons (head,
6171 Fcons (position,
6172 Fcons (make_number (2),
6173 Qnil)));
6174 else if (event->modifiers & triple_modifier)
6175 return Fcons (head,
6176 Fcons (position,
6177 Fcons (make_number (3),
6178 Qnil)));
6179 else
6180 return Fcons (head,
6181 Fcons (position,
6182 Qnil));
6183 }
6184#endif /* HAVE_GPM */
6185
6126 /* The 'kind' field of the event is something we don't recognize. */ 6186 /* The 'kind' field of the event is something we don't recognize. */
6127 default: 6187 default:
6128 abort (); 6188 abort ();
@@ -7057,7 +7117,27 @@ tty_read_avail_input (struct terminal *terminal,
7057 if (! tty->input) 7117 if (! tty->input)
7058 return 0; /* The terminal is suspended. */ 7118 return 0; /* The terminal is suspended. */
7059 7119
7060 /* Determine how many characters we should *try* to read. */ 7120#ifdef HAVE_GPM
7121 if (term_gpm && gpm_tty == tty->terminal->id)
7122 {
7123 Gpm_Event event;
7124 struct input_event hold_quit;
7125 int gpm;
7126
7127 EVENT_INIT (hold_quit);
7128 hold_quit.kind = NO_EVENT;
7129
7130 while (gpm = Gpm_GetEvent (&event), gpm == 1) {
7131 nread += handle_one_term_event (tty, &event, &hold_quit);
7132 }
7133 if (hold_quit.kind != NO_EVENT)
7134 kbd_buffer_store_event (&hold_quit);
7135 if (nread)
7136 return nread;
7137 }
7138#endif /* HAVE_GPM */
7139
7140/* Determine how many characters we should *try* to read. */
7061#ifdef FIONREAD 7141#ifdef FIONREAD
7062 /* Find out how much input is available. */ 7142 /* Find out how much input is available. */
7063 if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0) 7143 if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
@@ -11440,7 +11520,7 @@ init_keyboard ()
11440 recent_keys_index = 0; 11520 recent_keys_index = 0;
11441 kbd_fetch_ptr = kbd_buffer; 11521 kbd_fetch_ptr = kbd_buffer;
11442 kbd_store_ptr = kbd_buffer; 11522 kbd_store_ptr = kbd_buffer;
11443#ifdef HAVE_MOUSE 11523#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
11444 do_mouse_tracking = Qnil; 11524 do_mouse_tracking = Qnil;
11445#endif 11525#endif
11446 input_pending = 0; 11526 input_pending = 0;
@@ -11636,7 +11716,7 @@ syms_of_keyboard ()
11636 Qmenu_bar = intern ("menu-bar"); 11716 Qmenu_bar = intern ("menu-bar");
11637 staticpro (&Qmenu_bar); 11717 staticpro (&Qmenu_bar);
11638 11718
11639#ifdef HAVE_MOUSE 11719#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
11640 Qmouse_fixup_help_message = intern ("mouse-fixup-help-message"); 11720 Qmouse_fixup_help_message = intern ("mouse-fixup-help-message");
11641 staticpro (&Qmouse_fixup_help_message); 11721 staticpro (&Qmouse_fixup_help_message);
11642#endif 11722#endif
@@ -11768,7 +11848,7 @@ syms_of_keyboard ()
11768 defsubr (&Sread_key_sequence); 11848 defsubr (&Sread_key_sequence);
11769 defsubr (&Sread_key_sequence_vector); 11849 defsubr (&Sread_key_sequence_vector);
11770 defsubr (&Srecursive_edit); 11850 defsubr (&Srecursive_edit);
11771#ifdef HAVE_MOUSE 11851#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
11772 defsubr (&Strack_mouse); 11852 defsubr (&Strack_mouse);
11773#endif 11853#endif
11774 defsubr (&Sinput_pending_p); 11854 defsubr (&Sinput_pending_p);
diff --git a/src/lisp.h b/src/lisp.h
index 4ae55c5519e..82036f3030e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3101,6 +3101,8 @@ extern int wait_reading_process_output P_ ((int, int, int, int,
3101 int)); 3101 int));
3102extern void add_keyboard_wait_descriptor P_ ((int)); 3102extern void add_keyboard_wait_descriptor P_ ((int));
3103extern void delete_keyboard_wait_descriptor P_ ((int)); 3103extern void delete_keyboard_wait_descriptor P_ ((int));
3104extern void add_gpm_wait_descriptor P_ ((int));
3105extern void delete_gpm_wait_descriptor P_ ((int));
3104extern void close_process_descs P_ ((void)); 3106extern void close_process_descs P_ ((void));
3105extern void init_process P_ ((void)); 3107extern void init_process P_ ((void));
3106extern void syms_of_process P_ ((void)); 3108extern void syms_of_process P_ ((void));
diff --git a/src/m/alpha.h b/src/m/alpha.h
index 6a9f09ed0bd..3b29a8ee7be 100644
--- a/src/m/alpha.h
+++ b/src/m/alpha.h
@@ -99,10 +99,6 @@ NOTE-END
99# endif 99# endif
100#endif 100#endif
101 101
102#if defined(__OpenBSD__)
103#define ORDINARY_LINK
104#endif
105
106#ifdef __ELF__ 102#ifdef __ELF__
107#undef UNEXEC 103#undef UNEXEC
108#define UNEXEC unexelf.o 104#define UNEXEC unexelf.o
diff --git a/src/m/macppc.h b/src/m/macppc.h
index 117d7a11dc4..26994575edd 100644
--- a/src/m/macppc.h
+++ b/src/m/macppc.h
@@ -66,10 +66,6 @@ Boston, MA 02110-1301, USA. */
66 66
67/* #define NO_SOCK_SIGIO */ 67/* #define NO_SOCK_SIGIO */
68 68
69#if defined(__OpenBSD__)
70#define ORDINARY_LINK
71#endif
72
73#define UNEXEC unexelf.o 69#define UNEXEC unexelf.o
74 70
75#define NO_TERMIO 71#define NO_TERMIO
diff --git a/src/macterm.c b/src/macterm.c
index b48ffb47fdb..e31fba134f5 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -6079,7 +6079,9 @@ x_calc_absolute_position (f)
6079 6079
6080 /* Find the offsets of the outside upper-left corner of 6080 /* Find the offsets of the outside upper-left corner of
6081 the inner window, with respect to the outer window. */ 6081 the inner window, with respect to the outer window. */
6082 BLOCK_INPUT;
6082 mac_get_window_bounds (f, &inner, &outer); 6083 mac_get_window_bounds (f, &inner, &outer);
6084 UNBLOCK_INPUT;
6083 6085
6084 width_diff = (outer.right - outer.left) - (inner.right - inner.left); 6086 width_diff = (outer.right - outer.left) - (inner.right - inner.left);
6085 height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top); 6087 height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top);
@@ -9159,15 +9161,16 @@ mac_get_mouse_btn (EventRef ref)
9159 9161
9160/* Normally, ConvertEventRefToEventRecord will correctly handle all 9162/* Normally, ConvertEventRefToEventRecord will correctly handle all
9161 events. However the click of the mouse wheel is not converted to a 9163 events. However the click of the mouse wheel is not converted to a
9162 mouseDown or mouseUp event. Likewise for dead key down events. 9164 mouseDown or mouseUp event. Likewise for dead key events. This
9163 This calls ConvertEventRef, but then checks to see if it is a mouse 9165 calls ConvertEventRefToEventRecord, but then checks to see if it is
9164 up/down, or a dead key down carbon event that has not been 9166 a mouse up/down, or a dead key Carbon event that has not been
9165 converted, and if so, converts it by hand (to be picked up in the 9167 converted, and if so, converts it by hand (to be picked up in the
9166 XTread_socket loop). */ 9168 XTread_socket loop). */
9167static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) 9169static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
9168{ 9170{
9169 OSStatus err; 9171 OSStatus err;
9170 Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec); 9172 Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
9173 EventKind action;
9171 9174
9172 if (result) 9175 if (result)
9173 return result; 9176 return result;
@@ -9196,6 +9199,14 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
9196 switch (GetEventKind (eventRef)) 9199 switch (GetEventKind (eventRef))
9197 { 9200 {
9198 case kEventRawKeyDown: 9201 case kEventRawKeyDown:
9202 action = keyDown;
9203 goto keystroke_common;
9204 case kEventRawKeyRepeat:
9205 action = autoKey;
9206 goto keystroke_common;
9207 case kEventRawKeyUp:
9208 action = keyUp;
9209 keystroke_common:
9199 { 9210 {
9200 unsigned char char_codes; 9211 unsigned char char_codes;
9201 UInt32 key_code; 9212 UInt32 key_code;
@@ -9209,7 +9220,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
9209 NULL, &key_code); 9220 NULL, &key_code);
9210 if (err == noErr) 9221 if (err == noErr)
9211 { 9222 {
9212 eventRec->what = keyDown; 9223 eventRec->what = action;
9213 eventRec->message = char_codes | ((key_code & 0xff) << 8); 9224 eventRec->message = char_codes | ((key_code & 0xff) << 8);
9214 result = 1; 9225 result = 1;
9215 } 9226 }
diff --git a/src/process.c b/src/process.c
index bd12f3e1a68..9a7cf29963f 100644
--- a/src/process.c
+++ b/src/process.c
@@ -336,6 +336,10 @@ static SELECT_TYPE non_keyboard_wait_mask;
336 336
337static SELECT_TYPE non_process_wait_mask; 337static SELECT_TYPE non_process_wait_mask;
338 338
339/* Mask for the gpm mouse input descriptor. */
340
341static SELECT_TYPE gpm_wait_mask;
342
339#ifdef NON_BLOCKING_CONNECT 343#ifdef NON_BLOCKING_CONNECT
340/* Mask of bits indicating the descriptors that we wait for connect to 344/* Mask of bits indicating the descriptors that we wait for connect to
341 complete on. Once they complete, they are removed from this mask 345 complete on. Once they complete, they are removed from this mask
@@ -357,6 +361,9 @@ static int max_process_desc;
357/* The largest descriptor currently in use for keyboard input. */ 361/* The largest descriptor currently in use for keyboard input. */
358static int max_keyboard_desc; 362static int max_keyboard_desc;
359 363
364/* The largest descriptor currently in use for gpm mouse input. */
365static int max_gpm_desc;
366
360/* Nonzero means delete a process right away if it exits. */ 367/* Nonzero means delete a process right away if it exits. */
361static int delete_exited_processes; 368static int delete_exited_processes;
362 369
@@ -4451,7 +4458,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4451 IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask); 4458 IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
4452 4459
4453 EMACS_SET_SECS_USECS (timeout, 0, 0); 4460 EMACS_SET_SECS_USECS (timeout, 0, 0);
4454 if ((select (max (max_process_desc, max_keyboard_desc) + 1, 4461 if ((select (max (max (max_process_desc, max_keyboard_desc),
4462 max_gpm_desc) + 1,
4455 &Atemp, 4463 &Atemp,
4456#ifdef NON_BLOCKING_CONNECT 4464#ifdef NON_BLOCKING_CONNECT
4457 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), 4465 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
@@ -4596,7 +4604,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4596 } 4604 }
4597#endif 4605#endif
4598 4606
4599 nfds = select (max (max_process_desc, max_keyboard_desc) + 1, 4607 nfds = select (max (max (max_process_desc, max_keyboard_desc),
4608 max_gpm_desc) + 1,
4600 &Available, 4609 &Available,
4601#ifdef NON_BLOCKING_CONNECT 4610#ifdef NON_BLOCKING_CONNECT
4602 (check_connect ? &Connecting : (SELECT_TYPE *)0), 4611 (check_connect ? &Connecting : (SELECT_TYPE *)0),
@@ -6975,6 +6984,21 @@ add_keyboard_wait_descriptor (desc)
6975 max_keyboard_desc = desc; 6984 max_keyboard_desc = desc;
6976} 6985}
6977 6986
6987static int add_gpm_wait_descriptor_called_flag;
6988
6989void
6990add_gpm_wait_descriptor (desc)
6991 int desc;
6992{
6993 if (! add_gpm_wait_descriptor_called_flag)
6994 FD_CLR (0, &input_wait_mask);
6995 add_gpm_wait_descriptor_called_flag = 1;
6996 FD_SET (desc, &input_wait_mask);
6997 FD_SET (desc, &gpm_wait_mask);
6998 if (desc > max_gpm_desc)
6999 max_gpm_desc = desc;
7000}
7001
6978/* From now on, do not expect DESC to give keyboard input. */ 7002/* From now on, do not expect DESC to give keyboard input. */
6979 7003
6980void 7004void
@@ -6990,10 +7014,29 @@ delete_keyboard_wait_descriptor (desc)
6990 if (desc == max_keyboard_desc) 7014 if (desc == max_keyboard_desc)
6991 for (fd = 0; fd < lim; fd++) 7015 for (fd = 0; fd < lim; fd++)
6992 if (FD_ISSET (fd, &input_wait_mask) 7016 if (FD_ISSET (fd, &input_wait_mask)
6993 && !FD_ISSET (fd, &non_keyboard_wait_mask)) 7017 && !FD_ISSET (fd, &non_keyboard_wait_mask)
7018 && !FD_ISSET (fd, &gpm_wait_mask))
6994 max_keyboard_desc = fd; 7019 max_keyboard_desc = fd;
6995} 7020}
6996 7021
7022void
7023delete_gpm_wait_descriptor (desc)
7024 int desc;
7025{
7026 int fd;
7027 int lim = max_gpm_desc;
7028
7029 FD_CLR (desc, &input_wait_mask);
7030 FD_CLR (desc, &non_process_wait_mask);
7031
7032 if (desc == max_gpm_desc)
7033 for (fd = 0; fd < lim; fd++)
7034 if (FD_ISSET (fd, &input_wait_mask)
7035 && !FD_ISSET (fd, &non_keyboard_wait_mask)
7036 && !FD_ISSET (fd, &non_process_wait_mask))
7037 max_gpm_desc = fd;
7038}
7039
6997/* Return nonzero if *MASK has a bit set 7040/* Return nonzero if *MASK has a bit set
6998 that corresponds to one of the keyboard input descriptors. */ 7041 that corresponds to one of the keyboard input descriptors. */
6999 7042
diff --git a/src/syntax.c b/src/syntax.c
index a9e6dda81fe..acb5d37825c 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1669,10 +1669,10 @@ skip_chars (forwardp, syntaxp, string, lim, handle_iso_classes)
1669 p = GPT_ADDR; 1669 p = GPT_ADDR;
1670 stop = endp; 1670 stop = endp;
1671 } 1671 }
1672 UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
1672 if (! fastmap[(int) SYNTAX (p[-1])]) 1673 if (! fastmap[(int) SYNTAX (p[-1])])
1673 break; 1674 break;
1674 p--, pos--; 1675 p--, pos--;
1675 UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
1676 } 1676 }
1677 } 1677 }
1678 } 1678 }
diff --git a/src/sysdep.c b/src/sysdep.c
index bbaa09fbf27..ba55d2361bb 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1747,6 +1747,14 @@ init_sys_modes (tty_out)
1747 fcntl (fileno (tty_out->input), F_GETOWN, 0); 1747 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1748 fcntl (fileno (tty_out->input), F_SETOWN, getpid ()); 1748 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1749 init_sigio (fileno (tty_out->input)); 1749 init_sigio (fileno (tty_out->input));
1750#ifdef HAVE_GPM
1751 if (term_gpm)
1752 {
1753 fcntl (gpm_fd, F_SETOWN, getpid ());
1754 fcntl (gpm_fd, F_SETFL, O_NONBLOCK);
1755 init_sigio (gpm_fd);
1756 }
1757#endif /* HAVE_GPM */
1750 } 1758 }
1751#endif /* F_GETOWN */ 1759#endif /* F_GETOWN */
1752#endif /* F_SETOWN_BUG */ 1760#endif /* F_SETOWN_BUG */
diff --git a/src/term.c b/src/term.c
index 53727a975ea..1d8e885ade9 100644
--- a/src/term.c
+++ b/src/term.c
@@ -171,6 +171,9 @@ static int system_uses_terminfo;
171char *tparam (); 171char *tparam ();
172 172
173extern char *tgetstr (); 173extern char *tgetstr ();
174
175static void term_clear_mouse_face ();
176static void term_mouse_highlight (struct frame *f, int x, int y);
174 177
175 178
176#ifdef WINDOWSNT 179#ifdef WINDOWSNT
@@ -184,6 +187,35 @@ extern char *tgetstr ();
184#define FRAME_TERMCAP_P(_f_) 0 187#define FRAME_TERMCAP_P(_f_) 0
185#endif /* WINDOWSNT */ 188#endif /* WINDOWSNT */
186 189
190#ifdef HAVE_GPM
191#include <sys/fcntl.h>
192#include "buffer.h"
193
194/* Nonzero means mouse is enabled on Linux console. */
195int term_gpm = 0;
196
197/* The id of the terminal device for which we have gpm support. */
198int gpm_tty;
199
200/* These variables describe the range of text currently shown in its
201 mouse-face, together with the window they apply to. As long as
202 the mouse stays within this range, we need not redraw anything on
203 its account. Rows and columns are glyph matrix positions in
204 MOUSE_FACE_WINDOW. */
205static int mouse_face_beg_row, mouse_face_beg_col;
206static int mouse_face_end_row, mouse_face_end_col;
207static int mouse_face_past_end;
208static Lisp_Object mouse_face_window;
209static int mouse_face_face_id;
210
211/* FRAME and X, Y position of mouse when last checked for
212 highlighting. X and Y can be negative or out of range for the frame. */
213struct frame *mouse_face_mouse_frame;
214int mouse_face_mouse_x, mouse_face_mouse_y;
215
216static int pos_x, pos_y;
217static int last_mouse_x, last_mouse_y;
218#endif /* HAVE_GPM */
187 219
188/* Ring the bell on a tty. */ 220/* Ring the bell on a tty. */
189 221
@@ -715,6 +747,66 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
715 cmcheckmagic (tty); 747 cmcheckmagic (tty);
716} 748}
717 749
750static void
751tty_write_glyphs_with_face (f, string, len, face_id)
752 register struct frame *f;
753 register struct glyph *string;
754 register int len, face_id;
755{
756 unsigned char *conversion_buffer;
757 struct coding_system *coding;
758
759 struct tty_display_info *tty = FRAME_TTY (f);
760
761 tty_turn_off_insert (tty);
762 tty_hide_cursor (tty);
763
764 /* Don't dare write in last column of bottom line, if Auto-Wrap,
765 since that would scroll the whole frame on some terminals. */
766
767 if (AutoWrap (tty)
768 && curY (tty) + 1 == FRAME_LINES (f)
769 && (curX (tty) + len) == FRAME_COLS (f))
770 len --;
771 if (len <= 0)
772 return;
773
774 cmplus (tty, len);
775
776 /* If terminal_coding does any conversion, use it, otherwise use
777 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
778 because it always return 1 if the member src_multibyte is 1. */
779 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
780 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
781 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
782 the tail. */
783 coding->mode &= ~CODING_MODE_LAST_BLOCK;
784
785 /* Turn appearance modes of the face. */
786 tty_highlight_if_desired (tty);
787 turn_on_face (f, face_id);
788
789 coding->mode |= CODING_MODE_LAST_BLOCK;
790 conversion_buffer = encode_terminal_code (string, len, coding);
791 if (coding->produced > 0)
792 {
793 BLOCK_INPUT;
794 fwrite (conversion_buffer, 1, coding->produced, tty->output);
795 if (ferror (tty->output))
796 clearerr (tty->output);
797 if (tty->termscript)
798 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
799 UNBLOCK_INPUT;
800 }
801
802 /* Turn appearance modes off. */
803 turn_off_face (f, face_id);
804 tty_turn_off_highlight (tty);
805
806 cmcheckmagic (tty);
807}
808
809
718/* An implementation of insert_glyphs for termcap frames. */ 810/* An implementation of insert_glyphs for termcap frames. */
719 811
720static void 812static void
@@ -2248,6 +2340,663 @@ the currently selected frame. */)
2248 2340
2249 2341
2250/*********************************************************************** 2342/***********************************************************************
2343 Mouse
2344 ***********************************************************************/
2345
2346#ifdef HAVE_GPM
2347static void
2348term_show_mouse_face (enum draw_glyphs_face draw)
2349{
2350 struct window *w = XWINDOW (mouse_face_window);
2351 int save_x, save_y;
2352 int i, j;
2353
2354 struct frame *f = XFRAME (w->frame);
2355 struct tty_display_info *tty = FRAME_TTY (f);
2356
2357 if (/* If window is in the process of being destroyed, don't bother
2358 to do anything. */
2359 w->current_matrix != NULL
2360 /* Recognize when we are called to operate on rows that don't exist
2361 anymore. This can happen when a window is split. */
2362 && mouse_face_end_row < w->current_matrix->nrows)
2363 {
2364 /* write_glyphs writes at cursor position, so we need to
2365 temporarily move cursor coordinates to the beginning of
2366 the highlight region. */
2367
2368 /* Save current cursor co-ordinates */
2369 save_y = curY (tty);
2370 save_x = curX (tty);
2371
2372 /* Note that mouse_face_beg_row etc. are window relative. */
2373 for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
2374 {
2375 int start_hpos, end_hpos, nglyphs;
2376 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
2377
2378 /* Don't do anything if row doesn't have valid contents. */
2379 if (!row->enabled_p)
2380 continue;
2381
2382 /* For all but the first row, the highlight starts at column 0. */
2383 if (i == mouse_face_beg_row)
2384 start_hpos = mouse_face_beg_col;
2385 else
2386 start_hpos = 0;
2387
2388 if (i == mouse_face_end_row)
2389 end_hpos = mouse_face_end_col;
2390 else
2391 {
2392 end_hpos = row->used[TEXT_AREA];
2393 if (draw == DRAW_NORMAL_TEXT)
2394 row->fill_line_p = 1; /* Clear to end of line */
2395 }
2396
2397 if (end_hpos <= start_hpos)
2398 continue;
2399 /* Record that some glyphs of this row are displayed in
2400 mouse-face. */
2401 row->mouse_face_p = draw > 0;
2402
2403 nglyphs = end_hpos - start_hpos;
2404
2405 if (end_hpos >= row->used[TEXT_AREA])
2406 nglyphs = row->used[TEXT_AREA] - start_hpos;
2407
2408 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2409 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
2410 + WINDOW_LEFT_EDGE_X (w);
2411
2412 cursor_to (f, pos_y, pos_x);
2413
2414 if (draw == DRAW_MOUSE_FACE)
2415 {
2416 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
2417 nglyphs, mouse_face_face_id);
2418 }
2419 else /* draw == DRAW_NORMAL_TEXT */
2420 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2421 }
2422 cursor_to (f, save_y, save_x);
2423 }
2424}
2425
2426static void
2427term_clear_mouse_face ()
2428{
2429 if (!NILP (mouse_face_window))
2430 term_show_mouse_face (DRAW_NORMAL_TEXT);
2431
2432 mouse_face_beg_row = mouse_face_beg_col = -1;
2433 mouse_face_end_row = mouse_face_end_col = -1;
2434 mouse_face_window = Qnil;
2435}
2436
2437/* Find the glyph matrix position of buffer position POS in window W.
2438 *HPOS and *VPOS are set to the positions found. W's current glyphs
2439 must be up to date. If POS is above window start return (0, 0).
2440 If POS is after end of W, return end of last line in W.
2441 - taken from msdos.c */
2442static int
2443fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
2444{
2445 int i, lastcol, line_start_position, maybe_next_line_p = 0;
2446 int yb = window_text_bottom_y (w);
2447 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
2448
2449 while (row->y < yb)
2450 {
2451 if (row->used[TEXT_AREA])
2452 line_start_position = row->glyphs[TEXT_AREA]->charpos;
2453 else
2454 line_start_position = 0;
2455
2456 if (line_start_position > pos)
2457 break;
2458 /* If the position sought is the end of the buffer,
2459 don't include the blank lines at the bottom of the window. */
2460 else if (line_start_position == pos
2461 && pos == BUF_ZV (XBUFFER (w->buffer)))
2462 {
2463 maybe_next_line_p = 1;
2464 break;
2465 }
2466 else if (line_start_position > 0)
2467 best_row = row;
2468
2469 /* Don't overstep the last matrix row, lest we get into the
2470 never-never land... */
2471 if (row->y + 1 >= yb)
2472 break;
2473
2474 ++row;
2475 }
2476
2477 /* Find the right column within BEST_ROW. */
2478 lastcol = 0;
2479 row = best_row;
2480 for (i = 0; i < row->used[TEXT_AREA]; i++)
2481 {
2482 struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
2483 int charpos;
2484
2485 charpos = glyph->charpos;
2486 if (charpos == pos)
2487 {
2488 *hpos = i;
2489 *vpos = row->y;
2490 return 1;
2491 }
2492 else if (charpos > pos)
2493 break;
2494 else if (charpos > 0)
2495 lastcol = i;
2496 }
2497
2498 /* If we're looking for the end of the buffer,
2499 and we didn't find it in the line we scanned,
2500 use the start of the following line. */
2501 if (maybe_next_line_p)
2502 {
2503 ++row;
2504 lastcol = 0;
2505 }
2506
2507 *vpos = row->y;
2508 *hpos = lastcol + 1;
2509 return 0;
2510}
2511
2512static void
2513term_mouse_highlight (struct frame *f, int x, int y)
2514{
2515 enum window_part part;
2516 Lisp_Object window;
2517 struct window *w;
2518 struct buffer *b;
2519
2520 if (NILP (Vmouse_highlight)
2521 || !f->glyphs_initialized_p)
2522 return;
2523
2524 mouse_face_mouse_x = x;
2525 mouse_face_mouse_y = y;
2526 mouse_face_mouse_frame = f;
2527
2528 /* Which window is that in? */
2529 window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
2530
2531 /* Not on a window -> return. */
2532 if (!WINDOWP (window))
2533 return;
2534
2535 if (!EQ (window, mouse_face_window))
2536 term_clear_mouse_face ();
2537
2538 w = XWINDOW (window);
2539
2540 /* Are we in a window whose display is up to date?
2541 And verify the buffer's text has not changed. */
2542 b = XBUFFER (w->buffer);
2543 if (part == ON_TEXT
2544 && EQ (w->window_end_valid, w->buffer)
2545 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
2546 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
2547 {
2548 int pos, i, nrows = w->current_matrix->nrows;
2549 struct glyph_row *row;
2550 struct glyph *glyph;
2551
2552 /* Find the glyph under X/Y. */
2553 glyph = NULL;
2554 if (y >= 0 && y < nrows)
2555 {
2556 row = MATRIX_ROW (w->current_matrix, y);
2557 /* Give up if some row before the one we are looking for is
2558 not enabled. */
2559 for (i = 0; i <= y; i++)
2560 if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
2561 break;
2562 if (i > y /* all rows upto and including the one at Y are enabled */
2563 && row->displays_text_p
2564 && x < window_box_width (w, TEXT_AREA))
2565 {
2566 glyph = row->glyphs[TEXT_AREA];
2567 if (x >= row->used[TEXT_AREA])
2568 glyph = NULL;
2569 else
2570 {
2571 glyph += x;
2572 if (!BUFFERP (glyph->object))
2573 glyph = NULL;
2574 }
2575 }
2576 }
2577
2578 /* Clear mouse face if X/Y not over text. */
2579 if (glyph == NULL)
2580 {
2581 term_clear_mouse_face ();
2582 return;
2583 }
2584
2585 if (!BUFFERP (glyph->object))
2586 abort ();
2587 pos = glyph->charpos;
2588
2589 /* Check for mouse-face. */
2590 {
2591 extern Lisp_Object Qmouse_face;
2592 Lisp_Object mouse_face, overlay, position, *overlay_vec;
2593 int noverlays, obegv, ozv;;
2594 struct buffer *obuf;
2595
2596 /* If we get an out-of-range value, return now; avoid an error. */
2597 if (pos > BUF_Z (b))
2598 return;
2599
2600 /* Make the window's buffer temporarily current for
2601 overlays_at and compute_char_face. */
2602 obuf = current_buffer;
2603 current_buffer = b;
2604 obegv = BEGV;
2605 ozv = ZV;
2606 BEGV = BEG;
2607 ZV = Z;
2608
2609 /* Is this char mouse-active? */
2610 XSETINT (position, pos);
2611
2612 /* Put all the overlays we want in a vector in overlay_vec. */
2613 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
2614 /* Sort overlays into increasing priority order. */
2615 noverlays = sort_overlays (overlay_vec, noverlays, w);
2616
2617 /* Check mouse-face highlighting. */
2618 if (!(EQ (window, mouse_face_window)
2619 && y >= mouse_face_beg_row
2620 && y <= mouse_face_end_row
2621 && (y > mouse_face_beg_row
2622 || x >= mouse_face_beg_col)
2623 && (y < mouse_face_end_row
2624 || x < mouse_face_end_col
2625 || mouse_face_past_end)))
2626 {
2627 /* Clear the display of the old active region, if any. */
2628 term_clear_mouse_face ();
2629
2630 /* Find the highest priority overlay that has a mouse-face
2631 property. */
2632 overlay = Qnil;
2633 for (i = noverlays - 1; i >= 0; --i)
2634 {
2635 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
2636 if (!NILP (mouse_face))
2637 {
2638 overlay = overlay_vec[i];
2639 break;
2640 }
2641 }
2642
2643 /* If no overlay applies, get a text property. */
2644 if (NILP (overlay))
2645 mouse_face = Fget_text_property (position, Qmouse_face,
2646 w->buffer);
2647
2648 /* Handle the overlay case. */
2649 if (!NILP (overlay))
2650 {
2651 /* Find the range of text around this char that
2652 should be active. */
2653 Lisp_Object before, after;
2654 int ignore;
2655
2656
2657 before = Foverlay_start (overlay);
2658 after = Foverlay_end (overlay);
2659 /* Record this as the current active region. */
2660 fast_find_position (w, XFASTINT (before),
2661 &mouse_face_beg_col,
2662 &mouse_face_beg_row);
2663
2664 mouse_face_past_end
2665 = !fast_find_position (w, XFASTINT (after),
2666 &mouse_face_end_col,
2667 &mouse_face_end_row);
2668 mouse_face_window = window;
2669
2670 mouse_face_face_id
2671 = face_at_buffer_position (w, pos, 0, 0,
2672 &ignore, pos + 1, 1);
2673
2674 /* Display it as active. */
2675 term_show_mouse_face (DRAW_MOUSE_FACE);
2676 }
2677 /* Handle the text property case. */
2678 else if (!NILP (mouse_face))
2679 {
2680 /* Find the range of text around this char that
2681 should be active. */
2682 Lisp_Object before, after, beginning, end;
2683 int ignore;
2684
2685 beginning = Fmarker_position (w->start);
2686 XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos)));
2687 before
2688 = Fprevious_single_property_change (make_number (pos + 1),
2689 Qmouse_face,
2690 w->buffer, beginning);
2691 after
2692 = Fnext_single_property_change (position, Qmouse_face,
2693 w->buffer, end);
2694
2695 /* Record this as the current active region. */
2696 fast_find_position (w, XFASTINT (before),
2697 &mouse_face_beg_col,
2698 &mouse_face_beg_row);
2699 mouse_face_past_end
2700 = !fast_find_position (w, XFASTINT (after),
2701 &mouse_face_end_col,
2702 &mouse_face_end_row);
2703 mouse_face_window = window;
2704
2705 mouse_face_face_id
2706 = face_at_buffer_position (w, pos, 0, 0,
2707 &ignore, pos + 1, 1);
2708
2709 /* Display it as active. */
2710 term_show_mouse_face (DRAW_MOUSE_FACE);
2711 }
2712 }
2713
2714 /* Look for a `help-echo' property. */
2715 {
2716 Lisp_Object help;
2717 extern Lisp_Object Qhelp_echo;
2718
2719 /* Check overlays first. */
2720 help = Qnil;
2721 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
2722 {
2723 overlay = overlay_vec[i];
2724 help = Foverlay_get (overlay, Qhelp_echo);
2725 }
2726
2727 if (!NILP (help))
2728 {
2729 help_echo_string = help;
2730 help_echo_window = window;
2731 help_echo_object = overlay;
2732 help_echo_pos = pos;
2733 }
2734 /* Try text properties. */
2735 else if (NILP (help)
2736 && ((STRINGP (glyph->object)
2737 && glyph->charpos >= 0
2738 && glyph->charpos < SCHARS (glyph->object))
2739 || (BUFFERP (glyph->object)
2740 && glyph->charpos >= BEGV
2741 && glyph->charpos < ZV)))
2742 {
2743 help = Fget_text_property (make_number (glyph->charpos),
2744 Qhelp_echo, glyph->object);
2745 if (!NILP (help))
2746 {
2747 help_echo_string = help;
2748 help_echo_window = window;
2749 help_echo_object = glyph->object;
2750 help_echo_pos = glyph->charpos;
2751 }
2752 }
2753 }
2754
2755 BEGV = obegv;
2756 ZV = ozv;
2757 current_buffer = obuf;
2758 }
2759 }
2760}
2761
2762static int
2763term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2764{
2765 /* Has the mouse moved off the glyph it was on at the last sighting? */
2766 if (event->x != last_mouse_x || event->y != last_mouse_y)
2767 {
2768 frame->mouse_moved = 1;
2769 term_mouse_highlight (frame, event->x - 1, event->y - 1);
2770 /* Remember which glyph we're now on. */
2771 last_mouse_x = event->x;
2772 last_mouse_y = event->y;
2773 return 1;
2774 }
2775 return 0;
2776}
2777
2778/* Return the current position of the mouse.
2779
2780 Set *f to the frame the mouse is in, or zero if the mouse is in no
2781 Emacs frame. If it is set to zero, all the other arguments are
2782 garbage.
2783
2784 Set *bar_window to Qnil, and *x and *y to the column and
2785 row of the character cell the mouse is over.
2786
2787 Set *time to the time the mouse was at the returned position.
2788
2789 This should clear mouse_moved until the next motion
2790 event arrives.
2791
2792 NOT CURRENTLY INVOKED: see mouse_position_hook below. */
2793static void
2794term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
2795 enum scroll_bar_part *part, Lisp_Object *x,
2796 Lisp_Object *y, unsigned long *time)
2797{
2798 Gpm_Event event;
2799 struct timeval now;
2800 int i;
2801
2802 BLOCK_INPUT;
2803
2804 *fp = SELECTED_FRAME ();
2805
2806 *bar_window = Qnil;
2807 *part = 0;
2808
2809 i = Gpm_GetSnapshot (&event);
2810
2811 XSETINT (*x, event.x);
2812 XSETINT (*y, event.y);
2813 gettimeofday(&now, 0);
2814 *time = (now.tv_sec * 1000) + (now.tv_usec / 1000);
2815
2816 UNBLOCK_INPUT;
2817}
2818
2819/* Prepare a mouse-event in *RESULT for placement in the input queue.
2820
2821 If the event is a button press, then note that we have grabbed
2822 the mouse. */
2823
2824static Lisp_Object
2825term_mouse_click (struct input_event *result, Gpm_Event *event,
2826 struct frame *f)
2827{
2828 struct timeval now;
2829 int i, j;
2830
2831 result->kind = GPM_CLICK_EVENT;
2832 for (i = 0, j = GPM_B_LEFT; i < 3; i++, j >>= 1 )
2833 {
2834 if (event->buttons & j) {
2835 result->code = i; /* button number */
2836 break;
2837 }
2838 }
2839 gettimeofday(&now, 0);
2840 result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000);
2841
2842 if (event->type & GPM_UP)
2843 result->modifiers = up_modifier;
2844 else if (event->type & GPM_DOWN)
2845 result->modifiers = down_modifier;
2846 else
2847 result->modifiers = 0;
2848
2849 if (event->type & GPM_SINGLE)
2850 result->modifiers |= click_modifier;
2851
2852 if (event->type & GPM_DOUBLE)
2853 result->modifiers |= double_modifier;
2854
2855 if (event->type & GPM_TRIPLE)
2856 result->modifiers |= triple_modifier;
2857
2858 if (event->type & GPM_DRAG)
2859 result->modifiers |= drag_modifier;
2860
2861 if (!(event->type & (GPM_MOVE|GPM_DRAG))) {
2862
2863 /* 1 << KG_SHIFT */
2864 if (event->modifiers & (1 << 0))
2865 result->modifiers |= shift_modifier;
2866
2867 /* 1 << KG_CTRL */
2868 if (event->modifiers & (1 << 2))
2869 result->modifiers |= ctrl_modifier;
2870
2871 /* 1 << KG_ALT || KG_ALTGR */
2872 if (event->modifiers & (1 << 3)
2873 || event->modifiers & (1 << 1))
2874 result->modifiers |= meta_modifier;
2875 }
2876
2877 XSETINT (result->x, event->x - 1);
2878 XSETINT (result->y, event->y - 1);
2879 XSETFRAME (result->frame_or_window, f);
2880 result->arg = Qnil;
2881 return Qnil;
2882}
2883
2884int
2885handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct input_event* hold_quit)
2886{
2887 struct frame *f = XFRAME (tty->top_frame);
2888 int i, j, fd;
2889 struct input_event ie;
2890 int do_help = 0;
2891 int count = 0;
2892
2893 EVENT_INIT (ie);
2894 ie.kind = NO_EVENT;
2895 ie.arg = Qnil;
2896
2897 if (event->type & GPM_MOVE) {
2898 unsigned char buf[6 * sizeof (short)];
2899 unsigned short *arg = (unsigned short *) buf + 1;
2900 const char *name;
2901
2902 previous_help_echo_string = help_echo_string;
2903 help_echo_string = Qnil;
2904
2905 /* Display mouse pointer */
2906 buf[sizeof(short) - 1] = 2; /* set selection */
2907
2908 arg[0] = arg[2] = (unsigned short) event->x;
2909 arg[1] = arg[3] = (unsigned short) event->y;
2910 arg[4] = (unsigned short) 3;
2911
2912 name = (const char *) ttyname (0);
2913 fd = open (name, O_WRONLY);
2914 ioctl (fd, TIOCLINUX, buf + sizeof (short) - 1);
2915 close(fd);
2916
2917 term_mouse_movement (f, event);
2918
2919 /* If the contents of the global variable help_echo_string
2920 has changed, generate a HELP_EVENT. */
2921 if (!NILP (help_echo_string)
2922 || !NILP (previous_help_echo_string))
2923 do_help = 1;
2924
2925 goto done;
2926 }
2927 else {
2928 f->mouse_moved = 0;
2929 term_mouse_click (&ie, event, f);
2930 //kbd_buffer_store_event_hold (&ie, hold_quit);
2931 }
2932
2933 done:
2934 if (ie.kind != NO_EVENT)
2935 {
2936 kbd_buffer_store_event_hold (&ie, hold_quit);
2937 count++;
2938 }
2939
2940 if (do_help
2941 && !(hold_quit && hold_quit->kind != NO_EVENT))
2942 {
2943 Lisp_Object frame;
2944
2945 if (f)
2946 XSETFRAME (frame, f);
2947 else
2948 frame = Qnil;
2949
2950 gen_help_event (help_echo_string, frame, help_echo_window,
2951 help_echo_object, help_echo_pos);
2952 count++;
2953 }
2954
2955 return count;
2956}
2957
2958DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
2959 0, 0, 0,
2960 doc: /* Open a connection to Gpm. */)
2961 ()
2962{
2963 struct tty_display_info *tty = FRAME_TTY (SELECTED_FRAME ());
2964 Gpm_Connect connection;
2965
2966 connection.eventMask = ~0;
2967 connection.defaultMask = ~GPM_HARD;
2968 connection.maxMod = ~0;
2969 connection.minMod = 0;
2970
2971 /* We only support GPM on the controlling tty. */
2972 if (term_gpm || tty->terminal->id > 1
2973 || Gpm_Open (&connection, 0) < 0)
2974 return Qnil;
2975 else
2976 {
2977 term_gpm = 1;
2978 gpm_tty = tty->terminal->id;
2979 reset_sys_modes (tty);
2980 init_sys_modes (tty);
2981 add_gpm_wait_descriptor (gpm_fd);
2982 return Qt;
2983 }
2984}
2985
2986DEFUN ("term-close-connection", Fterm_close_connection, Sterm_close_connection,
2987 0, 0, 0,
2988 doc: /* Close a connection to Gpm. */)
2989 ()
2990{
2991 delete_gpm_wait_descriptor (gpm_fd);
2992 while (Gpm_Close()); /* close all the stack */
2993 term_gpm = 0;
2994 return Qnil;
2995}
2996#endif /* HAVE_GPM */
2997
2998
2999/***********************************************************************
2251 Initialization 3000 Initialization
2252 ***********************************************************************/ 3001 ***********************************************************************/
2253 3002
@@ -2509,6 +3258,14 @@ init_tty (char *name, char *terminal_type, int must_succeed)
2509 3258
2510 encode_terminal_bufsize = 0; 3259 encode_terminal_bufsize = 0;
2511 3260
3261#ifdef HAVE_GPM
3262 /* TODO: Can't get Gpm_Snapshot in term_mouse_position to work: test with
3263 (mouse-position). Also set-mouse-position won't work as is. */
3264 /* mouse_position_hook = term_mouse_position; */
3265
3266 mouse_face_window = Qnil;
3267#endif
3268
2512#ifdef WINDOWSNT 3269#ifdef WINDOWSNT
2513 initialize_w32_display (); 3270 initialize_w32_display ();
2514 3271
@@ -3139,6 +3896,10 @@ bigger, or it may make it blink, or it may do nothing at all. */);
3139 defsubr (&Scontrolling_tty_p); 3896 defsubr (&Scontrolling_tty_p);
3140 defsubr (&Ssuspend_tty); 3897 defsubr (&Ssuspend_tty);
3141 defsubr (&Sresume_tty); 3898 defsubr (&Sresume_tty);
3899#ifdef HAVE_GPM
3900 defsubr (&Sterm_open_connection);
3901 defsubr (&Sterm_close_connection);
3902#endif /* HAVE_GPM */
3142} 3903}
3143 3904
3144 3905
diff --git a/src/termhooks.h b/src/termhooks.h
index e9fcbb37750..373d1e34987 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -191,7 +191,11 @@ enum event_kind
191 symbols, respectively. Member `arg' is a Lisp object converted 191 symbols, respectively. Member `arg' is a Lisp object converted
192 from the received Apple event. Parameters for non-Apple events 192 from the received Apple event. Parameters for non-Apple events
193 are converted to those in Apple events. */ 193 are converted to those in Apple events. */
194 MAC_APPLE_EVENT 194 MAC_APPLE_EVENT,
195#endif
196
197#ifdef HAVE_GPM
198 GPM_CLICK_EVENT
195#endif 199#endif
196}; 200};
197 201
@@ -290,6 +294,17 @@ enum {
290 meta_modifier = CHAR_META /* Under X, the XK_Meta_[LR] keysyms. */ 294 meta_modifier = CHAR_META /* Under X, the XK_Meta_[LR] keysyms. */
291}; 295};
292 296
297#ifdef HAVE_GPM
298#include <gpm.h>
299extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *, struct input_event *);
300
301/* Nonzero means mouse is enabled on Linux console */
302extern int term_gpm;
303
304/* The id of the terminal device for which we have gpm support. */
305extern int gpm_tty;
306#endif
307
293#endif /* CONSP */ 308#endif /* CONSP */
294 309
295 310
diff --git a/src/xdisp.c b/src/xdisp.c
index da2c0e7c7a0..8459be7abb7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12786,7 +12786,7 @@ redisplay_window (window, just_this_one_p)
12786 int rc; 12786 int rc;
12787 int centering_position = -1; 12787 int centering_position = -1;
12788 int last_line_misfit = 0; 12788 int last_line_misfit = 0;
12789 int save_beg_unchanged, save_end_unchanged; 12789 int beg_unchanged, end_unchanged;
12790 12790
12791 SET_TEXT_POS (lpoint, PT, PT_BYTE); 12791 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12792 opoint = lpoint; 12792 opoint = lpoint;
@@ -12851,8 +12851,8 @@ redisplay_window (window, just_this_one_p)
12851 set_buffer_internal_1 (XBUFFER (w->buffer)); 12851 set_buffer_internal_1 (XBUFFER (w->buffer));
12852 SET_TEXT_POS (opoint, PT, PT_BYTE); 12852 SET_TEXT_POS (opoint, PT, PT_BYTE);
12853 12853
12854 save_beg_unchanged = BEG_UNCHANGED; 12854 beg_unchanged = BEG_UNCHANGED;
12855 save_end_unchanged = END_UNCHANGED; 12855 end_unchanged = END_UNCHANGED;
12856 12856
12857 current_matrix_up_to_date_p 12857 current_matrix_up_to_date_p
12858 = (!NILP (w->window_end_valid) 12858 = (!NILP (w->window_end_valid)
@@ -12977,6 +12977,8 @@ redisplay_window (window, just_this_one_p)
12977 w->force_start = Qt; 12977 w->force_start = Qt;
12978 } 12978 }
12979 12979
12980 force_start:
12981
12980 /* Handle case where place to start displaying has been specified, 12982 /* Handle case where place to start displaying has been specified,
12981 unless the specified location is outside the accessible range. */ 12983 unless the specified location is outside the accessible range. */
12982 if (!NILP (w->force_start) 12984 if (!NILP (w->force_start)
@@ -13156,40 +13158,16 @@ redisplay_window (window, just_this_one_p)
13156 than a simple mouse-click. */ 13158 than a simple mouse-click. */
13157 if (NILP (w->start_at_line_beg) 13159 if (NILP (w->start_at_line_beg)
13158 && NILP (do_mouse_tracking) 13160 && NILP (do_mouse_tracking)
13159 && CHARPOS (startp) > BEGV) 13161 && CHARPOS (startp) > BEGV
13162 && CHARPOS (startp) > BEG + beg_unchanged
13163 && CHARPOS (startp) <= Z - end_unchanged)
13160 { 13164 {
13161#if 0 13165 w->force_start = Qt;
13162 /* The following code tried to make BEG_UNCHANGED and 13166 if (XMARKER (w->start)->buffer == current_buffer)
13163 END_UNCHANGED up to date (similar to try_window_id). 13167 compute_window_start_on_continuation_line (w);
13164 Is it important to do so? 13168 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13165 13169 goto force_start;
13166 The trouble is that it's a little too strict when it 13170 }
13167 comes to overlays: modify_overlay can call
13168 BUF_COMPUTE_UNCHANGED, which alters BUF_BEG_UNCHANGED and
13169 BUF_END_UNCHANGED directly without moving the gap.
13170
13171 This can result in spurious recentering when overlays are
13172 altered in the buffer. So unless it's proven necessary,
13173 let's leave this commented out for now. -- cyd. */
13174 if (MODIFF > SAVE_MODIFF
13175 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13176 {
13177 if (GPT - BEG < BEG_UNCHANGED)
13178 BEG_UNCHANGED = GPT - BEG;
13179 if (Z - GPT < END_UNCHANGED)
13180 END_UNCHANGED = Z - GPT;
13181 }
13182#endif
13183
13184 if (CHARPOS (startp) > BEG + save_beg_unchanged
13185 && CHARPOS (startp) <= Z - save_end_unchanged)
13186 {
13187 /* There doesn't seems to be a simple way to find a new
13188 window start that is near the old window start, so
13189 we just recenter. */
13190 goto recenter;
13191 }
13192 }
13193 13171
13194#if GLYPH_DEBUG 13172#if GLYPH_DEBUG
13195 debug_method_add (w, "same window start"); 13173 debug_method_add (w, "same window start");