aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2004-11-19 06:55:13 +0000
committerMiles Bader2004-11-19 06:55:13 +0000
commit148396568043f50499340911c656c7234cefd50d (patch)
tree6bb3c035d0194f7e26bc8254a5189cb5a8722ce2 /src
parent77229aad98d5c81a559fb1ba5161ed2a7f13aec4 (diff)
parent6dd06769a945f59e048d8328e37a77b41f8c798f (diff)
downloademacs-148396568043f50499340911c656c7234cefd50d.tar.gz
emacs-148396568043f50499340911c656c7234cefd50d.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-72
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-693 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-695 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-696 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-697 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-702 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-703 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-704 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-708 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-72 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-73 Merge from emacs--cvs-trunk--0
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog251
-rw-r--r--src/dispextern.h43
-rw-r--r--src/fns.c32
-rw-r--r--src/frame.c3
-rw-r--r--src/fringe.c16
-rw-r--r--src/gtkutil.c227
-rw-r--r--src/indent.c47
-rw-r--r--src/keyboard.c2
-rw-r--r--src/keymap.c12
-rw-r--r--src/lisp.h3
-rw-r--r--src/minibuf.c4
-rw-r--r--src/window.c98
-rw-r--r--src/xdisp.c130
-rw-r--r--src/xfns.c46
-rw-r--r--src/xmenu.c239
-rw-r--r--src/xterm.h2
16 files changed, 858 insertions, 297 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 5895b4b6564..0d0a33d747e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,207 @@
12004-11-18 Kim F. Storm <storm@cua.dk>
2
3 * indent.c (Fvertical_motion): Undo 2004-11-16 change.
4 Instead, move back again if reseating moves too far ahead.
5
62004-11-17 Luc Teirlinck <teirllm@auburn.edu>
7
8 * xdisp.c (message3): Call clear_message.
9
102004-11-17 Kim F. Storm <storm@cua.dk>
11
12 * xdisp.c (erase_phys_cursor): Adjust cursor row visible height.
13
142004-11-16 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
15
16 * gtkutil.c (xg_get_file_name): Fix typo in
17 HAVE_GTK_FILE_SELECTION_NEW.
18
19 * xmenu.c (x_menu_in_use): Remove.
20 (x_menu_set_in_use): Also set popup_activated_flag.
21
22 * xfns.c (Fx_file_dialog): Call popup_activated instead of
23 x_menu_in_use. Call x_menu_set_in_use in Motif version also.
24
25 * xterm.h: (x_menu_in_use): Remove.
26
272004-11-16 Richard M. Stallman <rms@gnu.org>
28
29 * keymap.c (Fmap_keymap): New arg SORT-FIRST.
30 Use map-keymap-internal to implement that.
31
32 * indent.c (Fvertical_motion): In batch mode, use vmotion directly.
33
342004-11-16 Stefan Monnier <monnier@iro.umontreal.ca>
35
36 * xdisp.c (get_glyph_string_clip_rect, init_glyph_string): Check it's
37 a window before using XWINDOW.
38
39 * window.c (make_window, Fselect_window, make_dummy_parent)
40 (save_window_save):
41 * frame.c (make_frame):
42 * fns.c (concat): Avoid side-effects inside XSETFASTINT's arguments.
43
44 * lisp.h (NILP): Use EQ rather than XFASTINT.
45
462004-11-16 Kim F. Storm <storm@cua.dk>
47
48 * fringe.c (Fdefine_fringe_bitmap): Always set 'h'. Simplify.
49
50 * indent.c (Fvertical_motion): Fix last change. Only reseat when
51 moving backwards.
52
532004-11-16 Luc Teirlinck <teirllm@auburn.edu>
54
55 * dispextern.h: Extern reseat_at_previous_visible_line_start.
56
572004-11-16 Kenichi Handa <handa@m17n.org>
58
59 * xdisp.c (display_mode_element): Fix previous change (calculate
60 end position of substring to display correctly).
61
622004-11-16 Kim F. Storm <storm@cua.dk>
63
64 * keyboard.c (Fposn_at_point): Remove extra */ after doc string.
65 Reported by Andrew M. Scott.
66
672004-11-15 Kim F. Storm <storm@cua.dk>
68
69 * fns.c (Fsafe_plist_get): New defun.
70 (syms_of_fns): Defsubr it.
71
72 * lisp.h (Fsafe_plist_get): Add EXFUN.
73
74 * xdisp.c (store_mode_line_string, produce_stretch_glyph):
75 Use Fsafe_plist_get.
76 (note_mode_line_or_margin_highlight, note_mouse_highlight):
77 Fix image map element parsing. Use Fsafe_plist_get.
78
792004-11-15 Richard M. Stallman <rms@gnu.org>
80
81 * xdisp.c (get_next_display_element): Fix previous change.
82
832004-11-14 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
84
85 * window.c (shrink_windows): Handle special case of one window left
86 when trying to shrink the final reminder. Grow windows if
87 total_removed is less than total_shrink.
88
89 * xmenu.c (pop_down_menu): Remove global variable current_menu,
90 extract pointer from arg with XSAVE_VALUE.
91 (create_and_show_popup_menu, create_and_show_dialog, xmenu_show):
92 Construct arg to record_unwind_protect with make_save_value.
93
942004-11-13 Richard M. Stallman <rms@gnu.org>
95
96 * xdisp.c (reseat_at_previous_visible_line_start): No longer static.
97 (get_next_display_element): Fix previous change to apply only to \n.
98
99 * indent.c (Fvertical_motion): Scan to PT from start of line to
100 make iterator consistent.
101
102 * minibuf.c (syms_of_minibuf) <completion-ignore-case>: Doc fix.
103
1042004-11-14 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
105
106 * gtkutil.c (pop_down_file_dialog): Add BLOCK_INPUT.
107
108 * xfns.c (Fx_file_dialog): Call x_menu_in_use and x_menu_set_in_use.
109 Record unwind with clean_up_file_dialog.
110
111 * xterm.h (x_menu_in_use, x_menu_set_in_use, x_menu_wait_for_event):
112 Declare.
113
114 * xmenu.c (x_menu_in_use, x_menu_set_in_use): New functions.
115
1162004-11-13 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
117
118 * gtkutil.c (xg_file_sel_ok, xg_file_sel_cancel)
119 (xg_file_sel_destroy): Remove.
120 (xg_file_response_cb, pop_down_file_dialog)
121 (xg_get_file_name_from_chooser, xg_get_file_name_from_selector):
122 New functions.
123 (xg_get_file_with_chooser, xg_get_file_with_selection):
124 Take new arg func, set it to xg_get_file_name_from_chooser/selector.
125 Move common code to xg_get_file_name. Return widget created.
126 (xg_get_file_name): Set name, transient for, modal and destroy
127 with parent here. Connect response signal to xg_file_response_cb,
128 connect delete-event to gtk_true. Record pop_down_file_dialog
129 for unwind. Do event loop and call x_menu_wait_for_event in loop.
130 (xg_create_widget): Make dialogs modal.
131
132 * xmenu.c (unuse_menu_items, pop_down_menu): Arg is of type
133 Lisp_Object.
134 (popup_get_selection): Move unwind protect ...
135 (create_and_show_popup_menu, create_and_show_dialog): ... to here.
136 Move destroy of widget to pop_down_menu.
137 (popup_widget_loop): Move unwind protect ...
138 (create_and_show_popup_menu, create_and_show_dialog): ... to here.
139 Move destroy of widget to pop_down_menu.
140 (pop_down_menu): BLOCK_INPUT and destroy widget/window.
141 (xmenu_show): Record unwind pop_down_menu. Move XMenuDestroy,
142 x_mouse_leave and grabbed = 0 to pop_down_menu.
143
1442004-11-13 Kim F. Storm <storm@cua.dk>
145
146 * xdisp.c (make_cursor_line_fully_visible_p): New variable.
147 (syms_of_xdisp): DEFVAR_BOOL it.
148 (make_cursor_line_fully_visible, try_cursor_movement)
149 (try_window_id): Use it.
150
1512004-11-12 Kim F. Storm <storm@cua.dk>
152
153 * dispextern.h (struct glyph_row): New member extra_line_spacing.
154 (struct it): New member max_extra_line_spacing.
155 (MR_PARTIALLY_VISIBLE, MR_PARTIALLY_VISIBLE_AT_TOP)
156 (MR_PARTIALLY_VISIBLE_AT_BOTTOM): New helper macros.
157 (MATRIX_ROW_PARTIALLY_VISIBLE_P): Fix to return false if invisible
158 part of last line is only extra line spacing (so the text on the
159 line is fully visible). Use helper macros.
160 Add W arg (to use them). All callers changed.
161 (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P)
162 (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P): Use helper macros.
163
164 * window.c (window_scroll_pixel_based, Frecenter):
165 Use move_it_vertically_backward directly.
166 (Frecenter): Fix calculation of new start pos for negative arg.
167 Before, the new start pos was sometimes chosen too far back, so
168 the last line became only partially visible, and thus would be
169 either only semi-visible or automatically scrolled to the middle
170 of the window by redisplay.
171
172 * xdisp.c (init_iterator): Clear it.max_extra_line_spacing.
173 (move_it_vertically_backward): Don't recure to move further back.
174 (move_it_vertically): Remove superfluous condition.
175 (move_it_by_lines): Clear last_height when moved 0 lines.
176 (resize_mini_window): Use it.max_extra_line_spacing.
177 (display_tool_bar_line): Clear row->extra_line_spacing.
178 (try_scrolling): Use move_it_vertically_backward directly.
179 (redisplay_window): Likewise.
180 (compute_line_metrics): Set row->extra_line_spacing.
181 (display_line, display_string): Likewise.
182 (x_produce_glyphs): Update it->max_extra_line_spacing.
183
184 * xmenu.c (pop_down_menu): Return nil.
185
1862004-11-12 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
187
188 * xmenu.c (x_menu_wait_for_event): New function.
189 (popup_get_selection, popup_widget_loop): Call x_menu_wait_for_event
190 to handle timers.
191 (popup_widget_loop): Add argument do_timers.
192 (create_and_show_popup_menu, create_and_show_dialog): Pass 1 for
193 do_timers to popup_widget_loop.
194 (xmenu_show): Call XMenuActivateSetWaitFunction so that
195 x_menu_wait_for_event is called by XMenuActivate.
196 (create_and_show_popup_menu): Pass 1 for do_timers to
197 popup_get_selection.
198 (pop_down_menu): New function.
199 (popup_get_selection, popup_widget_loop): Unwind protect to
200 pop_down_menu.
201 (popup_widget_loop): Add argument widget.
202 (create_and_show_popup_menu, create_and_show_dialog): Pass new
203 argument widget to popup_widget_loop.
204
12004-11-10 Stefan Monnier <monnier@iro.umontreal.ca> 2052004-11-10 Stefan Monnier <monnier@iro.umontreal.ca>
2 206
3 * keymap.c (Fkeymap_prompt): Accept symbol keymaps. 207 * keymap.c (Fkeymap_prompt): Accept symbol keymaps.
@@ -61,7 +265,7 @@
61 * Makefile.in (SOME_MACHINE_OBJECTS): Add fringe.o, image.o 265 * Makefile.in (SOME_MACHINE_OBJECTS): Add fringe.o, image.o
62 and w32*.o. 266 and w32*.o.
63 (temacs${EXEEXT}): Generate buildobj.lst when temacs is linked. 267 (temacs${EXEEXT}): Generate buildobj.lst when temacs is linked.
64 (mostlyclean): rm buildobj.lst 268 (mostlyclean): Rm buildobj.lst
65 269
66 * makefile.w32-in ($(TEMACS)): Generate buildobj.lst when temacs 270 * makefile.w32-in ($(TEMACS)): Generate buildobj.lst when temacs
67 is linked. 271 is linked.
@@ -98,8 +302,8 @@
98 302
992004-11-07 Andreas Schwab <schwab@suse.de> 3032004-11-07 Andreas Schwab <schwab@suse.de>
100 304
101 * lisp.h: Declare Fmsdos_downcase_filename. 305 * lisp.h (Fmsdos_downcase_filename): Declare.
102 * dired.c: Don't declare Fmsdos_downcase_filename. 306 * dired.c (Fmsdos_downcase_filename): Don't declare here.
103 * fileio.c: Likewise. 307 * fileio.c: Likewise.
104 308
1052004-11-07 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 3092004-11-07 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
@@ -110,7 +314,7 @@
110 314
111 * msdos.c (IT_set_frame_parameters): Use EQ, not ==, for Lisp_Object:s. 315 * msdos.c (IT_set_frame_parameters): Use EQ, not ==, for Lisp_Object:s.
112 316
113 * dired.c: extern declare Fmsdos_downcase_filename on MSDOS to avoid 317 * dired.c (Fmsdos_downcase_filename): Declare extern on MSDOS to avoid
114 int/Lisp_Object mixup. 318 int/Lisp_Object mixup.
115 319
116 * fileio.c: Ditto. 320 * fileio.c: Ditto.
@@ -219,7 +423,7 @@
219 423
220 * fileio.c (Fnext_read_file_uses_dialog_p): New function. 424 * fileio.c (Fnext_read_file_uses_dialog_p): New function.
221 425
222 * gtkutil.h: Declare use_old_gtk_file_dialog. 426 * gtkutil.h (use_old_gtk_file_dialog): Declare.
223 427
224 * gtkutil.c: Make use_old_gtk_file_dialog non-static. 428 * gtkutil.c: Make use_old_gtk_file_dialog non-static.
225 (xg_initialize): Move DEFVAR_BOOL for use_old_gtk_file_dialog ... 429 (xg_initialize): Move DEFVAR_BOOL for use_old_gtk_file_dialog ...
@@ -691,7 +895,6 @@
691 precedence. 895 precedence.
692 (XTread_socket) [TARGET_API_MAC_CARBON]: Don't specify drag area. 896 (XTread_socket) [TARGET_API_MAC_CARBON]: Don't specify drag area.
693 897
694
6952004-10-05 Jan Dj,Ad(Brv. <jan.h.d@swipnet.se> 8982004-10-05 Jan Dj,Ad(Brv. <jan.h.d@swipnet.se>
696 899
697 * config.in: Regenerate. 900 * config.in: Regenerate.
@@ -1268,7 +1471,7 @@
1268 1471
12692004-07-24 Richard M. Stallman <rms@gnu.org> 14722004-07-24 Richard M. Stallman <rms@gnu.org>
1270 1473
1271 * keyboard.h (not_single_kboard_state): Declared. 1474 * keyboard.h (not_single_kboard_state): Declare.
1272 1475
1273 * fileio.c (Fwrite_region): Doc fix. 1476 * fileio.c (Fwrite_region): Doc fix.
1274 1477
@@ -1476,7 +1679,7 @@
1476 (lookup_image_type): Pass Qnil as second argument to 1679 (lookup_image_type): Pass Qnil as second argument to
1477 Finit_image_library. 1680 Finit_image_library.
1478 1681
1479 * lisp.h: Declare Finit_image_library. 1682 * lisp.h (Finit_image_library): Declare.
1480 1683
14812004-06-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 16842004-06-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
1482 1685
@@ -2321,7 +2524,7 @@
2321 2524
23222004-05-10 Andreas Schwab <schwab@suse.de> 25252004-05-10 Andreas Schwab <schwab@suse.de>
2323 2526
2324 * lisp.h: Declare Fmake_symbolic_link. 2527 * lisp.h (Fmake_symbolic_link): Declare.
2325 2528
2326 * fileio.c (Frename_file): Remove extra argument in call to 2529 * fileio.c (Frename_file): Remove extra argument in call to
2327 Fmake_symbolic_link. 2530 Fmake_symbolic_link.
@@ -4812,9 +5015,9 @@
4812 (update_frame_tool_bar): Call xg_get_gdk_pixmap_and_mask. 5015 (update_frame_tool_bar): Call xg_get_gdk_pixmap_and_mask.
4813 (xg_initialize): Remove xg_left_ptr_cursor. 5016 (xg_initialize): Remove xg_left_ptr_cursor.
4814 5017
4815 * gtkutil.h: xg_get_scroll_id_for_window, xg_win_to_widget takes 5018 * gtkutil.h (xg_get_scroll_id_for_window, xg_win_to_widget): Add
4816 Display* argument also. Declare xg_display_open, 5019 Display* argument.
4817 xg_display_close, xg_create_default_cursor. 5020 (xg_display_open, xg_display_close, xg_create_default_cursor): Declare.
4818 5021
48192003-11-14 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 50222003-11-14 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
4820 5023
@@ -4880,8 +5083,8 @@
4880 5083
48812003-11-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 50842003-11-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
4882 5085
4883 * gtkutil.h: Declare xg_have_tear_offs, remove xg_keep_popup 5086 * gtkutil.h (xg_have_tear_offs): Declare.
4884 and xg_did_tearoff. 5087 (xg_keep_popup, xg_did_tearoff): Remove.
4885 5088
4886 * gtkutil.c: Remove variable xg_did_tearoff. 5089 * gtkutil.c: Remove variable xg_did_tearoff.
4887 (xg_have_tear_offs): New function. 5090 (xg_have_tear_offs): New function.
@@ -5379,7 +5582,7 @@
5379 5582
5380 * alloc.c (lisp_align_malloc): Change type of `aligned'. 5583 * alloc.c (lisp_align_malloc): Change type of `aligned'.
5381 5584
5382 * alloca.s: Removed. 5585 * alloca.s: Remove.
5383 5586
53842003-08-19 Gerd Moellmann <gerd@gnu.org> 55872003-08-19 Gerd Moellmann <gerd@gnu.org>
5385 5588
@@ -8001,7 +8204,7 @@
8001 (handle_one_xevent): ButtonPress/Release: If event is for a toolkit 8204 (handle_one_xevent): ButtonPress/Release: If event is for a toolkit
8002 scrollbar and control is pressed, call x_scroll_bar_handle_click. 8205 scrollbar and control is pressed, call x_scroll_bar_handle_click.
8003 8206
8004 * gtkutil.h: Declare xg_get_scroll_id_for_window. 8207 * gtkutil.h (xg_get_scroll_id_for_window): Declare.
8005 8208
8006 * gtkutil.c (xg_get_scroll_id_for_window): New function. 8209 * gtkutil.c (xg_get_scroll_id_for_window): New function.
8007 (xg_tool_bar_item_expose_callback): New function. 8210 (xg_tool_bar_item_expose_callback): New function.
@@ -8703,7 +8906,7 @@
8703 (FRAME_OUTER_TO_INNER_DIFF_Y): Add FRAME_TOOLBAR_HEIGHT to calculation. 8906 (FRAME_OUTER_TO_INNER_DIFF_Y): Add FRAME_TOOLBAR_HEIGHT to calculation.
8704 8907
8705 * xterm.c: Include gtkutil.h for USE_GTK. 8908 * xterm.c: Include gtkutil.h for USE_GTK.
8706 Declare extern void free_frame_menubar for USE_GTK. 8909 (free_frame_menubar): Declare extern void for USE_GTK.
8707 (note_mouse_highlight): Check popup_activated for USE_GTK. 8910 (note_mouse_highlight): Check popup_activated for USE_GTK.
8708 (xt_action_hook): Don't compile if USE_GTK. 8911 (xt_action_hook): Don't compile if USE_GTK.
8709 (x_scroll_bar_to_input_event): Use CurrentTime for USE_GTK. 8912 (x_scroll_bar_to_input_event): Use CurrentTime for USE_GTK.
@@ -8773,7 +8976,7 @@
8773 (redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_TOOL_BAR. 8976 (redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_TOOL_BAR.
8774 (display_menu_bar): Add check for USE_GTK 8977 (display_menu_bar): Add check for USE_GTK
8775 8978
8776 * lisp.h: Declare Vx_resource_name extern. 8979 * lisp.h (Vx_resource_name): Declare extern.
8777 8980
8778 * keyboard.c (kbd_buffer_get_event): Check MENU_BAR_ACTIVATE_EVENT 8981 * keyboard.c (kbd_buffer_get_event): Check MENU_BAR_ACTIVATE_EVENT
8779 for USE_GTK. 8982 for USE_GTK.
@@ -8990,7 +9193,7 @@
8990 (XSAVE_VALUE): New macro. 9193 (XSAVE_VALUE): New macro.
8991 (struct Lisp_Save_Value): New data type. 9194 (struct Lisp_Save_Value): New data type.
8992 (union Lisp_Misc): Add u_save_value alternative. 9195 (union Lisp_Misc): Add u_save_value alternative.
8993 (make_save_value): Declared. 9196 (make_save_value): Declare.
8994 9197
8995 * alloc.c (make_save_value): New function. 9198 * alloc.c (make_save_value): New function.
8996 9199
@@ -12060,7 +12263,7 @@
12060 * fontset.c [MAC_OS]: Set Vdefault_fontset to ETL Fixed instead of 12263 * fontset.c [MAC_OS]: Set Vdefault_fontset to ETL Fixed instead of
12061 Apple Monaco. 12264 Apple Monaco.
12062 12265
12063 * process.c: Declare QCfamily and QCfilter as extern. 12266 * process.c (QCfamily, QCfilte): Declare extern.
12064 (wait_reading_process_input) [MAC_OSX]: Clear bit for stdin before 12267 (wait_reading_process_input) [MAC_OSX]: Clear bit for stdin before
12065 calling select. 12268 calling select.
12066 12269
@@ -12888,7 +13091,7 @@
12888 13091
128892002-03-10 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 130922002-03-10 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
12890 13093
12891 * xterm.h (x_session_check_input, x_session_initialize): Declared. 13094 * xterm.h (x_session_check_input, x_session_initialize): Declare.
12892 13095
12893 * xterm.c: (XTread_socket): Add call to x_session_check_input and 13096 * xterm.c: (XTread_socket): Add call to x_session_check_input and
12894 x_session_have_connection. 13097 x_session_have_connection.
@@ -12900,7 +13103,7 @@
12900 13103
12901 * emacs.c (main): Add call to syms_of_xsmfns. 13104 * emacs.c (main): Add call to syms_of_xsmfns.
12902 13105
12903 * lisp.h: Declare syms_of_xsmfns as extern. 13106 * lisp.h (syms_of_xsmfns): Declare extern.
12904 13107
12905 * config.in: Add HAVE_X_SM. 13108 * config.in: Add HAVE_X_SM.
12906 13109
@@ -14245,7 +14448,7 @@
142452001-12-09 Jason Rumney <jasonr@gnu.org> 144482001-12-09 Jason Rumney <jasonr@gnu.org>
14246 14449
14247 * w32menu.c (_widget_value): Make `help' field a Lisp_Object. 14450 * w32menu.c (_widget_value): Make `help' field a Lisp_Object.
14248 Add comment to explain where the struct came from. 14451 Add comment to explain where the struct came from.
14249 (single_submenu, w32_menu_show): Set `help' field as Lisp_Object. 14452 (single_submenu, w32_menu_show): Set `help' field as Lisp_Object.
14250 (add_menu_item): Process pop-up menus first to avoid memory leak. 14453 (add_menu_item): Process pop-up menus first to avoid memory leak.
14251 (add_menu_item, w32_menu_display_help): Use `help' field as 14454 (add_menu_item, w32_menu_display_help): Use `help' field as
@@ -15031,7 +15234,7 @@
15031 * insdel.c (replace_range): Use adjust_markers_for_replace 15234 * insdel.c (replace_range): Use adjust_markers_for_replace
15032 instead of adjust_markers_for_delete and adjust_markers_for_insert. 15235 instead of adjust_markers_for_delete and adjust_markers_for_insert.
15033 15236
15034 * intervals.h: Declare set_text_properties and set_text_properties_1. 15237 * intervals.h (set_text_properties, set_text_properties_1): Declare.
15035 15238
15036 * textprop.c (set_text_properties_1): New subroutine 15239 * textprop.c (set_text_properties_1): New subroutine
15037 broken out of set_text_properties. 15240 broken out of set_text_properties.
diff --git a/src/dispextern.h b/src/dispextern.h
index a87a38ce469..463e719d1bc 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -694,6 +694,10 @@ struct glyph_row
694 frames. It may be < 0 in case of completely invisible rows. */ 694 frames. It may be < 0 in case of completely invisible rows. */
695 int visible_height; 695 int visible_height;
696 696
697 /* Extra line spacing added after this row. Do not consider this
698 in last row when checking if row is fully visible. */
699 int extra_line_spacing;
700
697 /* Hash code. This hash code is available as soon as the row 701 /* Hash code. This hash code is available as soon as the row
698 is constructed, i.e. after a call to display_line. */ 702 is constructed, i.e. after a call to display_line. */
699 unsigned hash; 703 unsigned hash;
@@ -916,22 +920,39 @@ struct glyph_row *matrix_row P_ ((struct glyph_matrix *, int));
916 920
917#define MATRIX_ROW_DISPLAYS_TEXT_P(ROW) ((ROW)->displays_text_p) 921#define MATRIX_ROW_DISPLAYS_TEXT_P(ROW) ((ROW)->displays_text_p)
918 922
923
924/* Helper macros */
925
926#define MR_PARTIALLY_VISIBLE(ROW) \
927 ((ROW)->height != (ROW)->visible_height)
928
929#define MR_PARTIALLY_VISIBLE_AT_TOP(W, ROW) \
930 ((ROW)->y < WINDOW_HEADER_LINE_HEIGHT ((W)))
931
932#define MR_PARTIALLY_VISIBLE_AT_BOTTOM(W, ROW) \
933 (((ROW)->y + (ROW)->height - (ROW)->extra_line_spacing) \
934 > WINDOW_BOX_HEIGHT_NO_MODE_LINE ((W)))
935
919/* Non-zero if ROW is not completely visible in window W. */ 936/* Non-zero if ROW is not completely visible in window W. */
920 937
921#define MATRIX_ROW_PARTIALLY_VISIBLE_P(ROW) \ 938#define MATRIX_ROW_PARTIALLY_VISIBLE_P(W, ROW) \
922 ((ROW)->height != (ROW)->visible_height) 939 (MR_PARTIALLY_VISIBLE ((ROW)) \
940 && (MR_PARTIALLY_VISIBLE_AT_TOP ((W), (ROW)) \
941 || MR_PARTIALLY_VISIBLE_AT_BOTTOM ((W), (ROW))))
942
943
923 944
924/* Non-zero if ROW is partially visible at the top of window W. */ 945/* Non-zero if ROW is partially visible at the top of window W. */
925 946
926#define MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P(W, ROW) \ 947#define MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P(W, ROW) \
927 (MATRIX_ROW_PARTIALLY_VISIBLE_P ((ROW)) \ 948 (MR_PARTIALLY_VISIBLE ((ROW)) \
928 && (ROW)->y < WINDOW_HEADER_LINE_HEIGHT ((W))) 949 && MR_PARTIALLY_VISIBLE_AT_TOP ((W), (ROW)))
929 950
930/* Non-zero if ROW is partially visible at the bottom of window W. */ 951/* Non-zero if ROW is partially visible at the bottom of window W. */
931 952
932#define MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P(W, ROW) \ 953#define MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P(W, ROW) \
933 (MATRIX_ROW_PARTIALLY_VISIBLE_P ((ROW)) \ 954 (MR_PARTIALLY_VISIBLE ((ROW)) \
934 && (ROW)->y + (ROW)->height > WINDOW_BOX_HEIGHT_NO_MODE_LINE ((W))) 955 && MR_PARTIALLY_VISIBLE_AT_BOTTOM ((W), (ROW)))
935 956
936/* Return the bottom Y + 1 of ROW. */ 957/* Return the bottom Y + 1 of ROW. */
937 958
@@ -1984,10 +2005,13 @@ struct it
1984 line, if the window has one. */ 2005 line, if the window has one. */
1985 int last_visible_y; 2006 int last_visible_y;
1986 2007
1987 /* Additional space in pixels between lines (for window systems 2008 /* Default amount of additional space in pixels between lines (for
1988 only.) */ 2009 window systems only.) */
1989 int extra_line_spacing; 2010 int extra_line_spacing;
1990 2011
2012 /* Max extra line spacing added in this row. */
2013 int max_extra_line_spacing;
2014
1991 /* Override font height information for this glyph. 2015 /* Override font height information for this glyph.
1992 Used if override_ascent >= 0. Cleared after this glyph. */ 2016 Used if override_ascent >= 0. Cleared after this glyph. */
1993 int override_ascent, override_descent, override_boff; 2017 int override_ascent, override_descent, override_boff;
@@ -2574,6 +2598,7 @@ extern int help_echo_pos;
2574extern struct frame *last_mouse_frame; 2598extern struct frame *last_mouse_frame;
2575extern int last_tool_bar_item; 2599extern int last_tool_bar_item;
2576extern int mouse_autoselect_window; 2600extern int mouse_autoselect_window;
2601extern void reseat_at_previous_visible_line_start P_ ((struct it *));
2577 2602
2578extern int calc_pixel_width_or_height P_ ((double *, struct it *, Lisp_Object, 2603extern int calc_pixel_width_or_height P_ ((double *, struct it *, Lisp_Object,
2579 /* XFontStruct */ void *, int, int *)); 2604 /* XFontStruct */ void *, int, int *));
diff --git a/src/fns.c b/src/fns.c
index 442eb120b82..8d63b731fcf 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -701,7 +701,7 @@ concat (nargs, args, target_type, last_special)
701 } 701 }
702 else 702 else
703 { 703 {
704 XSETFASTINT (elt, SREF (this, thisindex++)); 704 XSETFASTINT (elt, SREF (this, thisindex)); thisindex++;
705 if (some_multibyte 705 if (some_multibyte
706 && XINT (elt) >= 0200 706 && XINT (elt) >= 0200
707 && XINT (elt) < 0400) 707 && XINT (elt) < 0400)
@@ -1924,6 +1924,35 @@ one of the properties on the list. */)
1924 return Qnil; 1924 return Qnil;
1925} 1925}
1926 1926
1927DEFUN ("safe-plist-get", Fsafe_plist_get, Ssafe_plist_get, 2, 2, 0,
1928 doc: /* Extract a value from a property list.
1929PLIST is a property list, which is a list of the form
1930\(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
1931corresponding to the given PROP, or nil if PROP is not
1932one of the properties on the list.
1933This function never signals an error. */)
1934 (plist, prop)
1935 Lisp_Object plist;
1936 Lisp_Object prop;
1937{
1938 Lisp_Object tail, halftail;
1939
1940 /* halftail is used to detect circular lists. */
1941 tail = halftail = plist;
1942 while (CONSP (tail) && CONSP (XCDR (tail)))
1943 {
1944 if (EQ (prop, XCAR (tail)))
1945 return XCAR (XCDR (tail));
1946
1947 tail = XCDR (XCDR (tail));
1948 halftail = XCDR (halftail);
1949 if (EQ (tail, halftail))
1950 break;
1951 }
1952
1953 return Qnil;
1954}
1955
1927DEFUN ("get", Fget, Sget, 2, 2, 0, 1956DEFUN ("get", Fget, Sget, 2, 2, 0,
1928 doc: /* Return the value of SYMBOL's PROPNAME property. 1957 doc: /* Return the value of SYMBOL's PROPNAME property.
1929This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */) 1958This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */)
@@ -5202,6 +5231,7 @@ used if both `use-dialog-box' and this variable are non-nil. */);
5202 defsubr (&Sreverse); 5231 defsubr (&Sreverse);
5203 defsubr (&Ssort); 5232 defsubr (&Ssort);
5204 defsubr (&Splist_get); 5233 defsubr (&Splist_get);
5234 defsubr (&Ssafe_plist_get);
5205 defsubr (&Sget); 5235 defsubr (&Sget);
5206 defsubr (&Splist_put); 5236 defsubr (&Splist_put);
5207 defsubr (&Sput); 5237 defsubr (&Sput);
diff --git a/src/frame.c b/src/frame.c
index ea60297a282..5e8a3780c9b 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -371,7 +371,8 @@ make_frame (mini_p)
371 f->selected_window = root_window; 371 f->selected_window = root_window;
372 /* Make sure this window seems more recently used than 372 /* Make sure this window seems more recently used than
373 a newly-created, never-selected window. */ 373 a newly-created, never-selected window. */
374 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count); 374 ++window_select_count;
375 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
375 376
376 f->default_face_done_p = 0; 377 f->default_face_done_p = 0;
377 378
diff --git a/src/fringe.c b/src/fringe.c
index 3de55b405cc..591d6acb290 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1204,7 +1204,6 @@ If BITMAP already exists, the existing definition is replaced. */)
1204 (bitmap, bits, height, width, align) 1204 (bitmap, bits, height, width, align)
1205 Lisp_Object bitmap, bits, height, width, align; 1205 Lisp_Object bitmap, bits, height, width, align;
1206{ 1206{
1207 Lisp_Object len;
1208 int n, h, i, j; 1207 int n, h, i, j;
1209 unsigned short *b; 1208 unsigned short *b;
1210 struct fringe_bitmap fb, *xfb; 1209 struct fringe_bitmap fb, *xfb;
@@ -1212,20 +1211,21 @@ If BITMAP already exists, the existing definition is replaced. */)
1212 1211
1213 CHECK_SYMBOL (bitmap); 1212 CHECK_SYMBOL (bitmap);
1214 1213
1215 if (!STRINGP (bits) && !VECTORP (bits)) 1214 if (STRINGP (bits))
1216 bits = wrong_type_argument (Qstringp, bits); 1215 h = SCHARS (bits);
1217 1216 else if (VECTORP (bits))
1218 len = Flength (bits); 1217 h = XVECTOR (bits)->size;
1218 else
1219 bits = wrong_type_argument (Qsequencep, bits);
1219 1220
1220 if (NILP (height)) 1221 if (NILP (height))
1221 h = fb.height = XINT (len); 1222 fb.height = h;
1222 else 1223 else
1223 { 1224 {
1224 CHECK_NUMBER (height); 1225 CHECK_NUMBER (height);
1225 fb.height = min (XINT (height), 255); 1226 fb.height = min (XINT (height), 255);
1226 if (fb.height > XINT (len)) 1227 if (fb.height > h)
1227 { 1228 {
1228 h = XINT (len);
1229 fill1 = (fb.height - h) / 2; 1229 fill1 = (fb.height - h) / 2;
1230 fill2 = fb.height - h - fill1; 1230 fill2 = fb.height - h - fill1;
1231 } 1231 }
diff --git a/src/gtkutil.c b/src/gtkutil.c
index f5f05709e48..25dd88d544e 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1122,41 +1122,75 @@ create_dialog (wv, select_cb, deactivate_cb)
1122/*********************************************************************** 1122/***********************************************************************
1123 File dialog functions 1123 File dialog functions
1124 ***********************************************************************/ 1124 ***********************************************************************/
1125enum
1126{
1127 XG_FILE_NOT_DONE,
1128 XG_FILE_OK,
1129 XG_FILE_CANCEL,
1130 XG_FILE_DESTROYED,
1131};
1132
1133#ifdef HAVE_GTK_FILE_BOTH 1125#ifdef HAVE_GTK_FILE_BOTH
1134int use_old_gtk_file_dialog; 1126int use_old_gtk_file_dialog;
1135#endif 1127#endif
1136 1128
1129/* Function that is called when the file dialog pops down.
1130 W is the dialog widget, RESPONSE is the response code.
1131 USER_DATA is what we passed in to g_signal_connect (pointer to int). */
1132
1133static void
1134xg_file_response_cb (w,
1135 response,
1136 user_data)
1137 GtkDialog *w;
1138 gint response;
1139 gpointer user_data;
1140{
1141 int *ptr = (int *) user_data;
1142 *ptr = response;
1143}
1144
1145
1146/* Destroy the dialog. This makes it pop down. */
1147
1148static Lisp_Object
1149pop_down_file_dialog (arg)
1150 Lisp_Object arg;
1151{
1152 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
1153 BLOCK_INPUT;
1154 gtk_widget_destroy (GTK_WIDGET (p->pointer));
1155 UNBLOCK_INPUT;
1156 return Qnil;
1157}
1158
1159typedef char * (*xg_get_file_func) P_ ((GtkWidget *));
1137 1160
1138#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW 1161#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW
1162
1163/* Return the selected file for file chooser dialog W.
1164 The returned string must be free:d. */
1165
1166static char *
1167xg_get_file_name_from_chooser (w)
1168 GtkWidget *w;
1169{
1170 return gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w));
1171}
1172
1139/* Read a file name from the user using a file chooser dialog. 1173/* Read a file name from the user using a file chooser dialog.
1140 F is the current frame. 1174 F is the current frame.
1141 PROMPT is a prompt to show to the user. May not be NULL. 1175 PROMPT is a prompt to show to the user. May not be NULL.
1142 DEFAULT_FILENAME is a default selection to be displayed. May be NULL. 1176 DEFAULT_FILENAME is a default selection to be displayed. May be NULL.
1143 If MUSTMATCH_P is non-zero, the returned file name must be an existing 1177 If MUSTMATCH_P is non-zero, the returned file name must be an existing
1144 file. 1178 file. *FUNC is set to a function that can be used to retrieve the
1179 selected file name from the returned widget.
1145 1180
1146 Returns a file name or NULL if no file was selected. 1181 Returns the created widget. */
1147 The returned string must be freed by the caller. */
1148 1182
1149static char * 1183static GtkWidget *
1150xg_get_file_with_chooser (f, prompt, default_filename, mustmatch_p, only_dir_p) 1184xg_get_file_with_chooser (f, prompt, default_filename,
1185 mustmatch_p, only_dir_p, func)
1151 FRAME_PTR f; 1186 FRAME_PTR f;
1152 char *prompt; 1187 char *prompt;
1153 char *default_filename; 1188 char *default_filename;
1154 int mustmatch_p, only_dir_p; 1189 int mustmatch_p, only_dir_p;
1190 xg_get_file_func *func;
1155{ 1191{
1156 GtkWidget *filewin; 1192 GtkWidget *filewin;
1157 GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); 1193 GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
1158
1159 char *fn = 0;
1160 GtkFileChooserAction action = (mustmatch_p ? 1194 GtkFileChooserAction action = (mustmatch_p ?
1161 GTK_FILE_CHOOSER_ACTION_OPEN : 1195 GTK_FILE_CHOOSER_ACTION_OPEN :
1162 GTK_FILE_CHOOSER_ACTION_SAVE); 1196 GTK_FILE_CHOOSER_ACTION_SAVE);
@@ -1171,12 +1205,6 @@ xg_get_file_with_chooser (f, prompt, default_filename, mustmatch_p, only_dir_p)
1171 GTK_RESPONSE_OK, 1205 GTK_RESPONSE_OK,
1172 NULL); 1206 NULL);
1173 1207
1174 xg_set_screen (filewin, f);
1175 gtk_widget_set_name (filewin, "emacs-filedialog");
1176 gtk_window_set_transient_for (GTK_WINDOW (filewin), gwin);
1177 gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE);
1178
1179
1180 if (default_filename) 1208 if (default_filename)
1181 { 1209 {
1182 Lisp_Object file; 1210 Lisp_Object file;
@@ -1197,104 +1225,49 @@ xg_get_file_with_chooser (f, prompt, default_filename, mustmatch_p, only_dir_p)
1197 UNGCPRO; 1225 UNGCPRO;
1198 } 1226 }
1199 1227
1200 gtk_widget_show (filewin); 1228 *func = xg_get_file_name_from_chooser;
1201 1229 return filewin;
1202 if (gtk_dialog_run (GTK_DIALOG (filewin)) == GTK_RESPONSE_OK)
1203 fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filewin));
1204
1205 gtk_widget_destroy (filewin);
1206
1207 return fn;
1208} 1230}
1209#endif /* HAVE_GTK_FILE_CHOOSER_DIALOG_NEW */ 1231#endif /* HAVE_GTK_FILE_CHOOSER_DIALOG_NEW */
1210 1232
1211#ifdef HAVE_GTK_FILE_SELECTION_NEW 1233#ifdef HAVE_GTK_FILE_SELECTION_NEW
1212/* Callback function invoked when the Ok button is pressed in
1213 a file dialog.
1214 W is the file dialog widget,
1215 ARG points to an integer where we record what has happend. */
1216 1234
1217static void 1235/* Return the selected file for file selector dialog W.
1218xg_file_sel_ok (w, arg) 1236 The returned string must be free:d. */
1219 GtkWidget *w;
1220 gpointer arg;
1221{
1222 *(int*)arg = XG_FILE_OK;
1223}
1224 1237
1225/* Callback function invoked when the Cancel button is pressed in 1238static char *
1226 a file dialog. 1239xg_get_file_name_from_selector (w)
1227 W is the file dialog widget,
1228 ARG points to an integer where we record what has happend. */
1229
1230static void
1231xg_file_sel_cancel (w, arg)
1232 GtkWidget *w;
1233 gpointer arg;
1234{
1235 *(int*)arg = XG_FILE_CANCEL;
1236}
1237
1238/* Callback function invoked when the file dialog is destroyed (i.e.
1239 popped down). We must keep track of this, because if this
1240 happens, GTK destroys the widget. But if for example, Ok is pressed,
1241 the dialog is popped down, but the dialog widget is not destroyed.
1242 W is the file dialog widget,
1243 ARG points to an integer where we record what has happend. */
1244
1245static void
1246xg_file_sel_destroy (w, arg)
1247 GtkWidget *w; 1240 GtkWidget *w;
1248 gpointer arg;
1249{ 1241{
1250 *(int*)arg = XG_FILE_DESTROYED; 1242 GtkFileSelection *filesel = GTK_FILE_SELECTION (w);
1243 return xstrdup ((char*) gtk_file_selection_get_filename (filesel));
1251} 1244}
1252 1245
1253/* Read a file name from the user using a file selection dialog. 1246/* Create a file selection dialog.
1254 F is the current frame. 1247 F is the current frame.
1255 PROMPT is a prompt to show to the user. May not be NULL. 1248 PROMPT is a prompt to show to the user. May not be NULL.
1256 DEFAULT_FILENAME is a default selection to be displayed. May be NULL. 1249 DEFAULT_FILENAME is a default selection to be displayed. May be NULL.
1257 If MUSTMATCH_P is non-zero, the returned file name must be an existing 1250 If MUSTMATCH_P is non-zero, the returned file name must be an existing
1258 file. 1251 file. *FUNC is set to a function that can be used to retrieve the
1252 selected file name from the returned widget.
1259 1253
1260 Returns a file name or NULL if no file was selected. 1254 Returns the created widget. */
1261 The returned string must be freed by the caller. */
1262 1255
1263static char * 1256static GtkWidget *
1264xg_get_file_with_selection (f, prompt, default_filename, 1257xg_get_file_with_selection (f, prompt, default_filename,
1265 mustmatch_p, only_dir_p) 1258 mustmatch_p, only_dir_p, func)
1266 FRAME_PTR f; 1259 FRAME_PTR f;
1267 char *prompt; 1260 char *prompt;
1268 char *default_filename; 1261 char *default_filename;
1269 int mustmatch_p, only_dir_p; 1262 int mustmatch_p, only_dir_p;
1263 xg_get_file_func *func;
1270{ 1264{
1271 GtkWidget *filewin; 1265 GtkWidget *filewin;
1272 GtkFileSelection *filesel; 1266 GtkFileSelection *filesel;
1273 int filesel_done = XG_FILE_NOT_DONE;
1274 char *fn = 0;
1275 1267
1276 filewin = gtk_file_selection_new (prompt); 1268 filewin = gtk_file_selection_new (prompt);
1277 filesel = GTK_FILE_SELECTION (filewin); 1269 filesel = GTK_FILE_SELECTION (filewin);
1278 1270
1279 xg_set_screen (filewin, f);
1280 gtk_widget_set_name (filewin, "emacs-filedialog");
1281 gtk_window_set_transient_for (GTK_WINDOW (filewin),
1282 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
1283 gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE);
1284
1285 g_signal_connect (G_OBJECT (filesel->ok_button),
1286 "clicked",
1287 G_CALLBACK (xg_file_sel_ok),
1288 &filesel_done);
1289 g_signal_connect (G_OBJECT (filesel->cancel_button),
1290 "clicked",
1291 G_CALLBACK (xg_file_sel_cancel),
1292 &filesel_done);
1293 g_signal_connect (G_OBJECT (filesel),
1294 "destroy",
1295 G_CALLBACK (xg_file_sel_destroy),
1296 &filesel_done);
1297
1298 if (default_filename) 1271 if (default_filename)
1299 gtk_file_selection_set_filename (filesel, default_filename); 1272 gtk_file_selection_set_filename (filesel, default_filename);
1300 1273
@@ -1305,19 +1278,9 @@ xg_get_file_with_selection (f, prompt, default_filename,
1305 gtk_file_selection_hide_fileop_buttons (filesel); 1278 gtk_file_selection_hide_fileop_buttons (filesel);
1306 } 1279 }
1307 1280
1281 *func = xg_get_file_name_from_selector;
1308 1282
1309 gtk_widget_show_all (filewin); 1283 return filewin;
1310
1311 while (filesel_done == XG_FILE_NOT_DONE)
1312 gtk_main_iteration ();
1313
1314 if (filesel_done == XG_FILE_OK)
1315 fn = xstrdup ((char*) gtk_file_selection_get_filename (filesel));
1316
1317 if (filesel_done != XG_FILE_DESTROYED)
1318 gtk_widget_destroy (filewin);
1319
1320 return fn;
1321} 1284}
1322#endif /* HAVE_GTK_FILE_SELECTION_NEW */ 1285#endif /* HAVE_GTK_FILE_SELECTION_NEW */
1323 1286
@@ -1341,26 +1304,63 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p)
1341 char *default_filename; 1304 char *default_filename;
1342 int mustmatch_p, only_dir_p; 1305 int mustmatch_p, only_dir_p;
1343{ 1306{
1307 GtkWidget *w = 0;
1308 int count = SPECPDL_INDEX ();
1309 char *fn = 0;
1310 int filesel_done = 0;
1311 xg_get_file_func func;
1312
1344#ifdef HAVE_GTK_FILE_BOTH 1313#ifdef HAVE_GTK_FILE_BOTH
1345 if (use_old_gtk_file_dialog) 1314 if (use_old_gtk_file_dialog)
1346 return xg_get_file_with_selection (f, prompt, default_filename, 1315 w = xg_get_file_with_selection (f, prompt, default_filename,
1347 mustmatch_p, only_dir_p); 1316 mustmatch_p, only_dir_p, &func);
1348 return xg_get_file_with_chooser (f, prompt, default_filename, 1317 else
1349 mustmatch_p, only_dir_p); 1318 w = xg_get_file_with_chooser (f, prompt, default_filename,
1319 mustmatch_p, only_dir_p, &func);
1350 1320
1351#else /* not HAVE_GTK_FILE_BOTH */ 1321#else /* not HAVE_GTK_FILE_BOTH */
1352 1322
1353#ifdef HAVE_GTK_FILE_SELECTION_DIALOG_NEW 1323#ifdef HAVE_GTK_FILE_SELECTION_NEW
1354 return xg_get_file_with_selection (f, prompt, default_filename, 1324 w = xg_get_file_with_selection (f, prompt, default_filename,
1355 mustmatch_p, only_dir_p); 1325 mustmatch_p, only_dir_p, &func);
1356#endif 1326#endif
1357#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW 1327#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW
1358 return xg_get_file_with_chooser (f, prompt, default_filename, 1328 w = xg_get_file_with_chooser (f, prompt, default_filename,
1359 mustmatch_p, only_dir_p); 1329 mustmatch_p, only_dir_p, &func);
1360#endif 1330#endif
1361 1331
1362#endif /* HAVE_GTK_FILE_BOTH */ 1332#endif /* HAVE_GTK_FILE_BOTH */
1363 return 0; 1333
1334 xg_set_screen (w, f);
1335 gtk_widget_set_name (w, "emacs-filedialog");
1336 gtk_window_set_transient_for (GTK_WINDOW (w),
1337 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
1338 gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
1339 gtk_window_set_modal (GTK_WINDOW (w), TRUE);
1340
1341 g_signal_connect (G_OBJECT (w),
1342 "response",
1343 G_CALLBACK (xg_file_response_cb),
1344 &filesel_done);
1345
1346 /* Don't destroy the widget if closed by the window manager close button. */
1347 g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL);
1348
1349 gtk_widget_show (w);
1350
1351 record_unwind_protect (pop_down_file_dialog, make_save_value (w, 0));
1352 while (! filesel_done)
1353 {
1354 x_menu_wait_for_event (0);
1355 gtk_main_iteration ();
1356 }
1357
1358 if (filesel_done == GTK_RESPONSE_OK)
1359 fn = (*func) (w);
1360
1361 unbind_to (count, Qnil);
1362
1363 return fn;
1364} 1364}
1365 1365
1366 1366
@@ -1999,6 +1999,7 @@ xg_create_widget (type, name, f, val,
1999 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); 1999 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
2000 gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE); 2000 gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
2001 gtk_widget_set_name (w, "emacs-dialog"); 2001 gtk_widget_set_name (w, "emacs-dialog");
2002 gtk_window_set_modal (GTK_WINDOW (w), TRUE);
2002 } 2003 }
2003 else if (menu_bar_p || pop_up_p) 2004 else if (menu_bar_p || pop_up_p)
2004 { 2005 {
diff --git a/src/indent.c b/src/indent.c
index 874662cc47c..5b2faba7fda 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2061,21 +2061,38 @@ whether or not it is currently displayed in some window. */)
2061 XSETBUFFER (w->buffer, current_buffer); 2061 XSETBUFFER (w->buffer, current_buffer);
2062 } 2062 }
2063 2063
2064 SET_TEXT_POS (pt, PT, PT_BYTE); 2064 if (noninteractive)
2065 start_display (&it, w, pt); 2065 {
2066 2066 struct position pos;
2067 /* Move to the start of the display line containing PT. If we don't 2067 pos = *vmotion (PT, XINT (lines), w);
2068 do this, we start moving with IT->current_x == 0, while PT is 2068 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2069 really at some x > 0. The effect is, in continuation lines, that 2069 }
2070 we end up with the iterator placed at where it thinks X is 0, 2070 else
2071 while the end position is really at some X > 0, the same X that 2071 {
2072 PT had. */ 2072 SET_TEXT_POS (pt, PT, PT_BYTE);
2073 move_it_by_lines (&it, 0, 0); 2073 start_display (&it, w, pt);
2074 2074
2075 if (XINT (lines) != 0) 2075 /* Scan from the start of the line containing PT. If we don't
2076 move_it_by_lines (&it, XINT (lines), 0); 2076 do this, we start moving with IT->current_x == 0, while PT is
2077 2077 really at some x > 0. The effect is, in continuation lines, that
2078 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 2078 we end up with the iterator placed at where it thinks X is 0,
2079 while the end position is really at some X > 0, the same X that
2080 PT had. */
2081 reseat_at_previous_visible_line_start (&it);
2082 it.current_x = it.hpos = 0;
2083 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2084
2085 /* Move back if we got too far. This may happen if
2086 truncate-lines is on and PT is beyond right margin. */
2087 if (IT_CHARPOS (it) > PT && XINT (lines) > 0)
2088 move_it_by_lines (&it, -1, 0);
2089
2090 it.vpos = 0;
2091 if (XINT (lines) != 0)
2092 move_it_by_lines (&it, XINT (lines), 0);
2093
2094 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2095 }
2079 2096
2080 if (BUFFERP (old_buffer)) 2097 if (BUFFERP (old_buffer))
2081 w->buffer = old_buffer; 2098 w->buffer = old_buffer;
diff --git a/src/keyboard.c b/src/keyboard.c
index c89a86eb80f..75bfa2180c7 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -10525,7 +10525,7 @@ a mouse click at the upper left corner of the glyph corresponding
10525to the given buffer position: 10525to the given buffer position:
10526 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW) 10526 (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
10527 IMAGE (DX . DY) (WIDTH . HEIGHT)) 10527 IMAGE (DX . DY) (WIDTH . HEIGHT))
10528The `posn-' functions access elements of such lists. */*/) 10528The `posn-' functions access elements of such lists. */)
10529 (pos, window) 10529 (pos, window)
10530 Lisp_Object pos, window; 10530 Lisp_Object pos, window;
10531{ 10531{
diff --git a/src/keymap.c b/src/keymap.c
index 1a86caff4c4..e76cbf5c00a 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -703,19 +703,23 @@ map_keymap_call (key, val, fun, dummy)
703 call2 (fun, key, val); 703 call2 (fun, key, val);
704} 704}
705 705
706DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 2, 0, 706DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0,
707 doc: /* Call FUNCTION for every binding in KEYMAP. 707 doc: /* Call FUNCTION for every binding in KEYMAP.
708FUNCTION is called with two arguments: the event and its binding. 708FUNCTION is called with two arguments: the event and its binding.
709If KEYMAP has a parent, the parent's bindings are included as well. 709If KEYMAP has a parent, the parent's bindings are included as well.
710This works recursively: if the parent has itself a parent, then the 710This works recursively: if the parent has itself a parent, then the
711grandparent's bindings are also included and so on. */) 711grandparent's bindings are also included and so on.
712 (function, keymap) 712usage: (map-keymap FUNCTION KEYMAP) */)
713 Lisp_Object function, keymap; 713 (function, keymap, sort_first)
714 Lisp_Object function, keymap, sort_first;
714{ 715{
715 if (INTEGERP (function)) 716 if (INTEGERP (function))
716 /* We have to stop integers early since map_keymap gives them special 717 /* We have to stop integers early since map_keymap gives them special
717 significance. */ 718 significance. */
718 Fsignal (Qinvalid_function, Fcons (function, Qnil)); 719 Fsignal (Qinvalid_function, Fcons (function, Qnil));
720 if (! NILP (sort_first))
721 return call3 (intern ("map-keymap-internal"), function, keymap, Qt);
722
719 map_keymap (keymap, map_keymap_call, function, NULL, 1); 723 map_keymap (keymap, map_keymap_call, function, NULL, 1);
720 return Qnil; 724 return Qnil;
721} 725}
diff --git a/src/lisp.h b/src/lisp.h
index b49602c1303..e89f778aa0e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1378,7 +1378,7 @@ typedef unsigned char UCHAR;
1378 1378
1379/* Data type checking */ 1379/* Data type checking */
1380 1380
1381#define NILP(x) (XFASTINT (x) == XFASTINT (Qnil)) 1381#define NILP(x) EQ (x, Qnil)
1382#define GC_NILP(x) GC_EQ (x, Qnil) 1382#define GC_NILP(x) GC_EQ (x, Qnil)
1383 1383
1384#define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) 1384#define NUMBERP(x) (INTEGERP (x) || FLOATP (x))
@@ -2328,6 +2328,7 @@ extern Lisp_Object string_make_multibyte P_ ((Lisp_Object));
2328extern Lisp_Object string_make_unibyte P_ ((Lisp_Object)); 2328extern Lisp_Object string_make_unibyte P_ ((Lisp_Object));
2329EXFUN (Fcopy_alist, 1); 2329EXFUN (Fcopy_alist, 1);
2330EXFUN (Fplist_get, 2); 2330EXFUN (Fplist_get, 2);
2331EXFUN (Fsafe_plist_get, 2);
2331EXFUN (Fplist_put, 3); 2332EXFUN (Fplist_put, 3);
2332EXFUN (Fplist_member, 2); 2333EXFUN (Fplist_member, 2);
2333EXFUN (Frassoc, 2); 2334EXFUN (Frassoc, 2);
diff --git a/src/minibuf.c b/src/minibuf.c
index 6d9402942e6..7aeb0283f2c 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2676,8 +2676,8 @@ elements are deleted. */);
2676 DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case, 2676 DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case,
2677 doc: /* Non-nil means don't consider case significant in completion. 2677 doc: /* Non-nil means don't consider case significant in completion.
2678 2678
2679See also `read-file-name-completion-ignore-case' concerning case significance 2679For file-name completion, the variable `read-file-name-completion-ignore-case'
2680in completion when reading a file name. */); 2680controls the behavior, rather than this variable. */);
2681 completion_ignore_case = 0; 2681 completion_ignore_case = 0;
2682 2682
2683 DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers, 2683 DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers,
diff --git a/src/window.c b/src/window.c
index 976e2b505cf..3f8fa513619 100644
--- a/src/window.c
+++ b/src/window.c
@@ -241,7 +241,8 @@ make_window ()
241 register struct window *p; 241 register struct window *p;
242 242
243 p = allocate_window (); 243 p = allocate_window ();
244 XSETFASTINT (p->sequence_number, ++sequence_number); 244 ++sequence_number;
245 XSETFASTINT (p->sequence_number, sequence_number);
245 XSETFASTINT (p->left_col, 0); 246 XSETFASTINT (p->left_col, 0);
246 XSETFASTINT (p->top_line, 0); 247 XSETFASTINT (p->top_line, 0);
247 XSETFASTINT (p->total_lines, 0); 248 XSETFASTINT (p->total_lines, 0);
@@ -2657,6 +2658,9 @@ shrink_windows (total, size, nchildren, shrinkable,
2657 --shrinkable; 2658 --shrinkable;
2658 total_removed += smallest; 2659 total_removed += smallest;
2659 2660
2661 /* We don't know what the smallest is now. */
2662 smallest = total;
2663
2660 /* Out of for, just remove one window at the time and 2664 /* Out of for, just remove one window at the time and
2661 check again if we have enough space. */ 2665 check again if we have enough space. */
2662 break; 2666 break;
@@ -2681,6 +2685,16 @@ shrink_windows (total, size, nchildren, shrinkable,
2681 that are left and still can be shrunk. */ 2685 that are left and still can be shrunk. */
2682 while (total_shrink > total_removed) 2686 while (total_shrink > total_removed)
2683 { 2687 {
2688 int nonzero_sizes = 0;
2689 int nonzero_idx = -1;
2690
2691 for (i = 0; i < nchildren; ++i)
2692 if (new_sizes[i] > 0)
2693 {
2694 ++nonzero_sizes;
2695 nonzero_idx = i;
2696 }
2697
2684 for (i = 0; i < nchildren; ++i) 2698 for (i = 0; i < nchildren; ++i)
2685 if (new_sizes[i] > min_size) 2699 if (new_sizes[i] > min_size)
2686 { 2700 {
@@ -2691,6 +2705,25 @@ shrink_windows (total, size, nchildren, shrinkable,
2691 check again if we have enough space. */ 2705 check again if we have enough space. */
2692 break; 2706 break;
2693 } 2707 }
2708
2709
2710 /* Special case, only one window left. */
2711 if (nonzero_sizes == 1)
2712 break;
2713 }
2714
2715 /* Any surplus due to rounding, we add to windows that are left. */
2716 while (total_shrink < total_removed)
2717 {
2718 for (i = 0; i < nchildren; ++i)
2719 {
2720 if (new_sizes[i] != 0 && total_shrink < total_removed)
2721 {
2722 ++new_sizes[i];
2723 --total_removed;
2724 break;
2725 }
2726 }
2694 } 2727 }
2695 2728
2696 return new_sizes; 2729 return new_sizes;
@@ -3117,7 +3150,8 @@ selects the buffer of the selected window before each command. */)
3117 w = XWINDOW (window); 3150 w = XWINDOW (window);
3118 w->frozen_window_start_p = 0; 3151 w->frozen_window_start_p = 0;
3119 3152
3120 XSETFASTINT (w->use_time, ++window_select_count); 3153 ++window_select_count;
3154 XSETFASTINT (w->use_time, window_select_count);
3121 if (EQ (window, selected_window)) 3155 if (EQ (window, selected_window))
3122 return window; 3156 return window;
3123 3157
@@ -3608,7 +3642,8 @@ make_dummy_parent (window)
3608 = ((struct Lisp_Vector *)o)->contents[i]; 3642 = ((struct Lisp_Vector *)o)->contents[i];
3609 XSETWINDOW (new, p); 3643 XSETWINDOW (new, p);
3610 3644
3611 XSETFASTINT (p->sequence_number, ++sequence_number); 3645 ++sequence_number;
3646 XSETFASTINT (p->sequence_number, sequence_number);
3612 3647
3613 /* Put new into window structure in place of window */ 3648 /* Put new into window structure in place of window */
3614 replace_window (window, new); 3649 replace_window (window, new);
@@ -4506,7 +4541,7 @@ window_scroll_pixel_based (window, n, whole, noerror)
4506 results for variable height lines. */ 4541 results for variable height lines. */
4507 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); 4542 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
4508 it.current_y = it.last_visible_y; 4543 it.current_y = it.last_visible_y;
4509 move_it_vertically (&it, - window_box_height (w) / 2); 4544 move_it_vertically_backward (&it, window_box_height (w) / 2);
4510 4545
4511 /* The function move_iterator_vertically may move over more than 4546 /* The function move_iterator_vertically may move over more than
4512 the specified y-distance. If it->w is small, e.g. a 4547 the specified y-distance. If it->w is small, e.g. a
@@ -4516,7 +4551,7 @@ window_scroll_pixel_based (window, n, whole, noerror)
4516 if (it.current_y <= 0) 4551 if (it.current_y <= 0)
4517 { 4552 {
4518 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); 4553 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
4519 move_it_vertically (&it, 0); 4554 move_it_vertically_backward (&it, 0);
4520 it.current_y = 0; 4555 it.current_y = 0;
4521 } 4556 }
4522 4557
@@ -5185,7 +5220,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5185 5220
5186 SET_TEXT_POS (pt, PT, PT_BYTE); 5221 SET_TEXT_POS (pt, PT, PT_BYTE);
5187 start_display (&it, w, pt); 5222 start_display (&it, w, pt);
5188 move_it_vertically (&it, - window_box_height (w) / 2); 5223 move_it_vertically_backward (&it, window_box_height (w) / 2);
5189 charpos = IT_CHARPOS (it); 5224 charpos = IT_CHARPOS (it);
5190 bytepos = IT_BYTEPOS (it); 5225 bytepos = IT_BYTEPOS (it);
5191 } 5226 }
@@ -5193,29 +5228,62 @@ and redisplay normally--don't erase and redraw the frame. */)
5193 { 5228 {
5194 struct it it; 5229 struct it it;
5195 struct text_pos pt; 5230 struct text_pos pt;
5196 int y0, y1, h, nlines; 5231 int nlines = - XINT (arg);
5232 int extra_line_spacing;
5233 int h = window_box_height (w);
5197 5234
5198 SET_TEXT_POS (pt, PT, PT_BYTE); 5235 SET_TEXT_POS (pt, PT, PT_BYTE);
5199 start_display (&it, w, pt); 5236 start_display (&it, w, pt);
5200 y0 = it.current_y; 5237
5238 /* Be sure we have the exact height of the full line containing PT. */
5239 move_it_by_lines (&it, 0, 1);
5201 5240
5202 /* The amount of pixels we have to move back is the window 5241 /* The amount of pixels we have to move back is the window
5203 height minus what's displayed in the line containing PT, 5242 height minus what's displayed in the line containing PT,
5204 and the lines below. */ 5243 and the lines below. */
5205 nlines = - XINT (arg) - 1; 5244 it.current_y = 0;
5245 it.vpos = 0;
5206 move_it_by_lines (&it, nlines, 1); 5246 move_it_by_lines (&it, nlines, 1);
5207 5247
5208 y1 = line_bottom_y (&it); 5248 if (it.vpos == nlines)
5249 h -= it.current_y;
5250 else
5251 {
5252 /* Last line has no newline */
5253 h -= line_bottom_y (&it);
5254 it.vpos++;
5255 }
5256
5257 /* Don't reserve space for extra line spacing of last line. */
5258 extra_line_spacing = it.max_extra_line_spacing;
5209 5259
5210 /* If we can't move down NLINES lines because we hit 5260 /* If we can't move down NLINES lines because we hit
5211 the end of the buffer, count in some empty lines. */ 5261 the end of the buffer, count in some empty lines. */
5212 if (it.vpos < nlines) 5262 if (it.vpos < nlines)
5213 y1 += (nlines - it.vpos) * FRAME_LINE_HEIGHT (it.f); 5263 {
5214 5264 nlines -= it.vpos;
5215 h = window_box_height (w) - (y1 - y0); 5265 extra_line_spacing = it.extra_line_spacing;
5266 h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
5267 }
5268 if (h <= 0)
5269 return Qnil;
5216 5270
5271 /* Now find the new top line (starting position) of the window. */
5217 start_display (&it, w, pt); 5272 start_display (&it, w, pt);
5218 move_it_vertically (&it, - h); 5273 it.current_y = 0;
5274 move_it_vertically_backward (&it, h);
5275
5276 /* If extra line spacing is present, we may move too far
5277 back. This causes the last line to be only partially
5278 visible (which triggers redisplay to recenter that line
5279 in the middle), so move forward.
5280 But ignore extra line spacing on last line, as it is not
5281 considered to be part of the visible height of the line.
5282 */
5283 h += extra_line_spacing;
5284 while (-it.current_y > h)
5285 move_it_by_lines (&it, 1, 1);
5286
5219 charpos = IT_CHARPOS (it); 5287 charpos = IT_CHARPOS (it);
5220 bytepos = IT_BYTEPOS (it); 5288 bytepos = IT_BYTEPOS (it);
5221 } 5289 }
@@ -5817,7 +5885,7 @@ save_window_save (window, vector, i)
5817 p = SAVED_WINDOW_N (vector, i); 5885 p = SAVED_WINDOW_N (vector, i);
5818 w = XWINDOW (window); 5886 w = XWINDOW (window);
5819 5887
5820 XSETFASTINT (w->temslot, i++); 5888 XSETFASTINT (w->temslot, i); i++;
5821 p->window = window; 5889 p->window = window;
5822 p->buffer = w->buffer; 5890 p->buffer = w->buffer;
5823 p->left_col = w->left_col; 5891 p->left_col = w->left_col;
diff --git a/src/xdisp.c b/src/xdisp.c
index 5498bbcde00..d4445cfec1a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -265,6 +265,10 @@ int mouse_autoselect_window;
265 265
266int auto_raise_tool_bar_buttons_p; 266int auto_raise_tool_bar_buttons_p;
267 267
268/* Non-zero means to reposition window if cursor line is only partially visible. */
269
270int make_cursor_line_fully_visible_p;
271
268/* Margin around tool bar buttons in pixels. */ 272/* Margin around tool bar buttons in pixels. */
269 273
270Lisp_Object Vtool_bar_button_margin; 274Lisp_Object Vtool_bar_button_margin;
@@ -891,7 +895,7 @@ static void next_overlay_string P_ ((struct it *));
891static void reseat P_ ((struct it *, struct text_pos, int)); 895static void reseat P_ ((struct it *, struct text_pos, int));
892static void reseat_1 P_ ((struct it *, struct text_pos, int)); 896static void reseat_1 P_ ((struct it *, struct text_pos, int));
893static void back_to_previous_visible_line_start P_ ((struct it *)); 897static void back_to_previous_visible_line_start P_ ((struct it *));
894static void reseat_at_previous_visible_line_start P_ ((struct it *)); 898void reseat_at_previous_visible_line_start P_ ((struct it *));
895static void reseat_at_next_visible_line_start P_ ((struct it *, int)); 899static void reseat_at_next_visible_line_start P_ ((struct it *, int));
896static int next_element_from_display_vector P_ ((struct it *)); 900static int next_element_from_display_vector P_ ((struct it *));
897static int next_element_from_string P_ ((struct it *)); 901static int next_element_from_string P_ ((struct it *));
@@ -1788,7 +1792,8 @@ get_glyph_string_clip_rect (s, nr)
1788 1792
1789 /* If drawing a tool-bar window, draw it over the internal border 1793 /* If drawing a tool-bar window, draw it over the internal border
1790 at the top of the window. */ 1794 at the top of the window. */
1791 if (s->w == XWINDOW (s->f->tool_bar_window)) 1795 if (WINDOWP (s->f->tool_bar_window)
1796 && s->w == XWINDOW (s->f->tool_bar_window))
1792 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f); 1797 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1793 } 1798 }
1794 1799
@@ -2078,6 +2083,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
2078 * FRAME_LINE_HEIGHT (it->f)); 2083 * FRAME_LINE_HEIGHT (it->f));
2079 else if (it->f->extra_line_spacing > 0) 2084 else if (it->f->extra_line_spacing > 0)
2080 it->extra_line_spacing = it->f->extra_line_spacing; 2085 it->extra_line_spacing = it->f->extra_line_spacing;
2086 it->max_extra_line_spacing = 0;
2081 } 2087 }
2082 2088
2083 /* If realized faces have been removed, e.g. because of face 2089 /* If realized faces have been removed, e.g. because of face
@@ -4683,7 +4689,7 @@ back_to_previous_visible_line_start (it)
4683 selective display. At the end, update IT's overlay information, 4689 selective display. At the end, update IT's overlay information,
4684 face information etc. */ 4690 face information etc. */
4685 4691
4686static void 4692void
4687reseat_at_previous_visible_line_start (it) 4693reseat_at_previous_visible_line_start (it)
4688 struct it *it; 4694 struct it *it;
4689{ 4695{
@@ -4988,7 +4994,8 @@ get_next_display_element (it)
4988 else if ((it->c < ' ' 4994 else if ((it->c < ' '
4989 ? (it->area != TEXT_AREA 4995 ? (it->area != TEXT_AREA
4990 /* In mode line, treat \n, \t like other crl chars. */ 4996 /* In mode line, treat \n, \t like other crl chars. */
4991 || (it->glyph_row && it->glyph_row->mode_line_p) 4997 || (it->c != '\n'
4998 && it->glyph_row && it->glyph_row->mode_line_p)
4992 || (it->c != '\n' && it->c != '\t')) 4999 || (it->c != '\n' && it->c != '\t'))
4993 : it->multibyte_p ? !CHAR_PRINTABLE_P (it->c) 5000 : it->multibyte_p ? !CHAR_PRINTABLE_P (it->c)
4994 : (it->c >= 127 5001 : (it->c >= 127
@@ -6177,10 +6184,13 @@ move_it_vertically_backward (it, dy)
6177{ 6184{
6178 int nlines, h; 6185 int nlines, h;
6179 struct it it2, it3; 6186 struct it it2, it3;
6180 int start_pos = IT_CHARPOS (*it); 6187 int start_pos;
6181 6188
6189 move_further_back:
6182 xassert (dy >= 0); 6190 xassert (dy >= 0);
6183 6191
6192 start_pos = IT_CHARPOS (*it);
6193
6184 /* Estimate how many newlines we must move back. */ 6194 /* Estimate how many newlines we must move back. */
6185 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f)); 6195 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6186 6196
@@ -6246,13 +6256,13 @@ move_it_vertically_backward (it, dy)
6246 a line height of 13 pixels each, recentering with point 6256 a line height of 13 pixels each, recentering with point
6247 on the bottom line will try to move -39/2 = 19 pixels 6257 on the bottom line will try to move -39/2 = 19 pixels
6248 backward. Try to avoid moving into the first line. */ 6258 backward. Try to avoid moving into the first line. */
6249 && it->current_y - target_y > line_height / 3 * 2 6259 && it->current_y - target_y > line_height * 2 / 3
6250 && IT_CHARPOS (*it) > BEGV) 6260 && IT_CHARPOS (*it) > BEGV)
6251 { 6261 {
6252 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", 6262 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6253 target_y - it->current_y)); 6263 target_y - it->current_y));
6254 move_it_vertically (it, target_y - it->current_y); 6264 dy = it->current_y - target_y;
6255 xassert (IT_CHARPOS (*it) >= BEGV); 6265 goto move_further_back;
6256 } 6266 }
6257 else if (target_y >= it->current_y + line_height 6267 else if (target_y >= it->current_y + line_height
6258 && IT_CHARPOS (*it) < ZV) 6268 && IT_CHARPOS (*it) < ZV)
@@ -6293,7 +6303,7 @@ move_it_vertically (it, dy)
6293{ 6303{
6294 if (dy <= 0) 6304 if (dy <= 0)
6295 move_it_vertically_backward (it, -dy); 6305 move_it_vertically_backward (it, -dy);
6296 else if (dy > 0) 6306 else
6297 { 6307 {
6298 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy)); 6308 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6299 move_it_to (it, ZV, -1, it->current_y + dy, -1, 6309 move_it_to (it, ZV, -1, it->current_y + dy, -1,
@@ -6390,6 +6400,8 @@ move_it_by_lines (it, dvpos, need_y_p)
6390 /* DVPOS == 0 means move to the start of the screen line. */ 6400 /* DVPOS == 0 means move to the start of the screen line. */
6391 move_it_vertically_backward (it, 0); 6401 move_it_vertically_backward (it, 0);
6392 xassert (it->current_x == 0 && it->hpos == 0); 6402 xassert (it->current_x == 0 && it->hpos == 0);
6403 /* Let next call to line_bottom_y calculate real line height */
6404 last_height = 0;
6393 } 6405 }
6394 else if (dvpos > 0) 6406 else if (dvpos > 0)
6395 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS); 6407 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
@@ -6802,6 +6814,7 @@ message3 (m, nbytes, multibyte)
6802 struct gcpro gcpro1; 6814 struct gcpro gcpro1;
6803 6815
6804 GCPRO1 (m); 6816 GCPRO1 (m);
6817 clear_message (1,1);
6805 6818
6806 /* First flush out any partial line written with print. */ 6819 /* First flush out any partial line written with print. */
6807 message_log_maybe_newline (); 6820 message_log_maybe_newline ();
@@ -7534,7 +7547,7 @@ resize_mini_window (w, exact_p)
7534 height = it.current_y + last_height; 7547 height = it.current_y + last_height;
7535 else 7548 else
7536 height = it.current_y + it.max_ascent + it.max_descent; 7549 height = it.current_y + it.max_ascent + it.max_descent;
7537 height -= it.extra_line_spacing; 7550 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7538 height = (height + unit - 1) / unit; 7551 height = (height + unit - 1) / unit;
7539 } 7552 }
7540 7553
@@ -8813,6 +8826,7 @@ display_tool_bar_line (it)
8813 { 8826 {
8814 row->height = row->phys_height = it->last_visible_y - row->y; 8827 row->height = row->phys_height = it->last_visible_y - row->y;
8815 row->ascent = row->phys_ascent = 0; 8828 row->ascent = row->phys_ascent = 0;
8829 row->extra_line_spacing = 0;
8816 } 8830 }
8817 8831
8818 row->full_width_p = 1; 8832 row->full_width_p = 1;
@@ -10981,6 +10995,9 @@ make_cursor_line_fully_visible (w, force_p)
10981 struct glyph_row *row; 10995 struct glyph_row *row;
10982 int window_height; 10996 int window_height;
10983 10997
10998 if (!make_cursor_line_fully_visible_p)
10999 return 1;
11000
10984 /* It's not always possible to find the cursor, e.g, when a window 11001 /* It's not always possible to find the cursor, e.g, when a window
10985 is full of overlay strings. Don't do anything in that case. */ 11002 is full of overlay strings. Don't do anything in that case. */
10986 if (w->cursor.vpos < 0) 11003 if (w->cursor.vpos < 0)
@@ -10990,7 +11007,7 @@ make_cursor_line_fully_visible (w, force_p)
10990 row = MATRIX_ROW (matrix, w->cursor.vpos); 11007 row = MATRIX_ROW (matrix, w->cursor.vpos);
10991 11008
10992 /* If the cursor row is not partially visible, there's nothing to do. */ 11009 /* If the cursor row is not partially visible, there's nothing to do. */
10993 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row)) 11010 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
10994 return 1; 11011 return 1;
10995 11012
10996 /* If the row the cursor is in is taller than the window's height, 11013 /* If the row the cursor is in is taller than the window's height,
@@ -11144,7 +11161,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
11144 { 11161 {
11145 start_display (&it, w, scroll_margin_pos); 11162 start_display (&it, w, scroll_margin_pos);
11146 if (this_scroll_margin) 11163 if (this_scroll_margin)
11147 move_it_vertically (&it, - this_scroll_margin); 11164 move_it_vertically_backward (&it, this_scroll_margin);
11148 if (extra_scroll_margin_lines) 11165 if (extra_scroll_margin_lines)
11149 move_it_by_lines (&it, - extra_scroll_margin_lines, 0); 11166 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11150 scroll_margin_pos = it.current.pos; 11167 scroll_margin_pos = it.current.pos;
@@ -11264,7 +11281,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
11264 if (amount_to_scroll <= 0) 11281 if (amount_to_scroll <= 0)
11265 return SCROLLING_FAILED; 11282 return SCROLLING_FAILED;
11266 11283
11267 move_it_vertically (&it, - amount_to_scroll); 11284 move_it_vertically_backward (&it, amount_to_scroll);
11268 startp = it.current.pos; 11285 startp = it.current.pos;
11269 } 11286 }
11270 } 11287 }
@@ -11568,7 +11585,8 @@ try_cursor_movement (window, startp, scroll_step)
11568 /* if PT is not in the glyph row, give up. */ 11585 /* if PT is not in the glyph row, give up. */
11569 rc = CURSOR_MOVEMENT_MUST_SCROLL; 11586 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11570 } 11587 }
11571 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row)) 11588 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11589 && make_cursor_line_fully_visible_p)
11572 { 11590 {
11573 if (PT == MATRIX_ROW_END_CHARPOS (row) 11591 if (PT == MATRIX_ROW_END_CHARPOS (row)
11574 && !row->ends_at_zv_p 11592 && !row->ends_at_zv_p
@@ -12143,7 +12161,7 @@ redisplay_window (window, just_this_one_p)
12143 if (it.current_y <= 0) 12161 if (it.current_y <= 0)
12144 { 12162 {
12145 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); 12163 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12146 move_it_vertically (&it, 0); 12164 move_it_vertically_backward (&it, 0);
12147 xassert (IT_CHARPOS (it) <= PT); 12165 xassert (IT_CHARPOS (it) <= PT);
12148 it.current_y = 0; 12166 it.current_y = 0;
12149 } 12167 }
@@ -12492,7 +12510,7 @@ try_window_reusing_current_matrix (w)
12492 /* Give up if old or new display is scrolled vertically. We could 12510 /* Give up if old or new display is scrolled vertically. We could
12493 make this function handle this, but right now it doesn't. */ 12511 make this function handle this, but right now it doesn't. */
12494 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 12512 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12495 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row)) 12513 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12496 return 0; 12514 return 0;
12497 12515
12498 /* The variable new_start now holds the new window start. The old 12516 /* The variable new_start now holds the new window start. The old
@@ -12540,7 +12558,7 @@ try_window_reusing_current_matrix (w)
12540 start = start_row->start.pos; 12558 start = start_row->start.pos;
12541 /* If there are no more rows to try, or just one, give up. */ 12559 /* If there are no more rows to try, or just one, give up. */
12542 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 12560 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12543 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row) 12561 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12544 || CHARPOS (start) == ZV) 12562 || CHARPOS (start) == ZV)
12545 { 12563 {
12546 clear_glyph_matrix (w->desired_matrix); 12564 clear_glyph_matrix (w->desired_matrix);
@@ -13609,7 +13627,9 @@ try_window_id (w)
13609 && CHARPOS (start) > BEGV) 13627 && CHARPOS (start) > BEGV)
13610 /* Old redisplay didn't take scroll margin into account at the bottom, 13628 /* Old redisplay didn't take scroll margin into account at the bottom,
13611 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */ 13629 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13612 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y) 13630 || (w->cursor.y + (make_cursor_line_fully_visible_p
13631 ? cursor_height + this_scroll_margin
13632 : 1)) > it.last_visible_y)
13613 { 13633 {
13614 w->cursor.vpos = -1; 13634 w->cursor.vpos = -1;
13615 clear_glyph_matrix (w->desired_matrix); 13635 clear_glyph_matrix (w->desired_matrix);
@@ -14334,6 +14354,7 @@ compute_line_metrics (it)
14334 row->height = it->max_ascent + it->max_descent; 14354 row->height = it->max_ascent + it->max_descent;
14335 row->phys_ascent = it->max_phys_ascent; 14355 row->phys_ascent = it->max_phys_ascent;
14336 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 14356 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14357 row->extra_line_spacing = it->max_extra_line_spacing;
14337 } 14358 }
14338 14359
14339 /* Compute the width of this line. */ 14360 /* Compute the width of this line. */
@@ -14377,6 +14398,7 @@ compute_line_metrics (it)
14377 row->pixel_width -= it->truncation_pixel_width; 14398 row->pixel_width -= it->truncation_pixel_width;
14378 row->ascent = row->phys_ascent = 0; 14399 row->ascent = row->phys_ascent = 0;
14379 row->height = row->phys_height = row->visible_height = 1; 14400 row->height = row->phys_height = row->visible_height = 1;
14401 row->extra_line_spacing = 0;
14380 } 14402 }
14381 14403
14382 /* Compute a hash code for this row. */ 14404 /* Compute a hash code for this row. */
@@ -14713,6 +14735,7 @@ display_line (it)
14713 row->height = it->max_ascent + it->max_descent; 14735 row->height = it->max_ascent + it->max_descent;
14714 row->phys_ascent = it->max_phys_ascent; 14736 row->phys_ascent = it->max_phys_ascent;
14715 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 14737 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14738 row->extra_line_spacing = it->max_extra_line_spacing;
14716 14739
14717 /* Loop generating characters. The loop is left with IT on the next 14740 /* Loop generating characters. The loop is left with IT on the next
14718 character to display. */ 14741 character to display. */
@@ -14778,6 +14801,8 @@ display_line (it)
14778 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 14801 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14779 row->phys_height = max (row->phys_height, 14802 row->phys_height = max (row->phys_height,
14780 it->max_phys_ascent + it->max_phys_descent); 14803 it->max_phys_ascent + it->max_phys_descent);
14804 row->extra_line_spacing = max (row->extra_line_spacing,
14805 it->max_extra_line_spacing);
14781 set_iterator_to_next (it, 1); 14806 set_iterator_to_next (it, 1);
14782 continue; 14807 continue;
14783 } 14808 }
@@ -14806,6 +14831,8 @@ display_line (it)
14806 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 14831 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14807 row->phys_height = max (row->phys_height, 14832 row->phys_height = max (row->phys_height,
14808 it->max_phys_ascent + it->max_phys_descent); 14833 it->max_phys_ascent + it->max_phys_descent);
14834 row->extra_line_spacing = max (row->extra_line_spacing,
14835 it->max_extra_line_spacing);
14809 if (it->current_x - it->pixel_width < it->first_visible_x) 14836 if (it->current_x - it->pixel_width < it->first_visible_x)
14810 row->x = x - it->first_visible_x; 14837 row->x = x - it->first_visible_x;
14811 } 14838 }
@@ -14957,6 +14984,8 @@ display_line (it)
14957 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 14984 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14958 row->phys_height = max (row->phys_height, 14985 row->phys_height = max (row->phys_height,
14959 it->max_phys_ascent + it->max_phys_descent); 14986 it->max_phys_ascent + it->max_phys_descent);
14987 row->extra_line_spacing = max (row->extra_line_spacing,
14988 it->max_extra_line_spacing);
14960 14989
14961 /* End of this display line if row is continued. */ 14990 /* End of this display line if row is continued. */
14962 if (row->continued_p || row->ends_at_zv_p) 14991 if (row->continued_p || row->ends_at_zv_p)
@@ -15584,7 +15613,9 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
15584 { 15613 {
15585 int bytepos = last - lisp_string; 15614 int bytepos = last - lisp_string;
15586 int charpos = string_byte_to_char (elt, bytepos); 15615 int charpos = string_byte_to_char (elt, bytepos);
15587 int endpos = (precision <= 0 ? SCHARS (elt) 15616 int endpos = (precision <= 0
15617 ? string_byte_to_char (elt,
15618 this - lisp_string)
15588 : charpos + nchars); 15619 : charpos + nchars);
15589 15620
15590 n += store_mode_line_string (NULL, 15621 n += store_mode_line_string (NULL,
@@ -15892,7 +15923,7 @@ store_mode_line_string (string, lisp_string, copy_string, field_width, precision
15892 props = mode_line_string_face_prop; 15923 props = mode_line_string_face_prop;
15893 else if (!NILP (mode_line_string_face)) 15924 else if (!NILP (mode_line_string_face))
15894 { 15925 {
15895 Lisp_Object face = Fplist_get (props, Qface); 15926 Lisp_Object face = Fsafe_plist_get (props, Qface);
15896 props = Fcopy_sequence (props); 15927 props = Fcopy_sequence (props);
15897 if (NILP (face)) 15928 if (NILP (face))
15898 face = mode_line_string_face; 15929 face = mode_line_string_face;
@@ -15917,7 +15948,7 @@ store_mode_line_string (string, lisp_string, copy_string, field_width, precision
15917 Lisp_Object face; 15948 Lisp_Object face;
15918 if (NILP (props)) 15949 if (NILP (props))
15919 props = Ftext_properties_at (make_number (0), lisp_string); 15950 props = Ftext_properties_at (make_number (0), lisp_string);
15920 face = Fplist_get (props, Qface); 15951 face = Fsafe_plist_get (props, Qface);
15921 if (NILP (face)) 15952 if (NILP (face))
15922 face = mode_line_string_face; 15953 face = mode_line_string_face;
15923 else 15954 else
@@ -16871,6 +16902,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
16871 row->height = it->max_ascent + it->max_descent; 16902 row->height = it->max_ascent + it->max_descent;
16872 row->phys_ascent = it->max_phys_ascent; 16903 row->phys_ascent = it->max_phys_ascent;
16873 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 16904 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16905 row->extra_line_spacing = it->max_extra_line_spacing;
16874 16906
16875 /* This condition is for the case that we are called with current_x 16907 /* This condition is for the case that we are called with current_x
16876 past last_visible_x. */ 16908 past last_visible_x. */
@@ -16930,6 +16962,8 @@ display_string (string, lisp_string, face_string, face_string_pos,
16930 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 16962 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16931 row->phys_height = max (row->phys_height, 16963 row->phys_height = max (row->phys_height,
16932 it->max_phys_ascent + it->max_phys_descent); 16964 it->max_phys_ascent + it->max_phys_descent);
16965 row->extra_line_spacing = max (row->extra_line_spacing,
16966 it->max_extra_line_spacing);
16933 x += glyph->pixel_width; 16967 x += glyph->pixel_width;
16934 ++i; 16968 ++i;
16935 } 16969 }
@@ -17366,7 +17400,8 @@ init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17366 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); 17400 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17367 17401
17368 /* Display the internal border below the tool-bar window. */ 17402 /* Display the internal border below the tool-bar window. */
17369 if (s->w == XWINDOW (s->f->tool_bar_window)) 17403 if (WINDOWP (s->f->tool_bar_window)
17404 && s->w == XWINDOW (s->f->tool_bar_window))
17370 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f); 17405 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17371 17406
17372 s->ybase = s->y + row->ascent; 17407 s->ybase = s->y + row->ascent;
@@ -18701,14 +18736,14 @@ produce_stretch_glyph (it)
18701 plist = XCDR (it->object); 18736 plist = XCDR (it->object);
18702 18737
18703 /* Compute the width of the stretch. */ 18738 /* Compute the width of the stretch. */
18704 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop)) 18739 if ((prop = Fsafe_plist_get (plist, QCwidth), !NILP (prop))
18705 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0)) 18740 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18706 { 18741 {
18707 /* Absolute width `:width WIDTH' specified and valid. */ 18742 /* Absolute width `:width WIDTH' specified and valid. */
18708 zero_width_ok_p = 1; 18743 zero_width_ok_p = 1;
18709 width = (int)tem; 18744 width = (int)tem;
18710 } 18745 }
18711 else if (prop = Fplist_get (plist, QCrelative_width), 18746 else if (prop = Fsafe_plist_get (plist, QCrelative_width),
18712 NUMVAL (prop) > 0) 18747 NUMVAL (prop) > 0)
18713 { 18748 {
18714 /* Relative width `:relative-width FACTOR' specified and valid. 18749 /* Relative width `:relative-width FACTOR' specified and valid.
@@ -18732,7 +18767,7 @@ produce_stretch_glyph (it)
18732 x_produce_glyphs (&it2); 18767 x_produce_glyphs (&it2);
18733 width = NUMVAL (prop) * it2.pixel_width; 18768 width = NUMVAL (prop) * it2.pixel_width;
18734 } 18769 }
18735 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop)) 18770 else if ((prop = Fsafe_plist_get (plist, QCalign_to), !NILP (prop))
18736 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to)) 18771 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18737 { 18772 {
18738 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p) 18773 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
@@ -18752,13 +18787,13 @@ produce_stretch_glyph (it)
18752 width = 1; 18787 width = 1;
18753 18788
18754 /* Compute height. */ 18789 /* Compute height. */
18755 if ((prop = Fplist_get (plist, QCheight), !NILP (prop)) 18790 if ((prop = Fsafe_plist_get (plist, QCheight), !NILP (prop))
18756 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0)) 18791 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18757 { 18792 {
18758 height = (int)tem; 18793 height = (int)tem;
18759 zero_height_ok_p = 1; 18794 zero_height_ok_p = 1;
18760 } 18795 }
18761 else if (prop = Fplist_get (plist, QCrelative_height), 18796 else if (prop = Fsafe_plist_get (plist, QCrelative_height),
18762 NUMVAL (prop) > 0) 18797 NUMVAL (prop) > 0)
18763 height = FONT_HEIGHT (font) * NUMVAL (prop); 18798 height = FONT_HEIGHT (font) * NUMVAL (prop);
18764 else 18799 else
@@ -18770,7 +18805,7 @@ produce_stretch_glyph (it)
18770 /* Compute percentage of height used for ascent. If 18805 /* Compute percentage of height used for ascent. If
18771 `:ascent ASCENT' is present and valid, use that. Otherwise, 18806 `:ascent ASCENT' is present and valid, use that. Otherwise,
18772 derive the ascent from the font in use. */ 18807 derive the ascent from the font in use. */
18773 if (prop = Fplist_get (plist, QCascent), 18808 if (prop = Fsafe_plist_get (plist, QCascent),
18774 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) 18809 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18775 ascent = height * NUMVAL (prop) / 100.0; 18810 ascent = height * NUMVAL (prop) / 100.0;
18776 else if (!NILP (prop) 18811 else if (!NILP (prop)
@@ -19594,7 +19629,11 @@ x_produce_glyphs (it)
19594 it->current_x += it->pixel_width; 19629 it->current_x += it->pixel_width;
19595 19630
19596 if (extra_line_spacing > 0) 19631 if (extra_line_spacing > 0)
19597 it->descent += extra_line_spacing; 19632 {
19633 it->descent += extra_line_spacing;
19634 if (extra_line_spacing > it->max_extra_line_spacing)
19635 it->max_extra_line_spacing = extra_line_spacing;
19636 }
19598 19637
19599 it->max_ascent = max (it->max_ascent, it->ascent); 19638 it->max_ascent = max (it->max_ascent, it->ascent);
19600 it->max_descent = max (it->max_descent, it->descent); 19639 it->max_descent = max (it->max_descent, it->descent);
@@ -20177,6 +20216,11 @@ erase_phys_cursor (w)
20177 if (!cursor_row->enabled_p) 20216 if (!cursor_row->enabled_p)
20178 goto mark_cursor_off; 20217 goto mark_cursor_off;
20179 20218
20219 /* If line spacing is > 0, old cursor may only be partially visible in
20220 window after split-window. So adjust visible height. */
20221 cursor_row->visible_height = min (cursor_row->visible_height,
20222 window_text_bottom_y (w) - cursor_row->y);
20223
20180 /* If row is completely invisible, don't attempt to delete a cursor which 20224 /* If row is completely invisible, don't attempt to delete a cursor which
20181 isn't there. This can happen if cursor is at top of a window, and 20225 isn't there. This can happen if cursor is at top of a window, and
20182 we switch to a buffer with a header line in that window. */ 20226 we switch to a buffer with a header line in that window. */
@@ -21010,7 +21054,7 @@ note_mode_line_or_margin_highlight (w, x, y, area)
21010 if (IMAGEP (object)) 21054 if (IMAGEP (object))
21011 { 21055 {
21012 Lisp_Object image_map, hotspot; 21056 Lisp_Object image_map, hotspot;
21013 if ((image_map = Fplist_get (XCDR (object), QCmap), 21057 if ((image_map = Fsafe_plist_get (XCDR (object), QCmap),
21014 !NILP (image_map)) 21058 !NILP (image_map))
21015 && (hotspot = find_hot_spot (image_map, dx, dy), 21059 && (hotspot = find_hot_spot (image_map, dx, dy),
21016 CONSP (hotspot)) 21060 CONSP (hotspot))
@@ -21022,12 +21066,14 @@ note_mode_line_or_margin_highlight (w, x, y, area)
21022 /* Could check AREA_ID to see if we enter/leave this hot-spot. 21066 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21023 If so, we could look for mouse-enter, mouse-leave 21067 If so, we could look for mouse-enter, mouse-leave
21024 properties in PLIST (and do something...). */ 21068 properties in PLIST (and do something...). */
21025 if ((plist = XCDR (hotspot), CONSP (plist))) 21069 hotspot = XCDR (hotspot);
21070 if (CONSP (hotspot)
21071 && (plist = XCAR (hotspot), CONSP (plist)))
21026 { 21072 {
21027 pointer = Fplist_get (plist, Qpointer); 21073 pointer = Fsafe_plist_get (plist, Qpointer);
21028 if (NILP (pointer)) 21074 if (NILP (pointer))
21029 pointer = Qhand; 21075 pointer = Qhand;
21030 help = Fplist_get (plist, Qhelp_echo); 21076 help = Fsafe_plist_get (plist, Qhelp_echo);
21031 if (!NILP (help)) 21077 if (!NILP (help))
21032 { 21078 {
21033 help_echo_string = help; 21079 help_echo_string = help;
@@ -21038,7 +21084,7 @@ note_mode_line_or_margin_highlight (w, x, y, area)
21038 } 21084 }
21039 } 21085 }
21040 if (NILP (pointer)) 21086 if (NILP (pointer))
21041 pointer = Fplist_get (XCDR (object), QCpointer); 21087 pointer = Fsafe_plist_get (XCDR (object), QCpointer);
21042 } 21088 }
21043 } 21089 }
21044 21090
@@ -21189,7 +21235,7 @@ note_mouse_highlight (f, x, y)
21189 if (img != NULL && IMAGEP (img->spec)) 21235 if (img != NULL && IMAGEP (img->spec))
21190 { 21236 {
21191 Lisp_Object image_map, hotspot; 21237 Lisp_Object image_map, hotspot;
21192 if ((image_map = Fplist_get (XCDR (img->spec), QCmap), 21238 if ((image_map = Fsafe_plist_get (XCDR (img->spec), QCmap),
21193 !NILP (image_map)) 21239 !NILP (image_map))
21194 && (hotspot = find_hot_spot (image_map, 21240 && (hotspot = find_hot_spot (image_map,
21195 glyph->slice.x + dx, 21241 glyph->slice.x + dx,
@@ -21203,12 +21249,14 @@ note_mouse_highlight (f, x, y)
21203 /* Could check AREA_ID to see if we enter/leave this hot-spot. 21249 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21204 If so, we could look for mouse-enter, mouse-leave 21250 If so, we could look for mouse-enter, mouse-leave
21205 properties in PLIST (and do something...). */ 21251 properties in PLIST (and do something...). */
21206 if ((plist = XCDR (hotspot), CONSP (plist))) 21252 hotspot = XCDR (hotspot);
21253 if (CONSP (hotspot)
21254 && (plist = XCAR (hotspot), CONSP (plist)))
21207 { 21255 {
21208 pointer = Fplist_get (plist, Qpointer); 21256 pointer = Fsafe_plist_get (plist, Qpointer);
21209 if (NILP (pointer)) 21257 if (NILP (pointer))
21210 pointer = Qhand; 21258 pointer = Qhand;
21211 help_echo_string = Fplist_get (plist, Qhelp_echo); 21259 help_echo_string = Fsafe_plist_get (plist, Qhelp_echo);
21212 if (!NILP (help_echo_string)) 21260 if (!NILP (help_echo_string))
21213 { 21261 {
21214 help_echo_window = window; 21262 help_echo_window = window;
@@ -21218,7 +21266,7 @@ note_mouse_highlight (f, x, y)
21218 } 21266 }
21219 } 21267 }
21220 if (NILP (pointer)) 21268 if (NILP (pointer))
21221 pointer = Fplist_get (XCDR (img->spec), QCpointer); 21269 pointer = Fsafe_plist_get (XCDR (img->spec), QCpointer);
21222 } 21270 }
21223 } 21271 }
21224 21272
@@ -22515,6 +22563,10 @@ otherwise. */);
22515 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */); 22563 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22516 auto_raise_tool_bar_buttons_p = 1; 22564 auto_raise_tool_bar_buttons_p = 1;
22517 22565
22566 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22567 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22568 make_cursor_line_fully_visible_p = 1;
22569
22518 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin, 22570 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22519 doc: /* *Margin around tool-bar buttons in pixels. 22571 doc: /* *Margin around tool-bar buttons in pixels.
22520If an integer, use that for both horizontal and vertical margins. 22572If an integer, use that for both horizontal and vertical margins.
diff --git a/src/xfns.c b/src/xfns.c
index 46bce6536c8..1f9098b2d24 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5089,6 +5089,23 @@ file_dialog_unmap_cb (widget, client_data, call_data)
5089 *result = XmCR_CANCEL; 5089 *result = XmCR_CANCEL;
5090} 5090}
5091 5091
5092static Lisp_Object
5093clean_up_file_dialog (arg)
5094 Lisp_Object arg;
5095{
5096 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
5097 Widget dialog = (Widget) p->pointer;
5098
5099 /* Clean up. */
5100 BLOCK_INPUT;
5101 XtUnmanageChild (dialog);
5102 XtDestroyWidget (dialog);
5103 x_menu_set_in_use (0);
5104 UNBLOCK_INPUT;
5105
5106 return Qnil;
5107}
5108
5092 5109
5093DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, 5110DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5094 doc: /* Read file name, prompting with PROMPT in directory DIR. 5111 doc: /* Read file name, prompting with PROMPT in directory DIR.
@@ -5110,6 +5127,10 @@ or directory must exist. ONLY-DIR-P is ignored." */)
5110 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 5127 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5111 5128
5112 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); 5129 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5130
5131 if (popup_activated ())
5132 error ("Trying to use a menu from within a menu-entry");
5133
5113 CHECK_STRING (prompt); 5134 CHECK_STRING (prompt);
5114 CHECK_STRING (dir); 5135 CHECK_STRING (dir);
5115 5136
@@ -5192,13 +5213,17 @@ or directory must exist. ONLY-DIR-P is ignored." */)
5192 XmStringFree (default_xmstring); 5213 XmStringFree (default_xmstring);
5193 } 5214 }
5194 5215
5216 record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0));
5217
5195 /* Process events until the user presses Cancel or OK. */ 5218 /* Process events until the user presses Cancel or OK. */
5219 x_menu_set_in_use (1);
5196 result = 0; 5220 result = 0;
5197 while (result == 0) 5221 while (result == 0)
5198 { 5222 {
5199 XEvent event; 5223 XEvent event;
5224 x_menu_wait_for_event (0);
5200 XtAppNextEvent (Xt_app_con, &event); 5225 XtAppNextEvent (Xt_app_con, &event);
5201 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f) ); 5226 (void) x_dispatch_event (&event, FRAME_X_DISPLAY (f));
5202 } 5227 }
5203 5228
5204 /* Get the result. */ 5229 /* Get the result. */
@@ -5216,9 +5241,6 @@ or directory must exist. ONLY-DIR-P is ignored." */)
5216 else 5241 else
5217 file = Qnil; 5242 file = Qnil;
5218 5243
5219 /* Clean up. */
5220 XtUnmanageChild (dialog);
5221 XtDestroyWidget (dialog);
5222 UNBLOCK_INPUT; 5244 UNBLOCK_INPUT;
5223 UNGCPRO; 5245 UNGCPRO;
5224 5246
@@ -5233,6 +5255,15 @@ or directory must exist. ONLY-DIR-P is ignored." */)
5233 5255
5234#ifdef USE_GTK 5256#ifdef USE_GTK
5235 5257
5258static Lisp_Object
5259clean_up_dialog (arg)
5260 Lisp_Object arg;
5261{
5262 x_menu_set_in_use (0);
5263
5264 return Qnil;
5265}
5266
5236DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, 5267DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5237 doc: /* Read file name, prompting with PROMPT in directory DIR. 5268 doc: /* Read file name, prompting with PROMPT in directory DIR.
5238Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file 5269Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
@@ -5245,16 +5276,21 @@ directories. */)
5245 FRAME_PTR f = SELECTED_FRAME (); 5276 FRAME_PTR f = SELECTED_FRAME ();
5246 char *fn; 5277 char *fn;
5247 Lisp_Object file = Qnil; 5278 Lisp_Object file = Qnil;
5248 int count = specpdl_ptr - specpdl; 5279 int count = SPECPDL_INDEX ();
5249 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 5280 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5250 char *cdef_file; 5281 char *cdef_file;
5251 5282
5252 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); 5283 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5284
5285 if (popup_activated ())
5286 error ("Trying to use a menu from within a menu-entry");
5287
5253 CHECK_STRING (prompt); 5288 CHECK_STRING (prompt);
5254 CHECK_STRING (dir); 5289 CHECK_STRING (dir);
5255 5290
5256 /* Prevent redisplay. */ 5291 /* Prevent redisplay. */
5257 specbind (Qinhibit_redisplay, Qt); 5292 specbind (Qinhibit_redisplay, Qt);
5293 record_unwind_protect (clean_up_dialog, Qnil);
5258 5294
5259 BLOCK_INPUT; 5295 BLOCK_INPUT;
5260 5296
diff --git a/src/xmenu.c b/src/xmenu.c
index f7e24e66838..6899b91ebd7 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */
48#include "buffer.h" 48#include "buffer.h"
49#include "charset.h" 49#include "charset.h"
50#include "coding.h" 50#include "coding.h"
51#include "sysselect.h"
51 52
52#ifdef MSDOS 53#ifdef MSDOS
53#include "msdos.h" 54#include "msdos.h"
@@ -157,8 +158,6 @@ static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
157static void list_of_panes P_ ((Lisp_Object)); 158static void list_of_panes P_ ((Lisp_Object));
158static void list_of_items P_ ((Lisp_Object)); 159static void list_of_items P_ ((Lisp_Object));
159 160
160extern EMACS_TIME timer_check P_ ((int));
161
162 161
163/* This holds a Lisp vector that holds the results of decoding 162/* This holds a Lisp vector that holds the results of decoding
164 the keymaps or alist-of-alists that specify a menu. 163 the keymaps or alist-of-alists that specify a menu.
@@ -289,7 +288,7 @@ finish_menu_items ()
289 288
290static Lisp_Object 289static Lisp_Object
291unuse_menu_items (dummy) 290unuse_menu_items (dummy)
292 int dummy; 291 Lisp_Object dummy;
293{ 292{
294 return menu_items_inuse = Qnil; 293 return menu_items_inuse = Qnil;
295} 294}
@@ -525,7 +524,7 @@ single_menu_item (key, item, dummy, skp_v)
525 return; /* Not a menu item. */ 524 return; /* Not a menu item. */
526 525
527 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; 526 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
528 527
529 if (skp->notreal) 528 if (skp->notreal)
530 { 529 {
531 /* We don't want to make a menu, just traverse the keymaps to 530 /* We don't want to make a menu, just traverse the keymaps to
@@ -1099,7 +1098,7 @@ on the left of the dialog box and all following items on the right.
1099 the dialog. Also, the lesstif/motif version crashes if there are 1098 the dialog. Also, the lesstif/motif version crashes if there are
1100 no buttons. */ 1099 no buttons. */
1101 contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil)); 1100 contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
1102 1101
1103 list_of_panes (Fcons (contents, Qnil)); 1102 list_of_panes (Fcons (contents, Qnil));
1104 1103
1105 /* Display them in a dialog box. */ 1104 /* Display them in a dialog box. */
@@ -1115,9 +1114,75 @@ on the left of the dialog box and all following items on the right.
1115 } 1114 }
1116#endif 1115#endif
1117} 1116}
1117
1118
1119#ifndef MSDOS
1120
1121/* Set menu_items_inuse so no other popup menu or dialog is created. */
1122
1123void
1124x_menu_set_in_use (in_use)
1125 int in_use;
1126{
1127 menu_items_inuse = in_use ? Qt : Qnil;
1128 popup_activated_flag = in_use;
1129}
1130
1131/* Wait for an X event to arrive or for a timer to expire. */
1132
1133void
1134x_menu_wait_for_event (void *data)
1135{
1136 extern EMACS_TIME timer_check P_ ((int));
1137
1138 /* Another way to do this is to register a timer callback, that can be
1139 done in GTK and Xt. But we have to do it like this when using only X
1140 anyway, and with callbacks we would have three variants for timer handling
1141 instead of the small ifdefs below. */
1142
1143 while (
1144#ifdef USE_X_TOOLKIT
1145 ! XtAppPending (Xt_app_con)
1146#elif defined USE_GTK
1147 ! gtk_events_pending ()
1148#else
1149 ! XPending ((Display*) data)
1150#endif
1151 )
1152 {
1153 EMACS_TIME next_time = timer_check (1);
1154 long secs = EMACS_SECS (next_time);
1155 long usecs = EMACS_USECS (next_time);
1156 SELECT_TYPE read_fds;
1157 struct x_display_info *dpyinfo;
1158 int n = 0;
1159
1160 FD_ZERO (&read_fds);
1161 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
1162 {
1163 int fd = ConnectionNumber (dpyinfo->display);
1164 FD_SET (fd, &read_fds);
1165 if (fd > n) n = fd;
1166 }
1167
1168 if (secs < 0 || (secs == 0 && usecs == 0))
1169 {
1170 /* Sometimes timer_check returns -1 (no timers) even if there are
1171 timers. So do a timeout anyway. */
1172 EMACS_SET_SECS (next_time, 1);
1173 EMACS_SET_USECS (next_time, 0);
1174 }
1175
1176 select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, &next_time);
1177 }
1178}
1179#endif /* ! MSDOS */
1180
1118 1181
1119#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 1182#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1120 1183
1184#ifdef USE_X_TOOLKIT
1185
1121/* Loop in Xt until the menu pulldown or dialog popup has been 1186/* Loop in Xt until the menu pulldown or dialog popup has been
1122 popped down (deactivated). This is used for x-popup-menu 1187 popped down (deactivated). This is used for x-popup-menu
1123 and x-popup-dialog; it is not used for the menu bar. 1188 and x-popup-dialog; it is not used for the menu bar.
@@ -1127,7 +1192,6 @@ on the left of the dialog box and all following items on the right.
1127 NOTE: All calls to popup_get_selection should be protected 1192 NOTE: All calls to popup_get_selection should be protected
1128 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ 1193 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
1129 1194
1130#ifdef USE_X_TOOLKIT
1131static void 1195static void
1132popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress) 1196popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1133 XEvent *initial_event; 1197 XEvent *initial_event;
@@ -1140,17 +1204,16 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1140 1204
1141 while (popup_activated_flag) 1205 while (popup_activated_flag)
1142 { 1206 {
1143 /* If we have no events to run, consider timers. */
1144 if (do_timers && !XtAppPending (Xt_app_con))
1145 timer_check (1);
1146
1147 if (initial_event) 1207 if (initial_event)
1148 { 1208 {
1149 event = *initial_event; 1209 event = *initial_event;
1150 initial_event = 0; 1210 initial_event = 0;
1151 } 1211 }
1152 else 1212 else
1153 XtAppNextEvent (Xt_app_con, &event); 1213 {
1214 if (do_timers) x_menu_wait_for_event (0);
1215 XtAppNextEvent (Xt_app_con, &event);
1216 }
1154 1217
1155 /* Make sure we don't consider buttons grabbed after menu goes. 1218 /* Make sure we don't consider buttons grabbed after menu goes.
1156 And make sure to deactivate for any ButtonRelease, 1219 And make sure to deactivate for any ButtonRelease,
@@ -1195,14 +1258,18 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1195#ifdef USE_GTK 1258#ifdef USE_GTK
1196/* Loop util popup_activated_flag is set to zero in a callback. 1259/* Loop util popup_activated_flag is set to zero in a callback.
1197 Used for popup menus and dialogs. */ 1260 Used for popup menus and dialogs. */
1261
1198static void 1262static void
1199popup_widget_loop () 1263popup_widget_loop (do_timers, widget)
1264 int do_timers;
1265 GtkWidget *widget;
1200{ 1266{
1201 ++popup_activated_flag; 1267 ++popup_activated_flag;
1202 1268
1203 /* Process events in the Gtk event loop until done. */ 1269 /* Process events in the Gtk event loop until done. */
1204 while (popup_activated_flag) 1270 while (popup_activated_flag)
1205 { 1271 {
1272 if (do_timers) x_menu_wait_for_event (0);
1206 gtk_main_iteration (); 1273 gtk_main_iteration ();
1207 } 1274 }
1208} 1275}
@@ -2329,7 +2396,7 @@ menu_position_func (menu, x, y, push_in, user_data)
2329 GtkRequisition req; 2396 GtkRequisition req;
2330 int disp_width = FRAME_X_DISPLAY_INFO (data->f)->width; 2397 int disp_width = FRAME_X_DISPLAY_INFO (data->f)->width;
2331 int disp_height = FRAME_X_DISPLAY_INFO (data->f)->height; 2398 int disp_height = FRAME_X_DISPLAY_INFO (data->f)->height;
2332 2399
2333 *x = data->x; 2400 *x = data->x;
2334 *y = data->y; 2401 *y = data->y;
2335 2402
@@ -2353,6 +2420,19 @@ popup_selection_callback (widget, client_data)
2353 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; 2420 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
2354} 2421}
2355 2422
2423static Lisp_Object
2424pop_down_menu (arg)
2425 Lisp_Object arg;
2426{
2427 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
2428
2429 popup_activated_flag = 0;
2430 BLOCK_INPUT;
2431 gtk_widget_destroy (GTK_WIDGET (p->pointer));
2432 UNBLOCK_INPUT;
2433 return Qnil;
2434}
2435
2356/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the 2436/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
2357 menu pops down. 2437 menu pops down.
2358 menu_item_selection will be set to the selection. */ 2438 menu_item_selection will be set to the selection. */
@@ -2368,6 +2448,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2368 GtkWidget *menu; 2448 GtkWidget *menu;
2369 GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */ 2449 GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */
2370 struct next_popup_x_y popup_x_y; 2450 struct next_popup_x_y popup_x_y;
2451 int specpdl_count = SPECPDL_INDEX ();
2371 2452
2372 xg_crazy_callback_abort = 1; 2453 xg_crazy_callback_abort = 1;
2373 menu = xg_create_widget ("popup", first_wv->name, f, first_wv, 2454 menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
@@ -2398,13 +2479,15 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2398 gtk_widget_show_all (menu); 2479 gtk_widget_show_all (menu);
2399 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0); 2480 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
2400 2481
2482 record_unwind_protect (pop_down_menu, make_save_value (menu, 0));
2483
2401 /* Set this to one. popup_widget_loop increases it by one, so it becomes 2484 /* Set this to one. popup_widget_loop increases it by one, so it becomes
2402 two. show_help_echo uses this to detect popup menus. */ 2485 two. show_help_echo uses this to detect popup menus. */
2403 popup_activated_flag = 1; 2486 popup_activated_flag = 1;
2404 /* Process events that apply to the menu. */ 2487 /* Process events that apply to the menu. */
2405 popup_widget_loop (); 2488 popup_widget_loop (1, menu);
2406 2489
2407 gtk_widget_destroy (menu); 2490 unbind_to (specpdl_count, Qnil);
2408 2491
2409 /* Must reset this manually because the button release event is not passed 2492 /* Must reset this manually because the button release event is not passed
2410 to Emacs event loop. */ 2493 to Emacs event loop. */
@@ -2432,6 +2515,24 @@ popup_selection_callback (widget, id, client_data)
2432 menu_item_selection = (Lisp_Object *) client_data; 2515 menu_item_selection = (Lisp_Object *) client_data;
2433} 2516}
2434 2517
2518/* ARG is the LWLIB ID of the dialog box, represented
2519 as a Lisp object as (HIGHPART . LOWPART). */
2520
2521static Lisp_Object
2522pop_down_menu (arg)
2523 Lisp_Object arg;
2524{
2525 LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
2526 | XINT (XCDR (arg)));
2527
2528 BLOCK_INPUT;
2529 lw_destroy_all_widgets (id);
2530 UNBLOCK_INPUT;
2531 popup_activated_flag = 0;
2532
2533 return Qnil;
2534}
2535
2435/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the 2536/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
2436 menu pops down. 2537 menu pops down.
2437 menu_item_selection will be set to the selection. */ 2538 menu_item_selection will be set to the selection. */
@@ -2488,15 +2589,19 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2488 /* Display the menu. */ 2589 /* Display the menu. */
2489 lw_popup_menu (menu, (XEvent *) &dummy); 2590 lw_popup_menu (menu, (XEvent *) &dummy);
2490 popup_activated_flag = 1; 2591 popup_activated_flag = 1;
2592
2593 {
2594 int fact = 4 * sizeof (LWLIB_ID);
2595 int specpdl_count = SPECPDL_INDEX ();
2596 record_unwind_protect (pop_down_menu,
2597 Fcons (make_number (menu_id >> (fact)),
2598 make_number (menu_id & ~(-1 << (fact)))));
2491 2599
2492 /* Process events that apply to the menu. */ 2600 /* Process events that apply to the menu. */
2493 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0, 0); 2601 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0);
2494 2602
2495 /* fp turned off the following statement and wrote a comment 2603 unbind_to (specpdl_count, Qnil);
2496 that it is unnecessary--that the menu has already disappeared. 2604 }
2497 Nowadays the menu disappears ok, all right, but
2498 we need to delete the widgets or multiple ones will pile up. */
2499 lw_destroy_all_widgets (menu_id);
2500} 2605}
2501 2606
2502#endif /* not USE_GTK */ 2607#endif /* not USE_GTK */
@@ -2807,13 +2912,16 @@ create_and_show_dialog (f, first_wv)
2807 2912
2808 if (menu) 2913 if (menu)
2809 { 2914 {
2915 int specpdl_count = SPECPDL_INDEX ();
2916 record_unwind_protect (pop_down_menu, make_save_value (menu, 0));
2917
2810 /* Display the menu. */ 2918 /* Display the menu. */
2811 gtk_widget_show_all (menu); 2919 gtk_widget_show_all (menu);
2812 2920
2813 /* Process events that apply to the menu. */ 2921 /* Process events that apply to the menu. */
2814 popup_widget_loop (); 2922 popup_widget_loop (1, menu);
2815 2923
2816 gtk_widget_destroy (menu); 2924 unbind_to (specpdl_count, Qnil);
2817 } 2925 }
2818} 2926}
2819 2927
@@ -2836,23 +2944,6 @@ dialog_selection_callback (widget, id, client_data)
2836} 2944}
2837 2945
2838 2946
2839/* ARG is the LWLIB ID of the dialog box, represented
2840 as a Lisp object as (HIGHPART . LOWPART). */
2841
2842Lisp_Object
2843xdialog_show_unwind (arg)
2844 Lisp_Object arg;
2845{
2846 LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
2847 | XINT (XCDR (arg)));
2848 BLOCK_INPUT;
2849 lw_destroy_all_widgets (id);
2850 UNBLOCK_INPUT;
2851 popup_activated_flag = 0;
2852 return Qnil;
2853}
2854
2855
2856/* Pop up the dialog for frame F defined by FIRST_WV and loop until the 2947/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
2857 dialog pops down. 2948 dialog pops down.
2858 menu_item_selection will be set to the selection. */ 2949 menu_item_selection will be set to the selection. */
@@ -2880,7 +2971,7 @@ create_and_show_dialog (f, first_wv)
2880 int fact = 4 * sizeof (LWLIB_ID); 2971 int fact = 4 * sizeof (LWLIB_ID);
2881 2972
2882 /* xdialog_show_unwind is responsible for popping the dialog box down. */ 2973 /* xdialog_show_unwind is responsible for popping the dialog box down. */
2883 record_unwind_protect (xdialog_show_unwind, 2974 record_unwind_protect (pop_down_menu,
2884 Fcons (make_number (dialog_id >> (fact)), 2975 Fcons (make_number (dialog_id >> (fact)),
2885 make_number (dialog_id & ~(-1 << (fact))))); 2976 make_number (dialog_id & ~(-1 << (fact)))));
2886 2977
@@ -3113,6 +3204,41 @@ menu_help_callback (help_string, pane, item)
3113 Qnil, menu_object, make_number (item), 1); 3204 Qnil, menu_object, make_number (item), 1);
3114} 3205}
3115 3206
3207static Lisp_Object
3208pop_down_menu (arg)
3209 Lisp_Object arg;
3210{
3211 struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg));
3212 struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg));
3213
3214 FRAME_PTR f = p1->pointer;
3215 XMenu *menu = p2->pointer;
3216
3217 BLOCK_INPUT;
3218#ifndef MSDOS
3219 XUngrabPointer (FRAME_X_DISPLAY (f), CurrentTime);
3220 XUngrabKeyboard (FRAME_X_DISPLAY (f), CurrentTime);
3221#endif
3222 XMenuDestroy (FRAME_X_DISPLAY (f), menu);
3223
3224#ifdef HAVE_X_WINDOWS
3225 /* Assume the mouse has moved out of the X window.
3226 If it has actually moved in, we will get an EnterNotify. */
3227 x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
3228
3229 /* State that no mouse buttons are now held.
3230 (The oldXMenu code doesn't track this info for us.)
3231 That is not necessarily true, but the fiction leads to reasonable
3232 results, and it is a pain to ask which are actually held now. */
3233 FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
3234
3235#endif /* HAVE_X_WINDOWS */
3236
3237 UNBLOCK_INPUT;
3238
3239 return Qnil;
3240}
3241
3116 3242
3117static Lisp_Object 3243static Lisp_Object
3118xmenu_show (f, x, y, for_click, keymaps, title, error) 3244xmenu_show (f, x, y, for_click, keymaps, title, error)
@@ -3134,6 +3260,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3134 int maxwidth; 3260 int maxwidth;
3135 int dummy_int; 3261 int dummy_int;
3136 unsigned int dummy_uint; 3262 unsigned int dummy_uint;
3263 int specpdl_count = SPECPDL_INDEX ();
3137 3264
3138 *error = 0; 3265 *error = 0;
3139 if (menu_items_n_panes == 0) 3266 if (menu_items_n_panes == 0)
@@ -3323,19 +3450,20 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3323 XMenuSetFreeze (menu, TRUE); 3450 XMenuSetFreeze (menu, TRUE);
3324 pane = selidx = 0; 3451 pane = selidx = 0;
3325 3452
3453#ifndef MSDOS
3454 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
3455#endif
3456
3457 record_unwind_protect (pop_down_menu,
3458 Fcons (make_save_value (f, 0),
3459 make_save_value (menu, 0)));
3460
3326 /* Help display under X won't work because XMenuActivate contains 3461 /* Help display under X won't work because XMenuActivate contains
3327 a loop that doesn't give Emacs a chance to process it. */ 3462 a loop that doesn't give Emacs a chance to process it. */
3328 menu_help_frame = f; 3463 menu_help_frame = f;
3329 status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, 3464 status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
3330 x, y, ButtonReleaseMask, &datap, 3465 x, y, ButtonReleaseMask, &datap,
3331 menu_help_callback); 3466 menu_help_callback);
3332
3333
3334#ifdef HAVE_X_WINDOWS
3335 /* Assume the mouse has moved out of the X window.
3336 If it has actually moved in, we will get an EnterNotify. */
3337 x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
3338#endif
3339 3467
3340 switch (status) 3468 switch (status)
3341 { 3469 {
@@ -3386,15 +3514,8 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3386 entry = Qnil; 3514 entry = Qnil;
3387 break; 3515 break;
3388 } 3516 }
3389 XMenuDestroy (FRAME_X_DISPLAY (f), menu);
3390 3517
3391#ifdef HAVE_X_WINDOWS 3518 unbind_to (specpdl_count, Qnil);
3392 /* State that no mouse buttons are now held.
3393 (The oldXMenu code doesn't track this info for us.)
3394 That is not necessarily true, but the fiction leads to reasonable
3395 results, and it is a pain to ask which are actually held now. */
3396 FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
3397#endif
3398 3519
3399 return entry; 3520 return entry;
3400} 3521}
diff --git a/src/xterm.h b/src/xterm.h
index ffd7e31f297..8c90621f79b 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1072,6 +1072,8 @@ extern void x_free_dpy_colors P_ ((Display *, Screen *, Colormap,
1072 1072
1073/* Defined in xmenu.c */ 1073/* Defined in xmenu.c */
1074 1074
1075extern void x_menu_set_in_use P_ ((int));
1076extern void x_menu_wait_for_event P_ ((void *data));
1075extern void x_activate_menubar P_ ((struct frame *)); 1077extern void x_activate_menubar P_ ((struct frame *));
1076extern int popup_activated P_ ((void)); 1078extern int popup_activated P_ ((void));
1077extern void initialize_frame_menubar P_ ((struct frame *)); 1079extern void initialize_frame_menubar P_ ((struct frame *));