diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 1403 | ||||
| -rw-r--r-- | src/Makefile.in | 8 | ||||
| -rw-r--r-- | src/alloc.c | 53 | ||||
| -rw-r--r-- | src/atimer.c | 33 | ||||
| -rw-r--r-- | src/atimer.h | 8 | ||||
| -rw-r--r-- | src/bidi.c | 39 | ||||
| -rw-r--r-- | src/buffer.c | 136 | ||||
| -rw-r--r-- | src/buffer.h | 30 | ||||
| -rw-r--r-- | src/callint.c | 11 | ||||
| -rw-r--r-- | src/callproc.c | 840 | ||||
| -rw-r--r-- | src/casefiddle.c | 2 | ||||
| -rw-r--r-- | src/casetab.c | 9 | ||||
| -rw-r--r-- | src/category.c | 8 | ||||
| -rw-r--r-- | src/character.c | 18 | ||||
| -rw-r--r-- | src/cmds.c | 20 | ||||
| -rw-r--r-- | src/coding.c | 5 | ||||
| -rw-r--r-- | src/coding.h | 2 | ||||
| -rw-r--r-- | src/composite.h | 6 | ||||
| -rw-r--r-- | src/data.c | 13 | ||||
| -rw-r--r-- | src/decompress.c | 232 | ||||
| -rw-r--r-- | src/dispextern.h | 175 | ||||
| -rw-r--r-- | src/dispnew.c | 218 | ||||
| -rw-r--r-- | src/doc.c | 2 | ||||
| -rw-r--r-- | src/editfns.c | 92 | ||||
| -rw-r--r-- | src/emacs.c | 10 | ||||
| -rw-r--r-- | src/emacsgtkfixed.c | 4 | ||||
| -rw-r--r-- | src/emacsgtkfixed.h | 2 | ||||
| -rw-r--r-- | src/eval.c | 31 | ||||
| -rw-r--r-- | src/fileio.c | 264 | ||||
| -rw-r--r-- | src/filelock.c | 33 | ||||
| -rw-r--r-- | src/font.c | 50 | ||||
| -rw-r--r-- | src/font.h | 8 | ||||
| -rw-r--r-- | src/fontset.c | 13 | ||||
| -rw-r--r-- | src/fontset.h | 3 | ||||
| -rw-r--r-- | src/frame.c | 132 | ||||
| -rw-r--r-- | src/frame.h | 49 | ||||
| -rw-r--r-- | src/fringe.c | 2 | ||||
| -rw-r--r-- | src/gtkutil.c | 124 | ||||
| -rw-r--r-- | src/gtkutil.h | 2 | ||||
| -rw-r--r-- | src/image.c | 399 | ||||
| -rw-r--r-- | src/indent.c | 44 | ||||
| -rw-r--r-- | src/insdel.c | 36 | ||||
| -rw-r--r-- | src/intervals.c | 12 | ||||
| -rw-r--r-- | src/keyboard.c | 129 | ||||
| -rw-r--r-- | src/keyboard.h | 14 | ||||
| -rw-r--r-- | src/keymap.c | 3 | ||||
| -rw-r--r-- | src/lisp.h | 84 | ||||
| -rw-r--r-- | src/lisp.mk | 1 | ||||
| -rw-r--r-- | src/lread.c | 10 | ||||
| -rw-r--r-- | src/marker.c | 6 | ||||
| -rw-r--r-- | src/minibuf.c | 27 | ||||
| -rw-r--r-- | src/msdos.c | 65 | ||||
| -rw-r--r-- | src/nsfns.m | 16 | ||||
| -rw-r--r-- | src/nsfont.m | 12 | ||||
| -rw-r--r-- | src/nsmenu.m | 66 | ||||
| -rw-r--r-- | src/nsterm.h | 40 | ||||
| -rw-r--r-- | src/nsterm.m | 200 | ||||
| -rw-r--r-- | src/print.c | 9 | ||||
| -rw-r--r-- | src/process.c | 520 | ||||
| -rw-r--r-- | src/process.h | 16 | ||||
| -rw-r--r-- | src/profiler.c | 4 | ||||
| -rw-r--r-- | src/regex.c | 44 | ||||
| -rw-r--r-- | src/scroll.c | 8 | ||||
| -rw-r--r-- | src/search.c | 90 | ||||
| -rw-r--r-- | src/sheap.c | 17 | ||||
| -rw-r--r-- | src/syntax.c | 7 | ||||
| -rw-r--r-- | src/sysdep.c | 204 | ||||
| -rw-r--r-- | src/sysselect.h | 11 | ||||
| -rw-r--r-- | src/systime.h | 134 | ||||
| -rw-r--r-- | src/syswait.h | 3 | ||||
| -rw-r--r-- | src/term.c | 38 | ||||
| -rw-r--r-- | src/termcap.c | 4 | ||||
| -rw-r--r-- | src/termchar.h | 17 | ||||
| -rw-r--r-- | src/termhooks.h | 28 | ||||
| -rw-r--r-- | src/textprop.c | 41 | ||||
| -rw-r--r-- | src/w16select.c | 12 | ||||
| -rw-r--r-- | src/w32.c | 140 | ||||
| -rw-r--r-- | src/w32.h | 1 | ||||
| -rw-r--r-- | src/w32console.c | 16 | ||||
| -rw-r--r-- | src/w32fns.c | 16 | ||||
| -rw-r--r-- | src/w32proc.c | 14 | ||||
| -rw-r--r-- | src/w32term.c | 182 | ||||
| -rw-r--r-- | src/w32term.h | 6 | ||||
| -rw-r--r-- | src/window.c | 468 | ||||
| -rw-r--r-- | src/window.h | 169 | ||||
| -rw-r--r-- | src/xdisp.c | 685 | ||||
| -rw-r--r-- | src/xfaces.c | 11 | ||||
| -rw-r--r-- | src/xfns.c | 55 | ||||
| -rw-r--r-- | src/xfont.c | 6 | ||||
| -rw-r--r-- | src/xgselect.c | 16 | ||||
| -rw-r--r-- | src/xgselect.h | 10 | ||||
| -rw-r--r-- | src/xmenu.c | 40 | ||||
| -rw-r--r-- | src/xrdb.c | 18 | ||||
| -rw-r--r-- | src/xselect.c | 10 | ||||
| -rw-r--r-- | src/xsmfns.c | 3 | ||||
| -rw-r--r-- | src/xterm.c | 421 | ||||
| -rw-r--r-- | src/xterm.h | 38 |
97 files changed, 5021 insertions, 3765 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 69e00cadbe9..e0aa1ed577f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,1388 @@ | |||
| 1 | 2013-09-03 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | * buffer.c (drop_overlay): | ||
| 4 | * fileio.c (restore_point_unwind): Prefer unchain_marker to | ||
| 5 | Fset_marker (X, Qnil, ...) (which is the same but a bit slower). | ||
| 6 | |||
| 7 | 2013-09-03 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 8 | |||
| 9 | * buffer.c (Fmake_overlay, Fmove_overlay): | ||
| 10 | * intervals.c (set_point_from_marker): | ||
| 11 | * print.c (PRINTPREPARE): Prefer signal_error | ||
| 12 | to plain error and report unsuitable marker too. | ||
| 13 | |||
| 14 | 2013-09-03 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 15 | |||
| 16 | * xterm.h (struct scroll_bar): Prefer int to Lisp_Object | ||
| 17 | for 'dragging' member. | ||
| 18 | (struct x_output): Remove set-but-unused leftovers | ||
| 19 | 'left_before_move' and 'top_before_move'. | ||
| 20 | * gtkutil.c (xg_set_toolkit_scroll_bar_thumb): | ||
| 21 | * xterm.c (xt_action_hook, xm_scroll_callback, xg_scroll_callback) | ||
| 22 | (xg_end_scroll_callback, xaw_jump_callback, xaw_scroll_callback) | ||
| 23 | (x_set_toolkit_scroll_bar_thumb, x_scroll_bar_create) | ||
| 24 | (x_scroll_bar_set_handle, XTset_vertical_scroll_bar) | ||
| 25 | (x_scroll_bar_handle_click, x_scroll_bar_note_movement) | ||
| 26 | (x_scroll_bar_report_motion, x_set_offset): Related users changed. | ||
| 27 | * xfns.c, image.c (XLIB_ILLEGAL_ACCESS): No longer needed. | ||
| 28 | |||
| 29 | 2013-09-03 Jan Djärv <jan.h.d@swipnet.se> | ||
| 30 | |||
| 31 | * nsfont.m (INVALID_GLYPH): New define. | ||
| 32 | (nsfont_encode_char): Use INVALID_GLYPH. | ||
| 33 | (ns_uni_to_glyphs): Ditto, check for NSNullGlyph (Bug#15138). | ||
| 34 | |||
| 35 | 2013-09-02 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 36 | |||
| 37 | * xterm.c (x_last_mouse_movement_time): Revert last change. | ||
| 38 | This code should use XDisplayMotionBufferSize to check display's | ||
| 39 | motion history first, and there are few other issues as well. | ||
| 40 | (x_scroll_bar_note_movement): Pass XMotionEvent rather than XEvent. | ||
| 41 | (handle_one_xevent): Adjust user. | ||
| 42 | |||
| 43 | 2013-09-02 Martin Rudalics <rudalics@gmx.at> | ||
| 44 | |||
| 45 | * dispnew.c (Flast_nonminibuf_frame): Move from here ... | ||
| 46 | * frame.c (Flast_nonminibuf_frame): ... to here. | ||
| 47 | (check_minibuf_window): Don't abort if no window was found | ||
| 48 | (Bug#15247). | ||
| 49 | |||
| 50 | 2013-09-02 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 51 | |||
| 52 | Use XGetMotionEvents to ask the last mouse motion time from X server. | ||
| 53 | * xterm.c (X_MOTION_HISTORY): Default to 1. | ||
| 54 | (x_last_mouse_movement_time) [X_MOTION_HISTORY]: New function. | ||
| 55 | (x_last_mouse_movement_time) [!X_MOTION_HISTORY]: Legacy version. | ||
| 56 | (note_mouse_movement, x_scroll_bar_note_movement) [!X_MOTION_HISTORY]: | ||
| 57 | Ifdef away legacy code. | ||
| 58 | (XTmouse_position, x_scroll_bar_report_motion): | ||
| 59 | Use x_last_mouse_movement_time. | ||
| 60 | (handle_one_xevent): Use event.xunmap and not event.xmap when handling | ||
| 61 | UnmapNotify event. | ||
| 62 | |||
| 63 | 2013-09-02 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 64 | |||
| 65 | * msdos.c (last_mouse_window): Move to... | ||
| 66 | (dos_rawgetc): ...this function and adjust comment. | ||
| 67 | * nsterm.m (last_window): Rename to last_mouse_window, move to... | ||
| 68 | (mouseMoved): ...this function and adjust comment. | ||
| 69 | * w32term.c (last_window): Likewise with... | ||
| 70 | (w32_read_socket): ...this function. | ||
| 71 | * xterm.c (last_window): Likewise with... | ||
| 72 | (handle_one_xevent): ...this function. | ||
| 73 | |||
| 74 | 2013-09-02 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 75 | |||
| 76 | * window.h (Vmouse_window, Vmouse_event): Remove the leftovers. | ||
| 77 | * xterm.c (toplevel): Drop obsolete comment and move compose_status... | ||
| 78 | (handle_one_xevent): ...to here. | ||
| 79 | (STORE_KEYSYM_FOR_DEBUG): Move under ENABLE_CHECKING and make no-op | ||
| 80 | otherwise. | ||
| 81 | |||
| 82 | 2013-09-02 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 83 | |||
| 84 | * msdos.c (IT_set_terminal_window): Remove no-op. | ||
| 85 | (initialize_msdos_display): Adjust terminal setup. | ||
| 86 | * w32console.c (w32con_set_terminal_window): Remove no-op. | ||
| 87 | (initialize_w32_display): Adjust terminal setup. | ||
| 88 | * w32term.c (w32_set_terminal_window): Remove no-op. | ||
| 89 | (w32_create_terminal): Adjust terminal setup. | ||
| 90 | * xterm.c (XTset_terminal_window): Remove no-op. | ||
| 91 | (x_create_terminal): Adjust terminal setup. | ||
| 92 | |||
| 93 | 2013-09-01 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 94 | |||
| 95 | * nsterm.m (ns_set_terminal_modes, ns_reset_terminal_modes): | ||
| 96 | Remove no-ops. | ||
| 97 | (ns_create_terminal): Adjust terminal setup. | ||
| 98 | * w32term.c (w32_set_terminal_modes, w32_reset_terminal_modes): | ||
| 99 | Remove no-ops. | ||
| 100 | (w32_create_terminal): Adjust terminal setup. | ||
| 101 | * xterm.c (XTset_terminal_modes, XTreset_terminal_modes): | ||
| 102 | Remove no-ops. | ||
| 103 | (x_create_terminal): Adjust terminal setup. | ||
| 104 | |||
| 105 | 2013-09-01 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 106 | |||
| 107 | * dispextern.h (SET_TEXT_POS_FROM_MARKER): Indent. | ||
| 108 | (CLIP_TEXT_POS_FROM_MARKER): New macro. | ||
| 109 | * dispnew.c (buffer_posn_from_coords): | ||
| 110 | * window.c (Fwindow_end, displayed_window_lines): | ||
| 111 | * xdisp.c (redisplay_mode_lines): Use it. | ||
| 112 | |||
| 113 | 2013-09-01 Jan Djärv <jan.h.d@swipnet.se> | ||
| 114 | |||
| 115 | * fontset.c (face_for_char): Check char in the current face font first | ||
| 116 | if HAVE_NS (Bug#15138). | ||
| 117 | |||
| 118 | 2013-08-31 Martin Rudalics <rudalics@gmx.at> | ||
| 119 | |||
| 120 | * window.c (temp_output_buffer_show): Make sure window returned | ||
| 121 | by display_buffer is live (Bug#15213). | ||
| 122 | |||
| 123 | 2013-08-30 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 124 | |||
| 125 | Minor cleanup to avoid forward declarations. | ||
| 126 | * coding.h (struct ccl_spec): Remove forward declaration. | ||
| 127 | * composite.h (toplevel): Include font.h. | ||
| 128 | (struct composition_it, struct face, struct font_metrics): | ||
| 129 | Remove forward declaration. | ||
| 130 | * dispextern.h (struct image, struct atimer): Likewise. | ||
| 131 | * emacsgtkfixed.h (struct frame): Likewise. | ||
| 132 | * emacsgtkfixed.c (toplevel): Reorder headers and drop stdio.h. | ||
| 133 | * font.h (struct font_driver, struct font, struct glyph_string) | ||
| 134 | (struct face): Remove forward declaration. | ||
| 135 | * fontset.h (struct face, struct font): Likewise. | ||
| 136 | * frame.h (toplevel): Style cleanup. | ||
| 137 | (enum output_method): Move to... | ||
| 138 | * termhooks.h (enum output_method): ...here. | ||
| 139 | (struct glyph, struct frame, struct ns_display_info) | ||
| 140 | (struct x_display_info, struct w32_display_info): | ||
| 141 | Remove forward declaration. | ||
| 142 | * xterm.h (toplevel): Include termhooks.h. | ||
| 143 | (struct font, struct window, struct glyph_matrix, struct frame) | ||
| 144 | (struct input_event, struct face, struct image): Remove forward | ||
| 145 | declaration. | ||
| 146 | * gtkutil.h (struct _widget_value): Likewise. | ||
| 147 | * keyboard.h (toplevel): Include termhooks.h. | ||
| 148 | (struct input_event): Remove forward declaration. | ||
| 149 | |||
| 150 | 2013-08-29 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 151 | |||
| 152 | * intervals.c (set_point_from_marker): New function. | ||
| 153 | * editfns.c (Fgoto_char): | ||
| 154 | * process.c (Finternal_default_process_filter): | ||
| 155 | * window.c (select_window_1): Use it. | ||
| 156 | * buffer.h (set_point_from_marker): Add prototype. | ||
| 157 | |||
| 158 | 2013-08-29 Eli Zaretskii <eliz@gnu.org> | ||
| 159 | |||
| 160 | * w32.c (term_winsock): Call release_listen_threads before calling | ||
| 161 | WSACleanup. | ||
| 162 | (_sys_wait_accept): Wait for accept event in a loop with a finite | ||
| 163 | timeout, instead of waiting indefinitely. Will hopefully avoid | ||
| 164 | hanging during exit because WSACleanup deadlocks waiting for the | ||
| 165 | event object to be released. (Bug#14333) | ||
| 166 | |||
| 167 | * w32proc.c (release_listen_threads): New function, signals all | ||
| 168 | the reader threads that listen for connections to stop waiting. | ||
| 169 | |||
| 170 | * w32.h (release_listen_threads): Add prototype. | ||
| 171 | |||
| 172 | 2013-08-29 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 173 | |||
| 174 | * alloc.c (Fmake_marker, build_marker): Zero need_adjustment | ||
| 175 | field of new marker (for sanity and safety). | ||
| 176 | * lisp.h (XSETMARKER): Remove unused macro (it doesn't work | ||
| 177 | anyway because XMISCTYPE is a function and can't be an lvalue). | ||
| 178 | |||
| 179 | 2013-08-29 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 180 | |||
| 181 | * xterm.c (x_clear_area): Lost 7th arg because it is always False. | ||
| 182 | (x_after_update_window_line, x_scroll_bar_create): | ||
| 183 | (x_scroll_bar_set_handle, XTset_vertical_scroll_bar): | ||
| 184 | (handle_one_xevent, x_clear_frame_area): | ||
| 185 | * gtkutil.c (xg_clear_under_internal_border, xg_update_scrollbar_pos): | ||
| 186 | * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Adjust users. | ||
| 187 | * xterm.h (x_clear_area): Adjust prototype. | ||
| 188 | |||
| 189 | 2013-08-29 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 190 | |||
| 191 | Hook scanning and indentation functions to find_newline. This helps | ||
| 192 | to avoid duplicated code and renders more respect to newline cache. | ||
| 193 | * lisp.h (scan_newline): Prefer ptrdiff_t to EMACS_INT. | ||
| 194 | * cmds.c (Fforward_line): | ||
| 195 | * indent.c (scan_for_column, Fcurrent_indentation, indented_beyond_p): | ||
| 196 | Use find_newline and avoid unnecessary point movements. | ||
| 197 | * search.c (scan_newline): Implement on top of find_newline. | ||
| 198 | |||
| 199 | 2013-08-28 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 200 | |||
| 201 | * eval.c (Ffuncall): Fix handling of ((lambda ..) ..) in lexically | ||
| 202 | scoped code (bug#11258). | ||
| 203 | |||
| 204 | 2013-08-28 Davor Cubranic <cubranic@stat.ubc.ca> (tiny change) | ||
| 205 | |||
| 206 | * nsterm.m (last_window): New variable. | ||
| 207 | (EV_TRAILER2): New macro. | ||
| 208 | (EV_TRAILER): Call EV_TRAILER2. | ||
| 209 | (mouseMoved:): Add support for mouse-autoselect-window | ||
| 210 | on nextstep (Bug#6888). | ||
| 211 | |||
| 212 | 2013-08-28 Andreas Schwab <schwab@suse.de> | ||
| 213 | |||
| 214 | * regex.c (CHAR_CHARSET, CHARSET_LEADING_CODE_BASE, CHAR_HEAD_P) | ||
| 215 | (SINGLE_BYTE_CHAR_P, SAME_CHARSET_P, MAKE_CHAR, BYTE8_TO_CHAR): | ||
| 216 | Remove unused macro definitions. | ||
| 217 | (CHARSET_RANGE_TABLE_BITS, EXTEND_RANGE_TABLE) | ||
| 218 | (SET_RANGE_TABLE_WORK_AREA_BIT, SET_RANGE_TABLE_WORK_AREA): | ||
| 219 | Only define if emacs. | ||
| 220 | |||
| 221 | 2013-08-28 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 222 | |||
| 223 | Prefer enum glyph_row_area to int where appropriate. | ||
| 224 | * dispextern.h (enum glyph_row_area): Add ANY_AREA member. | ||
| 225 | Fix comment. | ||
| 226 | (window_box, window_box_width, window_box_left, window_box_left_offset) | ||
| 227 | (window_box_right, window_box_right_offset): Adjust prototypes. | ||
| 228 | * xdisp.c (window_box, window_box_width, window_box_left) | ||
| 229 | (window_box_left_offset, window_box_right, window_box_right_offset): | ||
| 230 | Use enum glyph_row_area. Adjust users and tweak comment where needed. | ||
| 231 | (window_box_edges): Likewise. Lost 2nd arg since it is always ANY_AREA. | ||
| 232 | * nsterm.m (ns_clip_to_row): | ||
| 233 | * w32term.c (w32_clip_to_row): | ||
| 234 | * xterm.c (x_clip_to_row): Likewise. | ||
| 235 | |||
| 236 | 2013-08-28 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 237 | |||
| 238 | * buffer.c (Foverlays_at, Foverlays_in, Fnext_overlay_change) | ||
| 239 | (Fprevious_overlay_change): Fast path for buffer with no overlays. | ||
| 240 | |||
| 241 | 2013-08-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 242 | |||
| 243 | * Makefile.in (SHELL): Now @SHELL@, not /bin/sh, | ||
| 244 | for portability to hosts where /bin/sh has problems. | ||
| 245 | |||
| 246 | 2013-08-28 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 247 | |||
| 248 | Redesign redisplay interface to drop global output_cursor. | ||
| 249 | * dispextern.h (struct redisplay_interface): Remove cursor_to member. | ||
| 250 | (toplevel): Remove declaration of output_cursor. | ||
| 251 | (set_output_cursor, x_cursor_to): Remove prototype. | ||
| 252 | * window.h (struct window): New member output_cursor. | ||
| 253 | (output_cursor_to): New function to replace RIF member. | ||
| 254 | * dispnew.c (redraw_overlapped_rows, update_marginal_area) | ||
| 255 | (update_text_area, set_window_cursor_after_update): Use it. | ||
| 256 | * xdisp.c (output_cursor, set_output_cursor, x_cursor_to): Remove. | ||
| 257 | (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): | ||
| 258 | * nsterm.m (ns_update_window_begin, ns_update_window_end): | ||
| 259 | * w32term.c (x_update_window_begin, x_update_window_end): | ||
| 260 | * xterm.c (x_update_window_begin, x_update_window_end): | ||
| 261 | Adjust to use per-window output cursor. | ||
| 262 | |||
| 263 | 2013-08-27 Paul Eggert <eggert@cs.ucla.edu> | ||
| 264 | |||
| 265 | Simplify SELECT_TYPE-related code. | ||
| 266 | Like EMACS_TIME, this portability layer is no longer needed, since | ||
| 267 | Emacs has been using fd_set as a portability layer for some time. | ||
| 268 | * sysselect.h (FD_SETSIZE): Rename from MAXDESC. All uses changed. | ||
| 269 | (SELECT_TYPE): Remove. All uses changed to fd_set. | ||
| 270 | (fd_set) [!FD_SET]: New typedef. | ||
| 271 | |||
| 272 | Simplify EMACS_TIME-related code. | ||
| 273 | This portability layer is no longer needed, since Emacs has been | ||
| 274 | using struct timespec as a portability layer for some time. | ||
| 275 | * atimer.h, buffer.h, dispextern.h, xgselect.h: | ||
| 276 | Include <time.h> rather than "systime.h"; that's all that's needed now. | ||
| 277 | * dispnew.c: Include <timespec.h> rather than "systime.h"; | ||
| 278 | that's all that's needed now. | ||
| 279 | * systime.h (EMACS_TIME): Remove. All uses changed to struct timespec. | ||
| 280 | (EMACS_TIME_RESOLUTION): Remove. All uses changed to | ||
| 281 | TIMESPEC_RESOLUTION. | ||
| 282 | (LOG10_EMACS_TIME_RESOLUTION): Remove. All uses changed to | ||
| 283 | LOG10_TIMESPEC_RESOLUTION. | ||
| 284 | (EMACS_SECS, emacs_secs_addr): Remove. All uses changed to tv_sec. | ||
| 285 | (EMACS_NSECS): Remove. All uses changed to tv_nsec. | ||
| 286 | (make_emacs_time): Remove. All used changed to make_timespec. | ||
| 287 | (invalid_timespec): Rename from invalid_emacs_time. All uses changed. | ||
| 288 | (current_timespec): Rename from current_emacs_time. All uses changed. | ||
| 289 | (add_emacs_time): Remove. All uses changed to timespec_add. | ||
| 290 | (sub_emacs_time): Remove. All uses change dot timespec_sub. | ||
| 291 | (EMACS_TIME_SIGN): Remove. All uses changed to timespec_sign. | ||
| 292 | (timespec_valid_p): Rename from EMACS_TIME_VALID_P. All uses changed. | ||
| 293 | (EMACS_TIME_FROM_DOUBLE): Remove. All uses changed to dtotimespec. | ||
| 294 | (EMACS_TIME_TO_DOUBLE): Remove. All uses changed to timespectod. | ||
| 295 | (current_timespec): Rename from current_emacs_time. All uses changed. | ||
| 296 | (EMACS_TIME_EQ, EMACS_TIME_LT, EMACS_TIME_LE): Remove. All uses | ||
| 297 | changed to timespec_cmp. | ||
| 298 | * xgselect.c: Include <timespec.h>, since our .h files don't. | ||
| 299 | |||
| 300 | 2013-08-27 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 301 | |||
| 302 | * xterm.h (FONT_TYPE_FOR_UNIBYTE, FONT_TYPE_FOR_MULTIBYTE:) | ||
| 303 | * nsterm.h (FONT_TYPE_FOR_UNIBYTE, FONT_TYPE_FOR_MULTIBYTE): | ||
| 304 | Remove the leftovers. | ||
| 305 | * gtkutil.c (toplevel): Do not declare Qxft but include | ||
| 306 | font.h to do so. | ||
| 307 | * image.c (toplevel): Do not declare Vlibrary_cache because | ||
| 308 | it's already done in lisp.h. | ||
| 309 | |||
| 310 | 2013-08-27 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 311 | |||
| 312 | * lisp.h (Mouse_HLInfo): Move from here... | ||
| 313 | * dispextern.h (Mouse_HLInfo): ...to here and offload lisp.h. | ||
| 314 | (reset_mouse_highlight): New function. | ||
| 315 | * msdos.c (dos_set_window_size, IT_update_begin) | ||
| 316 | (internal_terminal_init): | ||
| 317 | * nsterm.m (ns_update_window_end, x_free_frame_resources) | ||
| 318 | (ns_initialize_display_info): | ||
| 319 | * w32console.c (initialize_w32_display): | ||
| 320 | * w32term.c (x_update_window_end, x_free_frame_resources) | ||
| 321 | (w32_initialize_display_info): | ||
| 322 | * xterm.c (x_update_window_end, x_free_frame_resources, x_term_init): | ||
| 323 | * window.c (Fdelete_other_windows_internal): | ||
| 324 | * xdisp.c (clear_mouse_face, cancel_mouse_face): Use it. | ||
| 325 | * termchar.h (toplevel): | ||
| 326 | * xterm.h (toplevel): Include dispextern.h. | ||
| 327 | |||
| 328 | 2013-08-26 Paul Eggert <eggert@cs.ucla.edu> | ||
| 329 | |||
| 330 | Fix minor problems found by static checking. | ||
| 331 | * image.c (XGetPixel, XPutPixel) [HAVE_NS]: Now static. | ||
| 332 | (expect): Avoid nested-if warning. | ||
| 333 | (x_build_heuristic_mask) [HAVE_NS]: Avoid unused-var warning. | ||
| 334 | * nsmenu.m (fillWithWidgetValue:): Avoid type warning. | ||
| 335 | * nsterm.h, nsterm.m (ns_select): | ||
| 336 | * xgselect.c, xgselect.h (xg_select): | ||
| 337 | Adjust signature to better match pselect's. | ||
| 338 | * nsterm.m (ns_select): | ||
| 339 | Don't set *TIMEOUT, since pselect doesn't. | ||
| 340 | * regex.c (whitespace_regexp): Now const_re_char *, to avoid | ||
| 341 | diagnostic about assigning const char * to it. | ||
| 342 | * xfaces.c (x_display_info) [HAVE_NS]: Remove; unused. | ||
| 343 | |||
| 344 | 2013-08-26 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 345 | |||
| 346 | * lread.c (substitute_object_recurse): Handle hash-tables as well | ||
| 347 | (bug#15190). | ||
| 348 | |||
| 349 | 2013-08-26 Paul Eggert <eggert@cs.ucla.edu> | ||
| 350 | |||
| 351 | Fix unlikely core dump in init_tty, and simplify terminfo case. | ||
| 352 | * term.c (init_tty) [TERMINFO]: Fix check for buffer overrun. | ||
| 353 | The old version incorrectly dumped core if malloc returned a | ||
| 354 | buffer containing only non-NUL bytes. | ||
| 355 | (init_tty): Do not allocate or free termcap buffers; the | ||
| 356 | struct does that for us now. | ||
| 357 | * termchar.h (TERMCAP_BUFFER_SIZE) [!TERMINFO]: New constant. | ||
| 358 | (struct tty_display_info): Define members termcap_term_buffer and | ||
| 359 | termcap_strings_buffer only if !TERMINFO, since terminfo doesn't | ||
| 360 | use them. Allocate them directly in struct rather than indirectly | ||
| 361 | via a pointer, to simplify init_tty. | ||
| 362 | |||
| 363 | * frame.c (check_minibuf_window): Initialize 'window' properly, | ||
| 364 | so that Emacs reliably aborts later if 'window' is not initialized. | ||
| 365 | |||
| 366 | 2013-08-26 Jan Djärv <jan.h.d@swipnet.se> | ||
| 367 | |||
| 368 | * gtkutil.c (xg_initialize): Set gtk-menu-bar-accel to "" instead | ||
| 369 | of VoidSymbol (Bug#15154). | ||
| 370 | |||
| 371 | 2013-08-26 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 372 | |||
| 373 | * lisp.h (Mouse_HLInfo): Drop set-but-unused members | ||
| 374 | mouse_face_beg_y and mouse_face_end_y. | ||
| 375 | * xdisp.c (note_tool_bar_highlight, mouse_face_from_buffer_pos) | ||
| 376 | (mouse_face_from_string_pos, note_mode_line_or_margin_highlight): | ||
| 377 | Adjust users and update comment where appropriate. | ||
| 378 | |||
| 379 | 2013-08-26 Martin Rudalics <rudalics@gmx.at> | ||
| 380 | |||
| 381 | * frame.c (check_minibuf_window): New function. | ||
| 382 | (delete_frame, Fmake_frame_invisible, Ficonify_frame): | ||
| 383 | Call check_minibuf_window (Bug#15183). | ||
| 384 | |||
| 385 | 2013-08-26 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 386 | |||
| 387 | * window.h (struct window): Replace last_cursor with last_cursor_vpos | ||
| 388 | because this is the only last cursor data we need to keep and consult. | ||
| 389 | * window.c (replace_window, set_window_buffer, Fsplit_window_internal): | ||
| 390 | * xdisp.c (mark_window_display_accurate_1, try_cursor_movement): | ||
| 391 | Adjust users. | ||
| 392 | |||
| 393 | 2013-08-26 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 394 | |||
| 395 | Fix recovering from possible decompression error. | ||
| 396 | Since insert_from_gap doesn't always move point, we can't use PT as | ||
| 397 | the position where the partially decompressed data ends, and | ||
| 398 | should count how many bytes was produced so far. | ||
| 399 | * decompress.c (struct decompress_unwind_data): Add nbytes member. | ||
| 400 | (unwind_decompress): Really delete partially uncompressed data. | ||
| 401 | (Fzlib_decompress_region): Take decompressed data size into account. | ||
| 402 | |||
| 403 | 2013-08-26 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 404 | |||
| 405 | * syntax.c (init_syntax_once): Adjust comment and do an early | ||
| 406 | initialization of Qchar_table_extra_slots just once... | ||
| 407 | * casetab.c (init_casetab_once): | ||
| 408 | * category.c (init_category_once): | ||
| 409 | * character.c (syms_of_character): | ||
| 410 | * coding.c (syms_of_coding): | ||
| 411 | * xdisp.c (syms_of_xdisp): ...and omit it here. | ||
| 412 | |||
| 413 | 2013-08-24 Eli Zaretskii <eliz@gnu.org> | ||
| 414 | |||
| 415 | * xdisp.c (get_next_display_element): Don't apply to characters | ||
| 416 | from a display vector the logic of setting it->end_of_box_run_p | ||
| 417 | suitable for characters from a buffer. (Bug#15175) | ||
| 418 | |||
| 419 | * w32.c (fdutimens): Call 'utime', which is implemented on w32.c | ||
| 420 | to handle directories, rather than '_utime' which doesn't. | ||
| 421 | (Bug#15176) | ||
| 422 | |||
| 423 | 2013-08-24 Jan Djärv <jan.h.d@swipnet.se> | ||
| 424 | |||
| 425 | * gtkutil.c (x_wm_set_size_hint): Don't set hints when maximized | ||
| 426 | or fullscreen (Bug#14627). | ||
| 427 | |||
| 428 | 2013-08-24 Paul Eggert <eggert@cs.ucla.edu> | ||
| 429 | |||
| 430 | System-dependent integer overflow fixes. | ||
| 431 | * process.c (Fset_process_window_size): Signal an error if | ||
| 432 | the window size is outside the range supported by the lower level. | ||
| 433 | * sysdep.c (set_window_size): Return negative on error, | ||
| 434 | nonnegative on success, rather than -1, 0, 1 on not in system, | ||
| 435 | failure, success. This is simpler. Caller changed. | ||
| 436 | (serial_configure): Remove unnecessary initialization of local. | ||
| 437 | (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory | ||
| 438 | size fits in unsigned long; this isn't true on some 32-bit hosts. | ||
| 439 | Avoid buffer overrun if some future version of /proc/meminfo has a | ||
| 440 | variable name longer than 20 bytes. | ||
| 441 | (system_process_attributes) [__FreeBSD__]: | ||
| 442 | Don't assume hw.availpages fits in 'int'. | ||
| 443 | |||
| 444 | 2013-08-23 Paul Eggert <eggert@cs.ucla.edu> | ||
| 445 | |||
| 446 | Don't let very long directory names overrun the stack. | ||
| 447 | Fix some related minor problems involving "//", vfork. | ||
| 448 | * callproc.c (encode_current_directory): New function. | ||
| 449 | (call_process): Don't append "/"; not needed. | ||
| 450 | * fileio.c (file_name_as_directory_slop): New constant. | ||
| 451 | (file_name_as_directory): Allow SRC to be longer than SRCLEN; | ||
| 452 | this can save the caller having to alloca. | ||
| 453 | (Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name): | ||
| 454 | Use SAFE_ALLOCA, not alloca. | ||
| 455 | (directory_file_name, Fexpand_file_name): Leave leading "//" | ||
| 456 | alone, since it can be special even on POSIX platforms. | ||
| 457 | * callproc.c (call_process): | ||
| 458 | * process.c (Fformat_network_address): | ||
| 459 | * sysdep.c (sys_subshell): | ||
| 460 | Use encode_current_directory rather than rolling our own. | ||
| 461 | (create_process): No need to encode directory; caller does that now. | ||
| 462 | * process.h (encode_current_directory): New decl. | ||
| 463 | * sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers. | ||
| 464 | Rework to avoid 'goto xyzzy;'. | ||
| 465 | |||
| 466 | 2013-08-23 Eli Zaretskii <eliz@gnu.org> | ||
| 467 | |||
| 468 | * xdisp.c (handle_face_prop): If the default face was remapped use | ||
| 469 | the remapped face for strings from prefix properties. (Bug#15155) | ||
| 470 | |||
| 471 | 2013-08-23 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 472 | |||
| 473 | Minor cleanup for redisplay interface and few related functions. | ||
| 474 | * frame.h (enum text_cursor_kinds): Move from here... | ||
| 475 | * dispextern.h (enum text_cursor_kinds): ...to here. | ||
| 476 | (toplevel): Drop unnecessary declarations. | ||
| 477 | (struct redisplay_interface): Use bool and enum text_cursor_kinds | ||
| 478 | in update_window_end_hook and draw_window_cursor functions. | ||
| 479 | (display_and_set_cursor, x_update_cursor): Adjust prototypes. | ||
| 480 | * nsterm.m (ns_update_window_end, ns_draw_window_cursor): | ||
| 481 | * w32term.c (x_update_window_end,w32_draw_window_cursor): | ||
| 482 | * xterm.c (x_update_window_end, x_draw_window_cursor): | ||
| 483 | * xdisp.c (display_and_set_cursor, update_window_cursor) | ||
| 484 | (update_cursor_in_window_tree, x_update_cursor): Use bool and | ||
| 485 | enum text_cursor_kinds where appropriate. | ||
| 486 | |||
| 487 | 2013-08-23 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 488 | |||
| 489 | Redesign redisplay interface to drop updated_row and updated_area. | ||
| 490 | * dispextern.h (updated_row, updated_area): Remove declaration. | ||
| 491 | (struct redisplay_interface): Pass glyph row and row area parameters | ||
| 492 | to write_glyphs, insert_glyphs and clear_end_of_line functions. | ||
| 493 | (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): | ||
| 494 | Adjust prototypes. | ||
| 495 | * dispnew.c (updated_row, updated_area): Remove. | ||
| 496 | (redraw_overlapped_rows, update_window_line): Adjust user. | ||
| 497 | (update_marginal_area, update_text_area): Likewise. Pass updated row | ||
| 498 | as a parameter. Prefer enum glyph_row_area to int where appropriate. | ||
| 499 | * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): | ||
| 500 | Adjust users. | ||
| 501 | |||
| 502 | 2013-08-22 Paul Eggert <eggert@cs.ucla.edu> | ||
| 503 | |||
| 504 | * process.c (flush_pending_output): Remove stub. | ||
| 505 | All uses removed. | ||
| 506 | |||
| 507 | 2013-08-21 Paul Eggert <eggert@cs.ucla.edu> | ||
| 508 | |||
| 509 | * callproc.c: Fix race that killed background processes (Bug#15144). | ||
| 510 | (call_process): New arg TEMPFILE_INDEX. Callers changed. | ||
| 511 | Record deleted process-id in critical section, not afterwards. | ||
| 512 | Don't mistakenly kill process created by a call-process invocation | ||
| 513 | that discards output and does not wait. | ||
| 514 | |||
| 515 | 2013-08-21 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 516 | |||
| 517 | Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE | ||
| 518 | and GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES. | ||
| 519 | * alloc.c (toplevel): Remove unnecessary nested #if...#endif. | ||
| 520 | (mark_maybe_object) [!GC_MARK_STACK]: Define to emacs_abort | ||
| 521 | to shut up compiler in mark_object. | ||
| 522 | (dump_zombies): Convert to global and add EXTERNALLY_VISIBLE. | ||
| 523 | |||
| 524 | 2013-08-21 Paul Eggert <eggert@cs.ucla.edu> | ||
| 525 | |||
| 526 | * process.c (allocate_pty) [PTY_OPEN]: Set fd's FD_CLOEXEC flag. | ||
| 527 | We can't portably rely on PTY_OPEN doing that, even if | ||
| 528 | it calls posix_openpt with O_CLOEXEC. | ||
| 529 | |||
| 530 | 2013-08-20 Kenichi Handa <handa@gnu.org> | ||
| 531 | |||
| 532 | * character.c (string_char): Improve commentary. | ||
| 533 | |||
| 534 | 2013-08-20 Paul Eggert <eggert@cs.ucla.edu> | ||
| 535 | |||
| 536 | * image.c (SIGNATURE_DIGESTSIZE): Remove. | ||
| 537 | (struct animation_cache): Make signature a flexible array member. | ||
| 538 | All uses changed. This is a tad slower but may insulate us better | ||
| 539 | from future changes to ImageMagick. | ||
| 540 | |||
| 541 | 2013-08-19 Paul Eggert <eggert@cs.ucla.edu> | ||
| 542 | |||
| 543 | * image.c: Shrink memory needed for animation cache. | ||
| 544 | (SIGNATURE_DIGESTSIZE): New constant. | ||
| 545 | (struct animation_cache): Make 'signature' a fixed size array of bytes. | ||
| 546 | (imagemagick_create_cache): Copy the signature. This saves | ||
| 547 | several KB of memory that ImageMagick wastes per signature. | ||
| 548 | Don't bother updating the update_time, as the caller does that now. | ||
| 549 | (imagemagick_prune_animation_cache): Don't destroy the signature, as | ||
| 550 | it's a fixed size struct member now. | ||
| 551 | (imagemagick_get_animation_cache): Always destroy the signature, | ||
| 552 | as it's now imagemagick_create_cache's responsibility to copy it. | ||
| 553 | Avoid duplicate calls to strcmp and to imagemagick_create_cache, | ||
| 554 | and use memcmp rather than strcmp. | ||
| 555 | eassert that ImageMagick returns a signature of the specified length. | ||
| 556 | |||
| 557 | 2013-08-19 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 558 | |||
| 559 | * image.c (imagemagick_get_animation_cache): Don't segfault on | ||
| 560 | each invocation. | ||
| 561 | (imagemagick_get_animation_cache): Revert to previous definition | ||
| 562 | so that it actually works. But keep the memory leak fix. | ||
| 563 | (imagemagick_get_animation_cache): Fix memory leak. | ||
| 564 | |||
| 565 | 2013-08-19 Paul Eggert <eggert@cs.ucla.edu> | ||
| 566 | |||
| 567 | * image.c: Fix animation cache signature memory leak. | ||
| 568 | Fix some other minor performance problems while we're at it. | ||
| 569 | (imagemagick_create_cache): Clear just the members that | ||
| 570 | need clearing. Don't set update_time, as caller does that now. | ||
| 571 | (imagemagick_prune_animation_cache, imagemagick_get_animation_cache): | ||
| 572 | Simplify by using pointer-to-pointer instead of a prev pointer. | ||
| 573 | (imagemagick_prune_animation_cache): Use make_emacs_time rather | ||
| 574 | than EMACS_TIME_FROM_DOUBLE, and DestroyString rather than free. | ||
| 575 | (imagemagick_get_animation_cache): Don't xstrdup the image signature; | ||
| 576 | it's already a copy. Free the signature probe unless it's cached. | ||
| 577 | |||
| 578 | * process.c (handle_child_signal): Fix crash; deleted pid (Bug#15106). | ||
| 579 | This was introduced by my 2013-08-12 fix for Bug#15035. | ||
| 580 | |||
| 581 | 2013-08-19 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 582 | |||
| 583 | * image.c (imagemagick_create_cache, imagemagick_get_animation_cache) | ||
| 584 | (imagemagick_prune_animation_cache): Now static. | ||
| 585 | |||
| 586 | 2013-08-18 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 587 | |||
| 588 | * image.c (imagemagick_get_animation_cache): Don't segfault when | ||
| 589 | pruning all entries. | ||
| 590 | |||
| 591 | 2013-08-18 Ken Brown <kbrown@cornell.edu> | ||
| 592 | |||
| 593 | * sheap.c (STATIC_HEAP_SIZE): Adjust to current needs; use bigger | ||
| 594 | static heap if ENABLE_CHECKING is defined. | ||
| 595 | (max_bss_sbrk_ptr): New variable. | ||
| 596 | (bss_sbrk): Use it. | ||
| 597 | (report_sheap_usage): Report maximum static heap usage instead of | ||
| 598 | ending static heap usage. | ||
| 599 | |||
| 600 | 2013-08-17 Eli Zaretskii <eliz@gnu.org> | ||
| 601 | |||
| 602 | * decompress.c (Fzlib_available_p) [WINDOWSNT]: Update the value | ||
| 603 | of zlib_initialized according to the results of calling | ||
| 604 | init_zlib_functions. | ||
| 605 | |||
| 606 | 2013-08-16 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 607 | |||
| 608 | * image.c: Implement an ImageMagick per-image cache. | ||
| 609 | (imagemagick_get_animation_cache): Fix a double-free error. | ||
| 610 | (imagemagick_load_image): Remove the ping_wand code, which only | ||
| 611 | apparently saved time on invalid animated images, and slowed down | ||
| 612 | everything else. Optimise for the common case. | ||
| 613 | |||
| 614 | 2013-08-16 Xue Fuqiao <xfq.free@gmail.com> | ||
| 615 | |||
| 616 | * buffer.c (syms_of_buffer) <buffer-undo-list>: Doc fix. | ||
| 617 | |||
| 618 | * editfns.c (insert_before_markers): Mention overlay in the doc string. | ||
| 619 | |||
| 620 | * marker.c (set_marker): Remove documentation of undefined behavior. | ||
| 621 | |||
| 622 | 2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 623 | |||
| 624 | * image.c (imagemagick_compute_animated_image): Animate correctly | ||
| 625 | when sub-images are smaller than the main image. | ||
| 626 | (imagemagick_compute_animated_image): Setting the iterator row to | ||
| 627 | zero is apparently not allowed. | ||
| 628 | (imagemagick_compute_animated_image): Allow images that say they | ||
| 629 | have sub-images that are bigger than the main image, but just crop | ||
| 630 | them. | ||
| 631 | |||
| 632 | 2013-08-15 Jan Djärv <jan.h.d@swipnet.se> | ||
| 633 | |||
| 634 | * nsmenu.m (menuWillOpen:): Fix preprocessor test (Bug#15001). | ||
| 635 | |||
| 636 | 2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 637 | |||
| 638 | * image.c (imagemagick_compute_animated_image): Respect the GIF | ||
| 639 | disposal methods. | ||
| 640 | |||
| 641 | 2013-08-15 Ken Brown <kbrown@cornell.edu> | ||
| 642 | |||
| 643 | * emacs.c (main): Update comment about G_SLICE_ALWAYS_MALLOC. | ||
| 644 | * gmalloc.c (memalign) [CYGWIN]: Revert last change; it's not | ||
| 645 | needed. | ||
| 646 | |||
| 647 | 2013-08-15 Paul Eggert <eggert@cs.ucla.edu> | ||
| 648 | |||
| 649 | Fix minor problems found by static checking. | ||
| 650 | * frame.c (delete_frame): | ||
| 651 | * xdisp.c (next_element_from_display_vector): | ||
| 652 | Avoid uninitialized local. | ||
| 653 | * image.c (imagemagick_compute_animated_image): Port to C89. | ||
| 654 | Prefer usual GNU indentation style for loops. | ||
| 655 | Be more careful about bizarrely large sizes, by using ptrdiff_t | ||
| 656 | instead of int. | ||
| 657 | |||
| 658 | 2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 659 | |||
| 660 | Fix infinite frame selection loop (Bug#15025). | ||
| 661 | * frame.c (delete_frame): Prefer fast ad-hoc loop to next_frame. | ||
| 662 | |||
| 663 | 2013-08-15 Eli Zaretskii <eliz@gnu.org> | ||
| 664 | |||
| 665 | * xdisp.c (compute_window_start_on_continuation_line): | ||
| 666 | When WORD_WRAP is in effect, use move_it_to instead of move_it_by_lines | ||
| 667 | to make sure we end up setting the window start at the leftmost | ||
| 668 | visible character of the display line. This avoids funky | ||
| 669 | horizontal shifting because the window start is not kept on the | ||
| 670 | same position. (Bug#15090) | ||
| 671 | (next_element_from_display_vector): Support 'box' face attribute | ||
| 672 | in the face definitions of a display vector. (Bug#15099) | ||
| 673 | |||
| 674 | 2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 675 | |||
| 676 | * image.c (imagemagick_compute_animated_image): Implement animated | ||
| 677 | images (bug#14700). | ||
| 678 | (imagemagick_compute_animated_image): Fix some compilation | ||
| 679 | warnings. Implement a very simple cache to make the animation | ||
| 680 | usable at all, but it should be replaced with a per-image cache. | ||
| 681 | |||
| 682 | 2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 683 | |||
| 684 | * lisp.h (FOR_EACH_ALIST_VALUE): New macro | ||
| 685 | to do `for' loops over alist values. | ||
| 686 | * buffer.h (FOR_EACH_BUFFER): | ||
| 687 | * process.c (FOR_EACH_PROCESS): Use it. | ||
| 688 | (handle_child_signal, status_notify, Fget_buffer_process) | ||
| 689 | (kill_buffer_processes): Use FOR_EACH_PROCESS. | ||
| 690 | |||
| 691 | 2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 692 | |||
| 693 | * term.c (get_named_tty, create_tty_output, tty_free_frame_resources) | ||
| 694 | (tty_free_frame_resources, delete_tty): Prefer eassert to emacs_abort. | ||
| 695 | * image.c (make_image_cache): For struct image_cache, prefer xmalloc | ||
| 696 | to xzalloc and so avoid redundant call to memset. | ||
| 697 | * xterm.c (x_term_init): Avoid unnecessary initializations of dpyinfo | ||
| 698 | members because it is allocated with xzalloc and so already zeroed. | ||
| 699 | |||
| 700 | 2013-08-14 Ken Brown <kbrown@cornell.edu> | ||
| 701 | |||
| 702 | * gmalloc.c (memalign) [CYGWIN]: Rename to emacs_memalign | ||
| 703 | (Bug#15094). | ||
| 704 | |||
| 705 | 2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 706 | |||
| 707 | Utility function and macro to copy Lisp string to C string. | ||
| 708 | * lisp.h (xlispstrdupa): New macro. | ||
| 709 | (xlispstrdup): New prototype. | ||
| 710 | * alloc.c (xlispstrdup): New function. | ||
| 711 | * callint.c (Fcall_interactively): | ||
| 712 | * fileio.c (Ffile_name_directory, Fexpand_file_name) | ||
| 713 | (Fsubstitute_in_file_name): | ||
| 714 | * frame.c (Fmake_terminal_frame): Use xlispstrdupa. | ||
| 715 | * image.c (x_create_bitmap_from_file): | ||
| 716 | * w32term.c (w32_term_init): | ||
| 717 | * xterm.c (x_term_init): Use xlispstrdup. | ||
| 718 | |||
| 719 | 2013-08-14 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 720 | |||
| 721 | * image.c (imagemagick_load_image): Make animated pictures work. | ||
| 722 | There's still some problems with background color settings, though | ||
| 723 | (bug#14700). | ||
| 724 | |||
| 725 | * decompress.c (unwind_decompress): Always restore point. | ||
| 726 | |||
| 727 | 2013-08-14 Xue Fuqiao <xfq.free@gmail.com> | ||
| 728 | |||
| 729 | * marker.c (set_marker): Reformat documentation. | ||
| 730 | |||
| 731 | 2013-08-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 732 | |||
| 733 | * xdisp.c (cursor_type_changed): Now static. | ||
| 734 | |||
| 735 | * image.c (imagemagick_filename_hint): New arg HINT_BUFFER. | ||
| 736 | Use changed. This avoids the need to call xmalloc and for the | ||
| 737 | caller to call xfree, and avoids memory leaks in some situations. | ||
| 738 | |||
| 739 | 2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 740 | |||
| 741 | * xdisp.c (adjust_window_ends): Move duplicated code to new function. | ||
| 742 | (try_window, try_window_reusing_current_matrix, try_window_id): Use it. | ||
| 743 | (redisplay_window): If window_end_valid is cleared due to non-zero | ||
| 744 | windows_or_buffers_changed, clear current_matrix_up_to_date_p and | ||
| 745 | so do not call to try_cursor_movement for that window. | ||
| 746 | |||
| 747 | 2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 748 | |||
| 749 | * window.h (struct window): Convert window_end_pos and | ||
| 750 | window_end_vpos from Lisp_Object to ptrdiff_t and int, respectively. | ||
| 751 | (wset_window_end_pos, wset_window_end_vpos): Remove. | ||
| 752 | * dispnew.c (adjust_glyph_matrix): | ||
| 753 | * window.c (Fwindow_end, replace_window, set_window_buffer) | ||
| 754 | (make_window): | ||
| 755 | * xdisp.c (check_window_end, move_it_to, redisplay_internal) | ||
| 756 | (set_vertical_scroll_bar, redisplay_window, try_window) | ||
| 757 | (try_window_reusing_current_matrix, find_first_unchanged_at_end_row) | ||
| 758 | (try_window_id, decode_mode_spec, mouse_face_from_buffer_pos) | ||
| 759 | (note_mouse_highlight): Adjust users. | ||
| 760 | (try_cursor_movement): Likewise. Convert old precondition to eassert. | ||
| 761 | Add comment. | ||
| 762 | |||
| 763 | 2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 764 | |||
| 765 | Fix --enable-gcc-warnings errors introduced in 2013-08-13 commit. | ||
| 766 | * image.c (imagemagick_filename_hint): Use `const char *' and | ||
| 767 | prefer SSDATA to SDATA to avoid warnings. | ||
| 768 | |||
| 769 | 2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 770 | |||
| 771 | Cleanup window fringes, margins and scroll bars adjustments. | ||
| 772 | * window.c (set_window_fringes, set_window_margins) | ||
| 773 | (set_window_scroll_bars, apply_window_adjustment): New functions. | ||
| 774 | (set_window_buffer, Fset_window_margins, Fset_window_fringes) | ||
| 775 | (Fset_window_scroll_bars): Use them. | ||
| 776 | |||
| 777 | 2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 778 | |||
| 779 | * window.h (struct window): Convert scroll_bar_width | ||
| 780 | from Lisp_Object to integer. Adjust comment. | ||
| 781 | (WINDOW_CONFIG_SCROLL_BAR_WIDTH, WINDOW_CONFIG_SCROLL_BAR_COLS): | ||
| 782 | Adjust users. | ||
| 783 | * window.c (wset_scroll_bar_width): Remove. | ||
| 784 | (make_window): Initialize scroll_bar_width. | ||
| 785 | (Fsplit_window_internal): Use direct assignment. | ||
| 786 | (Fset_window_configuration, save_window_save): | ||
| 787 | Convert Lisp_Object to integer and back where appropriate. | ||
| 788 | (Fset_window_scroll_bars): Adjust user. Return t if any scroll | ||
| 789 | bar was actually changed, and mention this in docstring. | ||
| 790 | |||
| 791 | 2013-08-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 792 | |||
| 793 | * decompress.c: Minor simplifications. | ||
| 794 | (Fzlib_decompress_region): Don't bother verifying | ||
| 795 | that avail_out <= UINT_MAX, as that was confusing. | ||
| 796 | Mention the restriction in a comment instead. | ||
| 797 | Prefer 'int' to 'ptrdiff_t' when 'int' is wide enough. | ||
| 798 | |||
| 799 | 2013-08-13 Jan Djärv <jan.h.d@swipnet.se> | ||
| 800 | |||
| 801 | * nsmenu.m (x_activate_menubar): Check for OSX >= 10.5 | ||
| 802 | (trackingNotification:): Call ns_check_menu_open only for OSX >= 10.5. | ||
| 803 | |||
| 804 | 2013-08-13 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 805 | |||
| 806 | * image.c (imagemagick_filename_hint): Check for errors in the | ||
| 807 | alist structure. | ||
| 808 | |||
| 809 | 2013-08-13 Eli Zaretskii <eliz@gnu.org> | ||
| 810 | |||
| 811 | * window.c (Fwindow_margins): Return nil when there's no marginal | ||
| 812 | area, as per the documented API. | ||
| 813 | |||
| 814 | * w32term.c (x_scroll_bar_create): Use ALLOCATE_PSEUDOVECTOR, not | ||
| 815 | Fmake_vector, as scroll bar's struct members are not all Lisp | ||
| 816 | objects now. This avoids crashes in GC. | ||
| 817 | |||
| 818 | * w32term.h (struct scroll_bar): Convert fringe_extended_p to a | ||
| 819 | bool, so its address could be taken. | ||
| 820 | |||
| 821 | 2013-08-13 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 822 | |||
| 823 | * image.c (imagemagick_filename_hint): New function to possibly | ||
| 824 | apply `image-content-type-suffixes'. | ||
| 825 | (imagemagick_load_image): Use it. | ||
| 826 | |||
| 827 | 2013-08-13 Eli Zaretskii <eliz@gnu.org> | ||
| 828 | |||
| 829 | * decompress.c (Fzlib_decompress_region) [WINDOWSNT]: Return Qnil | ||
| 830 | if loading zlib failed. | ||
| 831 | |||
| 832 | 2013-08-13 Jan Djärv <jan.h.d@swipnet.se> | ||
| 833 | |||
| 834 | * nsterm.m (ns_set_vertical_scroll_bar): Fix breakage intruduced by | ||
| 835 | 2013-08-13 checkin below. Change bool to BOOL, rule is: | ||
| 836 | All Obj-C code uses BOOL, except for interfaces callable from C. | ||
| 837 | |||
| 838 | * nsterm.h: Fix CGFloat for OSX 10.4 (Bug#15086). | ||
| 839 | |||
| 840 | 2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 841 | |||
| 842 | * window.h (WINDOW_FRINGE_EXTENDED_P): New macro. | ||
| 843 | * nsterm.m (ns_set_vertical_scroll_bar): Use it. Use convenient | ||
| 844 | bool instead of BOOL. | ||
| 845 | * w32term.h (struct scroll_bar): Convert fringe_extended_p | ||
| 846 | from Lisp_Object to bitfield. Adjust comment. | ||
| 847 | * w32term.c (x_scroll_bar_create): Adjust user. | ||
| 848 | Use WINDOW_FRINGE_EXTENDED_P and bool for boolean. | ||
| 849 | * xterm.c (XTset_vertical_scroll_bar): Likewise. | ||
| 850 | Use bool for boolean. | ||
| 851 | * xterm.h (struct scroll_bar): Prefer commonly used `unsigned' | ||
| 852 | to `unsigned int' when defining a bitfield. | ||
| 853 | |||
| 854 | 2013-08-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 855 | |||
| 856 | * decompress.c (Fzlib_decompress_region): Try to clarify 'avail_out'. | ||
| 857 | |||
| 858 | 2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 859 | |||
| 860 | * window.h (struct window): Convert left_margin_cols and | ||
| 861 | right_margin_cols from Lisp_Objects to integers. Adjust comment. | ||
| 862 | (WINDOW_LEFT_MARGIN_COLS, WINDOW_RIGHT_MARGIN_COLS) | ||
| 863 | (WINDOW_LEFT_MARGIN_WIDTH, WINDOW_RIGHT_MARGIN_WIDTH): | ||
| 864 | Adjust users. | ||
| 865 | * dispnew.c (margin_glyphs_to_reserve): Convert 3rd arg to int. | ||
| 866 | Adjust comment. | ||
| 867 | (showing_window_margins_p, update_window_line, update_frame_1): | ||
| 868 | * fringe.c (draw_fringe_bitmap_1): | ||
| 869 | * xdisp.c (window_box_width): Adjust users. | ||
| 870 | * window.c (wset_left_margin_cols, wset_right_margin_cols): Remove. | ||
| 871 | (adjust_window_margins, set_window_buffer, Fsplit_window_internal): | ||
| 872 | Use direct assignment. | ||
| 873 | (Fset_window_configuration, save_window_save, Fwindow_margins): | ||
| 874 | Convert Lisp_Object to integer and back where appropriate. | ||
| 875 | (Fset_window_margins): Adjust user. Return t if any margin | ||
| 876 | was actually changed, and mention this in docstring. | ||
| 877 | |||
| 878 | 2013-08-13 Xue Fuqiao <xfq.free@gmail.com> | ||
| 879 | |||
| 880 | * syntax.c (forward_word): | ||
| 881 | * cmds.c (forward_char, backward_char): Mention the optional argument. | ||
| 882 | |||
| 883 | 2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 884 | |||
| 885 | * window.h (struct window): Convert left_fringe_width | ||
| 886 | and right_fringe_width from Lisp_Objects to integers. | ||
| 887 | Adjust comment. | ||
| 888 | (WINDOW_FRINGE_COLS, WINDOW_LEFT_FRINGE_WIDTH) | ||
| 889 | (WINDOW_RIGHT_FRINGE_WIDTH): Adjust users. | ||
| 890 | * window.c (wset_left_fringe_width, wset_right_fringe_width): | ||
| 891 | Remove. | ||
| 892 | (make_window): Initialize new integer fields to -1. | ||
| 893 | (Fsplit_window_internal): Use direct assignment. | ||
| 894 | (Fset_window_configuration, save_window_save): | ||
| 895 | Convert Lisp_Object to integer and back where appropriate. | ||
| 896 | (Fset_window_fringes): Adjust user. Return t if any fringe | ||
| 897 | was actually changed, and mention this in docstring. | ||
| 898 | |||
| 899 | 2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 900 | |||
| 901 | * keyboard.c (Fdiscard_input): Do not increment update_mode_lines. | ||
| 902 | * nsfns.m (x_set_cursor_type): | ||
| 903 | * w32fns.c (x_set_cursor_type): | ||
| 904 | * xfns.m (x_set_cursor_type): Do not set cursor_type_changed here... | ||
| 905 | * xdisp.c (set_frame_cursor_types): ...but in common code. | ||
| 906 | |||
| 907 | 2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 908 | |||
| 909 | * font.c (clear_font_cache): New function, stripped from... | ||
| 910 | (Fclear_font_cache): ...here, which now uses the function | ||
| 911 | above. Adjust comment. | ||
| 912 | * font.h (clear_font_cache): Add prototype. | ||
| 913 | * xfaces.c (clear_face_cache): Use clear_font_cache. | ||
| 914 | |||
| 915 | 2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 916 | |||
| 917 | * window.c (Fset_window_start): Compare `w', not `window' because | ||
| 918 | `w' might not be equal to `window' after call to decode_live_window. | ||
| 919 | |||
| 920 | 2013-08-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 921 | |||
| 922 | * process.c (deactivate_process): Reset fds to -1 (Bug#15035). | ||
| 923 | This fixes a problem introduced by the Bug#15035 patch | ||
| 924 | when using GPG. Reported by Herbert J. Skuhra. | ||
| 925 | |||
| 926 | 2013-08-12 Eli Zaretskii <eliz@gnu.org> | ||
| 927 | |||
| 928 | * decompress.c <zlib_initialized> [WINDOWSNT]: New static variable. | ||
| 929 | (Fzlib_decompress_region) [WINDOWSNT]: Call init_zlib_functions if | ||
| 930 | not yet initialized. | ||
| 931 | |||
| 932 | 2013-08-12 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 933 | |||
| 934 | * decompress.c (Fzlib_decompress_region): Support zlib | ||
| 935 | decompression, too, and rename. | ||
| 936 | |||
| 937 | 2013-08-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 938 | |||
| 939 | Minor zlib configuration tweaks. | ||
| 940 | * decompress.c (fn_inflateInit2) [!WINDOWSNT]: | ||
| 941 | Don't assume presence of fn_inflateInit2_ zlib internal function. | ||
| 942 | |||
| 943 | 2013-08-12 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 944 | |||
| 945 | * decompress.c (Fzlib_decompress_gzipped_region): Rename to | ||
| 946 | include the zlib prefix. | ||
| 947 | |||
| 948 | 2013-08-12 Eli Zaretskii <eliz@gnu.org> | ||
| 949 | |||
| 950 | * decompress.c [WINDOWSNT]: Include windows.h and w32.h. | ||
| 951 | (DEF_ZLIB_FN, LOAD_ZLIB_FN) [WINDOWSNT]: New macros. Use them to | ||
| 952 | define static variables that are pointers to zlib functions to be | ||
| 953 | dynamically loaded. | ||
| 954 | (init_zlib_functions) [WINDOWSNT]: New function. | ||
| 955 | (fn_inflateInit2_, fn_inflate, fn_inflateEnd, fn_inflateInit2): | ||
| 956 | New macros. | ||
| 957 | (Fdecompress_gzipped_region, unwind_decompress): Use the fn_* | ||
| 958 | macros instead of invoking the zlib functions directly. | ||
| 959 | (syms_of_decompress): DEFSYM Qzlib_dll. | ||
| 960 | Staticpro Szlib_available_p. | ||
| 961 | |||
| 962 | 2013-08-12 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 963 | |||
| 964 | Avoid looping over all frame windows to freeze and unfreeze. | ||
| 965 | * window.h (struct window): Drop frozen_window_start_p. | ||
| 966 | (freeze_window_starts): Drop prototype. | ||
| 967 | * frame.h (struct frame): New frozen_window_starts flag. | ||
| 968 | (FRAME_WINDOWS_FROZEN): New macro. | ||
| 969 | * window.c (freeze_window_start, freeze_window_starts): | ||
| 970 | Remove. | ||
| 971 | (select_window, replace_window): Adjust users. | ||
| 972 | * xdisp.c (resize_mini_window): Use FRAME_WINDOWS_FROZEN. | ||
| 973 | (window_frozen_p): New function. | ||
| 974 | (redisplay_window): Use it. | ||
| 975 | |||
| 976 | 2013-08-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 977 | |||
| 978 | Fix some fd issues when running subprocesses (Bug#15035). | ||
| 979 | Fix bugs that can leak files or file descriptors on errors. | ||
| 980 | Don't unlink open temp files, as that's hard for users to diagnose | ||
| 981 | when things go awry (e.g., temp disk exhausted). | ||
| 982 | Don't bother to lock temp files. Check for invalid recursion. | ||
| 983 | * callproc.c (synch_process_fd): Remove. All uses removed. | ||
| 984 | (synch_process_tempfile): New var or macro. | ||
| 985 | (CALLPROC_STDOUT, CALLPROC_STDERR, CALLPROC_PIPEREAD, CALLPROC_FDS): | ||
| 986 | New constants. | ||
| 987 | (record_kill_process): New arg, the temp name. All callers changed. | ||
| 988 | (delete_temp_file): Now just a simple wrapper around unlink. | ||
| 989 | (call_process_kill): New arg, the call_process_fd array. | ||
| 990 | Close them all. Clear synch_process_pid. Remove the temp file, | ||
| 991 | or arrange for it to be removed. | ||
| 992 | (call_process_cleanup) [MSDOS]: Arg no longer contains file name; | ||
| 993 | that's been moved to synch_process_tempfile. Caller changed. | ||
| 994 | Do not remove the tempfile; that's now call_process_kill's | ||
| 995 | responsibility. | ||
| 996 | (call_process_cleanup) [!MSDOS]: Do not record unwind-protect for | ||
| 997 | call_process_kill; the caller now does that. | ||
| 998 | (call_process_cleanup): Do not close the process fd; that's now | ||
| 999 | call_process_kill's responsibility. | ||
| 1000 | (Fcall_process): Implement via new function call_process, which | ||
| 1001 | has most of the old body of Fcall_process, but with a different API. | ||
| 1002 | (call_process): New function that does not open or close filefd if | ||
| 1003 | it is nonnegative. Record which fds need to be closed, and let | ||
| 1004 | call_process_kill close (and remove the tempfile, on MSDOS) on error. | ||
| 1005 | Signal an error if invoked recursively (could be done via a hook). | ||
| 1006 | Simplify creation of the tempfile in the MSDOS case. | ||
| 1007 | Don't create the output file until after checking for the executable. | ||
| 1008 | Report any failure to open /dev/null. | ||
| 1009 | Don't open /dev/null for writing twice; once is enough. | ||
| 1010 | Don't create pipe if all output is being discarded or sent to file. | ||
| 1011 | Don't worry about setting up the coding system or reading from the | ||
| 1012 | pipe if all output is being discarded. | ||
| 1013 | Hoist fd_error local into top level, to lessen block nesting. | ||
| 1014 | Don't record deleted pid here; now done by Fcall_process_region. | ||
| 1015 | (Fcall_process) [MSDOS]: Report mktemp failure immediately, | ||
| 1016 | and note its success in synch_process_tempfile. | ||
| 1017 | Do not leak resources when child_setup fails. | ||
| 1018 | (Fcall_process) [!MSDOS && !WINDOWSNT]: Remove duplicate assignment | ||
| 1019 | to child_errno. Remove unnecessary close of fd0; it's close-on-exec. | ||
| 1020 | (create_temp_file): Now returns open fd, with an additional | ||
| 1021 | Lisp_Object * argument to return the name. All callers changed. | ||
| 1022 | Do not close the file; rewind it instead, and leave it open for | ||
| 1023 | the caller. Do not lock the temp file. Unwind-protect the file | ||
| 1024 | and the file-descriptor. | ||
| 1025 | (Fcall_process_region): If the input is /dev/null, unwind-protect it. | ||
| 1026 | If an asynchrounous process, record it here, not in call_process. | ||
| 1027 | (syms_of_callproc) [MSDOS]: Initialize synch_process_tempfile. | ||
| 1028 | * eval.c (set_unwind_protect): New function. | ||
| 1029 | * fileio.c (write_region): New function, generalized from the | ||
| 1030 | old Fwrite_region. Do not lock temp files. | ||
| 1031 | (Fwrite_region): Use it. | ||
| 1032 | * lisp.h (set_unwind_protect, write_region): New decls. | ||
| 1033 | * process.c: Include <verify.h>. | ||
| 1034 | (make_process): Mark fds as initially closed. | ||
| 1035 | (deleted_pid_list): Now a list of pid-filename pairs. | ||
| 1036 | All uses changed. | ||
| 1037 | (close_process_fd): New function. | ||
| 1038 | (SUBPROCESS_STDIN, WRITE_TO_SUBPROCESS, READ_FROM_SUBPROCESS) | ||
| 1039 | (SUBPROCESS_STDOUT, READ_FROM_EXEC_MONITOR, EXEC_MONITOR_OUTPUT): | ||
| 1040 | New constants. Verify that their number matches PROCESS_OPEN_FDS. | ||
| 1041 | (create_process, create_pty, Fmake_serial_process) | ||
| 1042 | (server_accept_connection): Record which fds need to be closed, | ||
| 1043 | and let deactivate_process close them. | ||
| 1044 | (Fmake_network_process): Do not discard the unwind-protect | ||
| 1045 | until it's safe to do so. | ||
| 1046 | (deactivate_process): Close the fds opened by create_process etc. | ||
| 1047 | (Fprocess_send_eof): Adjust to new way of recording open fds. | ||
| 1048 | Report an error if /dev/null can't be opened, instead of aborting. | ||
| 1049 | * process.h (PROCESS_OPEN_FDS): New constant. | ||
| 1050 | (struct Lisp_Process): New member open_fds. | ||
| 1051 | (record_kill_process, record_deleted_pid): Adjust signatures. | ||
| 1052 | (record_deleted_pid): Move decl here ... | ||
| 1053 | * syswait.h (record_deleted_pid): ... from here. | ||
| 1054 | |||
| 1055 | 2013-08-11 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1056 | |||
| 1057 | * decompress.c: Fix bugs with large buffers and weird inputs. | ||
| 1058 | Tune a bit. Reindent as per usual Emacs style. | ||
| 1059 | (BUFFER_SIZE): Remove. | ||
| 1060 | (Fdecompress_gzipped_region): Do not mishandle input buffers with | ||
| 1061 | more than UINT_MAX bytes. Decompress into the gap instead of into | ||
| 1062 | an auto buffer, as this should avoid copying. Return nil if | ||
| 1063 | 'inflate' returns Z_NEED_DICT, as we have no dictionary. Do not | ||
| 1064 | set immediate_quit; we shouldn't trust zlib code that much. | ||
| 1065 | |||
| 1066 | 2013-08-11 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 1067 | |||
| 1068 | * decompress.c (Fdecompress_gzipped_region): Respect all zlib | ||
| 1069 | errors, and really move the gap to where we want it. | ||
| 1070 | |||
| 1071 | * lisp.h: Include decompress.c support. | ||
| 1072 | |||
| 1073 | * emacs.c (main): Include decompress.c support. | ||
| 1074 | |||
| 1075 | * Makefile.in: Include -lz if present. | ||
| 1076 | |||
| 1077 | 2013-08-11 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1078 | |||
| 1079 | * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:frame: | ||
| 1080 | (initWithTitle:): Initialize frame to 0. | ||
| 1081 | (fillWithWidgetValue:): Call fillWithWidgetValue:frame. | ||
| 1082 | (fillWithWidgetValue:frame:): Rename from | ||
| 1083 | fillWithWidgetValue:setDelegate, call initWithTile:frame: if f. | ||
| 1084 | |||
| 1085 | * nsterm.h (EmacsMenu): fillWithWidgetValue:setDelegate renamed to | ||
| 1086 | fillWithWidgetValue:frame: | ||
| 1087 | |||
| 1088 | * nsfns.m (Fns_convert_utf8_nfd_to_nfc): Allocate and release pool to | ||
| 1089 | remove memory leak warnings. | ||
| 1090 | |||
| 1091 | * nsterm.m (menu_pending_title, ns_get_pending_menu_title): Remove. | ||
| 1092 | (ns_check_menu_open): Handle menu == nil. Remove assignment to | ||
| 1093 | menu_pending_title. | ||
| 1094 | |||
| 1095 | * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:setDelegate. | ||
| 1096 | (x_activate_menubar): Update the whole menu. | ||
| 1097 | (trackingNotification:): Call ns_check_menu_open if tracking ends. | ||
| 1098 | (menuWillOpen:): Increment trackingMenu. For OSX <= 10.6, exit if | ||
| 1099 | current event is not NSSystemDefined (Bug#15001). | ||
| 1100 | Call ns_check_menu_open only if trackingMenu is 2. | ||
| 1101 | (menuDidClose:): New method, decrease trackingMenu. | ||
| 1102 | (fillWithWidgetValue:setDelegate:): New method. | ||
| 1103 | (fillWithWidgetValue:): Call the above. | ||
| 1104 | |||
| 1105 | * nsterm.h (EmacsMenu): Add fillWithWidgetValue:setDelegate: | ||
| 1106 | |||
| 1107 | 2013-08-11 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1108 | |||
| 1109 | Omit some unnecessary casts. | ||
| 1110 | Many of these go back to the old pre-C89 days, when they may have | ||
| 1111 | been needed, but we've been assuming C89 or later for a while now. | ||
| 1112 | * alloc.c (live_string_p, live_cons_p, live_symbol_p) | ||
| 1113 | (live_float_p, live_misc_p, live_vector_p): | ||
| 1114 | * buffer.c (compare_overlays, cmp_for_strings, mmap_find) | ||
| 1115 | (mmap_alloc, alloc_buffer_text, enlarge_buffer_text) | ||
| 1116 | (defvar_per_buffer): | ||
| 1117 | * callint.c (Fcall_interactively): | ||
| 1118 | * doc.c (Fsubstitute_command_keys): | ||
| 1119 | * filelock.c (get_boot_time): | ||
| 1120 | * frame.c (xrdb_get_resource): | ||
| 1121 | * gtkutil.c (hierarchy_ch_cb, qttip_cb, style_changed_cb) | ||
| 1122 | (delete_cb, xg_dialog_response_cb, xg_maybe_add_timer) | ||
| 1123 | (xg_get_file_name_from_selector, menuitem_destroy_callback) | ||
| 1124 | (menuitem_highlight_callback, menu_destroy_callback) | ||
| 1125 | (xg_update_menu_item, xg_modify_menubar_widgets, menubar_map_cb) | ||
| 1126 | (xg_tool_bar_callback, xg_get_tool_bar_widgets) | ||
| 1127 | (xg_tool_bar_detach_callback, xg_tool_bar_attach_callback) | ||
| 1128 | (xg_tool_bar_help_callback, tb_size_cb): | ||
| 1129 | * image.c (xpm_alloc_color, png_read_from_memory) | ||
| 1130 | (png_read_from_file, png_load_body, our_memory_skip_input_data) | ||
| 1131 | (jpeg_memory_src, jpeg_file_src, imagemagick_load_image) | ||
| 1132 | (syms_of_image): | ||
| 1133 | * keymap.c (describe_map): | ||
| 1134 | * nsfns.m (Fns_display_monitor_attributes_list): | ||
| 1135 | * nsmenu.m (process_dialog:): | ||
| 1136 | * nsterm.m (hold_event): | ||
| 1137 | * process.c (wait_reading_process_output): | ||
| 1138 | * regex.c (REGEX_REALLOCATE, re_set_registers, re_exec, regexec): | ||
| 1139 | * scroll.c (do_direct_scrolling, scrolling_1): | ||
| 1140 | * termcap.c (tgetent): | ||
| 1141 | * window.c (check_window_containing, add_window_to_list) | ||
| 1142 | (freeze_window_starts): | ||
| 1143 | * xdisp.c (compare_overlay_entries, vmessage): | ||
| 1144 | * xfns.c (x_window, x_get_monitor_attributes_xinerama) | ||
| 1145 | (x_get_monitor_attributes_xrandr) | ||
| 1146 | (Fx_display_monitor_attributes_list, x_display_info_for_name) | ||
| 1147 | (Fx_open_connection, file_dialog_cb, file_dialog_unmap_cb): | ||
| 1148 | * xfont.c (xfont_match, xfont_open): | ||
| 1149 | * xmenu.c (x_menu_wait_for_event, menu_highlight_callback) | ||
| 1150 | (menubar_selection_callback, menu_position_func) | ||
| 1151 | (popup_selection_callback, create_and_show_popup_menu) | ||
| 1152 | (dialog_selection_callback, create_and_show_dialog): | ||
| 1153 | * xrdb.c (x_get_string_resource): | ||
| 1154 | (main) [TESTRM]: | ||
| 1155 | * xsmfns.c (x_session_check_input): | ||
| 1156 | * xterm.c (x_draw_glyphless_glyph_string_foreground) | ||
| 1157 | (xm_scroll_callback, xg_scroll_callback, xg_end_scroll_callback) | ||
| 1158 | (xaw_jump_callback, xaw_scroll_callback): | ||
| 1159 | Omit unnecessary casts. | ||
| 1160 | |||
| 1161 | 2013-08-10 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1162 | |||
| 1163 | Minor string-length refactoring. | ||
| 1164 | * alloc.c (xstrdup): Use memcpy, not strcpy, since the length's known. | ||
| 1165 | * frame.c (make_monitor_attribute_list): | ||
| 1166 | Prefer build_string to strlen + make_string. | ||
| 1167 | |||
| 1168 | 2013-08-10 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1169 | |||
| 1170 | * xterm.c (x_error_handler): Also ignore BadWindow for X_SetInputFocus, | ||
| 1171 | don't check minor_code (Bug#14417). | ||
| 1172 | |||
| 1173 | 2013-08-09 Eli Zaretskii <eliz@gnu.org> | ||
| 1174 | |||
| 1175 | * xdisp.c (draw_glyphs): Don't compare row pointers, compare row | ||
| 1176 | vertical positions instead. This avoids calling MATRIX_ROW with | ||
| 1177 | row numbers that are possibly beyond valid limits. (Bug#15064) | ||
| 1178 | |||
| 1179 | 2013-08-09 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1180 | |||
| 1181 | Use xstrdup and build_unibyte_string where applicable. | ||
| 1182 | * alloc.c (xstrdup): Tiny cleanup. Add eassert. | ||
| 1183 | * xfns.c (x_window): | ||
| 1184 | * xrdb.c (x_get_customization_string): | ||
| 1185 | * xterm.c (xim_initialize): | ||
| 1186 | * w32fns.c (w32_window): Use xstrdup. | ||
| 1187 | (w32_display_monitor_attributes_list): | ||
| 1188 | * emacs.c (init_cmdargs): | ||
| 1189 | * keyboard.c (PUSH_C_STR): | ||
| 1190 | * nsfont.m (nsfont_open): | ||
| 1191 | * sysdep.c (system_process_attributes): | ||
| 1192 | * w32.c (system_process_attributes): | ||
| 1193 | * xdisp.c (message1, message1_nolog): Use build_unibyte_string. | ||
| 1194 | |||
| 1195 | 2013-08-09 Eli Zaretskii <eliz@gnu.org> | ||
| 1196 | |||
| 1197 | * w32.c (PEXCEPTION_POINTERS, PEXCEPTION_RECORD, PCONTEXT): Define | ||
| 1198 | variables of these types so that GDB would know about them, as aid | ||
| 1199 | for debugging fatal exceptions. (Bug#15024) See also | ||
| 1200 | http://sourceware.org/ml/gdb/2013-08/msg00010.html for related | ||
| 1201 | discussions. | ||
| 1202 | |||
| 1203 | 2013-08-08 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1204 | |||
| 1205 | * nsterm.m (ns_update_begin): Don't change clip path if it would be | ||
| 1206 | larger than the NSWindow (Bug#14934). | ||
| 1207 | |||
| 1208 | 2013-08-08 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1209 | |||
| 1210 | Redesign redisplay interface to drop global variable updated_window. | ||
| 1211 | Always pass currently updated window as a parameter to update routines. | ||
| 1212 | * dispextern.h (updated_window): Remove declaration. | ||
| 1213 | (struct redisplay_interface): Pass window parameter to | ||
| 1214 | write_glyphs, insert_glyphs, clear_end_of_line, cursor_to | ||
| 1215 | and after_update_window_hook. | ||
| 1216 | (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to): | ||
| 1217 | Adjust prototypes. | ||
| 1218 | * dispnew.c (updated_window): Remove. | ||
| 1219 | (redraw_overlapped_rows, update_marginal_area, update_text_area) | ||
| 1220 | (update_window_line): Adjust to match redisplay interface changes. | ||
| 1221 | * nsterm.m (ns_update_window_begin, ns_update_window_end) | ||
| 1222 | (ns_scroll_run, ns_after_update_window_line): | ||
| 1223 | * w32term.c (x_update_window_begin, x_update_window_end) | ||
| 1224 | (x_after_update_window_line, x_scroll_run): | ||
| 1225 | * xterm.c (x_update_window_begin, x_update_window_end) | ||
| 1226 | (x_after_update_window_line, x_scroll_run): | ||
| 1227 | * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): | ||
| 1228 | Likewise. Adjust comments where appropriate. | ||
| 1229 | (x_cursor_to): Simplify because this is always called during window | ||
| 1230 | update (but install debugging check anyway). | ||
| 1231 | (expose_window): Check must_be_updated_p flag to see whether this | ||
| 1232 | function is called during window update. | ||
| 1233 | |||
| 1234 | 2013-08-08 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1235 | |||
| 1236 | Do not reset window modification event counters excessively. | ||
| 1237 | These leftovers and poor man's tricky methods to catch extra | ||
| 1238 | redisplay's attention are no longer needed. | ||
| 1239 | * frame.c (set_menu_bar_lines_1): | ||
| 1240 | * minibuf.c (read_minibuf_unwind): | ||
| 1241 | * window.c (Fset_window_start, set_window_buffer, window_resize_apply) | ||
| 1242 | (grow_mini_window, shrink_mini_window, window_scroll_pixel_based) | ||
| 1243 | (window_scroll_line_based, Fset_window_configuration): | ||
| 1244 | * xdisp.c (redisplay_window): Do not reset last_modified and | ||
| 1245 | last_overlay_modified counters. | ||
| 1246 | |||
| 1247 | 2013-08-07 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1248 | |||
| 1249 | * xselect.c (x_send_client_event): Set send_event and serial, memset | ||
| 1250 | data.l as it might be bigger than data.b. Use 24 bit mask to | ||
| 1251 | XSendEvent (Bug#15034). | ||
| 1252 | |||
| 1253 | 2013-08-07 Eli Zaretskii <eliz@gnu.org> | ||
| 1254 | |||
| 1255 | * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title | ||
| 1256 | for TTY frames that are not the top frame on their console. | ||
| 1257 | (Bug#14616) | ||
| 1258 | |||
| 1259 | 2013-08-07 Martin Rudalics <rudalics@gmx.at> | ||
| 1260 | |||
| 1261 | * w32term.c (w32fullscreen_hook): Really maximize frame when | ||
| 1262 | asked for (Bug#14841). | ||
| 1263 | |||
| 1264 | 2013-08-07 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1265 | |||
| 1266 | Prefer selected_window to Fselected_window, likewise for frames. | ||
| 1267 | * buffer.c (Fbuffer_swap_text): | ||
| 1268 | * data.c (Fvariable_binding_locus): | ||
| 1269 | * window.c (run_window_configuration_change_hook): Adjust users. | ||
| 1270 | * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data): | ||
| 1271 | Use decode_live_frame. | ||
| 1272 | |||
| 1273 | 2013-08-07 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1274 | |||
| 1275 | Be more careful if selected window shows the buffer other than current, | ||
| 1276 | use window_outdated only if this is not so. This change should also | ||
| 1277 | address some weird issues discussed in Bug#13012. | ||
| 1278 | * window.h (window_outdated): New prototype. | ||
| 1279 | * window.c (window_outdated): Now here. Convert from static and | ||
| 1280 | always assume window's buffer. | ||
| 1281 | (Fwindow_end, Fwindow_line_height): Use it. | ||
| 1282 | * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg | ||
| 1283 | and always assume window's buffer. | ||
| 1284 | (redisplay_window): Adjust user. | ||
| 1285 | (redisplay_internal): Call to reconsider_clip_changes once and | ||
| 1286 | check whether mode line should be updated only if selected window | ||
| 1287 | shows current buffer. | ||
| 1288 | (run_window_scroll_functions): Use eassert for debugging check. | ||
| 1289 | (Fmove_point_visually, note_mouse_highlight): Use window_outdated. | ||
| 1290 | |||
| 1291 | 2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1292 | |||
| 1293 | * window.c (window_scroll, window_scroll_pixel_based) | ||
| 1294 | (window_scroll_line_based): Use bool for booleans. | ||
| 1295 | |||
| 1296 | 2013-08-06 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1297 | |||
| 1298 | * process.c: Fix minor off-by-one issues in descriptor counts. | ||
| 1299 | This shouldn't fix any real bugs, but it cleans up the code a bit. | ||
| 1300 | (max_process_desc, max_input_desc): -1, not 0, means none. | ||
| 1301 | All uses changed. | ||
| 1302 | (delete_input_desc): New function. | ||
| 1303 | (delete_write_fd, delete_keyboard_wait_descriptor): Use it. | ||
| 1304 | (deactivate_process): Scan backwards when recomuting max_process_desc; | ||
| 1305 | that should be faster. | ||
| 1306 | (init_process_emacs): Initialize max_input_desc. | ||
| 1307 | |||
| 1308 | 2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1309 | |||
| 1310 | Use region cache to speedup bidi_find_paragraph_start. | ||
| 1311 | * buffer.h (struct buffer): New member bidi_paragraph_cache. | ||
| 1312 | Rename cache_long_line_scans to cache_long_scans. | ||
| 1313 | * buffer.c (bset_cache_long_line_scans): Rename to | ||
| 1314 | bset_cache_long_scans. | ||
| 1315 | (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer) | ||
| 1316 | (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache | ||
| 1317 | into account. | ||
| 1318 | (syms_of_buffer): Rename cache-long-line-scans to | ||
| 1319 | cache-long-scans. Adjust docstring. | ||
| 1320 | * search.c (newline_cache_on_off): | ||
| 1321 | * indent.c (width_run_cache_on_off): Adjust users. | ||
| 1322 | * bidi.c (bidi_paragraph_cache_on_off): New function. | ||
| 1323 | (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed. | ||
| 1324 | * insdel.c (prepare_to_modify_buffer): | ||
| 1325 | Invalidate bidi_paragraph_cache if enabled. | ||
| 1326 | |||
| 1327 | 2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1328 | |||
| 1329 | Invalidate region caches only if buffer text is going to be changed. | ||
| 1330 | * lisp.h (modify_region_1): Remove 3rd arg and rename to... | ||
| 1331 | (modify_text): ...new prototype. | ||
| 1332 | (prepare_to_modify_buffer_1): New prototype. | ||
| 1333 | * textprop.c (modify_region): Rename to... | ||
| 1334 | (modify_text_properties): ...new function. | ||
| 1335 | (add_text_properties_1, set_text_properties, Fremove_text_properties) | ||
| 1336 | (Fremove_list_of_text_properties): Adjust users. | ||
| 1337 | * insdel.c (modify_region_1): Remove 3rd arg and reimplement as... | ||
| 1338 | (modify_text): ...new function. | ||
| 1339 | (prepare_to_modify_buffer): Reimplement mostly as a wrapper for... | ||
| 1340 | (prepare_to_modify_buffer_1): ...new function. | ||
| 1341 | * casefiddle.c (casify_region): | ||
| 1342 | * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) | ||
| 1343 | (Ftranspose_regions): Use modify_text. | ||
| 1344 | |||
| 1345 | 2013-08-05 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 1346 | |||
| 1347 | * lisp.mk (lisp): Add nadvice.elc. | ||
| 1348 | |||
| 1349 | 2013-08-05 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1350 | |||
| 1351 | New macro to iterate over live buffers similar to frames. | ||
| 1352 | * buffer.h (FOR_EACH_LIVE_BUFFER): New macro. | ||
| 1353 | (Vbuffer_alist, Qpriority, Qbefore_string, Qafter_string): | ||
| 1354 | Declare buffer-related variables here to offload lisp.h. | ||
| 1355 | * buffer.c (Vbuffer_alist): Adjust comment. | ||
| 1356 | (Fget_file_buffer, get_truename_buffer, Fother_buffer) | ||
| 1357 | (other_buffer_safely): | ||
| 1358 | * data.c (store_symval_forwarding): | ||
| 1359 | * dispnew.c (Fframe_or_buffer_changed_p): | ||
| 1360 | * fileio.c (Fdo_auto_save): | ||
| 1361 | * filelock.c (unlock_all_files): | ||
| 1362 | * minibuf.c (read_minibuf): Use FOR_EACH_LIVE_BUFFER. | ||
| 1363 | |||
| 1364 | 2013-08-04 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1365 | |||
| 1366 | Fix some minor races in hosts lacking mkostemp (Bug#15015). | ||
| 1367 | * callproc.c (create_temp_file): | ||
| 1368 | * filelock.c (create_lock_file): | ||
| 1369 | Assume mkostemp, since it's now provided by Gnulib. | ||
| 1370 | |||
| 1371 | 2013-08-04 Eli Zaretskii <eliz@gnu.org> | ||
| 1372 | |||
| 1373 | * w32.c (mkostemp): New function. | ||
| 1374 | (mktemp): Remove, no longer used. Most of the code reused in | ||
| 1375 | mkostemp. (Bug#15015) | ||
| 1376 | (mktemp): Don't undef. | ||
| 1377 | |||
| 1378 | 2013-08-04 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1379 | |||
| 1380 | * dispnew.c (glyph_matrix_count, glyph_pool_count): | ||
| 1381 | Move under GLYPH_DEBUG and ENABLE_CHECKING. | ||
| 1382 | (new_glyph_matrix, free_glyph_matrix, new_glyph_pool) | ||
| 1383 | (free_glyph_pool, check_glyph_memory): Likewise for | ||
| 1384 | all users. Adjust comments where appropriate. | ||
| 1385 | |||
| 1 | 2013-08-03 Paul Eggert <eggert@cs.ucla.edu> | 1386 | 2013-08-03 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 1387 | ||
| 3 | * composite.h: Minor fixups. | 1388 | * composite.h: Minor fixups. |
| @@ -108,8 +1493,8 @@ | |||
| 108 | Avoid redundant Lisp_Object <-> struct frame conversions in font API. | 1493 | Avoid redundant Lisp_Object <-> struct frame conversions in font API. |
| 109 | * font.h (struct font_driver): Change list, match, and list_family | 1494 | * font.h (struct font_driver): Change list, match, and list_family |
| 110 | functions to accept struct frame * as first arg. | 1495 | functions to accept struct frame * as first arg. |
| 111 | * font.c (font_score, font_compare, font_sort_entities): Remove | 1496 | * font.c (font_score, font_compare, font_sort_entities): |
| 112 | prototypes. | 1497 | Remove prototypes. |
| 113 | (font_sort_entities, font_list_entities, font_select_entity): | 1498 | (font_sort_entities, font_list_entities, font_select_entity): |
| 114 | (font_find_for_lface, Flist_fonts, Ffont_family_list): Adjust to | 1499 | (font_find_for_lface, Flist_fonts, Ffont_family_list): Adjust to |
| 115 | match font API change. | 1500 | match font API change. |
| @@ -416,9 +1801,9 @@ | |||
| 416 | or fscanf fails. | 1801 | or fscanf fails. |
| 417 | (system_process_attributes): Prefer plain char to unsigned char | 1802 | (system_process_attributes): Prefer plain char to unsigned char |
| 418 | when either will do. Clean up properly if interrupted or if | 1803 | when either will do. Clean up properly if interrupted or if |
| 419 | memory allocations fail. Don't assume sscanf succeeds. Remove | 1804 | memory allocations fail. Don't assume sscanf succeeds. |
| 420 | no-longer-needed workaround to stop GCC from whining. Read | 1805 | Remove no-longer-needed workaround to stop GCC from whining. |
| 421 | command-line once, instead of multiple times. Check read status a | 1806 | Read command-line once, instead of multiple times. Check read status a |
| 422 | bit more carefully. | 1807 | bit more carefully. |
| 423 | 1808 | ||
| 424 | Fix obscure porting bug with varargs functions. | 1809 | Fix obscure porting bug with varargs functions. |
| @@ -772,8 +2157,8 @@ | |||
| 772 | of the old Fcall_process_region. Use Fcopy_sequence to create the | 2157 | of the old Fcall_process_region. Use Fcopy_sequence to create the |
| 773 | temp file name, rather than alloca + build_string, for simplicity. | 2158 | temp file name, rather than alloca + build_string, for simplicity. |
| 774 | Don't bother to block input around the temp file creation; | 2159 | Don't bother to block input around the temp file creation; |
| 775 | shouldn't be needed. Simplify use of mktemp. Use | 2160 | shouldn't be needed. Simplify use of mktemp. |
| 776 | record_unwind_protect immediately after creating the temp file; | 2161 | Use record_unwind_protect immediately after creating the temp file; |
| 777 | this closes an unlikely race where the temp file was not removed. | 2162 | this closes an unlikely race where the temp file was not removed. |
| 778 | Use memcpy rather than an open-coded loop. | 2163 | Use memcpy rather than an open-coded loop. |
| 779 | (Fcall_process_region): Use the new function. If the input is | 2164 | (Fcall_process_region): Use the new function. If the input is |
| @@ -1132,8 +2517,8 @@ | |||
| 1132 | (try_cursor_movement, redisplay_window, try_window) | 2517 | (try_cursor_movement, redisplay_window, try_window) |
| 1133 | (try_window_id): Use it instead of FRAME_LINE_HEIGHT. (Bug#14771) | 2518 | (try_window_id): Use it instead of FRAME_LINE_HEIGHT. (Bug#14771) |
| 1134 | 2519 | ||
| 1135 | * window.c (window_scroll_pixel_based): use | 2520 | * window.c (window_scroll_pixel_based): |
| 1136 | default_line_pixel_height. | 2521 | use default_line_pixel_height. |
| 1137 | 2522 | ||
| 1138 | * dispextern.h (default_line_pixel_height): Add prototype. | 2523 | * dispextern.h (default_line_pixel_height): Add prototype. |
| 1139 | 2524 | ||
diff --git a/src/Makefile.in b/src/Makefile.in index 65927ba236c..0e7ff9cbd33 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | # script may need modifying in sync with changes made here. Try to | 23 | # script may need modifying in sync with changes made here. Try to |
| 24 | # avoid shell-ism because the DOS build has to use the DOS shell. | 24 | # avoid shell-ism because the DOS build has to use the DOS shell. |
| 25 | 25 | ||
| 26 | SHELL = /bin/sh | 26 | SHELL = @SHELL@ |
| 27 | 27 | ||
| 28 | # Here are the things that we expect ../configure to edit. | 28 | # Here are the things that we expect ../configure to edit. |
| 29 | # We use $(srcdir) explicitly in dependencies so as not to depend on VPATH. | 29 | # We use $(srcdir) explicitly in dependencies so as not to depend on VPATH. |
| @@ -243,6 +243,8 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@ | |||
| 243 | LIBXML2_LIBS = @LIBXML2_LIBS@ | 243 | LIBXML2_LIBS = @LIBXML2_LIBS@ |
| 244 | LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ | 244 | LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ |
| 245 | 245 | ||
| 246 | LIBZ = @LIBZ@ | ||
| 247 | |||
| 246 | XRANDR_LIBS = @XRANDR_LIBS@ | 248 | XRANDR_LIBS = @XRANDR_LIBS@ |
| 247 | XRANDR_CFLAGS = @XRANDR_CFLAGS@ | 249 | XRANDR_CFLAGS = @XRANDR_CFLAGS@ |
| 248 | 250 | ||
| @@ -374,7 +376,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ | |||
| 374 | process.o gnutls.o callproc.o \ | 376 | process.o gnutls.o callproc.o \ |
| 375 | region-cache.o sound.o atimer.o \ | 377 | region-cache.o sound.o atimer.o \ |
| 376 | doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \ | 378 | doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \ |
| 377 | profiler.o \ | 379 | profiler.o decompress.o \ |
| 378 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ | 380 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ |
| 379 | $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) | 381 | $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) |
| 380 | obj = $(base_obj) $(NS_OBJC_OBJ) | 382 | obj = $(base_obj) $(NS_OBJC_OBJ) |
| @@ -429,7 +431,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ | |||
| 429 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ | 431 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ |
| 430 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ | 432 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ |
| 431 | $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ | 433 | $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ |
| 432 | $(GFILENOTIFY_LIBS) $(LIB_MATH) | 434 | $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) |
| 433 | 435 | ||
| 434 | all: emacs$(EXEEXT) $(OTHER_FILES) | 436 | all: emacs$(EXEEXT) $(OTHER_FILES) |
| 435 | .PHONY: all | 437 | .PHONY: all |
diff --git a/src/alloc.c b/src/alloc.c index c8141d22f95..8417ef4982b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -318,7 +318,6 @@ static void *min_heap_address, *max_heap_address; | |||
| 318 | static struct mem_node mem_z; | 318 | static struct mem_node mem_z; |
| 319 | #define MEM_NIL &mem_z | 319 | #define MEM_NIL &mem_z |
| 320 | 320 | ||
| 321 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | ||
| 322 | static struct mem_node *mem_insert (void *, void *, enum mem_type); | 321 | static struct mem_node *mem_insert (void *, void *, enum mem_type); |
| 323 | static void mem_insert_fixup (struct mem_node *); | 322 | static void mem_insert_fixup (struct mem_node *); |
| 324 | static void mem_rotate_left (struct mem_node *); | 323 | static void mem_rotate_left (struct mem_node *); |
| @@ -326,7 +325,6 @@ static void mem_rotate_right (struct mem_node *); | |||
| 326 | static void mem_delete (struct mem_node *); | 325 | static void mem_delete (struct mem_node *); |
| 327 | static void mem_delete_fixup (struct mem_node *); | 326 | static void mem_delete_fixup (struct mem_node *); |
| 328 | static struct mem_node *mem_find (void *); | 327 | static struct mem_node *mem_find (void *); |
| 329 | #endif | ||
| 330 | 328 | ||
| 331 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ | 329 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ |
| 332 | 330 | ||
| @@ -796,10 +794,19 @@ xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | |||
| 796 | char * | 794 | char * |
| 797 | xstrdup (const char *s) | 795 | xstrdup (const char *s) |
| 798 | { | 796 | { |
| 799 | size_t len = strlen (s) + 1; | 797 | ptrdiff_t size; |
| 800 | char *p = xmalloc (len); | 798 | eassert (s); |
| 801 | memcpy (p, s, len); | 799 | size = strlen (s) + 1; |
| 802 | return p; | 800 | return memcpy (xmalloc (size), s, size); |
| 801 | } | ||
| 802 | |||
| 803 | /* Like above, but duplicates Lisp string to C string. */ | ||
| 804 | |||
| 805 | char * | ||
| 806 | xlispstrdup (Lisp_Object string) | ||
| 807 | { | ||
| 808 | ptrdiff_t size = SBYTES (string) + 1; | ||
| 809 | return memcpy (xmalloc (size), SSDATA (string), size); | ||
| 803 | } | 810 | } |
| 804 | 811 | ||
| 805 | /* Like putenv, but (1) use the equivalent of xmalloc and (2) the | 812 | /* Like putenv, but (1) use the equivalent of xmalloc and (2) the |
| @@ -2798,7 +2805,7 @@ vector_nbytes (struct Lisp_Vector *v) | |||
| 2798 | static void | 2805 | static void |
| 2799 | sweep_vectors (void) | 2806 | sweep_vectors (void) |
| 2800 | { | 2807 | { |
| 2801 | struct vector_block *block = vector_blocks, **bprev = &vector_blocks; | 2808 | struct vector_block *block, **bprev = &vector_blocks; |
| 2802 | struct large_vector *lv, **lvprev = &large_vectors; | 2809 | struct large_vector *lv, **lvprev = &large_vectors; |
| 2803 | struct Lisp_Vector *vector, *next; | 2810 | struct Lisp_Vector *vector, *next; |
| 2804 | 2811 | ||
| @@ -3472,6 +3479,7 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3472 | p->charpos = 0; | 3479 | p->charpos = 0; |
| 3473 | p->next = NULL; | 3480 | p->next = NULL; |
| 3474 | p->insertion_type = 0; | 3481 | p->insertion_type = 0; |
| 3482 | p->need_adjustment = 0; | ||
| 3475 | return val; | 3483 | return val; |
| 3476 | } | 3484 | } |
| 3477 | 3485 | ||
| @@ -3496,6 +3504,7 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | |||
| 3496 | m->charpos = charpos; | 3504 | m->charpos = charpos; |
| 3497 | m->bytepos = bytepos; | 3505 | m->bytepos = bytepos; |
| 3498 | m->insertion_type = 0; | 3506 | m->insertion_type = 0; |
| 3507 | m->need_adjustment = 0; | ||
| 3499 | m->next = BUF_MARKERS (buf); | 3508 | m->next = BUF_MARKERS (buf); |
| 3500 | BUF_MARKERS (buf) = m; | 3509 | BUF_MARKERS (buf) = m; |
| 3501 | return obj; | 3510 | return obj; |
| @@ -4058,7 +4067,7 @@ live_string_p (struct mem_node *m, void *p) | |||
| 4058 | { | 4067 | { |
| 4059 | if (m->type == MEM_TYPE_STRING) | 4068 | if (m->type == MEM_TYPE_STRING) |
| 4060 | { | 4069 | { |
| 4061 | struct string_block *b = (struct string_block *) m->start; | 4070 | struct string_block *b = m->start; |
| 4062 | ptrdiff_t offset = (char *) p - (char *) &b->strings[0]; | 4071 | ptrdiff_t offset = (char *) p - (char *) &b->strings[0]; |
| 4063 | 4072 | ||
| 4064 | /* P must point to the start of a Lisp_String structure, and it | 4073 | /* P must point to the start of a Lisp_String structure, and it |
| @@ -4081,7 +4090,7 @@ live_cons_p (struct mem_node *m, void *p) | |||
| 4081 | { | 4090 | { |
| 4082 | if (m->type == MEM_TYPE_CONS) | 4091 | if (m->type == MEM_TYPE_CONS) |
| 4083 | { | 4092 | { |
| 4084 | struct cons_block *b = (struct cons_block *) m->start; | 4093 | struct cons_block *b = m->start; |
| 4085 | ptrdiff_t offset = (char *) p - (char *) &b->conses[0]; | 4094 | ptrdiff_t offset = (char *) p - (char *) &b->conses[0]; |
| 4086 | 4095 | ||
| 4087 | /* P must point to the start of a Lisp_Cons, not be | 4096 | /* P must point to the start of a Lisp_Cons, not be |
| @@ -4107,7 +4116,7 @@ live_symbol_p (struct mem_node *m, void *p) | |||
| 4107 | { | 4116 | { |
| 4108 | if (m->type == MEM_TYPE_SYMBOL) | 4117 | if (m->type == MEM_TYPE_SYMBOL) |
| 4109 | { | 4118 | { |
| 4110 | struct symbol_block *b = (struct symbol_block *) m->start; | 4119 | struct symbol_block *b = m->start; |
| 4111 | ptrdiff_t offset = (char *) p - (char *) &b->symbols[0]; | 4120 | ptrdiff_t offset = (char *) p - (char *) &b->symbols[0]; |
| 4112 | 4121 | ||
| 4113 | /* P must point to the start of a Lisp_Symbol, not be | 4122 | /* P must point to the start of a Lisp_Symbol, not be |
| @@ -4133,7 +4142,7 @@ live_float_p (struct mem_node *m, void *p) | |||
| 4133 | { | 4142 | { |
| 4134 | if (m->type == MEM_TYPE_FLOAT) | 4143 | if (m->type == MEM_TYPE_FLOAT) |
| 4135 | { | 4144 | { |
| 4136 | struct float_block *b = (struct float_block *) m->start; | 4145 | struct float_block *b = m->start; |
| 4137 | ptrdiff_t offset = (char *) p - (char *) &b->floats[0]; | 4146 | ptrdiff_t offset = (char *) p - (char *) &b->floats[0]; |
| 4138 | 4147 | ||
| 4139 | /* P must point to the start of a Lisp_Float and not be | 4148 | /* P must point to the start of a Lisp_Float and not be |
| @@ -4157,7 +4166,7 @@ live_misc_p (struct mem_node *m, void *p) | |||
| 4157 | { | 4166 | { |
| 4158 | if (m->type == MEM_TYPE_MISC) | 4167 | if (m->type == MEM_TYPE_MISC) |
| 4159 | { | 4168 | { |
| 4160 | struct marker_block *b = (struct marker_block *) m->start; | 4169 | struct marker_block *b = m->start; |
| 4161 | ptrdiff_t offset = (char *) p - (char *) &b->markers[0]; | 4170 | ptrdiff_t offset = (char *) p - (char *) &b->markers[0]; |
| 4162 | 4171 | ||
| 4163 | /* P must point to the start of a Lisp_Misc, not be | 4172 | /* P must point to the start of a Lisp_Misc, not be |
| @@ -4184,7 +4193,7 @@ live_vector_p (struct mem_node *m, void *p) | |||
| 4184 | if (m->type == MEM_TYPE_VECTOR_BLOCK) | 4193 | if (m->type == MEM_TYPE_VECTOR_BLOCK) |
| 4185 | { | 4194 | { |
| 4186 | /* This memory node corresponds to a vector block. */ | 4195 | /* This memory node corresponds to a vector block. */ |
| 4187 | struct vector_block *block = (struct vector_block *) m->start; | 4196 | struct vector_block *block = m->start; |
| 4188 | struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; | 4197 | struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; |
| 4189 | 4198 | ||
| 4190 | /* P is in the block's allocation range. Scan the block | 4199 | /* P is in the block's allocation range. Scan the block |
| @@ -4229,6 +4238,10 @@ live_buffer_p (struct mem_node *m, void *p) | |||
| 4229 | 4238 | ||
| 4230 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 4239 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4231 | 4240 | ||
| 4241 | /* Currently not used, but may be called from gdb. */ | ||
| 4242 | |||
| 4243 | void dump_zombies (void) EXTERNALLY_VISIBLE; | ||
| 4244 | |||
| 4232 | /* Array of objects that are kept alive because the C stack contains | 4245 | /* Array of objects that are kept alive because the C stack contains |
| 4233 | a pattern that looks like a reference to them . */ | 4246 | a pattern that looks like a reference to them . */ |
| 4234 | 4247 | ||
| @@ -4611,7 +4624,7 @@ check_gcpros (void) | |||
| 4611 | 4624 | ||
| 4612 | #elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 4625 | #elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4613 | 4626 | ||
| 4614 | static void | 4627 | void |
| 4615 | dump_zombies (void) | 4628 | dump_zombies (void) |
| 4616 | { | 4629 | { |
| 4617 | int i; | 4630 | int i; |
| @@ -4748,6 +4761,10 @@ mark_stack (void) | |||
| 4748 | #endif | 4761 | #endif |
| 4749 | } | 4762 | } |
| 4750 | 4763 | ||
| 4764 | #else /* GC_MARK_STACK == 0 */ | ||
| 4765 | |||
| 4766 | #define mark_maybe_object(obj) emacs_abort () | ||
| 4767 | |||
| 4751 | #endif /* GC_MARK_STACK != 0 */ | 4768 | #endif /* GC_MARK_STACK != 0 */ |
| 4752 | 4769 | ||
| 4753 | 4770 | ||
| @@ -5218,7 +5235,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5218 | ptrdiff_t i; | 5235 | ptrdiff_t i; |
| 5219 | bool message_p; | 5236 | bool message_p; |
| 5220 | ptrdiff_t count = SPECPDL_INDEX (); | 5237 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5221 | EMACS_TIME start; | 5238 | struct timespec start; |
| 5222 | Lisp_Object retval = Qnil; | 5239 | Lisp_Object retval = Qnil; |
| 5223 | size_t tot_before = 0; | 5240 | size_t tot_before = 0; |
| 5224 | 5241 | ||
| @@ -5243,7 +5260,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5243 | if (profiler_memory_running) | 5260 | if (profiler_memory_running) |
| 5244 | tot_before = total_bytes_of_live_objects (); | 5261 | tot_before = total_bytes_of_live_objects (); |
| 5245 | 5262 | ||
| 5246 | start = current_emacs_time (); | 5263 | start = current_timespec (); |
| 5247 | 5264 | ||
| 5248 | /* In case user calls debug_print during GC, | 5265 | /* In case user calls debug_print during GC, |
| 5249 | don't let that cause a recursive GC. */ | 5266 | don't let that cause a recursive GC. */ |
| @@ -5506,9 +5523,9 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5506 | /* Accumulate statistics. */ | 5523 | /* Accumulate statistics. */ |
| 5507 | if (FLOATP (Vgc_elapsed)) | 5524 | if (FLOATP (Vgc_elapsed)) |
| 5508 | { | 5525 | { |
| 5509 | EMACS_TIME since_start = sub_emacs_time (current_emacs_time (), start); | 5526 | struct timespec since_start = timespec_sub (current_timespec (), start); |
| 5510 | Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) | 5527 | Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) |
| 5511 | + EMACS_TIME_TO_DOUBLE (since_start)); | 5528 | + timespectod (since_start)); |
| 5512 | } | 5529 | } |
| 5513 | 5530 | ||
| 5514 | gcs_done++; | 5531 | gcs_done++; |
diff --git a/src/atimer.c b/src/atimer.c index 219b3502acc..6aef71db873 100644 --- a/src/atimer.c +++ b/src/atimer.c | |||
| @@ -94,17 +94,16 @@ static struct atimer *append_atimer_lists (struct atimer *, | |||
| 94 | to cancel_atimer; don't free it yourself. */ | 94 | to cancel_atimer; don't free it yourself. */ |
| 95 | 95 | ||
| 96 | struct atimer * | 96 | struct atimer * |
| 97 | start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn, | 97 | start_atimer (enum atimer_type type, struct timespec timestamp, |
| 98 | void *client_data) | 98 | atimer_callback fn, void *client_data) |
| 99 | { | 99 | { |
| 100 | struct atimer *t; | 100 | struct atimer *t; |
| 101 | 101 | ||
| 102 | /* Round TIME up to the next full second if we don't have | 102 | /* Round TIME up to the next full second if we don't have |
| 103 | itimers. */ | 103 | itimers. */ |
| 104 | #ifndef HAVE_SETITIMER | 104 | #ifndef HAVE_SETITIMER |
| 105 | if (EMACS_NSECS (timestamp) != 0 | 105 | if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t)) |
| 106 | && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t)) | 106 | timestamp = make_timespec (timestamp.tv_sec + 1, 0); |
| 107 | timestamp = make_emacs_time (EMACS_SECS (timestamp) + 1, 0); | ||
| 108 | #endif /* not HAVE_SETITIMER */ | 107 | #endif /* not HAVE_SETITIMER */ |
| 109 | 108 | ||
| 110 | /* Get an atimer structure from the free-list, or allocate | 109 | /* Get an atimer structure from the free-list, or allocate |
| @@ -133,11 +132,11 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn, | |||
| 133 | break; | 132 | break; |
| 134 | 133 | ||
| 135 | case ATIMER_RELATIVE: | 134 | case ATIMER_RELATIVE: |
| 136 | t->expiration = add_emacs_time (current_emacs_time (), timestamp); | 135 | t->expiration = timespec_add (current_timespec (), timestamp); |
| 137 | break; | 136 | break; |
| 138 | 137 | ||
| 139 | case ATIMER_CONTINUOUS: | 138 | case ATIMER_CONTINUOUS: |
| 140 | t->expiration = add_emacs_time (current_emacs_time (), timestamp); | 139 | t->expiration = timespec_add (current_timespec (), timestamp); |
| 141 | t->interval = timestamp; | 140 | t->interval = timestamp; |
| 142 | break; | 141 | break; |
| 143 | } | 142 | } |
| @@ -284,7 +283,7 @@ set_alarm (void) | |||
| 284 | #ifdef HAVE_SETITIMER | 283 | #ifdef HAVE_SETITIMER |
| 285 | struct itimerval it; | 284 | struct itimerval it; |
| 286 | #endif | 285 | #endif |
| 287 | EMACS_TIME now, interval; | 286 | struct timespec now, interval; |
| 288 | 287 | ||
| 289 | #ifdef HAVE_ITIMERSPEC | 288 | #ifdef HAVE_ITIMERSPEC |
| 290 | if (alarm_timer_ok) | 289 | if (alarm_timer_ok) |
| @@ -299,10 +298,10 @@ set_alarm (void) | |||
| 299 | 298 | ||
| 300 | /* Determine interval till the next timer is ripe. | 299 | /* Determine interval till the next timer is ripe. |
| 301 | Don't set the interval to 0; this disables the timer. */ | 300 | Don't set the interval to 0; this disables the timer. */ |
| 302 | now = current_emacs_time (); | 301 | now = current_timespec (); |
| 303 | interval = (EMACS_TIME_LE (atimers->expiration, now) | 302 | interval = (timespec_cmp (atimers->expiration, now) <= 0 |
| 304 | ? make_emacs_time (0, 1000 * 1000) | 303 | ? make_timespec (0, 1000 * 1000) |
| 305 | : sub_emacs_time (atimers->expiration, now)); | 304 | : timespec_sub (atimers->expiration, now)); |
| 306 | 305 | ||
| 307 | #ifdef HAVE_SETITIMER | 306 | #ifdef HAVE_SETITIMER |
| 308 | 307 | ||
| @@ -310,7 +309,7 @@ set_alarm (void) | |||
| 310 | it.it_value = make_timeval (interval); | 309 | it.it_value = make_timeval (interval); |
| 311 | setitimer (ITIMER_REAL, &it, 0); | 310 | setitimer (ITIMER_REAL, &it, 0); |
| 312 | #else /* not HAVE_SETITIMER */ | 311 | #else /* not HAVE_SETITIMER */ |
| 313 | alarm (max (EMACS_SECS (interval), 1)); | 312 | alarm (max (interval.tv_sec, 1)); |
| 314 | #endif /* not HAVE_SETITIMER */ | 313 | #endif /* not HAVE_SETITIMER */ |
| 315 | } | 314 | } |
| 316 | } | 315 | } |
| @@ -326,7 +325,7 @@ schedule_atimer (struct atimer *t) | |||
| 326 | struct atimer *a = atimers, *prev = NULL; | 325 | struct atimer *a = atimers, *prev = NULL; |
| 327 | 326 | ||
| 328 | /* Look for the first atimer that is ripe after T. */ | 327 | /* Look for the first atimer that is ripe after T. */ |
| 329 | while (a && EMACS_TIME_LT (a->expiration, t->expiration)) | 328 | while (a && timespec_cmp (a->expiration, t->expiration) < 0) |
| 330 | prev = a, a = a->next; | 329 | prev = a, a = a->next; |
| 331 | 330 | ||
| 332 | /* Insert T in front of the atimer found, if any. */ | 331 | /* Insert T in front of the atimer found, if any. */ |
| @@ -341,9 +340,9 @@ schedule_atimer (struct atimer *t) | |||
| 341 | static void | 340 | static void |
| 342 | run_timers (void) | 341 | run_timers (void) |
| 343 | { | 342 | { |
| 344 | EMACS_TIME now = current_emacs_time (); | 343 | struct timespec now = current_timespec (); |
| 345 | 344 | ||
| 346 | while (atimers && EMACS_TIME_LE (atimers->expiration, now)) | 345 | while (atimers && timespec_cmp (atimers->expiration, now) <= 0) |
| 347 | { | 346 | { |
| 348 | struct atimer *t = atimers; | 347 | struct atimer *t = atimers; |
| 349 | atimers = atimers->next; | 348 | atimers = atimers->next; |
| @@ -351,7 +350,7 @@ run_timers (void) | |||
| 351 | 350 | ||
| 352 | if (t->type == ATIMER_CONTINUOUS) | 351 | if (t->type == ATIMER_CONTINUOUS) |
| 353 | { | 352 | { |
| 354 | t->expiration = add_emacs_time (now, t->interval); | 353 | t->expiration = timespec_add (now, t->interval); |
| 355 | schedule_atimer (t); | 354 | schedule_atimer (t); |
| 356 | } | 355 | } |
| 357 | else | 356 | else |
diff --git a/src/atimer.h b/src/atimer.h index a1825fc0933..8c4d732aa4e 100644 --- a/src/atimer.h +++ b/src/atimer.h | |||
| @@ -19,8 +19,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 19 | #ifndef EMACS_ATIMER_H | 19 | #ifndef EMACS_ATIMER_H |
| 20 | #define EMACS_ATIMER_H | 20 | #define EMACS_ATIMER_H |
| 21 | 21 | ||
| 22 | #include "systime.h" /* for EMACS_TIME */ | ||
| 23 | #include <stdbool.h> | 22 | #include <stdbool.h> |
| 23 | #include <time.h> | ||
| 24 | 24 | ||
| 25 | /* Forward declaration. */ | 25 | /* Forward declaration. */ |
| 26 | 26 | ||
| @@ -52,10 +52,10 @@ struct atimer | |||
| 52 | enum atimer_type type; | 52 | enum atimer_type type; |
| 53 | 53 | ||
| 54 | /* Time when this timer is ripe. */ | 54 | /* Time when this timer is ripe. */ |
| 55 | EMACS_TIME expiration; | 55 | struct timespec expiration; |
| 56 | 56 | ||
| 57 | /* Interval of this timer. */ | 57 | /* Interval of this timer. */ |
| 58 | EMACS_TIME interval; | 58 | struct timespec interval; |
| 59 | 59 | ||
| 60 | /* Function to call when timer is ripe. Interrupt input is | 60 | /* Function to call when timer is ripe. Interrupt input is |
| 61 | guaranteed to not be blocked when this function is called. */ | 61 | guaranteed to not be blocked when this function is called. */ |
| @@ -70,7 +70,7 @@ struct atimer | |||
| 70 | 70 | ||
| 71 | /* Function prototypes. */ | 71 | /* Function prototypes. */ |
| 72 | 72 | ||
| 73 | struct atimer *start_atimer (enum atimer_type, EMACS_TIME, | 73 | struct atimer *start_atimer (enum atimer_type, struct timespec, |
| 74 | atimer_callback, void *); | 74 | atimer_callback, void *); |
| 75 | void cancel_atimer (struct atimer *); | 75 | void cancel_atimer (struct atimer *); |
| 76 | void do_pending_atimers (void); | 76 | void do_pending_atimers (void); |
diff --git a/src/bidi.c b/src/bidi.c index c31d208ecbc..7d082a94997 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -61,6 +61,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 61 | #include "character.h" | 61 | #include "character.h" |
| 62 | #include "buffer.h" | 62 | #include "buffer.h" |
| 63 | #include "dispextern.h" | 63 | #include "dispextern.h" |
| 64 | #include "region-cache.h" | ||
| 64 | 65 | ||
| 65 | static bool bidi_initialized = 0; | 66 | static bool bidi_initialized = 0; |
| 66 | 67 | ||
| @@ -1085,6 +1086,29 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos) | |||
| 1085 | return val; | 1086 | return val; |
| 1086 | } | 1087 | } |
| 1087 | 1088 | ||
| 1089 | /* If the user has requested the long scans caching, make sure that | ||
| 1090 | BIDI cache is enabled. Otherwise, make sure it's disabled. */ | ||
| 1091 | |||
| 1092 | static struct region_cache * | ||
| 1093 | bidi_paragraph_cache_on_off (void) | ||
| 1094 | { | ||
| 1095 | if (NILP (BVAR (current_buffer, cache_long_scans))) | ||
| 1096 | { | ||
| 1097 | if (current_buffer->bidi_paragraph_cache) | ||
| 1098 | { | ||
| 1099 | free_region_cache (current_buffer->bidi_paragraph_cache); | ||
| 1100 | current_buffer->bidi_paragraph_cache = 0; | ||
| 1101 | } | ||
| 1102 | return NULL; | ||
| 1103 | } | ||
| 1104 | else | ||
| 1105 | { | ||
| 1106 | if (!current_buffer->bidi_paragraph_cache) | ||
| 1107 | current_buffer->bidi_paragraph_cache = new_region_cache (); | ||
| 1108 | return current_buffer->bidi_paragraph_cache; | ||
| 1109 | } | ||
| 1110 | } | ||
| 1111 | |||
| 1088 | /* On my 2005-vintage machine, searching back for paragraph start | 1112 | /* On my 2005-vintage machine, searching back for paragraph start |
| 1089 | takes ~1 ms per line. And bidi_paragraph_init is called 4 times | 1113 | takes ~1 ms per line. And bidi_paragraph_init is called 4 times |
| 1090 | when user types C-p. The number below limits each call to | 1114 | when user types C-p. The number below limits each call to |
| @@ -1100,7 +1124,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1100 | { | 1124 | { |
| 1101 | Lisp_Object re = paragraph_start_re; | 1125 | Lisp_Object re = paragraph_start_re; |
| 1102 | ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; | 1126 | ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; |
| 1103 | ptrdiff_t n = 0; | 1127 | struct region_cache *bpc = bidi_paragraph_cache_on_off (); |
| 1128 | ptrdiff_t n = 0, oldpos = pos, next; | ||
| 1104 | 1129 | ||
| 1105 | while (pos_byte > BEGV_BYTE | 1130 | while (pos_byte > BEGV_BYTE |
| 1106 | && n++ < MAX_PARAGRAPH_SEARCH | 1131 | && n++ < MAX_PARAGRAPH_SEARCH |
| @@ -1111,10 +1136,18 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1111 | of the text over which we scan back includes | 1136 | of the text over which we scan back includes |
| 1112 | paragraph_start_re? */ | 1137 | paragraph_start_re? */ |
| 1113 | DEC_BOTH (pos, pos_byte); | 1138 | DEC_BOTH (pos, pos_byte); |
| 1114 | pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); | 1139 | if (bpc && region_cache_backward (current_buffer, bpc, pos, &next)) |
| 1140 | { | ||
| 1141 | pos = next, pos_byte = CHAR_TO_BYTE (pos); | ||
| 1142 | break; | ||
| 1143 | } | ||
| 1144 | else | ||
| 1145 | pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); | ||
| 1115 | } | 1146 | } |
| 1116 | if (n >= MAX_PARAGRAPH_SEARCH) | 1147 | if (n >= MAX_PARAGRAPH_SEARCH) |
| 1117 | pos_byte = BEGV_BYTE; | 1148 | pos = BEGV, pos_byte = BEGV_BYTE; |
| 1149 | if (bpc) | ||
| 1150 | know_region_cache (current_buffer, bpc, pos, oldpos); | ||
| 1118 | return pos_byte; | 1151 | return pos_byte; |
| 1119 | } | 1152 | } |
| 1120 | 1153 | ||
diff --git a/src/buffer.c b/src/buffer.c index dfc6b8bcc02..0bcb608dbd3 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -108,9 +108,9 @@ static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, | |||
| 108 | static void swap_out_buffer_local_variables (struct buffer *b); | 108 | static void swap_out_buffer_local_variables (struct buffer *b); |
| 109 | static void reset_buffer_local_variables (struct buffer *, bool); | 109 | static void reset_buffer_local_variables (struct buffer *, bool); |
| 110 | 110 | ||
| 111 | /* Alist of all buffer names vs the buffers. */ | 111 | /* Alist of all buffer names vs the buffers. This used to be |
| 112 | /* This used to be a variable, but is no longer, | 112 | a Lisp-visible variable, but is no longer, to prevent lossage |
| 113 | to prevent lossage due to user rplac'ing this alist or its elements. */ | 113 | due to user rplac'ing this alist or its elements. */ |
| 114 | Lisp_Object Vbuffer_alist; | 114 | Lisp_Object Vbuffer_alist; |
| 115 | 115 | ||
| 116 | static Lisp_Object Qkill_buffer_query_functions; | 116 | static Lisp_Object Qkill_buffer_query_functions; |
| @@ -203,9 +203,9 @@ bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val) | |||
| 203 | b->INTERNAL_FIELD (buffer_file_coding_system) = val; | 203 | b->INTERNAL_FIELD (buffer_file_coding_system) = val; |
| 204 | } | 204 | } |
| 205 | static void | 205 | static void |
| 206 | bset_cache_long_line_scans (struct buffer *b, Lisp_Object val) | 206 | bset_cache_long_scans (struct buffer *b, Lisp_Object val) |
| 207 | { | 207 | { |
| 208 | b->INTERNAL_FIELD (cache_long_line_scans) = val; | 208 | b->INTERNAL_FIELD (cache_long_scans) = val; |
| 209 | } | 209 | } |
| 210 | static void | 210 | static void |
| 211 | bset_case_fold_search (struct buffer *b, Lisp_Object val) | 211 | bset_case_fold_search (struct buffer *b, Lisp_Object val) |
| @@ -478,8 +478,7 @@ If there is no such live buffer, return nil. | |||
| 478 | See also `find-buffer-visiting'. */) | 478 | See also `find-buffer-visiting'. */) |
| 479 | (register Lisp_Object filename) | 479 | (register Lisp_Object filename) |
| 480 | { | 480 | { |
| 481 | register Lisp_Object tail, buf, tem; | 481 | register Lisp_Object tail, buf, handler; |
| 482 | Lisp_Object handler; | ||
| 483 | 482 | ||
| 484 | CHECK_STRING (filename); | 483 | CHECK_STRING (filename); |
| 485 | filename = Fexpand_file_name (filename, Qnil); | 484 | filename = Fexpand_file_name (filename, Qnil); |
| @@ -494,13 +493,10 @@ See also `find-buffer-visiting'. */) | |||
| 494 | return BUFFERP (handled_buf) ? handled_buf : Qnil; | 493 | return BUFFERP (handled_buf) ? handled_buf : Qnil; |
| 495 | } | 494 | } |
| 496 | 495 | ||
| 497 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 496 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 498 | { | 497 | { |
| 499 | buf = Fcdr (XCAR (tail)); | ||
| 500 | if (!BUFFERP (buf)) continue; | ||
| 501 | if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue; | 498 | if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue; |
| 502 | tem = Fstring_equal (BVAR (XBUFFER (buf), filename), filename); | 499 | if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), filename), filename))) |
| 503 | if (!NILP (tem)) | ||
| 504 | return buf; | 500 | return buf; |
| 505 | } | 501 | } |
| 506 | return Qnil; | 502 | return Qnil; |
| @@ -509,15 +505,12 @@ See also `find-buffer-visiting'. */) | |||
| 509 | Lisp_Object | 505 | Lisp_Object |
| 510 | get_truename_buffer (register Lisp_Object filename) | 506 | get_truename_buffer (register Lisp_Object filename) |
| 511 | { | 507 | { |
| 512 | register Lisp_Object tail, buf, tem; | 508 | register Lisp_Object tail, buf; |
| 513 | 509 | ||
| 514 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 510 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 515 | { | 511 | { |
| 516 | buf = Fcdr (XCAR (tail)); | ||
| 517 | if (!BUFFERP (buf)) continue; | ||
| 518 | if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue; | 512 | if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue; |
| 519 | tem = Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename); | 513 | if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename))) |
| 520 | if (!NILP (tem)) | ||
| 521 | return buf; | 514 | return buf; |
| 522 | } | 515 | } |
| 523 | return Qnil; | 516 | return Qnil; |
| @@ -590,6 +583,7 @@ even if it is dead. The return value is never nil. */) | |||
| 590 | 583 | ||
| 591 | b->newline_cache = 0; | 584 | b->newline_cache = 0; |
| 592 | b->width_run_cache = 0; | 585 | b->width_run_cache = 0; |
| 586 | b->bidi_paragraph_cache = 0; | ||
| 593 | bset_width_table (b, Qnil); | 587 | bset_width_table (b, Qnil); |
| 594 | b->prevent_redisplay_optimizations_p = 1; | 588 | b->prevent_redisplay_optimizations_p = 1; |
| 595 | 589 | ||
| @@ -813,6 +807,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 813 | 807 | ||
| 814 | b->newline_cache = 0; | 808 | b->newline_cache = 0; |
| 815 | b->width_run_cache = 0; | 809 | b->width_run_cache = 0; |
| 810 | b->bidi_paragraph_cache = 0; | ||
| 816 | bset_width_table (b, Qnil); | 811 | bset_width_table (b, Qnil); |
| 817 | 812 | ||
| 818 | name = Fcopy_sequence (name); | 813 | name = Fcopy_sequence (name); |
| @@ -893,8 +888,8 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) | |||
| 893 | eassert (b == XBUFFER (Fmarker_buffer (ov->start))); | 888 | eassert (b == XBUFFER (Fmarker_buffer (ov->start))); |
| 894 | modify_overlay (b, marker_position (ov->start), | 889 | modify_overlay (b, marker_position (ov->start), |
| 895 | marker_position (ov->end)); | 890 | marker_position (ov->end)); |
| 896 | Fset_marker (ov->start, Qnil, Qnil); | 891 | unchain_marker (XMARKER (ov->start)); |
| 897 | Fset_marker (ov->end, Qnil, Qnil); | 892 | unchain_marker (XMARKER (ov->end)); |
| 898 | 893 | ||
| 899 | } | 894 | } |
| 900 | 895 | ||
| @@ -938,7 +933,7 @@ reset_buffer (register struct buffer *b) | |||
| 938 | bset_filename (b, Qnil); | 933 | bset_filename (b, Qnil); |
| 939 | bset_file_truename (b, Qnil); | 934 | bset_file_truename (b, Qnil); |
| 940 | bset_directory (b, current_buffer ? BVAR (current_buffer, directory) : Qnil); | 935 | bset_directory (b, current_buffer ? BVAR (current_buffer, directory) : Qnil); |
| 941 | b->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS); | 936 | b->modtime = make_timespec (0, UNKNOWN_MODTIME_NSECS); |
| 942 | b->modtime_size = -1; | 937 | b->modtime_size = -1; |
| 943 | XSETFASTINT (BVAR (b, save_length), 0); | 938 | XSETFASTINT (BVAR (b, save_length), 0); |
| 944 | b->last_window_start = 1; | 939 | b->last_window_start = 1; |
| @@ -1581,10 +1576,8 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) | |||
| 1581 | } | 1576 | } |
| 1582 | 1577 | ||
| 1583 | /* Consider alist of all buffers next. */ | 1578 | /* Consider alist of all buffers next. */ |
| 1584 | tail = Vbuffer_alist; | 1579 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 1585 | for (; CONSP (tail); tail = XCDR (tail)) | ||
| 1586 | { | 1580 | { |
| 1587 | buf = Fcdr (XCAR (tail)); | ||
| 1588 | if (candidate_buffer (buf, buffer) | 1581 | if (candidate_buffer (buf, buffer) |
| 1589 | /* If the frame has a buffer_predicate, disregard buffers that | 1582 | /* If the frame has a buffer_predicate, disregard buffers that |
| 1590 | don't fit the predicate. */ | 1583 | don't fit the predicate. */ |
| @@ -1621,12 +1614,9 @@ other_buffer_safely (Lisp_Object buffer) | |||
| 1621 | { | 1614 | { |
| 1622 | Lisp_Object tail, buf; | 1615 | Lisp_Object tail, buf; |
| 1623 | 1616 | ||
| 1624 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 1617 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 1625 | { | 1618 | if (candidate_buffer (buf, buffer)) |
| 1626 | buf = Fcdr (XCAR (tail)); | 1619 | return buf; |
| 1627 | if (candidate_buffer (buf, buffer)) | ||
| 1628 | return buf; | ||
| 1629 | } | ||
| 1630 | 1620 | ||
| 1631 | buf = Fget_buffer (build_string ("*scratch*")); | 1621 | buf = Fget_buffer (build_string ("*scratch*")); |
| 1632 | if (NILP (buf)) | 1622 | if (NILP (buf)) |
| @@ -1957,6 +1947,11 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1957 | free_region_cache (b->width_run_cache); | 1947 | free_region_cache (b->width_run_cache); |
| 1958 | b->width_run_cache = 0; | 1948 | b->width_run_cache = 0; |
| 1959 | } | 1949 | } |
| 1950 | if (b->bidi_paragraph_cache) | ||
| 1951 | { | ||
| 1952 | free_region_cache (b->bidi_paragraph_cache); | ||
| 1953 | b->bidi_paragraph_cache = 0; | ||
| 1954 | } | ||
| 1960 | bset_width_table (b, Qnil); | 1955 | bset_width_table (b, Qnil); |
| 1961 | unblock_input (); | 1956 | unblock_input (); |
| 1962 | bset_undo_list (b, Qnil); | 1957 | bset_undo_list (b, Qnil); |
| @@ -2367,6 +2362,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, | |||
| 2367 | current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; | 2362 | current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; |
| 2368 | swapfield (newline_cache, struct region_cache *); | 2363 | swapfield (newline_cache, struct region_cache *); |
| 2369 | swapfield (width_run_cache, struct region_cache *); | 2364 | swapfield (width_run_cache, struct region_cache *); |
| 2365 | swapfield (bidi_paragraph_cache, struct region_cache *); | ||
| 2370 | current_buffer->prevent_redisplay_optimizations_p = 1; | 2366 | current_buffer->prevent_redisplay_optimizations_p = 1; |
| 2371 | other_buffer->prevent_redisplay_optimizations_p = 1; | 2367 | other_buffer->prevent_redisplay_optimizations_p = 1; |
| 2372 | swapfield (overlays_before, struct Lisp_Overlay *); | 2368 | swapfield (overlays_before, struct Lisp_Overlay *); |
| @@ -2413,7 +2409,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, | |||
| 2413 | live window points to that window's buffer. So since we | 2409 | live window points to that window's buffer. So since we |
| 2414 | just swapped the markers between the two buffers, we need | 2410 | just swapped the markers between the two buffers, we need |
| 2415 | to undo the effect of this swap for window markers. */ | 2411 | to undo the effect of this swap for window markers. */ |
| 2416 | Lisp_Object w = Fselected_window (), ws = Qnil; | 2412 | Lisp_Object w = selected_window, ws = Qnil; |
| 2417 | Lisp_Object buf1, buf2; | 2413 | Lisp_Object buf1, buf2; |
| 2418 | XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer); | 2414 | XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer); |
| 2419 | 2415 | ||
| @@ -3150,8 +3146,8 @@ struct sortvec | |||
| 3150 | static int | 3146 | static int |
| 3151 | compare_overlays (const void *v1, const void *v2) | 3147 | compare_overlays (const void *v1, const void *v2) |
| 3152 | { | 3148 | { |
| 3153 | const struct sortvec *s1 = (const struct sortvec *) v1; | 3149 | const struct sortvec *s1 = v1; |
| 3154 | const struct sortvec *s2 = (const struct sortvec *) v2; | 3150 | const struct sortvec *s2 = v2; |
| 3155 | if (s1->priority != s2->priority) | 3151 | if (s1->priority != s2->priority) |
| 3156 | return s1->priority < s2->priority ? -1 : 1; | 3152 | return s1->priority < s2->priority ? -1 : 1; |
| 3157 | if (s1->beg != s2->beg) | 3153 | if (s1->beg != s2->beg) |
| @@ -3257,8 +3253,8 @@ static ptrdiff_t overlay_str_len; | |||
| 3257 | static int | 3253 | static int |
| 3258 | cmp_for_strings (const void *as1, const void *as2) | 3254 | cmp_for_strings (const void *as1, const void *as2) |
| 3259 | { | 3255 | { |
| 3260 | struct sortstr *s1 = (struct sortstr *)as1; | 3256 | struct sortstr const *s1 = as1; |
| 3261 | struct sortstr *s2 = (struct sortstr *)as2; | 3257 | struct sortstr const *s2 = as2; |
| 3262 | if (s1->size != s2->size) | 3258 | if (s1->size != s2->size) |
| 3263 | return s2->size < s1->size ? -1 : 1; | 3259 | return s2->size < s1->size ? -1 : 1; |
| 3264 | if (s1->priority != s2->priority) | 3260 | if (s1->priority != s2->priority) |
| @@ -3838,7 +3834,8 @@ for the front of the overlay advance when text is inserted there | |||
| 3838 | The fifth arg REAR-ADVANCE, if non-nil, makes the marker | 3834 | The fifth arg REAR-ADVANCE, if non-nil, makes the marker |
| 3839 | for the rear of the overlay advance when text is inserted there | 3835 | for the rear of the overlay advance when text is inserted there |
| 3840 | \(which means the text *is* included in the overlay). */) | 3836 | \(which means the text *is* included in the overlay). */) |
| 3841 | (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, Lisp_Object front_advance, Lisp_Object rear_advance) | 3837 | (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, |
| 3838 | Lisp_Object front_advance, Lisp_Object rear_advance) | ||
| 3842 | { | 3839 | { |
| 3843 | Lisp_Object overlay; | 3840 | Lisp_Object overlay; |
| 3844 | struct buffer *b; | 3841 | struct buffer *b; |
| @@ -3847,12 +3844,11 @@ for the rear of the overlay advance when text is inserted there | |||
| 3847 | XSETBUFFER (buffer, current_buffer); | 3844 | XSETBUFFER (buffer, current_buffer); |
| 3848 | else | 3845 | else |
| 3849 | CHECK_BUFFER (buffer); | 3846 | CHECK_BUFFER (buffer); |
| 3850 | if (MARKERP (beg) | 3847 | |
| 3851 | && ! EQ (Fmarker_buffer (beg), buffer)) | 3848 | if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) |
| 3852 | error ("Marker points into wrong buffer"); | 3849 | signal_error ("Marker points into wrong buffer", beg); |
| 3853 | if (MARKERP (end) | 3850 | if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) |
| 3854 | && ! EQ (Fmarker_buffer (end), buffer)) | 3851 | signal_error ("Marker points into wrong buffer", end); |
| 3855 | error ("Marker points into wrong buffer"); | ||
| 3856 | 3852 | ||
| 3857 | CHECK_NUMBER_COERCE_MARKER (beg); | 3853 | CHECK_NUMBER_COERCE_MARKER (beg); |
| 3858 | CHECK_NUMBER_COERCE_MARKER (end); | 3854 | CHECK_NUMBER_COERCE_MARKER (end); |
| @@ -3978,12 +3974,10 @@ buffer. */) | |||
| 3978 | if (NILP (Fbuffer_live_p (buffer))) | 3974 | if (NILP (Fbuffer_live_p (buffer))) |
| 3979 | error ("Attempt to move overlay to a dead buffer"); | 3975 | error ("Attempt to move overlay to a dead buffer"); |
| 3980 | 3976 | ||
| 3981 | if (MARKERP (beg) | 3977 | if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) |
| 3982 | && ! EQ (Fmarker_buffer (beg), buffer)) | 3978 | signal_error ("Marker points into wrong buffer", beg); |
| 3983 | error ("Marker points into wrong buffer"); | 3979 | if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) |
| 3984 | if (MARKERP (end) | 3980 | signal_error ("Marker points into wrong buffer", end); |
| 3985 | && ! EQ (Fmarker_buffer (end), buffer)) | ||
| 3986 | error ("Marker points into wrong buffer"); | ||
| 3987 | 3981 | ||
| 3988 | CHECK_NUMBER_COERCE_MARKER (beg); | 3982 | CHECK_NUMBER_COERCE_MARKER (beg); |
| 3989 | CHECK_NUMBER_COERCE_MARKER (end); | 3983 | CHECK_NUMBER_COERCE_MARKER (end); |
| @@ -4165,6 +4159,9 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0, | |||
| 4165 | 4159 | ||
| 4166 | CHECK_NUMBER_COERCE_MARKER (pos); | 4160 | CHECK_NUMBER_COERCE_MARKER (pos); |
| 4167 | 4161 | ||
| 4162 | if (!buffer_has_overlays ()) | ||
| 4163 | return Qnil; | ||
| 4164 | |||
| 4168 | len = 10; | 4165 | len = 10; |
| 4169 | /* We can't use alloca here because overlays_at can call xrealloc. */ | 4166 | /* We can't use alloca here because overlays_at can call xrealloc. */ |
| 4170 | overlay_vec = xmalloc (len * sizeof *overlay_vec); | 4167 | overlay_vec = xmalloc (len * sizeof *overlay_vec); |
| @@ -4197,6 +4194,9 @@ end of the buffer. */) | |||
| 4197 | CHECK_NUMBER_COERCE_MARKER (beg); | 4194 | CHECK_NUMBER_COERCE_MARKER (beg); |
| 4198 | CHECK_NUMBER_COERCE_MARKER (end); | 4195 | CHECK_NUMBER_COERCE_MARKER (end); |
| 4199 | 4196 | ||
| 4197 | if (!buffer_has_overlays ()) | ||
| 4198 | return Qnil; | ||
| 4199 | |||
| 4200 | len = 10; | 4200 | len = 10; |
| 4201 | overlay_vec = xmalloc (len * sizeof *overlay_vec); | 4201 | overlay_vec = xmalloc (len * sizeof *overlay_vec); |
| 4202 | 4202 | ||
| @@ -4225,6 +4225,9 @@ the value is (point-max). */) | |||
| 4225 | 4225 | ||
| 4226 | CHECK_NUMBER_COERCE_MARKER (pos); | 4226 | CHECK_NUMBER_COERCE_MARKER (pos); |
| 4227 | 4227 | ||
| 4228 | if (!buffer_has_overlays ()) | ||
| 4229 | return make_number (ZV); | ||
| 4230 | |||
| 4228 | len = 10; | 4231 | len = 10; |
| 4229 | overlay_vec = xmalloc (len * sizeof *overlay_vec); | 4232 | overlay_vec = xmalloc (len * sizeof *overlay_vec); |
| 4230 | 4233 | ||
| @@ -4264,6 +4267,9 @@ the value is (point-min). */) | |||
| 4264 | 4267 | ||
| 4265 | CHECK_NUMBER_COERCE_MARKER (pos); | 4268 | CHECK_NUMBER_COERCE_MARKER (pos); |
| 4266 | 4269 | ||
| 4270 | if (!buffer_has_overlays ()) | ||
| 4271 | return make_number (BEGV); | ||
| 4272 | |||
| 4267 | /* At beginning of buffer, we know the answer; | 4273 | /* At beginning of buffer, we know the answer; |
| 4268 | avoid bug subtracting 1 below. */ | 4274 | avoid bug subtracting 1 below. */ |
| 4269 | if (XINT (pos) == BEGV) | 4275 | if (XINT (pos) == BEGV) |
| @@ -4756,7 +4762,7 @@ static struct mmap_region * | |||
| 4756 | mmap_find (void *start, void *end) | 4762 | mmap_find (void *start, void *end) |
| 4757 | { | 4763 | { |
| 4758 | struct mmap_region *r; | 4764 | struct mmap_region *r; |
| 4759 | char *s = (char *) start, *e = (char *) end; | 4765 | char *s = start, *e = end; |
| 4760 | 4766 | ||
| 4761 | for (r = mmap_regions; r; r = r->next) | 4767 | for (r = mmap_regions; r; r = r->next) |
| 4762 | { | 4768 | { |
| @@ -4915,7 +4921,7 @@ mmap_alloc (void **var, size_t nbytes) | |||
| 4915 | } | 4921 | } |
| 4916 | else | 4922 | else |
| 4917 | { | 4923 | { |
| 4918 | struct mmap_region *r = (struct mmap_region *) p; | 4924 | struct mmap_region *r = p; |
| 4919 | 4925 | ||
| 4920 | r->nbytes_specified = nbytes; | 4926 | r->nbytes_specified = nbytes; |
| 4921 | r->nbytes_mapped = map; | 4927 | r->nbytes_mapped = map; |
| @@ -5055,7 +5061,7 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes) | |||
| 5055 | memory_full (nbytes); | 5061 | memory_full (nbytes); |
| 5056 | } | 5062 | } |
| 5057 | 5063 | ||
| 5058 | b->text->beg = (unsigned char *) p; | 5064 | b->text->beg = p; |
| 5059 | unblock_input (); | 5065 | unblock_input (); |
| 5060 | } | 5066 | } |
| 5061 | 5067 | ||
| @@ -5083,7 +5089,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta) | |||
| 5083 | memory_full (nbytes); | 5089 | memory_full (nbytes); |
| 5084 | } | 5090 | } |
| 5085 | 5091 | ||
| 5086 | BUF_BEG_ADDR (b) = (unsigned char *) p; | 5092 | BUF_BEG_ADDR (b) = p; |
| 5087 | unblock_input (); | 5093 | unblock_input (); |
| 5088 | } | 5094 | } |
| 5089 | 5095 | ||
| @@ -5181,7 +5187,7 @@ init_buffer_once (void) | |||
| 5181 | bset_buffer_file_coding_system (&buffer_defaults, Qnil); | 5187 | bset_buffer_file_coding_system (&buffer_defaults, Qnil); |
| 5182 | XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70); | 5188 | XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70); |
| 5183 | XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0); | 5189 | XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0); |
| 5184 | bset_cache_long_line_scans (&buffer_defaults, Qnil); | 5190 | bset_cache_long_scans (&buffer_defaults, Qnil); |
| 5185 | bset_file_truename (&buffer_defaults, Qnil); | 5191 | bset_file_truename (&buffer_defaults, Qnil); |
| 5186 | XSETFASTINT (BVAR (&buffer_defaults, display_count), 0); | 5192 | XSETFASTINT (BVAR (&buffer_defaults, display_count), 0); |
| 5187 | XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0); | 5193 | XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0); |
| @@ -5245,7 +5251,7 @@ init_buffer_once (void) | |||
| 5245 | XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx; | 5251 | XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx; |
| 5246 | XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx; | 5252 | XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx; |
| 5247 | XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx; | 5253 | XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx; |
| 5248 | XSETFASTINT (BVAR (&buffer_local_flags, cache_long_line_scans), idx); ++idx; | 5254 | XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx; |
| 5249 | XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx; | 5255 | XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx; |
| 5250 | XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx; | 5256 | XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx; |
| 5251 | XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx; | 5257 | XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx; |
| @@ -5401,11 +5407,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, | |||
| 5401 | bo_fwd->predicate = predicate; | 5407 | bo_fwd->predicate = predicate; |
| 5402 | sym->declared_special = 1; | 5408 | sym->declared_special = 1; |
| 5403 | sym->redirect = SYMBOL_FORWARDED; | 5409 | sym->redirect = SYMBOL_FORWARDED; |
| 5404 | { | 5410 | SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); |
| 5405 | /* I tried to do the job without a cast, but it seems impossible. | ||
| 5406 | union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */ | ||
| 5407 | SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd); | ||
| 5408 | } | ||
| 5409 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); | 5411 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); |
| 5410 | 5412 | ||
| 5411 | if (PER_BUFFER_IDX (offset) == 0) | 5413 | if (PER_BUFFER_IDX (offset) == 0) |
| @@ -6114,7 +6116,7 @@ An entry (apply FUN-NAME . ARGS) means undo the change with | |||
| 6114 | 6116 | ||
| 6115 | An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo | 6117 | An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo |
| 6116 | in the active region. BEG and END is the range affected by this entry | 6118 | in the active region. BEG and END is the range affected by this entry |
| 6117 | and DELTA is the number of bytes added or deleted in that range by | 6119 | and DELTA is the number of characters added or deleted in that range by |
| 6118 | this change. | 6120 | this change. |
| 6119 | 6121 | ||
| 6120 | An entry (MARKER . DISTANCE) indicates that the marker MARKER | 6122 | An entry (MARKER . DISTANCE) indicates that the marker MARKER |
| @@ -6132,8 +6134,8 @@ If the value of the variable is t, undo information is not recorded. */); | |||
| 6132 | DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil, | 6134 | DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil, |
| 6133 | doc: /* Non-nil means the mark and region are currently active in this buffer. */); | 6135 | doc: /* Non-nil means the mark and region are currently active in this buffer. */); |
| 6134 | 6136 | ||
| 6135 | DEFVAR_PER_BUFFER ("cache-long-line-scans", &BVAR (current_buffer, cache_long_line_scans), Qnil, | 6137 | DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, cache_long_scans), Qnil, |
| 6136 | doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly. | 6138 | doc: /* Non-nil means that Emacs should use caches in attempt to speedup buffer scans. |
| 6137 | 6139 | ||
| 6138 | Normally, the line-motion functions work by scanning the buffer for | 6140 | Normally, the line-motion functions work by scanning the buffer for |
| 6139 | newlines. Columnar operations (like `move-to-column' and | 6141 | newlines. Columnar operations (like `move-to-column' and |
| @@ -6143,18 +6145,24 @@ buffer's lines are very long (say, more than 500 characters), these | |||
| 6143 | motion functions will take longer to execute. Emacs may also take | 6145 | motion functions will take longer to execute. Emacs may also take |
| 6144 | longer to update the display. | 6146 | longer to update the display. |
| 6145 | 6147 | ||
| 6146 | If `cache-long-line-scans' is non-nil, these motion functions cache the | 6148 | If `cache-long-scans' is non-nil, these motion functions cache the |
| 6147 | results of their scans, and consult the cache to avoid rescanning | 6149 | results of their scans, and consult the cache to avoid rescanning |
| 6148 | regions of the buffer until the text is modified. The caches are most | 6150 | regions of the buffer until the text is modified. The caches are most |
| 6149 | beneficial when they prevent the most searching---that is, when the | 6151 | beneficial when they prevent the most searching---that is, when the |
| 6150 | buffer contains long lines and large regions of characters with the | 6152 | buffer contains long lines and large regions of characters with the |
| 6151 | same, fixed screen width. | 6153 | same, fixed screen width. |
| 6152 | 6154 | ||
| 6153 | When `cache-long-line-scans' is non-nil, processing short lines will | 6155 | When `cache-long-scans' is non-nil, processing short lines will |
| 6154 | become slightly slower (because of the overhead of consulting the | 6156 | become slightly slower (because of the overhead of consulting the |
| 6155 | cache), and the caches will use memory roughly proportional to the | 6157 | cache), and the caches will use memory roughly proportional to the |
| 6156 | number of newlines and characters whose screen width varies. | 6158 | number of newlines and characters whose screen width varies. |
| 6157 | 6159 | ||
| 6160 | Bidirectional editing also requires buffer scans to find paragraph | ||
| 6161 | separators. If you have large paragraphs or no paragraph separators | ||
| 6162 | at all, these scans may be slow. If `cache-long-scans' is non-nil, | ||
| 6163 | results of these scans are cached. This doesn't help too much if | ||
| 6164 | paragraphs are of the reasonable (few thousands of characters) size. | ||
| 6165 | |||
| 6158 | The caches require no explicit maintenance; their accuracy is | 6166 | The caches require no explicit maintenance; their accuracy is |
| 6159 | maintained internally by the Emacs primitives. Enabling or disabling | 6167 | maintained internally by the Emacs primitives. Enabling or disabling |
| 6160 | the cache should not affect the behavior of any of the motion | 6168 | the cache should not affect the behavior of any of the motion |
diff --git a/src/buffer.h b/src/buffer.h index 641a561cafc..169a15c7d0f 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -18,8 +18,8 @@ GNU General Public License for more details. | |||
| 18 | You should have received a copy of the GNU General Public License | 18 | You should have received a copy of the GNU General Public License |
| 19 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 19 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 20 | 20 | ||
| 21 | #include <sys/types.h> /* for off_t, time_t */ | 21 | #include <sys/types.h> |
| 22 | #include "systime.h" /* for EMACS_TIME */ | 22 | #include <time.h> |
| 23 | 23 | ||
| 24 | INLINE_HEADER_BEGIN | 24 | INLINE_HEADER_BEGIN |
| 25 | #ifndef BUFFER_INLINE | 25 | #ifndef BUFFER_INLINE |
| @@ -249,6 +249,7 @@ extern void temp_set_point (struct buffer *, ptrdiff_t); | |||
| 249 | extern void set_point_both (ptrdiff_t, ptrdiff_t); | 249 | extern void set_point_both (ptrdiff_t, ptrdiff_t); |
| 250 | extern void temp_set_point_both (struct buffer *, | 250 | extern void temp_set_point_both (struct buffer *, |
| 251 | ptrdiff_t, ptrdiff_t); | 251 | ptrdiff_t, ptrdiff_t); |
| 252 | extern void set_point_from_marker (Lisp_Object); | ||
| 252 | extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); | 253 | extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); |
| 253 | 254 | ||
| 254 | 255 | ||
| @@ -632,9 +633,9 @@ struct buffer | |||
| 632 | /* List of symbols naming the file format used for auto-save file. */ | 633 | /* List of symbols naming the file format used for auto-save file. */ |
| 633 | Lisp_Object INTERNAL_FIELD (auto_save_file_format); | 634 | Lisp_Object INTERNAL_FIELD (auto_save_file_format); |
| 634 | 635 | ||
| 635 | /* True if the newline position cache and width run cache are | 636 | /* True if the newline position cache, width run cache and BIDI paragraph |
| 636 | enabled. See search.c and indent.c. */ | 637 | cache are enabled. See search.c, indent.c and bidi.c for details. */ |
| 637 | Lisp_Object INTERNAL_FIELD (cache_long_line_scans); | 638 | Lisp_Object INTERNAL_FIELD (cache_long_scans); |
| 638 | 639 | ||
| 639 | /* If the width run cache is enabled, this table contains the | 640 | /* If the width run cache is enabled, this table contains the |
| 640 | character widths width_run_cache (see above) assumes. When we | 641 | character widths width_run_cache (see above) assumes. When we |
| @@ -794,13 +795,13 @@ struct buffer | |||
| 794 | char local_flags[MAX_PER_BUFFER_VARS]; | 795 | char local_flags[MAX_PER_BUFFER_VARS]; |
| 795 | 796 | ||
| 796 | /* Set to the modtime of the visited file when read or written. | 797 | /* Set to the modtime of the visited file when read or written. |
| 797 | EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means | 798 | modtime.tv_nsec == NONEXISTENT_MODTIME_NSECS means |
| 798 | visited file was nonexistent. EMACS_NSECS (modtime) == | 799 | visited file was nonexistent. modtime.tv_nsec == |
| 799 | UNKNOWN_MODTIME_NSECS means visited file modtime unknown; | 800 | UNKNOWN_MODTIME_NSECS means visited file modtime unknown; |
| 800 | in no case complain about any mismatch on next save attempt. */ | 801 | in no case complain about any mismatch on next save attempt. */ |
| 801 | #define NONEXISTENT_MODTIME_NSECS (-1) | 802 | #define NONEXISTENT_MODTIME_NSECS (-1) |
| 802 | #define UNKNOWN_MODTIME_NSECS (-2) | 803 | #define UNKNOWN_MODTIME_NSECS (-2) |
| 803 | EMACS_TIME modtime; | 804 | struct timespec modtime; |
| 804 | 805 | ||
| 805 | /* Size of the file when modtime was set. This is used to detect the | 806 | /* Size of the file when modtime was set. This is used to detect the |
| 806 | case where the file grew while we were reading it, so the modtime | 807 | case where the file grew while we were reading it, so the modtime |
| @@ -839,9 +840,12 @@ struct buffer | |||
| 839 | the character's width; if it maps a character to zero, we don't | 840 | the character's width; if it maps a character to zero, we don't |
| 840 | know what its width is. This allows compute_motion to process | 841 | know what its width is. This allows compute_motion to process |
| 841 | such regions very quickly, using algebra instead of inspecting | 842 | such regions very quickly, using algebra instead of inspecting |
| 842 | each character. See also width_table, below. */ | 843 | each character. See also width_table, below. |
| 844 | |||
| 845 | The latter cache is used to speedup bidi_find_paragraph_start. */ | ||
| 843 | struct region_cache *newline_cache; | 846 | struct region_cache *newline_cache; |
| 844 | struct region_cache *width_run_cache; | 847 | struct region_cache *width_run_cache; |
| 848 | struct region_cache *bidi_paragraph_cache; | ||
| 845 | 849 | ||
| 846 | /* Non-zero means don't use redisplay optimizations for | 850 | /* Non-zero means don't use redisplay optimizations for |
| 847 | displaying this buffer. */ | 851 | displaying this buffer. */ |
| @@ -1120,9 +1124,17 @@ record_unwind_current_buffer (void) | |||
| 1120 | } \ | 1124 | } \ |
| 1121 | } while (0) | 1125 | } while (0) |
| 1122 | 1126 | ||
| 1127 | extern Lisp_Object Vbuffer_alist; | ||
| 1123 | extern Lisp_Object Qbefore_change_functions; | 1128 | extern Lisp_Object Qbefore_change_functions; |
| 1124 | extern Lisp_Object Qafter_change_functions; | 1129 | extern Lisp_Object Qafter_change_functions; |
| 1125 | extern Lisp_Object Qfirst_change_hook; | 1130 | extern Lisp_Object Qfirst_change_hook; |
| 1131 | extern Lisp_Object Qpriority, Qbefore_string, Qafter_string; | ||
| 1132 | |||
| 1133 | /* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is | ||
| 1134 | a `for' loop which iterates over the buffers from Vbuffer_alist. */ | ||
| 1135 | |||
| 1136 | #define FOR_EACH_LIVE_BUFFER(list_var, buf_var) \ | ||
| 1137 | FOR_EACH_ALIST_VALUE (Vbuffer_alist, list_var, buf_var) | ||
| 1126 | 1138 | ||
| 1127 | /* Get text properties of B. */ | 1139 | /* Get text properties of B. */ |
| 1128 | 1140 | ||
diff --git a/src/callint.c b/src/callint.c index 38431226508..25096af5068 100644 --- a/src/callint.c +++ b/src/callint.c | |||
| @@ -331,12 +331,9 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 331 | 331 | ||
| 332 | /* If SPECS is set to a string, use it as an interactive prompt. */ | 332 | /* If SPECS is set to a string, use it as an interactive prompt. */ |
| 333 | if (STRINGP (specs)) | 333 | if (STRINGP (specs)) |
| 334 | { | 334 | /* Make a copy of string so that if a GC relocates specs, |
| 335 | /* Make a copy of string so that if a GC relocates specs, | 335 | `string' will still be valid. */ |
| 336 | `string' will still be valid. */ | 336 | string = xlispstrdupa (specs); |
| 337 | string = alloca (SBYTES (specs) + 1); | ||
| 338 | memcpy (string, SSDATA (specs), SBYTES (specs) + 1); | ||
| 339 | } | ||
| 340 | else | 337 | else |
| 341 | { | 338 | { |
| 342 | Lisp_Object input; | 339 | Lisp_Object input; |
| @@ -529,7 +526,7 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 529 | make_number (SCHARS (callint_message)), | 526 | make_number (SCHARS (callint_message)), |
| 530 | Qface, Qminibuffer_prompt, callint_message); | 527 | Qface, Qminibuffer_prompt, callint_message); |
| 531 | args[i] = Fread_char (callint_message, Qnil, Qnil); | 528 | args[i] = Fread_char (callint_message, Qnil, Qnil); |
| 532 | message1_nolog ((char *) 0); | 529 | message1_nolog (0); |
| 533 | /* Passing args[i] directly stimulates compiler bug. */ | 530 | /* Passing args[i] directly stimulates compiler bug. */ |
| 534 | teml = args[i]; | 531 | teml = args[i]; |
| 535 | /* See bug#8479. */ | 532 | /* See bug#8479. */ |
diff --git a/src/callproc.c b/src/callproc.c index 450fc57f929..d4b4a26ec3a 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -68,9 +68,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 68 | /* Pattern used by call-process-region to make temp files. */ | 68 | /* Pattern used by call-process-region to make temp files. */ |
| 69 | static Lisp_Object Vtemp_file_name_pattern; | 69 | static Lisp_Object Vtemp_file_name_pattern; |
| 70 | 70 | ||
| 71 | /* The next two variables are valid only while record-unwind-protect | 71 | /* The next two variables are used while record-unwind-protect is in place |
| 72 | is in place during call-process for a synchronous subprocess. At | 72 | during call-process for a subprocess for which record_deleted_pid has |
| 73 | other times, their contents are irrelevant. Doing this via static | 73 | not yet been called. At other times, synch_process_pid is zero and |
| 74 | synch_process_tempfile's contents are irrelevant. Doing this via static | ||
| 74 | C variables is more convenient than putting them into the arguments | 75 | C variables is more convenient than putting them into the arguments |
| 75 | of record-unwind-protect, as they need to be updated at randomish | 76 | of record-unwind-protect, as they need to be updated at randomish |
| 76 | times in the code, and Lisp cannot always store these values as | 77 | times in the code, and Lisp cannot always store these values as |
| @@ -80,8 +81,28 @@ static Lisp_Object Vtemp_file_name_pattern; | |||
| 80 | /* If nonzero, a process-ID that has not been reaped. */ | 81 | /* If nonzero, a process-ID that has not been reaped. */ |
| 81 | static pid_t synch_process_pid; | 82 | static pid_t synch_process_pid; |
| 82 | 83 | ||
| 83 | /* If nonnegative, a file descriptor that has not been closed. */ | 84 | /* If a string, the name of a temp file that has not been removed. */ |
| 84 | static int synch_process_fd; | 85 | #ifdef MSDOS |
| 86 | static Lisp_Object synch_process_tempfile; | ||
| 87 | #else | ||
| 88 | # define synch_process_tempfile make_number (0) | ||
| 89 | #endif | ||
| 90 | |||
| 91 | /* Indexes of file descriptors that need closing on call_process_kill. */ | ||
| 92 | enum | ||
| 93 | { | ||
| 94 | /* The subsidiary process's stdout and stderr. stdin is handled | ||
| 95 | separately, in either Fcall_process_region or create_temp_file. */ | ||
| 96 | CALLPROC_STDOUT, CALLPROC_STDERR, | ||
| 97 | |||
| 98 | /* How to read from a pipe (or substitute) from the subsidiary process. */ | ||
| 99 | CALLPROC_PIPEREAD, | ||
| 100 | |||
| 101 | /* A bound on the number of file descriptors. */ | ||
| 102 | CALLPROC_FDS | ||
| 103 | }; | ||
| 104 | |||
| 105 | static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t); | ||
| 85 | 106 | ||
| 86 | /* Block SIGCHLD. */ | 107 | /* Block SIGCHLD. */ |
| 87 | 108 | ||
| @@ -102,85 +123,104 @@ unblock_child_signal (void) | |||
| 102 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 123 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 103 | } | 124 | } |
| 104 | 125 | ||
| 126 | /* Return the current buffer's working directory, or the home | ||
| 127 | directory if it's unreachable, as a string suitable for a system call. | ||
| 128 | Signal an error if the result would not be an accessible directory. */ | ||
| 129 | |||
| 130 | Lisp_Object | ||
| 131 | encode_current_directory (void) | ||
| 132 | { | ||
| 133 | Lisp_Object dir; | ||
| 134 | struct gcpro gcpro1; | ||
| 135 | |||
| 136 | dir = BVAR (current_buffer, directory); | ||
| 137 | GCPRO1 (dir); | ||
| 138 | |||
| 139 | dir = Funhandled_file_name_directory (dir); | ||
| 140 | |||
| 141 | /* If the file name handler says that dir is unreachable, use | ||
| 142 | a sensible default. */ | ||
| 143 | if (NILP (dir)) | ||
| 144 | dir = build_string ("~"); | ||
| 145 | |||
| 146 | dir = expand_and_dir_to_file (dir, Qnil); | ||
| 147 | |||
| 148 | if (STRING_MULTIBYTE (dir)) | ||
| 149 | dir = ENCODE_FILE (dir); | ||
| 150 | if (! file_accessible_directory_p (SSDATA (dir))) | ||
| 151 | report_file_error ("Setting current directory", | ||
| 152 | BVAR (current_buffer, directory)); | ||
| 153 | |||
| 154 | RETURN_UNGCPRO (dir); | ||
| 155 | } | ||
| 156 | |||
| 105 | /* If P is reapable, record it as a deleted process and kill it. | 157 | /* If P is reapable, record it as a deleted process and kill it. |
| 106 | Do this in a critical section. Unless PID is wedged it will be | 158 | Do this in a critical section. Unless PID is wedged it will be |
| 107 | reaped on receipt of the first SIGCHLD after the critical section. */ | 159 | reaped on receipt of the first SIGCHLD after the critical section. */ |
| 108 | 160 | ||
| 109 | void | 161 | void |
| 110 | record_kill_process (struct Lisp_Process *p) | 162 | record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) |
| 111 | { | 163 | { |
| 112 | block_child_signal (); | 164 | block_child_signal (); |
| 113 | 165 | ||
| 114 | if (p->alive) | 166 | if (p->alive) |
| 115 | { | 167 | { |
| 168 | record_deleted_pid (p->pid, tempfile); | ||
| 116 | p->alive = 0; | 169 | p->alive = 0; |
| 117 | record_deleted_pid (p->pid); | ||
| 118 | kill (- p->pid, SIGKILL); | 170 | kill (- p->pid, SIGKILL); |
| 119 | } | 171 | } |
| 120 | 172 | ||
| 121 | unblock_child_signal (); | 173 | unblock_child_signal (); |
| 122 | } | 174 | } |
| 123 | 175 | ||
| 124 | /* Clean up when exiting call_process_cleanup. */ | 176 | /* Clean up files, file descriptors and processes created by Fcall_process. */ |
| 177 | |||
| 178 | static void | ||
| 179 | delete_temp_file (Lisp_Object name) | ||
| 180 | { | ||
| 181 | unlink (SSDATA (name)); | ||
| 182 | } | ||
| 125 | 183 | ||
| 126 | static void | 184 | static void |
| 127 | call_process_kill (void) | 185 | call_process_kill (void *ptr) |
| 128 | { | 186 | { |
| 129 | if (synch_process_fd >= 0) | 187 | int *callproc_fd = ptr; |
| 130 | emacs_close (synch_process_fd); | 188 | int i; |
| 189 | for (i = 0; i < CALLPROC_FDS; i++) | ||
| 190 | if (0 <= callproc_fd[i]) | ||
| 191 | emacs_close (callproc_fd[i]); | ||
| 131 | 192 | ||
| 132 | if (synch_process_pid) | 193 | if (synch_process_pid) |
| 133 | { | 194 | { |
| 134 | struct Lisp_Process proc; | 195 | struct Lisp_Process proc; |
| 135 | proc.alive = 1; | 196 | proc.alive = 1; |
| 136 | proc.pid = synch_process_pid; | 197 | proc.pid = synch_process_pid; |
| 137 | record_kill_process (&proc); | 198 | record_kill_process (&proc, synch_process_tempfile); |
| 199 | synch_process_pid = 0; | ||
| 138 | } | 200 | } |
| 201 | else if (STRINGP (synch_process_tempfile)) | ||
| 202 | delete_temp_file (synch_process_tempfile); | ||
| 139 | } | 203 | } |
| 140 | 204 | ||
| 141 | /* Clean up when exiting Fcall_process. | 205 | /* Clean up when exiting Fcall_process: restore the buffer, and |
| 142 | On MSDOS, delete the temporary file on any kind of termination. | 206 | kill the subsidiary process group if the process still exists. */ |
| 143 | On Unix, kill the process and any children on termination by signal. */ | ||
| 144 | 207 | ||
| 145 | static void | 208 | static void |
| 146 | call_process_cleanup (Lisp_Object arg) | 209 | call_process_cleanup (Lisp_Object buffer) |
| 147 | { | 210 | { |
| 148 | #ifdef MSDOS | ||
| 149 | Lisp_Object buffer = Fcar (arg); | ||
| 150 | Lisp_Object file = Fcdr (arg); | ||
| 151 | #else | ||
| 152 | Lisp_Object buffer = arg; | ||
| 153 | #endif | ||
| 154 | |||
| 155 | Fset_buffer (buffer); | 211 | Fset_buffer (buffer); |
| 156 | 212 | ||
| 157 | #ifndef MSDOS | ||
| 158 | /* If the process still exists, kill its process group. */ | ||
| 159 | if (synch_process_pid) | 213 | if (synch_process_pid) |
| 160 | { | 214 | { |
| 161 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 162 | kill (-synch_process_pid, SIGINT); | 215 | kill (-synch_process_pid, SIGINT); |
| 163 | record_unwind_protect_void (call_process_kill); | ||
| 164 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); | 216 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); |
| 165 | immediate_quit = 1; | 217 | immediate_quit = 1; |
| 166 | QUIT; | 218 | QUIT; |
| 167 | wait_for_termination (synch_process_pid, 0, 1); | 219 | wait_for_termination (synch_process_pid, 0, 1); |
| 168 | synch_process_pid = 0; | 220 | synch_process_pid = 0; |
| 169 | immediate_quit = 0; | 221 | immediate_quit = 0; |
| 170 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ | ||
| 171 | message1 ("Waiting for process to die...done"); | 222 | message1 ("Waiting for process to die...done"); |
| 172 | } | 223 | } |
| 173 | #endif | ||
| 174 | |||
| 175 | if (synch_process_fd >= 0) | ||
| 176 | emacs_close (synch_process_fd); | ||
| 177 | |||
| 178 | #ifdef MSDOS | ||
| 179 | /* FILE is "" when we didn't actually create a temporary file in | ||
| 180 | call-process. */ | ||
| 181 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | ||
| 182 | unlink (SDATA (file)); | ||
| 183 | #endif | ||
| 184 | } | 224 | } |
| 185 | 225 | ||
| 186 | #ifdef DOS_NT | 226 | #ifdef DOS_NT |
| @@ -218,10 +258,48 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | |||
| 218 | usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) | 258 | usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) |
| 219 | (ptrdiff_t nargs, Lisp_Object *args) | 259 | (ptrdiff_t nargs, Lisp_Object *args) |
| 220 | { | 260 | { |
| 221 | Lisp_Object infile, buffer, current_dir, path; | 261 | Lisp_Object infile, encoded_infile; |
| 262 | int filefd; | ||
| 263 | struct gcpro gcpro1; | ||
| 264 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 265 | |||
| 266 | if (nargs >= 2 && ! NILP (args[1])) | ||
| 267 | { | ||
| 268 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | ||
| 269 | CHECK_STRING (infile); | ||
| 270 | } | ||
| 271 | else | ||
| 272 | infile = build_string (NULL_DEVICE); | ||
| 273 | |||
| 274 | GCPRO1 (infile); | ||
| 275 | encoded_infile = STRING_MULTIBYTE (infile) ? ENCODE_FILE (infile) : infile; | ||
| 276 | |||
| 277 | filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0); | ||
| 278 | if (filefd < 0) | ||
| 279 | report_file_error ("Opening process input file", infile); | ||
| 280 | record_unwind_protect_int (close_file_unwind, filefd); | ||
| 281 | UNGCPRO; | ||
| 282 | return unbind_to (count, call_process (nargs, args, filefd, -1)); | ||
| 283 | } | ||
| 284 | |||
| 285 | /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. | ||
| 286 | |||
| 287 | If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an | ||
| 288 | unwinder that is intended to remove the input temporary file; in | ||
| 289 | this case NARGS must be at least 2 and ARGS[1] is the file's name. | ||
| 290 | |||
| 291 | At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ | ||
| 292 | |||
| 293 | static Lisp_Object | ||
| 294 | call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | ||
| 295 | ptrdiff_t tempfile_index) | ||
| 296 | { | ||
| 297 | Lisp_Object buffer, current_dir, path; | ||
| 222 | bool display_p; | 298 | bool display_p; |
| 223 | int fd0, fd1, filefd; | 299 | int fd0; |
| 300 | int callproc_fd[CALLPROC_FDS]; | ||
| 224 | int status; | 301 | int status; |
| 302 | ptrdiff_t i; | ||
| 225 | ptrdiff_t count = SPECPDL_INDEX (); | 303 | ptrdiff_t count = SPECPDL_INDEX (); |
| 226 | USE_SAFE_ALLOCA; | 304 | USE_SAFE_ALLOCA; |
| 227 | 305 | ||
| @@ -231,19 +309,21 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 231 | Lisp_Object error_file; | 309 | Lisp_Object error_file; |
| 232 | Lisp_Object output_file = Qnil; | 310 | Lisp_Object output_file = Qnil; |
| 233 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 311 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 234 | char *outf, *tempfile = NULL; | 312 | char *tempfile = NULL; |
| 235 | int outfilefd; | ||
| 236 | int pid; | 313 | int pid; |
| 237 | #else | 314 | #else |
| 238 | pid_t pid; | 315 | pid_t pid; |
| 239 | #endif | 316 | #endif |
| 240 | int child_errno; | 317 | int child_errno; |
| 241 | int fd_output = -1; | 318 | int fd_output, fd_error; |
| 242 | struct coding_system process_coding; /* coding-system of process output */ | 319 | struct coding_system process_coding; /* coding-system of process output */ |
| 243 | struct coding_system argument_coding; /* coding-system of arguments */ | 320 | struct coding_system argument_coding; /* coding-system of arguments */ |
| 244 | /* Set to the return value of Ffind_operation_coding_system. */ | 321 | /* Set to the return value of Ffind_operation_coding_system. */ |
| 245 | Lisp_Object coding_systems; | 322 | Lisp_Object coding_systems; |
| 246 | bool output_to_buffer = 1; | 323 | bool discard_output; |
| 324 | |||
| 325 | if (synch_process_pid) | ||
| 326 | error ("call-process invoked recursively"); | ||
| 247 | 327 | ||
| 248 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ | 328 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ |
| 249 | coding_systems = Qt; | 329 | coding_systems = Qt; |
| @@ -262,7 +342,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 262 | /* Decide the coding-system for giving arguments. */ | 342 | /* Decide the coding-system for giving arguments. */ |
| 263 | { | 343 | { |
| 264 | Lisp_Object val, *args2; | 344 | Lisp_Object val, *args2; |
| 265 | ptrdiff_t i; | ||
| 266 | 345 | ||
| 267 | /* If arguments are supplied, we may have to encode them. */ | 346 | /* If arguments are supplied, we may have to encode them. */ |
| 268 | if (nargs >= 5) | 347 | if (nargs >= 5) |
| @@ -301,24 +380,16 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 301 | } | 380 | } |
| 302 | } | 381 | } |
| 303 | 382 | ||
| 304 | if (nargs >= 2 && ! NILP (args[1])) | 383 | if (nargs < 3) |
| 305 | { | 384 | buffer = Qnil; |
| 306 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | ||
| 307 | CHECK_STRING (infile); | ||
| 308 | } | ||
| 309 | else | 385 | else |
| 310 | infile = build_string (NULL_DEVICE); | ||
| 311 | |||
| 312 | if (nargs >= 3) | ||
| 313 | { | 386 | { |
| 314 | buffer = args[2]; | 387 | buffer = args[2]; |
| 315 | 388 | ||
| 316 | /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT | 389 | /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT |
| 317 | FILE-FOR-STDERR), unless the first element is :file, in which case see | 390 | FILE-FOR-STDERR), unless the first element is :file, in which case see |
| 318 | the next paragraph. */ | 391 | the next paragraph. */ |
| 319 | if (CONSP (buffer) | 392 | if (CONSP (buffer) && !EQ (XCAR (buffer), QCfile)) |
| 320 | && (! SYMBOLP (XCAR (buffer)) | ||
| 321 | || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))) | ||
| 322 | { | 393 | { |
| 323 | if (CONSP (XCDR (buffer))) | 394 | if (CONSP (XCDR (buffer))) |
| 324 | { | 395 | { |
| @@ -335,9 +406,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 335 | } | 406 | } |
| 336 | 407 | ||
| 337 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ | 408 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ |
| 338 | if (CONSP (buffer) | 409 | if (CONSP (buffer) && EQ (XCAR (buffer), QCfile)) |
| 339 | && SYMBOLP (XCAR (buffer)) | ||
| 340 | && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")) | ||
| 341 | { | 410 | { |
| 342 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), | 411 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), |
| 343 | BVAR (current_buffer, directory)); | 412 | BVAR (current_buffer, directory)); |
| @@ -345,9 +414,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 345 | buffer = Qnil; | 414 | buffer = Qnil; |
| 346 | } | 415 | } |
| 347 | 416 | ||
| 348 | if (!(EQ (buffer, Qnil) | 417 | if (! (NILP (buffer) || EQ (buffer, Qt) || INTEGERP (buffer))) |
| 349 | || EQ (buffer, Qt) | ||
| 350 | || INTEGERP (buffer))) | ||
| 351 | { | 418 | { |
| 352 | Lisp_Object spec_buffer; | 419 | Lisp_Object spec_buffer; |
| 353 | spec_buffer = buffer; | 420 | spec_buffer = buffer; |
| @@ -358,8 +425,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 358 | CHECK_BUFFER (buffer); | 425 | CHECK_BUFFER (buffer); |
| 359 | } | 426 | } |
| 360 | } | 427 | } |
| 361 | else | ||
| 362 | buffer = Qnil; | ||
| 363 | 428 | ||
| 364 | /* Make sure that the child will be able to chdir to the current | 429 | /* Make sure that the child will be able to chdir to the current |
| 365 | buffer's current directory, or its unhandled equivalent. We | 430 | buffer's current directory, or its unhandled equivalent. We |
| @@ -372,28 +437,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 372 | protected by the caller, so all we really have to worry about is | 437 | protected by the caller, so all we really have to worry about is |
| 373 | buffer. */ | 438 | buffer. */ |
| 374 | { | 439 | { |
| 375 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 440 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 376 | |||
| 377 | current_dir = BVAR (current_buffer, directory); | ||
| 378 | |||
| 379 | GCPRO5 (infile, buffer, current_dir, error_file, output_file); | ||
| 380 | 441 | ||
| 381 | current_dir = Funhandled_file_name_directory (current_dir); | 442 | current_dir = encode_current_directory (); |
| 382 | if (NILP (current_dir)) | ||
| 383 | /* If the file name handler says that current_dir is unreachable, use | ||
| 384 | a sensible default. */ | ||
| 385 | current_dir = build_string ("~/"); | ||
| 386 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | ||
| 387 | current_dir = Ffile_name_as_directory (current_dir); | ||
| 388 | 443 | ||
| 389 | if (NILP (Ffile_accessible_directory_p (current_dir))) | 444 | GCPRO4 (buffer, current_dir, error_file, output_file); |
| 390 | report_file_error ("Setting current directory", | ||
| 391 | BVAR (current_buffer, directory)); | ||
| 392 | 445 | ||
| 393 | if (STRING_MULTIBYTE (infile)) | ||
| 394 | infile = ENCODE_FILE (infile); | ||
| 395 | if (STRING_MULTIBYTE (current_dir)) | ||
| 396 | current_dir = ENCODE_FILE (current_dir); | ||
| 397 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) | 446 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) |
| 398 | error_file = ENCODE_FILE (error_file); | 447 | error_file = ENCODE_FILE (error_file); |
| 399 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) | 448 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) |
| @@ -403,44 +452,23 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 403 | 452 | ||
| 404 | display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); | 453 | display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); |
| 405 | 454 | ||
| 406 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); | 455 | for (i = 0; i < CALLPROC_FDS; i++) |
| 407 | if (filefd < 0) | 456 | callproc_fd[i] = -1; |
| 408 | { | 457 | #ifdef MSDOS |
| 409 | int open_errno = errno; | 458 | synch_process_tempfile = make_number (0); |
| 410 | report_file_errno ("Opening process input file", DECODE_FILE (infile), | 459 | #endif |
| 411 | open_errno); | 460 | record_unwind_protect_ptr (call_process_kill, callproc_fd); |
| 412 | } | ||
| 413 | |||
| 414 | if (STRINGP (output_file)) | ||
| 415 | { | ||
| 416 | fd_output = emacs_open (SSDATA (output_file), | ||
| 417 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | ||
| 418 | default_output_mode); | ||
| 419 | if (fd_output < 0) | ||
| 420 | { | ||
| 421 | int open_errno = errno; | ||
| 422 | output_file = DECODE_FILE (output_file); | ||
| 423 | report_file_errno ("Opening process output file", | ||
| 424 | output_file, open_errno); | ||
| 425 | } | ||
| 426 | if (STRINGP (error_file) || NILP (error_file)) | ||
| 427 | output_to_buffer = 0; | ||
| 428 | } | ||
| 429 | 461 | ||
| 430 | /* Search for program; barf if not found. */ | 462 | /* Search for program; barf if not found. */ |
| 431 | { | 463 | { |
| 432 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 464 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 433 | int ok; | 465 | int ok; |
| 434 | 466 | ||
| 435 | GCPRO4 (infile, buffer, current_dir, error_file); | 467 | GCPRO3 (buffer, current_dir, error_file); |
| 436 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); | 468 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); |
| 437 | UNGCPRO; | 469 | UNGCPRO; |
| 438 | if (ok < 0) | 470 | if (ok < 0) |
| 439 | { | 471 | report_file_error ("Searching for program", args[0]); |
| 440 | int openp_errno = errno; | ||
| 441 | emacs_close (filefd); | ||
| 442 | report_file_errno ("Searching for program", args[0], openp_errno); | ||
| 443 | } | ||
| 444 | } | 472 | } |
| 445 | 473 | ||
| 446 | /* If program file name starts with /: for quoting a magic name, | 474 | /* If program file name starts with /: for quoting a magic name, |
| @@ -452,9 +480,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 452 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); | 480 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); |
| 453 | 481 | ||
| 454 | { | 482 | { |
| 455 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 483 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 456 | 484 | ||
| 457 | GCPRO5 (infile, buffer, current_dir, path, error_file); | 485 | GCPRO4 (buffer, current_dir, path, error_file); |
| 458 | if (nargs > 4) | 486 | if (nargs > 4) |
| 459 | { | 487 | { |
| 460 | ptrdiff_t i; | 488 | ptrdiff_t i; |
| @@ -479,254 +507,228 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 479 | UNGCPRO; | 507 | UNGCPRO; |
| 480 | } | 508 | } |
| 481 | 509 | ||
| 482 | #ifdef MSDOS /* MW, July 1993 */ | 510 | discard_output = INTEGERP (buffer) || (NILP (buffer) && NILP (output_file)); |
| 483 | 511 | ||
| 484 | /* If we're redirecting STDOUT to a file, that file is already open | 512 | #ifdef MSDOS |
| 485 | on fd_output. */ | 513 | if (! discard_output && ! STRINGP (output_file)) |
| 486 | if (fd_output < 0) | ||
| 487 | { | 514 | { |
| 488 | if ((outf = egetenv ("TMPDIR"))) | 515 | char const *tmpdir = egetenv ("TMPDIR"); |
| 489 | strcpy (tempfile = alloca (strlen (outf) + 20), outf); | 516 | char const *outf = tmpdir ? tmpdir : ""; |
| 490 | else | 517 | tempfile = alloca (strlen (outf) + 20); |
| 491 | { | 518 | strcpy (tempfile, outf); |
| 492 | tempfile = alloca (20); | ||
| 493 | *tempfile = '\0'; | ||
| 494 | } | ||
| 495 | dostounix_filename (tempfile, 0); | 519 | dostounix_filename (tempfile, 0); |
| 496 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') | 520 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') |
| 497 | strcat (tempfile, "/"); | 521 | strcat (tempfile, "/"); |
| 498 | strcat (tempfile, "detmp.XXX"); | 522 | strcat (tempfile, "detmp.XXX"); |
| 499 | mktemp (tempfile); | 523 | mktemp (tempfile); |
| 500 | outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, | 524 | if (!*tempfile) |
| 501 | S_IREAD | S_IWRITE); | 525 | report_file_error ("Opening process output file", Qnil); |
| 502 | if (outfilefd < 0) | 526 | output_file = build_string (tempfile); |
| 527 | synch_process_tempfile = output_file; | ||
| 528 | } | ||
| 529 | #endif | ||
| 530 | |||
| 531 | if (discard_output) | ||
| 532 | { | ||
| 533 | fd_output = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 534 | if (fd_output < 0) | ||
| 535 | report_file_error ("Opening null device", Qnil); | ||
| 536 | } | ||
| 537 | else if (STRINGP (output_file)) | ||
| 538 | { | ||
| 539 | fd_output = emacs_open (SSDATA (output_file), | ||
| 540 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | ||
| 541 | default_output_mode); | ||
| 542 | if (fd_output < 0) | ||
| 503 | { | 543 | { |
| 504 | int open_errno = errno; | 544 | int open_errno = errno; |
| 505 | emacs_close (filefd); | 545 | output_file = DECODE_FILE (output_file); |
| 506 | report_file_errno ("Opening process output file", | 546 | report_file_errno ("Opening process output file", |
| 507 | build_string (tempfile), open_errno); | 547 | output_file, open_errno); |
| 508 | } | 548 | } |
| 509 | } | 549 | } |
| 510 | else | 550 | else |
| 511 | outfilefd = fd_output; | ||
| 512 | fd0 = filefd; | ||
| 513 | fd1 = outfilefd; | ||
| 514 | #endif /* MSDOS */ | ||
| 515 | |||
| 516 | if (INTEGERP (buffer)) | ||
| 517 | { | 551 | { |
| 518 | fd0 = -1; | ||
| 519 | fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 520 | } | ||
| 521 | else | ||
| 522 | { | ||
| 523 | #ifndef MSDOS | ||
| 524 | int fd[2]; | 552 | int fd[2]; |
| 525 | if (emacs_pipe (fd) != 0) | 553 | if (emacs_pipe (fd) != 0) |
| 526 | { | 554 | report_file_error ("Creating process pipe", Qnil); |
| 527 | int pipe_errno = errno; | 555 | callproc_fd[CALLPROC_PIPEREAD] = fd[0]; |
| 528 | emacs_close (filefd); | 556 | fd_output = fd[1]; |
| 529 | report_file_errno ("Creating process pipe", Qnil, pipe_errno); | ||
| 530 | } | ||
| 531 | fd0 = fd[0]; | ||
| 532 | fd1 = fd[1]; | ||
| 533 | #endif | ||
| 534 | } | 557 | } |
| 558 | callproc_fd[CALLPROC_STDOUT] = fd_output; | ||
| 535 | 559 | ||
| 536 | { | 560 | fd_error = fd_output; |
| 537 | int fd_error = fd1; | ||
| 538 | 561 | ||
| 539 | if (fd_output >= 0) | 562 | if (STRINGP (error_file) || (NILP (error_file) && !discard_output)) |
| 540 | fd1 = fd_output; | 563 | { |
| 541 | 564 | fd_error = emacs_open ((STRINGP (error_file) | |
| 542 | if (NILP (error_file)) | 565 | ? SSDATA (error_file) |
| 543 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 566 | : NULL_DEVICE), |
| 544 | else if (STRINGP (error_file)) | ||
| 545 | fd_error = emacs_open (SSDATA (error_file), | ||
| 546 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | 567 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, |
| 547 | default_output_mode); | 568 | default_output_mode); |
| 548 | 569 | if (fd_error < 0) | |
| 549 | if (fd_error < 0) | 570 | { |
| 550 | { | 571 | int open_errno = errno; |
| 551 | int open_errno = errno; | 572 | report_file_errno ("Cannot redirect stderr", |
| 552 | emacs_close (filefd); | 573 | (STRINGP (error_file) |
| 553 | if (fd0 != filefd) | 574 | ? DECODE_FILE (error_file) |
| 554 | emacs_close (fd0); | 575 | : build_string (NULL_DEVICE)), |
| 555 | if (fd1 >= 0) | 576 | open_errno); |
| 556 | emacs_close (fd1); | 577 | } |
| 557 | #ifdef MSDOS | 578 | callproc_fd[CALLPROC_STDERR] = fd_error; |
| 558 | unlink (tempfile); | 579 | } |
| 559 | #endif | ||
| 560 | if (NILP (error_file)) | ||
| 561 | error_file = build_string (NULL_DEVICE); | ||
| 562 | else if (STRINGP (error_file)) | ||
| 563 | error_file = DECODE_FILE (error_file); | ||
| 564 | report_file_errno ("Cannot redirect stderr", error_file, open_errno); | ||
| 565 | } | ||
| 566 | 580 | ||
| 567 | #ifdef MSDOS /* MW, July 1993 */ | 581 | #ifdef MSDOS /* MW, July 1993 */ |
| 568 | /* Note that on MSDOS `child_setup' actually returns the child process | 582 | /* Note that on MSDOS `child_setup' actually returns the child process |
| 569 | exit status, not its PID, so assign it to status below. */ | 583 | exit status, not its PID, so assign it to status below. */ |
| 570 | pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); | 584 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 571 | child_errno = errno; | 585 | |
| 572 | 586 | if (pid < 0) | |
| 573 | emacs_close (outfilefd); | 587 | { |
| 574 | if (fd_error != outfilefd) | 588 | child_errno = errno; |
| 575 | emacs_close (fd_error); | 589 | unbind_to (count, Qnil); |
| 576 | if (pid < 0) | 590 | synchronize_system_messages_locale (); |
| 577 | { | 591 | return |
| 578 | synchronize_system_messages_locale (); | 592 | code_convert_string_norecord (build_string (strerror (child_errno)), |
| 579 | return | 593 | Vlocale_coding_system, 0); |
| 580 | code_convert_string_norecord (build_string (strerror (child_errno)), | 594 | } |
| 581 | Vlocale_coding_system, 0); | 595 | status = pid; |
| 582 | } | 596 | |
| 583 | status = pid; | 597 | for (i = 0; i < CALLPROC_FDS; i++) |
| 584 | fd1 = -1; /* No harm in closing that one! */ | 598 | if (0 <= callproc_fd[i]) |
| 585 | if (tempfile) | ||
| 586 | { | 599 | { |
| 587 | /* Since CRLF is converted to LF within `decode_coding', we | 600 | emacs_close (callproc_fd[i]); |
| 588 | can always open a file with binary mode. */ | 601 | callproc_fd[i] = -1; |
| 589 | fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); | ||
| 590 | if (fd0 < 0) | ||
| 591 | { | ||
| 592 | int open_errno = errno; | ||
| 593 | unlink (tempfile); | ||
| 594 | emacs_close (filefd); | ||
| 595 | report_file_errno ("Cannot re-open temporary file", | ||
| 596 | build_string (tempfile), open_errno); | ||
| 597 | } | ||
| 598 | } | 602 | } |
| 599 | else | 603 | emacs_close (filefd); |
| 600 | fd0 = -1; /* We are not going to read from tempfile. */ | 604 | clear_unwind_protect (count - 1); |
| 605 | |||
| 606 | if (tempfile) | ||
| 607 | { | ||
| 608 | /* Since CRLF is converted to LF within `decode_coding', we | ||
| 609 | can always open a file with binary mode. */ | ||
| 610 | callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile, | ||
| 611 | O_RDONLY | O_BINARY, 0); | ||
| 612 | if (callproc_fd[CALLPROC_PIPEREAD] < 0) | ||
| 613 | { | ||
| 614 | int open_errno = errno; | ||
| 615 | report_file_errno ("Cannot re-open temporary file", | ||
| 616 | build_string (tempfile), open_errno); | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 601 | #endif /* MSDOS */ | 620 | #endif /* MSDOS */ |
| 602 | 621 | ||
| 603 | /* Do the unwind-protect now, even though the pid is not known, so | 622 | /* Do the unwind-protect now, even though the pid is not known, so |
| 604 | that no storage allocation is done in the critical section. | 623 | that no storage allocation is done in the critical section. |
| 605 | The actual PID will be filled in during the critical section. */ | 624 | The actual PID will be filled in during the critical section. */ |
| 606 | synch_process_pid = 0; | 625 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); |
| 607 | synch_process_fd = fd0; | ||
| 608 | 626 | ||
| 609 | #ifdef MSDOS | 627 | #ifndef MSDOS |
| 610 | /* MSDOS needs different cleanup information. */ | ||
| 611 | record_unwind_protect (call_process_cleanup, | ||
| 612 | Fcons (Fcurrent_buffer (), | ||
| 613 | build_string (tempfile ? tempfile : ""))); | ||
| 614 | #else | ||
| 615 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); | ||
| 616 | 628 | ||
| 617 | block_input (); | 629 | block_input (); |
| 618 | block_child_signal (); | 630 | block_child_signal (); |
| 619 | 631 | ||
| 620 | #ifdef WINDOWSNT | 632 | #ifdef WINDOWSNT |
| 621 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 633 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 622 | /* We need to record the input file of this child, for when we are | ||
| 623 | called from call-process-region to create an async subprocess. | ||
| 624 | That's because call-process-region's unwind procedure will | ||
| 625 | attempt to delete the temporary input file, which will fail | ||
| 626 | because that file is still in use. Recording it with the child | ||
| 627 | will allow us to delete the file when the subprocess exits. | ||
| 628 | The second part of this is in delete_temp_file, q.v. */ | ||
| 629 | if (pid > 0 && INTEGERP (buffer) && nargs >= 2 && !NILP (args[1])) | ||
| 630 | record_infile (pid, xstrdup (SSDATA (infile))); | ||
| 631 | #else /* not WINDOWSNT */ | 634 | #else /* not WINDOWSNT */ |
| 632 | 635 | ||
| 633 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 636 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 634 | { | 637 | { |
| 635 | Lisp_Object volatile buffer_volatile = buffer; | 638 | Lisp_Object volatile buffer_volatile = buffer; |
| 636 | Lisp_Object volatile coding_systems_volatile = coding_systems; | 639 | Lisp_Object volatile coding_systems_volatile = coding_systems; |
| 637 | Lisp_Object volatile current_dir_volatile = current_dir; | 640 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 638 | bool volatile display_p_volatile = display_p; | 641 | bool volatile display_p_volatile = display_p; |
| 639 | bool volatile output_to_buffer_volatile = output_to_buffer; | 642 | bool volatile sa_must_free_volatile = sa_must_free; |
| 640 | bool volatile sa_must_free_volatile = sa_must_free; | 643 | int volatile fd_error_volatile = fd_error; |
| 641 | int volatile fd1_volatile = fd1; | 644 | int volatile filefd_volatile = filefd; |
| 642 | int volatile fd_error_volatile = fd_error; | 645 | ptrdiff_t volatile count_volatile = count; |
| 643 | int volatile fd_output_volatile = fd_output; | 646 | ptrdiff_t volatile sa_count_volatile = sa_count; |
| 644 | int volatile filefd_volatile = filefd; | 647 | char **volatile new_argv_volatile = new_argv; |
| 645 | ptrdiff_t volatile count_volatile = count; | 648 | int volatile callproc_fd_volatile[CALLPROC_FDS]; |
| 646 | ptrdiff_t volatile sa_count_volatile = sa_count; | 649 | for (i = 0; i < CALLPROC_FDS; i++) |
| 647 | char **volatile new_argv_volatile = new_argv; | 650 | callproc_fd_volatile[i] = callproc_fd[i]; |
| 648 | 651 | ||
| 649 | pid = vfork (); | 652 | pid = vfork (); |
| 650 | child_errno = errno; | 653 | |
| 651 | 654 | buffer = buffer_volatile; | |
| 652 | buffer = buffer_volatile; | 655 | coding_systems = coding_systems_volatile; |
| 653 | coding_systems = coding_systems_volatile; | 656 | current_dir = current_dir_volatile; |
| 654 | current_dir = current_dir_volatile; | 657 | display_p = display_p_volatile; |
| 655 | display_p = display_p_volatile; | 658 | sa_must_free = sa_must_free_volatile; |
| 656 | output_to_buffer = output_to_buffer_volatile; | 659 | fd_error = fd_error_volatile; |
| 657 | sa_must_free = sa_must_free_volatile; | 660 | filefd = filefd_volatile; |
| 658 | fd1 = fd1_volatile; | 661 | count = count_volatile; |
| 659 | fd_error = fd_error_volatile; | 662 | sa_count = sa_count_volatile; |
| 660 | fd_output = fd_output_volatile; | 663 | new_argv = new_argv_volatile; |
| 661 | filefd = filefd_volatile; | 664 | |
| 662 | count = count_volatile; | 665 | for (i = 0; i < CALLPROC_FDS; i++) |
| 663 | sa_count = sa_count_volatile; | 666 | callproc_fd[i] = callproc_fd_volatile[i]; |
| 664 | new_argv = new_argv_volatile; | 667 | fd_output = callproc_fd[CALLPROC_STDOUT]; |
| 665 | 668 | } | |
| 666 | fd0 = synch_process_fd; | ||
| 667 | } | ||
| 668 | |||
| 669 | if (pid == 0) | ||
| 670 | { | ||
| 671 | unblock_child_signal (); | ||
| 672 | 669 | ||
| 673 | if (fd0 >= 0) | 670 | if (pid == 0) |
| 674 | emacs_close (fd0); | 671 | { |
| 672 | unblock_child_signal (); | ||
| 675 | 673 | ||
| 676 | setsid (); | 674 | setsid (); |
| 677 | 675 | ||
| 678 | /* Emacs ignores SIGPIPE, but the child should not. */ | 676 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 679 | signal (SIGPIPE, SIG_DFL); | 677 | signal (SIGPIPE, SIG_DFL); |
| 680 | 678 | ||
| 681 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 679 | child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 682 | } | 680 | } |
| 683 | 681 | ||
| 684 | #endif /* not WINDOWSNT */ | 682 | #endif /* not WINDOWSNT */ |
| 685 | 683 | ||
| 686 | child_errno = errno; | 684 | child_errno = errno; |
| 687 | 685 | ||
| 688 | if (pid > 0) | 686 | if (pid > 0) |
| 689 | { | 687 | { |
| 690 | if (INTEGERP (buffer)) | 688 | synch_process_pid = pid; |
| 691 | record_deleted_pid (pid); | ||
| 692 | else | ||
| 693 | synch_process_pid = pid; | ||
| 694 | } | ||
| 695 | 689 | ||
| 696 | unblock_child_signal (); | 690 | if (INTEGERP (buffer)) |
| 697 | unblock_input (); | 691 | { |
| 692 | if (tempfile_index < 0) | ||
| 693 | record_deleted_pid (pid, Qnil); | ||
| 694 | else | ||
| 695 | { | ||
| 696 | eassert (1 < nargs); | ||
| 697 | record_deleted_pid (pid, args[1]); | ||
| 698 | clear_unwind_protect (tempfile_index); | ||
| 699 | } | ||
| 700 | synch_process_pid = 0; | ||
| 701 | } | ||
| 702 | } | ||
| 698 | 703 | ||
| 699 | /* The MSDOS case did this already. */ | 704 | unblock_child_signal (); |
| 700 | if (fd_error >= 0) | 705 | unblock_input (); |
| 701 | emacs_close (fd_error); | ||
| 702 | #endif /* not MSDOS */ | ||
| 703 | 706 | ||
| 704 | /* Close most of our file descriptors, but not fd0 | 707 | #endif /* not MSDOS */ |
| 705 | since we will use that to read input from. */ | ||
| 706 | emacs_close (filefd); | ||
| 707 | if (fd_output >= 0) | ||
| 708 | emacs_close (fd_output); | ||
| 709 | if (fd1 >= 0 && fd1 != fd_error) | ||
| 710 | emacs_close (fd1); | ||
| 711 | } | ||
| 712 | 708 | ||
| 713 | if (pid < 0) | 709 | if (pid < 0) |
| 714 | report_file_errno ("Doing vfork", Qnil, child_errno); | 710 | report_file_errno ("Doing vfork", Qnil, child_errno); |
| 715 | 711 | ||
| 712 | /* Close our file descriptors, except for callproc_fd[CALLPROC_PIPEREAD] | ||
| 713 | since we will use that to read input from. */ | ||
| 714 | for (i = 0; i < CALLPROC_FDS; i++) | ||
| 715 | if (i != CALLPROC_PIPEREAD && 0 <= callproc_fd[i]) | ||
| 716 | { | ||
| 717 | emacs_close (callproc_fd[i]); | ||
| 718 | callproc_fd[i] = -1; | ||
| 719 | } | ||
| 720 | emacs_close (filefd); | ||
| 721 | clear_unwind_protect (count - 1); | ||
| 722 | |||
| 716 | if (INTEGERP (buffer)) | 723 | if (INTEGERP (buffer)) |
| 717 | return unbind_to (count, Qnil); | 724 | return unbind_to (count, Qnil); |
| 718 | 725 | ||
| 719 | if (BUFFERP (buffer)) | 726 | if (BUFFERP (buffer)) |
| 720 | Fset_buffer (buffer); | 727 | Fset_buffer (buffer); |
| 721 | 728 | ||
| 722 | if (NILP (buffer)) | 729 | fd0 = callproc_fd[CALLPROC_PIPEREAD]; |
| 723 | { | 730 | |
| 724 | /* If BUFFER is nil, we must read process output once and then | 731 | if (0 <= fd0) |
| 725 | discard it, so setup coding system but with nil. */ | ||
| 726 | setup_coding_system (Qnil, &process_coding); | ||
| 727 | process_coding.dst_multibyte = 0; | ||
| 728 | } | ||
| 729 | else | ||
| 730 | { | 732 | { |
| 731 | Lisp_Object val, *args2; | 733 | Lisp_Object val, *args2; |
| 732 | 734 | ||
| @@ -762,13 +764,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 762 | setup_coding_system (val, &process_coding); | 764 | setup_coding_system (val, &process_coding); |
| 763 | process_coding.dst_multibyte | 765 | process_coding.dst_multibyte |
| 764 | = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 766 | = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 767 | process_coding.src_multibyte = 0; | ||
| 765 | } | 768 | } |
| 766 | process_coding.src_multibyte = 0; | ||
| 767 | 769 | ||
| 768 | immediate_quit = 1; | 770 | immediate_quit = 1; |
| 769 | QUIT; | 771 | QUIT; |
| 770 | 772 | ||
| 771 | if (output_to_buffer) | 773 | if (0 <= fd0) |
| 772 | { | 774 | { |
| 773 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; | 775 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; |
| 774 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; | 776 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; |
| @@ -779,9 +781,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 779 | EMACS_INT total_read = 0; | 781 | EMACS_INT total_read = 0; |
| 780 | int carryover = 0; | 782 | int carryover = 0; |
| 781 | bool display_on_the_fly = display_p; | 783 | bool display_on_the_fly = display_p; |
| 782 | struct coding_system saved_coding; | 784 | struct coding_system saved_coding = process_coding; |
| 783 | 785 | ||
| 784 | saved_coding = process_coding; | ||
| 785 | while (1) | 786 | while (1) |
| 786 | { | 787 | { |
| 787 | /* Repeatedly read until we've filled as much as possible | 788 | /* Repeatedly read until we've filled as much as possible |
| @@ -812,58 +813,54 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 812 | /* Now NREAD is the total amount of data in the buffer. */ | 813 | /* Now NREAD is the total amount of data in the buffer. */ |
| 813 | immediate_quit = 0; | 814 | immediate_quit = 0; |
| 814 | 815 | ||
| 815 | if (!NILP (buffer)) | 816 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) |
| 816 | { | 817 | && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) |
| 817 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) | 818 | insert_1_both (buf, nread, nread, 0, 1, 0); |
| 818 | && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) | 819 | else |
| 819 | insert_1_both (buf, nread, nread, 0, 1, 0); | 820 | { /* We have to decode the input. */ |
| 820 | else | 821 | Lisp_Object curbuf; |
| 821 | { /* We have to decode the input. */ | 822 | ptrdiff_t count1 = SPECPDL_INDEX (); |
| 822 | Lisp_Object curbuf; | 823 | |
| 823 | ptrdiff_t count1 = SPECPDL_INDEX (); | 824 | XSETBUFFER (curbuf, current_buffer); |
| 824 | 825 | /* We cannot allow after-change-functions be run | |
| 825 | XSETBUFFER (curbuf, current_buffer); | 826 | during decoding, because that might modify the |
| 826 | /* We cannot allow after-change-functions be run | 827 | buffer, while we rely on process_coding.produced to |
| 827 | during decoding, because that might modify the | 828 | faithfully reflect inserted text until we |
| 828 | buffer, while we rely on process_coding.produced to | 829 | TEMP_SET_PT_BOTH below. */ |
| 829 | faithfully reflect inserted text until we | 830 | specbind (Qinhibit_modification_hooks, Qt); |
| 830 | TEMP_SET_PT_BOTH below. */ | 831 | decode_coding_c_string (&process_coding, |
| 831 | specbind (Qinhibit_modification_hooks, Qt); | 832 | (unsigned char *) buf, nread, curbuf); |
| 832 | decode_coding_c_string (&process_coding, | 833 | unbind_to (count1, Qnil); |
| 833 | (unsigned char *) buf, nread, curbuf); | 834 | if (display_on_the_fly |
| 834 | unbind_to (count1, Qnil); | 835 | && CODING_REQUIRE_DETECTION (&saved_coding) |
| 835 | if (display_on_the_fly | 836 | && ! CODING_REQUIRE_DETECTION (&process_coding)) |
| 836 | && CODING_REQUIRE_DETECTION (&saved_coding) | 837 | { |
| 837 | && ! CODING_REQUIRE_DETECTION (&process_coding)) | 838 | /* We have detected some coding system, but the |
| 838 | { | 839 | detection may have been via insufficient data. |
| 839 | /* We have detected some coding system. But, | 840 | So give up displaying on the fly. */ |
| 840 | there's a possibility that the detection was | 841 | if (process_coding.produced > 0) |
| 841 | done by insufficient data. So, we give up | 842 | del_range_2 (process_coding.dst_pos, |
| 842 | displaying on the fly. */ | 843 | process_coding.dst_pos_byte, |
| 843 | if (process_coding.produced > 0) | 844 | (process_coding.dst_pos |
| 844 | del_range_2 (process_coding.dst_pos, | 845 | + process_coding.produced_char), |
| 845 | process_coding.dst_pos_byte, | 846 | (process_coding.dst_pos_byte |
| 846 | process_coding.dst_pos | 847 | + process_coding.produced), |
| 847 | + process_coding.produced_char, | 848 | 0); |
| 848 | process_coding.dst_pos_byte | 849 | display_on_the_fly = 0; |
| 849 | + process_coding.produced, 0); | 850 | process_coding = saved_coding; |
| 850 | display_on_the_fly = 0; | 851 | carryover = nread; |
| 851 | process_coding = saved_coding; | 852 | /* Make the above condition always fail in the future. */ |
| 852 | carryover = nread; | 853 | saved_coding.common_flags |
| 853 | /* This is to make the above condition always | 854 | &= ~CODING_REQUIRE_DETECTION_MASK; |
| 854 | fails in the future. */ | 855 | continue; |
| 855 | saved_coding.common_flags | ||
| 856 | &= ~CODING_REQUIRE_DETECTION_MASK; | ||
| 857 | continue; | ||
| 858 | } | ||
| 859 | |||
| 860 | TEMP_SET_PT_BOTH (PT + process_coding.produced_char, | ||
| 861 | PT_BYTE + process_coding.produced); | ||
| 862 | carryover = process_coding.carryover_bytes; | ||
| 863 | if (carryover > 0) | ||
| 864 | memcpy (buf, process_coding.carryover, | ||
| 865 | process_coding.carryover_bytes); | ||
| 866 | } | 856 | } |
| 857 | |||
| 858 | TEMP_SET_PT_BOTH (PT + process_coding.produced_char, | ||
| 859 | PT_BYTE + process_coding.produced); | ||
| 860 | carryover = process_coding.carryover_bytes; | ||
| 861 | if (carryover > 0) | ||
| 862 | memcpy (buf, process_coding.carryover, | ||
| 863 | process_coding.carryover_bytes); | ||
| 867 | } | 864 | } |
| 868 | 865 | ||
| 869 | if (process_coding.mode & CODING_MODE_LAST_BLOCK) | 866 | if (process_coding.mode & CODING_MODE_LAST_BLOCK) |
| @@ -882,7 +879,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 882 | first = 0; | 879 | first = 0; |
| 883 | redisplay_preserve_echo_area (1); | 880 | redisplay_preserve_echo_area (1); |
| 884 | /* This variable might have been set to 0 for code | 881 | /* This variable might have been set to 0 for code |
| 885 | detection. In that case, we set it back to 1 because | 882 | detection. In that case, set it back to 1 because |
| 886 | we should have already detected a coding system. */ | 883 | we should have already detected a coding system. */ |
| 887 | display_on_the_fly = 1; | 884 | display_on_the_fly = 1; |
| 888 | } | 885 | } |
| @@ -901,7 +898,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 901 | 898 | ||
| 902 | #ifndef MSDOS | 899 | #ifndef MSDOS |
| 903 | /* Wait for it to terminate, unless it already has. */ | 900 | /* Wait for it to terminate, unless it already has. */ |
| 904 | wait_for_termination (pid, &status, !output_to_buffer); | 901 | wait_for_termination (pid, &status, fd0 < 0); |
| 905 | #endif | 902 | #endif |
| 906 | 903 | ||
| 907 | immediate_quit = 0; | 904 | immediate_quit = 0; |
| @@ -931,37 +928,18 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 931 | return make_number (WEXITSTATUS (status)); | 928 | return make_number (WEXITSTATUS (status)); |
| 932 | } | 929 | } |
| 933 | 930 | ||
| 934 | static void | ||
| 935 | delete_temp_file (Lisp_Object name) | ||
| 936 | { | ||
| 937 | /* Suppress jka-compr handling, etc. */ | ||
| 938 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 939 | specbind (intern ("file-name-handler-alist"), Qnil); | ||
| 940 | #ifdef WINDOWSNT | ||
| 941 | /* If this is called when the subprocess didn't exit yet, the | ||
| 942 | attempt to delete its input file will fail. In that case, we | ||
| 943 | schedule the file for deletion when the subprocess exits. This | ||
| 944 | is the 2nd part of handling this situation; see the call to | ||
| 945 | record_infile in call-process above, for the first part. */ | ||
| 946 | if (!internal_delete_file (name)) | ||
| 947 | { | ||
| 948 | Lisp_Object encoded_file = ENCODE_FILE (name); | ||
| 949 | |||
| 950 | record_pending_deletion (SSDATA (encoded_file)); | ||
| 951 | } | ||
| 952 | #else | ||
| 953 | internal_delete_file (name); | ||
| 954 | #endif | ||
| 955 | unbind_to (count, Qnil); | ||
| 956 | } | ||
| 957 | |||
| 958 | /* Create a temporary file suitable for storing the input data of | 931 | /* Create a temporary file suitable for storing the input data of |
| 959 | call-process-region. NARGS and ARGS are the same as for | 932 | call-process-region. NARGS and ARGS are the same as for |
| 960 | call-process-region. */ | 933 | call-process-region. Store into *FILENAME_STRING_PTR a Lisp string |
| 934 | naming the file, and return a file descriptor for reading. | ||
| 935 | Unwind-protect the file, so that the file descriptor will be closed | ||
| 936 | and the file removed when the caller unwinds the specpdl stack. */ | ||
| 961 | 937 | ||
| 962 | static Lisp_Object | 938 | static int |
| 963 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | 939 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args, |
| 940 | Lisp_Object *filename_string_ptr) | ||
| 964 | { | 941 | { |
| 942 | int fd; | ||
| 965 | struct gcpro gcpro1; | 943 | struct gcpro gcpro1; |
| 966 | Lisp_Object filename_string; | 944 | Lisp_Object filename_string; |
| 967 | Lisp_Object val, start, end; | 945 | Lisp_Object val, start, end; |
| @@ -988,6 +966,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 988 | { | 966 | { |
| 989 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); | 967 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); |
| 990 | char *tempfile; | 968 | char *tempfile; |
| 969 | ptrdiff_t count; | ||
| 991 | 970 | ||
| 992 | #ifdef WINDOWSNT | 971 | #ifdef WINDOWSNT |
| 993 | /* Cannot use the result of Fexpand_file_name, because it | 972 | /* Cannot use the result of Fexpand_file_name, because it |
| @@ -1008,27 +987,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1008 | GCPRO1 (filename_string); | 987 | GCPRO1 (filename_string); |
| 1009 | tempfile = SSDATA (filename_string); | 988 | tempfile = SSDATA (filename_string); |
| 1010 | 989 | ||
| 1011 | { | 990 | count = SPECPDL_INDEX (); |
| 1012 | int fd; | 991 | record_unwind_protect_nothing (); |
| 1013 | 992 | fd = mkostemp (tempfile, O_CLOEXEC); | |
| 1014 | #ifdef HAVE_MKOSTEMP | 993 | if (fd < 0) |
| 1015 | fd = mkostemp (tempfile, O_CLOEXEC); | 994 | report_file_error ("Failed to open temporary file using pattern", |
| 1016 | #elif defined HAVE_MKSTEMP | 995 | pattern); |
| 1017 | fd = mkstemp (tempfile); | 996 | set_unwind_protect (count, delete_temp_file, filename_string); |
| 1018 | #else | 997 | record_unwind_protect_int (close_file_unwind, fd); |
| 1019 | errno = EEXIST; | ||
| 1020 | mktemp (tempfile); | ||
| 1021 | fd = *tempfile ? 0 : -1; | ||
| 1022 | #endif | ||
| 1023 | if (fd < 0) | ||
| 1024 | report_file_error ("Failed to open temporary file using pattern", | ||
| 1025 | pattern); | ||
| 1026 | #if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP | ||
| 1027 | emacs_close (fd); | ||
| 1028 | #endif | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | record_unwind_protect (delete_temp_file, filename_string); | ||
| 1032 | } | 998 | } |
| 1033 | 999 | ||
| 1034 | start = args[0]; | 1000 | start = args[0]; |
| @@ -1059,15 +1025,20 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1059 | /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we | 1025 | /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we |
| 1060 | happen to get a ".Z" suffix. */ | 1026 | happen to get a ".Z" suffix. */ |
| 1061 | specbind (intern ("file-name-handler-alist"), Qnil); | 1027 | specbind (intern ("file-name-handler-alist"), Qnil); |
| 1062 | Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil); | 1028 | write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd); |
| 1063 | 1029 | ||
| 1064 | unbind_to (count1, Qnil); | 1030 | unbind_to (count1, Qnil); |
| 1065 | } | 1031 | } |
| 1066 | 1032 | ||
| 1033 | if (lseek (fd, 0, SEEK_SET) < 0) | ||
| 1034 | report_file_error ("Setting file position", filename_string); | ||
| 1035 | |||
| 1067 | /* Note that Fcall_process takes care of binding | 1036 | /* Note that Fcall_process takes care of binding |
| 1068 | coding-system-for-read. */ | 1037 | coding-system-for-read. */ |
| 1069 | 1038 | ||
| 1070 | RETURN_UNGCPRO (filename_string); | 1039 | *filename_string_ptr = filename_string; |
| 1040 | UNGCPRO; | ||
| 1041 | return fd; | ||
| 1071 | } | 1042 | } |
| 1072 | 1043 | ||
| 1073 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | 1044 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, |
| @@ -1098,11 +1069,12 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1098 | (ptrdiff_t nargs, Lisp_Object *args) | 1069 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1099 | { | 1070 | { |
| 1100 | struct gcpro gcpro1; | 1071 | struct gcpro gcpro1; |
| 1101 | Lisp_Object infile; | 1072 | Lisp_Object infile, val; |
| 1102 | ptrdiff_t count = SPECPDL_INDEX (); | 1073 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1103 | Lisp_Object start = args[0]; | 1074 | Lisp_Object start = args[0]; |
| 1104 | Lisp_Object end = args[1]; | 1075 | Lisp_Object end = args[1]; |
| 1105 | bool empty_input; | 1076 | bool empty_input; |
| 1077 | int fd; | ||
| 1106 | 1078 | ||
| 1107 | if (STRINGP (start)) | 1079 | if (STRINGP (start)) |
| 1108 | empty_input = SCHARS (start) == 0; | 1080 | empty_input = SCHARS (start) == 0; |
| @@ -1116,7 +1088,17 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1116 | empty_input = XINT (start) == XINT (end); | 1088 | empty_input = XINT (start) == XINT (end); |
| 1117 | } | 1089 | } |
| 1118 | 1090 | ||
| 1119 | infile = empty_input ? Qnil : create_temp_file (nargs, args); | 1091 | if (!empty_input) |
| 1092 | fd = create_temp_file (nargs, args, &infile); | ||
| 1093 | else | ||
| 1094 | { | ||
| 1095 | infile = Qnil; | ||
| 1096 | fd = emacs_open (NULL_DEVICE, O_RDONLY, 0); | ||
| 1097 | if (fd < 0) | ||
| 1098 | report_file_error ("Opening null device", Qnil); | ||
| 1099 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 1100 | } | ||
| 1101 | |||
| 1120 | GCPRO1 (infile); | 1102 | GCPRO1 (infile); |
| 1121 | 1103 | ||
| 1122 | if (nargs > 3 && !NILP (args[3])) | 1104 | if (nargs > 3 && !NILP (args[3])) |
| @@ -1134,7 +1116,8 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1134 | } | 1116 | } |
| 1135 | args[1] = infile; | 1117 | args[1] = infile; |
| 1136 | 1118 | ||
| 1137 | RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); | 1119 | val = call_process (nargs, args, fd, empty_input ? -1 : count); |
| 1120 | RETURN_UNGCPRO (unbind_to (count, val)); | ||
| 1138 | } | 1121 | } |
| 1139 | 1122 | ||
| 1140 | #ifndef WINDOWSNT | 1123 | #ifndef WINDOWSNT |
| @@ -1210,23 +1193,21 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1210 | static variables as if the superior had done alloca and will be | 1193 | static variables as if the superior had done alloca and will be |
| 1211 | cleaned up in the usual way. */ | 1194 | cleaned up in the usual way. */ |
| 1212 | { | 1195 | { |
| 1213 | register char *temp; | 1196 | char *temp; |
| 1214 | size_t i; /* size_t, because ptrdiff_t might overflow here! */ | 1197 | ptrdiff_t i; |
| 1215 | 1198 | ||
| 1216 | i = SBYTES (current_dir); | 1199 | i = SBYTES (current_dir); |
| 1217 | #ifdef MSDOS | 1200 | #ifdef MSDOS |
| 1218 | /* MSDOS must have all environment variables malloc'ed, because | 1201 | /* MSDOS must have all environment variables malloc'ed, because |
| 1219 | low-level libc functions that launch subsidiary processes rely | 1202 | low-level libc functions that launch subsidiary processes rely |
| 1220 | on that. */ | 1203 | on that. */ |
| 1221 | pwd_var = xmalloc (i + 6); | 1204 | pwd_var = xmalloc (i + 5); |
| 1222 | #else | 1205 | #else |
| 1223 | pwd_var = alloca (i + 6); | 1206 | pwd_var = alloca (i + 5); |
| 1224 | #endif | 1207 | #endif |
| 1225 | temp = pwd_var + 4; | 1208 | temp = pwd_var + 4; |
| 1226 | memcpy (pwd_var, "PWD=", 4); | 1209 | memcpy (pwd_var, "PWD=", 4); |
| 1227 | memcpy (temp, SDATA (current_dir), i); | 1210 | strcpy (temp, SSDATA (current_dir)); |
| 1228 | if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP; | ||
| 1229 | temp[i] = 0; | ||
| 1230 | 1211 | ||
| 1231 | #ifndef DOS_NT | 1212 | #ifndef DOS_NT |
| 1232 | /* We can't signal an Elisp error here; we're in a vfork. Since | 1213 | /* We can't signal an Elisp error here; we're in a vfork. Since |
| @@ -1695,6 +1676,11 @@ syms_of_callproc (void) | |||
| 1695 | #endif | 1676 | #endif |
| 1696 | staticpro (&Vtemp_file_name_pattern); | 1677 | staticpro (&Vtemp_file_name_pattern); |
| 1697 | 1678 | ||
| 1679 | #ifdef MSDOS | ||
| 1680 | synch_process_tempfile = make_number (0); | ||
| 1681 | staticpro (&synch_process_tempfile); | ||
| 1682 | #endif | ||
| 1683 | |||
| 1698 | DEFVAR_LISP ("shell-file-name", Vshell_file_name, | 1684 | DEFVAR_LISP ("shell-file-name", Vshell_file_name, |
| 1699 | doc: /* File name to load inferior shells from. | 1685 | doc: /* File name to load inferior shells from. |
| 1700 | Initialized from the SHELL environment variable, or to a system-dependent | 1686 | Initialized from the SHELL environment variable, or to a system-dependent |
diff --git a/src/casefiddle.c b/src/casefiddle.c index 7f5b99752fa..5a40790f87f 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -214,7 +214,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) | |||
| 214 | validate_region (&b, &e); | 214 | validate_region (&b, &e); |
| 215 | start = XFASTINT (b); | 215 | start = XFASTINT (b); |
| 216 | end = XFASTINT (e); | 216 | end = XFASTINT (e); |
| 217 | modify_region_1 (start, end, false); | 217 | modify_text (start, end); |
| 218 | record_change (start, end - start); | 218 | record_change (start, end - start); |
| 219 | start_byte = CHAR_TO_BYTE (start); | 219 | start_byte = CHAR_TO_BYTE (start); |
| 220 | 220 | ||
diff --git a/src/casetab.c b/src/casetab.c index 5f3c8db2869..b6b1c99c39f 100644 --- a/src/casetab.c +++ b/src/casetab.c | |||
| @@ -247,15 +247,8 @@ init_casetab_once (void) | |||
| 247 | { | 247 | { |
| 248 | register int i; | 248 | register int i; |
| 249 | Lisp_Object down, up, eqv; | 249 | Lisp_Object down, up, eqv; |
| 250 | DEFSYM (Qcase_table, "case-table"); | ||
| 251 | |||
| 252 | /* Intern this now in case it isn't already done. | ||
| 253 | Setting this variable twice is harmless. | ||
| 254 | But don't staticpro it here--that is done in alloc.c. */ | ||
| 255 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | ||
| 256 | 250 | ||
| 257 | /* Now we are ready to set up this property, so we can | 251 | DEFSYM (Qcase_table, "case-table"); |
| 258 | create char tables. */ | ||
| 259 | Fput (Qcase_table, Qchar_table_extra_slots, make_number (3)); | 252 | Fput (Qcase_table, Qchar_table_extra_slots, make_number (3)); |
| 260 | 253 | ||
| 261 | down = Fmake_char_table (Qcase_table, Qnil); | 254 | down = Fmake_char_table (Qcase_table, Qnil); |
diff --git a/src/category.c b/src/category.c index 30ffbd0890f..b28978fb721 100644 --- a/src/category.c +++ b/src/category.c | |||
| @@ -460,14 +460,6 @@ init_category_once (void) | |||
| 460 | { | 460 | { |
| 461 | /* This has to be done here, before we call Fmake_char_table. */ | 461 | /* This has to be done here, before we call Fmake_char_table. */ |
| 462 | DEFSYM (Qcategory_table, "category-table"); | 462 | DEFSYM (Qcategory_table, "category-table"); |
| 463 | |||
| 464 | /* Intern this now in case it isn't already done. | ||
| 465 | Setting this variable twice is harmless. | ||
| 466 | But don't staticpro it here--that is done in alloc.c. */ | ||
| 467 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | ||
| 468 | |||
| 469 | /* Now we are ready to set up this property, so we can | ||
| 470 | create category tables. */ | ||
| 471 | Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2)); | 463 | Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2)); |
| 472 | 464 | ||
| 473 | Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil); | 465 | Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil); |
diff --git a/src/character.c b/src/character.c index b2caaa290af..6fefb6e8824 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -174,11 +174,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len) | |||
| 174 | 174 | ||
| 175 | if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10)) | 175 | if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10)) |
| 176 | { | 176 | { |
| 177 | /* 1-, 2-, and 3-byte sequences can be handled by the macro. */ | ||
| 177 | c = STRING_CHAR_ADVANCE (p); | 178 | c = STRING_CHAR_ADVANCE (p); |
| 178 | } | 179 | } |
| 179 | else if (! (*p & 0x08)) | 180 | else if (! (*p & 0x08)) |
| 180 | { | 181 | { |
| 181 | c = ((((p)[0] & 0xF) << 18) | 182 | /* A 4-byte sequence of this form: |
| 183 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ | ||
| 184 | c = ((((p)[0] & 0x7) << 18) | ||
| 182 | | (((p)[1] & 0x3F) << 12) | 185 | | (((p)[1] & 0x3F) << 12) |
| 183 | | (((p)[2] & 0x3F) << 6) | 186 | | (((p)[2] & 0x3F) << 6) |
| 184 | | ((p)[3] & 0x3F)); | 187 | | ((p)[3] & 0x3F)); |
| @@ -186,7 +189,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len) | |||
| 186 | } | 189 | } |
| 187 | else | 190 | else |
| 188 | { | 191 | { |
| 189 | c = ((((p)[1] & 0x3F) << 18) | 192 | /* A 5-byte sequence of this form: |
| 193 | |||
| 194 | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
| 195 | |||
| 196 | Note that the top 4 `x's are always 0, so shifting p[1] can | ||
| 197 | never exceed the maximum valid character codepoint. */ | ||
| 198 | c = (/* (((p)[0] & 0x3) << 24) ... always 0, so no need to shift. */ | ||
| 199 | (((p)[1] & 0x3F) << 18) | ||
| 190 | | (((p)[2] & 0x3F) << 12) | 200 | | (((p)[2] & 0x3F) << 12) |
| 191 | | (((p)[3] & 0x3F) << 6) | 201 | | (((p)[3] & 0x3F) << 6) |
| 192 | | ((p)[4] & 0x3F)); | 202 | | ((p)[4] & 0x3F)); |
| @@ -1062,10 +1072,6 @@ A char-table for width (columns) of each character. */); | |||
| 1062 | doc: /* Char table of script symbols. | 1072 | doc: /* Char table of script symbols. |
| 1063 | It has one extra slot whose value is a list of script symbols. */); | 1073 | It has one extra slot whose value is a list of script symbols. */); |
| 1064 | 1074 | ||
| 1065 | /* Intern this now in case it isn't already done. | ||
| 1066 | Setting this variable twice is harmless. | ||
| 1067 | But don't staticpro it here--that is done in alloc.c. */ | ||
| 1068 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | ||
| 1069 | DEFSYM (Qchar_script_table, "char-script-table"); | 1075 | DEFSYM (Qchar_script_table, "char-script-table"); |
| 1070 | Fput (Qchar_script_table, Qchar_table_extra_slots, make_number (1)); | 1076 | Fput (Qchar_script_table, Qchar_table_extra_slots, make_number (1)); |
| 1071 | Vchar_script_table = Fmake_char_table (Qchar_script_table, Qnil); | 1077 | Vchar_script_table = Fmake_char_table (Qchar_script_table, Qnil); |
diff --git a/src/cmds.c b/src/cmds.c index 3ebad50184a..ee3be79a0ab 100644 --- a/src/cmds.c +++ b/src/cmds.c | |||
| @@ -86,6 +86,7 @@ DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p", | |||
| 86 | doc: /* Move point N characters forward (backward if N is negative). | 86 | doc: /* Move point N characters forward (backward if N is negative). |
| 87 | On reaching end or beginning of buffer, stop and signal error. | 87 | On reaching end or beginning of buffer, stop and signal error. |
| 88 | Interactively, N is the numeric prefix argument. | 88 | Interactively, N is the numeric prefix argument. |
| 89 | If N is omitted or nil, move point 1 character forward. | ||
| 89 | 90 | ||
| 90 | Depending on the bidirectional context, the movement may be to the | 91 | Depending on the bidirectional context, the movement may be to the |
| 91 | right or to the left on the screen. This is in contrast with | 92 | right or to the left on the screen. This is in contrast with |
| @@ -99,6 +100,7 @@ DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p", | |||
| 99 | doc: /* Move point N characters backward (forward if N is negative). | 100 | doc: /* Move point N characters backward (forward if N is negative). |
| 100 | On attempt to pass beginning or end of buffer, stop and signal error. | 101 | On attempt to pass beginning or end of buffer, stop and signal error. |
| 101 | Interactively, N is the numeric prefix argument. | 102 | Interactively, N is the numeric prefix argument. |
| 103 | If N is omitted or nil, move point 1 character backward. | ||
| 102 | 104 | ||
| 103 | Depending on the bidirectional context, the movement may be to the | 105 | Depending on the bidirectional context, the movement may be to the |
| 104 | right or to the left on the screen. This is in contrast with | 106 | right or to the left on the screen. This is in contrast with |
| @@ -119,9 +121,7 @@ With positive N, a non-empty line at the end counts as one line | |||
| 119 | successfully moved (for the return value). */) | 121 | successfully moved (for the return value). */) |
| 120 | (Lisp_Object n) | 122 | (Lisp_Object n) |
| 121 | { | 123 | { |
| 122 | ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; | 124 | ptrdiff_t opoint = PT, pos, pos_byte, shortage, count; |
| 123 | ptrdiff_t pos, pos_byte; | ||
| 124 | EMACS_INT count, shortage; | ||
| 125 | 125 | ||
| 126 | if (NILP (n)) | 126 | if (NILP (n)) |
| 127 | count = 1; | 127 | count = 1; |
| @@ -132,16 +132,12 @@ successfully moved (for the return value). */) | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (count <= 0) | 134 | if (count <= 0) |
| 135 | shortage = scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, 1); | 135 | pos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, |
| 136 | &shortage, &pos_byte, 1); | ||
| 136 | else | 137 | else |
| 137 | shortage = scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, 1); | 138 | pos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, |
| 138 | 139 | &shortage, &pos_byte, 1); | |
| 139 | /* Since scan_newline does TEMP_SET_PT_BOTH, | 140 | |
| 140 | and we want to set PT "for real", | ||
| 141 | go back to the old point and then come back here. */ | ||
| 142 | pos = PT; | ||
| 143 | pos_byte = PT_BYTE; | ||
| 144 | TEMP_SET_PT_BOTH (opoint, opoint_byte); | ||
| 145 | SET_PT_BOTH (pos, pos_byte); | 141 | SET_PT_BOTH (pos, pos_byte); |
| 146 | 142 | ||
| 147 | if (shortage > 0 | 143 | if (shortage > 0 |
diff --git a/src/coding.c b/src/coding.c index 5b637627763..c10fb375672 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -10814,11 +10814,6 @@ syms_of_coding (void) | |||
| 10814 | Fput (Qcoding_system_error, Qerror_message, | 10814 | Fput (Qcoding_system_error, Qerror_message, |
| 10815 | build_pure_c_string ("Invalid coding system")); | 10815 | build_pure_c_string ("Invalid coding system")); |
| 10816 | 10816 | ||
| 10817 | /* Intern this now in case it isn't already done. | ||
| 10818 | Setting this variable twice is harmless. | ||
| 10819 | But don't staticpro it here--that is done in alloc.c. */ | ||
| 10820 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | ||
| 10821 | |||
| 10822 | DEFSYM (Qtranslation_table, "translation-table"); | 10817 | DEFSYM (Qtranslation_table, "translation-table"); |
| 10823 | Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2)); | 10818 | Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2)); |
| 10824 | DEFSYM (Qtranslation_table_id, "translation-table-id"); | 10819 | DEFSYM (Qtranslation_table_id, "translation-table-id"); |
diff --git a/src/coding.h b/src/coding.h index 7b7078e06fa..2c01a05d197 100644 --- a/src/coding.h +++ b/src/coding.h | |||
| @@ -378,8 +378,6 @@ struct emacs_mule_spec | |||
| 378 | struct composition_status cmp_status; | 378 | struct composition_status cmp_status; |
| 379 | }; | 379 | }; |
| 380 | 380 | ||
| 381 | struct ccl_spec; | ||
| 382 | |||
| 383 | struct undecided_spec | 381 | struct undecided_spec |
| 384 | { | 382 | { |
| 385 | /* Inhibit null byte detection. 1 means always inhibit, | 383 | /* Inhibit null byte detection. 1 means always inhibit, |
diff --git a/src/composite.h b/src/composite.h index 53665b36bd1..df170093797 100644 --- a/src/composite.h +++ b/src/composite.h | |||
| @@ -25,6 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | #ifndef EMACS_COMPOSITE_H | 25 | #ifndef EMACS_COMPOSITE_H |
| 26 | #define EMACS_COMPOSITE_H | 26 | #define EMACS_COMPOSITE_H |
| 27 | 27 | ||
| 28 | #include "font.h" | ||
| 29 | |||
| 28 | INLINE_HEADER_BEGIN | 30 | INLINE_HEADER_BEGIN |
| 29 | #ifndef COMPOSITE_INLINE | 31 | #ifndef COMPOSITE_INLINE |
| 30 | # define COMPOSITE_INLINE INLINE | 32 | # define COMPOSITE_INLINE INLINE |
| @@ -312,10 +314,6 @@ enum lglyph_indices | |||
| 312 | #define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \ | 314 | #define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \ |
| 313 | ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 2)) : 0) | 315 | ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 2)) : 0) |
| 314 | 316 | ||
| 315 | struct composition_it; | ||
| 316 | struct face; | ||
| 317 | struct font_metrics; | ||
| 318 | |||
| 319 | extern Lisp_Object composition_gstring_put_cache (Lisp_Object, ptrdiff_t); | 317 | extern Lisp_Object composition_gstring_put_cache (Lisp_Object, ptrdiff_t); |
| 320 | extern Lisp_Object composition_gstring_from_id (ptrdiff_t); | 318 | extern Lisp_Object composition_gstring_from_id (ptrdiff_t); |
| 321 | extern bool composition_gstring_p (Lisp_Object); | 319 | extern bool composition_gstring_p (Lisp_Object); |
diff --git a/src/data.c b/src/data.c index d1e43ac1b5f..9f4bd1f1c02 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -981,19 +981,14 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva | |||
| 981 | - (char *) &buffer_defaults); | 981 | - (char *) &buffer_defaults); |
| 982 | int idx = PER_BUFFER_IDX (offset); | 982 | int idx = PER_BUFFER_IDX (offset); |
| 983 | 983 | ||
| 984 | Lisp_Object tail; | 984 | Lisp_Object tail, buf; |
| 985 | 985 | ||
| 986 | if (idx <= 0) | 986 | if (idx <= 0) |
| 987 | break; | 987 | break; |
| 988 | 988 | ||
| 989 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 989 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 990 | { | 990 | { |
| 991 | Lisp_Object lbuf; | 991 | struct buffer *b = XBUFFER (buf); |
| 992 | struct buffer *b; | ||
| 993 | |||
| 994 | lbuf = Fcdr (XCAR (tail)); | ||
| 995 | if (!BUFFERP (lbuf)) continue; | ||
| 996 | b = XBUFFER (lbuf); | ||
| 997 | 992 | ||
| 998 | if (! PER_BUFFER_VALUE_P (b, idx)) | 993 | if (! PER_BUFFER_VALUE_P (b, idx)) |
| 999 | set_per_buffer_value (b, offset, newval); | 994 | set_per_buffer_value (b, offset, newval); |
| @@ -1980,7 +1975,7 @@ If the current binding is global (the default), the value is nil. */) | |||
| 1980 | { | 1975 | { |
| 1981 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); | 1976 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); |
| 1982 | if (KBOARD_OBJFWDP (valcontents)) | 1977 | if (KBOARD_OBJFWDP (valcontents)) |
| 1983 | return Fframe_terminal (Fselected_frame ()); | 1978 | return Fframe_terminal (selected_frame); |
| 1984 | else if (!BUFFER_OBJFWDP (valcontents)) | 1979 | else if (!BUFFER_OBJFWDP (valcontents)) |
| 1985 | return Qnil; | 1980 | return Qnil; |
| 1986 | } | 1981 | } |
diff --git a/src/decompress.c b/src/decompress.c new file mode 100644 index 00000000000..dc9f4b72d93 --- /dev/null +++ b/src/decompress.c | |||
| @@ -0,0 +1,232 @@ | |||
| 1 | /* Interface to zlib. | ||
| 2 | Copyright (C) 2013 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation, either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | #ifdef HAVE_ZLIB | ||
| 22 | |||
| 23 | #include <zlib.h> | ||
| 24 | |||
| 25 | #include "lisp.h" | ||
| 26 | #include "character.h" | ||
| 27 | #include "buffer.h" | ||
| 28 | |||
| 29 | #include <verify.h> | ||
| 30 | |||
| 31 | static Lisp_Object Qzlib_dll; | ||
| 32 | |||
| 33 | #ifdef WINDOWSNT | ||
| 34 | #include <windows.h> | ||
| 35 | #include "w32.h" | ||
| 36 | |||
| 37 | /* Macro for defining functions that will be loaded from the zlib DLL. */ | ||
| 38 | #define DEF_ZLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args | ||
| 39 | |||
| 40 | /* Macro for loading zlib functions from the library. */ | ||
| 41 | #define LOAD_ZLIB_FN(lib,func) { \ | ||
| 42 | fn_##func = (void *) GetProcAddress (lib, #func); \ | ||
| 43 | if (!fn_##func) return false; \ | ||
| 44 | } | ||
| 45 | |||
| 46 | DEF_ZLIB_FN (int, inflateInit2_, | ||
| 47 | (z_streamp strm, int windowBits, const char *version, int stream_size)); | ||
| 48 | |||
| 49 | DEF_ZLIB_FN (int, inflate, | ||
| 50 | (z_streamp strm, int flush)); | ||
| 51 | |||
| 52 | DEF_ZLIB_FN (int, inflateEnd, | ||
| 53 | (z_streamp strm)); | ||
| 54 | |||
| 55 | static bool zlib_initialized; | ||
| 56 | |||
| 57 | static bool | ||
| 58 | init_zlib_functions (void) | ||
| 59 | { | ||
| 60 | HMODULE library = w32_delayed_load (Qzlib_dll); | ||
| 61 | |||
| 62 | if (!library) | ||
| 63 | { | ||
| 64 | message1 ("zlib library not found"); | ||
| 65 | return false; | ||
| 66 | } | ||
| 67 | |||
| 68 | LOAD_ZLIB_FN (library, inflateInit2_); | ||
| 69 | LOAD_ZLIB_FN (library, inflate); | ||
| 70 | LOAD_ZLIB_FN (library, inflateEnd); | ||
| 71 | return true; | ||
| 72 | } | ||
| 73 | |||
| 74 | #define fn_inflateInit2(strm, windowBits) \ | ||
| 75 | fn_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) | ||
| 76 | |||
| 77 | #else /* !WINDOWSNT */ | ||
| 78 | |||
| 79 | #define fn_inflateInit2 inflateInit2 | ||
| 80 | #define fn_inflate inflate | ||
| 81 | #define fn_inflateEnd inflateEnd | ||
| 82 | |||
| 83 | #endif /* WINDOWSNT */ | ||
| 84 | |||
| 85 | |||
| 86 | struct decompress_unwind_data | ||
| 87 | { | ||
| 88 | ptrdiff_t old_point, start, nbytes; | ||
| 89 | z_stream *stream; | ||
| 90 | }; | ||
| 91 | |||
| 92 | static void | ||
| 93 | unwind_decompress (void *ddata) | ||
| 94 | { | ||
| 95 | struct decompress_unwind_data *data = ddata; | ||
| 96 | fn_inflateEnd (data->stream); | ||
| 97 | |||
| 98 | /* Delete any uncompressed data already inserted on error. */ | ||
| 99 | if (data->start) | ||
| 100 | del_range (data->start, data->start + data->nbytes); | ||
| 101 | |||
| 102 | /* Put point where it was, or if the buffer has shrunk because the | ||
| 103 | compressed data is bigger than the uncompressed, at | ||
| 104 | point-max. */ | ||
| 105 | SET_PT (min (data->old_point, ZV)); | ||
| 106 | } | ||
| 107 | |||
| 108 | DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, | ||
| 109 | doc: /* Return t if zlib decompression is available in this instance of Emacs. */) | ||
| 110 | (void) | ||
| 111 | { | ||
| 112 | #ifdef WINDOWSNT | ||
| 113 | Lisp_Object found = Fassq (Qzlib_dll, Vlibrary_cache); | ||
| 114 | if (CONSP (found)) | ||
| 115 | return XCDR (found); | ||
| 116 | else | ||
| 117 | { | ||
| 118 | Lisp_Object status; | ||
| 119 | zlib_initialized = init_zlib_functions (); | ||
| 120 | status = zlib_initialized ? Qt : Qnil; | ||
| 121 | Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache); | ||
| 122 | return status; | ||
| 123 | } | ||
| 124 | #else | ||
| 125 | return Qt; | ||
| 126 | #endif | ||
| 127 | } | ||
| 128 | |||
| 129 | DEFUN ("zlib-decompress-region", Fzlib_decompress_region, | ||
| 130 | Szlib_decompress_region, | ||
| 131 | 2, 2, 0, | ||
| 132 | doc: /* Decompress a gzip- or zlib-compressed region. | ||
| 133 | Replace the text in the region by the decompressed data. | ||
| 134 | On failure, return nil and leave the data in place. | ||
| 135 | This function can be called only in unibyte buffers. */) | ||
| 136 | (Lisp_Object start, Lisp_Object end) | ||
| 137 | { | ||
| 138 | ptrdiff_t istart, iend, pos_byte; | ||
| 139 | z_stream stream; | ||
| 140 | int inflate_status; | ||
| 141 | struct decompress_unwind_data unwind_data; | ||
| 142 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 143 | |||
| 144 | validate_region (&start, &end); | ||
| 145 | |||
| 146 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) | ||
| 147 | error ("This function can be called only in unibyte buffers"); | ||
| 148 | |||
| 149 | #ifdef WINDOWSNT | ||
| 150 | if (!zlib_initialized) | ||
| 151 | zlib_initialized = init_zlib_functions (); | ||
| 152 | if (!zlib_initialized) | ||
| 153 | return Qnil; | ||
| 154 | #endif | ||
| 155 | |||
| 156 | /* This is a unibyte buffer, so character positions and bytes are | ||
| 157 | the same. */ | ||
| 158 | istart = XINT (start); | ||
| 159 | iend = XINT (end); | ||
| 160 | move_gap_both (iend, iend); | ||
| 161 | |||
| 162 | stream.zalloc = Z_NULL; | ||
| 163 | stream.zfree = Z_NULL; | ||
| 164 | stream.opaque = Z_NULL; | ||
| 165 | stream.avail_in = 0; | ||
| 166 | stream.next_in = Z_NULL; | ||
| 167 | |||
| 168 | /* The magic number 32 apparently means "autodetect both the gzip and | ||
| 169 | zlib formats" according to zlib.h. */ | ||
| 170 | if (fn_inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) | ||
| 171 | return Qnil; | ||
| 172 | |||
| 173 | unwind_data.start = iend; | ||
| 174 | unwind_data.stream = &stream; | ||
| 175 | unwind_data.old_point = PT; | ||
| 176 | unwind_data.nbytes = 0; | ||
| 177 | record_unwind_protect_ptr (unwind_decompress, &unwind_data); | ||
| 178 | |||
| 179 | /* Insert the decompressed data at the end of the compressed data. */ | ||
| 180 | SET_PT (iend); | ||
| 181 | |||
| 182 | pos_byte = istart; | ||
| 183 | |||
| 184 | /* Keep calling 'inflate' until it reports an error or end-of-input. */ | ||
| 185 | do | ||
| 186 | { | ||
| 187 | /* Maximum number of bytes that one 'inflate' call should read and write. | ||
| 188 | Do not make avail_out too large, as that might unduly delay C-g. | ||
| 189 | zlib requires that avail_in and avail_out not exceed UINT_MAX. */ | ||
| 190 | ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); | ||
| 191 | int avail_out = 16 * 1024; | ||
| 192 | int decompressed; | ||
| 193 | |||
| 194 | if (GAP_SIZE < avail_out) | ||
| 195 | make_gap (avail_out - GAP_SIZE); | ||
| 196 | stream.next_in = BYTE_POS_ADDR (pos_byte); | ||
| 197 | stream.avail_in = avail_in; | ||
| 198 | stream.next_out = GPT_ADDR; | ||
| 199 | stream.avail_out = avail_out; | ||
| 200 | inflate_status = fn_inflate (&stream, Z_NO_FLUSH); | ||
| 201 | pos_byte += avail_in - stream.avail_in; | ||
| 202 | decompressed = avail_out - stream.avail_out; | ||
| 203 | insert_from_gap (decompressed, decompressed, 0); | ||
| 204 | unwind_data.nbytes += decompressed; | ||
| 205 | QUIT; | ||
| 206 | } | ||
| 207 | while (inflate_status == Z_OK); | ||
| 208 | |||
| 209 | if (inflate_status != Z_STREAM_END) | ||
| 210 | return unbind_to (count, Qnil); | ||
| 211 | |||
| 212 | unwind_data.start = 0; | ||
| 213 | |||
| 214 | /* Delete the compressed data. */ | ||
| 215 | del_range (istart, iend); | ||
| 216 | |||
| 217 | return unbind_to (count, Qt); | ||
| 218 | } | ||
| 219 | |||
| 220 | |||
| 221 | /*********************************************************************** | ||
| 222 | Initialization | ||
| 223 | ***********************************************************************/ | ||
| 224 | void | ||
| 225 | syms_of_decompress (void) | ||
| 226 | { | ||
| 227 | DEFSYM (Qzlib_dll, "zlib"); | ||
| 228 | defsubr (&Szlib_decompress_region); | ||
| 229 | defsubr (&Szlib_available_p); | ||
| 230 | } | ||
| 231 | |||
| 232 | #endif /* HAVE_ZLIB */ | ||
diff --git a/src/dispextern.h b/src/dispextern.h index d747700fd66..947e50fa4dd 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -83,7 +83,7 @@ typedef XImagePtr XImagePtr_or_DC; | |||
| 83 | #endif | 83 | #endif |
| 84 | 84 | ||
| 85 | #ifdef HAVE_WINDOW_SYSTEM | 85 | #ifdef HAVE_WINDOW_SYSTEM |
| 86 | # include "systime.h" | 86 | # include <time.h> |
| 87 | #endif | 87 | #endif |
| 88 | 88 | ||
| 89 | #ifndef HAVE_WINDOW_SYSTEM | 89 | #ifndef HAVE_WINDOW_SYSTEM |
| @@ -95,18 +95,17 @@ typedef int Cursor; | |||
| 95 | #define NativeRectangle int | 95 | #define NativeRectangle int |
| 96 | #endif | 96 | #endif |
| 97 | 97 | ||
| 98 | /* Structure forward declarations. Some are here because function | 98 | /* Text cursor types. */ |
| 99 | prototypes below reference structure types before their definition | ||
| 100 | in this file. Some are here because not every file including | ||
| 101 | dispextern.h also includes frame.h and windows.h. */ | ||
| 102 | |||
| 103 | struct glyph; | ||
| 104 | struct glyph_row; | ||
| 105 | struct glyph_matrix; | ||
| 106 | struct glyph_pool; | ||
| 107 | struct frame; | ||
| 108 | struct window; | ||
| 109 | 99 | ||
| 100 | enum text_cursor_kinds | ||
| 101 | { | ||
| 102 | DEFAULT_CURSOR = -2, | ||
| 103 | NO_CURSOR = -1, | ||
| 104 | FILLED_BOX_CURSOR, | ||
| 105 | HOLLOW_BOX_CURSOR, | ||
| 106 | BAR_CURSOR, | ||
| 107 | HBAR_CURSOR | ||
| 108 | }; | ||
| 110 | 109 | ||
| 111 | /* Values returned from coordinates_in_window. */ | 110 | /* Values returned from coordinates_in_window. */ |
| 112 | 111 | ||
| @@ -224,8 +223,16 @@ struct text_pos | |||
| 224 | /* Set text position POS from marker MARKER. */ | 223 | /* Set text position POS from marker MARKER. */ |
| 225 | 224 | ||
| 226 | #define SET_TEXT_POS_FROM_MARKER(POS, MARKER) \ | 225 | #define SET_TEXT_POS_FROM_MARKER(POS, MARKER) \ |
| 227 | (CHARPOS (POS) = marker_position ((MARKER)), \ | 226 | (CHARPOS (POS) = marker_position (MARKER), \ |
| 228 | BYTEPOS (POS) = marker_byte_position ((MARKER))) | 227 | BYTEPOS (POS) = marker_byte_position (MARKER)) |
| 228 | |||
| 229 | /* Like above, but clip POS within accessible range. */ | ||
| 230 | |||
| 231 | #define CLIP_TEXT_POS_FROM_MARKER(POS, MARKER) \ | ||
| 232 | (CHARPOS (POS) = clip_to_bounds \ | ||
| 233 | (BEGV, marker_position (MARKER), ZV), \ | ||
| 234 | BYTEPOS (POS) = clip_to_bounds \ | ||
| 235 | (BEGV_BYTE, marker_byte_position (MARKER), ZV_BYTE)) | ||
| 229 | 236 | ||
| 230 | /* Set marker MARKER from text position POS. */ | 237 | /* Set marker MARKER from text position POS. */ |
| 231 | 238 | ||
| @@ -752,11 +759,12 @@ void check_matrix_pointer_lossage (struct glyph_matrix *); | |||
| 752 | Glyph Rows | 759 | Glyph Rows |
| 753 | ***********************************************************************/ | 760 | ***********************************************************************/ |
| 754 | 761 | ||
| 755 | /* Area in window glyph matrix. If values are added or removed, the | 762 | /* Area in window glyph matrix. If values are added or removed, |
| 756 | function mark_object in alloc.c has to be changed. */ | 763 | the function mark_glyph_matrix in alloc.c may need to be changed. */ |
| 757 | 764 | ||
| 758 | enum glyph_row_area | 765 | enum glyph_row_area |
| 759 | { | 766 | { |
| 767 | ANY_AREA = -1, | ||
| 760 | LEFT_MARGIN_AREA, | 768 | LEFT_MARGIN_AREA, |
| 761 | TEXT_AREA, | 769 | TEXT_AREA, |
| 762 | RIGHT_MARGIN_AREA, | 770 | RIGHT_MARGIN_AREA, |
| @@ -1197,16 +1205,6 @@ extern bool fonts_changed_p; | |||
| 1197 | 1205 | ||
| 1198 | extern struct glyph space_glyph; | 1206 | extern struct glyph space_glyph; |
| 1199 | 1207 | ||
| 1200 | /* Window being updated by update_window. This is non-null as long as | ||
| 1201 | update_window has not finished, and null otherwise. */ | ||
| 1202 | |||
| 1203 | extern struct window *updated_window; | ||
| 1204 | |||
| 1205 | /* Glyph row and area updated by update_window_line. */ | ||
| 1206 | |||
| 1207 | extern struct glyph_row *updated_row; | ||
| 1208 | extern int updated_area; | ||
| 1209 | |||
| 1210 | /* Non-zero means last display completed. Zero means it was | 1208 | /* Non-zero means last display completed. Zero means it was |
| 1211 | preempted. */ | 1209 | preempted. */ |
| 1212 | 1210 | ||
| @@ -2678,8 +2676,57 @@ enum move_operation_enum | |||
| 2678 | MOVE_TO_POS = 0x08 | 2676 | MOVE_TO_POS = 0x08 |
| 2679 | }; | 2677 | }; |
| 2680 | 2678 | ||
| 2679 | /*********************************************************************** | ||
| 2680 | Mouse Highlight | ||
| 2681 | ***********************************************************************/ | ||
| 2682 | |||
| 2683 | /* Structure to hold mouse highlight data. */ | ||
| 2684 | |||
| 2685 | typedef struct { | ||
| 2686 | /* These variables describe the range of text currently shown in its | ||
| 2687 | mouse-face, together with the window they apply to. As long as | ||
| 2688 | the mouse stays within this range, we need not redraw anything on | ||
| 2689 | its account. Rows and columns are glyph matrix positions in | ||
| 2690 | MOUSE_FACE_WINDOW. */ | ||
| 2691 | int mouse_face_beg_row, mouse_face_beg_col, mouse_face_beg_x; | ||
| 2692 | int mouse_face_end_row, mouse_face_end_col, mouse_face_end_x; | ||
| 2693 | Lisp_Object mouse_face_window; | ||
| 2694 | int mouse_face_face_id; | ||
| 2695 | Lisp_Object mouse_face_overlay; | ||
| 2696 | |||
| 2697 | /* FRAME and X, Y position of mouse when last checked for | ||
| 2698 | highlighting. X and Y can be negative or out of range for the frame. */ | ||
| 2699 | struct frame *mouse_face_mouse_frame; | ||
| 2700 | int mouse_face_mouse_x, mouse_face_mouse_y; | ||
| 2701 | |||
| 2702 | /* Nonzero if part of the text currently shown in | ||
| 2703 | its mouse-face is beyond the window end. */ | ||
| 2704 | unsigned mouse_face_past_end : 1; | ||
| 2705 | |||
| 2706 | /* Nonzero means defer mouse-motion highlighting. */ | ||
| 2707 | unsigned mouse_face_defer : 1; | ||
| 2708 | |||
| 2709 | /* Nonzero means that the mouse highlight should not be shown. */ | ||
| 2710 | unsigned mouse_face_hidden : 1; | ||
| 2711 | } Mouse_HLInfo; | ||
| 2712 | |||
| 2713 | DISPEXTERN_INLINE void | ||
| 2714 | reset_mouse_highlight (Mouse_HLInfo *hlinfo) | ||
| 2715 | { | ||
| 2716 | |||
| 2717 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 2718 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 2719 | hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; | ||
| 2720 | hlinfo->mouse_face_beg_x = hlinfo->mouse_face_end_x = 0; | ||
| 2721 | hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; | ||
| 2722 | hlinfo->mouse_face_mouse_frame = NULL; | ||
| 2723 | hlinfo->mouse_face_window = Qnil; | ||
| 2724 | hlinfo->mouse_face_overlay = Qnil; | ||
| 2725 | hlinfo->mouse_face_past_end = 0; | ||
| 2726 | hlinfo->mouse_face_hidden = 0; | ||
| 2727 | hlinfo->mouse_face_defer = 0; | ||
| 2728 | } | ||
| 2681 | 2729 | ||
| 2682 | |||
| 2683 | /*********************************************************************** | 2730 | /*********************************************************************** |
| 2684 | Window-based redisplay interface | 2731 | Window-based redisplay interface |
| 2685 | ***********************************************************************/ | 2732 | ***********************************************************************/ |
| @@ -2718,12 +2765,17 @@ struct redisplay_interface | |||
| 2718 | 2765 | ||
| 2719 | /* Write or insert LEN glyphs from STRING at the nominal output | 2766 | /* Write or insert LEN glyphs from STRING at the nominal output |
| 2720 | position. */ | 2767 | position. */ |
| 2721 | void (*write_glyphs) (struct glyph *string, int len); | 2768 | void (*write_glyphs) (struct window *w, struct glyph_row *row, |
| 2722 | void (*insert_glyphs) (struct glyph *start, int len); | 2769 | struct glyph *string, enum glyph_row_area area, |
| 2770 | int len); | ||
| 2771 | void (*insert_glyphs) (struct window *w, struct glyph_row *row, | ||
| 2772 | struct glyph *start, enum glyph_row_area area, | ||
| 2773 | int len); | ||
| 2723 | 2774 | ||
| 2724 | /* Clear from nominal output position to X. X < 0 means clear | 2775 | /* Clear from nominal output position to X. X < 0 means clear |
| 2725 | to right end of display. */ | 2776 | to right end of display. */ |
| 2726 | void (*clear_end_of_line) (int x); | 2777 | void (*clear_end_of_line) (struct window *w, struct glyph_row *row, |
| 2778 | enum glyph_row_area area, int x); | ||
| 2727 | 2779 | ||
| 2728 | /* Function to call to scroll the display as described by RUN on | 2780 | /* Function to call to scroll the display as described by RUN on |
| 2729 | window W. */ | 2781 | window W. */ |
| @@ -2732,7 +2784,8 @@ struct redisplay_interface | |||
| 2732 | /* Function to call after a line in a display has been completely | 2784 | /* Function to call after a line in a display has been completely |
| 2733 | updated. Used to draw truncation marks and alike. DESIRED_ROW | 2785 | updated. Used to draw truncation marks and alike. DESIRED_ROW |
| 2734 | is the desired row which has been updated. */ | 2786 | is the desired row which has been updated. */ |
| 2735 | void (*after_update_window_line_hook) (struct glyph_row *desired_row); | 2787 | void (*after_update_window_line_hook) (struct window *w, |
| 2788 | struct glyph_row *desired_row); | ||
| 2736 | 2789 | ||
| 2737 | /* Function to call before beginning to update window W in | 2790 | /* Function to call before beginning to update window W in |
| 2738 | window-based redisplay. */ | 2791 | window-based redisplay. */ |
| @@ -2743,13 +2796,8 @@ struct redisplay_interface | |||
| 2743 | MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W | 2796 | MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W |
| 2744 | that contained glyphs in mouse-face were overwritten, so we | 2797 | that contained glyphs in mouse-face were overwritten, so we |
| 2745 | have to update the mouse highlight. */ | 2798 | have to update the mouse highlight. */ |
| 2746 | void (*update_window_end_hook) (struct window *w, int cursor_on_p, | 2799 | void (*update_window_end_hook) (struct window *w, bool cursor_on_p, |
| 2747 | int mouse_face_overwritten_p); | 2800 | bool mouse_face_overwritten_p); |
| 2748 | |||
| 2749 | /* Move cursor to row/column position VPOS/HPOS, pixel coordinates | ||
| 2750 | Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y | ||
| 2751 | are window-relative pixel positions. */ | ||
| 2752 | void (*cursor_to) (int vpos, int hpos, int y, int x); | ||
| 2753 | 2801 | ||
| 2754 | /* Flush the display of frame F. For X, this is XFlush. */ | 2802 | /* Flush the display of frame F. For X, this is XFlush. */ |
| 2755 | void (*flush_display) (struct frame *f); | 2803 | void (*flush_display) (struct frame *f); |
| @@ -2803,10 +2851,10 @@ struct redisplay_interface | |||
| 2803 | 0, don't draw cursor. If ACTIVE_P is 1, system caret | 2851 | 0, don't draw cursor. If ACTIVE_P is 1, system caret |
| 2804 | should track this cursor (when applicable). */ | 2852 | should track this cursor (when applicable). */ |
| 2805 | void (*draw_window_cursor) (struct window *w, | 2853 | void (*draw_window_cursor) (struct window *w, |
| 2806 | struct glyph_row *glyph_row, | 2854 | struct glyph_row *glyph_row, |
| 2807 | int x, int y, | 2855 | int x, int y, |
| 2808 | int cursor_type, int cursor_width, | 2856 | enum text_cursor_kinds cursor_type, |
| 2809 | int on_p, int active_p); | 2857 | int cursor_width, bool on_p, bool active_p); |
| 2810 | 2858 | ||
| 2811 | /* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */ | 2859 | /* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */ |
| 2812 | void (*draw_vertical_window_border) (struct window *w, | 2860 | void (*draw_vertical_window_border) (struct window *w, |
| @@ -2829,11 +2877,6 @@ struct redisplay_interface | |||
| 2829 | 2877 | ||
| 2830 | #ifdef HAVE_WINDOW_SYSTEM | 2878 | #ifdef HAVE_WINDOW_SYSTEM |
| 2831 | 2879 | ||
| 2832 | /* Structure forward declarations. */ | ||
| 2833 | |||
| 2834 | struct image; | ||
| 2835 | |||
| 2836 | |||
| 2837 | /* Each image format (JPEG, TIFF, ...) supported is described by | 2880 | /* Each image format (JPEG, TIFF, ...) supported is described by |
| 2838 | a structure of the type below. */ | 2881 | a structure of the type below. */ |
| 2839 | 2882 | ||
| @@ -2870,7 +2913,7 @@ struct image | |||
| 2870 | { | 2913 | { |
| 2871 | /* The time in seconds at which the image was last displayed. Set | 2914 | /* The time in seconds at which the image was last displayed. Set |
| 2872 | in prepare_image_for_display. */ | 2915 | in prepare_image_for_display. */ |
| 2873 | EMACS_TIME timestamp; | 2916 | struct timespec timestamp; |
| 2874 | 2917 | ||
| 2875 | /* Pixmaps of the image. */ | 2918 | /* Pixmaps of the image. */ |
| 2876 | Pixmap pixmap, mask; | 2919 | Pixmap pixmap, mask; |
| @@ -3124,14 +3167,15 @@ int resize_mini_window (struct window *, int); | |||
| 3124 | void set_vertical_scroll_bar (struct window *); | 3167 | void set_vertical_scroll_bar (struct window *); |
| 3125 | #endif | 3168 | #endif |
| 3126 | int try_window (Lisp_Object, struct text_pos, int); | 3169 | int try_window (Lisp_Object, struct text_pos, int); |
| 3127 | void window_box (struct window *, int, int *, int *, int *, int *); | 3170 | void window_box (struct window *, enum glyph_row_area, |
| 3171 | int *, int *, int *, int *); | ||
| 3128 | int window_box_height (struct window *); | 3172 | int window_box_height (struct window *); |
| 3129 | int window_text_bottom_y (struct window *); | 3173 | int window_text_bottom_y (struct window *); |
| 3130 | int window_box_width (struct window *, int); | 3174 | int window_box_width (struct window *, enum glyph_row_area); |
| 3131 | int window_box_left (struct window *, int); | 3175 | int window_box_left (struct window *, enum glyph_row_area); |
| 3132 | int window_box_left_offset (struct window *, int); | 3176 | int window_box_left_offset (struct window *, enum glyph_row_area); |
| 3133 | int window_box_right (struct window *, int); | 3177 | int window_box_right (struct window *, enum glyph_row_area); |
| 3134 | int window_box_right_offset (struct window *, int); | 3178 | int window_box_right_offset (struct window *, enum glyph_row_area); |
| 3135 | int estimate_mode_line_height (struct frame *, enum face_id); | 3179 | int estimate_mode_line_height (struct frame *, enum face_id); |
| 3136 | void pixel_to_glyph_coords (struct frame *, int, int, int *, int *, | 3180 | void pixel_to_glyph_coords (struct frame *, int, int, int *, int *, |
| 3137 | NativeRectangle *, int); | 3181 | NativeRectangle *, int); |
| @@ -3182,12 +3226,12 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *, | |||
| 3182 | int *, int *); | 3226 | int *, int *); |
| 3183 | extern void x_produce_glyphs (struct it *); | 3227 | extern void x_produce_glyphs (struct it *); |
| 3184 | 3228 | ||
| 3185 | extern void x_write_glyphs (struct glyph *, int); | 3229 | extern void x_write_glyphs (struct window *, struct glyph_row *, |
| 3186 | extern void x_insert_glyphs (struct glyph *, int len); | 3230 | struct glyph *, enum glyph_row_area, int); |
| 3187 | extern void x_clear_end_of_line (int); | 3231 | extern void x_insert_glyphs (struct window *, struct glyph_row *, |
| 3188 | 3232 | struct glyph *, enum glyph_row_area, int); | |
| 3189 | extern struct cursor_pos output_cursor; | 3233 | extern void x_clear_end_of_line (struct window *, struct glyph_row *, |
| 3190 | 3234 | enum glyph_row_area, int); | |
| 3191 | extern void x_fix_overlapping_area (struct window *, struct glyph_row *, | 3235 | extern void x_fix_overlapping_area (struct window *, struct glyph_row *, |
| 3192 | enum glyph_row_area, int); | 3236 | enum glyph_row_area, int); |
| 3193 | extern void draw_phys_cursor_glyph (struct window *, | 3237 | extern void draw_phys_cursor_glyph (struct window *, |
| @@ -3196,13 +3240,8 @@ extern void draw_phys_cursor_glyph (struct window *, | |||
| 3196 | extern void get_phys_cursor_geometry (struct window *, struct glyph_row *, | 3240 | extern void get_phys_cursor_geometry (struct window *, struct glyph_row *, |
| 3197 | struct glyph *, int *, int *, int *); | 3241 | struct glyph *, int *, int *, int *); |
| 3198 | extern void erase_phys_cursor (struct window *); | 3242 | extern void erase_phys_cursor (struct window *); |
| 3199 | extern void display_and_set_cursor (struct window *, | 3243 | extern void display_and_set_cursor (struct window *, bool, int, int, int, int); |
| 3200 | int, int, int, int, int); | 3244 | extern void x_update_cursor (struct frame *, bool); |
| 3201 | |||
| 3202 | extern void set_output_cursor (struct cursor_pos *); | ||
| 3203 | extern void x_cursor_to (int, int, int, int); | ||
| 3204 | |||
| 3205 | extern void x_update_cursor (struct frame *, int); | ||
| 3206 | extern void x_clear_cursor (struct window *); | 3245 | extern void x_clear_cursor (struct window *); |
| 3207 | extern void x_draw_vertical_border (struct window *w); | 3246 | extern void x_draw_vertical_border (struct window *w); |
| 3208 | 3247 | ||
| @@ -3365,8 +3404,6 @@ extern frame_parm_handler x_frame_parm_handlers[]; | |||
| 3365 | extern void start_hourglass (void); | 3404 | extern void start_hourglass (void); |
| 3366 | extern void cancel_hourglass (void); | 3405 | extern void cancel_hourglass (void); |
| 3367 | extern int hourglass_shown_p; | 3406 | extern int hourglass_shown_p; |
| 3368 | |||
| 3369 | struct atimer; /* Defined in atimer.h. */ | ||
| 3370 | /* If non-null, an asynchronous timer that, when it expires, displays | 3407 | /* If non-null, an asynchronous timer that, when it expires, displays |
| 3371 | an hourglass cursor on all frames. */ | 3408 | an hourglass cursor on all frames. */ |
| 3372 | extern struct atimer *hourglass_atimer; | 3409 | extern struct atimer *hourglass_atimer; |
diff --git a/src/dispnew.c b/src/dispnew.c index 522a0e6a30d..1d7cad13e6d 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -49,12 +49,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 49 | #include TERM_HEADER | 49 | #include TERM_HEADER |
| 50 | #endif /* HAVE_WINDOW_SYSTEM */ | 50 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 51 | 51 | ||
| 52 | /* Include systime.h after xterm.h to avoid double inclusion of time.h. */ | ||
| 53 | |||
| 54 | #include "systime.h" | ||
| 55 | #include <errno.h> | 52 | #include <errno.h> |
| 56 | 53 | ||
| 57 | #include <fpending.h> | 54 | #include <fpending.h> |
| 55 | #include <timespec.h> | ||
| 58 | 56 | ||
| 59 | #if defined (HAVE_TERM_H) && defined (GNU_LINUX) | 57 | #if defined (HAVE_TERM_H) && defined (GNU_LINUX) |
| 60 | #include <term.h> /* for tgetent */ | 58 | #include <term.h> /* for tgetent */ |
| @@ -135,25 +133,20 @@ struct frame *last_nonminibuf_frame; | |||
| 135 | 133 | ||
| 136 | static bool delayed_size_change; | 134 | static bool delayed_size_change; |
| 137 | 135 | ||
| 138 | /* Updated window if != 0. Set by update_window. */ | ||
| 139 | |||
| 140 | struct window *updated_window; | ||
| 141 | |||
| 142 | /* Glyph row updated in update_window_line, and area that is updated. */ | ||
| 143 | |||
| 144 | struct glyph_row *updated_row; | ||
| 145 | int updated_area; | ||
| 146 | |||
| 147 | /* A glyph for a space. */ | 136 | /* A glyph for a space. */ |
| 148 | 137 | ||
| 149 | struct glyph space_glyph; | 138 | struct glyph space_glyph; |
| 150 | 139 | ||
| 140 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 141 | |||
| 151 | /* Counts of allocated structures. These counts serve to diagnose | 142 | /* Counts of allocated structures. These counts serve to diagnose |
| 152 | memory leaks and double frees. */ | 143 | memory leaks and double frees. */ |
| 153 | 144 | ||
| 154 | static int glyph_matrix_count; | 145 | static int glyph_matrix_count; |
| 155 | static int glyph_pool_count; | 146 | static int glyph_pool_count; |
| 156 | 147 | ||
| 148 | #endif /* GLYPH_DEBUG and ENABLE_CHECKING */ | ||
| 149 | |||
| 157 | /* If non-null, the frame whose frame matrices are manipulated. If | 150 | /* If non-null, the frame whose frame matrices are manipulated. If |
| 158 | null, window matrices are worked on. */ | 151 | null, window matrices are worked on. */ |
| 159 | 152 | ||
| @@ -307,9 +300,11 @@ new_glyph_matrix (struct glyph_pool *pool) | |||
| 307 | { | 300 | { |
| 308 | struct glyph_matrix *result = xzalloc (sizeof *result); | 301 | struct glyph_matrix *result = xzalloc (sizeof *result); |
| 309 | 302 | ||
| 303 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 310 | /* Increment number of allocated matrices. This count is used | 304 | /* Increment number of allocated matrices. This count is used |
| 311 | to detect memory leaks. */ | 305 | to detect memory leaks. */ |
| 312 | ++glyph_matrix_count; | 306 | ++glyph_matrix_count; |
| 307 | #endif | ||
| 313 | 308 | ||
| 314 | /* Set pool and return. */ | 309 | /* Set pool and return. */ |
| 315 | result->pool = pool; | 310 | result->pool = pool; |
| @@ -319,10 +314,10 @@ new_glyph_matrix (struct glyph_pool *pool) | |||
| 319 | 314 | ||
| 320 | /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed. | 315 | /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed. |
| 321 | 316 | ||
| 322 | The global counter glyph_matrix_count is decremented when a matrix | 317 | If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global counter |
| 323 | is freed. If the count gets negative, more structures were freed | 318 | glyph_matrix_count is decremented when a matrix is freed. If the count |
| 324 | than allocated, i.e. one matrix was freed more than once or a bogus | 319 | gets negative, more structures were freed than allocated, i.e. one matrix |
| 325 | pointer was passed to this function. | 320 | was freed more than once or a bogus pointer was passed to this function. |
| 326 | 321 | ||
| 327 | If MATRIX->pool is null, this means that the matrix manages its own | 322 | If MATRIX->pool is null, this means that the matrix manages its own |
| 328 | glyph memory---this is done for matrices on X frames. Freeing the | 323 | glyph memory---this is done for matrices on X frames. Freeing the |
| @@ -335,10 +330,12 @@ free_glyph_matrix (struct glyph_matrix *matrix) | |||
| 335 | { | 330 | { |
| 336 | int i; | 331 | int i; |
| 337 | 332 | ||
| 333 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 338 | /* Detect the case that more matrices are freed than were | 334 | /* Detect the case that more matrices are freed than were |
| 339 | allocated. */ | 335 | allocated. */ |
| 340 | if (--glyph_matrix_count < 0) | 336 | --glyph_matrix_count; |
| 341 | emacs_abort (); | 337 | eassert (glyph_matrix_count >= 0); |
| 338 | #endif | ||
| 342 | 339 | ||
| 343 | /* Free glyph memory if MATRIX owns it. */ | 340 | /* Free glyph memory if MATRIX owns it. */ |
| 344 | if (matrix->pool == NULL) | 341 | if (matrix->pool == NULL) |
| @@ -355,25 +352,19 @@ free_glyph_matrix (struct glyph_matrix *matrix) | |||
| 355 | /* Return the number of glyphs to reserve for a marginal area of | 352 | /* Return the number of glyphs to reserve for a marginal area of |
| 356 | window W. TOTAL_GLYPHS is the number of glyphs in a complete | 353 | window W. TOTAL_GLYPHS is the number of glyphs in a complete |
| 357 | display line of window W. MARGIN gives the width of the marginal | 354 | display line of window W. MARGIN gives the width of the marginal |
| 358 | area in canonical character units. MARGIN should be an integer | 355 | area in canonical character units. */ |
| 359 | or a float. */ | ||
| 360 | 356 | ||
| 361 | static int | 357 | static int |
| 362 | margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin) | 358 | margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin) |
| 363 | { | 359 | { |
| 364 | int n; | 360 | if (margin > 0) |
| 365 | |||
| 366 | if (NUMBERP (margin)) | ||
| 367 | { | 361 | { |
| 368 | int width = w->total_cols; | 362 | int width = w->total_cols; |
| 369 | double d = max (0, XFLOATINT (margin)); | 363 | double d = max (0, margin); |
| 370 | d = min (width / 2 - 1, d); | 364 | d = min (width / 2 - 1, d); |
| 371 | n = (int) ((double) total_glyphs / width * d); | 365 | return (int) ((double) total_glyphs / width * d); |
| 372 | } | 366 | } |
| 373 | else | 367 | return 0; |
| 374 | n = 0; | ||
| 375 | |||
| 376 | return n; | ||
| 377 | } | 368 | } |
| 378 | 369 | ||
| 379 | /* Return true if ROW's hash value is correct. | 370 | /* Return true if ROW's hash value is correct. |
| @@ -422,7 +413,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y | |||
| 422 | Get W's size. */ | 413 | Get W's size. */ |
| 423 | if (w) | 414 | if (w) |
| 424 | { | 415 | { |
| 425 | window_box (w, -1, 0, 0, &window_width, &window_height); | 416 | window_box (w, ANY_AREA, 0, 0, &window_width, &window_height); |
| 426 | 417 | ||
| 427 | header_line_p = WINDOW_WANTS_HEADER_LINE_P (w); | 418 | header_line_p = WINDOW_WANTS_HEADER_LINE_P (w); |
| 428 | header_line_changed_p = header_line_p != matrix->header_line_p; | 419 | header_line_changed_p = header_line_p != matrix->header_line_p; |
| @@ -600,8 +591,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y | |||
| 600 | 591 | ||
| 601 | /* Window end is invalid, if inside of the rows that | 592 | /* Window end is invalid, if inside of the rows that |
| 602 | are invalidated below. */ | 593 | are invalidated below. */ |
| 603 | if (INTEGERP (w->window_end_vpos) | 594 | if (w->window_end_vpos >= i) |
| 604 | && XFASTINT (w->window_end_vpos) >= i) | ||
| 605 | w->window_end_valid = 0; | 595 | w->window_end_valid = 0; |
| 606 | 596 | ||
| 607 | while (i < matrix->nrows) | 597 | while (i < matrix->nrows) |
| @@ -1310,38 +1300,41 @@ row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p) | |||
| 1310 | See dispextern.h for an overall explanation of glyph pools. | 1300 | See dispextern.h for an overall explanation of glyph pools. |
| 1311 | ***********************************************************************/ | 1301 | ***********************************************************************/ |
| 1312 | 1302 | ||
| 1313 | /* Allocate a glyph_pool structure. The structure returned is | 1303 | /* Allocate a glyph_pool structure. The structure returned is initialized |
| 1314 | initialized with zeros. The global variable glyph_pool_count is | 1304 | with zeros. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global |
| 1315 | incremented for each pool allocated. */ | 1305 | variable glyph_pool_count is incremented for each pool allocated. */ |
| 1316 | 1306 | ||
| 1317 | static struct glyph_pool * | 1307 | static struct glyph_pool * |
| 1318 | new_glyph_pool (void) | 1308 | new_glyph_pool (void) |
| 1319 | { | 1309 | { |
| 1320 | struct glyph_pool *result = xzalloc (sizeof *result); | 1310 | struct glyph_pool *result = xzalloc (sizeof *result); |
| 1321 | 1311 | ||
| 1312 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 1322 | /* For memory leak and double deletion checking. */ | 1313 | /* For memory leak and double deletion checking. */ |
| 1323 | ++glyph_pool_count; | 1314 | ++glyph_pool_count; |
| 1315 | #endif | ||
| 1324 | 1316 | ||
| 1325 | return result; | 1317 | return result; |
| 1326 | } | 1318 | } |
| 1327 | 1319 | ||
| 1328 | 1320 | ||
| 1329 | /* Free a glyph_pool structure POOL. The function may be called with | 1321 | /* Free a glyph_pool structure POOL. The function may be called with |
| 1330 | a null POOL pointer. The global variable glyph_pool_count is | 1322 | a null POOL pointer. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, |
| 1331 | decremented with every pool structure freed. If this count gets | 1323 | global variable glyph_pool_count is decremented with every pool structure |
| 1332 | negative, more structures were freed than allocated, i.e. one | 1324 | freed. If this count gets negative, more structures were freed than |
| 1333 | structure must have been freed more than once or a bogus pointer | 1325 | allocated, i.e. one structure must have been freed more than once or |
| 1334 | was passed to free_glyph_pool. */ | 1326 | a bogus pointer was passed to free_glyph_pool. */ |
| 1335 | 1327 | ||
| 1336 | static void | 1328 | static void |
| 1337 | free_glyph_pool (struct glyph_pool *pool) | 1329 | free_glyph_pool (struct glyph_pool *pool) |
| 1338 | { | 1330 | { |
| 1339 | if (pool) | 1331 | if (pool) |
| 1340 | { | 1332 | { |
| 1333 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 1341 | /* More freed than allocated? */ | 1334 | /* More freed than allocated? */ |
| 1342 | --glyph_pool_count; | 1335 | --glyph_pool_count; |
| 1343 | eassert (glyph_pool_count >= 0); | 1336 | eassert (glyph_pool_count >= 0); |
| 1344 | 1337 | #endif | |
| 1345 | xfree (pool->glyphs); | 1338 | xfree (pool->glyphs); |
| 1346 | xfree (pool); | 1339 | xfree (pool); |
| 1347 | } | 1340 | } |
| @@ -1860,7 +1853,7 @@ showing_window_margins_p (struct window *w) | |||
| 1860 | if (showing_window_margins_p (XWINDOW (w->contents))) | 1853 | if (showing_window_margins_p (XWINDOW (w->contents))) |
| 1861 | return 1; | 1854 | return 1; |
| 1862 | } | 1855 | } |
| 1863 | else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols)) | 1856 | else if (w->left_margin_cols > 0 || w->right_margin_cols > 0) |
| 1864 | return 1; | 1857 | return 1; |
| 1865 | 1858 | ||
| 1866 | w = NILP (w->next) ? 0 : XWINDOW (w->next); | 1859 | w = NILP (w->next) ? 0 : XWINDOW (w->next); |
| @@ -2254,11 +2247,11 @@ check_glyph_memory (void) | |||
| 2254 | FOR_EACH_FRAME (tail, frame) | 2247 | FOR_EACH_FRAME (tail, frame) |
| 2255 | free_glyphs (XFRAME (frame)); | 2248 | free_glyphs (XFRAME (frame)); |
| 2256 | 2249 | ||
| 2250 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 2257 | /* Check that nothing is left allocated. */ | 2251 | /* Check that nothing is left allocated. */ |
| 2258 | if (glyph_matrix_count) | 2252 | eassert (glyph_matrix_count == 0); |
| 2259 | emacs_abort (); | 2253 | eassert (glyph_pool_count == 0); |
| 2260 | if (glyph_pool_count) | 2254 | #endif |
| 2261 | emacs_abort (); | ||
| 2262 | } | 2255 | } |
| 2263 | 2256 | ||
| 2264 | 2257 | ||
| @@ -2275,7 +2268,7 @@ check_glyph_memory (void) | |||
| 2275 | screen. We build such a view by constructing a frame matrix from | 2268 | screen. We build such a view by constructing a frame matrix from |
| 2276 | window matrices in this section. | 2269 | window matrices in this section. |
| 2277 | 2270 | ||
| 2278 | Windows that must be updated have their must_be_update_p flag set. | 2271 | Windows that must be updated have their must_be_updated_p flag set. |
| 2279 | For all such windows, their desired matrix is made part of the | 2272 | For all such windows, their desired matrix is made part of the |
| 2280 | desired frame matrix. For other windows, their current matrix is | 2273 | desired frame matrix. For other windows, their current matrix is |
| 2281 | made part of the desired frame matrix. | 2274 | made part of the desired frame matrix. |
| @@ -3230,14 +3223,12 @@ redraw_overlapped_rows (struct window *w, int yb) | |||
| 3230 | 3223 | ||
| 3231 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | 3224 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) |
| 3232 | { | 3225 | { |
| 3233 | updated_row = row; | 3226 | output_cursor_to (w, i, 0, row->y, |
| 3234 | updated_area = area; | 3227 | area == TEXT_AREA ? row->x : 0); |
| 3235 | FRAME_RIF (f)->cursor_to (i, 0, row->y, | ||
| 3236 | area == TEXT_AREA ? row->x : 0); | ||
| 3237 | if (row->used[area]) | 3228 | if (row->used[area]) |
| 3238 | FRAME_RIF (f)->write_glyphs (row->glyphs[area], | 3229 | FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area], |
| 3239 | row->used[area]); | 3230 | area, row->used[area]); |
| 3240 | FRAME_RIF (f)->clear_end_of_line (-1); | 3231 | FRAME_RIF (f)->clear_end_of_line (w, row, area, -1); |
| 3241 | } | 3232 | } |
| 3242 | 3233 | ||
| 3243 | row->overlapped_p = 0; | 3234 | row->overlapped_p = 0; |
| @@ -3490,7 +3481,7 @@ update_window (struct window *w, bool force_p) | |||
| 3490 | /* End the update of window W. Don't set the cursor if we | 3481 | /* End the update of window W. Don't set the cursor if we |
| 3491 | paused updating the display because in this case, | 3482 | paused updating the display because in this case, |
| 3492 | set_window_cursor_after_update hasn't been called, and | 3483 | set_window_cursor_after_update hasn't been called, and |
| 3493 | output_cursor doesn't contain the cursor location. */ | 3484 | W->output_cursor doesn't contain the cursor location. */ |
| 3494 | rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p); | 3485 | rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p); |
| 3495 | } | 3486 | } |
| 3496 | else | 3487 | else |
| @@ -3511,22 +3502,20 @@ update_window (struct window *w, bool force_p) | |||
| 3511 | AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */ | 3502 | AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */ |
| 3512 | 3503 | ||
| 3513 | static void | 3504 | static void |
| 3514 | update_marginal_area (struct window *w, int area, int vpos) | 3505 | update_marginal_area (struct window *w, struct glyph_row *updated_row, |
| 3506 | enum glyph_row_area area, int vpos) | ||
| 3515 | { | 3507 | { |
| 3516 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 3508 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
| 3517 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3509 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3518 | 3510 | ||
| 3519 | /* Let functions in xterm.c know what area subsequent X positions | ||
| 3520 | will be relative to. */ | ||
| 3521 | updated_area = area; | ||
| 3522 | |||
| 3523 | /* Set cursor to start of glyphs, write them, and clear to the end | 3511 | /* Set cursor to start of glyphs, write them, and clear to the end |
| 3524 | of the area. I don't think that something more sophisticated is | 3512 | of the area. I don't think that something more sophisticated is |
| 3525 | necessary here, since marginal areas will not be the default. */ | 3513 | necessary here, since marginal areas will not be the default. */ |
| 3526 | rif->cursor_to (vpos, 0, desired_row->y, 0); | 3514 | output_cursor_to (w, vpos, 0, desired_row->y, 0); |
| 3527 | if (desired_row->used[area]) | 3515 | if (desired_row->used[area]) |
| 3528 | rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]); | 3516 | rif->write_glyphs (w, updated_row, desired_row->glyphs[area], |
| 3529 | rif->clear_end_of_line (-1); | 3517 | area, desired_row->used[area]); |
| 3518 | rif->clear_end_of_line (w, updated_row, area, -1); | ||
| 3530 | } | 3519 | } |
| 3531 | 3520 | ||
| 3532 | 3521 | ||
| @@ -3534,17 +3523,13 @@ update_marginal_area (struct window *w, int area, int vpos) | |||
| 3534 | Value is true if display has changed. */ | 3523 | Value is true if display has changed. */ |
| 3535 | 3524 | ||
| 3536 | static bool | 3525 | static bool |
| 3537 | update_text_area (struct window *w, int vpos) | 3526 | update_text_area (struct window *w, struct glyph_row *updated_row, int vpos) |
| 3538 | { | 3527 | { |
| 3539 | struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); | 3528 | struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); |
| 3540 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 3529 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
| 3541 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3530 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3542 | bool changed_p = 0; | 3531 | bool changed_p = 0; |
| 3543 | 3532 | ||
| 3544 | /* Let functions in xterm.c know what area subsequent X positions | ||
| 3545 | will be relative to. */ | ||
| 3546 | updated_area = TEXT_AREA; | ||
| 3547 | |||
| 3548 | /* If rows are at different X or Y, or rows have different height, | 3533 | /* If rows are at different X or Y, or rows have different height, |
| 3549 | or the current row is marked invalid, write the entire line. */ | 3534 | or the current row is marked invalid, write the entire line. */ |
| 3550 | if (!current_row->enabled_p | 3535 | if (!current_row->enabled_p |
| @@ -3564,14 +3549,14 @@ update_text_area (struct window *w, int vpos) | |||
| 3564 | && !(current_row->mode_line_p && vpos > 0)) | 3549 | && !(current_row->mode_line_p && vpos > 0)) |
| 3565 | || current_row->x != desired_row->x) | 3550 | || current_row->x != desired_row->x) |
| 3566 | { | 3551 | { |
| 3567 | rif->cursor_to (vpos, 0, desired_row->y, desired_row->x); | 3552 | output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x); |
| 3568 | 3553 | ||
| 3569 | if (desired_row->used[TEXT_AREA]) | 3554 | if (desired_row->used[TEXT_AREA]) |
| 3570 | rif->write_glyphs (desired_row->glyphs[TEXT_AREA], | 3555 | rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA], |
| 3571 | desired_row->used[TEXT_AREA]); | 3556 | TEXT_AREA, desired_row->used[TEXT_AREA]); |
| 3572 | 3557 | ||
| 3573 | /* Clear to end of window. */ | 3558 | /* Clear to end of window. */ |
| 3574 | rif->clear_end_of_line (-1); | 3559 | rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1); |
| 3575 | changed_p = 1; | 3560 | changed_p = 1; |
| 3576 | 3561 | ||
| 3577 | /* This erases the cursor. We do this here because | 3562 | /* This erases the cursor. We do this here because |
| @@ -3707,8 +3692,9 @@ update_text_area (struct window *w, int vpos) | |||
| 3707 | break; | 3692 | break; |
| 3708 | } | 3693 | } |
| 3709 | 3694 | ||
| 3710 | rif->cursor_to (vpos, start_hpos, desired_row->y, start_x); | 3695 | output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x); |
| 3711 | rif->write_glyphs (start, i - start_hpos); | 3696 | rif->write_glyphs (w, updated_row, start, |
| 3697 | TEXT_AREA, i - start_hpos); | ||
| 3712 | changed_p = 1; | 3698 | changed_p = 1; |
| 3713 | } | 3699 | } |
| 3714 | } | 3700 | } |
| @@ -3716,8 +3702,9 @@ update_text_area (struct window *w, int vpos) | |||
| 3716 | /* Write the rest. */ | 3702 | /* Write the rest. */ |
| 3717 | if (i < desired_row->used[TEXT_AREA]) | 3703 | if (i < desired_row->used[TEXT_AREA]) |
| 3718 | { | 3704 | { |
| 3719 | rif->cursor_to (vpos, i, desired_row->y, x); | 3705 | output_cursor_to (w, vpos, i, desired_row->y, x); |
| 3720 | rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i); | 3706 | rif->write_glyphs (w, updated_row, desired_glyph, |
| 3707 | TEXT_AREA, desired_row->used[TEXT_AREA] - i); | ||
| 3721 | changed_p = 1; | 3708 | changed_p = 1; |
| 3722 | } | 3709 | } |
| 3723 | 3710 | ||
| @@ -3737,9 +3724,9 @@ update_text_area (struct window *w, int vpos) | |||
| 3737 | { | 3724 | { |
| 3738 | /* If old row extends to the end of the text area, clear. */ | 3725 | /* If old row extends to the end of the text area, clear. */ |
| 3739 | if (i >= desired_row->used[TEXT_AREA]) | 3726 | if (i >= desired_row->used[TEXT_AREA]) |
| 3740 | rif->cursor_to (vpos, i, desired_row->y, | 3727 | output_cursor_to (w, vpos, i, desired_row->y, |
| 3741 | desired_row->pixel_width); | 3728 | desired_row->pixel_width); |
| 3742 | rif->clear_end_of_line (-1); | 3729 | rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1); |
| 3743 | changed_p = 1; | 3730 | changed_p = 1; |
| 3744 | } | 3731 | } |
| 3745 | else if (desired_row->pixel_width < current_row->pixel_width) | 3732 | else if (desired_row->pixel_width < current_row->pixel_width) |
| @@ -3749,8 +3736,8 @@ update_text_area (struct window *w, int vpos) | |||
| 3749 | int xlim; | 3736 | int xlim; |
| 3750 | 3737 | ||
| 3751 | if (i >= desired_row->used[TEXT_AREA]) | 3738 | if (i >= desired_row->used[TEXT_AREA]) |
| 3752 | rif->cursor_to (vpos, i, desired_row->y, | 3739 | output_cursor_to (w, vpos, i, desired_row->y, |
| 3753 | desired_row->pixel_width); | 3740 | desired_row->pixel_width); |
| 3754 | 3741 | ||
| 3755 | /* If cursor is displayed at the end of the line, make sure | 3742 | /* If cursor is displayed at the end of the line, make sure |
| 3756 | it's cleared. Nowadays we don't have a phys_cursor_glyph | 3743 | it's cleared. Nowadays we don't have a phys_cursor_glyph |
| @@ -3767,7 +3754,7 @@ update_text_area (struct window *w, int vpos) | |||
| 3767 | } | 3754 | } |
| 3768 | else | 3755 | else |
| 3769 | xlim = current_row->pixel_width; | 3756 | xlim = current_row->pixel_width; |
| 3770 | rif->clear_end_of_line (xlim); | 3757 | rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim); |
| 3771 | changed_p = 1; | 3758 | changed_p = 1; |
| 3772 | } | 3759 | } |
| 3773 | } | 3760 | } |
| @@ -3786,10 +3773,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3786 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3773 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3787 | bool changed_p = 0; | 3774 | bool changed_p = 0; |
| 3788 | 3775 | ||
| 3789 | /* Set the row being updated. This is important to let xterm.c | ||
| 3790 | know what line height values are in effect. */ | ||
| 3791 | updated_row = desired_row; | ||
| 3792 | |||
| 3793 | /* A row can be completely invisible in case a desired matrix was | 3776 | /* A row can be completely invisible in case a desired matrix was |
| 3794 | built with a vscroll and then make_cursor_line_fully_visible shifts | 3777 | built with a vscroll and then make_cursor_line_fully_visible shifts |
| 3795 | the matrix. Make sure to make such rows current anyway, since | 3778 | the matrix. Make sure to make such rows current anyway, since |
| @@ -3800,11 +3783,10 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3800 | eassert (desired_row->enabled_p); | 3783 | eassert (desired_row->enabled_p); |
| 3801 | 3784 | ||
| 3802 | /* Update display of the left margin area, if there is one. */ | 3785 | /* Update display of the left margin area, if there is one. */ |
| 3803 | if (!desired_row->full_width_p | 3786 | if (!desired_row->full_width_p && w->left_margin_cols > 0) |
| 3804 | && !NILP (w->left_margin_cols)) | ||
| 3805 | { | 3787 | { |
| 3806 | changed_p = 1; | 3788 | changed_p = 1; |
| 3807 | update_marginal_area (w, LEFT_MARGIN_AREA, vpos); | 3789 | update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos); |
| 3808 | /* Setting this flag will ensure the vertical border, if | 3790 | /* Setting this flag will ensure the vertical border, if |
| 3809 | any, between this window and the one on its left will be | 3791 | any, between this window and the one on its left will be |
| 3810 | redrawn. This is necessary because updating the left | 3792 | redrawn. This is necessary because updating the left |
| @@ -3813,7 +3795,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3813 | } | 3795 | } |
| 3814 | 3796 | ||
| 3815 | /* Update the display of the text area. */ | 3797 | /* Update the display of the text area. */ |
| 3816 | if (update_text_area (w, vpos)) | 3798 | if (update_text_area (w, desired_row, vpos)) |
| 3817 | { | 3799 | { |
| 3818 | changed_p = 1; | 3800 | changed_p = 1; |
| 3819 | if (current_row->mouse_face_p) | 3801 | if (current_row->mouse_face_p) |
| @@ -3821,11 +3803,10 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3821 | } | 3803 | } |
| 3822 | 3804 | ||
| 3823 | /* Update display of the right margin area, if there is one. */ | 3805 | /* Update display of the right margin area, if there is one. */ |
| 3824 | if (!desired_row->full_width_p | 3806 | if (!desired_row->full_width_p && w->right_margin_cols > 0) |
| 3825 | && !NILP (w->right_margin_cols)) | ||
| 3826 | { | 3807 | { |
| 3827 | changed_p = 1; | 3808 | changed_p = 1; |
| 3828 | update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); | 3809 | update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos); |
| 3829 | } | 3810 | } |
| 3830 | 3811 | ||
| 3831 | /* Draw truncation marks etc. */ | 3812 | /* Draw truncation marks etc. */ |
| @@ -3839,12 +3820,11 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3839 | || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p | 3820 | || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p |
| 3840 | || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row) | 3821 | || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row) |
| 3841 | != MATRIX_ROW_CONTINUATION_LINE_P (current_row))) | 3822 | != MATRIX_ROW_CONTINUATION_LINE_P (current_row))) |
| 3842 | rif->after_update_window_line_hook (desired_row); | 3823 | rif->after_update_window_line_hook (w, desired_row); |
| 3843 | } | 3824 | } |
| 3844 | 3825 | ||
| 3845 | /* Update current_row from desired_row. */ | 3826 | /* Update current_row from desired_row. */ |
| 3846 | make_current (w->desired_matrix, w->current_matrix, vpos); | 3827 | make_current (w->desired_matrix, w->current_matrix, vpos); |
| 3847 | updated_row = NULL; | ||
| 3848 | return changed_p; | 3828 | return changed_p; |
| 3849 | } | 3829 | } |
| 3850 | 3830 | ||
| @@ -3856,7 +3836,6 @@ static void | |||
| 3856 | set_window_cursor_after_update (struct window *w) | 3836 | set_window_cursor_after_update (struct window *w) |
| 3857 | { | 3837 | { |
| 3858 | struct frame *f = XFRAME (w->frame); | 3838 | struct frame *f = XFRAME (w->frame); |
| 3859 | struct redisplay_interface *rif = FRAME_RIF (f); | ||
| 3860 | int cx, cy, vpos, hpos; | 3839 | int cx, cy, vpos, hpos; |
| 3861 | 3840 | ||
| 3862 | /* Not intended for frame matrix updates. */ | 3841 | /* Not intended for frame matrix updates. */ |
| @@ -3928,7 +3907,7 @@ set_window_cursor_after_update (struct window *w) | |||
| 3928 | Horizontal position is -1 when cursor is on the left fringe. */ | 3907 | Horizontal position is -1 when cursor is on the left fringe. */ |
| 3929 | hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1); | 3908 | hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1); |
| 3930 | vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1); | 3909 | vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1); |
| 3931 | rif->cursor_to (vpos, hpos, cy, cx); | 3910 | output_cursor_to (w, vpos, hpos, cy, cx); |
| 3932 | } | 3911 | } |
| 3933 | 3912 | ||
| 3934 | 3913 | ||
| @@ -4599,10 +4578,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) | |||
| 4599 | int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos); | 4578 | int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos); |
| 4600 | int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); | 4579 | int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); |
| 4601 | 4580 | ||
| 4602 | if (INTEGERP (w->left_margin_cols)) | 4581 | x += max (0, w->left_margin_cols); |
| 4603 | x += XFASTINT (w->left_margin_cols); | ||
| 4604 | |||
| 4605 | /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */ | ||
| 4606 | cursor_to (f, y, x); | 4582 | cursor_to (f, y, x); |
| 4607 | } | 4583 | } |
| 4608 | } | 4584 | } |
| @@ -5090,9 +5066,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5090 | wrong thing with `face-remapping-alist' (bug#2044). */ | 5066 | wrong thing with `face-remapping-alist' (bug#2044). */ |
| 5091 | Fset_buffer (w->contents); | 5067 | Fset_buffer (w->contents); |
| 5092 | itdata = bidi_shelve_cache (); | 5068 | itdata = bidi_shelve_cache (); |
| 5093 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 5069 | CLIP_TEXT_POS_FROM_MARKER (startp, w->start); |
| 5094 | CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); | ||
| 5095 | BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); | ||
| 5096 | start_display (&it, w, startp); | 5070 | start_display (&it, w, startp); |
| 5097 | /* start_display takes into account the header-line row, but IT's | 5071 | /* start_display takes into account the header-line row, but IT's |
| 5098 | vpos still counts from the glyph row that includes the window's | 5072 | vpos still counts from the glyph row that includes the window's |
| @@ -5729,9 +5703,9 @@ additional wait period, in milliseconds; this is for backwards compatibility. | |||
| 5729 | 5703 | ||
| 5730 | if (duration > 0) | 5704 | if (duration > 0) |
| 5731 | { | 5705 | { |
| 5732 | EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration); | 5706 | struct timespec t = dtotimespec (duration); |
| 5733 | wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX), | 5707 | wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX), |
| 5734 | EMACS_NSECS (t), 0, 0, Qnil, NULL, 0); | 5708 | t.tv_nsec, 0, 0, Qnil, NULL, 0); |
| 5735 | } | 5709 | } |
| 5736 | 5710 | ||
| 5737 | return Qnil; | 5711 | return Qnil; |
| @@ -5778,9 +5752,9 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) | |||
| 5778 | return Qt; | 5752 | return Qt; |
| 5779 | else | 5753 | else |
| 5780 | { | 5754 | { |
| 5781 | EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds); | 5755 | struct timespec t = dtotimespec (seconds); |
| 5782 | sec = min (EMACS_SECS (t), WAIT_READING_MAX); | 5756 | sec = min (t.tv_sec, WAIT_READING_MAX); |
| 5783 | nsec = EMACS_NSECS (t); | 5757 | nsec = t.tv_nsec; |
| 5784 | } | 5758 | } |
| 5785 | } | 5759 | } |
| 5786 | else if (EQ (timeout, Qt)) | 5760 | else if (EQ (timeout, Qt)) |
| @@ -5884,9 +5858,8 @@ pass nil for VARIABLE. */) | |||
| 5884 | goto changed; | 5858 | goto changed; |
| 5885 | } | 5859 | } |
| 5886 | /* Check that the buffer info matches. */ | 5860 | /* Check that the buffer info matches. */ |
| 5887 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 5861 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 5888 | { | 5862 | { |
| 5889 | buf = XCDR (XCAR (tail)); | ||
| 5890 | /* Ignore buffers that aren't included in buffer lists. */ | 5863 | /* Ignore buffers that aren't included in buffer lists. */ |
| 5891 | if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') | 5864 | if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') |
| 5892 | continue; | 5865 | continue; |
| @@ -5916,7 +5889,7 @@ pass nil for VARIABLE. */) | |||
| 5916 | n = 1; | 5889 | n = 1; |
| 5917 | FOR_EACH_FRAME (tail, frame) | 5890 | FOR_EACH_FRAME (tail, frame) |
| 5918 | n += 2; | 5891 | n += 2; |
| 5919 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 5892 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 5920 | n += 3; | 5893 | n += 3; |
| 5921 | /* Reallocate the vector if data has grown to need it, | 5894 | /* Reallocate the vector if data has grown to need it, |
| 5922 | or if it has shrunk a lot. */ | 5895 | or if it has shrunk a lot. */ |
| @@ -5941,9 +5914,8 @@ pass nil for VARIABLE. */) | |||
| 5941 | ASET (state, idx, XFRAME (frame)->name); | 5914 | ASET (state, idx, XFRAME (frame)->name); |
| 5942 | idx++; | 5915 | idx++; |
| 5943 | } | 5916 | } |
| 5944 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 5917 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 5945 | { | 5918 | { |
| 5946 | buf = XCDR (XCAR (tail)); | ||
| 5947 | /* Ignore buffers that aren't included in buffer lists. */ | 5919 | /* Ignore buffers that aren't included in buffer lists. */ |
| 5948 | if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') | 5920 | if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') |
| 5949 | continue; | 5921 | continue; |
| @@ -6200,19 +6172,6 @@ WINDOW nil or omitted means report on the selected window. */) | |||
| 6200 | { | 6172 | { |
| 6201 | return decode_any_window (window)->cursor_off_p ? Qnil : Qt; | 6173 | return decode_any_window (window)->cursor_off_p ? Qnil : Qt; |
| 6202 | } | 6174 | } |
| 6203 | |||
| 6204 | DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, | ||
| 6205 | Slast_nonminibuf_frame, 0, 0, 0, | ||
| 6206 | doc: /* Value is last nonminibuffer frame. */) | ||
| 6207 | (void) | ||
| 6208 | { | ||
| 6209 | Lisp_Object frame = Qnil; | ||
| 6210 | |||
| 6211 | if (last_nonminibuf_frame) | ||
| 6212 | XSETFRAME (frame, last_nonminibuf_frame); | ||
| 6213 | |||
| 6214 | return frame; | ||
| 6215 | } | ||
| 6216 | 6175 | ||
| 6217 | /*********************************************************************** | 6176 | /*********************************************************************** |
| 6218 | Initialization | 6177 | Initialization |
| @@ -6231,7 +6190,6 @@ syms_of_display (void) | |||
| 6231 | defsubr (&Ssend_string_to_terminal); | 6190 | defsubr (&Ssend_string_to_terminal); |
| 6232 | defsubr (&Sinternal_show_cursor); | 6191 | defsubr (&Sinternal_show_cursor); |
| 6233 | defsubr (&Sinternal_show_cursor_p); | 6192 | defsubr (&Sinternal_show_cursor_p); |
| 6234 | defsubr (&Slast_nonminibuf_frame); | ||
| 6235 | 6193 | ||
| 6236 | #ifdef GLYPH_DEBUG | 6194 | #ifdef GLYPH_DEBUG |
| 6237 | defsubr (&Sdump_redisplay_history); | 6195 | defsubr (&Sdump_redisplay_history); |
| @@ -905,7 +905,7 @@ Otherwise, return a new string, without any text properties. */) | |||
| 905 | If this one's not active, get nil. */ | 905 | If this one's not active, get nil. */ |
| 906 | earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps))); | 906 | earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps))); |
| 907 | describe_map_tree (tem, 1, Fnreverse (earlier_maps), | 907 | describe_map_tree (tem, 1, Fnreverse (earlier_maps), |
| 908 | Qnil, (char *)0, 1, 0, 0, 1); | 908 | Qnil, 0, 1, 0, 0, 1); |
| 909 | } | 909 | } |
| 910 | tem = Fbuffer_string (); | 910 | tem = Fbuffer_string (); |
| 911 | Ferase_buffer (); | 911 | Ferase_buffer (); |
diff --git a/src/editfns.c b/src/editfns.c index 50bde90788d..84a5c8395fc 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -64,7 +64,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 64 | extern Lisp_Object w32_get_internal_run_time (void); | 64 | extern Lisp_Object w32_get_internal_run_time (void); |
| 65 | #endif | 65 | #endif |
| 66 | 66 | ||
| 67 | static Lisp_Object format_time_string (char const *, ptrdiff_t, EMACS_TIME, | 67 | static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, |
| 68 | bool, struct tm *); | 68 | bool, struct tm *); |
| 69 | static int tm_diff (struct tm *, struct tm *); | 69 | static int tm_diff (struct tm *, struct tm *); |
| 70 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); | 70 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); |
| @@ -233,26 +233,12 @@ Beginning of buffer is position (point-min), end is (point-max). | |||
| 233 | The return value is POSITION. */) | 233 | The return value is POSITION. */) |
| 234 | (register Lisp_Object position) | 234 | (register Lisp_Object position) |
| 235 | { | 235 | { |
| 236 | ptrdiff_t pos; | 236 | if (MARKERP (position)) |
| 237 | 237 | set_point_from_marker (position); | |
| 238 | if (MARKERP (position) | 238 | else if (INTEGERP (position)) |
| 239 | && current_buffer == XMARKER (position)->buffer) | 239 | SET_PT (clip_to_bounds (BEGV, XINT (position), ZV)); |
| 240 | { | 240 | else |
| 241 | pos = marker_position (position); | 241 | wrong_type_argument (Qinteger_or_marker_p, position); |
| 242 | if (pos < BEGV) | ||
| 243 | SET_PT_BOTH (BEGV, BEGV_BYTE); | ||
| 244 | else if (pos > ZV) | ||
| 245 | SET_PT_BOTH (ZV, ZV_BYTE); | ||
| 246 | else | ||
| 247 | SET_PT_BOTH (pos, marker_byte_position (position)); | ||
| 248 | |||
| 249 | return position; | ||
| 250 | } | ||
| 251 | |||
| 252 | CHECK_NUMBER_COERCE_MARKER (position); | ||
| 253 | |||
| 254 | pos = clip_to_bounds (BEGV, XINT (position), ZV); | ||
| 255 | SET_PT (pos); | ||
| 256 | return position; | 242 | return position; |
| 257 | } | 243 | } |
| 258 | 244 | ||
| @@ -1420,7 +1406,7 @@ least significant 16 bits. USEC and PSEC are the microsecond and | |||
| 1420 | picosecond counts. */) | 1406 | picosecond counts. */) |
| 1421 | (void) | 1407 | (void) |
| 1422 | { | 1408 | { |
| 1423 | return make_lisp_time (current_emacs_time ()); | 1409 | return make_lisp_time (current_timespec ()); |
| 1424 | } | 1410 | } |
| 1425 | 1411 | ||
| 1426 | DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, | 1412 | DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, |
| @@ -1450,7 +1436,7 @@ does the same thing as `current-time'. */) | |||
| 1450 | usecs -= 1000000; | 1436 | usecs -= 1000000; |
| 1451 | secs++; | 1437 | secs++; |
| 1452 | } | 1438 | } |
| 1453 | return make_lisp_time (make_emacs_time (secs, usecs * 1000)); | 1439 | return make_lisp_time (make_timespec (secs, usecs * 1000)); |
| 1454 | #else /* ! HAVE_GETRUSAGE */ | 1440 | #else /* ! HAVE_GETRUSAGE */ |
| 1455 | #ifdef WINDOWSNT | 1441 | #ifdef WINDOWSNT |
| 1456 | return w32_get_internal_run_time (); | 1442 | return w32_get_internal_run_time (); |
| @@ -1481,10 +1467,10 @@ make_time (time_t t) | |||
| 1481 | UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a | 1467 | UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a |
| 1482 | correspondingly negative picosecond count. */ | 1468 | correspondingly negative picosecond count. */ |
| 1483 | Lisp_Object | 1469 | Lisp_Object |
| 1484 | make_lisp_time (EMACS_TIME t) | 1470 | make_lisp_time (struct timespec t) |
| 1485 | { | 1471 | { |
| 1486 | int ns = EMACS_NSECS (t); | 1472 | int ns = t.tv_nsec; |
| 1487 | return make_time_tail (EMACS_SECS (t), list2i (ns / 1000, ns % 1000 * 1000)); | 1473 | return make_time_tail (t.tv_sec, list2i (ns / 1000, ns % 1000 * 1000)); |
| 1488 | } | 1474 | } |
| 1489 | 1475 | ||
| 1490 | /* Decode a Lisp list SPECIFIED_TIME that represents a time. | 1476 | /* Decode a Lisp list SPECIFIED_TIME that represents a time. |
| @@ -1529,7 +1515,7 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh, | |||
| 1529 | list, generate the corresponding time value. | 1515 | list, generate the corresponding time value. |
| 1530 | 1516 | ||
| 1531 | If RESULT is not null, store into *RESULT the converted time; | 1517 | If RESULT is not null, store into *RESULT the converted time; |
| 1532 | this can fail if the converted time does not fit into EMACS_TIME. | 1518 | this can fail if the converted time does not fit into struct timespec. |
| 1533 | If *DRESULT is not null, store into *DRESULT the number of | 1519 | If *DRESULT is not null, store into *DRESULT the number of |
| 1534 | seconds since the start of the POSIX Epoch. | 1520 | seconds since the start of the POSIX Epoch. |
| 1535 | 1521 | ||
| @@ -1537,7 +1523,7 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh, | |||
| 1537 | bool | 1523 | bool |
| 1538 | decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | 1524 | decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, |
| 1539 | Lisp_Object psec, | 1525 | Lisp_Object psec, |
| 1540 | EMACS_TIME *result, double *dresult) | 1526 | struct timespec *result, double *dresult) |
| 1541 | { | 1527 | { |
| 1542 | EMACS_INT hi, lo, us, ps; | 1528 | EMACS_INT hi, lo, us, ps; |
| 1543 | if (! (INTEGERP (high) && INTEGERP (low) | 1529 | if (! (INTEGERP (high) && INTEGERP (low) |
| @@ -1565,7 +1551,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1565 | /* Return the greatest representable time that is not greater | 1551 | /* Return the greatest representable time that is not greater |
| 1566 | than the requested time. */ | 1552 | than the requested time. */ |
| 1567 | time_t sec = hi; | 1553 | time_t sec = hi; |
| 1568 | *result = make_emacs_time ((sec << 16) + lo, us * 1000 + ps / 1000); | 1554 | *result = make_timespec ((sec << 16) + lo, us * 1000 + ps / 1000); |
| 1569 | } | 1555 | } |
| 1570 | else | 1556 | else |
| 1571 | { | 1557 | { |
| @@ -1583,15 +1569,15 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1583 | /* Decode a Lisp list SPECIFIED_TIME that represents a time. | 1569 | /* Decode a Lisp list SPECIFIED_TIME that represents a time. |
| 1584 | If SPECIFIED_TIME is nil, use the current time. | 1570 | If SPECIFIED_TIME is nil, use the current time. |
| 1585 | 1571 | ||
| 1586 | Round the time down to the nearest EMACS_TIME value. | 1572 | Round the time down to the nearest struct timespec value. |
| 1587 | Return seconds since the Epoch. | 1573 | Return seconds since the Epoch. |
| 1588 | Signal an error if unsuccessful. */ | 1574 | Signal an error if unsuccessful. */ |
| 1589 | EMACS_TIME | 1575 | struct timespec |
| 1590 | lisp_time_argument (Lisp_Object specified_time) | 1576 | lisp_time_argument (Lisp_Object specified_time) |
| 1591 | { | 1577 | { |
| 1592 | EMACS_TIME t; | 1578 | struct timespec t; |
| 1593 | if (NILP (specified_time)) | 1579 | if (NILP (specified_time)) |
| 1594 | t = current_emacs_time (); | 1580 | t = current_timespec (); |
| 1595 | else | 1581 | else |
| 1596 | { | 1582 | { |
| 1597 | Lisp_Object high, low, usec, psec; | 1583 | Lisp_Object high, low, usec, psec; |
| @@ -1613,12 +1599,12 @@ lisp_seconds_argument (Lisp_Object specified_time) | |||
| 1613 | else | 1599 | else |
| 1614 | { | 1600 | { |
| 1615 | Lisp_Object high, low, usec, psec; | 1601 | Lisp_Object high, low, usec, psec; |
| 1616 | EMACS_TIME t; | 1602 | struct timespec t; |
| 1617 | if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) | 1603 | if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) |
| 1618 | && decode_time_components (high, low, make_number (0), | 1604 | && decode_time_components (high, low, make_number (0), |
| 1619 | make_number (0), &t, 0))) | 1605 | make_number (0), &t, 0))) |
| 1620 | error ("Invalid time specification"); | 1606 | error ("Invalid time specification"); |
| 1621 | return EMACS_SECS (t); | 1607 | return t.tv_sec; |
| 1622 | } | 1608 | } |
| 1623 | } | 1609 | } |
| 1624 | 1610 | ||
| @@ -1639,8 +1625,8 @@ or (if you need time as a string) `format-time-string'. */) | |||
| 1639 | double t; | 1625 | double t; |
| 1640 | if (NILP (specified_time)) | 1626 | if (NILP (specified_time)) |
| 1641 | { | 1627 | { |
| 1642 | EMACS_TIME now = current_emacs_time (); | 1628 | struct timespec now = current_timespec (); |
| 1643 | t = EMACS_SECS (now) + EMACS_NSECS (now) / 1e9; | 1629 | t = now.tv_sec + now.tv_nsec / 1e9; |
| 1644 | } | 1630 | } |
| 1645 | else | 1631 | else |
| 1646 | { | 1632 | { |
| @@ -1758,7 +1744,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". | |||
| 1758 | usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | 1744 | usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) |
| 1759 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) | 1745 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) |
| 1760 | { | 1746 | { |
| 1761 | EMACS_TIME t = lisp_time_argument (timeval); | 1747 | struct timespec t = lisp_time_argument (timeval); |
| 1762 | struct tm tm; | 1748 | struct tm tm; |
| 1763 | 1749 | ||
| 1764 | CHECK_STRING (format_string); | 1750 | CHECK_STRING (format_string); |
| @@ -1770,20 +1756,20 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | |||
| 1770 | 1756 | ||
| 1771 | static Lisp_Object | 1757 | static Lisp_Object |
| 1772 | format_time_string (char const *format, ptrdiff_t formatlen, | 1758 | format_time_string (char const *format, ptrdiff_t formatlen, |
| 1773 | EMACS_TIME t, bool ut, struct tm *tmp) | 1759 | struct timespec t, bool ut, struct tm *tmp) |
| 1774 | { | 1760 | { |
| 1775 | char buffer[4000]; | 1761 | char buffer[4000]; |
| 1776 | char *buf = buffer; | 1762 | char *buf = buffer; |
| 1777 | ptrdiff_t size = sizeof buffer; | 1763 | ptrdiff_t size = sizeof buffer; |
| 1778 | size_t len; | 1764 | size_t len; |
| 1779 | Lisp_Object bufstring; | 1765 | Lisp_Object bufstring; |
| 1780 | int ns = EMACS_NSECS (t); | 1766 | int ns = t.tv_nsec; |
| 1781 | struct tm *tm; | 1767 | struct tm *tm; |
| 1782 | USE_SAFE_ALLOCA; | 1768 | USE_SAFE_ALLOCA; |
| 1783 | 1769 | ||
| 1784 | while (1) | 1770 | while (1) |
| 1785 | { | 1771 | { |
| 1786 | time_t *taddr = emacs_secs_addr (&t); | 1772 | time_t *taddr = &t.tv_sec; |
| 1787 | block_input (); | 1773 | block_input (); |
| 1788 | 1774 | ||
| 1789 | synchronize_system_time_locale (); | 1775 | synchronize_system_time_locale (); |
| @@ -2068,17 +2054,17 @@ in this case, `current-time-zone' returns a list containing nil for | |||
| 2068 | the data it can't find. */) | 2054 | the data it can't find. */) |
| 2069 | (Lisp_Object specified_time) | 2055 | (Lisp_Object specified_time) |
| 2070 | { | 2056 | { |
| 2071 | EMACS_TIME value; | 2057 | struct timespec value; |
| 2072 | int offset; | 2058 | int offset; |
| 2073 | struct tm *t; | 2059 | struct tm *t; |
| 2074 | struct tm localtm; | 2060 | struct tm localtm; |
| 2075 | Lisp_Object zone_offset, zone_name; | 2061 | Lisp_Object zone_offset, zone_name; |
| 2076 | 2062 | ||
| 2077 | zone_offset = Qnil; | 2063 | zone_offset = Qnil; |
| 2078 | value = make_emacs_time (lisp_seconds_argument (specified_time), 0); | 2064 | value = make_timespec (lisp_seconds_argument (specified_time), 0); |
| 2079 | zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm); | 2065 | zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm); |
| 2080 | block_input (); | 2066 | block_input (); |
| 2081 | t = gmtime (emacs_secs_addr (&value)); | 2067 | t = gmtime (&value.tv_sec); |
| 2082 | if (t) | 2068 | if (t) |
| 2083 | offset = tm_diff (&localtm, t); | 2069 | offset = tm_diff (&localtm, t); |
| 2084 | unblock_input (); | 2070 | unblock_input (); |
| @@ -2330,6 +2316,10 @@ to multibyte for insertion (see `unibyte-char-to-multibyte'). | |||
| 2330 | If the current buffer is unibyte, multibyte strings are converted | 2316 | If the current buffer is unibyte, multibyte strings are converted |
| 2331 | to unibyte for insertion. | 2317 | to unibyte for insertion. |
| 2332 | 2318 | ||
| 2319 | If an overlay begins at the insertion point, the inserted text falls | ||
| 2320 | outside the overlay; if a nonempty overlay ends at the insertion | ||
| 2321 | point, the inserted text falls inside that overlay. | ||
| 2322 | |||
| 2333 | usage: (insert-before-markers &rest ARGS) */) | 2323 | usage: (insert-before-markers &rest ARGS) */) |
| 2334 | (ptrdiff_t nargs, Lisp_Object *args) | 2324 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2335 | { | 2325 | { |
| @@ -2928,7 +2918,7 @@ Both characters must have the same length of multi-byte form. */) | |||
| 2928 | else if (!changed) | 2918 | else if (!changed) |
| 2929 | { | 2919 | { |
| 2930 | changed = -1; | 2920 | changed = -1; |
| 2931 | modify_region_1 (pos, XINT (end), false); | 2921 | modify_text (pos, XINT (end)); |
| 2932 | 2922 | ||
| 2933 | if (! NILP (noundo)) | 2923 | if (! NILP (noundo)) |
| 2934 | { | 2924 | { |
| @@ -3104,7 +3094,7 @@ It returns the number of characters changed. */) | |||
| 3104 | pos = XINT (start); | 3094 | pos = XINT (start); |
| 3105 | pos_byte = CHAR_TO_BYTE (pos); | 3095 | pos_byte = CHAR_TO_BYTE (pos); |
| 3106 | end_pos = XINT (end); | 3096 | end_pos = XINT (end); |
| 3107 | modify_region_1 (pos, end_pos, false); | 3097 | modify_text (pos, end_pos); |
| 3108 | 3098 | ||
| 3109 | cnt = 0; | 3099 | cnt = 0; |
| 3110 | for (; pos < end_pos; ) | 3100 | for (; pos < end_pos; ) |
| @@ -4615,7 +4605,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4615 | 4605 | ||
| 4616 | if (end1 == start2) /* adjacent regions */ | 4606 | if (end1 == start2) /* adjacent regions */ |
| 4617 | { | 4607 | { |
| 4618 | modify_region_1 (start1, end2, false); | 4608 | modify_text (start1, end2); |
| 4619 | record_change (start1, len1 + len2); | 4609 | record_change (start1, len1 + len2); |
| 4620 | 4610 | ||
| 4621 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4611 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| @@ -4674,8 +4664,8 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4674 | { | 4664 | { |
| 4675 | USE_SAFE_ALLOCA; | 4665 | USE_SAFE_ALLOCA; |
| 4676 | 4666 | ||
| 4677 | modify_region_1 (start1, end1, false); | 4667 | modify_text (start1, end1); |
| 4678 | modify_region_1 (start2, end2, false); | 4668 | modify_text (start2, end2); |
| 4679 | record_change (start1, len1); | 4669 | record_change (start1, len1); |
| 4680 | record_change (start2, len2); | 4670 | record_change (start2, len2); |
| 4681 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4671 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| @@ -4708,7 +4698,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4708 | { | 4698 | { |
| 4709 | USE_SAFE_ALLOCA; | 4699 | USE_SAFE_ALLOCA; |
| 4710 | 4700 | ||
| 4711 | modify_region_1 (start1, end2, false); | 4701 | modify_text (start1, end2); |
| 4712 | record_change (start1, (end2 - start1)); | 4702 | record_change (start1, (end2 - start1)); |
| 4713 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4703 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| 4714 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); | 4704 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); |
| @@ -4741,7 +4731,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4741 | USE_SAFE_ALLOCA; | 4731 | USE_SAFE_ALLOCA; |
| 4742 | 4732 | ||
| 4743 | record_change (start1, (end2 - start1)); | 4733 | record_change (start1, (end2 - start1)); |
| 4744 | modify_region_1 (start1, end2, false); | 4734 | modify_text (start1, end2); |
| 4745 | 4735 | ||
| 4746 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4736 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| 4747 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); | 4737 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); |
diff --git a/src/emacs.c b/src/emacs.c index cf3a3c68932..05384145330 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -517,8 +517,7 @@ init_cmdargs (int argc, char **argv, int skip_args) | |||
| 517 | They are decoded in the function command-line after we know | 517 | They are decoded in the function command-line after we know |
| 518 | locale-coding-system. */ | 518 | locale-coding-system. */ |
| 519 | Vcommand_line_args | 519 | Vcommand_line_args |
| 520 | = Fcons (make_unibyte_string (argv[i], strlen (argv[i])), | 520 | = Fcons (build_unibyte_string (argv[i]), Vcommand_line_args); |
| 521 | Vcommand_line_args); | ||
| 522 | } | 521 | } |
| 523 | 522 | ||
| 524 | unbind_to (count, Qnil); | 523 | unbind_to (count, Qnil); |
| @@ -697,7 +696,8 @@ main (int argc, char **argv) | |||
| 697 | #endif | 696 | #endif |
| 698 | 697 | ||
| 699 | #ifdef G_SLICE_ALWAYS_MALLOC | 698 | #ifdef G_SLICE_ALWAYS_MALLOC |
| 700 | /* This is used by the Cygwin build. */ | 699 | /* This is used by the Cygwin build. It's not needed starting with |
| 700 | cygwin-1.7.24, but it doesn't do any harm. */ | ||
| 701 | xputenv ("G_SLICE=always-malloc"); | 701 | xputenv ("G_SLICE=always-malloc"); |
| 702 | #endif | 702 | #endif |
| 703 | 703 | ||
| @@ -1407,6 +1407,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1407 | syms_of_xml (); | 1407 | syms_of_xml (); |
| 1408 | #endif | 1408 | #endif |
| 1409 | 1409 | ||
| 1410 | #ifdef HAVE_ZLIB | ||
| 1411 | syms_of_decompress (); | ||
| 1412 | #endif | ||
| 1413 | |||
| 1410 | syms_of_menu (); | 1414 | syms_of_menu (); |
| 1411 | 1415 | ||
| 1412 | #ifdef HAVE_NTGUI | 1416 | #ifdef HAVE_NTGUI |
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c index 8b19d89f3a0..44f5cde1b0b 100644 --- a/src/emacsgtkfixed.c +++ b/src/emacsgtkfixed.c | |||
| @@ -20,12 +20,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | 20 | ||
| 21 | #include <config.h> | 21 | #include <config.h> |
| 22 | 22 | ||
| 23 | #include "emacsgtkfixed.h" | ||
| 24 | #include <stdio.h> | ||
| 25 | |||
| 26 | #include "lisp.h" | 23 | #include "lisp.h" |
| 27 | #include "frame.h" | 24 | #include "frame.h" |
| 28 | #include "xterm.h" | 25 | #include "xterm.h" |
| 26 | #include "emacsgtkfixed.h" | ||
| 29 | 27 | ||
| 30 | /* Silence a bogus diagnostic; see GNOME bug 683906. */ | 28 | /* Silence a bogus diagnostic; see GNOME bug 683906. */ |
| 31 | #if 4 < __GNUC__ + (7 <= __GNUC_MINOR__) | 29 | #if 4 < __GNUC__ + (7 <= __GNUC_MINOR__) |
diff --git a/src/emacsgtkfixed.h b/src/emacsgtkfixed.h index d987797a934..773ca26b143 100644 --- a/src/emacsgtkfixed.h +++ b/src/emacsgtkfixed.h | |||
| @@ -25,8 +25,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | 25 | ||
| 26 | G_BEGIN_DECLS | 26 | G_BEGIN_DECLS |
| 27 | 27 | ||
| 28 | struct frame; | ||
| 29 | |||
| 30 | extern GtkWidget *emacs_fixed_new (struct frame *f); | 28 | extern GtkWidget *emacs_fixed_new (struct frame *f); |
| 31 | 29 | ||
| 32 | G_END_DECLS | 30 | G_END_DECLS |
diff --git a/src/eval.c b/src/eval.c index 8ee259110f4..1ce14ae94a6 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2149,6 +2149,8 @@ eval_sub (Lisp_Object form) | |||
| 2149 | if (SYMBOLP (fun) && !NILP (fun) | 2149 | if (SYMBOLP (fun) && !NILP (fun) |
| 2150 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | 2150 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) |
| 2151 | fun = indirect_function (fun); | 2151 | fun = indirect_function (fun); |
| 2152 | else | ||
| 2153 | fun = Ffunction (Fcons (fun, Qnil)); | ||
| 2152 | 2154 | ||
| 2153 | if (SUBRP (fun)) | 2155 | if (SUBRP (fun)) |
| 2154 | { | 2156 | { |
| @@ -3151,20 +3153,17 @@ let_shadows_global_binding_p (Lisp_Object symbol) | |||
| 3151 | return 0; | 3153 | return 0; |
| 3152 | } | 3154 | } |
| 3153 | 3155 | ||
| 3154 | /* `specpdl_ptr->symbol' is a field which describes which variable is | 3156 | /* `specpdl_ptr' describes which variable is |
| 3155 | let-bound, so it can be properly undone when we unbind_to. | 3157 | let-bound, so it can be properly undone when we unbind_to. |
| 3156 | It can have the following two shapes: | 3158 | It can be either a plain SPECPDL_LET or a SPECPDL_LET_LOCAL/DEFAULT. |
| 3157 | - SYMBOL : if it's a plain symbol, it means that we have let-bound | 3159 | - SYMBOL is the variable being bound. Note that it should not be |
| 3158 | a symbol that is not buffer-local (at least at the time | ||
| 3159 | the let binding started). Note also that it should not be | ||
| 3160 | aliased (i.e. when let-binding V1 that's aliased to V2, we want | 3160 | aliased (i.e. when let-binding V1 that's aliased to V2, we want |
| 3161 | to record V2 here). | 3161 | to record V2 here). |
| 3162 | - (SYMBOL WHERE . BUFFER) : this means that it is a let-binding for | 3162 | - WHERE tells us in which buffer the binding took place. |
| 3163 | variable SYMBOL which can be buffer-local. WHERE tells us | 3163 | This is used for SPECPDL_LET_LOCAL bindings (i.e. bindings to a |
| 3164 | which buffer is affected (or nil if the let-binding affects the | 3164 | buffer-local variable) as well as for SPECPDL_LET_DEFAULT bindings, |
| 3165 | global value of the variable) and BUFFER tells us which buffer was | 3165 | i.e. bindings to the default value of a variable which can be |
| 3166 | current (i.e. if WHERE is non-nil, then BUFFER==WHERE, otherwise | 3166 | buffer-local. */ |
| 3167 | BUFFER did not yet have a buffer-local value). */ | ||
| 3168 | 3167 | ||
| 3169 | void | 3168 | void |
| 3170 | specbind (Lisp_Object symbol, Lisp_Object value) | 3169 | specbind (Lisp_Object symbol, Lisp_Object value) |
| @@ -3302,6 +3301,16 @@ clear_unwind_protect (ptrdiff_t count) | |||
| 3302 | previous value without invoking it. */ | 3301 | previous value without invoking it. */ |
| 3303 | 3302 | ||
| 3304 | void | 3303 | void |
| 3304 | set_unwind_protect (ptrdiff_t count, void (*func) (Lisp_Object), | ||
| 3305 | Lisp_Object arg) | ||
| 3306 | { | ||
| 3307 | union specbinding *p = specpdl + count; | ||
| 3308 | p->unwind.kind = SPECPDL_UNWIND; | ||
| 3309 | p->unwind.func = func; | ||
| 3310 | p->unwind.arg = arg; | ||
| 3311 | } | ||
| 3312 | |||
| 3313 | void | ||
| 3305 | set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg) | 3314 | set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg) |
| 3306 | { | 3315 | { |
| 3307 | union specbinding *p = specpdl + count; | 3316 | union specbinding *p = specpdl + count; |
diff --git a/src/fileio.c b/src/fileio.c index 59e84053773..0e6113f349d 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -233,7 +233,7 @@ void | |||
| 233 | restore_point_unwind (Lisp_Object location) | 233 | restore_point_unwind (Lisp_Object location) |
| 234 | { | 234 | { |
| 235 | Fgoto_char (location); | 235 | Fgoto_char (location); |
| 236 | Fset_marker (location, Qnil, Qnil); | 236 | unchain_marker (XMARKER (location)); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | 239 | ||
| @@ -366,8 +366,7 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | #ifdef DOS_NT | 368 | #ifdef DOS_NT |
| 369 | beg = alloca (SBYTES (filename) + 1); | 369 | beg = xlispstrdupa (filename); |
| 370 | memcpy (beg, SSDATA (filename), SBYTES (filename) + 1); | ||
| 371 | #else | 370 | #else |
| 372 | beg = SSDATA (filename); | 371 | beg = SSDATA (filename); |
| 373 | #endif | 372 | #endif |
| @@ -505,6 +504,10 @@ get a current directory to run processes in. */) | |||
| 505 | return Ffile_name_directory (filename); | 504 | return Ffile_name_directory (filename); |
| 506 | } | 505 | } |
| 507 | 506 | ||
| 507 | /* Maximum number of bytes that DST will be longer than SRC | ||
| 508 | in file_name_as_directory. This occurs when SRCLEN == 0. */ | ||
| 509 | enum { file_name_as_directory_slop = 2 }; | ||
| 510 | |||
| 508 | /* Convert from file name SRC of length SRCLEN to directory name in | 511 | /* Convert from file name SRC of length SRCLEN to directory name in |
| 509 | DST. MULTIBYTE non-zero means the file name in SRC is a multibyte | 512 | DST. MULTIBYTE non-zero means the file name in SRC is a multibyte |
| 510 | string. On UNIX, just make sure there is a terminating /. Return | 513 | string. On UNIX, just make sure there is a terminating /. Return |
| @@ -522,14 +525,10 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen, | |||
| 522 | return 2; | 525 | return 2; |
| 523 | } | 526 | } |
| 524 | 527 | ||
| 525 | strcpy (dst, src); | 528 | memcpy (dst, src, srclen); |
| 526 | |||
| 527 | if (!IS_DIRECTORY_SEP (dst[srclen - 1])) | 529 | if (!IS_DIRECTORY_SEP (dst[srclen - 1])) |
| 528 | { | 530 | dst[srclen++] = DIRECTORY_SEP; |
| 529 | dst[srclen] = DIRECTORY_SEP; | 531 | dst[srclen] = 0; |
| 530 | dst[srclen + 1] = '\0'; | ||
| 531 | srclen++; | ||
| 532 | } | ||
| 533 | #ifdef DOS_NT | 532 | #ifdef DOS_NT |
| 534 | dostounix_filename (dst, multibyte); | 533 | dostounix_filename (dst, multibyte); |
| 535 | #endif | 534 | #endif |
| @@ -548,7 +547,8 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 548 | { | 547 | { |
| 549 | char *buf; | 548 | char *buf; |
| 550 | ptrdiff_t length; | 549 | ptrdiff_t length; |
| 551 | Lisp_Object handler; | 550 | Lisp_Object handler, val; |
| 551 | USE_SAFE_ALLOCA; | ||
| 552 | 552 | ||
| 553 | CHECK_STRING (file); | 553 | CHECK_STRING (file); |
| 554 | if (NILP (file)) | 554 | if (NILP (file)) |
| @@ -570,10 +570,12 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 570 | if (!NILP (Vw32_downcase_file_names)) | 570 | if (!NILP (Vw32_downcase_file_names)) |
| 571 | file = Fdowncase (file); | 571 | file = Fdowncase (file); |
| 572 | #endif | 572 | #endif |
| 573 | buf = alloca (SBYTES (file) + 10); | 573 | buf = SAFE_ALLOCA (SBYTES (file) + file_name_as_directory_slop + 1); |
| 574 | length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), | 574 | length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), |
| 575 | STRING_MULTIBYTE (file)); | 575 | STRING_MULTIBYTE (file)); |
| 576 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); | 576 | val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); |
| 577 | SAFE_FREE (); | ||
| 578 | return val; | ||
| 577 | } | 579 | } |
| 578 | 580 | ||
| 579 | /* Convert from directory name SRC of length SRCLEN to file name in | 581 | /* Convert from directory name SRC of length SRCLEN to file name in |
| @@ -585,18 +587,17 @@ static ptrdiff_t | |||
| 585 | directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) | 587 | directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) |
| 586 | { | 588 | { |
| 587 | /* Process as Unix format: just remove any final slash. | 589 | /* Process as Unix format: just remove any final slash. |
| 588 | But leave "/" unchanged; do not change it to "". */ | 590 | But leave "/" and "//" unchanged. */ |
| 589 | strcpy (dst, src); | 591 | while (srclen > 1 |
| 590 | if (srclen > 1 | ||
| 591 | && IS_DIRECTORY_SEP (dst[srclen - 1]) | ||
| 592 | #ifdef DOS_NT | 592 | #ifdef DOS_NT |
| 593 | && !IS_ANY_SEP (dst[srclen - 2]) | 593 | && !IS_ANY_SEP (src[srclen - 2]) |
| 594 | #endif | 594 | #endif |
| 595 | ) | 595 | && IS_DIRECTORY_SEP (src[srclen - 1]) |
| 596 | { | 596 | && ! (srclen == 2 && IS_DIRECTORY_SEP (src[0]))) |
| 597 | dst[srclen - 1] = 0; | 597 | srclen--; |
| 598 | srclen--; | 598 | |
| 599 | } | 599 | memcpy (dst, src, srclen); |
| 600 | dst[srclen] = 0; | ||
| 600 | #ifdef DOS_NT | 601 | #ifdef DOS_NT |
| 601 | dostounix_filename (dst, multibyte); | 602 | dostounix_filename (dst, multibyte); |
| 602 | #endif | 603 | #endif |
| @@ -614,7 +615,8 @@ In Unix-syntax, this function just removes the final slash. */) | |||
| 614 | { | 615 | { |
| 615 | char *buf; | 616 | char *buf; |
| 616 | ptrdiff_t length; | 617 | ptrdiff_t length; |
| 617 | Lisp_Object handler; | 618 | Lisp_Object handler, val; |
| 619 | USE_SAFE_ALLOCA; | ||
| 618 | 620 | ||
| 619 | CHECK_STRING (directory); | 621 | CHECK_STRING (directory); |
| 620 | 622 | ||
| @@ -637,10 +639,12 @@ In Unix-syntax, this function just removes the final slash. */) | |||
| 637 | if (!NILP (Vw32_downcase_file_names)) | 639 | if (!NILP (Vw32_downcase_file_names)) |
| 638 | directory = Fdowncase (directory); | 640 | directory = Fdowncase (directory); |
| 639 | #endif | 641 | #endif |
| 640 | buf = alloca (SBYTES (directory) + 20); | 642 | buf = SAFE_ALLOCA (SBYTES (directory) + 1); |
| 641 | length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), | 643 | length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), |
| 642 | STRING_MULTIBYTE (directory)); | 644 | STRING_MULTIBYTE (directory)); |
| 643 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); | 645 | val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); |
| 646 | SAFE_FREE (); | ||
| 647 | return val; | ||
| 644 | } | 648 | } |
| 645 | 649 | ||
| 646 | static const char make_temp_name_tbl[64] = | 650 | static const char make_temp_name_tbl[64] = |
| @@ -838,6 +842,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 838 | Lisp_Object handler, result, handled_name; | 842 | Lisp_Object handler, result, handled_name; |
| 839 | bool multibyte; | 843 | bool multibyte; |
| 840 | Lisp_Object hdir; | 844 | Lisp_Object hdir; |
| 845 | USE_SAFE_ALLOCA; | ||
| 841 | 846 | ||
| 842 | CHECK_STRING (name); | 847 | CHECK_STRING (name); |
| 843 | 848 | ||
| @@ -944,8 +949,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 944 | #endif | 949 | #endif |
| 945 | 950 | ||
| 946 | /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ | 951 | /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ |
| 947 | nm = alloca (SBYTES (name) + 1); | 952 | nm = xlispstrdupa (name); |
| 948 | memcpy (nm, SSDATA (name), SBYTES (name) + 1); | ||
| 949 | 953 | ||
| 950 | #ifdef DOS_NT | 954 | #ifdef DOS_NT |
| 951 | /* Note if special escape prefix is present, but remove for now. */ | 955 | /* Note if special escape prefix is present, but remove for now. */ |
| @@ -1013,11 +1017,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1013 | || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) | 1017 | || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) |
| 1014 | || p[3] == 0)))) | 1018 | || p[3] == 0)))) |
| 1015 | lose = 1; | 1019 | lose = 1; |
| 1016 | /* We want to replace multiple `/' in a row with a single | 1020 | /* Replace multiple slashes with a single one, except |
| 1017 | slash. */ | 1021 | leave leading "//" alone. */ |
| 1018 | else if (p > nm | 1022 | else if (IS_DIRECTORY_SEP (p[0]) |
| 1019 | && IS_DIRECTORY_SEP (p[0]) | 1023 | && IS_DIRECTORY_SEP (p[1]) |
| 1020 | && IS_DIRECTORY_SEP (p[1])) | 1024 | && (p != nm || IS_DIRECTORY_SEP (p[2]))) |
| 1021 | lose = 1; | 1025 | lose = 1; |
| 1022 | p++; | 1026 | p++; |
| 1023 | } | 1027 | } |
| @@ -1100,10 +1104,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1100 | else /* ~user/filename */ | 1104 | else /* ~user/filename */ |
| 1101 | { | 1105 | { |
| 1102 | char *o, *p; | 1106 | char *o, *p; |
| 1103 | for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++); | 1107 | for (p = nm; *p && !IS_DIRECTORY_SEP (*p); p++) |
| 1104 | o = alloca (p - nm + 1); | 1108 | continue; |
| 1109 | o = SAFE_ALLOCA (p - nm + 1); | ||
| 1105 | memcpy (o, nm, p - nm); | 1110 | memcpy (o, nm, p - nm); |
| 1106 | o [p - nm] = 0; | 1111 | o[p - nm] = 0; |
| 1107 | 1112 | ||
| 1108 | block_input (); | 1113 | block_input (); |
| 1109 | pw = getpwnam (o + 1); | 1114 | pw = getpwnam (o + 1); |
| @@ -1219,7 +1224,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1219 | if (!IS_DIRECTORY_SEP (nm[0])) | 1224 | if (!IS_DIRECTORY_SEP (nm[0])) |
| 1220 | { | 1225 | { |
| 1221 | ptrdiff_t newlen = strlen (newdir); | 1226 | ptrdiff_t newlen = strlen (newdir); |
| 1222 | char *tmp = alloca (newlen + strlen (nm) + 2); | 1227 | char *tmp = alloca (newlen + file_name_as_directory_slop |
| 1228 | + strlen (nm) + 1); | ||
| 1223 | file_name_as_directory (tmp, newdir, newlen, multibyte); | 1229 | file_name_as_directory (tmp, newdir, newlen, multibyte); |
| 1224 | strcat (tmp, nm); | 1230 | strcat (tmp, nm); |
| 1225 | nm = tmp; | 1231 | nm = tmp; |
| @@ -1273,31 +1279,18 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1273 | 1279 | ||
| 1274 | if (newdir) | 1280 | if (newdir) |
| 1275 | { | 1281 | { |
| 1276 | /* Get rid of any slash at the end of newdir, unless newdir is | 1282 | /* Ignore any slash at the end of newdir, unless newdir is |
| 1277 | just / or // (an incomplete UNC name). */ | 1283 | just "/" or "//". */ |
| 1278 | length = strlen (newdir); | 1284 | length = strlen (newdir); |
| 1279 | tlen = length + 1; | 1285 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
| 1280 | if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1286 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) |
| 1281 | #ifdef WINDOWSNT | 1287 | length--; |
| 1282 | && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) | ||
| 1283 | #endif | ||
| 1284 | ) | ||
| 1285 | { | ||
| 1286 | char *temp = alloca (length); | ||
| 1287 | memcpy (temp, newdir, length - 1); | ||
| 1288 | temp[length - 1] = 0; | ||
| 1289 | length--; | ||
| 1290 | newdir = temp; | ||
| 1291 | } | ||
| 1292 | } | 1288 | } |
| 1293 | else | 1289 | else |
| 1294 | { | 1290 | length = 0; |
| 1295 | length = 0; | ||
| 1296 | tlen = 0; | ||
| 1297 | } | ||
| 1298 | 1291 | ||
| 1299 | /* Now concatenate the directory and name to new space in the stack frame. */ | 1292 | /* Now concatenate the directory and name to new space in the stack frame. */ |
| 1300 | tlen += strlen (nm) + 1; | 1293 | tlen = length + file_name_as_directory_slop + strlen (nm) + 1; |
| 1301 | #ifdef DOS_NT | 1294 | #ifdef DOS_NT |
| 1302 | /* Reserve space for drive specifier and escape prefix, since either | 1295 | /* Reserve space for drive specifier and escape prefix, since either |
| 1303 | or both may need to be inserted. (The Microsoft x86 compiler | 1296 | or both may need to be inserted. (The Microsoft x86 compiler |
| @@ -1305,7 +1298,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1305 | target = alloca (tlen + 4); | 1298 | target = alloca (tlen + 4); |
| 1306 | target += 4; | 1299 | target += 4; |
| 1307 | #else /* not DOS_NT */ | 1300 | #else /* not DOS_NT */ |
| 1308 | target = alloca (tlen); | 1301 | target = SAFE_ALLOCA (tlen); |
| 1309 | #endif /* not DOS_NT */ | 1302 | #endif /* not DOS_NT */ |
| 1310 | *target = 0; | 1303 | *target = 0; |
| 1311 | 1304 | ||
| @@ -1322,7 +1315,10 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1322 | if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) | 1315 | if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) |
| 1323 | && newdir[1] == '\0')) | 1316 | && newdir[1] == '\0')) |
| 1324 | #endif | 1317 | #endif |
| 1325 | strcpy (target, newdir); | 1318 | { |
| 1319 | memcpy (target, newdir, length); | ||
| 1320 | target[length] = 0; | ||
| 1321 | } | ||
| 1326 | } | 1322 | } |
| 1327 | else | 1323 | else |
| 1328 | file_name_as_directory (target, newdir, length, multibyte); | 1324 | file_name_as_directory (target, newdir, length, multibyte); |
| @@ -1382,8 +1378,9 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1382 | ++o; | 1378 | ++o; |
| 1383 | p += 3; | 1379 | p += 3; |
| 1384 | } | 1380 | } |
| 1385 | else if (p > target && IS_DIRECTORY_SEP (p[1])) | 1381 | else if (IS_DIRECTORY_SEP (p[1]) |
| 1386 | /* Collapse multiple `/' in a row. */ | 1382 | && (p != target || IS_DIRECTORY_SEP (p[2]))) |
| 1383 | /* Collapse multiple "/", except leave leading "//" alone. */ | ||
| 1387 | p++; | 1384 | p++; |
| 1388 | else | 1385 | else |
| 1389 | { | 1386 | { |
| @@ -1431,11 +1428,12 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1431 | { | 1428 | { |
| 1432 | handled_name = call3 (handler, Qexpand_file_name, | 1429 | handled_name = call3 (handler, Qexpand_file_name, |
| 1433 | result, default_directory); | 1430 | result, default_directory); |
| 1434 | if (STRINGP (handled_name)) | 1431 | if (! STRINGP (handled_name)) |
| 1435 | return handled_name; | 1432 | error ("Invalid handler in `file-name-handler-alist'"); |
| 1436 | error ("Invalid handler in `file-name-handler-alist'"); | 1433 | result = handled_name; |
| 1437 | } | 1434 | } |
| 1438 | 1435 | ||
| 1436 | SAFE_FREE (); | ||
| 1439 | return result; | 1437 | return result; |
| 1440 | } | 1438 | } |
| 1441 | 1439 | ||
| @@ -1693,8 +1691,7 @@ those `/' is discarded. */) | |||
| 1693 | /* Always work on a copy of the string, in case GC happens during | 1691 | /* Always work on a copy of the string, in case GC happens during |
| 1694 | decode of environment variables, causing the original Lisp_String | 1692 | decode of environment variables, causing the original Lisp_String |
| 1695 | data to be relocated. */ | 1693 | data to be relocated. */ |
| 1696 | nm = alloca (SBYTES (filename) + 1); | 1694 | nm = xlispstrdupa (filename); |
| 1697 | memcpy (nm, SDATA (filename), SBYTES (filename) + 1); | ||
| 1698 | 1695 | ||
| 1699 | #ifdef DOS_NT | 1696 | #ifdef DOS_NT |
| 1700 | dostounix_filename (nm, multibyte); | 1697 | dostounix_filename (nm, multibyte); |
| @@ -2048,7 +2045,7 @@ entries (depending on how Emacs was built). */) | |||
| 2048 | /* CopyFile retains the timestamp by default. */ | 2045 | /* CopyFile retains the timestamp by default. */ |
| 2049 | else if (NILP (keep_time)) | 2046 | else if (NILP (keep_time)) |
| 2050 | { | 2047 | { |
| 2051 | EMACS_TIME now; | 2048 | struct timespec now; |
| 2052 | DWORD attributes; | 2049 | DWORD attributes; |
| 2053 | char * filename; | 2050 | char * filename; |
| 2054 | 2051 | ||
| @@ -2057,7 +2054,7 @@ entries (depending on how Emacs was built). */) | |||
| 2057 | /* Ensure file is writable while its modified time is set. */ | 2054 | /* Ensure file is writable while its modified time is set. */ |
| 2058 | attributes = GetFileAttributes (filename); | 2055 | attributes = GetFileAttributes (filename); |
| 2059 | SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY); | 2056 | SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY); |
| 2060 | now = current_emacs_time (); | 2057 | now = current_timespec (); |
| 2061 | if (set_file_times (-1, filename, now, now)) | 2058 | if (set_file_times (-1, filename, now, now)) |
| 2062 | { | 2059 | { |
| 2063 | /* Restore original attributes. */ | 2060 | /* Restore original attributes. */ |
| @@ -2181,8 +2178,8 @@ entries (depending on how Emacs was built). */) | |||
| 2181 | 2178 | ||
| 2182 | if (!NILP (keep_time)) | 2179 | if (!NILP (keep_time)) |
| 2183 | { | 2180 | { |
| 2184 | EMACS_TIME atime = get_stat_atime (&st); | 2181 | struct timespec atime = get_stat_atime (&st); |
| 2185 | EMACS_TIME mtime = get_stat_mtime (&st); | 2182 | struct timespec mtime = get_stat_mtime (&st); |
| 2186 | if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime)) | 2183 | if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime)) |
| 2187 | xsignal2 (Qfile_date_error, | 2184 | xsignal2 (Qfile_date_error, |
| 2188 | build_string ("Cannot set file date"), newname); | 2185 | build_string ("Cannot set file date"), newname); |
| @@ -3289,7 +3286,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of | |||
| 3289 | { | 3286 | { |
| 3290 | Lisp_Object absname, encoded_absname; | 3287 | Lisp_Object absname, encoded_absname; |
| 3291 | Lisp_Object handler; | 3288 | Lisp_Object handler; |
| 3292 | EMACS_TIME t = lisp_time_argument (timestamp); | 3289 | struct timespec t = lisp_time_argument (timestamp); |
| 3293 | 3290 | ||
| 3294 | absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); | 3291 | absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); |
| 3295 | 3292 | ||
| @@ -3366,7 +3363,7 @@ otherwise, if FILE2 does not exist, the answer is t. */) | |||
| 3366 | if (stat (SSDATA (absname2), &st2) < 0) | 3363 | if (stat (SSDATA (absname2), &st2) < 0) |
| 3367 | return Qt; | 3364 | return Qt; |
| 3368 | 3365 | ||
| 3369 | return (EMACS_TIME_LT (get_stat_mtime (&st2), get_stat_mtime (&st1)) | 3366 | return (timespec_cmp (get_stat_mtime (&st2), get_stat_mtime (&st1)) < 0 |
| 3370 | ? Qt : Qnil); | 3367 | ? Qt : Qnil); |
| 3371 | } | 3368 | } |
| 3372 | 3369 | ||
| @@ -3466,13 +3463,13 @@ file_offset (Lisp_Object val) | |||
| 3466 | } | 3463 | } |
| 3467 | 3464 | ||
| 3468 | /* Return a special time value indicating the error number ERRNUM. */ | 3465 | /* Return a special time value indicating the error number ERRNUM. */ |
| 3469 | static EMACS_TIME | 3466 | static struct timespec |
| 3470 | time_error_value (int errnum) | 3467 | time_error_value (int errnum) |
| 3471 | { | 3468 | { |
| 3472 | int ns = (errnum == ENOENT || errnum == EACCES || errnum == ENOTDIR | 3469 | int ns = (errnum == ENOENT || errnum == EACCES || errnum == ENOTDIR |
| 3473 | ? NONEXISTENT_MODTIME_NSECS | 3470 | ? NONEXISTENT_MODTIME_NSECS |
| 3474 | : UNKNOWN_MODTIME_NSECS); | 3471 | : UNKNOWN_MODTIME_NSECS); |
| 3475 | return make_emacs_time (0, ns); | 3472 | return make_timespec (0, ns); |
| 3476 | } | 3473 | } |
| 3477 | 3474 | ||
| 3478 | DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, | 3475 | DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, |
| @@ -3504,7 +3501,7 @@ by calling `format-decode', which see. */) | |||
| 3504 | (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) | 3501 | (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) |
| 3505 | { | 3502 | { |
| 3506 | struct stat st; | 3503 | struct stat st; |
| 3507 | EMACS_TIME mtime; | 3504 | struct timespec mtime; |
| 3508 | int fd; | 3505 | int fd; |
| 3509 | ptrdiff_t inserted = 0; | 3506 | ptrdiff_t inserted = 0; |
| 3510 | ptrdiff_t how_much; | 3507 | ptrdiff_t how_much; |
| @@ -4570,7 +4567,7 @@ by calling `format-decode', which see. */) | |||
| 4570 | } | 4567 | } |
| 4571 | 4568 | ||
| 4572 | if (!NILP (visit) | 4569 | if (!NILP (visit) |
| 4573 | && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) | 4570 | && current_buffer->modtime.tv_nsec == NONEXISTENT_MODTIME_NSECS) |
| 4574 | { | 4571 | { |
| 4575 | /* If visiting nonexistent file, return nil. */ | 4572 | /* If visiting nonexistent file, return nil. */ |
| 4576 | report_file_errno ("Opening input file", orig_filename, save_errno); | 4573 | report_file_errno ("Opening input file", orig_filename, save_errno); |
| @@ -4746,25 +4743,39 @@ This does code conversion according to the value of | |||
| 4746 | 4743 | ||
| 4747 | This calls `write-region-annotate-functions' at the start, and | 4744 | This calls `write-region-annotate-functions' at the start, and |
| 4748 | `write-region-post-annotation-function' at the end. */) | 4745 | `write-region-post-annotation-function' at the end. */) |
| 4749 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) | 4746 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, |
| 4747 | Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) | ||
| 4748 | { | ||
| 4749 | return write_region (start, end, filename, append, visit, lockname, mustbenew, | ||
| 4750 | -1); | ||
| 4751 | } | ||
| 4752 | |||
| 4753 | /* Like Fwrite_region, except that if DESC is nonnegative, it is a file | ||
| 4754 | descriptor for FILENAME, so do not open or close FILENAME. */ | ||
| 4755 | |||
| 4756 | Lisp_Object | ||
| 4757 | write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, | ||
| 4758 | Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, | ||
| 4759 | Lisp_Object mustbenew, int desc) | ||
| 4750 | { | 4760 | { |
| 4751 | int desc; | ||
| 4752 | int open_flags; | 4761 | int open_flags; |
| 4753 | int mode; | 4762 | int mode; |
| 4754 | off_t offset IF_LINT (= 0); | 4763 | off_t offset IF_LINT (= 0); |
| 4764 | bool open_and_close_file = desc < 0; | ||
| 4755 | bool ok; | 4765 | bool ok; |
| 4756 | int save_errno = 0; | 4766 | int save_errno = 0; |
| 4757 | const char *fn; | 4767 | const char *fn; |
| 4758 | struct stat st; | 4768 | struct stat st; |
| 4759 | EMACS_TIME modtime; | 4769 | struct timespec modtime; |
| 4760 | ptrdiff_t count = SPECPDL_INDEX (); | 4770 | ptrdiff_t count = SPECPDL_INDEX (); |
| 4761 | ptrdiff_t count1; | 4771 | ptrdiff_t count1 IF_LINT (= 0); |
| 4762 | Lisp_Object handler; | 4772 | Lisp_Object handler; |
| 4763 | Lisp_Object visit_file; | 4773 | Lisp_Object visit_file; |
| 4764 | Lisp_Object annotations; | 4774 | Lisp_Object annotations; |
| 4765 | Lisp_Object encoded_filename; | 4775 | Lisp_Object encoded_filename; |
| 4766 | bool visiting = (EQ (visit, Qt) || STRINGP (visit)); | 4776 | bool visiting = (EQ (visit, Qt) || STRINGP (visit)); |
| 4767 | bool quietly = !NILP (visit); | 4777 | bool quietly = !NILP (visit); |
| 4778 | bool file_locked = 0; | ||
| 4768 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 4779 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 4769 | struct buffer *given_buffer; | 4780 | struct buffer *given_buffer; |
| 4770 | struct coding_system coding; | 4781 | struct coding_system coding; |
| @@ -4832,7 +4843,6 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4832 | record_unwind_protect (build_annotations_unwind, | 4843 | record_unwind_protect (build_annotations_unwind, |
| 4833 | Vwrite_region_annotation_buffers); | 4844 | Vwrite_region_annotation_buffers); |
| 4834 | Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ()); | 4845 | Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ()); |
| 4835 | count1 = SPECPDL_INDEX (); | ||
| 4836 | 4846 | ||
| 4837 | given_buffer = current_buffer; | 4847 | given_buffer = current_buffer; |
| 4838 | 4848 | ||
| @@ -4871,8 +4881,11 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4871 | coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; | 4881 | coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; |
| 4872 | 4882 | ||
| 4873 | #ifdef CLASH_DETECTION | 4883 | #ifdef CLASH_DETECTION |
| 4874 | if (!auto_saving) | 4884 | if (open_and_close_file && !auto_saving) |
| 4875 | lock_file (lockname); | 4885 | { |
| 4886 | lock_file (lockname); | ||
| 4887 | file_locked = 1; | ||
| 4888 | } | ||
| 4876 | #endif /* CLASH_DETECTION */ | 4889 | #endif /* CLASH_DETECTION */ |
| 4877 | 4890 | ||
| 4878 | encoded_filename = ENCODE_FILE (filename); | 4891 | encoded_filename = ENCODE_FILE (filename); |
| @@ -4889,19 +4902,23 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4889 | mode = auto_saving ? auto_save_mode_bits : 0666; | 4902 | mode = auto_saving ? auto_save_mode_bits : 0666; |
| 4890 | #endif | 4903 | #endif |
| 4891 | 4904 | ||
| 4892 | desc = emacs_open (fn, open_flags, mode); | 4905 | if (open_and_close_file) |
| 4893 | |||
| 4894 | if (desc < 0) | ||
| 4895 | { | 4906 | { |
| 4896 | int open_errno = errno; | 4907 | desc = emacs_open (fn, open_flags, mode); |
| 4908 | if (desc < 0) | ||
| 4909 | { | ||
| 4910 | int open_errno = errno; | ||
| 4897 | #ifdef CLASH_DETECTION | 4911 | #ifdef CLASH_DETECTION |
| 4898 | if (!auto_saving) unlock_file (lockname); | 4912 | if (file_locked) |
| 4913 | unlock_file (lockname); | ||
| 4899 | #endif /* CLASH_DETECTION */ | 4914 | #endif /* CLASH_DETECTION */ |
| 4900 | UNGCPRO; | 4915 | UNGCPRO; |
| 4901 | report_file_errno ("Opening output file", filename, open_errno); | 4916 | report_file_errno ("Opening output file", filename, open_errno); |
| 4902 | } | 4917 | } |
| 4903 | 4918 | ||
| 4904 | record_unwind_protect_int (close_file_unwind, desc); | 4919 | count1 = SPECPDL_INDEX (); |
| 4920 | record_unwind_protect_int (close_file_unwind, desc); | ||
| 4921 | } | ||
| 4905 | 4922 | ||
| 4906 | if (NUMBERP (append)) | 4923 | if (NUMBERP (append)) |
| 4907 | { | 4924 | { |
| @@ -4910,7 +4927,8 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4910 | { | 4927 | { |
| 4911 | int lseek_errno = errno; | 4928 | int lseek_errno = errno; |
| 4912 | #ifdef CLASH_DETECTION | 4929 | #ifdef CLASH_DETECTION |
| 4913 | if (!auto_saving) unlock_file (lockname); | 4930 | if (file_locked) |
| 4931 | unlock_file (lockname); | ||
| 4914 | #endif /* CLASH_DETECTION */ | 4932 | #endif /* CLASH_DETECTION */ |
| 4915 | UNGCPRO; | 4933 | UNGCPRO; |
| 4916 | report_file_errno ("Lseek error", filename, lseek_errno); | 4934 | report_file_errno ("Lseek error", filename, lseek_errno); |
| @@ -4945,9 +4963,9 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4945 | 4963 | ||
| 4946 | immediate_quit = 0; | 4964 | immediate_quit = 0; |
| 4947 | 4965 | ||
| 4948 | /* fsync is not crucial for auto-save files, since they might lose | 4966 | /* fsync is not crucial for temporary files. Nor for auto-save |
| 4949 | some work anyway. */ | 4967 | files, since they might lose some work anyway. */ |
| 4950 | if (!auto_saving && !write_region_inhibit_fsync) | 4968 | if (open_and_close_file && !auto_saving && !write_region_inhibit_fsync) |
| 4951 | { | 4969 | { |
| 4952 | /* Transfer data and metadata to disk, retrying if interrupted. | 4970 | /* Transfer data and metadata to disk, retrying if interrupted. |
| 4953 | fsync can report a write failure here, e.g., due to disk full | 4971 | fsync can report a write failure here, e.g., due to disk full |
| @@ -4962,7 +4980,7 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4962 | } | 4980 | } |
| 4963 | } | 4981 | } |
| 4964 | 4982 | ||
| 4965 | modtime = invalid_emacs_time (); | 4983 | modtime = invalid_timespec (); |
| 4966 | if (visiting) | 4984 | if (visiting) |
| 4967 | { | 4985 | { |
| 4968 | if (fstat (desc, &st) == 0) | 4986 | if (fstat (desc, &st) == 0) |
| @@ -4971,12 +4989,15 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4971 | ok = 0, save_errno = errno; | 4989 | ok = 0, save_errno = errno; |
| 4972 | } | 4990 | } |
| 4973 | 4991 | ||
| 4974 | /* NFS can report a write failure now. */ | 4992 | if (open_and_close_file) |
| 4975 | if (emacs_close (desc) < 0) | 4993 | { |
| 4976 | ok = 0, save_errno = errno; | 4994 | /* NFS can report a write failure now. */ |
| 4995 | if (emacs_close (desc) < 0) | ||
| 4996 | ok = 0, save_errno = errno; | ||
| 4977 | 4997 | ||
| 4978 | /* Discard the unwind protect for close_file_unwind. */ | 4998 | /* Discard the unwind protect for close_file_unwind. */ |
| 4979 | specpdl_ptr = specpdl + count1; | 4999 | specpdl_ptr = specpdl + count1; |
| 5000 | } | ||
| 4980 | 5001 | ||
| 4981 | /* Some file systems have a bug where st_mtime is not updated | 5002 | /* Some file systems have a bug where st_mtime is not updated |
| 4982 | properly after a write. For example, CIFS might not see the | 5003 | properly after a write. For example, CIFS might not see the |
| @@ -4993,7 +5014,7 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4993 | unlikely and a similar race between the last write and the fstat | 5014 | unlikely and a similar race between the last write and the fstat |
| 4994 | above cannot possibly be closed anyway. */ | 5015 | above cannot possibly be closed anyway. */ |
| 4995 | 5016 | ||
| 4996 | if (EMACS_TIME_VALID_P (modtime) | 5017 | if (timespec_valid_p (modtime) |
| 4997 | && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system)) | 5018 | && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system)) |
| 4998 | { | 5019 | { |
| 4999 | int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0); | 5020 | int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0); |
| @@ -5015,11 +5036,11 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 5015 | bool use_heuristic | 5036 | bool use_heuristic |
| 5016 | = ((open_flags & (O_EXCL | O_TRUNC)) != 0 | 5037 | = ((open_flags & (O_EXCL | O_TRUNC)) != 0 |
| 5017 | && st.st_size != 0 | 5038 | && st.st_size != 0 |
| 5018 | && EMACS_NSECS (modtime) % 100 != 0); | 5039 | && modtime.tv_nsec % 100 != 0); |
| 5019 | 5040 | ||
| 5020 | EMACS_TIME modtime1 = get_stat_mtime (&st1); | 5041 | struct timespec modtime1 = get_stat_mtime (&st1); |
| 5021 | if (use_heuristic | 5042 | if (use_heuristic |
| 5022 | && EMACS_TIME_EQ (modtime, modtime1) | 5043 | && timespec_cmp (modtime, modtime1) == 0 |
| 5023 | && st.st_size == st1.st_size) | 5044 | && st.st_size == st1.st_size) |
| 5024 | { | 5045 | { |
| 5025 | timestamp_file_system = st.st_dev; | 5046 | timestamp_file_system = st.st_dev; |
| @@ -5052,14 +5073,14 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 5052 | unbind_to (count, Qnil); | 5073 | unbind_to (count, Qnil); |
| 5053 | 5074 | ||
| 5054 | #ifdef CLASH_DETECTION | 5075 | #ifdef CLASH_DETECTION |
| 5055 | if (!auto_saving) | 5076 | if (file_locked) |
| 5056 | unlock_file (lockname); | 5077 | unlock_file (lockname); |
| 5057 | #endif /* CLASH_DETECTION */ | 5078 | #endif /* CLASH_DETECTION */ |
| 5058 | 5079 | ||
| 5059 | /* Do this before reporting IO error | 5080 | /* Do this before reporting IO error |
| 5060 | to avoid a "file has changed on disk" warning on | 5081 | to avoid a "file has changed on disk" warning on |
| 5061 | next attempt to save. */ | 5082 | next attempt to save. */ |
| 5062 | if (EMACS_TIME_VALID_P (modtime)) | 5083 | if (timespec_valid_p (modtime)) |
| 5063 | { | 5084 | { |
| 5064 | current_buffer->modtime = modtime; | 5085 | current_buffer->modtime = modtime; |
| 5065 | current_buffer->modtime_size = st.st_size; | 5086 | current_buffer->modtime_size = st.st_size; |
| @@ -5334,7 +5355,7 @@ See Info node `(elisp)Modification Time' for more details. */) | |||
| 5334 | struct stat st; | 5355 | struct stat st; |
| 5335 | Lisp_Object handler; | 5356 | Lisp_Object handler; |
| 5336 | Lisp_Object filename; | 5357 | Lisp_Object filename; |
| 5337 | EMACS_TIME mtime; | 5358 | struct timespec mtime; |
| 5338 | 5359 | ||
| 5339 | if (NILP (buf)) | 5360 | if (NILP (buf)) |
| 5340 | b = current_buffer; | 5361 | b = current_buffer; |
| @@ -5345,7 +5366,7 @@ See Info node `(elisp)Modification Time' for more details. */) | |||
| 5345 | } | 5366 | } |
| 5346 | 5367 | ||
| 5347 | if (!STRINGP (BVAR (b, filename))) return Qt; | 5368 | if (!STRINGP (BVAR (b, filename))) return Qt; |
| 5348 | if (EMACS_NSECS (b->modtime) == UNKNOWN_MODTIME_NSECS) return Qt; | 5369 | if (b->modtime.tv_nsec == UNKNOWN_MODTIME_NSECS) return Qt; |
| 5349 | 5370 | ||
| 5350 | /* If the file name has special constructs in it, | 5371 | /* If the file name has special constructs in it, |
| 5351 | call the corresponding file handler. */ | 5372 | call the corresponding file handler. */ |
| @@ -5359,7 +5380,7 @@ See Info node `(elisp)Modification Time' for more details. */) | |||
| 5359 | mtime = (stat (SSDATA (filename), &st) == 0 | 5380 | mtime = (stat (SSDATA (filename), &st) == 0 |
| 5360 | ? get_stat_mtime (&st) | 5381 | ? get_stat_mtime (&st) |
| 5361 | : time_error_value (errno)); | 5382 | : time_error_value (errno)); |
| 5362 | if (EMACS_TIME_EQ (mtime, b->modtime) | 5383 | if (timespec_cmp (mtime, b->modtime) == 0 |
| 5363 | && (b->modtime_size < 0 | 5384 | && (b->modtime_size < 0 |
| 5364 | || st.st_size == b->modtime_size)) | 5385 | || st.st_size == b->modtime_size)) |
| 5365 | return Qt; | 5386 | return Qt; |
| @@ -5376,7 +5397,7 @@ doesn't exist, return -1. | |||
| 5376 | See Info node `(elisp)Modification Time' for more details. */) | 5397 | See Info node `(elisp)Modification Time' for more details. */) |
| 5377 | (void) | 5398 | (void) |
| 5378 | { | 5399 | { |
| 5379 | int ns = EMACS_NSECS (current_buffer->modtime); | 5400 | int ns = current_buffer->modtime.tv_nsec; |
| 5380 | if (ns < 0) | 5401 | if (ns < 0) |
| 5381 | return make_number (UNKNOWN_MODTIME_NSECS - ns); | 5402 | return make_number (UNKNOWN_MODTIME_NSECS - ns); |
| 5382 | return make_lisp_time (current_buffer->modtime); | 5403 | return make_lisp_time (current_buffer->modtime); |
| @@ -5395,11 +5416,11 @@ An argument specifies the modification time value to use | |||
| 5395 | { | 5416 | { |
| 5396 | if (!NILP (time_flag)) | 5417 | if (!NILP (time_flag)) |
| 5397 | { | 5418 | { |
| 5398 | EMACS_TIME mtime; | 5419 | struct timespec mtime; |
| 5399 | if (INTEGERP (time_flag)) | 5420 | if (INTEGERP (time_flag)) |
| 5400 | { | 5421 | { |
| 5401 | CHECK_RANGED_INTEGER (time_flag, -1, 0); | 5422 | CHECK_RANGED_INTEGER (time_flag, -1, 0); |
| 5402 | mtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag)); | 5423 | mtime = make_timespec (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag)); |
| 5403 | } | 5424 | } |
| 5404 | else | 5425 | else |
| 5405 | mtime = lisp_time_argument (time_flag); | 5426 | mtime = lisp_time_argument (time_flag); |
| @@ -5618,9 +5639,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) | |||
| 5618 | couldn't handle some ange-ftp'd file. */ | 5639 | couldn't handle some ange-ftp'd file. */ |
| 5619 | 5640 | ||
| 5620 | for (do_handled_files = 0; do_handled_files < 2; do_handled_files++) | 5641 | for (do_handled_files = 0; do_handled_files < 2; do_handled_files++) |
| 5621 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 5642 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 5622 | { | 5643 | { |
| 5623 | buf = XCDR (XCAR (tail)); | ||
| 5624 | b = XBUFFER (buf); | 5644 | b = XBUFFER (buf); |
| 5625 | 5645 | ||
| 5626 | /* Record all the buffers that have auto save mode | 5646 | /* Record all the buffers that have auto save mode |
| @@ -5663,12 +5683,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) | |||
| 5663 | || NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name), | 5683 | || NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name), |
| 5664 | Qwrite_region)))) | 5684 | Qwrite_region)))) |
| 5665 | { | 5685 | { |
| 5666 | EMACS_TIME before_time = current_emacs_time (); | 5686 | struct timespec before_time = current_timespec (); |
| 5667 | EMACS_TIME after_time; | 5687 | struct timespec after_time; |
| 5668 | 5688 | ||
| 5669 | /* If we had a failure, don't try again for 20 minutes. */ | 5689 | /* If we had a failure, don't try again for 20 minutes. */ |
| 5670 | if (b->auto_save_failure_time > 0 | 5690 | if (b->auto_save_failure_time > 0 |
| 5671 | && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200) | 5691 | && before_time.tv_sec - b->auto_save_failure_time < 1200) |
| 5672 | continue; | 5692 | continue; |
| 5673 | 5693 | ||
| 5674 | set_buffer_internal (b); | 5694 | set_buffer_internal (b); |
| @@ -5701,12 +5721,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) | |||
| 5701 | XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); | 5721 | XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); |
| 5702 | set_buffer_internal (old); | 5722 | set_buffer_internal (old); |
| 5703 | 5723 | ||
| 5704 | after_time = current_emacs_time (); | 5724 | after_time = current_timespec (); |
| 5705 | 5725 | ||
| 5706 | /* If auto-save took more than 60 seconds, | 5726 | /* If auto-save took more than 60 seconds, |
| 5707 | assume it was an NFS failure that got a timeout. */ | 5727 | assume it was an NFS failure that got a timeout. */ |
| 5708 | if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60) | 5728 | if (after_time.tv_sec - before_time.tv_sec > 60) |
| 5709 | b->auto_save_failure_time = EMACS_SECS (after_time); | 5729 | b->auto_save_failure_time = after_time.tv_sec; |
| 5710 | } | 5730 | } |
| 5711 | } | 5731 | } |
| 5712 | 5732 | ||
diff --git a/src/filelock.c b/src/filelock.c index b9c991e4baf..df72eff5950 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -181,7 +181,7 @@ get_boot_time (void) | |||
| 181 | since utmp is typically much smaller than wtmp. | 181 | since utmp is typically much smaller than wtmp. |
| 182 | Passing a null pointer causes get_boot_time_1 | 182 | Passing a null pointer causes get_boot_time_1 |
| 183 | to inspect the default file, namely utmp. */ | 183 | to inspect the default file, namely utmp. */ |
| 184 | get_boot_time_1 ((char *) 0, 0); | 184 | get_boot_time_1 (0, 0); |
| 185 | if (boot_time) | 185 | if (boot_time) |
| 186 | return boot_time; | 186 | return boot_time; |
| 187 | 187 | ||
| @@ -411,28 +411,14 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) | |||
| 411 | memcpy (nonce, lfname, lfdirlen); | 411 | memcpy (nonce, lfname, lfdirlen); |
| 412 | strcpy (nonce + lfdirlen, nonce_base); | 412 | strcpy (nonce + lfdirlen, nonce_base); |
| 413 | 413 | ||
| 414 | #if HAVE_MKOSTEMP | ||
| 415 | /* Prefer mkostemp to mkstemp, as it avoids a window where FD is | ||
| 416 | temporarily open without close-on-exec. */ | ||
| 417 | fd = mkostemp (nonce, O_BINARY | O_CLOEXEC); | 414 | fd = mkostemp (nonce, O_BINARY | O_CLOEXEC); |
| 418 | #elif HAVE_MKSTEMP | ||
| 419 | /* Prefer mkstemp to mktemp, as it avoids a race between | ||
| 420 | mktemp and emacs_open. */ | ||
| 421 | fd = mkstemp (nonce); | ||
| 422 | #else | ||
| 423 | mktemp (nonce); | ||
| 424 | fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, | ||
| 425 | S_IRUSR | S_IWUSR); | ||
| 426 | #endif | ||
| 427 | |||
| 428 | if (fd < 0) | 415 | if (fd < 0) |
| 429 | err = errno; | 416 | err = errno; |
| 430 | else | 417 | else |
| 431 | { | 418 | { |
| 432 | ptrdiff_t lock_info_len; | 419 | ptrdiff_t lock_info_len; |
| 433 | #if ! (HAVE_MKOSTEMP && O_CLOEXEC) | 420 | if (! O_CLOEXEC) |
| 434 | fcntl (fd, F_SETFD, FD_CLOEXEC); | 421 | fcntl (fd, F_SETFD, FD_CLOEXEC); |
| 435 | #endif | ||
| 436 | lock_info_len = strlen (lock_info_str); | 422 | lock_info_len = strlen (lock_info_str); |
| 437 | err = 0; | 423 | err = 0; |
| 438 | /* Use 'write', not 'emacs_write', as garbage collection | 424 | /* Use 'write', not 'emacs_write', as garbage collection |
| @@ -759,16 +745,15 @@ unlock_file (Lisp_Object fn) | |||
| 759 | void | 745 | void |
| 760 | unlock_all_files (void) | 746 | unlock_all_files (void) |
| 761 | { | 747 | { |
| 762 | register Lisp_Object tail; | 748 | register Lisp_Object tail, buf; |
| 763 | register struct buffer *b; | 749 | register struct buffer *b; |
| 764 | 750 | ||
| 765 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) | 751 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 766 | { | 752 | { |
| 767 | b = XBUFFER (XCDR (XCAR (tail))); | 753 | b = XBUFFER (buf); |
| 768 | if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) | 754 | if (STRINGP (BVAR (b, file_truename)) |
| 769 | { | 755 | && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) |
| 770 | unlock_file (BVAR (b, file_truename)); | 756 | unlock_file (BVAR (b, file_truename)); |
| 771 | } | ||
| 772 | } | 757 | } |
| 773 | } | 758 | } |
| 774 | 759 | ||
diff --git a/src/font.c b/src/font.c index 073487b540d..6a8262623dc 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -4226,36 +4226,38 @@ the consecutive wildcards are folded into one. */) | |||
| 4226 | return make_string (name, namelen); | 4226 | return make_string (name, namelen); |
| 4227 | } | 4227 | } |
| 4228 | 4228 | ||
| 4229 | void | ||
| 4230 | clear_font_cache (struct frame *f) | ||
| 4231 | { | ||
| 4232 | struct font_driver_list *driver_list = f->font_driver_list; | ||
| 4233 | |||
| 4234 | for (; driver_list; driver_list = driver_list->next) | ||
| 4235 | if (driver_list->on) | ||
| 4236 | { | ||
| 4237 | Lisp_Object val, tmp, cache = driver_list->driver->get_cache (f); | ||
| 4238 | |||
| 4239 | val = XCDR (cache); | ||
| 4240 | while (! NILP (val) | ||
| 4241 | && ! EQ (XCAR (XCAR (val)), driver_list->driver->type)) | ||
| 4242 | val = XCDR (val); | ||
| 4243 | eassert (! NILP (val)); | ||
| 4244 | tmp = XCDR (XCAR (val)); | ||
| 4245 | if (XINT (XCAR (tmp)) == 0) | ||
| 4246 | { | ||
| 4247 | font_clear_cache (f, XCAR (val), driver_list->driver); | ||
| 4248 | XSETCDR (cache, XCDR (val)); | ||
| 4249 | } | ||
| 4250 | } | ||
| 4251 | } | ||
| 4252 | |||
| 4229 | DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0, | 4253 | DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0, |
| 4230 | doc: /* Clear font cache. */) | 4254 | doc: /* Clear font cache of each frame. */) |
| 4231 | (void) | 4255 | (void) |
| 4232 | { | 4256 | { |
| 4233 | Lisp_Object list, frame; | 4257 | Lisp_Object list, frame; |
| 4234 | 4258 | ||
| 4235 | FOR_EACH_FRAME (list, frame) | 4259 | FOR_EACH_FRAME (list, frame) |
| 4236 | { | 4260 | clear_font_cache (XFRAME (frame)); |
| 4237 | struct frame *f = XFRAME (frame); | ||
| 4238 | struct font_driver_list *driver_list = f->font_driver_list; | ||
| 4239 | |||
| 4240 | for (; driver_list; driver_list = driver_list->next) | ||
| 4241 | if (driver_list->on) | ||
| 4242 | { | ||
| 4243 | Lisp_Object cache = driver_list->driver->get_cache (f); | ||
| 4244 | Lisp_Object val, tmp; | ||
| 4245 | |||
| 4246 | val = XCDR (cache); | ||
| 4247 | while (! NILP (val) | ||
| 4248 | && ! EQ (XCAR (XCAR (val)), driver_list->driver->type)) | ||
| 4249 | val = XCDR (val); | ||
| 4250 | eassert (! NILP (val)); | ||
| 4251 | tmp = XCDR (XCAR (val)); | ||
| 4252 | if (XINT (XCAR (tmp)) == 0) | ||
| 4253 | { | ||
| 4254 | font_clear_cache (f, XCAR (val), driver_list->driver); | ||
| 4255 | XSETCDR (cache, XCDR (val)); | ||
| 4256 | } | ||
| 4257 | } | ||
| 4258 | } | ||
| 4259 | 4261 | ||
| 4260 | return Qnil; | 4262 | return Qnil; |
| 4261 | } | 4263 | } |
diff --git a/src/font.h b/src/font.h index daeb320c1ab..3ee579aba2b 100644 --- a/src/font.h +++ b/src/font.h | |||
| @@ -56,11 +56,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 56 | 56 | ||
| 57 | extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; | 57 | extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; |
| 58 | 58 | ||
| 59 | |||
| 60 | struct font_driver; | ||
| 61 | struct font; | ||
| 62 | struct glyph_string; | ||
| 63 | |||
| 64 | /* An enumerator for each font property. This is used as an index to | 59 | /* An enumerator for each font property. This is used as an index to |
| 65 | the vector of FONT-SPEC and FONT-ENTITY. | 60 | the vector of FONT-SPEC and FONT-ENTITY. |
| 66 | 61 | ||
| @@ -487,8 +482,6 @@ struct font_bitmap | |||
| 487 | this value. */ | 482 | this value. */ |
| 488 | #define FONT_PIXEL_SIZE_QUANTUM 1 | 483 | #define FONT_PIXEL_SIZE_QUANTUM 1 |
| 489 | 484 | ||
| 490 | struct face; | ||
| 491 | |||
| 492 | #define FONT_INVALID_CODE 0xFFFFFFFF | 485 | #define FONT_INVALID_CODE 0xFFFFFFFF |
| 493 | 486 | ||
| 494 | /* Font driver. Members specified as "optional" can be NULL. */ | 487 | /* Font driver. Members specified as "optional" can be NULL. */ |
| @@ -760,6 +753,7 @@ extern Lisp_Object font_load_for_lface (struct frame *f, Lisp_Object *lface, | |||
| 760 | Lisp_Object spec); | 753 | Lisp_Object spec); |
| 761 | extern void font_prepare_for_face (struct frame *f, struct face *face); | 754 | extern void font_prepare_for_face (struct frame *f, struct face *face); |
| 762 | extern void font_done_for_face (struct frame *f, struct face *face); | 755 | extern void font_done_for_face (struct frame *f, struct face *face); |
| 756 | extern void clear_font_cache (struct frame *); | ||
| 763 | 757 | ||
| 764 | extern Lisp_Object font_open_by_spec (struct frame *f, Lisp_Object spec); | 758 | extern Lisp_Object font_open_by_spec (struct frame *f, Lisp_Object spec); |
| 765 | extern Lisp_Object font_open_by_name (struct frame *f, Lisp_Object name); | 759 | extern Lisp_Object font_open_by_name (struct frame *f, Lisp_Object name); |
diff --git a/src/fontset.c b/src/fontset.c index 0bf716bf1b2..a6277b050d5 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -944,6 +944,19 @@ face_for_char (struct frame *f, struct face *face, int c, int pos, Lisp_Object o | |||
| 944 | if (ASCII_CHAR_P (c) || face->fontset < 0) | 944 | if (ASCII_CHAR_P (c) || face->fontset < 0) |
| 945 | return face->ascii_face->id; | 945 | return face->ascii_face->id; |
| 946 | 946 | ||
| 947 | #ifdef HAVE_NS | ||
| 948 | if (face->font) | ||
| 949 | { | ||
| 950 | /* Fonts often have characters in other scripts, like symbol, even if they | ||
| 951 | don't match script: symbol. So check if the character is present | ||
| 952 | in the current face first. Only enable for NS for now, but should | ||
| 953 | perhaps be general? */ | ||
| 954 | Lisp_Object font_object; | ||
| 955 | XSETFONT (font_object, face->font); | ||
| 956 | if (font_has_char (f, font_object, c)) return face->id; | ||
| 957 | } | ||
| 958 | #endif | ||
| 959 | |||
| 947 | eassert (fontset_id_valid_p (face->fontset)); | 960 | eassert (fontset_id_valid_p (face->fontset)); |
| 948 | fontset = FONTSET_FROM_ID (face->fontset); | 961 | fontset = FONTSET_FROM_ID (face->fontset); |
| 949 | eassert (!BASE_FONTSET_P (fontset)); | 962 | eassert (!BASE_FONTSET_P (fontset)); |
diff --git a/src/fontset.h b/src/fontset.h index fd16c7178f5..b8ef4789e71 100644 --- a/src/fontset.h +++ b/src/fontset.h | |||
| @@ -26,8 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #ifndef EMACS_FONTSET_H | 26 | #ifndef EMACS_FONTSET_H |
| 27 | #define EMACS_FONTSET_H | 27 | #define EMACS_FONTSET_H |
| 28 | 28 | ||
| 29 | struct face; | ||
| 30 | |||
| 31 | extern void free_face_fontset (struct frame *, struct face *); | 29 | extern void free_face_fontset (struct frame *, struct face *); |
| 32 | extern int face_for_char (struct frame *, struct face *, int, | 30 | extern int face_for_char (struct frame *, struct face *, int, |
| 33 | int, Lisp_Object); | 31 | int, Lisp_Object); |
| @@ -42,7 +40,6 @@ extern Lisp_Object Qlatin; | |||
| 42 | extern Lisp_Object fontset_name (int); | 40 | extern Lisp_Object fontset_name (int); |
| 43 | extern Lisp_Object fontset_ascii (int); | 41 | extern Lisp_Object fontset_ascii (int); |
| 44 | 42 | ||
| 45 | struct font; | ||
| 46 | extern int face_for_font (struct frame *, Lisp_Object, struct face *); | 43 | extern int face_for_font (struct frame *, Lisp_Object, struct face *); |
| 47 | 44 | ||
| 48 | #endif /* EMACS_FONTSET_H */ | 45 | #endif /* EMACS_FONTSET_H */ |
diff --git a/src/frame.c b/src/frame.c index 14fc15c4717..d11a6b8fee9 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -185,7 +185,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n) | |||
| 185 | { | 185 | { |
| 186 | struct window *w = XWINDOW (window); | 186 | struct window *w = XWINDOW (window); |
| 187 | 187 | ||
| 188 | w->last_modified = 0; | ||
| 189 | w->top_line += n; | 188 | w->top_line += n; |
| 190 | w->total_lines -= n; | 189 | w->total_lines -= n; |
| 191 | 190 | ||
| @@ -693,24 +692,16 @@ affects all frames on the same terminal device. */) | |||
| 693 | ? FRAME_TTY (XFRAME (selected_frame))->name | 692 | ? FRAME_TTY (XFRAME (selected_frame))->name |
| 694 | : NULL)); | 693 | : NULL)); |
| 695 | if (!NILP (tty)) | 694 | if (!NILP (tty)) |
| 696 | { | 695 | name = xlispstrdupa (tty); |
| 697 | name = alloca (SBYTES (tty) + 1); | ||
| 698 | memcpy (name, SSDATA (tty), SBYTES (tty)); | ||
| 699 | name[SBYTES (tty)] = 0; | ||
| 700 | } | ||
| 701 | 696 | ||
| 702 | tty_type = get_future_frame_param | 697 | tty_type = get_future_frame_param |
| 703 | (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) | 698 | (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) |
| 704 | ? FRAME_TTY (XFRAME (selected_frame))->type | 699 | ? FRAME_TTY (XFRAME (selected_frame))->type |
| 705 | : NULL)); | 700 | : NULL)); |
| 706 | if (!NILP (tty_type)) | 701 | if (!NILP (tty_type)) |
| 707 | { | 702 | type = xlispstrdupa (tty_type); |
| 708 | type = alloca (SBYTES (tty_type) + 1); | ||
| 709 | memcpy (type, SSDATA (tty_type), SBYTES (tty_type)); | ||
| 710 | type[SBYTES (tty_type)] = 0; | ||
| 711 | } | ||
| 712 | 703 | ||
| 713 | t = init_tty (name, type, 0); /* Errors are not fatal. */ | 704 | t = init_tty (name, type, 0); /* Errors are not fatal. */ |
| 714 | } | 705 | } |
| 715 | 706 | ||
| 716 | f = make_terminal_frame (t); | 707 | f = make_terminal_frame (t); |
| @@ -726,7 +717,7 @@ affects all frames on the same terminal device. */) | |||
| 726 | XSETFRAME (frame, f); | 717 | XSETFRAME (frame, f); |
| 727 | 718 | ||
| 728 | store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); | 719 | store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); |
| 729 | store_in_alist (&parms, Qtty, | 720 | store_in_alist (&parms, Qtty, |
| 730 | (t->display_info.tty->name | 721 | (t->display_info.tty->name |
| 731 | ? build_string (t->display_info.tty->name) | 722 | ? build_string (t->display_info.tty->name) |
| 732 | : Qnil)); | 723 | : Qnil)); |
| @@ -1087,6 +1078,19 @@ Otherwise, include all frames. */) | |||
| 1087 | CHECK_LIVE_FRAME (frame); | 1078 | CHECK_LIVE_FRAME (frame); |
| 1088 | return prev_frame (frame, miniframe); | 1079 | return prev_frame (frame, miniframe); |
| 1089 | } | 1080 | } |
| 1081 | |||
| 1082 | DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, | ||
| 1083 | Slast_nonminibuf_frame, 0, 0, 0, | ||
| 1084 | doc: /* Return last non-minibuffer frame selected. */) | ||
| 1085 | (void) | ||
| 1086 | { | ||
| 1087 | Lisp_Object frame = Qnil; | ||
| 1088 | |||
| 1089 | if (last_nonminibuf_frame) | ||
| 1090 | XSETFRAME (frame, last_nonminibuf_frame); | ||
| 1091 | |||
| 1092 | return frame; | ||
| 1093 | } | ||
| 1090 | 1094 | ||
| 1091 | /* Return 1 if it is ok to delete frame F; | 1095 | /* Return 1 if it is ok to delete frame F; |
| 1092 | 0 if all frames aside from F are invisible. | 1096 | 0 if all frames aside from F are invisible. |
| @@ -1119,6 +1123,50 @@ other_visible_frames (struct frame *f) | |||
| 1119 | return 0; | 1123 | return 0; |
| 1120 | } | 1124 | } |
| 1121 | 1125 | ||
| 1126 | /* Make sure that minibuf_window doesn't refer to FRAME's minibuffer | ||
| 1127 | window. Preferably use the selected frame's minibuffer window | ||
| 1128 | instead. If the selected frame doesn't have one, get some other | ||
| 1129 | frame's minibuffer window. SELECT non-zero means select the new | ||
| 1130 | minibuffer window. */ | ||
| 1131 | static void | ||
| 1132 | check_minibuf_window (Lisp_Object frame, int select) | ||
| 1133 | { | ||
| 1134 | struct frame *f = decode_live_frame (frame); | ||
| 1135 | |||
| 1136 | if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window)) | ||
| 1137 | { | ||
| 1138 | Lisp_Object frames, this, window = make_number (0); | ||
| 1139 | |||
| 1140 | if (!EQ (frame, selected_frame) | ||
| 1141 | && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame))) | ||
| 1142 | window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame)); | ||
| 1143 | else | ||
| 1144 | FOR_EACH_FRAME (frames, this) | ||
| 1145 | { | ||
| 1146 | if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this))) | ||
| 1147 | { | ||
| 1148 | window = FRAME_MINIBUF_WINDOW (XFRAME (this)); | ||
| 1149 | break; | ||
| 1150 | } | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | /* Don't abort if no window was found (Bug#15247). */ | ||
| 1154 | if (WINDOWP (window)) | ||
| 1155 | { | ||
| 1156 | /* Use set_window_buffer instead of Fset_window_buffer (see | ||
| 1157 | discussion of bug#11984, bug#12025, bug#12026). */ | ||
| 1158 | set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0); | ||
| 1159 | minibuf_window = window; | ||
| 1160 | |||
| 1161 | /* SELECT non-zero usually means that FRAME's minibuffer | ||
| 1162 | window was selected; select the new one. */ | ||
| 1163 | if (select) | ||
| 1164 | Fselect_window (minibuf_window, Qnil); | ||
| 1165 | } | ||
| 1166 | } | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | |||
| 1122 | /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME | 1170 | /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME |
| 1123 | unconditionally. x_connection_closed and delete_terminal use | 1171 | unconditionally. x_connection_closed and delete_terminal use |
| 1124 | this. Any other value of FORCE implements the semantics | 1172 | this. Any other value of FORCE implements the semantics |
| @@ -1206,10 +1254,18 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1206 | /* Don't let the frame remain selected. */ | 1254 | /* Don't let the frame remain selected. */ |
| 1207 | if (f == sf) | 1255 | if (f == sf) |
| 1208 | { | 1256 | { |
| 1209 | Lisp_Object tail, frame1; | 1257 | Lisp_Object tail; |
| 1210 | 1258 | Lisp_Object frame1 = Qnil; | |
| 1211 | /* Look for another visible frame on the same terminal. */ | 1259 | |
| 1212 | frame1 = next_frame (frame, Qvisible); | 1260 | /* Look for another visible frame on the same terminal. |
| 1261 | Do not call next_frame here because it may loop forever. | ||
| 1262 | See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */ | ||
| 1263 | FOR_EACH_FRAME (tail, frame1) | ||
| 1264 | if (!EQ (frame, frame1) | ||
| 1265 | && (FRAME_TERMINAL (XFRAME (frame)) | ||
| 1266 | == FRAME_TERMINAL (XFRAME (frame1))) | ||
| 1267 | && FRAME_VISIBLE_P (XFRAME (frame1))) | ||
| 1268 | break; | ||
| 1213 | 1269 | ||
| 1214 | /* If there is none, find *some* other frame. */ | 1270 | /* If there is none, find *some* other frame. */ |
| 1215 | if (NILP (frame1) || EQ (frame1, frame)) | 1271 | if (NILP (frame1) || EQ (frame1, frame)) |
| @@ -1245,19 +1301,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1245 | } | 1301 | } |
| 1246 | 1302 | ||
| 1247 | /* Don't allow minibuf_window to remain on a deleted frame. */ | 1303 | /* Don't allow minibuf_window to remain on a deleted frame. */ |
| 1248 | if (EQ (f->minibuffer_window, minibuf_window)) | 1304 | check_minibuf_window (frame, minibuffer_selected); |
| 1249 | { | ||
| 1250 | /* Use set_window_buffer instead of Fset_window_buffer (see | ||
| 1251 | discussion of bug#11984, bug#12025, bug#12026). */ | ||
| 1252 | set_window_buffer (sf->minibuffer_window, | ||
| 1253 | XWINDOW (minibuf_window)->contents, 0, 0); | ||
| 1254 | minibuf_window = sf->minibuffer_window; | ||
| 1255 | |||
| 1256 | /* If the dying minibuffer window was selected, | ||
| 1257 | select the new one. */ | ||
| 1258 | if (minibuffer_selected) | ||
| 1259 | Fselect_window (minibuf_window, Qnil); | ||
| 1260 | } | ||
| 1261 | 1305 | ||
| 1262 | /* Don't let echo_area_window to remain on a deleted frame. */ | 1306 | /* Don't let echo_area_window to remain on a deleted frame. */ |
| 1263 | if (EQ (f->minibuffer_window, echo_area_window)) | 1307 | if (EQ (f->minibuffer_window, echo_area_window)) |
| @@ -1684,16 +1728,8 @@ displayed in the terminal. */) | |||
| 1684 | if (NILP (force) && !other_visible_frames (f)) | 1728 | if (NILP (force) && !other_visible_frames (f)) |
| 1685 | error ("Attempt to make invisible the sole visible or iconified frame"); | 1729 | error ("Attempt to make invisible the sole visible or iconified frame"); |
| 1686 | 1730 | ||
| 1687 | /* Don't allow minibuf_window to remain on a deleted frame. */ | 1731 | /* Don't allow minibuf_window to remain on an invisible frame. */ |
| 1688 | if (EQ (f->minibuffer_window, minibuf_window)) | 1732 | check_minibuf_window (frame, EQ (minibuf_window, selected_window)); |
| 1689 | { | ||
| 1690 | struct frame *sf = XFRAME (selected_frame); | ||
| 1691 | /* Use set_window_buffer instead of Fset_window_buffer (see | ||
| 1692 | discussion of bug#11984, bug#12025, bug#12026). */ | ||
| 1693 | set_window_buffer (sf->minibuffer_window, | ||
| 1694 | XWINDOW (minibuf_window)->contents, 0, 0); | ||
| 1695 | minibuf_window = sf->minibuffer_window; | ||
| 1696 | } | ||
| 1697 | 1733 | ||
| 1698 | /* I think this should be done with a hook. */ | 1734 | /* I think this should be done with a hook. */ |
| 1699 | #ifdef HAVE_WINDOW_SYSTEM | 1735 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -1716,15 +1752,7 @@ If omitted, FRAME defaults to the currently selected frame. */) | |||
| 1716 | struct frame *f = decode_live_frame (frame); | 1752 | struct frame *f = decode_live_frame (frame); |
| 1717 | 1753 | ||
| 1718 | /* Don't allow minibuf_window to remain on an iconified frame. */ | 1754 | /* Don't allow minibuf_window to remain on an iconified frame. */ |
| 1719 | if (EQ (f->minibuffer_window, minibuf_window)) | 1755 | check_minibuf_window (frame, EQ (minibuf_window, selected_window)); |
| 1720 | { | ||
| 1721 | struct frame *sf = XFRAME (selected_frame); | ||
| 1722 | /* Use set_window_buffer instead of Fset_window_buffer (see | ||
| 1723 | discussion of bug#11984, bug#12025, bug#12026). */ | ||
| 1724 | set_window_buffer (sf->minibuffer_window, | ||
| 1725 | XWINDOW (minibuf_window)->contents, 0, 0); | ||
| 1726 | minibuf_window = sf->minibuffer_window; | ||
| 1727 | } | ||
| 1728 | 1756 | ||
| 1729 | /* I think this should be done with a hook. */ | 1757 | /* I think this should be done with a hook. */ |
| 1730 | #ifdef HAVE_WINDOW_SYSTEM | 1758 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -3545,7 +3573,7 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li | |||
| 3545 | 3573 | ||
| 3546 | value = x_get_string_resource (rdb, name_key, class_key); | 3574 | value = x_get_string_resource (rdb, name_key, class_key); |
| 3547 | 3575 | ||
| 3548 | if (value != (char *) 0 && *value) | 3576 | if (value && *value) |
| 3549 | return build_string (value); | 3577 | return build_string (value); |
| 3550 | else | 3578 | else |
| 3551 | return Qnil; | 3579 | return Qnil; |
| @@ -4204,8 +4232,7 @@ make_monitor_attribute_list (struct MonitorInfo *monitors, | |||
| 4204 | mi->work.width, mi->work.height); | 4232 | mi->work.width, mi->work.height); |
| 4205 | geometry = list4i (mi->geom.x, mi->geom.y, | 4233 | geometry = list4i (mi->geom.x, mi->geom.y, |
| 4206 | mi->geom.width, mi->geom.height); | 4234 | mi->geom.width, mi->geom.height); |
| 4207 | attributes = Fcons (Fcons (Qsource, | 4235 | attributes = Fcons (Fcons (Qsource, build_string (source)), |
| 4208 | make_string (source, strlen (source))), | ||
| 4209 | attributes); | 4236 | attributes); |
| 4210 | attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), | 4237 | attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), |
| 4211 | attributes); | 4238 | attributes); |
| @@ -4478,6 +4505,7 @@ automatically. See also `mouse-autoselect-window'. */); | |||
| 4478 | defsubr (&Sframe_list); | 4505 | defsubr (&Sframe_list); |
| 4479 | defsubr (&Snext_frame); | 4506 | defsubr (&Snext_frame); |
| 4480 | defsubr (&Sprevious_frame); | 4507 | defsubr (&Sprevious_frame); |
| 4508 | defsubr (&Slast_nonminibuf_frame); | ||
| 4481 | defsubr (&Sdelete_frame); | 4509 | defsubr (&Sdelete_frame); |
| 4482 | defsubr (&Smouse_position); | 4510 | defsubr (&Smouse_position); |
| 4483 | defsubr (&Smouse_pixel_position); | 4511 | defsubr (&Smouse_pixel_position); |
diff --git a/src/frame.h b/src/frame.h index 33e4bb71d7a..17b6089120a 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -24,31 +24,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 24 | #define EMACS_FRAME_H | 24 | #define EMACS_FRAME_H |
| 25 | 25 | ||
| 26 | #include "dispextern.h" | 26 | #include "dispextern.h" |
| 27 | #include "termhooks.h" | ||
| 27 | 28 | ||
| 28 | INLINE_HEADER_BEGIN | 29 | INLINE_HEADER_BEGIN |
| 29 | #ifndef FRAME_INLINE | 30 | #ifndef FRAME_INLINE |
| 30 | # define FRAME_INLINE INLINE | 31 | # define FRAME_INLINE INLINE |
| 31 | #endif | 32 | #endif |
| 32 | 33 | ||
| 33 | |||
| 34 | /* Miscellanea. */ | ||
| 35 | |||
| 36 | /* Nonzero means there is at least one garbaged frame. */ | ||
| 37 | extern bool frame_garbaged; | ||
| 38 | |||
| 39 | |||
| 40 | /* The structure representing a frame. */ | ||
| 41 | |||
| 42 | enum output_method | ||
| 43 | { | ||
| 44 | output_initial, | ||
| 45 | output_termcap, | ||
| 46 | output_x_window, | ||
| 47 | output_msdos_raw, | ||
| 48 | output_w32, | ||
| 49 | output_ns | ||
| 50 | }; | ||
| 51 | |||
| 52 | enum vertical_scroll_bar_type | 34 | enum vertical_scroll_bar_type |
| 53 | { | 35 | { |
| 54 | vertical_scroll_bar_none, | 36 | vertical_scroll_bar_none, |
| @@ -56,16 +38,6 @@ enum vertical_scroll_bar_type | |||
| 56 | vertical_scroll_bar_right | 38 | vertical_scroll_bar_right |
| 57 | }; | 39 | }; |
| 58 | 40 | ||
| 59 | enum text_cursor_kinds | ||
| 60 | { | ||
| 61 | DEFAULT_CURSOR = -2, | ||
| 62 | NO_CURSOR = -1, | ||
| 63 | FILLED_BOX_CURSOR, | ||
| 64 | HOLLOW_BOX_CURSOR, | ||
| 65 | BAR_CURSOR, | ||
| 66 | HBAR_CURSOR | ||
| 67 | }; | ||
| 68 | |||
| 69 | enum fullscreen_type | 41 | enum fullscreen_type |
| 70 | { | 42 | { |
| 71 | FULLSCREEN_NONE, | 43 | FULLSCREEN_NONE, |
| @@ -76,10 +48,7 @@ enum fullscreen_type | |||
| 76 | FULLSCREEN_WAIT = 0x100 | 48 | FULLSCREEN_WAIT = 0x100 |
| 77 | }; | 49 | }; |
| 78 | 50 | ||
| 79 | 51 | /* The structure representing a frame. */ | |
| 80 | #define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel) | ||
| 81 | #define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel) | ||
| 82 | |||
| 83 | 52 | ||
| 84 | struct frame | 53 | struct frame |
| 85 | { | 54 | { |
| @@ -410,6 +379,10 @@ struct frame | |||
| 410 | /* Nonzero means that the pointer is invisible. */ | 379 | /* Nonzero means that the pointer is invisible. */ |
| 411 | unsigned pointer_invisible :1; | 380 | unsigned pointer_invisible :1; |
| 412 | 381 | ||
| 382 | /* Nonzero means that all windows except mini-window and | ||
| 383 | selected window on this frame have frozen window starts. */ | ||
| 384 | unsigned frozen_window_starts : 1; | ||
| 385 | |||
| 413 | /* Nonzero if we should actually display the scroll bars on this frame. */ | 386 | /* Nonzero if we should actually display the scroll bars on this frame. */ |
| 414 | enum vertical_scroll_bar_type vertical_scroll_bar_type; | 387 | enum vertical_scroll_bar_type vertical_scroll_bar_type; |
| 415 | 388 | ||
| @@ -761,6 +734,10 @@ default_pixels_per_inch_y (void) | |||
| 761 | /* Not really implemented. */ | 734 | /* Not really implemented. */ |
| 762 | #define FRAME_WANTS_MODELINE_P(f) (f)->wants_modeline | 735 | #define FRAME_WANTS_MODELINE_P(f) (f)->wants_modeline |
| 763 | 736 | ||
| 737 | /* Nonzero if all windows except selected window and mini window | ||
| 738 | are frozen on frame F. */ | ||
| 739 | #define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts | ||
| 740 | |||
| 764 | /* Nonzero if a size change has been requested for frame F | 741 | /* Nonzero if a size change has been requested for frame F |
| 765 | but not yet really put into effect. This can be true temporarily | 742 | but not yet really put into effect. This can be true temporarily |
| 766 | when an X event comes in at a bad time. */ | 743 | when an X event comes in at a bad time. */ |
| @@ -886,6 +863,9 @@ default_pixels_per_inch_y (void) | |||
| 886 | #define FRAME_CURSOR_WIDTH(f) ((f)->cursor_width) | 863 | #define FRAME_CURSOR_WIDTH(f) ((f)->cursor_width) |
| 887 | #define FRAME_BLINK_OFF_CURSOR_WIDTH(f) ((f)->blink_off_cursor_width) | 864 | #define FRAME_BLINK_OFF_CURSOR_WIDTH(f) ((f)->blink_off_cursor_width) |
| 888 | 865 | ||
| 866 | #define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel) | ||
| 867 | #define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel) | ||
| 868 | |||
| 889 | /* Return a pointer to the face cache of frame F. */ | 869 | /* Return a pointer to the face cache of frame F. */ |
| 890 | 870 | ||
| 891 | #define FRAME_FACE_CACHE(F) (F)->face_cache | 871 | #define FRAME_FACE_CACHE(F) (F)->face_cache |
| @@ -952,6 +932,9 @@ extern Lisp_Object Qtty_color_mode; | |||
| 952 | extern Lisp_Object Qterminal; | 932 | extern Lisp_Object Qterminal; |
| 953 | extern Lisp_Object Qnoelisp; | 933 | extern Lisp_Object Qnoelisp; |
| 954 | 934 | ||
| 935 | /* Nonzero means there is at least one garbaged frame. */ | ||
| 936 | extern bool frame_garbaged; | ||
| 937 | |||
| 955 | extern struct frame *last_nonminibuf_frame; | 938 | extern struct frame *last_nonminibuf_frame; |
| 956 | 939 | ||
| 957 | extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); | 940 | extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); |
diff --git a/src/fringe.c b/src/fringe.c index 1d05244e64e..492eddae8d4 100644 --- a/src/fringe.c +++ b/src/fringe.c | |||
| @@ -666,7 +666,7 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o | |||
| 666 | and OTOH leaving out that one pixel leaves behind | 666 | and OTOH leaving out that one pixel leaves behind |
| 667 | traces of the cursor, if it was in column zero | 667 | traces of the cursor, if it was in column zero |
| 668 | before drawing non-empty margin area. */ | 668 | before drawing non-empty margin area. */ |
| 669 | && NILP (w->left_margin_cols)) | 669 | && w->left_margin_cols == 0) |
| 670 | ? 1 : 0); | 670 | ? 1 : 0); |
| 671 | p.bx = x - wd; | 671 | p.bx = x - wd; |
| 672 | p.nx = wd; | 672 | p.nx = wd; |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 237d031295c..6228f2150f5 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -35,6 +35,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 35 | #include "keyboard.h" | 35 | #include "keyboard.h" |
| 36 | #include "charset.h" | 36 | #include "charset.h" |
| 37 | #include "coding.h" | 37 | #include "coding.h" |
| 38 | #include "font.h" | ||
| 39 | |||
| 38 | #include <gdk/gdkkeysyms.h> | 40 | #include <gdk/gdkkeysyms.h> |
| 39 | #include "xsettings.h" | 41 | #include "xsettings.h" |
| 40 | 42 | ||
| @@ -641,7 +643,7 @@ hierarchy_ch_cb (GtkWidget *widget, | |||
| 641 | GtkWidget *previous_toplevel, | 643 | GtkWidget *previous_toplevel, |
| 642 | gpointer user_data) | 644 | gpointer user_data) |
| 643 | { | 645 | { |
| 644 | struct frame *f = (struct frame *) user_data; | 646 | struct frame *f = user_data; |
| 645 | struct x_output *x = f->output_data.x; | 647 | struct x_output *x = f->output_data.x; |
| 646 | GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl); | 648 | GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl); |
| 647 | 649 | ||
| @@ -663,7 +665,7 @@ qttip_cb (GtkWidget *widget, | |||
| 663 | GtkTooltip *tooltip, | 665 | GtkTooltip *tooltip, |
| 664 | gpointer user_data) | 666 | gpointer user_data) |
| 665 | { | 667 | { |
| 666 | struct frame *f = (struct frame *) user_data; | 668 | struct frame *f = user_data; |
| 667 | struct x_output *x = f->output_data.x; | 669 | struct x_output *x = f->output_data.x; |
| 668 | if (x->ttip_widget == NULL) | 670 | if (x->ttip_widget == NULL) |
| 669 | { | 671 | { |
| @@ -870,29 +872,23 @@ xg_clear_under_internal_border (struct frame *f) | |||
| 870 | if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) | 872 | if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) |
| 871 | { | 873 | { |
| 872 | GtkWidget *wfixed = f->output_data.x->edit_widget; | 874 | GtkWidget *wfixed = f->output_data.x->edit_widget; |
| 875 | |||
| 873 | gtk_widget_queue_draw (wfixed); | 876 | gtk_widget_queue_draw (wfixed); |
| 874 | gdk_window_process_all_updates (); | 877 | gdk_window_process_all_updates (); |
| 875 | x_clear_area (FRAME_X_DISPLAY (f), | 878 | |
| 876 | FRAME_X_WINDOW (f), | 879 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, 0, |
| 877 | 0, 0, | 880 | FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f)); |
| 878 | FRAME_PIXEL_WIDTH (f), | 881 | |
| 879 | FRAME_INTERNAL_BORDER_WIDTH (f), 0); | 882 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, 0, |
| 880 | x_clear_area (FRAME_X_DISPLAY (f), | 883 | FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); |
| 881 | FRAME_X_WINDOW (f), | 884 | |
| 882 | 0, 0, | 885 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, |
| 883 | FRAME_INTERNAL_BORDER_WIDTH (f), | 886 | FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f), |
| 884 | FRAME_PIXEL_HEIGHT (f), 0); | 887 | FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f)); |
| 885 | x_clear_area (FRAME_X_DISPLAY (f), | 888 | |
| 886 | FRAME_X_WINDOW (f), | 889 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 887 | 0, FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f), | 890 | FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f), |
| 888 | FRAME_PIXEL_WIDTH (f), | 891 | 0, FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); |
| 889 | FRAME_INTERNAL_BORDER_WIDTH (f), 0); | ||
| 890 | x_clear_area (FRAME_X_DISPLAY (f), | ||
| 891 | FRAME_X_WINDOW (f), | ||
| 892 | FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f), | ||
| 893 | 0, | ||
| 894 | FRAME_INTERNAL_BORDER_WIDTH (f), | ||
| 895 | FRAME_PIXEL_HEIGHT (f), 0); | ||
| 896 | } | 892 | } |
| 897 | } | 893 | } |
| 898 | 894 | ||
| @@ -1073,7 +1069,7 @@ style_changed_cb (GObject *go, | |||
| 1073 | gpointer user_data) | 1069 | gpointer user_data) |
| 1074 | { | 1070 | { |
| 1075 | struct input_event event; | 1071 | struct input_event event; |
| 1076 | GdkDisplay *gdpy = (GdkDisplay *) user_data; | 1072 | GdkDisplay *gdpy = user_data; |
| 1077 | const char *display_name = gdk_display_get_name (gdpy); | 1073 | const char *display_name = gdk_display_get_name (gdpy); |
| 1078 | Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy); | 1074 | Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy); |
| 1079 | 1075 | ||
| @@ -1115,7 +1111,7 @@ delete_cb (GtkWidget *widget, | |||
| 1115 | #ifdef HAVE_GTK3 | 1111 | #ifdef HAVE_GTK3 |
| 1116 | /* The event doesn't arrive in the normal event loop. Send event | 1112 | /* The event doesn't arrive in the normal event loop. Send event |
| 1117 | here. */ | 1113 | here. */ |
| 1118 | struct frame *f = (struct frame *) user_data; | 1114 | struct frame *f = user_data; |
| 1119 | struct input_event ie; | 1115 | struct input_event ie; |
| 1120 | 1116 | ||
| 1121 | EVENT_INIT (ie); | 1117 | EVENT_INIT (ie); |
| @@ -1341,6 +1337,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1341 | int base_width, base_height; | 1337 | int base_width, base_height; |
| 1342 | int min_rows = 0, min_cols = 0; | 1338 | int min_rows = 0, min_cols = 0; |
| 1343 | int win_gravity = f->win_gravity; | 1339 | int win_gravity = f->win_gravity; |
| 1340 | Lisp_Object fs_state, frame; | ||
| 1344 | 1341 | ||
| 1345 | /* Don't set size hints during initialization; that apparently leads | 1342 | /* Don't set size hints during initialization; that apparently leads |
| 1346 | to a race condition. See the thread at | 1343 | to a race condition. See the thread at |
| @@ -1348,6 +1345,16 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1348 | if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f)) | 1345 | if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f)) |
| 1349 | return; | 1346 | return; |
| 1350 | 1347 | ||
| 1348 | XSETFRAME (frame, f); | ||
| 1349 | fs_state = Fframe_parameter (frame, Qfullscreen); | ||
| 1350 | if (EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth)) | ||
| 1351 | { | ||
| 1352 | /* Don't set hints when maximized or fullscreen. Apparently KWin and | ||
| 1353 | Gtk3 don't get along and the frame shrinks (!). | ||
| 1354 | */ | ||
| 1355 | return; | ||
| 1356 | } | ||
| 1357 | |||
| 1351 | if (flags) | 1358 | if (flags) |
| 1352 | { | 1359 | { |
| 1353 | memset (&size_hints, 0, sizeof (size_hints)); | 1360 | memset (&size_hints, 0, sizeof (size_hints)); |
| @@ -1642,7 +1649,7 @@ xg_dialog_response_cb (GtkDialog *w, | |||
| 1642 | gint response, | 1649 | gint response, |
| 1643 | gpointer user_data) | 1650 | gpointer user_data) |
| 1644 | { | 1651 | { |
| 1645 | struct xg_dialog_data *dd = (struct xg_dialog_data *)user_data; | 1652 | struct xg_dialog_data *dd = user_data; |
| 1646 | dd->response = response; | 1653 | dd->response = response; |
| 1647 | g_main_loop_quit (dd->loop); | 1654 | g_main_loop_quit (dd->loop); |
| 1648 | } | 1655 | } |
| @@ -1671,16 +1678,16 @@ pop_down_dialog (void *arg) | |||
| 1671 | static gboolean | 1678 | static gboolean |
| 1672 | xg_maybe_add_timer (gpointer data) | 1679 | xg_maybe_add_timer (gpointer data) |
| 1673 | { | 1680 | { |
| 1674 | struct xg_dialog_data *dd = (struct xg_dialog_data *) data; | 1681 | struct xg_dialog_data *dd = data; |
| 1675 | EMACS_TIME next_time = timer_check (); | 1682 | struct timespec next_time = timer_check (); |
| 1676 | 1683 | ||
| 1677 | dd->timerid = 0; | 1684 | dd->timerid = 0; |
| 1678 | 1685 | ||
| 1679 | if (EMACS_TIME_VALID_P (next_time)) | 1686 | if (timespec_valid_p (next_time)) |
| 1680 | { | 1687 | { |
| 1681 | time_t s = EMACS_SECS (next_time); | 1688 | time_t s = next_time.tv_sec; |
| 1682 | int per_ms = EMACS_TIME_RESOLUTION / 1000; | 1689 | int per_ms = TIMESPEC_RESOLUTION / 1000; |
| 1683 | int ms = (EMACS_NSECS (next_time) + per_ms - 1) / per_ms; | 1690 | int ms = (next_time.tv_nsec + per_ms - 1) / per_ms; |
| 1684 | if (s <= ((guint) -1 - ms) / 1000) | 1691 | if (s <= ((guint) -1 - ms) / 1000) |
| 1685 | dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd); | 1692 | dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd); |
| 1686 | } | 1693 | } |
| @@ -1921,7 +1928,7 @@ static char * | |||
| 1921 | xg_get_file_name_from_selector (GtkWidget *w) | 1928 | xg_get_file_name_from_selector (GtkWidget *w) |
| 1922 | { | 1929 | { |
| 1923 | GtkFileSelection *filesel = GTK_FILE_SELECTION (w); | 1930 | GtkFileSelection *filesel = GTK_FILE_SELECTION (w); |
| 1924 | return xstrdup ((char*) gtk_file_selection_get_filename (filesel)); | 1931 | return xstrdup (gtk_file_selection_get_filename (filesel)); |
| 1925 | } | 1932 | } |
| 1926 | 1933 | ||
| 1927 | /* Create a file selection dialog. | 1934 | /* Create a file selection dialog. |
| @@ -2039,7 +2046,6 @@ xg_get_file_name (struct frame *f, | |||
| 2039 | 2046 | ||
| 2040 | 2047 | ||
| 2041 | static char *x_last_font_name; | 2048 | static char *x_last_font_name; |
| 2042 | extern Lisp_Object Qxft; | ||
| 2043 | 2049 | ||
| 2044 | /* Pop up a GTK font selector and return the name of the font the user | 2050 | /* Pop up a GTK font selector and return the name of the font the user |
| 2045 | selects, as a C string. The returned font name follows GTK's own | 2051 | selects, as a C string. The returned font name follows GTK's own |
| @@ -2277,7 +2283,7 @@ menuitem_destroy_callback (GtkWidget *w, gpointer client_data) | |||
| 2277 | { | 2283 | { |
| 2278 | if (client_data) | 2284 | if (client_data) |
| 2279 | { | 2285 | { |
| 2280 | xg_menu_item_cb_data *data = (xg_menu_item_cb_data*) client_data; | 2286 | xg_menu_item_cb_data *data = client_data; |
| 2281 | xg_list_remove (&xg_menu_item_cb_list, &data->ptrs); | 2287 | xg_list_remove (&xg_menu_item_cb_list, &data->ptrs); |
| 2282 | xfree (data); | 2288 | xfree (data); |
| 2283 | } | 2289 | } |
| @@ -2301,8 +2307,7 @@ menuitem_highlight_callback (GtkWidget *w, | |||
| 2301 | 2307 | ||
| 2302 | ev.crossing = *event; | 2308 | ev.crossing = *event; |
| 2303 | subwidget = gtk_get_event_widget (&ev); | 2309 | subwidget = gtk_get_event_widget (&ev); |
| 2304 | data = (xg_menu_item_cb_data *) g_object_get_data (G_OBJECT (subwidget), | 2310 | data = g_object_get_data (G_OBJECT (subwidget), XG_ITEM_DATA); |
| 2305 | XG_ITEM_DATA); | ||
| 2306 | if (data) | 2311 | if (data) |
| 2307 | { | 2312 | { |
| 2308 | if (! NILP (data->help) && data->cl_data->highlight_cb) | 2313 | if (! NILP (data->help) && data->cl_data->highlight_cb) |
| @@ -2323,7 +2328,7 @@ menuitem_highlight_callback (GtkWidget *w, | |||
| 2323 | static void | 2328 | static void |
| 2324 | menu_destroy_callback (GtkWidget *w, gpointer client_data) | 2329 | menu_destroy_callback (GtkWidget *w, gpointer client_data) |
| 2325 | { | 2330 | { |
| 2326 | unref_cl_data ((xg_menu_cb_data*) client_data); | 2331 | unref_cl_data (client_data); |
| 2327 | } | 2332 | } |
| 2328 | 2333 | ||
| 2329 | /* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both | 2334 | /* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both |
| @@ -3064,8 +3069,7 @@ xg_update_menu_item (widget_value *val, | |||
| 3064 | else if (val->enabled && ! gtk_widget_get_sensitive (w)) | 3069 | else if (val->enabled && ! gtk_widget_get_sensitive (w)) |
| 3065 | gtk_widget_set_sensitive (w, TRUE); | 3070 | gtk_widget_set_sensitive (w, TRUE); |
| 3066 | 3071 | ||
| 3067 | cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (w), | 3072 | cb_data = g_object_get_data (G_OBJECT (w), XG_ITEM_DATA); |
| 3068 | XG_ITEM_DATA); | ||
| 3069 | if (cb_data) | 3073 | if (cb_data) |
| 3070 | { | 3074 | { |
| 3071 | cb_data->call_data = val->call_data; | 3075 | cb_data->call_data = val->call_data; |
| @@ -3271,8 +3275,7 @@ xg_modify_menubar_widgets (GtkWidget *menubar, struct frame *f, | |||
| 3271 | 3275 | ||
| 3272 | if (! list) return; | 3276 | if (! list) return; |
| 3273 | 3277 | ||
| 3274 | cl_data = (xg_menu_cb_data*) g_object_get_data (G_OBJECT (menubar), | 3278 | cl_data = g_object_get_data (G_OBJECT (menubar), XG_FRAME_DATA); |
| 3275 | XG_FRAME_DATA); | ||
| 3276 | 3279 | ||
| 3277 | xg_update_menubar (menubar, f, &list, list, 0, val->contents, | 3280 | xg_update_menubar (menubar, f, &list, list, 0, val->contents, |
| 3278 | select_cb, deactivate_cb, highlight_cb, cl_data); | 3281 | select_cb, deactivate_cb, highlight_cb, cl_data); |
| @@ -3336,7 +3339,7 @@ static void | |||
| 3336 | menubar_map_cb (GtkWidget *w, gpointer user_data) | 3339 | menubar_map_cb (GtkWidget *w, gpointer user_data) |
| 3337 | { | 3340 | { |
| 3338 | GtkRequisition req; | 3341 | GtkRequisition req; |
| 3339 | struct frame *f = (struct frame *) user_data; | 3342 | struct frame *f = user_data; |
| 3340 | gtk_widget_get_preferred_size (w, NULL, &req); | 3343 | gtk_widget_get_preferred_size (w, NULL, &req); |
| 3341 | if (FRAME_MENUBAR_HEIGHT (f) != req.height) | 3344 | if (FRAME_MENUBAR_HEIGHT (f) != req.height) |
| 3342 | { | 3345 | { |
| @@ -3742,14 +3745,11 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3742 | gtk_widget_queue_draw (wfixed); | 3745 | gtk_widget_queue_draw (wfixed); |
| 3743 | gdk_window_process_all_updates (); | 3746 | gdk_window_process_all_updates (); |
| 3744 | if (oldx != -1 && oldw > 0 && oldh > 0) | 3747 | if (oldx != -1 && oldw > 0 && oldh > 0) |
| 3745 | { | 3748 | /* Clear under old scroll bar position. This must be done after |
| 3746 | /* Clear under old scroll bar position. This must be done after | 3749 | the gtk_widget_queue_draw and gdk_window_process_all_updates |
| 3747 | the gtk_widget_queue_draw and gdk_window_process_all_updates | 3750 | above. */ |
| 3748 | above. */ | 3751 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 3749 | x_clear_area (FRAME_X_DISPLAY (f), | 3752 | oldx, oldy, oldw, oldh); |
| 3750 | FRAME_X_WINDOW (f), | ||
| 3751 | oldx, oldy, oldw, oldh, 0); | ||
| 3752 | } | ||
| 3753 | 3753 | ||
| 3754 | /* GTK does not redraw until the main loop is entered again, but | 3754 | /* GTK does not redraw until the main loop is entered again, but |
| 3755 | if there are no X events pending we will not enter it. So we sync | 3755 | if there are no X events pending we will not enter it. So we sync |
| @@ -3783,7 +3783,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, | |||
| 3783 | 3783 | ||
| 3784 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | 3784 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); |
| 3785 | 3785 | ||
| 3786 | if (wscroll && NILP (bar->dragging)) | 3786 | if (wscroll && bar->dragging == -1) |
| 3787 | { | 3787 | { |
| 3788 | GtkAdjustment *adj; | 3788 | GtkAdjustment *adj; |
| 3789 | gdouble shown; | 3789 | gdouble shown; |
| @@ -3946,8 +3946,7 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data) | |||
| 3946 | gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); | 3946 | gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); |
| 3947 | intptr_t mod = (intptr_t) gmod; | 3947 | intptr_t mod = (intptr_t) gmod; |
| 3948 | 3948 | ||
| 3949 | struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (w), | 3949 | struct frame *f = g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); |
| 3950 | XG_FRAME_DATA); | ||
| 3951 | Lisp_Object key, frame; | 3950 | Lisp_Object key, frame; |
| 3952 | struct input_event event; | 3951 | struct input_event event; |
| 3953 | EVENT_INIT (event); | 3952 | EVENT_INIT (event); |
| @@ -4020,8 +4019,8 @@ static GtkWidget * | |||
| 4020 | xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage) | 4019 | xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage) |
| 4021 | { | 4020 | { |
| 4022 | GList *clist = gtk_container_get_children (GTK_CONTAINER (vb)); | 4021 | GList *clist = gtk_container_get_children (GTK_CONTAINER (vb)); |
| 4023 | GtkWidget *c1 = (GtkWidget *) clist->data; | 4022 | GtkWidget *c1 = clist->data; |
| 4024 | GtkWidget *c2 = clist->next ? (GtkWidget *) clist->next->data : NULL; | 4023 | GtkWidget *c2 = clist->next ? clist->next->data : NULL; |
| 4025 | 4024 | ||
| 4026 | *wimage = GTK_IS_IMAGE (c1) ? c1 : c2; | 4025 | *wimage = GTK_IS_IMAGE (c1) ? c1 : c2; |
| 4027 | g_list_free (clist); | 4026 | g_list_free (clist); |
| @@ -4150,7 +4149,7 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox, | |||
| 4150 | GtkWidget *w, | 4149 | GtkWidget *w, |
| 4151 | gpointer client_data) | 4150 | gpointer client_data) |
| 4152 | { | 4151 | { |
| 4153 | struct frame *f = (struct frame *) client_data; | 4152 | struct frame *f = client_data; |
| 4154 | 4153 | ||
| 4155 | g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar, | 4154 | g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar, |
| 4156 | NULL); | 4155 | NULL); |
| @@ -4187,7 +4186,7 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox, | |||
| 4187 | GtkWidget *w, | 4186 | GtkWidget *w, |
| 4188 | gpointer client_data) | 4187 | gpointer client_data) |
| 4189 | { | 4188 | { |
| 4190 | struct frame *f = (struct frame *) client_data; | 4189 | struct frame *f = client_data; |
| 4191 | g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL); | 4190 | g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL); |
| 4192 | 4191 | ||
| 4193 | if (f) | 4192 | if (f) |
| @@ -4225,8 +4224,7 @@ xg_tool_bar_help_callback (GtkWidget *w, | |||
| 4225 | gpointer client_data) | 4224 | gpointer client_data) |
| 4226 | { | 4225 | { |
| 4227 | intptr_t idx = (intptr_t) client_data; | 4226 | intptr_t idx = (intptr_t) client_data; |
| 4228 | struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (w), | 4227 | struct frame *f = g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); |
| 4229 | XG_FRAME_DATA); | ||
| 4230 | Lisp_Object help, frame; | 4228 | Lisp_Object help, frame; |
| 4231 | 4229 | ||
| 4232 | if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items)) | 4230 | if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items)) |
| @@ -4366,7 +4364,7 @@ tb_size_cb (GtkWidget *widget, | |||
| 4366 | /* When tool bar is created it has one preferred size. But when size is | 4364 | /* When tool bar is created it has one preferred size. But when size is |
| 4367 | allocated between widgets, it may get another. So we must update | 4365 | allocated between widgets, it may get another. So we must update |
| 4368 | size hints if tool bar size changes. Seen on Fedora 18 at least. */ | 4366 | size hints if tool bar size changes. Seen on Fedora 18 at least. */ |
| 4369 | struct frame *f = (struct frame *) user_data; | 4367 | struct frame *f = user_data; |
| 4370 | if (xg_update_tool_bar_sizes (f)) | 4368 | if (xg_update_tool_bar_sizes (f)) |
| 4371 | x_wm_set_size_hint (f, 0, 0); | 4369 | x_wm_set_size_hint (f, 0, 0); |
| 4372 | } | 4370 | } |
| @@ -5038,10 +5036,10 @@ xg_initialize (void) | |||
| 5038 | (gdk_display_get_default ())); | 5036 | (gdk_display_get_default ())); |
| 5039 | /* Remove F10 as a menu accelerator, it does not mix well with Emacs key | 5037 | /* Remove F10 as a menu accelerator, it does not mix well with Emacs key |
| 5040 | bindings. It doesn't seem to be any way to remove properties, | 5038 | bindings. It doesn't seem to be any way to remove properties, |
| 5041 | so we set it to VoidSymbol which in X means "no key". */ | 5039 | so we set it to "" which in means "no key". */ |
| 5042 | gtk_settings_set_string_property (settings, | 5040 | gtk_settings_set_string_property (settings, |
| 5043 | "gtk-menu-bar-accel", | 5041 | "gtk-menu-bar-accel", |
| 5044 | "VoidSymbol", | 5042 | "", |
| 5045 | EMACS_CLASS); | 5043 | EMACS_CLASS); |
| 5046 | 5044 | ||
| 5047 | /* Make GTK text input widgets use Emacs style keybindings. This is | 5045 | /* Make GTK text input widgets use Emacs style keybindings. This is |
diff --git a/src/gtkutil.h b/src/gtkutil.h index 482331a8934..fc959862fd3 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h | |||
| @@ -74,8 +74,6 @@ typedef struct xg_menu_item_cb_data_ | |||
| 74 | 74 | ||
| 75 | } xg_menu_item_cb_data; | 75 | } xg_menu_item_cb_data; |
| 76 | 76 | ||
| 77 | struct _widget_value; | ||
| 78 | |||
| 79 | extern struct _widget_value *malloc_widget_value (void); | 77 | extern struct _widget_value *malloc_widget_value (void); |
| 80 | extern void free_widget_value (struct _widget_value *); | 78 | extern void free_widget_value (struct _widget_value *); |
| 81 | 79 | ||
diff --git a/src/image.c b/src/image.c index 911ca8e6681..1271376bcab 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -30,13 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #include <setjmp.h> | 32 | #include <setjmp.h> |
| 33 | |||
| 34 | #include <c-ctype.h> | 33 | #include <c-ctype.h> |
| 35 | 34 | ||
| 36 | /* This makes the fields of a Display accessible, in Xlib header files. */ | ||
| 37 | |||
| 38 | #define XLIB_ILLEGAL_ACCESS | ||
| 39 | |||
| 40 | #include "lisp.h" | 35 | #include "lisp.h" |
| 41 | #include "frame.h" | 36 | #include "frame.h" |
| 42 | #include "window.h" | 37 | #include "window.h" |
| @@ -145,7 +140,7 @@ static Lisp_Object QCmax_width, QCmax_height; | |||
| 145 | 140 | ||
| 146 | #ifdef HAVE_NS | 141 | #ifdef HAVE_NS |
| 147 | /* Use with images created by ns_image_for_XPM. */ | 142 | /* Use with images created by ns_image_for_XPM. */ |
| 148 | unsigned long | 143 | static unsigned long |
| 149 | XGetPixel (XImagePtr ximage, int x, int y) | 144 | XGetPixel (XImagePtr ximage, int x, int y) |
| 150 | { | 145 | { |
| 151 | return ns_get_pixel (ximage, x, y); | 146 | return ns_get_pixel (ximage, x, y); |
| @@ -153,7 +148,7 @@ XGetPixel (XImagePtr ximage, int x, int y) | |||
| 153 | 148 | ||
| 154 | /* Use with images created by ns_image_for_XPM; alpha set to 1; | 149 | /* Use with images created by ns_image_for_XPM; alpha set to 1; |
| 155 | pixel is assumed to be in RGB form. */ | 150 | pixel is assumed to be in RGB form. */ |
| 156 | void | 151 | static void |
| 157 | XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) | 152 | XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) |
| 158 | { | 153 | { |
| 159 | ns_put_pixel (ximage, x, y, pixel); | 154 | ns_put_pixel (ximage, x, y, pixel); |
| @@ -302,11 +297,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) | |||
| 302 | id = x_allocate_bitmap_record (f); | 297 | id = x_allocate_bitmap_record (f); |
| 303 | dpyinfo->bitmaps[id - 1].img = bitmap; | 298 | dpyinfo->bitmaps[id - 1].img = bitmap; |
| 304 | dpyinfo->bitmaps[id - 1].refcount = 1; | 299 | dpyinfo->bitmaps[id - 1].refcount = 1; |
| 305 | dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); | 300 | dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); |
| 306 | dpyinfo->bitmaps[id - 1].depth = 1; | 301 | dpyinfo->bitmaps[id - 1].depth = 1; |
| 307 | dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap); | 302 | dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap); |
| 308 | dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap); | 303 | dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap); |
| 309 | strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file)); | ||
| 310 | return id; | 304 | return id; |
| 311 | #endif | 305 | #endif |
| 312 | 306 | ||
| @@ -345,11 +339,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) | |||
| 345 | dpyinfo->bitmaps[id - 1].pixmap = bitmap; | 339 | dpyinfo->bitmaps[id - 1].pixmap = bitmap; |
| 346 | dpyinfo->bitmaps[id - 1].have_mask = 0; | 340 | dpyinfo->bitmaps[id - 1].have_mask = 0; |
| 347 | dpyinfo->bitmaps[id - 1].refcount = 1; | 341 | dpyinfo->bitmaps[id - 1].refcount = 1; |
| 348 | dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); | 342 | dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); |
| 349 | dpyinfo->bitmaps[id - 1].depth = 1; | 343 | dpyinfo->bitmaps[id - 1].depth = 1; |
| 350 | dpyinfo->bitmaps[id - 1].height = height; | 344 | dpyinfo->bitmaps[id - 1].height = height; |
| 351 | dpyinfo->bitmaps[id - 1].width = width; | 345 | dpyinfo->bitmaps[id - 1].width = width; |
| 352 | strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file)); | ||
| 353 | 346 | ||
| 354 | return id; | 347 | return id; |
| 355 | #endif /* HAVE_X_WINDOWS */ | 348 | #endif /* HAVE_X_WINDOWS */ |
| @@ -565,7 +558,6 @@ static void x_emboss (struct frame *, struct image *); | |||
| 565 | static void x_build_heuristic_mask (struct frame *, struct image *, | 558 | static void x_build_heuristic_mask (struct frame *, struct image *, |
| 566 | Lisp_Object); | 559 | Lisp_Object); |
| 567 | #ifdef WINDOWSNT | 560 | #ifdef WINDOWSNT |
| 568 | extern Lisp_Object Vlibrary_cache; | ||
| 569 | #define CACHE_IMAGE_TYPE(type, status) \ | 561 | #define CACHE_IMAGE_TYPE(type, status) \ |
| 570 | do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) | 562 | do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) |
| 571 | #else | 563 | #else |
| @@ -1044,7 +1036,7 @@ void | |||
| 1044 | prepare_image_for_display (struct frame *f, struct image *img) | 1036 | prepare_image_for_display (struct frame *f, struct image *img) |
| 1045 | { | 1037 | { |
| 1046 | /* We're about to display IMG, so set its timestamp to `now'. */ | 1038 | /* We're about to display IMG, so set its timestamp to `now'. */ |
| 1047 | img->timestamp = current_emacs_time (); | 1039 | img->timestamp = current_timespec (); |
| 1048 | 1040 | ||
| 1049 | /* If IMG doesn't have a pixmap yet, load it now, using the image | 1041 | /* If IMG doesn't have a pixmap yet, load it now, using the image |
| 1050 | type dependent loader function. */ | 1042 | type dependent loader function. */ |
| @@ -1362,14 +1354,12 @@ static void cache_image (struct frame *f, struct image *img); | |||
| 1362 | struct image_cache * | 1354 | struct image_cache * |
| 1363 | make_image_cache (void) | 1355 | make_image_cache (void) |
| 1364 | { | 1356 | { |
| 1365 | struct image_cache *c = xzalloc (sizeof *c); | 1357 | struct image_cache *c = xmalloc (sizeof *c); |
| 1366 | int size; | ||
| 1367 | 1358 | ||
| 1368 | size = 50; | 1359 | c->size = 50; |
| 1369 | c->images = xmalloc (size * sizeof *c->images); | 1360 | c->used = c->refcount = 0; |
| 1370 | c->size = size; | 1361 | c->images = xmalloc (c->size * sizeof *c->images); |
| 1371 | size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; | 1362 | c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets); |
| 1372 | c->buckets = xzalloc (size); | ||
| 1373 | return c; | 1363 | return c; |
| 1374 | } | 1364 | } |
| 1375 | 1365 | ||
| @@ -1485,7 +1475,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter) | |||
| 1485 | else if (INTEGERP (Vimage_cache_eviction_delay)) | 1475 | else if (INTEGERP (Vimage_cache_eviction_delay)) |
| 1486 | { | 1476 | { |
| 1487 | /* Free cache based on timestamp. */ | 1477 | /* Free cache based on timestamp. */ |
| 1488 | EMACS_TIME old, t; | 1478 | struct timespec old, t; |
| 1489 | double delay; | 1479 | double delay; |
| 1490 | ptrdiff_t nimages = 0; | 1480 | ptrdiff_t nimages = 0; |
| 1491 | 1481 | ||
| @@ -1500,13 +1490,13 @@ clear_image_cache (struct frame *f, Lisp_Object filter) | |||
| 1500 | delay = 1600 * delay / nimages / nimages; | 1490 | delay = 1600 * delay / nimages / nimages; |
| 1501 | delay = max (delay, 1); | 1491 | delay = max (delay, 1); |
| 1502 | 1492 | ||
| 1503 | t = current_emacs_time (); | 1493 | t = current_timespec (); |
| 1504 | old = sub_emacs_time (t, EMACS_TIME_FROM_DOUBLE (delay)); | 1494 | old = timespec_sub (t, dtotimespec (delay)); |
| 1505 | 1495 | ||
| 1506 | for (i = 0; i < c->used; ++i) | 1496 | for (i = 0; i < c->used; ++i) |
| 1507 | { | 1497 | { |
| 1508 | struct image *img = c->images[i]; | 1498 | struct image *img = c->images[i]; |
| 1509 | if (img && EMACS_TIME_LT (img->timestamp, old)) | 1499 | if (img && timespec_cmp (img->timestamp, old) < 0) |
| 1510 | { | 1500 | { |
| 1511 | free_image (f, img); | 1501 | free_image (f, img); |
| 1512 | ++nfreed; | 1502 | ++nfreed; |
| @@ -1769,7 +1759,7 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 1769 | } | 1759 | } |
| 1770 | 1760 | ||
| 1771 | /* We're using IMG, so set its timestamp to `now'. */ | 1761 | /* We're using IMG, so set its timestamp to `now'. */ |
| 1772 | img->timestamp = current_emacs_time (); | 1762 | img->timestamp = current_timespec (); |
| 1773 | 1763 | ||
| 1774 | /* Value is the image id. */ | 1764 | /* Value is the image id. */ |
| 1775 | return img->id; | 1765 | return img->id; |
| @@ -2717,10 +2707,13 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e | |||
| 2717 | LA1 = xbm_scan (&s, end, buffer, &value) | 2707 | LA1 = xbm_scan (&s, end, buffer, &value) |
| 2718 | 2708 | ||
| 2719 | #define expect(TOKEN) \ | 2709 | #define expect(TOKEN) \ |
| 2720 | if (LA1 != (TOKEN)) \ | 2710 | do \ |
| 2721 | goto failure; \ | 2711 | { \ |
| 2722 | else \ | 2712 | if (LA1 != (TOKEN)) \ |
| 2723 | match () | 2713 | goto failure; \ |
| 2714 | match (); \ | ||
| 2715 | } \ | ||
| 2716 | while (0) | ||
| 2724 | 2717 | ||
| 2725 | #define expect_ident(IDENT) \ | 2718 | #define expect_ident(IDENT) \ |
| 2726 | if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ | 2719 | if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ |
| @@ -3332,7 +3325,7 @@ static int | |||
| 3332 | xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color, | 3325 | xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color, |
| 3333 | void *closure) | 3326 | void *closure) |
| 3334 | { | 3327 | { |
| 3335 | return xpm_lookup_color ((struct frame *) closure, color_name, color); | 3328 | return xpm_lookup_color (closure, color_name, color); |
| 3336 | } | 3329 | } |
| 3337 | 3330 | ||
| 3338 | 3331 | ||
| @@ -3980,10 +3973,13 @@ xpm_load_image (struct frame *f, | |||
| 3980 | LA1 = xpm_scan (&s, end, &beg, &len) | 3973 | LA1 = xpm_scan (&s, end, &beg, &len) |
| 3981 | 3974 | ||
| 3982 | #define expect(TOKEN) \ | 3975 | #define expect(TOKEN) \ |
| 3983 | if (LA1 != (TOKEN)) \ | 3976 | do \ |
| 3984 | goto failure; \ | 3977 | { \ |
| 3985 | else \ | 3978 | if (LA1 != (TOKEN)) \ |
| 3986 | match () | 3979 | goto failure; \ |
| 3980 | match (); \ | ||
| 3981 | } \ | ||
| 3982 | while (0) | ||
| 3987 | 3983 | ||
| 3988 | #define expect_ident(IDENT) \ | 3984 | #define expect_ident(IDENT) \ |
| 3989 | if (LA1 == XPM_TK_IDENT \ | 3985 | if (LA1 == XPM_TK_IDENT \ |
| @@ -4936,7 +4932,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) | |||
| 4936 | int row_width; | 4932 | int row_width; |
| 4937 | #endif /* HAVE_NTGUI */ | 4933 | #endif /* HAVE_NTGUI */ |
| 4938 | int x, y; | 4934 | int x, y; |
| 4939 | bool rc, use_img_background; | 4935 | bool use_img_background; |
| 4940 | unsigned long bg = 0; | 4936 | unsigned long bg = 0; |
| 4941 | 4937 | ||
| 4942 | if (img->mask) | 4938 | if (img->mask) |
| @@ -4945,9 +4941,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) | |||
| 4945 | #ifndef HAVE_NTGUI | 4941 | #ifndef HAVE_NTGUI |
| 4946 | #ifndef HAVE_NS | 4942 | #ifndef HAVE_NS |
| 4947 | /* Create an image and pixmap serving as mask. */ | 4943 | /* Create an image and pixmap serving as mask. */ |
| 4948 | rc = image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, | 4944 | if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, |
| 4949 | &mask_img, 1); | 4945 | &mask_img, 1)) |
| 4950 | if (!rc) | ||
| 4951 | return; | 4946 | return; |
| 4952 | #endif /* !HAVE_NS */ | 4947 | #endif /* !HAVE_NS */ |
| 4953 | #else | 4948 | #else |
| @@ -5652,8 +5647,7 @@ struct png_memory_storage | |||
| 5652 | static void | 5647 | static void |
| 5653 | png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) | 5648 | png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) |
| 5654 | { | 5649 | { |
| 5655 | struct png_memory_storage *tbr | 5650 | struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr); |
| 5656 | = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr); | ||
| 5657 | 5651 | ||
| 5658 | if (length > tbr->len - tbr->index) | 5652 | if (length > tbr->len - tbr->index) |
| 5659 | fn_png_error (png_ptr, "Read error"); | 5653 | fn_png_error (png_ptr, "Read error"); |
| @@ -5670,7 +5664,7 @@ png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) | |||
| 5670 | static void | 5664 | static void |
| 5671 | png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) | 5665 | png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) |
| 5672 | { | 5666 | { |
| 5673 | FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr); | 5667 | FILE *fp = fn_png_get_io_ptr (png_ptr); |
| 5674 | 5668 | ||
| 5675 | if (fread (data, 1, length, fp) < length) | 5669 | if (fread (data, 1, length, fp) < length) |
| 5676 | fn_png_error (png_ptr, "Read error"); | 5670 | fn_png_error (png_ptr, "Read error"); |
| @@ -5814,9 +5808,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5814 | 5808 | ||
| 5815 | /* Read image info. */ | 5809 | /* Read image info. */ |
| 5816 | if (!NILP (specified_data)) | 5810 | if (!NILP (specified_data)) |
| 5817 | fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); | 5811 | fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory); |
| 5818 | else | 5812 | else |
| 5819 | fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file); | 5813 | fn_png_set_read_fn (png_ptr, fp, png_read_from_file); |
| 5820 | 5814 | ||
| 5821 | fn_png_set_sig_bytes (png_ptr, sizeof sig); | 5815 | fn_png_set_sig_bytes (png_ptr, sizeof sig); |
| 5822 | fn_png_read_info (png_ptr, info_ptr); | 5816 | fn_png_read_info (png_ptr, info_ptr); |
| @@ -6306,7 +6300,7 @@ our_memory_fill_input_buffer (j_decompress_ptr cinfo) | |||
| 6306 | static void | 6300 | static void |
| 6307 | our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) | 6301 | our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) |
| 6308 | { | 6302 | { |
| 6309 | struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src; | 6303 | struct jpeg_source_mgr *src = cinfo->src; |
| 6310 | 6304 | ||
| 6311 | if (src) | 6305 | if (src) |
| 6312 | { | 6306 | { |
| @@ -6326,19 +6320,17 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) | |||
| 6326 | static void | 6320 | static void |
| 6327 | jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) | 6321 | jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) |
| 6328 | { | 6322 | { |
| 6329 | struct jpeg_source_mgr *src; | 6323 | struct jpeg_source_mgr *src = cinfo->src; |
| 6330 | 6324 | ||
| 6331 | if (cinfo->src == NULL) | 6325 | if (! src) |
| 6332 | { | 6326 | { |
| 6333 | /* First time for this JPEG object? */ | 6327 | /* First time for this JPEG object? */ |
| 6334 | cinfo->src = (struct jpeg_source_mgr *) | 6328 | src = cinfo->mem->alloc_small ((j_common_ptr) cinfo, |
| 6335 | (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | 6329 | JPOOL_PERMANENT, sizeof *src); |
| 6336 | sizeof (struct jpeg_source_mgr)); | 6330 | cinfo->src = src; |
| 6337 | src = (struct jpeg_source_mgr *) cinfo->src; | ||
| 6338 | src->next_input_byte = data; | 6331 | src->next_input_byte = data; |
| 6339 | } | 6332 | } |
| 6340 | 6333 | ||
| 6341 | src = (struct jpeg_source_mgr *) cinfo->src; | ||
| 6342 | src->init_source = our_common_init_source; | 6334 | src->init_source = our_common_init_source; |
| 6343 | src->fill_input_buffer = our_memory_fill_input_buffer; | 6335 | src->fill_input_buffer = our_memory_fill_input_buffer; |
| 6344 | src->skip_input_data = our_memory_skip_input_data; | 6336 | src->skip_input_data = our_memory_skip_input_data; |
| @@ -6430,20 +6422,17 @@ our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) | |||
| 6430 | static void | 6422 | static void |
| 6431 | jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) | 6423 | jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) |
| 6432 | { | 6424 | { |
| 6433 | struct jpeg_stdio_mgr *src; | 6425 | struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src; |
| 6434 | 6426 | ||
| 6435 | if (cinfo->src != NULL) | 6427 | if (! src) |
| 6436 | src = (struct jpeg_stdio_mgr *) cinfo->src; | ||
| 6437 | else | ||
| 6438 | { | 6428 | { |
| 6439 | /* First time for this JPEG object? */ | 6429 | /* First time for this JPEG object? */ |
| 6440 | cinfo->src = (struct jpeg_source_mgr *) | 6430 | src = cinfo->mem->alloc_small ((j_common_ptr) cinfo, |
| 6441 | (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | 6431 | JPOOL_PERMANENT, sizeof *src); |
| 6442 | sizeof (struct jpeg_stdio_mgr)); | 6432 | cinfo->src = (struct jpeg_source_mgr *) src; |
| 6443 | src = (struct jpeg_stdio_mgr *) cinfo->src; | 6433 | src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo, |
| 6444 | src->buffer = (JOCTET *) | 6434 | JPOOL_PERMANENT, |
| 6445 | (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | 6435 | JPEG_STDIO_BUFFER_SIZE); |
| 6446 | JPEG_STDIO_BUFFER_SIZE); | ||
| 6447 | } | 6436 | } |
| 6448 | 6437 | ||
| 6449 | src->file = fp; | 6438 | src->file = fp; |
| @@ -7746,6 +7735,7 @@ enum imagemagick_keyword_index | |||
| 7746 | IMAGEMAGICK_WIDTH, | 7735 | IMAGEMAGICK_WIDTH, |
| 7747 | IMAGEMAGICK_MAX_HEIGHT, | 7736 | IMAGEMAGICK_MAX_HEIGHT, |
| 7748 | IMAGEMAGICK_MAX_WIDTH, | 7737 | IMAGEMAGICK_MAX_WIDTH, |
| 7738 | IMAGEMAGICK_FORMAT, | ||
| 7749 | IMAGEMAGICK_ROTATION, | 7739 | IMAGEMAGICK_ROTATION, |
| 7750 | IMAGEMAGICK_CROP, | 7740 | IMAGEMAGICK_CROP, |
| 7751 | IMAGEMAGICK_LAST | 7741 | IMAGEMAGICK_LAST |
| @@ -7770,6 +7760,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = | |||
| 7770 | {":width", IMAGE_INTEGER_VALUE, 0}, | 7760 | {":width", IMAGE_INTEGER_VALUE, 0}, |
| 7771 | {":max-height", IMAGE_INTEGER_VALUE, 0}, | 7761 | {":max-height", IMAGE_INTEGER_VALUE, 0}, |
| 7772 | {":max-width", IMAGE_INTEGER_VALUE, 0}, | 7762 | {":max-width", IMAGE_INTEGER_VALUE, 0}, |
| 7763 | {":format", IMAGE_SYMBOL_VALUE, 0}, | ||
| 7773 | {":rotation", IMAGE_NUMBER_VALUE, 0}, | 7764 | {":rotation", IMAGE_NUMBER_VALUE, 0}, |
| 7774 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 7765 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} |
| 7775 | }; | 7766 | }; |
| @@ -7848,6 +7839,233 @@ imagemagick_error (MagickWand *wand) | |||
| 7848 | description = (char *) MagickRelinquishMemory (description); | 7839 | description = (char *) MagickRelinquishMemory (description); |
| 7849 | } | 7840 | } |
| 7850 | 7841 | ||
| 7842 | /* Possibly give ImageMagick some extra help to determine the image | ||
| 7843 | type by supplying a "dummy" filename based on the Content-Type. */ | ||
| 7844 | |||
| 7845 | static char * | ||
| 7846 | imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent]) | ||
| 7847 | { | ||
| 7848 | Lisp_Object symbol = intern ("image-format-suffixes"); | ||
| 7849 | Lisp_Object val = find_symbol_value (symbol); | ||
| 7850 | Lisp_Object format; | ||
| 7851 | |||
| 7852 | if (! CONSP (val)) | ||
| 7853 | return NULL; | ||
| 7854 | |||
| 7855 | format = image_spec_value (spec, intern (":format"), NULL); | ||
| 7856 | val = Fcar_safe (Fcdr_safe (Fassq (format, val))); | ||
| 7857 | if (! STRINGP (val)) | ||
| 7858 | return NULL; | ||
| 7859 | |||
| 7860 | /* It's OK to truncate the hint if it has MaxTextExtent or more bytes, | ||
| 7861 | as ImageMagick would ignore the extra bytes anyway. */ | ||
| 7862 | snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val)); | ||
| 7863 | return hint_buffer; | ||
| 7864 | } | ||
| 7865 | |||
| 7866 | /* Animated images (e.g., GIF89a) are composed from one "master image" | ||
| 7867 | (which is the first one, and then there's a number of images that | ||
| 7868 | follow. If following images have non-transparent colors, these are | ||
| 7869 | composed "on top" of the master image. So, in general, one has to | ||
| 7870 | compute ann the preceding images to be able to display a particular | ||
| 7871 | sub-image. | ||
| 7872 | |||
| 7873 | Computing all the preceding images is too slow, so we maintain a | ||
| 7874 | cache of previously computed images. We have to maintain a cache | ||
| 7875 | separate from the image cache, because the images may be scaled | ||
| 7876 | before display. */ | ||
| 7877 | |||
| 7878 | struct animation_cache | ||
| 7879 | { | ||
| 7880 | MagickWand *wand; | ||
| 7881 | int index; | ||
| 7882 | struct timespec update_time; | ||
| 7883 | struct animation_cache *next; | ||
| 7884 | char signature[FLEXIBLE_ARRAY_MEMBER]; | ||
| 7885 | }; | ||
| 7886 | |||
| 7887 | static struct animation_cache *animation_cache = NULL; | ||
| 7888 | |||
| 7889 | static struct animation_cache * | ||
| 7890 | imagemagick_create_cache (char *signature) | ||
| 7891 | { | ||
| 7892 | struct animation_cache *cache | ||
| 7893 | = xmalloc (offsetof (struct animation_cache, signature) | ||
| 7894 | + strlen (signature) + 1); | ||
| 7895 | cache->wand = 0; | ||
| 7896 | cache->index = 0; | ||
| 7897 | cache->next = 0; | ||
| 7898 | strcpy (cache->signature, signature); | ||
| 7899 | return cache; | ||
| 7900 | } | ||
| 7901 | |||
| 7902 | /* Discard cached images that haven't been used for a minute. */ | ||
| 7903 | static void | ||
| 7904 | imagemagick_prune_animation_cache (void) | ||
| 7905 | { | ||
| 7906 | struct animation_cache **pcache = &animation_cache; | ||
| 7907 | struct timespec old = timespec_sub (current_timespec (), | ||
| 7908 | make_timespec (60, 0)); | ||
| 7909 | |||
| 7910 | while (*pcache) | ||
| 7911 | { | ||
| 7912 | struct animation_cache *cache = *pcache; | ||
| 7913 | if (timespec_cmp (old, cache->update_time) <= 0) | ||
| 7914 | pcache = &cache->next; | ||
| 7915 | else | ||
| 7916 | { | ||
| 7917 | if (cache->wand) | ||
| 7918 | DestroyMagickWand (cache->wand); | ||
| 7919 | *pcache = cache->next; | ||
| 7920 | xfree (cache); | ||
| 7921 | } | ||
| 7922 | } | ||
| 7923 | } | ||
| 7924 | |||
| 7925 | static struct animation_cache * | ||
| 7926 | imagemagick_get_animation_cache (MagickWand *wand) | ||
| 7927 | { | ||
| 7928 | char *signature = MagickGetImageSignature (wand); | ||
| 7929 | struct animation_cache *cache; | ||
| 7930 | struct animation_cache **pcache = &animation_cache; | ||
| 7931 | |||
| 7932 | imagemagick_prune_animation_cache (); | ||
| 7933 | |||
| 7934 | while (1) | ||
| 7935 | { | ||
| 7936 | cache = *pcache; | ||
| 7937 | if (! cache) | ||
| 7938 | { | ||
| 7939 | *pcache = cache = imagemagick_create_cache (signature); | ||
| 7940 | break; | ||
| 7941 | } | ||
| 7942 | if (strcmp (signature, cache->signature) == 0) | ||
| 7943 | break; | ||
| 7944 | pcache = &cache->next; | ||
| 7945 | } | ||
| 7946 | |||
| 7947 | DestroyString (signature); | ||
| 7948 | cache->update_time = current_timespec (); | ||
| 7949 | return cache; | ||
| 7950 | } | ||
| 7951 | |||
| 7952 | static MagickWand * | ||
| 7953 | imagemagick_compute_animated_image (MagickWand *super_wand, int ino) | ||
| 7954 | { | ||
| 7955 | int i; | ||
| 7956 | MagickWand *composite_wand; | ||
| 7957 | size_t dest_width, dest_height; | ||
| 7958 | struct animation_cache *cache = imagemagick_get_animation_cache (super_wand); | ||
| 7959 | |||
| 7960 | MagickSetIteratorIndex (super_wand, 0); | ||
| 7961 | |||
| 7962 | if (ino == 0 || cache->wand == NULL || cache->index > ino) | ||
| 7963 | { | ||
| 7964 | composite_wand = MagickGetImage (super_wand); | ||
| 7965 | if (cache->wand) | ||
| 7966 | DestroyMagickWand (cache->wand); | ||
| 7967 | } | ||
| 7968 | else | ||
| 7969 | composite_wand = cache->wand; | ||
| 7970 | |||
| 7971 | dest_width = MagickGetImageWidth (composite_wand); | ||
| 7972 | dest_height = MagickGetImageHeight (composite_wand); | ||
| 7973 | |||
| 7974 | for (i = max (1, cache->index + 1); i <= ino; i++) | ||
| 7975 | { | ||
| 7976 | MagickWand *sub_wand; | ||
| 7977 | PixelIterator *source_iterator, *dest_iterator; | ||
| 7978 | PixelWand **source, **dest; | ||
| 7979 | size_t source_width, source_height; | ||
| 7980 | ssize_t source_left, source_top; | ||
| 7981 | MagickPixelPacket pixel; | ||
| 7982 | DisposeType dispose; | ||
| 7983 | ptrdiff_t lines = 0; | ||
| 7984 | |||
| 7985 | MagickSetIteratorIndex (super_wand, i); | ||
| 7986 | sub_wand = MagickGetImage (super_wand); | ||
| 7987 | |||
| 7988 | MagickGetImagePage (sub_wand, &source_width, &source_height, | ||
| 7989 | &source_left, &source_top); | ||
| 7990 | |||
| 7991 | /* This flag says how to handle transparent pixels. */ | ||
| 7992 | dispose = MagickGetImageDispose (sub_wand); | ||
| 7993 | |||
| 7994 | source_iterator = NewPixelIterator (sub_wand); | ||
| 7995 | if (! source_iterator) | ||
| 7996 | { | ||
| 7997 | DestroyMagickWand (composite_wand); | ||
| 7998 | DestroyMagickWand (sub_wand); | ||
| 7999 | cache->wand = NULL; | ||
| 8000 | image_error ("Imagemagick pixel iterator creation failed", | ||
| 8001 | Qnil, Qnil); | ||
| 8002 | return NULL; | ||
| 8003 | } | ||
| 8004 | |||
| 8005 | dest_iterator = NewPixelIterator (composite_wand); | ||
| 8006 | if (! dest_iterator) | ||
| 8007 | { | ||
| 8008 | DestroyMagickWand (composite_wand); | ||
| 8009 | DestroyMagickWand (sub_wand); | ||
| 8010 | DestroyPixelIterator (source_iterator); | ||
| 8011 | cache->wand = NULL; | ||
| 8012 | image_error ("Imagemagick pixel iterator creation failed", | ||
| 8013 | Qnil, Qnil); | ||
| 8014 | return NULL; | ||
| 8015 | } | ||
| 8016 | |||
| 8017 | /* The sub-image may not start at origin, so move the destination | ||
| 8018 | iterator to where the sub-image should start. */ | ||
| 8019 | if (source_top > 0) | ||
| 8020 | { | ||
| 8021 | PixelSetIteratorRow (dest_iterator, source_top); | ||
| 8022 | lines = source_top; | ||
| 8023 | } | ||
| 8024 | |||
| 8025 | while ((source = PixelGetNextIteratorRow (source_iterator, &source_width)) | ||
| 8026 | != NULL) | ||
| 8027 | { | ||
| 8028 | ptrdiff_t x; | ||
| 8029 | |||
| 8030 | /* Sanity check. This shouldn't happen, but apparently | ||
| 8031 | does in some pictures. */ | ||
| 8032 | if (++lines >= dest_height) | ||
| 8033 | break; | ||
| 8034 | |||
| 8035 | dest = PixelGetNextIteratorRow (dest_iterator, &dest_width); | ||
| 8036 | for (x = 0; x < source_width; x++) | ||
| 8037 | { | ||
| 8038 | /* Sanity check. This shouldn't happen, but apparently | ||
| 8039 | also does in some pictures. */ | ||
| 8040 | if (x + source_left > dest_width) | ||
| 8041 | break; | ||
| 8042 | /* Normally we only copy over non-transparent pixels, | ||
| 8043 | but if the disposal method is "Background", then we | ||
| 8044 | copy over all pixels. */ | ||
| 8045 | if (dispose == BackgroundDispose || | ||
| 8046 | PixelGetAlpha (source[x])) | ||
| 8047 | { | ||
| 8048 | PixelGetMagickColor (source[x], &pixel); | ||
| 8049 | PixelSetMagickColor (dest[x + source_left], &pixel); | ||
| 8050 | } | ||
| 8051 | } | ||
| 8052 | PixelSyncIterator (dest_iterator); | ||
| 8053 | } | ||
| 8054 | |||
| 8055 | DestroyPixelIterator (source_iterator); | ||
| 8056 | DestroyPixelIterator (dest_iterator); | ||
| 8057 | DestroyMagickWand (sub_wand); | ||
| 8058 | } | ||
| 8059 | |||
| 8060 | /* Cache a copy for the next iteration. The current wand will be | ||
| 8061 | destroyed by the caller. */ | ||
| 8062 | cache->wand = CloneMagickWand (composite_wand); | ||
| 8063 | cache->index = ino; | ||
| 8064 | |||
| 8065 | return composite_wand; | ||
| 8066 | } | ||
| 8067 | |||
| 8068 | |||
| 7851 | /* Helper function for imagemagick_load, which does the actual loading | 8069 | /* Helper function for imagemagick_load, which does the actual loading |
| 7852 | given contents and size, apart from frame and image structures, | 8070 | given contents and size, apart from frame and image structures, |
| 7853 | passed from imagemagick_load. Uses librimagemagick to do most of | 8071 | passed from imagemagick_load. Uses librimagemagick to do most of |
| @@ -7870,7 +8088,6 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7870 | XImagePtr ximg; | 8088 | XImagePtr ximg; |
| 7871 | int x, y; | 8089 | int x, y; |
| 7872 | MagickWand *image_wand; | 8090 | MagickWand *image_wand; |
| 7873 | MagickWand *ping_wand; | ||
| 7874 | PixelIterator *iterator; | 8091 | PixelIterator *iterator; |
| 7875 | PixelWand **pixels, *bg_wand = NULL; | 8092 | PixelWand **pixels, *bg_wand = NULL; |
| 7876 | MagickPixelPacket pixel; | 8093 | MagickPixelPacket pixel; |
| @@ -7881,6 +8098,8 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7881 | int desired_width, desired_height; | 8098 | int desired_width, desired_height; |
| 7882 | double rotation; | 8099 | double rotation; |
| 7883 | int pixelwidth; | 8100 | int pixelwidth; |
| 8101 | char hint_buffer[MaxTextExtent]; | ||
| 8102 | char *filename_hint = NULL; | ||
| 7884 | 8103 | ||
| 7885 | /* Handle image index for image types who can contain more than one image. | 8104 | /* Handle image index for image types who can contain more than one image. |
| 7886 | Interface :index is same as for GIF. First we "ping" the image to see how | 8105 | Interface :index is same as for GIF. First we "ping" the image to see how |
| @@ -7891,48 +8110,48 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7891 | MagickWandGenesis (); | 8110 | MagickWandGenesis (); |
| 7892 | image = image_spec_value (img->spec, QCindex, NULL); | 8111 | image = image_spec_value (img->spec, QCindex, NULL); |
| 7893 | ino = INTEGERP (image) ? XFASTINT (image) : 0; | 8112 | ino = INTEGERP (image) ? XFASTINT (image) : 0; |
| 7894 | ping_wand = NewMagickWand (); | 8113 | image_wand = NewMagickWand (); |
| 7895 | /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */ | ||
| 7896 | 8114 | ||
| 7897 | status = filename | 8115 | if (filename) |
| 7898 | ? MagickPingImage (ping_wand, filename) | 8116 | status = MagickReadImage (image_wand, filename); |
| 7899 | : MagickPingImageBlob (ping_wand, contents, size); | 8117 | else |
| 8118 | { | ||
| 8119 | filename_hint = imagemagick_filename_hint (img->spec, hint_buffer); | ||
| 8120 | MagickSetFilename (image_wand, filename_hint); | ||
| 8121 | status = MagickReadImageBlob (image_wand, contents, size); | ||
| 8122 | } | ||
| 7900 | 8123 | ||
| 7901 | if (status == MagickFalse) | 8124 | if (status == MagickFalse) |
| 7902 | { | 8125 | { |
| 7903 | imagemagick_error (ping_wand); | 8126 | imagemagick_error (image_wand); |
| 7904 | DestroyMagickWand (ping_wand); | 8127 | DestroyMagickWand (image_wand); |
| 7905 | return 0; | 8128 | return 0; |
| 7906 | } | 8129 | } |
| 7907 | 8130 | ||
| 7908 | if (ino < 0 || ino >= MagickGetNumberImages (ping_wand)) | 8131 | if (ino < 0 || ino >= MagickGetNumberImages (image_wand)) |
| 7909 | { | 8132 | { |
| 7910 | image_error ("Invalid image number `%s' in image `%s'", | 8133 | image_error ("Invalid image number `%s' in image `%s'", |
| 7911 | image, img->spec); | 8134 | image, img->spec); |
| 7912 | DestroyMagickWand (ping_wand); | 8135 | DestroyMagickWand (image_wand); |
| 7913 | return 0; | 8136 | return 0; |
| 7914 | } | 8137 | } |
| 7915 | 8138 | ||
| 7916 | if (MagickGetNumberImages (ping_wand) > 1) | 8139 | if (MagickGetNumberImages (image_wand) > 1) |
| 7917 | img->lisp_data = | 8140 | img->lisp_data = |
| 7918 | Fcons (Qcount, | 8141 | Fcons (Qcount, |
| 7919 | Fcons (make_number (MagickGetNumberImages (ping_wand)), | 8142 | Fcons (make_number (MagickGetNumberImages (image_wand)), |
| 7920 | img->lisp_data)); | 8143 | img->lisp_data)); |
| 7921 | 8144 | ||
| 7922 | DestroyMagickWand (ping_wand); | 8145 | /* If we have an animated image, get the new wand based on the |
| 7923 | 8146 | "super-wand". */ | |
| 7924 | /* Now we know how many images are inside the file. If it's not a | 8147 | if (MagickGetNumberImages (image_wand) > 1) |
| 7925 | bundle, the number is one. Load the image data. */ | ||
| 7926 | |||
| 7927 | image_wand = NewMagickWand (); | ||
| 7928 | |||
| 7929 | if ((filename | ||
| 7930 | ? MagickReadImage (image_wand, filename) | ||
| 7931 | : MagickReadImageBlob (image_wand, contents, size)) | ||
| 7932 | == MagickFalse) | ||
| 7933 | { | 8148 | { |
| 7934 | imagemagick_error (image_wand); | 8149 | MagickWand *super_wand = image_wand; |
| 7935 | goto imagemagick_error; | 8150 | image_wand = imagemagick_compute_animated_image (super_wand, ino); |
| 8151 | if (! image_wand) | ||
| 8152 | image_wand = super_wand; | ||
| 8153 | else | ||
| 8154 | DestroyMagickWand (super_wand); | ||
| 7936 | } | 8155 | } |
| 7937 | 8156 | ||
| 7938 | /* Retrieve the frame's background color, for use later. */ | 8157 | /* Retrieve the frame's background color, for use later. */ |
| @@ -8120,7 +8339,7 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8120 | 8339 | ||
| 8121 | /* Copy pixels from the imagemagick image structure to the x image map. */ | 8340 | /* Copy pixels from the imagemagick image structure to the x image map. */ |
| 8122 | iterator = NewPixelIterator (image_wand); | 8341 | iterator = NewPixelIterator (image_wand); |
| 8123 | if (iterator == (PixelIterator *) NULL) | 8342 | if (! iterator) |
| 8124 | { | 8343 | { |
| 8125 | #ifdef COLOR_TABLE_SUPPORT | 8344 | #ifdef COLOR_TABLE_SUPPORT |
| 8126 | free_color_table (); | 8345 | free_color_table (); |
| @@ -8135,7 +8354,7 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8135 | for (y = 0; y < image_height; y++) | 8354 | for (y = 0; y < image_height; y++) |
| 8136 | { | 8355 | { |
| 8137 | pixels = PixelGetNextIteratorRow (iterator, &width); | 8356 | pixels = PixelGetNextIteratorRow (iterator, &width); |
| 8138 | if (pixels == (PixelWand **) NULL) | 8357 | if (! pixels) |
| 8139 | break; | 8358 | break; |
| 8140 | for (x = 0; x < (long) width; x++) | 8359 | for (x = 0; x < (long) width; x++) |
| 8141 | { | 8360 | { |
| @@ -9200,7 +9419,7 @@ A cross is always drawn on black & white displays. */); | |||
| 9200 | 9419 | ||
| 9201 | DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path, | 9420 | DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path, |
| 9202 | doc: /* List of directories to search for window system bitmap files. */); | 9421 | doc: /* List of directories to search for window system bitmap files. */); |
| 9203 | Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); | 9422 | Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS); |
| 9204 | 9423 | ||
| 9205 | DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay, | 9424 | DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay, |
| 9206 | doc: /* Maximum time after which images are removed from the cache. | 9425 | doc: /* Maximum time after which images are removed from the cache. |
diff --git a/src/indent.c b/src/indent.c index 47358e17db8..891b42788ed 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -141,13 +141,13 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) | |||
| 141 | XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); | 141 | XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | /* Allocate or free the width run cache, as requested by the current | 144 | /* Allocate or free the width run cache, as requested by the |
| 145 | state of current_buffer's cache_long_line_scans variable. */ | 145 | current state of current_buffer's cache_long_scans variable. */ |
| 146 | 146 | ||
| 147 | static void | 147 | static void |
| 148 | width_run_cache_on_off (void) | 148 | width_run_cache_on_off (void) |
| 149 | { | 149 | { |
| 150 | if (NILP (BVAR (current_buffer, cache_long_line_scans)) | 150 | if (NILP (BVAR (current_buffer, cache_long_scans)) |
| 151 | /* And, for the moment, this feature doesn't work on multibyte | 151 | /* And, for the moment, this feature doesn't work on multibyte |
| 152 | characters. */ | 152 | characters. */ |
| 153 | || !NILP (BVAR (current_buffer, enable_multibyte_characters))) | 153 | || !NILP (BVAR (current_buffer, enable_multibyte_characters))) |
| @@ -510,15 +510,10 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol) | |||
| 510 | register ptrdiff_t col = 0, prev_col = 0; | 510 | register ptrdiff_t col = 0, prev_col = 0; |
| 511 | EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM; | 511 | EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM; |
| 512 | ptrdiff_t end = endpos ? *endpos : PT; | 512 | ptrdiff_t end = endpos ? *endpos : PT; |
| 513 | ptrdiff_t scan, scan_byte; | 513 | ptrdiff_t scan, scan_byte, next_boundary; |
| 514 | ptrdiff_t next_boundary; | 514 | |
| 515 | { | 515 | scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1); |
| 516 | ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; | ||
| 517 | scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); | ||
| 518 | scan = PT, scan_byte = PT_BYTE; | ||
| 519 | SET_PT_BOTH (opoint, opoint_byte); | ||
| 520 | next_boundary = scan; | 516 | next_boundary = scan; |
| 521 | } | ||
| 522 | 517 | ||
| 523 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); | 518 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); |
| 524 | w = ! NILP (window) ? XWINDOW (window) : NULL; | 519 | w = ! NILP (window) ? XWINDOW (window) : NULL; |
| @@ -835,14 +830,10 @@ This is the horizontal position of the character | |||
| 835 | following any initial whitespace. */) | 830 | following any initial whitespace. */) |
| 836 | (void) | 831 | (void) |
| 837 | { | 832 | { |
| 838 | Lisp_Object val; | 833 | ptrdiff_t posbyte; |
| 839 | ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; | ||
| 840 | |||
| 841 | scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); | ||
| 842 | 834 | ||
| 843 | XSETFASTINT (val, position_indentation (PT_BYTE)); | 835 | find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &posbyte, 1); |
| 844 | SET_PT_BOTH (opoint, opoint_byte); | 836 | return make_number (position_indentation (posbyte)); |
| 845 | return val; | ||
| 846 | } | 837 | } |
| 847 | 838 | ||
| 848 | static ptrdiff_t | 839 | static ptrdiff_t |
| @@ -935,16 +926,13 @@ position_indentation (ptrdiff_t pos_byte) | |||
| 935 | bool | 926 | bool |
| 936 | indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column) | 927 | indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column) |
| 937 | { | 928 | { |
| 938 | ptrdiff_t val; | 929 | while (pos > BEGV && FETCH_BYTE (pos_byte) == '\n') |
| 939 | ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; | 930 | { |
| 940 | 931 | DEC_BOTH (pos, pos_byte); | |
| 941 | SET_PT_BOTH (pos, pos_byte); | 932 | pos = find_newline (pos, pos_byte, BEGV, BEGV_BYTE, |
| 942 | while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n') | 933 | -1, NULL, &pos_byte, 0); |
| 943 | scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0); | 934 | } |
| 944 | 935 | return position_indentation (pos_byte) >= column; | |
| 945 | val = position_indentation (PT_BYTE); | ||
| 946 | SET_PT_BOTH (opoint, opoint_byte); | ||
| 947 | return val >= column; | ||
| 948 | } | 936 | } |
| 949 | 937 | ||
| 950 | DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, | 938 | DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, |
diff --git a/src/insdel.c b/src/insdel.c index 58c3e15c233..f746fd34330 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -1756,27 +1756,22 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, | |||
| 1756 | return deletion; | 1756 | return deletion; |
| 1757 | } | 1757 | } |
| 1758 | 1758 | ||
| 1759 | /* Call this if you're about to change the region of current buffer | 1759 | /* Call this if you're about to change the text of current buffer |
| 1760 | from character positions START to END. This checks the read-only | 1760 | from character positions START to END. This checks the read-only |
| 1761 | properties of the region, calls the necessary modification hooks, | 1761 | properties of the region, calls the necessary modification hooks, |
| 1762 | and warns the next redisplay that it should pay attention to that | 1762 | and warns the next redisplay that it should pay attention to that |
| 1763 | area. | 1763 | area. */ |
| 1764 | |||
| 1765 | If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF. | ||
| 1766 | Otherwise set CHARS_MODIFF to the new value of MODIFF. */ | ||
| 1767 | 1764 | ||
| 1768 | void | 1765 | void |
| 1769 | modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) | 1766 | modify_text (ptrdiff_t start, ptrdiff_t end) |
| 1770 | { | 1767 | { |
| 1771 | prepare_to_modify_buffer (start, end, NULL); | 1768 | prepare_to_modify_buffer (start, end, NULL); |
| 1772 | 1769 | ||
| 1773 | BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); | 1770 | BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); |
| 1774 | |||
| 1775 | if (MODIFF <= SAVE_MODIFF) | 1771 | if (MODIFF <= SAVE_MODIFF) |
| 1776 | record_first_change (); | 1772 | record_first_change (); |
| 1777 | MODIFF++; | 1773 | MODIFF++; |
| 1778 | if (! preserve_chars_modiff) | 1774 | CHARS_MODIFF = MODIFF; |
| 1779 | CHARS_MODIFF = MODIFF; | ||
| 1780 | 1775 | ||
| 1781 | bset_point_before_scroll (current_buffer, Qnil); | 1776 | bset_point_before_scroll (current_buffer, Qnil); |
| 1782 | } | 1777 | } |
| @@ -1792,8 +1787,8 @@ modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) | |||
| 1792 | by holding its value temporarily in a marker. */ | 1787 | by holding its value temporarily in a marker. */ |
| 1793 | 1788 | ||
| 1794 | void | 1789 | void |
| 1795 | prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | 1790 | prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end, |
| 1796 | ptrdiff_t *preserve_ptr) | 1791 | ptrdiff_t *preserve_ptr) |
| 1797 | { | 1792 | { |
| 1798 | struct buffer *base_buffer; | 1793 | struct buffer *base_buffer; |
| 1799 | 1794 | ||
| @@ -1864,6 +1859,17 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | |||
| 1864 | } | 1859 | } |
| 1865 | 1860 | ||
| 1866 | signal_before_change (start, end, preserve_ptr); | 1861 | signal_before_change (start, end, preserve_ptr); |
| 1862 | Vdeactivate_mark = Qt; | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | /* Like above, but called when we know that the buffer text | ||
| 1866 | will be modified and region caches should be invalidated. */ | ||
| 1867 | |||
| 1868 | void | ||
| 1869 | prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | ||
| 1870 | ptrdiff_t *preserve_ptr) | ||
| 1871 | { | ||
| 1872 | prepare_to_modify_buffer_1 (start, end, preserve_ptr); | ||
| 1867 | 1873 | ||
| 1868 | if (current_buffer->newline_cache) | 1874 | if (current_buffer->newline_cache) |
| 1869 | invalidate_region_cache (current_buffer, | 1875 | invalidate_region_cache (current_buffer, |
| @@ -1873,10 +1879,12 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | |||
| 1873 | invalidate_region_cache (current_buffer, | 1879 | invalidate_region_cache (current_buffer, |
| 1874 | current_buffer->width_run_cache, | 1880 | current_buffer->width_run_cache, |
| 1875 | start - BEG, Z - end); | 1881 | start - BEG, Z - end); |
| 1876 | 1882 | if (current_buffer->bidi_paragraph_cache) | |
| 1877 | Vdeactivate_mark = Qt; | 1883 | invalidate_region_cache (current_buffer, |
| 1884 | current_buffer->bidi_paragraph_cache, | ||
| 1885 | start - BEG, Z - end); | ||
| 1878 | } | 1886 | } |
| 1879 | 1887 | ||
| 1880 | /* These macros work with an argument named `preserve_ptr' | 1888 | /* These macros work with an argument named `preserve_ptr' |
| 1881 | and a local variable named `preserve_marker'. */ | 1889 | and a local variable named `preserve_marker'. */ |
| 1882 | 1890 | ||
diff --git a/src/intervals.c b/src/intervals.c index f2ddcd01507..ded536ca3c8 100644 --- a/src/intervals.c +++ b/src/intervals.c | |||
| @@ -1821,6 +1821,18 @@ set_point (ptrdiff_t charpos) | |||
| 1821 | set_point_both (charpos, buf_charpos_to_bytepos (current_buffer, charpos)); | 1821 | set_point_both (charpos, buf_charpos_to_bytepos (current_buffer, charpos)); |
| 1822 | } | 1822 | } |
| 1823 | 1823 | ||
| 1824 | /* Set PT from MARKER's clipped position. */ | ||
| 1825 | |||
| 1826 | void | ||
| 1827 | set_point_from_marker (Lisp_Object marker) | ||
| 1828 | { | ||
| 1829 | if (XMARKER (marker)->buffer != current_buffer) | ||
| 1830 | signal_error ("Marker points into wrong buffer", marker); | ||
| 1831 | set_point_both | ||
| 1832 | (clip_to_bounds (BEGV, marker_position (marker), ZV), | ||
| 1833 | clip_to_bounds (BEGV_BYTE, marker_byte_position (marker), ZV_BYTE)); | ||
| 1834 | } | ||
| 1835 | |||
| 1824 | /* If there's an invisible character at position POS + TEST_OFFS in the | 1836 | /* If there's an invisible character at position POS + TEST_OFFS in the |
| 1825 | current buffer, and the invisible property has a `stickiness' such that | 1837 | current buffer, and the invisible property has a `stickiness' such that |
| 1826 | inserting a character at position POS would inherit the property it, | 1838 | inserting a character at position POS would inherit the property it, |
diff --git a/src/keyboard.c b/src/keyboard.c index c026b16e689..b8e05cf7925 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -360,7 +360,7 @@ Lisp_Object Qmenu_bar; | |||
| 360 | static void recursive_edit_unwind (Lisp_Object buffer); | 360 | static void recursive_edit_unwind (Lisp_Object buffer); |
| 361 | static Lisp_Object command_loop (void); | 361 | static Lisp_Object command_loop (void); |
| 362 | static Lisp_Object Qcommand_execute; | 362 | static Lisp_Object Qcommand_execute; |
| 363 | EMACS_TIME timer_check (void); | 363 | struct timespec timer_check (void); |
| 364 | 364 | ||
| 365 | static void echo_now (void); | 365 | static void echo_now (void); |
| 366 | static ptrdiff_t echo_length (void); | 366 | static ptrdiff_t echo_length (void); |
| @@ -370,9 +370,9 @@ static Lisp_Object Qpolling_period; | |||
| 370 | /* Incremented whenever a timer is run. */ | 370 | /* Incremented whenever a timer is run. */ |
| 371 | unsigned timers_run; | 371 | unsigned timers_run; |
| 372 | 372 | ||
| 373 | /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt | 373 | /* Address (if not 0) of struct timespec to zero out if a SIGIO interrupt |
| 374 | happens. */ | 374 | happens. */ |
| 375 | EMACS_TIME *input_available_clear_time; | 375 | struct timespec *input_available_clear_time; |
| 376 | 376 | ||
| 377 | /* True means use SIGIO interrupts; false means use CBREAK mode. | 377 | /* True means use SIGIO interrupts; false means use CBREAK mode. |
| 378 | Default is true if INTERRUPT_INPUT is defined. */ | 378 | Default is true if INTERRUPT_INPUT is defined. */ |
| @@ -389,12 +389,12 @@ bool interrupts_deferred; | |||
| 389 | 389 | ||
| 390 | /* The time when Emacs started being idle. */ | 390 | /* The time when Emacs started being idle. */ |
| 391 | 391 | ||
| 392 | static EMACS_TIME timer_idleness_start_time; | 392 | static struct timespec timer_idleness_start_time; |
| 393 | 393 | ||
| 394 | /* After Emacs stops being idle, this saves the last value | 394 | /* After Emacs stops being idle, this saves the last value |
| 395 | of timer_idleness_start_time from when it was idle. */ | 395 | of timer_idleness_start_time from when it was idle. */ |
| 396 | 396 | ||
| 397 | static EMACS_TIME timer_last_idleness_start_time; | 397 | static struct timespec timer_last_idleness_start_time; |
| 398 | 398 | ||
| 399 | 399 | ||
| 400 | /* Global variable declarations. */ | 400 | /* Global variable declarations. */ |
| @@ -1986,10 +1986,10 @@ start_polling (void) | |||
| 1986 | /* If poll timer doesn't exist, are we need one with | 1986 | /* If poll timer doesn't exist, are we need one with |
| 1987 | a different interval, start a new one. */ | 1987 | a different interval, start a new one. */ |
| 1988 | if (poll_timer == NULL | 1988 | if (poll_timer == NULL |
| 1989 | || EMACS_SECS (poll_timer->interval) != polling_period) | 1989 | || poll_timer->interval.tv_sec != polling_period) |
| 1990 | { | 1990 | { |
| 1991 | time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); | 1991 | time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); |
| 1992 | EMACS_TIME interval = make_emacs_time (period, 0); | 1992 | struct timespec interval = make_timespec (period, 0); |
| 1993 | 1993 | ||
| 1994 | if (poll_timer) | 1994 | if (poll_timer) |
| 1995 | cancel_atimer (poll_timer); | 1995 | cancel_atimer (poll_timer); |
| @@ -2182,7 +2182,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, | |||
| 2182 | /* Input of single characters from keyboard */ | 2182 | /* Input of single characters from keyboard */ |
| 2183 | 2183 | ||
| 2184 | static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, | 2184 | static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, |
| 2185 | EMACS_TIME *end_time); | 2185 | struct timespec *end_time); |
| 2186 | static void record_char (Lisp_Object c); | 2186 | static void record_char (Lisp_Object c); |
| 2187 | 2187 | ||
| 2188 | static Lisp_Object help_form_saved_window_configs; | 2188 | static Lisp_Object help_form_saved_window_configs; |
| @@ -2204,7 +2204,7 @@ do { if (polling_stopped_here) start_polling (); \ | |||
| 2204 | polling_stopped_here = 0; } while (0) | 2204 | polling_stopped_here = 0; } while (0) |
| 2205 | 2205 | ||
| 2206 | static Lisp_Object | 2206 | static Lisp_Object |
| 2207 | read_event_from_main_queue (EMACS_TIME *end_time, | 2207 | read_event_from_main_queue (struct timespec *end_time, |
| 2208 | sys_jmp_buf local_getcjmp, | 2208 | sys_jmp_buf local_getcjmp, |
| 2209 | bool *used_mouse_menu) | 2209 | bool *used_mouse_menu) |
| 2210 | { | 2210 | { |
| @@ -2217,7 +2217,7 @@ read_event_from_main_queue (EMACS_TIME *end_time, | |||
| 2217 | /* Read from the main queue, and if that gives us something we can't use yet, | 2217 | /* Read from the main queue, and if that gives us something we can't use yet, |
| 2218 | we put it on the appropriate side queue and try again. */ | 2218 | we put it on the appropriate side queue and try again. */ |
| 2219 | 2219 | ||
| 2220 | if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) | 2220 | if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0) |
| 2221 | return c; | 2221 | return c; |
| 2222 | 2222 | ||
| 2223 | /* Actually read a character, waiting if necessary. */ | 2223 | /* Actually read a character, waiting if necessary. */ |
| @@ -2278,7 +2278,7 @@ read_event_from_main_queue (EMACS_TIME *end_time, | |||
| 2278 | /* Like `read_event_from_main_queue' but applies keyboard-coding-system | 2278 | /* Like `read_event_from_main_queue' but applies keyboard-coding-system |
| 2279 | to tty input. */ | 2279 | to tty input. */ |
| 2280 | static Lisp_Object | 2280 | static Lisp_Object |
| 2281 | read_decoded_event_from_main_queue (EMACS_TIME *end_time, | 2281 | read_decoded_event_from_main_queue (struct timespec *end_time, |
| 2282 | sys_jmp_buf local_getcjmp, | 2282 | sys_jmp_buf local_getcjmp, |
| 2283 | Lisp_Object prev_event, | 2283 | Lisp_Object prev_event, |
| 2284 | bool *used_mouse_menu) | 2284 | bool *used_mouse_menu) |
| @@ -2376,7 +2376,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time, | |||
| 2376 | Value is -2 when we find input on another keyboard. A second call | 2376 | Value is -2 when we find input on another keyboard. A second call |
| 2377 | to read_char will read it. | 2377 | to read_char will read it. |
| 2378 | 2378 | ||
| 2379 | If END_TIME is non-null, it is a pointer to an EMACS_TIME | 2379 | If END_TIME is non-null, it is a pointer to a struct timespec |
| 2380 | specifying the maximum time to wait until. If no input arrives by | 2380 | specifying the maximum time to wait until. If no input arrives by |
| 2381 | that time, stop waiting and return nil. | 2381 | that time, stop waiting and return nil. |
| 2382 | 2382 | ||
| @@ -2385,7 +2385,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time, | |||
| 2385 | Lisp_Object | 2385 | Lisp_Object |
| 2386 | read_char (int commandflag, Lisp_Object map, | 2386 | read_char (int commandflag, Lisp_Object map, |
| 2387 | Lisp_Object prev_event, | 2387 | Lisp_Object prev_event, |
| 2388 | bool *used_mouse_menu, EMACS_TIME *end_time) | 2388 | bool *used_mouse_menu, struct timespec *end_time) |
| 2389 | { | 2389 | { |
| 2390 | Lisp_Object c; | 2390 | Lisp_Object c; |
| 2391 | ptrdiff_t jmpcount; | 2391 | ptrdiff_t jmpcount; |
| @@ -2877,7 +2877,7 @@ read_char (int commandflag, Lisp_Object map, | |||
| 2877 | { | 2877 | { |
| 2878 | c = read_decoded_event_from_main_queue (end_time, local_getcjmp, | 2878 | c = read_decoded_event_from_main_queue (end_time, local_getcjmp, |
| 2879 | prev_event, used_mouse_menu); | 2879 | prev_event, used_mouse_menu); |
| 2880 | if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) | 2880 | if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0) |
| 2881 | goto exit; | 2881 | goto exit; |
| 2882 | if (EQ (c, make_number (-2))) | 2882 | if (EQ (c, make_number (-2))) |
| 2883 | { | 2883 | { |
| @@ -3798,7 +3798,7 @@ clear_event (struct input_event *event) | |||
| 3798 | static Lisp_Object | 3798 | static Lisp_Object |
| 3799 | kbd_buffer_get_event (KBOARD **kbp, | 3799 | kbd_buffer_get_event (KBOARD **kbp, |
| 3800 | bool *used_mouse_menu, | 3800 | bool *used_mouse_menu, |
| 3801 | EMACS_TIME *end_time) | 3801 | struct timespec *end_time) |
| 3802 | { | 3802 | { |
| 3803 | Lisp_Object obj; | 3803 | Lisp_Object obj; |
| 3804 | 3804 | ||
| @@ -3856,15 +3856,15 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3856 | break; | 3856 | break; |
| 3857 | if (end_time) | 3857 | if (end_time) |
| 3858 | { | 3858 | { |
| 3859 | EMACS_TIME now = current_emacs_time (); | 3859 | struct timespec now = current_timespec (); |
| 3860 | if (EMACS_TIME_LE (*end_time, now)) | 3860 | if (timespec_cmp (*end_time, now) <= 0) |
| 3861 | return Qnil; /* Finished waiting. */ | 3861 | return Qnil; /* Finished waiting. */ |
| 3862 | else | 3862 | else |
| 3863 | { | 3863 | { |
| 3864 | EMACS_TIME duration = sub_emacs_time (*end_time, now); | 3864 | struct timespec duration = timespec_sub (*end_time, now); |
| 3865 | wait_reading_process_output (min (EMACS_SECS (duration), | 3865 | wait_reading_process_output (min (duration.tv_sec, |
| 3866 | WAIT_READING_MAX), | 3866 | WAIT_READING_MAX), |
| 3867 | EMACS_NSECS (duration), | 3867 | duration.tv_nsec, |
| 3868 | -1, 1, Qnil, NULL, 0); | 3868 | -1, 1, Qnil, NULL, 0); |
| 3869 | } | 3869 | } |
| 3870 | } | 3870 | } |
| @@ -4295,10 +4295,10 @@ static void | |||
| 4295 | timer_start_idle (void) | 4295 | timer_start_idle (void) |
| 4296 | { | 4296 | { |
| 4297 | /* If we are already in the idle state, do nothing. */ | 4297 | /* If we are already in the idle state, do nothing. */ |
| 4298 | if (EMACS_TIME_VALID_P (timer_idleness_start_time)) | 4298 | if (timespec_valid_p (timer_idleness_start_time)) |
| 4299 | return; | 4299 | return; |
| 4300 | 4300 | ||
| 4301 | timer_idleness_start_time = current_emacs_time (); | 4301 | timer_idleness_start_time = current_timespec (); |
| 4302 | timer_last_idleness_start_time = timer_idleness_start_time; | 4302 | timer_last_idleness_start_time = timer_idleness_start_time; |
| 4303 | 4303 | ||
| 4304 | /* Mark all idle-time timers as once again candidates for running. */ | 4304 | /* Mark all idle-time timers as once again candidates for running. */ |
| @@ -4310,7 +4310,7 @@ timer_start_idle (void) | |||
| 4310 | static void | 4310 | static void |
| 4311 | timer_stop_idle (void) | 4311 | timer_stop_idle (void) |
| 4312 | { | 4312 | { |
| 4313 | timer_idleness_start_time = invalid_emacs_time (); | 4313 | timer_idleness_start_time = invalid_timespec (); |
| 4314 | } | 4314 | } |
| 4315 | 4315 | ||
| 4316 | /* Resume idle timer from last idle start time. */ | 4316 | /* Resume idle timer from last idle start time. */ |
| @@ -4318,7 +4318,7 @@ timer_stop_idle (void) | |||
| 4318 | static void | 4318 | static void |
| 4319 | timer_resume_idle (void) | 4319 | timer_resume_idle (void) |
| 4320 | { | 4320 | { |
| 4321 | if (EMACS_TIME_VALID_P (timer_idleness_start_time)) | 4321 | if (timespec_valid_p (timer_idleness_start_time)) |
| 4322 | return; | 4322 | return; |
| 4323 | 4323 | ||
| 4324 | timer_idleness_start_time = timer_last_idleness_start_time; | 4324 | timer_idleness_start_time = timer_last_idleness_start_time; |
| @@ -4334,7 +4334,7 @@ Lisp_Object pending_funcalls; | |||
| 4334 | 4334 | ||
| 4335 | /* Return true if TIMER is a valid timer, placing its value into *RESULT. */ | 4335 | /* Return true if TIMER is a valid timer, placing its value into *RESULT. */ |
| 4336 | static bool | 4336 | static bool |
| 4337 | decode_timer (Lisp_Object timer, EMACS_TIME *result) | 4337 | decode_timer (Lisp_Object timer, struct timespec *result) |
| 4338 | { | 4338 | { |
| 4339 | Lisp_Object *vector; | 4339 | Lisp_Object *vector; |
| 4340 | 4340 | ||
| @@ -4361,16 +4361,16 @@ decode_timer (Lisp_Object timer, EMACS_TIME *result) | |||
| 4361 | In that case we return 0 to indicate that a new timer_check_2 call | 4361 | In that case we return 0 to indicate that a new timer_check_2 call |
| 4362 | should be done. */ | 4362 | should be done. */ |
| 4363 | 4363 | ||
| 4364 | static EMACS_TIME | 4364 | static struct timespec |
| 4365 | timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | 4365 | timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) |
| 4366 | { | 4366 | { |
| 4367 | EMACS_TIME nexttime; | 4367 | struct timespec nexttime; |
| 4368 | EMACS_TIME now; | 4368 | struct timespec now; |
| 4369 | EMACS_TIME idleness_now; | 4369 | struct timespec idleness_now; |
| 4370 | Lisp_Object chosen_timer; | 4370 | Lisp_Object chosen_timer; |
| 4371 | struct gcpro gcpro1; | 4371 | struct gcpro gcpro1; |
| 4372 | 4372 | ||
| 4373 | nexttime = invalid_emacs_time (); | 4373 | nexttime = invalid_timespec (); |
| 4374 | 4374 | ||
| 4375 | chosen_timer = Qnil; | 4375 | chosen_timer = Qnil; |
| 4376 | GCPRO1 (chosen_timer); | 4376 | GCPRO1 (chosen_timer); |
| @@ -4385,19 +4385,19 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | |||
| 4385 | 4385 | ||
| 4386 | if (CONSP (timers) || CONSP (idle_timers)) | 4386 | if (CONSP (timers) || CONSP (idle_timers)) |
| 4387 | { | 4387 | { |
| 4388 | now = current_emacs_time (); | 4388 | now = current_timespec (); |
| 4389 | idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time) | 4389 | idleness_now = (timespec_valid_p (timer_idleness_start_time) |
| 4390 | ? sub_emacs_time (now, timer_idleness_start_time) | 4390 | ? timespec_sub (now, timer_idleness_start_time) |
| 4391 | : make_emacs_time (0, 0)); | 4391 | : make_timespec (0, 0)); |
| 4392 | } | 4392 | } |
| 4393 | 4393 | ||
| 4394 | while (CONSP (timers) || CONSP (idle_timers)) | 4394 | while (CONSP (timers) || CONSP (idle_timers)) |
| 4395 | { | 4395 | { |
| 4396 | Lisp_Object timer = Qnil, idle_timer = Qnil; | 4396 | Lisp_Object timer = Qnil, idle_timer = Qnil; |
| 4397 | EMACS_TIME timer_time, idle_timer_time; | 4397 | struct timespec timer_time, idle_timer_time; |
| 4398 | EMACS_TIME difference; | 4398 | struct timespec difference; |
| 4399 | EMACS_TIME timer_difference = invalid_emacs_time (); | 4399 | struct timespec timer_difference = invalid_timespec (); |
| 4400 | EMACS_TIME idle_timer_difference = invalid_emacs_time (); | 4400 | struct timespec idle_timer_difference = invalid_timespec (); |
| 4401 | bool ripe, timer_ripe = 0, idle_timer_ripe = 0; | 4401 | bool ripe, timer_ripe = 0, idle_timer_ripe = 0; |
| 4402 | 4402 | ||
| 4403 | /* Set TIMER and TIMER_DIFFERENCE | 4403 | /* Set TIMER and TIMER_DIFFERENCE |
| @@ -4414,10 +4414,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | |||
| 4414 | continue; | 4414 | continue; |
| 4415 | } | 4415 | } |
| 4416 | 4416 | ||
| 4417 | timer_ripe = EMACS_TIME_LE (timer_time, now); | 4417 | timer_ripe = timespec_cmp (timer_time, now) <= 0; |
| 4418 | timer_difference = (timer_ripe | 4418 | timer_difference = (timer_ripe |
| 4419 | ? sub_emacs_time (now, timer_time) | 4419 | ? timespec_sub (now, timer_time) |
| 4420 | : sub_emacs_time (timer_time, now)); | 4420 | : timespec_sub (timer_time, now)); |
| 4421 | } | 4421 | } |
| 4422 | 4422 | ||
| 4423 | /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE | 4423 | /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE |
| @@ -4431,26 +4431,27 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | |||
| 4431 | continue; | 4431 | continue; |
| 4432 | } | 4432 | } |
| 4433 | 4433 | ||
| 4434 | idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now); | 4434 | idle_timer_ripe = timespec_cmp (idle_timer_time, idleness_now) <= 0; |
| 4435 | idle_timer_difference | 4435 | idle_timer_difference |
| 4436 | = (idle_timer_ripe | 4436 | = (idle_timer_ripe |
| 4437 | ? sub_emacs_time (idleness_now, idle_timer_time) | 4437 | ? timespec_sub (idleness_now, idle_timer_time) |
| 4438 | : sub_emacs_time (idle_timer_time, idleness_now)); | 4438 | : timespec_sub (idle_timer_time, idleness_now)); |
| 4439 | } | 4439 | } |
| 4440 | 4440 | ||
| 4441 | /* Decide which timer is the next timer, | 4441 | /* Decide which timer is the next timer, |
| 4442 | and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly. | 4442 | and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly. |
| 4443 | Also step down the list where we found that timer. */ | 4443 | Also step down the list where we found that timer. */ |
| 4444 | 4444 | ||
| 4445 | if (EMACS_TIME_VALID_P (timer_difference) | 4445 | if (timespec_valid_p (timer_difference) |
| 4446 | && (! EMACS_TIME_VALID_P (idle_timer_difference) | 4446 | && (! timespec_valid_p (idle_timer_difference) |
| 4447 | || idle_timer_ripe < timer_ripe | 4447 | || idle_timer_ripe < timer_ripe |
| 4448 | || (idle_timer_ripe == timer_ripe | 4448 | || (idle_timer_ripe == timer_ripe |
| 4449 | && (timer_ripe | 4449 | && ((timer_ripe |
| 4450 | ? EMACS_TIME_LT (idle_timer_difference, | 4450 | ? timespec_cmp (idle_timer_difference, |
| 4451 | timer_difference) | 4451 | timer_difference) |
| 4452 | : EMACS_TIME_LT (timer_difference, | 4452 | : timespec_cmp (timer_difference, |
| 4453 | idle_timer_difference))))) | 4453 | idle_timer_difference)) |
| 4454 | < 0)))) | ||
| 4454 | { | 4455 | { |
| 4455 | chosen_timer = timer; | 4456 | chosen_timer = timer; |
| 4456 | timers = XCDR (timers); | 4457 | timers = XCDR (timers); |
| @@ -4490,7 +4491,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | |||
| 4490 | return 0 to indicate that. */ | 4491 | return 0 to indicate that. */ |
| 4491 | } | 4492 | } |
| 4492 | 4493 | ||
| 4493 | nexttime = make_emacs_time (0, 0); | 4494 | nexttime = make_timespec (0, 0); |
| 4494 | break; | 4495 | break; |
| 4495 | } | 4496 | } |
| 4496 | else | 4497 | else |
| @@ -4518,10 +4519,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) | |||
| 4518 | 4519 | ||
| 4519 | As long as any timer is ripe, we run it. */ | 4520 | As long as any timer is ripe, we run it. */ |
| 4520 | 4521 | ||
| 4521 | EMACS_TIME | 4522 | struct timespec |
| 4522 | timer_check (void) | 4523 | timer_check (void) |
| 4523 | { | 4524 | { |
| 4524 | EMACS_TIME nexttime; | 4525 | struct timespec nexttime; |
| 4525 | Lisp_Object timers, idle_timers; | 4526 | Lisp_Object timers, idle_timers; |
| 4526 | struct gcpro gcpro1, gcpro2; | 4527 | struct gcpro gcpro1, gcpro2; |
| 4527 | 4528 | ||
| @@ -4535,7 +4536,7 @@ timer_check (void) | |||
| 4535 | /* Always consider the ordinary timers. */ | 4536 | /* Always consider the ordinary timers. */ |
| 4536 | timers = Fcopy_sequence (Vtimer_list); | 4537 | timers = Fcopy_sequence (Vtimer_list); |
| 4537 | /* Consider the idle timers only if Emacs is idle. */ | 4538 | /* Consider the idle timers only if Emacs is idle. */ |
| 4538 | if (EMACS_TIME_VALID_P (timer_idleness_start_time)) | 4539 | if (timespec_valid_p (timer_idleness_start_time)) |
| 4539 | idle_timers = Fcopy_sequence (Vtimer_idle_list); | 4540 | idle_timers = Fcopy_sequence (Vtimer_idle_list); |
| 4540 | else | 4541 | else |
| 4541 | idle_timers = Qnil; | 4542 | idle_timers = Qnil; |
| @@ -4548,7 +4549,7 @@ timer_check (void) | |||
| 4548 | { | 4549 | { |
| 4549 | nexttime = timer_check_2 (timers, idle_timers); | 4550 | nexttime = timer_check_2 (timers, idle_timers); |
| 4550 | } | 4551 | } |
| 4551 | while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0); | 4552 | while (nexttime.tv_sec == 0 && nexttime.tv_nsec == 0); |
| 4552 | 4553 | ||
| 4553 | UNGCPRO; | 4554 | UNGCPRO; |
| 4554 | return nexttime; | 4555 | return nexttime; |
| @@ -4564,9 +4565,9 @@ The value when Emacs is not idle is nil. | |||
| 4564 | PSEC is a multiple of the system clock resolution. */) | 4565 | PSEC is a multiple of the system clock resolution. */) |
| 4565 | (void) | 4566 | (void) |
| 4566 | { | 4567 | { |
| 4567 | if (EMACS_TIME_VALID_P (timer_idleness_start_time)) | 4568 | if (timespec_valid_p (timer_idleness_start_time)) |
| 4568 | return make_lisp_time (sub_emacs_time (current_emacs_time (), | 4569 | return make_lisp_time (timespec_sub (current_timespec (), |
| 4569 | timer_idleness_start_time)); | 4570 | timer_idleness_start_time)); |
| 4570 | 4571 | ||
| 4571 | return Qnil; | 4572 | return Qnil; |
| 4572 | } | 4573 | } |
| @@ -7126,7 +7127,7 @@ handle_input_available_signal (int sig) | |||
| 7126 | pending_signals = 1; | 7127 | pending_signals = 1; |
| 7127 | 7128 | ||
| 7128 | if (input_available_clear_time) | 7129 | if (input_available_clear_time) |
| 7129 | *input_available_clear_time = make_emacs_time (0, 0); | 7130 | *input_available_clear_time = make_timespec (0, 0); |
| 7130 | } | 7131 | } |
| 7131 | 7132 | ||
| 7132 | static void | 7133 | static void |
| @@ -7213,7 +7214,7 @@ handle_user_signal (int sig) | |||
| 7213 | /* Tell wait_reading_process_output that it needs to wake | 7214 | /* Tell wait_reading_process_output that it needs to wake |
| 7214 | up and look around. */ | 7215 | up and look around. */ |
| 7215 | if (input_available_clear_time) | 7216 | if (input_available_clear_time) |
| 7216 | *input_available_clear_time = make_emacs_time (0, 0); | 7217 | *input_available_clear_time = make_timespec (0, 0); |
| 7217 | } | 7218 | } |
| 7218 | break; | 7219 | break; |
| 7219 | } | 7220 | } |
| @@ -8431,7 +8432,7 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8431 | return Qnil; | 8432 | return Qnil; |
| 8432 | 8433 | ||
| 8433 | #define PUSH_C_STR(str, listvar) \ | 8434 | #define PUSH_C_STR(str, listvar) \ |
| 8434 | listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar) | 8435 | listvar = Fcons (build_unibyte_string (str), listvar) |
| 8435 | 8436 | ||
| 8436 | /* Prompt string always starts with map's prompt, and a space. */ | 8437 | /* Prompt string always starts with map's prompt, and a space. */ |
| 8437 | prompt_strings = Fcons (name, prompt_strings); | 8438 | prompt_strings = Fcons (name, prompt_strings); |
| @@ -10124,8 +10125,6 @@ Also end any kbd macro being defined. */) | |||
| 10124 | end_kbd_macro (); | 10125 | end_kbd_macro (); |
| 10125 | } | 10126 | } |
| 10126 | 10127 | ||
| 10127 | update_mode_lines++; | ||
| 10128 | |||
| 10129 | Vunread_command_events = Qnil; | 10128 | Vunread_command_events = Qnil; |
| 10130 | 10129 | ||
| 10131 | discard_tty_input (); | 10130 | discard_tty_input (); |
| @@ -10237,7 +10236,7 @@ stuff_buffered_input (Lisp_Object stuffstring) | |||
| 10237 | } | 10236 | } |
| 10238 | 10237 | ||
| 10239 | void | 10238 | void |
| 10240 | set_waiting_for_input (EMACS_TIME *time_to_clear) | 10239 | set_waiting_for_input (struct timespec *time_to_clear) |
| 10241 | { | 10240 | { |
| 10242 | input_available_clear_time = time_to_clear; | 10241 | input_available_clear_time = time_to_clear; |
| 10243 | 10242 | ||
| @@ -10848,7 +10847,7 @@ init_keyboard (void) | |||
| 10848 | immediate_quit = 0; | 10847 | immediate_quit = 0; |
| 10849 | quit_char = Ctl ('g'); | 10848 | quit_char = Ctl ('g'); |
| 10850 | Vunread_command_events = Qnil; | 10849 | Vunread_command_events = Qnil; |
| 10851 | timer_idleness_start_time = invalid_emacs_time (); | 10850 | timer_idleness_start_time = invalid_timespec (); |
| 10852 | total_keys = 0; | 10851 | total_keys = 0; |
| 10853 | recent_keys_index = 0; | 10852 | recent_keys_index = 0; |
| 10854 | kbd_fetch_ptr = kbd_buffer; | 10853 | kbd_fetch_ptr = kbd_buffer; |
diff --git a/src/keyboard.h b/src/keyboard.h index daba94898d8..1ee4a97c5c5 100644 --- a/src/keyboard.h +++ b/src/keyboard.h | |||
| @@ -17,8 +17,9 @@ GNU General Public License for more details. | |||
| 17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | 19 | ||
| 20 | #include "systime.h" /* for EMACS_TIME, Time */ | 20 | #include "systime.h" /* for struct timespec, Time */ |
| 21 | #include "coding.h" /* for ENCODE_UTF_8 and ENCODE_SYSTEM */ | 21 | #include "coding.h" /* for ENCODE_UTF_8 and ENCODE_SYSTEM */ |
| 22 | #include "termhooks.h" | ||
| 22 | 23 | ||
| 23 | INLINE_HEADER_BEGIN | 24 | INLINE_HEADER_BEGIN |
| 24 | #ifndef KEYBOARD_INLINE | 25 | #ifndef KEYBOARD_INLINE |
| @@ -466,9 +467,9 @@ extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line; | |||
| 466 | /* True while doing kbd input. */ | 467 | /* True while doing kbd input. */ |
| 467 | extern bool waiting_for_input; | 468 | extern bool waiting_for_input; |
| 468 | 469 | ||
| 469 | /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt | 470 | /* Address (if not 0) of struct timespec to zero out if a SIGIO interrupt |
| 470 | happens. */ | 471 | happens. */ |
| 471 | extern EMACS_TIME *input_available_clear_time; | 472 | extern struct timespec *input_available_clear_time; |
| 472 | 473 | ||
| 473 | #if defined HAVE_WINDOW_SYSTEM && !defined USE_GTK && !defined HAVE_NS | 474 | #if defined HAVE_WINDOW_SYSTEM && !defined USE_GTK && !defined HAVE_NS |
| 474 | extern bool ignore_mouse_drag_p; | 475 | extern bool ignore_mouse_drag_p; |
| @@ -477,13 +478,10 @@ extern bool ignore_mouse_drag_p; | |||
| 477 | /* The primary selection. */ | 478 | /* The primary selection. */ |
| 478 | extern Lisp_Object QPRIMARY; | 479 | extern Lisp_Object QPRIMARY; |
| 479 | 480 | ||
| 480 | /* Forward declaration for prototypes. */ | ||
| 481 | struct input_event; | ||
| 482 | |||
| 483 | extern Lisp_Object parse_modifiers (Lisp_Object); | 481 | extern Lisp_Object parse_modifiers (Lisp_Object); |
| 484 | extern Lisp_Object reorder_modifiers (Lisp_Object); | 482 | extern Lisp_Object reorder_modifiers (Lisp_Object); |
| 485 | extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object, | 483 | extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object, |
| 486 | bool *, EMACS_TIME *); | 484 | bool *, struct timespec *); |
| 487 | extern int parse_solitary_modifier (Lisp_Object symbol); | 485 | extern int parse_solitary_modifier (Lisp_Object symbol); |
| 488 | 486 | ||
| 489 | 487 | ||
| @@ -549,7 +547,7 @@ extern bool kbd_buffer_events_waiting (void); | |||
| 549 | extern void add_user_signal (int, const char *); | 547 | extern void add_user_signal (int, const char *); |
| 550 | 548 | ||
| 551 | extern int tty_read_avail_input (struct terminal *, struct input_event *); | 549 | extern int tty_read_avail_input (struct terminal *, struct input_event *); |
| 552 | extern EMACS_TIME timer_check (void); | 550 | extern struct timespec timer_check (void); |
| 553 | extern void mark_kboards (void); | 551 | extern void mark_kboards (void); |
| 554 | 552 | ||
| 555 | #ifdef HAVE_NTGUI | 553 | #ifdef HAVE_NTGUI |
diff --git a/src/keymap.c b/src/keymap.c index d13a6274347..7a18cd5d983 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -3249,8 +3249,7 @@ describe_map (Lisp_Object map, Lisp_Object prefix, | |||
| 3249 | for (tail = map; CONSP (tail); tail = XCDR (tail)) | 3249 | for (tail = map; CONSP (tail); tail = XCDR (tail)) |
| 3250 | length_needed++; | 3250 | length_needed++; |
| 3251 | 3251 | ||
| 3252 | vect = ((struct describe_map_elt *) | 3252 | vect = alloca (length_needed * sizeof *vect); |
| 3253 | alloca (sizeof (struct describe_map_elt) * length_needed)); | ||
| 3254 | 3253 | ||
| 3255 | for (tail = map; CONSP (tail); tail = XCDR (tail)) | 3254 | for (tail = map; CONSP (tail); tail = XCDR (tail)) |
| 3256 | { | 3255 | { |
diff --git a/src/lisp.h b/src/lisp.h index 5daddb7d335..b19745baf91 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -734,6 +734,7 @@ extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; | |||
| 734 | extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; | 734 | extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; |
| 735 | extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; | 735 | extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; |
| 736 | extern Lisp_Object Qvector_or_char_table_p, Qwholenump; | 736 | extern Lisp_Object Qvector_or_char_table_p, Qwholenump; |
| 737 | extern Lisp_Object Qwindow; | ||
| 737 | extern Lisp_Object Ffboundp (Lisp_Object); | 738 | extern Lisp_Object Ffboundp (Lisp_Object); |
| 738 | extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); | 739 | extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); |
| 739 | 740 | ||
| @@ -865,11 +866,7 @@ make_lisp_proc (struct Lisp_Process *p) | |||
| 865 | #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) | 866 | #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) |
| 866 | #define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol)) | 867 | #define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol)) |
| 867 | #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) | 868 | #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) |
| 868 | |||
| 869 | /* Misc types. */ | ||
| 870 | |||
| 871 | #define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) | 869 | #define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) |
| 872 | #define XSETMARKER(a, b) (XSETMISC (a, b), XMISCTYPE (a) = Lisp_Misc_Marker) | ||
| 873 | 870 | ||
| 874 | /* Pseudovector types. */ | 871 | /* Pseudovector types. */ |
| 875 | 872 | ||
| @@ -2163,38 +2160,6 @@ enum char_bits | |||
| 2163 | CHARACTERBITS = 22 | 2160 | CHARACTERBITS = 22 |
| 2164 | }; | 2161 | }; |
| 2165 | 2162 | ||
| 2166 | /* Structure to hold mouse highlight data. This is here because other | ||
| 2167 | header files need it for defining struct x_output etc. */ | ||
| 2168 | typedef struct { | ||
| 2169 | /* These variables describe the range of text currently shown in its | ||
| 2170 | mouse-face, together with the window they apply to. As long as | ||
| 2171 | the mouse stays within this range, we need not redraw anything on | ||
| 2172 | its account. Rows and columns are glyph matrix positions in | ||
| 2173 | MOUSE_FACE_WINDOW. */ | ||
| 2174 | int mouse_face_beg_row, mouse_face_beg_col; | ||
| 2175 | int mouse_face_beg_x, mouse_face_beg_y; | ||
| 2176 | int mouse_face_end_row, mouse_face_end_col; | ||
| 2177 | int mouse_face_end_x, mouse_face_end_y; | ||
| 2178 | Lisp_Object mouse_face_window; | ||
| 2179 | int mouse_face_face_id; | ||
| 2180 | Lisp_Object mouse_face_overlay; | ||
| 2181 | |||
| 2182 | /* FRAME and X, Y position of mouse when last checked for | ||
| 2183 | highlighting. X and Y can be negative or out of range for the frame. */ | ||
| 2184 | struct frame *mouse_face_mouse_frame; | ||
| 2185 | int mouse_face_mouse_x, mouse_face_mouse_y; | ||
| 2186 | |||
| 2187 | /* Nonzero if part of the text currently shown in | ||
| 2188 | its mouse-face is beyond the window end. */ | ||
| 2189 | unsigned mouse_face_past_end : 1; | ||
| 2190 | |||
| 2191 | /* Nonzero means defer mouse-motion highlighting. */ | ||
| 2192 | unsigned mouse_face_defer : 1; | ||
| 2193 | |||
| 2194 | /* Nonzero means that the mouse highlight should not be shown. */ | ||
| 2195 | unsigned mouse_face_hidden : 1; | ||
| 2196 | } Mouse_HLInfo; | ||
| 2197 | |||
| 2198 | /* Data type checking. */ | 2163 | /* Data type checking. */ |
| 2199 | 2164 | ||
| 2200 | LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x)) | 2165 | LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x)) |
| @@ -2665,19 +2630,6 @@ typedef jmp_buf sys_jmp_buf; | |||
| 2665 | they are bound by a function application or a let form, stores the | 2630 | they are bound by a function application or a let form, stores the |
| 2666 | code to be executed for unwind-protect forms. | 2631 | code to be executed for unwind-protect forms. |
| 2667 | 2632 | ||
| 2668 | If func is non-zero, undoing this binding applies func to old_value; | ||
| 2669 | This implements record_unwind_protect. | ||
| 2670 | |||
| 2671 | Otherwise, the element is a variable binding. | ||
| 2672 | |||
| 2673 | If the symbol field is a symbol, it is an ordinary variable binding. | ||
| 2674 | |||
| 2675 | Otherwise, it should be a structure (SYMBOL WHERE . CURRENT-BUFFER), | ||
| 2676 | which means having bound a local value while CURRENT-BUFFER was active. | ||
| 2677 | If WHERE is nil this means we saw the default value when binding SYMBOL. | ||
| 2678 | WHERE being a buffer or frame means we saw a buffer-local or frame-local | ||
| 2679 | value. Other values of WHERE mean an internal error. | ||
| 2680 | |||
| 2681 | NOTE: The specbinding union is defined here, because SPECPDL_INDEX is | 2633 | NOTE: The specbinding union is defined here, because SPECPDL_INDEX is |
| 2682 | used all over the place, needs to be fast, and needs to know the size of | 2634 | used all over the place, needs to be fast, and needs to know the size of |
| 2683 | union specbinding. But only eval.c should access it. */ | 2635 | union specbinding. But only eval.c should access it. */ |
| @@ -3369,8 +3321,9 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool); | |||
| 3369 | extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); | 3321 | extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); |
| 3370 | extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, | 3322 | extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, |
| 3371 | ptrdiff_t, ptrdiff_t, bool); | 3323 | ptrdiff_t, ptrdiff_t, bool); |
| 3372 | extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); | 3324 | extern void modify_text (ptrdiff_t, ptrdiff_t); |
| 3373 | extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); | 3325 | extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); |
| 3326 | extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *); | ||
| 3374 | extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); | 3327 | extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 3375 | extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3328 | extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3376 | ptrdiff_t, ptrdiff_t); | 3329 | ptrdiff_t, ptrdiff_t); |
| @@ -3744,11 +3697,12 @@ extern Lisp_Object internal_condition_case_n | |||
| 3744 | Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); | 3697 | Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); |
| 3745 | extern void specbind (Lisp_Object, Lisp_Object); | 3698 | extern void specbind (Lisp_Object, Lisp_Object); |
| 3746 | extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); | 3699 | extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); |
| 3747 | extern void record_unwind_protect_int (void (*) (int), int); | ||
| 3748 | extern void record_unwind_protect_ptr (void (*) (void *), void *); | 3700 | extern void record_unwind_protect_ptr (void (*) (void *), void *); |
| 3701 | extern void record_unwind_protect_int (void (*) (int), int); | ||
| 3749 | extern void record_unwind_protect_void (void (*) (void)); | 3702 | extern void record_unwind_protect_void (void (*) (void)); |
| 3750 | extern void record_unwind_protect_nothing (void); | 3703 | extern void record_unwind_protect_nothing (void); |
| 3751 | extern void clear_unwind_protect (ptrdiff_t); | 3704 | extern void clear_unwind_protect (ptrdiff_t); |
| 3705 | extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object); | ||
| 3752 | extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *); | 3706 | extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *); |
| 3753 | extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); | 3707 | extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); |
| 3754 | extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); | 3708 | extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); |
| @@ -3797,9 +3751,7 @@ extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t); | |||
| 3797 | extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, | 3751 | extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, |
| 3798 | Lisp_Object, Lisp_Object, Lisp_Object); | 3752 | Lisp_Object, Lisp_Object, Lisp_Object); |
| 3799 | extern bool overlay_touches_p (ptrdiff_t); | 3753 | extern bool overlay_touches_p (ptrdiff_t); |
| 3800 | extern Lisp_Object Vbuffer_alist; | ||
| 3801 | extern Lisp_Object other_buffer_safely (Lisp_Object); | 3754 | extern Lisp_Object other_buffer_safely (Lisp_Object); |
| 3802 | extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; | ||
| 3803 | extern Lisp_Object get_truename_buffer (Lisp_Object); | 3755 | extern Lisp_Object get_truename_buffer (Lisp_Object); |
| 3804 | extern void init_buffer_once (void); | 3756 | extern void init_buffer_once (void); |
| 3805 | extern void init_buffer (void); | 3757 | extern void init_buffer (void); |
| @@ -3830,6 +3782,9 @@ extern Lisp_Object Qfile_directory_p; | |||
| 3830 | extern Lisp_Object Qinsert_file_contents; | 3782 | extern Lisp_Object Qinsert_file_contents; |
| 3831 | extern Lisp_Object Qfile_name_history; | 3783 | extern Lisp_Object Qfile_name_history; |
| 3832 | extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); | 3784 | extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); |
| 3785 | extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, | ||
| 3786 | Lisp_Object, Lisp_Object, Lisp_Object, | ||
| 3787 | Lisp_Object, int); | ||
| 3833 | EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ | 3788 | EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ |
| 3834 | extern void close_file_unwind (int); | 3789 | extern void close_file_unwind (int); |
| 3835 | extern void fclose_unwind (void *); | 3790 | extern void fclose_unwind (void *); |
| @@ -3862,8 +3817,8 @@ extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, | |||
| 3862 | ptrdiff_t, ptrdiff_t, Lisp_Object); | 3817 | ptrdiff_t, ptrdiff_t, Lisp_Object); |
| 3863 | extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3818 | extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3864 | ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); | 3819 | ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); |
| 3865 | extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3820 | extern ptrdiff_t scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3866 | EMACS_INT, bool); | 3821 | ptrdiff_t, bool); |
| 3867 | extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t, | 3822 | extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t, |
| 3868 | ptrdiff_t, ptrdiff_t *); | 3823 | ptrdiff_t, ptrdiff_t *); |
| 3869 | extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, | 3824 | extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, |
| @@ -4096,7 +4051,6 @@ extern void init_sys_modes (struct tty_display_info *); | |||
| 4096 | extern void reset_sys_modes (struct tty_display_info *); | 4051 | extern void reset_sys_modes (struct tty_display_info *); |
| 4097 | extern void init_all_sys_modes (void); | 4052 | extern void init_all_sys_modes (void); |
| 4098 | extern void reset_all_sys_modes (void); | 4053 | extern void reset_all_sys_modes (void); |
| 4099 | extern void flush_pending_output (int) ATTRIBUTE_CONST; | ||
| 4100 | extern void child_setup_tty (int); | 4054 | extern void child_setup_tty (int); |
| 4101 | extern void setup_pty (int); | 4055 | extern void setup_pty (int); |
| 4102 | extern int set_window_size (int, int, int); | 4056 | extern int set_window_size (int, int, int); |
| @@ -4213,6 +4167,11 @@ extern void syms_of_xml (void); | |||
| 4213 | extern void xml_cleanup_parser (void); | 4167 | extern void xml_cleanup_parser (void); |
| 4214 | #endif | 4168 | #endif |
| 4215 | 4169 | ||
| 4170 | #ifdef HAVE_ZLIB | ||
| 4171 | /* Defined in decompress.c. */ | ||
| 4172 | extern void syms_of_decompress (void); | ||
| 4173 | #endif | ||
| 4174 | |||
| 4216 | #ifdef HAVE_DBUS | 4175 | #ifdef HAVE_DBUS |
| 4217 | /* Defined in dbusbind.c. */ | 4176 | /* Defined in dbusbind.c. */ |
| 4218 | void syms_of_dbusbind (void); | 4177 | void syms_of_dbusbind (void); |
| @@ -4246,10 +4205,17 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t); | |||
| 4246 | extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); | 4205 | extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 4247 | 4206 | ||
| 4248 | extern char *xstrdup (const char *); | 4207 | extern char *xstrdup (const char *); |
| 4208 | extern char *xlispstrdup (Lisp_Object); | ||
| 4249 | extern void xputenv (const char *); | 4209 | extern void xputenv (const char *); |
| 4250 | 4210 | ||
| 4251 | extern char *egetenv (const char *); | 4211 | extern char *egetenv (const char *); |
| 4252 | 4212 | ||
| 4213 | /* Copy Lisp string to temporary (allocated on stack) C string. */ | ||
| 4214 | |||
| 4215 | #define xlispstrdupa(string) \ | ||
| 4216 | memcpy (alloca (SBYTES (string) + 1), \ | ||
| 4217 | SSDATA (string), SBYTES (string) + 1) | ||
| 4218 | |||
| 4253 | /* Set up the name of the machine we're running on. */ | 4219 | /* Set up the name of the machine we're running on. */ |
| 4254 | extern void init_system_name (void); | 4220 | extern void init_system_name (void); |
| 4255 | 4221 | ||
| @@ -4326,6 +4292,12 @@ extern void *record_xmalloc (size_t); | |||
| 4326 | memory_full (SIZE_MAX); \ | 4292 | memory_full (SIZE_MAX); \ |
| 4327 | } while (0) | 4293 | } while (0) |
| 4328 | 4294 | ||
| 4295 | /* Do a `for' loop over alist values. */ | ||
| 4296 | |||
| 4297 | #define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \ | ||
| 4298 | for (list_var = head_var; \ | ||
| 4299 | (CONSP (list_var) && (value_var = XCDR (XCAR (list_var)), 1)); \ | ||
| 4300 | list_var = XCDR (list_var)) | ||
| 4329 | 4301 | ||
| 4330 | /* Check whether it's time for GC, and run it if so. */ | 4302 | /* Check whether it's time for GC, and run it if so. */ |
| 4331 | 4303 | ||
diff --git a/src/lisp.mk b/src/lisp.mk index edd81bcf493..a9a661ea3a8 100644 --- a/src/lisp.mk +++ b/src/lisp.mk | |||
| @@ -71,6 +71,7 @@ lisp = \ | |||
| 71 | $(lispsource)/faces.elc \ | 71 | $(lispsource)/faces.elc \ |
| 72 | $(lispsource)/button.elc \ | 72 | $(lispsource)/button.elc \ |
| 73 | $(lispsource)/startup.elc \ | 73 | $(lispsource)/startup.elc \ |
| 74 | $(lispsource)/emacs-lisp/nadvice.elc \ | ||
| 74 | $(lispsource)/minibuffer.elc \ | 75 | $(lispsource)/minibuffer.elc \ |
| 75 | $(lispsource)/abbrev.elc \ | 76 | $(lispsource)/abbrev.elc \ |
| 76 | $(lispsource)/simple.elc \ | 77 | $(lispsource)/simple.elc \ |
diff --git a/src/lread.c b/src/lread.c index 57c7df74127..9518631ba6d 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -609,7 +609,7 @@ read_filtered_event (bool no_switch_frame, bool ascii_required, | |||
| 609 | bool error_nonascii, bool input_method, Lisp_Object seconds) | 609 | bool error_nonascii, bool input_method, Lisp_Object seconds) |
| 610 | { | 610 | { |
| 611 | Lisp_Object val, delayed_switch_frame; | 611 | Lisp_Object val, delayed_switch_frame; |
| 612 | EMACS_TIME end_time; | 612 | struct timespec end_time; |
| 613 | 613 | ||
| 614 | #ifdef HAVE_WINDOW_SYSTEM | 614 | #ifdef HAVE_WINDOW_SYSTEM |
| 615 | if (display_hourglass_p) | 615 | if (display_hourglass_p) |
| @@ -622,8 +622,8 @@ read_filtered_event (bool no_switch_frame, bool ascii_required, | |||
| 622 | if (NUMBERP (seconds)) | 622 | if (NUMBERP (seconds)) |
| 623 | { | 623 | { |
| 624 | double duration = extract_float (seconds); | 624 | double duration = extract_float (seconds); |
| 625 | EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration); | 625 | struct timespec wait_time = dtotimespec (duration); |
| 626 | end_time = add_emacs_time (current_emacs_time (), wait_time); | 626 | end_time = timespec_add (current_timespec (), wait_time); |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | /* Read until we get an acceptable event. */ | 629 | /* Read until we get an acceptable event. */ |
| @@ -1262,7 +1262,7 @@ Return t if the file exists and loads successfully. */) | |||
| 1262 | } | 1262 | } |
| 1263 | 1263 | ||
| 1264 | if (result == 0 | 1264 | if (result == 0 |
| 1265 | && EMACS_TIME_LT (get_stat_mtime (&s1), get_stat_mtime (&s2))) | 1265 | && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0) |
| 1266 | { | 1266 | { |
| 1267 | /* Make the progress messages mention that source is newer. */ | 1267 | /* Make the progress messages mention that source is newer. */ |
| 1268 | newer = 1; | 1268 | newer = 1; |
| @@ -3229,7 +3229,7 @@ substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, Lisp_Obj | |||
| 3229 | if (BOOL_VECTOR_P (subtree)) | 3229 | if (BOOL_VECTOR_P (subtree)) |
| 3230 | return subtree; /* No sub-objects anyway. */ | 3230 | return subtree; /* No sub-objects anyway. */ |
| 3231 | else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree) | 3231 | else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree) |
| 3232 | || COMPILEDP (subtree)) | 3232 | || COMPILEDP (subtree) || HASH_TABLE_P (subtree)) |
| 3233 | length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK; | 3233 | length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK; |
| 3234 | else if (VECTORP (subtree)) | 3234 | else if (VECTORP (subtree)) |
| 3235 | length = ASIZE (subtree); | 3235 | length = ASIZE (subtree); |
diff --git a/src/marker.c b/src/marker.c index 6c50def51a3..2f91bdf9727 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -534,9 +534,9 @@ set_marker_internal (Lisp_Object marker, Lisp_Object position, | |||
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0, | 536 | DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0, |
| 537 | doc: /* Position MARKER before character number POSITION in BUFFER, | 537 | doc: /* Position MARKER before character number POSITION in BUFFER. |
| 538 | which defaults to the current buffer. If POSITION is nil, | 538 | If BUFFER is omitted or nil, it defaults to the current buffer. If |
| 539 | makes marker point nowhere so it no longer slows down | 539 | POSITION is nil, makes marker point nowhere so it no longer slows down |
| 540 | editing in any buffer. Returns MARKER. */) | 540 | editing in any buffer. Returns MARKER. */) |
| 541 | (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer) | 541 | (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer) |
| 542 | { | 542 | { |
diff --git a/src/minibuf.c b/src/minibuf.c index 2c33b83c11b..7403fc6c32d 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -568,22 +568,15 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 568 | bset_directory (current_buffer, ambient_dir); | 568 | bset_directory (current_buffer, ambient_dir); |
| 569 | else | 569 | else |
| 570 | { | 570 | { |
| 571 | Lisp_Object buf_list; | 571 | Lisp_Object tail, buf; |
| 572 | 572 | ||
| 573 | for (buf_list = Vbuffer_alist; | 573 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| 574 | CONSP (buf_list); | 574 | if (STRINGP (BVAR (XBUFFER (buf), directory))) |
| 575 | buf_list = XCDR (buf_list)) | 575 | { |
| 576 | { | 576 | bset_directory (current_buffer, |
| 577 | Lisp_Object other_buf; | 577 | BVAR (XBUFFER (buf), directory)); |
| 578 | 578 | break; | |
| 579 | other_buf = XCDR (XCAR (buf_list)); | 579 | } |
| 580 | if (STRINGP (BVAR (XBUFFER (other_buf), directory))) | ||
| 581 | { | ||
| 582 | bset_directory (current_buffer, | ||
| 583 | BVAR (XBUFFER (other_buf), directory)); | ||
| 584 | break; | ||
| 585 | } | ||
| 586 | } | ||
| 587 | } | 580 | } |
| 588 | 581 | ||
| 589 | if (!EQ (mini_frame, selected_frame)) | 582 | if (!EQ (mini_frame, selected_frame)) |
| @@ -877,10 +870,8 @@ read_minibuf_unwind (void) | |||
| 877 | if (minibuf_level == 0) | 870 | if (minibuf_level == 0) |
| 878 | resize_mini_window (XWINDOW (window), 0); | 871 | resize_mini_window (XWINDOW (window), 0); |
| 879 | 872 | ||
| 880 | /* Make sure minibuffer window is erased, not ignored. */ | 873 | /* Enforce full redisplay. FIXME: make it more selective. */ |
| 881 | windows_or_buffers_changed++; | 874 | windows_or_buffers_changed++; |
| 882 | XWINDOW (window)->last_modified = 0; | ||
| 883 | XWINDOW (window)->last_overlay_modified = 0; | ||
| 884 | 875 | ||
| 885 | /* In case the previous minibuffer displayed in this miniwindow is | 876 | /* In case the previous minibuffer displayed in this miniwindow is |
| 886 | dead, we may keep displaying this buffer (tho it's inactive), so reset it, | 877 | dead, we may keep displaying this buffer (tho it's inactive), so reset it, |
diff --git a/src/msdos.c b/src/msdos.c index 88a2eb60726..7142c3ada77 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -602,11 +602,7 @@ dos_set_window_size (int *rows, int *cols) | |||
| 602 | Lisp_Object window = hlinfo->mouse_face_window; | 602 | Lisp_Object window = hlinfo->mouse_face_window; |
| 603 | 603 | ||
| 604 | if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) | 604 | if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) |
| 605 | { | 605 | reset_mouse_highlight (hlinfo); |
| 606 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 607 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 608 | hlinfo->mouse_face_window = Qnil; | ||
| 609 | } | ||
| 610 | } | 606 | } |
| 611 | 607 | ||
| 612 | /* Enable bright background colors. */ | 608 | /* Enable bright background colors. */ |
| @@ -950,9 +946,6 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) | |||
| 950 | Mouse Highlight (and friends..) | 946 | Mouse Highlight (and friends..) |
| 951 | ************************************************************************/ | 947 | ************************************************************************/ |
| 952 | 948 | ||
| 953 | /* Last window where we saw the mouse. Used by mouse-autoselect-window. */ | ||
| 954 | static Lisp_Object last_mouse_window; | ||
| 955 | |||
| 956 | static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */ | 949 | static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */ |
| 957 | 950 | ||
| 958 | int | 951 | int |
| @@ -1276,14 +1269,9 @@ IT_update_begin (struct frame *f) | |||
| 1276 | } | 1269 | } |
| 1277 | } | 1270 | } |
| 1278 | else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame)) | 1271 | else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame)) |
| 1279 | { | 1272 | /* If the frame with mouse highlight was deleted, invalidate the |
| 1280 | /* If the frame with mouse highlight was deleted, invalidate the | 1273 | highlight info. */ |
| 1281 | highlight info. */ | 1274 | reset_mouse_highlight (hlinfo); |
| 1282 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 1283 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 1284 | hlinfo->mouse_face_window = Qnil; | ||
| 1285 | hlinfo->mouse_face_mouse_frame = NULL; | ||
| 1286 | } | ||
| 1287 | 1275 | ||
| 1288 | unblock_input (); | 1276 | unblock_input (); |
| 1289 | } | 1277 | } |
| @@ -1555,11 +1543,6 @@ IT_reset_terminal_modes (struct terminal *term) | |||
| 1555 | term_setup_done = 0; | 1543 | term_setup_done = 0; |
| 1556 | } | 1544 | } |
| 1557 | 1545 | ||
| 1558 | static void | ||
| 1559 | IT_set_terminal_window (struct frame *f, int foo) | ||
| 1560 | { | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | /* Remember the screen colors of the current frame, to serve as the | 1546 | /* Remember the screen colors of the current frame, to serve as the |
| 1564 | default colors for newly-created frames. */ | 1547 | default colors for newly-created frames. */ |
| 1565 | DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors, | 1548 | DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors, |
| @@ -1843,17 +1826,8 @@ internal_terminal_init (void) | |||
| 1843 | if (colors[1] >= 0 && colors[1] < 16) | 1826 | if (colors[1] >= 0 && colors[1] < 16) |
| 1844 | FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1]; | 1827 | FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1]; |
| 1845 | } | 1828 | } |
| 1846 | the_only_display_info.mouse_highlight.mouse_face_mouse_frame = NULL; | 1829 | |
| 1847 | the_only_display_info.mouse_highlight.mouse_face_beg_row = | 1830 | reset_mouse_highlight (&the_only_display_info.mouse_highlight); |
| 1848 | the_only_display_info.mouse_highlight.mouse_face_beg_col = -1; | ||
| 1849 | the_only_display_info.mouse_highlight.mouse_face_end_row = | ||
| 1850 | the_only_display_info.mouse_highlight.mouse_face_end_col = -1; | ||
| 1851 | the_only_display_info.mouse_highlight.mouse_face_face_id = DEFAULT_FACE_ID; | ||
| 1852 | the_only_display_info.mouse_highlight.mouse_face_window = Qnil; | ||
| 1853 | the_only_display_info.mouse_highlight.mouse_face_mouse_x = | ||
| 1854 | the_only_display_info.mouse_highlight.mouse_face_mouse_y = 0; | ||
| 1855 | the_only_display_info.mouse_highlight.mouse_face_defer = 0; | ||
| 1856 | the_only_display_info.mouse_highlight.mouse_face_hidden = 0; | ||
| 1857 | 1831 | ||
| 1858 | if (have_mouse) /* detected in dos_ttraw, which see */ | 1832 | if (have_mouse) /* detected in dos_ttraw, which see */ |
| 1859 | { | 1833 | { |
| @@ -1889,7 +1863,7 @@ initialize_msdos_display (struct terminal *term) | |||
| 1889 | term->ring_bell_hook = IT_ring_bell; | 1863 | term->ring_bell_hook = IT_ring_bell; |
| 1890 | term->reset_terminal_modes_hook = IT_reset_terminal_modes; | 1864 | term->reset_terminal_modes_hook = IT_reset_terminal_modes; |
| 1891 | term->set_terminal_modes_hook = IT_set_terminal_modes; | 1865 | term->set_terminal_modes_hook = IT_set_terminal_modes; |
| 1892 | term->set_terminal_window_hook = IT_set_terminal_window; | 1866 | term->set_terminal_window_hook = NULL; |
| 1893 | term->update_begin_hook = IT_update_begin; | 1867 | term->update_begin_hook = IT_update_begin; |
| 1894 | term->update_end_hook = IT_update_end; | 1868 | term->update_end_hook = IT_update_end; |
| 1895 | term->frame_up_to_date_hook = IT_frame_up_to_date; | 1869 | term->frame_up_to_date_hook = IT_frame_up_to_date; |
| @@ -2691,10 +2665,10 @@ dos_rawgetc (void) | |||
| 2691 | /* Generate SELECT_WINDOW_EVENTs when needed. */ | 2665 | /* Generate SELECT_WINDOW_EVENTs when needed. */ |
| 2692 | if (!NILP (Vmouse_autoselect_window)) | 2666 | if (!NILP (Vmouse_autoselect_window)) |
| 2693 | { | 2667 | { |
| 2694 | mouse_window = window_from_coordinates (SELECTED_FRAME (), | 2668 | static Lisp_Object last_mouse_window; |
| 2695 | mouse_last_x, | 2669 | |
| 2696 | mouse_last_y, | 2670 | mouse_window = window_from_coordinates |
| 2697 | 0, 0); | 2671 | (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0); |
| 2698 | /* A window will be selected only when it is not | 2672 | /* A window will be selected only when it is not |
| 2699 | selected now, and the last mouse movement event was | 2673 | selected now, and the last mouse movement event was |
| 2700 | not in it. A minibuffer window will be selected iff | 2674 | not in it. A minibuffer window will be selected iff |
| @@ -2709,10 +2683,9 @@ dos_rawgetc (void) | |||
| 2709 | event.timestamp = event_timestamp (); | 2683 | event.timestamp = event_timestamp (); |
| 2710 | kbd_buffer_store_event (&event); | 2684 | kbd_buffer_store_event (&event); |
| 2711 | } | 2685 | } |
| 2686 | /* Remember the last window where we saw the mouse. */ | ||
| 2712 | last_mouse_window = mouse_window; | 2687 | last_mouse_window = mouse_window; |
| 2713 | } | 2688 | } |
| 2714 | else | ||
| 2715 | last_mouse_window = Qnil; | ||
| 2716 | 2689 | ||
| 2717 | previous_help_echo_string = help_echo_string; | 2690 | previous_help_echo_string = help_echo_string; |
| 2718 | help_echo_string = help_echo_object = help_echo_window = Qnil; | 2691 | help_echo_string = help_echo_object = help_echo_window = Qnil; |
| @@ -4073,7 +4046,7 @@ dos_yield_time_slice (void) | |||
| 4073 | because wait_reading_process_output takes care of that. */ | 4046 | because wait_reading_process_output takes care of that. */ |
| 4074 | int | 4047 | int |
| 4075 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | 4048 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, |
| 4076 | EMACS_TIME *timeout, void *ignored) | 4049 | struct timespec *timeout, void *ignored) |
| 4077 | { | 4050 | { |
| 4078 | int check_input; | 4051 | int check_input; |
| 4079 | struct timespec t; | 4052 | struct timespec t; |
| @@ -4103,20 +4076,20 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 4103 | } | 4076 | } |
| 4104 | else | 4077 | else |
| 4105 | { | 4078 | { |
| 4106 | EMACS_TIME clnow, cllast, cldiff; | 4079 | struct timespec clnow, cllast, cldiff; |
| 4107 | 4080 | ||
| 4108 | gettime (&t); | 4081 | gettime (&t); |
| 4109 | cllast = make_emacs_time (t.tv_sec, t.tv_nsec); | 4082 | cllast = make_timespec (t.tv_sec, t.tv_nsec); |
| 4110 | 4083 | ||
| 4111 | while (!check_input || !detect_input_pending ()) | 4084 | while (!check_input || !detect_input_pending ()) |
| 4112 | { | 4085 | { |
| 4113 | gettime (&t); | 4086 | gettime (&t); |
| 4114 | clnow = make_emacs_time (t.tv_sec, t.tv_nsec); | 4087 | clnow = make_timespec (t.tv_sec, t.tv_nsec); |
| 4115 | cldiff = sub_emacs_time (clnow, cllast); | 4088 | cldiff = timespec_sub (clnow, cllast); |
| 4116 | *timeout = sub_emacs_time (*timeout, cldiff); | 4089 | *timeout = timespec_sub (*timeout, cldiff); |
| 4117 | 4090 | ||
| 4118 | /* Stop when timeout value crosses zero. */ | 4091 | /* Stop when timeout value crosses zero. */ |
| 4119 | if (EMACS_TIME_SIGN (*timeout) <= 0) | 4092 | if (timespec_sign (*timeout) <= 0) |
| 4120 | return 0; | 4093 | return 0; |
| 4121 | cllast = clnow; | 4094 | cllast = clnow; |
| 4122 | dos_yield_time_slice (); | 4095 | dos_yield_time_slice (); |
diff --git a/src/nsfns.m b/src/nsfns.m index 3f43afde787..fc276c2b12d 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -860,11 +860,7 @@ static void | |||
| 860 | x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | 860 | x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) |
| 861 | { | 861 | { |
| 862 | set_frame_cursor_types (f, arg); | 862 | set_frame_cursor_types (f, arg); |
| 863 | |||
| 864 | /* Make sure the cursor gets redrawn. */ | ||
| 865 | cursor_type_changed = 1; | ||
| 866 | } | 863 | } |
| 867 | |||
| 868 | 864 | ||
| 869 | /* called to set mouse pointer color, but all other terms use it to | 865 | /* called to set mouse pointer color, but all other terms use it to |
| 870 | initialize pointer types (and don't set the color ;) */ | 866 | initialize pointer types (and don't set the color ;) */ |
| @@ -2035,13 +2031,17 @@ DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc, | |||
| 2035 | /* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping, | 2031 | /* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping, |
| 2036 | remove this. */ | 2032 | remove this. */ |
| 2037 | NSString *utfStr; | 2033 | NSString *utfStr; |
| 2034 | Lisp_Object ret; | ||
| 2038 | 2035 | ||
| 2039 | CHECK_STRING (str); | 2036 | CHECK_STRING (str); |
| 2040 | utfStr = [NSString stringWithUTF8String: SSDATA (str)]; | 2037 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
| 2038 | utfStr = [NSString stringWithUTF8String: SSDATA (str)]; | ||
| 2041 | #ifdef NS_IMPL_COCOA | 2039 | #ifdef NS_IMPL_COCOA |
| 2042 | utfStr = [utfStr precomposedStringWithCanonicalMapping]; | 2040 | utfStr = [utfStr precomposedStringWithCanonicalMapping]; |
| 2043 | #endif | 2041 | #endif |
| 2044 | return build_string ([utfStr UTF8String]); | 2042 | ret = build_string ([utfStr UTF8String]); |
| 2043 | [pool release]; | ||
| 2044 | return ret; | ||
| 2045 | } | 2045 | } |
| 2046 | 2046 | ||
| 2047 | 2047 | ||
| @@ -2447,7 +2447,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) | |||
| 2447 | if (n_monitors == 0) | 2447 | if (n_monitors == 0) |
| 2448 | return Qnil; | 2448 | return Qnil; |
| 2449 | 2449 | ||
| 2450 | monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); | 2450 | monitors = xzalloc (n_monitors * sizeof *monitors); |
| 2451 | 2451 | ||
| 2452 | for (i = 0; i < [screens count]; ++i) | 2452 | for (i = 0; i < [screens count]; ++i) |
| 2453 | { | 2453 | { |
diff --git a/src/nsfont.m b/src/nsfont.m index ad169d7ddae..e1c7d32dde0 100644 --- a/src/nsfont.m +++ b/src/nsfont.m | |||
| @@ -61,6 +61,7 @@ static void ns_uni_to_glyphs (struct nsfont_info *font_info, | |||
| 61 | static void ns_glyph_metrics (struct nsfont_info *font_info, | 61 | static void ns_glyph_metrics (struct nsfont_info *font_info, |
| 62 | unsigned char block); | 62 | unsigned char block); |
| 63 | 63 | ||
| 64 | #define INVALID_GLYPH 0xFFFF | ||
| 64 | 65 | ||
| 65 | /* ========================================================================== | 66 | /* ========================================================================== |
| 66 | 67 | ||
| @@ -920,8 +921,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size) | |||
| 920 | font->underline_thickness = lrint (font_info->underwidth); | 921 | font->underline_thickness = lrint (font_info->underwidth); |
| 921 | 922 | ||
| 922 | font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil); | 923 | font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil); |
| 923 | font->props[FONT_FULLNAME_INDEX] = | 924 | font->props[FONT_FULLNAME_INDEX] = build_unibyte_string (font_info->name); |
| 924 | make_unibyte_string (font_info->name, strlen (font_info->name)); | ||
| 925 | } | 925 | } |
| 926 | unblock_input (); | 926 | unblock_input (); |
| 927 | 927 | ||
| @@ -982,7 +982,7 @@ nsfont_encode_char (struct font *font, int c) | |||
| 982 | ns_uni_to_glyphs (font_info, high); | 982 | ns_uni_to_glyphs (font_info, high); |
| 983 | 983 | ||
| 984 | g = font_info->glyphs[high][low]; | 984 | g = font_info->glyphs[high][low]; |
| 985 | return g == 0xFFFF ? FONT_INVALID_CODE : g; | 985 | return g == INVALID_GLYPH ? FONT_INVALID_CODE : g; |
| 986 | } | 986 | } |
| 987 | 987 | ||
| 988 | 988 | ||
| @@ -1355,8 +1355,8 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block) | |||
| 1355 | #else | 1355 | #else |
| 1356 | g = glyphStorage->cglyphs[i]; | 1356 | g = glyphStorage->cglyphs[i]; |
| 1357 | /* TODO: is this a good check? maybe need to use coveredChars.. */ | 1357 | /* TODO: is this a good check? maybe need to use coveredChars.. */ |
| 1358 | if (g > numGlyphs) | 1358 | if (g > numGlyphs || g == NSNullGlyph) |
| 1359 | g = 0xFFFF; /* hopefully unused... */ | 1359 | g = INVALID_GLYPH; /* hopefully unused... */ |
| 1360 | #endif | 1360 | #endif |
| 1361 | *glyphs = g; | 1361 | *glyphs = g; |
| 1362 | } | 1362 | } |
| @@ -1484,7 +1484,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block) | |||
| 1484 | characterIndex: (NSUInteger)charIndex | 1484 | characterIndex: (NSUInteger)charIndex |
| 1485 | { | 1485 | { |
| 1486 | len = glyphIndex+length; | 1486 | len = glyphIndex+length; |
| 1487 | for (i =glyphIndex; i<len; i++) | 1487 | for (i =glyphIndex; i<len; i++) |
| 1488 | cglyphs[i] = glyphs[i-glyphIndex]; | 1488 | cglyphs[i] = glyphs[i-glyphIndex]; |
| 1489 | if (len > maxGlyph) | 1489 | if (len > maxGlyph) |
| 1490 | maxGlyph = len; | 1490 | maxGlyph = len; |
diff --git a/src/nsmenu.m b/src/nsmenu.m index 464be89c524..f9cd511efe9 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -366,7 +366,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) | |||
| 366 | } | 366 | } |
| 367 | else | 367 | else |
| 368 | { | 368 | { |
| 369 | [menu fillWithWidgetValue: first_wv->contents]; | 369 | [menu fillWithWidgetValue: first_wv->contents frame: f]; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | } | 372 | } |
| @@ -504,23 +504,11 @@ void | |||
| 504 | x_activate_menubar (struct frame *f) | 504 | x_activate_menubar (struct frame *f) |
| 505 | { | 505 | { |
| 506 | #ifdef NS_IMPL_COCOA | 506 | #ifdef NS_IMPL_COCOA |
| 507 | NSArray *a = [[NSApp mainMenu] itemArray]; | 507 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 |
| 508 | /* Update each submenu separately so ns_update_menubar doesn't reset | 508 | ns_update_menubar (f, true, nil); |
| 509 | the delegate. */ | ||
| 510 | int i = 0; | ||
| 511 | while (i < [a count]) | ||
| 512 | { | ||
| 513 | EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu]; | ||
| 514 | const char *title = [[menu title] UTF8String]; | ||
| 515 | if (strcmp (title, ns_get_pending_menu_title ()) == 0) | ||
| 516 | { | ||
| 517 | ns_update_menubar (f, true, menu); | ||
| 518 | break; | ||
| 519 | } | ||
| 520 | ++i; | ||
| 521 | } | ||
| 522 | ns_check_pending_open_menu (); | 509 | ns_check_pending_open_menu (); |
| 523 | #endif | 510 | #endif |
| 511 | #endif | ||
| 524 | } | 512 | } |
| 525 | 513 | ||
| 526 | 514 | ||
| @@ -541,6 +529,7 @@ x_activate_menubar (struct frame *f) | |||
| 541 | /* override designated initializer */ | 529 | /* override designated initializer */ |
| 542 | - initWithTitle: (NSString *)title | 530 | - initWithTitle: (NSString *)title |
| 543 | { | 531 | { |
| 532 | frame = 0; | ||
| 544 | if ((self = [super initWithTitle: title])) | 533 | if ((self = [super initWithTitle: title])) |
| 545 | [self setAutoenablesItems: NO]; | 534 | [self setAutoenablesItems: NO]; |
| 546 | return self; | 535 | return self; |
| @@ -576,17 +565,36 @@ extern NSString *NSMenuDidBeginTrackingNotification; | |||
| 576 | /* Update menu in menuNeedsUpdate only while tracking menus. */ | 565 | /* Update menu in menuNeedsUpdate only while tracking menus. */ |
| 577 | trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification | 566 | trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification |
| 578 | ? 1 : 0); | 567 | ? 1 : 0); |
| 568 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 | ||
| 569 | if (! trackingMenu) ns_check_menu_open (nil); | ||
| 570 | #endif | ||
| 579 | } | 571 | } |
| 580 | 572 | ||
| 581 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 | 573 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 |
| 582 | - (void)menuWillOpen:(NSMenu *)menu | 574 | - (void)menuWillOpen:(NSMenu *)menu |
| 583 | { | 575 | { |
| 584 | ns_check_menu_open (menu); | 576 | ++trackingMenu; |
| 585 | } | ||
| 586 | #endif | ||
| 587 | 577 | ||
| 578 | #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | ||
| 579 | // On 10.6 we get repeated calls, only the one for NSSystemDefined is "real". | ||
| 580 | if ([[NSApp currentEvent] type] != NSSystemDefined) return; | ||
| 588 | #endif | 581 | #endif |
| 589 | 582 | ||
| 583 | /* When dragging from one menu to another, we get willOpen followed by didClose, | ||
| 584 | i.e. trackingMenu == 3 in willOpen and then 2 after didClose. | ||
| 585 | We have updated all menus, so avoid doing it when trackingMenu == 3. */ | ||
| 586 | if (trackingMenu == 2) | ||
| 587 | ns_check_menu_open (menu); | ||
| 588 | } | ||
| 589 | |||
| 590 | - (void)menuDidClose:(NSMenu *)menu | ||
| 591 | { | ||
| 592 | --trackingMenu; | ||
| 593 | } | ||
| 594 | #endif /* OSX >= 10.5 */ | ||
| 595 | |||
| 596 | #endif /* NS_IMPL_COCOA */ | ||
| 597 | |||
| 590 | /* delegate method called when a submenu is being opened: run a 'deep' call | 598 | /* delegate method called when a submenu is being opened: run a 'deep' call |
| 591 | to set_frame_menubar */ | 599 | to set_frame_menubar */ |
| 592 | - (void)menuNeedsUpdate: (NSMenu *)menu | 600 | - (void)menuNeedsUpdate: (NSMenu *)menu |
| @@ -722,6 +730,11 @@ extern NSString *NSMenuDidBeginTrackingNotification; | |||
| 722 | 730 | ||
| 723 | - (void)fillWithWidgetValue: (void *)wvptr | 731 | - (void)fillWithWidgetValue: (void *)wvptr |
| 724 | { | 732 | { |
| 733 | [self fillWithWidgetValue: wvptr frame: (struct frame *)nil]; | ||
| 734 | } | ||
| 735 | |||
| 736 | - (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f | ||
| 737 | { | ||
| 725 | widget_value *wv = (widget_value *)wvptr; | 738 | widget_value *wv = (widget_value *)wvptr; |
| 726 | 739 | ||
| 727 | /* clear existing contents */ | 740 | /* clear existing contents */ |
| @@ -735,7 +748,12 @@ extern NSString *NSMenuDidBeginTrackingNotification; | |||
| 735 | 748 | ||
| 736 | if (wv->contents) | 749 | if (wv->contents) |
| 737 | { | 750 | { |
| 738 | EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; | 751 | EmacsMenu *submenu; |
| 752 | |||
| 753 | if (f) | ||
| 754 | submenu = [[EmacsMenu alloc] initWithTitle: [item title] frame:f]; | ||
| 755 | else | ||
| 756 | submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; | ||
| 739 | 757 | ||
| 740 | [self setSubmenu: submenu forItem: item]; | 758 | [self setSubmenu: submenu forItem: item]; |
| 741 | [submenu fillWithWidgetValue: wv->contents]; | 759 | [submenu fillWithWidgetValue: wv->contents]; |
| @@ -1665,7 +1683,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | |||
| 1665 | } | 1683 | } |
| 1666 | 1684 | ||
| 1667 | if (buttons > 0) | 1685 | if (buttons > 0) |
| 1668 | button_values = (Lisp_Object *) xmalloc (buttons * sizeof (*button_values)); | 1686 | button_values = xmalloc (buttons * sizeof *button_values); |
| 1669 | 1687 | ||
| 1670 | for (; XTYPE (list) == Lisp_Cons; list = XCDR (list)) | 1688 | for (; XTYPE (list) == Lisp_Cons; list = XCDR (list)) |
| 1671 | { | 1689 | { |
| @@ -1849,11 +1867,11 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | |||
| 1849 | while (popup_activated_flag) | 1867 | while (popup_activated_flag) |
| 1850 | { | 1868 | { |
| 1851 | NSTimer *tmo = nil; | 1869 | NSTimer *tmo = nil; |
| 1852 | EMACS_TIME next_time = timer_check (); | 1870 | struct timespec next_time = timer_check (); |
| 1853 | 1871 | ||
| 1854 | if (EMACS_TIME_VALID_P (next_time)) | 1872 | if (timespec_valid_p (next_time)) |
| 1855 | { | 1873 | { |
| 1856 | double time = EMACS_TIME_TO_DOUBLE (next_time); | 1874 | double time = timespectod (next_time); |
| 1857 | tmo = [NSTimer timerWithTimeInterval: time | 1875 | tmo = [NSTimer timerWithTimeInterval: time |
| 1858 | target: self | 1876 | target: self |
| 1859 | selector: @selector (timeout_handler:) | 1877 | selector: @selector (timeout_handler:) |
diff --git a/src/nsterm.h b/src/nsterm.h index 1303a475547..4e07d796250 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -53,9 +53,24 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 53 | 53 | ||
| 54 | /* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some | 54 | /* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some |
| 55 | versions. | 55 | versions. |
| 56 | On Cocoa, functions expect CGFloat*. Make compatible type. */ | 56 | On Cocoa >= 10.5, functions expect CGFloat*. Make compatible type. */ |
| 57 | #if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \ | 57 | #ifdef NS_IMPL_COCOA |
| 58 | GNUSTEP_GUI_MINOR_VERSION >= 22 | 58 | |
| 59 | #ifndef NS_HAVE_NSINTEGER | ||
| 60 | #if defined (__LP64__) && __LP64__ | ||
| 61 | typedef double CGFloat; | ||
| 62 | typedef long NSInteger; | ||
| 63 | typedef unsigned long NSUInteger; | ||
| 64 | #else | ||
| 65 | typedef float CGFloat; | ||
| 66 | typedef int NSInteger; | ||
| 67 | typedef unsigned int NSUInteger; | ||
| 68 | #endif /* not LP64 */ | ||
| 69 | #endif /* not NS_HAVE_NSINTEGER */ | ||
| 70 | |||
| 71 | typedef CGFloat EmacsCGFloat; | ||
| 72 | |||
| 73 | #elif GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 22 | ||
| 59 | typedef CGFloat EmacsCGFloat; | 74 | typedef CGFloat EmacsCGFloat; |
| 60 | #else | 75 | #else |
| 61 | typedef float EmacsCGFloat; | 76 | typedef float EmacsCGFloat; |
| @@ -196,6 +211,7 @@ typedef float EmacsCGFloat; | |||
| 196 | - (NSString *)parseKeyEquiv: (const char *)key; | 211 | - (NSString *)parseKeyEquiv: (const char *)key; |
| 197 | - (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr; | 212 | - (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr; |
| 198 | - (void)fillWithWidgetValue: (void *)wvptr; | 213 | - (void)fillWithWidgetValue: (void *)wvptr; |
| 214 | - (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f; | ||
| 199 | - (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f; | 215 | - (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f; |
| 200 | - (void) clear; | 216 | - (void) clear; |
| 201 | - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f | 217 | - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f |
| @@ -423,18 +439,6 @@ extern EmacsMenu *mainMenu, *svcsMenu, *dockMenu; | |||
| 423 | @end | 439 | @end |
| 424 | #endif | 440 | #endif |
| 425 | 441 | ||
| 426 | #ifndef NS_HAVE_NSINTEGER | ||
| 427 | #if defined (__LP64__) && __LP64__ | ||
| 428 | typedef double CGFloat; | ||
| 429 | typedef long NSInteger; | ||
| 430 | typedef unsigned long NSUInteger; | ||
| 431 | #else | ||
| 432 | typedef float CGFloat; | ||
| 433 | typedef int NSInteger; | ||
| 434 | typedef unsigned int NSUInteger; | ||
| 435 | #endif /* not LP64 */ | ||
| 436 | #endif /* not NS_HAVE_NSINTEGER */ | ||
| 437 | |||
| 438 | #endif /* __OBJC__ */ | 442 | #endif /* __OBJC__ */ |
| 439 | 443 | ||
| 440 | 444 | ||
| @@ -748,8 +752,6 @@ struct x_output | |||
| 748 | (FRAME_NS_DISPLAY_INFO (f)->smallest_char_width) | 752 | (FRAME_NS_DISPLAY_INFO (f)->smallest_char_width) |
| 749 | #define FRAME_SMALLEST_FONT_HEIGHT(f) \ | 753 | #define FRAME_SMALLEST_FONT_HEIGHT(f) \ |
| 750 | (FRAME_NS_DISPLAY_INFO (f)->smallest_font_height) | 754 | (FRAME_NS_DISPLAY_INFO (f)->smallest_font_height) |
| 751 | #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0 | ||
| 752 | #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0 | ||
| 753 | #define FRAME_BASELINE_OFFSET(f) ((f)->output_data.ns->baseline_offset) | 755 | #define FRAME_BASELINE_OFFSET(f) ((f)->output_data.ns->baseline_offset) |
| 754 | #define BLACK_PIX_DEFAULT(f) 0x000000 | 756 | #define BLACK_PIX_DEFAULT(f) 0x000000 |
| 755 | #define WHITE_PIX_DEFAULT(f) 0xFFFFFF | 757 | #define WHITE_PIX_DEFAULT(f) 0xFFFFFF |
| @@ -870,8 +872,8 @@ extern int x_display_pixel_width (struct ns_display_info *); | |||
| 870 | /* This in nsterm.m */ | 872 | /* This in nsterm.m */ |
| 871 | extern void x_destroy_window (struct frame *f); | 873 | extern void x_destroy_window (struct frame *f); |
| 872 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 874 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, |
| 873 | fd_set *exceptfds, EMACS_TIME *timeout, | 875 | fd_set *exceptfds, struct timespec const *timeout, |
| 874 | sigset_t *sigmask); | 876 | sigset_t const *sigmask); |
| 875 | extern unsigned long ns_get_rgb_color (struct frame *f, | 877 | extern unsigned long ns_get_rgb_color (struct frame *f, |
| 876 | float r, float g, float b, float a); | 878 | float r, float g, float b, float a); |
| 877 | extern NSPoint last_mouse_motion_position; | 879 | extern NSPoint last_mouse_motion_position; |
diff --git a/src/nsterm.m b/src/nsterm.m index 3672c7656da..31053ca7a0d 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -214,7 +214,7 @@ static NSTimer *scroll_repeat_entry = nil; | |||
| 214 | static fd_set select_readfds, select_writefds; | 214 | static fd_set select_readfds, select_writefds; |
| 215 | enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 }; | 215 | enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 }; |
| 216 | static int select_nfds = 0, select_valid = 0; | 216 | static int select_nfds = 0, select_valid = 0; |
| 217 | static EMACS_TIME select_timeout = { 0, 0 }; | 217 | static struct timespec select_timeout = { 0, 0 }; |
| 218 | static int selfds[2] = { -1, -1 }; | 218 | static int selfds[2] = { -1, -1 }; |
| 219 | static pthread_mutex_t select_mutex; | 219 | static pthread_mutex_t select_mutex; |
| 220 | static int apploopnr = 0; | 220 | static int apploopnr = 0; |
| @@ -250,9 +250,6 @@ static int menu_will_open_state = MENU_NONE; | |||
| 250 | 250 | ||
| 251 | /* Saved position for menu click. */ | 251 | /* Saved position for menu click. */ |
| 252 | static CGPoint menu_mouse_point; | 252 | static CGPoint menu_mouse_point; |
| 253 | |||
| 254 | /* Title for the menu to open. */ | ||
| 255 | static char *menu_pending_title = 0; | ||
| 256 | #endif | 253 | #endif |
| 257 | 254 | ||
| 258 | /* Convert modifiers in a NeXTstep event to emacs style modifiers. */ | 255 | /* Convert modifiers in a NeXTstep event to emacs style modifiers. */ |
| @@ -311,8 +308,13 @@ static char *menu_pending_title = 0; | |||
| 311 | /* This is a piece of code which is common to all the event handling | 308 | /* This is a piece of code which is common to all the event handling |
| 312 | methods. Maybe it should even be a function. */ | 309 | methods. Maybe it should even be a function. */ |
| 313 | #define EV_TRAILER(e) \ | 310 | #define EV_TRAILER(e) \ |
| 314 | { \ | 311 | { \ |
| 315 | XSETFRAME (emacs_event->frame_or_window, emacsframe); \ | 312 | XSETFRAME (emacs_event->frame_or_window, emacsframe); \ |
| 313 | EV_TRAILER2 (e); \ | ||
| 314 | } | ||
| 315 | |||
| 316 | #define EV_TRAILER2(e) \ | ||
| 317 | { \ | ||
| 316 | if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ | 318 | if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ |
| 317 | if (q_event_ptr) \ | 319 | if (q_event_ptr) \ |
| 318 | { \ | 320 | { \ |
| @@ -344,8 +346,8 @@ hold_event (struct input_event *event) | |||
| 344 | { | 346 | { |
| 345 | if (hold_event_q.cap == 0) hold_event_q.cap = 10; | 347 | if (hold_event_q.cap == 0) hold_event_q.cap = 10; |
| 346 | else hold_event_q.cap *= 2; | 348 | else hold_event_q.cap *= 2; |
| 347 | hold_event_q.q = (struct input_event *) | 349 | hold_event_q.q = |
| 348 | xrealloc (hold_event_q.q, hold_event_q.cap * sizeof (*hold_event_q.q)); | 350 | xrealloc (hold_event_q.q, hold_event_q.cap * sizeof *hold_event_q.q); |
| 349 | } | 351 | } |
| 350 | 352 | ||
| 351 | hold_event_q.q[hold_event_q.nr++] = *event; | 353 | hold_event_q.q[hold_event_q.nr++] = *event; |
| @@ -488,16 +490,16 @@ ns_timeout (int usecs) | |||
| 488 | Blocking timer utility used by ns_ring_bell | 490 | Blocking timer utility used by ns_ring_bell |
| 489 | -------------------------------------------------------------------------- */ | 491 | -------------------------------------------------------------------------- */ |
| 490 | { | 492 | { |
| 491 | EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), | 493 | struct timespec wakeup = timespec_add (current_timespec (), |
| 492 | make_emacs_time (0, usecs * 1000)); | 494 | make_timespec (0, usecs * 1000)); |
| 493 | 495 | ||
| 494 | /* Keep waiting until past the time wakeup. */ | 496 | /* Keep waiting until past the time wakeup. */ |
| 495 | while (1) | 497 | while (1) |
| 496 | { | 498 | { |
| 497 | EMACS_TIME timeout, now = current_emacs_time (); | 499 | struct timespec timeout, now = current_timespec (); |
| 498 | if (EMACS_TIME_LE (wakeup, now)) | 500 | if (timespec_cmp (wakeup, now) <= 0) |
| 499 | break; | 501 | break; |
| 500 | timeout = sub_emacs_time (wakeup, now); | 502 | timeout = timespec_sub (wakeup, now); |
| 501 | 503 | ||
| 502 | /* Try to wait that long--but we might wake up sooner. */ | 504 | /* Try to wait that long--but we might wake up sooner. */ |
| 503 | pselect (0, NULL, NULL, NULL, &timeout, NULL); | 505 | pselect (0, NULL, NULL, NULL, &timeout, NULL); |
| @@ -691,9 +693,18 @@ ns_update_begin (struct frame *f) | |||
| 691 | { | 693 | { |
| 692 | NSBezierPath *bp; | 694 | NSBezierPath *bp; |
| 693 | NSRect r = [view frame]; | 695 | NSRect r = [view frame]; |
| 694 | bp = [[NSBezierPath bezierPathWithRect: r] retain]; | 696 | NSRect cr = [[view window] frame]; |
| 695 | [bp setClip]; | 697 | /* If a large frame size is set, r may be larger than the window frame |
| 696 | [bp release]; | 698 | before constrained. In that case don't change the clip path, as we |
| 699 | will clear in to the tool bar and title bar. */ | ||
| 700 | if (r.size.height | ||
| 701 | + FRAME_NS_TITLEBAR_HEIGHT (f) | ||
| 702 | + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) | ||
| 703 | { | ||
| 704 | bp = [[NSBezierPath bezierPathWithRect: r] retain]; | ||
| 705 | [bp setClip]; | ||
| 706 | [bp release]; | ||
| 707 | } | ||
| 697 | } | 708 | } |
| 698 | #endif | 709 | #endif |
| 699 | 710 | ||
| @@ -711,10 +722,10 @@ ns_update_window_begin (struct window *w) | |||
| 711 | -------------------------------------------------------------------------- */ | 722 | -------------------------------------------------------------------------- */ |
| 712 | { | 723 | { |
| 713 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 724 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 714 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); | 725 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); |
| 726 | |||
| 715 | NSTRACE (ns_update_window_begin); | 727 | NSTRACE (ns_update_window_begin); |
| 716 | updated_window = w; | 728 | w->output_cursor = w->cursor; |
| 717 | set_output_cursor (&w->cursor); | ||
| 718 | 729 | ||
| 719 | block_input (); | 730 | block_input (); |
| 720 | 731 | ||
| @@ -736,15 +747,13 @@ ns_update_window_begin (struct window *w) | |||
| 736 | 747 | ||
| 737 | 748 | ||
| 738 | static void | 749 | static void |
| 739 | ns_update_window_end (struct window *w, int cursor_on_p, | 750 | ns_update_window_end (struct window *w, bool cursor_on_p, |
| 740 | int mouse_face_overwritten_p) | 751 | bool mouse_face_overwritten_p) |
| 741 | /* -------------------------------------------------------------------------- | 752 | /* -------------------------------------------------------------------------- |
| 742 | Finished a grouped sequence of drawing calls | 753 | Finished a grouped sequence of drawing calls |
| 743 | external (RIF) call; for one window called before update_end | 754 | external (RIF) call; for one window called before update_end |
| 744 | -------------------------------------------------------------------------- */ | 755 | -------------------------------------------------------------------------- */ |
| 745 | { | 756 | { |
| 746 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); | ||
| 747 | |||
| 748 | /* note: this fn is nearly identical in all terms */ | 757 | /* note: this fn is nearly identical in all terms */ |
| 749 | if (!w->pseudo_window_p) | 758 | if (!w->pseudo_window_p) |
| 750 | { | 759 | { |
| @@ -752,8 +761,8 @@ ns_update_window_end (struct window *w, int cursor_on_p, | |||
| 752 | 761 | ||
| 753 | if (cursor_on_p) | 762 | if (cursor_on_p) |
| 754 | display_and_set_cursor (w, 1, | 763 | display_and_set_cursor (w, 1, |
| 755 | output_cursor.hpos, output_cursor.vpos, | 764 | w->output_cursor.hpos, w->output_cursor.vpos, |
| 756 | output_cursor.x, output_cursor.y); | 765 | w->output_cursor.x, w->output_cursor.y); |
| 757 | 766 | ||
| 758 | if (draw_window_fringes (w, 1)) | 767 | if (draw_window_fringes (w, 1)) |
| 759 | x_draw_vertical_border (w); | 768 | x_draw_vertical_border (w); |
| @@ -764,13 +773,8 @@ ns_update_window_end (struct window *w, int cursor_on_p, | |||
| 764 | /* If a row with mouse-face was overwritten, arrange for | 773 | /* If a row with mouse-face was overwritten, arrange for |
| 765 | frame_up_to_date to redisplay the mouse highlight. */ | 774 | frame_up_to_date to redisplay the mouse highlight. */ |
| 766 | if (mouse_face_overwritten_p) | 775 | if (mouse_face_overwritten_p) |
| 767 | { | 776 | reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame))); |
| 768 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 769 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 770 | hlinfo->mouse_face_window = Qnil; | ||
| 771 | } | ||
| 772 | 777 | ||
| 773 | updated_window = NULL; | ||
| 774 | NSTRACE (update_window_end); | 778 | NSTRACE (update_window_end); |
| 775 | } | 779 | } |
| 776 | 780 | ||
| @@ -785,9 +789,9 @@ ns_update_end (struct frame *f) | |||
| 785 | EmacsView *view = FRAME_NS_VIEW (f); | 789 | EmacsView *view = FRAME_NS_VIEW (f); |
| 786 | 790 | ||
| 787 | /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ | 791 | /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ |
| 788 | MOUSE_HL_INFO (f)->mouse_face_defer = 0; | 792 | MOUSE_HL_INFO (f)->mouse_face_defer = 0; |
| 789 | 793 | ||
| 790 | block_input (); | 794 | block_input (); |
| 791 | 795 | ||
| 792 | [view unlockFocus]; | 796 | [view unlockFocus]; |
| 793 | [[view window] flushWindow]; | 797 | [[view window] flushWindow]; |
| @@ -886,7 +890,8 @@ ns_unfocus (struct frame *f) | |||
| 886 | 890 | ||
| 887 | 891 | ||
| 888 | static void | 892 | static void |
| 889 | ns_clip_to_row (struct window *w, struct glyph_row *row, int area, BOOL gc) | 893 | ns_clip_to_row (struct window *w, struct glyph_row *row, |
| 894 | enum glyph_row_area area, BOOL gc) | ||
| 890 | /* -------------------------------------------------------------------------- | 895 | /* -------------------------------------------------------------------------- |
| 891 | Internal (but parallels other terms): Focus drawing on given row | 896 | Internal (but parallels other terms): Focus drawing on given row |
| 892 | -------------------------------------------------------------------------- */ | 897 | -------------------------------------------------------------------------- */ |
| @@ -955,24 +960,6 @@ ns_ring_bell (struct frame *f) | |||
| 955 | } | 960 | } |
| 956 | } | 961 | } |
| 957 | 962 | ||
| 958 | |||
| 959 | static void | ||
| 960 | ns_reset_terminal_modes (struct terminal *terminal) | ||
| 961 | /* Externally called as hook */ | ||
| 962 | { | ||
| 963 | NSTRACE (ns_reset_terminal_modes); | ||
| 964 | } | ||
| 965 | |||
| 966 | |||
| 967 | static void | ||
| 968 | ns_set_terminal_modes (struct terminal *terminal) | ||
| 969 | /* Externally called as hook */ | ||
| 970 | { | ||
| 971 | NSTRACE (ns_set_terminal_modes); | ||
| 972 | } | ||
| 973 | |||
| 974 | |||
| 975 | |||
| 976 | /* ========================================================================== | 963 | /* ========================================================================== |
| 977 | 964 | ||
| 978 | Frame / window manager related functions | 965 | Frame / window manager related functions |
| @@ -1178,12 +1165,7 @@ x_free_frame_resources (struct frame *f) | |||
| 1178 | if (f == dpyinfo->x_highlight_frame) | 1165 | if (f == dpyinfo->x_highlight_frame) |
| 1179 | dpyinfo->x_highlight_frame = 0; | 1166 | dpyinfo->x_highlight_frame = 0; |
| 1180 | if (f == hlinfo->mouse_face_mouse_frame) | 1167 | if (f == hlinfo->mouse_face_mouse_frame) |
| 1181 | { | 1168 | reset_mouse_highlight (hlinfo); |
| 1182 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 1183 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 1184 | hlinfo->mouse_face_window = Qnil; | ||
| 1185 | hlinfo->mouse_face_mouse_frame = 0; | ||
| 1186 | } | ||
| 1187 | 1169 | ||
| 1188 | if (f->output_data.ns->miniimage != nil) | 1170 | if (f->output_data.ns->miniimage != nil) |
| 1189 | [f->output_data.ns->miniimage release]; | 1171 | [f->output_data.ns->miniimage release]; |
| @@ -1995,9 +1977,6 @@ ns_clear_frame (struct frame *f) | |||
| 1995 | 1977 | ||
| 1996 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); | 1978 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); |
| 1997 | 1979 | ||
| 1998 | output_cursor.hpos = output_cursor.vpos = 0; | ||
| 1999 | output_cursor.x = -1; | ||
| 2000 | |||
| 2001 | r = [view bounds]; | 1980 | r = [view bounds]; |
| 2002 | 1981 | ||
| 2003 | block_input (); | 1982 | block_input (); |
| @@ -2053,7 +2032,7 @@ ns_scroll_run (struct window *w, struct run *run) | |||
| 2053 | /* Get frame-relative bounding box of the text display area of W, | 2032 | /* Get frame-relative bounding box of the text display area of W, |
| 2054 | without mode lines. Include in this box the left and right | 2033 | without mode lines. Include in this box the left and right |
| 2055 | fringe of W. */ | 2034 | fringe of W. */ |
| 2056 | window_box (w, -1, &x, &y, &width, &height); | 2035 | window_box (w, ANY_AREA, &x, &y, &width, &height); |
| 2057 | 2036 | ||
| 2058 | from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); | 2037 | from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); |
| 2059 | to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); | 2038 | to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); |
| @@ -2084,7 +2063,6 @@ ns_scroll_run (struct window *w, struct run *run) | |||
| 2084 | 2063 | ||
| 2085 | block_input (); | 2064 | block_input (); |
| 2086 | 2065 | ||
| 2087 | updated_window = w; | ||
| 2088 | x_clear_cursor (w); | 2066 | x_clear_cursor (w); |
| 2089 | 2067 | ||
| 2090 | { | 2068 | { |
| @@ -2102,12 +2080,11 @@ ns_scroll_run (struct window *w, struct run *run) | |||
| 2102 | 2080 | ||
| 2103 | 2081 | ||
| 2104 | static void | 2082 | static void |
| 2105 | ns_after_update_window_line (struct glyph_row *desired_row) | 2083 | ns_after_update_window_line (struct window *w, struct glyph_row *desired_row) |
| 2106 | /* -------------------------------------------------------------------------- | 2084 | /* -------------------------------------------------------------------------- |
| 2107 | External (RIF): preparatory to fringe update after text was updated | 2085 | External (RIF): preparatory to fringe update after text was updated |
| 2108 | -------------------------------------------------------------------------- */ | 2086 | -------------------------------------------------------------------------- */ |
| 2109 | { | 2087 | { |
| 2110 | struct window *w = updated_window; | ||
| 2111 | struct frame *f; | 2088 | struct frame *f; |
| 2112 | int width, height; | 2089 | int width, height; |
| 2113 | 2090 | ||
| @@ -2230,7 +2207,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 2230 | } | 2207 | } |
| 2231 | 2208 | ||
| 2232 | /* Must clip because of partially visible lines. */ | 2209 | /* Must clip because of partially visible lines. */ |
| 2233 | ns_clip_to_row (w, row, -1, YES); | 2210 | ns_clip_to_row (w, row, ANY_AREA, YES); |
| 2234 | 2211 | ||
| 2235 | if (!p->overlay_p) | 2212 | if (!p->overlay_p) |
| 2236 | { | 2213 | { |
| @@ -2338,8 +2315,8 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 2338 | 2315 | ||
| 2339 | static void | 2316 | static void |
| 2340 | ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | 2317 | ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, |
| 2341 | int x, int y, int cursor_type, int cursor_width, | 2318 | int x, int y, enum text_cursor_kinds cursor_type, |
| 2342 | int on_p, int active_p) | 2319 | int cursor_width, bool on_p, bool active_p) |
| 2343 | /* -------------------------------------------------------------------------- | 2320 | /* -------------------------------------------------------------------------- |
| 2344 | External call (RIF): draw cursor. | 2321 | External call (RIF): draw cursor. |
| 2345 | Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. | 2322 | Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. |
| @@ -2410,7 +2387,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | |||
| 2410 | 2387 | ||
| 2411 | /* TODO: only needed in rare cases with last-resort font in HELLO.. | 2388 | /* TODO: only needed in rare cases with last-resort font in HELLO.. |
| 2412 | should we do this more efficiently? */ | 2389 | should we do this more efficiently? */ |
| 2413 | ns_clip_to_row (w, glyph_row, -1, NO); /* do ns_focus(f, &r, 1); if remove */ | 2390 | ns_clip_to_row (w, glyph_row, ANY_AREA, NO); /* do ns_focus(f, &r, 1); if remove */ |
| 2414 | 2391 | ||
| 2415 | 2392 | ||
| 2416 | face = FACE_FROM_ID (f, phys_cursor_glyph->face_id); | 2393 | face = FACE_FROM_ID (f, phys_cursor_glyph->face_id); |
| @@ -3391,12 +3368,6 @@ check_native_fs () | |||
| 3391 | /* GNUStep and OSX <= 10.4 does not have cancelTracking. */ | 3368 | /* GNUStep and OSX <= 10.4 does not have cancelTracking. */ |
| 3392 | #if defined (NS_IMPL_COCOA) && \ | 3369 | #if defined (NS_IMPL_COCOA) && \ |
| 3393 | MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 | 3370 | MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 |
| 3394 | const char * | ||
| 3395 | ns_get_pending_menu_title () | ||
| 3396 | { | ||
| 3397 | return menu_pending_title; | ||
| 3398 | } | ||
| 3399 | |||
| 3400 | /* Check if menu open should be cancelled or continued as normal. */ | 3371 | /* Check if menu open should be cancelled or continued as normal. */ |
| 3401 | void | 3372 | void |
| 3402 | ns_check_menu_open (NSMenu *menu) | 3373 | ns_check_menu_open (NSMenu *menu) |
| @@ -3405,6 +3376,14 @@ ns_check_menu_open (NSMenu *menu) | |||
| 3405 | NSArray *a = [[NSApp mainMenu] itemArray]; | 3376 | NSArray *a = [[NSApp mainMenu] itemArray]; |
| 3406 | int i; | 3377 | int i; |
| 3407 | BOOL found = NO; | 3378 | BOOL found = NO; |
| 3379 | |||
| 3380 | if (menu == nil) // Menu tracking ended. | ||
| 3381 | { | ||
| 3382 | if (menu_will_open_state == MENU_OPENING) | ||
| 3383 | menu_will_open_state = MENU_NONE; | ||
| 3384 | return; | ||
| 3385 | } | ||
| 3386 | |||
| 3408 | for (i = 0; ! found && i < [a count]; i++) | 3387 | for (i = 0; ! found && i < [a count]; i++) |
| 3409 | found = menu == [[a objectAtIndex:i] submenu]; | 3388 | found = menu == [[a objectAtIndex:i] submenu]; |
| 3410 | if (found) | 3389 | if (found) |
| @@ -3422,8 +3401,6 @@ ns_check_menu_open (NSMenu *menu) | |||
| 3422 | CGEventRef ourEvent = CGEventCreate (NULL); | 3401 | CGEventRef ourEvent = CGEventCreate (NULL); |
| 3423 | menu_mouse_point = CGEventGetLocation (ourEvent); | 3402 | menu_mouse_point = CGEventGetLocation (ourEvent); |
| 3424 | CFRelease (ourEvent); | 3403 | CFRelease (ourEvent); |
| 3425 | xfree (menu_pending_title); | ||
| 3426 | menu_pending_title = xstrdup ([[menu title] UTF8String]); | ||
| 3427 | } | 3404 | } |
| 3428 | else if (menu_will_open_state == MENU_OPENING) | 3405 | else if (menu_will_open_state == MENU_OPENING) |
| 3429 | { | 3406 | { |
| @@ -3537,7 +3514,8 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 3537 | 3514 | ||
| 3538 | int | 3515 | int |
| 3539 | ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 3516 | ns_select (int nfds, fd_set *readfds, fd_set *writefds, |
| 3540 | fd_set *exceptfds, EMACS_TIME *timeout, sigset_t *sigmask) | 3517 | fd_set *exceptfds, struct timespec const *timeout, |
| 3518 | sigset_t const *sigmask) | ||
| 3541 | /* -------------------------------------------------------------------------- | 3519 | /* -------------------------------------------------------------------------- |
| 3542 | Replacement for select, checking for events | 3520 | Replacement for select, checking for events |
| 3543 | -------------------------------------------------------------------------- */ | 3521 | -------------------------------------------------------------------------- */ |
| @@ -3607,7 +3585,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 3607 | else if (nr == 0 && timeout) | 3585 | else if (nr == 0 && timeout) |
| 3608 | { | 3586 | { |
| 3609 | /* No file descriptor, just a timeout, no need to wake fd_handler */ | 3587 | /* No file descriptor, just a timeout, no need to wake fd_handler */ |
| 3610 | double time = EMACS_TIME_TO_DOUBLE (*timeout); | 3588 | double time = timespectod (*timeout); |
| 3611 | timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time | 3589 | timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time |
| 3612 | target: NSApp | 3590 | target: NSApp |
| 3613 | selector: | 3591 | selector: |
| @@ -3663,7 +3641,6 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 3663 | pthread_mutex_lock (&select_mutex); | 3641 | pthread_mutex_lock (&select_mutex); |
| 3664 | if (readfds) *readfds = select_readfds; | 3642 | if (readfds) *readfds = select_readfds; |
| 3665 | if (writefds) *writefds = select_writefds; | 3643 | if (writefds) *writefds = select_writefds; |
| 3666 | if (timeout) *timeout = select_timeout; | ||
| 3667 | pthread_mutex_unlock (&select_mutex); | 3644 | pthread_mutex_unlock (&select_mutex); |
| 3668 | result = t; | 3645 | result = t; |
| 3669 | } | 3646 | } |
| @@ -3721,7 +3698,7 @@ ns_set_vertical_scroll_bar (struct window *window, | |||
| 3721 | NSTRACE (ns_set_vertical_scroll_bar); | 3698 | NSTRACE (ns_set_vertical_scroll_bar); |
| 3722 | 3699 | ||
| 3723 | /* Get dimensions. */ | 3700 | /* Get dimensions. */ |
| 3724 | window_box (window, -1, 0, &window_y, 0, &window_height); | 3701 | window_box (window, ANY_AREA, 0, &window_y, 0, &window_height); |
| 3725 | top = window_y; | 3702 | top = window_y; |
| 3726 | height = window_height; | 3703 | height = window_height; |
| 3727 | width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f); | 3704 | width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f); |
| @@ -3737,16 +3714,7 @@ ns_set_vertical_scroll_bar (struct window *window, | |||
| 3737 | v = [view frame]; | 3714 | v = [view frame]; |
| 3738 | r.origin.y = (v.size.height - r.size.height - r.origin.y); | 3715 | r.origin.y = (v.size.height - r.size.height - r.origin.y); |
| 3739 | 3716 | ||
| 3740 | if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (window)) | 3717 | fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (window); |
| 3741 | fringe_extended_p = (WINDOW_LEFTMOST_P (window) | ||
| 3742 | && WINDOW_LEFT_FRINGE_WIDTH (window) | ||
| 3743 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window) | ||
| 3744 | || WINDOW_LEFT_MARGIN_COLS (window) == 0)); | ||
| 3745 | else | ||
| 3746 | fringe_extended_p = (WINDOW_RIGHTMOST_P (window) | ||
| 3747 | && WINDOW_RIGHT_FRINGE_WIDTH (window) | ||
| 3748 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window) | ||
| 3749 | || WINDOW_RIGHT_MARGIN_COLS (window) == 0)); | ||
| 3750 | 3718 | ||
| 3751 | XSETWINDOW (win, window); | 3719 | XSETWINDOW (win, window); |
| 3752 | block_input (); | 3720 | block_input (); |
| @@ -3957,7 +3925,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) | |||
| 3957 | { | 3925 | { |
| 3958 | NSScreen *screen = [NSScreen mainScreen]; | 3926 | NSScreen *screen = [NSScreen mainScreen]; |
| 3959 | NSWindowDepth depth = [screen depth]; | 3927 | NSWindowDepth depth = [screen depth]; |
| 3960 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; | ||
| 3961 | 3928 | ||
| 3962 | dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */ | 3929 | dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */ |
| 3963 | dpyinfo->resy = 72.27; | 3930 | dpyinfo->resy = 72.27; |
| @@ -3970,22 +3937,12 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) | |||
| 3970 | dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table); | 3937 | dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table); |
| 3971 | dpyinfo->color_table->colors = NULL; | 3938 | dpyinfo->color_table->colors = NULL; |
| 3972 | dpyinfo->root_window = 42; /* a placeholder.. */ | 3939 | dpyinfo->root_window = 42; /* a placeholder.. */ |
| 3973 | |||
| 3974 | hlinfo->mouse_face_mouse_frame = NULL; | ||
| 3975 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 3976 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 3977 | hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; | ||
| 3978 | hlinfo->mouse_face_window = hlinfo->mouse_face_overlay = Qnil; | ||
| 3979 | hlinfo->mouse_face_hidden = 0; | ||
| 3980 | |||
| 3981 | hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; | ||
| 3982 | hlinfo->mouse_face_defer = 0; | ||
| 3983 | |||
| 3984 | dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL; | 3940 | dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL; |
| 3985 | |||
| 3986 | dpyinfo->n_fonts = 0; | 3941 | dpyinfo->n_fonts = 0; |
| 3987 | dpyinfo->smallest_font_height = 1; | 3942 | dpyinfo->smallest_font_height = 1; |
| 3988 | dpyinfo->smallest_char_width = 1; | 3943 | dpyinfo->smallest_char_width = 1; |
| 3944 | |||
| 3945 | reset_mouse_highlight (&dpyinfo->mouse_highlight); | ||
| 3989 | } | 3946 | } |
| 3990 | 3947 | ||
| 3991 | 3948 | ||
| @@ -4006,7 +3963,6 @@ static struct redisplay_interface ns_redisplay_interface = | |||
| 4006 | ns_after_update_window_line, | 3963 | ns_after_update_window_line, |
| 4007 | ns_update_window_begin, | 3964 | ns_update_window_begin, |
| 4008 | ns_update_window_end, | 3965 | ns_update_window_end, |
| 4009 | x_cursor_to, | ||
| 4010 | ns_flush, | 3966 | ns_flush, |
| 4011 | 0, /* flush_display_optional */ | 3967 | 0, /* flush_display_optional */ |
| 4012 | x_clear_window_mouse_face, | 3968 | x_clear_window_mouse_face, |
| @@ -4073,8 +4029,8 @@ ns_create_terminal (struct ns_display_info *dpyinfo) | |||
| 4073 | terminal->ins_del_lines_hook = 0; /* XXX vestigial? */ | 4029 | terminal->ins_del_lines_hook = 0; /* XXX vestigial? */ |
| 4074 | terminal->delete_glyphs_hook = 0; /* XXX vestigial? */ | 4030 | terminal->delete_glyphs_hook = 0; /* XXX vestigial? */ |
| 4075 | terminal->ring_bell_hook = ns_ring_bell; | 4031 | terminal->ring_bell_hook = ns_ring_bell; |
| 4076 | terminal->reset_terminal_modes_hook = ns_reset_terminal_modes; | 4032 | terminal->reset_terminal_modes_hook = NULL; |
| 4077 | terminal->set_terminal_modes_hook = ns_set_terminal_modes; | 4033 | terminal->set_terminal_modes_hook = NULL; |
| 4078 | terminal->update_begin_hook = ns_update_begin; | 4034 | terminal->update_begin_hook = ns_update_begin; |
| 4079 | terminal->update_end_hook = ns_update_end; | 4035 | terminal->update_end_hook = ns_update_end; |
| 4080 | terminal->set_terminal_window_hook = NULL; /* XXX vestigial? */ | 4036 | terminal->set_terminal_window_hook = NULL; /* XXX vestigial? */ |
| @@ -4714,8 +4670,8 @@ not_in_argv (NSString *arg) | |||
| 4714 | int waiting = 1, nfds; | 4670 | int waiting = 1, nfds; |
| 4715 | char c; | 4671 | char c; |
| 4716 | 4672 | ||
| 4717 | SELECT_TYPE readfds, writefds, *wfds; | 4673 | fd_set readfds, writefds, *wfds; |
| 4718 | EMACS_TIME timeout, *tmo; | 4674 | struct timespec timeout, *tmo; |
| 4719 | NSAutoreleasePool *pool = nil; | 4675 | NSAutoreleasePool *pool = nil; |
| 4720 | 4676 | ||
| 4721 | /* NSTRACE (fd_handler); */ | 4677 | /* NSTRACE (fd_handler); */ |
| @@ -4727,7 +4683,7 @@ not_in_argv (NSString *arg) | |||
| 4727 | 4683 | ||
| 4728 | if (waiting) | 4684 | if (waiting) |
| 4729 | { | 4685 | { |
| 4730 | SELECT_TYPE fds; | 4686 | fd_set fds; |
| 4731 | FD_ZERO (&fds); | 4687 | FD_ZERO (&fds); |
| 4732 | FD_SET (selfds[0], &fds); | 4688 | FD_SET (selfds[0], &fds); |
| 4733 | result = select (selfds[0]+1, &fds, NULL, NULL, NULL); | 4689 | result = select (selfds[0]+1, &fds, NULL, NULL, NULL); |
| @@ -5496,6 +5452,30 @@ not_in_argv (NSString *arg) | |||
| 5496 | previous_help_echo_string = help_echo_string; | 5452 | previous_help_echo_string = help_echo_string; |
| 5497 | help_echo_string = Qnil; | 5453 | help_echo_string = Qnil; |
| 5498 | 5454 | ||
| 5455 | if (!NILP (Vmouse_autoselect_window)) | ||
| 5456 | { | ||
| 5457 | NSTRACE (mouse_autoselect_window); | ||
| 5458 | static Lisp_Object last_mouse_window; | ||
| 5459 | Lisp_Object window = window_from_coordinates | ||
| 5460 | (emacsframe, last_mouse_motion_position.x, | ||
| 5461 | last_mouse_motion_position.y, 0, 0); | ||
| 5462 | |||
| 5463 | if (WINDOWP (window) | ||
| 5464 | && !EQ (window, last_mouse_window) | ||
| 5465 | && !EQ (window, selected_window) | ||
| 5466 | && (focus_follows_mouse | ||
| 5467 | || (EQ (XWINDOW (window)->frame, | ||
| 5468 | XWINDOW (selected_window)->frame)))) | ||
| 5469 | { | ||
| 5470 | NSTRACE (in_window); | ||
| 5471 | emacs_event->kind = SELECT_WINDOW_EVENT; | ||
| 5472 | emacs_event->frame_or_window = window; | ||
| 5473 | EV_TRAILER2 (e); | ||
| 5474 | } | ||
| 5475 | /* Remember the last window where we saw the mouse. */ | ||
| 5476 | last_mouse_window = window; | ||
| 5477 | } | ||
| 5478 | |||
| 5499 | if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x, | 5479 | if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x, |
| 5500 | last_mouse_motion_position.y)) | 5480 | last_mouse_motion_position.y)) |
| 5501 | help_echo_string = previous_help_echo_string; | 5481 | help_echo_string = previous_help_echo_string; |
diff --git a/src/print.c b/src/print.c index 80f1bb6beb4..4ad34534da3 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -124,7 +124,8 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1; | |||
| 124 | set_buffer_internal (XMARKER (printcharfun)->buffer); \ | 124 | set_buffer_internal (XMARKER (printcharfun)->buffer); \ |
| 125 | marker_pos = marker_position (printcharfun); \ | 125 | marker_pos = marker_position (printcharfun); \ |
| 126 | if (marker_pos < BEGV || marker_pos > ZV) \ | 126 | if (marker_pos < BEGV || marker_pos > ZV) \ |
| 127 | error ("Marker is outside the accessible part of the buffer"); \ | 127 | signal_error ("Marker is outside the accessible " \ |
| 128 | "part of the buffer", printcharfun); \ | ||
| 128 | old_point = PT; \ | 129 | old_point = PT; \ |
| 129 | old_point_byte = PT_BYTE; \ | 130 | old_point_byte = PT_BYTE; \ |
| 130 | SET_PT_BOTH (marker_pos, \ | 131 | SET_PT_BOTH (marker_pos, \ |
| @@ -136,10 +137,10 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1; | |||
| 136 | if (NILP (printcharfun)) \ | 137 | if (NILP (printcharfun)) \ |
| 137 | { \ | 138 | { \ |
| 138 | Lisp_Object string; \ | 139 | Lisp_Object string; \ |
| 139 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) \ | 140 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) \ |
| 140 | && ! print_escape_multibyte) \ | 141 | && ! print_escape_multibyte) \ |
| 141 | specbind (Qprint_escape_multibyte, Qt); \ | 142 | specbind (Qprint_escape_multibyte, Qt); \ |
| 142 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters)) \ | 143 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters)) \ |
| 143 | && ! print_escape_nonascii) \ | 144 | && ! print_escape_nonascii) \ |
| 144 | specbind (Qprint_escape_nonascii, Qt); \ | 145 | specbind (Qprint_escape_nonascii, Qt); \ |
| 145 | if (print_buffer != 0) \ | 146 | if (print_buffer != 0) \ |
| @@ -166,7 +167,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1; | |||
| 166 | if (NILP (printcharfun)) \ | 167 | if (NILP (printcharfun)) \ |
| 167 | { \ | 168 | { \ |
| 168 | if (print_buffer_pos != print_buffer_pos_byte \ | 169 | if (print_buffer_pos != print_buffer_pos_byte \ |
| 169 | && NILP (BVAR (current_buffer, enable_multibyte_characters))) \ | 170 | && NILP (BVAR (current_buffer, enable_multibyte_characters)))\ |
| 170 | { \ | 171 | { \ |
| 171 | unsigned char *temp = alloca (print_buffer_pos + 1); \ | 172 | unsigned char *temp = alloca (print_buffer_pos + 1); \ |
| 172 | copy_text ((unsigned char *) print_buffer, temp, \ | 173 | copy_text ((unsigned char *) print_buffer, temp, \ |
diff --git a/src/process.c b/src/process.c index d87a1803fe2..20f84990d6f 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -92,6 +92,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 92 | 92 | ||
| 93 | #include <c-ctype.h> | 93 | #include <c-ctype.h> |
| 94 | #include <sig2str.h> | 94 | #include <sig2str.h> |
| 95 | #include <verify.h> | ||
| 95 | 96 | ||
| 96 | #endif /* subprocesses */ | 97 | #endif /* subprocesses */ |
| 97 | 98 | ||
| @@ -131,8 +132,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 131 | #endif | 132 | #endif |
| 132 | 133 | ||
| 133 | #ifdef WINDOWSNT | 134 | #ifdef WINDOWSNT |
| 134 | extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | 135 | extern int sys_select (int, fd_set *, fd_set *, fd_set *, |
| 135 | EMACS_TIME *, void *); | 136 | struct timespec *, void *); |
| 136 | #endif | 137 | #endif |
| 137 | 138 | ||
| 138 | #ifndef SOCK_CLOEXEC | 139 | #ifndef SOCK_CLOEXEC |
| @@ -260,7 +261,7 @@ static EMACS_INT update_tick; | |||
| 260 | #endif | 261 | #endif |
| 261 | 262 | ||
| 262 | #ifdef ADAPTIVE_READ_BUFFERING | 263 | #ifdef ADAPTIVE_READ_BUFFERING |
| 263 | #define READ_OUTPUT_DELAY_INCREMENT (EMACS_TIME_RESOLUTION / 100) | 264 | #define READ_OUTPUT_DELAY_INCREMENT (TIMESPEC_RESOLUTION / 100) |
| 264 | #define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5) | 265 | #define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5) |
| 265 | #define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7) | 266 | #define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7) |
| 266 | 267 | ||
| @@ -279,7 +280,7 @@ static bool process_output_skip; | |||
| 279 | 280 | ||
| 280 | static void create_process (Lisp_Object, char **, Lisp_Object); | 281 | static void create_process (Lisp_Object, char **, Lisp_Object); |
| 281 | #ifdef USABLE_SIGIO | 282 | #ifdef USABLE_SIGIO |
| 282 | static bool keyboard_bit_set (SELECT_TYPE *); | 283 | static bool keyboard_bit_set (fd_set *); |
| 283 | #endif | 284 | #endif |
| 284 | static void deactivate_process (Lisp_Object); | 285 | static void deactivate_process (Lisp_Object); |
| 285 | static void status_notify (struct Lisp_Process *); | 286 | static void status_notify (struct Lisp_Process *); |
| @@ -298,39 +299,39 @@ static void exec_sentinel (Lisp_Object proc, Lisp_Object reason); | |||
| 298 | 299 | ||
| 299 | /* Mask of bits indicating the descriptors that we wait for input on. */ | 300 | /* Mask of bits indicating the descriptors that we wait for input on. */ |
| 300 | 301 | ||
| 301 | static SELECT_TYPE input_wait_mask; | 302 | static fd_set input_wait_mask; |
| 302 | 303 | ||
| 303 | /* Mask that excludes keyboard input descriptor(s). */ | 304 | /* Mask that excludes keyboard input descriptor(s). */ |
| 304 | 305 | ||
| 305 | static SELECT_TYPE non_keyboard_wait_mask; | 306 | static fd_set non_keyboard_wait_mask; |
| 306 | 307 | ||
| 307 | /* Mask that excludes process input descriptor(s). */ | 308 | /* Mask that excludes process input descriptor(s). */ |
| 308 | 309 | ||
| 309 | static SELECT_TYPE non_process_wait_mask; | 310 | static fd_set non_process_wait_mask; |
| 310 | 311 | ||
| 311 | /* Mask for selecting for write. */ | 312 | /* Mask for selecting for write. */ |
| 312 | 313 | ||
| 313 | static SELECT_TYPE write_mask; | 314 | static fd_set write_mask; |
| 314 | 315 | ||
| 315 | #ifdef NON_BLOCKING_CONNECT | 316 | #ifdef NON_BLOCKING_CONNECT |
| 316 | /* Mask of bits indicating the descriptors that we wait for connect to | 317 | /* Mask of bits indicating the descriptors that we wait for connect to |
| 317 | complete on. Once they complete, they are removed from this mask | 318 | complete on. Once they complete, they are removed from this mask |
| 318 | and added to the input_wait_mask and non_keyboard_wait_mask. */ | 319 | and added to the input_wait_mask and non_keyboard_wait_mask. */ |
| 319 | 320 | ||
| 320 | static SELECT_TYPE connect_wait_mask; | 321 | static fd_set connect_wait_mask; |
| 321 | 322 | ||
| 322 | /* Number of bits set in connect_wait_mask. */ | 323 | /* Number of bits set in connect_wait_mask. */ |
| 323 | static int num_pending_connects; | 324 | static int num_pending_connects; |
| 324 | #endif /* NON_BLOCKING_CONNECT */ | 325 | #endif /* NON_BLOCKING_CONNECT */ |
| 325 | 326 | ||
| 326 | /* The largest descriptor currently in use for a process object. */ | 327 | /* The largest descriptor currently in use for a process object; -1 if none. */ |
| 327 | static int max_process_desc; | 328 | static int max_process_desc; |
| 328 | 329 | ||
| 329 | /* The largest descriptor currently in use for input. */ | 330 | /* The largest descriptor currently in use for input; -1 if none. */ |
| 330 | static int max_input_desc; | 331 | static int max_input_desc; |
| 331 | 332 | ||
| 332 | /* Indexed by descriptor, gives the process (if any) for that descriptor */ | 333 | /* Indexed by descriptor, gives the process (if any) for that descriptor */ |
| 333 | static Lisp_Object chan_process[MAXDESC]; | 334 | static Lisp_Object chan_process[FD_SETSIZE]; |
| 334 | 335 | ||
| 335 | /* Alist of elements (NAME . PROCESS) */ | 336 | /* Alist of elements (NAME . PROCESS) */ |
| 336 | static Lisp_Object Vprocess_alist; | 337 | static Lisp_Object Vprocess_alist; |
| @@ -341,18 +342,18 @@ static Lisp_Object Vprocess_alist; | |||
| 341 | output from the process is to read at least one char. | 342 | output from the process is to read at least one char. |
| 342 | Always -1 on systems that support FIONREAD. */ | 343 | Always -1 on systems that support FIONREAD. */ |
| 343 | 344 | ||
| 344 | static int proc_buffered_char[MAXDESC]; | 345 | static int proc_buffered_char[FD_SETSIZE]; |
| 345 | 346 | ||
| 346 | /* Table of `struct coding-system' for each process. */ | 347 | /* Table of `struct coding-system' for each process. */ |
| 347 | static struct coding_system *proc_decode_coding_system[MAXDESC]; | 348 | static struct coding_system *proc_decode_coding_system[FD_SETSIZE]; |
| 348 | static struct coding_system *proc_encode_coding_system[MAXDESC]; | 349 | static struct coding_system *proc_encode_coding_system[FD_SETSIZE]; |
| 349 | 350 | ||
| 350 | #ifdef DATAGRAM_SOCKETS | 351 | #ifdef DATAGRAM_SOCKETS |
| 351 | /* Table of `partner address' for datagram sockets. */ | 352 | /* Table of `partner address' for datagram sockets. */ |
| 352 | static struct sockaddr_and_len { | 353 | static struct sockaddr_and_len { |
| 353 | struct sockaddr *sa; | 354 | struct sockaddr *sa; |
| 354 | int len; | 355 | int len; |
| 355 | } datagram_address[MAXDESC]; | 356 | } datagram_address[FD_SETSIZE]; |
| 356 | #define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0) | 357 | #define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0) |
| 357 | #define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XPROCESS (proc)->infd].sa != 0) | 358 | #define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XPROCESS (proc)->infd].sa != 0) |
| 358 | #else | 359 | #else |
| @@ -360,6 +361,12 @@ static struct sockaddr_and_len { | |||
| 360 | #define DATAGRAM_CONN_P(proc) (0) | 361 | #define DATAGRAM_CONN_P(proc) (0) |
| 361 | #endif | 362 | #endif |
| 362 | 363 | ||
| 364 | /* FOR_EACH_PROCESS (LIST_VAR, PROC_VAR) followed by a statement is | ||
| 365 | a `for' loop which iterates over processes from Vprocess_alist. */ | ||
| 366 | |||
| 367 | #define FOR_EACH_PROCESS(list_var, proc_var) \ | ||
| 368 | FOR_EACH_ALIST_VALUE (Vprocess_alist, list_var, proc_var) | ||
| 369 | |||
| 363 | /* These setters are used only in this file, so they can be private. */ | 370 | /* These setters are used only in this file, so they can be private. */ |
| 364 | static void | 371 | static void |
| 365 | pset_buffer (struct Lisp_Process *p, Lisp_Object val) | 372 | pset_buffer (struct Lisp_Process *p, Lisp_Object val) |
| @@ -451,7 +458,7 @@ static struct fd_callback_data | |||
| 451 | #define FOR_READ 1 | 458 | #define FOR_READ 1 |
| 452 | #define FOR_WRITE 2 | 459 | #define FOR_WRITE 2 |
| 453 | int condition; /* mask of the defines above. */ | 460 | int condition; /* mask of the defines above. */ |
| 454 | } fd_callback_info[MAXDESC]; | 461 | } fd_callback_info[FD_SETSIZE]; |
| 455 | 462 | ||
| 456 | 463 | ||
| 457 | /* Add a file descriptor FD to be monitored for when read is possible. | 464 | /* Add a file descriptor FD to be monitored for when read is possible. |
| @@ -460,7 +467,7 @@ static struct fd_callback_data | |||
| 460 | void | 467 | void |
| 461 | add_read_fd (int fd, fd_callback func, void *data) | 468 | add_read_fd (int fd, fd_callback func, void *data) |
| 462 | { | 469 | { |
| 463 | eassert (fd < MAXDESC); | 470 | eassert (fd < FD_SETSIZE); |
| 464 | add_keyboard_wait_descriptor (fd); | 471 | add_keyboard_wait_descriptor (fd); |
| 465 | 472 | ||
| 466 | fd_callback_info[fd].func = func; | 473 | fd_callback_info[fd].func = func; |
| @@ -473,7 +480,7 @@ add_read_fd (int fd, fd_callback func, void *data) | |||
| 473 | void | 480 | void |
| 474 | delete_read_fd (int fd) | 481 | delete_read_fd (int fd) |
| 475 | { | 482 | { |
| 476 | eassert (fd < MAXDESC); | 483 | eassert (fd < FD_SETSIZE); |
| 477 | delete_keyboard_wait_descriptor (fd); | 484 | delete_keyboard_wait_descriptor (fd); |
| 478 | 485 | ||
| 479 | fd_callback_info[fd].condition &= ~FOR_READ; | 486 | fd_callback_info[fd].condition &= ~FOR_READ; |
| @@ -490,7 +497,7 @@ delete_read_fd (int fd) | |||
| 490 | void | 497 | void |
| 491 | add_write_fd (int fd, fd_callback func, void *data) | 498 | add_write_fd (int fd, fd_callback func, void *data) |
| 492 | { | 499 | { |
| 493 | eassert (fd < MAXDESC); | 500 | eassert (fd < FD_SETSIZE); |
| 494 | FD_SET (fd, &write_mask); | 501 | FD_SET (fd, &write_mask); |
| 495 | if (fd > max_input_desc) | 502 | if (fd > max_input_desc) |
| 496 | max_input_desc = fd; | 503 | max_input_desc = fd; |
| @@ -500,29 +507,35 @@ add_write_fd (int fd, fd_callback func, void *data) | |||
| 500 | fd_callback_info[fd].condition |= FOR_WRITE; | 507 | fd_callback_info[fd].condition |= FOR_WRITE; |
| 501 | } | 508 | } |
| 502 | 509 | ||
| 510 | /* FD is no longer an input descriptor; update max_input_desc accordingly. */ | ||
| 511 | |||
| 512 | static void | ||
| 513 | delete_input_desc (int fd) | ||
| 514 | { | ||
| 515 | if (fd == max_input_desc) | ||
| 516 | { | ||
| 517 | do | ||
| 518 | fd--; | ||
| 519 | while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask) | ||
| 520 | || FD_ISSET (fd, &write_mask))); | ||
| 521 | |||
| 522 | max_input_desc = fd; | ||
| 523 | } | ||
| 524 | } | ||
| 525 | |||
| 503 | /* Stop monitoring file descriptor FD for when write is possible. */ | 526 | /* Stop monitoring file descriptor FD for when write is possible. */ |
| 504 | 527 | ||
| 505 | void | 528 | void |
| 506 | delete_write_fd (int fd) | 529 | delete_write_fd (int fd) |
| 507 | { | 530 | { |
| 508 | int lim = max_input_desc; | 531 | eassert (fd < FD_SETSIZE); |
| 509 | |||
| 510 | eassert (fd < MAXDESC); | ||
| 511 | FD_CLR (fd, &write_mask); | 532 | FD_CLR (fd, &write_mask); |
| 512 | fd_callback_info[fd].condition &= ~FOR_WRITE; | 533 | fd_callback_info[fd].condition &= ~FOR_WRITE; |
| 513 | if (fd_callback_info[fd].condition == 0) | 534 | if (fd_callback_info[fd].condition == 0) |
| 514 | { | 535 | { |
| 515 | fd_callback_info[fd].func = 0; | 536 | fd_callback_info[fd].func = 0; |
| 516 | fd_callback_info[fd].data = 0; | 537 | fd_callback_info[fd].data = 0; |
| 517 | 538 | delete_input_desc (fd); | |
| 518 | if (fd == max_input_desc) | ||
| 519 | for (fd = lim; fd >= 0; fd--) | ||
| 520 | if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) | ||
| 521 | { | ||
| 522 | max_input_desc = fd; | ||
| 523 | break; | ||
| 524 | } | ||
| 525 | |||
| 526 | } | 539 | } |
| 527 | } | 540 | } |
| 528 | 541 | ||
| @@ -674,6 +687,15 @@ allocate_pty (char pty_name[PTY_NAME_SIZE]) | |||
| 674 | 687 | ||
| 675 | if (fd >= 0) | 688 | if (fd >= 0) |
| 676 | { | 689 | { |
| 690 | #ifdef PTY_OPEN | ||
| 691 | /* Set FD's close-on-exec flag. This is needed even if | ||
| 692 | PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX | ||
| 693 | doesn't require support for that combination. | ||
| 694 | Multithreaded platforms where posix_openpt ignores | ||
| 695 | O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt) | ||
| 696 | have a race condition between the PTY_OPEN and here. */ | ||
| 697 | fcntl (fd, F_SETFD, FD_CLOEXEC); | ||
| 698 | #endif | ||
| 677 | /* check to make certain that both sides are available | 699 | /* check to make certain that both sides are available |
| 678 | this avoids a nasty yet stupid bug in rlogins */ | 700 | this avoids a nasty yet stupid bug in rlogins */ |
| 679 | #ifdef PTY_TTY_NAME_SPRINTF | 701 | #ifdef PTY_TTY_NAME_SPRINTF |
| @@ -716,6 +738,8 @@ make_process (Lisp_Object name) | |||
| 716 | non-Lisp data, so do it only for slots which should not be zero. */ | 738 | non-Lisp data, so do it only for slots which should not be zero. */ |
| 717 | p->infd = -1; | 739 | p->infd = -1; |
| 718 | p->outfd = -1; | 740 | p->outfd = -1; |
| 741 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | ||
| 742 | p->open_fd[i] = -1; | ||
| 719 | 743 | ||
| 720 | #ifdef HAVE_GNUTLS | 744 | #ifdef HAVE_GNUTLS |
| 721 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; | 745 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; |
| @@ -812,13 +836,17 @@ get_process (register Lisp_Object name) | |||
| 812 | treated by the SIGCHLD handler and waitpid has been invoked on them; | 836 | treated by the SIGCHLD handler and waitpid has been invoked on them; |
| 813 | otherwise they might fill up the kernel's process table. | 837 | otherwise they might fill up the kernel's process table. |
| 814 | 838 | ||
| 815 | Some processes created by call-process are also put onto this list. */ | 839 | Some processes created by call-process are also put onto this list. |
| 840 | |||
| 841 | Members of this list are (process-ID . filename) pairs. The | ||
| 842 | process-ID is a number; the filename, if a string, is a file that | ||
| 843 | needs to be removed after the process exits. */ | ||
| 816 | static Lisp_Object deleted_pid_list; | 844 | static Lisp_Object deleted_pid_list; |
| 817 | 845 | ||
| 818 | void | 846 | void |
| 819 | record_deleted_pid (pid_t pid) | 847 | record_deleted_pid (pid_t pid, Lisp_Object filename) |
| 820 | { | 848 | { |
| 821 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), | 849 | deleted_pid_list = Fcons (Fcons (make_fixnum_or_float (pid), filename), |
| 822 | /* GC treated elements set to nil. */ | 850 | /* GC treated elements set to nil. */ |
| 823 | Fdelq (Qnil, deleted_pid_list)); | 851 | Fdelq (Qnil, deleted_pid_list)); |
| 824 | 852 | ||
| @@ -846,7 +874,7 @@ nil, indicating the current buffer's process. */) | |||
| 846 | else | 874 | else |
| 847 | { | 875 | { |
| 848 | if (p->alive) | 876 | if (p->alive) |
| 849 | record_kill_process (p); | 877 | record_kill_process (p, Qnil); |
| 850 | 878 | ||
| 851 | if (p->infd >= 0) | 879 | if (p->infd >= 0) |
| 852 | { | 880 | { |
| @@ -1112,15 +1140,18 @@ See `set-process-sentinel' for more info on sentinels. */) | |||
| 1112 | DEFUN ("set-process-window-size", Fset_process_window_size, | 1140 | DEFUN ("set-process-window-size", Fset_process_window_size, |
| 1113 | Sset_process_window_size, 3, 3, 0, | 1141 | Sset_process_window_size, 3, 3, 0, |
| 1114 | doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) | 1142 | doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) |
| 1115 | (register Lisp_Object process, Lisp_Object height, Lisp_Object width) | 1143 | (Lisp_Object process, Lisp_Object height, Lisp_Object width) |
| 1116 | { | 1144 | { |
| 1117 | CHECK_PROCESS (process); | 1145 | CHECK_PROCESS (process); |
| 1118 | CHECK_RANGED_INTEGER (height, 0, INT_MAX); | 1146 | |
| 1119 | CHECK_RANGED_INTEGER (width, 0, INT_MAX); | 1147 | /* All known platforms store window sizes as 'unsigned short'. */ |
| 1148 | CHECK_RANGED_INTEGER (height, 0, USHRT_MAX); | ||
| 1149 | CHECK_RANGED_INTEGER (width, 0, USHRT_MAX); | ||
| 1120 | 1150 | ||
| 1121 | if (XPROCESS (process)->infd < 0 | 1151 | if (XPROCESS (process)->infd < 0 |
| 1122 | || set_window_size (XPROCESS (process)->infd, | 1152 | || (set_window_size (XPROCESS (process)->infd, |
| 1123 | XINT (height), XINT (width)) <= 0) | 1153 | XINT (height), XINT (width)) |
| 1154 | < 0)) | ||
| 1124 | return Qnil; | 1155 | return Qnil; |
| 1125 | else | 1156 | else |
| 1126 | return Qt; | 1157 | return Qt; |
| @@ -1380,22 +1411,9 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1380 | function. The argument list is protected by the caller, so all | 1411 | function. The argument list is protected by the caller, so all |
| 1381 | we really have to worry about is buffer. */ | 1412 | we really have to worry about is buffer. */ |
| 1382 | { | 1413 | { |
| 1383 | struct gcpro gcpro1, gcpro2; | 1414 | struct gcpro gcpro1; |
| 1384 | 1415 | GCPRO1 (buffer); | |
| 1385 | current_dir = BVAR (current_buffer, directory); | 1416 | current_dir = encode_current_directory (); |
| 1386 | |||
| 1387 | GCPRO2 (buffer, current_dir); | ||
| 1388 | |||
| 1389 | current_dir = Funhandled_file_name_directory (current_dir); | ||
| 1390 | if (NILP (current_dir)) | ||
| 1391 | /* If the file name handler says that current_dir is unreachable, use | ||
| 1392 | a sensible default. */ | ||
| 1393 | current_dir = build_string ("~/"); | ||
| 1394 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | ||
| 1395 | if (NILP (Ffile_accessible_directory_p (current_dir))) | ||
| 1396 | report_file_error ("Setting current directory", | ||
| 1397 | BVAR (current_buffer, directory)); | ||
| 1398 | |||
| 1399 | UNGCPRO; | 1417 | UNGCPRO; |
| 1400 | } | 1418 | } |
| 1401 | 1419 | ||
| @@ -1599,22 +1617,49 @@ start_process_unwind (Lisp_Object proc) | |||
| 1599 | remove_process (proc); | 1617 | remove_process (proc); |
| 1600 | } | 1618 | } |
| 1601 | 1619 | ||
| 1620 | /* If *FD_ADDR is nonnegative, close it, and mark it as closed. */ | ||
| 1621 | |||
| 1622 | static void | ||
| 1623 | close_process_fd (int *fd_addr) | ||
| 1624 | { | ||
| 1625 | int fd = *fd_addr; | ||
| 1626 | if (0 <= fd) | ||
| 1627 | { | ||
| 1628 | *fd_addr = -1; | ||
| 1629 | emacs_close (fd); | ||
| 1630 | } | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | /* Indexes of file descriptors in open_fds. */ | ||
| 1634 | enum | ||
| 1635 | { | ||
| 1636 | /* The pipe from Emacs to its subprocess. */ | ||
| 1637 | SUBPROCESS_STDIN, | ||
| 1638 | WRITE_TO_SUBPROCESS, | ||
| 1639 | |||
| 1640 | /* The main pipe from the subprocess to Emacs. */ | ||
| 1641 | READ_FROM_SUBPROCESS, | ||
| 1642 | SUBPROCESS_STDOUT, | ||
| 1643 | |||
| 1644 | /* The pipe from the subprocess to Emacs that is closed when the | ||
| 1645 | subprocess execs. */ | ||
| 1646 | READ_FROM_EXEC_MONITOR, | ||
| 1647 | EXEC_MONITOR_OUTPUT | ||
| 1648 | }; | ||
| 1649 | |||
| 1650 | verify (PROCESS_OPEN_FDS == EXEC_MONITOR_OUTPUT + 1); | ||
| 1602 | 1651 | ||
| 1603 | static void | 1652 | static void |
| 1604 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | 1653 | create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) |
| 1605 | { | 1654 | { |
| 1655 | struct Lisp_Process *p = XPROCESS (process); | ||
| 1606 | int inchannel, outchannel; | 1656 | int inchannel, outchannel; |
| 1607 | pid_t pid; | 1657 | pid_t pid; |
| 1608 | int vfork_errno; | 1658 | int vfork_errno; |
| 1609 | int sv[2]; | ||
| 1610 | #ifndef WINDOWSNT | ||
| 1611 | int wait_child_setup[2]; | ||
| 1612 | #endif | ||
| 1613 | int forkin, forkout; | 1659 | int forkin, forkout; |
| 1614 | bool pty_flag = 0; | 1660 | bool pty_flag = 0; |
| 1615 | char pty_name[PTY_NAME_SIZE]; | 1661 | char pty_name[PTY_NAME_SIZE]; |
| 1616 | Lisp_Object lisp_pty_name = Qnil; | 1662 | Lisp_Object lisp_pty_name = Qnil; |
| 1617 | Lisp_Object encoded_current_dir; | ||
| 1618 | 1663 | ||
| 1619 | inchannel = outchannel = -1; | 1664 | inchannel = outchannel = -1; |
| 1620 | 1665 | ||
| @@ -1623,6 +1668,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1623 | 1668 | ||
| 1624 | if (inchannel >= 0) | 1669 | if (inchannel >= 0) |
| 1625 | { | 1670 | { |
| 1671 | p->open_fd[READ_FROM_SUBPROCESS] = inchannel; | ||
| 1626 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) | 1672 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
| 1627 | /* On most USG systems it does not work to open the pty's tty here, | 1673 | /* On most USG systems it does not work to open the pty's tty here, |
| 1628 | then close it and reopen it in the child. */ | 1674 | then close it and reopen it in the child. */ |
| @@ -1631,6 +1677,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1631 | forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); | 1677 | forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); |
| 1632 | if (forkin < 0) | 1678 | if (forkin < 0) |
| 1633 | report_file_error ("Opening pty", Qnil); | 1679 | report_file_error ("Opening pty", Qnil); |
| 1680 | p->open_fd[SUBPROCESS_STDIN] = forkin; | ||
| 1634 | #else | 1681 | #else |
| 1635 | forkin = forkout = -1; | 1682 | forkin = forkout = -1; |
| 1636 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1683 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| @@ -1639,23 +1686,17 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1639 | } | 1686 | } |
| 1640 | else | 1687 | else |
| 1641 | { | 1688 | { |
| 1642 | if (emacs_pipe (sv) != 0) | 1689 | if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 |
| 1690 | || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) | ||
| 1643 | report_file_error ("Creating pipe", Qnil); | 1691 | report_file_error ("Creating pipe", Qnil); |
| 1644 | inchannel = sv[0]; | 1692 | forkin = p->open_fd[SUBPROCESS_STDIN]; |
| 1645 | forkout = sv[1]; | 1693 | outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; |
| 1646 | if (emacs_pipe (sv) != 0) | 1694 | inchannel = p->open_fd[READ_FROM_SUBPROCESS]; |
| 1647 | { | 1695 | forkout = p->open_fd[SUBPROCESS_STDOUT]; |
| 1648 | int pipe_errno = errno; | ||
| 1649 | emacs_close (inchannel); | ||
| 1650 | emacs_close (forkout); | ||
| 1651 | report_file_errno ("Creating pipe", Qnil, pipe_errno); | ||
| 1652 | } | ||
| 1653 | outchannel = sv[1]; | ||
| 1654 | forkin = sv[0]; | ||
| 1655 | } | 1696 | } |
| 1656 | 1697 | ||
| 1657 | #ifndef WINDOWSNT | 1698 | #ifndef WINDOWSNT |
| 1658 | if (emacs_pipe (wait_child_setup) != 0) | 1699 | if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0) |
| 1659 | report_file_error ("Creating pipe", Qnil); | 1700 | report_file_error ("Creating pipe", Qnil); |
| 1660 | #endif | 1701 | #endif |
| 1661 | 1702 | ||
| @@ -1664,16 +1705,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1664 | 1705 | ||
| 1665 | /* Record this as an active process, with its channels. */ | 1706 | /* Record this as an active process, with its channels. */ |
| 1666 | chan_process[inchannel] = process; | 1707 | chan_process[inchannel] = process; |
| 1667 | XPROCESS (process)->infd = inchannel; | 1708 | p->infd = inchannel; |
| 1668 | XPROCESS (process)->outfd = outchannel; | 1709 | p->outfd = outchannel; |
| 1669 | 1710 | ||
| 1670 | /* Previously we recorded the tty descriptor used in the subprocess. | 1711 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 1671 | It was only used for getting the foreground tty process, so now | 1712 | It was only used for getting the foreground tty process, so now |
| 1672 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 1713 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 1673 | more portable (see USG_SUBTTY_WORKS above). */ | 1714 | more portable (see USG_SUBTTY_WORKS above). */ |
| 1674 | 1715 | ||
| 1675 | XPROCESS (process)->pty_flag = pty_flag; | 1716 | p->pty_flag = pty_flag; |
| 1676 | pset_status (XPROCESS (process), Qrun); | 1717 | pset_status (p, Qrun); |
| 1677 | 1718 | ||
| 1678 | FD_SET (inchannel, &input_wait_mask); | 1719 | FD_SET (inchannel, &input_wait_mask); |
| 1679 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1720 | FD_SET (inchannel, &non_keyboard_wait_mask); |
| @@ -1683,35 +1724,29 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1683 | /* This may signal an error. */ | 1724 | /* This may signal an error. */ |
| 1684 | setup_process_coding_systems (process); | 1725 | setup_process_coding_systems (process); |
| 1685 | 1726 | ||
| 1686 | encoded_current_dir = ENCODE_FILE (current_dir); | ||
| 1687 | |||
| 1688 | block_input (); | 1727 | block_input (); |
| 1689 | block_child_signal (); | 1728 | block_child_signal (); |
| 1690 | 1729 | ||
| 1691 | #ifndef WINDOWSNT | 1730 | #ifndef WINDOWSNT |
| 1692 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1731 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 1693 | { | 1732 | { |
| 1694 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1733 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 1695 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1734 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1696 | Lisp_Object volatile process_volatile = process; | ||
| 1697 | char **volatile new_argv_volatile = new_argv; | 1735 | char **volatile new_argv_volatile = new_argv; |
| 1698 | int volatile forkin_volatile = forkin; | 1736 | int volatile forkin_volatile = forkin; |
| 1699 | int volatile forkout_volatile = forkout; | 1737 | int volatile forkout_volatile = forkout; |
| 1700 | int volatile wait_child_setup_0_volatile = wait_child_setup[0]; | 1738 | struct Lisp_Process *p_volatile = p; |
| 1701 | int volatile wait_child_setup_1_volatile = wait_child_setup[1]; | ||
| 1702 | 1739 | ||
| 1703 | pid = vfork (); | 1740 | pid = vfork (); |
| 1704 | 1741 | ||
| 1705 | encoded_current_dir = encoded_current_dir_volatile; | 1742 | current_dir = current_dir_volatile; |
| 1706 | lisp_pty_name = lisp_pty_name_volatile; | 1743 | lisp_pty_name = lisp_pty_name_volatile; |
| 1707 | process = process_volatile; | ||
| 1708 | new_argv = new_argv_volatile; | 1744 | new_argv = new_argv_volatile; |
| 1709 | forkin = forkin_volatile; | 1745 | forkin = forkin_volatile; |
| 1710 | forkout = forkout_volatile; | 1746 | forkout = forkout_volatile; |
| 1711 | wait_child_setup[0] = wait_child_setup_0_volatile; | 1747 | p = p_volatile; |
| 1712 | wait_child_setup[1] = wait_child_setup_1_volatile; | ||
| 1713 | 1748 | ||
| 1714 | pty_flag = XPROCESS (process)->pty_flag; | 1749 | pty_flag = p->pty_flag; |
| 1715 | } | 1750 | } |
| 1716 | 1751 | ||
| 1717 | if (pid == 0) | 1752 | if (pid == 0) |
| @@ -1816,53 +1851,51 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1816 | if (pty_flag) | 1851 | if (pty_flag) |
| 1817 | child_setup_tty (xforkout); | 1852 | child_setup_tty (xforkout); |
| 1818 | #ifdef WINDOWSNT | 1853 | #ifdef WINDOWSNT |
| 1819 | pid = child_setup (xforkin, xforkout, xforkout, | 1854 | pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); |
| 1820 | new_argv, 1, encoded_current_dir); | ||
| 1821 | #else /* not WINDOWSNT */ | 1855 | #else /* not WINDOWSNT */ |
| 1822 | child_setup (xforkin, xforkout, xforkout, | 1856 | child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); |
| 1823 | new_argv, 1, encoded_current_dir); | ||
| 1824 | #endif /* not WINDOWSNT */ | 1857 | #endif /* not WINDOWSNT */ |
| 1825 | } | 1858 | } |
| 1826 | 1859 | ||
| 1827 | /* Back in the parent process. */ | 1860 | /* Back in the parent process. */ |
| 1828 | 1861 | ||
| 1829 | vfork_errno = errno; | 1862 | vfork_errno = errno; |
| 1830 | XPROCESS (process)->pid = pid; | 1863 | p->pid = pid; |
| 1831 | if (pid >= 0) | 1864 | if (pid >= 0) |
| 1832 | XPROCESS (process)->alive = 1; | 1865 | p->alive = 1; |
| 1833 | 1866 | ||
| 1834 | /* Stop blocking in the parent. */ | 1867 | /* Stop blocking in the parent. */ |
| 1835 | unblock_child_signal (); | 1868 | unblock_child_signal (); |
| 1836 | unblock_input (); | 1869 | unblock_input (); |
| 1837 | 1870 | ||
| 1838 | if (forkin >= 0) | ||
| 1839 | emacs_close (forkin); | ||
| 1840 | if (forkin != forkout && forkout >= 0) | ||
| 1841 | emacs_close (forkout); | ||
| 1842 | |||
| 1843 | if (pid < 0) | 1871 | if (pid < 0) |
| 1844 | report_file_errno ("Doing vfork", Qnil, vfork_errno); | 1872 | report_file_errno ("Doing vfork", Qnil, vfork_errno); |
| 1845 | else | 1873 | else |
| 1846 | { | 1874 | { |
| 1847 | /* vfork succeeded. */ | 1875 | /* vfork succeeded. */ |
| 1848 | 1876 | ||
| 1877 | /* Close the pipe ends that the child uses, or the child's pty. */ | ||
| 1878 | close_process_fd (&p->open_fd[SUBPROCESS_STDIN]); | ||
| 1879 | close_process_fd (&p->open_fd[SUBPROCESS_STDOUT]); | ||
| 1880 | |||
| 1849 | #ifdef WINDOWSNT | 1881 | #ifdef WINDOWSNT |
| 1850 | register_child (pid, inchannel); | 1882 | register_child (pid, inchannel); |
| 1851 | #endif /* WINDOWSNT */ | 1883 | #endif /* WINDOWSNT */ |
| 1852 | 1884 | ||
| 1853 | pset_tty_name (XPROCESS (process), lisp_pty_name); | 1885 | pset_tty_name (p, lisp_pty_name); |
| 1854 | 1886 | ||
| 1855 | #ifndef WINDOWSNT | 1887 | #ifndef WINDOWSNT |
| 1856 | /* Wait for child_setup to complete in case that vfork is | 1888 | /* Wait for child_setup to complete in case that vfork is |
| 1857 | actually defined as fork. The descriptor wait_child_setup[1] | 1889 | actually defined as fork. The descriptor |
| 1890 | XPROCESS (proc)->open_fd[EXEC_MONITOR_OUTPUT] | ||
| 1858 | of a pipe is closed at the child side either by close-on-exec | 1891 | of a pipe is closed at the child side either by close-on-exec |
| 1859 | on successful execve or the _exit call in child_setup. */ | 1892 | on successful execve or the _exit call in child_setup. */ |
| 1860 | { | 1893 | { |
| 1861 | char dummy; | 1894 | char dummy; |
| 1862 | 1895 | ||
| 1863 | emacs_close (wait_child_setup[1]); | 1896 | close_process_fd (&p->open_fd[EXEC_MONITOR_OUTPUT]); |
| 1864 | emacs_read (wait_child_setup[0], &dummy, 1); | 1897 | emacs_read (p->open_fd[READ_FROM_EXEC_MONITOR], &dummy, 1); |
| 1865 | emacs_close (wait_child_setup[0]); | 1898 | close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); |
| 1866 | } | 1899 | } |
| 1867 | #endif | 1900 | #endif |
| 1868 | } | 1901 | } |
| @@ -1871,16 +1904,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1871 | static void | 1904 | static void |
| 1872 | create_pty (Lisp_Object process) | 1905 | create_pty (Lisp_Object process) |
| 1873 | { | 1906 | { |
| 1907 | struct Lisp_Process *p = XPROCESS (process); | ||
| 1874 | char pty_name[PTY_NAME_SIZE]; | 1908 | char pty_name[PTY_NAME_SIZE]; |
| 1875 | int inchannel, outchannel; | 1909 | int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name); |
| 1876 | 1910 | ||
| 1877 | inchannel = outchannel = -1; | 1911 | if (pty_fd >= 0) |
| 1878 | |||
| 1879 | if (!NILP (Vprocess_connection_type)) | ||
| 1880 | outchannel = inchannel = allocate_pty (pty_name); | ||
| 1881 | |||
| 1882 | if (inchannel >= 0) | ||
| 1883 | { | 1912 | { |
| 1913 | p->open_fd[SUBPROCESS_STDIN] = pty_fd; | ||
| 1884 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) | 1914 | #if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
| 1885 | /* On most USG systems it does not work to open the pty's tty here, | 1915 | /* On most USG systems it does not work to open the pty's tty here, |
| 1886 | then close it and reopen it in the child. */ | 1916 | then close it and reopen it in the child. */ |
| @@ -1889,6 +1919,7 @@ create_pty (Lisp_Object process) | |||
| 1889 | int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); | 1919 | int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); |
| 1890 | if (forkout < 0) | 1920 | if (forkout < 0) |
| 1891 | report_file_error ("Opening pty", Qnil); | 1921 | report_file_error ("Opening pty", Qnil); |
| 1922 | p->open_fd[WRITE_TO_SUBPROCESS] = forkout; | ||
| 1892 | #if defined (DONT_REOPEN_PTY) | 1923 | #if defined (DONT_REOPEN_PTY) |
| 1893 | /* In the case that vfork is defined as fork, the parent process | 1924 | /* In the case that vfork is defined as fork, the parent process |
| 1894 | (Emacs) may send some data before the child process completes | 1925 | (Emacs) may send some data before the child process completes |
| @@ -1897,33 +1928,32 @@ create_pty (Lisp_Object process) | |||
| 1897 | #endif /* DONT_REOPEN_PTY */ | 1928 | #endif /* DONT_REOPEN_PTY */ |
| 1898 | #endif /* not USG, or USG_SUBTTY_WORKS */ | 1929 | #endif /* not USG, or USG_SUBTTY_WORKS */ |
| 1899 | 1930 | ||
| 1900 | fcntl (inchannel, F_SETFL, O_NONBLOCK); | 1931 | fcntl (pty_fd, F_SETFL, O_NONBLOCK); |
| 1901 | fcntl (outchannel, F_SETFL, O_NONBLOCK); | ||
| 1902 | 1932 | ||
| 1903 | /* Record this as an active process, with its channels. | 1933 | /* Record this as an active process, with its channels. |
| 1904 | As a result, child_setup will close Emacs's side of the pipes. */ | 1934 | As a result, child_setup will close Emacs's side of the pipes. */ |
| 1905 | chan_process[inchannel] = process; | 1935 | chan_process[pty_fd] = process; |
| 1906 | XPROCESS (process)->infd = inchannel; | 1936 | p->infd = pty_fd; |
| 1907 | XPROCESS (process)->outfd = outchannel; | 1937 | p->outfd = pty_fd; |
| 1908 | 1938 | ||
| 1909 | /* Previously we recorded the tty descriptor used in the subprocess. | 1939 | /* Previously we recorded the tty descriptor used in the subprocess. |
| 1910 | It was only used for getting the foreground tty process, so now | 1940 | It was only used for getting the foreground tty process, so now |
| 1911 | we just reopen the device (see emacs_get_tty_pgrp) as this is | 1941 | we just reopen the device (see emacs_get_tty_pgrp) as this is |
| 1912 | more portable (see USG_SUBTTY_WORKS above). */ | 1942 | more portable (see USG_SUBTTY_WORKS above). */ |
| 1913 | 1943 | ||
| 1914 | XPROCESS (process)->pty_flag = 1; | 1944 | p->pty_flag = 1; |
| 1915 | pset_status (XPROCESS (process), Qrun); | 1945 | pset_status (p, Qrun); |
| 1916 | setup_process_coding_systems (process); | 1946 | setup_process_coding_systems (process); |
| 1917 | 1947 | ||
| 1918 | FD_SET (inchannel, &input_wait_mask); | 1948 | FD_SET (pty_fd, &input_wait_mask); |
| 1919 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1949 | FD_SET (pty_fd, &non_keyboard_wait_mask); |
| 1920 | if (inchannel > max_process_desc) | 1950 | if (pty_fd > max_process_desc) |
| 1921 | max_process_desc = inchannel; | 1951 | max_process_desc = pty_fd; |
| 1922 | 1952 | ||
| 1923 | pset_tty_name (XPROCESS (process), build_string (pty_name)); | 1953 | pset_tty_name (p, build_string (pty_name)); |
| 1924 | } | 1954 | } |
| 1925 | 1955 | ||
| 1926 | XPROCESS (process)->pid = -2; | 1956 | p->pid = -2; |
| 1927 | } | 1957 | } |
| 1928 | 1958 | ||
| 1929 | 1959 | ||
| @@ -2529,6 +2559,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2529 | p = XPROCESS (proc); | 2559 | p = XPROCESS (proc); |
| 2530 | 2560 | ||
| 2531 | fd = serial_open (port); | 2561 | fd = serial_open (port); |
| 2562 | p->open_fd[SUBPROCESS_STDIN] = fd; | ||
| 2532 | p->infd = fd; | 2563 | p->infd = fd; |
| 2533 | p->outfd = fd; | 2564 | p->outfd = fd; |
| 2534 | if (fd > max_process_desc) | 2565 | if (fd > max_process_desc) |
| @@ -3201,7 +3232,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3201 | wait for completion is pselect(). */ | 3232 | wait for completion is pselect(). */ |
| 3202 | int sc; | 3233 | int sc; |
| 3203 | socklen_t len; | 3234 | socklen_t len; |
| 3204 | SELECT_TYPE fdset; | 3235 | fd_set fdset; |
| 3205 | retry_select: | 3236 | retry_select: |
| 3206 | FD_ZERO (&fdset); | 3237 | FD_ZERO (&fdset); |
| 3207 | FD_SET (s, &fdset); | 3238 | FD_SET (s, &fdset); |
| @@ -3291,12 +3322,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3291 | } | 3322 | } |
| 3292 | #endif | 3323 | #endif |
| 3293 | 3324 | ||
| 3294 | /* Discard the unwind protect for closing S, if any. */ | ||
| 3295 | specpdl_ptr = specpdl + count1; | ||
| 3296 | |||
| 3297 | /* Unwind bind_polling_period and request_sigio. */ | ||
| 3298 | unbind_to (count, Qnil); | ||
| 3299 | |||
| 3300 | if (s < 0) | 3325 | if (s < 0) |
| 3301 | { | 3326 | { |
| 3302 | /* If non-blocking got this far - and failed - assume non-blocking is | 3327 | /* If non-blocking got this far - and failed - assume non-blocking is |
| @@ -3338,8 +3363,17 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3338 | if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) | 3363 | if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) |
| 3339 | pset_command (p, Qt); | 3364 | pset_command (p, Qt); |
| 3340 | p->pid = 0; | 3365 | p->pid = 0; |
| 3366 | |||
| 3367 | p->open_fd[SUBPROCESS_STDIN] = inch; | ||
| 3341 | p->infd = inch; | 3368 | p->infd = inch; |
| 3342 | p->outfd = outch; | 3369 | p->outfd = outch; |
| 3370 | |||
| 3371 | /* Discard the unwind protect for closing S, if any. */ | ||
| 3372 | specpdl_ptr = specpdl + count1; | ||
| 3373 | |||
| 3374 | /* Unwind bind_polling_period and request_sigio. */ | ||
| 3375 | unbind_to (count, Qnil); | ||
| 3376 | |||
| 3343 | if (is_server && socktype != SOCK_DGRAM) | 3377 | if (is_server && socktype != SOCK_DGRAM) |
| 3344 | pset_status (p, Qlisten); | 3378 | pset_status (p, Qlisten); |
| 3345 | 3379 | ||
| @@ -3778,17 +3812,15 @@ FLAGS is the current flags of the interface. */) | |||
| 3778 | static void | 3812 | static void |
| 3779 | deactivate_process (Lisp_Object proc) | 3813 | deactivate_process (Lisp_Object proc) |
| 3780 | { | 3814 | { |
| 3781 | register int inchannel, outchannel; | 3815 | int inchannel; |
| 3782 | register struct Lisp_Process *p = XPROCESS (proc); | 3816 | struct Lisp_Process *p = XPROCESS (proc); |
| 3817 | int i; | ||
| 3783 | 3818 | ||
| 3784 | #ifdef HAVE_GNUTLS | 3819 | #ifdef HAVE_GNUTLS |
| 3785 | /* Delete GnuTLS structures in PROC, if any. */ | 3820 | /* Delete GnuTLS structures in PROC, if any. */ |
| 3786 | emacs_gnutls_deinit (proc); | 3821 | emacs_gnutls_deinit (proc); |
| 3787 | #endif /* HAVE_GNUTLS */ | 3822 | #endif /* HAVE_GNUTLS */ |
| 3788 | 3823 | ||
| 3789 | inchannel = p->infd; | ||
| 3790 | outchannel = p->outfd; | ||
| 3791 | |||
| 3792 | #ifdef ADAPTIVE_READ_BUFFERING | 3824 | #ifdef ADAPTIVE_READ_BUFFERING |
| 3793 | if (p->read_output_delay > 0) | 3825 | if (p->read_output_delay > 0) |
| 3794 | { | 3826 | { |
| @@ -3799,14 +3831,14 @@ deactivate_process (Lisp_Object proc) | |||
| 3799 | } | 3831 | } |
| 3800 | #endif | 3832 | #endif |
| 3801 | 3833 | ||
| 3834 | /* Beware SIGCHLD hereabouts. */ | ||
| 3835 | |||
| 3836 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | ||
| 3837 | close_process_fd (&p->open_fd[i]); | ||
| 3838 | |||
| 3839 | inchannel = p->infd; | ||
| 3802 | if (inchannel >= 0) | 3840 | if (inchannel >= 0) |
| 3803 | { | 3841 | { |
| 3804 | /* Beware SIGCHLD hereabouts. */ | ||
| 3805 | flush_pending_output (inchannel); | ||
| 3806 | emacs_close (inchannel); | ||
| 3807 | if (outchannel >= 0 && outchannel != inchannel) | ||
| 3808 | emacs_close (outchannel); | ||
| 3809 | |||
| 3810 | p->infd = -1; | 3842 | p->infd = -1; |
| 3811 | p->outfd = -1; | 3843 | p->outfd = -1; |
| 3812 | #ifdef DATAGRAM_SOCKETS | 3844 | #ifdef DATAGRAM_SOCKETS |
| @@ -3831,13 +3863,14 @@ deactivate_process (Lisp_Object proc) | |||
| 3831 | #endif | 3863 | #endif |
| 3832 | if (inchannel == max_process_desc) | 3864 | if (inchannel == max_process_desc) |
| 3833 | { | 3865 | { |
| 3834 | int i; | ||
| 3835 | /* We just closed the highest-numbered process input descriptor, | 3866 | /* We just closed the highest-numbered process input descriptor, |
| 3836 | so recompute the highest-numbered one now. */ | 3867 | so recompute the highest-numbered one now. */ |
| 3837 | max_process_desc = 0; | 3868 | int i = inchannel; |
| 3838 | for (i = 0; i < MAXDESC; i++) | 3869 | do |
| 3839 | if (!NILP (chan_process[i])) | 3870 | i--; |
| 3840 | max_process_desc = i; | 3871 | while (0 <= i && NILP (chan_process[i])); |
| 3872 | |||
| 3873 | max_process_desc = i; | ||
| 3841 | } | 3874 | } |
| 3842 | } | 3875 | } |
| 3843 | } | 3876 | } |
| @@ -3899,9 +3932,9 @@ Return non-nil if we received any output before the timeout expired. */) | |||
| 3899 | { | 3932 | { |
| 3900 | if (XFLOAT_DATA (seconds) > 0) | 3933 | if (XFLOAT_DATA (seconds) > 0) |
| 3901 | { | 3934 | { |
| 3902 | EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds)); | 3935 | struct timespec t = dtotimespec (XFLOAT_DATA (seconds)); |
| 3903 | secs = min (EMACS_SECS (t), WAIT_READING_MAX); | 3936 | secs = min (t.tv_sec, WAIT_READING_MAX); |
| 3904 | nsecs = EMACS_NSECS (t); | 3937 | nsecs = t.tv_nsec; |
| 3905 | } | 3938 | } |
| 3906 | } | 3939 | } |
| 3907 | else | 3940 | else |
| @@ -4088,6 +4121,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4088 | /* Discard the unwind protect for closing S. */ | 4121 | /* Discard the unwind protect for closing S. */ |
| 4089 | specpdl_ptr = specpdl + count; | 4122 | specpdl_ptr = specpdl + count; |
| 4090 | 4123 | ||
| 4124 | p->open_fd[SUBPROCESS_STDIN] = s; | ||
| 4091 | p->infd = s; | 4125 | p->infd = s; |
| 4092 | p->outfd = s; | 4126 | p->outfd = s; |
| 4093 | pset_status (p, Qrun); | 4127 | pset_status (p, Qrun); |
| @@ -4198,14 +4232,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4198 | struct Lisp_Process *wait_proc, int just_wait_proc) | 4232 | struct Lisp_Process *wait_proc, int just_wait_proc) |
| 4199 | { | 4233 | { |
| 4200 | int channel, nfds; | 4234 | int channel, nfds; |
| 4201 | SELECT_TYPE Available; | 4235 | fd_set Available; |
| 4202 | SELECT_TYPE Writeok; | 4236 | fd_set Writeok; |
| 4203 | bool check_write; | 4237 | bool check_write; |
| 4204 | int check_delay; | 4238 | int check_delay; |
| 4205 | bool no_avail; | 4239 | bool no_avail; |
| 4206 | int xerrno; | 4240 | int xerrno; |
| 4207 | Lisp_Object proc; | 4241 | Lisp_Object proc; |
| 4208 | EMACS_TIME timeout, end_time; | 4242 | struct timespec timeout, end_time; |
| 4209 | int wait_channel = -1; | 4243 | int wait_channel = -1; |
| 4210 | bool got_some_input = 0; | 4244 | bool got_some_input = 0; |
| 4211 | ptrdiff_t count = SPECPDL_INDEX (); | 4245 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -4238,8 +4272,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4238 | compute the absolute time to return at. */ | 4272 | compute the absolute time to return at. */ |
| 4239 | if (time_limit || nsecs > 0) | 4273 | if (time_limit || nsecs > 0) |
| 4240 | { | 4274 | { |
| 4241 | timeout = make_emacs_time (time_limit, nsecs); | 4275 | timeout = make_timespec (time_limit, nsecs); |
| 4242 | end_time = add_emacs_time (current_emacs_time (), timeout); | 4276 | end_time = timespec_add (current_timespec (), timeout); |
| 4243 | } | 4277 | } |
| 4244 | 4278 | ||
| 4245 | while (1) | 4279 | while (1) |
| @@ -4266,18 +4300,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4266 | gobble output available now | 4300 | gobble output available now |
| 4267 | but don't wait at all. */ | 4301 | but don't wait at all. */ |
| 4268 | 4302 | ||
| 4269 | timeout = make_emacs_time (0, 0); | 4303 | timeout = make_timespec (0, 0); |
| 4270 | } | 4304 | } |
| 4271 | else if (time_limit || nsecs > 0) | 4305 | else if (time_limit || nsecs > 0) |
| 4272 | { | 4306 | { |
| 4273 | EMACS_TIME now = current_emacs_time (); | 4307 | struct timespec now = current_timespec (); |
| 4274 | if (EMACS_TIME_LE (end_time, now)) | 4308 | if (timespec_cmp (end_time, now) <= 0) |
| 4275 | break; | 4309 | break; |
| 4276 | timeout = sub_emacs_time (end_time, now); | 4310 | timeout = timespec_sub (end_time, now); |
| 4277 | } | 4311 | } |
| 4278 | else | 4312 | else |
| 4279 | { | 4313 | { |
| 4280 | timeout = make_emacs_time (100000, 0); | 4314 | timeout = make_timespec (100000, 0); |
| 4281 | } | 4315 | } |
| 4282 | 4316 | ||
| 4283 | /* Normally we run timers here. | 4317 | /* Normally we run timers here. |
| @@ -4287,7 +4321,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4287 | if (NILP (wait_for_cell) | 4321 | if (NILP (wait_for_cell) |
| 4288 | && just_wait_proc >= 0) | 4322 | && just_wait_proc >= 0) |
| 4289 | { | 4323 | { |
| 4290 | EMACS_TIME timer_delay; | 4324 | struct timespec timer_delay; |
| 4291 | 4325 | ||
| 4292 | do | 4326 | do |
| 4293 | { | 4327 | { |
| @@ -4322,9 +4356,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4322 | /* A negative timeout means do not wait at all. */ | 4356 | /* A negative timeout means do not wait at all. */ |
| 4323 | if (nsecs >= 0) | 4357 | if (nsecs >= 0) |
| 4324 | { | 4358 | { |
| 4325 | if (EMACS_TIME_VALID_P (timer_delay)) | 4359 | if (timespec_valid_p (timer_delay)) |
| 4326 | { | 4360 | { |
| 4327 | if (EMACS_TIME_LT (timer_delay, timeout)) | 4361 | if (timespec_cmp (timer_delay, timeout) < 0) |
| 4328 | { | 4362 | { |
| 4329 | timeout = timer_delay; | 4363 | timeout = timer_delay; |
| 4330 | timeout_reduced_for_timers = 1; | 4364 | timeout_reduced_for_timers = 1; |
| @@ -4353,8 +4387,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4353 | timeout to get our attention. */ | 4387 | timeout to get our attention. */ |
| 4354 | if (update_tick != process_tick) | 4388 | if (update_tick != process_tick) |
| 4355 | { | 4389 | { |
| 4356 | SELECT_TYPE Atemp; | 4390 | fd_set Atemp; |
| 4357 | SELECT_TYPE Ctemp; | 4391 | fd_set Ctemp; |
| 4358 | 4392 | ||
| 4359 | if (kbd_on_hold_p ()) | 4393 | if (kbd_on_hold_p ()) |
| 4360 | FD_ZERO (&Atemp); | 4394 | FD_ZERO (&Atemp); |
| @@ -4362,7 +4396,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4362 | Atemp = input_wait_mask; | 4396 | Atemp = input_wait_mask; |
| 4363 | Ctemp = write_mask; | 4397 | Ctemp = write_mask; |
| 4364 | 4398 | ||
| 4365 | timeout = make_emacs_time (0, 0); | 4399 | timeout = make_timespec (0, 0); |
| 4366 | if ((pselect (max (max_process_desc, max_input_desc) + 1, | 4400 | if ((pselect (max (max_process_desc, max_input_desc) + 1, |
| 4367 | &Atemp, | 4401 | &Atemp, |
| 4368 | #ifdef NON_BLOCKING_CONNECT | 4402 | #ifdef NON_BLOCKING_CONNECT |
| @@ -4484,8 +4518,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4484 | Vprocess_adaptive_read_buffering is nil. */ | 4518 | Vprocess_adaptive_read_buffering is nil. */ |
| 4485 | if (process_output_skip && check_delay > 0) | 4519 | if (process_output_skip && check_delay > 0) |
| 4486 | { | 4520 | { |
| 4487 | int nsecs = EMACS_NSECS (timeout); | 4521 | int nsecs = timeout.tv_nsec; |
| 4488 | if (EMACS_SECS (timeout) > 0 || nsecs > READ_OUTPUT_DELAY_MAX) | 4522 | if (timeout.tv_sec > 0 || nsecs > READ_OUTPUT_DELAY_MAX) |
| 4489 | nsecs = READ_OUTPUT_DELAY_MAX; | 4523 | nsecs = READ_OUTPUT_DELAY_MAX; |
| 4490 | for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) | 4524 | for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) |
| 4491 | { | 4525 | { |
| @@ -4505,7 +4539,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4505 | nsecs = XPROCESS (proc)->read_output_delay; | 4539 | nsecs = XPROCESS (proc)->read_output_delay; |
| 4506 | } | 4540 | } |
| 4507 | } | 4541 | } |
| 4508 | timeout = make_emacs_time (0, nsecs); | 4542 | timeout = make_timespec (0, nsecs); |
| 4509 | process_output_skip = 0; | 4543 | process_output_skip = 0; |
| 4510 | } | 4544 | } |
| 4511 | #endif | 4545 | #endif |
| @@ -4519,7 +4553,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4519 | #endif | 4553 | #endif |
| 4520 | (max (max_process_desc, max_input_desc) + 1, | 4554 | (max (max_process_desc, max_input_desc) + 1, |
| 4521 | &Available, | 4555 | &Available, |
| 4522 | (check_write ? &Writeok : (SELECT_TYPE *)0), | 4556 | (check_write ? &Writeok : 0), |
| 4523 | NULL, &timeout, NULL); | 4557 | NULL, &timeout, NULL); |
| 4524 | 4558 | ||
| 4525 | #ifdef HAVE_GNUTLS | 4559 | #ifdef HAVE_GNUTLS |
| @@ -4537,7 +4571,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4537 | the gnutls library -- 2.12.14 has been confirmed | 4571 | the gnutls library -- 2.12.14 has been confirmed |
| 4538 | to need it. See | 4572 | to need it. See |
| 4539 | http://comments.gmane.org/gmane.emacs.devel/145074 */ | 4573 | http://comments.gmane.org/gmane.emacs.devel/145074 */ |
| 4540 | for (channel = 0; channel < MAXDESC; ++channel) | 4574 | for (channel = 0; channel < FD_SETSIZE; ++channel) |
| 4541 | if (! NILP (chan_process[channel])) | 4575 | if (! NILP (chan_process[channel])) |
| 4542 | { | 4576 | { |
| 4543 | struct Lisp_Process *p = | 4577 | struct Lisp_Process *p = |
| @@ -5144,15 +5178,10 @@ DEFUN ("internal-default-process-filter", Finternal_default_process_filter, | |||
| 5144 | 5178 | ||
| 5145 | bset_read_only (current_buffer, Qnil); | 5179 | bset_read_only (current_buffer, Qnil); |
| 5146 | 5180 | ||
| 5147 | /* Insert new output into buffer | 5181 | /* Insert new output into buffer at the current end-of-output |
| 5148 | at the current end-of-output marker, | 5182 | marker, thus preserving logical ordering of input and output. */ |
| 5149 | thus preserving logical ordering of input and output. */ | ||
| 5150 | if (XMARKER (p->mark)->buffer) | 5183 | if (XMARKER (p->mark)->buffer) |
| 5151 | SET_PT_BOTH (clip_to_bounds (BEGV, | 5184 | set_point_from_marker (p->mark); |
| 5152 | marker_position (p->mark), ZV), | ||
| 5153 | clip_to_bounds (BEGV_BYTE, | ||
| 5154 | marker_byte_position (p->mark), | ||
| 5155 | ZV_BYTE)); | ||
| 5156 | else | 5185 | else |
| 5157 | SET_PT_BOTH (ZV, ZV_BYTE); | 5186 | SET_PT_BOTH (ZV, ZV_BYTE); |
| 5158 | before = PT; | 5187 | before = PT; |
| @@ -5733,10 +5762,9 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5733 | return; | 5762 | return; |
| 5734 | } | 5763 | } |
| 5735 | 5764 | ||
| 5736 | switch (signo) | ||
| 5737 | { | ||
| 5738 | #ifdef SIGCONT | 5765 | #ifdef SIGCONT |
| 5739 | case SIGCONT: | 5766 | if (signo == SIGCONT) |
| 5767 | { | ||
| 5740 | p->raw_status_new = 0; | 5768 | p->raw_status_new = 0; |
| 5741 | pset_status (p, Qrun); | 5769 | pset_status (p, Qrun); |
| 5742 | p->tick = ++process_tick; | 5770 | p->tick = ++process_tick; |
| @@ -5745,14 +5773,8 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5745 | status_notify (NULL); | 5773 | status_notify (NULL); |
| 5746 | redisplay_preserve_echo_area (13); | 5774 | redisplay_preserve_echo_area (13); |
| 5747 | } | 5775 | } |
| 5748 | break; | ||
| 5749 | #endif /* ! defined (SIGCONT) */ | ||
| 5750 | case SIGINT: | ||
| 5751 | case SIGQUIT: | ||
| 5752 | case SIGKILL: | ||
| 5753 | flush_pending_output (p->infd); | ||
| 5754 | break; | ||
| 5755 | } | 5776 | } |
| 5777 | #endif | ||
| 5756 | 5778 | ||
| 5757 | /* If we don't have process groups, send the signal to the immediate | 5779 | /* If we don't have process groups, send the signal to the immediate |
| 5758 | subprocess. That isn't really right, but it's better than any | 5780 | subprocess. That isn't really right, but it's better than any |
| @@ -6007,7 +6029,8 @@ process has been transmitted to the serial port. */) | |||
| 6007 | } | 6029 | } |
| 6008 | else | 6030 | else |
| 6009 | { | 6031 | { |
| 6010 | int old_outfd, new_outfd; | 6032 | int old_outfd = XPROCESS (proc)->outfd; |
| 6033 | int new_outfd; | ||
| 6011 | 6034 | ||
| 6012 | #ifdef HAVE_SHUTDOWN | 6035 | #ifdef HAVE_SHUTDOWN |
| 6013 | /* If this is a network connection, or socketpair is used | 6036 | /* If this is a network connection, or socketpair is used |
| @@ -6015,18 +6038,15 @@ process has been transmitted to the serial port. */) | |||
| 6015 | (In some old system, shutdown to socketpair doesn't work. | 6038 | (In some old system, shutdown to socketpair doesn't work. |
| 6016 | Then we just can't win.) */ | 6039 | Then we just can't win.) */ |
| 6017 | if (EQ (XPROCESS (proc)->type, Qnetwork) | 6040 | if (EQ (XPROCESS (proc)->type, Qnetwork) |
| 6018 | || XPROCESS (proc)->outfd == XPROCESS (proc)->infd) | 6041 | || XPROCESS (proc)->infd == old_outfd) |
| 6019 | shutdown (XPROCESS (proc)->outfd, 1); | 6042 | shutdown (old_outfd, 1); |
| 6020 | /* In case of socketpair, outfd == infd, so don't close it. */ | 6043 | #endif |
| 6021 | if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd) | 6044 | close_process_fd (&XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS]); |
| 6022 | emacs_close (XPROCESS (proc)->outfd); | ||
| 6023 | #else /* not HAVE_SHUTDOWN */ | ||
| 6024 | emacs_close (XPROCESS (proc)->outfd); | ||
| 6025 | #endif /* not HAVE_SHUTDOWN */ | ||
| 6026 | new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 6045 | new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 6027 | if (new_outfd < 0) | 6046 | if (new_outfd < 0) |
| 6028 | emacs_abort (); | 6047 | report_file_error ("Opening null device", Qnil); |
| 6029 | old_outfd = XPROCESS (proc)->outfd; | 6048 | XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS] = new_outfd; |
| 6049 | XPROCESS (proc)->outfd = new_outfd; | ||
| 6030 | 6050 | ||
| 6031 | if (!proc_encode_coding_system[new_outfd]) | 6051 | if (!proc_encode_coding_system[new_outfd]) |
| 6032 | proc_encode_coding_system[new_outfd] | 6052 | proc_encode_coding_system[new_outfd] |
| @@ -6035,8 +6055,6 @@ process has been transmitted to the serial port. */) | |||
| 6035 | = *proc_encode_coding_system[old_outfd]; | 6055 | = *proc_encode_coding_system[old_outfd]; |
| 6036 | memset (proc_encode_coding_system[old_outfd], 0, | 6056 | memset (proc_encode_coding_system[old_outfd], 0, |
| 6037 | sizeof (struct coding_system)); | 6057 | sizeof (struct coding_system)); |
| 6038 | |||
| 6039 | XPROCESS (proc)->outfd = new_outfd; | ||
| 6040 | } | 6058 | } |
| 6041 | return process; | 6059 | return process; |
| 6042 | } | 6060 | } |
| @@ -6102,7 +6120,7 @@ static signal_handler_t volatile lib_child_handler; | |||
| 6102 | static void | 6120 | static void |
| 6103 | handle_child_signal (int sig) | 6121 | handle_child_signal (int sig) |
| 6104 | { | 6122 | { |
| 6105 | Lisp_Object tail; | 6123 | Lisp_Object tail, proc; |
| 6106 | 6124 | ||
| 6107 | /* Find the process that signaled us, and record its status. */ | 6125 | /* Find the process that signaled us, and record its status. */ |
| 6108 | 6126 | ||
| @@ -6113,7 +6131,11 @@ handle_child_signal (int sig) | |||
| 6113 | bool all_pids_are_fixnums | 6131 | bool all_pids_are_fixnums |
| 6114 | = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) | 6132 | = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) |
| 6115 | && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); | 6133 | && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); |
| 6116 | Lisp_Object xpid = XCAR (tail); | 6134 | Lisp_Object head = XCAR (tail); |
| 6135 | Lisp_Object xpid; | ||
| 6136 | if (! CONSP (head)) | ||
| 6137 | continue; | ||
| 6138 | xpid = XCAR (head); | ||
| 6117 | if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) | 6139 | if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) |
| 6118 | { | 6140 | { |
| 6119 | pid_t deleted_pid; | 6141 | pid_t deleted_pid; |
| @@ -6122,14 +6144,17 @@ handle_child_signal (int sig) | |||
| 6122 | else | 6144 | else |
| 6123 | deleted_pid = XFLOAT_DATA (xpid); | 6145 | deleted_pid = XFLOAT_DATA (xpid); |
| 6124 | if (child_status_changed (deleted_pid, 0, 0)) | 6146 | if (child_status_changed (deleted_pid, 0, 0)) |
| 6125 | XSETCAR (tail, Qnil); | 6147 | { |
| 6148 | if (STRINGP (XCDR (head))) | ||
| 6149 | unlink (SSDATA (XCDR (head))); | ||
| 6150 | XSETCAR (tail, Qnil); | ||
| 6151 | } | ||
| 6126 | } | 6152 | } |
| 6127 | } | 6153 | } |
| 6128 | 6154 | ||
| 6129 | /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ | 6155 | /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ |
| 6130 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 6156 | FOR_EACH_PROCESS (tail, proc) |
| 6131 | { | 6157 | { |
| 6132 | Lisp_Object proc = XCDR (XCAR (tail)); | ||
| 6133 | struct Lisp_Process *p = XPROCESS (proc); | 6158 | struct Lisp_Process *p = XPROCESS (proc); |
| 6134 | int status; | 6159 | int status; |
| 6135 | 6160 | ||
| @@ -6284,13 +6309,10 @@ status_notify (struct Lisp_Process *deleting_process) | |||
| 6284 | that we run, we get called again to handle their status changes. */ | 6309 | that we run, we get called again to handle their status changes. */ |
| 6285 | update_tick = process_tick; | 6310 | update_tick = process_tick; |
| 6286 | 6311 | ||
| 6287 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 6312 | FOR_EACH_PROCESS (tail, proc) |
| 6288 | { | 6313 | { |
| 6289 | Lisp_Object symbol; | 6314 | Lisp_Object symbol; |
| 6290 | register struct Lisp_Process *p; | 6315 | register struct Lisp_Process *p = XPROCESS (proc); |
| 6291 | |||
| 6292 | proc = Fcdr (XCAR (tail)); | ||
| 6293 | p = XPROCESS (proc); | ||
| 6294 | 6316 | ||
| 6295 | if (p->tick != p->update_tick) | 6317 | if (p->tick != p->update_tick) |
| 6296 | { | 6318 | { |
| @@ -6515,8 +6537,8 @@ keyboard_bit_set (fd_set *mask) | |||
| 6515 | #else /* not subprocesses */ | 6537 | #else /* not subprocesses */ |
| 6516 | 6538 | ||
| 6517 | /* Defined on msdos.c. */ | 6539 | /* Defined on msdos.c. */ |
| 6518 | extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | 6540 | extern int sys_select (int, fd_set *, fd_set *, fd_set *, |
| 6519 | EMACS_TIME *, void *); | 6541 | struct timespec *, void *); |
| 6520 | 6542 | ||
| 6521 | /* Implementation of wait_reading_process_output, assuming that there | 6543 | /* Implementation of wait_reading_process_output, assuming that there |
| 6522 | are no subprocesses. Used only by the MS-DOS build. | 6544 | are no subprocesses. Used only by the MS-DOS build. |
| @@ -6555,7 +6577,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6555 | struct Lisp_Process *wait_proc, int just_wait_proc) | 6577 | struct Lisp_Process *wait_proc, int just_wait_proc) |
| 6556 | { | 6578 | { |
| 6557 | register int nfds; | 6579 | register int nfds; |
| 6558 | EMACS_TIME end_time, timeout; | 6580 | struct timespec end_time, timeout; |
| 6559 | 6581 | ||
| 6560 | if (time_limit < 0) | 6582 | if (time_limit < 0) |
| 6561 | { | 6583 | { |
| @@ -6568,8 +6590,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6568 | /* What does time_limit really mean? */ | 6590 | /* What does time_limit really mean? */ |
| 6569 | if (time_limit || nsecs > 0) | 6591 | if (time_limit || nsecs > 0) |
| 6570 | { | 6592 | { |
| 6571 | timeout = make_emacs_time (time_limit, nsecs); | 6593 | timeout = make_timespec (time_limit, nsecs); |
| 6572 | end_time = add_emacs_time (current_emacs_time (), timeout); | 6594 | end_time = timespec_add (current_timespec (), timeout); |
| 6573 | } | 6595 | } |
| 6574 | 6596 | ||
| 6575 | /* Turn off periodic alarms (in case they are in use) | 6597 | /* Turn off periodic alarms (in case they are in use) |
| @@ -6581,7 +6603,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6581 | while (1) | 6603 | while (1) |
| 6582 | { | 6604 | { |
| 6583 | bool timeout_reduced_for_timers = 0; | 6605 | bool timeout_reduced_for_timers = 0; |
| 6584 | SELECT_TYPE waitchannels; | 6606 | fd_set waitchannels; |
| 6585 | int xerrno; | 6607 | int xerrno; |
| 6586 | 6608 | ||
| 6587 | /* If calling from keyboard input, do not quit | 6609 | /* If calling from keyboard input, do not quit |
| @@ -6602,18 +6624,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6602 | gobble output available now | 6624 | gobble output available now |
| 6603 | but don't wait at all. */ | 6625 | but don't wait at all. */ |
| 6604 | 6626 | ||
| 6605 | timeout = make_emacs_time (0, 0); | 6627 | timeout = make_timespec (0, 0); |
| 6606 | } | 6628 | } |
| 6607 | else if (time_limit || nsecs > 0) | 6629 | else if (time_limit || nsecs > 0) |
| 6608 | { | 6630 | { |
| 6609 | EMACS_TIME now = current_emacs_time (); | 6631 | struct timespec now = current_timespec (); |
| 6610 | if (EMACS_TIME_LE (end_time, now)) | 6632 | if (timespec_cmp (end_time, now) <= 0) |
| 6611 | break; | 6633 | break; |
| 6612 | timeout = sub_emacs_time (end_time, now); | 6634 | timeout = timespec_sub (end_time, now); |
| 6613 | } | 6635 | } |
| 6614 | else | 6636 | else |
| 6615 | { | 6637 | { |
| 6616 | timeout = make_emacs_time (100000, 0); | 6638 | timeout = make_timespec (100000, 0); |
| 6617 | } | 6639 | } |
| 6618 | 6640 | ||
| 6619 | /* If our caller will not immediately handle keyboard events, | 6641 | /* If our caller will not immediately handle keyboard events, |
| @@ -6622,7 +6644,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6622 | call timer_delay on their own.) */ | 6644 | call timer_delay on their own.) */ |
| 6623 | if (NILP (wait_for_cell)) | 6645 | if (NILP (wait_for_cell)) |
| 6624 | { | 6646 | { |
| 6625 | EMACS_TIME timer_delay; | 6647 | struct timespec timer_delay; |
| 6626 | 6648 | ||
| 6627 | do | 6649 | do |
| 6628 | { | 6650 | { |
| @@ -6642,9 +6664,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 6642 | && requeued_events_pending_p ()) | 6664 | && requeued_events_pending_p ()) |
| 6643 | break; | 6665 | break; |
| 6644 | 6666 | ||
| 6645 | if (EMACS_TIME_VALID_P (timer_delay) && nsecs >= 0) | 6667 | if (timespec_valid_p (timer_delay) && nsecs >= 0) |
| 6646 | { | 6668 | { |
| 6647 | if (EMACS_TIME_LT (timer_delay, timeout)) | 6669 | if (timespec_cmp (timer_delay, timeout) < 0) |
| 6648 | { | 6670 | { |
| 6649 | timeout = timer_delay; | 6671 | timeout = timer_delay; |
| 6650 | timeout_reduced_for_timers = 1; | 6672 | timeout_reduced_for_timers = 1; |
| @@ -6763,16 +6785,9 @@ void | |||
| 6763 | delete_keyboard_wait_descriptor (int desc) | 6785 | delete_keyboard_wait_descriptor (int desc) |
| 6764 | { | 6786 | { |
| 6765 | #ifdef subprocesses | 6787 | #ifdef subprocesses |
| 6766 | int fd; | ||
| 6767 | int lim = max_input_desc; | ||
| 6768 | |||
| 6769 | FD_CLR (desc, &input_wait_mask); | 6788 | FD_CLR (desc, &input_wait_mask); |
| 6770 | FD_CLR (desc, &non_process_wait_mask); | 6789 | FD_CLR (desc, &non_process_wait_mask); |
| 6771 | 6790 | delete_input_desc (desc); | |
| 6772 | if (desc == max_input_desc) | ||
| 6773 | for (fd = 0; fd < lim; fd++) | ||
| 6774 | if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) | ||
| 6775 | max_input_desc = fd; | ||
| 6776 | #endif | 6791 | #endif |
| 6777 | } | 6792 | } |
| 6778 | 6793 | ||
| @@ -6820,12 +6835,9 @@ BUFFER may be a buffer or the name of one. */) | |||
| 6820 | buf = Fget_buffer (buffer); | 6835 | buf = Fget_buffer (buffer); |
| 6821 | if (NILP (buf)) return Qnil; | 6836 | if (NILP (buf)) return Qnil; |
| 6822 | 6837 | ||
| 6823 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 6838 | FOR_EACH_PROCESS (tail, proc) |
| 6824 | { | 6839 | if (EQ (XPROCESS (proc)->buffer, buf)) |
| 6825 | proc = Fcdr (XCAR (tail)); | 6840 | return proc; |
| 6826 | if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf)) | ||
| 6827 | return proc; | ||
| 6828 | } | ||
| 6829 | #endif /* subprocesses */ | 6841 | #endif /* subprocesses */ |
| 6830 | return Qnil; | 6842 | return Qnil; |
| 6831 | } | 6843 | } |
| @@ -6858,18 +6870,14 @@ kill_buffer_processes (Lisp_Object buffer) | |||
| 6858 | #ifdef subprocesses | 6870 | #ifdef subprocesses |
| 6859 | Lisp_Object tail, proc; | 6871 | Lisp_Object tail, proc; |
| 6860 | 6872 | ||
| 6861 | for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) | 6873 | FOR_EACH_PROCESS (tail, proc) |
| 6862 | { | 6874 | if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) |
| 6863 | proc = XCDR (XCAR (tail)); | 6875 | { |
| 6864 | if (PROCESSP (proc) | 6876 | if (NETCONN_P (proc) || SERIALCONN_P (proc)) |
| 6865 | && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) | 6877 | Fdelete_process (proc); |
| 6866 | { | 6878 | else if (XPROCESS (proc)->infd >= 0) |
| 6867 | if (NETCONN_P (proc) || SERIALCONN_P (proc)) | 6879 | process_send_signal (proc, SIGHUP, Qnil, 1); |
| 6868 | Fdelete_process (proc); | 6880 | } |
| 6869 | else if (XPROCESS (proc)->infd >= 0) | ||
| 6870 | process_send_signal (proc, SIGHUP, Qnil, 1); | ||
| 6871 | } | ||
| 6872 | } | ||
| 6873 | #else /* subprocesses */ | 6881 | #else /* subprocesses */ |
| 6874 | /* Since we have no subprocesses, this does nothing. */ | 6882 | /* Since we have no subprocesses, this does nothing. */ |
| 6875 | #endif /* subprocesses */ | 6883 | #endif /* subprocesses */ |
| @@ -7037,7 +7045,7 @@ init_process_emacs (void) | |||
| 7037 | FD_ZERO (&non_keyboard_wait_mask); | 7045 | FD_ZERO (&non_keyboard_wait_mask); |
| 7038 | FD_ZERO (&non_process_wait_mask); | 7046 | FD_ZERO (&non_process_wait_mask); |
| 7039 | FD_ZERO (&write_mask); | 7047 | FD_ZERO (&write_mask); |
| 7040 | max_process_desc = 0; | 7048 | max_process_desc = max_input_desc = -1; |
| 7041 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); | 7049 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); |
| 7042 | 7050 | ||
| 7043 | #ifdef NON_BLOCKING_CONNECT | 7051 | #ifdef NON_BLOCKING_CONNECT |
| @@ -7059,7 +7067,7 @@ init_process_emacs (void) | |||
| 7059 | 7067 | ||
| 7060 | Vprocess_alist = Qnil; | 7068 | Vprocess_alist = Qnil; |
| 7061 | deleted_pid_list = Qnil; | 7069 | deleted_pid_list = Qnil; |
| 7062 | for (i = 0; i < MAXDESC; i++) | 7070 | for (i = 0; i < FD_SETSIZE; i++) |
| 7063 | { | 7071 | { |
| 7064 | chan_process[i] = Qnil; | 7072 | chan_process[i] = Qnil; |
| 7065 | proc_buffered_char[i] = -1; | 7073 | proc_buffered_char[i] = -1; |
diff --git a/src/process.h b/src/process.h index 8ae33aebf39..6aff95686a2 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -31,6 +31,11 @@ INLINE_HEADER_BEGIN | |||
| 31 | # define PROCESS_INLINE INLINE | 31 | # define PROCESS_INLINE INLINE |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | /* Bound on number of file descriptors opened on behalf of a process, | ||
| 35 | that need to be closed. */ | ||
| 36 | |||
| 37 | enum { PROCESS_OPEN_FDS = 6 }; | ||
| 38 | |||
| 34 | /* This structure records information about a subprocess | 39 | /* This structure records information about a subprocess |
| 35 | or network connection. */ | 40 | or network connection. */ |
| 36 | 41 | ||
| @@ -115,6 +120,9 @@ struct Lisp_Process | |||
| 115 | int infd; | 120 | int infd; |
| 116 | /* Descriptor by which we write to this process */ | 121 | /* Descriptor by which we write to this process */ |
| 117 | int outfd; | 122 | int outfd; |
| 123 | /* Descriptors that were created for this process and that need | ||
| 124 | closing. Unused entries are negative. */ | ||
| 125 | int open_fd[PROCESS_OPEN_FDS]; | ||
| 118 | /* Event-count of last event in which this process changed status. */ | 126 | /* Event-count of last event in which this process changed status. */ |
| 119 | EMACS_INT tick; | 127 | EMACS_INT tick; |
| 120 | /* Event-count of last such event reported. */ | 128 | /* Event-count of last such event reported. */ |
| @@ -210,13 +218,17 @@ enum | |||
| 210 | 218 | ||
| 211 | extern void block_child_signal (void); | 219 | extern void block_child_signal (void); |
| 212 | extern void unblock_child_signal (void); | 220 | extern void unblock_child_signal (void); |
| 213 | extern void record_kill_process (struct Lisp_Process *); | 221 | extern Lisp_Object encode_current_directory (void); |
| 222 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); | ||
| 214 | 223 | ||
| 215 | /* Defined in process.c. */ | 224 | /* Defined in sysdep.c. */ |
| 216 | 225 | ||
| 217 | extern Lisp_Object list_system_processes (void); | 226 | extern Lisp_Object list_system_processes (void); |
| 218 | extern Lisp_Object system_process_attributes (Lisp_Object); | 227 | extern Lisp_Object system_process_attributes (Lisp_Object); |
| 219 | 228 | ||
| 229 | /* Defined in process.c. */ | ||
| 230 | |||
| 231 | extern void record_deleted_pid (pid_t, Lisp_Object); | ||
| 220 | extern void hold_keyboard_input (void); | 232 | extern void hold_keyboard_input (void); |
| 221 | extern void unhold_keyboard_input (void); | 233 | extern void unhold_keyboard_input (void); |
| 222 | extern bool kbd_on_hold_p (void); | 234 | extern bool kbd_on_hold_p (void); |
diff --git a/src/profiler.c b/src/profiler.c index c86fb47d21d..64eb5cafc25 100644 --- a/src/profiler.c +++ b/src/profiler.c | |||
| @@ -267,8 +267,8 @@ setup_cpu_timer (Lisp_Object sampling_interval) | |||
| 267 | return NOT_RUNNING; | 267 | return NOT_RUNNING; |
| 268 | 268 | ||
| 269 | current_sampling_interval = XINT (sampling_interval); | 269 | current_sampling_interval = XINT (sampling_interval); |
| 270 | interval = make_emacs_time (current_sampling_interval / billion, | 270 | interval = make_timespec (current_sampling_interval / billion, |
| 271 | current_sampling_interval % billion); | 271 | current_sampling_interval % billion); |
| 272 | emacs_sigaction_init (&action, deliver_profiler_signal); | 272 | emacs_sigaction_init (&action, deliver_profiler_signal); |
| 273 | sigaction (SIGPROF, &action, 0); | 273 | sigaction (SIGPROF, &action, 0); |
| 274 | 274 | ||
diff --git a/src/regex.c b/src/regex.c index 39adb080efd..1befececd22 100644 --- a/src/regex.c +++ b/src/regex.c | |||
| @@ -257,15 +257,10 @@ xrealloc (void *block, size_t size) | |||
| 257 | enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 }; | 257 | enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 }; |
| 258 | 258 | ||
| 259 | /* Dummy macros for non-Emacs environments. */ | 259 | /* Dummy macros for non-Emacs environments. */ |
| 260 | # define CHAR_CHARSET(c) 0 | ||
| 261 | # define CHARSET_LEADING_CODE_BASE(c) 0 | ||
| 262 | # define MAX_MULTIBYTE_LENGTH 1 | 260 | # define MAX_MULTIBYTE_LENGTH 1 |
| 263 | # define RE_MULTIBYTE_P(x) 0 | 261 | # define RE_MULTIBYTE_P(x) 0 |
| 264 | # define RE_TARGET_MULTIBYTE_P(x) 0 | 262 | # define RE_TARGET_MULTIBYTE_P(x) 0 |
| 265 | # define WORD_BOUNDARY_P(c1, c2) (0) | 263 | # define WORD_BOUNDARY_P(c1, c2) (0) |
| 266 | # define CHAR_HEAD_P(p) (1) | ||
| 267 | # define SINGLE_BYTE_CHAR_P(c) (1) | ||
| 268 | # define SAME_CHARSET_P(c1, c2) (1) | ||
| 269 | # define BYTES_BY_CHAR_HEAD(p) (1) | 264 | # define BYTES_BY_CHAR_HEAD(p) (1) |
| 270 | # define PREV_CHAR_BOUNDARY(p, limit) ((p)--) | 265 | # define PREV_CHAR_BOUNDARY(p, limit) ((p)--) |
| 271 | # define STRING_CHAR(p) (*(p)) | 266 | # define STRING_CHAR(p) (*(p)) |
| @@ -279,8 +274,6 @@ enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 }; | |||
| 279 | (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1))) | 274 | (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1))) |
| 280 | # define GET_CHAR_AFTER(c, p, len) \ | 275 | # define GET_CHAR_AFTER(c, p, len) \ |
| 281 | (c = *p, len = 1) | 276 | (c = *p, len = 1) |
| 282 | # define MAKE_CHAR(charset, c1, c2) (c1) | ||
| 283 | # define BYTE8_TO_CHAR(c) (c) | ||
| 284 | # define CHAR_BYTE8_P(c) (0) | 277 | # define CHAR_BYTE8_P(c) (0) |
| 285 | # define CHAR_LEADING_CODE(c) (c) | 278 | # define CHAR_LEADING_CODE(c) (c) |
| 286 | 279 | ||
| @@ -468,7 +461,7 @@ init_syntax_once (void) | |||
| 468 | 461 | ||
| 469 | /* Assumes a `char *destination' variable. */ | 462 | /* Assumes a `char *destination' variable. */ |
| 470 | # define REGEX_REALLOCATE(source, osize, nsize) \ | 463 | # define REGEX_REALLOCATE(source, osize, nsize) \ |
| 471 | (destination = (char *) alloca (nsize), \ | 464 | (destination = alloca (nsize), \ |
| 472 | memcpy (destination, source, osize)) | 465 | memcpy (destination, source, osize)) |
| 473 | 466 | ||
| 474 | /* No need to do anything to free, after alloca. */ | 467 | /* No need to do anything to free, after alloca. */ |
| @@ -775,10 +768,12 @@ extract_number_and_incr (re_char **source) | |||
| 775 | and the 2 bytes of flags at the start of the range table. */ | 768 | and the 2 bytes of flags at the start of the range table. */ |
| 776 | #define CHARSET_RANGE_TABLE(p) (&(p)[4 + CHARSET_BITMAP_SIZE (p)]) | 769 | #define CHARSET_RANGE_TABLE(p) (&(p)[4 + CHARSET_BITMAP_SIZE (p)]) |
| 777 | 770 | ||
| 771 | #ifdef emacs | ||
| 778 | /* Extract the bit flags that start a range table. */ | 772 | /* Extract the bit flags that start a range table. */ |
| 779 | #define CHARSET_RANGE_TABLE_BITS(p) \ | 773 | #define CHARSET_RANGE_TABLE_BITS(p) \ |
| 780 | ((p)[2 + CHARSET_BITMAP_SIZE (p)] \ | 774 | ((p)[2 + CHARSET_BITMAP_SIZE (p)] \ |
| 781 | + (p)[3 + CHARSET_BITMAP_SIZE (p)] * 0x100) | 775 | + (p)[3 + CHARSET_BITMAP_SIZE (p)] * 0x100) |
| 776 | #endif | ||
| 782 | 777 | ||
| 783 | /* Return the address of end of RANGE_TABLE. COUNT is number of | 778 | /* Return the address of end of RANGE_TABLE. COUNT is number of |
| 784 | ranges (which is a pair of (start, end)) in the RANGE_TABLE. `* 2' | 779 | ranges (which is a pair of (start, end)) in the RANGE_TABLE. `* 2' |
| @@ -1238,12 +1233,12 @@ re_set_syntax (reg_syntax_t syntax) | |||
| 1238 | WEAK_ALIAS (__re_set_syntax, re_set_syntax) | 1233 | WEAK_ALIAS (__re_set_syntax, re_set_syntax) |
| 1239 | 1234 | ||
| 1240 | /* Regexp to use to replace spaces, or NULL meaning don't. */ | 1235 | /* Regexp to use to replace spaces, or NULL meaning don't. */ |
| 1241 | static re_char *whitespace_regexp; | 1236 | static const_re_char *whitespace_regexp; |
| 1242 | 1237 | ||
| 1243 | void | 1238 | void |
| 1244 | re_set_whitespace_regexp (const char *regexp) | 1239 | re_set_whitespace_regexp (const char *regexp) |
| 1245 | { | 1240 | { |
| 1246 | whitespace_regexp = (re_char *) regexp; | 1241 | whitespace_regexp = (const_re_char *) regexp; |
| 1247 | } | 1242 | } |
| 1248 | WEAK_ALIAS (__re_set_syntax, re_set_syntax) | 1243 | WEAK_ALIAS (__re_set_syntax, re_set_syntax) |
| 1249 | 1244 | ||
| @@ -1830,6 +1825,8 @@ struct range_table_work_area | |||
| 1830 | int bits; /* flag to record character classes */ | 1825 | int bits; /* flag to record character classes */ |
| 1831 | }; | 1826 | }; |
| 1832 | 1827 | ||
| 1828 | #ifdef emacs | ||
| 1829 | |||
| 1833 | /* Make sure that WORK_AREA can hold more N multibyte characters. | 1830 | /* Make sure that WORK_AREA can hold more N multibyte characters. |
| 1834 | This is used only in set_image_of_range and set_image_of_range_1. | 1831 | This is used only in set_image_of_range and set_image_of_range_1. |
| 1835 | It expects WORK_AREA to be a pointer. | 1832 | It expects WORK_AREA to be a pointer. |
| @@ -1848,15 +1845,6 @@ struct range_table_work_area | |||
| 1848 | #define SET_RANGE_TABLE_WORK_AREA_BIT(work_area, bit) \ | 1845 | #define SET_RANGE_TABLE_WORK_AREA_BIT(work_area, bit) \ |
| 1849 | (work_area).bits |= (bit) | 1846 | (work_area).bits |= (bit) |
| 1850 | 1847 | ||
| 1851 | /* Bits used to implement the multibyte-part of the various character classes | ||
| 1852 | such as [:alnum:] in a charset's range table. */ | ||
| 1853 | #define BIT_WORD 0x1 | ||
| 1854 | #define BIT_LOWER 0x2 | ||
| 1855 | #define BIT_PUNCT 0x4 | ||
| 1856 | #define BIT_SPACE 0x8 | ||
| 1857 | #define BIT_UPPER 0x10 | ||
| 1858 | #define BIT_MULTIBYTE 0x20 | ||
| 1859 | |||
| 1860 | /* Set a range (RANGE_START, RANGE_END) to WORK_AREA. */ | 1848 | /* Set a range (RANGE_START, RANGE_END) to WORK_AREA. */ |
| 1861 | #define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end) \ | 1849 | #define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end) \ |
| 1862 | do { \ | 1850 | do { \ |
| @@ -1865,6 +1853,8 @@ struct range_table_work_area | |||
| 1865 | (work_area).table[(work_area).used++] = (range_end); \ | 1853 | (work_area).table[(work_area).used++] = (range_end); \ |
| 1866 | } while (0) | 1854 | } while (0) |
| 1867 | 1855 | ||
| 1856 | #endif /* emacs */ | ||
| 1857 | |||
| 1868 | /* Free allocated memory for WORK_AREA. */ | 1858 | /* Free allocated memory for WORK_AREA. */ |
| 1869 | #define FREE_RANGE_TABLE_WORK_AREA(work_area) \ | 1859 | #define FREE_RANGE_TABLE_WORK_AREA(work_area) \ |
| 1870 | do { \ | 1860 | do { \ |
| @@ -1876,6 +1866,15 @@ struct range_table_work_area | |||
| 1876 | #define RANGE_TABLE_WORK_USED(work_area) ((work_area).used) | 1866 | #define RANGE_TABLE_WORK_USED(work_area) ((work_area).used) |
| 1877 | #define RANGE_TABLE_WORK_BITS(work_area) ((work_area).bits) | 1867 | #define RANGE_TABLE_WORK_BITS(work_area) ((work_area).bits) |
| 1878 | #define RANGE_TABLE_WORK_ELT(work_area, i) ((work_area).table[i]) | 1868 | #define RANGE_TABLE_WORK_ELT(work_area, i) ((work_area).table[i]) |
| 1869 | |||
| 1870 | /* Bits used to implement the multibyte-part of the various character classes | ||
| 1871 | such as [:alnum:] in a charset's range table. */ | ||
| 1872 | #define BIT_WORD 0x1 | ||
| 1873 | #define BIT_LOWER 0x2 | ||
| 1874 | #define BIT_PUNCT 0x4 | ||
| 1875 | #define BIT_SPACE 0x8 | ||
| 1876 | #define BIT_UPPER 0x10 | ||
| 1877 | #define BIT_MULTIBYTE 0x20 | ||
| 1879 | 1878 | ||
| 1880 | 1879 | ||
| 1881 | /* Set the bit for character C in a list. */ | 1880 | /* Set the bit for character C in a list. */ |
| @@ -4208,7 +4207,7 @@ re_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs, uns | |||
| 4208 | { | 4207 | { |
| 4209 | bufp->regs_allocated = REGS_UNALLOCATED; | 4208 | bufp->regs_allocated = REGS_UNALLOCATED; |
| 4210 | regs->num_regs = 0; | 4209 | regs->num_regs = 0; |
| 4211 | regs->start = regs->end = (regoff_t *) 0; | 4210 | regs->start = regs->end = 0; |
| 4212 | } | 4211 | } |
| 4213 | } | 4212 | } |
| 4214 | WEAK_ALIAS (__re_set_registers, re_set_registers) | 4213 | WEAK_ALIAS (__re_set_registers, re_set_registers) |
| @@ -6395,8 +6394,7 @@ weak_function | |||
| 6395 | re_exec (const char *s) | 6394 | re_exec (const char *s) |
| 6396 | { | 6395 | { |
| 6397 | const size_t len = strlen (s); | 6396 | const size_t len = strlen (s); |
| 6398 | return (re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0) | 6397 | return re_search (&re_comp_buf, s, len, 0, len, 0) >= 0; |
| 6399 | >= 0); | ||
| 6400 | } | 6398 | } |
| 6401 | #endif /* _REGEX_RE_COMP */ | 6399 | #endif /* _REGEX_RE_COMP */ |
| 6402 | 6400 | ||
| @@ -6560,7 +6558,7 @@ regexec (const regex_t *_Restrict_ preg, const char *_Restrict_ string, | |||
| 6560 | /* Perform the searching operation. */ | 6558 | /* Perform the searching operation. */ |
| 6561 | ret = re_search (&private_preg, string, len, | 6559 | ret = re_search (&private_preg, string, len, |
| 6562 | /* start: */ 0, /* range: */ len, | 6560 | /* start: */ 0, /* range: */ len, |
| 6563 | want_reg_info ? ®s : (struct re_registers *) 0); | 6561 | want_reg_info ? ®s : 0); |
| 6564 | 6562 | ||
| 6565 | /* Copy the register information to the POSIX structure. */ | 6563 | /* Copy the register information to the POSIX structure. */ |
| 6566 | if (want_reg_info) | 6564 | if (want_reg_info) |
diff --git a/src/scroll.c b/src/scroll.c index 3e296068e8f..b9ed8c04ba8 100644 --- a/src/scroll.c +++ b/src/scroll.c | |||
| @@ -652,8 +652,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix, | |||
| 652 | 652 | ||
| 653 | /* A queue of deletions and insertions to be performed. */ | 653 | /* A queue of deletions and insertions to be performed. */ |
| 654 | struct alt_queue { int count, pos, window; }; | 654 | struct alt_queue { int count, pos, window; }; |
| 655 | struct alt_queue *queue_start = (struct alt_queue *) | 655 | struct alt_queue *queue_start = alloca (window_size * sizeof *queue_start); |
| 656 | alloca (window_size * sizeof *queue_start); | ||
| 657 | struct alt_queue *queue = queue_start; | 656 | struct alt_queue *queue = queue_start; |
| 658 | 657 | ||
| 659 | /* True if a terminal window has been set with set_terminal_window. */ | 658 | /* True if a terminal window has been set with set_terminal_window. */ |
| @@ -797,9 +796,8 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top, | |||
| 797 | int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, | 796 | int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, |
| 798 | int *old_hash, int *new_hash, int free_at_end) | 797 | int *old_hash, int *new_hash, int free_at_end) |
| 799 | { | 798 | { |
| 800 | struct matrix_elt *matrix; | 799 | struct matrix_elt *matrix |
| 801 | matrix = ((struct matrix_elt *) | 800 | = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix); |
| 802 | alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix)); | ||
| 803 | 801 | ||
| 804 | if (FRAME_SCROLL_REGION_OK (frame)) | 802 | if (FRAME_SCROLL_REGION_OK (frame)) |
| 805 | { | 803 | { |
diff --git a/src/search.c b/src/search.c index 0f4d41586a3..99e8d2501fe 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -598,14 +598,14 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 598 | 598 | ||
| 599 | /* The newline cache: remembering which sections of text have no newlines. */ | 599 | /* The newline cache: remembering which sections of text have no newlines. */ |
| 600 | 600 | ||
| 601 | /* If the user has requested newline caching, make sure it's on. | 601 | /* If the user has requested the long scans caching, make sure it's on. |
| 602 | Otherwise, make sure it's off. | 602 | Otherwise, make sure it's off. |
| 603 | This is our cheezy way of associating an action with the change of | 603 | This is our cheezy way of associating an action with the change of |
| 604 | state of a buffer-local variable. */ | 604 | state of a buffer-local variable. */ |
| 605 | static void | 605 | static void |
| 606 | newline_cache_on_off (struct buffer *buf) | 606 | newline_cache_on_off (struct buffer *buf) |
| 607 | { | 607 | { |
| 608 | if (NILP (BVAR (buf, cache_long_line_scans))) | 608 | if (NILP (BVAR (buf, cache_long_scans))) |
| 609 | { | 609 | { |
| 610 | /* It should be off. */ | 610 | /* It should be off. */ |
| 611 | if (buf->newline_cache) | 611 | if (buf->newline_cache) |
| @@ -859,88 +859,20 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 859 | If ALLOW_QUIT, set immediate_quit. That's good to do | 859 | If ALLOW_QUIT, set immediate_quit. That's good to do |
| 860 | except in special cases. */ | 860 | except in special cases. */ |
| 861 | 861 | ||
| 862 | EMACS_INT | 862 | ptrdiff_t |
| 863 | scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | 863 | scan_newline (ptrdiff_t start, ptrdiff_t start_byte, |
| 864 | ptrdiff_t limit, ptrdiff_t limit_byte, | 864 | ptrdiff_t limit, ptrdiff_t limit_byte, |
| 865 | EMACS_INT count, bool allow_quit) | 865 | ptrdiff_t count, bool allow_quit) |
| 866 | { | 866 | { |
| 867 | int direction = ((count > 0) ? 1 : -1); | 867 | ptrdiff_t charpos, bytepos, shortage; |
| 868 | |||
| 869 | unsigned char *cursor; | ||
| 870 | unsigned char *base; | ||
| 871 | |||
| 872 | ptrdiff_t ceiling; | ||
| 873 | unsigned char *ceiling_addr; | ||
| 874 | |||
| 875 | bool old_immediate_quit = immediate_quit; | ||
| 876 | |||
| 877 | if (allow_quit) | ||
| 878 | immediate_quit++; | ||
| 879 | 868 | ||
| 880 | if (count > 0) | 869 | charpos = find_newline (start, start_byte, limit, limit_byte, |
| 881 | { | 870 | count, &shortage, &bytepos, allow_quit); |
| 882 | while (start_byte < limit_byte) | 871 | if (shortage) |
| 883 | { | 872 | TEMP_SET_PT_BOTH (limit, limit_byte); |
| 884 | ceiling = BUFFER_CEILING_OF (start_byte); | ||
| 885 | ceiling = min (limit_byte - 1, ceiling); | ||
| 886 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; | ||
| 887 | base = (cursor = BYTE_POS_ADDR (start_byte)); | ||
| 888 | |||
| 889 | do | ||
| 890 | { | ||
| 891 | unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); | ||
| 892 | if (! nl) | ||
| 893 | break; | ||
| 894 | if (--count == 0) | ||
| 895 | { | ||
| 896 | immediate_quit = old_immediate_quit; | ||
| 897 | start_byte += nl - base + 1; | ||
| 898 | start = BYTE_TO_CHAR (start_byte); | ||
| 899 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 900 | return 0; | ||
| 901 | } | ||
| 902 | cursor = nl + 1; | ||
| 903 | } | ||
| 904 | while (cursor < ceiling_addr); | ||
| 905 | |||
| 906 | start_byte += ceiling_addr - base; | ||
| 907 | } | ||
| 908 | } | ||
| 909 | else | 873 | else |
| 910 | { | 874 | TEMP_SET_PT_BOTH (charpos, bytepos); |
| 911 | while (start_byte > limit_byte) | 875 | return shortage; |
| 912 | { | ||
| 913 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); | ||
| 914 | ceiling = max (limit_byte, ceiling); | ||
| 915 | ceiling_addr = BYTE_POS_ADDR (ceiling); | ||
| 916 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); | ||
| 917 | while (1) | ||
| 918 | { | ||
| 919 | unsigned char *nl = memrchr (ceiling_addr, '\n', | ||
| 920 | cursor - ceiling_addr); | ||
| 921 | if (! nl) | ||
| 922 | break; | ||
| 923 | |||
| 924 | if (++count == 0) | ||
| 925 | { | ||
| 926 | immediate_quit = old_immediate_quit; | ||
| 927 | /* Return the position AFTER the match we found. */ | ||
| 928 | start_byte += nl - base + 1; | ||
| 929 | start = BYTE_TO_CHAR (start_byte); | ||
| 930 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | cursor = nl; | ||
| 935 | } | ||
| 936 | start_byte += ceiling_addr - base; | ||
| 937 | } | ||
| 938 | } | ||
| 939 | |||
| 940 | TEMP_SET_PT_BOTH (limit, limit_byte); | ||
| 941 | immediate_quit = old_immediate_quit; | ||
| 942 | |||
| 943 | return count * direction; | ||
| 944 | } | 876 | } |
| 945 | 877 | ||
| 946 | /* Like find_newline, but doesn't allow QUITting and doesn't return | 878 | /* Like find_newline, but doesn't allow QUITting and doesn't return |
diff --git a/src/sheap.c b/src/sheap.c index 54eef60c27d..daff0c1d700 100644 --- a/src/sheap.c +++ b/src/sheap.c | |||
| @@ -26,10 +26,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #include <unistd.h> | 26 | #include <unistd.h> |
| 27 | 27 | ||
| 28 | #ifdef __x86_64__ | 28 | #ifdef __x86_64__ |
| 29 | #ifdef ENABLE_CHECKING | ||
| 30 | #define STATIC_HEAP_SIZE (28 * 1024 * 1024) | ||
| 31 | #else | ||
| 32 | #define STATIC_HEAP_SIZE (19 * 1024 * 1024) | ||
| 33 | #endif | ||
| 34 | #else /* x86 */ | ||
| 35 | #ifdef ENABLE_CHECKING | ||
| 29 | #define STATIC_HEAP_SIZE (18 * 1024 * 1024) | 36 | #define STATIC_HEAP_SIZE (18 * 1024 * 1024) |
| 30 | #else | 37 | #else |
| 31 | #define STATIC_HEAP_SIZE (13 * 1024 * 1024) | 38 | #define STATIC_HEAP_SIZE (13 * 1024 * 1024) |
| 32 | #endif | 39 | #endif |
| 40 | #endif /* x86 */ | ||
| 33 | 41 | ||
| 34 | int debug_sheap = 0; | 42 | int debug_sheap = 0; |
| 35 | 43 | ||
| @@ -37,6 +45,7 @@ int debug_sheap = 0; | |||
| 37 | 45 | ||
| 38 | char bss_sbrk_buffer[STATIC_HEAP_SIZE]; | 46 | char bss_sbrk_buffer[STATIC_HEAP_SIZE]; |
| 39 | char *bss_sbrk_ptr; | 47 | char *bss_sbrk_ptr; |
| 48 | char *max_bss_sbrk_ptr; | ||
| 40 | int bss_sbrk_did_unexec; | 49 | int bss_sbrk_did_unexec; |
| 41 | 50 | ||
| 42 | void * | 51 | void * |
| @@ -44,7 +53,7 @@ bss_sbrk (ptrdiff_t request_size) | |||
| 44 | { | 53 | { |
| 45 | if (!bss_sbrk_ptr) | 54 | if (!bss_sbrk_ptr) |
| 46 | { | 55 | { |
| 47 | bss_sbrk_ptr = bss_sbrk_buffer; | 56 | max_bss_sbrk_ptr = bss_sbrk_ptr = bss_sbrk_buffer; |
| 48 | #ifdef CYGWIN | 57 | #ifdef CYGWIN |
| 49 | sbrk (BLOCKSIZE); /* force space for fork to work */ | 58 | sbrk (BLOCKSIZE); /* force space for fork to work */ |
| 50 | #endif | 59 | #endif |
| @@ -85,6 +94,8 @@ bss_sbrk (ptrdiff_t request_size) | |||
| 85 | if (debug_sheap) | 94 | if (debug_sheap) |
| 86 | printf ("allocated 0x%08x size %d\n", ret, request_size); | 95 | printf ("allocated 0x%08x size %d\n", ret, request_size); |
| 87 | bss_sbrk_ptr += (int) request_size; | 96 | bss_sbrk_ptr += (int) request_size; |
| 97 | if (bss_sbrk_ptr > max_bss_sbrk_ptr) | ||
| 98 | max_bss_sbrk_ptr = bss_sbrk_ptr; | ||
| 88 | return ret; | 99 | return ret; |
| 89 | } | 100 | } |
| 90 | } | 101 | } |
| @@ -93,8 +104,8 @@ void | |||
| 93 | report_sheap_usage (int die_if_pure_storage_exceeded) | 104 | report_sheap_usage (int die_if_pure_storage_exceeded) |
| 94 | { | 105 | { |
| 95 | char buf[200]; | 106 | char buf[200]; |
| 96 | sprintf (buf, "Static heap usage: %d of %d bytes", | 107 | sprintf (buf, "Maximum static heap usage: %d of %d bytes", |
| 97 | bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); | 108 | max_bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); |
| 98 | /* Don't log messages, cause at this point, we're not allowed to create | 109 | /* Don't log messages, cause at this point, we're not allowed to create |
| 99 | buffers. */ | 110 | buffers. */ |
| 100 | message1_nolog (buf); | 111 | message1_nolog (buf); |
diff --git a/src/syntax.c b/src/syntax.c index 6d52d115889..31eb86faed8 100644 --- a/src/syntax.c +++ b/src/syntax.c | |||
| @@ -1464,6 +1464,7 @@ scan_words (register ptrdiff_t from, register EMACS_INT count) | |||
| 1464 | 1464 | ||
| 1465 | DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p", | 1465 | DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p", |
| 1466 | doc: /* Move point forward ARG words (backward if ARG is negative). | 1466 | doc: /* Move point forward ARG words (backward if ARG is negative). |
| 1467 | If ARG is omitted or nil, move point forward one word. | ||
| 1467 | Normally returns t. | 1468 | Normally returns t. |
| 1468 | If an edge of the buffer or a field boundary is reached, point is left there | 1469 | If an edge of the buffer or a field boundary is reached, point is left there |
| 1469 | and the function returns nil. Field boundaries are not noticed if | 1470 | and the function returns nil. Field boundaries are not noticed if |
| @@ -3485,9 +3486,9 @@ init_syntax_once (void) | |||
| 3485 | /* This has to be done here, before we call Fmake_char_table. */ | 3486 | /* This has to be done here, before we call Fmake_char_table. */ |
| 3486 | DEFSYM (Qsyntax_table, "syntax-table"); | 3487 | DEFSYM (Qsyntax_table, "syntax-table"); |
| 3487 | 3488 | ||
| 3488 | /* Intern_C_String this now in case it isn't already done. | 3489 | /* This variable is DEFSYMed in alloc.c and not initialized yet, so |
| 3489 | Setting this variable twice is harmless. | 3490 | intern it here. NOTE: you must guarantee that init_syntax_once |
| 3490 | But don't staticpro it here--that is done in alloc.c. */ | 3491 | is called before all other users of this variable. */ |
| 3491 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | 3492 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); |
| 3492 | 3493 | ||
| 3493 | /* Create objects which can be shared among syntax tables. */ | 3494 | /* Create objects which can be shared among syntax tables. */ |
diff --git a/src/sysdep.c b/src/sysdep.c index 11a6f4a76ce..6439697501e 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -306,7 +306,7 @@ get_child_status (pid_t child, int *status, int options, bool interruptible) | |||
| 306 | /* If successful and status is requested, tell wait_reading_process_output | 306 | /* If successful and status is requested, tell wait_reading_process_output |
| 307 | that it needs to wake up and look around. */ | 307 | that it needs to wake up and look around. */ |
| 308 | if (pid && status && input_available_clear_time) | 308 | if (pid && status && input_available_clear_time) |
| 309 | *input_available_clear_time = make_emacs_time (0, 0); | 309 | *input_available_clear_time = make_timespec (0, 0); |
| 310 | 310 | ||
| 311 | return pid; | 311 | return pid; |
| 312 | } | 312 | } |
| @@ -337,16 +337,6 @@ child_status_changed (pid_t child, int *status, int options) | |||
| 337 | return get_child_status (child, status, WNOHANG | options, 0); | 337 | return get_child_status (child, status, WNOHANG | options, 0); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | /* | ||
| 341 | * flush any pending output | ||
| 342 | * (may flush input as well; it does not matter the way we use it) | ||
| 343 | */ | ||
| 344 | |||
| 345 | void | ||
| 346 | flush_pending_output (int channel) | ||
| 347 | { | ||
| 348 | /* FIXME: maybe this function should be removed */ | ||
| 349 | } | ||
| 350 | 340 | ||
| 351 | /* Set up the terminal at the other end of a pseudo-terminal that | 341 | /* Set up the terminal at the other end of a pseudo-terminal that |
| 352 | we will be controlling an inferior through. | 342 | we will be controlling an inferior through. |
| @@ -481,10 +471,20 @@ sys_subshell (void) | |||
| 481 | pid_t pid; | 471 | pid_t pid; |
| 482 | int status; | 472 | int status; |
| 483 | struct save_signal saved_handlers[5]; | 473 | struct save_signal saved_handlers[5]; |
| 484 | Lisp_Object dir; | 474 | char *str = SSDATA (encode_current_directory ()); |
| 485 | unsigned char *volatile str_volatile = 0; | 475 | |
| 486 | unsigned char *str; | 476 | #ifdef DOS_NT |
| 487 | int len; | 477 | pid = 0; |
| 478 | #else | ||
| 479 | { | ||
| 480 | char *volatile str_volatile = str; | ||
| 481 | pid = vfork (); | ||
| 482 | str = str_volatile; | ||
| 483 | } | ||
| 484 | #endif | ||
| 485 | |||
| 486 | if (pid < 0) | ||
| 487 | error ("Can't spawn subshell"); | ||
| 488 | 488 | ||
| 489 | saved_handlers[0].code = SIGINT; | 489 | saved_handlers[0].code = SIGINT; |
| 490 | saved_handlers[1].code = SIGQUIT; | 490 | saved_handlers[1].code = SIGQUIT; |
| @@ -496,31 +496,8 @@ sys_subshell (void) | |||
| 496 | saved_handlers[3].code = 0; | 496 | saved_handlers[3].code = 0; |
| 497 | #endif | 497 | #endif |
| 498 | 498 | ||
| 499 | /* Mentioning current_buffer->buffer would mean including buffer.h, | ||
| 500 | which somehow wedges the hp compiler. So instead... */ | ||
| 501 | |||
| 502 | dir = intern ("default-directory"); | ||
| 503 | if (NILP (Fboundp (dir))) | ||
| 504 | goto xyzzy; | ||
| 505 | dir = Fsymbol_value (dir); | ||
| 506 | if (!STRINGP (dir)) | ||
| 507 | goto xyzzy; | ||
| 508 | |||
| 509 | dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil); | ||
| 510 | str_volatile = str = alloca (SCHARS (dir) + 2); | ||
| 511 | len = SCHARS (dir); | ||
| 512 | memcpy (str, SDATA (dir), len); | ||
| 513 | if (str[len - 1] != '/') str[len++] = '/'; | ||
| 514 | str[len] = 0; | ||
| 515 | xyzzy: | ||
| 516 | |||
| 517 | #ifdef DOS_NT | 499 | #ifdef DOS_NT |
| 518 | pid = 0; | ||
| 519 | save_signal_handlers (saved_handlers); | 500 | save_signal_handlers (saved_handlers); |
| 520 | #else | ||
| 521 | pid = vfork (); | ||
| 522 | if (pid == -1) | ||
| 523 | error ("Can't spawn subshell"); | ||
| 524 | #endif | 501 | #endif |
| 525 | 502 | ||
| 526 | if (pid == 0) | 503 | if (pid == 0) |
| @@ -538,11 +515,10 @@ sys_subshell (void) | |||
| 538 | sh = "sh"; | 515 | sh = "sh"; |
| 539 | 516 | ||
| 540 | /* Use our buffer's default directory for the subshell. */ | 517 | /* Use our buffer's default directory for the subshell. */ |
| 541 | str = str_volatile; | 518 | if (chdir (str) != 0) |
| 542 | if (str && chdir ((char *) str) != 0) | ||
| 543 | { | 519 | { |
| 544 | #ifndef DOS_NT | 520 | #ifndef DOS_NT |
| 545 | emacs_perror ((char *) str); | 521 | emacs_perror (str); |
| 546 | _exit (EXIT_CANCELED); | 522 | _exit (EXIT_CANCELED); |
| 547 | #endif | 523 | #endif |
| 548 | } | 524 | } |
| @@ -556,8 +532,6 @@ sys_subshell (void) | |||
| 556 | if (epwd) | 532 | if (epwd) |
| 557 | { | 533 | { |
| 558 | strcpy (old_pwd, epwd); | 534 | strcpy (old_pwd, epwd); |
| 559 | if (str[len - 1] == '/') | ||
| 560 | str[len - 1] = '\0'; | ||
| 561 | setenv ("PWD", str, 1); | 535 | setenv ("PWD", str, 1); |
| 562 | } | 536 | } |
| 563 | st = system (sh); | 537 | st = system (sh); |
| @@ -614,7 +588,7 @@ restore_signal_handlers (struct save_signal *saved_handlers) | |||
| 614 | } | 588 | } |
| 615 | 589 | ||
| 616 | #ifdef USABLE_SIGIO | 590 | #ifdef USABLE_SIGIO |
| 617 | static int old_fcntl_flags[MAXDESC]; | 591 | static int old_fcntl_flags[FD_SETSIZE]; |
| 618 | #endif | 592 | #endif |
| 619 | 593 | ||
| 620 | void | 594 | void |
| @@ -843,7 +817,7 @@ emacs_set_tty (int fd, struct emacs_tty *settings, bool flushp) | |||
| 843 | 817 | ||
| 844 | 818 | ||
| 845 | #ifdef F_SETOWN | 819 | #ifdef F_SETOWN |
| 846 | static int old_fcntl_owner[MAXDESC]; | 820 | static int old_fcntl_owner[FD_SETSIZE]; |
| 847 | #endif /* F_SETOWN */ | 821 | #endif /* F_SETOWN */ |
| 848 | 822 | ||
| 849 | /* This may also be defined in stdio, | 823 | /* This may also be defined in stdio, |
| @@ -1196,7 +1170,8 @@ get_tty_size (int fd, int *widthp, int *heightp) | |||
| 1196 | } | 1170 | } |
| 1197 | 1171 | ||
| 1198 | /* Set the logical window size associated with descriptor FD | 1172 | /* Set the logical window size associated with descriptor FD |
| 1199 | to HEIGHT and WIDTH. This is used mainly with ptys. */ | 1173 | to HEIGHT and WIDTH. This is used mainly with ptys. |
| 1174 | Return a negative value on failure. */ | ||
| 1200 | 1175 | ||
| 1201 | int | 1176 | int |
| 1202 | set_window_size (int fd, int height, int width) | 1177 | set_window_size (int fd, int height, int width) |
| @@ -1208,10 +1183,7 @@ set_window_size (int fd, int height, int width) | |||
| 1208 | size.ws_row = height; | 1183 | size.ws_row = height; |
| 1209 | size.ws_col = width; | 1184 | size.ws_col = width; |
| 1210 | 1185 | ||
| 1211 | if (ioctl (fd, TIOCSWINSZ, &size) == -1) | 1186 | return ioctl (fd, TIOCSWINSZ, &size); |
| 1212 | return 0; /* error */ | ||
| 1213 | else | ||
| 1214 | return 1; | ||
| 1215 | 1187 | ||
| 1216 | #else | 1188 | #else |
| 1217 | #ifdef TIOCSSIZE | 1189 | #ifdef TIOCSSIZE |
| @@ -1221,10 +1193,7 @@ set_window_size (int fd, int height, int width) | |||
| 1221 | size.ts_lines = height; | 1193 | size.ts_lines = height; |
| 1222 | size.ts_cols = width; | 1194 | size.ts_cols = width; |
| 1223 | 1195 | ||
| 1224 | if (ioctl (fd, TIOCGSIZE, &size) == -1) | 1196 | return ioctl (fd, TIOCGSIZE, &size); |
| 1225 | return 0; | ||
| 1226 | else | ||
| 1227 | return 1; | ||
| 1228 | #else | 1197 | #else |
| 1229 | return -1; | 1198 | return -1; |
| 1230 | #endif /* not SunOS-style */ | 1199 | #endif /* not SunOS-style */ |
| @@ -2052,8 +2021,8 @@ seed_random (void *seed, ptrdiff_t seed_size) | |||
| 2052 | void | 2021 | void |
| 2053 | init_random (void) | 2022 | init_random (void) |
| 2054 | { | 2023 | { |
| 2055 | EMACS_TIME t = current_emacs_time (); | 2024 | struct timespec t = current_timespec (); |
| 2056 | uintmax_t v = getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t); | 2025 | uintmax_t v = getpid () ^ t.tv_sec ^ t.tv_nsec; |
| 2057 | seed_random (&v, sizeof v); | 2026 | seed_random (&v, sizeof v); |
| 2058 | } | 2027 | } |
| 2059 | 2028 | ||
| @@ -2388,7 +2357,7 @@ emacs_perror (char const *message) | |||
| 2388 | Use the least timeval not less than T. | 2357 | Use the least timeval not less than T. |
| 2389 | Return an extremal value if the result would overflow. */ | 2358 | Return an extremal value if the result would overflow. */ |
| 2390 | struct timeval | 2359 | struct timeval |
| 2391 | make_timeval (EMACS_TIME t) | 2360 | make_timeval (struct timespec t) |
| 2392 | { | 2361 | { |
| 2393 | struct timeval tv; | 2362 | struct timeval tv; |
| 2394 | tv.tv_sec = t.tv_sec; | 2363 | tv.tv_sec = t.tv_sec; |
| @@ -2415,7 +2384,7 @@ make_timeval (EMACS_TIME t) | |||
| 2415 | If FD is nonnegative, then FILE can be NULL. */ | 2384 | If FD is nonnegative, then FILE can be NULL. */ |
| 2416 | int | 2385 | int |
| 2417 | set_file_times (int fd, const char *filename, | 2386 | set_file_times (int fd, const char *filename, |
| 2418 | EMACS_TIME atime, EMACS_TIME mtime) | 2387 | struct timespec atime, struct timespec mtime) |
| 2419 | { | 2388 | { |
| 2420 | struct timespec timespec[2]; | 2389 | struct timespec timespec[2]; |
| 2421 | timespec[0] = atime; | 2390 | timespec[0] = atime; |
| @@ -2485,7 +2454,7 @@ serial_configure (struct Lisp_Process *p, | |||
| 2485 | Lisp_Object childp2 = Qnil; | 2454 | Lisp_Object childp2 = Qnil; |
| 2486 | Lisp_Object tem = Qnil; | 2455 | Lisp_Object tem = Qnil; |
| 2487 | struct termios attr; | 2456 | struct termios attr; |
| 2488 | int err = -1; | 2457 | int err; |
| 2489 | char summary[4] = "???"; /* This usually becomes "8N1". */ | 2458 | char summary[4] = "???"; /* This usually becomes "8N1". */ |
| 2490 | 2459 | ||
| 2491 | childp2 = Fcopy_sequence (p->childp); | 2460 | childp2 = Fcopy_sequence (p->childp); |
| @@ -2732,7 +2701,7 @@ list_system_processes (void) | |||
| 2732 | #endif /* !defined (WINDOWSNT) */ | 2701 | #endif /* !defined (WINDOWSNT) */ |
| 2733 | 2702 | ||
| 2734 | #if defined GNU_LINUX && defined HAVE_LONG_LONG_INT | 2703 | #if defined GNU_LINUX && defined HAVE_LONG_LONG_INT |
| 2735 | static EMACS_TIME | 2704 | static struct timespec |
| 2736 | time_from_jiffies (unsigned long long tval, long hz) | 2705 | time_from_jiffies (unsigned long long tval, long hz) |
| 2737 | { | 2706 | { |
| 2738 | unsigned long long s = tval / hz; | 2707 | unsigned long long s = tval / hz; |
| @@ -2741,34 +2710,34 @@ time_from_jiffies (unsigned long long tval, long hz) | |||
| 2741 | 2710 | ||
| 2742 | if (TYPE_MAXIMUM (time_t) < s) | 2711 | if (TYPE_MAXIMUM (time_t) < s) |
| 2743 | time_overflow (); | 2712 | time_overflow (); |
| 2744 | if (LONG_MAX - 1 <= ULLONG_MAX / EMACS_TIME_RESOLUTION | 2713 | if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_RESOLUTION |
| 2745 | || frac <= ULLONG_MAX / EMACS_TIME_RESOLUTION) | 2714 | || frac <= ULLONG_MAX / TIMESPEC_RESOLUTION) |
| 2746 | ns = frac * EMACS_TIME_RESOLUTION / hz; | 2715 | ns = frac * TIMESPEC_RESOLUTION / hz; |
| 2747 | else | 2716 | else |
| 2748 | { | 2717 | { |
| 2749 | /* This is reachable only in the unlikely case that HZ * HZ | 2718 | /* This is reachable only in the unlikely case that HZ * HZ |
| 2750 | exceeds ULLONG_MAX. It calculates an approximation that is | 2719 | exceeds ULLONG_MAX. It calculates an approximation that is |
| 2751 | guaranteed to be in range. */ | 2720 | guaranteed to be in range. */ |
| 2752 | long hz_per_ns = (hz / EMACS_TIME_RESOLUTION | 2721 | long hz_per_ns = (hz / TIMESPEC_RESOLUTION |
| 2753 | + (hz % EMACS_TIME_RESOLUTION != 0)); | 2722 | + (hz % TIMESPEC_RESOLUTION != 0)); |
| 2754 | ns = frac / hz_per_ns; | 2723 | ns = frac / hz_per_ns; |
| 2755 | } | 2724 | } |
| 2756 | 2725 | ||
| 2757 | return make_emacs_time (s, ns); | 2726 | return make_timespec (s, ns); |
| 2758 | } | 2727 | } |
| 2759 | 2728 | ||
| 2760 | static Lisp_Object | 2729 | static Lisp_Object |
| 2761 | ltime_from_jiffies (unsigned long long tval, long hz) | 2730 | ltime_from_jiffies (unsigned long long tval, long hz) |
| 2762 | { | 2731 | { |
| 2763 | EMACS_TIME t = time_from_jiffies (tval, hz); | 2732 | struct timespec t = time_from_jiffies (tval, hz); |
| 2764 | return make_lisp_time (t); | 2733 | return make_lisp_time (t); |
| 2765 | } | 2734 | } |
| 2766 | 2735 | ||
| 2767 | static EMACS_TIME | 2736 | static struct timespec |
| 2768 | get_up_time (void) | 2737 | get_up_time (void) |
| 2769 | { | 2738 | { |
| 2770 | FILE *fup; | 2739 | FILE *fup; |
| 2771 | EMACS_TIME up = make_emacs_time (0, 0); | 2740 | struct timespec up = make_timespec (0, 0); |
| 2772 | 2741 | ||
| 2773 | block_input (); | 2742 | block_input (); |
| 2774 | fup = emacs_fopen ("/proc/uptime", "r"); | 2743 | fup = emacs_fopen ("/proc/uptime", "r"); |
| @@ -2786,18 +2755,18 @@ get_up_time (void) | |||
| 2786 | if (TYPE_MAXIMUM (time_t) < upsec) | 2755 | if (TYPE_MAXIMUM (time_t) < upsec) |
| 2787 | { | 2756 | { |
| 2788 | upsec = TYPE_MAXIMUM (time_t); | 2757 | upsec = TYPE_MAXIMUM (time_t); |
| 2789 | upfrac = EMACS_TIME_RESOLUTION - 1; | 2758 | upfrac = TIMESPEC_RESOLUTION - 1; |
| 2790 | } | 2759 | } |
| 2791 | else | 2760 | else |
| 2792 | { | 2761 | { |
| 2793 | int upfraclen = upfrac_end - upfrac_start; | 2762 | int upfraclen = upfrac_end - upfrac_start; |
| 2794 | for (; upfraclen < LOG10_EMACS_TIME_RESOLUTION; upfraclen++) | 2763 | for (; upfraclen < LOG10_TIMESPEC_RESOLUTION; upfraclen++) |
| 2795 | upfrac *= 10; | 2764 | upfrac *= 10; |
| 2796 | for (; LOG10_EMACS_TIME_RESOLUTION < upfraclen; upfraclen--) | 2765 | for (; LOG10_TIMESPEC_RESOLUTION < upfraclen; upfraclen--) |
| 2797 | upfrac /= 10; | 2766 | upfrac /= 10; |
| 2798 | upfrac = min (upfrac, EMACS_TIME_RESOLUTION - 1); | 2767 | upfrac = min (upfrac, TIMESPEC_RESOLUTION - 1); |
| 2799 | } | 2768 | } |
| 2800 | up = make_emacs_time (upsec, upfrac); | 2769 | up = make_timespec (upsec, upfrac); |
| 2801 | } | 2770 | } |
| 2802 | fclose (fup); | 2771 | fclose (fup); |
| 2803 | } | 2772 | } |
| @@ -2852,29 +2821,41 @@ procfs_ttyname (int rdev) | |||
| 2852 | return build_string (name); | 2821 | return build_string (name); |
| 2853 | } | 2822 | } |
| 2854 | 2823 | ||
| 2855 | static unsigned long | 2824 | static uintmax_t |
| 2856 | procfs_get_total_memory (void) | 2825 | procfs_get_total_memory (void) |
| 2857 | { | 2826 | { |
| 2858 | FILE *fmem; | 2827 | FILE *fmem; |
| 2859 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ | 2828 | uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */ |
| 2829 | int c; | ||
| 2860 | 2830 | ||
| 2861 | block_input (); | 2831 | block_input (); |
| 2862 | fmem = emacs_fopen ("/proc/meminfo", "r"); | 2832 | fmem = emacs_fopen ("/proc/meminfo", "r"); |
| 2863 | 2833 | ||
| 2864 | if (fmem) | 2834 | if (fmem) |
| 2865 | { | 2835 | { |
| 2866 | unsigned long entry_value; | 2836 | uintmax_t entry_value; |
| 2867 | char entry_name[20]; /* the longest I saw is 13+1 */ | 2837 | bool done; |
| 2838 | |||
| 2839 | do | ||
| 2840 | switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value)) | ||
| 2841 | { | ||
| 2842 | case 1: | ||
| 2843 | retval = entry_value; | ||
| 2844 | done = 1; | ||
| 2845 | break; | ||
| 2846 | |||
| 2847 | case 0: | ||
| 2848 | while ((c = getc (fmem)) != EOF && c != '\n') | ||
| 2849 | continue; | ||
| 2850 | done = c == EOF; | ||
| 2851 | break; | ||
| 2852 | |||
| 2853 | default: | ||
| 2854 | done = 1; | ||
| 2855 | break; | ||
| 2856 | } | ||
| 2857 | while (!done); | ||
| 2868 | 2858 | ||
| 2869 | while (!feof (fmem) && !ferror (fmem)) | ||
| 2870 | { | ||
| 2871 | if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2 | ||
| 2872 | && strcmp (entry_name, "MemTotal:") == 0) | ||
| 2873 | { | ||
| 2874 | retval = entry_value; | ||
| 2875 | break; | ||
| 2876 | } | ||
| 2877 | } | ||
| 2878 | fclose (fmem); | 2859 | fclose (fmem); |
| 2879 | } | 2860 | } |
| 2880 | unblock_input (); | 2861 | unblock_input (); |
| @@ -2906,7 +2887,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 2906 | unsigned long long u_time, s_time, cutime, cstime, start; | 2887 | unsigned long long u_time, s_time, cutime, cstime, start; |
| 2907 | long priority, niceness, rss; | 2888 | long priority, niceness, rss; |
| 2908 | unsigned long minflt, majflt, cminflt, cmajflt, vsize; | 2889 | unsigned long minflt, majflt, cminflt, cmajflt, vsize; |
| 2909 | EMACS_TIME tnow, tstart, tboot, telapsed, us_time; | 2890 | struct timespec tnow, tstart, tboot, telapsed, us_time; |
| 2910 | double pcpu, pmem; | 2891 | double pcpu, pmem; |
| 2911 | Lisp_Object attrs = Qnil; | 2892 | Lisp_Object attrs = Qnil; |
| 2912 | Lisp_Object cmd_str, decoded_cmd; | 2893 | Lisp_Object cmd_str, decoded_cmd; |
| @@ -3027,20 +3008,19 @@ system_process_attributes (Lisp_Object pid) | |||
| 3027 | attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); | 3008 | attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); |
| 3028 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), | 3009 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), |
| 3029 | attrs); | 3010 | attrs); |
| 3030 | tnow = current_emacs_time (); | 3011 | tnow = current_timespec (); |
| 3031 | telapsed = get_up_time (); | 3012 | telapsed = get_up_time (); |
| 3032 | tboot = sub_emacs_time (tnow, telapsed); | 3013 | tboot = timespec_sub (tnow, telapsed); |
| 3033 | tstart = time_from_jiffies (start, clocks_per_sec); | 3014 | tstart = time_from_jiffies (start, clocks_per_sec); |
| 3034 | tstart = add_emacs_time (tboot, tstart); | 3015 | tstart = timespec_add (tboot, tstart); |
| 3035 | attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); | 3016 | attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); |
| 3036 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)), | 3017 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)), |
| 3037 | attrs); | 3018 | attrs); |
| 3038 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs); | 3019 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs); |
| 3039 | telapsed = sub_emacs_time (tnow, tstart); | 3020 | telapsed = timespec_sub (tnow, tstart); |
| 3040 | attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); | 3021 | attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); |
| 3041 | us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); | 3022 | us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); |
| 3042 | pcpu = (EMACS_TIME_TO_DOUBLE (us_time) | 3023 | pcpu = timespectod (us_time) / timespectod (telapsed); |
| 3043 | / EMACS_TIME_TO_DOUBLE (telapsed)); | ||
| 3044 | if (pcpu > 1.0) | 3024 | if (pcpu > 1.0) |
| 3045 | pcpu = 1.0; | 3025 | pcpu = 1.0; |
| 3046 | attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs); | 3026 | attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs); |
| @@ -3243,13 +3223,11 @@ system_process_attributes (Lisp_Object pid) | |||
| 3243 | attrs); | 3223 | attrs); |
| 3244 | 3224 | ||
| 3245 | decoded_cmd = (code_convert_string_norecord | 3225 | decoded_cmd = (code_convert_string_norecord |
| 3246 | (make_unibyte_string (pinfo.pr_fname, | 3226 | (build_unibyte_string (pinfo.pr_fname), |
| 3247 | strlen (pinfo.pr_fname)), | ||
| 3248 | Vlocale_coding_system, 0)); | 3227 | Vlocale_coding_system, 0)); |
| 3249 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | 3228 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); |
| 3250 | decoded_cmd = (code_convert_string_norecord | 3229 | decoded_cmd = (code_convert_string_norecord |
| 3251 | (make_unibyte_string (pinfo.pr_psargs, | 3230 | (build_unibyte_string (pinfo.pr_psargs), |
| 3252 | strlen (pinfo.pr_psargs)), | ||
| 3253 | Vlocale_coding_system, 0)); | 3231 | Vlocale_coding_system, 0)); |
| 3254 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | 3232 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); |
| 3255 | } | 3233 | } |
| @@ -3260,16 +3238,16 @@ system_process_attributes (Lisp_Object pid) | |||
| 3260 | 3238 | ||
| 3261 | #elif defined __FreeBSD__ | 3239 | #elif defined __FreeBSD__ |
| 3262 | 3240 | ||
| 3263 | static EMACS_TIME | 3241 | static struct timespec |
| 3264 | timeval_to_EMACS_TIME (struct timeval t) | 3242 | timeval_to_timespec (struct timeval t) |
| 3265 | { | 3243 | { |
| 3266 | return make_emacs_time (t.tv_sec, t.tv_usec * 1000); | 3244 | return make_timespec (t.tv_sec, t.tv_usec * 1000); |
| 3267 | } | 3245 | } |
| 3268 | 3246 | ||
| 3269 | static Lisp_Object | 3247 | static Lisp_Object |
| 3270 | make_lisp_timeval (struct timeval t) | 3248 | make_lisp_timeval (struct timeval t) |
| 3271 | { | 3249 | { |
| 3272 | return make_lisp_time (timeval_to_EMACS_TIME (t)); | 3250 | return make_lisp_time (timeval_to_timespec (t)); |
| 3273 | } | 3251 | } |
| 3274 | 3252 | ||
| 3275 | Lisp_Object | 3253 | Lisp_Object |
| @@ -3277,14 +3255,14 @@ system_process_attributes (Lisp_Object pid) | |||
| 3277 | { | 3255 | { |
| 3278 | int proc_id; | 3256 | int proc_id; |
| 3279 | int pagesize = getpagesize (); | 3257 | int pagesize = getpagesize (); |
| 3280 | int npages; | 3258 | unsigned long npages; |
| 3281 | int fscale; | 3259 | int fscale; |
| 3282 | struct passwd *pw; | 3260 | struct passwd *pw; |
| 3283 | struct group *gr; | 3261 | struct group *gr; |
| 3284 | char *ttyname; | 3262 | char *ttyname; |
| 3285 | size_t len; | 3263 | size_t len; |
| 3286 | char args[MAXPATHLEN]; | 3264 | char args[MAXPATHLEN]; |
| 3287 | EMACS_TIME t, now; | 3265 | struct timespec t, now; |
| 3288 | 3266 | ||
| 3289 | int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID}; | 3267 | int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID}; |
| 3290 | struct kinfo_proc proc; | 3268 | struct kinfo_proc proc; |
| @@ -3319,9 +3297,9 @@ system_process_attributes (Lisp_Object pid) | |||
| 3319 | if (gr) | 3297 | if (gr) |
| 3320 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | 3298 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); |
| 3321 | 3299 | ||
| 3322 | decoded_comm = code_convert_string_norecord | 3300 | decoded_comm = (code_convert_string_norecord |
| 3323 | (make_unibyte_string (proc.ki_comm, strlen (proc.ki_comm)), | 3301 | (build_unibyte_string (proc.ki_comm), |
| 3324 | Vlocale_coding_system, 0); | 3302 | Vlocale_coding_system, 0)); |
| 3325 | 3303 | ||
| 3326 | attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); | 3304 | attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); |
| 3327 | { | 3305 | { |
| @@ -3371,8 +3349,8 @@ system_process_attributes (Lisp_Object pid) | |||
| 3371 | attrs); | 3349 | attrs); |
| 3372 | attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.ki_rusage.ru_stime)), | 3350 | attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.ki_rusage.ru_stime)), |
| 3373 | attrs); | 3351 | attrs); |
| 3374 | t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage.ru_utime), | 3352 | t = timespec_add (timeval_to_timespec (proc.ki_rusage.ru_utime), |
| 3375 | timeval_to_EMACS_TIME (proc.ki_rusage.ru_stime)); | 3353 | timeval_to_timespec (proc.ki_rusage.ru_stime)); |
| 3376 | attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); | 3354 | attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); |
| 3377 | 3355 | ||
| 3378 | attrs = Fcons (Fcons (Qcutime, | 3356 | attrs = Fcons (Fcons (Qcutime, |
| @@ -3381,8 +3359,8 @@ system_process_attributes (Lisp_Object pid) | |||
| 3381 | attrs = Fcons (Fcons (Qcstime, | 3359 | attrs = Fcons (Fcons (Qcstime, |
| 3382 | make_lisp_timeval (proc.ki_rusage_ch.ru_utime)), | 3360 | make_lisp_timeval (proc.ki_rusage_ch.ru_utime)), |
| 3383 | attrs); | 3361 | attrs); |
| 3384 | t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_utime), | 3362 | t = timespec_add (timeval_to_timespec (proc.ki_rusage_ch.ru_utime), |
| 3385 | timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_stime)); | 3363 | timeval_to_timespec (proc.ki_rusage_ch.ru_stime)); |
| 3386 | attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs); | 3364 | attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs); |
| 3387 | 3365 | ||
| 3388 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)), | 3366 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)), |
| @@ -3394,8 +3372,8 @@ system_process_attributes (Lisp_Object pid) | |||
| 3394 | attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)), | 3372 | attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)), |
| 3395 | attrs); | 3373 | attrs); |
| 3396 | 3374 | ||
| 3397 | now = current_emacs_time (); | 3375 | now = current_timespec (); |
| 3398 | t = sub_emacs_time (now, timeval_to_EMACS_TIME (proc.ki_start)); | 3376 | t = timespec_sub (now, timeval_to_timespec (proc.ki_start)); |
| 3399 | attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); | 3377 | attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); |
| 3400 | 3378 | ||
| 3401 | len = sizeof fscale; | 3379 | len = sizeof fscale; |
diff --git a/src/sysselect.h b/src/sysselect.h index 0a4f7e3ad96..5df0af9ed37 100644 --- a/src/sysselect.h +++ b/src/sysselect.h | |||
| @@ -25,15 +25,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | definitions in w32.h are incompatible with the below. */ | 25 | definitions in w32.h are incompatible with the below. */ |
| 26 | #ifndef WINDOWSNT | 26 | #ifndef WINDOWSNT |
| 27 | #ifdef FD_SET | 27 | #ifdef FD_SET |
| 28 | #ifdef FD_SETSIZE | 28 | #ifndef FD_SETSIZE |
| 29 | #define MAXDESC FD_SETSIZE | 29 | #define FD_SETSIZE 64 |
| 30 | #else | ||
| 31 | #define MAXDESC 64 | ||
| 32 | #endif | 30 | #endif |
| 33 | #define SELECT_TYPE fd_set | ||
| 34 | #else /* no FD_SET */ | 31 | #else /* no FD_SET */ |
| 35 | #define MAXDESC 32 | 32 | #define FD_SETSIZE 32 |
| 36 | #define SELECT_TYPE int | 33 | typedef int fd_set; |
| 37 | 34 | ||
| 38 | /* Define the macros to access a single-int bitmap of descriptors. */ | 35 | /* Define the macros to access a single-int bitmap of descriptors. */ |
| 39 | #define FD_SET(n, p) (*(p) |= (1 << (n))) | 36 | #define FD_SET(n, p) (*(p) |= (1 << (n))) |
diff --git a/src/systime.h b/src/systime.h index df733b290c3..b1c3d940b0e 100644 --- a/src/systime.h +++ b/src/systime.h | |||
| @@ -46,140 +46,56 @@ typedef unsigned long Time; | |||
| 46 | 46 | ||
| 47 | #include <sys/time.h> /* for 'struct timeval' */ | 47 | #include <sys/time.h> /* for 'struct timeval' */ |
| 48 | 48 | ||
| 49 | /* The type to use to represent non-negative temporal intervals. Its | 49 | /* Emacs uses struct timespec to represent nonnegative temporal intervals. |
| 50 | address can be passed as the timeout argument to the pselect system | ||
| 51 | call. */ | ||
| 52 | typedef struct timespec EMACS_TIME; | ||
| 53 | |||
| 54 | /* Resolution of EMACS_TIME time stamps (in units per second), and log | ||
| 55 | base 10 of the resolution. The log must be a positive integer. */ | ||
| 56 | enum { EMACS_TIME_RESOLUTION = 1000000000 }; | ||
| 57 | enum { LOG10_EMACS_TIME_RESOLUTION = 9 }; | ||
| 58 | |||
| 59 | /* EMACS_SECS (TIME) is the seconds component of TIME. | ||
| 60 | EMACS_NSECS (TIME) is the nanoseconds component of TIME. | ||
| 61 | emacs_secs_addr (PTIME) is the address of *PTIME's seconds component. */ | ||
| 62 | SYSTIME_INLINE time_t EMACS_SECS (EMACS_TIME t) { return t.tv_sec; } | ||
| 63 | SYSTIME_INLINE int EMACS_NSECS (EMACS_TIME t) { return t.tv_nsec; } | ||
| 64 | SYSTIME_INLINE time_t *emacs_secs_addr (EMACS_TIME *t) { return &t->tv_sec; } | ||
| 65 | |||
| 66 | /* Return an Emacs time with seconds S and nanoseconds NS. */ | ||
| 67 | SYSTIME_INLINE EMACS_TIME | ||
| 68 | make_emacs_time (time_t s, int ns) | ||
| 69 | { | ||
| 70 | EMACS_TIME r; | ||
| 71 | r.tv_sec = s; | ||
| 72 | r.tv_nsec = ns; | ||
| 73 | return r; | ||
| 74 | } | ||
| 75 | 50 | ||
| 76 | /* Return an invalid Emacs time. */ | 51 | WARNING: Since tv_sec might be an unsigned value, do not use struct |
| 77 | SYSTIME_INLINE EMACS_TIME | 52 | timespec as a general-purpose data type for adding or subtracting |
| 78 | invalid_emacs_time (void) | 53 | arbitrary time values! When computing A + B or A - B, typically A |
| 79 | { | 54 | should be an absolute time since the epoch and B a nonnegative offset. */ |
| 80 | EMACS_TIME r; | ||
| 81 | r.tv_sec = 0; | ||
| 82 | r.tv_nsec = -1; | ||
| 83 | return r; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* Return current system time. */ | ||
| 87 | SYSTIME_INLINE EMACS_TIME | ||
| 88 | current_emacs_time (void) | ||
| 89 | { | ||
| 90 | EMACS_TIME r; | ||
| 91 | gettime (&r); | ||
| 92 | return r; | ||
| 93 | } | ||
| 94 | |||
| 95 | /* Return the result of adding A to B, or of subtracting B from A. | ||
| 96 | On overflow, store an extremal value: ergo, if time_t is unsigned, | ||
| 97 | return 0 if the true answer would be negative. | ||
| 98 | |||
| 99 | WARNING: These are NOT general-purpose macros for adding or | ||
| 100 | subtracting arbitrary time values! They are generally intended to | ||
| 101 | be used with their first argument an absolute time since the epoch | ||
| 102 | and the second argument a non-negative offset. Do NOT use them for | ||
| 103 | anything else. */ | ||
| 104 | SYSTIME_INLINE EMACS_TIME | ||
| 105 | add_emacs_time (EMACS_TIME a, EMACS_TIME b) | ||
| 106 | { | ||
| 107 | return timespec_add (a, b); | ||
| 108 | } | ||
| 109 | SYSTIME_INLINE EMACS_TIME | ||
| 110 | sub_emacs_time (EMACS_TIME a, EMACS_TIME b) | ||
| 111 | { | ||
| 112 | return timespec_sub (a, b); | ||
| 113 | } | ||
| 114 | 55 | ||
| 115 | /* Return the sign of the valid time stamp TIME, either -1, 0, or 1. | 56 | /* Return an invalid timespec. */ |
| 116 | Note: this can only return a negative value if time_t is a signed | 57 | SYSTIME_INLINE struct timespec |
| 117 | data type. */ | 58 | invalid_timespec (void) |
| 118 | SYSTIME_INLINE int | ||
| 119 | EMACS_TIME_SIGN (EMACS_TIME t) | ||
| 120 | { | 59 | { |
| 121 | return timespec_sign (t); | 60 | return make_timespec (0, -1); |
| 122 | } | 61 | } |
| 123 | 62 | ||
| 124 | /* Return 1 if TIME is a valid time stamp. */ | 63 | /* Return 1 if TIME is a valid timespec. This currently doesn't worry |
| 64 | about whether tv_nsec is less than TIMESPEC_RESOLUTION; leap seconds | ||
| 65 | might cause a problem if it did. */ | ||
| 125 | SYSTIME_INLINE int | 66 | SYSTIME_INLINE int |
| 126 | EMACS_TIME_VALID_P (EMACS_TIME t) | 67 | timespec_valid_p (struct timespec t) |
| 127 | { | 68 | { |
| 128 | return t.tv_nsec >= 0; | 69 | return t.tv_nsec >= 0; |
| 129 | } | 70 | } |
| 130 | 71 | ||
| 131 | /* Convert the double D to the greatest EMACS_TIME not greater than D. | 72 | /* Return current system time. */ |
| 132 | On overflow, return an extremal value; in particular, if time_t is | 73 | SYSTIME_INLINE struct timespec |
| 133 | an unsigned data type and D is negative, return zero. Return the | 74 | current_timespec (void) |
| 134 | minimum EMACS_TIME if D is not a number. */ | ||
| 135 | SYSTIME_INLINE EMACS_TIME | ||
| 136 | EMACS_TIME_FROM_DOUBLE (double d) | ||
| 137 | { | ||
| 138 | return dtotimespec (d); | ||
| 139 | } | ||
| 140 | |||
| 141 | /* Convert the Emacs time T to an approximate double value D. */ | ||
| 142 | SYSTIME_INLINE double | ||
| 143 | EMACS_TIME_TO_DOUBLE (EMACS_TIME t) | ||
| 144 | { | 75 | { |
| 145 | return timespectod (t); | 76 | struct timespec r; |
| 77 | gettime (&r); | ||
| 78 | return r; | ||
| 146 | } | 79 | } |
| 147 | 80 | ||
| 148 | /* defined in sysdep.c */ | 81 | /* defined in sysdep.c */ |
| 149 | extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME); | 82 | extern int set_file_times (int, const char *, struct timespec, struct timespec); |
| 150 | extern struct timeval make_timeval (EMACS_TIME) ATTRIBUTE_CONST; | 83 | extern struct timeval make_timeval (struct timespec) ATTRIBUTE_CONST; |
| 151 | 84 | ||
| 152 | /* defined in keyboard.c */ | 85 | /* defined in keyboard.c */ |
| 153 | extern void set_waiting_for_input (EMACS_TIME *); | 86 | extern void set_waiting_for_input (struct timespec *); |
| 154 | 87 | ||
| 155 | /* When lisp.h is not included Lisp_Object is not defined (this can | 88 | /* When lisp.h is not included Lisp_Object is not defined (this can |
| 156 | happen when this files is used outside the src directory). | 89 | happen when this files is used outside the src directory). |
| 157 | Use GCPRO1 to determine if lisp.h was included. */ | 90 | Use GCPRO1 to determine if lisp.h was included. */ |
| 158 | #ifdef GCPRO1 | 91 | #ifdef GCPRO1 |
| 159 | /* defined in editfns.c */ | 92 | /* defined in editfns.c */ |
| 160 | extern Lisp_Object make_lisp_time (EMACS_TIME); | 93 | extern Lisp_Object make_lisp_time (struct timespec); |
| 161 | extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, | 94 | extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, |
| 162 | Lisp_Object, EMACS_TIME *, double *); | 95 | Lisp_Object, struct timespec *, double *); |
| 163 | extern EMACS_TIME lisp_time_argument (Lisp_Object); | 96 | extern struct timespec lisp_time_argument (Lisp_Object); |
| 164 | #endif | 97 | #endif |
| 165 | 98 | ||
| 166 | /* Compare times T1 and T2 for equality, inequality etc. */ | ||
| 167 | SYSTIME_INLINE int | ||
| 168 | EMACS_TIME_EQ (EMACS_TIME t1, EMACS_TIME t2) | ||
| 169 | { | ||
| 170 | return timespec_cmp (t1, t2) == 0; | ||
| 171 | } | ||
| 172 | SYSTIME_INLINE int | ||
| 173 | EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2) | ||
| 174 | { | ||
| 175 | return timespec_cmp (t1, t2) < 0; | ||
| 176 | } | ||
| 177 | SYSTIME_INLINE int | ||
| 178 | EMACS_TIME_LE (EMACS_TIME t1, EMACS_TIME t2) | ||
| 179 | { | ||
| 180 | return timespec_cmp (t1, t2) <= 0; | ||
| 181 | } | ||
| 182 | |||
| 183 | INLINE_HEADER_END | 99 | INLINE_HEADER_END |
| 184 | 100 | ||
| 185 | #endif /* EMACS_SYSTIME_H */ | 101 | #endif /* EMACS_SYSTIME_H */ |
diff --git a/src/syswait.h b/src/syswait.h index 03e5cb5fe2e..4ae9129d7ed 100644 --- a/src/syswait.h +++ b/src/syswait.h | |||
| @@ -52,9 +52,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 52 | #define WTERMSIG(status) ((status) & 0x7f) | 52 | #define WTERMSIG(status) ((status) & 0x7f) |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | /* Defined in process.c. */ | ||
| 56 | extern void record_deleted_pid (pid_t); | ||
| 57 | |||
| 58 | /* Defined in sysdep.c. */ | 55 | /* Defined in sysdep.c. */ |
| 59 | extern void wait_for_termination (pid_t, int *, bool); | 56 | extern void wait_for_termination (pid_t, int *, bool); |
| 60 | extern pid_t child_status_changed (pid_t, int *, int); | 57 | extern pid_t child_status_changed (pid_t, int *, int); |
diff --git a/src/term.c b/src/term.c index fb69aefbe7a..aa61fde06ee 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2233,8 +2233,7 @@ get_named_tty (const char *name) | |||
| 2233 | { | 2233 | { |
| 2234 | struct terminal *t; | 2234 | struct terminal *t; |
| 2235 | 2235 | ||
| 2236 | if (!name) | 2236 | eassert (name); |
| 2237 | emacs_abort (); | ||
| 2238 | 2237 | ||
| 2239 | for (t = terminal_list; t; t = t->next_terminal) | 2238 | for (t = terminal_list; t; t = t->next_terminal) |
| 2240 | { | 2239 | { |
| @@ -2786,8 +2785,7 @@ create_tty_output (struct frame *f) | |||
| 2786 | { | 2785 | { |
| 2787 | struct tty_output *t = xzalloc (sizeof *t); | 2786 | struct tty_output *t = xzalloc (sizeof *t); |
| 2788 | 2787 | ||
| 2789 | if (! FRAME_TERMCAP_P (f)) | 2788 | eassert (FRAME_TERMCAP_P (f)); |
| 2790 | emacs_abort (); | ||
| 2791 | 2789 | ||
| 2792 | t->display_info = FRAME_TERMINAL (f)->display_info.tty; | 2790 | t->display_info = FRAME_TERMINAL (f)->display_info.tty; |
| 2793 | 2791 | ||
| @@ -2799,8 +2797,7 @@ create_tty_output (struct frame *f) | |||
| 2799 | static void | 2797 | static void |
| 2800 | tty_free_frame_resources (struct frame *f) | 2798 | tty_free_frame_resources (struct frame *f) |
| 2801 | { | 2799 | { |
| 2802 | if (! FRAME_TERMCAP_P (f)) | 2800 | eassert (FRAME_TERMCAP_P (f)); |
| 2803 | emacs_abort (); | ||
| 2804 | 2801 | ||
| 2805 | if (FRAME_FACE_CACHE (f)) | 2802 | if (FRAME_FACE_CACHE (f)) |
| 2806 | free_frame_faces (f); | 2803 | free_frame_faces (f); |
| @@ -2815,8 +2812,7 @@ tty_free_frame_resources (struct frame *f) | |||
| 2815 | static void | 2812 | static void |
| 2816 | tty_free_frame_resources (struct frame *f) | 2813 | tty_free_frame_resources (struct frame *f) |
| 2817 | { | 2814 | { |
| 2818 | if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f)) | 2815 | eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); |
| 2819 | emacs_abort (); | ||
| 2820 | 2816 | ||
| 2821 | if (FRAME_FACE_CACHE (f)) | 2817 | if (FRAME_FACE_CACHE (f)) |
| 2822 | free_frame_faces (f); | 2818 | free_frame_faces (f); |
| @@ -2938,9 +2934,12 @@ dissociate_if_controlling_tty (int fd) | |||
| 2938 | struct terminal * | 2934 | struct terminal * |
| 2939 | init_tty (const char *name, const char *terminal_type, bool must_succeed) | 2935 | init_tty (const char *name, const char *terminal_type, bool must_succeed) |
| 2940 | { | 2936 | { |
| 2941 | char *area = NULL; | 2937 | #ifdef TERMINFO |
| 2938 | char **address = 0; | ||
| 2939 | #else | ||
| 2940 | char *area; | ||
| 2942 | char **address = &area; | 2941 | char **address = &area; |
| 2943 | int buffer_size = 4096; | 2942 | #endif |
| 2944 | int status; | 2943 | int status; |
| 2945 | struct tty_display_info *tty = NULL; | 2944 | struct tty_display_info *tty = NULL; |
| 2946 | struct terminal *terminal = NULL; | 2945 | struct terminal *terminal = NULL; |
| @@ -3028,12 +3027,16 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) | |||
| 3028 | 3027 | ||
| 3029 | Wcm_clear (tty); | 3028 | Wcm_clear (tty); |
| 3030 | 3029 | ||
| 3031 | tty->termcap_term_buffer = xmalloc (buffer_size); | ||
| 3032 | |||
| 3033 | /* On some systems, tgetent tries to access the controlling | 3030 | /* On some systems, tgetent tries to access the controlling |
| 3034 | terminal. */ | 3031 | terminal. */ |
| 3035 | block_tty_out_signal (); | 3032 | block_tty_out_signal (); |
| 3033 | #ifdef TERMINFO | ||
| 3034 | status = tgetent (0, terminal_type); | ||
| 3035 | #else | ||
| 3036 | status = tgetent (tty->termcap_term_buffer, terminal_type); | 3036 | status = tgetent (tty->termcap_term_buffer, terminal_type); |
| 3037 | if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1]) | ||
| 3038 | emacs_abort (); | ||
| 3039 | #endif | ||
| 3037 | unblock_tty_out_signal (); | 3040 | unblock_tty_out_signal (); |
| 3038 | 3041 | ||
| 3039 | if (status < 0) | 3042 | if (status < 0) |
| @@ -3065,11 +3068,8 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ | |||
| 3065 | } | 3068 | } |
| 3066 | 3069 | ||
| 3067 | #ifndef TERMINFO | 3070 | #ifndef TERMINFO |
| 3068 | if (strlen (tty->termcap_term_buffer) >= buffer_size) | 3071 | area = tty->termcap_strings_buffer; |
| 3069 | emacs_abort (); | ||
| 3070 | buffer_size = strlen (tty->termcap_term_buffer); | ||
| 3071 | #endif | 3072 | #endif |
| 3072 | tty->termcap_strings_buffer = area = xmalloc (buffer_size); | ||
| 3073 | tty->TS_ins_line = tgetstr ("al", address); | 3073 | tty->TS_ins_line = tgetstr ("al", address); |
| 3074 | tty->TS_ins_multi_lines = tgetstr ("AL", address); | 3074 | tty->TS_ins_multi_lines = tgetstr ("AL", address); |
| 3075 | tty->TS_bell = tgetstr ("bl", address); | 3075 | tty->TS_bell = tgetstr ("bl", address); |
| @@ -3443,8 +3443,7 @@ delete_tty (struct terminal *terminal) | |||
| 3443 | if (!terminal->name) | 3443 | if (!terminal->name) |
| 3444 | return; | 3444 | return; |
| 3445 | 3445 | ||
| 3446 | if (terminal->type != output_termcap) | 3446 | eassert (terminal->type == output_termcap); |
| 3447 | emacs_abort (); | ||
| 3448 | 3447 | ||
| 3449 | tty = terminal->display_info.tty; | 3448 | tty = terminal->display_info.tty; |
| 3450 | 3449 | ||
| @@ -3486,9 +3485,6 @@ delete_tty (struct terminal *terminal) | |||
| 3486 | 3485 | ||
| 3487 | xfree (tty->old_tty); | 3486 | xfree (tty->old_tty); |
| 3488 | xfree (tty->Wcm); | 3487 | xfree (tty->Wcm); |
| 3489 | xfree (tty->termcap_strings_buffer); | ||
| 3490 | xfree (tty->termcap_term_buffer); | ||
| 3491 | |||
| 3492 | xfree (tty); | 3488 | xfree (tty); |
| 3493 | } | 3489 | } |
| 3494 | 3490 | ||
diff --git a/src/termcap.c b/src/termcap.c index be05828eea6..aa225d9b3b1 100644 --- a/src/termcap.c +++ b/src/termcap.c | |||
| @@ -406,7 +406,7 @@ tgetent (char *bp, const char *name) | |||
| 406 | 406 | ||
| 407 | if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) | 407 | if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) |
| 408 | { | 408 | { |
| 409 | indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); | 409 | indirect = tgetst1 (find_capability (termcap_name, "tc"), 0); |
| 410 | if (!indirect) | 410 | if (!indirect) |
| 411 | { | 411 | { |
| 412 | if (!bp) | 412 | if (!bp) |
| @@ -490,7 +490,7 @@ tgetent (char *bp, const char *name) | |||
| 490 | /* Does this entry refer to another terminal type's entry? | 490 | /* Does this entry refer to another terminal type's entry? |
| 491 | If something is found, copy it into heap and null-terminate it. */ | 491 | If something is found, copy it into heap and null-terminate it. */ |
| 492 | tc_search_point = find_capability (tc_search_point, "tc"); | 492 | tc_search_point = find_capability (tc_search_point, "tc"); |
| 493 | term = tgetst1 (tc_search_point, (char **) 0); | 493 | term = tgetst1 (tc_search_point, 0); |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | emacs_close (fd); | 496 | emacs_close (fd); |
diff --git a/src/termchar.h b/src/termchar.h index 1c8e8646d4e..687f7fbd119 100644 --- a/src/termchar.h +++ b/src/termchar.h | |||
| @@ -16,6 +16,8 @@ GNU General Public License for more details. | |||
| 16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License |
| 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 18 | 18 | ||
| 19 | #include "dispextern.h" | ||
| 20 | |||
| 19 | /* Each termcap frame points to its own struct tty_output object in | 21 | /* Each termcap frame points to its own struct tty_output object in |
| 20 | the output_data.tty field. The tty_output structure contains the | 22 | the output_data.tty field. The tty_output structure contains the |
| 21 | information that is specific to termcap frames. */ | 23 | information that is specific to termcap frames. */ |
| @@ -28,6 +30,10 @@ struct tty_output | |||
| 28 | /* There is nothing else here at the moment... */ | 30 | /* There is nothing else here at the moment... */ |
| 29 | }; | 31 | }; |
| 30 | 32 | ||
| 33 | #ifndef TERMINFO | ||
| 34 | enum { TERMCAP_BUFFER_SIZE = 4096 }; | ||
| 35 | #endif | ||
| 36 | |||
| 31 | /* Parameters that are shared between frames on the same tty device. */ | 37 | /* Parameters that are shared between frames on the same tty device. */ |
| 32 | 38 | ||
| 33 | struct tty_display_info | 39 | struct tty_display_info |
| @@ -72,14 +78,15 @@ struct tty_display_info | |||
| 72 | mouse-face. */ | 78 | mouse-face. */ |
| 73 | Mouse_HLInfo mouse_highlight; | 79 | Mouse_HLInfo mouse_highlight; |
| 74 | 80 | ||
| 81 | #ifndef TERMINFO | ||
| 75 | /* Buffer used internally by termcap (see tgetent in the Termcap | 82 | /* Buffer used internally by termcap (see tgetent in the Termcap |
| 76 | manual). Only init_tty and delete_tty should change this. */ | 83 | manual). Only init_tty should use this. */ |
| 77 | char *termcap_term_buffer; | 84 | char termcap_term_buffer[TERMCAP_BUFFER_SIZE]; |
| 78 | 85 | ||
| 79 | /* Buffer storing terminal description strings (see tgetstr in the | 86 | /* Buffer storing terminal description strings (see tgetstr in the |
| 80 | Termcap manual). Only init_tty and delete_tty should change | 87 | Termcap manual). Only init_tty should use this. */ |
| 81 | this. */ | 88 | char termcap_strings_buffer[TERMCAP_BUFFER_SIZE]; |
| 82 | char *termcap_strings_buffer; | 89 | #endif |
| 83 | 90 | ||
| 84 | /* Strings, numbers and flags taken from the termcap entry. */ | 91 | /* Strings, numbers and flags taken from the termcap entry. */ |
| 85 | 92 | ||
diff --git a/src/termhooks.h b/src/termhooks.h index b49a7bc706b..77f98938edb 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -18,7 +18,9 @@ GNU General Public License for more details. | |||
| 18 | You should have received a copy of the GNU General Public License | 18 | You should have received a copy of the GNU General Public License |
| 19 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 19 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 20 | 20 | ||
| 21 | 21 | #ifndef EMACS_TERMHOOKS_H | |
| 22 | #define EMACS_TERMHOOKS_H | ||
| 23 | |||
| 22 | /* Miscellanea. */ | 24 | /* Miscellanea. */ |
| 23 | 25 | ||
| 24 | #include "systime.h" /* for Time */ | 26 | #include "systime.h" /* for Time */ |
| @@ -28,10 +30,6 @@ INLINE_HEADER_BEGIN | |||
| 28 | # define TERMHOOKS_INLINE INLINE | 30 | # define TERMHOOKS_INLINE INLINE |
| 29 | #endif | 31 | #endif |
| 30 | 32 | ||
| 31 | struct glyph; | ||
| 32 | struct frame; | ||
| 33 | |||
| 34 | |||
| 35 | enum scroll_bar_part { | 33 | enum scroll_bar_part { |
| 36 | scroll_bar_above_handle, | 34 | scroll_bar_above_handle, |
| 37 | scroll_bar_handle, | 35 | scroll_bar_handle, |
| @@ -49,7 +47,18 @@ enum scroll_bar_part { | |||
| 49 | may do something OS dependent, like extended window manager hints on X11. */ | 47 | may do something OS dependent, like extended window manager hints on X11. */ |
| 50 | extern void (*fullscreen_hook) (struct frame *f); | 48 | extern void (*fullscreen_hook) (struct frame *f); |
| 51 | 49 | ||
| 52 | 50 | /* Output method of a terminal (and frames on this terminal, respectively). */ | |
| 51 | |||
| 52 | enum output_method | ||
| 53 | { | ||
| 54 | output_initial, | ||
| 55 | output_termcap, | ||
| 56 | output_x_window, | ||
| 57 | output_msdos_raw, | ||
| 58 | output_w32, | ||
| 59 | output_ns | ||
| 60 | }; | ||
| 61 | |||
| 53 | /* Input queue declarations and hooks. */ | 62 | /* Input queue declarations and hooks. */ |
| 54 | 63 | ||
| 55 | enum event_kind | 64 | enum event_kind |
| @@ -321,11 +330,6 @@ extern void term_mouse_moveto (int, int); | |||
| 321 | extern struct tty_display_info *gpm_tty; | 330 | extern struct tty_display_info *gpm_tty; |
| 322 | #endif | 331 | #endif |
| 323 | 332 | ||
| 324 | |||
| 325 | struct ns_display_info; | ||
| 326 | struct x_display_info; | ||
| 327 | struct w32_display_info; | ||
| 328 | |||
| 329 | /* Terminal-local parameters. */ | 333 | /* Terminal-local parameters. */ |
| 330 | struct terminal | 334 | struct terminal |
| 331 | { | 335 | { |
| @@ -660,3 +664,5 @@ extern void close_gpm (int gpm_fd); | |||
| 660 | #endif | 664 | #endif |
| 661 | 665 | ||
| 662 | INLINE_HEADER_END | 666 | INLINE_HEADER_END |
| 667 | |||
| 668 | #endif /* EMACS_TERMHOOKS_H */ | ||
diff --git a/src/textprop.c b/src/textprop.c index 282ae11d4ac..b804f345047 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -93,15 +93,25 @@ text_read_only (Lisp_Object propval) | |||
| 93 | xsignal0 (Qtext_read_only); | 93 | xsignal0 (Qtext_read_only); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | /* Prepare to modify the region of BUFFER from START to END. */ | 96 | /* Prepare to modify the text properties of BUFFER from START to END. */ |
| 97 | 97 | ||
| 98 | static void | 98 | static void |
| 99 | modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) | 99 | modify_text_properties (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) |
| 100 | { | 100 | { |
| 101 | ptrdiff_t b = XINT (start), e = XINT (end); | ||
| 101 | struct buffer *buf = XBUFFER (buffer), *old = current_buffer; | 102 | struct buffer *buf = XBUFFER (buffer), *old = current_buffer; |
| 102 | 103 | ||
| 103 | set_buffer_internal (buf); | 104 | set_buffer_internal (buf); |
| 104 | modify_region_1 (XINT (start), XINT (end), true); | 105 | |
| 106 | prepare_to_modify_buffer_1 (b, e, NULL); | ||
| 107 | |||
| 108 | BUF_COMPUTE_UNCHANGED (buf, b - 1, e); | ||
| 109 | if (MODIFF <= SAVE_MODIFF) | ||
| 110 | record_first_change (); | ||
| 111 | MODIFF++; | ||
| 112 | |||
| 113 | bset_point_before_scroll (current_buffer, Qnil); | ||
| 114 | |||
| 105 | set_buffer_internal (old); | 115 | set_buffer_internal (old); |
| 106 | } | 116 | } |
| 107 | 117 | ||
| @@ -1213,9 +1223,9 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end, | |||
| 1213 | ptrdiff_t prev_total_length = TOTAL_LENGTH (i); | 1223 | ptrdiff_t prev_total_length = TOTAL_LENGTH (i); |
| 1214 | ptrdiff_t prev_pos = i->position; | 1224 | ptrdiff_t prev_pos = i->position; |
| 1215 | 1225 | ||
| 1216 | modify_region (object, start, end); | 1226 | modify_text_properties (object, start, end); |
| 1217 | /* If someone called us recursively as a side effect of | 1227 | /* If someone called us recursively as a side effect of |
| 1218 | modify_region, and changed the intervals behind our back | 1228 | modify_text_properties, and changed the intervals behind our back |
| 1219 | (could happen if lock_file, called by prepare_to_modify_buffer, | 1229 | (could happen if lock_file, called by prepare_to_modify_buffer, |
| 1220 | triggers redisplay, and that calls add-text-properties again | 1230 | triggers redisplay, and that calls add-text-properties again |
| 1221 | in the same buffer), we cannot continue with I, because its | 1231 | in the same buffer), we cannot continue with I, because its |
| @@ -1357,7 +1367,8 @@ into it. */) | |||
| 1357 | otherwise. */ | 1367 | otherwise. */ |
| 1358 | 1368 | ||
| 1359 | Lisp_Object | 1369 | Lisp_Object |
| 1360 | set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, Lisp_Object coherent_change_p) | 1370 | set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, |
| 1371 | Lisp_Object object, Lisp_Object coherent_change_p) | ||
| 1361 | { | 1372 | { |
| 1362 | register INTERVAL i; | 1373 | register INTERVAL i; |
| 1363 | Lisp_Object ostart, oend; | 1374 | Lisp_Object ostart, oend; |
| @@ -1403,7 +1414,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1403 | } | 1414 | } |
| 1404 | 1415 | ||
| 1405 | if (BUFFERP (object) && !NILP (coherent_change_p)) | 1416 | if (BUFFERP (object) && !NILP (coherent_change_p)) |
| 1406 | modify_region (object, start, end); | 1417 | modify_text_properties (object, start, end); |
| 1407 | 1418 | ||
| 1408 | set_text_properties_1 (start, end, properties, object, i); | 1419 | set_text_properties_1 (start, end, properties, object, i); |
| 1409 | 1420 | ||
| @@ -1558,9 +1569,9 @@ Use `set-text-properties' if you want to remove all text properties. */) | |||
| 1558 | ptrdiff_t prev_total_length = TOTAL_LENGTH (i); | 1569 | ptrdiff_t prev_total_length = TOTAL_LENGTH (i); |
| 1559 | ptrdiff_t prev_pos = i->position; | 1570 | ptrdiff_t prev_pos = i->position; |
| 1560 | 1571 | ||
| 1561 | modify_region (object, start, end); | 1572 | modify_text_properties (object, start, end); |
| 1562 | /* If someone called us recursively as a side effect of | 1573 | /* If someone called us recursively as a side effect of |
| 1563 | modify_region, and changed the intervals behind our back | 1574 | modify_text_properties, and changed the intervals behind our back |
| 1564 | (could happen if lock_file, called by prepare_to_modify_buffer, | 1575 | (could happen if lock_file, called by prepare_to_modify_buffer, |
| 1565 | triggers redisplay, and that calls add-text-properties again | 1576 | triggers redisplay, and that calls add-text-properties again |
| 1566 | in the same buffer), we cannot continue with I, because its | 1577 | in the same buffer), we cannot continue with I, because its |
| @@ -1667,9 +1678,9 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1667 | 1678 | ||
| 1668 | /* We are at the beginning of an interval, with len to scan. | 1679 | /* We are at the beginning of an interval, with len to scan. |
| 1669 | The flag `modified' records if changes have been made. | 1680 | The flag `modified' records if changes have been made. |
| 1670 | When object is a buffer, we must call modify_region before changes are | 1681 | When object is a buffer, we must call modify_text_properties |
| 1671 | made and signal_after_change when we are done. | 1682 | before changes are made and signal_after_change when we are done. |
| 1672 | We call modify_region before calling remove_properties if modified == 0, | 1683 | We call modify_text_properties before calling remove_properties if modified == 0, |
| 1673 | and we call signal_after_change before returning if modified != 0. */ | 1684 | and we call signal_after_change before returning if modified != 0. */ |
| 1674 | for (;;) | 1685 | for (;;) |
| 1675 | { | 1686 | { |
| @@ -1693,7 +1704,7 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1693 | else if (LENGTH (i) == len) | 1704 | else if (LENGTH (i) == len) |
| 1694 | { | 1705 | { |
| 1695 | if (!modified && BUFFERP (object)) | 1706 | if (!modified && BUFFERP (object)) |
| 1696 | modify_region (object, start, end); | 1707 | modify_text_properties (object, start, end); |
| 1697 | remove_properties (Qnil, properties, i, object); | 1708 | remove_properties (Qnil, properties, i, object); |
| 1698 | if (BUFFERP (object)) | 1709 | if (BUFFERP (object)) |
| 1699 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1710 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| @@ -1706,7 +1717,7 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1706 | i = split_interval_left (i, len); | 1717 | i = split_interval_left (i, len); |
| 1707 | copy_properties (unchanged, i); | 1718 | copy_properties (unchanged, i); |
| 1708 | if (!modified && BUFFERP (object)) | 1719 | if (!modified && BUFFERP (object)) |
| 1709 | modify_region (object, start, end); | 1720 | modify_text_properties (object, start, end); |
| 1710 | remove_properties (Qnil, properties, i, object); | 1721 | remove_properties (Qnil, properties, i, object); |
| 1711 | if (BUFFERP (object)) | 1722 | if (BUFFERP (object)) |
| 1712 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1723 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| @@ -1717,7 +1728,7 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1717 | if (interval_has_some_properties_list (properties, i)) | 1728 | if (interval_has_some_properties_list (properties, i)) |
| 1718 | { | 1729 | { |
| 1719 | if (!modified && BUFFERP (object)) | 1730 | if (!modified && BUFFERP (object)) |
| 1720 | modify_region (object, start, end); | 1731 | modify_text_properties (object, start, end); |
| 1721 | remove_properties (Qnil, properties, i, object); | 1732 | remove_properties (Qnil, properties, i, object); |
| 1722 | modified = 1; | 1733 | modified = 1; |
| 1723 | } | 1734 | } |
diff --git a/src/w16select.c b/src/w16select.c index 3bcc663e565..864757b3e61 100644 --- a/src/w16select.c +++ b/src/w16select.c | |||
| @@ -452,11 +452,7 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat | |||
| 452 | 452 | ||
| 453 | CHECK_STRING (string); | 453 | CHECK_STRING (string); |
| 454 | 454 | ||
| 455 | if (NILP (frame)) | 455 | if (!FRAME_MSDOS_P (decode_live_frame (frame))) |
| 456 | frame = Fselected_frame (); | ||
| 457 | |||
| 458 | CHECK_LIVE_FRAME (frame); | ||
| 459 | if ( !FRAME_MSDOS_P (XFRAME (frame))) | ||
| 460 | goto done; | 456 | goto done; |
| 461 | 457 | ||
| 462 | block_input (); | 458 | block_input (); |
| @@ -558,11 +554,7 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat | |||
| 558 | Lisp_Object ret = Qnil; | 554 | Lisp_Object ret = Qnil; |
| 559 | int require_decoding = 0; | 555 | int require_decoding = 0; |
| 560 | 556 | ||
| 561 | if (NILP (frame)) | 557 | if (!FRAME_MSDOS_P (decode_live_frame (frame))) |
| 562 | frame = Fselected_frame (); | ||
| 563 | |||
| 564 | CHECK_LIVE_FRAME (frame); | ||
| 565 | if ( !FRAME_MSDOS_P (XFRAME (frame))) | ||
| 566 | goto done; | 558 | goto done; |
| 567 | 559 | ||
| 568 | block_input (); | 560 | block_input (); |
| @@ -47,7 +47,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 47 | #undef fopen | 47 | #undef fopen |
| 48 | #undef link | 48 | #undef link |
| 49 | #undef mkdir | 49 | #undef mkdir |
| 50 | #undef mktemp | ||
| 51 | #undef open | 50 | #undef open |
| 52 | #undef rename | 51 | #undef rename |
| 53 | #undef rmdir | 52 | #undef rmdir |
| @@ -90,6 +89,21 @@ typedef struct _MEMORY_STATUS_EX { | |||
| 90 | DWORDLONG ullAvailExtendedVirtual; | 89 | DWORDLONG ullAvailExtendedVirtual; |
| 91 | } MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX; | 90 | } MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX; |
| 92 | 91 | ||
| 92 | /* These are here so that GDB would know about these data types. This | ||
| 93 | allows to attach GDB to Emacs when a fatal exception is triggered | ||
| 94 | and Windows pops up the "application needs to be closed" dialog. | ||
| 95 | At that point, _gnu_exception_handler, the top-level exception | ||
| 96 | handler installed by the MinGW startup code, is somewhere on the | ||
| 97 | call-stack of the main thread, so going to that call frame and | ||
| 98 | looking at the argument to _gnu_exception_handler, which is a | ||
| 99 | PEXCEPTION_POINTERS pointer, can reveal the exception code | ||
| 100 | (excptr->ExceptionRecord->ExceptionCode) and the address where the | ||
| 101 | exception happened (excptr->ExceptionRecord->ExceptionAddress), as | ||
| 102 | well as some additional information specific to the exception. */ | ||
| 103 | PEXCEPTION_POINTERS excptr; | ||
| 104 | PEXCEPTION_RECORD excprec; | ||
| 105 | PCONTEXT ctxrec; | ||
| 106 | |||
| 93 | #include <lmcons.h> | 107 | #include <lmcons.h> |
| 94 | #include <shlobj.h> | 108 | #include <shlobj.h> |
| 95 | 109 | ||
| @@ -233,7 +247,7 @@ static BOOL WINAPI revert_to_self (void); | |||
| 233 | extern int sys_access (const char *, int); | 247 | extern int sys_access (const char *, int); |
| 234 | extern void *e_malloc (size_t); | 248 | extern void *e_malloc (size_t); |
| 235 | extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, | 249 | extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, |
| 236 | EMACS_TIME *, void *); | 250 | struct timespec *, void *); |
| 237 | extern int sys_dup (int); | 251 | extern int sys_dup (int); |
| 238 | 252 | ||
| 239 | 253 | ||
| @@ -2489,8 +2503,6 @@ gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz) | |||
| 2489 | int | 2503 | int |
| 2490 | fdutimens (int fd, char const *file, struct timespec const timespec[2]) | 2504 | fdutimens (int fd, char const *file, struct timespec const timespec[2]) |
| 2491 | { | 2505 | { |
| 2492 | struct _utimbuf ut; | ||
| 2493 | |||
| 2494 | if (!timespec) | 2506 | if (!timespec) |
| 2495 | { | 2507 | { |
| 2496 | errno = ENOSYS; | 2508 | errno = ENOSYS; |
| @@ -2501,12 +2513,28 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) | |||
| 2501 | errno = EBADF; | 2513 | errno = EBADF; |
| 2502 | return -1; | 2514 | return -1; |
| 2503 | } | 2515 | } |
| 2504 | ut.actime = timespec[0].tv_sec; | 2516 | /* _futime's prototype defines 2nd arg as having the type 'struct |
| 2505 | ut.modtime = timespec[1].tv_sec; | 2517 | _utimbuf', while utime needs to accept 'struct utimbuf' for |
| 2518 | compatibility with Posix. So we need to use 2 different (but | ||
| 2519 | equivalent) types to avoid compiler warnings, sigh. */ | ||
| 2506 | if (fd >= 0) | 2520 | if (fd >= 0) |
| 2507 | return _futime (fd, &ut); | 2521 | { |
| 2522 | struct _utimbuf _ut; | ||
| 2523 | |||
| 2524 | _ut.actime = timespec[0].tv_sec; | ||
| 2525 | _ut.modtime = timespec[1].tv_sec; | ||
| 2526 | return _futime (fd, &_ut); | ||
| 2527 | } | ||
| 2508 | else | 2528 | else |
| 2509 | return _utime (file, &ut); | 2529 | { |
| 2530 | struct utimbuf ut; | ||
| 2531 | |||
| 2532 | ut.actime = timespec[0].tv_sec; | ||
| 2533 | ut.modtime = timespec[1].tv_sec; | ||
| 2534 | /* Call 'utime', which is implemented below, not the MS library | ||
| 2535 | function, which fails on directories. */ | ||
| 2536 | return utime (file, &ut); | ||
| 2537 | } | ||
| 2510 | } | 2538 | } |
| 2511 | 2539 | ||
| 2512 | 2540 | ||
| @@ -3414,25 +3442,46 @@ sys_mkdir (const char * path) | |||
| 3414 | return _mkdir (map_w32_filename (path, NULL)); | 3442 | return _mkdir (map_w32_filename (path, NULL)); |
| 3415 | } | 3443 | } |
| 3416 | 3444 | ||
| 3417 | /* Because of long name mapping issues, we need to implement this | 3445 | int |
| 3418 | ourselves. Also, MSVC's _mktemp returns NULL when it can't generate | 3446 | sys_open (const char * path, int oflag, int mode) |
| 3419 | a unique name, instead of setting the input template to an empty | 3447 | { |
| 3420 | string. | 3448 | const char* mpath = map_w32_filename (path, NULL); |
| 3449 | int res = -1; | ||
| 3450 | |||
| 3451 | /* If possible, try to open file without _O_CREAT, to be able to | ||
| 3452 | write to existing hidden and system files. Force all file | ||
| 3453 | handles to be non-inheritable. */ | ||
| 3454 | if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL)) | ||
| 3455 | res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); | ||
| 3456 | if (res < 0) | ||
| 3457 | res = _open (mpath, oflag | _O_NOINHERIT, mode); | ||
| 3458 | |||
| 3459 | return res; | ||
| 3460 | } | ||
| 3461 | |||
| 3462 | /* Implementation of mkostemp for MS-Windows, to avoid race conditions | ||
| 3463 | when using mktemp. | ||
| 3421 | 3464 | ||
| 3422 | Standard algorithm seems to be use pid or tid with a letter on the | 3465 | Standard algorithm for generating a temporary file name seems to be |
| 3423 | front (in place of the 6 X's) and cycle through the letters to find a | 3466 | use pid or tid with a letter on the front (in place of the 6 X's) |
| 3424 | unique name. We extend that to allow any reasonable character as the | 3467 | and cycle through the letters to find a unique name. We extend |
| 3425 | first of the 6 X's. */ | 3468 | that to allow any reasonable character as the first of the 6 X's, |
| 3426 | char * | 3469 | so that the number of simultaneously used temporary files will be |
| 3427 | sys_mktemp (char * template) | 3470 | greater. */ |
| 3471 | |||
| 3472 | int | ||
| 3473 | mkostemp (char * template, int flags) | ||
| 3428 | { | 3474 | { |
| 3429 | char * p; | 3475 | char * p; |
| 3430 | int i; | 3476 | int i, fd = -1; |
| 3431 | unsigned uid = GetCurrentThreadId (); | 3477 | unsigned uid = GetCurrentThreadId (); |
| 3478 | int save_errno = errno; | ||
| 3432 | static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; | 3479 | static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; |
| 3433 | 3480 | ||
| 3481 | errno = EINVAL; | ||
| 3434 | if (template == NULL) | 3482 | if (template == NULL) |
| 3435 | return NULL; | 3483 | return -1; |
| 3484 | |||
| 3436 | p = template + strlen (template); | 3485 | p = template + strlen (template); |
| 3437 | i = 5; | 3486 | i = 5; |
| 3438 | /* replace up to the last 5 X's with uid in decimal */ | 3487 | /* replace up to the last 5 X's with uid in decimal */ |
| @@ -3447,38 +3496,22 @@ sys_mktemp (char * template) | |||
| 3447 | i = 0; | 3496 | i = 0; |
| 3448 | do | 3497 | do |
| 3449 | { | 3498 | { |
| 3450 | int save_errno = errno; | ||
| 3451 | p[0] = first_char[i]; | 3499 | p[0] = first_char[i]; |
| 3452 | if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0) | 3500 | if ((fd = sys_open (template, |
| 3501 | flags | _O_CREAT | _O_EXCL | _O_RDWR, | ||
| 3502 | S_IRUSR | S_IWUSR)) >= 0 | ||
| 3503 | || errno != EEXIST) | ||
| 3453 | { | 3504 | { |
| 3454 | errno = save_errno; | 3505 | if (fd >= 0) |
| 3455 | return template; | 3506 | errno = save_errno; |
| 3507 | return fd; | ||
| 3456 | } | 3508 | } |
| 3457 | } | 3509 | } |
| 3458 | while (++i < sizeof (first_char)); | 3510 | while (++i < sizeof (first_char)); |
| 3459 | } | 3511 | } |
| 3460 | 3512 | ||
| 3461 | /* Template is badly formed or else we can't generate a unique name, | 3513 | /* Template is badly formed or else we can't generate a unique name. */ |
| 3462 | so return empty string */ | 3514 | return -1; |
| 3463 | template[0] = 0; | ||
| 3464 | return template; | ||
| 3465 | } | ||
| 3466 | |||
| 3467 | int | ||
| 3468 | sys_open (const char * path, int oflag, int mode) | ||
| 3469 | { | ||
| 3470 | const char* mpath = map_w32_filename (path, NULL); | ||
| 3471 | int res = -1; | ||
| 3472 | |||
| 3473 | /* If possible, try to open file without _O_CREAT, to be able to | ||
| 3474 | write to existing hidden and system files. Force all file | ||
| 3475 | handles to be non-inheritable. */ | ||
| 3476 | if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL)) | ||
| 3477 | res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); | ||
| 3478 | if (res < 0) | ||
| 3479 | res = _open (mpath, oflag | _O_NOINHERIT, mode); | ||
| 3480 | |||
| 3481 | return res; | ||
| 3482 | } | 3515 | } |
| 3483 | 3516 | ||
| 3484 | int | 3517 | int |
| @@ -4482,6 +4515,9 @@ fstat (int desc, struct stat * buf) | |||
| 4482 | return 0; | 4515 | return 0; |
| 4483 | } | 4516 | } |
| 4484 | 4517 | ||
| 4518 | /* A version of 'utime' which handles directories as well as | ||
| 4519 | files. */ | ||
| 4520 | |||
| 4485 | int | 4521 | int |
| 4486 | utime (const char *name, struct utimbuf *times) | 4522 | utime (const char *name, struct utimbuf *times) |
| 4487 | { | 4523 | { |
| @@ -5750,8 +5786,8 @@ system_process_attributes (Lisp_Object pid) | |||
| 5750 | { | 5786 | { |
| 5751 | /* Decode the command name from locale-specific | 5787 | /* Decode the command name from locale-specific |
| 5752 | encoding. */ | 5788 | encoding. */ |
| 5753 | cmd_str = make_unibyte_string (pe.szExeFile, | 5789 | cmd_str = build_unibyte_string (pe.szExeFile); |
| 5754 | strlen (pe.szExeFile)); | 5790 | |
| 5755 | decoded_cmd = | 5791 | decoded_cmd = |
| 5756 | code_convert_string_norecord (cmd_str, | 5792 | code_convert_string_norecord (cmd_str, |
| 5757 | Vlocale_coding_system, 0); | 5793 | Vlocale_coding_system, 0); |
| @@ -6056,6 +6092,7 @@ term_winsock (void) | |||
| 6056 | { | 6092 | { |
| 6057 | if (winsock_lib != NULL && winsock_inuse == 0) | 6093 | if (winsock_lib != NULL && winsock_inuse == 0) |
| 6058 | { | 6094 | { |
| 6095 | release_listen_threads (); | ||
| 6059 | /* Not sure what would cause WSAENETDOWN, or even if it can happen | 6096 | /* Not sure what would cause WSAENETDOWN, or even if it can happen |
| 6060 | after WSAStartup returns successfully, but it seems reasonable | 6097 | after WSAStartup returns successfully, but it seems reasonable |
| 6061 | to allow unloading winsock anyway in that case. */ | 6098 | to allow unloading winsock anyway in that case. */ |
| @@ -7040,7 +7077,12 @@ _sys_wait_accept (int fd) | |||
| 7040 | rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT); | 7077 | rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT); |
| 7041 | if (rc != SOCKET_ERROR) | 7078 | if (rc != SOCKET_ERROR) |
| 7042 | { | 7079 | { |
| 7043 | rc = WaitForSingleObject (hEv, INFINITE); | 7080 | do { |
| 7081 | rc = WaitForSingleObject (hEv, 500); | ||
| 7082 | Sleep (5); | ||
| 7083 | } while (rc == WAIT_TIMEOUT | ||
| 7084 | && cp->status != STATUS_READ_ERROR | ||
| 7085 | && cp->char_avail); | ||
| 7044 | pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0); | 7086 | pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0); |
| 7045 | if (rc == WAIT_OBJECT_0) | 7087 | if (rc == WAIT_OBJECT_0) |
| 7046 | cp->status = STATUS_READ_SUCCEEDED; | 7088 | cp->status = STATUS_READ_SUCCEEDED; |
| @@ -7903,7 +7945,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz) | |||
| 7903 | { | 7945 | { |
| 7904 | int n, err; | 7946 | int n, err; |
| 7905 | SELECT_TYPE fdset; | 7947 | SELECT_TYPE fdset; |
| 7906 | EMACS_TIME timeout; | 7948 | struct timespec timeout; |
| 7907 | struct Lisp_Process *process = (struct Lisp_Process *)p; | 7949 | struct Lisp_Process *process = (struct Lisp_Process *)p; |
| 7908 | int fd = process->infd; | 7950 | int fd = process->infd; |
| 7909 | 7951 | ||
| @@ -163,6 +163,7 @@ extern void reset_standard_handles (int in, int out, | |||
| 163 | /* Return the string resource associated with KEY of type TYPE. */ | 163 | /* Return the string resource associated with KEY of type TYPE. */ |
| 164 | extern LPBYTE w32_get_resource (char * key, LPDWORD type); | 164 | extern LPBYTE w32_get_resource (char * key, LPDWORD type); |
| 165 | 165 | ||
| 166 | extern void release_listen_threads (void); | ||
| 166 | extern void init_ntproc (int); | 167 | extern void init_ntproc (int); |
| 167 | extern void term_ntproc (int); | 168 | extern void term_ntproc (int); |
| 168 | extern void globals_of_w32 (void); | 169 | extern void globals_of_w32 (void); |
diff --git a/src/w32console.c b/src/w32console.c index ee92a593301..8da1ccf1892 100644 --- a/src/w32console.c +++ b/src/w32console.c | |||
| @@ -53,7 +53,6 @@ static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len) | |||
| 53 | static void w32con_delete_glyphs (struct frame *f, int n); | 53 | static void w32con_delete_glyphs (struct frame *f, int n); |
| 54 | static void w32con_reset_terminal_modes (struct terminal *t); | 54 | static void w32con_reset_terminal_modes (struct terminal *t); |
| 55 | static void w32con_set_terminal_modes (struct terminal *t); | 55 | static void w32con_set_terminal_modes (struct terminal *t); |
| 56 | static void w32con_set_terminal_window (struct frame *f, int size); | ||
| 57 | static void w32con_update_begin (struct frame * f); | 56 | static void w32con_update_begin (struct frame * f); |
| 58 | static void w32con_update_end (struct frame * f); | 57 | static void w32con_update_end (struct frame * f); |
| 59 | static WORD w32_face_attributes (struct frame *f, int face_id); | 58 | static WORD w32_face_attributes (struct frame *f, int face_id); |
| @@ -497,11 +496,6 @@ w32con_update_end (struct frame * f) | |||
| 497 | SetConsoleCursorPosition (cur_screen, cursor_coords); | 496 | SetConsoleCursorPosition (cur_screen, cursor_coords); |
| 498 | } | 497 | } |
| 499 | 498 | ||
| 500 | static void | ||
| 501 | w32con_set_terminal_window (struct frame *f, int size) | ||
| 502 | { | ||
| 503 | } | ||
| 504 | |||
| 505 | /*********************************************************************** | 499 | /*********************************************************************** |
| 506 | stubs from termcap.c | 500 | stubs from termcap.c |
| 507 | ***********************************************************************/ | 501 | ***********************************************************************/ |
| @@ -619,7 +613,7 @@ initialize_w32_display (struct terminal *term, int *width, int *height) | |||
| 619 | term->ring_bell_hook = w32_sys_ring_bell; | 613 | term->ring_bell_hook = w32_sys_ring_bell; |
| 620 | term->reset_terminal_modes_hook = w32con_reset_terminal_modes; | 614 | term->reset_terminal_modes_hook = w32con_reset_terminal_modes; |
| 621 | term->set_terminal_modes_hook = w32con_set_terminal_modes; | 615 | term->set_terminal_modes_hook = w32con_set_terminal_modes; |
| 622 | term->set_terminal_window_hook = w32con_set_terminal_window; | 616 | term->set_terminal_window_hook = NULL; |
| 623 | term->update_begin_hook = w32con_update_begin; | 617 | term->update_begin_hook = w32con_update_begin; |
| 624 | term->update_end_hook = w32con_update_end; | 618 | term->update_end_hook = w32con_update_end; |
| 625 | 619 | ||
| @@ -636,13 +630,7 @@ initialize_w32_display (struct terminal *term, int *width, int *height) | |||
| 636 | term->frame_up_to_date_hook = 0; | 630 | term->frame_up_to_date_hook = 0; |
| 637 | 631 | ||
| 638 | /* Initialize the mouse-highlight data. */ | 632 | /* Initialize the mouse-highlight data. */ |
| 639 | hlinfo = &term->display_info.tty->mouse_highlight; | 633 | reset_mouse_highlight (&term->display_info.tty->mouse_highlight); |
| 640 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 641 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 642 | hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; | ||
| 643 | hlinfo->mouse_face_mouse_frame = NULL; | ||
| 644 | hlinfo->mouse_face_window = Qnil; | ||
| 645 | hlinfo->mouse_face_hidden = 0; | ||
| 646 | 634 | ||
| 647 | /* Initialize interrupt_handle. */ | 635 | /* Initialize interrupt_handle. */ |
| 648 | init_crit (); | 636 | init_crit (); |
diff --git a/src/w32fns.c b/src/w32fns.c index dff35de0973..b8c445a3a36 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -1528,11 +1528,8 @@ void | |||
| 1528 | x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | 1528 | x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) |
| 1529 | { | 1529 | { |
| 1530 | set_frame_cursor_types (f, arg); | 1530 | set_frame_cursor_types (f, arg); |
| 1531 | |||
| 1532 | /* Make sure the cursor gets redrawn. */ | ||
| 1533 | cursor_type_changed = 1; | ||
| 1534 | } | 1531 | } |
| 1535 | 1532 | ||
| 1536 | void | 1533 | void |
| 1537 | x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | 1534 | x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) |
| 1538 | { | 1535 | { |
| @@ -4124,12 +4121,7 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only) | |||
| 4124 | for the window manager, so GC relocation won't bother it. | 4121 | for the window manager, so GC relocation won't bother it. |
| 4125 | 4122 | ||
| 4126 | Elsewhere we specify the window name for the window manager. */ | 4123 | Elsewhere we specify the window name for the window manager. */ |
| 4127 | 4124 | f->namebuf = xstrdup (SSDATA (Vx_resource_name)); | |
| 4128 | { | ||
| 4129 | char *str = SSDATA (Vx_resource_name); | ||
| 4130 | f->namebuf = xmalloc (strlen (str) + 1); | ||
| 4131 | strcpy (f->namebuf, str); | ||
| 4132 | } | ||
| 4133 | 4125 | ||
| 4134 | my_create_window (f); | 4126 | my_create_window (f); |
| 4135 | 4127 | ||
| @@ -4992,8 +4984,8 @@ w32_display_monitor_attributes_list (void) | |||
| 4992 | attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), | 4984 | attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), |
| 4993 | attributes); | 4985 | attributes); |
| 4994 | 4986 | ||
| 4995 | name = DECODE_SYSTEM (make_unibyte_string (mi.szDevice, | 4987 | name = DECODE_SYSTEM (build_unibyte_string (mi.szDevice)); |
| 4996 | strlen (mi.szDevice))); | 4988 | |
| 4997 | attributes = Fcons (Fcons (Qname, name), attributes); | 4989 | attributes = Fcons (Fcons (Qname, name), attributes); |
| 4998 | 4990 | ||
| 4999 | attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), | 4991 | attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), |
diff --git a/src/w32proc.c b/src/w32proc.c index 84589388cd7..dabaa62f71c 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -990,6 +990,18 @@ find_child_pid (DWORD pid) | |||
| 990 | return NULL; | 990 | return NULL; |
| 991 | } | 991 | } |
| 992 | 992 | ||
| 993 | void | ||
| 994 | release_listen_threads (void) | ||
| 995 | { | ||
| 996 | int i; | ||
| 997 | |||
| 998 | for (i = child_proc_count - 1; i >= 0; i--) | ||
| 999 | { | ||
| 1000 | if (CHILD_ACTIVE (&child_procs[i]) | ||
| 1001 | && (fd_info[child_procs[i].fd].flags & FILE_LISTEN)) | ||
| 1002 | child_procs[i].status = STATUS_READ_ERROR; | ||
| 1003 | } | ||
| 1004 | } | ||
| 993 | 1005 | ||
| 994 | /* Thread proc for child process and socket reader threads. Each thread | 1006 | /* Thread proc for child process and socket reader threads. Each thread |
| 995 | is normally blocked until woken by select() to check for input by | 1007 | is normally blocked until woken by select() to check for input by |
| @@ -1916,7 +1928,7 @@ extern int proc_buffered_char[]; | |||
| 1916 | 1928 | ||
| 1917 | int | 1929 | int |
| 1918 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | 1930 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, |
| 1919 | EMACS_TIME *timeout, void *ignored) | 1931 | struct timespec *timeout, void *ignored) |
| 1920 | { | 1932 | { |
| 1921 | SELECT_TYPE orfds; | 1933 | SELECT_TYPE orfds; |
| 1922 | DWORD timeout_ms, start_time; | 1934 | DWORD timeout_ms, start_time; |
diff --git a/src/w32term.c b/src/w32term.c index 59cfdee86b0..532ded7cdad 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -84,9 +84,6 @@ static int last_mousemove_y = 0; | |||
| 84 | 84 | ||
| 85 | static int any_help_event_p; | 85 | static int any_help_event_p; |
| 86 | 86 | ||
| 87 | /* Last window where we saw the mouse. Used by mouse-autoselect-window. */ | ||
| 88 | static Lisp_Object last_window; | ||
| 89 | |||
| 90 | extern unsigned int msh_mousewheel; | 87 | extern unsigned int msh_mousewheel; |
| 91 | 88 | ||
| 92 | extern void free_frame_menubar (struct frame *); | 89 | extern void free_frame_menubar (struct frame *); |
| @@ -210,7 +207,6 @@ static int volatile input_signal_count; | |||
| 210 | int w32_message_fd = -1; | 207 | int w32_message_fd = -1; |
| 211 | #endif /* CYGWIN */ | 208 | #endif /* CYGWIN */ |
| 212 | 209 | ||
| 213 | static void x_update_window_end (struct window *, int, int); | ||
| 214 | static void w32_handle_tool_bar_click (struct frame *, | 210 | static void w32_handle_tool_bar_click (struct frame *, |
| 215 | struct input_event *); | 211 | struct input_event *); |
| 216 | static void w32_define_cursor (Window, Cursor); | 212 | static void w32_define_cursor (Window, Cursor); |
| @@ -225,8 +221,6 @@ void x_wm_set_icon_pixmap (struct frame *, int); | |||
| 225 | static void w32_initialize (void); | 221 | static void w32_initialize (void); |
| 226 | static void x_update_end (struct frame *); | 222 | static void x_update_end (struct frame *); |
| 227 | static void w32_frame_up_to_date (struct frame *); | 223 | static void w32_frame_up_to_date (struct frame *); |
| 228 | static void w32_set_terminal_modes (struct terminal *); | ||
| 229 | static void w32_reset_terminal_modes (struct terminal *); | ||
| 230 | static void x_clear_frame (struct frame *); | 224 | static void x_clear_frame (struct frame *); |
| 231 | static void frame_highlight (struct frame *); | 225 | static void frame_highlight (struct frame *); |
| 232 | static void frame_unhighlight (struct frame *); | 226 | static void frame_unhighlight (struct frame *); |
| @@ -241,7 +235,8 @@ static void x_frame_rehighlight (struct w32_display_info *); | |||
| 241 | static void x_draw_hollow_cursor (struct window *, struct glyph_row *); | 235 | static void x_draw_hollow_cursor (struct window *, struct glyph_row *); |
| 242 | static void x_draw_bar_cursor (struct window *, struct glyph_row *, int, | 236 | static void x_draw_bar_cursor (struct window *, struct glyph_row *, int, |
| 243 | enum text_cursor_kinds); | 237 | enum text_cursor_kinds); |
| 244 | static void w32_clip_to_row (struct window *, struct glyph_row *, int, HDC); | 238 | static void w32_clip_to_row (struct window *, struct glyph_row *, |
| 239 | enum glyph_row_area, HDC); | ||
| 245 | static BOOL my_show_window (struct frame *, HWND, int); | 240 | static BOOL my_show_window (struct frame *, HWND, int); |
| 246 | static void my_set_window_pos (HWND, HWND, int, int, int, int, UINT); | 241 | static void my_set_window_pos (HWND, HWND, int, int, int, int, UINT); |
| 247 | #if 0 | 242 | #if 0 |
| @@ -577,9 +572,7 @@ x_update_begin (struct frame *f) | |||
| 577 | } | 572 | } |
| 578 | 573 | ||
| 579 | 574 | ||
| 580 | /* Start update of window W. Set the global variable updated_window | 575 | /* Start update of window W. */ |
| 581 | to the window being updated and set output_cursor to the cursor | ||
| 582 | position of W. */ | ||
| 583 | 576 | ||
| 584 | static void | 577 | static void |
| 585 | x_update_window_begin (struct window *w) | 578 | x_update_window_begin (struct window *w) |
| @@ -593,8 +586,7 @@ x_update_window_begin (struct window *w) | |||
| 593 | SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0); | 586 | SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0); |
| 594 | } | 587 | } |
| 595 | 588 | ||
| 596 | updated_window = w; | 589 | w->output_cursor = w->cursor; |
| 597 | set_output_cursor (&w->cursor); | ||
| 598 | 590 | ||
| 599 | block_input (); | 591 | block_input (); |
| 600 | 592 | ||
| @@ -664,7 +656,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 664 | } | 656 | } |
| 665 | 657 | ||
| 666 | 658 | ||
| 667 | /* End update of window W (which is equal to updated_window). | 659 | /* End update of window W. |
| 668 | 660 | ||
| 669 | Draw vertical borders between horizontally adjacent windows, and | 661 | Draw vertical borders between horizontally adjacent windows, and |
| 670 | display W's cursor if CURSOR_ON_P is non-zero. | 662 | display W's cursor if CURSOR_ON_P is non-zero. |
| @@ -678,19 +670,17 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 678 | here. */ | 670 | here. */ |
| 679 | 671 | ||
| 680 | static void | 672 | static void |
| 681 | x_update_window_end (struct window *w, int cursor_on_p, | 673 | x_update_window_end (struct window *w, bool cursor_on_p, |
| 682 | int mouse_face_overwritten_p) | 674 | bool mouse_face_overwritten_p) |
| 683 | { | 675 | { |
| 684 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); | ||
| 685 | |||
| 686 | if (!w->pseudo_window_p) | 676 | if (!w->pseudo_window_p) |
| 687 | { | 677 | { |
| 688 | block_input (); | 678 | block_input (); |
| 689 | 679 | ||
| 690 | if (cursor_on_p) | 680 | if (cursor_on_p) |
| 691 | display_and_set_cursor (w, 1, output_cursor.hpos, | 681 | display_and_set_cursor (w, 1, |
| 692 | output_cursor.vpos, | 682 | w->output_cursor.hpos, w->output_cursor.vpos, |
| 693 | output_cursor.x, output_cursor.y); | 683 | w->output_cursor.x, w->output_cursor.y); |
| 694 | 684 | ||
| 695 | if (draw_window_fringes (w, 1)) | 685 | if (draw_window_fringes (w, 1)) |
| 696 | x_draw_vertical_border (w); | 686 | x_draw_vertical_border (w); |
| @@ -701,11 +691,7 @@ x_update_window_end (struct window *w, int cursor_on_p, | |||
| 701 | /* If a row with mouse-face was overwritten, arrange for | 691 | /* If a row with mouse-face was overwritten, arrange for |
| 702 | XTframe_up_to_date to redisplay the mouse highlight. */ | 692 | XTframe_up_to_date to redisplay the mouse highlight. */ |
| 703 | if (mouse_face_overwritten_p) | 693 | if (mouse_face_overwritten_p) |
| 704 | { | 694 | reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame))); |
| 705 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 706 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 707 | hlinfo->mouse_face_window = Qnil; | ||
| 708 | } | ||
| 709 | 695 | ||
| 710 | /* Unhide the caret. This won't actually show the cursor, unless it | 696 | /* Unhide the caret. This won't actually show the cursor, unless it |
| 711 | was visible before the corresponding call to HideCaret in | 697 | was visible before the corresponding call to HideCaret in |
| @@ -714,8 +700,6 @@ x_update_window_end (struct window *w, int cursor_on_p, | |||
| 714 | { | 700 | { |
| 715 | SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0); | 701 | SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0); |
| 716 | } | 702 | } |
| 717 | |||
| 718 | updated_window = NULL; | ||
| 719 | } | 703 | } |
| 720 | 704 | ||
| 721 | 705 | ||
| @@ -733,9 +717,8 @@ x_update_end (struct frame *f) | |||
| 733 | } | 717 | } |
| 734 | 718 | ||
| 735 | 719 | ||
| 736 | /* This function is called from various places in xdisp.c whenever a | 720 | /* This function is called from various places in xdisp.c |
| 737 | complete update has been performed. The global variable | 721 | whenever a complete update has been performed. */ |
| 738 | updated_window is not available here. */ | ||
| 739 | 722 | ||
| 740 | static void | 723 | static void |
| 741 | w32_frame_up_to_date (struct frame *f) | 724 | w32_frame_up_to_date (struct frame *f) |
| @@ -747,15 +730,13 @@ w32_frame_up_to_date (struct frame *f) | |||
| 747 | 730 | ||
| 748 | /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay | 731 | /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay |
| 749 | arrow bitmaps, or clear the fringes if no bitmaps are required | 732 | arrow bitmaps, or clear the fringes if no bitmaps are required |
| 750 | before DESIRED_ROW is made current. The window being updated is | 733 | before DESIRED_ROW is made current. This function is called from |
| 751 | found in updated_window. This function is called from | ||
| 752 | update_window_line only if it is known that there are differences | 734 | update_window_line only if it is known that there are differences |
| 753 | between bitmaps to be drawn between current row and DESIRED_ROW. */ | 735 | between bitmaps to be drawn between current row and DESIRED_ROW. */ |
| 754 | 736 | ||
| 755 | static void | 737 | static void |
| 756 | x_after_update_window_line (struct glyph_row *desired_row) | 738 | x_after_update_window_line (struct window *w, struct glyph_row *desired_row) |
| 757 | { | 739 | { |
| 758 | struct window *w = updated_window; | ||
| 759 | struct frame *f; | 740 | struct frame *f; |
| 760 | int width, height; | 741 | int width, height; |
| 761 | 742 | ||
| @@ -766,7 +747,7 @@ x_after_update_window_line (struct glyph_row *desired_row) | |||
| 766 | 747 | ||
| 767 | /* When a window has disappeared, make sure that no rest of | 748 | /* When a window has disappeared, make sure that no rest of |
| 768 | full-width rows stays visible in the internal border. Could | 749 | full-width rows stays visible in the internal border. Could |
| 769 | check here if updated_window is the leftmost/rightmost window, | 750 | check here if updated window is the leftmost/rightmost window, |
| 770 | but I guess it's not worth doing since vertically split windows | 751 | but I guess it's not worth doing since vertically split windows |
| 771 | are almost never used, internal border is rarely set, and the | 752 | are almost never used, internal border is rarely set, and the |
| 772 | overhead is very small. */ | 753 | overhead is very small. */ |
| @@ -863,7 +844,7 @@ w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 863 | } | 844 | } |
| 864 | 845 | ||
| 865 | /* Must clip because of partially visible lines. */ | 846 | /* Must clip because of partially visible lines. */ |
| 866 | w32_clip_to_row (w, row, -1, hdc); | 847 | w32_clip_to_row (w, row, ANY_AREA, hdc); |
| 867 | 848 | ||
| 868 | if (p->which && p->which < max_fringe_bmp) | 849 | if (p->which && p->which < max_fringe_bmp) |
| 869 | { | 850 | { |
| @@ -948,28 +929,6 @@ w32_destroy_fringe_bitmap (int which) | |||
| 948 | fringe_bmp[which] = 0; | 929 | fringe_bmp[which] = 0; |
| 949 | } | 930 | } |
| 950 | 931 | ||
| 951 | |||
| 952 | |||
| 953 | /* This is called when starting Emacs and when restarting after | ||
| 954 | suspend. When starting Emacs, no window is mapped. And nothing | ||
| 955 | must be done to Emacs's own window if it is suspended (though that | ||
| 956 | rarely happens). */ | ||
| 957 | |||
| 958 | static void | ||
| 959 | w32_set_terminal_modes (struct terminal *term) | ||
| 960 | { | ||
| 961 | } | ||
| 962 | |||
| 963 | /* This is called when exiting or suspending Emacs. Exiting will make | ||
| 964 | the W32 windows go away, and suspending requires no action. */ | ||
| 965 | |||
| 966 | static void | ||
| 967 | w32_reset_terminal_modes (struct terminal *term) | ||
| 968 | { | ||
| 969 | } | ||
| 970 | |||
| 971 | |||
| 972 | |||
| 973 | /*********************************************************************** | 932 | /*********************************************************************** |
| 974 | Display Iterator | 933 | Display Iterator |
| 975 | ***********************************************************************/ | 934 | ***********************************************************************/ |
| @@ -2665,11 +2624,7 @@ x_clear_frame (struct frame *f) | |||
| 2665 | /* Clearing the frame will erase any cursor, so mark them all as no | 2624 | /* Clearing the frame will erase any cursor, so mark them all as no |
| 2666 | longer visible. */ | 2625 | longer visible. */ |
| 2667 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); | 2626 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); |
| 2668 | output_cursor.hpos = output_cursor.vpos = 0; | ||
| 2669 | output_cursor.x = -1; | ||
| 2670 | 2627 | ||
| 2671 | /* We don't set the output cursor here because there will always | ||
| 2672 | follow an explicit cursor_to. */ | ||
| 2673 | block_input (); | 2628 | block_input (); |
| 2674 | 2629 | ||
| 2675 | w32_clear_window (f); | 2630 | w32_clear_window (f); |
| @@ -2707,19 +2662,6 @@ w32_ring_bell (struct frame *f) | |||
| 2707 | unblock_input (); | 2662 | unblock_input (); |
| 2708 | } | 2663 | } |
| 2709 | 2664 | ||
| 2710 | |||
| 2711 | /* Specify how many text lines, from the top of the window, | ||
| 2712 | should be affected by insert-lines and delete-lines operations. | ||
| 2713 | This, and those operations, are used only within an update | ||
| 2714 | that is bounded by calls to x_update_begin and x_update_end. */ | ||
| 2715 | |||
| 2716 | static void | ||
| 2717 | w32_set_terminal_window (struct frame *f, int n) | ||
| 2718 | { | ||
| 2719 | /* This function intentionally left blank. */ | ||
| 2720 | } | ||
| 2721 | |||
| 2722 | |||
| 2723 | /*********************************************************************** | 2665 | /*********************************************************************** |
| 2724 | Line Dance | 2666 | Line Dance |
| 2725 | ***********************************************************************/ | 2667 | ***********************************************************************/ |
| @@ -2750,7 +2692,7 @@ x_scroll_run (struct window *w, struct run *run) | |||
| 2750 | /* Get frame-relative bounding box of the text display area of W, | 2692 | /* Get frame-relative bounding box of the text display area of W, |
| 2751 | without mode lines. Include in this box the left and right | 2693 | without mode lines. Include in this box the left and right |
| 2752 | fringes of W. */ | 2694 | fringes of W. */ |
| 2753 | window_box (w, -1, &x, &y, &width, &height); | 2695 | window_box (w, ANY_AREA, &x, &y, &width, &height); |
| 2754 | 2696 | ||
| 2755 | /* If the fringe is adjacent to the left (right) scroll bar of a | 2697 | /* If the fringe is adjacent to the left (right) scroll bar of a |
| 2756 | leftmost (rightmost, respectively) window, then extend its | 2698 | leftmost (rightmost, respectively) window, then extend its |
| @@ -2806,7 +2748,6 @@ x_scroll_run (struct window *w, struct run *run) | |||
| 2806 | block_input (); | 2748 | block_input (); |
| 2807 | 2749 | ||
| 2808 | /* Cursor off. Will be switched on again in x_update_window_end. */ | 2750 | /* Cursor off. Will be switched on again in x_update_window_end. */ |
| 2809 | updated_window = w; | ||
| 2810 | x_clear_cursor (w); | 2751 | x_clear_cursor (w); |
| 2811 | 2752 | ||
| 2812 | { | 2753 | { |
| @@ -3765,7 +3706,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 3765 | HWND hwnd; | 3706 | HWND hwnd; |
| 3766 | SCROLLINFO si; | 3707 | SCROLLINFO si; |
| 3767 | struct scroll_bar *bar | 3708 | struct scroll_bar *bar |
| 3768 | = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil)); | 3709 | = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, fringe_extended_p, PVEC_OTHER); |
| 3769 | Lisp_Object barobj; | 3710 | Lisp_Object barobj; |
| 3770 | 3711 | ||
| 3771 | block_input (); | 3712 | block_input (); |
| @@ -3778,7 +3719,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 3778 | XSETINT (bar->start, 0); | 3719 | XSETINT (bar->start, 0); |
| 3779 | XSETINT (bar->end, 0); | 3720 | XSETINT (bar->end, 0); |
| 3780 | bar->dragging = Qnil; | 3721 | bar->dragging = Qnil; |
| 3781 | bar->fringe_extended_p = Qnil; | 3722 | bar->fringe_extended_p = 0; |
| 3782 | 3723 | ||
| 3783 | /* Requires geometry to be set before call to create the real window */ | 3724 | /* Requires geometry to be set before call to create the real window */ |
| 3784 | 3725 | ||
| @@ -3842,10 +3783,10 @@ w32_set_vertical_scroll_bar (struct window *w, | |||
| 3842 | struct scroll_bar *bar; | 3783 | struct scroll_bar *bar; |
| 3843 | int top, height, left, sb_left, width, sb_width; | 3784 | int top, height, left, sb_left, width, sb_width; |
| 3844 | int window_y, window_height; | 3785 | int window_y, window_height; |
| 3845 | int fringe_extended_p; | 3786 | bool fringe_extended_p; |
| 3846 | 3787 | ||
| 3847 | /* Get window dimensions. */ | 3788 | /* Get window dimensions. */ |
| 3848 | window_box (w, -1, 0, &window_y, 0, &window_height); | 3789 | window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); |
| 3849 | top = window_y; | 3790 | top = window_y; |
| 3850 | width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); | 3791 | width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); |
| 3851 | height = window_height; | 3792 | height = window_height; |
| @@ -3866,16 +3807,7 @@ w32_set_vertical_scroll_bar (struct window *w, | |||
| 3866 | else | 3807 | else |
| 3867 | sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width); | 3808 | sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width); |
| 3868 | 3809 | ||
| 3869 | if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) | 3810 | fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w); |
| 3870 | fringe_extended_p = (WINDOW_LEFTMOST_P (w) | ||
| 3871 | && WINDOW_LEFT_FRINGE_WIDTH (w) | ||
| 3872 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | ||
| 3873 | || WINDOW_LEFT_MARGIN_COLS (w) == 0)); | ||
| 3874 | else | ||
| 3875 | fringe_extended_p = (WINDOW_RIGHTMOST_P (w) | ||
| 3876 | && WINDOW_RIGHT_FRINGE_WIDTH (w) | ||
| 3877 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | ||
| 3878 | || WINDOW_RIGHT_MARGIN_COLS (w) == 0)); | ||
| 3879 | 3811 | ||
| 3880 | /* Does the scroll bar exist yet? */ | 3812 | /* Does the scroll bar exist yet? */ |
| 3881 | if (NILP (w->vertical_scroll_bar)) | 3813 | if (NILP (w->vertical_scroll_bar)) |
| @@ -3904,11 +3836,11 @@ w32_set_vertical_scroll_bar (struct window *w, | |||
| 3904 | hwnd = SCROLL_BAR_W32_WINDOW (bar); | 3836 | hwnd = SCROLL_BAR_W32_WINDOW (bar); |
| 3905 | 3837 | ||
| 3906 | /* If already correctly positioned, do nothing. */ | 3838 | /* If already correctly positioned, do nothing. */ |
| 3907 | if ( XINT (bar->left) == sb_left | 3839 | if (XINT (bar->left) == sb_left |
| 3908 | && XINT (bar->top) == top | 3840 | && XINT (bar->top) == top |
| 3909 | && XINT (bar->width) == sb_width | 3841 | && XINT (bar->width) == sb_width |
| 3910 | && XINT (bar->height) == height | 3842 | && XINT (bar->height) == height |
| 3911 | && !NILP (bar->fringe_extended_p) == fringe_extended_p ) | 3843 | && bar->fringe_extended_p == fringe_extended_p) |
| 3912 | { | 3844 | { |
| 3913 | /* Redraw after clear_frame. */ | 3845 | /* Redraw after clear_frame. */ |
| 3914 | if (!my_show_window (f, hwnd, SW_NORMAL)) | 3846 | if (!my_show_window (f, hwnd, SW_NORMAL)) |
| @@ -3958,7 +3890,7 @@ w32_set_vertical_scroll_bar (struct window *w, | |||
| 3958 | unblock_input (); | 3890 | unblock_input (); |
| 3959 | } | 3891 | } |
| 3960 | } | 3892 | } |
| 3961 | bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil; | 3893 | bar->fringe_extended_p = fringe_extended_p; |
| 3962 | 3894 | ||
| 3963 | w32_set_scroll_bar_thumb (bar, portion, position, whole); | 3895 | w32_set_scroll_bar_thumb (bar, portion, position, whole); |
| 3964 | XSETVECTOR (barobj, bar); | 3896 | XSETVECTOR (barobj, bar); |
| @@ -4568,18 +4500,16 @@ w32_read_socket (struct terminal *terminal, | |||
| 4568 | /* Generate SELECT_WINDOW_EVENTs when needed. */ | 4500 | /* Generate SELECT_WINDOW_EVENTs when needed. */ |
| 4569 | if (!NILP (Vmouse_autoselect_window)) | 4501 | if (!NILP (Vmouse_autoselect_window)) |
| 4570 | { | 4502 | { |
| 4571 | Lisp_Object window; | 4503 | static Lisp_Object last_mouse_window; |
| 4572 | int x = LOWORD (msg.msg.lParam); | 4504 | Lisp_Object window = window_from_coordinates |
| 4573 | int y = HIWORD (msg.msg.lParam); | 4505 | (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0); |
| 4574 | |||
| 4575 | window = window_from_coordinates (f, x, y, 0, 0); | ||
| 4576 | 4506 | ||
| 4577 | /* Window will be selected only when it is not | 4507 | /* Window will be selected only when it is not |
| 4578 | selected now and last mouse movement event was | 4508 | selected now and last mouse movement event was |
| 4579 | not in it. Minibuffer window will be selected | 4509 | not in it. Minibuffer window will be selected |
| 4580 | only when it is active. */ | 4510 | only when it is active. */ |
| 4581 | if (WINDOWP (window) | 4511 | if (WINDOWP (window) |
| 4582 | && !EQ (window, last_window) | 4512 | && !EQ (window, last_mouse_window) |
| 4583 | && !EQ (window, selected_window) | 4513 | && !EQ (window, selected_window) |
| 4584 | /* For click-to-focus window managers | 4514 | /* For click-to-focus window managers |
| 4585 | create event iff we don't leave the | 4515 | create event iff we don't leave the |
| @@ -4591,8 +4521,8 @@ w32_read_socket (struct terminal *terminal, | |||
| 4591 | inev.kind = SELECT_WINDOW_EVENT; | 4521 | inev.kind = SELECT_WINDOW_EVENT; |
| 4592 | inev.frame_or_window = window; | 4522 | inev.frame_or_window = window; |
| 4593 | } | 4523 | } |
| 4594 | 4524 | /* Remember the last window where we saw the mouse. */ | |
| 4595 | last_window = window; | 4525 | last_mouse_window = window; |
| 4596 | } | 4526 | } |
| 4597 | if (!note_mouse_movement (f, &msg.msg)) | 4527 | if (!note_mouse_movement (f, &msg.msg)) |
| 4598 | help_echo_string = previous_help_echo_string; | 4528 | help_echo_string = previous_help_echo_string; |
| @@ -5147,7 +5077,8 @@ w32_read_socket (struct terminal *terminal, | |||
| 5147 | mode lines must be clipped to the whole window. */ | 5077 | mode lines must be clipped to the whole window. */ |
| 5148 | 5078 | ||
| 5149 | static void | 5079 | static void |
| 5150 | w32_clip_to_row (struct window *w, struct glyph_row *row, int area, HDC hdc) | 5080 | w32_clip_to_row (struct window *w, struct glyph_row *row, |
| 5081 | enum glyph_row_area area, HDC hdc) | ||
| 5151 | { | 5082 | { |
| 5152 | RECT clip_rect; | 5083 | RECT clip_rect; |
| 5153 | int window_x, window_y, window_width; | 5084 | int window_x, window_y, window_width; |
| @@ -5317,8 +5248,8 @@ w32_clear_frame_area (struct frame *f, int x, int y, int width, int height) | |||
| 5317 | 5248 | ||
| 5318 | static void | 5249 | static void |
| 5319 | w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | 5250 | w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, |
| 5320 | int x, int y, int cursor_type, int cursor_width, | 5251 | int x, int y, enum text_cursor_kinds cursor_type, |
| 5321 | int on_p, int active_p) | 5252 | int cursor_width, bool on_p, bool active_p) |
| 5322 | { | 5253 | { |
| 5323 | if (on_p) | 5254 | if (on_p) |
| 5324 | { | 5255 | { |
| @@ -5717,7 +5648,9 @@ w32fullscreen_hook (struct frame *f) | |||
| 5717 | w32_fullscreen_rect (hwnd, f->want_fullscreen, | 5648 | w32_fullscreen_rect (hwnd, f->want_fullscreen, |
| 5718 | FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); | 5649 | FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); |
| 5719 | FRAME_PREV_FSMODE (f) = f->want_fullscreen; | 5650 | FRAME_PREV_FSMODE (f) = f->want_fullscreen; |
| 5720 | if (f->want_fullscreen == FULLSCREEN_BOTH) | 5651 | if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) |
| 5652 | PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0); | ||
| 5653 | else if (f->want_fullscreen == FULLSCREEN_BOTH) | ||
| 5721 | { | 5654 | { |
| 5722 | SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); | 5655 | SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); |
| 5723 | SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, | 5656 | SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, |
| @@ -6172,16 +6105,8 @@ x_free_frame_resources (struct frame *f) | |||
| 6172 | dpyinfo->w32_focus_event_frame = 0; | 6105 | dpyinfo->w32_focus_event_frame = 0; |
| 6173 | if (f == dpyinfo->x_highlight_frame) | 6106 | if (f == dpyinfo->x_highlight_frame) |
| 6174 | dpyinfo->x_highlight_frame = 0; | 6107 | dpyinfo->x_highlight_frame = 0; |
| 6175 | |||
| 6176 | if (f == hlinfo->mouse_face_mouse_frame) | 6108 | if (f == hlinfo->mouse_face_mouse_frame) |
| 6177 | { | 6109 | reset_mouse_highlight (hlinfo); |
| 6178 | hlinfo->mouse_face_beg_row | ||
| 6179 | = hlinfo->mouse_face_beg_col = -1; | ||
| 6180 | hlinfo->mouse_face_end_row | ||
| 6181 | = hlinfo->mouse_face_end_col = -1; | ||
| 6182 | hlinfo->mouse_face_window = Qnil; | ||
| 6183 | hlinfo->mouse_face_mouse_frame = 0; | ||
| 6184 | } | ||
| 6185 | 6110 | ||
| 6186 | unblock_input (); | 6111 | unblock_input (); |
| 6187 | } | 6112 | } |
| @@ -6251,7 +6176,6 @@ void | |||
| 6251 | w32_initialize_display_info (Lisp_Object display_name) | 6176 | w32_initialize_display_info (Lisp_Object display_name) |
| 6252 | { | 6177 | { |
| 6253 | struct w32_display_info *dpyinfo = &one_w32_display_info; | 6178 | struct w32_display_info *dpyinfo = &one_w32_display_info; |
| 6254 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; | ||
| 6255 | 6179 | ||
| 6256 | memset (dpyinfo, 0, sizeof (*dpyinfo)); | 6180 | memset (dpyinfo, 0, sizeof (*dpyinfo)); |
| 6257 | 6181 | ||
| @@ -6274,17 +6198,10 @@ w32_initialize_display_info (Lisp_Object display_name) | |||
| 6274 | dpyinfo->n_fonts = 0; | 6198 | dpyinfo->n_fonts = 0; |
| 6275 | dpyinfo->smallest_font_height = 1; | 6199 | dpyinfo->smallest_font_height = 1; |
| 6276 | dpyinfo->smallest_char_width = 1; | 6200 | dpyinfo->smallest_char_width = 1; |
| 6277 | |||
| 6278 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 6279 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 6280 | hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; | ||
| 6281 | hlinfo->mouse_face_window = Qnil; | ||
| 6282 | hlinfo->mouse_face_overlay = Qnil; | ||
| 6283 | hlinfo->mouse_face_hidden = 0; | ||
| 6284 | |||
| 6285 | dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW); | 6201 | dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW); |
| 6286 | /* TODO: dpyinfo->gray */ | 6202 | /* TODO: dpyinfo->gray */ |
| 6287 | 6203 | ||
| 6204 | reset_mouse_highlight (&dpyinfo->mouse_highlight); | ||
| 6288 | } | 6205 | } |
| 6289 | 6206 | ||
| 6290 | /* Create an xrdb-style database of resources to supersede registry settings. | 6207 | /* Create an xrdb-style database of resources to supersede registry settings. |
| @@ -6359,7 +6276,6 @@ static struct redisplay_interface w32_redisplay_interface = | |||
| 6359 | x_after_update_window_line, | 6276 | x_after_update_window_line, |
| 6360 | x_update_window_begin, | 6277 | x_update_window_begin, |
| 6361 | x_update_window_end, | 6278 | x_update_window_end, |
| 6362 | x_cursor_to, | ||
| 6363 | x_flush, | 6279 | x_flush, |
| 6364 | 0, /* flush_display_optional */ | 6280 | 0, /* flush_display_optional */ |
| 6365 | x_clear_window_mouse_face, | 6281 | x_clear_window_mouse_face, |
| @@ -6396,11 +6312,11 @@ w32_create_terminal (struct w32_display_info *dpyinfo) | |||
| 6396 | terminal->ins_del_lines_hook = x_ins_del_lines; | 6312 | terminal->ins_del_lines_hook = x_ins_del_lines; |
| 6397 | terminal->delete_glyphs_hook = x_delete_glyphs; | 6313 | terminal->delete_glyphs_hook = x_delete_glyphs; |
| 6398 | terminal->ring_bell_hook = w32_ring_bell; | 6314 | terminal->ring_bell_hook = w32_ring_bell; |
| 6399 | terminal->reset_terminal_modes_hook = w32_reset_terminal_modes; | 6315 | terminal->reset_terminal_modes_hook = NULL; |
| 6400 | terminal->set_terminal_modes_hook = w32_set_terminal_modes; | 6316 | terminal->set_terminal_modes_hook = NULL; |
| 6401 | terminal->update_begin_hook = x_update_begin; | 6317 | terminal->update_begin_hook = x_update_begin; |
| 6402 | terminal->update_end_hook = x_update_end; | 6318 | terminal->update_end_hook = x_update_end; |
| 6403 | terminal->set_terminal_window_hook = w32_set_terminal_window; | 6319 | terminal->set_terminal_window_hook = NULL; |
| 6404 | terminal->read_socket_hook = w32_read_socket; | 6320 | terminal->read_socket_hook = w32_read_socket; |
| 6405 | terminal->frame_up_to_date_hook = w32_frame_up_to_date; | 6321 | terminal->frame_up_to_date_hook = w32_frame_up_to_date; |
| 6406 | terminal->mouse_position_hook = w32_mouse_position; | 6322 | terminal->mouse_position_hook = w32_mouse_position; |
| @@ -6478,9 +6394,7 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 6478 | terminal = w32_create_terminal (dpyinfo); | 6394 | terminal = w32_create_terminal (dpyinfo); |
| 6479 | 6395 | ||
| 6480 | /* Set the name of the terminal. */ | 6396 | /* Set the name of the terminal. */ |
| 6481 | terminal->name = xmalloc (SBYTES (display_name) + 1); | 6397 | terminal->name = xlispstrdup (display_name); |
| 6482 | strncpy (terminal->name, SDATA (display_name), SBYTES (display_name)); | ||
| 6483 | terminal->name[SBYTES (display_name)] = 0; | ||
| 6484 | 6398 | ||
| 6485 | dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL; | 6399 | dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL; |
| 6486 | 6400 | ||
diff --git a/src/w32term.h b/src/w32term.h index 3c9cce35221..41c5c71832a 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -451,9 +451,11 @@ struct scroll_bar { | |||
| 451 | being dragged, this is Qnil. */ | 451 | being dragged, this is Qnil. */ |
| 452 | Lisp_Object dragging; | 452 | Lisp_Object dragging; |
| 453 | 453 | ||
| 454 | /* t if the background of the fringe that is adjacent to a scroll | 454 | /* 1 if the background of the fringe that is adjacent to a scroll |
| 455 | bar is extended to the gap between the fringe and the bar. */ | 455 | bar is extended to the gap between the fringe and the bar. */ |
| 456 | Lisp_Object fringe_extended_p; | 456 | /* Note: this could be a bit field, but we need to take its address |
| 457 | in ALLOCATE_PSEUDOVECTOR (see x_scroll_bar_create). */ | ||
| 458 | bool fringe_extended_p; | ||
| 457 | }; | 459 | }; |
| 458 | 460 | ||
| 459 | /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ | 461 | /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ |
diff --git a/src/window.c b/src/window.c index 1b288368884..ef96861dc71 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -66,10 +66,9 @@ static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; | |||
| 66 | static int displayed_window_lines (struct window *); | 66 | static int displayed_window_lines (struct window *); |
| 67 | static int count_windows (struct window *); | 67 | static int count_windows (struct window *); |
| 68 | static int get_leaf_windows (struct window *, struct window **, int); | 68 | static int get_leaf_windows (struct window *, struct window **, int); |
| 69 | static void window_scroll (Lisp_Object, EMACS_INT, int, int); | 69 | static void window_scroll (Lisp_Object, EMACS_INT, bool, int); |
| 70 | static void window_scroll_pixel_based (Lisp_Object, int, int, int); | 70 | static void window_scroll_pixel_based (Lisp_Object, int, bool, int); |
| 71 | static void window_scroll_line_based (Lisp_Object, int, int, int); | 71 | static void window_scroll_line_based (Lisp_Object, int, bool, int); |
| 72 | static int freeze_window_start (struct window *, void *); | ||
| 73 | static Lisp_Object window_list (void); | 72 | static Lisp_Object window_list (void); |
| 74 | static int add_window_to_list (struct window *, void *); | 73 | static int add_window_to_list (struct window *, void *); |
| 75 | static Lisp_Object next_window (Lisp_Object, Lisp_Object, | 74 | static Lisp_Object next_window (Lisp_Object, Lisp_Object, |
| @@ -88,6 +87,14 @@ static void window_resize_apply (struct window *, bool); | |||
| 88 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); | 87 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); |
| 89 | static void select_window_1 (Lisp_Object, bool); | 88 | static void select_window_1 (Lisp_Object, bool); |
| 90 | 89 | ||
| 90 | static struct window *set_window_fringes (struct window *, Lisp_Object, | ||
| 91 | Lisp_Object, Lisp_Object); | ||
| 92 | static struct window *set_window_margins (struct window *, Lisp_Object, | ||
| 93 | Lisp_Object); | ||
| 94 | static struct window *set_window_scroll_bars (struct window *, Lisp_Object, | ||
| 95 | Lisp_Object, Lisp_Object); | ||
| 96 | static void apply_window_adjustment (struct window *); | ||
| 97 | |||
| 91 | /* This is the window in which the terminal's cursor should | 98 | /* This is the window in which the terminal's cursor should |
| 92 | be left when nothing is being done with it. This must | 99 | be left when nothing is being done with it. This must |
| 93 | always be a leaf window, and its buffer is selected by | 100 | always be a leaf window, and its buffer is selected by |
| @@ -152,16 +159,6 @@ wset_display_table (struct window *w, Lisp_Object val) | |||
| 152 | w->display_table = val; | 159 | w->display_table = val; |
| 153 | } | 160 | } |
| 154 | static void | 161 | static void |
| 155 | wset_left_fringe_width (struct window *w, Lisp_Object val) | ||
| 156 | { | ||
| 157 | w->left_fringe_width = val; | ||
| 158 | } | ||
| 159 | static void | ||
| 160 | wset_left_margin_cols (struct window *w, Lisp_Object val) | ||
| 161 | { | ||
| 162 | w->left_margin_cols = val; | ||
| 163 | } | ||
| 164 | static void | ||
| 165 | wset_new_normal (struct window *w, Lisp_Object val) | 162 | wset_new_normal (struct window *w, Lisp_Object val) |
| 166 | { | 163 | { |
| 167 | w->new_normal = val; | 164 | w->new_normal = val; |
| @@ -192,21 +189,6 @@ wset_pointm (struct window *w, Lisp_Object val) | |||
| 192 | w->pointm = val; | 189 | w->pointm = val; |
| 193 | } | 190 | } |
| 194 | static void | 191 | static void |
| 195 | wset_right_fringe_width (struct window *w, Lisp_Object val) | ||
| 196 | { | ||
| 197 | w->right_fringe_width = val; | ||
| 198 | } | ||
| 199 | static void | ||
| 200 | wset_right_margin_cols (struct window *w, Lisp_Object val) | ||
| 201 | { | ||
| 202 | w->right_margin_cols = val; | ||
| 203 | } | ||
| 204 | static void | ||
| 205 | wset_scroll_bar_width (struct window *w, Lisp_Object val) | ||
| 206 | { | ||
| 207 | w->scroll_bar_width = val; | ||
| 208 | } | ||
| 209 | static void | ||
| 210 | wset_start (struct window *w, Lisp_Object val) | 192 | wset_start (struct window *w, Lisp_Object val) |
| 211 | { | 193 | { |
| 212 | w->start = val; | 194 | w->start = val; |
| @@ -239,6 +221,17 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val) | |||
| 239 | w->horizontal = horflag; | 221 | w->horizontal = horflag; |
| 240 | } | 222 | } |
| 241 | 223 | ||
| 224 | /* Nonzero if leaf window W doesn't reflect the actual state | ||
| 225 | of displayed buffer due to its text or overlays change. */ | ||
| 226 | |||
| 227 | bool | ||
| 228 | window_outdated (struct window *w) | ||
| 229 | { | ||
| 230 | struct buffer *b = XBUFFER (w->contents); | ||
| 231 | return (w->last_modified < BUF_MODIFF (b) | ||
| 232 | || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)); | ||
| 233 | } | ||
| 234 | |||
| 242 | struct window * | 235 | struct window * |
| 243 | decode_live_window (register Lisp_Object window) | 236 | decode_live_window (register Lisp_Object window) |
| 244 | { | 237 | { |
| @@ -488,7 +481,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) | |||
| 488 | CHECK_LIVE_WINDOW (window); | 481 | CHECK_LIVE_WINDOW (window); |
| 489 | 482 | ||
| 490 | w = XWINDOW (window); | 483 | w = XWINDOW (window); |
| 491 | w->frozen_window_start_p = 0; | ||
| 492 | 484 | ||
| 493 | /* Make the selected window's buffer current. */ | 485 | /* Make the selected window's buffer current. */ |
| 494 | Fset_buffer (w->contents); | 486 | Fset_buffer (w->contents); |
| @@ -557,15 +549,7 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap) | |||
| 557 | than one window. It also matters when | 549 | than one window. It also matters when |
| 558 | redisplay_window has altered point after scrolling, | 550 | redisplay_window has altered point after scrolling, |
| 559 | because it makes the change only in the window. */ | 551 | because it makes the change only in the window. */ |
| 560 | { | 552 | set_point_from_marker (XWINDOW (window)->pointm); |
| 561 | register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm); | ||
| 562 | if (new_point < BEGV) | ||
| 563 | SET_PT (BEGV); | ||
| 564 | else if (new_point > ZV) | ||
| 565 | SET_PT (ZV); | ||
| 566 | else | ||
| 567 | SET_PT (new_point); | ||
| 568 | } | ||
| 569 | } | 553 | } |
| 570 | 554 | ||
| 571 | DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, | 555 | DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, |
| @@ -1353,7 +1337,7 @@ struct check_window_data | |||
| 1353 | static int | 1337 | static int |
| 1354 | check_window_containing (struct window *w, void *user_data) | 1338 | check_window_containing (struct window *w, void *user_data) |
| 1355 | { | 1339 | { |
| 1356 | struct check_window_data *cw = (struct check_window_data *) user_data; | 1340 | struct check_window_data *cw = user_data; |
| 1357 | enum window_part found; | 1341 | enum window_part found; |
| 1358 | int continue_p = 1; | 1342 | int continue_p = 1; |
| 1359 | 1343 | ||
| @@ -1506,12 +1490,10 @@ if it isn't already recorded. */) | |||
| 1506 | || !w->window_end_valid | 1490 | || !w->window_end_valid |
| 1507 | || b->clip_changed | 1491 | || b->clip_changed |
| 1508 | || b->prevent_redisplay_optimizations_p | 1492 | || b->prevent_redisplay_optimizations_p |
| 1509 | || w->last_modified < BUF_MODIFF (b) | 1493 | || window_outdated (w)) |
| 1510 | || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) | ||
| 1511 | && !noninteractive) | 1494 | && !noninteractive) |
| 1512 | { | 1495 | { |
| 1513 | struct text_pos startp; | 1496 | struct text_pos startp; |
| 1514 | ptrdiff_t charpos = marker_position (w->start); | ||
| 1515 | struct it it; | 1497 | struct it it; |
| 1516 | struct buffer *old_buffer = NULL; | 1498 | struct buffer *old_buffer = NULL; |
| 1517 | void *itdata = NULL; | 1499 | void *itdata = NULL; |
| @@ -1529,12 +1511,7 @@ if it isn't already recorded. */) | |||
| 1529 | `-l' containing a call to `rmail' with subsequent other | 1511 | `-l' containing a call to `rmail' with subsequent other |
| 1530 | commands. At the end, W->start happened to be BEG, while | 1512 | commands. At the end, W->start happened to be BEG, while |
| 1531 | rmail had already narrowed the buffer. */ | 1513 | rmail had already narrowed the buffer. */ |
| 1532 | if (charpos < BEGV) | 1514 | CLIP_TEXT_POS_FROM_MARKER (startp, w->start); |
| 1533 | SET_TEXT_POS (startp, BEGV, BEGV_BYTE); | ||
| 1534 | else if (charpos > ZV) | ||
| 1535 | SET_TEXT_POS (startp, ZV, ZV_BYTE); | ||
| 1536 | else | ||
| 1537 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | ||
| 1538 | 1515 | ||
| 1539 | itdata = bidi_shelve_cache (); | 1516 | itdata = bidi_shelve_cache (); |
| 1540 | start_display (&it, w, startp); | 1517 | start_display (&it, w, startp); |
| @@ -1548,7 +1525,7 @@ if it isn't already recorded. */) | |||
| 1548 | set_buffer_internal (old_buffer); | 1525 | set_buffer_internal (old_buffer); |
| 1549 | } | 1526 | } |
| 1550 | else | 1527 | else |
| 1551 | XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); | 1528 | XSETINT (value, BUF_Z (b) - w->window_end_pos); |
| 1552 | 1529 | ||
| 1553 | return value; | 1530 | return value; |
| 1554 | } | 1531 | } |
| @@ -1604,9 +1581,8 @@ overriding motion of point in order to display at this exact start. */) | |||
| 1604 | if (NILP (noforce)) | 1581 | if (NILP (noforce)) |
| 1605 | w->force_start = 1; | 1582 | w->force_start = 1; |
| 1606 | w->update_mode_line = 1; | 1583 | w->update_mode_line = 1; |
| 1607 | w->last_modified = 0; | 1584 | if (w != XWINDOW (selected_window)) |
| 1608 | w->last_overlay_modified = 0; | 1585 | /* Enforce full redisplay. FIXME: make it more selective. */ |
| 1609 | if (!EQ (window, selected_window)) | ||
| 1610 | windows_or_buffers_changed++; | 1586 | windows_or_buffers_changed++; |
| 1611 | 1587 | ||
| 1612 | return pos; | 1588 | return pos; |
| @@ -1720,8 +1696,7 @@ Return nil if window display is not up-to-date. In that case, use | |||
| 1720 | || windows_or_buffers_changed | 1696 | || windows_or_buffers_changed |
| 1721 | || b->clip_changed | 1697 | || b->clip_changed |
| 1722 | || b->prevent_redisplay_optimizations_p | 1698 | || b->prevent_redisplay_optimizations_p |
| 1723 | || w->last_modified < BUF_MODIFF (b) | 1699 | || window_outdated (w)) |
| 1724 | || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) | ||
| 1725 | return Qnil; | 1700 | return Qnil; |
| 1726 | 1701 | ||
| 1727 | if (NILP (line)) | 1702 | if (NILP (line)) |
| @@ -2038,16 +2013,15 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag) | |||
| 2038 | n->desired_matrix = n->current_matrix = 0; | 2013 | n->desired_matrix = n->current_matrix = 0; |
| 2039 | n->vscroll = 0; | 2014 | n->vscroll = 0; |
| 2040 | memset (&n->cursor, 0, sizeof (n->cursor)); | 2015 | memset (&n->cursor, 0, sizeof (n->cursor)); |
| 2041 | memset (&n->last_cursor, 0, sizeof (n->last_cursor)); | ||
| 2042 | memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); | 2016 | memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); |
| 2017 | n->last_cursor_vpos = 0; | ||
| 2043 | n->phys_cursor_type = -1; | 2018 | n->phys_cursor_type = -1; |
| 2044 | n->phys_cursor_width = -1; | 2019 | n->phys_cursor_width = -1; |
| 2045 | n->must_be_updated_p = 0; | 2020 | n->must_be_updated_p = 0; |
| 2046 | n->pseudo_window_p = 0; | 2021 | n->pseudo_window_p = 0; |
| 2047 | wset_window_end_vpos (n, make_number (0)); | 2022 | n->window_end_vpos = 0; |
| 2048 | wset_window_end_pos (n, make_number (0)); | 2023 | n->window_end_pos = 0; |
| 2049 | n->window_end_valid = 0; | 2024 | n->window_end_valid = 0; |
| 2050 | n->frozen_window_start_p = 0; | ||
| 2051 | } | 2025 | } |
| 2052 | 2026 | ||
| 2053 | tem = o->next; | 2027 | tem = o->next; |
| @@ -2156,7 +2130,7 @@ delete_deletable_window (Lisp_Object window) | |||
| 2156 | static int | 2130 | static int |
| 2157 | add_window_to_list (struct window *w, void *user_data) | 2131 | add_window_to_list (struct window *w, void *user_data) |
| 2158 | { | 2132 | { |
| 2159 | Lisp_Object *list = (Lisp_Object *) user_data; | 2133 | Lisp_Object *list = user_data; |
| 2160 | Lisp_Object window; | 2134 | Lisp_Object window; |
| 2161 | XSETWINDOW (window, w); | 2135 | XSETWINDOW (window, w); |
| 2162 | *list = Fcons (window, *list); | 2136 | *list = Fcons (window, *list); |
| @@ -2854,7 +2828,7 @@ window-start value is reasonable when this function is called. */) | |||
| 2854 | block_input (); | 2828 | block_input (); |
| 2855 | if (!FRAME_INITIAL_P (f)) | 2829 | if (!FRAME_INITIAL_P (f)) |
| 2856 | { | 2830 | { |
| 2857 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); | 2831 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); |
| 2858 | 2832 | ||
| 2859 | /* We are going to free the glyph matrices of WINDOW, and with | 2833 | /* We are going to free the glyph matrices of WINDOW, and with |
| 2860 | that we might lose any information about glyph rows that have | 2834 | that we might lose any information about glyph rows that have |
| @@ -2864,11 +2838,7 @@ window-start value is reasonable when this function is called. */) | |||
| 2864 | frame's up-to-date hook that mouse highlight was overwritten, | 2838 | frame's up-to-date hook that mouse highlight was overwritten, |
| 2865 | so that it will arrange for redisplaying the highlight. */ | 2839 | so that it will arrange for redisplaying the highlight. */ |
| 2866 | if (EQ (hlinfo->mouse_face_window, window)) | 2840 | if (EQ (hlinfo->mouse_face_window, window)) |
| 2867 | { | 2841 | reset_mouse_highlight (hlinfo); |
| 2868 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 2869 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 2870 | hlinfo->mouse_face_window = Qnil; | ||
| 2871 | } | ||
| 2872 | } | 2842 | } |
| 2873 | free_window_matrices (r); | 2843 | free_window_matrices (r); |
| 2874 | 2844 | ||
| @@ -3063,15 +3033,12 @@ adjust_window_margins (struct window *w) | |||
| 3063 | if (WINDOW_RIGHT_MARGIN_COLS (w) > 0) | 3033 | if (WINDOW_RIGHT_MARGIN_COLS (w) > 0) |
| 3064 | { | 3034 | { |
| 3065 | if (WINDOW_LEFT_MARGIN_COLS (w) > 0) | 3035 | if (WINDOW_LEFT_MARGIN_COLS (w) > 0) |
| 3066 | { | 3036 | w->left_margin_cols = w->right_margin_cols = margin_cols / 2; |
| 3067 | wset_left_margin_cols (w, make_number (margin_cols / 2)); | ||
| 3068 | wset_right_margin_cols (w, make_number (margin_cols / 2)); | ||
| 3069 | } | ||
| 3070 | else | 3037 | else |
| 3071 | wset_right_margin_cols (w, make_number (margin_cols)); | 3038 | w->right_margin_cols = margin_cols; |
| 3072 | } | 3039 | } |
| 3073 | else | 3040 | else |
| 3074 | wset_left_margin_cols (w, make_number (margin_cols)); | 3041 | w->left_margin_cols = margin_cols; |
| 3075 | return 1; | 3042 | return 1; |
| 3076 | } | 3043 | } |
| 3077 | 3044 | ||
| @@ -3119,7 +3086,7 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3119 | 3086 | ||
| 3120 | if (SELECTED_FRAME () != f) | 3087 | if (SELECTED_FRAME () != f) |
| 3121 | { | 3088 | { |
| 3122 | record_unwind_protect (select_frame_norecord, Fselected_frame ()); | 3089 | record_unwind_protect (select_frame_norecord, selected_frame); |
| 3123 | select_frame_norecord (frame); | 3090 | select_frame_norecord (frame); |
| 3124 | } | 3091 | } |
| 3125 | 3092 | ||
| @@ -3134,7 +3101,7 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3134 | buffer))) | 3101 | buffer))) |
| 3135 | { | 3102 | { |
| 3136 | ptrdiff_t inner_count = SPECPDL_INDEX (); | 3103 | ptrdiff_t inner_count = SPECPDL_INDEX (); |
| 3137 | record_unwind_protect (select_window_norecord, Fselected_window ()); | 3104 | record_unwind_protect (select_window_norecord, selected_window); |
| 3138 | select_window_norecord (window); | 3105 | select_window_norecord (window); |
| 3139 | run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, | 3106 | run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, |
| 3140 | buffer)); | 3107 | buffer)); |
| @@ -3185,9 +3152,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, | |||
| 3185 | bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1)); | 3152 | bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1)); |
| 3186 | bset_display_time (b, Fcurrent_time ()); | 3153 | bset_display_time (b, Fcurrent_time ()); |
| 3187 | 3154 | ||
| 3188 | wset_window_end_pos (w, make_number (0)); | 3155 | w->window_end_pos = 0; |
| 3189 | wset_window_end_vpos (w, make_number (0)); | 3156 | w->window_end_vpos = 0; |
| 3190 | memset (&w->last_cursor, 0, sizeof w->last_cursor); | 3157 | w->last_cursor_vpos = 0; |
| 3191 | 3158 | ||
| 3192 | if (!(keep_margins_p && samebuf)) | 3159 | if (!(keep_margins_p && samebuf)) |
| 3193 | { /* If we're not actually changing the buffer, don't reset hscroll and | 3160 | { /* If we're not actually changing the buffer, don't reset hscroll and |
| @@ -3206,8 +3173,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, | |||
| 3206 | buffer); | 3173 | buffer); |
| 3207 | w->start_at_line_beg = 0; | 3174 | w->start_at_line_beg = 0; |
| 3208 | w->force_start = 0; | 3175 | w->force_start = 0; |
| 3209 | w->last_modified = 0; | ||
| 3210 | w->last_overlay_modified = 0; | ||
| 3211 | } | 3176 | } |
| 3212 | /* Maybe we could move this into the `if' but it's not obviously safe and | 3177 | /* Maybe we could move this into the `if' but it's not obviously safe and |
| 3213 | I doubt it's worth the trouble. */ | 3178 | I doubt it's worth the trouble. */ |
| @@ -3227,28 +3192,14 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, | |||
| 3227 | if (!keep_margins_p) | 3192 | if (!keep_margins_p) |
| 3228 | { | 3193 | { |
| 3229 | /* Set left and right marginal area width etc. from buffer. */ | 3194 | /* Set left and right marginal area width etc. from buffer. */ |
| 3230 | 3195 | set_window_fringes (w, BVAR (b, left_fringe_width), | |
| 3231 | /* This may call adjust_window_margins three times, so | 3196 | BVAR (b, right_fringe_width), |
| 3232 | temporarily disable window margins. */ | 3197 | BVAR (b, fringes_outside_margins)); |
| 3233 | Lisp_Object save_left = w->left_margin_cols; | 3198 | set_window_scroll_bars (w, BVAR (b, scroll_bar_width), |
| 3234 | Lisp_Object save_right = w->right_margin_cols; | 3199 | BVAR (b, vertical_scroll_bar_type), Qnil); |
| 3235 | 3200 | set_window_margins (w, BVAR (b, left_margin_cols), | |
| 3236 | wset_left_margin_cols (w, Qnil); | 3201 | BVAR (b, right_margin_cols)); |
| 3237 | wset_right_margin_cols (w, Qnil); | 3202 | apply_window_adjustment (w); |
| 3238 | |||
| 3239 | Fset_window_fringes (window, | ||
| 3240 | BVAR (b, left_fringe_width), BVAR (b, right_fringe_width), | ||
| 3241 | BVAR (b, fringes_outside_margins)); | ||
| 3242 | |||
| 3243 | Fset_window_scroll_bars (window, | ||
| 3244 | BVAR (b, scroll_bar_width), | ||
| 3245 | BVAR (b, vertical_scroll_bar_type), Qnil); | ||
| 3246 | |||
| 3247 | wset_left_margin_cols (w, save_left); | ||
| 3248 | wset_right_margin_cols (w, save_right); | ||
| 3249 | |||
| 3250 | Fset_window_margins (window, | ||
| 3251 | BVAR (b, left_margin_cols), BVAR (b, right_margin_cols)); | ||
| 3252 | } | 3203 | } |
| 3253 | 3204 | ||
| 3254 | if (run_hooks_p) | 3205 | if (run_hooks_p) |
| @@ -3384,10 +3335,8 @@ temp_output_buffer_show (register Lisp_Object buf) | |||
| 3384 | 3335 | ||
| 3385 | if (!NILP (Vtemp_buffer_show_function)) | 3336 | if (!NILP (Vtemp_buffer_show_function)) |
| 3386 | call1 (Vtemp_buffer_show_function, buf); | 3337 | call1 (Vtemp_buffer_show_function, buf); |
| 3387 | else | 3338 | else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil))) |
| 3388 | { | 3339 | { |
| 3389 | window = display_buffer (buf, Qnil, Qnil); | ||
| 3390 | |||
| 3391 | if (!EQ (XWINDOW (window)->frame, selected_frame)) | 3340 | if (!EQ (XWINDOW (window)->frame, selected_frame)) |
| 3392 | Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); | 3341 | Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); |
| 3393 | Vminibuf_scroll_window = window; | 3342 | Vminibuf_scroll_window = window; |
| @@ -3468,8 +3417,6 @@ make_window (void) | |||
| 3468 | wset_start (w, Fmake_marker ()); | 3417 | wset_start (w, Fmake_marker ()); |
| 3469 | wset_pointm (w, Fmake_marker ()); | 3418 | wset_pointm (w, Fmake_marker ()); |
| 3470 | wset_vertical_scroll_bar_type (w, Qt); | 3419 | wset_vertical_scroll_bar_type (w, Qt); |
| 3471 | wset_window_end_pos (w, make_number (0)); | ||
| 3472 | wset_window_end_vpos (w, make_number (0)); | ||
| 3473 | /* These Lisp fields are marked specially so they're not set to nil by | 3420 | /* These Lisp fields are marked specially so they're not set to nil by |
| 3474 | allocate_window. */ | 3421 | allocate_window. */ |
| 3475 | wset_prev_buffers (w, Qnil); | 3422 | wset_prev_buffers (w, Qnil); |
| @@ -3478,8 +3425,10 @@ make_window (void) | |||
| 3478 | /* Initialize non-Lisp data. Note that allocate_window zeroes out all | 3425 | /* Initialize non-Lisp data. Note that allocate_window zeroes out all |
| 3479 | non-Lisp data, so do it only for slots which should not be zero. */ | 3426 | non-Lisp data, so do it only for slots which should not be zero. */ |
| 3480 | w->nrows_scale_factor = w->ncols_scale_factor = 1; | 3427 | w->nrows_scale_factor = w->ncols_scale_factor = 1; |
| 3428 | w->left_fringe_width = w->right_fringe_width = -1; | ||
| 3481 | w->phys_cursor_type = -1; | 3429 | w->phys_cursor_type = -1; |
| 3482 | w->phys_cursor_width = -1; | 3430 | w->phys_cursor_width = -1; |
| 3431 | w->scroll_bar_width = -1; | ||
| 3483 | w->column_number_displayed = -1; | 3432 | w->column_number_displayed = -1; |
| 3484 | 3433 | ||
| 3485 | /* Reset window_list. */ | 3434 | /* Reset window_list. */ |
| @@ -3668,10 +3617,6 @@ window_resize_apply (struct window *w, bool horflag) | |||
| 3668 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | 3617 | c = NILP (c->next) ? 0 : XWINDOW (c->next); |
| 3669 | } | 3618 | } |
| 3670 | } | 3619 | } |
| 3671 | |||
| 3672 | /* Clear out some redisplay caches. */ | ||
| 3673 | w->last_modified = 0; | ||
| 3674 | w->last_overlay_modified = 0; | ||
| 3675 | } | 3620 | } |
| 3676 | 3621 | ||
| 3677 | 3622 | ||
| @@ -3946,15 +3891,15 @@ set correctly. See the code of `split-window' for how this is done. */) | |||
| 3946 | } | 3891 | } |
| 3947 | 3892 | ||
| 3948 | n->window_end_valid = 0; | 3893 | n->window_end_valid = 0; |
| 3949 | memset (&n->last_cursor, 0, sizeof n->last_cursor); | 3894 | n->last_cursor_vpos = 0; |
| 3950 | 3895 | ||
| 3951 | /* Get special geometry settings from reference window. */ | 3896 | /* Get special geometry settings from reference window. */ |
| 3952 | wset_left_margin_cols (n, r->left_margin_cols); | 3897 | n->left_margin_cols = r->left_margin_cols; |
| 3953 | wset_right_margin_cols (n, r->right_margin_cols); | 3898 | n->right_margin_cols = r->right_margin_cols; |
| 3954 | wset_left_fringe_width (n, r->left_fringe_width); | 3899 | n->left_fringe_width = r->left_fringe_width; |
| 3955 | wset_right_fringe_width (n, r->right_fringe_width); | 3900 | n->right_fringe_width = r->right_fringe_width; |
| 3956 | n->fringes_outside_margins = r->fringes_outside_margins; | 3901 | n->fringes_outside_margins = r->fringes_outside_margins; |
| 3957 | wset_scroll_bar_width (n, r->scroll_bar_width); | 3902 | n->scroll_bar_width = r->scroll_bar_width; |
| 3958 | wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); | 3903 | wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); |
| 3959 | 3904 | ||
| 3960 | /* Directly assign orthogonal coordinates and sizes. */ | 3905 | /* Directly assign orthogonal coordinates and sizes. */ |
| @@ -4190,9 +4135,7 @@ grow_mini_window (struct window *w, int delta) | |||
| 4190 | /* Grow the mini-window. */ | 4135 | /* Grow the mini-window. */ |
| 4191 | w->top_line = r->top_line + r->total_lines; | 4136 | w->top_line = r->top_line + r->total_lines; |
| 4192 | w->total_lines -= XINT (value); | 4137 | w->total_lines -= XINT (value); |
| 4193 | w->last_modified = 0; | 4138 | /* Enforce full redisplay. FIXME: make it more selective. */ |
| 4194 | w->last_overlay_modified = 0; | ||
| 4195 | |||
| 4196 | windows_or_buffers_changed++; | 4139 | windows_or_buffers_changed++; |
| 4197 | adjust_glyphs (f); | 4140 | adjust_glyphs (f); |
| 4198 | unblock_input (); | 4141 | unblock_input (); |
| @@ -4226,10 +4169,7 @@ shrink_mini_window (struct window *w) | |||
| 4226 | /* Shrink the mini-window. */ | 4169 | /* Shrink the mini-window. */ |
| 4227 | w->top_line = r->top_line + r->total_lines; | 4170 | w->top_line = r->top_line + r->total_lines; |
| 4228 | w->total_lines = 1; | 4171 | w->total_lines = 1; |
| 4229 | 4172 | /* Enforce full redisplay. FIXME: make it more selective. */ | |
| 4230 | w->last_modified = 0; | ||
| 4231 | w->last_overlay_modified = 0; | ||
| 4232 | |||
| 4233 | windows_or_buffers_changed++; | 4173 | windows_or_buffers_changed++; |
| 4234 | adjust_glyphs (f); | 4174 | adjust_glyphs (f); |
| 4235 | unblock_input (); | 4175 | unblock_input (); |
| @@ -4336,7 +4276,7 @@ window_internal_height (struct window *w) | |||
| 4336 | respectively. */ | 4276 | respectively. */ |
| 4337 | 4277 | ||
| 4338 | static void | 4278 | static void |
| 4339 | window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) | 4279 | window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror) |
| 4340 | { | 4280 | { |
| 4341 | immediate_quit = 1; | 4281 | immediate_quit = 1; |
| 4342 | n = clip_to_bounds (INT_MIN, n, INT_MAX); | 4282 | n = clip_to_bounds (INT_MIN, n, INT_MAX); |
| @@ -4357,7 +4297,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) | |||
| 4357 | descriptions. */ | 4297 | descriptions. */ |
| 4358 | 4298 | ||
| 4359 | static void | 4299 | static void |
| 4360 | window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | 4300 | window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) |
| 4361 | { | 4301 | { |
| 4362 | struct it it; | 4302 | struct it it; |
| 4363 | struct window *w = XWINDOW (window); | 4303 | struct window *w = XWINDOW (window); |
| @@ -4455,8 +4395,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4455 | w->contents); | 4395 | w->contents); |
| 4456 | w->start_at_line_beg = 1; | 4396 | w->start_at_line_beg = 1; |
| 4457 | w->update_mode_line = 1; | 4397 | w->update_mode_line = 1; |
| 4458 | w->last_modified = 0; | ||
| 4459 | w->last_overlay_modified = 0; | ||
| 4460 | /* Set force_start so that redisplay_window will run the | 4398 | /* Set force_start so that redisplay_window will run the |
| 4461 | window-scroll-functions. */ | 4399 | window-scroll-functions. */ |
| 4462 | w->force_start = 1; | 4400 | w->force_start = 1; |
| @@ -4601,8 +4539,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4601 | bytepos = marker_byte_position (w->start); | 4539 | bytepos = marker_byte_position (w->start); |
| 4602 | w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); | 4540 | w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); |
| 4603 | w->update_mode_line = 1; | 4541 | w->update_mode_line = 1; |
| 4604 | w->last_modified = 0; | ||
| 4605 | w->last_overlay_modified = 0; | ||
| 4606 | /* Set force_start so that redisplay_window will run the | 4542 | /* Set force_start so that redisplay_window will run the |
| 4607 | window-scroll-functions. */ | 4543 | window-scroll-functions. */ |
| 4608 | w->force_start = 1; | 4544 | w->force_start = 1; |
| @@ -4725,7 +4661,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4725 | See the comment of window_scroll for parameter descriptions. */ | 4661 | See the comment of window_scroll for parameter descriptions. */ |
| 4726 | 4662 | ||
| 4727 | static void | 4663 | static void |
| 4728 | window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) | 4664 | window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror) |
| 4729 | { | 4665 | { |
| 4730 | register struct window *w = XWINDOW (window); | 4666 | register struct window *w = XWINDOW (window); |
| 4731 | /* Fvertical_motion enters redisplay, which can trigger | 4667 | /* Fvertical_motion enters redisplay, which can trigger |
| @@ -4737,7 +4673,7 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4737 | register ptrdiff_t pos, pos_byte; | 4673 | register ptrdiff_t pos, pos_byte; |
| 4738 | register int ht = window_internal_height (w); | 4674 | register int ht = window_internal_height (w); |
| 4739 | register Lisp_Object tem; | 4675 | register Lisp_Object tem; |
| 4740 | int lose; | 4676 | bool lose; |
| 4741 | Lisp_Object bolp; | 4677 | Lisp_Object bolp; |
| 4742 | ptrdiff_t startpos = marker_position (w->start); | 4678 | ptrdiff_t startpos = marker_position (w->start); |
| 4743 | ptrdiff_t startbyte = marker_byte_position (w->start); | 4679 | ptrdiff_t startbyte = marker_byte_position (w->start); |
| @@ -4801,8 +4737,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4801 | set_marker_restricted_both (w->start, w->contents, pos, pos_byte); | 4737 | set_marker_restricted_both (w->start, w->contents, pos, pos_byte); |
| 4802 | w->start_at_line_beg = !NILP (bolp); | 4738 | w->start_at_line_beg = !NILP (bolp); |
| 4803 | w->update_mode_line = 1; | 4739 | w->update_mode_line = 1; |
| 4804 | w->last_modified = 0; | ||
| 4805 | w->last_overlay_modified = 0; | ||
| 4806 | /* Set force_start so that redisplay_window will run | 4740 | /* Set force_start so that redisplay_window will run |
| 4807 | the window-scroll-functions. */ | 4741 | the window-scroll-functions. */ |
| 4808 | w->force_start = 1; | 4742 | w->force_start = 1; |
| @@ -5098,7 +5032,6 @@ displayed_window_lines (struct window *w) | |||
| 5098 | { | 5032 | { |
| 5099 | struct it it; | 5033 | struct it it; |
| 5100 | struct text_pos start; | 5034 | struct text_pos start; |
| 5101 | ptrdiff_t charpos = marker_position (w->start); | ||
| 5102 | int height = window_box_height (w); | 5035 | int height = window_box_height (w); |
| 5103 | struct buffer *old_buffer; | 5036 | struct buffer *old_buffer; |
| 5104 | int bottom_y; | 5037 | int bottom_y; |
| @@ -5115,12 +5048,7 @@ displayed_window_lines (struct window *w) | |||
| 5115 | /* In case W->start is out of the accessible range, do something | 5048 | /* In case W->start is out of the accessible range, do something |
| 5116 | reasonable. This happens in Info mode when Info-scroll-down | 5049 | reasonable. This happens in Info mode when Info-scroll-down |
| 5117 | calls (recenter -1) while W->start is 1. */ | 5050 | calls (recenter -1) while W->start is 1. */ |
| 5118 | if (charpos < BEGV) | 5051 | CLIP_TEXT_POS_FROM_MARKER (start, w->start); |
| 5119 | SET_TEXT_POS (start, BEGV, BEGV_BYTE); | ||
| 5120 | else if (charpos > ZV) | ||
| 5121 | SET_TEXT_POS (start, ZV, ZV_BYTE); | ||
| 5122 | else | ||
| 5123 | SET_TEXT_POS_FROM_MARKER (start, w->start); | ||
| 5124 | 5052 | ||
| 5125 | itdata = bidi_shelve_cache (); | 5053 | itdata = bidi_shelve_cache (); |
| 5126 | start_display (&it, w, start); | 5054 | start_display (&it, w, start); |
| @@ -5454,7 +5382,7 @@ struct save_window_data | |||
| 5454 | Lisp_Object saved_windows; | 5382 | Lisp_Object saved_windows; |
| 5455 | 5383 | ||
| 5456 | /* All fields above are traced by the GC. | 5384 | /* All fields above are traced by the GC. |
| 5457 | From `fame-cols' down, the fields are ignored by the GC. */ | 5385 | From `frame-cols' down, the fields are ignored by the GC. */ |
| 5458 | 5386 | ||
| 5459 | int frame_cols, frame_lines, frame_menu_bar_lines; | 5387 | int frame_cols, frame_lines, frame_menu_bar_lines; |
| 5460 | int frame_tool_bar_lines; | 5388 | int frame_tool_bar_lines; |
| @@ -5703,12 +5631,12 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5703 | w->hscroll = XFASTINT (p->hscroll); | 5631 | w->hscroll = XFASTINT (p->hscroll); |
| 5704 | w->min_hscroll = XFASTINT (p->min_hscroll); | 5632 | w->min_hscroll = XFASTINT (p->min_hscroll); |
| 5705 | wset_display_table (w, p->display_table); | 5633 | wset_display_table (w, p->display_table); |
| 5706 | wset_left_margin_cols (w, p->left_margin_cols); | 5634 | w->left_margin_cols = XINT (p->left_margin_cols); |
| 5707 | wset_right_margin_cols (w, p->right_margin_cols); | 5635 | w->right_margin_cols = XINT (p->right_margin_cols); |
| 5708 | wset_left_fringe_width (w, p->left_fringe_width); | 5636 | w->left_fringe_width = XINT (p->left_fringe_width); |
| 5709 | wset_right_fringe_width (w, p->right_fringe_width); | 5637 | w->right_fringe_width = XINT (p->right_fringe_width); |
| 5710 | w->fringes_outside_margins = !NILP (p->fringes_outside_margins); | 5638 | w->fringes_outside_margins = !NILP (p->fringes_outside_margins); |
| 5711 | wset_scroll_bar_width (w, p->scroll_bar_width); | 5639 | w->scroll_bar_width = XINT (p->scroll_bar_width); |
| 5712 | wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); | 5640 | wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); |
| 5713 | wset_dedicated (w, p->dedicated); | 5641 | wset_dedicated (w, p->dedicated); |
| 5714 | wset_combination_limit (w, p->combination_limit); | 5642 | wset_combination_limit (w, p->combination_limit); |
| @@ -5734,9 +5662,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5734 | } | 5662 | } |
| 5735 | } | 5663 | } |
| 5736 | 5664 | ||
| 5737 | w->last_modified = 0; | ||
| 5738 | w->last_overlay_modified = 0; | ||
| 5739 | |||
| 5740 | if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) | 5665 | if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) |
| 5741 | /* If saved buffer is alive, install it. */ | 5666 | /* If saved buffer is alive, install it. */ |
| 5742 | { | 5667 | { |
| @@ -6007,12 +5932,12 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i) | |||
| 6007 | XSETFASTINT (p->hscroll, w->hscroll); | 5932 | XSETFASTINT (p->hscroll, w->hscroll); |
| 6008 | XSETFASTINT (p->min_hscroll, w->min_hscroll); | 5933 | XSETFASTINT (p->min_hscroll, w->min_hscroll); |
| 6009 | p->display_table = w->display_table; | 5934 | p->display_table = w->display_table; |
| 6010 | p->left_margin_cols = w->left_margin_cols; | 5935 | p->left_margin_cols = make_number (w->left_margin_cols); |
| 6011 | p->right_margin_cols = w->right_margin_cols; | 5936 | p->right_margin_cols = make_number (w->right_margin_cols); |
| 6012 | p->left_fringe_width = w->left_fringe_width; | 5937 | p->left_fringe_width = make_number (w->left_fringe_width); |
| 6013 | p->right_fringe_width = w->right_fringe_width; | 5938 | p->right_fringe_width = make_number (w->right_fringe_width); |
| 6014 | p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; | 5939 | p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; |
| 6015 | p->scroll_bar_width = w->scroll_bar_width; | 5940 | p->scroll_bar_width = make_number (w->scroll_bar_width); |
| 6016 | p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; | 5941 | p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; |
| 6017 | p->dedicated = w->dedicated; | 5942 | p->dedicated = w->dedicated; |
| 6018 | p->combination_limit = w->combination_limit; | 5943 | p->combination_limit = w->combination_limit; |
| @@ -6153,11 +6078,46 @@ saved by this function. */) | |||
| 6153 | XSETWINDOW_CONFIGURATION (tem, data); | 6078 | XSETWINDOW_CONFIGURATION (tem, data); |
| 6154 | return (tem); | 6079 | return (tem); |
| 6155 | } | 6080 | } |
| 6081 | |||
| 6082 | /* Called after W's margins, fringes or scroll bars was adjusted. */ | ||
| 6083 | |||
| 6084 | static void | ||
| 6085 | apply_window_adjustment (struct window *w) | ||
| 6086 | { | ||
| 6087 | eassert (w); | ||
| 6088 | adjust_window_margins (w); | ||
| 6089 | clear_glyph_matrix (w->current_matrix); | ||
| 6090 | w->window_end_valid = 0; | ||
| 6091 | windows_or_buffers_changed++; | ||
| 6092 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); | ||
| 6093 | } | ||
| 6094 | |||
| 6156 | 6095 | ||
| 6157 | /*********************************************************************** | 6096 | /*********************************************************************** |
| 6158 | Marginal Areas | 6097 | Marginal Areas |
| 6159 | ***********************************************************************/ | 6098 | ***********************************************************************/ |
| 6160 | 6099 | ||
| 6100 | static struct window * | ||
| 6101 | set_window_margins (struct window *w, Lisp_Object left_width, | ||
| 6102 | Lisp_Object right_width) | ||
| 6103 | { | ||
| 6104 | int left, right; | ||
| 6105 | |||
| 6106 | /* FIXME: what about margins that are too wide? */ | ||
| 6107 | left = (NILP (left_width) ? 0 | ||
| 6108 | : (CHECK_NATNUM (left_width), XINT (left_width))); | ||
| 6109 | right = (NILP (right_width) ? 0 | ||
| 6110 | : (CHECK_NATNUM (right_width), XINT (right_width))); | ||
| 6111 | |||
| 6112 | if (w->left_margin_cols != left || w->right_margin_cols != right) | ||
| 6113 | { | ||
| 6114 | w->left_margin_cols = left; | ||
| 6115 | w->right_margin_cols = right; | ||
| 6116 | return w; | ||
| 6117 | } | ||
| 6118 | return NULL; | ||
| 6119 | } | ||
| 6120 | |||
| 6161 | DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, | 6121 | DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, |
| 6162 | 2, 3, 0, | 6122 | 2, 3, 0, |
| 6163 | doc: /* Set width of marginal areas of window WINDOW. | 6123 | doc: /* Set width of marginal areas of window WINDOW. |
| @@ -6166,41 +6126,14 @@ WINDOW must be a live window and defaults to the selected one. | |||
| 6166 | Second arg LEFT-WIDTH specifies the number of character cells to | 6126 | Second arg LEFT-WIDTH specifies the number of character cells to |
| 6167 | reserve for the left marginal area. Optional third arg RIGHT-WIDTH | 6127 | reserve for the left marginal area. Optional third arg RIGHT-WIDTH |
| 6168 | does the same for the right marginal area. A nil width parameter | 6128 | does the same for the right marginal area. A nil width parameter |
| 6169 | means no margin. */) | 6129 | means no margin. |
| 6130 | |||
| 6131 | Return t if any margin was actually changed and nil otherwise. */) | ||
| 6170 | (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width) | 6132 | (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width) |
| 6171 | { | 6133 | { |
| 6172 | struct window *w = decode_live_window (window); | 6134 | struct window *w = set_window_margins (decode_live_window (window), |
| 6173 | 6135 | left_width, right_width); | |
| 6174 | /* Translate negative or zero widths to nil. | 6136 | return w ? (apply_window_adjustment (w), Qt) : Qnil; |
| 6175 | Margins that are too wide have to be checked elsewhere. */ | ||
| 6176 | |||
| 6177 | if (!NILP (left_width)) | ||
| 6178 | { | ||
| 6179 | CHECK_NUMBER (left_width); | ||
| 6180 | if (XINT (left_width) <= 0) | ||
| 6181 | left_width = Qnil; | ||
| 6182 | } | ||
| 6183 | |||
| 6184 | if (!NILP (right_width)) | ||
| 6185 | { | ||
| 6186 | CHECK_NUMBER (right_width); | ||
| 6187 | if (XINT (right_width) <= 0) | ||
| 6188 | right_width = Qnil; | ||
| 6189 | } | ||
| 6190 | |||
| 6191 | if (!EQ (w->left_margin_cols, left_width) | ||
| 6192 | || !EQ (w->right_margin_cols, right_width)) | ||
| 6193 | { | ||
| 6194 | wset_left_margin_cols (w, left_width); | ||
| 6195 | wset_right_margin_cols (w, right_width); | ||
| 6196 | |||
| 6197 | adjust_window_margins (w); | ||
| 6198 | |||
| 6199 | ++windows_or_buffers_changed; | ||
| 6200 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); | ||
| 6201 | } | ||
| 6202 | |||
| 6203 | return Qnil; | ||
| 6204 | } | 6137 | } |
| 6205 | 6138 | ||
| 6206 | 6139 | ||
| @@ -6215,7 +6148,8 @@ as nil. */) | |||
| 6215 | (Lisp_Object window) | 6148 | (Lisp_Object window) |
| 6216 | { | 6149 | { |
| 6217 | struct window *w = decode_live_window (window); | 6150 | struct window *w = decode_live_window (window); |
| 6218 | return Fcons (w->left_margin_cols, w->right_margin_cols); | 6151 | return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil, |
| 6152 | w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil); | ||
| 6219 | } | 6153 | } |
| 6220 | 6154 | ||
| 6221 | 6155 | ||
| @@ -6224,6 +6158,31 @@ as nil. */) | |||
| 6224 | Fringes | 6158 | Fringes |
| 6225 | ***********************************************************************/ | 6159 | ***********************************************************************/ |
| 6226 | 6160 | ||
| 6161 | static struct window * | ||
| 6162 | set_window_fringes (struct window *w, Lisp_Object left_width, | ||
| 6163 | Lisp_Object right_width, Lisp_Object outside_margins) | ||
| 6164 | { | ||
| 6165 | int left, right, outside = !NILP (outside_margins); | ||
| 6166 | |||
| 6167 | left = (NILP (left_width) ? -1 | ||
| 6168 | : (CHECK_NATNUM (left_width), XINT (left_width))); | ||
| 6169 | right = (NILP (right_width) ? -1 | ||
| 6170 | : (CHECK_NATNUM (right_width), XINT (right_width))); | ||
| 6171 | |||
| 6172 | /* Do nothing on a tty or if nothing to actually change. */ | ||
| 6173 | if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) | ||
| 6174 | && (w->left_fringe_width != left | ||
| 6175 | || w->right_fringe_width != right | ||
| 6176 | || w->fringes_outside_margins != outside)) | ||
| 6177 | { | ||
| 6178 | w->left_fringe_width = left; | ||
| 6179 | w->right_fringe_width = right; | ||
| 6180 | w->fringes_outside_margins = outside; | ||
| 6181 | return w; | ||
| 6182 | } | ||
| 6183 | return NULL; | ||
| 6184 | } | ||
| 6185 | |||
| 6227 | DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, | 6186 | DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, |
| 6228 | 2, 4, 0, | 6187 | 2, 4, 0, |
| 6229 | doc: /* Set the fringe widths of window WINDOW. | 6188 | doc: /* Set the fringe widths of window WINDOW. |
| @@ -6236,37 +6195,16 @@ frame's default fringe width. Default fringe widths can be set with | |||
| 6236 | the command `set-fringe-style'. | 6195 | the command `set-fringe-style'. |
| 6237 | If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes | 6196 | If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes |
| 6238 | outside of the display margins. By default, fringes are drawn between | 6197 | outside of the display margins. By default, fringes are drawn between |
| 6239 | display marginal areas and the text area. */) | 6198 | display marginal areas and the text area. |
| 6240 | (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins) | ||
| 6241 | { | ||
| 6242 | struct window *w = decode_live_window (window); | ||
| 6243 | int outside = !NILP (outside_margins); | ||
| 6244 | |||
| 6245 | if (!NILP (left_width)) | ||
| 6246 | CHECK_NATNUM (left_width); | ||
| 6247 | if (!NILP (right_width)) | ||
| 6248 | CHECK_NATNUM (right_width); | ||
| 6249 | |||
| 6250 | /* Do nothing on a tty. */ | ||
| 6251 | if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) | ||
| 6252 | && (!EQ (w->left_fringe_width, left_width) | ||
| 6253 | || !EQ (w->right_fringe_width, right_width) | ||
| 6254 | || w->fringes_outside_margins != outside)) | ||
| 6255 | { | ||
| 6256 | wset_left_fringe_width (w, left_width); | ||
| 6257 | wset_right_fringe_width (w, right_width); | ||
| 6258 | w->fringes_outside_margins = outside; | ||
| 6259 | 6199 | ||
| 6260 | adjust_window_margins (w); | 6200 | Return t if any fringe was actually changed and nil otherwise. */) |
| 6261 | 6201 | (Lisp_Object window, Lisp_Object left_width, | |
| 6262 | clear_glyph_matrix (w->current_matrix); | 6202 | Lisp_Object right_width, Lisp_Object outside_margins) |
| 6263 | w->window_end_valid = 0; | 6203 | { |
| 6264 | 6204 | struct window *w | |
| 6265 | ++windows_or_buffers_changed; | 6205 | = set_window_fringes (decode_live_window (window), |
| 6266 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); | 6206 | left_width, right_width, outside_margins); |
| 6267 | } | 6207 | return w ? (apply_window_adjustment (w), Qt) : Qnil; |
| 6268 | |||
| 6269 | return Qnil; | ||
| 6270 | } | 6208 | } |
| 6271 | 6209 | ||
| 6272 | 6210 | ||
| @@ -6291,29 +6229,14 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */) | |||
| 6291 | Scroll bars | 6229 | Scroll bars |
| 6292 | ***********************************************************************/ | 6230 | ***********************************************************************/ |
| 6293 | 6231 | ||
| 6294 | DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, | 6232 | static struct window * |
| 6295 | Sset_window_scroll_bars, 2, 4, 0, | 6233 | set_window_scroll_bars (struct window *w, Lisp_Object width, |
| 6296 | doc: /* Set width and type of scroll bars of window WINDOW. | 6234 | Lisp_Object vertical_type, Lisp_Object horizontal_type) |
| 6297 | WINDOW must be a live window and defaults to the selected one. | ||
| 6298 | |||
| 6299 | Second parameter WIDTH specifies the pixel width for the scroll bar; | ||
| 6300 | this is automatically adjusted to a multiple of the frame column width. | ||
| 6301 | Third parameter VERTICAL-TYPE specifies the type of the vertical scroll | ||
| 6302 | bar: left, right, or nil. | ||
| 6303 | If WIDTH is nil, use the frame's scroll-bar width. | ||
| 6304 | If VERTICAL-TYPE is t, use the frame's scroll-bar type. | ||
| 6305 | Fourth parameter HORIZONTAL-TYPE is currently unused. */) | ||
| 6306 | (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, Lisp_Object horizontal_type) | ||
| 6307 | { | 6235 | { |
| 6308 | struct window *w = decode_live_window (window); | 6236 | int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); |
| 6309 | 6237 | ||
| 6310 | if (!NILP (width)) | 6238 | if (iwidth == 0) |
| 6311 | { | 6239 | vertical_type = Qnil; |
| 6312 | CHECK_RANGED_INTEGER (width, 0, INT_MAX); | ||
| 6313 | |||
| 6314 | if (XINT (width) == 0) | ||
| 6315 | vertical_type = Qnil; | ||
| 6316 | } | ||
| 6317 | 6240 | ||
| 6318 | if (!(NILP (vertical_type) | 6241 | if (!(NILP (vertical_type) |
| 6319 | || EQ (vertical_type, Qleft) | 6242 | || EQ (vertical_type, Qleft) |
| @@ -6321,22 +6244,37 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */) | |||
| 6321 | || EQ (vertical_type, Qt))) | 6244 | || EQ (vertical_type, Qt))) |
| 6322 | error ("Invalid type of vertical scroll bar"); | 6245 | error ("Invalid type of vertical scroll bar"); |
| 6323 | 6246 | ||
| 6324 | if (!EQ (w->scroll_bar_width, width) | 6247 | if (w->scroll_bar_width != iwidth |
| 6325 | || !EQ (w->vertical_scroll_bar_type, vertical_type)) | 6248 | || !EQ (w->vertical_scroll_bar_type, vertical_type)) |
| 6326 | { | 6249 | { |
| 6327 | wset_scroll_bar_width (w, width); | 6250 | w->scroll_bar_width = iwidth; |
| 6328 | wset_vertical_scroll_bar_type (w, vertical_type); | 6251 | wset_vertical_scroll_bar_type (w, vertical_type); |
| 6252 | return w; | ||
| 6253 | } | ||
| 6254 | return NULL; | ||
| 6255 | } | ||
| 6329 | 6256 | ||
| 6330 | adjust_window_margins (w); | 6257 | DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, |
| 6331 | 6258 | Sset_window_scroll_bars, 2, 4, 0, | |
| 6332 | clear_glyph_matrix (w->current_matrix); | 6259 | doc: /* Set width and type of scroll bars of window WINDOW. |
| 6333 | w->window_end_valid = 0; | 6260 | WINDOW must be a live window and defaults to the selected one. |
| 6334 | 6261 | ||
| 6335 | ++windows_or_buffers_changed; | 6262 | Second parameter WIDTH specifies the pixel width for the scroll bar; |
| 6336 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); | 6263 | this is automatically adjusted to a multiple of the frame column width. |
| 6337 | } | 6264 | Third parameter VERTICAL-TYPE specifies the type of the vertical scroll |
| 6265 | bar: left, right, or nil. | ||
| 6266 | If WIDTH is nil, use the frame's scroll-bar width. | ||
| 6267 | If VERTICAL-TYPE is t, use the frame's scroll-bar type. | ||
| 6268 | Fourth parameter HORIZONTAL-TYPE is currently unused. | ||
| 6338 | 6269 | ||
| 6339 | return Qnil; | 6270 | Return t if scroll bars was actually changed and nil otherwise. */) |
| 6271 | (Lisp_Object window, Lisp_Object width, | ||
| 6272 | Lisp_Object vertical_type, Lisp_Object horizontal_type) | ||
| 6273 | { | ||
| 6274 | struct window *w | ||
| 6275 | = set_window_scroll_bars (decode_live_window (window), | ||
| 6276 | width, vertical_type, horizontal_type); | ||
| 6277 | return w ? (apply_window_adjustment (w), Qt) : Qnil; | ||
| 6340 | } | 6278 | } |
| 6341 | 6279 | ||
| 6342 | 6280 | ||
| @@ -6465,38 +6403,6 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u | |||
| 6465 | return cont; | 6403 | return cont; |
| 6466 | } | 6404 | } |
| 6467 | 6405 | ||
| 6468 | |||
| 6469 | /* Freeze or unfreeze the window start of W unless it is a | ||
| 6470 | mini-window or the selected window. FREEZE_P non-null means freeze | ||
| 6471 | the window start. */ | ||
| 6472 | |||
| 6473 | static int | ||
| 6474 | freeze_window_start (struct window *w, void *freeze_p) | ||
| 6475 | { | ||
| 6476 | if (MINI_WINDOW_P (w) | ||
| 6477 | || (WINDOWP (selected_window) /* Can be nil in corner cases. */ | ||
| 6478 | && (w == XWINDOW (selected_window) | ||
| 6479 | || (MINI_WINDOW_P (XWINDOW (selected_window)) | ||
| 6480 | && ! NILP (Vminibuf_scroll_window) | ||
| 6481 | && w == XWINDOW (Vminibuf_scroll_window))))) | ||
| 6482 | freeze_p = NULL; | ||
| 6483 | |||
| 6484 | w->frozen_window_start_p = freeze_p != NULL; | ||
| 6485 | return 1; | ||
| 6486 | } | ||
| 6487 | |||
| 6488 | |||
| 6489 | /* Freeze or unfreeze the window starts of all leaf windows on frame | ||
| 6490 | F, except the selected window and a mini-window. FREEZE_P non-zero | ||
| 6491 | means freeze the window start. */ | ||
| 6492 | |||
| 6493 | void | ||
| 6494 | freeze_window_starts (struct frame *f, bool freeze_p) | ||
| 6495 | { | ||
| 6496 | foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0)); | ||
| 6497 | } | ||
| 6498 | |||
| 6499 | |||
| 6500 | /*********************************************************************** | 6406 | /*********************************************************************** |
| 6501 | Initialization | 6407 | Initialization |
| 6502 | ***********************************************************************/ | 6408 | ***********************************************************************/ |
diff --git a/src/window.h b/src/window.h index 5da6165c48d..efe03737052 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -141,32 +141,10 @@ struct window | |||
| 141 | it yet, or if the frame doesn't have any scroll bars, this is nil. */ | 141 | it yet, or if the frame doesn't have any scroll bars, this is nil. */ |
| 142 | Lisp_Object vertical_scroll_bar; | 142 | Lisp_Object vertical_scroll_bar; |
| 143 | 143 | ||
| 144 | /* Width of left and right marginal areas. A value of nil means | ||
| 145 | no margin. */ | ||
| 146 | Lisp_Object left_margin_cols; | ||
| 147 | Lisp_Object right_margin_cols; | ||
| 148 | |||
| 149 | /* Width of left and right fringes. | ||
| 150 | A value of nil or t means use frame values. */ | ||
| 151 | Lisp_Object left_fringe_width; | ||
| 152 | Lisp_Object right_fringe_width; | ||
| 153 | |||
| 154 | /* Pixel width of scroll bars. | ||
| 155 | A value of nil or t means use frame values. */ | ||
| 156 | Lisp_Object scroll_bar_width; | ||
| 157 | |||
| 158 | /* Type of vertical scroll bar. A value of nil means | 144 | /* Type of vertical scroll bar. A value of nil means |
| 159 | no scroll bar. A value of t means use frame value. */ | 145 | no scroll bar. A value of t means use frame value. */ |
| 160 | Lisp_Object vertical_scroll_bar_type; | 146 | Lisp_Object vertical_scroll_bar_type; |
| 161 | 147 | ||
| 162 | /* Z - the buffer position of the last glyph in the current | ||
| 163 | matrix of W. Only valid if window_end_valid is nonzero. */ | ||
| 164 | Lisp_Object window_end_pos; | ||
| 165 | |||
| 166 | /* Glyph matrix row of the last glyph in the current matrix | ||
| 167 | of W. Only valid if window_end_valid is nonzero. */ | ||
| 168 | Lisp_Object window_end_vpos; | ||
| 169 | |||
| 170 | /* Display-table to use for displaying chars in this window. | 148 | /* Display-table to use for displaying chars in this window. |
| 171 | Nil means use the buffer's own display-table. */ | 149 | Nil means use the buffer's own display-table. */ |
| 172 | Lisp_Object display_table; | 150 | Lisp_Object display_table; |
| @@ -251,10 +229,6 @@ struct window | |||
| 251 | as the normal may yield a matrix which is too small. */ | 229 | as the normal may yield a matrix which is too small. */ |
| 252 | int nrows_scale_factor, ncols_scale_factor; | 230 | int nrows_scale_factor, ncols_scale_factor; |
| 253 | 231 | ||
| 254 | /* Cursor position as of last update that completed without | ||
| 255 | pause. This is the position of last_point. */ | ||
| 256 | struct cursor_pos last_cursor; | ||
| 257 | |||
| 258 | /* Intended cursor position. This is a position within the | 232 | /* Intended cursor position. This is a position within the |
| 259 | glyph matrix. */ | 233 | glyph matrix. */ |
| 260 | struct cursor_pos cursor; | 234 | struct cursor_pos cursor; |
| @@ -262,6 +236,13 @@ struct window | |||
| 262 | /* Where the cursor actually is. */ | 236 | /* Where the cursor actually is. */ |
| 263 | struct cursor_pos phys_cursor; | 237 | struct cursor_pos phys_cursor; |
| 264 | 238 | ||
| 239 | /* Internally used for redisplay purposes. */ | ||
| 240 | struct cursor_pos output_cursor; | ||
| 241 | |||
| 242 | /* Vertical cursor position as of last update that completed | ||
| 243 | without pause. This is the position of last_point. */ | ||
| 244 | int last_cursor_vpos; | ||
| 245 | |||
| 265 | /* Cursor type and width of last cursor drawn on the window. | 246 | /* Cursor type and width of last cursor drawn on the window. |
| 266 | Used for X and w32 frames; -1 initially. */ | 247 | Used for X and w32 frames; -1 initially. */ |
| 267 | int phys_cursor_type, phys_cursor_width; | 248 | int phys_cursor_type, phys_cursor_width; |
| @@ -269,6 +250,28 @@ struct window | |||
| 269 | /* This is handy for undrawing the cursor. */ | 250 | /* This is handy for undrawing the cursor. */ |
| 270 | int phys_cursor_ascent, phys_cursor_height; | 251 | int phys_cursor_ascent, phys_cursor_height; |
| 271 | 252 | ||
| 253 | /* Width of left and right fringes, in pixels. | ||
| 254 | A value of -1 means use frame values. */ | ||
| 255 | int left_fringe_width; | ||
| 256 | int right_fringe_width; | ||
| 257 | |||
| 258 | /* Width of left and right marginal areas in columns. | ||
| 259 | A value of 0 means no margin. */ | ||
| 260 | int left_margin_cols; | ||
| 261 | int right_margin_cols; | ||
| 262 | |||
| 263 | /* Pixel width of scroll bars. | ||
| 264 | A value of -1 means use frame values. */ | ||
| 265 | int scroll_bar_width; | ||
| 266 | |||
| 267 | /* Z - the buffer position of the last glyph in the current | ||
| 268 | matrix of W. Only valid if window_end_valid is nonzero. */ | ||
| 269 | ptrdiff_t window_end_pos; | ||
| 270 | |||
| 271 | /* Glyph matrix row of the last glyph in the current matrix | ||
| 272 | of W. Only valid if window_end_valid is nonzero. */ | ||
| 273 | int window_end_vpos; | ||
| 274 | |||
| 272 | /* Non-zero if this window is a minibuffer window. */ | 275 | /* Non-zero if this window is a minibuffer window. */ |
| 273 | unsigned mini : 1; | 276 | unsigned mini : 1; |
| 274 | 277 | ||
| @@ -316,11 +319,6 @@ struct window | |||
| 316 | Currently only used for menu bar windows of frames. */ | 319 | Currently only used for menu bar windows of frames. */ |
| 317 | unsigned pseudo_window_p : 1; | 320 | unsigned pseudo_window_p : 1; |
| 318 | 321 | ||
| 319 | /* 1 means the window start of this window is frozen and may not | ||
| 320 | be changed during redisplay. If point is not in the window, | ||
| 321 | accept that. */ | ||
| 322 | unsigned frozen_window_start_p : 1; | ||
| 323 | |||
| 324 | /* Non-zero means fringes are drawn outside display margins. | 322 | /* Non-zero means fringes are drawn outside display margins. |
| 325 | Otherwise draw them between margin areas and text. */ | 323 | Otherwise draw them between margin areas and text. */ |
| 326 | unsigned fringes_outside_margins : 1; | 324 | unsigned fringes_outside_margins : 1; |
| @@ -371,16 +369,6 @@ wset_vertical_scroll_bar (struct window *w, Lisp_Object val) | |||
| 371 | w->vertical_scroll_bar = val; | 369 | w->vertical_scroll_bar = val; |
| 372 | } | 370 | } |
| 373 | WINDOW_INLINE void | 371 | WINDOW_INLINE void |
| 374 | wset_window_end_pos (struct window *w, Lisp_Object val) | ||
| 375 | { | ||
| 376 | w->window_end_pos = val; | ||
| 377 | } | ||
| 378 | WINDOW_INLINE void | ||
| 379 | wset_window_end_vpos (struct window *w, Lisp_Object val) | ||
| 380 | { | ||
| 381 | w->window_end_vpos = val; | ||
| 382 | } | ||
| 383 | WINDOW_INLINE void | ||
| 384 | wset_prev_buffers (struct window *w, Lisp_Object val) | 372 | wset_prev_buffers (struct window *w, Lisp_Object val) |
| 385 | { | 373 | { |
| 386 | w->prev_buffers = val; | 374 | w->prev_buffers = val; |
| @@ -605,33 +593,21 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 605 | 593 | ||
| 606 | /* Width of left margin area in columns. */ | 594 | /* Width of left margin area in columns. */ |
| 607 | 595 | ||
| 608 | #define WINDOW_LEFT_MARGIN_COLS(W) \ | 596 | #define WINDOW_LEFT_MARGIN_COLS(W) (W->left_margin_cols) |
| 609 | (NILP (W->left_margin_cols) \ | ||
| 610 | ? 0 \ | ||
| 611 | : XINT (W->left_margin_cols)) | ||
| 612 | 597 | ||
| 613 | /* Width of right marginal area in columns. */ | 598 | /* Width of right marginal area in columns. */ |
| 614 | 599 | ||
| 615 | #define WINDOW_RIGHT_MARGIN_COLS(W) \ | 600 | #define WINDOW_RIGHT_MARGIN_COLS(W) (W->right_margin_cols) |
| 616 | (NILP (W->right_margin_cols) \ | ||
| 617 | ? 0 \ | ||
| 618 | : XINT (W->right_margin_cols)) | ||
| 619 | 601 | ||
| 620 | /* Width of left margin area in pixels. */ | 602 | /* Width of left margin area in pixels. */ |
| 621 | 603 | ||
| 622 | #define WINDOW_LEFT_MARGIN_WIDTH(W) \ | 604 | #define WINDOW_LEFT_MARGIN_WIDTH(W) \ |
| 623 | (NILP (W->left_margin_cols) \ | 605 | (W->left_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W)) |
| 624 | ? 0 \ | ||
| 625 | : (XINT (W->left_margin_cols) \ | ||
| 626 | * WINDOW_FRAME_COLUMN_WIDTH (W))) | ||
| 627 | 606 | ||
| 628 | /* Width of right marginal area in pixels. */ | 607 | /* Width of right marginal area in pixels. */ |
| 629 | 608 | ||
| 630 | #define WINDOW_RIGHT_MARGIN_WIDTH(W) \ | 609 | #define WINDOW_RIGHT_MARGIN_WIDTH(W) \ |
| 631 | (NILP (W->right_margin_cols) \ | 610 | (W->right_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W)) |
| 632 | ? 0 \ | ||
| 633 | : (XINT (W->right_margin_cols) \ | ||
| 634 | * WINDOW_FRAME_COLUMN_WIDTH (W))) | ||
| 635 | 611 | ||
| 636 | /* Total width of fringes reserved for drawing truncation bitmaps, | 612 | /* Total width of fringes reserved for drawing truncation bitmaps, |
| 637 | continuation bitmaps and alike. The width is in canonical char | 613 | continuation bitmaps and alike. The width is in canonical char |
| @@ -640,10 +616,10 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 640 | able to split windows horizontally nicely. */ | 616 | able to split windows horizontally nicely. */ |
| 641 | 617 | ||
| 642 | #define WINDOW_FRINGE_COLS(W) \ | 618 | #define WINDOW_FRINGE_COLS(W) \ |
| 643 | ((INTEGERP (W->left_fringe_width) \ | 619 | ((W->left_fringe_width >= 0 \ |
| 644 | || INTEGERP (W->right_fringe_width)) \ | 620 | && W->right_fringe_width >= 0) \ |
| 645 | ? ((WINDOW_LEFT_FRINGE_WIDTH (W) \ | 621 | ? ((W->left_fringe_width \ |
| 646 | + WINDOW_RIGHT_FRINGE_WIDTH (W) \ | 622 | + W->right_fringe_width \ |
| 647 | + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ | 623 | + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ |
| 648 | / WINDOW_FRAME_COLUMN_WIDTH (W)) \ | 624 | / WINDOW_FRAME_COLUMN_WIDTH (W)) \ |
| 649 | : FRAME_FRINGE_COLS (WINDOW_XFRAME (W))) | 625 | : FRAME_FRINGE_COLS (WINDOW_XFRAME (W))) |
| @@ -663,13 +639,11 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 663 | /* Pixel-width of the left and right fringe. */ | 639 | /* Pixel-width of the left and right fringe. */ |
| 664 | 640 | ||
| 665 | #define WINDOW_LEFT_FRINGE_WIDTH(W) \ | 641 | #define WINDOW_LEFT_FRINGE_WIDTH(W) \ |
| 666 | (INTEGERP (W->left_fringe_width) \ | 642 | (W->left_fringe_width >= 0 ? W->left_fringe_width \ |
| 667 | ? XFASTINT (W->left_fringe_width) \ | ||
| 668 | : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W))) | 643 | : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W))) |
| 669 | 644 | ||
| 670 | #define WINDOW_RIGHT_FRINGE_WIDTH(W) \ | 645 | #define WINDOW_RIGHT_FRINGE_WIDTH(W) \ |
| 671 | (INTEGERP (W->right_fringe_width) \ | 646 | (W->right_fringe_width >= 0 ? W->right_fringe_width \ |
| 672 | ? XFASTINT (W->right_fringe_width) \ | ||
| 673 | : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W))) | 647 | : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W))) |
| 674 | 648 | ||
| 675 | /* Total width of fringes in pixels. */ | 649 | /* Total width of fringes in pixels. */ |
| @@ -714,8 +688,7 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 714 | nonzero. */ | 688 | nonzero. */ |
| 715 | 689 | ||
| 716 | #define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \ | 690 | #define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \ |
| 717 | (INTEGERP (w->scroll_bar_width) \ | 691 | (w->scroll_bar_width >= 0 ? w->scroll_bar_width \ |
| 718 | ? XFASTINT (w->scroll_bar_width) \ | ||
| 719 | : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w))) | 692 | : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w))) |
| 720 | 693 | ||
| 721 | /* Width that a scroll bar in window W should have, if there is one. | 694 | /* Width that a scroll bar in window W should have, if there is one. |
| @@ -723,8 +696,8 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 723 | this is still nonzero. */ | 696 | this is still nonzero. */ |
| 724 | 697 | ||
| 725 | #define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \ | 698 | #define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \ |
| 726 | (INTEGERP (w->scroll_bar_width) \ | 699 | (w->scroll_bar_width >= 0 \ |
| 727 | ? ((XFASTINT (w->scroll_bar_width) \ | 700 | ? ((w->scroll_bar_width \ |
| 728 | + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) \ | 701 | + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) \ |
| 729 | / WINDOW_FRAME_COLUMN_WIDTH (w)) \ | 702 | / WINDOW_FRAME_COLUMN_WIDTH (w)) \ |
| 730 | : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w))) | 703 | : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w))) |
| @@ -847,13 +820,25 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 847 | #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ | 820 | #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ |
| 848 | (window_box_left ((W), TEXT_AREA) + (X)) | 821 | (window_box_left ((W), TEXT_AREA) + (X)) |
| 849 | 822 | ||
| 850 | /* This is the window in which the terminal's cursor should | 823 | /* Nonzero if the background of the window W's fringe that is adjacent to |
| 851 | be left when nothing is being done with it. This must | 824 | a scroll bar is extended to the gap between the fringe and the bar. */ |
| 852 | always be a leaf window, and its buffer is selected by | 825 | |
| 853 | the top level editing loop at the end of each command. | 826 | #define WINDOW_FRINGE_EXTENDED_P(w) \ |
| 827 | (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \ | ||
| 828 | ? (WINDOW_LEFTMOST_P (w) \ | ||
| 829 | && WINDOW_LEFT_FRINGE_WIDTH (w) \ | ||
| 830 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \ | ||
| 831 | || WINDOW_LEFT_MARGIN_COLS (w) == 0)) \ | ||
| 832 | : (WINDOW_RIGHTMOST_P (w) \ | ||
| 833 | && WINDOW_RIGHT_FRINGE_WIDTH (w) \ | ||
| 834 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \ | ||
| 835 | || WINDOW_RIGHT_MARGIN_COLS (w) == 0))) | ||
| 854 | 836 | ||
| 855 | This value is always the same as | 837 | /* This is the window in which the terminal's cursor should be left when |
| 856 | FRAME_SELECTED_WINDOW (selected_frame). */ | 838 | nothing is being done with it. This must always be a leaf window, and its |
| 839 | buffer is selected by the top level editing loop at the end of each command. | ||
| 840 | |||
| 841 | This value is always the same as FRAME_SELECTED_WINDOW (selected_frame). */ | ||
| 857 | 842 | ||
| 858 | extern Lisp_Object selected_window; | 843 | extern Lisp_Object selected_window; |
| 859 | 844 | ||
| @@ -874,21 +859,12 @@ extern Lisp_Object minibuf_window; | |||
| 874 | 859 | ||
| 875 | extern Lisp_Object minibuf_selected_window; | 860 | extern Lisp_Object minibuf_selected_window; |
| 876 | 861 | ||
| 877 | /* Window that the mouse is over (nil if no mouse support). */ | ||
| 878 | |||
| 879 | extern Lisp_Object Vmouse_window; | ||
| 880 | |||
| 881 | /* Last mouse-click event (nil if no mouse support). */ | ||
| 882 | |||
| 883 | extern Lisp_Object Vmouse_event; | ||
| 884 | |||
| 885 | extern Lisp_Object make_window (void); | 862 | extern Lisp_Object make_window (void); |
| 886 | extern Lisp_Object window_from_coordinates (struct frame *, int, int, | 863 | extern Lisp_Object window_from_coordinates (struct frame *, int, int, |
| 887 | enum window_part *, bool); | 864 | enum window_part *, bool); |
| 888 | extern void resize_frame_windows (struct frame *, int, bool); | 865 | extern void resize_frame_windows (struct frame *, int, bool); |
| 889 | extern void restore_window_configuration (Lisp_Object); | 866 | extern void restore_window_configuration (Lisp_Object); |
| 890 | extern void delete_all_child_windows (Lisp_Object); | 867 | extern void delete_all_child_windows (Lisp_Object); |
| 891 | extern void freeze_window_starts (struct frame *, bool); | ||
| 892 | extern void grow_mini_window (struct window *, int); | 868 | extern void grow_mini_window (struct window *, int); |
| 893 | extern void shrink_mini_window (struct window *); | 869 | extern void shrink_mini_window (struct window *); |
| 894 | extern int window_relative_x_coord (struct window *, enum window_part, int); | 870 | extern int window_relative_x_coord (struct window *, enum window_part, int); |
| @@ -925,10 +901,6 @@ extern int update_mode_lines; | |||
| 925 | 901 | ||
| 926 | extern int windows_or_buffers_changed; | 902 | extern int windows_or_buffers_changed; |
| 927 | 903 | ||
| 928 | /* Nonzero means a frame's cursor type has been changed. */ | ||
| 929 | |||
| 930 | extern int cursor_type_changed; | ||
| 931 | |||
| 932 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the | 904 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
| 933 | minimum allowable size. */ | 905 | minimum allowable size. */ |
| 934 | 906 | ||
| @@ -973,11 +945,28 @@ extern void replace_buffer_in_windows (Lisp_Object); | |||
| 973 | extern void replace_buffer_in_windows_safely (Lisp_Object); | 945 | extern void replace_buffer_in_windows_safely (Lisp_Object); |
| 974 | /* This looks like a setter, but it is a bit special. */ | 946 | /* This looks like a setter, but it is a bit special. */ |
| 975 | extern void wset_buffer (struct window *, Lisp_Object); | 947 | extern void wset_buffer (struct window *, Lisp_Object); |
| 948 | extern bool window_outdated (struct window *); | ||
| 976 | extern void init_window_once (void); | 949 | extern void init_window_once (void); |
| 977 | extern void init_window (void); | 950 | extern void init_window (void); |
| 978 | extern void syms_of_window (void); | 951 | extern void syms_of_window (void); |
| 979 | extern void keys_of_window (void); | 952 | extern void keys_of_window (void); |
| 980 | 953 | ||
| 954 | /* Move cursor to row/column position VPOS/HPOS, pixel coordinates | ||
| 955 | Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y | ||
| 956 | are window-relative pixel positions. This is always done during | ||
| 957 | window update, so the position is the future output cursor position | ||
| 958 | for currently updated window W. */ | ||
| 959 | |||
| 960 | WINDOW_INLINE void | ||
| 961 | output_cursor_to (struct window *w, int vpos, int hpos, int y, int x) | ||
| 962 | { | ||
| 963 | eassert (w); | ||
| 964 | w->output_cursor.hpos = hpos; | ||
| 965 | w->output_cursor.vpos = vpos; | ||
| 966 | w->output_cursor.x = x; | ||
| 967 | w->output_cursor.y = y; | ||
| 968 | } | ||
| 969 | |||
| 981 | INLINE_HEADER_END | 970 | INLINE_HEADER_END |
| 982 | 971 | ||
| 983 | #endif /* not WINDOW_H_INCLUDED */ | 972 | #endif /* not WINDOW_H_INCLUDED */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 7a1f03ce244..d78e78a58d3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -524,7 +524,7 @@ int windows_or_buffers_changed; | |||
| 524 | 524 | ||
| 525 | /* Nonzero means a frame's cursor type has been changed. */ | 525 | /* Nonzero means a frame's cursor type has been changed. */ |
| 526 | 526 | ||
| 527 | int cursor_type_changed; | 527 | static int cursor_type_changed; |
| 528 | 528 | ||
| 529 | /* Nonzero after display_mode_line if %l was used and it displayed a | 529 | /* Nonzero after display_mode_line if %l was used and it displayed a |
| 530 | line number. */ | 530 | line number. */ |
| @@ -804,7 +804,6 @@ static void pint2str (char *, int, ptrdiff_t); | |||
| 804 | static void pint2hrstr (char *, int, ptrdiff_t); | 804 | static void pint2hrstr (char *, int, ptrdiff_t); |
| 805 | static struct text_pos run_window_scroll_functions (Lisp_Object, | 805 | static struct text_pos run_window_scroll_functions (Lisp_Object, |
| 806 | struct text_pos); | 806 | struct text_pos); |
| 807 | static void reconsider_clip_changes (struct window *, struct buffer *); | ||
| 808 | static int text_outside_line_unchanged_p (struct window *, | 807 | static int text_outside_line_unchanged_p (struct window *, |
| 809 | ptrdiff_t, ptrdiff_t); | 808 | ptrdiff_t, ptrdiff_t); |
| 810 | static void store_mode_line_noprop_char (char); | 809 | static void store_mode_line_noprop_char (char); |
| @@ -967,12 +966,12 @@ window_text_bottom_y (struct window *w) | |||
| 967 | return height; | 966 | return height; |
| 968 | } | 967 | } |
| 969 | 968 | ||
| 970 | /* Return the pixel width of display area AREA of window W. AREA < 0 | 969 | /* Return the pixel width of display area AREA of window W. |
| 971 | means return the total width of W, not including fringes to | 970 | ANY_AREA means return the total width of W, not including |
| 972 | the left and right of the window. */ | 971 | fringes to the left and right of the window. */ |
| 973 | 972 | ||
| 974 | int | 973 | int |
| 975 | window_box_width (struct window *w, int area) | 974 | window_box_width (struct window *w, enum glyph_row_area area) |
| 976 | { | 975 | { |
| 977 | int cols = w->total_cols; | 976 | int cols = w->total_cols; |
| 978 | int pixels = 0; | 977 | int pixels = 0; |
| @@ -983,22 +982,18 @@ window_box_width (struct window *w, int area) | |||
| 983 | 982 | ||
| 984 | if (area == TEXT_AREA) | 983 | if (area == TEXT_AREA) |
| 985 | { | 984 | { |
| 986 | if (INTEGERP (w->left_margin_cols)) | 985 | cols -= max (0, w->left_margin_cols); |
| 987 | cols -= XFASTINT (w->left_margin_cols); | 986 | cols -= max (0, w->right_margin_cols); |
| 988 | if (INTEGERP (w->right_margin_cols)) | ||
| 989 | cols -= XFASTINT (w->right_margin_cols); | ||
| 990 | pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w); | 987 | pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w); |
| 991 | } | 988 | } |
| 992 | else if (area == LEFT_MARGIN_AREA) | 989 | else if (area == LEFT_MARGIN_AREA) |
| 993 | { | 990 | { |
| 994 | cols = (INTEGERP (w->left_margin_cols) | 991 | cols = max (0, w->left_margin_cols); |
| 995 | ? XFASTINT (w->left_margin_cols) : 0); | ||
| 996 | pixels = 0; | 992 | pixels = 0; |
| 997 | } | 993 | } |
| 998 | else if (area == RIGHT_MARGIN_AREA) | 994 | else if (area == RIGHT_MARGIN_AREA) |
| 999 | { | 995 | { |
| 1000 | cols = (INTEGERP (w->right_margin_cols) | 996 | cols = max (0, w->right_margin_cols); |
| 1001 | ? XFASTINT (w->right_margin_cols) : 0); | ||
| 1002 | pixels = 0; | 997 | pixels = 0; |
| 1003 | } | 998 | } |
| 1004 | } | 999 | } |
| @@ -1054,11 +1049,11 @@ window_box_height (struct window *w) | |||
| 1054 | } | 1049 | } |
| 1055 | 1050 | ||
| 1056 | /* Return the window-relative coordinate of the left edge of display | 1051 | /* Return the window-relative coordinate of the left edge of display |
| 1057 | area AREA of window W. AREA < 0 means return the left edge of the | 1052 | area AREA of window W. ANY_AREA means return the left edge of the |
| 1058 | whole window, to the right of the left fringe of W. */ | 1053 | whole window, to the right of the left fringe of W. */ |
| 1059 | 1054 | ||
| 1060 | int | 1055 | int |
| 1061 | window_box_left_offset (struct window *w, int area) | 1056 | window_box_left_offset (struct window *w, enum glyph_row_area area) |
| 1062 | { | 1057 | { |
| 1063 | int x; | 1058 | int x; |
| 1064 | 1059 | ||
| @@ -1086,21 +1081,21 @@ window_box_left_offset (struct window *w, int area) | |||
| 1086 | 1081 | ||
| 1087 | 1082 | ||
| 1088 | /* Return the window-relative coordinate of the right edge of display | 1083 | /* Return the window-relative coordinate of the right edge of display |
| 1089 | area AREA of window W. AREA < 0 means return the right edge of the | 1084 | area AREA of window W. ANY_AREA means return the right edge of the |
| 1090 | whole window, to the left of the right fringe of W. */ | 1085 | whole window, to the left of the right fringe of W. */ |
| 1091 | 1086 | ||
| 1092 | int | 1087 | int |
| 1093 | window_box_right_offset (struct window *w, int area) | 1088 | window_box_right_offset (struct window *w, enum glyph_row_area area) |
| 1094 | { | 1089 | { |
| 1095 | return window_box_left_offset (w, area) + window_box_width (w, area); | 1090 | return window_box_left_offset (w, area) + window_box_width (w, area); |
| 1096 | } | 1091 | } |
| 1097 | 1092 | ||
| 1098 | /* Return the frame-relative coordinate of the left edge of display | 1093 | /* Return the frame-relative coordinate of the left edge of display |
| 1099 | area AREA of window W. AREA < 0 means return the left edge of the | 1094 | area AREA of window W. ANY_AREA means return the left edge of the |
| 1100 | whole window, to the right of the left fringe of W. */ | 1095 | whole window, to the right of the left fringe of W. */ |
| 1101 | 1096 | ||
| 1102 | int | 1097 | int |
| 1103 | window_box_left (struct window *w, int area) | 1098 | window_box_left (struct window *w, enum glyph_row_area area) |
| 1104 | { | 1099 | { |
| 1105 | struct frame *f = XFRAME (w->frame); | 1100 | struct frame *f = XFRAME (w->frame); |
| 1106 | int x; | 1101 | int x; |
| @@ -1116,25 +1111,25 @@ window_box_left (struct window *w, int area) | |||
| 1116 | 1111 | ||
| 1117 | 1112 | ||
| 1118 | /* Return the frame-relative coordinate of the right edge of display | 1113 | /* Return the frame-relative coordinate of the right edge of display |
| 1119 | area AREA of window W. AREA < 0 means return the right edge of the | 1114 | area AREA of window W. ANY_AREA means return the right edge of the |
| 1120 | whole window, to the left of the right fringe of W. */ | 1115 | whole window, to the left of the right fringe of W. */ |
| 1121 | 1116 | ||
| 1122 | int | 1117 | int |
| 1123 | window_box_right (struct window *w, int area) | 1118 | window_box_right (struct window *w, enum glyph_row_area area) |
| 1124 | { | 1119 | { |
| 1125 | return window_box_left (w, area) + window_box_width (w, area); | 1120 | return window_box_left (w, area) + window_box_width (w, area); |
| 1126 | } | 1121 | } |
| 1127 | 1122 | ||
| 1128 | /* Get the bounding box of the display area AREA of window W, without | 1123 | /* Get the bounding box of the display area AREA of window W, without |
| 1129 | mode lines, in frame-relative coordinates. AREA < 0 means the | 1124 | mode lines, in frame-relative coordinates. ANY_AREA means the |
| 1130 | whole window, not including the left and right fringes of | 1125 | whole window, not including the left and right fringes of |
| 1131 | the window. Return in *BOX_X and *BOX_Y the frame-relative pixel | 1126 | the window. Return in *BOX_X and *BOX_Y the frame-relative pixel |
| 1132 | coordinates of the upper-left corner of the box. Return in | 1127 | coordinates of the upper-left corner of the box. Return in |
| 1133 | *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */ | 1128 | *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */ |
| 1134 | 1129 | ||
| 1135 | void | 1130 | void |
| 1136 | window_box (struct window *w, int area, int *box_x, int *box_y, | 1131 | window_box (struct window *w, enum glyph_row_area area, int *box_x, |
| 1137 | int *box_width, int *box_height) | 1132 | int *box_y, int *box_width, int *box_height) |
| 1138 | { | 1133 | { |
| 1139 | if (box_width) | 1134 | if (box_width) |
| 1140 | *box_width = window_box_width (w, area); | 1135 | *box_width = window_box_width (w, area); |
| @@ -1152,19 +1147,18 @@ window_box (struct window *w, int area, int *box_x, int *box_y, | |||
| 1152 | 1147 | ||
| 1153 | 1148 | ||
| 1154 | /* Get the bounding box of the display area AREA of window W, without | 1149 | /* Get the bounding box of the display area AREA of window W, without |
| 1155 | mode lines. AREA < 0 means the whole window, not including the | 1150 | mode lines and both fringes of the window. Return in *TOP_LEFT_X |
| 1156 | left and right fringe of the window. Return in *TOP_LEFT_X | ||
| 1157 | and TOP_LEFT_Y the frame-relative pixel coordinates of the | 1151 | and TOP_LEFT_Y the frame-relative pixel coordinates of the |
| 1158 | upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and | 1152 | upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and |
| 1159 | *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the | 1153 | *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the |
| 1160 | box. */ | 1154 | box. */ |
| 1161 | 1155 | ||
| 1162 | static void | 1156 | static void |
| 1163 | window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y, | 1157 | window_box_edges (struct window *w, int *top_left_x, int *top_left_y, |
| 1164 | int *bottom_right_x, int *bottom_right_y) | 1158 | int *bottom_right_x, int *bottom_right_y) |
| 1165 | { | 1159 | { |
| 1166 | window_box (w, area, top_left_x, top_left_y, bottom_right_x, | 1160 | window_box (w, ANY_AREA, top_left_x, top_left_y, |
| 1167 | bottom_right_y); | 1161 | bottom_right_x, bottom_right_y); |
| 1168 | *bottom_right_x += *top_left_x; | 1162 | *bottom_right_x += *top_left_x; |
| 1169 | *bottom_right_y += *top_left_y; | 1163 | *bottom_right_y += *top_left_y; |
| 1170 | } | 1164 | } |
| @@ -2466,7 +2460,16 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect) | |||
| 2466 | 2460 | ||
| 2467 | #endif /* HAVE_WINDOW_SYSTEM */ | 2461 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 2468 | 2462 | ||
| 2469 | 2463 | static void | |
| 2464 | adjust_window_ends (struct window *w, struct glyph_row *row, bool current) | ||
| 2465 | { | ||
| 2466 | eassert (w); | ||
| 2467 | w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); | ||
| 2468 | w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); | ||
| 2469 | w->window_end_vpos | ||
| 2470 | = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix); | ||
| 2471 | } | ||
| 2472 | |||
| 2470 | /*********************************************************************** | 2473 | /*********************************************************************** |
| 2471 | Lisp form evaluation | 2474 | Lisp form evaluation |
| 2472 | ***********************************************************************/ | 2475 | ***********************************************************************/ |
| @@ -2602,8 +2605,7 @@ check_window_end (struct window *w) | |||
| 2602 | if (!MINI_WINDOW_P (w) && w->window_end_valid) | 2605 | if (!MINI_WINDOW_P (w) && w->window_end_valid) |
| 2603 | { | 2606 | { |
| 2604 | struct glyph_row *row; | 2607 | struct glyph_row *row; |
| 2605 | eassert ((row = MATRIX_ROW (w->current_matrix, | 2608 | eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos), |
| 2606 | XFASTINT (w->window_end_vpos)), | ||
| 2607 | !row->enabled_p | 2609 | !row->enabled_p |
| 2608 | || MATRIX_ROW_DISPLAYS_TEXT_P (row) | 2610 | || MATRIX_ROW_DISPLAYS_TEXT_P (row) |
| 2609 | || MATRIX_ROW_VPOS (row, w->current_matrix) == 0)); | 2611 | || MATRIX_ROW_VPOS (row, w->current_matrix) == 0)); |
| @@ -3909,10 +3911,14 @@ handle_face_prop (struct it *it) | |||
| 3909 | /* For strings from a `display' property, use the face at | 3911 | /* For strings from a `display' property, use the face at |
| 3910 | IT's current buffer position as the base face to merge | 3912 | IT's current buffer position as the base face to merge |
| 3911 | with, so that overlay strings appear in the same face as | 3913 | with, so that overlay strings appear in the same face as |
| 3912 | surrounding text, unless they specify their own | 3914 | surrounding text, unless they specify their own faces. |
| 3913 | faces. */ | 3915 | For strings from wrap-prefix and line-prefix properties, |
| 3916 | use the default face, possibly remapped via | ||
| 3917 | Vface_remapping_alist. */ | ||
| 3914 | base_face_id = it->string_from_prefix_prop_p | 3918 | base_face_id = it->string_from_prefix_prop_p |
| 3915 | ? DEFAULT_FACE_ID | 3919 | ? (!NILP (Vface_remapping_alist) |
| 3920 | ? lookup_basic_face (it->f, DEFAULT_FACE_ID) | ||
| 3921 | : DEFAULT_FACE_ID) | ||
| 3916 | : underlying_face_id (it); | 3922 | : underlying_face_id (it); |
| 3917 | } | 3923 | } |
| 3918 | 3924 | ||
| @@ -5509,8 +5515,8 @@ next_overlay_string (struct it *it) | |||
| 5509 | static int | 5515 | static int |
| 5510 | compare_overlay_entries (const void *e1, const void *e2) | 5516 | compare_overlay_entries (const void *e1, const void *e2) |
| 5511 | { | 5517 | { |
| 5512 | struct overlay_entry *entry1 = (struct overlay_entry *) e1; | 5518 | struct overlay_entry const *entry1 = e1; |
| 5513 | struct overlay_entry *entry2 = (struct overlay_entry *) e2; | 5519 | struct overlay_entry const *entry2 = e2; |
| 5514 | int result; | 5520 | int result; |
| 5515 | 5521 | ||
| 5516 | if (entry1->after_string_p != entry2->after_string_p) | 5522 | if (entry1->after_string_p != entry2->after_string_p) |
| @@ -7043,7 +7049,9 @@ get_next_display_element (struct it *it) | |||
| 7043 | } | 7049 | } |
| 7044 | } | 7050 | } |
| 7045 | } | 7051 | } |
| 7046 | else | 7052 | /* next_element_from_display_vector sets this flag according to |
| 7053 | faces of the display vector glyphs, see there. */ | ||
| 7054 | else if (it->method != GET_FROM_DISPLAY_VECTOR) | ||
| 7047 | { | 7055 | { |
| 7048 | int face_id = face_after_it_pos (it); | 7056 | int face_id = face_after_it_pos (it); |
| 7049 | it->end_of_box_run_p | 7057 | it->end_of_box_run_p |
| @@ -7458,6 +7466,8 @@ static int | |||
| 7458 | next_element_from_display_vector (struct it *it) | 7466 | next_element_from_display_vector (struct it *it) |
| 7459 | { | 7467 | { |
| 7460 | Lisp_Object gc; | 7468 | Lisp_Object gc; |
| 7469 | int prev_face_id = it->face_id; | ||
| 7470 | int next_face_id; | ||
| 7461 | 7471 | ||
| 7462 | /* Precondition. */ | 7472 | /* Precondition. */ |
| 7463 | eassert (it->dpvec && it->current.dpvec_index >= 0); | 7473 | eassert (it->dpvec && it->current.dpvec_index >= 0); |
| @@ -7470,6 +7480,8 @@ next_element_from_display_vector (struct it *it) | |||
| 7470 | 7480 | ||
| 7471 | if (GLYPH_CODE_P (gc)) | 7481 | if (GLYPH_CODE_P (gc)) |
| 7472 | { | 7482 | { |
| 7483 | struct face *this_face, *prev_face, *next_face; | ||
| 7484 | |||
| 7473 | it->c = GLYPH_CODE_CHAR (gc); | 7485 | it->c = GLYPH_CODE_CHAR (gc); |
| 7474 | it->len = CHAR_BYTES (it->c); | 7486 | it->len = CHAR_BYTES (it->c); |
| 7475 | 7487 | ||
| @@ -7485,6 +7497,41 @@ next_element_from_display_vector (struct it *it) | |||
| 7485 | it->face_id = merge_faces (it->f, Qt, lface_id, | 7497 | it->face_id = merge_faces (it->f, Qt, lface_id, |
| 7486 | it->saved_face_id); | 7498 | it->saved_face_id); |
| 7487 | } | 7499 | } |
| 7500 | |||
| 7501 | /* Glyphs in the display vector could have the box face, so we | ||
| 7502 | need to set the related flags in the iterator, as | ||
| 7503 | appropriate. */ | ||
| 7504 | this_face = FACE_FROM_ID (it->f, it->face_id); | ||
| 7505 | prev_face = FACE_FROM_ID (it->f, prev_face_id); | ||
| 7506 | |||
| 7507 | /* Is this character the first character of a box-face run? */ | ||
| 7508 | it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX | ||
| 7509 | && (!prev_face | ||
| 7510 | || prev_face->box == FACE_NO_BOX)); | ||
| 7511 | |||
| 7512 | /* For the last character of the box-face run, we need to look | ||
| 7513 | either at the next glyph from the display vector, or at the | ||
| 7514 | face we saw before the display vector. */ | ||
| 7515 | next_face_id = it->saved_face_id; | ||
| 7516 | if (it->current.dpvec_index < it->dpend - it->dpvec - 1) | ||
| 7517 | { | ||
| 7518 | if (it->dpvec_face_id >= 0) | ||
| 7519 | next_face_id = it->dpvec_face_id; | ||
| 7520 | else | ||
| 7521 | { | ||
| 7522 | int lface_id = | ||
| 7523 | GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]); | ||
| 7524 | |||
| 7525 | if (lface_id > 0) | ||
| 7526 | next_face_id = merge_faces (it->f, Qt, lface_id, | ||
| 7527 | it->saved_face_id); | ||
| 7528 | } | ||
| 7529 | } | ||
| 7530 | next_face = FACE_FROM_ID (it->f, next_face_id); | ||
| 7531 | it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX | ||
| 7532 | && (!next_face | ||
| 7533 | || next_face->box == FACE_NO_BOX)); | ||
| 7534 | it->face_box_p = this_face && this_face->box != FACE_NO_BOX; | ||
| 7488 | } | 7535 | } |
| 7489 | else | 7536 | else |
| 7490 | /* Display table entry is invalid. Return a space. */ | 7537 | /* Display table entry is invalid. Return a space. */ |
| @@ -9059,7 +9106,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos | |||
| 9059 | && it->current_x == it->last_visible_x - 1 | 9106 | && it->current_x == it->last_visible_x - 1 |
| 9060 | && it->c != '\n' | 9107 | && it->c != '\n' |
| 9061 | && it->c != '\t' | 9108 | && it->c != '\t' |
| 9062 | && it->vpos < XFASTINT (it->w->window_end_vpos)) | 9109 | && it->vpos < it->w->window_end_vpos) |
| 9063 | { | 9110 | { |
| 9064 | it->continuation_lines_width += it->current_x; | 9111 | it->continuation_lines_width += it->current_x; |
| 9065 | it->current_x = it->hpos = it->max_ascent = it->max_descent = 0; | 9112 | it->current_x = it->hpos = it->max_ascent = it->max_descent = 0; |
| @@ -9790,7 +9837,7 @@ message3_nolog (Lisp_Object m) | |||
| 9790 | void | 9837 | void |
| 9791 | message1 (const char *m) | 9838 | message1 (const char *m) |
| 9792 | { | 9839 | { |
| 9793 | message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil); | 9840 | message3 (m ? build_unibyte_string (m) : Qnil); |
| 9794 | } | 9841 | } |
| 9795 | 9842 | ||
| 9796 | 9843 | ||
| @@ -9799,7 +9846,7 @@ message1 (const char *m) | |||
| 9799 | void | 9846 | void |
| 9800 | message1_nolog (const char *m) | 9847 | message1_nolog (const char *m) |
| 9801 | { | 9848 | { |
| 9802 | message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil); | 9849 | message3_nolog (m ? build_unibyte_string (m) : Qnil); |
| 9803 | } | 9850 | } |
| 9804 | 9851 | ||
| 9805 | /* Display a message M which contains a single %s | 9852 | /* Display a message M which contains a single %s |
| @@ -9909,7 +9956,7 @@ vmessage (const char *m, va_list ap) | |||
| 9909 | ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f); | 9956 | ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f); |
| 9910 | char *message_buf = alloca (maxsize + 1); | 9957 | char *message_buf = alloca (maxsize + 1); |
| 9911 | 9958 | ||
| 9912 | len = doprnt (message_buf, maxsize, m, (char *)0, ap); | 9959 | len = doprnt (message_buf, maxsize, m, 0, ap); |
| 9913 | 9960 | ||
| 9914 | message3 (make_string (message_buf, len)); | 9961 | message3 (make_string (message_buf, len)); |
| 9915 | } | 9962 | } |
| @@ -10461,7 +10508,8 @@ resize_mini_window (struct window *w, int exact_p) | |||
| 10461 | if (height > WINDOW_TOTAL_LINES (w)) | 10508 | if (height > WINDOW_TOTAL_LINES (w)) |
| 10462 | { | 10509 | { |
| 10463 | int old_height = WINDOW_TOTAL_LINES (w); | 10510 | int old_height = WINDOW_TOTAL_LINES (w); |
| 10464 | freeze_window_starts (f, 1); | 10511 | |
| 10512 | FRAME_WINDOWS_FROZEN (f) = 1; | ||
| 10465 | grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); | 10513 | grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); |
| 10466 | window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; | 10514 | window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; |
| 10467 | } | 10515 | } |
| @@ -10469,7 +10517,8 @@ resize_mini_window (struct window *w, int exact_p) | |||
| 10469 | && (exact_p || BEGV == ZV)) | 10517 | && (exact_p || BEGV == ZV)) |
| 10470 | { | 10518 | { |
| 10471 | int old_height = WINDOW_TOTAL_LINES (w); | 10519 | int old_height = WINDOW_TOTAL_LINES (w); |
| 10472 | freeze_window_starts (f, 0); | 10520 | |
| 10521 | FRAME_WINDOWS_FROZEN (f) = 0; | ||
| 10473 | shrink_mini_window (w); | 10522 | shrink_mini_window (w); |
| 10474 | window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; | 10523 | window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; |
| 10475 | } | 10524 | } |
| @@ -10480,19 +10529,21 @@ resize_mini_window (struct window *w, int exact_p) | |||
| 10480 | if (height > WINDOW_TOTAL_LINES (w)) | 10529 | if (height > WINDOW_TOTAL_LINES (w)) |
| 10481 | { | 10530 | { |
| 10482 | int old_height = WINDOW_TOTAL_LINES (w); | 10531 | int old_height = WINDOW_TOTAL_LINES (w); |
| 10483 | freeze_window_starts (f, 1); | 10532 | |
| 10533 | FRAME_WINDOWS_FROZEN (f) = 1; | ||
| 10484 | grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); | 10534 | grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); |
| 10485 | window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; | 10535 | window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; |
| 10486 | } | 10536 | } |
| 10487 | else if (height < WINDOW_TOTAL_LINES (w)) | 10537 | else if (height < WINDOW_TOTAL_LINES (w)) |
| 10488 | { | 10538 | { |
| 10489 | int old_height = WINDOW_TOTAL_LINES (w); | 10539 | int old_height = WINDOW_TOTAL_LINES (w); |
| 10490 | freeze_window_starts (f, 0); | 10540 | |
| 10541 | FRAME_WINDOWS_FROZEN (f) = 0; | ||
| 10491 | shrink_mini_window (w); | 10542 | shrink_mini_window (w); |
| 10492 | 10543 | ||
| 10493 | if (height) | 10544 | if (height) |
| 10494 | { | 10545 | { |
| 10495 | freeze_window_starts (f, 1); | 10546 | FRAME_WINDOWS_FROZEN (f) = 1; |
| 10496 | grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); | 10547 | grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); |
| 10497 | } | 10548 | } |
| 10498 | 10549 | ||
| @@ -10850,17 +10901,6 @@ buffer_shared_and_changed (void) | |||
| 10850 | && UNCHANGED_MODIFIED < MODIFF); | 10901 | && UNCHANGED_MODIFIED < MODIFF); |
| 10851 | } | 10902 | } |
| 10852 | 10903 | ||
| 10853 | /* Nonzero if W doesn't reflect the actual state of current buffer due | ||
| 10854 | to its text or overlays change. FIXME: this may be called when | ||
| 10855 | XBUFFER (w->contents) != current_buffer, which looks suspicious. */ | ||
| 10856 | |||
| 10857 | static int | ||
| 10858 | window_outdated (struct window *w) | ||
| 10859 | { | ||
| 10860 | return (w->last_modified < MODIFF | ||
| 10861 | || w->last_overlay_modified < OVERLAY_MODIFF); | ||
| 10862 | } | ||
| 10863 | |||
| 10864 | /* Nonzero if W's buffer was changed but not saved or Transient Mark mode | 10904 | /* Nonzero if W's buffer was changed but not saved or Transient Mark mode |
| 10865 | is enabled and mark of W's buffer was changed since last W's update. */ | 10905 | is enabled and mark of W's buffer was changed since last W's update. */ |
| 10866 | 10906 | ||
| @@ -10886,6 +10926,31 @@ mode_line_update_needed (struct window *w) | |||
| 10886 | && (w->column_number_displayed != current_column ())); | 10926 | && (w->column_number_displayed != current_column ())); |
| 10887 | } | 10927 | } |
| 10888 | 10928 | ||
| 10929 | /* Nonzero if window start of W is frozen and may not be changed during | ||
| 10930 | redisplay. */ | ||
| 10931 | |||
| 10932 | static bool | ||
| 10933 | window_frozen_p (struct window *w) | ||
| 10934 | { | ||
| 10935 | if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w)))) | ||
| 10936 | { | ||
| 10937 | Lisp_Object window; | ||
| 10938 | |||
| 10939 | XSETWINDOW (window, w); | ||
| 10940 | if (MINI_WINDOW_P (w)) | ||
| 10941 | return 0; | ||
| 10942 | else if (EQ (window, selected_window)) | ||
| 10943 | return 0; | ||
| 10944 | else if (MINI_WINDOW_P (XWINDOW (selected_window)) | ||
| 10945 | && EQ (window, Vminibuf_scroll_window)) | ||
| 10946 | /* This special window can't be frozen too. */ | ||
| 10947 | return 0; | ||
| 10948 | else | ||
| 10949 | return 1; | ||
| 10950 | } | ||
| 10951 | return 0; | ||
| 10952 | } | ||
| 10953 | |||
| 10889 | /*********************************************************************** | 10954 | /*********************************************************************** |
| 10890 | Mode Lines and Frame Titles | 10955 | Mode Lines and Frame Titles |
| 10891 | ***********************************************************************/ | 10956 | ***********************************************************************/ |
| @@ -11181,7 +11246,18 @@ prepare_menu_bars (void) | |||
| 11181 | { | 11246 | { |
| 11182 | f = XFRAME (frame); | 11247 | f = XFRAME (frame); |
| 11183 | if (!EQ (frame, tooltip_frame) | 11248 | if (!EQ (frame, tooltip_frame) |
| 11184 | && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))) | 11249 | && (FRAME_ICONIFIED_P (f) |
| 11250 | || FRAME_VISIBLE_P (f) == 1 | ||
| 11251 | /* Exclude TTY frames that are obscured because they | ||
| 11252 | are not the top frame on their console. This is | ||
| 11253 | because x_consider_frame_title actually switches | ||
| 11254 | to the frame, which for TTY frames means it is | ||
| 11255 | marked as garbaged, and will be completely | ||
| 11256 | redrawn on the next redisplay cycle. This causes | ||
| 11257 | TTY frames to be completely redrawn, when there | ||
| 11258 | are more than one of them, even though nothing | ||
| 11259 | should be changed on display. */ | ||
| 11260 | || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f)))) | ||
| 11185 | x_consider_frame_title (frame); | 11261 | x_consider_frame_title (frame); |
| 11186 | } | 11262 | } |
| 11187 | } | 11263 | } |
| @@ -11368,79 +11444,6 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run) | |||
| 11368 | return hooks_run; | 11444 | return hooks_run; |
| 11369 | } | 11445 | } |
| 11370 | 11446 | ||
| 11371 | |||
| 11372 | |||
| 11373 | /*********************************************************************** | ||
| 11374 | Output Cursor | ||
| 11375 | ***********************************************************************/ | ||
| 11376 | |||
| 11377 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 11378 | |||
| 11379 | /* EXPORT: | ||
| 11380 | Nominal cursor position -- where to draw output. | ||
| 11381 | HPOS and VPOS are window relative glyph matrix coordinates. | ||
| 11382 | X and Y are window relative pixel coordinates. */ | ||
| 11383 | |||
| 11384 | struct cursor_pos output_cursor; | ||
| 11385 | |||
| 11386 | |||
| 11387 | /* EXPORT: | ||
| 11388 | Set the global variable output_cursor to CURSOR. All cursor | ||
| 11389 | positions are relative to updated_window. */ | ||
| 11390 | |||
| 11391 | void | ||
| 11392 | set_output_cursor (struct cursor_pos *cursor) | ||
| 11393 | { | ||
| 11394 | output_cursor.hpos = cursor->hpos; | ||
| 11395 | output_cursor.vpos = cursor->vpos; | ||
| 11396 | output_cursor.x = cursor->x; | ||
| 11397 | output_cursor.y = cursor->y; | ||
| 11398 | } | ||
| 11399 | |||
| 11400 | |||
| 11401 | /* EXPORT for RIF: | ||
| 11402 | Set a nominal cursor position. | ||
| 11403 | |||
| 11404 | HPOS and VPOS are column/row positions in a window glyph matrix. X | ||
| 11405 | and Y are window text area relative pixel positions. | ||
| 11406 | |||
| 11407 | If this is done during an update, updated_window will contain the | ||
| 11408 | window that is being updated and the position is the future output | ||
| 11409 | cursor position for that window. If updated_window is null, use | ||
| 11410 | selected_window and display the cursor at the given position. */ | ||
| 11411 | |||
| 11412 | void | ||
| 11413 | x_cursor_to (int vpos, int hpos, int y, int x) | ||
| 11414 | { | ||
| 11415 | struct window *w; | ||
| 11416 | |||
| 11417 | /* If updated_window is not set, work on selected_window. */ | ||
| 11418 | if (updated_window) | ||
| 11419 | w = updated_window; | ||
| 11420 | else | ||
| 11421 | w = XWINDOW (selected_window); | ||
| 11422 | |||
| 11423 | /* Set the output cursor. */ | ||
| 11424 | output_cursor.hpos = hpos; | ||
| 11425 | output_cursor.vpos = vpos; | ||
| 11426 | output_cursor.x = x; | ||
| 11427 | output_cursor.y = y; | ||
| 11428 | |||
| 11429 | /* If not called as part of an update, really display the cursor. | ||
| 11430 | This will also set the cursor position of W. */ | ||
| 11431 | if (updated_window == NULL) | ||
| 11432 | { | ||
| 11433 | block_input (); | ||
| 11434 | display_and_set_cursor (w, 1, hpos, vpos, x, y); | ||
| 11435 | if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional) | ||
| 11436 | FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ()); | ||
| 11437 | unblock_input (); | ||
| 11438 | } | ||
| 11439 | } | ||
| 11440 | |||
| 11441 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 11442 | |||
| 11443 | |||
| 11444 | /*********************************************************************** | 11447 | /*********************************************************************** |
| 11445 | Tool-bars | 11448 | Tool-bars |
| 11446 | ***********************************************************************/ | 11449 | ***********************************************************************/ |
| @@ -12324,13 +12327,11 @@ note_tool_bar_highlight (struct frame *f, int x, int y) | |||
| 12324 | hlinfo->mouse_face_beg_col = hpos; | 12327 | hlinfo->mouse_face_beg_col = hpos; |
| 12325 | hlinfo->mouse_face_beg_row = vpos; | 12328 | hlinfo->mouse_face_beg_row = vpos; |
| 12326 | hlinfo->mouse_face_beg_x = x; | 12329 | hlinfo->mouse_face_beg_x = x; |
| 12327 | hlinfo->mouse_face_beg_y = row->y; | ||
| 12328 | hlinfo->mouse_face_past_end = 0; | 12330 | hlinfo->mouse_face_past_end = 0; |
| 12329 | 12331 | ||
| 12330 | hlinfo->mouse_face_end_col = hpos + 1; | 12332 | hlinfo->mouse_face_end_col = hpos + 1; |
| 12331 | hlinfo->mouse_face_end_row = vpos; | 12333 | hlinfo->mouse_face_end_row = vpos; |
| 12332 | hlinfo->mouse_face_end_x = x + glyph->pixel_width; | 12334 | hlinfo->mouse_face_end_x = x + glyph->pixel_width; |
| 12333 | hlinfo->mouse_face_end_y = row->y; | ||
| 12334 | hlinfo->mouse_face_window = window; | 12335 | hlinfo->mouse_face_window = window; |
| 12335 | hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; | 12336 | hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; |
| 12336 | 12337 | ||
| @@ -12866,13 +12867,13 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt, | |||
| 12866 | && start < pt && end > pt); | 12867 | && start < pt && end > pt); |
| 12867 | } | 12868 | } |
| 12868 | 12869 | ||
| 12869 | 12870 | /* Reconsider the clip changes of buffer which is displayed in W. */ | |
| 12870 | /* Reconsider the setting of B->clip_changed which is displayed | ||
| 12871 | in window W. */ | ||
| 12872 | 12871 | ||
| 12873 | static void | 12872 | static void |
| 12874 | reconsider_clip_changes (struct window *w, struct buffer *b) | 12873 | reconsider_clip_changes (struct window *w) |
| 12875 | { | 12874 | { |
| 12875 | struct buffer *b = XBUFFER (w->contents); | ||
| 12876 | |||
| 12876 | if (b->clip_changed | 12877 | if (b->clip_changed |
| 12877 | && w->window_end_valid | 12878 | && w->window_end_valid |
| 12878 | && w->current_matrix->buffer == b | 12879 | && w->current_matrix->buffer == b |
| @@ -12885,24 +12886,17 @@ reconsider_clip_changes (struct window *w, struct buffer *b) | |||
| 12885 | we set b->clip_changed to 1 to force updating the screen. If | 12886 | we set b->clip_changed to 1 to force updating the screen. If |
| 12886 | b->clip_changed has already been set to 1, we can skip this | 12887 | b->clip_changed has already been set to 1, we can skip this |
| 12887 | check. */ | 12888 | check. */ |
| 12888 | if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid) | 12889 | if (!b->clip_changed && w->window_end_valid) |
| 12889 | { | 12890 | { |
| 12890 | ptrdiff_t pt; | 12891 | ptrdiff_t pt = (w == XWINDOW (selected_window) |
| 12891 | 12892 | ? PT : marker_position (w->pointm)); | |
| 12892 | if (w == XWINDOW (selected_window)) | ||
| 12893 | pt = PT; | ||
| 12894 | else | ||
| 12895 | pt = marker_position (w->pointm); | ||
| 12896 | 12893 | ||
| 12897 | if ((w->current_matrix->buffer != XBUFFER (w->contents) | 12894 | if ((w->current_matrix->buffer != b || pt != w->last_point) |
| 12898 | || pt != w->last_point) | ||
| 12899 | && check_point_in_composition (w->current_matrix->buffer, | 12895 | && check_point_in_composition (w->current_matrix->buffer, |
| 12900 | w->last_point, | 12896 | w->last_point, b, pt)) |
| 12901 | XBUFFER (w->contents), pt)) | ||
| 12902 | b->clip_changed = 1; | 12897 | b->clip_changed = 1; |
| 12903 | } | 12898 | } |
| 12904 | } | 12899 | } |
| 12905 | |||
| 12906 | 12900 | ||
| 12907 | #define STOP_POLLING \ | 12901 | #define STOP_POLLING \ |
| 12908 | do { if (! polling_stopped_here) stop_polling (); \ | 12902 | do { if (! polling_stopped_here) stop_polling (); \ |
| @@ -12923,10 +12917,10 @@ redisplay_internal (void) | |||
| 12923 | struct window *sw; | 12917 | struct window *sw; |
| 12924 | struct frame *fr; | 12918 | struct frame *fr; |
| 12925 | int pending; | 12919 | int pending; |
| 12926 | int must_finish = 0; | 12920 | bool must_finish = 0, match_p; |
| 12927 | struct text_pos tlbufpos, tlendpos; | 12921 | struct text_pos tlbufpos, tlendpos; |
| 12928 | int number_of_visible_frames; | 12922 | int number_of_visible_frames; |
| 12929 | ptrdiff_t count, count1; | 12923 | ptrdiff_t count; |
| 12930 | struct frame *sf; | 12924 | struct frame *sf; |
| 12931 | int polling_stopped_here = 0; | 12925 | int polling_stopped_here = 0; |
| 12932 | Lisp_Object tail, frame; | 12926 | Lisp_Object tail, frame; |
| @@ -12983,7 +12977,6 @@ redisplay_internal (void) | |||
| 12983 | sw = w; | 12977 | sw = w; |
| 12984 | 12978 | ||
| 12985 | pending = 0; | 12979 | pending = 0; |
| 12986 | reconsider_clip_changes (w, current_buffer); | ||
| 12987 | last_escape_glyph_frame = NULL; | 12980 | last_escape_glyph_frame = NULL; |
| 12988 | last_escape_glyph_face_id = (1 << FACE_ID_BITS); | 12981 | last_escape_glyph_face_id = (1 << FACE_ID_BITS); |
| 12989 | last_glyphless_glyph_frame = NULL; | 12982 | last_glyphless_glyph_frame = NULL; |
| @@ -13038,10 +13031,7 @@ redisplay_internal (void) | |||
| 13038 | /* do_pending_window_change could change the selected_window due to | 13031 | /* do_pending_window_change could change the selected_window due to |
| 13039 | frame resizing which makes the selected window too small. */ | 13032 | frame resizing which makes the selected window too small. */ |
| 13040 | if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) | 13033 | if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) |
| 13041 | { | 13034 | sw = w; |
| 13042 | sw = w; | ||
| 13043 | reconsider_clip_changes (w, current_buffer); | ||
| 13044 | } | ||
| 13045 | 13035 | ||
| 13046 | /* Clear frames marked as garbaged. */ | 13036 | /* Clear frames marked as garbaged. */ |
| 13047 | clear_garbaged_frames (); | 13037 | clear_garbaged_frames (); |
| @@ -13053,22 +13043,31 @@ redisplay_internal (void) | |||
| 13053 | if (windows_or_buffers_changed) | 13043 | if (windows_or_buffers_changed) |
| 13054 | update_mode_lines++; | 13044 | update_mode_lines++; |
| 13055 | 13045 | ||
| 13056 | /* Detect case that we need to write or remove a star in the mode line. */ | 13046 | reconsider_clip_changes (w); |
| 13057 | if ((SAVE_MODIFF < MODIFF) != w->last_had_star) | 13047 | |
| 13048 | /* In most cases selected window displays current buffer. */ | ||
| 13049 | match_p = XBUFFER (w->contents) == current_buffer; | ||
| 13050 | if (match_p) | ||
| 13058 | { | 13051 | { |
| 13059 | w->update_mode_line = 1; | 13052 | ptrdiff_t count1; |
| 13060 | if (buffer_shared_and_changed ()) | ||
| 13061 | update_mode_lines++; | ||
| 13062 | } | ||
| 13063 | 13053 | ||
| 13064 | /* Avoid invocation of point motion hooks by `current_column' below. */ | 13054 | /* Detect case that we need to write or remove a star in the mode line. */ |
| 13065 | count1 = SPECPDL_INDEX (); | 13055 | if ((SAVE_MODIFF < MODIFF) != w->last_had_star) |
| 13066 | specbind (Qinhibit_point_motion_hooks, Qt); | 13056 | { |
| 13057 | w->update_mode_line = 1; | ||
| 13058 | if (buffer_shared_and_changed ()) | ||
| 13059 | update_mode_lines++; | ||
| 13060 | } | ||
| 13067 | 13061 | ||
| 13068 | if (mode_line_update_needed (w)) | 13062 | /* Avoid invocation of point motion hooks by `current_column' below. */ |
| 13069 | w->update_mode_line = 1; | 13063 | count1 = SPECPDL_INDEX (); |
| 13064 | specbind (Qinhibit_point_motion_hooks, Qt); | ||
| 13070 | 13065 | ||
| 13071 | unbind_to (count1, Qnil); | 13066 | if (mode_line_update_needed (w)) |
| 13067 | w->update_mode_line = 1; | ||
| 13068 | |||
| 13069 | unbind_to (count1, Qnil); | ||
| 13070 | } | ||
| 13072 | 13071 | ||
| 13073 | consider_all_windows_p = (update_mode_lines | 13072 | consider_all_windows_p = (update_mode_lines |
| 13074 | || buffer_shared_and_changed () | 13073 | || buffer_shared_and_changed () |
| @@ -13167,7 +13166,7 @@ redisplay_internal (void) | |||
| 13167 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) | 13166 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) |
| 13168 | /* Make sure recorded data applies to current buffer, etc. */ | 13167 | /* Make sure recorded data applies to current buffer, etc. */ |
| 13169 | && this_line_buffer == current_buffer | 13168 | && this_line_buffer == current_buffer |
| 13170 | && current_buffer == XBUFFER (w->contents) | 13169 | && match_p |
| 13171 | && !w->force_start | 13170 | && !w->force_start |
| 13172 | && !w->optional_new_start | 13171 | && !w->optional_new_start |
| 13173 | /* Point must be on the line that we have info recorded about. */ | 13172 | /* Point must be on the line that we have info recorded about. */ |
| @@ -13263,12 +13262,12 @@ redisplay_internal (void) | |||
| 13263 | adjusted. */ | 13262 | adjusted. */ |
| 13264 | if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1)) | 13263 | if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1)) |
| 13265 | { | 13264 | { |
| 13266 | if (XFASTINT (w->window_end_vpos) < this_line_vpos) | 13265 | if (w->window_end_vpos < this_line_vpos) |
| 13267 | wset_window_end_vpos (w, make_number (this_line_vpos)); | 13266 | w->window_end_vpos = this_line_vpos; |
| 13268 | } | 13267 | } |
| 13269 | else if (XFASTINT (w->window_end_vpos) == this_line_vpos | 13268 | else if (w->window_end_vpos == this_line_vpos |
| 13270 | && this_line_vpos > 0) | 13269 | && this_line_vpos > 0) |
| 13271 | wset_window_end_vpos (w, make_number (this_line_vpos - 1)); | 13270 | w->window_end_vpos = this_line_vpos - 1; |
| 13272 | w->window_end_valid = 0; | 13271 | w->window_end_valid = 0; |
| 13273 | 13272 | ||
| 13274 | /* Update hint: No need to try to scroll in update_window. */ | 13273 | /* Update hint: No need to try to scroll in update_window. */ |
| @@ -13685,7 +13684,7 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p) | |||
| 13685 | w->current_matrix->begv = BUF_BEGV (b); | 13684 | w->current_matrix->begv = BUF_BEGV (b); |
| 13686 | w->current_matrix->zv = BUF_ZV (b); | 13685 | w->current_matrix->zv = BUF_ZV (b); |
| 13687 | 13686 | ||
| 13688 | w->last_cursor = w->cursor; | 13687 | w->last_cursor_vpos = w->cursor.vpos; |
| 13689 | w->last_cursor_off_p = w->cursor_off_p; | 13688 | w->last_cursor_off_p = w->cursor_off_p; |
| 13690 | 13689 | ||
| 13691 | if (w == XWINDOW (selected_window)) | 13690 | if (w == XWINDOW (selected_window)) |
| @@ -14458,8 +14457,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp) | |||
| 14458 | struct window *w = XWINDOW (window); | 14457 | struct window *w = XWINDOW (window); |
| 14459 | SET_MARKER_FROM_TEXT_POS (w->start, startp); | 14458 | SET_MARKER_FROM_TEXT_POS (w->start, startp); |
| 14460 | 14459 | ||
| 14461 | if (current_buffer != XBUFFER (w->contents)) | 14460 | eassert (current_buffer == XBUFFER (w->contents)); |
| 14462 | emacs_abort (); | ||
| 14463 | 14461 | ||
| 14464 | if (!NILP (Vwindow_scroll_functions)) | 14462 | if (!NILP (Vwindow_scroll_functions)) |
| 14465 | { | 14463 | { |
| @@ -14900,7 +14898,25 @@ compute_window_start_on_continuation_line (struct window *w) | |||
| 14900 | { | 14898 | { |
| 14901 | min_distance = distance; | 14899 | min_distance = distance; |
| 14902 | pos = it.current.pos; | 14900 | pos = it.current.pos; |
| 14903 | move_it_by_lines (&it, 1); | 14901 | if (it.line_wrap == WORD_WRAP) |
| 14902 | { | ||
| 14903 | /* Under WORD_WRAP, move_it_by_lines is likely to | ||
| 14904 | overshoot and stop not at the first, but the | ||
| 14905 | second character from the left margin. So in | ||
| 14906 | that case, we need a more tight control on the X | ||
| 14907 | coordinate of the iterator than move_it_by_lines | ||
| 14908 | promises in its contract. The method is to first | ||
| 14909 | go to the last (rightmost) visible character of a | ||
| 14910 | line, then move to the leftmost character on the | ||
| 14911 | next line in a separate call. */ | ||
| 14912 | move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1, | ||
| 14913 | MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); | ||
| 14914 | move_it_to (&it, ZV, 0, | ||
| 14915 | it.current_y + it.max_ascent + it.max_descent, -1, | ||
| 14916 | MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); | ||
| 14917 | } | ||
| 14918 | else | ||
| 14919 | move_it_by_lines (&it, 1); | ||
| 14904 | } | 14920 | } |
| 14905 | 14921 | ||
| 14906 | /* Set the window start there. */ | 14922 | /* Set the window start there. */ |
| @@ -14952,6 +14968,10 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste | |||
| 14952 | if-statement below. Now, this field is converted to | 14968 | if-statement below. Now, this field is converted to |
| 14953 | ptrdiff_t, thus zero means invalid position in a buffer. */ | 14969 | ptrdiff_t, thus zero means invalid position in a buffer. */ |
| 14954 | eassert (w->last_point > 0); | 14970 | eassert (w->last_point > 0); |
| 14971 | /* Likewise there was a check whether window_end_vpos is nil or larger | ||
| 14972 | than the window. Now window_end_vpos is int and so never nil, but | ||
| 14973 | let's leave eassert to check whether it fits in the window. */ | ||
| 14974 | eassert (w->window_end_vpos < w->current_matrix->nrows); | ||
| 14955 | 14975 | ||
| 14956 | /* Handle case where text has not changed, only point, and it has | 14976 | /* Handle case where text has not changed, only point, and it has |
| 14957 | not moved off the frame. */ | 14977 | not moved off the frame. */ |
| @@ -14979,13 +14999,6 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste | |||
| 14979 | since the handling of this_line_start_pos, etc., in redisplay | 14999 | since the handling of this_line_start_pos, etc., in redisplay |
| 14980 | handles the same cases. */ | 15000 | handles the same cases. */ |
| 14981 | && !EQ (window, minibuf_window) | 15001 | && !EQ (window, minibuf_window) |
| 14982 | /* When splitting windows or for new windows, it happens that | ||
| 14983 | redisplay is called with a nil window_end_vpos or one being | ||
| 14984 | larger than the window. This should really be fixed in | ||
| 14985 | window.c. I don't have this on my list, now, so we do | ||
| 14986 | approximately the same as the old redisplay code. --gerd. */ | ||
| 14987 | && INTEGERP (w->window_end_vpos) | ||
| 14988 | && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows | ||
| 14989 | && (FRAME_WINDOW_P (f) | 15002 | && (FRAME_WINDOW_P (f) |
| 14990 | || !overlay_arrow_in_current_buffer_p ())) | 15003 | || !overlay_arrow_in_current_buffer_p ())) |
| 14991 | { | 15004 | { |
| @@ -15015,12 +15028,12 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste | |||
| 15015 | 15028 | ||
| 15016 | /* Start with the row the cursor was displayed during the last | 15029 | /* Start with the row the cursor was displayed during the last |
| 15017 | not paused redisplay. Give up if that row is not valid. */ | 15030 | not paused redisplay. Give up if that row is not valid. */ |
| 15018 | if (w->last_cursor.vpos < 0 | 15031 | if (w->last_cursor_vpos < 0 |
| 15019 | || w->last_cursor.vpos >= w->current_matrix->nrows) | 15032 | || w->last_cursor_vpos >= w->current_matrix->nrows) |
| 15020 | rc = CURSOR_MOVEMENT_MUST_SCROLL; | 15033 | rc = CURSOR_MOVEMENT_MUST_SCROLL; |
| 15021 | else | 15034 | else |
| 15022 | { | 15035 | { |
| 15023 | row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos); | 15036 | row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos); |
| 15024 | if (row->mode_line_p) | 15037 | if (row->mode_line_p) |
| 15025 | ++row; | 15038 | ++row; |
| 15026 | if (!row->enabled_p) | 15039 | if (!row->enabled_p) |
| @@ -15299,7 +15312,7 @@ set_vertical_scroll_bar (struct window *w) | |||
| 15299 | start = marker_position (w->start) - BUF_BEGV (buf); | 15312 | start = marker_position (w->start) - BUF_BEGV (buf); |
| 15300 | /* I don't think this is guaranteed to be right. For the | 15313 | /* I don't think this is guaranteed to be right. For the |
| 15301 | moment, we'll pretend it is. */ | 15314 | moment, we'll pretend it is. */ |
| 15302 | end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf); | 15315 | end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf); |
| 15303 | 15316 | ||
| 15304 | if (end < start) | 15317 | if (end < start) |
| 15305 | end = start; | 15318 | end = start; |
| @@ -15360,7 +15373,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15360 | eassert (XMARKER (w->pointm)->buffer == buffer); | 15373 | eassert (XMARKER (w->pointm)->buffer == buffer); |
| 15361 | 15374 | ||
| 15362 | restart: | 15375 | restart: |
| 15363 | reconsider_clip_changes (w, buffer); | 15376 | reconsider_clip_changes (w); |
| 15364 | frame_line_height = default_line_pixel_height (w); | 15377 | frame_line_height = default_line_pixel_height (w); |
| 15365 | 15378 | ||
| 15366 | /* Has the mode line to be updated? */ | 15379 | /* Has the mode line to be updated? */ |
| @@ -15440,8 +15453,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15440 | && !current_buffer->clip_changed | 15453 | && !current_buffer->clip_changed |
| 15441 | && !window_outdated (w)); | 15454 | && !window_outdated (w)); |
| 15442 | 15455 | ||
| 15443 | /* When windows_or_buffers_changed is non-zero, we can't rely on | 15456 | /* When windows_or_buffers_changed is non-zero, we can't rely |
| 15444 | the window end being valid, so set it to nil there. */ | 15457 | on the window end being valid, so set it to zero there. */ |
| 15445 | if (windows_or_buffers_changed) | 15458 | if (windows_or_buffers_changed) |
| 15446 | { | 15459 | { |
| 15447 | /* If window starts on a continuation line, maybe adjust the | 15460 | /* If window starts on a continuation line, maybe adjust the |
| @@ -15450,6 +15463,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15450 | compute_window_start_on_continuation_line (w); | 15463 | compute_window_start_on_continuation_line (w); |
| 15451 | 15464 | ||
| 15452 | w->window_end_valid = 0; | 15465 | w->window_end_valid = 0; |
| 15466 | /* If so, we also can't rely on current matrix | ||
| 15467 | and should not fool try_cursor_movement below. */ | ||
| 15468 | current_matrix_up_to_date_p = 0; | ||
| 15453 | } | 15469 | } |
| 15454 | 15470 | ||
| 15455 | /* Some sanity checks. */ | 15471 | /* Some sanity checks. */ |
| @@ -15531,7 +15547,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15531 | 15547 | ||
| 15532 | /* Handle case where place to start displaying has been specified, | 15548 | /* Handle case where place to start displaying has been specified, |
| 15533 | unless the specified location is outside the accessible range. */ | 15549 | unless the specified location is outside the accessible range. */ |
| 15534 | if (w->force_start || w->frozen_window_start_p) | 15550 | if (w->force_start || window_frozen_p (w)) |
| 15535 | { | 15551 | { |
| 15536 | /* We set this later on if we have to adjust point. */ | 15552 | /* We set this later on if we have to adjust point. */ |
| 15537 | int new_vpos = -1; | 15553 | int new_vpos = -1; |
| @@ -15559,8 +15575,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15559 | startp = run_window_scroll_functions (window, startp); | 15575 | startp = run_window_scroll_functions (window, startp); |
| 15560 | } | 15576 | } |
| 15561 | 15577 | ||
| 15562 | w->last_modified = 0; | ||
| 15563 | w->last_overlay_modified = 0; | ||
| 15564 | if (CHARPOS (startp) < BEGV) | 15578 | if (CHARPOS (startp) < BEGV) |
| 15565 | SET_TEXT_POS (startp, BEGV, BEGV_BYTE); | 15579 | SET_TEXT_POS (startp, BEGV, BEGV_BYTE); |
| 15566 | else if (CHARPOS (startp) > ZV) | 15580 | else if (CHARPOS (startp) > ZV) |
| @@ -15578,7 +15592,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15578 | goto need_larger_matrices; | 15592 | goto need_larger_matrices; |
| 15579 | } | 15593 | } |
| 15580 | 15594 | ||
| 15581 | if (w->cursor.vpos < 0 && !w->frozen_window_start_p) | 15595 | if (w->cursor.vpos < 0 && !window_frozen_p (w)) |
| 15582 | { | 15596 | { |
| 15583 | /* If point does not appear, try to move point so it does | 15597 | /* If point does not appear, try to move point so it does |
| 15584 | appear. The desired matrix has been built above, so we | 15598 | appear. The desired matrix has been built above, so we |
| @@ -15806,9 +15820,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15806 | 15820 | ||
| 15807 | try_to_scroll: | 15821 | try_to_scroll: |
| 15808 | 15822 | ||
| 15809 | w->last_modified = 0; | ||
| 15810 | w->last_overlay_modified = 0; | ||
| 15811 | |||
| 15812 | /* Redisplay the mode line. Select the buffer properly for that. */ | 15823 | /* Redisplay the mode line. Select the buffer properly for that. */ |
| 15813 | if (!update_mode_line) | 15824 | if (!update_mode_line) |
| 15814 | { | 15825 | { |
| @@ -15994,7 +16005,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15994 | line.) */ | 16005 | line.) */ |
| 15995 | if (w->cursor.vpos < 0) | 16006 | if (w->cursor.vpos < 0) |
| 15996 | { | 16007 | { |
| 15997 | if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos)) | 16008 | if (w->window_end_valid && PT >= Z - w->window_end_pos) |
| 15998 | { | 16009 | { |
| 15999 | clear_glyph_matrix (w->desired_matrix); | 16010 | clear_glyph_matrix (w->desired_matrix); |
| 16000 | move_it_by_lines (&it, 1); | 16011 | move_it_by_lines (&it, 1); |
| @@ -16287,8 +16298,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) | |||
| 16287 | } | 16298 | } |
| 16288 | 16299 | ||
| 16289 | /* If bottom moved off end of frame, change mode line percentage. */ | 16300 | /* If bottom moved off end of frame, change mode line percentage. */ |
| 16290 | if (XFASTINT (w->window_end_pos) <= 0 | 16301 | if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it)) |
| 16291 | && Z != IT_CHARPOS (it)) | ||
| 16292 | w->update_mode_line = 1; | 16302 | w->update_mode_line = 1; |
| 16293 | 16303 | ||
| 16294 | /* Set window_end_pos to the offset of the last character displayed | 16304 | /* Set window_end_pos to the offset of the last character displayed |
| @@ -16297,21 +16307,16 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) | |||
| 16297 | if (last_text_row) | 16307 | if (last_text_row) |
| 16298 | { | 16308 | { |
| 16299 | eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row)); | 16309 | eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row)); |
| 16300 | w->window_end_bytepos | 16310 | adjust_window_ends (w, last_text_row, 0); |
| 16301 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); | ||
| 16302 | wset_window_end_pos | ||
| 16303 | (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); | ||
| 16304 | wset_window_end_vpos | ||
| 16305 | (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix))); | ||
| 16306 | eassert | 16311 | eassert |
| 16307 | (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix, | 16312 | (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix, |
| 16308 | XFASTINT (w->window_end_vpos)))); | 16313 | w->window_end_vpos))); |
| 16309 | } | 16314 | } |
| 16310 | else | 16315 | else |
| 16311 | { | 16316 | { |
| 16312 | w->window_end_bytepos = Z_BYTE - ZV_BYTE; | 16317 | w->window_end_bytepos = Z_BYTE - ZV_BYTE; |
| 16313 | wset_window_end_pos (w, make_number (Z - ZV)); | 16318 | w->window_end_pos = Z - ZV; |
| 16314 | wset_window_end_vpos (w, make_number (0)); | 16319 | w->window_end_vpos = 0; |
| 16315 | } | 16320 | } |
| 16316 | 16321 | ||
| 16317 | /* But that is not valid info until redisplay finishes. */ | 16322 | /* But that is not valid info until redisplay finishes. */ |
| @@ -16535,32 +16540,15 @@ try_window_reusing_current_matrix (struct window *w) | |||
| 16535 | The value of last_text_row is the last displayed line | 16540 | The value of last_text_row is the last displayed line |
| 16536 | containing text. */ | 16541 | containing text. */ |
| 16537 | if (last_reused_text_row) | 16542 | if (last_reused_text_row) |
| 16538 | { | 16543 | adjust_window_ends (w, last_reused_text_row, 1); |
| 16539 | w->window_end_bytepos | ||
| 16540 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row); | ||
| 16541 | wset_window_end_pos | ||
| 16542 | (w, make_number (Z | ||
| 16543 | - MATRIX_ROW_END_CHARPOS (last_reused_text_row))); | ||
| 16544 | wset_window_end_vpos | ||
| 16545 | (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row, | ||
| 16546 | w->current_matrix))); | ||
| 16547 | } | ||
| 16548 | else if (last_text_row) | 16544 | else if (last_text_row) |
| 16549 | { | 16545 | adjust_window_ends (w, last_text_row, 0); |
| 16550 | w->window_end_bytepos | ||
| 16551 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); | ||
| 16552 | wset_window_end_pos | ||
| 16553 | (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); | ||
| 16554 | wset_window_end_vpos | ||
| 16555 | (w, make_number (MATRIX_ROW_VPOS (last_text_row, | ||
| 16556 | w->desired_matrix))); | ||
| 16557 | } | ||
| 16558 | else | 16546 | else |
| 16559 | { | 16547 | { |
| 16560 | /* This window must be completely empty. */ | 16548 | /* This window must be completely empty. */ |
| 16561 | w->window_end_bytepos = Z_BYTE - ZV_BYTE; | 16549 | w->window_end_bytepos = Z_BYTE - ZV_BYTE; |
| 16562 | wset_window_end_pos (w, make_number (Z - ZV)); | 16550 | w->window_end_pos = Z - ZV; |
| 16563 | wset_window_end_vpos (w, make_number (0)); | 16551 | w->window_end_vpos = 0; |
| 16564 | } | 16552 | } |
| 16565 | w->window_end_valid = 0; | 16553 | w->window_end_valid = 0; |
| 16566 | 16554 | ||
| @@ -16745,20 +16733,9 @@ try_window_reusing_current_matrix (struct window *w) | |||
| 16745 | the window end is in reused rows which in turn means that | 16733 | the window end is in reused rows which in turn means that |
| 16746 | only its vpos can have changed. */ | 16734 | only its vpos can have changed. */ |
| 16747 | if (last_text_row) | 16735 | if (last_text_row) |
| 16748 | { | 16736 | adjust_window_ends (w, last_text_row, 0); |
| 16749 | w->window_end_bytepos | ||
| 16750 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); | ||
| 16751 | wset_window_end_pos | ||
| 16752 | (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); | ||
| 16753 | wset_window_end_vpos | ||
| 16754 | (w, make_number (MATRIX_ROW_VPOS (last_text_row, | ||
| 16755 | w->desired_matrix))); | ||
| 16756 | } | ||
| 16757 | else | 16737 | else |
| 16758 | { | 16738 | w->window_end_vpos -= nrows_scrolled; |
| 16759 | wset_window_end_vpos | ||
| 16760 | (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled)); | ||
| 16761 | } | ||
| 16762 | 16739 | ||
| 16763 | w->window_end_valid = 0; | 16740 | w->window_end_valid = 0; |
| 16764 | w->desired_matrix->no_scrolling_p = 1; | 16741 | w->desired_matrix->no_scrolling_p = 1; |
| @@ -16898,11 +16875,11 @@ find_first_unchanged_at_end_row (struct window *w, | |||
| 16898 | /* A value of window_end_pos >= END_UNCHANGED means that the window | 16875 | /* A value of window_end_pos >= END_UNCHANGED means that the window |
| 16899 | end is in the range of changed text. If so, there is no | 16876 | end is in the range of changed text. If so, there is no |
| 16900 | unchanged row at the end of W's current matrix. */ | 16877 | unchanged row at the end of W's current matrix. */ |
| 16901 | if (XFASTINT (w->window_end_pos) >= END_UNCHANGED) | 16878 | if (w->window_end_pos >= END_UNCHANGED) |
| 16902 | return NULL; | 16879 | return NULL; |
| 16903 | 16880 | ||
| 16904 | /* Set row to the last row in W's current matrix displaying text. */ | 16881 | /* Set row to the last row in W's current matrix displaying text. */ |
| 16905 | row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); | 16882 | row = MATRIX_ROW (w->current_matrix, w->window_end_vpos); |
| 16906 | 16883 | ||
| 16907 | /* If matrix is entirely empty, no unchanged row exists. */ | 16884 | /* If matrix is entirely empty, no unchanged row exists. */ |
| 16908 | if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) | 16885 | if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) |
| @@ -16913,7 +16890,7 @@ find_first_unchanged_at_end_row (struct window *w, | |||
| 16913 | buffer positions in the current matrix to current buffer | 16890 | buffer positions in the current matrix to current buffer |
| 16914 | positions for characters not in changed text. */ | 16891 | positions for characters not in changed text. */ |
| 16915 | ptrdiff_t Z_old = | 16892 | ptrdiff_t Z_old = |
| 16916 | MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); | 16893 | MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos; |
| 16917 | ptrdiff_t Z_BYTE_old = | 16894 | ptrdiff_t Z_BYTE_old = |
| 16918 | MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; | 16895 | MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; |
| 16919 | ptrdiff_t last_unchanged_pos, last_unchanged_pos_old; | 16896 | ptrdiff_t last_unchanged_pos, last_unchanged_pos_old; |
| @@ -17247,7 +17224,7 @@ try_window_id (struct window *w) | |||
| 17247 | This case happens with stealth-fontification. Note that although | 17224 | This case happens with stealth-fontification. Note that although |
| 17248 | the display is unchanged, glyph positions in the matrix have to | 17225 | the display is unchanged, glyph positions in the matrix have to |
| 17249 | be adjusted, of course. */ | 17226 | be adjusted, of course. */ |
| 17250 | row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); | 17227 | row = MATRIX_ROW (w->current_matrix, w->window_end_vpos); |
| 17251 | if (MATRIX_ROW_DISPLAYS_TEXT_P (row) | 17228 | if (MATRIX_ROW_DISPLAYS_TEXT_P (row) |
| 17252 | && ((last_changed_charpos < CHARPOS (start) | 17229 | && ((last_changed_charpos < CHARPOS (start) |
| 17253 | && CHARPOS (start) == BEGV) | 17230 | && CHARPOS (start) == BEGV) |
| @@ -17259,7 +17236,7 @@ try_window_id (struct window *w) | |||
| 17259 | 17236 | ||
| 17260 | /* Compute how many chars/bytes have been added to or removed | 17237 | /* Compute how many chars/bytes have been added to or removed |
| 17261 | from the buffer. */ | 17238 | from the buffer. */ |
| 17262 | Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); | 17239 | Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos; |
| 17263 | Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; | 17240 | Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; |
| 17264 | Z_delta = Z - Z_old; | 17241 | Z_delta = Z - Z_old; |
| 17265 | Z_delta_bytes = Z_BYTE - Z_BYTE_old; | 17242 | Z_delta_bytes = Z_BYTE - Z_BYTE_old; |
| @@ -17330,10 +17307,8 @@ try_window_id (struct window *w) | |||
| 17330 | { | 17307 | { |
| 17331 | /* We have to compute the window end anew since text | 17308 | /* We have to compute the window end anew since text |
| 17332 | could have been added/removed after it. */ | 17309 | could have been added/removed after it. */ |
| 17333 | wset_window_end_pos | 17310 | w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); |
| 17334 | (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); | 17311 | w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); |
| 17335 | w->window_end_bytepos | ||
| 17336 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); | ||
| 17337 | 17312 | ||
| 17338 | /* Set the cursor. */ | 17313 | /* Set the cursor. */ |
| 17339 | row = row_containing_pos (w, PT, r0, NULL, 0); | 17314 | row = row_containing_pos (w, PT, r0, NULL, 0); |
| @@ -17366,7 +17341,7 @@ try_window_id (struct window *w) | |||
| 17366 | 17341 | ||
| 17367 | /* Give up if the window ends in strings. Overlay strings | 17342 | /* Give up if the window ends in strings. Overlay strings |
| 17368 | at the end are difficult to handle, so don't try. */ | 17343 | at the end are difficult to handle, so don't try. */ |
| 17369 | row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos)); | 17344 | row = MATRIX_ROW (current_matrix, w->window_end_vpos); |
| 17370 | if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row)) | 17345 | if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row)) |
| 17371 | GIVE_UP (20); | 17346 | GIVE_UP (20); |
| 17372 | 17347 | ||
| @@ -17712,7 +17687,7 @@ try_window_id (struct window *w) | |||
| 17712 | /* Set last_row to the glyph row in the current matrix where the | 17687 | /* Set last_row to the glyph row in the current matrix where the |
| 17713 | window end line is found. It has been moved up or down in | 17688 | window end line is found. It has been moved up or down in |
| 17714 | the matrix by dvpos. */ | 17689 | the matrix by dvpos. */ |
| 17715 | int last_vpos = XFASTINT (w->window_end_vpos) + dvpos; | 17690 | int last_vpos = w->window_end_vpos + dvpos; |
| 17716 | struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos); | 17691 | struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos); |
| 17717 | 17692 | ||
| 17718 | /* If last_row is the window end line, it should display text. */ | 17693 | /* If last_row is the window end line, it should display text. */ |
| @@ -17756,8 +17731,7 @@ try_window_id (struct window *w) | |||
| 17756 | } | 17731 | } |
| 17757 | 17732 | ||
| 17758 | /* Update window_end_pos and window_end_vpos. */ | 17733 | /* Update window_end_pos and window_end_vpos. */ |
| 17759 | if (first_unchanged_at_end_row | 17734 | if (first_unchanged_at_end_row && !last_text_row_at_end) |
| 17760 | && !last_text_row_at_end) | ||
| 17761 | { | 17735 | { |
| 17762 | /* Window end line if one of the preserved rows from the current | 17736 | /* Window end line if one of the preserved rows from the current |
| 17763 | matrix. Set row to the last row displaying text in current | 17737 | matrix. Set row to the last row displaying text in current |
| @@ -17767,23 +17741,13 @@ try_window_id (struct window *w) | |||
| 17767 | row = find_last_row_displaying_text (w->current_matrix, &it, | 17741 | row = find_last_row_displaying_text (w->current_matrix, &it, |
| 17768 | first_unchanged_at_end_row); | 17742 | first_unchanged_at_end_row); |
| 17769 | eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); | 17743 | eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); |
| 17770 | 17744 | adjust_window_ends (w, row, 1); | |
| 17771 | wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); | ||
| 17772 | w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); | ||
| 17773 | wset_window_end_vpos | ||
| 17774 | (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix))); | ||
| 17775 | eassert (w->window_end_bytepos >= 0); | 17745 | eassert (w->window_end_bytepos >= 0); |
| 17776 | IF_DEBUG (debug_method_add (w, "A")); | 17746 | IF_DEBUG (debug_method_add (w, "A")); |
| 17777 | } | 17747 | } |
| 17778 | else if (last_text_row_at_end) | 17748 | else if (last_text_row_at_end) |
| 17779 | { | 17749 | { |
| 17780 | wset_window_end_pos | 17750 | adjust_window_ends (w, last_text_row_at_end, 0); |
| 17781 | (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end))); | ||
| 17782 | w->window_end_bytepos | ||
| 17783 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end); | ||
| 17784 | wset_window_end_vpos | ||
| 17785 | (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end, | ||
| 17786 | desired_matrix))); | ||
| 17787 | eassert (w->window_end_bytepos >= 0); | 17751 | eassert (w->window_end_bytepos >= 0); |
| 17788 | IF_DEBUG (debug_method_add (w, "B")); | 17752 | IF_DEBUG (debug_method_add (w, "B")); |
| 17789 | } | 17753 | } |
| @@ -17792,12 +17756,7 @@ try_window_id (struct window *w) | |||
| 17792 | /* We have displayed either to the end of the window or at the | 17756 | /* We have displayed either to the end of the window or at the |
| 17793 | end of the window, i.e. the last row with text is to be found | 17757 | end of the window, i.e. the last row with text is to be found |
| 17794 | in the desired matrix. */ | 17758 | in the desired matrix. */ |
| 17795 | wset_window_end_pos | 17759 | adjust_window_ends (w, last_text_row, 0); |
| 17796 | (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); | ||
| 17797 | w->window_end_bytepos | ||
| 17798 | = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); | ||
| 17799 | wset_window_end_vpos | ||
| 17800 | (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix))); | ||
| 17801 | eassert (w->window_end_bytepos >= 0); | 17760 | eassert (w->window_end_bytepos >= 0); |
| 17802 | } | 17761 | } |
| 17803 | else if (first_unchanged_at_end_row == NULL | 17762 | else if (first_unchanged_at_end_row == NULL |
| @@ -17807,7 +17766,7 @@ try_window_id (struct window *w) | |||
| 17807 | /* Displayed to end of window, but no line containing text was | 17766 | /* Displayed to end of window, but no line containing text was |
| 17808 | displayed. Lines were deleted at the end of the window. */ | 17767 | displayed. Lines were deleted at the end of the window. */ |
| 17809 | int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; | 17768 | int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; |
| 17810 | int vpos = XFASTINT (w->window_end_vpos); | 17769 | int vpos = w->window_end_vpos; |
| 17811 | struct glyph_row *current_row = current_matrix->rows + vpos; | 17770 | struct glyph_row *current_row = current_matrix->rows + vpos; |
| 17812 | struct glyph_row *desired_row = desired_matrix->rows + vpos; | 17771 | struct glyph_row *desired_row = desired_matrix->rows + vpos; |
| 17813 | 17772 | ||
| @@ -17825,8 +17784,8 @@ try_window_id (struct window *w) | |||
| 17825 | } | 17784 | } |
| 17826 | 17785 | ||
| 17827 | eassert (row != NULL); | 17786 | eassert (row != NULL); |
| 17828 | wset_window_end_vpos (w, make_number (vpos + 1)); | 17787 | w->window_end_vpos = vpos + 1; |
| 17829 | wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); | 17788 | w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); |
| 17830 | w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); | 17789 | w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); |
| 17831 | eassert (w->window_end_bytepos >= 0); | 17790 | eassert (w->window_end_bytepos >= 0); |
| 17832 | IF_DEBUG (debug_method_add (w, "C")); | 17791 | IF_DEBUG (debug_method_add (w, "C")); |
| @@ -17834,8 +17793,8 @@ try_window_id (struct window *w) | |||
| 17834 | else | 17793 | else |
| 17835 | emacs_abort (); | 17794 | emacs_abort (); |
| 17836 | 17795 | ||
| 17837 | IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos); | 17796 | IF_DEBUG (debug_end_pos = w->window_end_pos; |
| 17838 | debug_end_vpos = XFASTINT (w->window_end_vpos)); | 17797 | debug_end_vpos = w->window_end_vpos); |
| 17839 | 17798 | ||
| 17840 | /* Record that display has not been completed. */ | 17799 | /* Record that display has not been completed. */ |
| 17841 | w->window_end_valid = 0; | 17800 | w->window_end_valid = 0; |
| @@ -20115,7 +20074,7 @@ Value is the new character position of point. */) | |||
| 20115 | (Lisp_Object direction) | 20074 | (Lisp_Object direction) |
| 20116 | { | 20075 | { |
| 20117 | struct window *w = XWINDOW (selected_window); | 20076 | struct window *w = XWINDOW (selected_window); |
| 20118 | struct buffer *b = NULL; | 20077 | struct buffer *b = XBUFFER (w->contents); |
| 20119 | struct glyph_row *row; | 20078 | struct glyph_row *row; |
| 20120 | int dir; | 20079 | int dir; |
| 20121 | Lisp_Object paragraph_dir; | 20080 | Lisp_Object paragraph_dir; |
| @@ -20135,9 +20094,6 @@ Value is the new character position of point. */) | |||
| 20135 | else | 20094 | else |
| 20136 | dir = -1; | 20095 | dir = -1; |
| 20137 | 20096 | ||
| 20138 | if (BUFFERP (w->contents)) | ||
| 20139 | b = XBUFFER (w->contents); | ||
| 20140 | |||
| 20141 | /* If current matrix is up-to-date, we can use the information | 20097 | /* If current matrix is up-to-date, we can use the information |
| 20142 | recorded in the glyphs, at least as long as the goal is on the | 20098 | recorded in the glyphs, at least as long as the goal is on the |
| 20143 | screen. */ | 20099 | screen. */ |
| @@ -20146,8 +20102,7 @@ Value is the new character position of point. */) | |||
| 20146 | && b | 20102 | && b |
| 20147 | && !b->clip_changed | 20103 | && !b->clip_changed |
| 20148 | && !b->prevent_redisplay_optimizations_p | 20104 | && !b->prevent_redisplay_optimizations_p |
| 20149 | && w->last_modified >= BUF_MODIFF (b) | 20105 | && !window_outdated (w) |
| 20150 | && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b) | ||
| 20151 | && w->cursor.vpos >= 0 | 20106 | && w->cursor.vpos >= 0 |
| 20152 | && w->cursor.vpos < w->current_matrix->nrows | 20107 | && w->cursor.vpos < w->current_matrix->nrows |
| 20153 | && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) | 20108 | && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) |
| @@ -20651,13 +20606,8 @@ redisplay_mode_lines (Lisp_Object window, int force) | |||
| 20651 | { | 20606 | { |
| 20652 | struct text_pos pt; | 20607 | struct text_pos pt; |
| 20653 | 20608 | ||
| 20654 | SET_TEXT_POS_FROM_MARKER (pt, w->pointm); | 20609 | CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm); |
| 20655 | if (CHARPOS (pt) < BEGV) | 20610 | TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt)); |
| 20656 | TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE); | ||
| 20657 | else if (CHARPOS (pt) > (ZV - 1)) | ||
| 20658 | TEMP_SET_PT_BOTH (ZV, ZV_BYTE); | ||
| 20659 | else | ||
| 20660 | TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt)); | ||
| 20661 | } | 20611 | } |
| 20662 | 20612 | ||
| 20663 | /* Display mode lines. */ | 20613 | /* Display mode lines. */ |
| @@ -22007,7 +21957,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 22007 | ptrdiff_t pos = marker_position (w->start); | 21957 | ptrdiff_t pos = marker_position (w->start); |
| 22008 | ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); | 21958 | ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); |
| 22009 | 21959 | ||
| 22010 | if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b)) | 21960 | if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b)) |
| 22011 | { | 21961 | { |
| 22012 | if (pos <= BUF_BEGV (b)) | 21962 | if (pos <= BUF_BEGV (b)) |
| 22013 | return "All"; | 21963 | return "All"; |
| @@ -22036,7 +21986,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 22036 | case 'P': | 21986 | case 'P': |
| 22037 | { | 21987 | { |
| 22038 | ptrdiff_t toppos = marker_position (w->start); | 21988 | ptrdiff_t toppos = marker_position (w->start); |
| 22039 | ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos); | 21989 | ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos; |
| 22040 | ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); | 21990 | ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); |
| 22041 | 21991 | ||
| 22042 | if (botpos >= BUF_ZV (b)) | 21992 | if (botpos >= BUF_ZV (b)) |
| @@ -23856,17 +23806,15 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, | |||
| 23856 | && hlinfo->mouse_face_beg_row >= 0 | 23806 | && hlinfo->mouse_face_beg_row >= 0 |
| 23857 | && hlinfo->mouse_face_end_row >= 0) | 23807 | && hlinfo->mouse_face_end_row >= 0) |
| 23858 | { | 23808 | { |
| 23859 | struct glyph_row *mouse_beg_row, *mouse_end_row; | 23809 | ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix); |
| 23860 | |||
| 23861 | mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row); | ||
| 23862 | mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row); | ||
| 23863 | 23810 | ||
| 23864 | if (row >= mouse_beg_row && row <= mouse_end_row) | 23811 | if (row_vpos >= hlinfo->mouse_face_beg_row |
| 23812 | && row_vpos <= hlinfo->mouse_face_end_row) | ||
| 23865 | { | 23813 | { |
| 23866 | check_mouse_face = 1; | 23814 | check_mouse_face = 1; |
| 23867 | mouse_beg_col = (row == mouse_beg_row) | 23815 | mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row) |
| 23868 | ? hlinfo->mouse_face_beg_col : 0; | 23816 | ? hlinfo->mouse_face_beg_col : 0; |
| 23869 | mouse_end_col = (row == mouse_end_row) | 23817 | mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row) |
| 23870 | ? hlinfo->mouse_face_end_col | 23818 | ? hlinfo->mouse_face_end_col |
| 23871 | : row->used[TEXT_AREA]; | 23819 | : row->used[TEXT_AREA]; |
| 23872 | } | 23820 | } |
| @@ -25757,17 +25705,16 @@ x_produce_glyphs (struct it *it) | |||
| 25757 | 25705 | ||
| 25758 | /* EXPORT for RIF: | 25706 | /* EXPORT for RIF: |
| 25759 | Output LEN glyphs starting at START at the nominal cursor position. | 25707 | Output LEN glyphs starting at START at the nominal cursor position. |
| 25760 | Advance the nominal cursor over the text. The global variable | 25708 | Advance the nominal cursor over the text. UPDATED_ROW is the glyph row |
| 25761 | updated_window contains the window being updated, updated_row is | 25709 | being updated, and UPDATED_AREA is the area of that row being updated. */ |
| 25762 | the glyph row being updated, and updated_area is the area of that | ||
| 25763 | row being updated. */ | ||
| 25764 | 25710 | ||
| 25765 | void | 25711 | void |
| 25766 | x_write_glyphs (struct glyph *start, int len) | 25712 | x_write_glyphs (struct window *w, struct glyph_row *updated_row, |
| 25713 | struct glyph *start, enum glyph_row_area updated_area, int len) | ||
| 25767 | { | 25714 | { |
| 25768 | int x, hpos, chpos = updated_window->phys_cursor.hpos; | 25715 | int x, hpos, chpos = w->phys_cursor.hpos; |
| 25769 | 25716 | ||
| 25770 | eassert (updated_window && updated_row); | 25717 | eassert (updated_row); |
| 25771 | /* When the window is hscrolled, cursor hpos can legitimately be out | 25718 | /* When the window is hscrolled, cursor hpos can legitimately be out |
| 25772 | of bounds, but we draw the cursor at the corresponding window | 25719 | of bounds, but we draw the cursor at the corresponding window |
| 25773 | margin in that case. */ | 25720 | margin in that case. */ |
| @@ -25781,24 +25728,24 @@ x_write_glyphs (struct glyph *start, int len) | |||
| 25781 | /* Write glyphs. */ | 25728 | /* Write glyphs. */ |
| 25782 | 25729 | ||
| 25783 | hpos = start - updated_row->glyphs[updated_area]; | 25730 | hpos = start - updated_row->glyphs[updated_area]; |
| 25784 | x = draw_glyphs (updated_window, output_cursor.x, | 25731 | x = draw_glyphs (w, w->output_cursor.x, |
| 25785 | updated_row, updated_area, | 25732 | updated_row, updated_area, |
| 25786 | hpos, hpos + len, | 25733 | hpos, hpos + len, |
| 25787 | DRAW_NORMAL_TEXT, 0); | 25734 | DRAW_NORMAL_TEXT, 0); |
| 25788 | 25735 | ||
| 25789 | /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ | 25736 | /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ |
| 25790 | if (updated_area == TEXT_AREA | 25737 | if (updated_area == TEXT_AREA |
| 25791 | && updated_window->phys_cursor_on_p | 25738 | && w->phys_cursor_on_p |
| 25792 | && updated_window->phys_cursor.vpos == output_cursor.vpos | 25739 | && w->phys_cursor.vpos == w->output_cursor.vpos |
| 25793 | && chpos >= hpos | 25740 | && chpos >= hpos |
| 25794 | && chpos < hpos + len) | 25741 | && chpos < hpos + len) |
| 25795 | updated_window->phys_cursor_on_p = 0; | 25742 | w->phys_cursor_on_p = 0; |
| 25796 | 25743 | ||
| 25797 | unblock_input (); | 25744 | unblock_input (); |
| 25798 | 25745 | ||
| 25799 | /* Advance the output cursor. */ | 25746 | /* Advance the output cursor. */ |
| 25800 | output_cursor.hpos += len; | 25747 | w->output_cursor.hpos += len; |
| 25801 | output_cursor.x = x; | 25748 | w->output_cursor.x = x; |
| 25802 | } | 25749 | } |
| 25803 | 25750 | ||
| 25804 | 25751 | ||
| @@ -25806,19 +25753,18 @@ x_write_glyphs (struct glyph *start, int len) | |||
| 25806 | Insert LEN glyphs from START at the nominal cursor position. */ | 25753 | Insert LEN glyphs from START at the nominal cursor position. */ |
| 25807 | 25754 | ||
| 25808 | void | 25755 | void |
| 25809 | x_insert_glyphs (struct glyph *start, int len) | 25756 | x_insert_glyphs (struct window *w, struct glyph_row *updated_row, |
| 25757 | struct glyph *start, enum glyph_row_area updated_area, int len) | ||
| 25810 | { | 25758 | { |
| 25811 | struct frame *f; | 25759 | struct frame *f; |
| 25812 | struct window *w; | ||
| 25813 | int line_height, shift_by_width, shifted_region_width; | 25760 | int line_height, shift_by_width, shifted_region_width; |
| 25814 | struct glyph_row *row; | 25761 | struct glyph_row *row; |
| 25815 | struct glyph *glyph; | 25762 | struct glyph *glyph; |
| 25816 | int frame_x, frame_y; | 25763 | int frame_x, frame_y; |
| 25817 | ptrdiff_t hpos; | 25764 | ptrdiff_t hpos; |
| 25818 | 25765 | ||
| 25819 | eassert (updated_window && updated_row); | 25766 | eassert (updated_row); |
| 25820 | block_input (); | 25767 | block_input (); |
| 25821 | w = updated_window; | ||
| 25822 | f = XFRAME (WINDOW_FRAME (w)); | 25768 | f = XFRAME (WINDOW_FRAME (w)); |
| 25823 | 25769 | ||
| 25824 | /* Get the height of the line we are in. */ | 25770 | /* Get the height of the line we are in. */ |
| @@ -25832,25 +25778,25 @@ x_insert_glyphs (struct glyph *start, int len) | |||
| 25832 | 25778 | ||
| 25833 | /* Get the width of the region to shift right. */ | 25779 | /* Get the width of the region to shift right. */ |
| 25834 | shifted_region_width = (window_box_width (w, updated_area) | 25780 | shifted_region_width = (window_box_width (w, updated_area) |
| 25835 | - output_cursor.x | 25781 | - w->output_cursor.x |
| 25836 | - shift_by_width); | 25782 | - shift_by_width); |
| 25837 | 25783 | ||
| 25838 | /* Shift right. */ | 25784 | /* Shift right. */ |
| 25839 | frame_x = window_box_left (w, updated_area) + output_cursor.x; | 25785 | frame_x = window_box_left (w, updated_area) + w->output_cursor.x; |
| 25840 | frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y); | 25786 | frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y); |
| 25841 | 25787 | ||
| 25842 | FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width, | 25788 | FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width, |
| 25843 | line_height, shift_by_width); | 25789 | line_height, shift_by_width); |
| 25844 | 25790 | ||
| 25845 | /* Write the glyphs. */ | 25791 | /* Write the glyphs. */ |
| 25846 | hpos = start - row->glyphs[updated_area]; | 25792 | hpos = start - row->glyphs[updated_area]; |
| 25847 | draw_glyphs (w, output_cursor.x, row, updated_area, | 25793 | draw_glyphs (w, w->output_cursor.x, row, updated_area, |
| 25848 | hpos, hpos + len, | 25794 | hpos, hpos + len, |
| 25849 | DRAW_NORMAL_TEXT, 0); | 25795 | DRAW_NORMAL_TEXT, 0); |
| 25850 | 25796 | ||
| 25851 | /* Advance the output cursor. */ | 25797 | /* Advance the output cursor. */ |
| 25852 | output_cursor.hpos += len; | 25798 | w->output_cursor.hpos += len; |
| 25853 | output_cursor.x += shift_by_width; | 25799 | w->output_cursor.x += shift_by_width; |
| 25854 | unblock_input (); | 25800 | unblock_input (); |
| 25855 | } | 25801 | } |
| 25856 | 25802 | ||
| @@ -25860,18 +25806,18 @@ x_insert_glyphs (struct glyph *start, int len) | |||
| 25860 | (inclusive) to pixel column TO_X (exclusive). The idea is that | 25806 | (inclusive) to pixel column TO_X (exclusive). The idea is that |
| 25861 | everything from TO_X onward is already erased. | 25807 | everything from TO_X onward is already erased. |
| 25862 | 25808 | ||
| 25863 | TO_X is a pixel position relative to updated_area of | 25809 | TO_X is a pixel position relative to UPDATED_AREA of currently |
| 25864 | updated_window. TO_X == -1 means clear to the end of this area. */ | 25810 | updated window W. TO_X == -1 means clear to the end of this area. */ |
| 25865 | 25811 | ||
| 25866 | void | 25812 | void |
| 25867 | x_clear_end_of_line (int to_x) | 25813 | x_clear_end_of_line (struct window *w, struct glyph_row *updated_row, |
| 25814 | enum glyph_row_area updated_area, int to_x) | ||
| 25868 | { | 25815 | { |
| 25869 | struct frame *f; | 25816 | struct frame *f; |
| 25870 | struct window *w = updated_window; | ||
| 25871 | int max_x, min_y, max_y; | 25817 | int max_x, min_y, max_y; |
| 25872 | int from_x, from_y, to_y; | 25818 | int from_x, from_y, to_y; |
| 25873 | 25819 | ||
| 25874 | eassert (updated_window && updated_row); | 25820 | eassert (updated_row); |
| 25875 | f = XFRAME (w->frame); | 25821 | f = XFRAME (w->frame); |
| 25876 | 25822 | ||
| 25877 | if (updated_row->full_width_p) | 25823 | if (updated_row->full_width_p) |
| @@ -25889,16 +25835,16 @@ x_clear_end_of_line (int to_x) | |||
| 25889 | else | 25835 | else |
| 25890 | to_x = min (to_x, max_x); | 25836 | to_x = min (to_x, max_x); |
| 25891 | 25837 | ||
| 25892 | to_y = min (max_y, output_cursor.y + updated_row->height); | 25838 | to_y = min (max_y, w->output_cursor.y + updated_row->height); |
| 25893 | 25839 | ||
| 25894 | /* Notice if the cursor will be cleared by this operation. */ | 25840 | /* Notice if the cursor will be cleared by this operation. */ |
| 25895 | if (!updated_row->full_width_p) | 25841 | if (!updated_row->full_width_p) |
| 25896 | notice_overwritten_cursor (w, updated_area, | 25842 | notice_overwritten_cursor (w, updated_area, |
| 25897 | output_cursor.x, -1, | 25843 | w->output_cursor.x, -1, |
| 25898 | updated_row->y, | 25844 | updated_row->y, |
| 25899 | MATRIX_ROW_BOTTOM_Y (updated_row)); | 25845 | MATRIX_ROW_BOTTOM_Y (updated_row)); |
| 25900 | 25846 | ||
| 25901 | from_x = output_cursor.x; | 25847 | from_x = w->output_cursor.x; |
| 25902 | 25848 | ||
| 25903 | /* Translate to frame coordinates. */ | 25849 | /* Translate to frame coordinates. */ |
| 25904 | if (updated_row->full_width_p) | 25850 | if (updated_row->full_width_p) |
| @@ -25914,7 +25860,7 @@ x_clear_end_of_line (int to_x) | |||
| 25914 | } | 25860 | } |
| 25915 | 25861 | ||
| 25916 | min_y = WINDOW_HEADER_LINE_HEIGHT (w); | 25862 | min_y = WINDOW_HEADER_LINE_HEIGHT (w); |
| 25917 | from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y)); | 25863 | from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y)); |
| 25918 | to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); | 25864 | to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); |
| 25919 | 25865 | ||
| 25920 | /* Prevent inadvertently clearing to end of the X window. */ | 25866 | /* Prevent inadvertently clearing to end of the X window. */ |
| @@ -26010,6 +25956,9 @@ set_frame_cursor_types (struct frame *f, Lisp_Object arg) | |||
| 26010 | } | 25956 | } |
| 26011 | else | 25957 | else |
| 26012 | FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR; | 25958 | FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR; |
| 25959 | |||
| 25960 | /* Make sure the cursor gets redrawn. */ | ||
| 25961 | cursor_type_changed = 1; | ||
| 26013 | } | 25962 | } |
| 26014 | 25963 | ||
| 26015 | 25964 | ||
| @@ -26458,7 +26407,7 @@ erase_phys_cursor (struct window *w) | |||
| 26458 | where to put the cursor is specified by HPOS, VPOS, X and Y. */ | 26407 | where to put the cursor is specified by HPOS, VPOS, X and Y. */ |
| 26459 | 26408 | ||
| 26460 | void | 26409 | void |
| 26461 | display_and_set_cursor (struct window *w, int on, | 26410 | display_and_set_cursor (struct window *w, bool on, |
| 26462 | int hpos, int vpos, int x, int y) | 26411 | int hpos, int vpos, int x, int y) |
| 26463 | { | 26412 | { |
| 26464 | struct frame *f = XFRAME (w->frame); | 26413 | struct frame *f = XFRAME (w->frame); |
| @@ -26542,7 +26491,7 @@ display_and_set_cursor (struct window *w, int on, | |||
| 26542 | of ON. */ | 26491 | of ON. */ |
| 26543 | 26492 | ||
| 26544 | static void | 26493 | static void |
| 26545 | update_window_cursor (struct window *w, int on) | 26494 | update_window_cursor (struct window *w, bool on) |
| 26546 | { | 26495 | { |
| 26547 | /* Don't update cursor in windows whose frame is in the process | 26496 | /* Don't update cursor in windows whose frame is in the process |
| 26548 | of being deleted. */ | 26497 | of being deleted. */ |
| @@ -26578,7 +26527,7 @@ update_window_cursor (struct window *w, int on) | |||
| 26578 | in the window tree rooted at W. */ | 26527 | in the window tree rooted at W. */ |
| 26579 | 26528 | ||
| 26580 | static void | 26529 | static void |
| 26581 | update_cursor_in_window_tree (struct window *w, int on_p) | 26530 | update_cursor_in_window_tree (struct window *w, bool on_p) |
| 26582 | { | 26531 | { |
| 26583 | while (w) | 26532 | while (w) |
| 26584 | { | 26533 | { |
| @@ -26597,7 +26546,7 @@ update_cursor_in_window_tree (struct window *w, int on_p) | |||
| 26597 | Don't change the cursor's position. */ | 26546 | Don't change the cursor's position. */ |
| 26598 | 26547 | ||
| 26599 | void | 26548 | void |
| 26600 | x_update_cursor (struct frame *f, int on_p) | 26549 | x_update_cursor (struct frame *f, bool on_p) |
| 26601 | { | 26550 | { |
| 26602 | update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); | 26551 | update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); |
| 26603 | } | 26552 | } |
| @@ -26784,10 +26733,7 @@ clear_mouse_face (Mouse_HLInfo *hlinfo) | |||
| 26784 | cleared = 1; | 26733 | cleared = 1; |
| 26785 | } | 26734 | } |
| 26786 | 26735 | ||
| 26787 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | 26736 | reset_mouse_highlight (hlinfo); |
| 26788 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 26789 | hlinfo->mouse_face_window = Qnil; | ||
| 26790 | hlinfo->mouse_face_overlay = Qnil; | ||
| 26791 | return cleared; | 26737 | return cleared; |
| 26792 | } | 26738 | } |
| 26793 | 26739 | ||
| @@ -27048,7 +26994,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, | |||
| 27048 | /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */ | 26994 | /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */ |
| 27049 | rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2); | 26995 | rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2); |
| 27050 | if (r1 == NULL) | 26996 | if (r1 == NULL) |
| 27051 | r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); | 26997 | r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos); |
| 27052 | /* If the before-string or display-string contains newlines, | 26998 | /* If the before-string or display-string contains newlines, |
| 27053 | rows_from_pos_range skips to its last row. Move back. */ | 26999 | rows_from_pos_range skips to its last row. Move back. */ |
| 27054 | if (!NILP (before_string) || !NILP (disp_string)) | 27000 | if (!NILP (before_string) || !NILP (disp_string)) |
| @@ -27070,7 +27016,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, | |||
| 27070 | } | 27016 | } |
| 27071 | if (r2 == NULL) | 27017 | if (r2 == NULL) |
| 27072 | { | 27018 | { |
| 27073 | r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); | 27019 | r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos); |
| 27074 | hlinfo->mouse_face_past_end = 1; | 27020 | hlinfo->mouse_face_past_end = 1; |
| 27075 | } | 27021 | } |
| 27076 | else if (!NILP (after_string)) | 27022 | else if (!NILP (after_string)) |
| @@ -27078,7 +27024,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, | |||
| 27078 | /* If the after-string has newlines, advance to its last row. */ | 27024 | /* If the after-string has newlines, advance to its last row. */ |
| 27079 | struct glyph_row *next; | 27025 | struct glyph_row *next; |
| 27080 | struct glyph_row *last | 27026 | struct glyph_row *last |
| 27081 | = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); | 27027 | = MATRIX_ROW (w->current_matrix, w->window_end_vpos); |
| 27082 | 27028 | ||
| 27083 | for (next = r2 + 1; | 27029 | for (next = r2 + 1; |
| 27084 | next <= last | 27030 | next <= last |
| @@ -27100,9 +27046,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, | |||
| 27100 | r1 = tem; | 27046 | r1 = tem; |
| 27101 | } | 27047 | } |
| 27102 | 27048 | ||
| 27103 | hlinfo->mouse_face_beg_y = r1->y; | ||
| 27104 | hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix); | 27049 | hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix); |
| 27105 | hlinfo->mouse_face_end_y = r2->y; | ||
| 27106 | hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix); | 27050 | hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix); |
| 27107 | 27051 | ||
| 27108 | /* For a bidi-reordered row, the positions of BEFORE_STRING, | 27052 | /* For a bidi-reordered row, the positions of BEFORE_STRING, |
| @@ -27466,7 +27410,6 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo, | |||
| 27466 | { | 27410 | { |
| 27467 | hlinfo->mouse_face_beg_row | 27411 | hlinfo->mouse_face_beg_row |
| 27468 | = MATRIX_ROW_VPOS (r, w->current_matrix); | 27412 | = MATRIX_ROW_VPOS (r, w->current_matrix); |
| 27469 | hlinfo->mouse_face_beg_y = r->y; | ||
| 27470 | hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA]; | 27413 | hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA]; |
| 27471 | hlinfo->mouse_face_beg_x = gx; | 27414 | hlinfo->mouse_face_beg_x = gx; |
| 27472 | found = 1; | 27415 | found = 1; |
| @@ -27485,7 +27428,6 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo, | |||
| 27485 | { | 27428 | { |
| 27486 | hlinfo->mouse_face_beg_row | 27429 | hlinfo->mouse_face_beg_row |
| 27487 | = MATRIX_ROW_VPOS (r, w->current_matrix); | 27430 | = MATRIX_ROW_VPOS (r, w->current_matrix); |
| 27488 | hlinfo->mouse_face_beg_y = r->y; | ||
| 27489 | hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA]; | 27431 | hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA]; |
| 27490 | for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1) | 27432 | for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1) |
| 27491 | gx += g1->pixel_width; | 27433 | gx += g1->pixel_width; |
| @@ -27522,9 +27464,8 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo, | |||
| 27522 | /* The highlighted region ends on the previous row. */ | 27464 | /* The highlighted region ends on the previous row. */ |
| 27523 | r--; | 27465 | r--; |
| 27524 | 27466 | ||
| 27525 | /* Set the end row and its vertical pixel coordinate. */ | 27467 | /* Set the end row. */ |
| 27526 | hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix); | 27468 | hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix); |
| 27527 | hlinfo->mouse_face_end_y = r->y; | ||
| 27528 | 27469 | ||
| 27529 | /* Compute and set the end column and the end column's horizontal | 27470 | /* Compute and set the end column and the end column's horizontal |
| 27530 | pixel coordinate. */ | 27471 | pixel coordinate. */ |
| @@ -28022,8 +27963,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y, | |||
| 28022 | 27963 | ||
| 28023 | hlinfo->mouse_face_beg_row = vpos; | 27964 | hlinfo->mouse_face_beg_row = vpos; |
| 28024 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row; | 27965 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row; |
| 28025 | hlinfo->mouse_face_beg_y = 0; | ||
| 28026 | hlinfo->mouse_face_end_y = 0; | ||
| 28027 | hlinfo->mouse_face_past_end = 0; | 27966 | hlinfo->mouse_face_past_end = 0; |
| 28028 | hlinfo->mouse_face_window = window; | 27967 | hlinfo->mouse_face_window = window; |
| 28029 | 27968 | ||
| @@ -28142,10 +28081,7 @@ note_mouse_highlight (struct frame *f, int x, int y) | |||
| 28142 | /* Are we in a window whose display is up to date? | 28081 | /* Are we in a window whose display is up to date? |
| 28143 | And verify the buffer's text has not changed. */ | 28082 | And verify the buffer's text has not changed. */ |
| 28144 | b = XBUFFER (w->contents); | 28083 | b = XBUFFER (w->contents); |
| 28145 | if (part == ON_TEXT | 28084 | if (part == ON_TEXT && w->window_end_valid && !window_outdated (w)) |
| 28146 | && w->window_end_valid | ||
| 28147 | && w->last_modified == BUF_MODIFF (b) | ||
| 28148 | && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b)) | ||
| 28149 | { | 28085 | { |
| 28150 | int hpos, vpos, dx, dy, area = LAST_AREA; | 28086 | int hpos, vpos, dx, dy, area = LAST_AREA; |
| 28151 | ptrdiff_t pos; | 28087 | ptrdiff_t pos; |
| @@ -28387,8 +28323,7 @@ note_mouse_highlight (struct frame *f, int x, int y) | |||
| 28387 | : Qnil; | 28323 | : Qnil; |
| 28388 | Lisp_Object lim2 = | 28324 | Lisp_Object lim2 = |
| 28389 | NILP (BVAR (XBUFFER (buffer), bidi_display_reordering)) | 28325 | NILP (BVAR (XBUFFER (buffer), bidi_display_reordering)) |
| 28390 | ? make_number (BUF_Z (XBUFFER (buffer)) | 28326 | ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos) |
| 28391 | - XFASTINT (w->window_end_pos)) | ||
| 28392 | : Qnil; | 28327 | : Qnil; |
| 28393 | 28328 | ||
| 28394 | if (NILP (overlay)) | 28329 | if (NILP (overlay)) |
| @@ -28586,11 +28521,7 @@ cancel_mouse_face (struct frame *f) | |||
| 28586 | 28521 | ||
| 28587 | window = hlinfo->mouse_face_window; | 28522 | window = hlinfo->mouse_face_window; |
| 28588 | if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) | 28523 | if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) |
| 28589 | { | 28524 | reset_mouse_highlight (hlinfo); |
| 28590 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 28591 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 28592 | hlinfo->mouse_face_window = Qnil; | ||
| 28593 | } | ||
| 28594 | } | 28525 | } |
| 28595 | 28526 | ||
| 28596 | 28527 | ||
| @@ -28790,7 +28721,7 @@ x_draw_vertical_border (struct window *w) | |||
| 28790 | { | 28721 | { |
| 28791 | int x0, x1, y0, y1; | 28722 | int x0, x1, y0, y1; |
| 28792 | 28723 | ||
| 28793 | window_box_edges (w, -1, &x0, &y0, &x1, &y1); | 28724 | window_box_edges (w, &x0, &y0, &x1, &y1); |
| 28794 | y1 -= 1; | 28725 | y1 -= 1; |
| 28795 | 28726 | ||
| 28796 | if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) | 28727 | if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) |
| @@ -28803,7 +28734,7 @@ x_draw_vertical_border (struct window *w) | |||
| 28803 | { | 28734 | { |
| 28804 | int x0, x1, y0, y1; | 28735 | int x0, x1, y0, y1; |
| 28805 | 28736 | ||
| 28806 | window_box_edges (w, -1, &x0, &y0, &x1, &y1); | 28737 | window_box_edges (w, &x0, &y0, &x1, &y1); |
| 28807 | y1 -= 1; | 28738 | y1 -= 1; |
| 28808 | 28739 | ||
| 28809 | if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) | 28740 | if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) |
| @@ -28836,7 +28767,7 @@ expose_window (struct window *w, XRectangle *fr) | |||
| 28836 | /* When we're currently updating the window, display and current | 28767 | /* When we're currently updating the window, display and current |
| 28837 | matrix usually don't agree. Arrange for a thorough display | 28768 | matrix usually don't agree. Arrange for a thorough display |
| 28838 | later. */ | 28769 | later. */ |
| 28839 | if (w == updated_window) | 28770 | if (w->must_be_updated_p) |
| 28840 | { | 28771 | { |
| 28841 | SET_FRAME_GARBAGED (f); | 28772 | SET_FRAME_GARBAGED (f); |
| 28842 | return 0; | 28773 | return 0; |
| @@ -29722,10 +29653,6 @@ cursor shapes. */); | |||
| 29722 | DEFSYM (Qzero_width, "zero-width"); | 29653 | DEFSYM (Qzero_width, "zero-width"); |
| 29723 | 29654 | ||
| 29724 | DEFSYM (Qglyphless_char_display, "glyphless-char-display"); | 29655 | DEFSYM (Qglyphless_char_display, "glyphless-char-display"); |
| 29725 | /* Intern this now in case it isn't already done. | ||
| 29726 | Setting this variable twice is harmless. | ||
| 29727 | But don't staticpro it here--that is done in alloc.c. */ | ||
| 29728 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | ||
| 29729 | Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1)); | 29656 | Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1)); |
| 29730 | 29657 | ||
| 29731 | DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display, | 29658 | DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display, |
| @@ -29811,20 +29738,20 @@ void | |||
| 29811 | start_hourglass (void) | 29738 | start_hourglass (void) |
| 29812 | { | 29739 | { |
| 29813 | #if defined (HAVE_WINDOW_SYSTEM) | 29740 | #if defined (HAVE_WINDOW_SYSTEM) |
| 29814 | EMACS_TIME delay; | 29741 | struct timespec delay; |
| 29815 | 29742 | ||
| 29816 | cancel_hourglass (); | 29743 | cancel_hourglass (); |
| 29817 | 29744 | ||
| 29818 | if (INTEGERP (Vhourglass_delay) | 29745 | if (INTEGERP (Vhourglass_delay) |
| 29819 | && XINT (Vhourglass_delay) > 0) | 29746 | && XINT (Vhourglass_delay) > 0) |
| 29820 | delay = make_emacs_time (min (XINT (Vhourglass_delay), | 29747 | delay = make_timespec (min (XINT (Vhourglass_delay), |
| 29821 | TYPE_MAXIMUM (time_t)), | 29748 | TYPE_MAXIMUM (time_t)), |
| 29822 | 0); | 29749 | 0); |
| 29823 | else if (FLOATP (Vhourglass_delay) | 29750 | else if (FLOATP (Vhourglass_delay) |
| 29824 | && XFLOAT_DATA (Vhourglass_delay) > 0) | 29751 | && XFLOAT_DATA (Vhourglass_delay) > 0) |
| 29825 | delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay)); | 29752 | delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay)); |
| 29826 | else | 29753 | else |
| 29827 | delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); | 29754 | delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0); |
| 29828 | 29755 | ||
| 29829 | #ifdef HAVE_NTGUI | 29756 | #ifdef HAVE_NTGUI |
| 29830 | { | 29757 | { |
diff --git a/src/xfaces.c b/src/xfaces.c index acd2d2b1116..a55ac90086d 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -236,7 +236,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 236 | #ifdef HAVE_NS | 236 | #ifdef HAVE_NS |
| 237 | #undef FRAME_X_DISPLAY_INFO | 237 | #undef FRAME_X_DISPLAY_INFO |
| 238 | #define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO | 238 | #define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO |
| 239 | #define x_display_info ns_display_info | ||
| 240 | #define GCGraphicsExposures 0 | 239 | #define GCGraphicsExposures 0 |
| 241 | #endif /* HAVE_NS */ | 240 | #endif /* HAVE_NS */ |
| 242 | #endif /* HAVE_WINDOW_SYSTEM */ | 241 | #endif /* HAVE_WINDOW_SYSTEM */ |
| @@ -759,11 +758,6 @@ clear_face_cache (int clear_fonts_p) | |||
| 759 | if (clear_fonts_p | 758 | if (clear_fonts_p |
| 760 | || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) | 759 | || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) |
| 761 | { | 760 | { |
| 762 | #if 0 | ||
| 763 | /* Not yet implemented. */ | ||
| 764 | clear_font_cache (frame); | ||
| 765 | #endif | ||
| 766 | |||
| 767 | /* From time to time see if we can unload some fonts. This also | 761 | /* From time to time see if we can unload some fonts. This also |
| 768 | frees all realized faces on all frames. Fonts needed by | 762 | frees all realized faces on all frames. Fonts needed by |
| 769 | faces will be loaded again when faces are realized again. */ | 763 | faces will be loaded again when faces are realized again. */ |
| @@ -774,7 +768,10 @@ clear_face_cache (int clear_fonts_p) | |||
| 774 | struct frame *f = XFRAME (frame); | 768 | struct frame *f = XFRAME (frame); |
| 775 | if (FRAME_WINDOW_P (f) | 769 | if (FRAME_WINDOW_P (f) |
| 776 | && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS) | 770 | && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS) |
| 777 | free_all_realized_faces (frame); | 771 | { |
| 772 | clear_font_cache (f); | ||
| 773 | free_all_realized_faces (frame); | ||
| 774 | } | ||
| 778 | } | 775 | } |
| 779 | } | 776 | } |
| 780 | else | 777 | else |
diff --git a/src/xfns.c b/src/xfns.c index a1e9e916aba..b08fc76524c 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -22,10 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 22 | #include <math.h> | 22 | #include <math.h> |
| 23 | #include <unistd.h> | 23 | #include <unistd.h> |
| 24 | 24 | ||
| 25 | /* This makes the fields of a Display accessible, in Xlib header files. */ | ||
| 26 | |||
| 27 | #define XLIB_ILLEGAL_ACCESS | ||
| 28 | |||
| 29 | #include "lisp.h" | 25 | #include "lisp.h" |
| 30 | #include "xterm.h" | 26 | #include "xterm.h" |
| 31 | #include "frame.h" | 27 | #include "frame.h" |
| @@ -1053,11 +1049,8 @@ static void | |||
| 1053 | x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | 1049 | x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) |
| 1054 | { | 1050 | { |
| 1055 | set_frame_cursor_types (f, arg); | 1051 | set_frame_cursor_types (f, arg); |
| 1056 | |||
| 1057 | /* Make sure the cursor gets redrawn. */ | ||
| 1058 | cursor_type_changed = 1; | ||
| 1059 | } | 1052 | } |
| 1060 | 1053 | ||
| 1061 | static void | 1054 | static void |
| 1062 | x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | 1055 | x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) |
| 1063 | { | 1056 | { |
| @@ -1189,7 +1182,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | |||
| 1189 | 1182 | ||
| 1190 | block_input (); | 1183 | block_input (); |
| 1191 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 1184 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 1192 | 0, y, width, height, False); | 1185 | 0, y, width, height); |
| 1193 | unblock_input (); | 1186 | unblock_input (); |
| 1194 | } | 1187 | } |
| 1195 | 1188 | ||
| @@ -1200,7 +1193,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | |||
| 1200 | 1193 | ||
| 1201 | block_input (); | 1194 | block_input (); |
| 1202 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 1195 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 1203 | 0, y, width, height, False); | 1196 | 0, y, width, height); |
| 1204 | unblock_input (); | 1197 | unblock_input (); |
| 1205 | } | 1198 | } |
| 1206 | 1199 | ||
| @@ -1298,8 +1291,8 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | |||
| 1298 | if (height > 0 && width > 0) | 1291 | if (height > 0 && width > 0) |
| 1299 | { | 1292 | { |
| 1300 | block_input (); | 1293 | block_input (); |
| 1301 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 1294 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 1302 | 0, y, width, height, False); | 1295 | 0, y, width, height); |
| 1303 | unblock_input (); | 1296 | unblock_input (); |
| 1304 | } | 1297 | } |
| 1305 | 1298 | ||
| @@ -2313,12 +2306,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) | |||
| 2313 | for the window manager, so GC relocation won't bother it. | 2306 | for the window manager, so GC relocation won't bother it. |
| 2314 | 2307 | ||
| 2315 | Elsewhere we specify the window name for the window manager. */ | 2308 | Elsewhere we specify the window name for the window manager. */ |
| 2316 | 2309 | f->namebuf = xstrdup (SSDATA (Vx_resource_name)); | |
| 2317 | { | ||
| 2318 | char *str = SSDATA (Vx_resource_name); | ||
| 2319 | f->namebuf = xmalloc (strlen (str) + 1); | ||
| 2320 | strcpy (f->namebuf, str); | ||
| 2321 | } | ||
| 2322 | 2310 | ||
| 2323 | ac = 0; | 2311 | ac = 0; |
| 2324 | XtSetArg (al[ac], XtNallowShellResize, 1); ac++; | 2312 | XtSetArg (al[ac], XtNallowShellResize, 1); ac++; |
| @@ -2336,12 +2324,8 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) | |||
| 2336 | /* maybe_set_screen_title_format (shell_widget); */ | 2324 | /* maybe_set_screen_title_format (shell_widget); */ |
| 2337 | 2325 | ||
| 2338 | pane_widget = lw_create_widget ("main", "pane", widget_id_tick++, | 2326 | pane_widget = lw_create_widget ("main", "pane", widget_id_tick++, |
| 2339 | (widget_value *) NULL, | 2327 | NULL, shell_widget, False, |
| 2340 | shell_widget, False, | 2328 | NULL, NULL, NULL, NULL); |
| 2341 | (lw_callback) NULL, | ||
| 2342 | (lw_callback) NULL, | ||
| 2343 | (lw_callback) NULL, | ||
| 2344 | (lw_callback) NULL); | ||
| 2345 | 2329 | ||
| 2346 | ac = 0; | 2330 | ac = 0; |
| 2347 | XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++; | 2331 | XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++; |
| @@ -2488,8 +2472,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) | |||
| 2488 | */ | 2472 | */ |
| 2489 | XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget), | 2473 | XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget), |
| 2490 | FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, | 2474 | FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, |
| 2491 | XA_ATOM, 32, PropModeAppend, | 2475 | XA_ATOM, 32, PropModeAppend, NULL, 0); |
| 2492 | (unsigned char*) NULL, 0); | ||
| 2493 | 2476 | ||
| 2494 | /* Make all the standard events reach the Emacs frame. */ | 2477 | /* Make all the standard events reach the Emacs frame. */ |
| 2495 | attributes.event_mask = STANDARD_EVENT_SET; | 2478 | attributes.event_mask = STANDARD_EVENT_SET; |
| @@ -4014,7 +3997,7 @@ x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo) | |||
| 4014 | / x_display_pixel_width (dpyinfo)); | 3997 | / x_display_pixel_width (dpyinfo)); |
| 4015 | mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen) | 3998 | mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen) |
| 4016 | / x_display_pixel_height (dpyinfo)); | 3999 | / x_display_pixel_height (dpyinfo)); |
| 4017 | monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); | 4000 | monitors = xzalloc (n_monitors * sizeof *monitors); |
| 4018 | for (i = 0; i < n_monitors; ++i) | 4001 | for (i = 0; i < n_monitors; ++i) |
| 4019 | { | 4002 | { |
| 4020 | struct MonitorInfo *mi = &monitors[i]; | 4003 | struct MonitorInfo *mi = &monitors[i]; |
| @@ -4074,7 +4057,7 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo) | |||
| 4074 | return Qnil; | 4057 | return Qnil; |
| 4075 | } | 4058 | } |
| 4076 | n_monitors = resources->noutput; | 4059 | n_monitors = resources->noutput; |
| 4077 | monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); | 4060 | monitors = xzalloc (n_monitors * sizeof *monitors); |
| 4078 | 4061 | ||
| 4079 | #ifdef HAVE_XRRGETOUTPUTPRIMARY | 4062 | #ifdef HAVE_XRRGETOUTPUTPRIMARY |
| 4080 | pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window); | 4063 | pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window); |
| @@ -4230,7 +4213,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) | |||
| 4230 | #endif | 4213 | #endif |
| 4231 | n_monitors = gdk_screen_get_n_monitors (gscreen); | 4214 | n_monitors = gdk_screen_get_n_monitors (gscreen); |
| 4232 | monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); | 4215 | monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); |
| 4233 | monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); | 4216 | monitors = xzalloc (n_monitors * sizeof *monitors); |
| 4234 | 4217 | ||
| 4235 | FOR_EACH_FRAME (rest, frame) | 4218 | FOR_EACH_FRAME (rest, frame) |
| 4236 | { | 4219 | { |
| @@ -4468,8 +4451,7 @@ x_display_info_for_name (Lisp_Object name) | |||
| 4468 | 4451 | ||
| 4469 | validate_x_resource_name (); | 4452 | validate_x_resource_name (); |
| 4470 | 4453 | ||
| 4471 | dpyinfo = x_term_init (name, (char *)0, | 4454 | dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name)); |
| 4472 | SSDATA (Vx_resource_name)); | ||
| 4473 | 4455 | ||
| 4474 | if (dpyinfo == 0) | 4456 | if (dpyinfo == 0) |
| 4475 | error ("Cannot connect to X server %s", SDATA (name)); | 4457 | error ("Cannot connect to X server %s", SDATA (name)); |
| @@ -4502,10 +4484,7 @@ terminate Emacs if we can't open the connection. | |||
| 4502 | error ("Not using X Windows"); /* That doesn't stop us anymore. */ | 4484 | error ("Not using X Windows"); /* That doesn't stop us anymore. */ |
| 4503 | #endif | 4485 | #endif |
| 4504 | 4486 | ||
| 4505 | if (! NILP (xrm_string)) | 4487 | xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string); |
| 4506 | xrm_option = SSDATA (xrm_string); | ||
| 4507 | else | ||
| 4508 | xrm_option = (char *) 0; | ||
| 4509 | 4488 | ||
| 4510 | validate_x_resource_name (); | 4489 | validate_x_resource_name (); |
| 4511 | 4490 | ||
| @@ -5729,8 +5708,8 @@ DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog, | |||
| 5729 | static void | 5708 | static void |
| 5730 | file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data) | 5709 | file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data) |
| 5731 | { | 5710 | { |
| 5732 | int *result = (int *) client_data; | 5711 | int *result = client_data; |
| 5733 | XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data; | 5712 | XmAnyCallbackStruct *cb = call_data; |
| 5734 | *result = cb->reason; | 5713 | *result = cb->reason; |
| 5735 | } | 5714 | } |
| 5736 | 5715 | ||
| @@ -5743,7 +5722,7 @@ file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 5743 | static void | 5722 | static void |
| 5744 | file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data) | 5723 | file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data) |
| 5745 | { | 5724 | { |
| 5746 | int *result = (int *) client_data; | 5725 | int *result = client_data; |
| 5747 | *result = XmCR_CANCEL; | 5726 | *result = XmCR_CANCEL; |
| 5748 | } | 5727 | } |
| 5749 | 5728 | ||
diff --git a/src/xfont.c b/src/xfont.c index f673adbbd5e..1aface6f972 100644 --- a/src/xfont.c +++ b/src/xfont.c | |||
| @@ -593,9 +593,7 @@ xfont_match (struct frame *f, Lisp_Object spec) | |||
| 593 | { | 593 | { |
| 594 | if (XGetFontProperty (xfont, XA_FONT, &value)) | 594 | if (XGetFontProperty (xfont, XA_FONT, &value)) |
| 595 | { | 595 | { |
| 596 | char *s; | 596 | char *s = XGetAtomName (display, (Atom) value); |
| 597 | |||
| 598 | s = (char *) XGetAtomName (display, (Atom) value); | ||
| 599 | 597 | ||
| 600 | /* If DXPC (a Differential X Protocol Compressor) | 598 | /* If DXPC (a Differential X Protocol Compressor) |
| 601 | Ver.3.7 is running, XGetAtomName will return null | 599 | Ver.3.7 is running, XGetAtomName will return null |
| @@ -760,7 +758,7 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | |||
| 760 | char *p0, *p; | 758 | char *p0, *p; |
| 761 | int dashes = 0; | 759 | int dashes = 0; |
| 762 | 760 | ||
| 763 | p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value); | 761 | p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value); |
| 764 | /* Count the number of dashes in the "full name". | 762 | /* Count the number of dashes in the "full name". |
| 765 | If it is too few, this isn't really the font's full name, | 763 | If it is too few, this isn't really the font's full name, |
| 766 | so don't use it. | 764 | so don't use it. |
diff --git a/src/xgselect.c b/src/xgselect.c index 4d90298a9d9..7a754bd75c0 100644 --- a/src/xgselect.c +++ b/src/xgselect.c | |||
| @@ -25,14 +25,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | 25 | ||
| 26 | #include <glib.h> | 26 | #include <glib.h> |
| 27 | #include <errno.h> | 27 | #include <errno.h> |
| 28 | #include <timespec.h> | ||
| 28 | #include "frame.h" | 29 | #include "frame.h" |
| 29 | 30 | ||
| 30 | int | 31 | int |
| 31 | xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | 32 | xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, |
| 32 | EMACS_TIME *timeout, sigset_t *sigmask) | 33 | struct timespec const *timeout, sigset_t const *sigmask) |
| 33 | { | 34 | { |
| 34 | SELECT_TYPE all_rfds, all_wfds; | 35 | fd_set all_rfds, all_wfds; |
| 35 | EMACS_TIME tmo, *tmop = timeout; | 36 | struct timespec tmo; |
| 37 | struct timespec const *tmop = timeout; | ||
| 36 | 38 | ||
| 37 | GMainContext *context; | 39 | GMainContext *context; |
| 38 | int have_wfds = wfds != NULL; | 40 | int have_wfds = wfds != NULL; |
| @@ -85,9 +87,9 @@ xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 85 | 87 | ||
| 86 | if (tmo_in_millisec >= 0) | 88 | if (tmo_in_millisec >= 0) |
| 87 | { | 89 | { |
| 88 | tmo = make_emacs_time (tmo_in_millisec / 1000, | 90 | tmo = make_timespec (tmo_in_millisec / 1000, |
| 89 | 1000 * 1000 * (tmo_in_millisec % 1000)); | 91 | 1000 * 1000 * (tmo_in_millisec % 1000)); |
| 90 | if (!timeout || EMACS_TIME_LT (tmo, *timeout)) | 92 | if (!timeout || timespec_cmp (tmo, *timeout) < 0) |
| 91 | tmop = &tmo; | 93 | tmop = &tmo; |
| 92 | } | 94 | } |
| 93 | 95 | ||
diff --git a/src/xgselect.h b/src/xgselect.h index f142e85d877..1f8555591d0 100644 --- a/src/xgselect.h +++ b/src/xgselect.h | |||
| @@ -21,14 +21,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 21 | #define XGSELECT_H | 21 | #define XGSELECT_H |
| 22 | 22 | ||
| 23 | #include "lisp.h" | 23 | #include "lisp.h" |
| 24 | #include "systime.h" | 24 | #include <time.h> |
| 25 | #include "sysselect.h" | 25 | #include "sysselect.h" |
| 26 | 26 | ||
| 27 | extern int xg_select (int max_fds, | 27 | extern int xg_select (int max_fds, |
| 28 | SELECT_TYPE *rfds, | 28 | fd_set *rfds, fd_set *wfds, fd_set *efds, |
| 29 | SELECT_TYPE *wfds, | 29 | struct timespec const *timeout, |
| 30 | SELECT_TYPE *efds, | 30 | sigset_t const *sigmask); |
| 31 | EMACS_TIME *timeout, | ||
| 32 | sigset_t *sigmask); | ||
| 33 | 31 | ||
| 34 | #endif /* XGSELECT_H */ | 32 | #endif /* XGSELECT_H */ |
diff --git a/src/xmenu.c b/src/xmenu.c index cad892444ff..823c63bfc6f 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -373,12 +373,12 @@ x_menu_wait_for_event (void *data) | |||
| 373 | #elif defined USE_GTK | 373 | #elif defined USE_GTK |
| 374 | ! gtk_events_pending () | 374 | ! gtk_events_pending () |
| 375 | #else | 375 | #else |
| 376 | ! XPending ((Display*) data) | 376 | ! XPending (data) |
| 377 | #endif | 377 | #endif |
| 378 | ) | 378 | ) |
| 379 | { | 379 | { |
| 380 | EMACS_TIME next_time = timer_check (), *ntp; | 380 | struct timespec next_time = timer_check (), *ntp; |
| 381 | SELECT_TYPE read_fds; | 381 | fd_set read_fds; |
| 382 | struct x_display_info *dpyinfo; | 382 | struct x_display_info *dpyinfo; |
| 383 | int n = 0; | 383 | int n = 0; |
| 384 | 384 | ||
| @@ -391,7 +391,7 @@ x_menu_wait_for_event (void *data) | |||
| 391 | XFlush (dpyinfo->display); | 391 | XFlush (dpyinfo->display); |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | if (! EMACS_TIME_VALID_P (next_time)) | 394 | if (! timespec_valid_p (next_time)) |
| 395 | ntp = 0; | 395 | ntp = 0; |
| 396 | else | 396 | else |
| 397 | ntp = &next_time; | 397 | ntp = &next_time; |
| @@ -722,8 +722,7 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data) | |||
| 722 | xg_menu_item_cb_data *cb_data; | 722 | xg_menu_item_cb_data *cb_data; |
| 723 | Lisp_Object help; | 723 | Lisp_Object help; |
| 724 | 724 | ||
| 725 | cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (widget), | 725 | cb_data = g_object_get_data (G_OBJECT (widget), XG_ITEM_DATA); |
| 726 | XG_ITEM_DATA); | ||
| 727 | if (! cb_data) return; | 726 | if (! cb_data) return; |
| 728 | 727 | ||
| 729 | help = call_data ? cb_data->help : Qnil; | 728 | help = call_data ? cb_data->help : Qnil; |
| @@ -741,15 +740,11 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data) | |||
| 741 | static void | 740 | static void |
| 742 | menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data) | 741 | menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data) |
| 743 | { | 742 | { |
| 744 | struct frame *f; | 743 | widget_value *wv = call_data; |
| 745 | Lisp_Object help; | 744 | Lisp_Object help = wv ? wv->help : Qnil; |
| 746 | |||
| 747 | widget_value *wv = (widget_value *) call_data; | ||
| 748 | |||
| 749 | help = wv ? wv->help : Qnil; | ||
| 750 | 745 | ||
| 751 | /* Determine the frame for the help event. */ | 746 | /* Determine the frame for the help event. */ |
| 752 | f = menubar_id_to_frame (id); | 747 | struct frame *f = menubar_id_to_frame (id); |
| 753 | 748 | ||
| 754 | show_help_event (f, widget, help); | 749 | show_help_event (f, widget, help); |
| 755 | } | 750 | } |
| @@ -769,7 +764,7 @@ static int xg_crazy_callback_abort; | |||
| 769 | static void | 764 | static void |
| 770 | menubar_selection_callback (GtkWidget *widget, gpointer client_data) | 765 | menubar_selection_callback (GtkWidget *widget, gpointer client_data) |
| 771 | { | 766 | { |
| 772 | xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data; | 767 | xg_menu_item_cb_data *cb_data = client_data; |
| 773 | 768 | ||
| 774 | if (xg_crazy_callback_abort) | 769 | if (xg_crazy_callback_abort) |
| 775 | return; | 770 | return; |
| @@ -1370,7 +1365,7 @@ struct next_popup_x_y | |||
| 1370 | static void | 1365 | static void |
| 1371 | menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) | 1366 | menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) |
| 1372 | { | 1367 | { |
| 1373 | struct next_popup_x_y* data = (struct next_popup_x_y*)user_data; | 1368 | struct next_popup_x_y *data = user_data; |
| 1374 | GtkRequisition req; | 1369 | GtkRequisition req; |
| 1375 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (data->f); | 1370 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (data->f); |
| 1376 | int disp_width = x_display_pixel_width (dpyinfo); | 1371 | int disp_width = x_display_pixel_width (dpyinfo); |
| @@ -1391,10 +1386,10 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer | |||
| 1391 | static void | 1386 | static void |
| 1392 | popup_selection_callback (GtkWidget *widget, gpointer client_data) | 1387 | popup_selection_callback (GtkWidget *widget, gpointer client_data) |
| 1393 | { | 1388 | { |
| 1394 | xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data; | 1389 | xg_menu_item_cb_data *cb_data = client_data; |
| 1395 | 1390 | ||
| 1396 | if (xg_crazy_callback_abort) return; | 1391 | if (xg_crazy_callback_abort) return; |
| 1397 | if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; | 1392 | if (cb_data) menu_item_selection = cb_data->call_data; |
| 1398 | } | 1393 | } |
| 1399 | 1394 | ||
| 1400 | static void | 1395 | static void |
| @@ -1497,7 +1492,7 @@ LWLIB_ID widget_id_tick; | |||
| 1497 | static void | 1492 | static void |
| 1498 | popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) | 1493 | popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) |
| 1499 | { | 1494 | { |
| 1500 | menu_item_selection = (Lisp_Object *) client_data; | 1495 | menu_item_selection = client_data; |
| 1501 | } | 1496 | } |
| 1502 | 1497 | ||
| 1503 | /* ARG is the LWLIB ID of the dialog box, represented | 1498 | /* ARG is the LWLIB ID of the dialog box, represented |
| @@ -1583,7 +1578,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, | |||
| 1583 | make_number (menu_id & ~(-1 << (fact))))); | 1578 | make_number (menu_id & ~(-1 << (fact))))); |
| 1584 | 1579 | ||
| 1585 | /* Process events that apply to the menu. */ | 1580 | /* Process events that apply to the menu. */ |
| 1586 | popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1); | 1581 | popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), menu_id, 1); |
| 1587 | 1582 | ||
| 1588 | unbind_to (specpdl_count, Qnil); | 1583 | unbind_to (specpdl_count, Qnil); |
| 1589 | } | 1584 | } |
| @@ -1882,7 +1877,7 @@ dialog_selection_callback (GtkWidget *widget, gpointer client_data) | |||
| 1882 | /* Treat the pointer as an integer. There's no problem | 1877 | /* Treat the pointer as an integer. There's no problem |
| 1883 | as long as pointers have enough bits to hold small integers. */ | 1878 | as long as pointers have enough bits to hold small integers. */ |
| 1884 | if ((intptr_t) client_data != -1) | 1879 | if ((intptr_t) client_data != -1) |
| 1885 | menu_item_selection = (Lisp_Object *) client_data; | 1880 | menu_item_selection = client_data; |
| 1886 | 1881 | ||
| 1887 | popup_activated_flag = 0; | 1882 | popup_activated_flag = 0; |
| 1888 | } | 1883 | } |
| @@ -1924,7 +1919,7 @@ dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) | |||
| 1924 | /* Treat the pointer as an integer. There's no problem | 1919 | /* Treat the pointer as an integer. There's no problem |
| 1925 | as long as pointers have enough bits to hold small integers. */ | 1920 | as long as pointers have enough bits to hold small integers. */ |
| 1926 | if ((intptr_t) client_data != -1) | 1921 | if ((intptr_t) client_data != -1) |
| 1927 | menu_item_selection = (Lisp_Object *) client_data; | 1922 | menu_item_selection = client_data; |
| 1928 | 1923 | ||
| 1929 | block_input (); | 1924 | block_input (); |
| 1930 | lw_destroy_all_widgets (id); | 1925 | lw_destroy_all_widgets (id); |
| @@ -1967,8 +1962,7 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv) | |||
| 1967 | Fcons (make_number (dialog_id >> (fact)), | 1962 | Fcons (make_number (dialog_id >> (fact)), |
| 1968 | make_number (dialog_id & ~(-1 << (fact))))); | 1963 | make_number (dialog_id & ~(-1 << (fact))))); |
| 1969 | 1964 | ||
| 1970 | popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), | 1965 | popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1); |
| 1971 | dialog_id, 1); | ||
| 1972 | 1966 | ||
| 1973 | unbind_to (count, Qnil); | 1967 | unbind_to (count, Qnil); |
| 1974 | } | 1968 | } |
diff --git a/src/xrdb.c b/src/xrdb.c index 7c9cd53fa8c..60dcdae080d 100644 --- a/src/xrdb.c +++ b/src/xrdb.c | |||
| @@ -75,18 +75,9 @@ x_get_customization_string (XrmDatabase db, const char *name, | |||
| 75 | sprintf (full_class, "%s.%s", class, "Customization"); | 75 | sprintf (full_class, "%s.%s", class, "Customization"); |
| 76 | 76 | ||
| 77 | result = x_get_string_resource (db, full_name, full_class); | 77 | result = x_get_string_resource (db, full_name, full_class); |
| 78 | 78 | return result ? xstrdup (result) : NULL; | |
| 79 | if (result) | ||
| 80 | { | ||
| 81 | char *copy = xmalloc (strlen (result) + 1); | ||
| 82 | strcpy (copy, result); | ||
| 83 | return copy; | ||
| 84 | } | ||
| 85 | else | ||
| 86 | return 0; | ||
| 87 | } | 79 | } |
| 88 | 80 | ||
| 89 | |||
| 90 | /* Expand all the Xt-style %-escapes in STRING, whose length is given | 81 | /* Expand all the Xt-style %-escapes in STRING, whose length is given |
| 91 | by STRING_LEN. Here are the escapes we're supposed to recognize: | 82 | by STRING_LEN. Here are the escapes we're supposed to recognize: |
| 92 | 83 | ||
| @@ -605,7 +596,7 @@ x_get_string_resource (XrmDatabase rdb, const char *name, const char *class) | |||
| 605 | if (x_get_resource (rdb, name, class, x_rm_string, &value)) | 596 | if (x_get_resource (rdb, name, class, x_rm_string, &value)) |
| 606 | return (char *) value.addr; | 597 | return (char *) value.addr; |
| 607 | 598 | ||
| 608 | return (char *) 0; | 599 | return 0; |
| 609 | } | 600 | } |
| 610 | 601 | ||
| 611 | /* Stand-alone test facilities. */ | 602 | /* Stand-alone test facilities. */ |
| @@ -655,10 +646,7 @@ main (int argc, char **argv) | |||
| 655 | displayname = "localhost:0.0"; | 646 | displayname = "localhost:0.0"; |
| 656 | 647 | ||
| 657 | lp = member ("-xrm", arg_list); | 648 | lp = member ("-xrm", arg_list); |
| 658 | if (! NIL (lp)) | 649 | resource_string = NIL (lp) ? 0 : car (cdr (lp)); |
| 659 | resource_string = car (cdr (lp)); | ||
| 660 | else | ||
| 661 | resource_string = (char *) 0; | ||
| 662 | 650 | ||
| 663 | lp = member ("-c", arg_list); | 651 | lp = member ("-c", arg_list); |
| 664 | if (! NIL (lp)) | 652 | if (! NIL (lp)) |
diff --git a/src/xselect.c b/src/xselect.c index 3a16d7d3496..e5f2e214fba 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -2628,6 +2628,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, | |||
| 2628 | 2628 | ||
| 2629 | block_input (); | 2629 | block_input (); |
| 2630 | 2630 | ||
| 2631 | event.xclient.send_event = True; | ||
| 2632 | event.xclient.serial = 0; | ||
| 2631 | event.xclient.message_type = message_type; | 2633 | event.xclient.message_type = message_type; |
| 2632 | event.xclient.display = dpyinfo->display; | 2634 | event.xclient.display = dpyinfo->display; |
| 2633 | 2635 | ||
| @@ -2635,19 +2637,19 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, | |||
| 2635 | when sending to the root window. */ | 2637 | when sending to the root window. */ |
| 2636 | event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; | 2638 | event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; |
| 2637 | 2639 | ||
| 2638 | 2640 | memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l)); | |
| 2639 | memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); | ||
| 2640 | x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, | 2641 | x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, |
| 2641 | event.xclient.format); | 2642 | event.xclient.format); |
| 2642 | 2643 | ||
| 2643 | /* If event mask is 0 the event is sent to the client that created | 2644 | /* If event mask is 0 the event is sent to the client that created |
| 2644 | the destination window. But if we are sending to the root window, | 2645 | the destination window. But if we are sending to the root window, |
| 2645 | there is no such client. Then we set the event mask to 0xffff. The | 2646 | there is no such client. Then we set the event mask to 0xffffff. The |
| 2646 | event then goes to clients selecting for events on the root window. */ | 2647 | event then goes to clients selecting for events on the root window. */ |
| 2647 | x_catch_errors (dpyinfo->display); | 2648 | x_catch_errors (dpyinfo->display); |
| 2648 | { | 2649 | { |
| 2649 | int propagate = to_root ? False : True; | 2650 | int propagate = to_root ? False : True; |
| 2650 | unsigned mask = to_root ? 0xffff : 0; | 2651 | long mask = to_root ? 0xffffff : 0; |
| 2652 | |||
| 2651 | XSendEvent (dpyinfo->display, wdest, propagate, mask, &event); | 2653 | XSendEvent (dpyinfo->display, wdest, propagate, mask, &event); |
| 2652 | XFlush (dpyinfo->display); | 2654 | XFlush (dpyinfo->display); |
| 2653 | } | 2655 | } |
diff --git a/src/xsmfns.c b/src/xsmfns.c index cb7122202df..526d4c3610b 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c | |||
| @@ -107,8 +107,7 @@ x_session_check_input (int fd, void *data) | |||
| 107 | will be called. */ | 107 | will be called. */ |
| 108 | emacs_event.kind = NO_EVENT; | 108 | emacs_event.kind = NO_EVENT; |
| 109 | 109 | ||
| 110 | ret = IceProcessMessages (SmcGetIceConnection (smc_conn), | 110 | ret = IceProcessMessages (SmcGetIceConnection (smc_conn), 0, 0); |
| 111 | (IceReplyWaitInfo *)0, (Bool *)0); | ||
| 112 | if (ret != IceProcessMessagesSuccess) | 111 | if (ret != IceProcessMessagesSuccess) |
| 113 | { | 112 | { |
| 114 | /* Either IO error or Connection closed. */ | 113 | /* Either IO error or Connection closed. */ |
diff --git a/src/xterm.c b/src/xterm.c index a486242b8c3..bd990014cea 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -140,16 +140,11 @@ int use_xim = 1; | |||
| 140 | int use_xim = 0; /* configure --without-xim */ | 140 | int use_xim = 0; /* configure --without-xim */ |
| 141 | #endif | 141 | #endif |
| 142 | 142 | ||
| 143 | |||
| 144 | |||
| 145 | /* Non-zero means that a HELP_EVENT has been generated since Emacs | 143 | /* Non-zero means that a HELP_EVENT has been generated since Emacs |
| 146 | start. */ | 144 | start. */ |
| 147 | 145 | ||
| 148 | static bool any_help_event_p; | 146 | static bool any_help_event_p; |
| 149 | 147 | ||
| 150 | /* Last window where we saw the mouse. Used by mouse-autoselect-window. */ | ||
| 151 | static Lisp_Object last_window; | ||
| 152 | |||
| 153 | /* This is a chain of structures for all the X displays currently in | 148 | /* This is a chain of structures for all the X displays currently in |
| 154 | use. */ | 149 | use. */ |
| 155 | 150 | ||
| @@ -292,15 +287,11 @@ static void x_set_window_size_1 (struct frame *, int, int, int); | |||
| 292 | static void x_raise_frame (struct frame *); | 287 | static void x_raise_frame (struct frame *); |
| 293 | static void x_lower_frame (struct frame *); | 288 | static void x_lower_frame (struct frame *); |
| 294 | static const XColor *x_color_cells (Display *, int *); | 289 | static const XColor *x_color_cells (Display *, int *); |
| 295 | static void x_update_window_end (struct window *, int, int); | ||
| 296 | |||
| 297 | static int x_io_error_quitter (Display *); | 290 | static int x_io_error_quitter (Display *); |
| 298 | static struct terminal *x_create_terminal (struct x_display_info *); | 291 | static struct terminal *x_create_terminal (struct x_display_info *); |
| 299 | void x_delete_terminal (struct terminal *); | 292 | void x_delete_terminal (struct terminal *); |
| 300 | static void x_update_end (struct frame *); | 293 | static void x_update_end (struct frame *); |
| 301 | static void XTframe_up_to_date (struct frame *); | 294 | static void XTframe_up_to_date (struct frame *); |
| 302 | static void XTset_terminal_modes (struct terminal *); | ||
| 303 | static void XTreset_terminal_modes (struct terminal *); | ||
| 304 | static void x_clear_frame (struct frame *); | 295 | static void x_clear_frame (struct frame *); |
| 305 | static _Noreturn void x_ins_del_lines (struct frame *, int, int); | 296 | static _Noreturn void x_ins_del_lines (struct frame *, int, int); |
| 306 | static void frame_highlight (struct frame *); | 297 | static void frame_highlight (struct frame *); |
| @@ -316,11 +307,11 @@ static void x_draw_hollow_cursor (struct window *, struct glyph_row *); | |||
| 316 | static void x_draw_bar_cursor (struct window *, struct glyph_row *, int, | 307 | static void x_draw_bar_cursor (struct window *, struct glyph_row *, int, |
| 317 | enum text_cursor_kinds); | 308 | enum text_cursor_kinds); |
| 318 | 309 | ||
| 319 | static void x_clip_to_row (struct window *, struct glyph_row *, int, GC); | 310 | static void x_clip_to_row (struct window *, struct glyph_row *, |
| 311 | enum glyph_row_area, GC); | ||
| 320 | static void x_flush (struct frame *f); | 312 | static void x_flush (struct frame *f); |
| 321 | static void x_update_begin (struct frame *); | 313 | static void x_update_begin (struct frame *); |
| 322 | static void x_update_window_begin (struct window *); | 314 | static void x_update_window_begin (struct window *); |
| 323 | static void x_after_update_window_line (struct glyph_row *); | ||
| 324 | static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); | 315 | static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); |
| 325 | static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, | 316 | static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, |
| 326 | enum scroll_bar_part *, | 317 | enum scroll_bar_part *, |
| @@ -554,9 +545,7 @@ x_update_begin (struct frame *f) | |||
| 554 | } | 545 | } |
| 555 | 546 | ||
| 556 | 547 | ||
| 557 | /* Start update of window W. Set the global variable updated_window | 548 | /* Start update of window W. */ |
| 558 | to the window being updated and set output_cursor to the cursor | ||
| 559 | position of W. */ | ||
| 560 | 549 | ||
| 561 | static void | 550 | static void |
| 562 | x_update_window_begin (struct window *w) | 551 | x_update_window_begin (struct window *w) |
| @@ -564,8 +553,7 @@ x_update_window_begin (struct window *w) | |||
| 564 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 553 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 565 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); | 554 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); |
| 566 | 555 | ||
| 567 | updated_window = w; | 556 | w->output_cursor = w->cursor; |
| 568 | set_output_cursor (&w->cursor); | ||
| 569 | 557 | ||
| 570 | block_input (); | 558 | block_input (); |
| 571 | 559 | ||
| @@ -601,7 +589,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 601 | f->output_data.x->normal_gc, x, y0, x, y1); | 589 | f->output_data.x->normal_gc, x, y0, x, y1); |
| 602 | } | 590 | } |
| 603 | 591 | ||
| 604 | /* End update of window W (which is equal to updated_window). | 592 | /* End update of window W. |
| 605 | 593 | ||
| 606 | Draw vertical borders between horizontally adjacent windows, and | 594 | Draw vertical borders between horizontally adjacent windows, and |
| 607 | display W's cursor if CURSOR_ON_P is non-zero. | 595 | display W's cursor if CURSOR_ON_P is non-zero. |
| @@ -615,18 +603,17 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 615 | here. */ | 603 | here. */ |
| 616 | 604 | ||
| 617 | static void | 605 | static void |
| 618 | x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritten_p) | 606 | x_update_window_end (struct window *w, bool cursor_on_p, |
| 607 | bool mouse_face_overwritten_p) | ||
| 619 | { | 608 | { |
| 620 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); | ||
| 621 | |||
| 622 | if (!w->pseudo_window_p) | 609 | if (!w->pseudo_window_p) |
| 623 | { | 610 | { |
| 624 | block_input (); | 611 | block_input (); |
| 625 | 612 | ||
| 626 | if (cursor_on_p) | 613 | if (cursor_on_p) |
| 627 | display_and_set_cursor (w, 1, output_cursor.hpos, | 614 | display_and_set_cursor (w, 1, |
| 628 | output_cursor.vpos, | 615 | w->output_cursor.hpos, w->output_cursor.vpos, |
| 629 | output_cursor.x, output_cursor.y); | 616 | w->output_cursor.x, w->output_cursor.y); |
| 630 | 617 | ||
| 631 | if (draw_window_fringes (w, 1)) | 618 | if (draw_window_fringes (w, 1)) |
| 632 | x_draw_vertical_border (w); | 619 | x_draw_vertical_border (w); |
| @@ -637,13 +624,7 @@ x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritt | |||
| 637 | /* If a row with mouse-face was overwritten, arrange for | 624 | /* If a row with mouse-face was overwritten, arrange for |
| 638 | XTframe_up_to_date to redisplay the mouse highlight. */ | 625 | XTframe_up_to_date to redisplay the mouse highlight. */ |
| 639 | if (mouse_face_overwritten_p) | 626 | if (mouse_face_overwritten_p) |
| 640 | { | 627 | reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame))); |
| 641 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 642 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 643 | hlinfo->mouse_face_window = Qnil; | ||
| 644 | } | ||
| 645 | |||
| 646 | updated_window = NULL; | ||
| 647 | } | 628 | } |
| 648 | 629 | ||
| 649 | 630 | ||
| @@ -664,9 +645,8 @@ x_update_end (struct frame *f) | |||
| 664 | } | 645 | } |
| 665 | 646 | ||
| 666 | 647 | ||
| 667 | /* This function is called from various places in xdisp.c whenever a | 648 | /* This function is called from various places in xdisp.c |
| 668 | complete update has been performed. The global variable | 649 | whenever a complete update has been performed. */ |
| 669 | updated_window is not available here. */ | ||
| 670 | 650 | ||
| 671 | static void | 651 | static void |
| 672 | XTframe_up_to_date (struct frame *f) | 652 | XTframe_up_to_date (struct frame *f) |
| @@ -678,15 +658,13 @@ XTframe_up_to_date (struct frame *f) | |||
| 678 | 658 | ||
| 679 | /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay | 659 | /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay |
| 680 | arrow bitmaps, or clear the fringes if no bitmaps are required | 660 | arrow bitmaps, or clear the fringes if no bitmaps are required |
| 681 | before DESIRED_ROW is made current. The window being updated is | 661 | before DESIRED_ROW is made current. This function is called from |
| 682 | found in updated_window. This function It is called from | ||
| 683 | update_window_line only if it is known that there are differences | 662 | update_window_line only if it is known that there are differences |
| 684 | between bitmaps to be drawn between current row and DESIRED_ROW. */ | 663 | between bitmaps to be drawn between current row and DESIRED_ROW. */ |
| 685 | 664 | ||
| 686 | static void | 665 | static void |
| 687 | x_after_update_window_line (struct glyph_row *desired_row) | 666 | x_after_update_window_line (struct window *w, struct glyph_row *desired_row) |
| 688 | { | 667 | { |
| 689 | struct window *w = updated_window; | ||
| 690 | struct frame *f; | 668 | struct frame *f; |
| 691 | int width, height; | 669 | int width, height; |
| 692 | 670 | ||
| @@ -697,7 +675,7 @@ x_after_update_window_line (struct glyph_row *desired_row) | |||
| 697 | 675 | ||
| 698 | /* When a window has disappeared, make sure that no rest of | 676 | /* When a window has disappeared, make sure that no rest of |
| 699 | full-width rows stays visible in the internal border. Could | 677 | full-width rows stays visible in the internal border. Could |
| 700 | check here if updated_window is the leftmost/rightmost window, | 678 | check here if updated window is the leftmost/rightmost window, |
| 701 | but I guess it's not worth doing since vertically split windows | 679 | but I guess it's not worth doing since vertically split windows |
| 702 | are almost never used, internal border is rarely set, and the | 680 | are almost never used, internal border is rarely set, and the |
| 703 | overhead is very small. */ | 681 | overhead is very small. */ |
| @@ -713,10 +691,10 @@ x_after_update_window_line (struct glyph_row *desired_row) | |||
| 713 | 691 | ||
| 714 | block_input (); | 692 | block_input (); |
| 715 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 693 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 716 | 0, y, width, height, False); | 694 | 0, y, width, height); |
| 717 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 695 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 718 | FRAME_PIXEL_WIDTH (f) - width, | 696 | FRAME_PIXEL_WIDTH (f) - width, |
| 719 | y, width, height, False); | 697 | y, width, height); |
| 720 | unblock_input (); | 698 | unblock_input (); |
| 721 | } | 699 | } |
| 722 | } | 700 | } |
| @@ -731,7 +709,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring | |||
| 731 | struct face *face = p->face; | 709 | struct face *face = p->face; |
| 732 | 710 | ||
| 733 | /* Must clip because of partially visible lines. */ | 711 | /* Must clip because of partially visible lines. */ |
| 734 | x_clip_to_row (w, row, -1, gc); | 712 | x_clip_to_row (w, row, ANY_AREA, gc); |
| 735 | 713 | ||
| 736 | if (!p->overlay_p) | 714 | if (!p->overlay_p) |
| 737 | { | 715 | { |
| @@ -848,27 +826,6 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring | |||
| 848 | XSetClipMask (display, gc, None); | 826 | XSetClipMask (display, gc, None); |
| 849 | } | 827 | } |
| 850 | 828 | ||
| 851 | |||
| 852 | |||
| 853 | /* This is called when starting Emacs and when restarting after | ||
| 854 | suspend. When starting Emacs, no X window is mapped. And nothing | ||
| 855 | must be done to Emacs's own window if it is suspended (though that | ||
| 856 | rarely happens). */ | ||
| 857 | |||
| 858 | static void | ||
| 859 | XTset_terminal_modes (struct terminal *terminal) | ||
| 860 | { | ||
| 861 | } | ||
| 862 | |||
| 863 | /* This is called when exiting or suspending Emacs. Exiting will make | ||
| 864 | the X-windows go away, and suspending requires no action. */ | ||
| 865 | |||
| 866 | static void | ||
| 867 | XTreset_terminal_modes (struct terminal *terminal) | ||
| 868 | { | ||
| 869 | } | ||
| 870 | |||
| 871 | |||
| 872 | /*********************************************************************** | 829 | /*********************************************************************** |
| 873 | Glyph display | 830 | Glyph display |
| 874 | ***********************************************************************/ | 831 | ***********************************************************************/ |
| @@ -1374,7 +1331,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) | |||
| 1374 | } | 1331 | } |
| 1375 | else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE) | 1332 | else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE) |
| 1376 | { | 1333 | { |
| 1377 | sprintf ((char *) buf, "%0*X", | 1334 | sprintf (buf, "%0*X", |
| 1378 | glyph->u.glyphless.ch < 0x10000 ? 4 : 6, | 1335 | glyph->u.glyphless.ch < 0x10000 ? 4 : 6, |
| 1379 | glyph->u.glyphless.ch); | 1336 | glyph->u.glyphless.ch); |
| 1380 | str = buf; | 1337 | str = buf; |
| @@ -2983,10 +2940,10 @@ x_delete_glyphs (struct frame *f, register int n) | |||
| 2983 | If they are <= 0, this is probably an error. */ | 2940 | If they are <= 0, this is probably an error. */ |
| 2984 | 2941 | ||
| 2985 | void | 2942 | void |
| 2986 | x_clear_area (Display *dpy, Window window, int x, int y, int width, int height, int exposures) | 2943 | x_clear_area (Display *dpy, Window window, int x, int y, int width, int height) |
| 2987 | { | 2944 | { |
| 2988 | eassert (width > 0 && height > 0); | 2945 | eassert (width > 0 && height > 0); |
| 2989 | XClearArea (dpy, window, x, y, width, height, exposures); | 2946 | XClearArea (dpy, window, x, y, width, height, False); |
| 2990 | } | 2947 | } |
| 2991 | 2948 | ||
| 2992 | 2949 | ||
| @@ -2998,11 +2955,7 @@ x_clear_frame (struct frame *f) | |||
| 2998 | /* Clearing the frame will erase any cursor, so mark them all as no | 2955 | /* Clearing the frame will erase any cursor, so mark them all as no |
| 2999 | longer visible. */ | 2956 | longer visible. */ |
| 3000 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); | 2957 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); |
| 3001 | output_cursor.hpos = output_cursor.vpos = 0; | ||
| 3002 | output_cursor.x = -1; | ||
| 3003 | 2958 | ||
| 3004 | /* We don't set the output cursor here because there will always | ||
| 3005 | follow an explicit cursor_to. */ | ||
| 3006 | block_input (); | 2959 | block_input (); |
| 3007 | 2960 | ||
| 3008 | XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); | 2961 | XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| @@ -3127,22 +3080,22 @@ XTflash (struct frame *f) | |||
| 3127 | x_flush (f); | 3080 | x_flush (f); |
| 3128 | 3081 | ||
| 3129 | { | 3082 | { |
| 3130 | EMACS_TIME delay = make_emacs_time (0, 150 * 1000 * 1000); | 3083 | struct timespec delay = make_timespec (0, 150 * 1000 * 1000); |
| 3131 | EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), delay); | 3084 | struct timespec wakeup = timespec_add (current_timespec (), delay); |
| 3132 | 3085 | ||
| 3133 | /* Keep waiting until past the time wakeup or any input gets | 3086 | /* Keep waiting until past the time wakeup or any input gets |
| 3134 | available. */ | 3087 | available. */ |
| 3135 | while (! detect_input_pending ()) | 3088 | while (! detect_input_pending ()) |
| 3136 | { | 3089 | { |
| 3137 | EMACS_TIME current = current_emacs_time (); | 3090 | struct timespec current = current_timespec (); |
| 3138 | EMACS_TIME timeout; | 3091 | struct timespec timeout; |
| 3139 | 3092 | ||
| 3140 | /* Break if result would not be positive. */ | 3093 | /* Break if result would not be positive. */ |
| 3141 | if (EMACS_TIME_LE (wakeup, current)) | 3094 | if (timespec_cmp (wakeup, current) <= 0) |
| 3142 | break; | 3095 | break; |
| 3143 | 3096 | ||
| 3144 | /* How long `select' should wait. */ | 3097 | /* How long `select' should wait. */ |
| 3145 | timeout = make_emacs_time (0, 10 * 1000 * 1000); | 3098 | timeout = make_timespec (0, 10 * 1000 * 1000); |
| 3146 | 3099 | ||
| 3147 | /* Try to wait that long--but we might wake up sooner. */ | 3100 | /* Try to wait that long--but we might wake up sooner. */ |
| 3148 | pselect (0, NULL, NULL, NULL, &timeout, NULL); | 3101 | pselect (0, NULL, NULL, NULL, &timeout, NULL); |
| @@ -3228,20 +3181,6 @@ XTring_bell (struct frame *f) | |||
| 3228 | } | 3181 | } |
| 3229 | } | 3182 | } |
| 3230 | 3183 | ||
| 3231 | |||
| 3232 | /* Specify how many text lines, from the top of the window, | ||
| 3233 | should be affected by insert-lines and delete-lines operations. | ||
| 3234 | This, and those operations, are used only within an update | ||
| 3235 | that is bounded by calls to x_update_begin and x_update_end. */ | ||
| 3236 | |||
| 3237 | static void | ||
| 3238 | XTset_terminal_window (struct frame *f, int n) | ||
| 3239 | { | ||
| 3240 | /* This function intentionally left blank. */ | ||
| 3241 | } | ||
| 3242 | |||
| 3243 | |||
| 3244 | |||
| 3245 | /*********************************************************************** | 3184 | /*********************************************************************** |
| 3246 | Line Dance | 3185 | Line Dance |
| 3247 | ***********************************************************************/ | 3186 | ***********************************************************************/ |
| @@ -3267,7 +3206,7 @@ x_scroll_run (struct window *w, struct run *run) | |||
| 3267 | /* Get frame-relative bounding box of the text display area of W, | 3206 | /* Get frame-relative bounding box of the text display area of W, |
| 3268 | without mode lines. Include in this box the left and right | 3207 | without mode lines. Include in this box the left and right |
| 3269 | fringe of W. */ | 3208 | fringe of W. */ |
| 3270 | window_box (w, -1, &x, &y, &width, &height); | 3209 | window_box (w, ANY_AREA, &x, &y, &width, &height); |
| 3271 | 3210 | ||
| 3272 | #ifdef USE_TOOLKIT_SCROLL_BARS | 3211 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 3273 | /* If the fringe is adjacent to the left (right) scroll bar of a | 3212 | /* If the fringe is adjacent to the left (right) scroll bar of a |
| @@ -3323,7 +3262,6 @@ x_scroll_run (struct window *w, struct run *run) | |||
| 3323 | block_input (); | 3262 | block_input (); |
| 3324 | 3263 | ||
| 3325 | /* Cursor off. Will be switched on again in x_update_window_end. */ | 3264 | /* Cursor off. Will be switched on again in x_update_window_end. */ |
| 3326 | updated_window = w; | ||
| 3327 | x_clear_cursor (w); | 3265 | x_clear_cursor (w); |
| 3328 | 3266 | ||
| 3329 | XCopyArea (FRAME_X_DISPLAY (f), | 3267 | XCopyArea (FRAME_X_DISPLAY (f), |
| @@ -3784,7 +3722,6 @@ construct_mouse_click (struct input_event *result, XButtonEvent *event, struct f | |||
| 3784 | return Qnil; | 3722 | return Qnil; |
| 3785 | } | 3723 | } |
| 3786 | 3724 | ||
| 3787 | |||
| 3788 | /* Function to report a mouse movement to the mainstream Emacs code. | 3725 | /* Function to report a mouse movement to the mainstream Emacs code. |
| 3789 | The input handler calls this. | 3726 | The input handler calls this. |
| 3790 | 3727 | ||
| @@ -4204,9 +4141,9 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, | |||
| 4204 | scroll_bar_end_scroll, 0, 0); | 4141 | scroll_bar_end_scroll, 0, 0); |
| 4205 | w = XWINDOW (window_being_scrolled); | 4142 | w = XWINDOW (window_being_scrolled); |
| 4206 | 4143 | ||
| 4207 | if (!NILP (XSCROLL_BAR (w->vertical_scroll_bar)->dragging)) | 4144 | if (XSCROLL_BAR (w->vertical_scroll_bar)->dragging != -1) |
| 4208 | { | 4145 | { |
| 4209 | XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil; | 4146 | XSCROLL_BAR (w->vertical_scroll_bar)->dragging = -1; |
| 4210 | /* The thumb size is incorrect while dragging: fix it. */ | 4147 | /* The thumb size is incorrect while dragging: fix it. */ |
| 4211 | set_vertical_scroll_bar (w); | 4148 | set_vertical_scroll_bar (w); |
| 4212 | } | 4149 | } |
| @@ -4337,39 +4274,39 @@ x_scroll_bar_to_input_event (XEvent *event, struct input_event *ievent) | |||
| 4337 | static void | 4274 | static void |
| 4338 | xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | 4275 | xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) |
| 4339 | { | 4276 | { |
| 4340 | struct scroll_bar *bar = (struct scroll_bar *) client_data; | 4277 | struct scroll_bar *bar = client_data; |
| 4341 | XmScrollBarCallbackStruct *cs = (XmScrollBarCallbackStruct *) call_data; | 4278 | XmScrollBarCallbackStruct *cs = call_data; |
| 4342 | int part = -1, whole = 0, portion = 0; | 4279 | int part = -1, whole = 0, portion = 0; |
| 4343 | 4280 | ||
| 4344 | switch (cs->reason) | 4281 | switch (cs->reason) |
| 4345 | { | 4282 | { |
| 4346 | case XmCR_DECREMENT: | 4283 | case XmCR_DECREMENT: |
| 4347 | bar->dragging = Qnil; | 4284 | bar->dragging = -1; |
| 4348 | part = scroll_bar_up_arrow; | 4285 | part = scroll_bar_up_arrow; |
| 4349 | break; | 4286 | break; |
| 4350 | 4287 | ||
| 4351 | case XmCR_INCREMENT: | 4288 | case XmCR_INCREMENT: |
| 4352 | bar->dragging = Qnil; | 4289 | bar->dragging = -1; |
| 4353 | part = scroll_bar_down_arrow; | 4290 | part = scroll_bar_down_arrow; |
| 4354 | break; | 4291 | break; |
| 4355 | 4292 | ||
| 4356 | case XmCR_PAGE_DECREMENT: | 4293 | case XmCR_PAGE_DECREMENT: |
| 4357 | bar->dragging = Qnil; | 4294 | bar->dragging = -1; |
| 4358 | part = scroll_bar_above_handle; | 4295 | part = scroll_bar_above_handle; |
| 4359 | break; | 4296 | break; |
| 4360 | 4297 | ||
| 4361 | case XmCR_PAGE_INCREMENT: | 4298 | case XmCR_PAGE_INCREMENT: |
| 4362 | bar->dragging = Qnil; | 4299 | bar->dragging = -1; |
| 4363 | part = scroll_bar_below_handle; | 4300 | part = scroll_bar_below_handle; |
| 4364 | break; | 4301 | break; |
| 4365 | 4302 | ||
| 4366 | case XmCR_TO_TOP: | 4303 | case XmCR_TO_TOP: |
| 4367 | bar->dragging = Qnil; | 4304 | bar->dragging = -1; |
| 4368 | part = scroll_bar_to_top; | 4305 | part = scroll_bar_to_top; |
| 4369 | break; | 4306 | break; |
| 4370 | 4307 | ||
| 4371 | case XmCR_TO_BOTTOM: | 4308 | case XmCR_TO_BOTTOM: |
| 4372 | bar->dragging = Qnil; | 4309 | bar->dragging = -1; |
| 4373 | part = scroll_bar_to_bottom; | 4310 | part = scroll_bar_to_bottom; |
| 4374 | break; | 4311 | break; |
| 4375 | 4312 | ||
| @@ -4385,7 +4322,7 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4385 | whole = XM_SB_MAX - slider_size; | 4322 | whole = XM_SB_MAX - slider_size; |
| 4386 | portion = min (cs->value, whole); | 4323 | portion = min (cs->value, whole); |
| 4387 | part = scroll_bar_handle; | 4324 | part = scroll_bar_handle; |
| 4388 | bar->dragging = make_number (cs->value); | 4325 | bar->dragging = cs->value; |
| 4389 | } | 4326 | } |
| 4390 | break; | 4327 | break; |
| 4391 | 4328 | ||
| @@ -4412,12 +4349,11 @@ xg_scroll_callback (GtkRange *range, | |||
| 4412 | gdouble value, | 4349 | gdouble value, |
| 4413 | gpointer user_data) | 4350 | gpointer user_data) |
| 4414 | { | 4351 | { |
| 4415 | struct scroll_bar *bar = (struct scroll_bar *) user_data; | 4352 | struct scroll_bar *bar = user_data; |
| 4416 | gdouble position; | 4353 | gdouble position; |
| 4417 | int part = -1, whole = 0, portion = 0; | 4354 | int part = -1, whole = 0, portion = 0; |
| 4418 | GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); | 4355 | GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); |
| 4419 | struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (range), | 4356 | struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA); |
| 4420 | XG_FRAME_DATA); | ||
| 4421 | 4357 | ||
| 4422 | if (xg_ignore_gtk_scrollbar) return FALSE; | 4358 | if (xg_ignore_gtk_scrollbar) return FALSE; |
| 4423 | position = gtk_adjustment_get_value (adj); | 4359 | position = gtk_adjustment_get_value (adj); |
| @@ -4434,24 +4370,24 @@ xg_scroll_callback (GtkRange *range, | |||
| 4434 | whole = gtk_adjustment_get_upper (adj) - | 4370 | whole = gtk_adjustment_get_upper (adj) - |
| 4435 | gtk_adjustment_get_page_size (adj); | 4371 | gtk_adjustment_get_page_size (adj); |
| 4436 | portion = min ((int)position, whole); | 4372 | portion = min ((int)position, whole); |
| 4437 | bar->dragging = make_number ((int)portion); | 4373 | bar->dragging = portion; |
| 4438 | } | 4374 | } |
| 4439 | break; | 4375 | break; |
| 4440 | case GTK_SCROLL_STEP_BACKWARD: | 4376 | case GTK_SCROLL_STEP_BACKWARD: |
| 4441 | part = scroll_bar_up_arrow; | 4377 | part = scroll_bar_up_arrow; |
| 4442 | bar->dragging = Qnil; | 4378 | bar->dragging = -1; |
| 4443 | break; | 4379 | break; |
| 4444 | case GTK_SCROLL_STEP_FORWARD: | 4380 | case GTK_SCROLL_STEP_FORWARD: |
| 4445 | part = scroll_bar_down_arrow; | 4381 | part = scroll_bar_down_arrow; |
| 4446 | bar->dragging = Qnil; | 4382 | bar->dragging = -1; |
| 4447 | break; | 4383 | break; |
| 4448 | case GTK_SCROLL_PAGE_BACKWARD: | 4384 | case GTK_SCROLL_PAGE_BACKWARD: |
| 4449 | part = scroll_bar_above_handle; | 4385 | part = scroll_bar_above_handle; |
| 4450 | bar->dragging = Qnil; | 4386 | bar->dragging = -1; |
| 4451 | break; | 4387 | break; |
| 4452 | case GTK_SCROLL_PAGE_FORWARD: | 4388 | case GTK_SCROLL_PAGE_FORWARD: |
| 4453 | part = scroll_bar_below_handle; | 4389 | part = scroll_bar_below_handle; |
| 4454 | bar->dragging = Qnil; | 4390 | bar->dragging = -1; |
| 4455 | break; | 4391 | break; |
| 4456 | } | 4392 | } |
| 4457 | 4393 | ||
| @@ -4465,15 +4401,15 @@ xg_scroll_callback (GtkRange *range, | |||
| 4465 | return FALSE; | 4401 | return FALSE; |
| 4466 | } | 4402 | } |
| 4467 | 4403 | ||
| 4468 | /* Callback for button release. Sets dragging to Qnil when dragging is done. */ | 4404 | /* Callback for button release. Sets dragging to -1 when dragging is done. */ |
| 4469 | 4405 | ||
| 4470 | static gboolean | 4406 | static gboolean |
| 4471 | xg_end_scroll_callback (GtkWidget *widget, | 4407 | xg_end_scroll_callback (GtkWidget *widget, |
| 4472 | GdkEventButton *event, | 4408 | GdkEventButton *event, |
| 4473 | gpointer user_data) | 4409 | gpointer user_data) |
| 4474 | { | 4410 | { |
| 4475 | struct scroll_bar *bar = (struct scroll_bar *) user_data; | 4411 | struct scroll_bar *bar = user_data; |
| 4476 | bar->dragging = Qnil; | 4412 | bar->dragging = -1; |
| 4477 | if (WINDOWP (window_being_scrolled)) | 4413 | if (WINDOWP (window_being_scrolled)) |
| 4478 | { | 4414 | { |
| 4479 | x_send_scroll_bar_event (window_being_scrolled, | 4415 | x_send_scroll_bar_event (window_being_scrolled, |
| @@ -4495,8 +4431,9 @@ xg_end_scroll_callback (GtkWidget *widget, | |||
| 4495 | static void | 4431 | static void |
| 4496 | xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) | 4432 | xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) |
| 4497 | { | 4433 | { |
| 4498 | struct scroll_bar *bar = (struct scroll_bar *) client_data; | 4434 | struct scroll_bar *bar = client_data; |
| 4499 | float top = *(float *) call_data; | 4435 | float *top_addr = call_data; |
| 4436 | float top = *top_addr; | ||
| 4500 | float shown; | 4437 | float shown; |
| 4501 | int whole, portion, height; | 4438 | int whole, portion, height; |
| 4502 | int part; | 4439 | int part; |
| @@ -4520,7 +4457,7 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4520 | part = scroll_bar_handle; | 4457 | part = scroll_bar_handle; |
| 4521 | 4458 | ||
| 4522 | window_being_scrolled = bar->window; | 4459 | window_being_scrolled = bar->window; |
| 4523 | bar->dragging = make_number (portion); | 4460 | bar->dragging = portion; |
| 4524 | last_scroll_bar_part = part; | 4461 | last_scroll_bar_part = part; |
| 4525 | x_send_scroll_bar_event (bar->window, part, portion, whole); | 4462 | x_send_scroll_bar_event (bar->window, part, portion, whole); |
| 4526 | } | 4463 | } |
| @@ -4537,9 +4474,9 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4537 | static void | 4474 | static void |
| 4538 | xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | 4475 | xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) |
| 4539 | { | 4476 | { |
| 4540 | struct scroll_bar *bar = (struct scroll_bar *) client_data; | 4477 | struct scroll_bar *bar = client_data; |
| 4541 | /* The position really is stored cast to a pointer. */ | 4478 | /* The position really is stored cast to a pointer. */ |
| 4542 | int position = (long) call_data; | 4479 | int position = (intptr_t) call_data; |
| 4543 | Dimension height; | 4480 | Dimension height; |
| 4544 | int part; | 4481 | int part; |
| 4545 | 4482 | ||
| @@ -4559,7 +4496,7 @@ xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 4559 | part = scroll_bar_move_ratio; | 4496 | part = scroll_bar_move_ratio; |
| 4560 | 4497 | ||
| 4561 | window_being_scrolled = bar->window; | 4498 | window_being_scrolled = bar->window; |
| 4562 | bar->dragging = Qnil; | 4499 | bar->dragging = -1; |
| 4563 | last_scroll_bar_part = part; | 4500 | last_scroll_bar_part = part; |
| 4564 | x_send_scroll_bar_event (bar->window, part, position, height); | 4501 | x_send_scroll_bar_event (bar->window, part, position, height); |
| 4565 | } | 4502 | } |
| @@ -4835,7 +4772,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4835 | shown = (float) portion / whole; | 4772 | shown = (float) portion / whole; |
| 4836 | } | 4773 | } |
| 4837 | 4774 | ||
| 4838 | if (NILP (bar->dragging)) | 4775 | if (bar->dragging == -1) |
| 4839 | { | 4776 | { |
| 4840 | int size, value; | 4777 | int size, value; |
| 4841 | 4778 | ||
| @@ -4870,7 +4807,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4870 | NULL); | 4807 | NULL); |
| 4871 | 4808 | ||
| 4872 | /* Massage the top+shown values. */ | 4809 | /* Massage the top+shown values. */ |
| 4873 | if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow) | 4810 | if (bar->dragging == -1 || last_scroll_bar_part == scroll_bar_down_arrow) |
| 4874 | top = max (0, min (1, top)); | 4811 | top = max (0, min (1, top)); |
| 4875 | else | 4812 | else |
| 4876 | top = old_top; | 4813 | top = old_top; |
| @@ -4882,7 +4819,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4882 | for `NARROWPROTO'. See s/freebsd.h for an example. */ | 4819 | for `NARROWPROTO'. See s/freebsd.h for an example. */ |
| 4883 | if (top != old_top || shown != old_shown) | 4820 | if (top != old_top || shown != old_shown) |
| 4884 | { | 4821 | { |
| 4885 | if (NILP (bar->dragging)) | 4822 | if (bar->dragging == -1) |
| 4886 | XawScrollbarSetThumb (widget, top, shown); | 4823 | XawScrollbarSetThumb (widget, top, shown); |
| 4887 | else | 4824 | else |
| 4888 | { | 4825 | { |
| @@ -4947,8 +4884,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 4947 | this case, no clear_frame is generated to reduce flickering. */ | 4884 | this case, no clear_frame is generated to reduce flickering. */ |
| 4948 | if (width > 0 && height > 0) | 4885 | if (width > 0 && height > 0) |
| 4949 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 4886 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 4950 | left, top, width, | 4887 | left, top, width, window_box_height (w)); |
| 4951 | window_box_height (w), False); | ||
| 4952 | 4888 | ||
| 4953 | window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 4889 | window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 4954 | /* Position and size of scroll bar. */ | 4890 | /* Position and size of scroll bar. */ |
| @@ -4974,7 +4910,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 4974 | bar->height = height; | 4910 | bar->height = height; |
| 4975 | bar->start = 0; | 4911 | bar->start = 0; |
| 4976 | bar->end = 0; | 4912 | bar->end = 0; |
| 4977 | bar->dragging = Qnil; | 4913 | bar->dragging = -1; |
| 4978 | bar->fringe_extended_p = 0; | 4914 | bar->fringe_extended_p = 0; |
| 4979 | 4915 | ||
| 4980 | /* Add bar to its frame's list of scroll bars. */ | 4916 | /* Add bar to its frame's list of scroll bars. */ |
| @@ -5032,7 +4968,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) | |||
| 5032 | static void | 4968 | static void |
| 5033 | x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild) | 4969 | x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild) |
| 5034 | { | 4970 | { |
| 5035 | int dragging = ! NILP (bar->dragging); | 4971 | bool dragging = bar->dragging != -1; |
| 5036 | Window w = bar->x_window; | 4972 | Window w = bar->x_window; |
| 5037 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | 4973 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); |
| 5038 | GC gc = f->output_data.x->normal_gc; | 4974 | GC gc = f->output_data.x->normal_gc; |
| @@ -5084,11 +5020,9 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild | |||
| 5084 | zero-height areas; that means "clear to end of window." */ | 5020 | zero-height areas; that means "clear to end of window." */ |
| 5085 | if (start > 0) | 5021 | if (start > 0) |
| 5086 | x_clear_area (FRAME_X_DISPLAY (f), w, | 5022 | x_clear_area (FRAME_X_DISPLAY (f), w, |
| 5087 | /* x, y, width, height, and exposures. */ | ||
| 5088 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | 5023 | VERTICAL_SCROLL_BAR_LEFT_BORDER, |
| 5089 | VERTICAL_SCROLL_BAR_TOP_BORDER, | 5024 | VERTICAL_SCROLL_BAR_TOP_BORDER, |
| 5090 | inside_width, start, | 5025 | inside_width, start); |
| 5091 | False); | ||
| 5092 | 5026 | ||
| 5093 | /* Change to proper foreground color if one is specified. */ | 5027 | /* Change to proper foreground color if one is specified. */ |
| 5094 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 5028 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| @@ -5111,12 +5045,9 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild | |||
| 5111 | clear zero-height areas; that means "clear to end of window." */ | 5045 | clear zero-height areas; that means "clear to end of window." */ |
| 5112 | if (end < inside_height) | 5046 | if (end < inside_height) |
| 5113 | x_clear_area (FRAME_X_DISPLAY (f), w, | 5047 | x_clear_area (FRAME_X_DISPLAY (f), w, |
| 5114 | /* x, y, width, height, and exposures. */ | ||
| 5115 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | 5048 | VERTICAL_SCROLL_BAR_LEFT_BORDER, |
| 5116 | VERTICAL_SCROLL_BAR_TOP_BORDER + end, | 5049 | VERTICAL_SCROLL_BAR_TOP_BORDER + end, |
| 5117 | inside_width, inside_height - end, | 5050 | inside_width, inside_height - end); |
| 5118 | False); | ||
| 5119 | |||
| 5120 | } | 5051 | } |
| 5121 | 5052 | ||
| 5122 | unblock_input (); | 5053 | unblock_input (); |
| @@ -5164,11 +5095,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5164 | int top, height, left, sb_left, width, sb_width; | 5095 | int top, height, left, sb_left, width, sb_width; |
| 5165 | int window_y, window_height; | 5096 | int window_y, window_height; |
| 5166 | #ifdef USE_TOOLKIT_SCROLL_BARS | 5097 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 5167 | int fringe_extended_p; | 5098 | bool fringe_extended_p; |
| 5168 | #endif | 5099 | #endif |
| 5169 | 5100 | ||
| 5170 | /* Get window dimensions. */ | 5101 | /* Get window dimensions. */ |
| 5171 | window_box (w, -1, 0, &window_y, 0, &window_height); | 5102 | window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); |
| 5172 | top = window_y; | 5103 | top = window_y; |
| 5173 | width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); | 5104 | width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); |
| 5174 | height = window_height; | 5105 | height = window_height; |
| @@ -5197,16 +5128,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5197 | #endif | 5128 | #endif |
| 5198 | 5129 | ||
| 5199 | #ifdef USE_TOOLKIT_SCROLL_BARS | 5130 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 5200 | if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) | 5131 | fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w); |
| 5201 | fringe_extended_p = (WINDOW_LEFTMOST_P (w) | ||
| 5202 | && WINDOW_LEFT_FRINGE_WIDTH (w) | ||
| 5203 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | ||
| 5204 | || WINDOW_LEFT_MARGIN_COLS (w) == 0)); | ||
| 5205 | else | ||
| 5206 | fringe_extended_p = (WINDOW_RIGHTMOST_P (w) | ||
| 5207 | && WINDOW_RIGHT_FRINGE_WIDTH (w) | ||
| 5208 | && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | ||
| 5209 | || WINDOW_RIGHT_MARGIN_COLS (w) == 0)); | ||
| 5210 | #endif | 5132 | #endif |
| 5211 | 5133 | ||
| 5212 | /* Does the scroll bar exist yet? */ | 5134 | /* Does the scroll bar exist yet? */ |
| @@ -5218,11 +5140,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5218 | #ifdef USE_TOOLKIT_SCROLL_BARS | 5140 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 5219 | if (fringe_extended_p) | 5141 | if (fringe_extended_p) |
| 5220 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5142 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5221 | sb_left, top, sb_width, height, False); | 5143 | sb_left, top, sb_width, height); |
| 5222 | else | 5144 | else |
| 5223 | #endif | 5145 | #endif |
| 5224 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5146 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5225 | left, top, width, height, False); | 5147 | left, top, width, height); |
| 5226 | unblock_input (); | 5148 | unblock_input (); |
| 5227 | } | 5149 | } |
| 5228 | 5150 | ||
| @@ -5257,10 +5179,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5257 | { | 5179 | { |
| 5258 | if (fringe_extended_p) | 5180 | if (fringe_extended_p) |
| 5259 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5181 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5260 | sb_left, top, sb_width, height, False); | 5182 | sb_left, top, sb_width, height); |
| 5261 | else | 5183 | else |
| 5262 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5184 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5263 | left, top, width, height, False); | 5185 | left, top, width, height); |
| 5264 | } | 5186 | } |
| 5265 | #ifdef USE_GTK | 5187 | #ifdef USE_GTK |
| 5266 | xg_update_scrollbar_pos (f, | 5188 | xg_update_scrollbar_pos (f, |
| @@ -5284,12 +5206,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5284 | if (VERTICAL_SCROLL_BAR_WIDTH_TRIM) | 5206 | if (VERTICAL_SCROLL_BAR_WIDTH_TRIM) |
| 5285 | { | 5207 | { |
| 5286 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5208 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5287 | left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, | 5209 | left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, height); |
| 5288 | height, False); | ||
| 5289 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5210 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5290 | left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM, | 5211 | left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM, |
| 5291 | top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, | 5212 | top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, height); |
| 5292 | height, False); | ||
| 5293 | } | 5213 | } |
| 5294 | 5214 | ||
| 5295 | /* Clear areas not covered by the scroll bar because it's not as | 5215 | /* Clear areas not covered by the scroll bar because it's not as |
| @@ -5303,11 +5223,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5303 | { | 5223 | { |
| 5304 | if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) | 5224 | if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) |
| 5305 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5225 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5306 | left + area_width - rest, top, | 5226 | left + area_width - rest, top, rest, height); |
| 5307 | rest, height, False); | ||
| 5308 | else | 5227 | else |
| 5309 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5228 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 5310 | left, top, rest, height, False); | 5229 | left, top, rest, height); |
| 5311 | } | 5230 | } |
| 5312 | } | 5231 | } |
| 5313 | 5232 | ||
| @@ -5342,7 +5261,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 5342 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | 5261 | #else /* not USE_TOOLKIT_SCROLL_BARS */ |
| 5343 | /* Set the scroll bar's current state, unless we're currently being | 5262 | /* Set the scroll bar's current state, unless we're currently being |
| 5344 | dragged. */ | 5263 | dragged. */ |
| 5345 | if (NILP (bar->dragging)) | 5264 | if (bar->dragging == -1) |
| 5346 | { | 5265 | { |
| 5347 | int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height); | 5266 | int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height); |
| 5348 | 5267 | ||
| @@ -5552,14 +5471,13 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e | |||
| 5552 | 5471 | ||
| 5553 | #ifndef USE_TOOLKIT_SCROLL_BARS | 5472 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| 5554 | /* If the user has released the handle, set it to its final position. */ | 5473 | /* If the user has released the handle, set it to its final position. */ |
| 5555 | if (event->type == ButtonRelease | 5474 | if (event->type == ButtonRelease && bar->dragging != -1) |
| 5556 | && ! NILP (bar->dragging)) | ||
| 5557 | { | 5475 | { |
| 5558 | int new_start = y - XINT (bar->dragging); | 5476 | int new_start = y - XINT (bar->dragging); |
| 5559 | int new_end = new_start + bar->end - bar->start; | 5477 | int new_end = new_start + bar->end - bar->start; |
| 5560 | 5478 | ||
| 5561 | x_scroll_bar_set_handle (bar, new_start, new_end, 0); | 5479 | x_scroll_bar_set_handle (bar, new_start, new_end, 0); |
| 5562 | bar->dragging = Qnil; | 5480 | bar->dragging = -1; |
| 5563 | } | 5481 | } |
| 5564 | #endif | 5482 | #endif |
| 5565 | 5483 | ||
| @@ -5576,20 +5494,20 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e | |||
| 5576 | mark bits. */ | 5494 | mark bits. */ |
| 5577 | 5495 | ||
| 5578 | static void | 5496 | static void |
| 5579 | x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event) | 5497 | x_scroll_bar_note_movement (struct scroll_bar *bar, XMotionEvent *event) |
| 5580 | { | 5498 | { |
| 5581 | struct frame *f = XFRAME (XWINDOW (bar->window)->frame); | 5499 | struct frame *f = XFRAME (XWINDOW (bar->window)->frame); |
| 5582 | 5500 | ||
| 5583 | last_mouse_movement_time = event->xmotion.time; | 5501 | last_mouse_movement_time = event->time; |
| 5584 | 5502 | ||
| 5585 | f->mouse_moved = 1; | 5503 | f->mouse_moved = 1; |
| 5586 | XSETVECTOR (last_mouse_scroll_bar, bar); | 5504 | XSETVECTOR (last_mouse_scroll_bar, bar); |
| 5587 | 5505 | ||
| 5588 | /* If we're dragging the bar, display it. */ | 5506 | /* If we're dragging the bar, display it. */ |
| 5589 | if (! NILP (bar->dragging)) | 5507 | if (bar->dragging != -1) |
| 5590 | { | 5508 | { |
| 5591 | /* Where should the handle be now? */ | 5509 | /* Where should the handle be now? */ |
| 5592 | int new_start = event->xmotion.y - XINT (bar->dragging); | 5510 | int new_start = event->y - bar->dragging; |
| 5593 | 5511 | ||
| 5594 | if (new_start != bar->start) | 5512 | if (new_start != bar->start) |
| 5595 | { | 5513 | { |
| @@ -5641,8 +5559,8 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, | |||
| 5641 | 5559 | ||
| 5642 | win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER; | 5560 | win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER; |
| 5643 | 5561 | ||
| 5644 | if (! NILP (bar->dragging)) | 5562 | if (bar->dragging != -1) |
| 5645 | win_y -= XINT (bar->dragging); | 5563 | win_y -= bar->dragging; |
| 5646 | 5564 | ||
| 5647 | if (win_y < 0) | 5565 | if (win_y < 0) |
| 5648 | win_y = 0; | 5566 | win_y = 0; |
| @@ -5652,7 +5570,7 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, | |||
| 5652 | *fp = f; | 5570 | *fp = f; |
| 5653 | *bar_window = bar->window; | 5571 | *bar_window = bar->window; |
| 5654 | 5572 | ||
| 5655 | if (! NILP (bar->dragging)) | 5573 | if (bar->dragging != -1) |
| 5656 | *part = scroll_bar_handle; | 5574 | *part = scroll_bar_handle; |
| 5657 | else if (win_y < bar->start) | 5575 | else if (win_y < bar->start) |
| 5658 | *part = scroll_bar_above_handle; | 5576 | *part = scroll_bar_above_handle; |
| @@ -5697,18 +5615,7 @@ x_scroll_bar_clear (struct frame *f) | |||
| 5697 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 5615 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 5698 | } | 5616 | } |
| 5699 | 5617 | ||
| 5700 | 5618 | #ifdef ENABLE_CHECKING | |
| 5701 | /* The main X event-reading loop - XTread_socket. */ | ||
| 5702 | |||
| 5703 | /* This holds the state XLookupString needs to implement dead keys | ||
| 5704 | and other tricks known as "compose processing". _X Window System_ | ||
| 5705 | says that a portable program can't use this, but Stephen Gildea assures | ||
| 5706 | me that letting the compiler initialize it to zeros will work okay. | ||
| 5707 | |||
| 5708 | This must be defined outside of XTread_socket, for the same reasons | ||
| 5709 | given for enter_timestamp, above. */ | ||
| 5710 | |||
| 5711 | static XComposeStatus compose_status; | ||
| 5712 | 5619 | ||
| 5713 | /* Record the last 100 characters stored | 5620 | /* Record the last 100 characters stored |
| 5714 | to help debug the loss-of-chars-during-GC problem. */ | 5621 | to help debug the loss-of-chars-during-GC problem. */ |
| @@ -5721,6 +5628,12 @@ static short temp_buffer[100]; | |||
| 5721 | temp_index = 0; \ | 5628 | temp_index = 0; \ |
| 5722 | temp_buffer[temp_index++] = (keysym) | 5629 | temp_buffer[temp_index++] = (keysym) |
| 5723 | 5630 | ||
| 5631 | #else /* not ENABLE_CHECKING */ | ||
| 5632 | |||
| 5633 | #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0) | ||
| 5634 | |||
| 5635 | #endif /* ENABLE_CHECKING */ | ||
| 5636 | |||
| 5724 | /* Set this to nonzero to fake an "X I/O error" | 5637 | /* Set this to nonzero to fake an "X I/O error" |
| 5725 | on a particular display. */ | 5638 | on a particular display. */ |
| 5726 | 5639 | ||
| @@ -5858,6 +5771,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 5858 | struct coding_system coding; | 5771 | struct coding_system coding; |
| 5859 | XEvent event = *eventptr; | 5772 | XEvent event = *eventptr; |
| 5860 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; | 5773 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; |
| 5774 | /* This holds the state XLookupString needs to implement dead keys | ||
| 5775 | and other tricks known as "compose processing". _X Window System_ | ||
| 5776 | says that a portable program can't use this, but Stephen Gildea assures | ||
| 5777 | me that letting the compiler initialize it to zeros will work okay. */ | ||
| 5778 | static XComposeStatus compose_status; | ||
| 5779 | |||
| 5861 | USE_SAFE_ALLOCA; | 5780 | USE_SAFE_ALLOCA; |
| 5862 | 5781 | ||
| 5863 | *finish = X_EVENT_NORMAL; | 5782 | *finish = X_EVENT_NORMAL; |
| @@ -6151,11 +6070,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6151 | { | 6070 | { |
| 6152 | #ifdef USE_GTK | 6071 | #ifdef USE_GTK |
| 6153 | /* This seems to be needed for GTK 2.6. */ | 6072 | /* This seems to be needed for GTK 2.6. */ |
| 6154 | x_clear_area (event.xexpose.display, | 6073 | x_clear_area (event.xexpose.display, |
| 6155 | event.xexpose.window, | 6074 | event.xexpose.window, |
| 6156 | event.xexpose.x, event.xexpose.y, | 6075 | event.xexpose.x, event.xexpose.y, |
| 6157 | event.xexpose.width, event.xexpose.height, | 6076 | event.xexpose.width, event.xexpose.height); |
| 6158 | FALSE); | ||
| 6159 | #endif | 6077 | #endif |
| 6160 | if (!FRAME_VISIBLE_P (f)) | 6078 | if (!FRAME_VISIBLE_P (f)) |
| 6161 | { | 6079 | { |
| @@ -6227,7 +6145,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6227 | 6145 | ||
| 6228 | case UnmapNotify: | 6146 | case UnmapNotify: |
| 6229 | /* Redo the mouse-highlight after the tooltip has gone. */ | 6147 | /* Redo the mouse-highlight after the tooltip has gone. */ |
| 6230 | if (event.xmap.window == tip_window) | 6148 | if (event.xunmap.window == tip_window) |
| 6231 | { | 6149 | { |
| 6232 | tip_window = 0; | 6150 | tip_window = 0; |
| 6233 | redo_mouse_highlight (); | 6151 | redo_mouse_highlight (); |
| @@ -6731,18 +6649,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6731 | /* Generate SELECT_WINDOW_EVENTs when needed. | 6649 | /* Generate SELECT_WINDOW_EVENTs when needed. |
| 6732 | Don't let popup menus influence things (bug#1261). */ | 6650 | Don't let popup menus influence things (bug#1261). */ |
| 6733 | if (!NILP (Vmouse_autoselect_window) && !popup_activated ()) | 6651 | if (!NILP (Vmouse_autoselect_window) && !popup_activated ()) |
| 6734 | { | 6652 | { |
| 6735 | Lisp_Object window; | 6653 | static Lisp_Object last_mouse_window; |
| 6736 | 6654 | Lisp_Object window = window_from_coordinates | |
| 6737 | window = window_from_coordinates (f, | 6655 | (f, event.xmotion.x, event.xmotion.y, 0, 0); |
| 6738 | event.xmotion.x, event.xmotion.y, | 6656 | |
| 6739 | 0, 0); | 6657 | /* Window will be selected only when it is not selected now and |
| 6740 | 6658 | last mouse movement event was not in it. Minibuffer window | |
| 6741 | /* Window will be selected only when it is not selected now and | 6659 | will be selected only when it is active. */ |
| 6742 | last mouse movement event was not in it. Minibuffer window | 6660 | if (WINDOWP (window) |
| 6743 | will be selected only when it is active. */ | 6661 | && !EQ (window, last_mouse_window) |
| 6744 | if (WINDOWP (window) | ||
| 6745 | && !EQ (window, last_window) | ||
| 6746 | && !EQ (window, selected_window) | 6662 | && !EQ (window, selected_window) |
| 6747 | /* For click-to-focus window managers | 6663 | /* For click-to-focus window managers |
| 6748 | create event iff we don't leave the | 6664 | create event iff we don't leave the |
| @@ -6750,13 +6666,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6750 | && (focus_follows_mouse | 6666 | && (focus_follows_mouse |
| 6751 | || (EQ (XWINDOW (window)->frame, | 6667 | || (EQ (XWINDOW (window)->frame, |
| 6752 | XWINDOW (selected_window)->frame)))) | 6668 | XWINDOW (selected_window)->frame)))) |
| 6753 | { | 6669 | { |
| 6754 | inev.ie.kind = SELECT_WINDOW_EVENT; | 6670 | inev.ie.kind = SELECT_WINDOW_EVENT; |
| 6755 | inev.ie.frame_or_window = window; | 6671 | inev.ie.frame_or_window = window; |
| 6756 | } | 6672 | } |
| 6757 | 6673 | /* Remember the last window where we saw the mouse. */ | |
| 6758 | last_window=window; | 6674 | last_mouse_window = window; |
| 6759 | } | 6675 | } |
| 6760 | if (!note_mouse_movement (f, &event.xmotion)) | 6676 | if (!note_mouse_movement (f, &event.xmotion)) |
| 6761 | help_echo_string = previous_help_echo_string; | 6677 | help_echo_string = previous_help_echo_string; |
| 6762 | } | 6678 | } |
| @@ -6768,7 +6684,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6768 | event.xmotion.window); | 6684 | event.xmotion.window); |
| 6769 | 6685 | ||
| 6770 | if (bar) | 6686 | if (bar) |
| 6771 | x_scroll_bar_note_movement (bar, &event); | 6687 | x_scroll_bar_note_movement (bar, &event.xmotion); |
| 6772 | #endif /* USE_TOOLKIT_SCROLL_BARS */ | 6688 | #endif /* USE_TOOLKIT_SCROLL_BARS */ |
| 6773 | 6689 | ||
| 6774 | /* If we move outside the frame, then we're | 6690 | /* If we move outside the frame, then we're |
| @@ -7200,7 +7116,8 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 7200 | mode lines must be clipped to the whole window. */ | 7116 | mode lines must be clipped to the whole window. */ |
| 7201 | 7117 | ||
| 7202 | static void | 7118 | static void |
| 7203 | x_clip_to_row (struct window *w, struct glyph_row *row, int area, GC gc) | 7119 | x_clip_to_row (struct window *w, struct glyph_row *row, |
| 7120 | enum glyph_row_area area, GC gc) | ||
| 7204 | { | 7121 | { |
| 7205 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 7122 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 7206 | XRectangle clip_rect; | 7123 | XRectangle clip_rect; |
| @@ -7377,8 +7294,7 @@ x_define_frame_cursor (struct frame *f, Cursor cursor) | |||
| 7377 | static void | 7294 | static void |
| 7378 | x_clear_frame_area (struct frame *f, int x, int y, int width, int height) | 7295 | x_clear_frame_area (struct frame *f, int x, int y, int width, int height) |
| 7379 | { | 7296 | { |
| 7380 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 7297 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), x, y, width, height); |
| 7381 | x, y, width, height, False); | ||
| 7382 | #ifdef USE_GTK | 7298 | #ifdef USE_GTK |
| 7383 | /* Must queue a redraw, because scroll bars might have been cleared. */ | 7299 | /* Must queue a redraw, because scroll bars might have been cleared. */ |
| 7384 | if (FRAME_GTK_WIDGET (f)) | 7300 | if (FRAME_GTK_WIDGET (f)) |
| @@ -7390,7 +7306,9 @@ x_clear_frame_area (struct frame *f, int x, int y, int width, int height) | |||
| 7390 | /* RIF: Draw cursor on window W. */ | 7306 | /* RIF: Draw cursor on window W. */ |
| 7391 | 7307 | ||
| 7392 | static void | 7308 | static void |
| 7393 | x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int y, int cursor_type, int cursor_width, int on_p, int active_p) | 7309 | x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, |
| 7310 | int y, enum text_cursor_kinds cursor_type, | ||
| 7311 | int cursor_width, bool on_p, bool active_p) | ||
| 7394 | { | 7312 | { |
| 7395 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 7313 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 7396 | 7314 | ||
| @@ -7817,9 +7735,8 @@ static int | |||
| 7817 | x_error_handler (Display *display, XErrorEvent *event) | 7735 | x_error_handler (Display *display, XErrorEvent *event) |
| 7818 | { | 7736 | { |
| 7819 | #if defined USE_GTK && defined HAVE_GTK3 | 7737 | #if defined USE_GTK && defined HAVE_GTK3 |
| 7820 | if (event->error_code == BadMatch | 7738 | if ((event->error_code == BadMatch || event->error_code == BadWindow) |
| 7821 | && event->request_code == X_SetInputFocus | 7739 | && event->request_code == X_SetInputFocus) |
| 7822 | && event->minor_code == 0) | ||
| 7823 | { | 7740 | { |
| 7824 | return 0; | 7741 | return 0; |
| 7825 | } | 7742 | } |
| @@ -8090,13 +8007,10 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name) | |||
| 8090 | { | 8007 | { |
| 8091 | #ifdef HAVE_X11R6_XIM | 8008 | #ifdef HAVE_X11R6_XIM |
| 8092 | struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst); | 8009 | struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst); |
| 8093 | ptrdiff_t len; | ||
| 8094 | 8010 | ||
| 8095 | dpyinfo->xim_callback_data = xim_inst; | 8011 | dpyinfo->xim_callback_data = xim_inst; |
| 8096 | xim_inst->dpyinfo = dpyinfo; | 8012 | xim_inst->dpyinfo = dpyinfo; |
| 8097 | len = strlen (resource_name); | 8013 | xim_inst->resource_name = xstrdup (resource_name); |
| 8098 | xim_inst->resource_name = xmalloc (len + 1); | ||
| 8099 | memcpy (xim_inst->resource_name, resource_name, len + 1); | ||
| 8100 | XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb, | 8014 | XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb, |
| 8101 | resource_name, emacs_class, | 8015 | resource_name, emacs_class, |
| 8102 | xim_instantiate_callback, | 8016 | xim_instantiate_callback, |
| @@ -8202,9 +8116,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_ | |||
| 8202 | 8116 | ||
| 8203 | if (change_gravity > 0) | 8117 | if (change_gravity > 0) |
| 8204 | { | 8118 | { |
| 8205 | FRAME_X_OUTPUT (f)->left_before_move = f->left_pos; | ||
| 8206 | FRAME_X_OUTPUT (f)->top_before_move = f->top_pos; | ||
| 8207 | |||
| 8208 | f->top_pos = yoff; | 8119 | f->top_pos = yoff; |
| 8209 | f->left_pos = xoff; | 8120 | f->left_pos = xoff; |
| 8210 | f->size_hint_flags &= ~ (XNegative | YNegative); | 8121 | f->size_hint_flags &= ~ (XNegative | YNegative); |
| @@ -8703,8 +8614,8 @@ x_wait_for_event (struct frame *f, int eventtype) | |||
| 8703 | { | 8614 | { |
| 8704 | int level = interrupt_input_blocked; | 8615 | int level = interrupt_input_blocked; |
| 8705 | 8616 | ||
| 8706 | SELECT_TYPE fds; | 8617 | fd_set fds; |
| 8707 | EMACS_TIME tmo, tmo_at, time_now; | 8618 | struct timespec tmo, tmo_at, time_now; |
| 8708 | int fd = ConnectionNumber (FRAME_X_DISPLAY (f)); | 8619 | int fd = ConnectionNumber (FRAME_X_DISPLAY (f)); |
| 8709 | 8620 | ||
| 8710 | pending_event_wait.f = f; | 8621 | pending_event_wait.f = f; |
| @@ -8712,8 +8623,8 @@ x_wait_for_event (struct frame *f, int eventtype) | |||
| 8712 | 8623 | ||
| 8713 | /* Set timeout to 0.1 second. Hopefully not noticeable. | 8624 | /* Set timeout to 0.1 second. Hopefully not noticeable. |
| 8714 | Maybe it should be configurable. */ | 8625 | Maybe it should be configurable. */ |
| 8715 | tmo = make_emacs_time (0, 100 * 1000 * 1000); | 8626 | tmo = make_timespec (0, 100 * 1000 * 1000); |
| 8716 | tmo_at = add_emacs_time (current_emacs_time (), tmo); | 8627 | tmo_at = timespec_add (current_timespec (), tmo); |
| 8717 | 8628 | ||
| 8718 | while (pending_event_wait.eventtype) | 8629 | while (pending_event_wait.eventtype) |
| 8719 | { | 8630 | { |
| @@ -8726,11 +8637,11 @@ x_wait_for_event (struct frame *f, int eventtype) | |||
| 8726 | FD_ZERO (&fds); | 8637 | FD_ZERO (&fds); |
| 8727 | FD_SET (fd, &fds); | 8638 | FD_SET (fd, &fds); |
| 8728 | 8639 | ||
| 8729 | time_now = current_emacs_time (); | 8640 | time_now = current_timespec (); |
| 8730 | if (EMACS_TIME_LT (tmo_at, time_now)) | 8641 | if (timespec_cmp (tmo_at, time_now) < 0) |
| 8731 | break; | 8642 | break; |
| 8732 | 8643 | ||
| 8733 | tmo = sub_emacs_time (tmo_at, time_now); | 8644 | tmo = timespec_sub (tmo_at, time_now); |
| 8734 | if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0) | 8645 | if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0) |
| 8735 | break; /* Timeout */ | 8646 | break; /* Timeout */ |
| 8736 | } | 8647 | } |
| @@ -9466,16 +9377,8 @@ x_free_frame_resources (struct frame *f) | |||
| 9466 | dpyinfo->x_focus_event_frame = 0; | 9377 | dpyinfo->x_focus_event_frame = 0; |
| 9467 | if (f == dpyinfo->x_highlight_frame) | 9378 | if (f == dpyinfo->x_highlight_frame) |
| 9468 | dpyinfo->x_highlight_frame = 0; | 9379 | dpyinfo->x_highlight_frame = 0; |
| 9469 | |||
| 9470 | if (f == hlinfo->mouse_face_mouse_frame) | 9380 | if (f == hlinfo->mouse_face_mouse_frame) |
| 9471 | { | 9381 | reset_mouse_highlight (hlinfo); |
| 9472 | hlinfo->mouse_face_beg_row | ||
| 9473 | = hlinfo->mouse_face_beg_col = -1; | ||
| 9474 | hlinfo->mouse_face_end_row | ||
| 9475 | = hlinfo->mouse_face_end_col = -1; | ||
| 9476 | hlinfo->mouse_face_window = Qnil; | ||
| 9477 | hlinfo->mouse_face_mouse_frame = 0; | ||
| 9478 | } | ||
| 9479 | 9382 | ||
| 9480 | unblock_input (); | 9383 | unblock_input (); |
| 9481 | } | 9384 | } |
| @@ -9847,7 +9750,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 9847 | struct terminal *terminal; | 9750 | struct terminal *terminal; |
| 9848 | struct x_display_info *dpyinfo; | 9751 | struct x_display_info *dpyinfo; |
| 9849 | XrmDatabase xrdb; | 9752 | XrmDatabase xrdb; |
| 9850 | Mouse_HLInfo *hlinfo; | ||
| 9851 | ptrdiff_t lim; | 9753 | ptrdiff_t lim; |
| 9852 | 9754 | ||
| 9853 | block_input (); | 9755 | block_input (); |
| @@ -9988,8 +9890,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 9988 | /* We have definitely succeeded. Record the new connection. */ | 9890 | /* We have definitely succeeded. Record the new connection. */ |
| 9989 | 9891 | ||
| 9990 | dpyinfo = xzalloc (sizeof *dpyinfo); | 9892 | dpyinfo = xzalloc (sizeof *dpyinfo); |
| 9991 | hlinfo = &dpyinfo->mouse_highlight; | ||
| 9992 | |||
| 9993 | terminal = x_create_terminal (dpyinfo); | 9893 | terminal = x_create_terminal (dpyinfo); |
| 9994 | 9894 | ||
| 9995 | { | 9895 | { |
| @@ -10060,9 +9960,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10060 | dpyinfo->display = dpy; | 9960 | dpyinfo->display = dpy; |
| 10061 | 9961 | ||
| 10062 | /* Set the name of the terminal. */ | 9962 | /* Set the name of the terminal. */ |
| 10063 | terminal->name = xmalloc (SBYTES (display_name) + 1); | 9963 | terminal->name = xlispstrdup (display_name); |
| 10064 | memcpy (terminal->name, SSDATA (display_name), SBYTES (display_name)); | ||
| 10065 | terminal->name[SBYTES (display_name)] = 0; | ||
| 10066 | 9964 | ||
| 10067 | #if 0 | 9965 | #if 0 |
| 10068 | XSetAfterFunction (x_current_display, x_trace_wire); | 9966 | XSetAfterFunction (x_current_display, x_trace_wire); |
| @@ -10104,33 +10002,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10104 | select_visual (dpyinfo); | 10002 | select_visual (dpyinfo); |
| 10105 | dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen); | 10003 | dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen); |
| 10106 | dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen); | 10004 | dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen); |
| 10107 | dpyinfo->client_leader_window = 0; | ||
| 10108 | dpyinfo->grabbed = 0; | ||
| 10109 | dpyinfo->reference_count = 0; | ||
| 10110 | dpyinfo->icon_bitmap_id = -1; | 10005 | dpyinfo->icon_bitmap_id = -1; |
| 10111 | dpyinfo->n_fonts = 0; | ||
| 10112 | dpyinfo->bitmaps = 0; | ||
| 10113 | dpyinfo->bitmaps_size = 0; | ||
| 10114 | dpyinfo->bitmaps_last = 0; | ||
| 10115 | dpyinfo->scratch_cursor_gc = 0; | ||
| 10116 | hlinfo->mouse_face_mouse_frame = 0; | ||
| 10117 | hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; | ||
| 10118 | hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; | ||
| 10119 | hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; | ||
| 10120 | hlinfo->mouse_face_window = Qnil; | ||
| 10121 | hlinfo->mouse_face_overlay = Qnil; | ||
| 10122 | hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; | ||
| 10123 | hlinfo->mouse_face_defer = 0; | ||
| 10124 | hlinfo->mouse_face_hidden = 0; | ||
| 10125 | dpyinfo->x_focus_frame = 0; | ||
| 10126 | dpyinfo->x_focus_event_frame = 0; | ||
| 10127 | dpyinfo->x_highlight_frame = 0; | ||
| 10128 | dpyinfo->wm_type = X_WMTYPE_UNKNOWN; | 10006 | dpyinfo->wm_type = X_WMTYPE_UNKNOWN; |
| 10129 | 10007 | ||
| 10130 | /* See if we can construct pixel values from RGB values. */ | 10008 | reset_mouse_highlight (&dpyinfo->mouse_highlight); |
| 10131 | dpyinfo->red_bits = dpyinfo->blue_bits = dpyinfo->green_bits = 0; | ||
| 10132 | dpyinfo->red_offset = dpyinfo->blue_offset = dpyinfo->green_offset = 0; | ||
| 10133 | 10009 | ||
| 10010 | /* See if we can construct pixel values from RGB values. */ | ||
| 10134 | if (dpyinfo->visual->class == TrueColor) | 10011 | if (dpyinfo->visual->class == TrueColor) |
| 10135 | { | 10012 | { |
| 10136 | get_bits_and_offset (dpyinfo->visual->red_mask, | 10013 | get_bits_and_offset (dpyinfo->visual->red_mask, |
| @@ -10291,14 +10168,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10291 | } | 10168 | } |
| 10292 | 10169 | ||
| 10293 | dpyinfo->x_dnd_atoms_size = 8; | 10170 | dpyinfo->x_dnd_atoms_size = 8; |
| 10294 | dpyinfo->x_dnd_atoms_length = 0; | ||
| 10295 | dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms | 10171 | dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms |
| 10296 | * dpyinfo->x_dnd_atoms_size); | 10172 | * dpyinfo->x_dnd_atoms_size); |
| 10297 | 10173 | ||
| 10298 | dpyinfo->net_supported_atoms = NULL; | ||
| 10299 | dpyinfo->nr_net_supported_atoms = 0; | ||
| 10300 | dpyinfo->net_supported_window = 0; | ||
| 10301 | |||
| 10302 | connection = ConnectionNumber (dpyinfo->display); | 10174 | connection = ConnectionNumber (dpyinfo->display); |
| 10303 | dpyinfo->connection = connection; | 10175 | dpyinfo->connection = connection; |
| 10304 | dpyinfo->gray | 10176 | dpyinfo->gray |
| @@ -10491,7 +10363,7 @@ x_activate_timeout_atimer (void) | |||
| 10491 | block_input (); | 10363 | block_input (); |
| 10492 | if (!x_timeout_atimer_activated_flag) | 10364 | if (!x_timeout_atimer_activated_flag) |
| 10493 | { | 10365 | { |
| 10494 | EMACS_TIME interval = make_emacs_time (0, 100 * 1000 * 1000); | 10366 | struct timespec interval = make_timespec (0, 100 * 1000 * 1000); |
| 10495 | start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0); | 10367 | start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0); |
| 10496 | x_timeout_atimer_activated_flag = 1; | 10368 | x_timeout_atimer_activated_flag = 1; |
| 10497 | } | 10369 | } |
| @@ -10514,7 +10386,6 @@ static struct redisplay_interface x_redisplay_interface = | |||
| 10514 | x_after_update_window_line, | 10386 | x_after_update_window_line, |
| 10515 | x_update_window_begin, | 10387 | x_update_window_begin, |
| 10516 | x_update_window_end, | 10388 | x_update_window_end, |
| 10517 | x_cursor_to, | ||
| 10518 | x_flush, | 10389 | x_flush, |
| 10519 | #ifdef XFlush | 10390 | #ifdef XFlush |
| 10520 | x_flush, | 10391 | x_flush, |
| @@ -10627,11 +10498,11 @@ x_create_terminal (struct x_display_info *dpyinfo) | |||
| 10627 | terminal->delete_glyphs_hook = x_delete_glyphs; | 10498 | terminal->delete_glyphs_hook = x_delete_glyphs; |
| 10628 | terminal->ring_bell_hook = XTring_bell; | 10499 | terminal->ring_bell_hook = XTring_bell; |
| 10629 | terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer; | 10500 | terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer; |
| 10630 | terminal->reset_terminal_modes_hook = XTreset_terminal_modes; | 10501 | terminal->reset_terminal_modes_hook = NULL; |
| 10631 | terminal->set_terminal_modes_hook = XTset_terminal_modes; | 10502 | terminal->set_terminal_modes_hook = NULL; |
| 10632 | terminal->update_begin_hook = x_update_begin; | 10503 | terminal->update_begin_hook = x_update_begin; |
| 10633 | terminal->update_end_hook = x_update_end; | 10504 | terminal->update_end_hook = x_update_end; |
| 10634 | terminal->set_terminal_window_hook = XTset_terminal_window; | 10505 | terminal->set_terminal_window_hook = NULL; |
| 10635 | terminal->read_socket_hook = XTread_socket; | 10506 | terminal->read_socket_hook = XTread_socket; |
| 10636 | terminal->frame_up_to_date_hook = XTframe_up_to_date; | 10507 | terminal->frame_up_to_date_hook = XTframe_up_to_date; |
| 10637 | terminal->mouse_position_hook = XTmouse_position; | 10508 | terminal->mouse_position_hook = XTmouse_position; |
diff --git a/src/xterm.h b/src/xterm.h index 5324ef628e7..c579d342215 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -71,14 +71,13 @@ typedef GtkWidget *xt_or_gtk_widget; | |||
| 71 | #define USE_GTK_TOOLTIP | 71 | #define USE_GTK_TOOLTIP |
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | |||
| 75 | /* Bookkeeping to distinguish X versions. */ | ||
| 76 | |||
| 77 | |||
| 78 | #ifdef HAVE_X_I18N | 74 | #ifdef HAVE_X_I18N |
| 79 | #include <X11/Xlocale.h> | 75 | #include <X11/Xlocale.h> |
| 80 | #endif | 76 | #endif |
| 81 | 77 | ||
| 78 | #include "dispextern.h" | ||
| 79 | #include "termhooks.h" | ||
| 80 | |||
| 82 | #define BLACK_PIX_DEFAULT(f) BlackPixel (FRAME_X_DISPLAY (f), \ | 81 | #define BLACK_PIX_DEFAULT(f) BlackPixel (FRAME_X_DISPLAY (f), \ |
| 83 | XScreenNumberOfScreen (FRAME_X_SCREEN (f))) | 82 | XScreenNumberOfScreen (FRAME_X_SCREEN (f))) |
| 84 | #define WHITE_PIX_DEFAULT(f) WhitePixel (FRAME_X_DISPLAY (f), \ | 83 | #define WHITE_PIX_DEFAULT(f) WhitePixel (FRAME_X_DISPLAY (f), \ |
| @@ -407,9 +406,6 @@ extern bool x_display_ok (const char *); | |||
| 407 | 406 | ||
| 408 | extern void select_visual (struct x_display_info *); | 407 | extern void select_visual (struct x_display_info *); |
| 409 | 408 | ||
| 410 | |||
| 411 | struct font; | ||
| 412 | |||
| 413 | /* Each X frame object points to its own struct x_output object | 409 | /* Each X frame object points to its own struct x_output object |
| 414 | in the output_data.x field. The x_output structure contains | 410 | in the output_data.x field. The x_output structure contains |
| 415 | the information that is specific to X windows. */ | 411 | the information that is specific to X windows. */ |
| @@ -630,11 +626,6 @@ struct x_output | |||
| 630 | int move_offset_top; | 626 | int move_offset_top; |
| 631 | int move_offset_left; | 627 | int move_offset_left; |
| 632 | 628 | ||
| 633 | /* The frame's left/top offsets before we call XMoveWindow. See | ||
| 634 | x_check_expected_move. */ | ||
| 635 | int left_before_move; | ||
| 636 | int top_before_move; | ||
| 637 | |||
| 638 | /* Non-zero if _NET_WM_STATE_HIDDEN is set for this frame. */ | 629 | /* Non-zero if _NET_WM_STATE_HIDDEN is set for this frame. */ |
| 639 | unsigned net_wm_state_hidden_seen : 1; | 630 | unsigned net_wm_state_hidden_seen : 1; |
| 640 | }; | 631 | }; |
| @@ -810,12 +801,12 @@ struct scroll_bar | |||
| 810 | /* If the scroll bar handle is currently being dragged by the user, | 801 | /* If the scroll bar handle is currently being dragged by the user, |
| 811 | this is the number of pixels from the top of the handle to the | 802 | this is the number of pixels from the top of the handle to the |
| 812 | place where the user grabbed it. If the handle isn't currently | 803 | place where the user grabbed it. If the handle isn't currently |
| 813 | being dragged, this is Qnil. */ | 804 | being dragged, this is -1. */ |
| 814 | Lisp_Object dragging; | 805 | int dragging; |
| 815 | 806 | ||
| 816 | /* 1 if the background of the fringe that is adjacent to a scroll | 807 | /* 1 if the background of the fringe that is adjacent to a scroll |
| 817 | bar is extended to the gap between the fringe and the bar. */ | 808 | bar is extended to the gap between the fringe and the bar. */ |
| 818 | unsigned int fringe_extended_p : 1; | 809 | unsigned fringe_extended_p : 1; |
| 819 | }; | 810 | }; |
| 820 | 811 | ||
| 821 | /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ | 812 | /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ |
| @@ -917,14 +908,6 @@ struct selection_input_event | |||
| 917 | #define SELECTION_EVENT_TIME(eventp) \ | 908 | #define SELECTION_EVENT_TIME(eventp) \ |
| 918 | (((struct selection_input_event *) (eventp))->time) | 909 | (((struct selection_input_event *) (eventp))->time) |
| 919 | 910 | ||
| 920 | |||
| 921 | struct window; | ||
| 922 | struct glyph_matrix; | ||
| 923 | struct frame; | ||
| 924 | struct input_event; | ||
| 925 | struct face; | ||
| 926 | struct image; | ||
| 927 | |||
| 928 | /* From xselect.c. */ | 911 | /* From xselect.c. */ |
| 929 | 912 | ||
| 930 | void x_handle_selection_notify (XSelectionEvent *); | 913 | void x_handle_selection_notify (XSelectionEvent *); |
| @@ -966,7 +949,7 @@ extern bool x_alloc_lighter_color_for_widget (Widget, Display *, Colormap, | |||
| 966 | #endif | 949 | #endif |
| 967 | extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *); | 950 | extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *); |
| 968 | extern void x_query_color (struct frame *f, XColor *); | 951 | extern void x_query_color (struct frame *f, XColor *); |
| 969 | extern void x_clear_area (Display *, Window, int, int, int, int, int); | 952 | extern void x_clear_area (Display *, Window, int, int, int, int); |
| 970 | #if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK | 953 | #if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK |
| 971 | extern void x_mouse_leave (struct x_display_info *); | 954 | extern void x_mouse_leave (struct x_display_info *); |
| 972 | #endif | 955 | #endif |
| @@ -1076,10 +1059,6 @@ extern Lisp_Object Qx_gtk_map_stock; | |||
| 1076 | 1059 | ||
| 1077 | #define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0) | 1060 | #define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0) |
| 1078 | 1061 | ||
| 1079 | |||
| 1080 | #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0 | ||
| 1081 | #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0 | ||
| 1082 | |||
| 1083 | #define STORE_XCHAR2B(chp, b1, b2) \ | 1062 | #define STORE_XCHAR2B(chp, b1, b2) \ |
| 1084 | ((chp)->byte1 = (b1), (chp)->byte2 = (b2)) | 1063 | ((chp)->byte1 = (b1), (chp)->byte2 = (b2)) |
| 1085 | 1064 | ||
| @@ -1089,7 +1068,6 @@ extern Lisp_Object Qx_gtk_map_stock; | |||
| 1089 | #define XCHAR2B_BYTE2(chp) \ | 1068 | #define XCHAR2B_BYTE2(chp) \ |
| 1090 | ((chp)->byte2) | 1069 | ((chp)->byte2) |
| 1091 | 1070 | ||
| 1092 | |||
| 1093 | #define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \ | 1071 | #define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \ |
| 1094 | ((nr).x = (rx), \ | 1072 | ((nr).x = (rx), \ |
| 1095 | (nr).y = (ry), \ | 1073 | (nr).y = (ry), \ |