aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/ChangeLog108
-rw-r--r--src/Makefile.in11
-rw-r--r--src/config.in3
-rw-r--r--src/image.c52
-rw-r--r--src/keyboard.c112
-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.c20
-rw-r--r--src/process.c53
-rw-r--r--src/syntax.c14
-rw-r--r--src/sysdep.c8
-rw-r--r--src/term.c770
-rw-r--r--src/termhooks.h14
-rw-r--r--src/xdisp.c50
-rw-r--r--src/xterm.c4
16 files changed, 1131 insertions, 98 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d8d0894e2ca..54970e7ecf3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,111 @@
12007-05-24 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2
3 * macterm.c [USE_CARBON_EVENTS] (mac_handle_window_event):
4 Call mac_wakeup_from_rne on window size change.
5
62007-05-23 Johannes Weiner <hannes@saeurebad.de> (tiny change)
7
8 * keyboard.c (make_lispy_movement): Condition on HAVE_GPM too.
9
102007-05-22 Richard Stallman <rms@gnu.org>
11
12 * xterm.c (x_connection_closed): Remove NO_RETURN.
13
142007-05-22 Martin Rudalics <rudalics@gmx.at>
15
16 * syntax.c (scan_words): Fix arg to UPDATE_SYNTAX_TABLE_BACKWARD.
17
182007-05-21 Chong Yidong <cyd@stupidchicken.com>
19
20 * image.c (uncache_image): New function.
21 (Fimage_refresh): New function.
22
232007-05-20 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
24
25 * Makefile.in: Move GPM check outside HAVE_X_WINDOWS.
26
272007-05-20 Nick Roberts <nickrob@snap.net.nz>
28
29 * config.in, keyboard.c, Makefile.in, sysdep.c, term.c,
30 * termhooks.h: Use HAVE_GPM instead of HAVE_GPM_H.
31
322007-05-20 Nick Roberts <nickrob@snap.net.nz>
33
34 * keyboard.c (make_lispy_event): Make case GPM_CLICK_EVENT
35 conditional on [HAVE_GPM_H].
36
372007-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
38
39 * syntax.c (skip_chars): Update syntax-table only after we checked that
40 the new location is valid.
41
422007-05-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
43
44 * macterm.c (x_calc_absolute_position): Add BLOCK_INPUT around
45 mac_get_window_bounds.
46
472007-05-20 Nick Roberts <nickrob@snap.net.nz>
48
49 * Makefile.in (LIBGPM): Allow it to be set from configure.
50 If set then link Emacs with it.
51
52 * config.in: Regenerate.
53
54 * lisp.h (add_gpm_wait_descriptor, delete_gpm_wait_descriptor):
55 New externs.
56
57 * termhooks.h [HAVE_GPM_H] (enum event_kind): Add GPM_CLICK_EVENT.
58 Include gpm.h.
59 (handle_one_term_event, term_gpm) New externs.
60
61 * sysdep.c [HAVE_GPM_H] (init_sys_modes): Make gpm_fd nonblocking
62 and allow it to be interrupted by SIGIO.
63
64 * process.c (gpm_wait_mask, max_gpm_desc): New variables.
65 (wait_reading_process_output): Wait on gpm_fd too.
66 (add_gpm_wait_descriptor, delete_gpm_wait_descriptor)): New functions.
67 (add_gpm_wait_descriptor_called_flag): New variable.
68 (delete_keyboard_wait_descriptor): Check gpm_wait_mask.
69
70 * keyboard.c [HAVE_GPM_H] (Qmouse_fixup_help_message)
71 (make_lispy_movement, tracking_off, Ftrack_mouse, some_mouse_moved)
72 (show_help_echo, readable_events, kbd_buffer_get_event, init_keyboard):
73 Extend HAVE_MOUSE ifdefs to HAVE_GPM_H.
74 (make_lispy_event): Add case GPM_CLICK_EVENT.
75 (read_avail_input): Handle mouse input.
76
77 * term.c (write_glyphs_with_face): New function.
78 [HAVE_GPM_H]: Include buffer.h, sys/fcntl.h.
79 (mouse_face_beg_row, mouse_face_beg_col, mouse_face_end_row)
80 (mouse_face_end_col, mouse_face_past_end, mouse_face_window)
81 (mouse_face_face_id, term_gpm, pos_x, pos_y)
82 (last_mouse_x, last_mouse_y): New variables.
83 (term_show_mouse_face, term_clear_mouse_face, fast_find_position)
84 (term_mouse_highlight, term_mouse_movement, term_mouse_position)
85 (term_mouse_click, handle_one_term_event, Fterm_open_connection)
86 (Fterm_close_connection): New functions.
87 (term_init): Initialise mouse_face_window.
88
892007-05-19 Chong Yidong <cyd@stupidchicken.com>
90
91 * xdisp.c (redisplay_window): If first window line is a
92 continuation line, recompute the new window start instead of
93 recentering.
94
952007-05-18 Glenn Morris <rgm@gnu.org>
96
97 * m/alpha.h (ORDINARY_LINK): No longer define on OpenBSD.
98 Suggested by Alfred M. Szmidt <ams@gnu.org>.
99
1002007-05-17 Glenn Morris <rgm@gnu.org>
101
102 * m/macppc.h (ORDINARY_LINK): No longer define on OpenBSD.
103
1042007-05-16 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
105
106 * macterm.c [USE_CARBON_EVENTS] (mac_convert_event_ref): Also convert
107 dead key repeat and up events.
108
12007-05-14 Chong Yidong <cyd@stupidchicken.com> 1092007-05-14 Chong Yidong <cyd@stupidchicken.com>
2 110
3 * image.c (pbm_load): Check image size for monochrome pbm. 111 * image.c (pbm_load): Check image size for monochrome pbm.
diff --git a/src/Makefile.in b/src/Makefile.in
index f62bb8c2b26..f0733a7c125 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -458,6 +458,15 @@ LIBX= $(LIBXMENU) LD_SWITCH_X_SITE -lX10 LIBX10_MACHINE LIBX10_SYSTEM
458#else /* not HAVE_X_WINDOWS */ 458#else /* not HAVE_X_WINDOWS */
459#endif /* not HAVE_X_WINDOWS */ 459#endif /* not HAVE_X_WINDOWS */
460 460
461#if HAVE_GPM
462#ifndef LIBGPM
463#define LIBGPM -lgpm
464#endif /* not defined LIBGPM */
465#else /* not HAVE_GPM */
466#define LIBGPM
467#endif /* not HAVE_GPM */
468
469
461LIBSOUND= @LIBSOUND@ 470LIBSOUND= @LIBSOUND@
462CFLAGS_SOUND= @CFLAGS_SOUND@ 471CFLAGS_SOUND= @CFLAGS_SOUND@
463 472
@@ -934,7 +943,7 @@ SOME_MACHINE_LISP = ${dotdot}/lisp/mouse.elc \
934 Note that SunOS needs -lm to come before -lc; otherwise, you get 943 Note that SunOS needs -lm to come before -lc; otherwise, you get
935 duplicated symbols. If the standard libraries were compiled 944 duplicated symbols. If the standard libraries were compiled
936 with GCC, we might need gnulib again after them. */ 945 with GCC, we might need gnulib again after them. */
937LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) \ 946LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) LIBGPM \
938 LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ 947 LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
939 LIBS_DEBUG $(GETLOADAVG_LIBS) \ 948 LIBS_DEBUG $(GETLOADAVG_LIBS) \
940 @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ \ 949 @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ \
diff --git a/src/config.in b/src/config.in
index e4535b605cd..136565ab928 100644
--- a/src/config.in
+++ b/src/config.in
@@ -234,6 +234,9 @@ Boston, MA 02110-1301, USA. */
234/* Define to 1 if you have the ungif library (-lungif). */ 234/* Define to 1 if you have the ungif library (-lungif). */
235#undef HAVE_GIF 235#undef HAVE_GIF
236 236
237/* Define to 1 if you have the gpm library (-lgpm). */
238#undef HAVE_GPM
239
237/* Define to 1 if you have the `grantpt' function. */ 240/* Define to 1 if you have the `grantpt' function. */
238#undef HAVE_GRANTPT 241#undef HAVE_GRANTPT
239 242
diff --git a/src/image.c b/src/image.c
index 12b27fe359f..6858675d9e4 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1631,6 +1631,27 @@ make_image_cache ()
1631} 1631}
1632 1632
1633 1633
1634/* Search frame F for an images with spec SPEC, and free it. */
1635
1636static void
1637uncache_image (f, spec)
1638 struct frame *f;
1639 Lisp_Object spec;
1640{
1641 struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1642 struct image *img = IMAGE_FROM_ID (f, lookup_image (f, spec));
1643 unsigned hash = sxhash (spec, 0);
1644 int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1645
1646 for (img = c->buckets[i]; img; img = img->next)
1647 if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
1648 {
1649 free_image (f, img);
1650 break;
1651 }
1652}
1653
1654
1634/* Free image cache of frame F. Be aware that X frames share images 1655/* Free image cache of frame F. Be aware that X frames share images
1635 caches. */ 1656 caches. */
1636 1657
@@ -1741,6 +1762,36 @@ FRAME t means clear the image caches of all frames. */)
1741} 1762}
1742 1763
1743 1764
1765DEFUN ("image-refresh", Fimage_refresh, Simage_refresh,
1766 1, 2, 0,
1767 doc: /* Refresh the image with specification SPEC on frame FRAME.
1768If SPEC specifies an image file, the displayed image is updated with
1769the current contents of that file.
1770FRAME nil or omitted means use the selected frame.
1771FRAME t means refresh the image on all frames. */)
1772 (spec, frame)
1773 Lisp_Object spec, frame;
1774{
1775 if (!valid_image_p (spec))
1776 error ("Invalid image specification");
1777
1778 if (EQ (frame, Qt))
1779 {
1780 Lisp_Object tail;
1781 FOR_EACH_FRAME (tail, frame)
1782 {
1783 struct frame *f = XFRAME (frame);
1784 if (FRAME_WINDOW_P (f))
1785 uncache_image (f, spec);
1786 }
1787 }
1788 else
1789 uncache_image (check_x_frame (frame), spec);
1790
1791 return Qnil;
1792}
1793
1794
1744/* Compute masks and transform image IMG on frame F, as specified 1795/* Compute masks and transform image IMG on frame F, as specified
1745 by the image's specification, */ 1796 by the image's specification, */
1746 1797
@@ -8660,6 +8711,7 @@ non-numeric, there is no explicit limit on the size of images. */);
8660 8711
8661 defsubr (&Sinit_image_library); 8712 defsubr (&Sinit_image_library);
8662 defsubr (&Sclear_image_cache); 8713 defsubr (&Sclear_image_cache);
8714 defsubr (&Simage_refresh);
8663 defsubr (&Simage_size); 8715 defsubr (&Simage_size);
8664 defsubr (&Simage_mask_p); 8716 defsubr (&Simage_mask_p);
8665 defsubr (&Simage_extension_data); 8717 defsubr (&Simage_extension_data);
diff --git a/src/keyboard.c b/src/keyboard.c
index 0d091e07cf0..bcc4a5fd655 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -521,7 +521,7 @@ Lisp_Object Qmake_frame_visible;
521Lisp_Object Qselect_window; 521Lisp_Object Qselect_window;
522Lisp_Object Qhelp_echo; 522Lisp_Object Qhelp_echo;
523 523
524#ifdef HAVE_MOUSE 524#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
525Lisp_Object Qmouse_fixup_help_message; 525Lisp_Object Qmouse_fixup_help_message;
526#endif 526#endif
527 527
@@ -677,7 +677,7 @@ static Lisp_Object read_char_x_menu_prompt ();
677static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int, 677static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int,
678 Lisp_Object *)); 678 Lisp_Object *));
679static Lisp_Object make_lispy_event P_ ((struct input_event *)); 679static Lisp_Object make_lispy_event P_ ((struct input_event *));
680#ifdef HAVE_MOUSE 680#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
681static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object, 681static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object,
682 enum scroll_bar_part, 682 enum scroll_bar_part,
683 Lisp_Object, Lisp_Object, 683 Lisp_Object, Lisp_Object,
@@ -1390,7 +1390,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
1390 return Qnil; 1390 return Qnil;
1391} 1391}
1392 1392
1393#ifdef HAVE_MOUSE 1393#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1394 1394
1395/* Restore mouse tracking enablement. See Ftrack_mouse for the only use 1395/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
1396 of this function. */ 1396 of this function. */
@@ -1466,7 +1466,7 @@ some_mouse_moved ()
1466 return 0; 1466 return 0;
1467} 1467}
1468 1468
1469#endif /* HAVE_MOUSE */ 1469#endif /* HAVE_MOUSE || HAVE_GPM */
1470 1470
1471/* This is the actual command reading loop, 1471/* This is the actual command reading loop,
1472 sans error-handling encapsulation. */ 1472 sans error-handling encapsulation. */
@@ -2388,7 +2388,7 @@ show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo)
2388 return; 2388 return;
2389 } 2389 }
2390 2390
2391#ifdef HAVE_MOUSE 2391#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
2392 if (!noninteractive && STRINGP (help)) 2392 if (!noninteractive && STRINGP (help))
2393 { 2393 {
2394 /* The mouse-fixup-help-message Lisp function can call 2394 /* The mouse-fixup-help-message Lisp function can call
@@ -3640,7 +3640,7 @@ readable_events (flags)
3640 return 1; 3640 return 1;
3641 } 3641 }
3642 3642
3643#ifdef HAVE_MOUSE 3643#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
3644 if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) 3644 if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
3645 && !NILP (do_mouse_tracking) && some_mouse_moved ()) 3645 && !NILP (do_mouse_tracking) && some_mouse_moved ())
3646 return 1; 3646 return 1;
@@ -3992,7 +3992,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
3992 { 3992 {
3993 if (kbd_fetch_ptr != kbd_store_ptr) 3993 if (kbd_fetch_ptr != kbd_store_ptr)
3994 break; 3994 break;
3995#ifdef HAVE_MOUSE 3995#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
3996 if (!NILP (do_mouse_tracking) && some_mouse_moved ()) 3996 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
3997 break; 3997 break;
3998#endif 3998#endif
@@ -4014,7 +4014,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4014#endif /* SIGIO */ 4014#endif /* SIGIO */
4015 if (kbd_fetch_ptr != kbd_store_ptr) 4015 if (kbd_fetch_ptr != kbd_store_ptr)
4016 break; 4016 break;
4017#ifdef HAVE_MOUSE 4017#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
4018 if (!NILP (do_mouse_tracking) && some_mouse_moved ()) 4018 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
4019 break; 4019 break;
4020#endif 4020#endif
@@ -4250,7 +4250,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4250 } 4250 }
4251 } 4251 }
4252 } 4252 }
4253#ifdef HAVE_MOUSE 4253#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
4254 /* Try generating a mouse motion event. */ 4254 /* Try generating a mouse motion event. */
4255 else if (!NILP (do_mouse_tracking) && some_mouse_moved ()) 4255 else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
4256 { 4256 {
@@ -4291,7 +4291,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4291 if (!NILP (x) && NILP (obj)) 4291 if (!NILP (x) && NILP (obj))
4292 obj = make_lispy_movement (f, bar_window, part, x, y, time); 4292 obj = make_lispy_movement (f, bar_window, part, x, y, time);
4293 } 4293 }
4294#endif /* HAVE_MOUSE */ 4294#endif /* HAVE_MOUSE || HAVE GPM */
4295 else 4295 else
4296 /* We were promised by the above while loop that there was 4296 /* We were promised by the above while loop that there was
4297 something for us to read! */ 4297 something for us to read! */
@@ -6008,13 +6008,73 @@ make_lispy_event (event)
6008 } 6008 }
6009#endif 6009#endif
6010 6010
6011#ifdef HAVE_GPM
6012 case GPM_CLICK_EVENT:
6013 {
6014 FRAME_PTR f = XFRAME (event->frame_or_window);
6015 Lisp_Object head, position;
6016 Lisp_Object *start_pos_ptr;
6017 Lisp_Object start_pos;
6018 int button = event->code;
6019
6020 if (button >= ASIZE (button_down_location))
6021 {
6022 button_down_location = larger_vector (button_down_location,
6023 button + 1, Qnil);
6024 mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
6025 }
6026
6027 start_pos_ptr = &AREF (button_down_location, button);
6028 start_pos = *start_pos_ptr;
6029
6030 position = make_lispy_position (f, &event->x, &event->y,
6031 event->timestamp);
6032
6033 if (event->modifiers & down_modifier)
6034 *start_pos_ptr = Fcopy_alist (position);
6035 else if (event->modifiers & (up_modifier | drag_modifier))
6036 {
6037 if (!CONSP (start_pos))
6038 return Qnil;
6039 event->modifiers &= ~up_modifier;
6040 }
6041
6042 head = modify_event_symbol (button,
6043 event->modifiers,
6044 Qmouse_click, Vlispy_mouse_stem,
6045 NULL,
6046 &mouse_syms,
6047 XVECTOR (mouse_syms)->size);
6048
6049 if (event->modifiers & drag_modifier)
6050 return Fcons (head,
6051 Fcons (start_pos,
6052 Fcons (position,
6053 Qnil)));
6054 else if (event->modifiers & double_modifier)
6055 return Fcons (head,
6056 Fcons (position,
6057 Fcons (make_number (2),
6058 Qnil)));
6059 else if (event->modifiers & triple_modifier)
6060 return Fcons (head,
6061 Fcons (position,
6062 Fcons (make_number (3),
6063 Qnil)));
6064 else
6065 return Fcons (head,
6066 Fcons (position,
6067 Qnil));
6068 }
6069#endif /* HAVE_GPM */
6070
6011 /* The 'kind' field of the event is something we don't recognize. */ 6071 /* The 'kind' field of the event is something we don't recognize. */
6012 default: 6072 default:
6013 abort (); 6073 abort ();
6014 } 6074 }
6015} 6075}
6016 6076
6017#ifdef HAVE_MOUSE 6077#if defined(HAVE_MOUSE) || defined(HAVE_GPM)
6018 6078
6019static Lisp_Object 6079static Lisp_Object
6020make_lispy_movement (frame, bar_window, part, x, y, time) 6080make_lispy_movement (frame, bar_window, part, x, y, time)
@@ -6053,7 +6113,7 @@ make_lispy_movement (frame, bar_window, part, x, y, time)
6053 } 6113 }
6054} 6114}
6055 6115
6056#endif /* HAVE_MOUSE */ 6116#endif /* HAVE_MOUSE || HAVE GPM */
6057 6117
6058/* Construct a switch frame event. */ 6118/* Construct a switch frame event. */
6059static Lisp_Object 6119static Lisp_Object
@@ -6865,8 +6925,28 @@ read_avail_input (expected)
6865 if (n_to_read == 0) 6925 if (n_to_read == 0)
6866 return 0; 6926 return 0;
6867#else /* not MSDOS */ 6927#else /* not MSDOS */
6928#ifdef HAVE_GPM
6929 if (term_gpm)
6930 {
6931 Gpm_Event event;
6932 struct input_event hold_quit;
6933 int gpm;
6934
6935 EVENT_INIT (hold_quit);
6936 hold_quit.kind = NO_EVENT;
6937
6938 while (gpm = Gpm_GetEvent (&event), gpm == 1) {
6939 nread += handle_one_term_event (&event, &hold_quit);
6940 }
6941 if (hold_quit.kind != NO_EVENT)
6942 kbd_buffer_store_event (&hold_quit);
6943 if (nread)
6944 return nread;
6945 }
6946#endif /* HAVE_GPM */
6868#ifdef FIONREAD 6947#ifdef FIONREAD
6869 /* Find out how much input is available. */ 6948
6949 /* Find out how much input is available. */
6870 if (ioctl (input_fd, FIONREAD, &n_to_read) < 0) 6950 if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
6871 /* Formerly simply reported no input, but that sometimes led to 6951 /* Formerly simply reported no input, but that sometimes led to
6872 a failure of Emacs to terminate. 6952 a failure of Emacs to terminate.
@@ -11044,7 +11124,7 @@ init_keyboard ()
11044 recent_keys_index = 0; 11124 recent_keys_index = 0;
11045 kbd_fetch_ptr = kbd_buffer; 11125 kbd_fetch_ptr = kbd_buffer;
11046 kbd_store_ptr = kbd_buffer; 11126 kbd_store_ptr = kbd_buffer;
11047#ifdef HAVE_MOUSE 11127#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
11048 do_mouse_tracking = Qnil; 11128 do_mouse_tracking = Qnil;
11049#endif 11129#endif
11050 input_pending = 0; 11130 input_pending = 0;
@@ -11234,7 +11314,7 @@ syms_of_keyboard ()
11234 Qmenu_bar = intern ("menu-bar"); 11314 Qmenu_bar = intern ("menu-bar");
11235 staticpro (&Qmenu_bar); 11315 staticpro (&Qmenu_bar);
11236 11316
11237#ifdef HAVE_MOUSE 11317#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
11238 Qmouse_fixup_help_message = intern ("mouse-fixup-help-message"); 11318 Qmouse_fixup_help_message = intern ("mouse-fixup-help-message");
11239 staticpro (&Qmouse_fixup_help_message); 11319 staticpro (&Qmouse_fixup_help_message);
11240#endif 11320#endif
@@ -11366,7 +11446,7 @@ syms_of_keyboard ()
11366 defsubr (&Sread_key_sequence); 11446 defsubr (&Sread_key_sequence);
11367 defsubr (&Sread_key_sequence_vector); 11447 defsubr (&Sread_key_sequence_vector);
11368 defsubr (&Srecursive_edit); 11448 defsubr (&Srecursive_edit);
11369#ifdef HAVE_MOUSE 11449#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
11370 defsubr (&Strack_mouse); 11450 defsubr (&Strack_mouse);
11371#endif 11451#endif
11372 defsubr (&Sinput_pending_p); 11452 defsubr (&Sinput_pending_p);
diff --git a/src/lisp.h b/src/lisp.h
index 850e15ec2c4..407c59e0c63 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3134,6 +3134,8 @@ extern int wait_reading_process_output P_ ((int, int, int, int,
3134 int)); 3134 int));
3135extern void add_keyboard_wait_descriptor P_ ((int)); 3135extern void add_keyboard_wait_descriptor P_ ((int));
3136extern void delete_keyboard_wait_descriptor P_ ((int)); 3136extern void delete_keyboard_wait_descriptor P_ ((int));
3137extern void add_gpm_wait_descriptor P_ ((int));
3138extern void delete_gpm_wait_descriptor P_ ((int));
3137extern void close_process_descs P_ ((void)); 3139extern void close_process_descs P_ ((void));
3138extern void init_process P_ ((void)); 3140extern void init_process P_ ((void));
3139extern void syms_of_process P_ ((void)); 3141extern 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 df0275fe22b..f7b375c22da 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -6103,7 +6103,9 @@ x_calc_absolute_position (f)
6103 6103
6104 /* Find the offsets of the outside upper-left corner of 6104 /* Find the offsets of the outside upper-left corner of
6105 the inner window, with respect to the outer window. */ 6105 the inner window, with respect to the outer window. */
6106 BLOCK_INPUT;
6106 mac_get_window_bounds (f, &inner, &outer); 6107 mac_get_window_bounds (f, &inner, &outer);
6108 UNBLOCK_INPUT;
6107 6109
6108 width_diff = (outer.right - outer.left) - (inner.right - inner.left); 6110 width_diff = (outer.right - outer.left) - (inner.right - inner.left);
6109 height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top); 6111 height_diff = (outer.bottom - outer.top) - (inner.bottom - inner.top);
@@ -9185,15 +9187,16 @@ mac_get_mouse_btn (EventRef ref)
9185 9187
9186/* Normally, ConvertEventRefToEventRecord will correctly handle all 9188/* Normally, ConvertEventRefToEventRecord will correctly handle all
9187 events. However the click of the mouse wheel is not converted to a 9189 events. However the click of the mouse wheel is not converted to a
9188 mouseDown or mouseUp event. Likewise for dead key down events. 9190 mouseDown or mouseUp event. Likewise for dead key events. This
9189 This calls ConvertEventRef, but then checks to see if it is a mouse 9191 calls ConvertEventRefToEventRecord, but then checks to see if it is
9190 up/down, or a dead key down carbon event that has not been 9192 a mouse up/down, or a dead key Carbon event that has not been
9191 converted, and if so, converts it by hand (to be picked up in the 9193 converted, and if so, converts it by hand (to be picked up in the
9192 XTread_socket loop). */ 9194 XTread_socket loop). */
9193static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) 9195static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
9194{ 9196{
9195 OSStatus err; 9197 OSStatus err;
9196 Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec); 9198 Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
9199 EventKind action;
9197 9200
9198 if (result) 9201 if (result)
9199 return result; 9202 return result;
@@ -9222,6 +9225,14 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
9222 switch (GetEventKind (eventRef)) 9225 switch (GetEventKind (eventRef))
9223 { 9226 {
9224 case kEventRawKeyDown: 9227 case kEventRawKeyDown:
9228 action = keyDown;
9229 goto keystroke_common;
9230 case kEventRawKeyRepeat:
9231 action = autoKey;
9232 goto keystroke_common;
9233 case kEventRawKeyUp:
9234 action = keyUp;
9235 keystroke_common:
9225 { 9236 {
9226 unsigned char char_codes; 9237 unsigned char char_codes;
9227 UInt32 key_code; 9238 UInt32 key_code;
@@ -9235,7 +9246,7 @@ static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
9235 NULL, &key_code); 9246 NULL, &key_code);
9236 if (err == noErr) 9247 if (err == noErr)
9237 { 9248 {
9238 eventRec->what = keyDown; 9249 eventRec->what = action;
9239 eventRec->message = char_codes | ((key_code & 0xff) << 8); 9250 eventRec->message = char_codes | ((key_code & 0xff) << 8);
9240 result = 1; 9251 result = 1;
9241 } 9252 }
@@ -9903,6 +9914,7 @@ mac_handle_window_event (next_handler, event, data)
9903 width = bounds.right - bounds.left; 9914 width = bounds.right - bounds.left;
9904 height = bounds.bottom - bounds.top; 9915 height = bounds.bottom - bounds.top;
9905 mac_handle_size_change (f, width, height); 9916 mac_handle_size_change (f, width, height);
9917 mac_wakeup_from_rne ();
9906 } 9918 }
9907 } 9919 }
9908 9920
diff --git a/src/process.c b/src/process.c
index 567aae7c08f..be88ba25123 100644
--- a/src/process.c
+++ b/src/process.c
@@ -328,14 +328,18 @@ extern int timers_run;
328 328
329static SELECT_TYPE input_wait_mask; 329static SELECT_TYPE input_wait_mask;
330 330
331/* Mask that excludes keyboard input descriptor (s). */ 331/* Mask that excludes keyboard input descriptor(s). */
332 332
333static SELECT_TYPE non_keyboard_wait_mask; 333static SELECT_TYPE non_keyboard_wait_mask;
334 334
335/* Mask that excludes process input descriptor (s). */ 335/* Mask that excludes process input descriptor(s). */
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
@@ -4445,7 +4452,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4445 IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask); 4452 IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
4446 4453
4447 EMACS_SET_SECS_USECS (timeout, 0, 0); 4454 EMACS_SET_SECS_USECS (timeout, 0, 0);
4448 if ((select (max (max_process_desc, max_keyboard_desc) + 1, 4455 if ((select (max (max (max_process_desc, max_keyboard_desc),
4456 max_gpm_desc) + 1,
4449 &Atemp, 4457 &Atemp,
4450#ifdef NON_BLOCKING_CONNECT 4458#ifdef NON_BLOCKING_CONNECT
4451 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), 4459 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
@@ -4590,7 +4598,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4590 } 4598 }
4591#endif 4599#endif
4592 4600
4593 nfds = select (max (max_process_desc, max_keyboard_desc) + 1, 4601 nfds = select (max (max (max_process_desc, max_keyboard_desc),
4602 max_gpm_desc) + 1,
4594 &Available, 4603 &Available,
4595#ifdef NON_BLOCKING_CONNECT 4604#ifdef NON_BLOCKING_CONNECT
4596 (check_connect ? &Connecting : (SELECT_TYPE *)0), 4605 (check_connect ? &Connecting : (SELECT_TYPE *)0),
@@ -6884,6 +6893,21 @@ add_keyboard_wait_descriptor (desc)
6884 max_keyboard_desc = desc; 6893 max_keyboard_desc = desc;
6885} 6894}
6886 6895
6896static int add_gpm_wait_descriptor_called_flag;
6897
6898void
6899add_gpm_wait_descriptor (desc)
6900 int desc;
6901{
6902 if (! add_gpm_wait_descriptor_called_flag)
6903 FD_CLR (0, &input_wait_mask);
6904 add_gpm_wait_descriptor_called_flag = 1;
6905 FD_SET (desc, &input_wait_mask);
6906 FD_SET (desc, &gpm_wait_mask);
6907 if (desc > max_gpm_desc)
6908 max_gpm_desc = desc;
6909}
6910
6887/* From now on, do not expect DESC to give keyboard input. */ 6911/* From now on, do not expect DESC to give keyboard input. */
6888 6912
6889void 6913void
@@ -6899,10 +6923,29 @@ delete_keyboard_wait_descriptor (desc)
6899 if (desc == max_keyboard_desc) 6923 if (desc == max_keyboard_desc)
6900 for (fd = 0; fd < lim; fd++) 6924 for (fd = 0; fd < lim; fd++)
6901 if (FD_ISSET (fd, &input_wait_mask) 6925 if (FD_ISSET (fd, &input_wait_mask)
6902 && !FD_ISSET (fd, &non_keyboard_wait_mask)) 6926 && !FD_ISSET (fd, &non_keyboard_wait_mask)
6927 && !FD_ISSET (fd, &gpm_wait_mask))
6903 max_keyboard_desc = fd; 6928 max_keyboard_desc = fd;
6904} 6929}
6905 6930
6931void
6932delete_gpm_wait_descriptor (desc)
6933 int desc;
6934{
6935 int fd;
6936 int lim = max_gpm_desc;
6937
6938 FD_CLR (desc, &input_wait_mask);
6939 FD_CLR (desc, &non_process_wait_mask);
6940
6941 if (desc == max_gpm_desc)
6942 for (fd = 0; fd < lim; fd++)
6943 if (FD_ISSET (fd, &input_wait_mask)
6944 && !FD_ISSET (fd, &non_keyboard_wait_mask)
6945 && !FD_ISSET (fd, &non_process_wait_mask))
6946 max_gpm_desc = fd;
6947}
6948
6906/* Return nonzero if *MASK has a bit set 6949/* Return nonzero if *MASK has a bit set
6907 that corresponds to one of the keyboard input descriptors. */ 6950 that corresponds to one of the keyboard input descriptors. */
6908 6951
diff --git a/src/syntax.c b/src/syntax.c
index a1de152fd43..f40900834a3 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1299,20 +1299,20 @@ scan_words (from, count)
1299 script = CHAR_TABLE_REF (Vchar_script_table, ch1); 1299 script = CHAR_TABLE_REF (Vchar_script_table, ch1);
1300 while (1) 1300 while (1)
1301 { 1301 {
1302 int temp_byte;
1303
1304 if (from == beg) 1302 if (from == beg)
1305 break; 1303 break;
1306 temp_byte = dec_bytepos (from_byte); 1304 DEC_BOTH (from, from_byte);
1307 UPDATE_SYNTAX_TABLE_BACKWARD (from); 1305 UPDATE_SYNTAX_TABLE_BACKWARD (from);
1308 ch0 = FETCH_CHAR_AS_MULTIBYTE (temp_byte); 1306 ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1309 code = SYNTAX (ch0); 1307 code = SYNTAX (ch0);
1310 if ((code != Sword 1308 if ((code != Sword
1311 && (! words_include_escapes 1309 && (! words_include_escapes
1312 || (code != Sescape && code != Scharquote))) 1310 || (code != Sescape && code != Scharquote)))
1313 || ! EQ (CHAR_TABLE_REF (Vchar_script_table, ch0), script)) 1311 || ! EQ (CHAR_TABLE_REF (Vchar_script_table, ch0), script))
1314 break; 1312 {
1315 DEC_BOTH (from, from_byte); 1313 INC_BOTH (from, from_byte);
1314 break;
1315 }
1316 ch1 = ch0; 1316 ch1 = ch0;
1317 } 1317 }
1318 } 1318 }
@@ -2031,13 +2031,13 @@ skip_syntaxes (forwardp, string, lim)
2031 p = GPT_ADDR; 2031 p = GPT_ADDR;
2032 stop = endp; 2032 stop = endp;
2033 } 2033 }
2034 UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
2034 prev_p = p; 2035 prev_p = p;
2035 while (--p >= stop && ! CHAR_HEAD_P (*p)); 2036 while (--p >= stop && ! CHAR_HEAD_P (*p));
2036 c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH); 2037 c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
2037 if (! fastmap[(int) SYNTAX (c)]) 2038 if (! fastmap[(int) SYNTAX (c)])
2038 break; 2039 break;
2039 pos--, pos_byte -= prev_p - p; 2040 pos--, pos_byte -= prev_p - p;
2040 UPDATE_SYNTAX_TABLE_BACKWARD (pos);
2041 } 2041 }
2042 } 2042 }
2043 else 2043 else
diff --git a/src/sysdep.c b/src/sysdep.c
index 27e90349cb6..202cab4abd2 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1675,6 +1675,14 @@ init_sys_modes ()
1675 old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0); 1675 old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
1676 fcntl (input_fd, F_SETOWN, getpid ()); 1676 fcntl (input_fd, F_SETOWN, getpid ());
1677 init_sigio (input_fd); 1677 init_sigio (input_fd);
1678#ifdef HAVE_GPM
1679 if (term_gpm)
1680 {
1681 fcntl (gpm_fd, F_SETOWN, getpid ());
1682 fcntl (gpm_fd, F_SETFL, O_NONBLOCK);
1683 init_sigio (gpm_fd);
1684 }
1685#endif /* HAVE_GPM */
1678 } 1686 }
1679#endif /* F_GETOWN */ 1687#endif /* F_GETOWN */
1680#endif /* F_SETOWN_BUG */ 1688#endif /* F_SETOWN_BUG */
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}
diff --git a/src/termhooks.h b/src/termhooks.h
index 8aef23bc2a7..1e9968530e8 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -340,7 +340,11 @@ enum event_kind
340 symbols, respectively. Member `arg' is a Lisp object converted 340 symbols, respectively. Member `arg' is a Lisp object converted
341 from the received Apple event. Parameters for non-Apple events 341 from the received Apple event. Parameters for non-Apple events
342 are converted to those in Apple events. */ 342 are converted to those in Apple events. */
343 MAC_APPLE_EVENT 343 MAC_APPLE_EVENT,
344#endif
345
346#ifdef HAVE_GPM
347 GPM_CLICK_EVENT
344#endif 348#endif
345}; 349};
346 350
@@ -446,6 +450,14 @@ enum {
446 meta_modifier = CHAR_META /* Under X, the XK_Meta_[LR] keysyms. */ 450 meta_modifier = CHAR_META /* Under X, the XK_Meta_[LR] keysyms. */
447}; 451};
448 452
453#ifdef HAVE_GPM
454#include <gpm.h>
455extern int handle_one_term_event (Gpm_Event *, struct input_event *);
456
457/* Nonzero means mouse is enabled on Linux console */
458extern int term_gpm;
459#endif
460
449#endif 461#endif
450 462
451/* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d 463/* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d
diff --git a/src/xdisp.c b/src/xdisp.c
index dae45042685..48e894afcec 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12926,7 +12926,7 @@ redisplay_window (window, just_this_one_p)
12926 int rc; 12926 int rc;
12927 int centering_position = -1; 12927 int centering_position = -1;
12928 int last_line_misfit = 0; 12928 int last_line_misfit = 0;
12929 int save_beg_unchanged, save_end_unchanged; 12929 int beg_unchanged, end_unchanged;
12930 12930
12931 SET_TEXT_POS (lpoint, PT, PT_BYTE); 12931 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12932 opoint = lpoint; 12932 opoint = lpoint;
@@ -12991,8 +12991,8 @@ redisplay_window (window, just_this_one_p)
12991 set_buffer_internal_1 (XBUFFER (w->buffer)); 12991 set_buffer_internal_1 (XBUFFER (w->buffer));
12992 SET_TEXT_POS (opoint, PT, PT_BYTE); 12992 SET_TEXT_POS (opoint, PT, PT_BYTE);
12993 12993
12994 save_beg_unchanged = BEG_UNCHANGED; 12994 beg_unchanged = BEG_UNCHANGED;
12995 save_end_unchanged = END_UNCHANGED; 12995 end_unchanged = END_UNCHANGED;
12996 12996
12997 current_matrix_up_to_date_p 12997 current_matrix_up_to_date_p
12998 = (!NILP (w->window_end_valid) 12998 = (!NILP (w->window_end_valid)
@@ -13117,6 +13117,8 @@ redisplay_window (window, just_this_one_p)
13117 w->force_start = Qt; 13117 w->force_start = Qt;
13118 } 13118 }
13119 13119
13120 force_start:
13121
13120 /* Handle case where place to start displaying has been specified, 13122 /* Handle case where place to start displaying has been specified,
13121 unless the specified location is outside the accessible range. */ 13123 unless the specified location is outside the accessible range. */
13122 if (!NILP (w->force_start) 13124 if (!NILP (w->force_start)
@@ -13296,40 +13298,16 @@ redisplay_window (window, just_this_one_p)
13296 than a simple mouse-click. */ 13298 than a simple mouse-click. */
13297 if (NILP (w->start_at_line_beg) 13299 if (NILP (w->start_at_line_beg)
13298 && NILP (do_mouse_tracking) 13300 && NILP (do_mouse_tracking)
13299 && CHARPOS (startp) > BEGV) 13301 && CHARPOS (startp) > BEGV
13302 && CHARPOS (startp) > BEG + beg_unchanged
13303 && CHARPOS (startp) <= Z - end_unchanged)
13300 { 13304 {
13301#if 0 13305 w->force_start = Qt;
13302 /* The following code tried to make BEG_UNCHANGED and 13306 if (XMARKER (w->start)->buffer == current_buffer)
13303 END_UNCHANGED up to date (similar to try_window_id). 13307 compute_window_start_on_continuation_line (w);
13304 Is it important to do so? 13308 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13305 13309 goto force_start;
13306 The trouble is that it's a little too strict when it 13310 }
13307 comes to overlays: modify_overlay can call
13308 BUF_COMPUTE_UNCHANGED, which alters BUF_BEG_UNCHANGED and
13309 BUF_END_UNCHANGED directly without moving the gap.
13310
13311 This can result in spurious recentering when overlays are
13312 altered in the buffer. So unless it's proven necessary,
13313 let's leave this commented out for now. -- cyd. */
13314 if (MODIFF > SAVE_MODIFF
13315 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13316 {
13317 if (GPT - BEG < BEG_UNCHANGED)
13318 BEG_UNCHANGED = GPT - BEG;
13319 if (Z - GPT < END_UNCHANGED)
13320 END_UNCHANGED = Z - GPT;
13321 }
13322#endif
13323
13324 if (CHARPOS (startp) > BEG + save_beg_unchanged
13325 && CHARPOS (startp) <= Z - save_end_unchanged)
13326 {
13327 /* There doesn't seems to be a simple way to find a new
13328 window start that is near the old window start, so
13329 we just recenter. */
13330 goto recenter;
13331 }
13332 }
13333 13311
13334#if GLYPH_DEBUG 13312#if GLYPH_DEBUG
13335 debug_method_add (w, "same window start"); 13313 debug_method_add (w, "same window start");
diff --git a/src/xterm.c b/src/xterm.c
index 8b33bf00e54..724bc2a596e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -371,7 +371,9 @@ static void x_check_expected_move P_ ((struct frame *, int, int));
371static void x_sync_with_move P_ ((struct frame *, int, int, int)); 371static void x_sync_with_move P_ ((struct frame *, int, int, int));
372static int handle_one_xevent P_ ((struct x_display_info *, XEvent *, 372static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
373 int *, struct input_event *)); 373 int *, struct input_event *));
374static SIGTYPE x_connection_closed P_ ((Display *, char *)) NO_RETURN; 374/* Don't declare this NO_RETURN because we want no
375 interference with debugging failing X calls. */
376static SIGTYPE x_connection_closed P_ ((Display *, char *));
375 377
376 378
377/* Flush display of frame F, or of all frames if F is null. */ 379/* Flush display of frame F, or of all frames if F is null. */