diff options
| author | Miles Bader | 2007-05-20 23:29:14 +0000 |
|---|---|---|
| committer | Miles Bader | 2007-05-20 23:29:14 +0000 |
| commit | 7be1c21aedb2f8e7b7831d494e065a31afe13146 (patch) | |
| tree | a998f949002bf05307fe6b59969e6ebfb0c88b8d /src | |
| parent | 3c28868aeb2d445830019837294e96f432456754 (diff) | |
| parent | 26114bc08f03789f30f0acca925955f2139df690 (diff) | |
| download | emacs-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/ChangeLog | 100 | ||||
| -rw-r--r-- | src/Makefile.in | 11 | ||||
| -rw-r--r-- | src/config.in | 3 | ||||
| -rw-r--r-- | src/image.c | 18 | ||||
| -rw-r--r-- | src/keyboard.c | 108 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/m/alpha.h | 4 | ||||
| -rw-r--r-- | src/m/macppc.h | 4 | ||||
| -rw-r--r-- | src/macterm.c | 19 | ||||
| -rw-r--r-- | src/process.c | 49 | ||||
| -rw-r--r-- | src/syntax.c | 2 | ||||
| -rw-r--r-- | src/sysdep.c | 8 | ||||
| -rw-r--r-- | src/term.c | 761 | ||||
| -rw-r--r-- | src/termhooks.h | 17 | ||||
| -rw-r--r-- | src/xdisp.c | 50 |
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 @@ | |||
| 1 | 2007-05-20 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * Makefile.in: Move GPM check outside HAVE_X_WINDOWS. | ||
| 4 | |||
| 5 | 2007-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 | |||
| 10 | 2007-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 | |||
| 15 | 2007-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 | |||
| 20 | 2007-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 | |||
| 25 | 2007-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 | |||
| 67 | 2007-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 | |||
| 73 | 2007-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 | |||
| 78 | 2007-05-17 Glenn Morris <rgm@gnu.org> | ||
| 79 | |||
| 80 | * m/macppc.h (ORDINARY_LINK): No longer define on OpenBSD. | ||
| 81 | |||
| 82 | 2007-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 | |||
| 87 | 2007-05-14 Chong Yidong <cyd@stupidchicken.com> | ||
| 88 | |||
| 89 | * image.c (pbm_load): Check image size for monochrome pbm. | ||
| 90 | |||
| 91 | 2007-05-13 Chong Yidong <cyd@stupidchicken.com> | ||
| 92 | |||
| 93 | * xterm.c (XTread_socket): Revert last change. | ||
| 94 | |||
| 95 | 2007-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 | |||
| 1 | 2007-05-07 Stefan Monnier <monnier@iro.umontreal.ca> | 101 | 2007-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 | |||
| 460 | LIBSOUND= @LIBSOUND@ | 469 | LIBSOUND= @LIBSOUND@ |
| 461 | CFLAGS_SOUND= @CFLAGS_SOUND@ | 470 | CFLAGS_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. */ |
| 942 | LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) \ | 951 | LIBES = $(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; | |||
| 508 | Lisp_Object Qselect_window; | 508 | Lisp_Object Qselect_window; |
| 509 | Lisp_Object Qhelp_echo; | 509 | Lisp_Object Qhelp_echo; |
| 510 | 510 | ||
| 511 | #ifdef HAVE_MOUSE | 511 | #if defined (HAVE_MOUSE) || defined (HAVE_GPM) |
| 512 | Lisp_Object Qmouse_fixup_help_message; | 512 | Lisp_Object Qmouse_fixup_help_message; |
| 513 | #endif | 513 | #endif |
| 514 | 514 | ||
| @@ -661,7 +661,7 @@ static Lisp_Object read_char_x_menu_prompt (); | |||
| 661 | static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int, | 661 | static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int, |
| 662 | Lisp_Object *)); | 662 | Lisp_Object *)); |
| 663 | static Lisp_Object make_lispy_event P_ ((struct input_event *)); | 663 | static Lisp_Object make_lispy_event P_ ((struct input_event *)); |
| 664 | #ifdef HAVE_MOUSE | 664 | #if defined (HAVE_MOUSE) || defined (HAVE_GPM) |
| 665 | static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object, | 665 | static 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)); |
| 3102 | extern void add_keyboard_wait_descriptor P_ ((int)); | 3102 | extern void add_keyboard_wait_descriptor P_ ((int)); |
| 3103 | extern void delete_keyboard_wait_descriptor P_ ((int)); | 3103 | extern void delete_keyboard_wait_descriptor P_ ((int)); |
| 3104 | extern void add_gpm_wait_descriptor P_ ((int)); | ||
| 3105 | extern void delete_gpm_wait_descriptor P_ ((int)); | ||
| 3104 | extern void close_process_descs P_ ((void)); | 3106 | extern void close_process_descs P_ ((void)); |
| 3105 | extern void init_process P_ ((void)); | 3107 | extern void init_process P_ ((void)); |
| 3106 | extern void syms_of_process P_ ((void)); | 3108 | extern 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). */ |
| 9167 | static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) | 9169 | static 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 | ||
| 337 | static SELECT_TYPE non_process_wait_mask; | 337 | static SELECT_TYPE non_process_wait_mask; |
| 338 | 338 | ||
| 339 | /* Mask for the gpm mouse input descriptor. */ | ||
| 340 | |||
| 341 | static 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. */ |
| 358 | static int max_keyboard_desc; | 362 | static int max_keyboard_desc; |
| 359 | 363 | ||
| 364 | /* The largest descriptor currently in use for gpm mouse input. */ | ||
| 365 | static 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. */ |
| 361 | static int delete_exited_processes; | 368 | static 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 | ||
| 6987 | static int add_gpm_wait_descriptor_called_flag; | ||
| 6988 | |||
| 6989 | void | ||
| 6990 | add_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 | ||
| 6980 | void | 7004 | void |
| @@ -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 | ||
| 7022 | void | ||
| 7023 | delete_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; | |||
| 171 | char *tparam (); | 171 | char *tparam (); |
| 172 | 172 | ||
| 173 | extern char *tgetstr (); | 173 | extern char *tgetstr (); |
| 174 | |||
| 175 | static void term_clear_mouse_face (); | ||
| 176 | static 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. */ | ||
| 195 | int term_gpm = 0; | ||
| 196 | |||
| 197 | /* The id of the terminal device for which we have gpm support. */ | ||
| 198 | int 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. */ | ||
| 205 | static int mouse_face_beg_row, mouse_face_beg_col; | ||
| 206 | static int mouse_face_end_row, mouse_face_end_col; | ||
| 207 | static int mouse_face_past_end; | ||
| 208 | static Lisp_Object mouse_face_window; | ||
| 209 | static 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. */ | ||
| 213 | struct frame *mouse_face_mouse_frame; | ||
| 214 | int mouse_face_mouse_x, mouse_face_mouse_y; | ||
| 215 | |||
| 216 | static int pos_x, pos_y; | ||
| 217 | static 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 | ||
| 750 | static void | ||
| 751 | tty_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 | ||
| 720 | static void | 812 | static void |
| @@ -2248,6 +2340,663 @@ the currently selected frame. */) | |||
| 2248 | 2340 | ||
| 2249 | 2341 | ||
| 2250 | /*********************************************************************** | 2342 | /*********************************************************************** |
| 2343 | Mouse | ||
| 2344 | ***********************************************************************/ | ||
| 2345 | |||
| 2346 | #ifdef HAVE_GPM | ||
| 2347 | static void | ||
| 2348 | term_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 | |||
| 2426 | static void | ||
| 2427 | term_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 */ | ||
| 2442 | static int | ||
| 2443 | fast_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 | |||
| 2512 | static void | ||
| 2513 | term_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 | |||
| 2762 | static int | ||
| 2763 | term_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. */ | ||
| 2793 | static void | ||
| 2794 | term_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 | |||
| 2824 | static Lisp_Object | ||
| 2825 | term_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 | |||
| 2884 | int | ||
| 2885 | handle_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 | |||
| 2958 | DEFUN ("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 | |||
| 2986 | DEFUN ("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> | ||
| 299 | extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *, struct input_event *); | ||
| 300 | |||
| 301 | /* Nonzero means mouse is enabled on Linux console */ | ||
| 302 | extern int term_gpm; | ||
| 303 | |||
| 304 | /* The id of the terminal device for which we have gpm support. */ | ||
| 305 | extern 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"); |