diff options
| author | Bill Wohler | 2013-02-18 10:11:43 -0800 |
|---|---|---|
| committer | Bill Wohler | 2013-02-18 10:11:43 -0800 |
| commit | 21733e4f154f8830fa568a347a0d6dbd59793c2b (patch) | |
| tree | 3170dbbcdfafeb42f6c381d6b80b251e9f31b788 /src | |
| parent | 6d14beddb06b5ae86f9dd770a1661ebd24846f28 (diff) | |
| parent | 587feed443522f738b65b57b22a31cc8a25525c5 (diff) | |
| download | emacs-21733e4f154f8830fa568a347a0d6dbd59793c2b.tar.gz emacs-21733e4f154f8830fa568a347a0d6dbd59793c2b.zip | |
Merge from trunk; up to 2013-02-18T01:30:27Z!monnier@iro.umontreal.ca.
Diffstat (limited to 'src')
199 files changed, 8174 insertions, 4063 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index e1ee81e66b5..4215ffa312b 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # Copyright (C) 1992-1998, 2000-2012 Free Software Foundation, Inc. | 1 | # Copyright (C) 1992-1998, 2000-2013 Free Software Foundation, Inc. |
| 2 | # | 2 | # |
| 3 | # This file is part of GNU Emacs. | 3 | # This file is part of GNU Emacs. |
| 4 | # | 4 | # |
| @@ -13,9 +13,7 @@ | |||
| 13 | # GNU General Public License for more details. | 13 | # GNU General Public License for more details. |
| 14 | # | 14 | # |
| 15 | # You should have received a copy of the GNU General Public License | 15 | # You should have received a copy of the GNU General Public License |
| 16 | # along with GNU Emacs; see the file COPYING. If not, write to the | 16 | # along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
| 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| 18 | # Boston, MA 02110-1301, USA. | ||
| 19 | 17 | ||
| 20 | # Force loading of symbols, enough to give us VALBITS etc. | 18 | # Force loading of symbols, enough to give us VALBITS etc. |
| 21 | set $dummy = main + 8 | 19 | set $dummy = main + 8 |
| @@ -360,7 +358,6 @@ end | |||
| 360 | 358 | ||
| 361 | define pwinx | 359 | define pwinx |
| 362 | set $w = $arg0 | 360 | set $w = $arg0 |
| 363 | xgetint $w->sequence_number | ||
| 364 | if ($w->mini_p != Qnil) | 361 | if ($w->mini_p != Qnil) |
| 365 | printf "Mini " | 362 | printf "Mini " |
| 366 | end | 363 | end |
diff --git a/src/ChangeLog b/src/ChangeLog index 222be9575b8..e945e221593 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,1749 @@ | |||
| 1 | 2013-02-17 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (x_draw_vertical_border): For a window that is neither | ||
| 4 | the leftmost nor the rightmost, redraw both the left and the right | ||
| 5 | vertical borders. (Bug#13723) | ||
| 6 | |||
| 7 | 2013-02-17 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 8 | |||
| 9 | * xml.c (init_libxml2_functions): | ||
| 10 | * sound.c (sound_warning): | ||
| 11 | * sheap.c (report_sheap_usage): | ||
| 12 | * process.c (wait_reading_process_output): | ||
| 13 | * msdos.c (XMenuActivate): | ||
| 14 | * macros.c (Fstart_kbd_macro, Fend_kbd_macro): | ||
| 15 | * keyboard.c (top_level_1): | ||
| 16 | * editfns.c (Fmessage, Fmessage_box): | ||
| 17 | * callint.c (Fcall_interactively): | ||
| 18 | * fns.c (Fyes_or_no_p): Prefer `message1' over `message'. | ||
| 19 | |||
| 20 | 2013-02-17 Jan Djärv <jan.h.d@swipnet.se> | ||
| 21 | |||
| 22 | * xterm.c (syms_of_xterm): Move scroll-bar-adjust-thumb-portion ... | ||
| 23 | * frame.c (syms_of_frame): ... to here. | ||
| 24 | |||
| 25 | 2013-02-16 Eli Zaretskii <eliz@gnu.org> | ||
| 26 | |||
| 27 | * w32.c (sys_chown): Remove unused function. | ||
| 28 | |||
| 29 | * w32term.c <input_signal_count>: Declare 'volatile' | ||
| 30 | unconditionally. (Bug#9066) | ||
| 31 | |||
| 32 | * w32.c (set_errno): Reset h_errno and don't set it to any other | ||
| 33 | value. Set errno instead. | ||
| 34 | (check_errno): Reset h_errno. | ||
| 35 | (sys_socket, socket_to_fd, sys_bind, sys_connect) | ||
| 36 | (sys_gethostname, sys_getservbyname, sys_getpeername) | ||
| 37 | (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname) | ||
| 38 | (sys_accept, sys_recvfrom, sys_sendto, fcntl, sys_read): Don't set | ||
| 39 | h_errno. | ||
| 40 | (sys_gethostbyname): Set h_errno only errors detected. | ||
| 41 | |||
| 42 | 2013-02-15 Paul Eggert <eggert@cs.ucla.edu> | ||
| 43 | |||
| 44 | * process.c (h_errno) [!HAVE_H_ERRNO]: Remove unused decl. | ||
| 45 | |||
| 46 | 2013-02-15 Eli Zaretskii <eliz@gnu.org> | ||
| 47 | |||
| 48 | * keyboard.c (read_char): Fix calculation of auto-save time out | ||
| 49 | when auto-save-timeout is less than 4. (Bug#13720) | ||
| 50 | |||
| 51 | * w32proc.c (new_child): Free up to 2 slots of dead processes at a | ||
| 52 | time. Improve diagnostics in DebPrint. (Bug#13546) | ||
| 53 | |||
| 54 | * w32.c (sys_socket, sys_bind, sys_connect, sys_gethostname) | ||
| 55 | (sys_gethostbyname, sys_getservbyname, sys_getpeername) | ||
| 56 | (sys_shutdown, sys_setsockopt, sys_listen, sys_getsockname) | ||
| 57 | (sys_accept, sys_recvfrom, sys_sendto, fcntl): In case of failure, | ||
| 58 | make sure errno is set to an appropriate value. (Bug#13546) | ||
| 59 | (socket_to_fd): Add assertion against indexing fd_info[] with a | ||
| 60 | value that is out of bounds. | ||
| 61 | (sys_accept): If fd is negative, do not set up the child_process | ||
| 62 | structure for reading. | ||
| 63 | |||
| 64 | 2013-02-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 65 | |||
| 66 | * composite.c (fill_gstring_header): Remove useless prototype. | ||
| 67 | Break long line. | ||
| 68 | * lisp.h (message_dolog, compile_pattern): Adjust prototype. | ||
| 69 | * print.c (PRINTDECLARE, print_object): | ||
| 70 | * search.c (compile_pattern, fast_looking_at, search_buffer): | ||
| 71 | (simple_search, boyer_moore, Freplace_match): | ||
| 72 | * xdisp.c (c_string_pos, number_of_chars, message_dolog): | ||
| 73 | (get_overlay_arrow_glyph_row, display_mode_element): | ||
| 74 | (decode_mode_spec_coding, message3): | ||
| 75 | * xfaces.c (face_at_string_position): Use bool for booleans. | ||
| 76 | Adjust comments. | ||
| 77 | |||
| 78 | 2013-02-15 Paul Eggert <eggert@cs.ucla.edu> | ||
| 79 | |||
| 80 | Fix AIX port (Bug#13650). | ||
| 81 | * lisp.h (XPNTR) [!USE_LSB_TAG && DATA_SEG_BITS]: | ||
| 82 | Fix bug introduced in 2012-07-27 change. DATA_SEG_BITS, if set, | ||
| 83 | was #undeffed earlier, so it cannot be used as a macro here. | ||
| 84 | Use the constant and not the macro. | ||
| 85 | |||
| 86 | 2013-02-15 Eli Zaretskii <eliz@gnu.org> | ||
| 87 | |||
| 88 | * w32proc.c (new_child): If no vacant slots are found in | ||
| 89 | child_procs[], make another pass looking for slots whose process | ||
| 90 | has exited or died. (Bug#13546) | ||
| 91 | |||
| 92 | * w32.c (sys_pipe): When failing due to file descriptors above | ||
| 93 | MAXDESC, set errno to EMFILE. | ||
| 94 | (_sys_read_ahead): Update cp->status when failing to read serial | ||
| 95 | communications input, so that the status doesn't stay at | ||
| 96 | STATUS_READ_IN_PROGRESS. (Bug#13546) | ||
| 97 | |||
| 98 | 2013-02-14 Jan Djärv <jan.h.d@swipnet.se> | ||
| 99 | |||
| 100 | * gtkutil.c (tb_size_cb): New function. | ||
| 101 | (xg_create_tool_bar): Connect size-allocate to tb_size_cb (Bug#13512). | ||
| 102 | |||
| 103 | 2013-02-14 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 104 | |||
| 105 | * keyboard.c (active_maps): Fcurrent_active_maps expects a position, not | ||
| 106 | an event. | ||
| 107 | |||
| 108 | 2013-02-13 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 109 | |||
| 110 | * keyboard.c (syms_of_keyboard): Further tweaks of docstring. | ||
| 111 | |||
| 112 | 2013-02-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 113 | |||
| 114 | * font.c (font_range): Add pos_byte argument. Adjust comment | ||
| 115 | and break long line. | ||
| 116 | * font.h (font_range): Adjust prototype. | ||
| 117 | * composite.c (autocmp_chars): Pass byte position to font_range. | ||
| 118 | Break long line. Remove useless prototype and format comment. | ||
| 119 | |||
| 120 | 2013-02-13 Glenn Morris <rgm@gnu.org> | ||
| 121 | |||
| 122 | * keyboard.c (input-decode-map, key-translation-map): Doc fixes. | ||
| 123 | |||
| 124 | 2013-02-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 125 | |||
| 126 | Improve AIX port some more (Bug#13650). | ||
| 127 | With this, it should be as good as it was in 23.3, though it's | ||
| 128 | still pretty bad: the dumped emacs does not run. See Mark Fleishman in | ||
| 129 | http://lists.gnu.org/archive/html/help-gnu-emacs/2011-04/msg00287.html | ||
| 130 | * unexaix.c (start_of_text): Remove. | ||
| 131 | (_data, _text): Declare as char[], not int, as AIX manual suggests. | ||
| 132 | (bias, lnnoptr, text_scnptr, data_scnptr, load_scnptr) | ||
| 133 | (orig_load_scnptr, orig_data_scnptr): | ||
| 134 | Now off_t, not long, since they are file offsets. | ||
| 135 | (make_hdr): Use _data, not start_of_data (). | ||
| 136 | This is the key part of the fix. | ||
| 137 | (make_hdr, unrelocate_symbols): Use off_t for file offsets. | ||
| 138 | (unrelocate_symbols): Cast pointers to intptr_t, not to ulong. | ||
| 139 | |||
| 140 | * pre-crt0.c (data_start): Initialize to 1. | ||
| 141 | This ports to compilers that optimize the external declaration | ||
| 142 | 'int x = 0;' as if it were 'int x;' to shrink the executable. | ||
| 143 | |||
| 144 | Improve AIX port (Bug#13650). | ||
| 145 | This doesn't fix the bug, but it makes progress: Emacs builds now. | ||
| 146 | * unexaix.c: Include inttypes.h, stdarg.h. | ||
| 147 | (report_error, report_error_1): Mark as _Noreturn. | ||
| 148 | (report_error): Don't report the wrong errno. | ||
| 149 | (report_error_1): Now varargs. All callers changed. | ||
| 150 | (make_hdr): Use uintptr_t, not unsigned, when converting pointers | ||
| 151 | to unsigned. Don't use ADDR_CORRECT, as it no longer exists. | ||
| 152 | (write_ptr): Use %p to print address rather than %lx and a cast | ||
| 153 | to unsigned long. Grow buffer a bit, to be safer. | ||
| 154 | |||
| 155 | 2013-02-13 Eli Zaretskii <eliz@gnu.org> | ||
| 156 | |||
| 157 | * bidi.c (bidi_resolve_neutral): After finding the next | ||
| 158 | non-neutral character, accept NEUTRAL_ON type as well, because | ||
| 159 | directional control characters, such as LRE and RLE, have their | ||
| 160 | type converted to that by bidi_resolve_weak. This avoids aborts | ||
| 161 | when LRE/RLE follows a run of neutrals. | ||
| 162 | (bidi_move_to_visually_next): Assert that return value of | ||
| 163 | bidi_peek_at_next_level is non-negative. Negative values will | ||
| 164 | cause an infloop. | ||
| 165 | |||
| 166 | 2013-02-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 167 | |||
| 168 | Minor getenv-related fixes. | ||
| 169 | * callproc.c (Fcall_process_region) [!DOS_NT]: | ||
| 170 | Avoid unnecessary duplicate call to getenv. | ||
| 171 | * callproc.c (init_callproc): | ||
| 172 | * dispnew.c (init_display): | ||
| 173 | * sysdep.c (sys_subshell): | ||
| 174 | Omit unnecessary cast of getenv or egetenv. | ||
| 175 | |||
| 176 | 2013-02-13 Juanma Barranquero <lekktu@gmail.com> | ||
| 177 | |||
| 178 | * makefile.w32-in ($(BLD)/filelock.$(O), $(BLD)/sysdep.$(O)): | ||
| 179 | Update dependencies. | ||
| 180 | |||
| 181 | 2013-02-12 Eli Zaretskii <eliz@gnu.org> | ||
| 182 | |||
| 183 | * xdisp.c (redisplay_internal): Don't set w->region_showing to the | ||
| 184 | marker's position. | ||
| 185 | (display_line): Set w->region_showing to the value of | ||
| 186 | it->region_beg_charpos, not to -1. This fixes redisplay | ||
| 187 | optimization when cursor is moved up after M->. (Bug#13623) | ||
| 188 | (Bug#13626) | ||
| 189 | (try_scrolling): Scroll text up more if point is too close to ZV | ||
| 190 | and inside the scroll margin. This makes sure point is moved | ||
| 191 | outside the scroll margin in these cases. | ||
| 192 | |||
| 193 | * window.h (struct window): region_showing can no longer be | ||
| 194 | negative. | ||
| 195 | |||
| 196 | 2013-02-11 Paul Eggert <eggert@cs.ucla.edu> | ||
| 197 | |||
| 198 | Tune by using memchr and memrchr. | ||
| 199 | * doc.c (Fsnarf_documentation): | ||
| 200 | * fileio.c (Fsubstitute_in_file_name): | ||
| 201 | * search.c (find_newline, scan_newline): | ||
| 202 | * xdisp.c (pos_visible_p, display_count_lines): | ||
| 203 | Use memchr and memrchr rather than scanning byte-by-byte. | ||
| 204 | * search.c (find_newline): Rename from scan_buffer. | ||
| 205 | Omit first arg TARGET, as it's always '\n'. All callers changed. | ||
| 206 | |||
| 207 | Clean up read_key_sequence a tiny bit more. | ||
| 208 | * keyboard.c (read_char_x_menu_prompt) [HAVE_MENUS]: | ||
| 209 | (read_key_sequence): Remove unused locals. | ||
| 210 | |||
| 211 | 2013-02-11 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 212 | |||
| 213 | Clean up read_key_sequence a bit; reread active keymaps after first event. | ||
| 214 | * keyboard.c (read_char, read_char_x_menu_prompt) | ||
| 215 | (read_char_minibuf_menu_prompt): | ||
| 216 | Replace nmaps+maps with a single `map' arg. | ||
| 217 | (follow_key): Operate on a single map. | ||
| 218 | (active_maps): New function. | ||
| 219 | (test_undefined): Also return true for nil bindings. | ||
| 220 | (read_key_sequence): Use active_maps to replace the arrays of keymaps with | ||
| 221 | a single (composed) keymap. Remember `first_event' to choose the right | ||
| 222 | set of active keymaps. Recompute the set of keymaps after receiving | ||
| 223 | the first event. Remove GOBBLE_FIRST_EVENT. | ||
| 224 | (syms_of_keyboard): Remove inhibit_local_menu_bar_menus. | ||
| 225 | * keyboard.h (read_char): Update declaration. | ||
| 226 | * lread.c (read_filtered_event): Adjust call to read_char. | ||
| 227 | |||
| 228 | 2013-02-11 Eli Zaretskii <eliz@gnu.org> | ||
| 229 | |||
| 230 | * xdisp.c (move_it_vertically_backward, move_it_by_lines): | ||
| 231 | Don't use the limitation on backwards movement when lines are truncated | ||
| 232 | in the window. (Bug#13675) | ||
| 233 | |||
| 234 | 2013-02-11 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 235 | |||
| 236 | * marker.c (set_marker_internal): If desired position is passed | ||
| 237 | as a marker, avoid call to buf_charpos_to_bytepos. | ||
| 238 | * window.c (Fset_window_point): Omit redundant type checking. | ||
| 239 | (Fset_window_start): Likewise. Format comment. | ||
| 240 | (window_scroll_pixel_based): Use set_marker_restricted_both | ||
| 241 | with character and byte positions obtained from an iterator. | ||
| 242 | (Fset_window_configuration): Use set_marker_restricted_both. | ||
| 243 | * xdisp.c (message_dolog): Likewise. | ||
| 244 | |||
| 245 | 2013-02-10 Eli Zaretskii <eliz@gnu.org> | ||
| 246 | |||
| 247 | * xdisp.c (move_it_vertically_backward, move_it_by_lines): | ||
| 248 | When text lines are longer than window's screen lines, don't move back | ||
| 249 | too far. This speeds up some redisplay operations. (Bug#13675) | ||
| 250 | |||
| 251 | 2013-02-10 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 252 | |||
| 253 | * syntax.c (scan_sexps_forward): Fix byte position calculation | ||
| 254 | Bug#13664 (a.k.a Bug#13667) introduced with 2013-02-08 change. | ||
| 255 | |||
| 256 | 2013-02-10 Paul Eggert <eggert@cs.ucla.edu> | ||
| 257 | |||
| 258 | * fileio.c (Fexpand_file_name): Omit confusing pointer comparison | ||
| 259 | that was not needed. | ||
| 260 | |||
| 261 | 2013-02-09 Paul Eggert <eggert@cs.ucla.edu> | ||
| 262 | |||
| 263 | Minor hashing refactoring. | ||
| 264 | * fns.c (SXHASH_REDUCE): Move to lisp.h. | ||
| 265 | (sxhash_float): Return EMACS_UINT, for consistency with the other | ||
| 266 | hash functions. | ||
| 267 | * lisp.h (INTMASK): Now a macro, since SXHASH_REDUCE is now a | ||
| 268 | non-static inline function and therefore can't use static vars. | ||
| 269 | (SXHASH_REDUCE): Move here from fns.c, and make it inline. | ||
| 270 | * profiler.c (hashfn_profiler): Use SXHASH_REDUCE, to be consistent | ||
| 271 | with the other hash functions. | ||
| 272 | |||
| 273 | 2013-02-09 Eli Zaretskii <eliz@gnu.org> | ||
| 274 | |||
| 275 | * callproc.c (Fcall_process_region) [WINDOWSNT]: Make sure the | ||
| 276 | XXXXXX part of the temporary file pattern is not downcased even | ||
| 277 | when w32-downcase-file-names is non-nil. (Bug#13661) | ||
| 278 | |||
| 279 | * xdisp.c (decode_mode_spec): Remove handling of %t. | ||
| 280 | |||
| 281 | * msdos.c (careadlinkatcwd): Remove. | ||
| 282 | |||
| 283 | 2013-02-08 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 284 | |||
| 285 | * lread.c (skip_dyn_bytes): New function (bug#12598). | ||
| 286 | (read1): Use it. Use getc instead of READCHAR to read bytes. | ||
| 287 | (load_each_byte): Remove. Update users. | ||
| 288 | |||
| 289 | 2013-02-08 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 290 | |||
| 291 | * search.c (scan_buffer): Calculate end byte position just once. | ||
| 292 | (scan_newline): Do not recalculate start_byte. | ||
| 293 | (search_command): Use eassert. | ||
| 294 | * syntax.c (struct lisp_parse_state): New member location_byte. | ||
| 295 | (scan_sexps_forward): Record from_byte and avoid redundant | ||
| 296 | character to byte position calculation ... | ||
| 297 | (Fparse_partial_sexp): ... here. Break too long line. | ||
| 298 | |||
| 299 | 2013-02-08 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 300 | |||
| 301 | * lisp.h (make_uninit_vector): New function. | ||
| 302 | * alloc.c (Fvector, Fmake_byte_code): | ||
| 303 | * ccl.c (Fregister_ccl_program): | ||
| 304 | * charset.c (Fdefine_charset_internal, define_charset_internal): | ||
| 305 | * coding.c (make_subsidiaries, Fdefine_coding_system_internal): | ||
| 306 | * composite.c (syms_of_composite): | ||
| 307 | * font.c (Fquery_font, Ffont_info, syms_of_font): | ||
| 308 | * fontset.c (FONT_DEF_NEW, Fset_fontset_font): | ||
| 309 | * ftfont.c (ftfont_shape_by_flt): | ||
| 310 | * indent.c (recompute_width_table): | ||
| 311 | * nsselect.m (clean_local_selection_data): | ||
| 312 | * syntax.c (init_syntax_once): | ||
| 313 | * w32unsubscribe.c (uniscribe_shape): | ||
| 314 | * window.c (Fcurrent_window_configuration): | ||
| 315 | * xfaces.c (Fx_family_fonts): | ||
| 316 | * xselect.c (selection_data_to_lisp_data): Use it. | ||
| 317 | |||
| 318 | 2013-02-07 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 319 | |||
| 320 | * coding.c (Fdefine_coding_system_internal): Use AREF where | ||
| 321 | argument is known to be a vector. | ||
| 322 | * fns.c (Flocale_info): Likewise for ASET. | ||
| 323 | * xselect.c (selection_data_to_lisp_data): Likewise for ASET. | ||
| 324 | * w32fns.c (w32_parse_hot_key): Likewise for ASIZE and AREF. | ||
| 325 | |||
| 326 | 2013-02-05 Jan Djärv <jan.h.d@swipnet.se> | ||
| 327 | |||
| 328 | * nsmenu.m (update_frame_tool_bar): Check for negative tool bar | ||
| 329 | height. | ||
| 330 | |||
| 331 | * nsterm.h (HAVE_NATIVE_FS): Define if OSX => 10.7. | ||
| 332 | (EmacsView): Add fs_is_native, fsIsNative, isFullscreen and | ||
| 333 | updateCollectionBehaviour. | ||
| 334 | |||
| 335 | * nsterm.m (NEW_STYLE_FS): Remove. | ||
| 336 | (ns_last_use_native_fullscreen): New variable. | ||
| 337 | (x_make_frame_visible): Replace NEW_STYLE_FS with isFullscreen. | ||
| 338 | (x_set_window_size): Do not take title bar and tool bar into account | ||
| 339 | if isFullscreen returns YES. | ||
| 340 | (ns_fullscreen_hook): Replace NEW_STYLE_FS with isFullscreen. | ||
| 341 | (check_native_fs): New function. | ||
| 342 | (ns_select, ns_read_socket): Call check_native_fs if HAVE_NATIVE_FS. | ||
| 343 | (ns_term_init): Remove NEW_STYLE_FS. | ||
| 344 | (updateFrameSize:, windowWillResize:toSize:): Only adjust for title bar | ||
| 345 | and tool bar if isFullscreen returns NO. | ||
| 346 | (windowDidResize:): Replace NEW_STYLE_FS with fsIsNative. | ||
| 347 | (initFrameFromEmacs:): Initialize fs_is_native. Replace NEW_STYLE_FS | ||
| 348 | with HAVE_NATIVE_FS. | ||
| 349 | (window:willUseFullScreenPresentationOptions:): New method. | ||
| 350 | (windowDidEnterFullScreen:): Replace NEW_STYLE_FS with fsIsNative. | ||
| 351 | Hide toolbar if not enabled (Bug#13444). | ||
| 352 | (windowDidExitFullScreen:): Call updateCollectionBehaviour. | ||
| 353 | Restore tool bar if enabled, hide it otherwise (Bug#13444). | ||
| 354 | (fsIsNative, isFullscreen, updateCollectionBehaviour): New methods. | ||
| 355 | (toggleFullScreen:): If fs_is_native, call toggleFullScreen on | ||
| 356 | window. Do no set FRAME_EXTERNAL_TOOL_BAR (f) to 0. | ||
| 357 | Check FRAME_EXTERNAL_TOOL_BAR (f) before restoring | ||
| 358 | FRAME_TOOLBAR_HEIGHT (f). Call updateFrameSize when going non-fs. | ||
| 359 | (syms_of_nsterm): Add ns-use-native-fullscreen. | ||
| 360 | |||
| 361 | 2013-02-04 Paul Eggert <eggert@cs.ucla.edu> | ||
| 362 | |||
| 363 | * fileio.c (Qchoose_write_coding_system): Now static. | ||
| 364 | |||
| 365 | 2013-02-04 Eli Zaretskii <eliz@gnu.org> | ||
| 366 | |||
| 367 | * xdisp.c (window_buffer_changed): region_showing can be negative, | ||
| 368 | which still means region is being displayed. | ||
| 369 | (redisplay_internal): Resurrect code that forced redisplay of the | ||
| 370 | whole window when showing region and the mark has changed. | ||
| 371 | Record the new mark position to allow redisplay optimizations. | ||
| 372 | (display_line): If it->region_beg_charpos is non-zero, set the | ||
| 373 | window's region_showing member to -1. (Bug#13623) (Bug#13626) | ||
| 374 | |||
| 375 | * window.h (struct window) <region_showing>: Declare ptrdiff_t, | ||
| 376 | not bitfield of 1 bit. | ||
| 377 | |||
| 378 | 2013-02-03 Daniel Colascione <dancol@dancol.org> | ||
| 379 | |||
| 380 | * emacs.c: Use execvp, not execv, when DAEMON_MUST_EXEC, so that | ||
| 381 | daemon mode works on cygw32 when Emacs is installed and not just | ||
| 382 | during development. | ||
| 383 | |||
| 384 | 2013-02-02 Paul Eggert <eggert@cs.ucla.edu> | ||
| 385 | |||
| 386 | Avoid file time stamp bug on MS-Windows (Bug#13149). | ||
| 387 | * fileio.c (Fwrite_region): Don't use the heuristic on empty files, | ||
| 388 | as FAT32 doesn't update time stamps when truncating them. | ||
| 389 | Also, check that a file time stamp is not a multiple of 100 ns; | ||
| 390 | this should catch all instances of the problem on MS-Windows, | ||
| 391 | as its native file system resolution is 100 ns or worse, and | ||
| 392 | checking for a non-multiple of 100 ns should impose only a small | ||
| 393 | overhead on systems with ns resolution. | ||
| 394 | |||
| 395 | 2013-02-02 Eli Zaretskii <eliz@gnu.org> | ||
| 396 | |||
| 397 | Avoid encoding file names on MS-Windows when they need to be run | ||
| 398 | through dostounix_filename. | ||
| 399 | * w32.c (normalize_filename): Accept an additional argument | ||
| 400 | MULTIBYTE; if non-zero, traverse the file name by bytes and don't | ||
| 401 | downcase it even if w32-downcase-file-names is non-nil. | ||
| 402 | (dostounix_filename): Accept an additional argument MULTIBYTE and | ||
| 403 | pass it to normalize_filename. | ||
| 404 | (emacs_root_dir): Adjust. | ||
| 405 | |||
| 406 | * msdos.h (dostounix_filename): Adjust prototype. | ||
| 407 | |||
| 408 | * w32.h (dostounix_filename): Adjust prototype. | ||
| 409 | |||
| 410 | * msdos.c (dostounix_filename): Accept an additional argument and | ||
| 411 | ignore it. | ||
| 412 | (init_environment): Adjust callers of dostounix_filename. | ||
| 413 | |||
| 414 | * fileio.c (Ffile_name_directory, file_name_as_directory) | ||
| 415 | (directory_file_name, Fexpand_file_name) | ||
| 416 | (Fsubstitute_in_file_name): [DOS_NT] Adjust call to | ||
| 417 | dostounix_filename. | ||
| 418 | [WINDOWSNT]: Downcase file names if w32-downcase-file-names is | ||
| 419 | non-nil. | ||
| 420 | (Fsubstitute_in_file_name): [DOS_NT] Don't downcase environment | ||
| 421 | variables, as egetenv is case-insensitive for DOS_NT. | ||
| 422 | |||
| 423 | * dired.c (file_name_completion): Don't call Fdirectory_file_name | ||
| 424 | with an encoded file name. | ||
| 425 | |||
| 426 | * w32proc.c (Fw32_short_file_name, Fw32_long_file_name): | ||
| 427 | Adjust calls to dostounix_filename. | ||
| 428 | |||
| 429 | * w32fns.c (Fx_file_dialog): Adjust call to dostounix_filename. | ||
| 430 | |||
| 431 | * unexw32.c (unexec): Adjust call to dostounix_filename. | ||
| 432 | |||
| 433 | * termcap.c (tgetent) [MSDOS]: Adjust call to dostounix_filename. | ||
| 434 | |||
| 435 | * emacs.c (decode_env_path) [DOS_NT]: Adjust call to | ||
| 436 | dostounix_filename. | ||
| 437 | |||
| 438 | * callproc.c (Fcall_process) [MSDOS]: Adjust call to | ||
| 439 | dostounix_filename. | ||
| 440 | |||
| 441 | * callproc.c (Fcall_process): Make sure program name in PATH and | ||
| 442 | new_argv[0] is encoded, if needed. Otherwise, un-encoded string | ||
| 443 | is passed to exec/spawnve, which fails unless the file-name | ||
| 444 | encoding is UTF-8. | ||
| 445 | |||
| 446 | * w32proc.c (sys_spawnve): Make sure escape_char is initialized, | ||
| 447 | even if w32-quote-process-args is nil. | ||
| 448 | |||
| 449 | 2013-02-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 450 | |||
| 451 | Fix timestamp bug when write-region appends nothing (Bug#13149). | ||
| 452 | * fileio.c (Fwrite_region): When neither O_EXCL nor O_TRUNC is used, | ||
| 453 | the file's time stamp doesn't change if Emacs happens to write nothing | ||
| 454 | to the file, and on a buggy file system this could cause Emacs to | ||
| 455 | incorrectly infer that the file system doesn't have the bug. | ||
| 456 | Avoid this problem by inhibiting the inference in this case. | ||
| 457 | |||
| 458 | 2013-02-01 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 459 | |||
| 460 | * window.h (struct window): Convert base_line_number, base_line_pos | ||
| 461 | and column_number_displayed members from Lisp_Object to ptrdiff_t. | ||
| 462 | Convert region_showing member from Lisp_Object to bitfield. | ||
| 463 | Remove sequence_number member. Adjust comments. | ||
| 464 | * window.c (sequence_number): Remove. | ||
| 465 | (make_window): Initialize column_number_displayed. | ||
| 466 | * print.c (print_object): Follow the printed representation of | ||
| 467 | frames and print window pointer to distinguish between windows. | ||
| 468 | (adjust_window_count): Invalidate base_line_pos. Adjust comment. | ||
| 469 | * xdisp.c (wset_base_line_number, wset_base_line_pos) | ||
| 470 | (wset_column_number_displayed, wset_region_showing): Remove. | ||
| 471 | (window_buffer_changed, mode_line_update_needed, redisplay_internal) | ||
| 472 | (try_scrolling, try_cursor_movement, redisplay_window) | ||
| 473 | (try_window_reusing_current_matrix, try_window_id, display_line) | ||
| 474 | (display_mode_lines, decode_mode_spec): Adjust users. | ||
| 475 | * .gdbinit (pwinx): Do not print sequence_number. | ||
| 476 | |||
| 477 | 2013-02-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 478 | |||
| 479 | Use fdopendir, fstatat and readlinkat, for efficiency (Bug#13539). | ||
| 480 | * conf_post.h (GNULIB_SUPPORT_ONLY_AT_FDCWD): Remove. | ||
| 481 | * dired.c: Include <fcntl.h>. | ||
| 482 | (open_directory): New function, which uses open and fdopendir | ||
| 483 | rather than opendir. DOS_NT platforms still use opendir, though. | ||
| 484 | (directory_files_internal, file_name_completion): Use it. | ||
| 485 | (file_attributes): New function, with most of the old Ffile_attributes. | ||
| 486 | (directory_files_internal, Ffile_attributes): Use it. | ||
| 487 | (file_attributes, file_name_completion_stat): First arg is now fd, | ||
| 488 | not dir name. All uses changed. Use fstatat rather than lstat + | ||
| 489 | stat. | ||
| 490 | (file_attributes): Use emacs_readlinkat rather than Ffile_symlink_p. | ||
| 491 | * fileio.c: Include <allocator.h>, <careadlinkat.h>. | ||
| 492 | (emacs_readlinkat): New function, with much of the old | ||
| 493 | Ffile_symlink_p, but with an fd argument for speed. | ||
| 494 | It uses readlinkat rather than careadlinkatcwd, so that it | ||
| 495 | need not assume the working directory. | ||
| 496 | (Ffile_symlink_p): Use it. | ||
| 497 | * filelock.c (current_lock_owner): Use emacs_readlinkat | ||
| 498 | rather than emacs_readlink. | ||
| 499 | * lisp.h (emacs_readlinkat): New decl. | ||
| 500 | (READLINK_BUFSIZE, emacs_readlink): Remove. | ||
| 501 | * sysdep.c: Do not include <allocator.h>, <careadlinkat.h>. | ||
| 502 | (emacs_norealloc_allocator, emacs_readlink): Remove. | ||
| 503 | This stuff is moved to fileio.c. | ||
| 504 | * w32.c (fstatat, readlinkat): New functions. | ||
| 505 | (careadlinkat): Don't check that fd == AT_FDCWD. | ||
| 506 | (careadlinkatcwd): Remove; no longer needed. | ||
| 507 | |||
| 508 | 2013-01-31 Glenn Morris <rgm@gnu.org> | ||
| 509 | |||
| 510 | * fileio.c (choose_write_coding_system): Make it callable from Lisp. | ||
| 511 | (Fwrite_region): Update for new choose_write_coding_system args. | ||
| 512 | Move the last piece of choose_write_coding_system here. (Bug#13522) | ||
| 513 | (syms_of_fileio): Add choose-write-coding-system. | ||
| 514 | |||
| 515 | 2013-01-30 Eli Zaretskii <eliz@gnu.org> | ||
| 516 | |||
| 517 | * w32.c (sys_open): Zero out the flags for the new file descriptor. | ||
| 518 | (sys_close): Zero out the flags for the file descriptor before | ||
| 519 | closing it. (Bug#13546) | ||
| 520 | |||
| 521 | * w32.c (parse_root, get_volume_info, readdir, read_unc_volume) | ||
| 522 | (logon_network_drive, stat_worker, symlink, chase_symlinks): | ||
| 523 | Use CharNextExA and CharPrevExA to iterate over file names encoded in | ||
| 524 | DBCS. (Bug#13553) | ||
| 525 | |||
| 526 | * w32.c (w32_get_long_filename, init_environment, readlink): | ||
| 527 | Support file names encoded in DBCS codepages. | ||
| 528 | (readlink): Use the current file-name-coding-system, not the ANSI | ||
| 529 | codepage, to decode and handle targets of symlinks. | ||
| 530 | |||
| 531 | 2013-01-28 Eli Zaretskii <eliz@gnu.org> | ||
| 532 | |||
| 533 | * w32.c (opendir): Now accepts a 'const char *'. | ||
| 534 | |||
| 535 | 2013-01-28 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 536 | |||
| 537 | Remove obsolete redisplay code. See the discussion at | ||
| 538 | http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00576.html. | ||
| 539 | * dispnew.c (preemption_period, preemption_next_check): Remove. | ||
| 540 | (Vredisplay_preemption_period): Likewise. | ||
| 541 | (update_frame, update_single_window, update_window, update_frame_1): | ||
| 542 | Adjust users. Always assume that PERIODIC_PREEMPTION_CHECKING is not | ||
| 543 | used, following the 2012-06-22 change. | ||
| 544 | |||
| 545 | 2013-01-25 Eli Zaretskii <eliz@gnu.org> | ||
| 546 | |||
| 547 | * w32notify.c (Fw32notify_add_watch): Doc fix. (Bug#13540) | ||
| 548 | |||
| 549 | 2013-01-25 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 550 | |||
| 551 | * font.c (num_fonts): Remove the leftover from old | ||
| 552 | debugging code. Adjust comment style here and there. | ||
| 553 | * insdel.c (insert_1): Remove. | ||
| 554 | * lisp.h (insert_1): Remove prototype. | ||
| 555 | * xdisp.c (message_dolog): Adjust users to call insert_1_both. | ||
| 556 | |||
| 557 | 2013-01-25 Eli Zaretskii <eliz@gnu.org> | ||
| 558 | |||
| 559 | * w32.c (max_filename_mbslen): New function. | ||
| 560 | (normalize_filename, readdir): Use it to detect locales where ANSI | ||
| 561 | encoding of file names uses a double-byte character set (DBCS). | ||
| 562 | If a DBCS encoding is used, advance by characters using | ||
| 563 | CharNextExA, instead of incrementing a 'char *' pointer. | ||
| 564 | Use _mbslwr instead of _strlwr. (Bug#13515) | ||
| 565 | |||
| 566 | * w32heap.c (allocate_heap) [!_WIN64]: Decrease the initial | ||
| 567 | request of memory reservation to 1.7GB. (Bug#13065) | ||
| 568 | |||
| 569 | 2013-01-25 Andreas Schwab <schwab@linux-m68k.org> | ||
| 570 | |||
| 571 | * coding.c (detect_coding_iso_2022): Move back mis-reordered code | ||
| 572 | at check_extra_latin label. (Bug#13505) | ||
| 573 | |||
| 574 | 2013-01-24 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 575 | |||
| 576 | * nsfont.m (ns_escape_name, ns_unescape_name, ns_registry_to_script): | ||
| 577 | Avoid redundant calls to strlen. | ||
| 578 | |||
| 579 | 2013-01-24 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 580 | |||
| 581 | Drop async_visible and async_iconified fields of struct frame. | ||
| 582 | This is possible because async input is gone; for details, see | ||
| 583 | http://lists.gnu.org/archive/html/emacs-devel/2012-12/msg00734.html. | ||
| 584 | * frame.h (struct frame): Remove async_visible and async_iconified | ||
| 585 | members, convert garbaged to unsigned bitfield. Adjust comments. | ||
| 586 | (FRAME_SAMPLE_VISIBILITY): Remove. Adjust all users. | ||
| 587 | (SET_FRAME_VISIBLE, SET_FRAME_ICONIFIED): New macros. | ||
| 588 | * frame.c, gtkutil.c, term.c, w32fns.c, window.c, xdisp.c: | ||
| 589 | Consistently use SET_FRAME_VISIBLE, SET_FRAME_ICONIFIED, | ||
| 590 | FRAME_VISIBLE_P and FRAME_ICONIFIED_P macros where appropriate. | ||
| 591 | * w32term.c: Ditto. | ||
| 592 | (w32_read_socket): Save iconified state to generate DEICONIFY_EVENT | ||
| 593 | properly. Likewise for obscured. | ||
| 594 | * xterm.c: Ditto. | ||
| 595 | (handle_one_xevent): Save visible state to generate ICONIFY_EVENT | ||
| 596 | properly. | ||
| 597 | * nsterm.m: Ditto. | ||
| 598 | (windowDidDeminiaturize): Generate DEICONIFY_EVENT. | ||
| 599 | |||
| 600 | 2013-01-24 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 601 | |||
| 602 | * insdel.c (prepare_to_modify_buffer): Revert last change as suggested | ||
| 603 | in http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00555.html. | ||
| 604 | |||
| 605 | 2013-01-23 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 606 | |||
| 607 | * xdisp.c (message2, message2_nolog): Remove functions. | ||
| 608 | (message3, message3_nolog): Extract nbytes and multibyteness directly | ||
| 609 | from the string. Change all callers. | ||
| 610 | (message3_nolog): Don't set message_enable_multibyte since set_message | ||
| 611 | will reset it anyway. | ||
| 612 | (message1, message1_nolog): Use message3. | ||
| 613 | (vmessage): Use a stack allocated buffer rather than f->message_buf. | ||
| 614 | (with_echo_area_buffer): Remove last two arguments. Update all callers. | ||
| 615 | (set_message): Drop all but the second arg, which has to be a string. | ||
| 616 | (set_message_1): Simplify now that we know that a1 is NULL and the | ||
| 617 | second arg is a string. | ||
| 618 | * frame.h (struct frame): Remove `message_buf' field. | ||
| 619 | Use glyphs_initialized_p instead. | ||
| 620 | (FRAME_MESSAGE_BUF): Remove macro. | ||
| 621 | * w16select.c (Fw16_set_clipboard_data): Prefer message3 to message2. | ||
| 622 | * lisp.h (message2, message2_nolog): Remove declarations. | ||
| 623 | (message3, message3_nolog): Update declarations. | ||
| 624 | * keyboard.c (read_char_minibuf_menu_text) | ||
| 625 | (read_char_minibuf_menu_width): Remove vars. | ||
| 626 | (read_char_minibuf_menu_prompt): Rewrite the menu's construction so as | ||
| 627 | to correctly handle multibyte strings. | ||
| 628 | * frame.c (delete_frame): Don't free message_buf any more. | ||
| 629 | * editfns.c (message_text, message_length): Remove vars. | ||
| 630 | (Fmessage_box): Don't copy the Lisp string's bytes any longer. | ||
| 631 | * fileio.c (auto_save_error): Use message3 instead of message2. | ||
| 632 | * dispnew.c (adjust_frame_message_buffer): Remove function. | ||
| 633 | |||
| 634 | 2013-01-23 Eli Zaretskii <eliz@gnu.org> | ||
| 635 | |||
| 636 | * w32term.c (w32fullscreen_hook): Account correctly for the screen | ||
| 637 | real estate used for the tool bar and the menu bar. | ||
| 638 | |||
| 639 | 2013-01-23 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 640 | |||
| 641 | * insdel.c (prepare_to_modify_buffer): Force redisplay if | ||
| 642 | hidden buffer is prepared to modification (Bug#13164). | ||
| 643 | |||
| 644 | 2013-01-22 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 645 | |||
| 646 | * window.h (struct window): Change window_end_valid member from | ||
| 647 | Lisp_Object to a bitfield. Adjust comments. | ||
| 648 | (wset_window_end_valid): Remove. | ||
| 649 | * window.c (adjust_window_count): Clear window_end_valid. | ||
| 650 | (Fwindow_end): Adjust user. Remove ancient #if 0 code. | ||
| 651 | (Fwindow_line_height, set_window_buffer, Frecenter) | ||
| 652 | (Fsplit_window_internal, Fdelete_other_windows_internal) | ||
| 653 | (Fset_window_fringes, Fset_window_scroll_bars): Adjust users. | ||
| 654 | * dispnew.c (adjust_glyph_matrix, clear_window_matrices): Likewise. | ||
| 655 | * xdisp.c (check_window_end, reconsider_clip_changes) | ||
| 656 | (redisplay_internal, mark_window_display_accurate_1, redisplay_window) | ||
| 657 | (try_window, try_window_reusing_current_matrix, note_mouse_highlight) | ||
| 658 | (find_first_unchanged_at_end_row, try_window_id): Likewise. | ||
| 659 | |||
| 660 | 2013-01-22 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 661 | |||
| 662 | * xdisp.c (mark_window_display_accurate): Simplify the loop | ||
| 663 | assuming that the only one of vchild, hchild or buffer window | ||
| 664 | slots is non-nil. Call mark_window_display_accurate_1 for | ||
| 665 | the leaf windows only. | ||
| 666 | (mark_window_display_accurate_1): Always assume leaf window. | ||
| 667 | Adjust comment. | ||
| 668 | |||
| 669 | 2013-01-22 Paul Eggert <eggert@cs.ucla.edu> | ||
| 670 | |||
| 671 | * emacs.c (Qkill_emacs_hook): Now static. | ||
| 672 | |||
| 673 | * fileio.c (Finsert_file_contents): Simplify. | ||
| 674 | Remove unnecessary assignments and tests. | ||
| 675 | |||
| 676 | 2013-01-21 Eli Zaretskii <eliz@gnu.org> | ||
| 677 | |||
| 678 | * w32.c (acl_set_file): Don't test for errors unless | ||
| 679 | set_file_security returns FALSE. Avoids spurious errors when | ||
| 680 | saving files. | ||
| 681 | |||
| 682 | 2013-01-21 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 683 | |||
| 684 | * fileio.c (Finsert_file_contents): Revert code introduced at | ||
| 685 | 2013-01-18 in favor of the simpler and generally better fix. | ||
| 686 | Save stack space by removing 'buffer' and reusing 'read_buf' | ||
| 687 | where appropriate. | ||
| 688 | |||
| 689 | 2013-01-19 Paul Eggert <eggert@cs.ucla.edu> | ||
| 690 | |||
| 691 | * lisp.h (eabs): Define unconditionally (Bug#13419). | ||
| 692 | The old "#if !defined (eabs)" was an unnecessary revenant of back | ||
| 693 | when this macro was called "abs". Document 'eabs' better. | ||
| 694 | |||
| 695 | 2013-01-19 Glenn Morris <rgm@gnu.org> | ||
| 696 | |||
| 697 | * fns.c (Frandom): Doc fix. | ||
| 698 | |||
| 699 | 2013-01-19 Eli Zaretskii <eliz@gnu.org> | ||
| 700 | |||
| 701 | * editfns.c (get_pos_property): Use SAFE_ALLOCA_LISP, to avoid | ||
| 702 | segfault when there are lots of overlays. | ||
| 703 | |||
| 704 | * buffer.c (sort_overlays): Use SAFE_NALLOCA, to avoid segfault | ||
| 705 | when there are lots of overlays. | ||
| 706 | See http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00421.html | ||
| 707 | for the details and a way to reproduce. | ||
| 708 | |||
| 709 | 2013-01-19 Paul Eggert <eggert@cs.ucla.edu> | ||
| 710 | |||
| 711 | * fileio.c: Use O_APPEND to append. | ||
| 712 | This corresponds better to the natural interpretation of "append", | ||
| 713 | and avoids the need to open the output file twice, or to invoke | ||
| 714 | lseek when APPEND is neither nil nor a number. | ||
| 715 | This relies on POSIX 1003.1-1988 or later, which is OK nowadays. | ||
| 716 | (Fwrite_region): Simplify. Use O_APPEND instead of opening the | ||
| 717 | file possibly twice, and lseeking to its end; this avoids the | ||
| 718 | need to lseek on non-regular files. Do not use O_EXCL and O_TRUNC | ||
| 719 | at the same time: the combination is never needed and apparently | ||
| 720 | it doesn't work with DOS_NT. | ||
| 721 | |||
| 722 | Fix size bug on DOS_NT introduced by CIFS workaround (Bug#13149). | ||
| 723 | * fileio.c (Fwrite_region): Use O_BINARY in checking code, too. | ||
| 724 | |||
| 725 | Allow floating-point file offsets. | ||
| 726 | Problem reported by Vitalie Spinu in | ||
| 727 | <http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00411.html>. | ||
| 728 | * fileio.c (emacs_lseek): Remove. | ||
| 729 | (file_offset): New function. | ||
| 730 | (Finsert_file_contents, Fwrite_region): Use it. | ||
| 731 | |||
| 732 | 2013-01-19 Chong Yidong <cyd@gnu.org> | ||
| 733 | |||
| 734 | * emacs.c (Fkill_emacs): Set waiting_for_input to 0 to avoid | ||
| 735 | aborting on Fsignal (Bug#13289). | ||
| 736 | |||
| 737 | 2013-01-19 Eli Zaretskii <eliz@gnu.org> | ||
| 738 | |||
| 739 | * w32.c (acl_set_file): Treat ERROR_ACCESS_DENIED from | ||
| 740 | set_file_security as failure due to insufficient privileges. | ||
| 741 | Reported by Fabrice Popineau <fabrice.popineau@supelec.fr>. | ||
| 742 | (fstat): Return owner and group like 'stat' and 'lstat' do. | ||
| 743 | |||
| 744 | 2013-01-19 Paul Eggert <eggert@cs.ucla.edu> | ||
| 745 | |||
| 746 | Work around bug in CIFS and vboxsf file systems (Bug#13149). | ||
| 747 | The bug was observed on Ubuntu operating inside a virtual machine, | ||
| 748 | editing files mounted via CIFS or vboxsf from the MS Windows 7 host. | ||
| 749 | The workaround introduces a race condition on non-buggy hosts, | ||
| 750 | but it's an unlikely race and anyway there's a nearly identical | ||
| 751 | nearby race that can't be fixed. | ||
| 752 | * fileio.c (valid_timestamp_file_system, timestamp_file_system): | ||
| 753 | New static vars. | ||
| 754 | (Fwrite_region): Test for file system time stamp bug. | ||
| 755 | (init_fileio): New function. | ||
| 756 | * lisp.h (init_fileio): Declare it. | ||
| 757 | * emacs.c (main): Call it. | ||
| 758 | |||
| 759 | * fileio.c (Finsert_file_contents): Simplify new diagnostic | ||
| 760 | and make it more consistent with other stat-failure diagnostics. | ||
| 761 | |||
| 762 | 2013-01-18 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 763 | |||
| 764 | Fix crash when inserting data from non-regular files. | ||
| 765 | See http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00406.html | ||
| 766 | for the error description produced by valgrind. | ||
| 767 | * fileio.c (read_non_regular): Rename to read_contents. | ||
| 768 | Free Lisp_Save_Value object used to pass parameters. | ||
| 769 | (read_non_regular_quit): Rename to read_contents_quit. | ||
| 770 | (Finsert_file_contents): Redesign internal file reading loop to adjust | ||
| 771 | gap and end positions after each read and so help make_gap to work | ||
| 772 | properly. Do not signal an I/O error too early and so do not leave | ||
| 773 | not yet decoded characters in a buffer, which was the reason of | ||
| 774 | redisplay crash. Use list2 to build return value. Adjust comments. | ||
| 775 | |||
| 776 | 2013-01-17 Paul Eggert <eggert@cs.ucla.edu> | ||
| 777 | |||
| 778 | Close a race when statting and reading files (Bug#13149). | ||
| 779 | * fileio.c (Finsert_file_contents): Use open+fstat, not stat+open. | ||
| 780 | This avoids a race if the file is renamed between stat and open. | ||
| 781 | This race is not the problem originally noted in Bug#13149; | ||
| 782 | see <http://bugs.gnu.org/13149#73> and later messages in the thread. | ||
| 783 | |||
| 784 | 2013-01-17 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 785 | |||
| 786 | * lisp.h (toplevel): Add comment about using Lisp_Save_Value | ||
| 787 | objects, related functions and macros. | ||
| 788 | (make_save_value): Adjust prototype. | ||
| 789 | (make_save_pointer): New prototype. | ||
| 790 | (SAFE_NALLOCA): Fix indentation. Use make_save_pointer. | ||
| 791 | (SAFE_ALLOCA_LISP): Adjust make_save_value usage. | ||
| 792 | * alloc.c (format_save_value): Rename to make_save_value. | ||
| 793 | (make_save_pointer): New function. | ||
| 794 | (record_xmalloc): Use make_save_pointer. | ||
| 795 | * dired.c, editfns.c, fileio.c, font.c, gtkutil.c, lread.c: | ||
| 796 | * nsmenu.m, nsterm.m, xfns.c, xmenu.c, xselect.c, keymap.c: | ||
| 797 | Change users of make_save_value to make_save_pointer. | ||
| 798 | Likewise for format_save_value and make_save_value. | ||
| 799 | |||
| 800 | 2013-01-17 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 801 | |||
| 802 | * buffer.h (NARROWED, BUF_NARROWED): Drop unused macros. | ||
| 803 | (DECODE_POSITION, BUFFER_CHECK_INDIRECTION): Fix indentation. | ||
| 804 | * buffer.c (toplevel, syms_of_buffer): Drop old commented-out | ||
| 805 | debugging stubs. | ||
| 806 | |||
| 807 | 2013-01-15 Paul Eggert <eggert@cs.ucla.edu> | ||
| 808 | |||
| 809 | * alloc.c (free_save_value): Now static. | ||
| 810 | |||
| 811 | 2013-01-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 812 | |||
| 813 | * keymap.c (map_keymap_internal): Use format_save_value. | ||
| 814 | (map_keymap_char_table_item): Adjust accordingly. | ||
| 815 | * fileio.c (non_regular_fd, non_regular_inserted) | ||
| 816 | (non_regular_nbytes): Remove. | ||
| 817 | (Finsert_file_contents): Convert trytry to ptrdiff_t. | ||
| 818 | Use format_save_value to pass parameters to read_non_regular. | ||
| 819 | (read_non_regular): Use XSAVE_ macros to extract parameters. | ||
| 820 | Adjust comment. | ||
| 821 | * xmenu.c (xmenu_show) [!USE_X_TOOLKIT && !USE_GTK]: Use | ||
| 822 | format_save_value. | ||
| 823 | (pop_down_menu) [!USE_X_TOOLKIT && !USE_GTK]: Adjust user. | ||
| 824 | |||
| 825 | 2013-01-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 826 | |||
| 827 | * lisp.h (XSAVE_POINTER, XSAVE_INTEGER): Change to allow | ||
| 828 | extraction from any Lisp_Save_Value slot. Add type checking. | ||
| 829 | * alloc.c, dired.c, editfns.c, fileio.c, ftfont.c, gtkutil.c: | ||
| 830 | * keymap.c, lread.c, nsterm.h, nsmenu.c, xfns.c, xmenu.c: | ||
| 831 | * xselect.c: All users changed. | ||
| 832 | |||
| 833 | 2013-01-15 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 834 | |||
| 835 | Some convenient bits to deal with Lisp_Save_Values. | ||
| 836 | * lisp.h (XSAVE_OBJECT): New macro to extract saved objects. | ||
| 837 | (allocate_misc): Remove prototype. | ||
| 838 | (format_save_value): New prototype. | ||
| 839 | * alloc.c (allocate_misc): Revert back to static. | ||
| 840 | (format_save_value): New function to build Lisp_Save_Value | ||
| 841 | object with the specified internal structure. | ||
| 842 | (make_save_value): Reimplement using format_save_value. | ||
| 843 | * editfns.c (save_excursion_save): Use format_save_value. | ||
| 844 | (save_excursion_restore): Use XSAVE_OBJECT. | ||
| 845 | |||
| 846 | 2013-01-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 847 | |||
| 848 | Avoid needless casts with XSAVE_POINTER. | ||
| 849 | * alloc.c (mark_object) [GC_MARK_STACK]: | ||
| 850 | * dired.c (directory_files_internal_unwind): | ||
| 851 | * fileio.c (do_auto_save_unwind): | ||
| 852 | * gtkutil.c (pop_down_dialog): | ||
| 853 | * keymap.c (map_keymap_char_table_item): | ||
| 854 | * lread.c (load_unwind): | ||
| 855 | * nsmenu.m (pop_down_menu): | ||
| 856 | * print.c (print_object) [GC_MARK_STACK]: | ||
| 857 | * xfns.c (clean_up_file_dialog): | ||
| 858 | * xmenu.c (cleanup_widget_value_tree): | ||
| 859 | Omit casts between XSAVE_POINTER and a pointer type. | ||
| 860 | |||
| 861 | 2013-01-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 862 | |||
| 863 | Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE. | ||
| 864 | * eval.c (eval_sub): Protect `form' from being GCed before its | ||
| 865 | car and cdr becomes protected with the backtrace entry. | ||
| 866 | |||
| 867 | 2013-01-14 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 868 | |||
| 869 | Make Lisp_Save_Value more versatile storage for up to four objects. | ||
| 870 | * lisp.h (toplevel): Enumeration to describe types of saved objects. | ||
| 871 | (struct Lisp_Save_Value): New layout. Adjust comments. | ||
| 872 | (XSAVE_POINTER): New macro. | ||
| 873 | (XSAVE_INTEGER): Likewise. | ||
| 874 | (allocate_misc): Add prototype. | ||
| 875 | (free_misc): Likewise. | ||
| 876 | * alloc.c (allocate_misc): Now global. | ||
| 877 | (free_misc): Likewise. Adjust comment. | ||
| 878 | (make_save_value): Use new Lisp_Save_Value layout. Adjust comment. | ||
| 879 | (free_save_value): Likewise. | ||
| 880 | (mark_object): Likewise. | ||
| 881 | * editfns.c (save_excursion_save): Pack everything within | ||
| 882 | Lisp_Save_Value and so avoid xmalloc. | ||
| 883 | (save_excursion_restore): Adjust to match new layout. Use free_misc | ||
| 884 | because we do not allocate extra memory any more. Add eassert. | ||
| 885 | * print.c (print_object): New code to print Lisp_Save_Value. Do not | ||
| 886 | rely on valid_lisp_object_p if !GC_MARK_STACK. Adjust comments. | ||
| 887 | * dired.c, fileio.c, font.c, ftfont.c, gtkutil.c, keymap.c, | ||
| 888 | * lread.c, nsmenu.m, nsterm.h, xfns.c, xmenu.c, xselect.c: | ||
| 889 | Use XSAVE_POINTER and XSAVE_INTEGER where appropriate. | ||
| 890 | |||
| 891 | 2013-01-13 Jan Djärv <jan.h.d@swipnet.se> | ||
| 892 | |||
| 893 | * nsfont.m (LCD_SMOOTHING_MARGIN): New define. | ||
| 894 | (nsfont_draw): Remove disabling of LCD smoothing. | ||
| 895 | (ns_glyph_metrics): Add LCD_SMOOTHING_MARGIN to bearings to fix | ||
| 896 | Bug#11484 with LCD smoothing on. | ||
| 897 | |||
| 898 | 2013-01-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 899 | |||
| 900 | Fix SIGDANGER handlers, for AIX (Bug#13408). | ||
| 901 | * sysdep.c.c (handle_danger_signal, deliver_danger_signal) [SIGDANGER]: | ||
| 902 | Move handlers here from emacs.c; they were out of place. | ||
| 903 | |||
| 904 | 2013-01-11 Jan Djärv <jan.h.d@swipnet.se> | ||
| 905 | |||
| 906 | * xterm.c (syms_of_xterm): Adjust documentation for | ||
| 907 | scroll-bar-adjust-thumb-portion. | ||
| 908 | |||
| 909 | 2012-12-31 Adam Sjøgren <asjo@koldfront.dk> (tiny change) | ||
| 910 | |||
| 911 | * xterm.c (scroll-bar-adjust-thumb-portion): New variable to | ||
| 912 | determine whether scroll bar thumb size should be adjusted or | ||
| 913 | not. Use variable for MOTIF. | ||
| 914 | |||
| 915 | * gtkutil.c (scroll-bar-adjust-thumb-portion): Use variable for | ||
| 916 | GTK. | ||
| 917 | |||
| 918 | 2013-01-13 Jan Djärv <jan.h.d@swipnet.se> | ||
| 919 | |||
| 920 | * nsterm.m (keyDown:): Set processingCompose to NO if an emacs key | ||
| 921 | event is generated. | ||
| 922 | (doCommandBySelector:): Set processingCompose to NO. | ||
| 923 | |||
| 924 | * nsfont.m (ns_findfonts): Add block/unblock_input calls. | ||
| 925 | Remove check for fkeys count > zero, block/unblock fixes the real bug. | ||
| 926 | (nsfont_list_family): Add block/unblock_input calls. | ||
| 927 | (nsfont_open): Move block_input earlier. Add unblock_input before early | ||
| 928 | return. | ||
| 929 | (nsfont_draw): Add block/unblock_input calls. | ||
| 930 | |||
| 931 | 2013-01-12 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 932 | |||
| 933 | * indent.c (Fvertical_motion): Remove now-incorrect GCPROs | ||
| 934 | for old_charpos and old_bytepos. | ||
| 935 | |||
| 936 | 2013-01-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 937 | |||
| 938 | Fix bug with set-time-zone-rule and LOCALTIME_CACHE (Bug#13415). | ||
| 939 | * editfns.c (set_time_zone_rule) [LOCALTIME_CACHE]: | ||
| 940 | Clear tzvalbuf_in_environ if this workaround is in effect. | ||
| 941 | Problem and fix reported by Kazuhiro Ito. | ||
| 942 | |||
| 943 | 2013-01-11 Aaron S. Hawley <Aaron.Hawley@vtinfo.com> | ||
| 944 | |||
| 945 | * insdel.c (Fcombine_after_change_execute, syms_of_insdel): | ||
| 946 | Fix ambiguous doc string cross-reference(s). | ||
| 947 | |||
| 948 | * keyboard.c (Fcommand_execute, syms_of_keyboard): Fix ambiguous | ||
| 949 | doc string cross-reference(s). | ||
| 950 | |||
| 951 | * window.c (Fwindow_point, syms_of_window): Fix ambiguous doc | ||
| 952 | string cross-reference(s). | ||
| 953 | |||
| 954 | 2013-01-11 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 955 | |||
| 956 | Avoid unnecessary byte position calculation for the gap movement. | ||
| 957 | Since all users of move_gap do CHAR_TO_BYTE for other purposes | ||
| 958 | anyway, all of them should use move_gap_both instead. | ||
| 959 | * lisp.h (move_gap): Remove prototype. | ||
| 960 | * insdel.c (move_gap): Remove. | ||
| 961 | (move_gap_both): Add eassert. | ||
| 962 | * editfns.c (Ftranspose_regions): Tweak to use move_gap_both. | ||
| 963 | * xml.c (parse_region): Likewise. | ||
| 964 | |||
| 965 | 2013-01-11 Paul Eggert <eggert@cs.ucla.edu> | ||
| 966 | |||
| 967 | emacsclient -t should not suspend Emacs server (Bug#13387) | ||
| 968 | * lisp.h, sysdep.c (block_tty_out_signal, unblock_tty_out_signal): | ||
| 969 | New functions. | ||
| 970 | * term.c (init_tty): Use them instead of rolling our own code. | ||
| 971 | * sysdep.c (tcsetpgrp_without_stopping): Likewise. Here, this | ||
| 972 | switches from 'signal' to 'pthread_sigmask', which is safer in | ||
| 973 | multithreaded applications. | ||
| 974 | * term.c (Fresume_tty): Don't bother dissociating if O_IGNORE_CTTY, | ||
| 975 | which has already arranged for that. | ||
| 976 | (dissociate_if_controlling_tty): If setsid fails, fall back on TIOCNOTTY. | ||
| 977 | This is the main part of the bug fix. | ||
| 978 | |||
| 979 | 2013-01-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> (tiny change) | ||
| 980 | |||
| 981 | * gtkutil.c (xg_initialize): Add ifdef HAVE_FREETYPE around | ||
| 982 | x_last_font_name (Bug#13403). | ||
| 983 | |||
| 984 | 2013-01-10 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 985 | |||
| 986 | Omit buffer_slot_type_mismatch and use generic predicates to enforce | ||
| 987 | the type of per-buffer values where appropriate. | ||
| 988 | * lisp.h (struct Lisp_Buffer_Objfwd): Rename slottype member to | ||
| 989 | predicate, which is how it's really used now. Adjust comment. | ||
| 990 | * buffer.h (buffer_slot_type_mismatch): Remove prototype. | ||
| 991 | * buffer.c (buffer_slot_type_mismatch): Remove. | ||
| 992 | (DEFVAR_PER_BUFFER, defvar_per_buffer): Rename type argument to | ||
| 993 | predicate. Adjust comment. | ||
| 994 | (syms_of_buffer): Use Qsymbolp for major-mode. Use Qintegerp for | ||
| 995 | fill-column, left-margin, tab-width, buffer-saved-size, | ||
| 996 | left-margin-width, right-margin-width, left-fringe-width, | ||
| 997 | right-fringe-width, scroll-bar-width and buffer-display-count. | ||
| 998 | Use Qstringp for default-directory, buffer-file-name, | ||
| 999 | buffer-file-truename and buffer-auto-save-file-name. Use Qfloatp for | ||
| 1000 | scroll-up-aggressively and scroll-down-aggressively. Use Qnumberp for | ||
| 1001 | line-spacing. | ||
| 1002 | * data.c (store_symval_forwarding): Adjust to call the predicate. | ||
| 1003 | |||
| 1004 | 2013-01-09 Juanma Barranquero <lekktu@gmail.com> | ||
| 1005 | |||
| 1006 | * w32.c (get_name_and_id, acl_set_file): | ||
| 1007 | * w32term.c (w32fullscreen_hook): Remove unused local variables. | ||
| 1008 | |||
| 1009 | 2013-01-09 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1010 | |||
| 1011 | * lisp.h (make_gap_1): New prototype. | ||
| 1012 | * buffer.h (GAP_BYTES_DFL, GAP_BYTES_MIN): New macros for the special | ||
| 1013 | gap size values. | ||
| 1014 | * editfns.c (Fbuffer_size): Rename from Fbufsize to fit the common | ||
| 1015 | naming convention. | ||
| 1016 | (syms_of_editfns): Adjust defsubr. Drop commented-out obsolete code. | ||
| 1017 | * insdel.c (make_gap_larger): Use GAP_BYTES_DFL. Adjust comment. | ||
| 1018 | (make_gap_smaller): Use GAP_BYTES_MIN. Adjust comment. | ||
| 1019 | (make_gap_1): New function to adjust the gap of any buffer. | ||
| 1020 | * coding.c (coding_alloc_by_making_gap): Use it. | ||
| 1021 | * buffer.c (compact_buffer): Likewise. Use BUF_Z_BYTE, BUF_GAP_SIZE, | ||
| 1022 | GAP_BYTES_DFL and GAP_BYTES_MIN. Adjust comment. | ||
| 1023 | |||
| 1024 | 2013-01-08 Juri Linkov <juri@jurta.org> | ||
| 1025 | |||
| 1026 | * xfaces.c (tty_supports_face_attributes_p): Return 0 for the case | ||
| 1027 | of (supports :underline (:style wave)). (Bug#13000) | ||
| 1028 | |||
| 1029 | 2013-01-08 Aaron S. Hawley <aaron.s.hawley@gmail.com> | ||
| 1030 | |||
| 1031 | * undo.c (Fprimitive_undo): Move to simple.el. | ||
| 1032 | (syms_of_undo): Remove declarations for Sprimitive_undo. | ||
| 1033 | |||
| 1034 | 2013-01-08 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 1035 | |||
| 1036 | * keyboard.c (echo_add_key): Rename from echo_add_char. | ||
| 1037 | |||
| 1038 | 2013-01-06 Chong Yidong <cyd@gnu.org> | ||
| 1039 | |||
| 1040 | * keyboard.c (echo_add_char): New function, factored out from | ||
| 1041 | echo_char. Don't add a space if the previous echo string was | ||
| 1042 | empty (Bug#13255). | ||
| 1043 | (echo_char): Use it. | ||
| 1044 | (read_key_sequence): When echoing mock input, ensure that the | ||
| 1045 | trailing dash is properly added. | ||
| 1046 | |||
| 1047 | 2013-01-05 Eli Zaretskii <eliz@gnu.org> | ||
| 1048 | |||
| 1049 | * xdisp.c (dump_glyph): Align glyph data better. Use "pD" instead | ||
| 1050 | of a non-portable "t" to print ptrdiff_t values. Allow up to 9 | ||
| 1051 | digits for buffer positions, before misalignment starts. | ||
| 1052 | Display "0" for integer "object" field. | ||
| 1053 | (dump_glyph_row): Adapt the header line to changes in dump_glyph. | ||
| 1054 | Display the newline glyph more unambiguously. | ||
| 1055 | |||
| 1056 | 2013-01-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 1057 | |||
| 1058 | * nsterm.m (ns_draw_underwave): | ||
| 1059 | * w32term.c (w32_draw_underwave): | ||
| 1060 | * xterm.c (x_draw_underwave): Make underwave look more triangular | ||
| 1061 | and also degrade gracefully for small fonts. (Bug#13000) | ||
| 1062 | |||
| 1063 | * nsterm.m (ns_draw_text_decoration): | ||
| 1064 | * w32term.c (x_draw_glyph_string): | ||
| 1065 | * xterm.c (x_draw_glyph_string): Don't use previous underline | ||
| 1066 | thickness and position if previous underline type is underwave. | ||
| 1067 | |||
| 1068 | 2013-01-04 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 1069 | |||
| 1070 | * fileio.c (Ffile_acl): Undocument return format. | ||
| 1071 | |||
| 1072 | 2013-01-02 Glenn Morris <rgm@gnu.org> | ||
| 1073 | |||
| 1074 | * keymap.c (Fkey_description): Doc fix. (Bug#13323) | ||
| 1075 | |||
| 1076 | 2013-01-02 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1077 | |||
| 1078 | Simplify via eabs. | ||
| 1079 | * dired.c (file_name_completion): | ||
| 1080 | * doc.c (get_doc_string): | ||
| 1081 | * floatfns.c (round2): | ||
| 1082 | * font.c (font_score, font_delete_unmatched): | ||
| 1083 | * fringe.c (compute_fringe_widths): | ||
| 1084 | * lread.c (read_list): | ||
| 1085 | * minibuf.c (Ftry_completion): | ||
| 1086 | * term.c (tty_ins_del_lines): | ||
| 1087 | * xterm.c (x_draw_image_foreground, x_draw_image_foreground_1): | ||
| 1088 | Use eabs (x) rather than open-coding it as (x < 0 ? -x : x). | ||
| 1089 | |||
| 1090 | 2012-12-31 Eli Zaretskii <eliz@gnu.org> | ||
| 1091 | |||
| 1092 | * w32.c (unsetenv): Set up the string passed to _putenv | ||
| 1093 | correctly. | ||
| 1094 | See http://lists.gnu.org/archive/html/emacs-devel/2012-12/msg00863.html | ||
| 1095 | for the bug this caused. | ||
| 1096 | |||
| 1097 | 2012-12-30 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1098 | |||
| 1099 | * coding.c (Qmac): Now static. | ||
| 1100 | |||
| 1101 | 2012-12-30 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1102 | |||
| 1103 | * gtkutil.c (TOOLBAR_TOP_WIDGET): New macro. | ||
| 1104 | (xg_pack_tool_bar): Use TOOLBAR_TOP_WIDGET, condition out use of | ||
| 1105 | handlebox_widget. Set toolbar_in_hbox to false/true, set | ||
| 1106 | toolbar_is_packed to true. | ||
| 1107 | (xg_update_tool_bar_sizes): Use widget returned by TOOLBAR_TOP_WIDGET. | ||
| 1108 | (update_frame_tool_bar): Check toolbar_is_packed for packing. | ||
| 1109 | Show all on TOOLBAR_TOP_WIDGET. | ||
| 1110 | (free_frame_tool_bar): Check toolbar_is_packed. Use widget returned | ||
| 1111 | by TOOLBAR_TOP_WIDGET. | ||
| 1112 | (xg_change_toolbar_position): Use widget returned by TOOLBAR_TOP_WIDGET. | ||
| 1113 | Check toolbar_is_packed. | ||
| 1114 | (xg_have_tear_offs, tearoff_remove, tearoff_activate): Condition on | ||
| 1115 | HAVE_GTK_TEAROFF_MENU_ITEM_NEW. | ||
| 1116 | (xg_have_tear_offs): When ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW, return | ||
| 1117 | false. | ||
| 1118 | (create_menus): Create tearoff only if HAVE_GTK_TEAROFF_MENU_ITEM_NEW. | ||
| 1119 | (xg_update_menubar): Update title only if | ||
| 1120 | HAVE_GTK_TEAROFF_MENU_ITEM_NEW. | ||
| 1121 | (xg_update_submenu): Skip tearoff only if | ||
| 1122 | HAVE_GTK_TEAROFF_MENU_ITEM_NEW. | ||
| 1123 | (xg_initialize): Initialize xg_detached_menus only if | ||
| 1124 | HAVE_GTK_TEAROFF_MENU_ITEM_NEW. | ||
| 1125 | |||
| 1126 | * xterm.h (struct x_output): Surround handlebox_widget with | ||
| 1127 | #ifdef HAVE_GTK_HANDLE_BOX_NEW. toolbar_is_packed is new, | ||
| 1128 | toolbar_in_hbox is bool. | ||
| 1129 | |||
| 1130 | 2012-12-30 Andreas Schwab <schwab@linux-m68k.org> | ||
| 1131 | |||
| 1132 | * src/Makefile.in (TEMACS_LDFLAGS2): Remove. | ||
| 1133 | (LIBS_GNUSTEP): Define. | ||
| 1134 | (LIBES): Add $(LIBS_GNUSTEP). | ||
| 1135 | (temacs$(EXEEXT)): Use $(LDFLAGS) instead of $(TEMACS_LDFLAGS2). | ||
| 1136 | |||
| 1137 | 2012-12-30 Eli Zaretskii <eliz@gnu.org> | ||
| 1138 | |||
| 1139 | * xdisp.c (set_cursor_from_row): Don't confuse a truncation or | ||
| 1140 | continuation glyph on a TTY with an indication of an empty line. | ||
| 1141 | (Bug#13277) | ||
| 1142 | |||
| 1143 | 2012-12-29 Eli Zaretskii <eliz@gnu.org> | ||
| 1144 | |||
| 1145 | * fileio.c (Fset_file_selinux_context, Fset_file_acl): Return t if | ||
| 1146 | file's SELinux context or ACLs successfully set, nil otherwise. | ||
| 1147 | (Bug#13298) | ||
| 1148 | (Fcopy_file) [WINDOWSNT]: Improve diagnostics when CopyFile fails. | ||
| 1149 | |||
| 1150 | * w32proc.c (reader_thread): Avoid passing NULL handles to | ||
| 1151 | SetEvent and WaitForSingleObject. | ||
| 1152 | |||
| 1153 | 2012-12-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1154 | |||
| 1155 | Port EXTERNALLY_VISIBLE to Clang 3.2. | ||
| 1156 | * conf_post.h (__has_attribute): New macro. | ||
| 1157 | (EXTERNALLY_VISIBLE): Use it. This ports to Clang 3.2. | ||
| 1158 | |||
| 1159 | 2012-12-27 Glenn Morris <rgm@gnu.org> | ||
| 1160 | |||
| 1161 | * cygw32.c (Fcygwin_convert_file_name_to_windows) | ||
| 1162 | (Fcygwin_convert_file_name_from_windows): Doc fixes. | ||
| 1163 | |||
| 1164 | 2012-12-27 Eli Zaretskii <eliz@gnu.org> | ||
| 1165 | |||
| 1166 | * fileio.c (file_name_as_directory, directory_file_name): | ||
| 1167 | Accept an additional argument MULTIBYTE to indicate whether the input C | ||
| 1168 | came from a multibyte or a unibyte Lisp string; all callers | ||
| 1169 | adjusted. Don't assume the input string is always multibyte. | ||
| 1170 | (Bug#13262) | ||
| 1171 | (Ffile_name_directory) [DOS_NT]: Handle unibyte strings correctly: | ||
| 1172 | don't ENCODE_FILE them, and return a unibyte string if the input | ||
| 1173 | was unibyte. | ||
| 1174 | (Fexpand_file_name): Don't mix unibyte with multibyte strings, and | ||
| 1175 | don't assume the input strings will always be multibyte. If the | ||
| 1176 | input strings are multibyte, decode strings obtained from C | ||
| 1177 | library functions. | ||
| 1178 | |||
| 1179 | 2012-12-26 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1180 | |||
| 1181 | * lisp.h (toplevel): Add two notices to the comment about | ||
| 1182 | defining a new Lisp data type. | ||
| 1183 | * print.c (print_object): If Lisp_Save_Value object's pointer | ||
| 1184 | is the address of a memory area containing Lisp_Objects, try | ||
| 1185 | to print them. | ||
| 1186 | * alloc.c (valid_lisp_object_p): Adjust comment. | ||
| 1187 | |||
| 1188 | 2012-12-26 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1189 | |||
| 1190 | * keyboard.c (record_asynch_buffer_change): Initialize an event | ||
| 1191 | only if it's really needed. | ||
| 1192 | * frame.h (enum output_method): Remove output_mac member since | ||
| 1193 | it's a leftover from the deleted code. | ||
| 1194 | * frame.c (Fframep): Adjust user here ... | ||
| 1195 | * terminal.c (Fterminal_live_p): ... and here. | ||
| 1196 | * coding.c (Qmac): Now here because it's only used to denote | ||
| 1197 | end-of-line encoding type. | ||
| 1198 | (syms_of_coding): DEFSYM it. | ||
| 1199 | * frame.h (Qmac): Remove duplicated declaration. | ||
| 1200 | |||
| 1201 | 2012-12-26 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1202 | |||
| 1203 | * window.c (select_window_1): Now static, since it's used only here. | ||
| 1204 | |||
| 1205 | 2012-12-25 Eli Zaretskii <eliz@gnu.org> | ||
| 1206 | |||
| 1207 | * window.c (window_body_cols): Subtract display margins from the | ||
| 1208 | window body width on TTYs as well. See | ||
| 1209 | http://lists.gnu.org/archive/html/help-gnu-emacs/2012-12/msg00317.html | ||
| 1210 | for the original report. | ||
| 1211 | |||
| 1212 | 2012-12-25 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1213 | |||
| 1214 | * xdisp.c (redisplay_window): Remove inner local variable | ||
| 1215 | because the outer shadowed one has the same meaning. | ||
| 1216 | * xterm.h (struct x_output): Remove toolbar_detached member since it's | ||
| 1217 | set but never used. | ||
| 1218 | * gtkutil.c (xg_tool_bar_detach_callback, xg_tool_bar_attach_callback) | ||
| 1219 | (xg_create_tool_bar): Adjust users. | ||
| 1220 | |||
| 1221 | 2012-12-24 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1222 | |||
| 1223 | * buffer.h (BUF_COMPACT): New macro to follow the common style. | ||
| 1224 | * buffer.c (Fget_buffer_create): Use it to set compact field of | ||
| 1225 | struct buffer_text to avoid accessing an uninitialized value | ||
| 1226 | when compact_buffer is called for the first time. | ||
| 1227 | (compact_buffer): Use convenient BUF_COMPACT and BUF_MODIFF. | ||
| 1228 | (Fset_buffer_modified_p): Use buffer_window_count to check | ||
| 1229 | whether the buffer is displayed in some window. | ||
| 1230 | * xdisp.c (message_dolog): Likewise. | ||
| 1231 | |||
| 1232 | 2012-12-23 Eli Zaretskii <eliz@gnu.org> | ||
| 1233 | |||
| 1234 | * w32.c (acl_set_file): If setting the file security descriptor | ||
| 1235 | fails, and the new DACL is identical to the existing one, silently | ||
| 1236 | return success. This fixes problems for users backing up their | ||
| 1237 | own files without having the necessary privileges for setting | ||
| 1238 | security descriptors. | ||
| 1239 | |||
| 1240 | * w32proc.c (reader_thread): Do not index fd_info[] with negative | ||
| 1241 | values. | ||
| 1242 | (reader_thread): Exit when cp->status becomes STATUS_READ_ERROR | ||
| 1243 | after WaitForSingleObject returns normally. This expedites reader | ||
| 1244 | thread shutdown when delete_child triggers it. | ||
| 1245 | (reap_subprocess): More accurate commentary for why we call | ||
| 1246 | delete_child only when cp->fd is negative. | ||
| 1247 | |||
| 1248 | * w32.c (sys_close): Do not call delete_child on a subprocess | ||
| 1249 | whose handle is not yet closed. Instead, set its file descriptor | ||
| 1250 | to a negative value, so that reap_subprocess will call | ||
| 1251 | delete_child on that subprocess when its SIGCHLD arrives. | ||
| 1252 | This avoids closing handles used for communications between sys_select | ||
| 1253 | and reader_thread, which doesn't give sys_select a chance to | ||
| 1254 | notice that the process exited and invoke the SIGCHLD handler for | ||
| 1255 | it. | ||
| 1256 | |||
| 1257 | 2012-12-23 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1258 | |||
| 1259 | * nsfns.m (Fns_do_applescript): Run event loop until script has | ||
| 1260 | been executed (Bug#12969). | ||
| 1261 | (ns_run_ascript): Chech as_script for nil, set to nil after | ||
| 1262 | executing script. | ||
| 1263 | |||
| 1264 | 2012-12-22 Martin Rudalics <rudalics@gmx.at> | ||
| 1265 | |||
| 1266 | * window.c (Fselect_window): Reword doc-string (Bug#13248). | ||
| 1267 | |||
| 1268 | 2012-12-22 Eli Zaretskii <eliz@gnu.org> | ||
| 1269 | |||
| 1270 | * w32term.c (w32fullscreen_hook): New function. | ||
| 1271 | (w32_create_terminal): Plug it into the terminal's fullscreen_hook. | ||
| 1272 | |||
| 1273 | 2012-12-21 Eli Zaretskii <eliz@gnu.org> | ||
| 1274 | |||
| 1275 | * fileio.c (Finsert_file_contents): Doc fix. | ||
| 1276 | |||
| 1277 | * w32proc.c (new_child, delete_child, find_child_pid): For a | ||
| 1278 | subprocess, consider its slot being in use as long as its process | ||
| 1279 | handle (procinfo.hProcess) is not NULL. This avoids reusing the | ||
| 1280 | slot when a new process is started immediately after killing | ||
| 1281 | another one, without waiting enough time for the first process to | ||
| 1282 | be reaped and resources allocated for it be orderly freed. | ||
| 1283 | (Bug#13086) | ||
| 1284 | Suggested by Fabrice Popineau <fabrice.popineau@supelec.fr>. | ||
| 1285 | |||
| 1286 | 2012-12-21 Chong Yidong <cyd@gnu.org> | ||
| 1287 | |||
| 1288 | * buffer.c (Fset_buffer_major_mode): Doc fix (Bug#13231). | ||
| 1289 | |||
| 1290 | * fns.c (Fcompare_strings): Doc fix (Bug#13081). | ||
| 1291 | |||
| 1292 | 2012-12-21 Eli Zaretskii <eliz@gnu.org> | ||
| 1293 | |||
| 1294 | * w32.c (get_name_and_id): Always pass NULL as the first argument | ||
| 1295 | of lookup_account_sid. Avoids crashes with UNC file names that | ||
| 1296 | refer to DFS domains, not to specific machine names. (Bug#12621) | ||
| 1297 | Remove now unused argument FNAME; all callers changed. | ||
| 1298 | (get_file_owner_and_group): Remove now unused argument FNAME; all | ||
| 1299 | callers changed. | ||
| 1300 | |||
| 1301 | 2012-12-21 Chong Yidong <cyd@gnu.org> | ||
| 1302 | |||
| 1303 | * editfns.c (Finsert_char): Since read-char-by-name now signals an | ||
| 1304 | error for invalid chars, don't check for a nil return value. | ||
| 1305 | |||
| 1306 | 2012-12-20 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1307 | |||
| 1308 | Avoid calls to CHAR_TO_BYTE if byte position is known. | ||
| 1309 | * editfns.c (make_buffer_string_both): Use move_gap_both. | ||
| 1310 | (Fbuffer_string): Use make_buffer_string_both. | ||
| 1311 | * marker.c (buf_charpos_to_bytepos): Convert to eassert. | ||
| 1312 | Adjust comment. | ||
| 1313 | (buf_bytepos_to_charpos): Likewise. | ||
| 1314 | (charpos_to_bytepos): Remove. | ||
| 1315 | * fileio.c (Finsert_file_contents): Use move_gap_both. | ||
| 1316 | * search.c (Freplace_match): Likewise. | ||
| 1317 | * process.c (process_send_region): Likewise. Use convenient | ||
| 1318 | names for byte positions. | ||
| 1319 | * lisp.h (charpos_to_bytepos): Remove prototype. | ||
| 1320 | * indent.c (scan_for_column): Use CHAR_TO_BYTE. | ||
| 1321 | * insdel.c (move_gap): Likewise. | ||
| 1322 | |||
| 1323 | 2012-12-20 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1324 | |||
| 1325 | * xdisp.c (redisplay_internal): Remove now-unused local. | ||
| 1326 | |||
| 1327 | 2012-12-20 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 1328 | |||
| 1329 | * xdisp.c (select_frame_for_redisplay, ensure_selected_frame): Remove. | ||
| 1330 | (redisplay_internal): Don't bother selecting the frame to get the | ||
| 1331 | proper value of frame-local variables (bug#13225). | ||
| 1332 | |||
| 1333 | 2012-12-20 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1334 | |||
| 1335 | * textprop.c (set_text_properties_1): Do not allow NULL interval. | ||
| 1336 | Rename 4th argument since it may be buffer or string. Adjust comment. | ||
| 1337 | * intervals.c (graft_intervals_info_buffer): Find an interval here. | ||
| 1338 | |||
| 1339 | 2012-12-19 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1340 | |||
| 1341 | * coding.c (Fdetect_coding_region): Do not check start and end with | ||
| 1342 | CHECK_NUMBER_COERCE_MARKER since validate_region does that itself. | ||
| 1343 | (code_convert_region): Likewise. | ||
| 1344 | |||
| 1345 | 2012-12-18 Eli Zaretskii <eliz@gnu.org> | ||
| 1346 | |||
| 1347 | * w32.c (acl_get_file, acl_set_file): Run the file name through | ||
| 1348 | map_w32_filename, and resolve any symlinks in the file name, like | ||
| 1349 | Posix platforms do. | ||
| 1350 | (acl_set_file): Call revert_to_self, if any privileges were | ||
| 1351 | enabled. | ||
| 1352 | |||
| 1353 | 2012-12-17 Juanma Barranquero <lekktu@gmail.com> | ||
| 1354 | |||
| 1355 | * makefile.w32-in ($(BLD)/editfns.$(O), $(BLD)/fileio.$(O)) | ||
| 1356 | ($(BLD)/w32.$(O)): Update dependencies. | ||
| 1357 | |||
| 1358 | 2012-12-17 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 1359 | |||
| 1360 | * xdisp.c (select_frame_for_redisplay): Use select_window_1 to | ||
| 1361 | propagate redisplay's scrolling (if any) to the right window. | ||
| 1362 | (redisplay_internal): Use ensure_selected_frame. | ||
| 1363 | (display_mode_lines): Complete last fix. | ||
| 1364 | * window.c (select_window_1): New func, extracted from select_window. | ||
| 1365 | (select_window): Use it. | ||
| 1366 | * window.h (select_window_1): Declare. | ||
| 1367 | |||
| 1368 | 2012-12-17 Eli Zaretskii <eliz@gnu.org> | ||
| 1369 | |||
| 1370 | Emulate Posix ACL APIs on MS-Windows. | ||
| 1371 | * w32.c: Include sddl.h and sys/acl.h. | ||
| 1372 | (SDDL_REVISION_1): Define if not already defined. | ||
| 1373 | (g_b_init_get_security_descriptor_dacl) | ||
| 1374 | (g_b_init_convert_sd_to_sddl, g_b_init_convert_sddl_to_sd) | ||
| 1375 | (g_b_init_is_valid_security_descriptor) | ||
| 1376 | (g_b_init_set_file_security): New static flags. | ||
| 1377 | (globals_of_w32): Initialize them to zero. | ||
| 1378 | (SetFileSecurity_Name): New string constant. | ||
| 1379 | (SetFileSecurity_Proc, GetSecurityDescriptorDacl_Proc) | ||
| 1380 | (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc) | ||
| 1381 | (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc) | ||
| 1382 | (IsValidSecurityDescriptor_Proc): New typedefs. | ||
| 1383 | (get_file_security, get_security_descriptor_owner) | ||
| 1384 | (get_security_descriptor_group): Set errno to ENOTSUP. | ||
| 1385 | (set_file_security, get_security_descriptor_dacl) | ||
| 1386 | (is_valid_security_descriptor, convert_sd_to_sddl) | ||
| 1387 | (convert_sddl_to_sd, acl_valid, acl_to_text, acl_from_text) | ||
| 1388 | (acl_free, acl_get_file, acl_set_file): New functions. | ||
| 1389 | |||
| 1390 | * fileio.c (Fcopy_file) [WINDOWSNT]: Support copying ACLs. | ||
| 1391 | |||
| 1392 | 2012-12-17 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1393 | |||
| 1394 | Don't reraise SIGCHLD, as that can now lose (Bug#13192). | ||
| 1395 | With the 2012-12-03 fix for Bug#12980 in place, an old workaround | ||
| 1396 | for some of that bug's symptoms can now cause Emacs to abort. | ||
| 1397 | Remove the workaround. | ||
| 1398 | * process.c (wait_reading_process_output): Don't reraise SIGCHLD. | ||
| 1399 | The bug that caused SIGCHLD to get lost has been fixed, and the | ||
| 1400 | workaround for it can now cause Emacs to abort. | ||
| 1401 | |||
| 1402 | 2012-12-16 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1403 | |||
| 1404 | * sysdep.c (emacs_abort): Bump backtrace size to 40. | ||
| 1405 | Companion to the 2012-09-30 patch. Suggested by Eli Zaretskii in | ||
| 1406 | <http://lists.gnu.org/archive/html/emacs-devel/2012-09/msg00796.html>. | ||
| 1407 | |||
| 1408 | 2012-12-16 Romain Francoise <romain@orebokech.com> | ||
| 1409 | |||
| 1410 | * fileio.c (Ffile_acl, Fset_file_acl): New functions. | ||
| 1411 | (Fcopy_file): Change last arg to `preserve_extended_attributes' | ||
| 1412 | and copy ACL entries of file in addition to SELinux context if set. | ||
| 1413 | (syms_of_fileio): Add `file-acl' and `set-file-acl'. | ||
| 1414 | |||
| 1415 | * Makefile.in (LIBACL_LIBS): New macro. | ||
| 1416 | (LIBES): Use it. | ||
| 1417 | |||
| 1418 | 2012-12-15 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1419 | |||
| 1420 | * fileio.c (internal_delete_file): Use bool for boolean. | ||
| 1421 | |||
| 1422 | 2012-12-15 Eli Zaretskii <eliz@gnu.org> | ||
| 1423 | |||
| 1424 | Fix bug #13079 on MS-Windows with temp files not being deleted. | ||
| 1425 | * w32.h (_child_process): New members input_file and | ||
| 1426 | pending_deletion. | ||
| 1427 | (register_child): First argument is now pid_t. | ||
| 1428 | (record_infile, record_pending_deletion): New prototypes. | ||
| 1429 | |||
| 1430 | * w32proc.c (new_child): Initialize input_file and | ||
| 1431 | pending_deletion members of the child. | ||
| 1432 | (delete_child): Delete the child's temporary input file, if any, | ||
| 1433 | that is pending deletion. | ||
| 1434 | (register_child): First argument is now pid_t. | ||
| 1435 | (record_infile, record_pending_deletion): New functions. | ||
| 1436 | (reap_subprocess): Fix a typo in DebPrint string. | ||
| 1437 | (sys_spawnve, sys_kill): Use pid_t for PID arguments. | ||
| 1438 | |||
| 1439 | * fileio.c (internal_delete_file): Return an int again: non-zero | ||
| 1440 | if delete-file succeeds, zero otherwise. | ||
| 1441 | |||
| 1442 | * lisp.h (internal_delete_file): Adjust prototype. | ||
| 1443 | |||
| 1444 | * callproc.c (Fcall_process): Don't overwrite infile with result | ||
| 1445 | of DECODE_FILE. | ||
| 1446 | [WINDOWSNT] If BUFFER is an integer, i.e. we are launching an | ||
| 1447 | asynchronous subprocess, record the name of the input file name, | ||
| 1448 | if any. | ||
| 1449 | (delete_temp_file) [WINDOWSNT]: If internal_delete_file fails to | ||
| 1450 | delete the file, record it as pending deletion when the subprocess | ||
| 1451 | exits. | ||
| 1452 | |||
| 1453 | 2012-12-14 Eli Zaretskii <eliz@gnu.org> | ||
| 1454 | |||
| 1455 | * editfns.c [HAVE_PWD_H]: Include grp.h. | ||
| 1456 | |||
| 1457 | * makefile.w32-in ($(BLD)/editfns.$(O)): Add $(NT_INC)/grp.h. | ||
| 1458 | |||
| 1459 | 2012-12-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1460 | |||
| 1461 | Fix permissions bugs with setgid directories etc. (Bug#13125) | ||
| 1462 | * dired.c (Ffile_attributes): Return t as the 9th attribute, | ||
| 1463 | to mark it as a placeholder. The old value was often wrong. | ||
| 1464 | The only user of this attribute has been changed to use | ||
| 1465 | file-ownership-preserved-p instead, with its new group arg. | ||
| 1466 | * editfns.c (Fgroup_gid, Fgroup_real_gid): New functions. | ||
| 1467 | |||
| 1468 | 2012-12-14 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 1469 | |||
| 1470 | * xdisp.c (select_frame_for_redisplay, display_mode_lines): | ||
| 1471 | Keep selected_window and selected_frame in sync. | ||
| 1472 | |||
| 1473 | 2012-12-14 Eli Zaretskii <eliz@gnu.org> | ||
| 1474 | |||
| 1475 | * w32.c (stat_worker): If w32_stat_get_owner_group is zero, do not | ||
| 1476 | try to get accurate owner and group information from NT file | ||
| 1477 | security APIs. This is to make most callers of 'stat' and | ||
| 1478 | 'lstat', which don't need that information, much faster. | ||
| 1479 | |||
| 1480 | * dired.c (Ffile_attributes) [WINDOWSNT]: | ||
| 1481 | Set w32_stat_get_owner_group to a non-zero value, to request accurate | ||
| 1482 | owner and group information from 'lstat'. | ||
| 1483 | |||
| 1484 | 2012-12-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1485 | |||
| 1486 | * fileio.c (Finsert_file_contents): Don't put tail into head area, | ||
| 1487 | as that confuses set-auto-coding, so insist on the head-read | ||
| 1488 | returning the full 1024 bytes. Let lseek compute the tail offset; | ||
| 1489 | less work for us. Do not ignore I/O errors when reading the tail. | ||
| 1490 | |||
| 1491 | * xdisp.c: Minor style fixes. | ||
| 1492 | (init_iterator): Hoist assignment out of if-expression. | ||
| 1493 | (markpos_of_region): Callers now test for sign, not for -1. | ||
| 1494 | |||
| 1495 | 2012-12-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1496 | |||
| 1497 | Minor redisplay optimization when the region length is zero. | ||
| 1498 | * xdisp.c (markpos_of_region): New function. | ||
| 1499 | (init_iterator): Do not highlight the region of zero length. | ||
| 1500 | (redisplay_window): Check whether the region is of non-zero length. | ||
| 1501 | (try_cursor_movement): Allow if the region length is zero. | ||
| 1502 | (try_window_reusing_current_matrix, try_window_id): Likewise. | ||
| 1503 | |||
| 1504 | 2012-12-13 Eli Zaretskii <eliz@gnu.org> | ||
| 1505 | |||
| 1506 | * search.c (search_buffer): Check the inverse translations of each | ||
| 1507 | character in pattern when the buffer being searched is unibyte. | ||
| 1508 | (Bug#13084) | ||
| 1509 | |||
| 1510 | 2012-12-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1511 | |||
| 1512 | * fileio.c (Fvisited_file_modtime): Return (-1 ...) for nonexistent | ||
| 1513 | files, fixing a regression from 24.2. | ||
| 1514 | (Fverify_visited_file_modtime): Don't read uninitialized st.st_size. | ||
| 1515 | |||
| 1516 | 2012-12-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1517 | |||
| 1518 | * fileio.c (Fcopy_file): Make fstat failure as serious as open failure. | ||
| 1519 | fstat shouldn't fail, and if it does fail copy-file should not proceed. | ||
| 1520 | Remove unnecessary S_ISLNK test, as (contra the comments) this | ||
| 1521 | function can't copy symlinks. Improve quality of error message | ||
| 1522 | when attempting to copy files that are neither regular files nor | ||
| 1523 | directories. | ||
| 1524 | |||
| 1525 | 2012-12-12 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1526 | |||
| 1527 | * dispnew.c (set_window_cursor_after_update): Use clip_to_bounds. | ||
| 1528 | * gtkutil.c (xg_set_toolkit_scroll_bar_thumb): | ||
| 1529 | * window.c (Frecenter): | ||
| 1530 | * xdisp.c (resize_mini_window, hscroll_window_tree, draw_glyphs): | ||
| 1531 | * xterm.c (x_set_toolkit_scroll_bar_thumb): Likewise. | ||
| 1532 | |||
| 1533 | 2012-12-12 Daniel Colascione <dancol@dancol.org> | ||
| 1534 | |||
| 1535 | * unexcw.c (fixup_executable): Use posix_fallocate to ensure that | ||
| 1536 | the dumped Emacs is not a sparse file, greatly improving Cygwin | ||
| 1537 | "make bootstrap" performance. | ||
| 1538 | |||
| 1539 | 2012-12-11 Michael Albinus <michael.albinus@gmx.de> | ||
| 1540 | |||
| 1541 | * inotify.c (inotify_callback): Generate an Emacs event for every | ||
| 1542 | incoming inotify event. | ||
| 1543 | |||
| 1544 | 2012-12-11 Eli Zaretskii <eliz@gnu.org> | ||
| 1545 | |||
| 1546 | * xdisp.c (handle_face_prop): Fix logic of computing | ||
| 1547 | it->start_of_box_run_p. | ||
| 1548 | (append_space_for_newline): If the glyph row is R2L, reset the | ||
| 1549 | iterator's end_of_box_run_p flag before prepending the space glyph. | ||
| 1550 | (extend_face_to_end_of_line): If the glyph row is R2L, reset the | ||
| 1551 | iterator's start_of_box_run_p flag before prepending the stretch. | ||
| 1552 | (append_glyph, produce_image_glyph, append_composite_glyph) | ||
| 1553 | (append_stretch_glyph, append_glyphless_glyph): Reverse the | ||
| 1554 | left_box_line_p and right_box_line_p flags of the glyph for R2L | ||
| 1555 | glyph rows. (Bug#13011) | ||
| 1556 | |||
| 1557 | 2012-12-11 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1558 | |||
| 1559 | * buffer.c (Fset_buffer_multibyte): Do not force redisplay | ||
| 1560 | if changed buffer is not shown in a window. | ||
| 1561 | * insdel.c (prepare_to_modify_buffer): Likewise. | ||
| 1562 | * window.c (replace_buffer_in_windows_safely): Do nothing | ||
| 1563 | if buffer is not shown in a window. | ||
| 1564 | (Fforce_window_update): Likewise if string or buffer argument | ||
| 1565 | is passed. | ||
| 1566 | |||
| 1567 | 2012-12-11 Eli Zaretskii <eliz@gnu.org> | ||
| 1568 | |||
| 1569 | * inotify.c (Finotify_add_watch): Rename decoded_file_name to | ||
| 1570 | encoded_file_name, which is what it is. | ||
| 1571 | |||
| 1572 | 2012-12-11 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1573 | |||
| 1574 | Consistently use marker_position and marker_byte_position. | ||
| 1575 | * fringe.c (Ffringe_bitmaps_at_pos): | ||
| 1576 | * indent.c (Fvertical_motion): | ||
| 1577 | * insdel.c (prepare_to_modify_buffer): | ||
| 1578 | * keyboard.c (make_lispy_position): | ||
| 1579 | * window.c (Fwindow_end, Fpos_visible_in_window_p, unshow_buffer) | ||
| 1580 | (window_scroll_pixel_based, displayed_window_lines) | ||
| 1581 | (Fset_window_configuration): | ||
| 1582 | * xdisp.c (message_dolog, with_echo_area_buffer_unwind_data) | ||
| 1583 | (mark_window_display_accurate_1, redisplay_window, decode_mode_spec): | ||
| 1584 | Replace direct access to marker fields with calls | ||
| 1585 | to marker_position and/or marker_byte_position. | ||
| 1586 | |||
| 1587 | 2012-12-11 Juanma Barranquero <lekktu@gmail.com> | ||
| 1588 | |||
| 1589 | * makefile.w32-in (SIG2STR_H): New macro. | ||
| 1590 | (SYSWAIT_H, $(BLD)/emacs.$(O), $(BLD)/process.$(O)) | ||
| 1591 | ($(BLD)/w32notify.$(O)): Update dependencies. | ||
| 1592 | |||
| 1593 | 2012-12-10 Daniel Colascione <dancol@dancol.org> | ||
| 1594 | |||
| 1595 | * w32term.c, keyboard.c: Fix build break in cygw32 by omitting | ||
| 1596 | Windows file notification functionality unless WINDOWSNT. | ||
| 1597 | |||
| 1598 | * w32gui.h (hprevinst, lpCmdLine, nCmdShow): Remove unused | ||
| 1599 | declarations. | ||
| 1600 | |||
| 1601 | * w32fns.c (cache_system_info): Initialize the global hinst | ||
| 1602 | variable here so various initialization calls DTRT. | ||
| 1603 | |||
| 1604 | * unexw32.c (hprevinst, lpCmdLine, nCmdShow): Remove unused variables. | ||
| 1605 | (hinst): Remove unneeded extern declaration. | ||
| 1606 | (_start): Remove initialization of above variables; remove | ||
| 1607 | initialization of hinst, as cache_system_info now does that. | ||
| 1608 | |||
| 1609 | * emacs.c (main): Call cache_system_info early in startup; we | ||
| 1610 | previously weren't calling it in Cygwin builds. | ||
| 1611 | |||
| 1612 | * Makefile.in (ntsource, WINDRES, W32_RES, W#@_RES_LINK): | ||
| 1613 | Teach the autoconf build system how to compile a Windows resource file | ||
| 1614 | and link it to Emacs. | ||
| 1615 | |||
| 1616 | 2012-12-10 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 1617 | |||
| 1618 | Per-buffer window counters. | ||
| 1619 | * buffer.h (struct buffer): New member window_count. | ||
| 1620 | (buffer_window_count): New function. | ||
| 1621 | * buffer.c (Fget_buffer_create, Fmake_indirect_buffer): | ||
| 1622 | Initialize window_count. | ||
| 1623 | (Fkill_buffer): Verify window_count for the buffer being killed. | ||
| 1624 | (modify_overlay): Do not force redisplay if buffer is not shown | ||
| 1625 | in any window. | ||
| 1626 | (init_buffer_once): Initialize window_count for buffer_defaults | ||
| 1627 | and buffer_local_symbols. | ||
| 1628 | * window.h (buffer_shared): Remove declaration. | ||
| 1629 | (wset_buffer): Convert from inline ... | ||
| 1630 | * window.c (wset_buffer): ... to an ordinary function. | ||
| 1631 | (adjust_window_count): New function. | ||
| 1632 | (make_parent_window): Use it. | ||
| 1633 | * xdisp.c (buffer_shared): Remove. | ||
| 1634 | (redisplay_internal, redisplay_window): Adjust users. | ||
| 1635 | (buffer_shared_and_changed): Use per-buffer window counter. | ||
| 1636 | |||
| 1637 | 2012-12-10 Eli Zaretskii <eliz@gnu.org> | ||
| 1638 | |||
| 1639 | Support for filesystem notifications on MS-Windows. | ||
| 1640 | * w32proc.c (sys_select): If drain_message_queue returns non-zero, | ||
| 1641 | and this is a TTY frame, signal the caller that keyboard input is | ||
| 1642 | available. | ||
| 1643 | |||
| 1644 | * w32xfns.c (drain_message_queue): Now returns an int: an | ||
| 1645 | indication whether any WM_EMACS_FILENOTIFY messages were found in | ||
| 1646 | the queue. | ||
| 1647 | |||
| 1648 | * w32inevt.c (handle_file_notifications): New function. | ||
| 1649 | (w32_console_read_socket): Call it to process file notifications. | ||
| 1650 | |||
| 1651 | * w32console.c (initialize_w32_display): Record the main thread ID | ||
| 1652 | in dwMainThreadId. | ||
| 1653 | |||
| 1654 | * deps.mk (inotify.o): New dependency list. | ||
| 1655 | |||
| 1656 | * Makefile.in (SOME_MACHINE_OBJECTS): Add w32notify.o. | ||
| 1657 | |||
| 1658 | * w32term.h (WM_EMACS_FILENOTIFY): New custom message. | ||
| 1659 | (WM_EMACS_END): Bump value by 1. | ||
| 1660 | (notification_buffer_in_use, file_notifications) | ||
| 1661 | (notifications_size, notifications_desc): Declare. | ||
| 1662 | (w32_get_watch_object, lispy_file_action, globals_of_w32notify): | ||
| 1663 | Add prototypes. | ||
| 1664 | |||
| 1665 | * w32term.c (lispy_file_action, queue_notifications): New functions. | ||
| 1666 | (syms_of_w32term) <Qadded, Qremoved, Qmodified, Qrenamed_from> | ||
| 1667 | <Qrenamed_to>: New symbols. | ||
| 1668 | (w32_read_socket): Handle the WM_EMACS_FILENOTIFY message. | ||
| 1669 | |||
| 1670 | * w32notify.c: New file, implements file event notifications for | ||
| 1671 | MS-Windows. | ||
| 1672 | |||
| 1673 | * w32fns.c (w32_wnd_proc): Handle the WM_EMACS_FILENOTIFY message | ||
| 1674 | by posting it to the w32_read_socket queue. | ||
| 1675 | |||
| 1676 | * termhooks.h (enum event_kind) [HAVE_NTGUI]: Support FILE_NOTIFY_EVENT. | ||
| 1677 | |||
| 1678 | * makefile.w32-in (OBJ2): Add $(BLD)/w32notify.$(O). | ||
| 1679 | (GLOBAL_SOURCES): Add w32notify.c | ||
| 1680 | ($(BLD)/w32notify.$(O)): New set of dependencies. | ||
| 1681 | |||
| 1682 | * lisp.h (syms_of_w32notify) [WINDOWSNT]: Add prototype. | ||
| 1683 | |||
| 1684 | * keyboard.c (kbd_buffer_get_event) [WINDOWSNT]: | ||
| 1685 | Handle FILE_NOTIFY_EVENT. | ||
| 1686 | (syms_of_keyboard) [HAVE_NTGUI] <Qfile_notify>: New symbol. | ||
| 1687 | (keys_of_keyboard) [WINDOWSNT]: Bind file-notify to | ||
| 1688 | w32notify-handle-event by default. | ||
| 1689 | |||
| 1690 | * emacs.c (main) [WINDOWSNT]: Call globals_of_w32notify and | ||
| 1691 | syms_of_w32notify. | ||
| 1692 | |||
| 1693 | 2012-12-10 Rüdiger Sonderfeld <ruediger@c-plusplus.de> | ||
| 1694 | |||
| 1695 | Support for filesystem notifications on GNU/Linux via inotify. | ||
| 1696 | * termhooks.h (enum event_kind) [HAVE_INOTIFY]: Add FILE_NOTIFY_EVENT. | ||
| 1697 | |||
| 1698 | * lisp.h (syms_of_inotify) [HAVE_INOTIFY]: Add prototype. | ||
| 1699 | |||
| 1700 | * keyboard.c (Qfile_inotify) [HAVE_INOTIFY]: New variable. | ||
| 1701 | (syms_of_keyboard): DEFSYM it. | ||
| 1702 | (kbd_buffer_get_event) [HAVE_INOTIFY]: Generate FILE_NOTIFY_EVENT. | ||
| 1703 | (make_lispy_event): Support FILE_NOTIFY_EVENT by generating | ||
| 1704 | Qfile_inotify events. | ||
| 1705 | (keys_of_keyboard) [HAVE_INOTIFY]: Bind file-inotify events in | ||
| 1706 | special-event-map to inotify-handle-event. | ||
| 1707 | |||
| 1708 | * emacs.c (main) [HAVE_INOTIFY]: Call syms_of_inotify. | ||
| 1709 | |||
| 1710 | * Makefile.in (base_obj): Add inotify.o. | ||
| 1711 | |||
| 1712 | * inotify.c: New file. | ||
| 1713 | |||
| 1714 | 2012-12-10 Jan Djärv <jan.h.d@swipnet.se> | ||
| 1715 | |||
| 1716 | * nsterm.m (fd_handler:): FD_ZERO fds (Bug#13103). | ||
| 1717 | |||
| 1718 | 2012-12-10 Fabrice Popineau <fabrice.popineau@gmail.com> | ||
| 1719 | |||
| 1720 | * w32fns.c (cache_system_info): Cast sysinfo_cache.dwPageSize to | ||
| 1721 | DWORD_PTR, for compatibility with 64-bit builds. | ||
| 1722 | |||
| 1723 | * w32.c (_PROCESS_MEMORY_COUNTERS_EX): | ||
| 1724 | (GetProcessWorkingSetSize_Proc, get_process_working_set_size) | ||
| 1725 | (system_process_attributes): Use SIZE_T rather than DWORD, for | ||
| 1726 | compatibility with 64-bit builds. | ||
| 1727 | |||
| 1728 | 2012-12-10 Christopher Schmidt <christopher@ch.ristopher.com> | ||
| 1729 | |||
| 1730 | * lread.c (Vload_source_file_function): Doc fix (Bug#11647). | ||
| 1731 | |||
| 1732 | 2012-12-10 Eli Zaretskii <eliz@gnu.org> | ||
| 1733 | |||
| 1734 | * indent.c (Fvertical_motion): If a display string will be | ||
| 1735 | displayed on the left or the right margin, don't consider it as a | ||
| 1736 | factor in cursor positioning. (Bug#13108) | ||
| 1737 | |||
| 1738 | 2012-12-10 Martin Rudalics <rudalics@gmx.at> | ||
| 1739 | |||
| 1740 | * editfns.c (Fcompare_buffer_substrings): Reword doc-string. | ||
| 1741 | |||
| 1742 | 2012-12-10 Paul Eggert <eggert@cs.ucla.edu> | ||
| 1743 | |||
| 1744 | * fileio.c (Fsubstitute_in_file_name): Use ptrdiff_t, not int, | ||
| 1745 | for string length. | ||
| 1746 | |||
| 1 | 2012-12-08 Eli Zaretskii <eliz@gnu.org> | 1747 | 2012-12-08 Eli Zaretskii <eliz@gnu.org> |
| 2 | 1748 | ||
| 3 | * w32.c (unsetenv): Return 0 if the input string is too long. | 1749 | * w32.c (unsetenv): Return 0 if the input string is too long. |
| @@ -264,9 +2010,9 @@ | |||
| 264 | 2012-12-03 Fabrice Popineau <fabrice.popineau@gmail.com> | 2010 | 2012-12-03 Fabrice Popineau <fabrice.popineau@gmail.com> |
| 265 | 2011 | ||
| 266 | * w32fns.c: Remove prototype of atof. | 2012 | * w32fns.c: Remove prototype of atof. |
| 267 | (syspage_mask): Declared DWORD_PTR, for compatibility with 64-bit | 2013 | (syspage_mask): Make it DWORD_PTR, for compatibility with 64-bit |
| 268 | builds. | 2014 | builds. |
| 269 | (file_dialog_callback): Declared UINT_PTR. | 2015 | (file_dialog_callback): Make it UINT_PTR. |
| 270 | 2016 | ||
| 271 | * w32common.h (syspage_mask): Declare DWORD_PTR, for compatibility | 2017 | * w32common.h (syspage_mask): Declare DWORD_PTR, for compatibility |
| 272 | with 64-bit builds. | 2018 | with 64-bit builds. |
| @@ -409,8 +2155,8 @@ | |||
| 409 | (set_frame_menubar): Adjust user. | 2155 | (set_frame_menubar): Adjust user. |
| 410 | * w32term.h (struct x_output): Drop outdated #if 0 code. | 2156 | * w32term.h (struct x_output): Drop outdated #if 0 code. |
| 411 | (struct w32_output): Use bitfields for explicit_parent, | 2157 | (struct w32_output): Use bitfields for explicit_parent, |
| 412 | asked_for_visible and menubar_active members. Drop | 2158 | asked_for_visible and menubar_active members. |
| 413 | unused pending_menu_activation member. | 2159 | Drop unused pending_menu_activation member. |
| 414 | * xterm.h (struct x_output): Drop outdated #if 0 code. | 2160 | * xterm.h (struct x_output): Drop outdated #if 0 code. |
| 415 | Use bitfields for explicit_parent, asked_for_visible, | 2161 | Use bitfields for explicit_parent, asked_for_visible, |
| 416 | has_been_visible and net_wm_state_hidden_seen members. | 2162 | has_been_visible and net_wm_state_hidden_seen members. |
| @@ -503,8 +2249,8 @@ | |||
| 503 | * fileio.c (Fsubstitute_in_file_name, Ffile_name_directory) | 2249 | * fileio.c (Fsubstitute_in_file_name, Ffile_name_directory) |
| 504 | (Fexpand_file_name) [DOS_NT]: Pass encoded file name to | 2250 | (Fexpand_file_name) [DOS_NT]: Pass encoded file name to |
| 505 | dostounix_filename. Prevents crashes down the road, because | 2251 | dostounix_filename. Prevents crashes down the road, because |
| 506 | dostounix_filename assumes it gets a unibyte string. Reported by | 2252 | dostounix_filename assumes it gets a unibyte string. |
| 507 | Michel de Ruiter <michel@sentient.nl>, see | 2253 | Reported by Michel de Ruiter <michel@sentient.nl>, see |
| 508 | http://lists.gnu.org/archive/html/help-emacs-windows/2012-11/msg00017.html | 2254 | http://lists.gnu.org/archive/html/help-emacs-windows/2012-11/msg00017.html |
| 509 | 2255 | ||
| 510 | 2012-11-20 Stefan Monnier <monnier@iro.umontreal.ca> | 2256 | 2012-11-20 Stefan Monnier <monnier@iro.umontreal.ca> |
| @@ -942,7 +2688,7 @@ | |||
| 942 | * image.c (xpm_make_color_table_h): Fix compiler error because | 2688 | * image.c (xpm_make_color_table_h): Fix compiler error because |
| 943 | make_hash_table changed. | 2689 | make_hash_table changed. |
| 944 | 2690 | ||
| 945 | 2012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change) | 2691 | 2012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change) |
| 946 | 2692 | ||
| 947 | * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541). | 2693 | * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541). |
| 948 | 2694 | ||
| @@ -1499,7 +3245,7 @@ | |||
| 1499 | 3245 | ||
| 1500 | 2012-10-19 Stefan Monnier <monnier@iro.umontreal.ca> | 3246 | 2012-10-19 Stefan Monnier <monnier@iro.umontreal.ca> |
| 1501 | 3247 | ||
| 1502 | * fns.c (Fnreverse): Include the problem element when signalling an | 3248 | * fns.c (Fnreverse): Include the problem element when signaling an |
| 1503 | error (bug#12677). | 3249 | error (bug#12677). |
| 1504 | 3250 | ||
| 1505 | 2012-10-18 Jan Djärv <jan.h.d@swipnet.se> | 3251 | 2012-10-18 Jan Djärv <jan.h.d@swipnet.se> |
| @@ -10390,7 +12136,7 @@ | |||
| 10390 | 2012-05-09 Michael Albinus <michael.albinus@gmx.de> | 12136 | 2012-05-09 Michael Albinus <michael.albinus@gmx.de> |
| 10391 | 12137 | ||
| 10392 | * dbusbind.c (xd_registered_buses): New internal Lisp object. | 12138 | * dbusbind.c (xd_registered_buses): New internal Lisp object. |
| 10393 | Rename all occurences of Vdbus_registered_buses to xd_registered_buses. | 12139 | Rename all occurrences of Vdbus_registered_buses to xd_registered_buses. |
| 10394 | (syms_of_dbusbind): Remove declaration of Vdbus_registered_buses. | 12140 | (syms_of_dbusbind): Remove declaration of Vdbus_registered_buses. |
| 10395 | Initialize xd_registered_buses. | 12141 | Initialize xd_registered_buses. |
| 10396 | 12142 | ||
| @@ -20634,7 +22380,7 @@ See ChangeLog.11 for earlier changes. | |||
| 20634 | ;; coding: utf-8 | 22380 | ;; coding: utf-8 |
| 20635 | ;; End: | 22381 | ;; End: |
| 20636 | 22382 | ||
| 20637 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | 22383 | Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 20638 | 22384 | ||
| 20639 | This file is part of GNU Emacs. | 22385 | This file is part of GNU Emacs. |
| 20640 | 22386 | ||
diff --git a/src/ChangeLog.1 b/src/ChangeLog.1 index 5265d6fdf59..0d926760017 100644 --- a/src/ChangeLog.1 +++ b/src/ChangeLog.1 | |||
| @@ -3521,7 +3521,7 @@ | |||
| 3521 | * minibuf.c: Don't allow entry to minibuffer | 3521 | * minibuf.c: Don't allow entry to minibuffer |
| 3522 | while minibuffer is selected. | 3522 | while minibuffer is selected. |
| 3523 | 3523 | ||
| 3524 | Copyright (C) 1985-1986, 2001-2012 Free Software Foundation, Inc. | 3524 | Copyright (C) 1985-1986, 2001-2013 Free Software Foundation, Inc. |
| 3525 | 3525 | ||
| 3526 | This file is part of GNU Emacs. | 3526 | This file is part of GNU Emacs. |
| 3527 | 3527 | ||
diff --git a/src/ChangeLog.10 b/src/ChangeLog.10 index 6eda101c815..c878c48a4f4 100644 --- a/src/ChangeLog.10 +++ b/src/ChangeLog.10 | |||
| @@ -27912,7 +27912,7 @@ See ChangeLog.9 for earlier changes. | |||
| 27912 | ;; add-log-time-zone-rule: t | 27912 | ;; add-log-time-zone-rule: t |
| 27913 | ;; End: | 27913 | ;; End: |
| 27914 | 27914 | ||
| 27915 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 27915 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 27916 | 27916 | ||
| 27917 | This file is part of GNU Emacs. | 27917 | This file is part of GNU Emacs. |
| 27918 | 27918 | ||
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11 index 1f444b9292c..1195a8f9592 100644 --- a/src/ChangeLog.11 +++ b/src/ChangeLog.11 | |||
| @@ -31383,7 +31383,7 @@ See ChangeLog.10 for earlier changes. | |||
| 31383 | ;; coding: utf-8 | 31383 | ;; coding: utf-8 |
| 31384 | ;; End: | 31384 | ;; End: |
| 31385 | 31385 | ||
| 31386 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | 31386 | Copyright (C) 2007-2013 Free Software Foundation, Inc. |
| 31387 | 31387 | ||
| 31388 | This file is part of GNU Emacs. | 31388 | This file is part of GNU Emacs. |
| 31389 | 31389 | ||
diff --git a/src/ChangeLog.2 b/src/ChangeLog.2 index 0806106836e..64e793c763c 100644 --- a/src/ChangeLog.2 +++ b/src/ChangeLog.2 | |||
| @@ -4771,7 +4771,7 @@ | |||
| 4771 | 4771 | ||
| 4772 | See ChangeLog.1 for earlier changes. | 4772 | See ChangeLog.1 for earlier changes. |
| 4773 | 4773 | ||
| 4774 | Copyright (C) 1986-1988, 2001-2012 Free Software Foundation, Inc. | 4774 | Copyright (C) 1986-1988, 2001-2013 Free Software Foundation, Inc. |
| 4775 | 4775 | ||
| 4776 | This file is part of GNU Emacs. | 4776 | This file is part of GNU Emacs. |
| 4777 | 4777 | ||
diff --git a/src/ChangeLog.3 b/src/ChangeLog.3 index 4f6e02ff8d3..2f798e1f0bc 100644 --- a/src/ChangeLog.3 +++ b/src/ChangeLog.3 | |||
| @@ -16507,7 +16507,7 @@ See ChangeLog.2 for earlier changes. | |||
| 16507 | ;; coding: utf-8 | 16507 | ;; coding: utf-8 |
| 16508 | ;; End: | 16508 | ;; End: |
| 16509 | 16509 | ||
| 16510 | Copyright (C) 1993, 2001-2012 Free Software Foundation, Inc. | 16510 | Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. |
| 16511 | 16511 | ||
| 16512 | This file is part of GNU Emacs. | 16512 | This file is part of GNU Emacs. |
| 16513 | 16513 | ||
diff --git a/src/ChangeLog.4 b/src/ChangeLog.4 index d7ef7d8779a..54ce63556ea 100644 --- a/src/ChangeLog.4 +++ b/src/ChangeLog.4 | |||
| @@ -6906,7 +6906,7 @@ See ChangeLog.3 for earlier changes. | |||
| 6906 | ;; coding: utf-8 | 6906 | ;; coding: utf-8 |
| 6907 | ;; End: | 6907 | ;; End: |
| 6908 | 6908 | ||
| 6909 | Copyright (C) 1993-1994, 2001-2012 Free Software Foundation, Inc. | 6909 | Copyright (C) 1993-1994, 2001-2013 Free Software Foundation, Inc. |
| 6910 | 6910 | ||
| 6911 | This file is part of GNU Emacs. | 6911 | This file is part of GNU Emacs. |
| 6912 | 6912 | ||
diff --git a/src/ChangeLog.5 b/src/ChangeLog.5 index c6dfde7496b..6fefabc5cd0 100644 --- a/src/ChangeLog.5 +++ b/src/ChangeLog.5 | |||
| @@ -7148,7 +7148,7 @@ See ChangeLog.4 for earlier changes. | |||
| 7148 | ;; coding: utf-8 | 7148 | ;; coding: utf-8 |
| 7149 | ;; End: | 7149 | ;; End: |
| 7150 | 7150 | ||
| 7151 | Copyright (C) 1994-1995, 2001-2012 Free Software Foundation, Inc. | 7151 | Copyright (C) 1994-1995, 2001-2013 Free Software Foundation, Inc. |
| 7152 | 7152 | ||
| 7153 | This file is part of GNU Emacs. | 7153 | This file is part of GNU Emacs. |
| 7154 | 7154 | ||
diff --git a/src/ChangeLog.6 b/src/ChangeLog.6 index 64f8b3a8314..77aadf4cf10 100644 --- a/src/ChangeLog.6 +++ b/src/ChangeLog.6 | |||
| @@ -5354,7 +5354,7 @@ | |||
| 5354 | 5354 | ||
| 5355 | See ChangeLog.5 for earlier changes. | 5355 | See ChangeLog.5 for earlier changes. |
| 5356 | 5356 | ||
| 5357 | Copyright (C) 1995-1996, 2001-2012 Free Software Foundation, Inc. | 5357 | Copyright (C) 1995-1996, 2001-2013 Free Software Foundation, Inc. |
| 5358 | 5358 | ||
| 5359 | This file is part of GNU Emacs. | 5359 | This file is part of GNU Emacs. |
| 5360 | 5360 | ||
diff --git a/src/ChangeLog.7 b/src/ChangeLog.7 index ce240ab2928..bb12627b698 100644 --- a/src/ChangeLog.7 +++ b/src/ChangeLog.7 | |||
| @@ -11091,7 +11091,7 @@ See ChangeLog.6 for earlier changes. | |||
| 11091 | ;; coding: utf-8 | 11091 | ;; coding: utf-8 |
| 11092 | ;; End: | 11092 | ;; End: |
| 11093 | 11093 | ||
| 11094 | Copyright (C) 1997-1998, 2001-2012 Free Software Foundation, Inc. | 11094 | Copyright (C) 1997-1998, 2001-2013 Free Software Foundation, Inc. |
| 11095 | 11095 | ||
| 11096 | This file is part of GNU Emacs. | 11096 | This file is part of GNU Emacs. |
| 11097 | 11097 | ||
diff --git a/src/ChangeLog.8 b/src/ChangeLog.8 index e68966b16a2..e89e6b006b7 100644 --- a/src/ChangeLog.8 +++ b/src/ChangeLog.8 | |||
| @@ -13979,7 +13979,7 @@ | |||
| 13979 | 13979 | ||
| 13980 | See ChangeLog.7 for earlier changes. | 13980 | See ChangeLog.7 for earlier changes. |
| 13981 | 13981 | ||
| 13982 | Copyright (C) 1999, 2001-2012 Free Software Foundation, Inc. | 13982 | Copyright (C) 1999, 2001-2013 Free Software Foundation, Inc. |
| 13983 | 13983 | ||
| 13984 | This file is part of GNU Emacs. | 13984 | This file is part of GNU Emacs. |
| 13985 | 13985 | ||
diff --git a/src/ChangeLog.9 b/src/ChangeLog.9 index d6d772c5f95..b451b78944f 100644 --- a/src/ChangeLog.9 +++ b/src/ChangeLog.9 | |||
| @@ -13294,7 +13294,7 @@ See ChangeLog.8 for earlier changes. | |||
| 13294 | ;; coding: utf-8 | 13294 | ;; coding: utf-8 |
| 13295 | ;; End: | 13295 | ;; End: |
| 13296 | 13296 | ||
| 13297 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 13297 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 13298 | 13298 | ||
| 13299 | This file is part of GNU Emacs. | 13299 | This file is part of GNU Emacs. |
| 13300 | 13300 | ||
diff --git a/src/Makefile.in b/src/Makefile.in index d034ad04796..6ee03177861 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # src/Makefile for GNU Emacs. | 1 | # src/Makefile for GNU Emacs. |
| 2 | 2 | ||
| 3 | # Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2012 | 3 | # Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2013 Free Software |
| 4 | # Free Software Foundation, Inc. | 4 | # Foundation, Inc. |
| 5 | 5 | ||
| 6 | # This file is part of GNU Emacs. | 6 | # This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -28,9 +28,11 @@ SHELL = /bin/sh | |||
| 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. |
| 30 | srcdir = @srcdir@ | 30 | srcdir = @srcdir@ |
| 31 | ntsource = $(srcdir)/../nt | ||
| 31 | abs_builddir = @abs_builddir@ | 32 | abs_builddir = @abs_builddir@ |
| 32 | VPATH = $(srcdir) | 33 | VPATH = $(srcdir) |
| 33 | CC = @CC@ | 34 | CC = @CC@ |
| 35 | WINDRES = @WINDRES@ | ||
| 34 | CFLAGS = @CFLAGS@ | 36 | CFLAGS = @CFLAGS@ |
| 35 | CPPFLAGS = @CPPFLAGS@ | 37 | CPPFLAGS = @CPPFLAGS@ |
| 36 | LDFLAGS = @LDFLAGS@ | 38 | LDFLAGS = @LDFLAGS@ |
| @@ -109,9 +111,6 @@ LD_SWITCH_SYSTEM_TEMACS=@LD_SWITCH_SYSTEM_TEMACS@ | |||
| 109 | ## Flags to pass to ld only for temacs. | 111 | ## Flags to pass to ld only for temacs. |
| 110 | TEMACS_LDFLAGS = $(LD_SWITCH_SYSTEM) $(LD_SWITCH_SYSTEM_TEMACS) | 112 | TEMACS_LDFLAGS = $(LD_SWITCH_SYSTEM) $(LD_SWITCH_SYSTEM_TEMACS) |
| 111 | 113 | ||
| 112 | ## $LDFLAGS or empty if NS_IMPL_GNUSTEP (for some reason). | ||
| 113 | TEMACS_LDFLAGS2 = @TEMACS_LDFLAGS2@ | ||
| 114 | |||
| 115 | ## If available, the full path to the paxctl program. | 114 | ## If available, the full path to the paxctl program. |
| 116 | ## On grsecurity/PaX systems, unexec will fail due to a gap between | 115 | ## On grsecurity/PaX systems, unexec will fail due to a gap between |
| 117 | ## the bss section and the heap. This can be prevented by disabling | 116 | ## the bss section and the heap. This can be prevented by disabling |
| @@ -228,6 +227,9 @@ LIBX_OTHER=@LIBX_OTHER@ | |||
| 228 | ## configure, which should set it to nil in non-X builds. | 227 | ## configure, which should set it to nil in non-X builds. |
| 229 | LIBX_BASE=$(LIBXMENU) $(LD_SWITCH_X_SITE) | 228 | LIBX_BASE=$(LIBXMENU) $(LD_SWITCH_X_SITE) |
| 230 | 229 | ||
| 230 | ## Only used for GNUstep | ||
| 231 | LIBS_GNUSTEP=@LIBS_GNUSTEP@ | ||
| 232 | |||
| 231 | LIBSOUND= @LIBSOUND@ | 233 | LIBSOUND= @LIBSOUND@ |
| 232 | CFLAGS_SOUND= @CFLAGS_SOUND@ | 234 | CFLAGS_SOUND= @CFLAGS_SOUND@ |
| 233 | 235 | ||
| @@ -267,6 +269,13 @@ W32_OBJ=@W32_OBJ@ | |||
| 267 | ## --lwinspool if HAVE_W32, else empty. | 269 | ## --lwinspool if HAVE_W32, else empty. |
| 268 | W32_LIBS=@W32_LIBS@ | 270 | W32_LIBS=@W32_LIBS@ |
| 269 | 271 | ||
| 272 | ## emacs.res if HAVE_W32 | ||
| 273 | W32_RES=@W32_RES@ | ||
| 274 | ## If HAVE_W32, compiler arguments for including | ||
| 275 | ## the resource file in the binary. | ||
| 276 | ## XXX -Wl,-b -Wl,pe-i386 -Wl,emacs.res | ||
| 277 | W32_RES_LINK=@W32_RES_LINK@ | ||
| 278 | |||
| 270 | ## Empty if !HAVE_X_WINDOWS | 279 | ## Empty if !HAVE_X_WINDOWS |
| 271 | ## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT | 280 | ## xfont.o ftfont.o xftfont.o ftxfont.o if HAVE_XFT |
| 272 | ## xfont.o ftfont.o ftxfont.o if HAVE_FREETYPE | 281 | ## xfont.o ftfont.o ftxfont.o if HAVE_FREETYPE |
| @@ -283,6 +292,8 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ | |||
| 283 | LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ | 292 | LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ |
| 284 | LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ | 293 | LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ |
| 285 | 294 | ||
| 295 | LIBACL_LIBS = @LIBACL_LIBS@ | ||
| 296 | |||
| 286 | LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ | 297 | LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ |
| 287 | 298 | ||
| 288 | INTERVALS_H = dispextern.h intervals.h composite.h | 299 | INTERVALS_H = dispextern.h intervals.h composite.h |
| @@ -329,7 +340,6 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) | |||
| 329 | @$(MKDEPDIR) | 340 | @$(MKDEPDIR) |
| 330 | $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $< | 341 | $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $< |
| 331 | 342 | ||
| 332 | |||
| 333 | ## lastfile must follow all files whose initialized data areas should | 343 | ## lastfile must follow all files whose initialized data areas should |
| 334 | ## be dumped as pure by dump-emacs. | 344 | ## be dumped as pure by dump-emacs. |
| 335 | base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ | 345 | base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ |
| @@ -344,7 +354,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ | |||
| 344 | syntax.o $(UNEXEC_OBJ) bytecode.o \ | 354 | syntax.o $(UNEXEC_OBJ) bytecode.o \ |
| 345 | process.o gnutls.o callproc.o \ | 355 | process.o gnutls.o callproc.o \ |
| 346 | region-cache.o sound.o atimer.o \ | 356 | region-cache.o sound.o atimer.o \ |
| 347 | doprnt.o intervals.o textprop.o composite.o xml.o \ | 357 | doprnt.o intervals.o textprop.o composite.o xml.o inotify.o \ |
| 348 | profiler.o \ | 358 | profiler.o \ |
| 349 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ | 359 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ |
| 350 | $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) | 360 | $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) |
| @@ -358,7 +368,7 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ | |||
| 358 | xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \ | 368 | xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \ |
| 359 | fontset.o dbusbind.o cygw32.o \ | 369 | fontset.o dbusbind.o cygw32.o \ |
| 360 | nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \ | 370 | nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \ |
| 361 | w32.o w32console.o w32fns.o w32heap.o w32inevt.o \ | 371 | w32.o w32console.o w32fns.o w32heap.o w32inevt.o w32notify.o \ |
| 362 | w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \ | 372 | w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \ |
| 363 | w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \ | 373 | w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \ |
| 364 | xsettings.o xgselect.o termcap.o | 374 | xsettings.o xgselect.o termcap.o |
| @@ -390,7 +400,7 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \ | |||
| 390 | ## Note that SunOS needs -lm to come before -lc; otherwise, you get | 400 | ## Note that SunOS needs -lm to come before -lc; otherwise, you get |
| 391 | ## duplicated symbols. If the standard libraries were compiled | 401 | ## duplicated symbols. If the standard libraries were compiled |
| 392 | ## with GCC, we might need LIB_GCC again after them. | 402 | ## with GCC, we might need LIB_GCC again after them. |
| 393 | LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \ | 403 | LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ |
| 394 | $(LIBX_OTHER) $(LIBSOUND) \ | 404 | $(LIBX_OTHER) $(LIBSOUND) \ |
| 395 | $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \ | 405 | $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \ |
| 396 | $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \ | 406 | $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \ |
| @@ -398,7 +408,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \ | |||
| 398 | $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ | 408 | $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ |
| 399 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ | 409 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ |
| 400 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ | 410 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ |
| 401 | $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ | 411 | $(LIBACL_LIBS) $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ |
| 402 | $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) | 412 | $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) |
| 403 | 413 | ||
| 404 | all: emacs$(EXEEXT) $(OTHER_FILES) | 414 | all: emacs$(EXEEXT) $(OTHER_FILES) |
| @@ -463,9 +473,11 @@ $(obj) $(otherobj): globals.h | |||
| 463 | $(lib)/libgnu.a: $(config_h) | 473 | $(lib)/libgnu.a: $(config_h) |
| 464 | cd $(lib) && $(MAKE) libgnu.a | 474 | cd $(lib) && $(MAKE) libgnu.a |
| 465 | 475 | ||
| 466 | temacs$(EXEEXT): $(START_FILES) stamp-oldxmenu $(obj) $(otherobj) $(lib)/libgnu.a | 476 | temacs$(EXEEXT): $(START_FILES) stamp-oldxmenu $(obj) $(otherobj) \ |
| 467 | $(CC) $(LD_FIRSTFLAG) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(TEMACS_LDFLAGS2) \ | 477 | $(lib)/libgnu.a $(W32_RES) |
| 468 | -o temacs $(START_FILES) $(obj) $(otherobj) $(lib)/libgnu.a $(LIBES) | 478 | $(CC) $(LD_FIRSTFLAG) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \ |
| 479 | -o temacs $(START_FILES) $(obj) $(otherobj) $(lib)/libgnu.a $(LIBES) \ | ||
| 480 | $(W32_RES_LINK) | ||
| 469 | test "$(CANNOT_DUMP)" = "yes" || \ | 481 | test "$(CANNOT_DUMP)" = "yes" || \ |
| 470 | test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT) | 482 | test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT) |
| 471 | 483 | ||
| @@ -506,11 +518,14 @@ $(OLDXMENU): $(OLDXMENU_TARGET) | |||
| 506 | 518 | ||
| 507 | doc.o: buildobj.h | 519 | doc.o: buildobj.h |
| 508 | 520 | ||
| 521 | emacs.res: $(ntsource)/emacs.rc \ | ||
| 522 | $(ntsource)/icons/emacs.ico \ | ||
| 523 | $(ntsource)/emacs-x86.manifest | ||
| 524 | $(WINDRES) -O COFF -o $@ $(ntsource)/emacs.rc | ||
| 509 | 525 | ||
| 510 | ns-app: emacs$(EXEEXT) | 526 | ns-app: emacs$(EXEEXT) |
| 511 | cd ../nextstep && $(MAKE) $(MFLAGS) all | 527 | cd ../nextstep && $(MAKE) $(MFLAGS) all |
| 512 | 528 | ||
| 513 | |||
| 514 | .PHONY: mostlyclean clean bootstrap-clean distclean maintainer-clean | 529 | .PHONY: mostlyclean clean bootstrap-clean distclean maintainer-clean |
| 515 | .PHONY: versionclean extraclean frc | 530 | .PHONY: versionclean extraclean frc |
| 516 | 531 | ||
diff --git a/src/README b/src/README index 558710627a7..0508137cbea 100644 --- a/src/README +++ b/src/README | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 1 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 2 | See the end of the file for license conditions. | 2 | See the end of the file for license conditions. |
| 3 | 3 | ||
| 4 | 4 | ||
diff --git a/src/alloc.c b/src/alloc.c index 5a3ba465d81..80086433e65 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Storage allocation and gc for GNU Emacs Lisp interpreter. | 1 | /* Storage allocation and gc for GNU Emacs Lisp interpreter. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2012 | 3 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #include <limits.h> /* For CHAR_BIT. */ | 26 | #include <limits.h> /* For CHAR_BIT. */ |
| 27 | 27 | ||
| 28 | #ifdef ENABLE_CHECKING | 28 | #ifdef ENABLE_CHECKING |
| 29 | #include <signal.h> /* For SIGABRT. */ | 29 | #include <signal.h> /* For SIGABRT. */ |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #ifdef HAVE_PTHREAD | 32 | #ifdef HAVE_PTHREAD |
| @@ -209,6 +209,7 @@ Lisp_Object Qchar_table_extra_slots; | |||
| 209 | 209 | ||
| 210 | static Lisp_Object Qpost_gc_hook; | 210 | static Lisp_Object Qpost_gc_hook; |
| 211 | 211 | ||
| 212 | static void free_save_value (Lisp_Object); | ||
| 212 | static void mark_terminals (void); | 213 | static void mark_terminals (void); |
| 213 | static void gc_sweep (void); | 214 | static void gc_sweep (void); |
| 214 | static Lisp_Object make_pure_vector (ptrdiff_t); | 215 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -219,7 +220,6 @@ static void refill_memory_reserve (void); | |||
| 219 | #endif | 220 | #endif |
| 220 | static void compact_small_strings (void); | 221 | static void compact_small_strings (void); |
| 221 | static void free_large_strings (void); | 222 | static void free_large_strings (void); |
| 222 | static void free_misc (Lisp_Object); | ||
| 223 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; | 223 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; |
| 224 | 224 | ||
| 225 | /* When scanning the C stack for live Lisp objects, Emacs keeps track of | 225 | /* When scanning the C stack for live Lisp objects, Emacs keeps track of |
| @@ -845,7 +845,7 @@ void * | |||
| 845 | record_xmalloc (size_t size) | 845 | record_xmalloc (size_t size) |
| 846 | { | 846 | { |
| 847 | void *p = xmalloc (size); | 847 | void *p = xmalloc (size); |
| 848 | record_unwind_protect (safe_alloca_unwind, make_save_value (p, 0)); | 848 | record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); |
| 849 | return p; | 849 | return p; |
| 850 | } | 850 | } |
| 851 | 851 | ||
| @@ -1684,7 +1684,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1684 | b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); | 1684 | b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); |
| 1685 | 1685 | ||
| 1686 | #ifdef DOUG_LEA_MALLOC | 1686 | #ifdef DOUG_LEA_MALLOC |
| 1687 | /* Back to a reasonable maximum of mmap'ed areas. */ | 1687 | /* Back to a reasonable maximum of mmap'ed areas. */ |
| 1688 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 1688 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 1689 | #endif | 1689 | #endif |
| 1690 | 1690 | ||
| @@ -1901,7 +1901,7 @@ compact_small_strings (void) | |||
| 1901 | 1901 | ||
| 1902 | #ifdef GC_CHECK_STRING_BYTES | 1902 | #ifdef GC_CHECK_STRING_BYTES |
| 1903 | /* Check that the string size recorded in the string is the | 1903 | /* Check that the string size recorded in the string is the |
| 1904 | same as the one recorded in the sdata structure. */ | 1904 | same as the one recorded in the sdata structure. */ |
| 1905 | if (s && string_bytes (s) != SDATA_NBYTES (from)) | 1905 | if (s && string_bytes (s) != SDATA_NBYTES (from)) |
| 1906 | emacs_abort (); | 1906 | emacs_abort (); |
| 1907 | #endif /* GC_CHECK_STRING_BYTES */ | 1907 | #endif /* GC_CHECK_STRING_BYTES */ |
| @@ -3105,13 +3105,10 @@ Any number of arguments, even zero arguments, are allowed. | |||
| 3105 | usage: (vector &rest OBJECTS) */) | 3105 | usage: (vector &rest OBJECTS) */) |
| 3106 | (ptrdiff_t nargs, Lisp_Object *args) | 3106 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3107 | { | 3107 | { |
| 3108 | register Lisp_Object len, val; | ||
| 3109 | ptrdiff_t i; | 3108 | ptrdiff_t i; |
| 3110 | register struct Lisp_Vector *p; | 3109 | register Lisp_Object val = make_uninit_vector (nargs); |
| 3110 | register struct Lisp_Vector *p = XVECTOR (val); | ||
| 3111 | 3111 | ||
| 3112 | XSETFASTINT (len, nargs); | ||
| 3113 | val = Fmake_vector (len, Qnil); | ||
| 3114 | p = XVECTOR (val); | ||
| 3115 | for (i = 0; i < nargs; i++) | 3112 | for (i = 0; i < nargs; i++) |
| 3116 | p->contents[i] = args[i]; | 3113 | p->contents[i] = args[i]; |
| 3117 | return val; | 3114 | return val; |
| @@ -3149,9 +3146,9 @@ stack before executing the byte-code. | |||
| 3149 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 3146 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 3150 | (ptrdiff_t nargs, Lisp_Object *args) | 3147 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3151 | { | 3148 | { |
| 3152 | register Lisp_Object len, val; | ||
| 3153 | ptrdiff_t i; | 3149 | ptrdiff_t i; |
| 3154 | register struct Lisp_Vector *p; | 3150 | register Lisp_Object val = make_uninit_vector (nargs); |
| 3151 | register struct Lisp_Vector *p = XVECTOR (val); | ||
| 3155 | 3152 | ||
| 3156 | /* We used to purecopy everything here, if purify-flag was set. This worked | 3153 | /* We used to purecopy everything here, if purify-flag was set. This worked |
| 3157 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be | 3154 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| @@ -3161,10 +3158,6 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3161 | just wasteful and other times plainly wrong (e.g. those free vars may want | 3158 | just wasteful and other times plainly wrong (e.g. those free vars may want |
| 3162 | to be setcar'd). */ | 3159 | to be setcar'd). */ |
| 3163 | 3160 | ||
| 3164 | XSETFASTINT (len, nargs); | ||
| 3165 | val = Fmake_vector (len, Qnil); | ||
| 3166 | |||
| 3167 | p = XVECTOR (val); | ||
| 3168 | for (i = 0; i < nargs; i++) | 3161 | for (i = 0; i < nargs; i++) |
| 3169 | p->contents[i] = args[i]; | 3162 | p->contents[i] = args[i]; |
| 3170 | make_byte_code (p); | 3163 | make_byte_code (p); |
| @@ -3339,9 +3332,9 @@ allocate_misc (enum Lisp_Misc_Type type) | |||
| 3339 | return val; | 3332 | return val; |
| 3340 | } | 3333 | } |
| 3341 | 3334 | ||
| 3342 | /* Free a Lisp_Misc object */ | 3335 | /* Free a Lisp_Misc object. */ |
| 3343 | 3336 | ||
| 3344 | static void | 3337 | void |
| 3345 | free_misc (Lisp_Object misc) | 3338 | free_misc (Lisp_Object misc) |
| 3346 | { | 3339 | { |
| 3347 | XMISCTYPE (misc) = Lisp_Misc_Free; | 3340 | XMISCTYPE (misc) = Lisp_Misc_Free; |
| @@ -3351,34 +3344,81 @@ free_misc (Lisp_Object misc) | |||
| 3351 | total_free_markers++; | 3344 | total_free_markers++; |
| 3352 | } | 3345 | } |
| 3353 | 3346 | ||
| 3354 | /* Return a Lisp_Misc_Save_Value object containing POINTER and | 3347 | /* Return a Lisp_Save_Value object with the data saved according to |
| 3355 | INTEGER. This is used to package C values to call record_unwind_protect. | 3348 | FMT. Format specifiers are `i' for an integer, `p' for a pointer |
| 3356 | The unwind function can get the C values back using XSAVE_VALUE. */ | 3349 | and `o' for Lisp_Object. Up to 4 objects can be specified. */ |
| 3357 | 3350 | ||
| 3358 | Lisp_Object | 3351 | Lisp_Object |
| 3359 | make_save_value (void *pointer, ptrdiff_t integer) | 3352 | make_save_value (const char *fmt, ...) |
| 3360 | { | 3353 | { |
| 3361 | register Lisp_Object val; | 3354 | va_list ap; |
| 3362 | register struct Lisp_Save_Value *p; | 3355 | int len = strlen (fmt); |
| 3356 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | ||
| 3357 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3358 | |||
| 3359 | eassert (0 < len && len < 5); | ||
| 3360 | va_start (ap, fmt); | ||
| 3361 | |||
| 3362 | #define INITX(index) \ | ||
| 3363 | do { \ | ||
| 3364 | if (len <= index) \ | ||
| 3365 | p->type ## index = SAVE_UNUSED; \ | ||
| 3366 | else \ | ||
| 3367 | { \ | ||
| 3368 | if (fmt[index] == 'i') \ | ||
| 3369 | { \ | ||
| 3370 | p->type ## index = SAVE_INTEGER; \ | ||
| 3371 | p->data[index].integer = va_arg (ap, ptrdiff_t); \ | ||
| 3372 | } \ | ||
| 3373 | else if (fmt[index] == 'p') \ | ||
| 3374 | { \ | ||
| 3375 | p->type ## index = SAVE_POINTER; \ | ||
| 3376 | p->data[index].pointer = va_arg (ap, void *); \ | ||
| 3377 | } \ | ||
| 3378 | else if (fmt[index] == 'o') \ | ||
| 3379 | { \ | ||
| 3380 | p->type ## index = SAVE_OBJECT; \ | ||
| 3381 | p->data[index].object = va_arg (ap, Lisp_Object); \ | ||
| 3382 | } \ | ||
| 3383 | else \ | ||
| 3384 | emacs_abort (); \ | ||
| 3385 | } \ | ||
| 3386 | } while (0) | ||
| 3387 | |||
| 3388 | INITX (0); | ||
| 3389 | INITX (1); | ||
| 3390 | INITX (2); | ||
| 3391 | INITX (3); | ||
| 3363 | 3392 | ||
| 3364 | val = allocate_misc (Lisp_Misc_Save_Value); | 3393 | #undef INITX |
| 3365 | p = XSAVE_VALUE (val); | 3394 | |
| 3366 | p->pointer = pointer; | 3395 | va_end (ap); |
| 3367 | p->integer = integer; | 3396 | p->area = 0; |
| 3368 | p->dogc = 0; | ||
| 3369 | return val; | 3397 | return val; |
| 3370 | } | 3398 | } |
| 3371 | 3399 | ||
| 3372 | /* Free a Lisp_Misc_Save_Value object. */ | 3400 | /* The most common task it to save just one C pointer. */ |
| 3373 | 3401 | ||
| 3374 | void | 3402 | Lisp_Object |
| 3375 | free_save_value (Lisp_Object save) | 3403 | make_save_pointer (void *pointer) |
| 3376 | { | 3404 | { |
| 3377 | register struct Lisp_Save_Value *p = XSAVE_VALUE (save); | 3405 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); |
| 3406 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3378 | 3407 | ||
| 3379 | p->dogc = 0; | 3408 | p->area = 0; |
| 3380 | xfree (p->pointer); | 3409 | p->type0 = SAVE_POINTER; |
| 3381 | p->pointer = NULL; | 3410 | p->data[0].pointer = pointer; |
| 3411 | p->type1 = p->type2 = p->type3 = SAVE_UNUSED; | ||
| 3412 | return val; | ||
| 3413 | } | ||
| 3414 | |||
| 3415 | /* Free a Lisp_Save_Value object. Do not use this function | ||
| 3416 | if SAVE contains pointer other than returned by xmalloc. */ | ||
| 3417 | |||
| 3418 | static void | ||
| 3419 | free_save_value (Lisp_Object save) | ||
| 3420 | { | ||
| 3421 | xfree (XSAVE_POINTER (save, 0)); | ||
| 3382 | free_misc (save); | 3422 | free_misc (save); |
| 3383 | } | 3423 | } |
| 3384 | 3424 | ||
| @@ -4446,11 +4486,6 @@ mark_memory (void *start, void *end) | |||
| 4446 | } | 4486 | } |
| 4447 | } | 4487 | } |
| 4448 | 4488 | ||
| 4449 | /* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in | ||
| 4450 | the GCC system configuration. In gcc 3.2, the only systems for | ||
| 4451 | which this is so are i386-sco5 non-ELF, i386-sysv3 (maybe included | ||
| 4452 | by others?) and ns32k-pc532-min. */ | ||
| 4453 | |||
| 4454 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS | 4489 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS |
| 4455 | 4490 | ||
| 4456 | static bool setjmp_tested_p; | 4491 | static bool setjmp_tested_p; |
| @@ -4721,12 +4756,12 @@ valid_pointer_p (void *p) | |||
| 4721 | #endif | 4756 | #endif |
| 4722 | } | 4757 | } |
| 4723 | 4758 | ||
| 4724 | /* Return 2 if OBJ is a killed or special buffer object. | 4759 | /* Return 2 if OBJ is a killed or special buffer object, 1 if OBJ is a |
| 4725 | Return 1 if OBJ is a valid lisp object. | 4760 | valid lisp object, 0 if OBJ is NOT a valid lisp object, or -1 if we |
| 4726 | Return 0 if OBJ is NOT a valid lisp object. | 4761 | cannot validate OBJ. This function can be quite slow, so its primary |
| 4727 | Return -1 if we cannot validate OBJ. | 4762 | use is the manual debugging. The only exception is print_object, where |
| 4728 | This function can be quite slow, | 4763 | we use it to check whether the memory referenced by the pointer of |
| 4729 | so it should only be used in code for manual debugging. */ | 4764 | Lisp_Save_Value object contains valid objects. */ |
| 4730 | 4765 | ||
| 4731 | int | 4766 | int |
| 4732 | valid_lisp_object_p (Lisp_Object obj) | 4767 | valid_lisp_object_p (Lisp_Object obj) |
| @@ -5940,20 +5975,33 @@ mark_object (Lisp_Object arg) | |||
| 5940 | 5975 | ||
| 5941 | case Lisp_Misc_Save_Value: | 5976 | case Lisp_Misc_Save_Value: |
| 5942 | XMISCANY (obj)->gcmarkbit = 1; | 5977 | XMISCANY (obj)->gcmarkbit = 1; |
| 5943 | #if GC_MARK_STACK | ||
| 5944 | { | 5978 | { |
| 5945 | register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); | 5979 | register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); |
| 5946 | /* If DOGC is set, POINTER is the address of a memory | 5980 | /* If `area' is nonzero, `data[0].pointer' is the address |
| 5947 | area containing INTEGER potential Lisp_Objects. */ | 5981 | of a memory area containing `data[1].integer' potential |
| 5948 | if (ptr->dogc) | 5982 | Lisp_Objects. */ |
| 5983 | #if GC_MARK_STACK | ||
| 5984 | if (ptr->area) | ||
| 5949 | { | 5985 | { |
| 5950 | Lisp_Object *p = (Lisp_Object *) ptr->pointer; | 5986 | Lisp_Object *p = ptr->data[0].pointer; |
| 5951 | ptrdiff_t nelt; | 5987 | ptrdiff_t nelt; |
| 5952 | for (nelt = ptr->integer; nelt > 0; nelt--, p++) | 5988 | for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++) |
| 5953 | mark_maybe_object (*p); | 5989 | mark_maybe_object (*p); |
| 5954 | } | 5990 | } |
| 5991 | else | ||
| 5992 | #endif /* GC_MARK_STACK */ | ||
| 5993 | { | ||
| 5994 | /* Find Lisp_Objects in `data[N]' slots and mark them. */ | ||
| 5995 | if (ptr->type0 == SAVE_OBJECT) | ||
| 5996 | mark_object (ptr->data[0].object); | ||
| 5997 | if (ptr->type1 == SAVE_OBJECT) | ||
| 5998 | mark_object (ptr->data[1].object); | ||
| 5999 | if (ptr->type2 == SAVE_OBJECT) | ||
| 6000 | mark_object (ptr->data[2].object); | ||
| 6001 | if (ptr->type3 == SAVE_OBJECT) | ||
| 6002 | mark_object (ptr->data[3].object); | ||
| 6003 | } | ||
| 5955 | } | 6004 | } |
| 5956 | #endif | ||
| 5957 | break; | 6005 | break; |
| 5958 | 6006 | ||
| 5959 | case Lisp_Misc_Overlay: | 6007 | case Lisp_Misc_Overlay: |
| @@ -6509,7 +6557,7 @@ die (const char *msg, const char *file, int line) | |||
| 6509 | } | 6557 | } |
| 6510 | #endif | 6558 | #endif |
| 6511 | 6559 | ||
| 6512 | /* Initialization */ | 6560 | /* Initialization. */ |
| 6513 | 6561 | ||
| 6514 | void | 6562 | void |
| 6515 | init_alloc_once (void) | 6563 | init_alloc_once (void) |
| @@ -6524,9 +6572,9 @@ init_alloc_once (void) | |||
| 6524 | #endif | 6572 | #endif |
| 6525 | 6573 | ||
| 6526 | #ifdef DOUG_LEA_MALLOC | 6574 | #ifdef DOUG_LEA_MALLOC |
| 6527 | mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ | 6575 | mallopt (M_TRIM_THRESHOLD, 128 * 1024); /* Trim threshold. */ |
| 6528 | mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */ | 6576 | mallopt (M_MMAP_THRESHOLD, 64 * 1024); /* Mmap threshold. */ |
| 6529 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* max. number of mmap'ed areas */ | 6577 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* Max. number of mmap'ed areas. */ |
| 6530 | #endif | 6578 | #endif |
| 6531 | init_strings (); | 6579 | init_strings (); |
| 6532 | init_vectors (); | 6580 | init_vectors (); |
diff --git a/src/atimer.c b/src/atimer.c index 5752192be76..73c7aa5686b 100644 --- a/src/atimer.c +++ b/src/atimer.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Asynchronous timers. | 1 | /* Asynchronous timers. |
| 2 | Copyright (C) 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/atimer.h b/src/atimer.h index 6d441d71641..2a92f1bebea 100644 --- a/src/atimer.h +++ b/src/atimer.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Asynchronous timers. | 1 | /* Asynchronous timers. |
| 2 | Copyright (C) 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/bidi.c b/src/bidi.c index 6f3d749ef22..db2e48a2ca7 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Low-level bidirectional buffer/string-scanning functions for GNU Emacs. | 1 | /* Low-level bidirectional buffer/string-scanning functions for GNU Emacs. |
| 2 | Copyright (C) 2000-2001, 2004-2005, 2009-2012 | 2 | Copyright (C) 2000-2001, 2004-2005, 2009-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -1973,6 +1973,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1973 | next_type = STRONG_R; | 1973 | next_type = STRONG_R; |
| 1974 | break; | 1974 | break; |
| 1975 | case WEAK_BN: | 1975 | case WEAK_BN: |
| 1976 | case NEUTRAL_ON: /* W6/Retaining */ | ||
| 1976 | if (!bidi_explicit_dir_char (bidi_it->ch)) | 1977 | if (!bidi_explicit_dir_char (bidi_it->ch)) |
| 1977 | emacs_abort (); /* can't happen: BNs are skipped */ | 1978 | emacs_abort (); /* can't happen: BNs are skipped */ |
| 1978 | /* FALLTHROUGH */ | 1979 | /* FALLTHROUGH */ |
| @@ -2391,6 +2392,10 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 2391 | next_level = bidi_peek_at_next_level (bidi_it); | 2392 | next_level = bidi_peek_at_next_level (bidi_it); |
| 2392 | while (next_level != expected_next_level) | 2393 | while (next_level != expected_next_level) |
| 2393 | { | 2394 | { |
| 2395 | /* If next_level is -1, it means we have an unresolved level | ||
| 2396 | in the cache, which at this point should not happen. If | ||
| 2397 | it does, we will infloop. */ | ||
| 2398 | eassert (next_level >= 0); | ||
| 2394 | expected_next_level += incr; | 2399 | expected_next_level += incr; |
| 2395 | level_to_search += incr; | 2400 | level_to_search += incr; |
| 2396 | bidi_find_other_level_edge (bidi_it, level_to_search, !ascending); | 2401 | bidi_find_other_level_edge (bidi_it, level_to_search, !ascending); |
diff --git a/src/blockinput.h b/src/blockinput.h index 70822e29be7..192c813073d 100644 --- a/src/blockinput.h +++ b/src/blockinput.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* blockinput.h - interface to blocking complicated interrupt-driven input. | 1 | /* blockinput.h - interface to blocking complicated interrupt-driven input. |
| 2 | Copyright (C) 1989, 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1989, 1993, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/buffer.c b/src/buffer.c index 6e2191dc22f..aa3fcf8c234 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Buffer manipulation primitives for GNU Emacs. | 1 | /* Buffer manipulation primitives for GNU Emacs. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1989, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -371,9 +372,6 @@ bset_zv_marker (struct buffer *b, Lisp_Object val) | |||
| 371 | b->INTERNAL_FIELD (zv_marker) = val; | 372 | b->INTERNAL_FIELD (zv_marker) = val; |
| 372 | } | 373 | } |
| 373 | 374 | ||
| 374 | /* For debugging; temporary. See set_buffer_internal. */ | ||
| 375 | /* Lisp_Object Qlisp_mode, Vcheck_symbol; */ | ||
| 376 | |||
| 377 | void | 375 | void |
| 378 | nsberror (Lisp_Object spec) | 376 | nsberror (Lisp_Object spec) |
| 379 | { | 377 | { |
| @@ -547,6 +545,8 @@ even if it is dead. The return value is never nil. */) | |||
| 547 | b->base_buffer = NULL; | 545 | b->base_buffer = NULL; |
| 548 | /* No one shares the text with us now. */ | 546 | /* No one shares the text with us now. */ |
| 549 | b->indirections = 0; | 547 | b->indirections = 0; |
| 548 | /* No one shows us now. */ | ||
| 549 | b->window_count = 0; | ||
| 550 | 550 | ||
| 551 | BUF_GAP_SIZE (b) = 20; | 551 | BUF_GAP_SIZE (b) = 20; |
| 552 | block_input (); | 552 | block_input (); |
| @@ -573,6 +573,7 @@ even if it is dead. The return value is never nil. */) | |||
| 573 | BUF_CHARS_MODIFF (b) = 1; | 573 | BUF_CHARS_MODIFF (b) = 1; |
| 574 | BUF_OVERLAY_MODIFF (b) = 1; | 574 | BUF_OVERLAY_MODIFF (b) = 1; |
| 575 | BUF_SAVE_MODIFF (b) = 1; | 575 | BUF_SAVE_MODIFF (b) = 1; |
| 576 | BUF_COMPACT (b) = 1; | ||
| 576 | set_buffer_intervals (b, NULL); | 577 | set_buffer_intervals (b, NULL); |
| 577 | BUF_UNCHANGED_MODIFIED (b) = 1; | 578 | BUF_UNCHANGED_MODIFIED (b) = 1; |
| 578 | BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1; | 579 | BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1; |
| @@ -794,6 +795,8 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 794 | b->indirections = -1; | 795 | b->indirections = -1; |
| 795 | /* Notify base buffer that we share the text now. */ | 796 | /* Notify base buffer that we share the text now. */ |
| 796 | b->base_buffer->indirections++; | 797 | b->base_buffer->indirections++; |
| 798 | /* Always -1 for an indirect buffer. */ | ||
| 799 | b->window_count = -1; | ||
| 797 | 800 | ||
| 798 | b->pt = b->base_buffer->pt; | 801 | b->pt = b->base_buffer->pt; |
| 799 | b->begv = b->base_buffer->begv; | 802 | b->begv = b->base_buffer->begv; |
| @@ -1336,7 +1339,7 @@ DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p, | |||
| 1336 | A non-nil FLAG means mark the buffer modified. */) | 1339 | A non-nil FLAG means mark the buffer modified. */) |
| 1337 | (Lisp_Object flag) | 1340 | (Lisp_Object flag) |
| 1338 | { | 1341 | { |
| 1339 | Lisp_Object fn, buffer, window; | 1342 | Lisp_Object fn; |
| 1340 | 1343 | ||
| 1341 | #ifdef CLASH_DETECTION | 1344 | #ifdef CLASH_DETECTION |
| 1342 | /* If buffer becoming modified, lock the file. | 1345 | /* If buffer becoming modified, lock the file. |
| @@ -1389,9 +1392,7 @@ A non-nil FLAG means mark the buffer modified. */) | |||
| 1389 | Ideally, I think there should be another mechanism for fontifying | 1392 | Ideally, I think there should be another mechanism for fontifying |
| 1390 | buffers without "modifying" buffers, or redisplay should be | 1393 | buffers without "modifying" buffers, or redisplay should be |
| 1391 | smarter about updating the `*' in mode lines. --gerd */ | 1394 | smarter about updating the `*' in mode lines. --gerd */ |
| 1392 | XSETBUFFER (buffer, current_buffer); | 1395 | if (buffer_window_count (current_buffer)) |
| 1393 | window = Fget_buffer_window (buffer, Qt); | ||
| 1394 | if (WINDOWP (window)) | ||
| 1395 | { | 1396 | { |
| 1396 | ++update_mode_lines; | 1397 | ++update_mode_lines; |
| 1397 | current_buffer->prevent_redisplay_optimizations_p = 1; | 1398 | current_buffer->prevent_redisplay_optimizations_p = 1; |
| @@ -1665,7 +1666,7 @@ compact_buffer (struct buffer *buffer) | |||
| 1665 | which aren't changed since last compaction. */ | 1666 | which aren't changed since last compaction. */ |
| 1666 | if (BUFFER_LIVE_P (buffer) | 1667 | if (BUFFER_LIVE_P (buffer) |
| 1667 | && (buffer->base_buffer == NULL) | 1668 | && (buffer->base_buffer == NULL) |
| 1668 | && (buffer->text->compact != buffer->text->modiff)) | 1669 | && (BUF_COMPACT (buffer) != BUF_MODIFF (buffer))) |
| 1669 | { | 1670 | { |
| 1670 | /* If a buffer's undo list is Qt, that means that undo is | 1671 | /* If a buffer's undo list is Qt, that means that undo is |
| 1671 | turned off in that buffer. Calling truncate_undo_list on | 1672 | turned off in that buffer. Calling truncate_undo_list on |
| @@ -1678,19 +1679,15 @@ compact_buffer (struct buffer *buffer) | |||
| 1678 | if (!buffer->text->inhibit_shrinking) | 1679 | if (!buffer->text->inhibit_shrinking) |
| 1679 | { | 1680 | { |
| 1680 | /* If a buffer's gap size is more than 10% of the buffer | 1681 | /* If a buffer's gap size is more than 10% of the buffer |
| 1681 | size, or larger than 2000 bytes, then shrink it | 1682 | size, or larger than GAP_BYTES_DFL bytes, then shrink it |
| 1682 | accordingly. Keep a minimum size of 20 bytes. */ | 1683 | accordingly. Keep a minimum size of GAP_BYTES_MIN bytes. */ |
| 1683 | int size = min (2000, max (20, (buffer->text->z_byte / 10))); | 1684 | ptrdiff_t size = clip_to_bounds (GAP_BYTES_MIN, |
| 1684 | 1685 | BUF_Z_BYTE (buffer) / 10, | |
| 1685 | if (buffer->text->gap_size > size) | 1686 | GAP_BYTES_DFL); |
| 1686 | { | 1687 | if (BUF_GAP_SIZE (buffer) > size) |
| 1687 | struct buffer *save_current = current_buffer; | 1688 | make_gap_1 (buffer, -(BUF_GAP_SIZE (buffer) - size)); |
| 1688 | current_buffer = buffer; | ||
| 1689 | make_gap (-(buffer->text->gap_size - size)); | ||
| 1690 | current_buffer = save_current; | ||
| 1691 | } | ||
| 1692 | } | 1689 | } |
| 1693 | buffer->text->compact = buffer->text->modiff; | 1690 | BUF_COMPACT (buffer) = BUF_MODIFF (buffer); |
| 1694 | } | 1691 | } |
| 1695 | } | 1692 | } |
| 1696 | 1693 | ||
| @@ -1929,10 +1926,16 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1929 | eassert (b->indirections == -1); | 1926 | eassert (b->indirections == -1); |
| 1930 | b->base_buffer->indirections--; | 1927 | b->base_buffer->indirections--; |
| 1931 | eassert (b->base_buffer->indirections >= 0); | 1928 | eassert (b->base_buffer->indirections >= 0); |
| 1929 | /* Make sure that we wasn't confused. */ | ||
| 1930 | eassert (b->window_count == -1); | ||
| 1932 | } | 1931 | } |
| 1933 | else | 1932 | else |
| 1934 | /* No one shares our buffer text, can free it. */ | 1933 | { |
| 1935 | free_buffer_text (b); | 1934 | /* Make sure that no one shows us. */ |
| 1935 | eassert (b->window_count == 0); | ||
| 1936 | /* No one shares our buffer text, can free it. */ | ||
| 1937 | free_buffer_text (b); | ||
| 1938 | } | ||
| 1936 | 1939 | ||
| 1937 | if (b->newline_cache) | 1940 | if (b->newline_cache) |
| 1938 | { | 1941 | { |
| @@ -2039,7 +2042,7 @@ DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal, | |||
| 2039 | DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0, | 2042 | DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0, |
| 2040 | doc: /* Set an appropriate major mode for BUFFER. | 2043 | doc: /* Set an appropriate major mode for BUFFER. |
| 2041 | For the *scratch* buffer, use `initial-major-mode', otherwise choose a mode | 2044 | For the *scratch* buffer, use `initial-major-mode', otherwise choose a mode |
| 2042 | according to `default-major-mode'. | 2045 | according to the default value of `major-mode'. |
| 2043 | Use this function before selecting the buffer, since it may need to inspect | 2046 | Use this function before selecting the buffer, since it may need to inspect |
| 2044 | the current buffer's major mode. */) | 2047 | the current buffer's major mode. */) |
| 2045 | (Lisp_Object buffer) | 2048 | (Lisp_Object buffer) |
| @@ -2681,10 +2684,11 @@ current buffer is cleared. */) | |||
| 2681 | 2684 | ||
| 2682 | UNGCPRO; | 2685 | UNGCPRO; |
| 2683 | 2686 | ||
| 2684 | /* Changing the multibyteness of a buffer means that all windows | ||
| 2685 | showing that buffer must be updated thoroughly. */ | ||
| 2686 | current_buffer->prevent_redisplay_optimizations_p = 1; | 2687 | current_buffer->prevent_redisplay_optimizations_p = 1; |
| 2687 | ++windows_or_buffers_changed; | 2688 | |
| 2689 | /* If buffer is shown in a window, let redisplay consider other windows. */ | ||
| 2690 | if (buffer_window_count (current_buffer)) | ||
| 2691 | ++windows_or_buffers_changed; | ||
| 2688 | 2692 | ||
| 2689 | /* Copy this buffer's new multibyte status | 2693 | /* Copy this buffer's new multibyte status |
| 2690 | into all of its indirect buffers. */ | 2694 | into all of its indirect buffers. */ |
| @@ -3147,7 +3151,10 @@ ptrdiff_t | |||
| 3147 | sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) | 3151 | sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) |
| 3148 | { | 3152 | { |
| 3149 | ptrdiff_t i, j; | 3153 | ptrdiff_t i, j; |
| 3150 | struct sortvec *sortvec = alloca (noverlays * sizeof *sortvec); | 3154 | USE_SAFE_ALLOCA; |
| 3155 | struct sortvec *sortvec; | ||
| 3156 | |||
| 3157 | SAFE_NALLOCA (sortvec, 1, noverlays); | ||
| 3151 | 3158 | ||
| 3152 | /* Put the valid and relevant overlays into sortvec. */ | 3159 | /* Put the valid and relevant overlays into sortvec. */ |
| 3153 | 3160 | ||
| @@ -3193,6 +3200,8 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) | |||
| 3193 | 3200 | ||
| 3194 | for (i = 0; i < noverlays; i++) | 3201 | for (i = 0; i < noverlays; i++) |
| 3195 | overlay_vec[i] = sortvec[i].overlay; | 3202 | overlay_vec[i] = sortvec[i].overlay; |
| 3203 | |||
| 3204 | SAFE_FREE (); | ||
| 3196 | return (noverlays); | 3205 | return (noverlays); |
| 3197 | } | 3206 | } |
| 3198 | 3207 | ||
| @@ -3880,17 +3889,17 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) | |||
| 3880 | 3889 | ||
| 3881 | BUF_COMPUTE_UNCHANGED (buf, start, end); | 3890 | BUF_COMPUTE_UNCHANGED (buf, start, end); |
| 3882 | 3891 | ||
| 3883 | /* If this is a buffer not in the selected window, | 3892 | /* If BUF is visible, consider updating the display if ... */ |
| 3884 | we must do other windows. */ | 3893 | if (buffer_window_count (buf) > 0) |
| 3885 | if (buf != XBUFFER (XWINDOW (selected_window)->buffer)) | 3894 | { |
| 3886 | windows_or_buffers_changed = 1; | 3895 | /* ... it's visible in other window than selected, */ |
| 3887 | /* If multiple windows show this buffer, we must do other windows. */ | 3896 | if (buf != XBUFFER (XWINDOW (selected_window)->buffer)) |
| 3888 | else if (buffer_shared > 1) | 3897 | windows_or_buffers_changed = 1; |
| 3889 | windows_or_buffers_changed = 1; | 3898 | /* ... or if we modify an overlay at the end of the buffer |
| 3890 | /* If we modify an overlay at the end of the buffer, we cannot | 3899 | and so we cannot be sure that window end is still valid. */ |
| 3891 | be sure that window end is still valid. */ | 3900 | else if (end >= ZV && start <= ZV) |
| 3892 | else if (end >= ZV && start <= ZV) | 3901 | windows_or_buffers_changed = 1; |
| 3893 | windows_or_buffers_changed = 1; | 3902 | } |
| 3894 | 3903 | ||
| 3895 | ++BUF_OVERLAY_MODIFF (buf); | 3904 | ++BUF_OVERLAY_MODIFF (buf); |
| 3896 | } | 3905 | } |
| @@ -4569,27 +4578,7 @@ evaporate_overlays (ptrdiff_t pos) | |||
| 4569 | for (; CONSP (hit_list); hit_list = XCDR (hit_list)) | 4578 | for (; CONSP (hit_list); hit_list = XCDR (hit_list)) |
| 4570 | Fdelete_overlay (XCAR (hit_list)); | 4579 | Fdelete_overlay (XCAR (hit_list)); |
| 4571 | } | 4580 | } |
| 4572 | |||
| 4573 | /* Somebody has tried to store a value with an unacceptable type | ||
| 4574 | in the slot with offset OFFSET. */ | ||
| 4575 | |||
| 4576 | void | ||
| 4577 | buffer_slot_type_mismatch (Lisp_Object newval, int type) | ||
| 4578 | { | ||
| 4579 | Lisp_Object predicate; | ||
| 4580 | |||
| 4581 | switch (type) | ||
| 4582 | { | ||
| 4583 | case_Lisp_Int: predicate = Qintegerp; break; | ||
| 4584 | case Lisp_String: predicate = Qstringp; break; | ||
| 4585 | case Lisp_Symbol: predicate = Qsymbolp; break; | ||
| 4586 | default: emacs_abort (); | ||
| 4587 | } | ||
| 4588 | |||
| 4589 | wrong_type_argument (predicate, newval); | ||
| 4590 | } | ||
| 4591 | 4581 | ||
| 4592 | |||
| 4593 | /*********************************************************************** | 4582 | /*********************************************************************** |
| 4594 | Allocation with mmap | 4583 | Allocation with mmap |
| 4595 | ***********************************************************************/ | 4584 | ***********************************************************************/ |
| @@ -5125,6 +5114,9 @@ init_buffer_once (void) | |||
| 5125 | /* No one will share the text with these buffers, but let's play it safe. */ | 5114 | /* No one will share the text with these buffers, but let's play it safe. */ |
| 5126 | buffer_defaults.indirections = 0; | 5115 | buffer_defaults.indirections = 0; |
| 5127 | buffer_local_symbols.indirections = 0; | 5116 | buffer_local_symbols.indirections = 0; |
| 5117 | /* Likewise no one will display them. */ | ||
| 5118 | buffer_defaults.window_count = 0; | ||
| 5119 | buffer_local_symbols.window_count = 0; | ||
| 5128 | set_buffer_intervals (&buffer_defaults, NULL); | 5120 | set_buffer_intervals (&buffer_defaults, NULL); |
| 5129 | set_buffer_intervals (&buffer_local_symbols, NULL); | 5121 | set_buffer_intervals (&buffer_local_symbols, NULL); |
| 5130 | /* This is not strictly necessary, but let's make them initialized. */ | 5122 | /* This is not strictly necessary, but let's make them initialized. */ |
| @@ -5360,25 +5352,23 @@ init_buffer (void) | |||
| 5360 | free (pwd); | 5352 | free (pwd); |
| 5361 | } | 5353 | } |
| 5362 | 5354 | ||
| 5363 | /* Similar to defvar_lisp but define a variable whose value is the Lisp | 5355 | /* Similar to defvar_lisp but define a variable whose value is the |
| 5364 | Object stored in the current buffer. address is the address of the slot | 5356 | Lisp_Object stored in the current buffer. LNAME is the Lisp-level |
| 5365 | in the buffer that is current now. */ | 5357 | variable name. VNAME is the name of the buffer slot. PREDICATE |
| 5366 | 5358 | is nil for a general Lisp variable. If PREDICATE is non-nil, then | |
| 5367 | /* TYPE is nil for a general Lisp variable. | 5359 | only Lisp values that satisfies the PREDICATE are allowed (except |
| 5368 | An integer specifies a type; then only Lisp values | 5360 | that nil is allowed too). DOC is a dummy where you write the doc |
| 5369 | with that type code are allowed (except that nil is allowed too). | 5361 | string as a comment. */ |
| 5370 | LNAME is the Lisp-level variable name. | 5362 | |
| 5371 | VNAME is the name of the buffer slot. | 5363 | #define DEFVAR_PER_BUFFER(lname, vname, predicate, doc) \ |
| 5372 | DOC is a dummy where you write the doc string as a comment. */ | 5364 | do { \ |
| 5373 | #define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ | 5365 | static struct Lisp_Buffer_Objfwd bo_fwd; \ |
| 5374 | do { \ | 5366 | defvar_per_buffer (&bo_fwd, lname, vname, predicate); \ |
| 5375 | static struct Lisp_Buffer_Objfwd bo_fwd; \ | ||
| 5376 | defvar_per_buffer (&bo_fwd, lname, vname, type); \ | ||
| 5377 | } while (0) | 5367 | } while (0) |
| 5378 | 5368 | ||
| 5379 | static void | 5369 | static void |
| 5380 | defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, | 5370 | defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, |
| 5381 | Lisp_Object *address, Lisp_Object type) | 5371 | Lisp_Object *address, Lisp_Object predicate) |
| 5382 | { | 5372 | { |
| 5383 | struct Lisp_Symbol *sym; | 5373 | struct Lisp_Symbol *sym; |
| 5384 | int offset; | 5374 | int offset; |
| @@ -5388,7 +5378,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, | |||
| 5388 | 5378 | ||
| 5389 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; | 5379 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; |
| 5390 | bo_fwd->offset = offset; | 5380 | bo_fwd->offset = offset; |
| 5391 | bo_fwd->slottype = type; | 5381 | bo_fwd->predicate = predicate; |
| 5392 | sym->declared_special = 1; | 5382 | sym->declared_special = 1; |
| 5393 | sym->redirect = SYMBOL_FORWARDED; | 5383 | sym->redirect = SYMBOL_FORWARDED; |
| 5394 | { | 5384 | { |
| @@ -5651,7 +5641,7 @@ Decimal digits after the % specify field width to which to pad. */); | |||
| 5651 | doc: /* Value of `major-mode' for new buffers. */); | 5641 | doc: /* Value of `major-mode' for new buffers. */); |
| 5652 | 5642 | ||
| 5653 | DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode), | 5643 | DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode), |
| 5654 | make_number (Lisp_Symbol), | 5644 | Qsymbolp, |
| 5655 | doc: /* Symbol for current buffer's major mode. | 5645 | doc: /* Symbol for current buffer's major mode. |
| 5656 | The default value (normally `fundamental-mode') affects new buffers. | 5646 | The default value (normally `fundamental-mode') affects new buffers. |
| 5657 | A value of nil means to use the current buffer's major mode, provided | 5647 | A value of nil means to use the current buffer's major mode, provided |
| @@ -5682,17 +5672,17 @@ Use the command `abbrev-mode' to change this variable. */); | |||
| 5682 | doc: /* Non-nil if searches and matches should ignore case. */); | 5672 | doc: /* Non-nil if searches and matches should ignore case. */); |
| 5683 | 5673 | ||
| 5684 | DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column), | 5674 | DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column), |
| 5685 | make_number (Lisp_Int0), | 5675 | Qintegerp, |
| 5686 | doc: /* Column beyond which automatic line-wrapping should happen. | 5676 | doc: /* Column beyond which automatic line-wrapping should happen. |
| 5687 | Interactively, you can set the buffer local value using \\[set-fill-column]. */); | 5677 | Interactively, you can set the buffer local value using \\[set-fill-column]. */); |
| 5688 | 5678 | ||
| 5689 | DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin), | 5679 | DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin), |
| 5690 | make_number (Lisp_Int0), | 5680 | Qintegerp, |
| 5691 | doc: /* Column for the default `indent-line-function' to indent to. | 5681 | doc: /* Column for the default `indent-line-function' to indent to. |
| 5692 | Linefeed indents to this column in Fundamental mode. */); | 5682 | Linefeed indents to this column in Fundamental mode. */); |
| 5693 | 5683 | ||
| 5694 | DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), | 5684 | DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), |
| 5695 | make_number (Lisp_Int0), | 5685 | Qintegerp, |
| 5696 | doc: /* Distance between tab stops (for display of tab characters), in columns. | 5686 | doc: /* Distance between tab stops (for display of tab characters), in columns. |
| 5697 | This should be an integer greater than zero. */); | 5687 | This should be an integer greater than zero. */); |
| 5698 | 5688 | ||
| @@ -5777,7 +5767,7 @@ visual lines rather than logical lines. See the documentation of | |||
| 5777 | `visual-line-mode'. */); | 5767 | `visual-line-mode'. */); |
| 5778 | 5768 | ||
| 5779 | DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), | 5769 | DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), |
| 5780 | make_number (Lisp_String), | 5770 | Qstringp, |
| 5781 | doc: /* Name of default directory of current buffer. Should end with slash. | 5771 | doc: /* Name of default directory of current buffer. Should end with slash. |
| 5782 | To interactively change the default directory, use command `cd'. */); | 5772 | To interactively change the default directory, use command `cd'. */); |
| 5783 | 5773 | ||
| @@ -5790,18 +5780,18 @@ NOTE: This variable is not a hook; | |||
| 5790 | its value may not be a list of functions. */); | 5780 | its value may not be a list of functions. */); |
| 5791 | 5781 | ||
| 5792 | DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename), | 5782 | DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename), |
| 5793 | make_number (Lisp_String), | 5783 | Qstringp, |
| 5794 | doc: /* Name of file visited in current buffer, or nil if not visiting a file. */); | 5784 | doc: /* Name of file visited in current buffer, or nil if not visiting a file. */); |
| 5795 | 5785 | ||
| 5796 | DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename), | 5786 | DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename), |
| 5797 | make_number (Lisp_String), | 5787 | Qstringp, |
| 5798 | doc: /* Abbreviated truename of file visited in current buffer, or nil if none. | 5788 | doc: /* Abbreviated truename of file visited in current buffer, or nil if none. |
| 5799 | The truename of a file is calculated by `file-truename' | 5789 | The truename of a file is calculated by `file-truename' |
| 5800 | and then abbreviated with `abbreviate-file-name'. */); | 5790 | and then abbreviated with `abbreviate-file-name'. */); |
| 5801 | 5791 | ||
| 5802 | DEFVAR_PER_BUFFER ("buffer-auto-save-file-name", | 5792 | DEFVAR_PER_BUFFER ("buffer-auto-save-file-name", |
| 5803 | &BVAR (current_buffer, auto_save_file_name), | 5793 | &BVAR (current_buffer, auto_save_file_name), |
| 5804 | make_number (Lisp_String), | 5794 | Qstringp, |
| 5805 | doc: /* Name of file for auto-saving current buffer. | 5795 | doc: /* Name of file for auto-saving current buffer. |
| 5806 | If it is nil, that means don't auto-save this buffer. */); | 5796 | If it is nil, that means don't auto-save this buffer. */); |
| 5807 | 5797 | ||
| @@ -5813,7 +5803,7 @@ If it is nil, that means don't auto-save this buffer. */); | |||
| 5813 | Backing up is done before the first time the file is saved. */); | 5803 | Backing up is done before the first time the file is saved. */); |
| 5814 | 5804 | ||
| 5815 | DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length), | 5805 | DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length), |
| 5816 | make_number (Lisp_Int0), | 5806 | Qintegerp, |
| 5817 | doc: /* Length of current buffer when last read in, saved or auto-saved. | 5807 | doc: /* Length of current buffer when last read in, saved or auto-saved. |
| 5818 | 0 initially. | 5808 | 0 initially. |
| 5819 | -1 means auto-saving turned off until next real save. | 5809 | -1 means auto-saving turned off until next real save. |
| @@ -5883,23 +5873,23 @@ In addition, a char-table has six extra slots to control the display of: | |||
| 5883 | See also the functions `display-table-slot' and `set-display-table-slot'. */); | 5873 | See also the functions `display-table-slot' and `set-display-table-slot'. */); |
| 5884 | 5874 | ||
| 5885 | DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols), | 5875 | DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols), |
| 5886 | Qnil, | 5876 | Qintegerp, |
| 5887 | doc: /* Width of left marginal area for display of a buffer. | 5877 | doc: /* Width of left marginal area for display of a buffer. |
| 5888 | A value of nil means no marginal area. */); | 5878 | A value of nil means no marginal area. */); |
| 5889 | 5879 | ||
| 5890 | DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols), | 5880 | DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols), |
| 5891 | Qnil, | 5881 | Qintegerp, |
| 5892 | doc: /* Width of right marginal area for display of a buffer. | 5882 | doc: /* Width of right marginal area for display of a buffer. |
| 5893 | A value of nil means no marginal area. */); | 5883 | A value of nil means no marginal area. */); |
| 5894 | 5884 | ||
| 5895 | DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width), | 5885 | DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width), |
| 5896 | Qnil, | 5886 | Qintegerp, |
| 5897 | doc: /* Width of this buffer's left fringe (in pixels). | 5887 | doc: /* Width of this buffer's left fringe (in pixels). |
| 5898 | A value of 0 means no left fringe is shown in this buffer's window. | 5888 | A value of 0 means no left fringe is shown in this buffer's window. |
| 5899 | A value of nil means to use the left fringe width from the window's frame. */); | 5889 | A value of nil means to use the left fringe width from the window's frame. */); |
| 5900 | 5890 | ||
| 5901 | DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width), | 5891 | DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width), |
| 5902 | Qnil, | 5892 | Qintegerp, |
| 5903 | doc: /* Width of this buffer's right fringe (in pixels). | 5893 | doc: /* Width of this buffer's right fringe (in pixels). |
| 5904 | A value of 0 means no right fringe is shown in this buffer's window. | 5894 | A value of 0 means no right fringe is shown in this buffer's window. |
| 5905 | A value of nil means to use the right fringe width from the window's frame. */); | 5895 | A value of nil means to use the right fringe width from the window's frame. */); |
| @@ -5910,7 +5900,7 @@ A value of nil means to use the right fringe width from the window's frame. */) | |||
| 5910 | A value of nil means to display fringes between margins and buffer text. */); | 5900 | A value of nil means to display fringes between margins and buffer text. */); |
| 5911 | 5901 | ||
| 5912 | DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width), | 5902 | DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width), |
| 5913 | Qnil, | 5903 | Qintegerp, |
| 5914 | doc: /* Width of this buffer's scroll bars in pixels. | 5904 | doc: /* Width of this buffer's scroll bars in pixels. |
| 5915 | A value of nil means to use the scroll bar width from the window's frame. */); | 5905 | A value of nil means to use the scroll bar width from the window's frame. */); |
| 5916 | 5906 | ||
| @@ -5990,7 +5980,7 @@ BITMAP is the corresponding fringe bitmap shown for the logical | |||
| 5990 | cursor type. */); | 5980 | cursor type. */); |
| 5991 | 5981 | ||
| 5992 | DEFVAR_PER_BUFFER ("scroll-up-aggressively", | 5982 | DEFVAR_PER_BUFFER ("scroll-up-aggressively", |
| 5993 | &BVAR (current_buffer, scroll_up_aggressively), Qnil, | 5983 | &BVAR (current_buffer, scroll_up_aggressively), Qfloatp, |
| 5994 | doc: /* How far to scroll windows upward. | 5984 | doc: /* How far to scroll windows upward. |
| 5995 | If you move point off the bottom, the window scrolls automatically. | 5985 | If you move point off the bottom, the window scrolls automatically. |
| 5996 | This variable controls how far it scrolls. The value nil, the default, | 5986 | This variable controls how far it scrolls. The value nil, the default, |
| @@ -6003,7 +5993,7 @@ window scrolls by a full window height. Meaningful values are | |||
| 6003 | between 0.0 and 1.0, inclusive. */); | 5993 | between 0.0 and 1.0, inclusive. */); |
| 6004 | 5994 | ||
| 6005 | DEFVAR_PER_BUFFER ("scroll-down-aggressively", | 5995 | DEFVAR_PER_BUFFER ("scroll-down-aggressively", |
| 6006 | &BVAR (current_buffer, scroll_down_aggressively), Qnil, | 5996 | &BVAR (current_buffer, scroll_down_aggressively), Qfloatp, |
| 6007 | doc: /* How far to scroll windows downward. | 5997 | doc: /* How far to scroll windows downward. |
| 6008 | If you move point off the top, the window scrolls automatically. | 5998 | If you move point off the top, the window scrolls automatically. |
| 6009 | This variable controls how far it scrolls. The value nil, the default, | 5999 | This variable controls how far it scrolls. The value nil, the default, |
| @@ -6015,10 +6005,6 @@ simple case that you moved off with C-b means scrolling just one line. | |||
| 6015 | window scrolls by a full window height. Meaningful values are | 6005 | window scrolls by a full window height. Meaningful values are |
| 6016 | between 0.0 and 1.0, inclusive. */); | 6006 | between 0.0 and 1.0, inclusive. */); |
| 6017 | 6007 | ||
| 6018 | /*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol, | ||
| 6019 | "Don't ask."); | ||
| 6020 | */ | ||
| 6021 | |||
| 6022 | DEFVAR_LISP ("before-change-functions", Vbefore_change_functions, | 6008 | DEFVAR_LISP ("before-change-functions", Vbefore_change_functions, |
| 6023 | doc: /* List of functions to call before each text change. | 6009 | doc: /* List of functions to call before each text change. |
| 6024 | Two arguments are passed to each function: the positions of | 6010 | Two arguments are passed to each function: the positions of |
| @@ -6157,7 +6143,7 @@ then characters with property value PROP are invisible, | |||
| 6157 | and they have an ellipsis as well if ELLIPSIS is non-nil. */); | 6143 | and they have an ellipsis as well if ELLIPSIS is non-nil. */); |
| 6158 | 6144 | ||
| 6159 | DEFVAR_PER_BUFFER ("buffer-display-count", | 6145 | DEFVAR_PER_BUFFER ("buffer-display-count", |
| 6160 | &BVAR (current_buffer, display_count), Qnil, | 6146 | &BVAR (current_buffer, display_count), Qintegerp, |
| 6161 | doc: /* A number incremented each time this buffer is displayed in a window. | 6147 | doc: /* A number incremented each time this buffer is displayed in a window. |
| 6162 | The function `set-window-buffer' increments it. */); | 6148 | The function `set-window-buffer' increments it. */); |
| 6163 | 6149 | ||
| @@ -6216,7 +6202,7 @@ cursor's appearance is instead controlled by the variable | |||
| 6216 | `cursor-in-non-selected-windows'. */); | 6202 | `cursor-in-non-selected-windows'. */); |
| 6217 | 6203 | ||
| 6218 | DEFVAR_PER_BUFFER ("line-spacing", | 6204 | DEFVAR_PER_BUFFER ("line-spacing", |
| 6219 | &BVAR (current_buffer, extra_line_spacing), Qnil, | 6205 | &BVAR (current_buffer, extra_line_spacing), Qnumberp, |
| 6220 | doc: /* Additional space to put between lines when displaying a buffer. | 6206 | doc: /* Additional space to put between lines when displaying a buffer. |
| 6221 | The space is measured in pixels, and put below lines on graphic displays, | 6207 | The space is measured in pixels, and put below lines on graphic displays, |
| 6222 | see `display-graphic-p'. | 6208 | see `display-graphic-p'. |
diff --git a/src/buffer.h b/src/buffer.h index 1129840bd47..276cca32e48 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Header file for the buffer manipulation primitives. | 1 | /* Header file for the buffer manipulation primitives. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993-1995, 1997-2012 | 3 | Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Free Software Foundation, Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -82,9 +82,6 @@ INLINE_HEADER_BEGIN | |||
| 82 | /* Size of gap. */ | 82 | /* Size of gap. */ |
| 83 | #define GAP_SIZE (current_buffer->text->gap_size) | 83 | #define GAP_SIZE (current_buffer->text->gap_size) |
| 84 | 84 | ||
| 85 | /* Is the current buffer narrowed? */ | ||
| 86 | #define NARROWED ((BEGV != BEG) || (ZV != Z)) | ||
| 87 | |||
| 88 | /* Modification count. */ | 85 | /* Modification count. */ |
| 89 | #define MODIFF (current_buffer->text->modiff) | 86 | #define MODIFF (current_buffer->text->modiff) |
| 90 | 87 | ||
| @@ -173,10 +170,6 @@ INLINE_HEADER_BEGIN | |||
| 173 | /* Size of gap. */ | 170 | /* Size of gap. */ |
| 174 | #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size) | 171 | #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size) |
| 175 | 172 | ||
| 176 | /* Is this buffer narrowed? */ | ||
| 177 | #define BUF_NARROWED(buf) ((BUF_BEGV (buf) != BUF_BEG (buf)) \ | ||
| 178 | || (BUF_ZV (buf) != BUF_Z (buf))) | ||
| 179 | |||
| 180 | /* Modification count. */ | 173 | /* Modification count. */ |
| 181 | #define BUF_MODIFF(buf) ((buf)->text->modiff) | 174 | #define BUF_MODIFF(buf) ((buf)->text->modiff) |
| 182 | 175 | ||
| @@ -193,6 +186,9 @@ INLINE_HEADER_BEGIN | |||
| 193 | /* FIXME: should we move this into ->text->auto_save_modiff? */ | 186 | /* FIXME: should we move this into ->text->auto_save_modiff? */ |
| 194 | #define BUF_AUTOSAVE_MODIFF(buf) ((buf)->auto_save_modified) | 187 | #define BUF_AUTOSAVE_MODIFF(buf) ((buf)->auto_save_modified) |
| 195 | 188 | ||
| 189 | /* Compaction count. */ | ||
| 190 | #define BUF_COMPACT(buf) ((buf)->text->compact) | ||
| 191 | |||
| 196 | /* Marker chain of buffer. */ | 192 | /* Marker chain of buffer. */ |
| 197 | #define BUF_MARKERS(buf) ((buf)->text->markers) | 193 | #define BUF_MARKERS(buf) ((buf)->text->markers) |
| 198 | 194 | ||
| @@ -291,24 +287,24 @@ extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); | |||
| 291 | /* Access a Lisp position value in POS, | 287 | /* Access a Lisp position value in POS, |
| 292 | and store the charpos in CHARPOS and the bytepos in BYTEPOS. */ | 288 | and store the charpos in CHARPOS and the bytepos in BYTEPOS. */ |
| 293 | 289 | ||
| 294 | #define DECODE_POSITION(charpos, bytepos, pos) \ | 290 | #define DECODE_POSITION(charpos, bytepos, pos) \ |
| 295 | do \ | 291 | do \ |
| 296 | { \ | 292 | { \ |
| 297 | Lisp_Object __pos = (pos); \ | 293 | Lisp_Object __pos = (pos); \ |
| 298 | if (NUMBERP (__pos)) \ | 294 | if (NUMBERP (__pos)) \ |
| 299 | { \ | 295 | { \ |
| 300 | charpos = __pos; \ | 296 | charpos = __pos; \ |
| 301 | bytepos = buf_charpos_to_bytepos (current_buffer, __pos); \ | 297 | bytepos = buf_charpos_to_bytepos (current_buffer, __pos); \ |
| 302 | } \ | 298 | } \ |
| 303 | else if (MARKERP (__pos)) \ | 299 | else if (MARKERP (__pos)) \ |
| 304 | { \ | 300 | { \ |
| 305 | charpos = marker_position (__pos); \ | 301 | charpos = marker_position (__pos); \ |
| 306 | bytepos = marker_byte_position (__pos); \ | 302 | bytepos = marker_byte_position (__pos); \ |
| 307 | } \ | 303 | } \ |
| 308 | else \ | 304 | else \ |
| 309 | wrong_type_argument (Qinteger_or_marker_p, __pos); \ | 305 | wrong_type_argument (Qinteger_or_marker_p, __pos); \ |
| 310 | } \ | 306 | } \ |
| 311 | while (0) | 307 | while (0) |
| 312 | 308 | ||
| 313 | /* Maximum number of bytes in a buffer. | 309 | /* Maximum number of bytes in a buffer. |
| 314 | A buffer cannot contain more bytes than a 1-origin fixnum can represent, | 310 | A buffer cannot contain more bytes than a 1-origin fixnum can represent, |
| @@ -317,6 +313,16 @@ while (0) | |||
| 317 | #define BUF_BYTES_MAX \ | 313 | #define BUF_BYTES_MAX \ |
| 318 | (ptrdiff_t) min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX)) | 314 | (ptrdiff_t) min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX)) |
| 319 | 315 | ||
| 316 | /* Maximum gap size after compact_buffer, in bytes. Also | ||
| 317 | used in make_gap_larger to get some extra reserved space. */ | ||
| 318 | |||
| 319 | #define GAP_BYTES_DFL 2000 | ||
| 320 | |||
| 321 | /* Minimum gap size after compact_buffer, in bytes. Also | ||
| 322 | used in make_gap_smaller to avoid too small gap size. */ | ||
| 323 | |||
| 324 | #define GAP_BYTES_MIN 20 | ||
| 325 | |||
| 320 | /* Return the address of byte position N in current buffer. */ | 326 | /* Return the address of byte position N in current buffer. */ |
| 321 | 327 | ||
| 322 | #define BYTE_POS_ADDR(n) \ | 328 | #define BYTE_POS_ADDR(n) \ |
| @@ -770,11 +776,15 @@ struct buffer | |||
| 770 | In an ordinary buffer, it is 0. */ | 776 | In an ordinary buffer, it is 0. */ |
| 771 | struct buffer *base_buffer; | 777 | struct buffer *base_buffer; |
| 772 | 778 | ||
| 773 | /* In an indirect buffer, this is -1. In an ordinary buffer, | 779 | /* In an indirect buffer, this is -1. In an ordinary buffer, |
| 774 | it's the number of indirect buffers that share our text; | 780 | it's the number of indirect buffers that share our text; |
| 775 | zero means that we're the only owner of this text. */ | 781 | zero means that we're the only owner of this text. */ |
| 776 | int indirections; | 782 | int indirections; |
| 777 | 783 | ||
| 784 | /* Number of windows showing this buffer. Always -1 for | ||
| 785 | an indirect buffer since it counts as its base buffer. */ | ||
| 786 | int window_count; | ||
| 787 | |||
| 778 | /* A non-zero value in slot IDX means that per-buffer variable | 788 | /* A non-zero value in slot IDX means that per-buffer variable |
| 779 | with index IDX has a local value in this buffer. The index IDX | 789 | with index IDX has a local value in this buffer. The index IDX |
| 780 | for a buffer-local variable is stored in that variable's slot | 790 | for a buffer-local variable is stored in that variable's slot |
| @@ -992,15 +1002,15 @@ bset_width_table (struct buffer *b, Lisp_Object val) | |||
| 992 | #define BUFFER_CHECK_INDIRECTION(b) \ | 1002 | #define BUFFER_CHECK_INDIRECTION(b) \ |
| 993 | do { \ | 1003 | do { \ |
| 994 | if (BUFFER_LIVE_P (b)) \ | 1004 | if (BUFFER_LIVE_P (b)) \ |
| 995 | { \ | 1005 | { \ |
| 996 | if (b->base_buffer) \ | 1006 | if (b->base_buffer) \ |
| 997 | { \ | 1007 | { \ |
| 998 | eassert (b->indirections == -1); \ | 1008 | eassert (b->indirections == -1); \ |
| 999 | eassert (b->base_buffer->indirections > 0); \ | 1009 | eassert (b->base_buffer->indirections > 0); \ |
| 1000 | } \ | 1010 | } \ |
| 1001 | else \ | 1011 | else \ |
| 1002 | eassert (b->indirections >= 0); \ | 1012 | eassert (b->indirections >= 0); \ |
| 1003 | } \ | 1013 | } \ |
| 1004 | } while (0) | 1014 | } while (0) |
| 1005 | 1015 | ||
| 1006 | /* Chain of all buffers, including killed ones. */ | 1016 | /* Chain of all buffers, including killed ones. */ |
| @@ -1061,7 +1071,6 @@ extern void set_buffer_internal_1 (struct buffer *); | |||
| 1061 | extern void set_buffer_temp (struct buffer *); | 1071 | extern void set_buffer_temp (struct buffer *); |
| 1062 | extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object); | 1072 | extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object); |
| 1063 | extern void record_buffer (Lisp_Object); | 1073 | extern void record_buffer (Lisp_Object); |
| 1064 | extern _Noreturn void buffer_slot_type_mismatch (Lisp_Object, int); | ||
| 1065 | extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t); | 1074 | extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t); |
| 1066 | extern void mmap_set_vars (bool); | 1075 | extern void mmap_set_vars (bool); |
| 1067 | 1076 | ||
| @@ -1173,7 +1182,18 @@ BUF_FETCH_MULTIBYTE_CHAR (struct buffer *buf, ptrdiff_t pos) | |||
| 1173 | + pos + BUF_BEG_ADDR (buf) - BEG_BYTE); | 1182 | + pos + BUF_BEG_ADDR (buf) - BEG_BYTE); |
| 1174 | return STRING_CHAR (p); | 1183 | return STRING_CHAR (p); |
| 1175 | } | 1184 | } |
| 1176 | 1185 | ||
| 1186 | /* Return number of windows showing B. */ | ||
| 1187 | |||
| 1188 | BUFFER_INLINE int | ||
| 1189 | buffer_window_count (struct buffer *b) | ||
| 1190 | { | ||
| 1191 | if (b->base_buffer) | ||
| 1192 | b = b->base_buffer; | ||
| 1193 | eassert (b->window_count >= 0); | ||
| 1194 | return b->window_count; | ||
| 1195 | } | ||
| 1196 | |||
| 1177 | /* Overlays */ | 1197 | /* Overlays */ |
| 1178 | 1198 | ||
| 1179 | /* Return the marker that stands for where OV starts in the buffer. */ | 1199 | /* Return the marker that stands for where OV starts in the buffer. */ |
diff --git a/src/bytecode.c b/src/bytecode.c index 4c5ac151de1..bd8abe85e04 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Execution of byte code produced by bytecomp.el. | 1 | /* Execution of byte code produced by bytecomp.el. |
| 2 | Copyright (C) 1985-1988, 1993, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1988, 1993, 2000-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
diff --git a/src/callint.c b/src/callint.c index c4c087e83d7..3e295a3b26b 100644 --- a/src/callint.c +++ b/src/callint.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Call a Lisp function interactively. | 1 | /* Call a Lisp function interactively. |
| 2 | Copyright (C) 1985-1986, 1993-1995, 1997, 2000-2012 | 2 | Copyright (C) 1985-1986, 1993-1995, 1997, 2000-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -497,47 +497,47 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 497 | 497 | ||
| 498 | switch (*tem) | 498 | switch (*tem) |
| 499 | { | 499 | { |
| 500 | case 'a': /* Symbol defined as a function */ | 500 | case 'a': /* Symbol defined as a function. */ |
| 501 | visargs[i] = Fcompleting_read (callint_message, | 501 | visargs[i] = Fcompleting_read (callint_message, |
| 502 | Vobarray, Qfboundp, Qt, | 502 | Vobarray, Qfboundp, Qt, |
| 503 | Qnil, Qnil, Qnil, Qnil); | 503 | Qnil, Qnil, Qnil, Qnil); |
| 504 | /* Passing args[i] directly stimulates compiler bug */ | 504 | /* Passing args[i] directly stimulates compiler bug. */ |
| 505 | teml = visargs[i]; | 505 | teml = visargs[i]; |
| 506 | args[i] = Fintern (teml, Qnil); | 506 | args[i] = Fintern (teml, Qnil); |
| 507 | break; | 507 | break; |
| 508 | 508 | ||
| 509 | case 'b': /* Name of existing buffer */ | 509 | case 'b': /* Name of existing buffer. */ |
| 510 | args[i] = Fcurrent_buffer (); | 510 | args[i] = Fcurrent_buffer (); |
| 511 | if (EQ (selected_window, minibuf_window)) | 511 | if (EQ (selected_window, minibuf_window)) |
| 512 | args[i] = Fother_buffer (args[i], Qnil, Qnil); | 512 | args[i] = Fother_buffer (args[i], Qnil, Qnil); |
| 513 | args[i] = Fread_buffer (callint_message, args[i], Qt); | 513 | args[i] = Fread_buffer (callint_message, args[i], Qt); |
| 514 | break; | 514 | break; |
| 515 | 515 | ||
| 516 | case 'B': /* Name of buffer, possibly nonexistent */ | 516 | case 'B': /* Name of buffer, possibly nonexistent. */ |
| 517 | args[i] = Fread_buffer (callint_message, | 517 | args[i] = Fread_buffer (callint_message, |
| 518 | Fother_buffer (Fcurrent_buffer (), Qnil, Qnil), | 518 | Fother_buffer (Fcurrent_buffer (), Qnil, Qnil), |
| 519 | Qnil); | 519 | Qnil); |
| 520 | break; | 520 | break; |
| 521 | 521 | ||
| 522 | case 'c': /* Character */ | 522 | case 'c': /* Character. */ |
| 523 | /* Prompt in `minibuffer-prompt' face. */ | 523 | /* Prompt in `minibuffer-prompt' face. */ |
| 524 | Fput_text_property (make_number (0), | 524 | Fput_text_property (make_number (0), |
| 525 | make_number (SCHARS (callint_message)), | 525 | make_number (SCHARS (callint_message)), |
| 526 | Qface, Qminibuffer_prompt, callint_message); | 526 | Qface, Qminibuffer_prompt, callint_message); |
| 527 | args[i] = Fread_char (callint_message, Qnil, Qnil); | 527 | args[i] = Fread_char (callint_message, Qnil, Qnil); |
| 528 | message1_nolog ((char *) 0); | 528 | message1_nolog ((char *) 0); |
| 529 | /* Passing args[i] directly stimulates compiler bug */ | 529 | /* Passing args[i] directly stimulates compiler bug. */ |
| 530 | teml = args[i]; | 530 | teml = args[i]; |
| 531 | /* See bug#8479. */ | 531 | /* See bug#8479. */ |
| 532 | if (! CHARACTERP (teml)) error ("Non-character input-event"); | 532 | if (! CHARACTERP (teml)) error ("Non-character input-event"); |
| 533 | visargs[i] = Fchar_to_string (teml); | 533 | visargs[i] = Fchar_to_string (teml); |
| 534 | break; | 534 | break; |
| 535 | 535 | ||
| 536 | case 'C': /* Command: symbol with interactive function */ | 536 | case 'C': /* Command: symbol with interactive function. */ |
| 537 | visargs[i] = Fcompleting_read (callint_message, | 537 | visargs[i] = Fcompleting_read (callint_message, |
| 538 | Vobarray, Qcommandp, | 538 | Vobarray, Qcommandp, |
| 539 | Qt, Qnil, Qnil, Qnil, Qnil); | 539 | Qt, Qnil, Qnil, Qnil, Qnil); |
| 540 | /* Passing args[i] directly stimulates compiler bug */ | 540 | /* Passing args[i] directly stimulates compiler bug. */ |
| 541 | teml = visargs[i]; | 541 | teml = visargs[i]; |
| 542 | args[i] = Fintern (teml, Qnil); | 542 | args[i] = Fintern (teml, Qnil); |
| 543 | break; | 543 | break; |
| @@ -549,33 +549,33 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 549 | varies[i] = 1; | 549 | varies[i] = 1; |
| 550 | break; | 550 | break; |
| 551 | 551 | ||
| 552 | case 'D': /* Directory name. */ | 552 | case 'D': /* Directory name. */ |
| 553 | args[i] = Fread_file_name (callint_message, Qnil, | 553 | args[i] = Fread_file_name (callint_message, Qnil, |
| 554 | BVAR (current_buffer, directory), Qlambda, Qnil, | 554 | BVAR (current_buffer, directory), Qlambda, Qnil, |
| 555 | Qfile_directory_p); | 555 | Qfile_directory_p); |
| 556 | break; | 556 | break; |
| 557 | 557 | ||
| 558 | case 'f': /* Existing file name. */ | 558 | case 'f': /* Existing file name. */ |
| 559 | args[i] = Fread_file_name (callint_message, | 559 | args[i] = Fread_file_name (callint_message, |
| 560 | Qnil, Qnil, Qlambda, Qnil, Qnil); | 560 | Qnil, Qnil, Qlambda, Qnil, Qnil); |
| 561 | break; | 561 | break; |
| 562 | 562 | ||
| 563 | case 'F': /* Possibly nonexistent file name. */ | 563 | case 'F': /* Possibly nonexistent file name. */ |
| 564 | args[i] = Fread_file_name (callint_message, | 564 | args[i] = Fread_file_name (callint_message, |
| 565 | Qnil, Qnil, Qnil, Qnil, Qnil); | 565 | Qnil, Qnil, Qnil, Qnil, Qnil); |
| 566 | break; | 566 | break; |
| 567 | 567 | ||
| 568 | case 'G': /* Possibly nonexistent file name, | 568 | case 'G': /* Possibly nonexistent file name, |
| 569 | default to directory alone. */ | 569 | default to directory alone. */ |
| 570 | args[i] = Fread_file_name (callint_message, | 570 | args[i] = Fread_file_name (callint_message, |
| 571 | Qnil, Qnil, Qnil, empty_unibyte_string, Qnil); | 571 | Qnil, Qnil, Qnil, empty_unibyte_string, Qnil); |
| 572 | break; | 572 | break; |
| 573 | 573 | ||
| 574 | case 'i': /* Ignore an argument -- Does not do I/O */ | 574 | case 'i': /* Ignore an argument -- Does not do I/O. */ |
| 575 | varies[i] = -1; | 575 | varies[i] = -1; |
| 576 | break; | 576 | break; |
| 577 | 577 | ||
| 578 | case 'k': /* Key sequence. */ | 578 | case 'k': /* Key sequence. */ |
| 579 | { | 579 | { |
| 580 | ptrdiff_t speccount1 = SPECPDL_INDEX (); | 580 | ptrdiff_t speccount1 = SPECPDL_INDEX (); |
| 581 | specbind (Qcursor_in_echo_area, Qt); | 581 | specbind (Qcursor_in_echo_area, Qt); |
| @@ -607,7 +607,7 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 607 | } | 607 | } |
| 608 | break; | 608 | break; |
| 609 | 609 | ||
| 610 | case 'K': /* Key sequence to be defined. */ | 610 | case 'K': /* Key sequence to be defined. */ |
| 611 | { | 611 | { |
| 612 | ptrdiff_t speccount1 = SPECPDL_INDEX (); | 612 | ptrdiff_t speccount1 = SPECPDL_INDEX (); |
| 613 | specbind (Qcursor_in_echo_area, Qt); | 613 | specbind (Qcursor_in_echo_area, Qt); |
| @@ -639,7 +639,7 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 639 | } | 639 | } |
| 640 | break; | 640 | break; |
| 641 | 641 | ||
| 642 | case 'U': /* Up event from last k or K */ | 642 | case 'U': /* Up event from last k or K. */ |
| 643 | if (!NILP (up_event)) | 643 | if (!NILP (up_event)) |
| 644 | { | 644 | { |
| 645 | args[i] = Fmake_vector (make_number (1), up_event); | 645 | args[i] = Fmake_vector (make_number (1), up_event); |
| @@ -679,7 +679,7 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 679 | Qnil, Qnil, Qnil, Qt); | 679 | Qnil, Qnil, Qnil, Qt); |
| 680 | break; | 680 | break; |
| 681 | 681 | ||
| 682 | case 'N': /* Prefix arg as number, else number from minibuffer */ | 682 | case 'N': /* Prefix arg as number, else number from minibuffer. */ |
| 683 | if (!NILP (prefix_arg)) | 683 | if (!NILP (prefix_arg)) |
| 684 | goto have_prefix_arg; | 684 | goto have_prefix_arg; |
| 685 | case 'n': /* Read number from minibuffer. */ | 685 | case 'n': /* Read number from minibuffer. */ |
| @@ -690,7 +690,7 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 690 | Lisp_Object str; | 690 | Lisp_Object str; |
| 691 | if (! first) | 691 | if (! first) |
| 692 | { | 692 | { |
| 693 | message ("Please enter a number."); | 693 | message1 ("Please enter a number."); |
| 694 | sit_for (make_number (1), 0, 0); | 694 | sit_for (make_number (1), 0, 0); |
| 695 | } | 695 | } |
| 696 | first = 0; | 696 | first = 0; |
| @@ -714,14 +714,14 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 714 | varies[i] = -1; | 714 | varies[i] = -1; |
| 715 | break; | 715 | break; |
| 716 | 716 | ||
| 717 | case 'p': /* Prefix arg converted to number. No I/O. */ | 717 | case 'p': /* Prefix arg converted to number. No I/O. */ |
| 718 | have_prefix_arg: | 718 | have_prefix_arg: |
| 719 | args[i] = Fprefix_numeric_value (prefix_arg); | 719 | args[i] = Fprefix_numeric_value (prefix_arg); |
| 720 | /* visargs[i] = Qnil; */ | 720 | /* visargs[i] = Qnil; */ |
| 721 | varies[i] = -1; | 721 | varies[i] = -1; |
| 722 | break; | 722 | break; |
| 723 | 723 | ||
| 724 | case 'r': /* Region, point and mark as 2 args. */ | 724 | case 'r': /* Region, point and mark as 2 args. */ |
| 725 | check_mark (1); | 725 | check_mark (1); |
| 726 | set_marker_both (point_marker, Qnil, PT, PT_BYTE); | 726 | set_marker_both (point_marker, Qnil, PT, PT_BYTE); |
| 727 | /* visargs[i+1] = Qnil; */ | 727 | /* visargs[i+1] = Qnil; */ |
| @@ -742,29 +742,29 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 742 | case 'S': /* Any symbol. */ | 742 | case 'S': /* Any symbol. */ |
| 743 | visargs[i] = Fread_string (callint_message, | 743 | visargs[i] = Fread_string (callint_message, |
| 744 | Qnil, Qnil, Qnil, Qnil); | 744 | Qnil, Qnil, Qnil, Qnil); |
| 745 | /* Passing args[i] directly stimulates compiler bug */ | 745 | /* Passing args[i] directly stimulates compiler bug. */ |
| 746 | teml = visargs[i]; | 746 | teml = visargs[i]; |
| 747 | args[i] = Fintern (teml, Qnil); | 747 | args[i] = Fintern (teml, Qnil); |
| 748 | break; | 748 | break; |
| 749 | 749 | ||
| 750 | case 'v': /* Variable name: symbol that is | 750 | case 'v': /* Variable name: symbol that is |
| 751 | custom-variable-p. */ | 751 | custom-variable-p. */ |
| 752 | args[i] = Fread_variable (callint_message, Qnil); | 752 | args[i] = Fread_variable (callint_message, Qnil); |
| 753 | visargs[i] = last_minibuf_string; | 753 | visargs[i] = last_minibuf_string; |
| 754 | break; | 754 | break; |
| 755 | 755 | ||
| 756 | case 'x': /* Lisp expression read but not evaluated */ | 756 | case 'x': /* Lisp expression read but not evaluated. */ |
| 757 | args[i] = Fread_minibuffer (callint_message, Qnil); | 757 | args[i] = Fread_minibuffer (callint_message, Qnil); |
| 758 | visargs[i] = last_minibuf_string; | 758 | visargs[i] = last_minibuf_string; |
| 759 | break; | 759 | break; |
| 760 | 760 | ||
| 761 | case 'X': /* Lisp expression read and evaluated */ | 761 | case 'X': /* Lisp expression read and evaluated. */ |
| 762 | args[i] = Feval_minibuffer (callint_message, Qnil); | 762 | args[i] = Feval_minibuffer (callint_message, Qnil); |
| 763 | visargs[i] = last_minibuf_string; | 763 | visargs[i] = last_minibuf_string; |
| 764 | break; | 764 | break; |
| 765 | 765 | ||
| 766 | case 'Z': /* Coding-system symbol, or ignore the | 766 | case 'Z': /* Coding-system symbol, or ignore the |
| 767 | argument if no prefix */ | 767 | argument if no prefix. */ |
| 768 | if (NILP (prefix_arg)) | 768 | if (NILP (prefix_arg)) |
| 769 | { | 769 | { |
| 770 | args[i] = Qnil; | 770 | args[i] = Qnil; |
| @@ -778,7 +778,7 @@ invoke it. If KEYS is omitted or nil, the return value of | |||
| 778 | } | 778 | } |
| 779 | break; | 779 | break; |
| 780 | 780 | ||
| 781 | case 'z': /* Coding-system symbol or nil */ | 781 | case 'z': /* Coding-system symbol or nil. */ |
| 782 | args[i] = Fread_coding_system (callint_message, Qnil); | 782 | args[i] = Fread_coding_system (callint_message, Qnil); |
| 783 | visargs[i] = last_minibuf_string; | 783 | visargs[i] = last_minibuf_string; |
| 784 | break; | 784 | break; |
diff --git a/src/callproc.c b/src/callproc.c index 70e349d0d3a..9132c0dd976 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -402,10 +402,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 402 | 402 | ||
| 403 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); | 403 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); |
| 404 | if (filefd < 0) | 404 | if (filefd < 0) |
| 405 | { | 405 | report_file_error ("Opening process input file", |
| 406 | infile = DECODE_FILE (infile); | 406 | Fcons (DECODE_FILE (infile), Qnil)); |
| 407 | report_file_error ("Opening process input file", Fcons (infile, Qnil)); | ||
| 408 | } | ||
| 409 | 407 | ||
| 410 | if (STRINGP (output_file)) | 408 | if (STRINGP (output_file)) |
| 411 | { | 409 | { |
| @@ -447,28 +445,34 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 447 | path = Fsubstring (path, make_number (2), Qnil); | 445 | path = Fsubstring (path, make_number (2), Qnil); |
| 448 | 446 | ||
| 449 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); | 447 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); |
| 450 | if (nargs > 4) | ||
| 451 | { | ||
| 452 | ptrdiff_t i; | ||
| 453 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | ||
| 454 | 448 | ||
| 455 | GCPRO5 (infile, buffer, current_dir, path, error_file); | 449 | { |
| 456 | argument_coding.dst_multibyte = 0; | 450 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 457 | for (i = 4; i < nargs; i++) | 451 | |
| 458 | { | 452 | GCPRO5 (infile, buffer, current_dir, path, error_file); |
| 459 | argument_coding.src_multibyte = STRING_MULTIBYTE (args[i]); | 453 | if (nargs > 4) |
| 460 | if (CODING_REQUIRE_ENCODING (&argument_coding)) | 454 | { |
| 461 | /* We must encode this argument. */ | 455 | ptrdiff_t i; |
| 462 | args[i] = encode_coding_string (&argument_coding, args[i], 1); | 456 | |
| 463 | } | 457 | argument_coding.dst_multibyte = 0; |
| 464 | UNGCPRO; | 458 | for (i = 4; i < nargs; i++) |
| 465 | for (i = 4; i < nargs; i++) | 459 | { |
| 466 | new_argv[i - 3] = SSDATA (args[i]); | 460 | argument_coding.src_multibyte = STRING_MULTIBYTE (args[i]); |
| 467 | new_argv[i - 3] = 0; | 461 | if (CODING_REQUIRE_ENCODING (&argument_coding)) |
| 468 | } | 462 | /* We must encode this argument. */ |
| 469 | else | 463 | args[i] = encode_coding_string (&argument_coding, args[i], 1); |
| 470 | new_argv[1] = 0; | 464 | } |
| 471 | new_argv[0] = SSDATA (path); | 465 | for (i = 4; i < nargs; i++) |
| 466 | new_argv[i - 3] = SSDATA (args[i]); | ||
| 467 | new_argv[i - 3] = 0; | ||
| 468 | } | ||
| 469 | else | ||
| 470 | new_argv[1] = 0; | ||
| 471 | if (STRING_MULTIBYTE (path)) | ||
| 472 | path = ENCODE_FILE (path); | ||
| 473 | new_argv[0] = SSDATA (path); | ||
| 474 | UNGCPRO; | ||
| 475 | } | ||
| 472 | 476 | ||
| 473 | #ifdef MSDOS /* MW, July 1993 */ | 477 | #ifdef MSDOS /* MW, July 1993 */ |
| 474 | 478 | ||
| @@ -483,7 +487,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 483 | tempfile = alloca (20); | 487 | tempfile = alloca (20); |
| 484 | *tempfile = '\0'; | 488 | *tempfile = '\0'; |
| 485 | } | 489 | } |
| 486 | dostounix_filename (tempfile); | 490 | dostounix_filename (tempfile, 0); |
| 487 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') | 491 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') |
| 488 | strcat (tempfile, "/"); | 492 | strcat (tempfile, "/"); |
| 489 | strcat (tempfile, "detmp.XXX"); | 493 | strcat (tempfile, "detmp.XXX"); |
| @@ -612,6 +616,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 612 | 616 | ||
| 613 | #ifdef WINDOWSNT | 617 | #ifdef WINDOWSNT |
| 614 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 618 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
| 619 | /* We need to record the input file of this child, for when we are | ||
| 620 | called from call-process-region to create an async subprocess. | ||
| 621 | That's because call-process-region's unwind procedure will | ||
| 622 | attempt to delete the temporary input file, which will fail | ||
| 623 | because that file is still in use. Recording it with the child | ||
| 624 | will allow us to delete the file when the subprocess exits. | ||
| 625 | The second part of this is in delete_temp_file, q.v. */ | ||
| 626 | if (pid > 0 && INTEGERP (buffer) && nargs >= 2 && !NILP (args[1])) | ||
| 627 | record_infile (pid, xstrdup (SSDATA (infile))); | ||
| 615 | #else /* not WINDOWSNT */ | 628 | #else /* not WINDOWSNT */ |
| 616 | 629 | ||
| 617 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 630 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| @@ -924,7 +937,21 @@ delete_temp_file (Lisp_Object name) | |||
| 924 | /* Suppress jka-compr handling, etc. */ | 937 | /* Suppress jka-compr handling, etc. */ |
| 925 | ptrdiff_t count = SPECPDL_INDEX (); | 938 | ptrdiff_t count = SPECPDL_INDEX (); |
| 926 | specbind (intern ("file-name-handler-alist"), Qnil); | 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 | ||
| 927 | internal_delete_file (name); | 953 | internal_delete_file (name); |
| 954 | #endif | ||
| 928 | unbind_to (count, Qnil); | 955 | unbind_to (count, Qnil); |
| 929 | return Qnil; | 956 | return Qnil; |
| 930 | } | 957 | } |
| @@ -970,13 +997,11 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 970 | tmpdir = Vtemporary_file_directory; | 997 | tmpdir = Vtemporary_file_directory; |
| 971 | else | 998 | else |
| 972 | { | 999 | { |
| 1000 | char *outf; | ||
| 973 | #ifndef DOS_NT | 1001 | #ifndef DOS_NT |
| 974 | if (getenv ("TMPDIR")) | 1002 | outf = getenv ("TMPDIR"); |
| 975 | tmpdir = build_string (getenv ("TMPDIR")); | 1003 | tmpdir = build_string (outf ? outf : "/tmp/"); |
| 976 | else | ||
| 977 | tmpdir = build_string ("/tmp/"); | ||
| 978 | #else /* DOS_NT */ | 1004 | #else /* DOS_NT */ |
| 979 | char *outf; | ||
| 980 | if ((outf = egetenv ("TMPDIR")) | 1005 | if ((outf = egetenv ("TMPDIR")) |
| 981 | || (outf = egetenv ("TMP")) | 1006 | || (outf = egetenv ("TMP")) |
| 982 | || (outf = egetenv ("TEMP"))) | 1007 | || (outf = egetenv ("TEMP"))) |
| @@ -989,8 +1014,26 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 989 | { | 1014 | { |
| 990 | USE_SAFE_ALLOCA; | 1015 | USE_SAFE_ALLOCA; |
| 991 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); | 1016 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); |
| 992 | Lisp_Object encoded_tem = ENCODE_FILE (pattern); | 1017 | Lisp_Object encoded_tem; |
| 993 | char *tempfile = SAFE_ALLOCA (SBYTES (encoded_tem) + 1); | 1018 | char *tempfile; |
| 1019 | |||
| 1020 | #ifdef WINDOWSNT | ||
| 1021 | /* Cannot use the result of Fexpand_file_name, because it | ||
| 1022 | downcases the XXXXXX part of the pattern, and mktemp then | ||
| 1023 | doesn't recognize it. */ | ||
| 1024 | if (!NILP (Vw32_downcase_file_names)) | ||
| 1025 | { | ||
| 1026 | Lisp_Object dirname = Ffile_name_directory (pattern); | ||
| 1027 | |||
| 1028 | if (NILP (dirname)) | ||
| 1029 | pattern = Vtemp_file_name_pattern; | ||
| 1030 | else | ||
| 1031 | pattern = concat2 (dirname, Vtemp_file_name_pattern); | ||
| 1032 | } | ||
| 1033 | #endif | ||
| 1034 | |||
| 1035 | encoded_tem = ENCODE_FILE (pattern); | ||
| 1036 | tempfile = SAFE_ALLOCA (SBYTES (encoded_tem) + 1); | ||
| 994 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); | 1037 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); |
| 995 | coding_systems = Qt; | 1038 | coding_systems = Qt; |
| 996 | 1039 | ||
| @@ -1274,7 +1317,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1274 | #ifdef WINDOWSNT | 1317 | #ifdef WINDOWSNT |
| 1275 | prepare_standard_handles (in, out, err, handles); | 1318 | prepare_standard_handles (in, out, err, handles); |
| 1276 | set_process_dir (SDATA (current_dir)); | 1319 | set_process_dir (SDATA (current_dir)); |
| 1277 | /* Spawn the child. (See ntproc.c:Spawnve). */ | 1320 | /* Spawn the child. (See w32proc.c:sys_spawnve). */ |
| 1278 | cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env); | 1321 | cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env); |
| 1279 | reset_standard_handles (in, out, err, handles); | 1322 | reset_standard_handles (in, out, err, handles); |
| 1280 | if (cpid == -1) | 1323 | if (cpid == -1) |
| @@ -1610,7 +1653,7 @@ init_callproc (void) | |||
| 1610 | if (! file_accessible_directory_p (SSDATA (tempdir))) | 1653 | if (! file_accessible_directory_p (SSDATA (tempdir))) |
| 1611 | dir_warning ("arch-independent data dir", Vdata_directory); | 1654 | dir_warning ("arch-independent data dir", Vdata_directory); |
| 1612 | 1655 | ||
| 1613 | sh = (char *) getenv ("SHELL"); | 1656 | sh = getenv ("SHELL"); |
| 1614 | Vshell_file_name = build_string (sh ? sh : "/bin/sh"); | 1657 | Vshell_file_name = build_string (sh ? sh : "/bin/sh"); |
| 1615 | 1658 | ||
| 1616 | #ifdef DOS_NT | 1659 | #ifdef DOS_NT |
diff --git a/src/casefiddle.c b/src/casefiddle.c index d9c6a078973..7f5b99752fa 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* GNU Emacs case conversion functions. | 1 | /* GNU Emacs case conversion functions. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985, 1994, 1997-1999, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985, 1994, 1997-1999, 2001-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
diff --git a/src/casetab.c b/src/casetab.c index a84bc9202d0..76f72b26db3 100644 --- a/src/casetab.c +++ b/src/casetab.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* GNU Emacs routines to deal with case tables. | 1 | /* GNU Emacs routines to deal with case tables. |
| 2 | Copyright (C) 1993-1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | Author: Howard Gayle | 4 | Author: Howard Gayle |
| 5 | 5 | ||
diff --git a/src/category.c b/src/category.c index 31cc90bca68..30ffbd0890f 100644 --- a/src/category.c +++ b/src/category.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* GNU Emacs routines to deal with category tables. | 1 | /* GNU Emacs routines to deal with category tables. |
| 2 | 2 | ||
| 3 | Copyright (C) 1998, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1998, 2001-2013 Free Software Foundation, Inc. |
| 4 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 4 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 5 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 5 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 6 | National Institute of Advanced Industrial Science and Technology (AIST) | 6 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* CCL (Code Conversion Language) interpreter. | 1 | /* CCL (Code Conversion Language) interpreter. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -2228,9 +2228,8 @@ Return index number of the registered CCL program. */) | |||
| 2228 | Vccl_program_table = larger_vector (Vccl_program_table, 1, -1); | 2228 | Vccl_program_table = larger_vector (Vccl_program_table, 1, -1); |
| 2229 | 2229 | ||
| 2230 | { | 2230 | { |
| 2231 | Lisp_Object elt; | 2231 | Lisp_Object elt = make_uninit_vector (4); |
| 2232 | 2232 | ||
| 2233 | elt = Fmake_vector (make_number (4), Qnil); | ||
| 2234 | ASET (elt, 0, name); | 2233 | ASET (elt, 0, name); |
| 2235 | ASET (elt, 1, ccl_prog); | 2234 | ASET (elt, 1, ccl_prog); |
| 2236 | ASET (elt, 2, resolved); | 2235 | ASET (elt, 2, resolved); |
diff --git a/src/character.c b/src/character.c index 5808d48a235..b2caaa290af 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Basic character support. | 1 | /* Basic character support. |
| 2 | 2 | ||
| 3 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 4 | Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN. | 4 | Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN. |
| 5 | Licensed to the Free Software Foundation. | 5 | Licensed to the Free Software Foundation. |
| 6 | Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 6 | Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
diff --git a/src/charset.c b/src/charset.c index 43be0e9c780..fdb8eebde8b 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Basic character set support. | 1 | /* Basic character set support. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -1053,7 +1053,7 @@ usage: (define-charset-internal ...) */) | |||
| 1053 | CHECK_NATNUM (parent_max_code); | 1053 | CHECK_NATNUM (parent_max_code); |
| 1054 | parent_code_offset = Fnth (make_number (3), val); | 1054 | parent_code_offset = Fnth (make_number (3), val); |
| 1055 | CHECK_NUMBER (parent_code_offset); | 1055 | CHECK_NUMBER (parent_code_offset); |
| 1056 | val = Fmake_vector (make_number (4), Qnil); | 1056 | val = make_uninit_vector (4); |
| 1057 | ASET (val, 0, make_number (parent_charset->id)); | 1057 | ASET (val, 0, make_number (parent_charset->id)); |
| 1058 | ASET (val, 1, parent_min_code); | 1058 | ASET (val, 1, parent_min_code); |
| 1059 | ASET (val, 2, parent_max_code); | 1059 | ASET (val, 2, parent_max_code); |
| @@ -1259,7 +1259,7 @@ define_charset_internal (Lisp_Object name, | |||
| 1259 | 1259 | ||
| 1260 | args[charset_arg_name] = name; | 1260 | args[charset_arg_name] = name; |
| 1261 | args[charset_arg_dimension] = make_number (dimension); | 1261 | args[charset_arg_dimension] = make_number (dimension); |
| 1262 | val = Fmake_vector (make_number (8), make_number (0)); | 1262 | val = make_uninit_vector (8); |
| 1263 | for (i = 0; i < 8; i++) | 1263 | for (i = 0; i < 8; i++) |
| 1264 | ASET (val, i, make_number (code_space[i])); | 1264 | ASET (val, i, make_number (code_space[i])); |
| 1265 | args[charset_arg_code_space] = val; | 1265 | args[charset_arg_code_space] = val; |
diff --git a/src/charset.h b/src/charset.h index b5fa36290c8..d9a5662e520 100644 --- a/src/charset.h +++ b/src/charset.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Header for charset handler. | 1 | /* Header for charset handler. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Cursor motion subroutines for GNU Emacs. | 1 | /* Cursor motion subroutines for GNU Emacs. |
| 2 | Copyright (C) 1985, 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 1995, 2001-2013 Free Software Foundation, Inc. |
| 3 | based primarily on public domain code written by Chris Torek | 3 | based primarily on public domain code written by Chris Torek |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| @@ -28,8 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 28 | #include "termchar.h" | 28 | #include "termchar.h" |
| 29 | #include "tparam.h" | 29 | #include "tparam.h" |
| 30 | 30 | ||
| 31 | #define BIG 9999 /* 9999 good on VAXen. For 16 bit machines | 31 | #define BIG 9999 /* Good on 32-bit hosts. */ |
| 32 | use about 2000.... */ | ||
| 33 | 32 | ||
| 34 | int cost; /* sums up costs */ | 33 | int cost; /* sums up costs */ |
| 35 | 34 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Cursor motion calculation definitions for GNU Emacs | 1 | /* Cursor motion calculation definitions for GNU Emacs |
| 2 | Copyright (C) 1985, 1989, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 1989, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/cmds.c b/src/cmds.c index 453a4b67e57..3ebad50184a 100644 --- a/src/cmds.c +++ b/src/cmds.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Simple built-in editing commands. | 1 | /* Simple built-in editing commands. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985, 1993-1998, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985, 1993-1998, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/coding.c b/src/coding.c index 56202e4861d..868fb7df0ea 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Coding system handler (conversion, detection, etc). | 1 | /* Coding system handler (conversion, detection, etc). |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -302,6 +302,7 @@ Lisp_Object Vcoding_system_hash_table; | |||
| 302 | static Lisp_Object Qcoding_system, Qeol_type; | 302 | static Lisp_Object Qcoding_system, Qeol_type; |
| 303 | static Lisp_Object Qcoding_aliases; | 303 | static Lisp_Object Qcoding_aliases; |
| 304 | Lisp_Object Qunix, Qdos; | 304 | Lisp_Object Qunix, Qdos; |
| 305 | static Lisp_Object Qmac; | ||
| 305 | Lisp_Object Qbuffer_file_coding_system; | 306 | Lisp_Object Qbuffer_file_coding_system; |
| 306 | static Lisp_Object Qpost_read_conversion, Qpre_write_conversion; | 307 | static Lisp_Object Qpost_read_conversion, Qpre_write_conversion; |
| 307 | static Lisp_Object Qdefault_char; | 308 | static Lisp_Object Qdefault_char; |
| @@ -1048,14 +1049,7 @@ coding_alloc_by_making_gap (struct coding_system *coding, | |||
| 1048 | GPT -= gap_head_used, GPT_BYTE -= gap_head_used; | 1049 | GPT -= gap_head_used, GPT_BYTE -= gap_head_used; |
| 1049 | } | 1050 | } |
| 1050 | else | 1051 | else |
| 1051 | { | 1052 | make_gap_1 (XBUFFER (coding->dst_object), bytes); |
| 1052 | Lisp_Object this_buffer; | ||
| 1053 | |||
| 1054 | this_buffer = Fcurrent_buffer (); | ||
| 1055 | set_buffer_internal (XBUFFER (coding->dst_object)); | ||
| 1056 | make_gap (bytes); | ||
| 1057 | set_buffer_internal (XBUFFER (this_buffer)); | ||
| 1058 | } | ||
| 1059 | } | 1053 | } |
| 1060 | 1054 | ||
| 1061 | 1055 | ||
| @@ -3063,20 +3057,7 @@ detect_coding_iso_2022 (struct coding_system *coding, | |||
| 3063 | } | 3057 | } |
| 3064 | if (single_shifting) | 3058 | if (single_shifting) |
| 3065 | break; | 3059 | break; |
| 3066 | check_extra_latin: | 3060 | goto check_extra_latin; |
| 3067 | if (! VECTORP (Vlatin_extra_code_table) | ||
| 3068 | || NILP (AREF (Vlatin_extra_code_table, c))) | ||
| 3069 | { | ||
| 3070 | rejected = CATEGORY_MASK_ISO; | ||
| 3071 | break; | ||
| 3072 | } | ||
| 3073 | if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1]) | ||
| 3074 | & CODING_ISO_FLAG_LATIN_EXTRA) | ||
| 3075 | found |= CATEGORY_MASK_ISO_8_1; | ||
| 3076 | else | ||
| 3077 | rejected |= CATEGORY_MASK_ISO_8_1; | ||
| 3078 | rejected |= CATEGORY_MASK_ISO_8_2; | ||
| 3079 | break; | ||
| 3080 | 3061 | ||
| 3081 | default: | 3062 | default: |
| 3082 | if (c < 0) | 3063 | if (c < 0) |
| @@ -3127,6 +3108,20 @@ detect_coding_iso_2022 (struct coding_system *coding, | |||
| 3127 | } | 3108 | } |
| 3128 | break; | 3109 | break; |
| 3129 | } | 3110 | } |
| 3111 | check_extra_latin: | ||
| 3112 | if (! VECTORP (Vlatin_extra_code_table) | ||
| 3113 | || NILP (AREF (Vlatin_extra_code_table, c))) | ||
| 3114 | { | ||
| 3115 | rejected = CATEGORY_MASK_ISO; | ||
| 3116 | break; | ||
| 3117 | } | ||
| 3118 | if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1]) | ||
| 3119 | & CODING_ISO_FLAG_LATIN_EXTRA) | ||
| 3120 | found |= CATEGORY_MASK_ISO_8_1; | ||
| 3121 | else | ||
| 3122 | rejected |= CATEGORY_MASK_ISO_8_1; | ||
| 3123 | rejected |= CATEGORY_MASK_ISO_8_2; | ||
| 3124 | break; | ||
| 3130 | } | 3125 | } |
| 3131 | } | 3126 | } |
| 3132 | detect_info->rejected |= CATEGORY_MASK_ISO; | 3127 | detect_info->rejected |= CATEGORY_MASK_ISO; |
| @@ -8426,9 +8421,6 @@ highest priority. */) | |||
| 8426 | ptrdiff_t from, to; | 8421 | ptrdiff_t from, to; |
| 8427 | ptrdiff_t from_byte, to_byte; | 8422 | ptrdiff_t from_byte, to_byte; |
| 8428 | 8423 | ||
| 8429 | CHECK_NUMBER_COERCE_MARKER (start); | ||
| 8430 | CHECK_NUMBER_COERCE_MARKER (end); | ||
| 8431 | |||
| 8432 | validate_region (&start, &end); | 8424 | validate_region (&start, &end); |
| 8433 | from = XINT (start), to = XINT (end); | 8425 | from = XINT (start), to = XINT (end); |
| 8434 | from_byte = CHAR_TO_BYTE (from); | 8426 | from_byte = CHAR_TO_BYTE (from); |
| @@ -8872,8 +8864,6 @@ code_convert_region (Lisp_Object start, Lisp_Object end, | |||
| 8872 | ptrdiff_t from, from_byte, to, to_byte; | 8864 | ptrdiff_t from, from_byte, to, to_byte; |
| 8873 | Lisp_Object src_object; | 8865 | Lisp_Object src_object; |
| 8874 | 8866 | ||
| 8875 | CHECK_NUMBER_COERCE_MARKER (start); | ||
| 8876 | CHECK_NUMBER_COERCE_MARKER (end); | ||
| 8877 | if (NILP (coding_system)) | 8867 | if (NILP (coding_system)) |
| 8878 | coding_system = Qno_conversion; | 8868 | coding_system = Qno_conversion; |
| 8879 | else | 8869 | else |
| @@ -9493,7 +9483,7 @@ make_subsidiaries (Lisp_Object base) | |||
| 9493 | int i; | 9483 | int i; |
| 9494 | 9484 | ||
| 9495 | memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len); | 9485 | memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len); |
| 9496 | subsidiaries = Fmake_vector (make_number (3), Qnil); | 9486 | subsidiaries = make_uninit_vector (3); |
| 9497 | for (i = 0; i < 3; i++) | 9487 | for (i = 0; i < 3; i++) |
| 9498 | { | 9488 | { |
| 9499 | strcpy (buf + base_name_len, suffixes[i]); | 9489 | strcpy (buf + base_name_len, suffixes[i]); |
| @@ -9793,7 +9783,7 @@ usage: (define-coding-system-internal ...) */) | |||
| 9793 | CHECK_VECTOR (initial); | 9783 | CHECK_VECTOR (initial); |
| 9794 | for (i = 0; i < 4; i++) | 9784 | for (i = 0; i < 4; i++) |
| 9795 | { | 9785 | { |
| 9796 | val = Faref (initial, make_number (i)); | 9786 | val = AREF (initial, i); |
| 9797 | if (! NILP (val)) | 9787 | if (! NILP (val)) |
| 9798 | { | 9788 | { |
| 9799 | struct charset *charset; | 9789 | struct charset *charset; |
| @@ -9998,7 +9988,8 @@ usage: (define-coding-system-internal ...) */) | |||
| 9998 | this_name = AREF (eol_type, i); | 9988 | this_name = AREF (eol_type, i); |
| 9999 | this_aliases = Fcons (this_name, Qnil); | 9989 | this_aliases = Fcons (this_name, Qnil); |
| 10000 | this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac); | 9990 | this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac); |
| 10001 | this_spec = Fmake_vector (make_number (3), attrs); | 9991 | this_spec = make_uninit_vector (3); |
| 9992 | ASET (this_spec, 0, attrs); | ||
| 10002 | ASET (this_spec, 1, this_aliases); | 9993 | ASET (this_spec, 1, this_aliases); |
| 10003 | ASET (this_spec, 2, this_eol_type); | 9994 | ASET (this_spec, 2, this_eol_type); |
| 10004 | Fputhash (this_name, this_spec, Vcoding_system_hash_table); | 9995 | Fputhash (this_name, this_spec, Vcoding_system_hash_table); |
| @@ -10011,7 +10002,8 @@ usage: (define-coding-system-internal ...) */) | |||
| 10011 | } | 10002 | } |
| 10012 | } | 10003 | } |
| 10013 | 10004 | ||
| 10014 | spec_vec = Fmake_vector (make_number (3), attrs); | 10005 | spec_vec = make_uninit_vector (3); |
| 10006 | ASET (spec_vec, 0, attrs); | ||
| 10015 | ASET (spec_vec, 1, aliases); | 10007 | ASET (spec_vec, 1, aliases); |
| 10016 | ASET (spec_vec, 2, eol_type); | 10008 | ASET (spec_vec, 2, eol_type); |
| 10017 | 10009 | ||
| @@ -10308,6 +10300,7 @@ syms_of_coding (void) | |||
| 10308 | DEFSYM (Qeol_type, "eol-type"); | 10300 | DEFSYM (Qeol_type, "eol-type"); |
| 10309 | DEFSYM (Qunix, "unix"); | 10301 | DEFSYM (Qunix, "unix"); |
| 10310 | DEFSYM (Qdos, "dos"); | 10302 | DEFSYM (Qdos, "dos"); |
| 10303 | DEFSYM (Qmac, "mac"); | ||
| 10311 | 10304 | ||
| 10312 | DEFSYM (Qbuffer_file_coding_system, "buffer-file-coding-system"); | 10305 | DEFSYM (Qbuffer_file_coding_system, "buffer-file-coding-system"); |
| 10313 | DEFSYM (Qpost_read_conversion, "post-read-conversion"); | 10306 | DEFSYM (Qpost_read_conversion, "post-read-conversion"); |
| @@ -10719,7 +10712,7 @@ reading if you suppress escape sequence detection. | |||
| 10719 | 10712 | ||
| 10720 | The other way to read escape sequences in a file without decoding is | 10713 | The other way to read escape sequences in a file without decoding is |
| 10721 | to explicitly specify some coding system that doesn't use ISO-2022 | 10714 | to explicitly specify some coding system that doesn't use ISO-2022 |
| 10722 | escape sequence (e.g `latin-1') on reading by \\[universal-coding-system-argument]. */); | 10715 | escape sequence (e.g., `latin-1') on reading by \\[universal-coding-system-argument]. */); |
| 10723 | inhibit_iso_escape_detection = 0; | 10716 | inhibit_iso_escape_detection = 0; |
| 10724 | 10717 | ||
| 10725 | DEFVAR_BOOL ("inhibit-null-byte-detection", | 10718 | DEFVAR_BOOL ("inhibit-null-byte-detection", |
diff --git a/src/coding.h b/src/coding.h index 192be58f083..eb95fa13ddb 100644 --- a/src/coding.h +++ b/src/coding.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Header for coding system handler. | 1 | /* Header for coding system handler. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -767,7 +767,7 @@ extern Lisp_Object Qcoding_system_p; | |||
| 767 | extern Lisp_Object Qraw_text, Qemacs_mule, Qno_conversion, Qundecided; | 767 | extern Lisp_Object Qraw_text, Qemacs_mule, Qno_conversion, Qundecided; |
| 768 | extern Lisp_Object Qbuffer_file_coding_system; | 768 | extern Lisp_Object Qbuffer_file_coding_system; |
| 769 | 769 | ||
| 770 | extern Lisp_Object Qunix, Qdos, Qmac; | 770 | extern Lisp_Object Qunix, Qdos; |
| 771 | 771 | ||
| 772 | extern Lisp_Object Qtranslation_table; | 772 | extern Lisp_Object Qtranslation_table; |
| 773 | extern Lisp_Object Qtranslation_table_id; | 773 | extern Lisp_Object Qtranslation_table_id; |
diff --git a/src/commands.h b/src/commands.h index 510fce0e182..35c2c05fe72 100644 --- a/src/commands.h +++ b/src/commands.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions needed by most editing commands. | 1 | /* Definitions needed by most editing commands. |
| 2 | Copyright (C) 1985, 1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/composite.c b/src/composite.c index bcde0a4c9e6..2da98cfc36c 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Composite sequence support. | 1 | /* Composite sequence support. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H14PRO021 | 5 | Registration Number H14PRO021 |
| @@ -642,13 +642,7 @@ compose_text (ptrdiff_t start, ptrdiff_t end, Lisp_Object components, | |||
| 642 | Qcomposition, prop, string); | 642 | Qcomposition, prop, string); |
| 643 | } | 643 | } |
| 644 | 644 | ||
| 645 | 645 | /* Lisp glyph-string handlers. */ | |
| 646 | static Lisp_Object autocmp_chars (Lisp_Object, ptrdiff_t, ptrdiff_t, | ||
| 647 | ptrdiff_t, struct window *, | ||
| 648 | struct face *, Lisp_Object); | ||
| 649 | |||
| 650 | |||
| 651 | /* Lisp glyph-string handlers */ | ||
| 652 | 646 | ||
| 653 | /* Hash table for automatic composition. The key is a header of a | 647 | /* Hash table for automatic composition. The key is a header of a |
| 654 | lgstring (Lispy glyph-string), and the value is a body of a | 648 | lgstring (Lispy glyph-string), and the value is a body of a |
| @@ -704,10 +698,6 @@ composition_gstring_from_id (ptrdiff_t id) | |||
| 704 | return HASH_VALUE (h, id); | 698 | return HASH_VALUE (h, id); |
| 705 | } | 699 | } |
| 706 | 700 | ||
| 707 | static Lisp_Object fill_gstring_header (Lisp_Object, Lisp_Object, | ||
| 708 | Lisp_Object, Lisp_Object, | ||
| 709 | Lisp_Object); | ||
| 710 | |||
| 711 | bool | 701 | bool |
| 712 | composition_gstring_p (Lisp_Object gstring) | 702 | composition_gstring_p (Lisp_Object gstring) |
| 713 | { | 703 | { |
| @@ -797,7 +787,8 @@ static Lisp_Object gstring_work; | |||
| 797 | static Lisp_Object gstring_work_headers; | 787 | static Lisp_Object gstring_work_headers; |
| 798 | 788 | ||
| 799 | static Lisp_Object | 789 | static Lisp_Object |
| 800 | fill_gstring_header (Lisp_Object header, Lisp_Object start, Lisp_Object end, Lisp_Object font_object, Lisp_Object string) | 790 | fill_gstring_header (Lisp_Object header, Lisp_Object start, Lisp_Object end, |
| 791 | Lisp_Object font_object, Lisp_Object string) | ||
| 801 | { | 792 | { |
| 802 | ptrdiff_t from, to, from_byte; | 793 | ptrdiff_t from, to, from_byte; |
| 803 | ptrdiff_t len, i; | 794 | ptrdiff_t len, i; |
| @@ -905,7 +896,9 @@ fill_gstring_body (Lisp_Object gstring) | |||
| 905 | object. Otherwise return nil. */ | 896 | object. Otherwise return nil. */ |
| 906 | 897 | ||
| 907 | static Lisp_Object | 898 | static Lisp_Object |
| 908 | autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t limit, struct window *win, struct face *face, Lisp_Object string) | 899 | autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, |
| 900 | ptrdiff_t limit, struct window *win, struct face *face, | ||
| 901 | Lisp_Object string) | ||
| 909 | { | 902 | { |
| 910 | ptrdiff_t count = SPECPDL_INDEX (); | 903 | ptrdiff_t count = SPECPDL_INDEX (); |
| 911 | FRAME_PTR f = XFRAME (win->frame); | 904 | FRAME_PTR f = XFRAME (win->frame); |
| @@ -935,7 +928,7 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t | |||
| 935 | #ifdef HAVE_WINDOW_SYSTEM | 928 | #ifdef HAVE_WINDOW_SYSTEM |
| 936 | if (FRAME_WINDOW_P (f)) | 929 | if (FRAME_WINDOW_P (f)) |
| 937 | { | 930 | { |
| 938 | font_object = font_range (charpos, &to, win, face, string); | 931 | font_object = font_range (charpos, bytepos, &to, win, face, string); |
| 939 | if (! FONT_OBJECT_P (font_object) | 932 | if (! FONT_OBJECT_P (font_object) |
| 940 | || (! NILP (re) | 933 | || (! NILP (re) |
| 941 | && to < limit | 934 | && to < limit |
| @@ -1958,7 +1951,7 @@ syms_of_composite (void) | |||
| 1958 | } | 1951 | } |
| 1959 | 1952 | ||
| 1960 | staticpro (&gstring_work_headers); | 1953 | staticpro (&gstring_work_headers); |
| 1961 | gstring_work_headers = Fmake_vector (make_number (8), Qnil); | 1954 | gstring_work_headers = make_uninit_vector (8); |
| 1962 | for (i = 0; i < 8; i++) | 1955 | for (i = 0; i < 8; i++) |
| 1963 | ASET (gstring_work_headers, i, Fmake_vector (make_number (i + 2), Qnil)); | 1956 | ASET (gstring_work_headers, i, Fmake_vector (make_number (i + 2), Qnil)); |
| 1964 | staticpro (&gstring_work); | 1957 | staticpro (&gstring_work); |
diff --git a/src/composite.h b/src/composite.h index 9462b932c66..603291044bc 100644 --- a/src/composite.h +++ b/src/composite.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Header for composite sequence handler. | 1 | /* Header for composite sequence handler. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H14PRO021 | 5 | Registration Number H14PRO021 |
diff --git a/src/conf_post.h b/src/conf_post.h index b1997e79081..6c9747a436c 100644 --- a/src/conf_post.h +++ b/src/conf_post.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* conf_post.h --- configure.ac includes this via AH_BOTTOM | 1 | /* conf_post.h --- configure.ac includes this via AH_BOTTOM |
| 2 | 2 | ||
| 3 | Copyright (C) 1988, 1993-1994, 1999-2002, 2004-2012 | 3 | Copyright (C) 1988, 1993-1994, 1999-2002, 2004-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -40,6 +40,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 40 | #endif | 40 | #endif |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #ifndef __has_attribute | ||
| 44 | # define __has_attribute(a) 0 /* non-clang */ | ||
| 45 | #endif | ||
| 46 | |||
| 43 | /* This silences a few compilation warnings on FreeBSD. */ | 47 | /* This silences a few compilation warnings on FreeBSD. */ |
| 44 | #ifdef BSD_SYSTEM_AHB | 48 | #ifdef BSD_SYSTEM_AHB |
| 45 | #undef BSD_SYSTEM_AHB | 49 | #undef BSD_SYSTEM_AHB |
| @@ -178,10 +182,6 @@ extern void _DebPrint (const char *fmt, ...); | |||
| 178 | #endif | 182 | #endif |
| 179 | #endif | 183 | #endif |
| 180 | 184 | ||
| 181 | /* Tell gnulib to omit support for openat-related functions having a | ||
| 182 | first argument other than AT_FDCWD. */ | ||
| 183 | #define GNULIB_SUPPORT_ONLY_AT_FDCWD | ||
| 184 | |||
| 185 | #include <string.h> | 185 | #include <string.h> |
| 186 | #include <stdlib.h> | 186 | #include <stdlib.h> |
| 187 | 187 | ||
| @@ -191,7 +191,9 @@ extern void _DebPrint (const char *fmt, ...); | |||
| 191 | #define NO_INLINE | 191 | #define NO_INLINE |
| 192 | #endif | 192 | #endif |
| 193 | 193 | ||
| 194 | #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) | 194 | #if (__clang__ \ |
| 195 | ? __has_attribute (externally_visible) \ | ||
| 196 | : (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))) | ||
| 195 | #define EXTERNALLY_VISIBLE __attribute__((externally_visible)) | 197 | #define EXTERNALLY_VISIBLE __attribute__((externally_visible)) |
| 196 | #else | 198 | #else |
| 197 | #define EXTERNALLY_VISIBLE | 199 | #define EXTERNALLY_VISIBLE |
diff --git a/src/cygw32.c b/src/cygw32.c index d9777d5e22e..a7dbdaed615 100644 --- a/src/cygw32.c +++ b/src/cygw32.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Cygwin support routines. | 1 | /* Cygwin support routines. |
| 2 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -110,23 +110,25 @@ DEFUN ("cygwin-convert-file-name-to-windows", | |||
| 110 | Fcygwin_convert_file_name_to_windows, | 110 | Fcygwin_convert_file_name_to_windows, |
| 111 | Scygwin_convert_file_name_to_windows, | 111 | Scygwin_convert_file_name_to_windows, |
| 112 | 1, 2, 0, | 112 | 1, 2, 0, |
| 113 | doc: /* Convert PATH to a Windows path. If ABSOLUTE-P is | 113 | doc: /* Convert a Cygwin file name FILE to a Windows-style file name. |
| 114 | non-nil, return an absolute path.*/) | 114 | If ABSOLUTE-P is non-nil, return an absolute file name. |
| 115 | (Lisp_Object path, Lisp_Object absolute_p) | 115 | For the reverse operation, see `cygwin-convert-file-name-from-windows'. */) |
| 116 | (Lisp_Object file, Lisp_Object absolute_p) | ||
| 116 | { | 117 | { |
| 117 | return from_unicode ( | 118 | return from_unicode ( |
| 118 | conv_filename_to_w32_unicode (path, EQ (absolute_p, Qnil) ? 0 : 1)); | 119 | conv_filename_to_w32_unicode (file, EQ (absolute_p, Qnil) ? 0 : 1)); |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | DEFUN ("cygwin-convert-file-name-from-windows", | 122 | DEFUN ("cygwin-convert-file-name-from-windows", |
| 122 | Fcygwin_convert_file_name_from_windows, | 123 | Fcygwin_convert_file_name_from_windows, |
| 123 | Scygwin_convert_file_name_from_windows, | 124 | Scygwin_convert_file_name_from_windows, |
| 124 | 1, 2, 0, | 125 | 1, 2, 0, |
| 125 | doc: /* Convert a Windows path to a Cygwin path. If ABSOLUTE-P | 126 | doc: /* Convert a Windows-style file name FILE to a Cygwin file name. |
| 126 | is non-nil, return an absolute path.*/) | 127 | If ABSOLUTE-P is non-nil, return an absolute file name. |
| 127 | (Lisp_Object path, Lisp_Object absolute_p) | 128 | For the reverse operation, see `cygwin-convert-file-name-to-windows'. */) |
| 129 | (Lisp_Object file, Lisp_Object absolute_p) | ||
| 128 | { | 130 | { |
| 129 | return conv_filename_from_w32_unicode (to_unicode (path, &path), | 131 | return conv_filename_from_w32_unicode (to_unicode (file, &file), |
| 130 | EQ (absolute_p, Qnil) ? 0 : 1); | 132 | EQ (absolute_p, Qnil) ? 0 : 1); |
| 131 | } | 133 | } |
| 132 | 134 | ||
diff --git a/src/cygw32.h b/src/cygw32.h index 51571913fd1..5c7066f26d1 100644 --- a/src/cygw32.h +++ b/src/cygw32.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Header for Cygwin support routines. | 1 | /* Header for Cygwin support routines. |
| 2 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/data.c b/src/data.c index a72fa3e2b5f..6622088b648 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter. | 1 | /* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter. |
| 2 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2012 | 2 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -583,7 +583,7 @@ DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, | |||
| 583 | (register Lisp_Object symbol) | 583 | (register Lisp_Object symbol) |
| 584 | { | 584 | { |
| 585 | CHECK_SYMBOL (symbol); | 585 | CHECK_SYMBOL (symbol); |
| 586 | return XSYMBOL (symbol)->function; | 586 | return XSYMBOL (symbol)->function; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, | 589 | DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, |
| @@ -914,13 +914,11 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva | |||
| 914 | case Lisp_Fwd_Buffer_Obj: | 914 | case Lisp_Fwd_Buffer_Obj: |
| 915 | { | 915 | { |
| 916 | int offset = XBUFFER_OBJFWD (valcontents)->offset; | 916 | int offset = XBUFFER_OBJFWD (valcontents)->offset; |
| 917 | Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype; | 917 | Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate; |
| 918 | 918 | ||
| 919 | if (!(NILP (type) || NILP (newval) | 919 | if (!NILP (predicate) && !NILP (newval) |
| 920 | || (XINT (type) == Lisp_Int0 | 920 | && NILP (call1 (predicate, newval))) |
| 921 | ? INTEGERP (newval) | 921 | wrong_type_argument (predicate, newval); |
| 922 | : XTYPE (newval) == XINT (type)))) | ||
| 923 | buffer_slot_type_mismatch (newval, XINT (type)); | ||
| 924 | 922 | ||
| 925 | if (buf == NULL) | 923 | if (buf == NULL) |
| 926 | buf = current_buffer; | 924 | buf = current_buffer; |
diff --git a/src/dbusbind.c b/src/dbusbind.c index da8bbb1e5d7..863f7634eb5 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Elisp bindings for D-Bus. | 1 | /* Elisp bindings for D-Bus. |
| 2 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/deps.mk b/src/deps.mk index c7316a24dad..47185c9262c 100644 --- a/src/deps.mk +++ b/src/deps.mk | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ### deps.mk --- src/Makefile fragment for GNU Emacs | 1 | ### deps.mk --- src/Makefile fragment for GNU Emacs |
| 2 | 2 | ||
| 3 | ## Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2012 | 3 | ## Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2013 Free Software |
| 4 | ## Free Software Foundation, Inc. | 4 | ## Foundation, Inc. |
| 5 | 5 | ||
| 6 | ## This file is part of GNU Emacs. | 6 | ## This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -128,6 +128,7 @@ image.o: image.c frame.h window.h dispextern.h blockinput.h atimer.h \ | |||
| 128 | indent.o: indent.c frame.h window.h indent.h buffer.h lisp.h $(config_h) \ | 128 | indent.o: indent.c frame.h window.h indent.h buffer.h lisp.h $(config_h) \ |
| 129 | termchar.h termopts.h disptab.h region-cache.h character.h category.h \ | 129 | termchar.h termopts.h disptab.h region-cache.h character.h category.h \ |
| 130 | keyboard.h systime.h coding.h $(INTERVALS_H) globals.h | 130 | keyboard.h systime.h coding.h $(INTERVALS_H) globals.h |
| 131 | inotify.o: inotify.c lisp.h coding.h process.h keyboard.h frame.h termhooks.h | ||
| 131 | insdel.o: insdel.c window.h buffer.h $(INTERVALS_H) blockinput.h character.h \ | 132 | insdel.o: insdel.c window.h buffer.h $(INTERVALS_H) blockinput.h character.h \ |
| 132 | atimer.h systime.h region-cache.h lisp.h globals.h $(config_h) | 133 | atimer.h systime.h region-cache.h lisp.h globals.h $(config_h) |
| 133 | keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \ | 134 | keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \ |
diff --git a/src/dired.c b/src/dired.c index bdb71c46364..0e37568f211 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Lisp functions for making directory listings. | 1 | /* Lisp functions for making directory listings. |
| 2 | Copyright (C) 1985-1986, 1993-1994, 1999-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1986, 1993-1994, 1999-2013 Free Software |
| 3 | Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -29,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 29 | #include <grp.h> | 30 | #include <grp.h> |
| 30 | 31 | ||
| 31 | #include <errno.h> | 32 | #include <errno.h> |
| 33 | #include <fcntl.h> | ||
| 32 | #include <unistd.h> | 34 | #include <unistd.h> |
| 33 | 35 | ||
| 34 | #include <dirent.h> | 36 | #include <dirent.h> |
| @@ -53,6 +55,7 @@ static Lisp_Object Qfile_attributes; | |||
| 53 | static Lisp_Object Qfile_attributes_lessp; | 55 | static Lisp_Object Qfile_attributes_lessp; |
| 54 | 56 | ||
| 55 | static ptrdiff_t scmp (const char *, const char *, ptrdiff_t); | 57 | static ptrdiff_t scmp (const char *, const char *, ptrdiff_t); |
| 58 | static Lisp_Object file_attributes (int, char const *, Lisp_Object); | ||
| 56 | 59 | ||
| 57 | /* Return the number of bytes in DP's name. */ | 60 | /* Return the number of bytes in DP's name. */ |
| 58 | static ptrdiff_t | 61 | static ptrdiff_t |
| @@ -65,6 +68,44 @@ dirent_namelen (struct dirent *dp) | |||
| 65 | #endif | 68 | #endif |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 71 | static DIR * | ||
| 72 | open_directory (char const *name, int *fdp) | ||
| 73 | { | ||
| 74 | DIR *d; | ||
| 75 | int fd, opendir_errno; | ||
| 76 | |||
| 77 | block_input (); | ||
| 78 | |||
| 79 | #ifdef DOS_NT | ||
| 80 | /* Directories cannot be opened. The emulation assumes that any | ||
| 81 | file descriptor other than AT_FDCWD corresponds to the most | ||
| 82 | recently opened directory. This hack is good enough for Emacs. */ | ||
| 83 | fd = 0; | ||
| 84 | d = opendir (name); | ||
| 85 | opendir_errno = errno; | ||
| 86 | #else | ||
| 87 | fd = emacs_open (name, O_RDONLY | O_DIRECTORY, 0); | ||
| 88 | if (fd < 0) | ||
| 89 | { | ||
| 90 | opendir_errno = errno; | ||
| 91 | d = 0; | ||
| 92 | } | ||
| 93 | else | ||
| 94 | { | ||
| 95 | d = fdopendir (fd); | ||
| 96 | opendir_errno = errno; | ||
| 97 | if (! d) | ||
| 98 | close (fd); | ||
| 99 | } | ||
| 100 | #endif | ||
| 101 | |||
| 102 | unblock_input (); | ||
| 103 | |||
| 104 | *fdp = fd; | ||
| 105 | errno = opendir_errno; | ||
| 106 | return d; | ||
| 107 | } | ||
| 108 | |||
| 68 | #ifdef WINDOWSNT | 109 | #ifdef WINDOWSNT |
| 69 | Lisp_Object | 110 | Lisp_Object |
| 70 | directory_files_internal_w32_unwind (Lisp_Object arg) | 111 | directory_files_internal_w32_unwind (Lisp_Object arg) |
| @@ -77,7 +118,7 @@ directory_files_internal_w32_unwind (Lisp_Object arg) | |||
| 77 | static Lisp_Object | 118 | static Lisp_Object |
| 78 | directory_files_internal_unwind (Lisp_Object dh) | 119 | directory_files_internal_unwind (Lisp_Object dh) |
| 79 | { | 120 | { |
| 80 | DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer; | 121 | DIR *d = XSAVE_POINTER (dh, 0); |
| 81 | block_input (); | 122 | block_input (); |
| 82 | closedir (d); | 123 | closedir (d); |
| 83 | unblock_input (); | 124 | unblock_input (); |
| @@ -95,6 +136,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 95 | Lisp_Object id_format) | 136 | Lisp_Object id_format) |
| 96 | { | 137 | { |
| 97 | DIR *d; | 138 | DIR *d; |
| 139 | int fd; | ||
| 98 | ptrdiff_t directory_nbytes; | 140 | ptrdiff_t directory_nbytes; |
| 99 | Lisp_Object list, dirfilename, encoded_directory; | 141 | Lisp_Object list, dirfilename, encoded_directory; |
| 100 | struct re_pattern_buffer *bufp = NULL; | 142 | struct re_pattern_buffer *bufp = NULL; |
| @@ -141,9 +183,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 141 | /* Now *bufp is the compiled form of MATCH; don't call anything | 183 | /* Now *bufp is the compiled form of MATCH; don't call anything |
| 142 | which might compile a new regexp until we're done with the loop! */ | 184 | which might compile a new regexp until we're done with the loop! */ |
| 143 | 185 | ||
| 144 | block_input (); | 186 | d = open_directory (SSDATA (dirfilename), &fd); |
| 145 | d = opendir (SSDATA (dirfilename)); | ||
| 146 | unblock_input (); | ||
| 147 | if (d == NULL) | 187 | if (d == NULL) |
| 148 | report_file_error ("Opening directory", Fcons (directory, Qnil)); | 188 | report_file_error ("Opening directory", Fcons (directory, Qnil)); |
| 149 | 189 | ||
| @@ -151,7 +191,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 151 | file-attributes on filenames, both of which can throw, so we must | 191 | file-attributes on filenames, both of which can throw, so we must |
| 152 | do a proper unwind-protect. */ | 192 | do a proper unwind-protect. */ |
| 153 | record_unwind_protect (directory_files_internal_unwind, | 193 | record_unwind_protect (directory_files_internal_unwind, |
| 154 | make_save_value (d, 0)); | 194 | make_save_pointer (d)); |
| 155 | 195 | ||
| 156 | #ifdef WINDOWSNT | 196 | #ifdef WINDOWSNT |
| 157 | if (attrs) | 197 | if (attrs) |
| @@ -258,20 +298,9 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 258 | 298 | ||
| 259 | if (attrs) | 299 | if (attrs) |
| 260 | { | 300 | { |
| 261 | /* Construct an expanded filename for the directory entry. | 301 | Lisp_Object fileattrs |
| 262 | Use the decoded names for input to Ffile_attributes. */ | 302 | = file_attributes (fd, dp->d_name, id_format); |
| 263 | Lisp_Object decoded_fullname, fileattrs; | ||
| 264 | struct gcpro gcpro1, gcpro2; | ||
| 265 | |||
| 266 | decoded_fullname = fileattrs = Qnil; | ||
| 267 | GCPRO2 (decoded_fullname, fileattrs); | ||
| 268 | |||
| 269 | /* Both Fexpand_file_name and Ffile_attributes can GC. */ | ||
| 270 | decoded_fullname = Fexpand_file_name (name, directory); | ||
| 271 | fileattrs = Ffile_attributes (decoded_fullname, id_format); | ||
| 272 | |||
| 273 | list = Fcons (Fcons (finalname, fileattrs), list); | 303 | list = Fcons (Fcons (finalname, fileattrs), list); |
| 274 | UNGCPRO; | ||
| 275 | } | 304 | } |
| 276 | else | 305 | else |
| 277 | list = Fcons (finalname, list); | 306 | list = Fcons (finalname, list); |
| @@ -412,8 +441,7 @@ These are all file names in directory DIRECTORY which begin with FILE. */) | |||
| 412 | return file_name_completion (file, directory, 1, Qnil); | 441 | return file_name_completion (file, directory, 1, Qnil); |
| 413 | } | 442 | } |
| 414 | 443 | ||
| 415 | static int file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, | 444 | static int file_name_completion_stat (int, struct dirent *, struct stat *); |
| 416 | struct stat *st_addr); | ||
| 417 | static Lisp_Object Qdefault_directory; | 445 | static Lisp_Object Qdefault_directory; |
| 418 | 446 | ||
| 419 | static Lisp_Object | 447 | static Lisp_Object |
| @@ -421,6 +449,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 421 | Lisp_Object predicate) | 449 | Lisp_Object predicate) |
| 422 | { | 450 | { |
| 423 | DIR *d; | 451 | DIR *d; |
| 452 | int fd; | ||
| 424 | ptrdiff_t bestmatchsize = 0; | 453 | ptrdiff_t bestmatchsize = 0; |
| 425 | int matchcount = 0; | 454 | int matchcount = 0; |
| 426 | /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded. | 455 | /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded. |
| @@ -455,16 +484,14 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 455 | on the encoded file name. */ | 484 | on the encoded file name. */ |
| 456 | encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file; | 485 | encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file; |
| 457 | 486 | ||
| 458 | encoded_dir = ENCODE_FILE (dirname); | 487 | encoded_dir = ENCODE_FILE (Fdirectory_file_name (dirname)); |
| 459 | 488 | ||
| 460 | block_input (); | 489 | d = open_directory (SSDATA (encoded_dir), &fd); |
| 461 | d = opendir (SSDATA (Fdirectory_file_name (encoded_dir))); | ||
| 462 | unblock_input (); | ||
| 463 | if (!d) | 490 | if (!d) |
| 464 | report_file_error ("Opening directory", Fcons (dirname, Qnil)); | 491 | report_file_error ("Opening directory", Fcons (dirname, Qnil)); |
| 465 | 492 | ||
| 466 | record_unwind_protect (directory_files_internal_unwind, | 493 | record_unwind_protect (directory_files_internal_unwind, |
| 467 | make_save_value (d, 0)); | 494 | make_save_pointer (d)); |
| 468 | 495 | ||
| 469 | /* Loop reading blocks */ | 496 | /* Loop reading blocks */ |
| 470 | /* (att3b compiler bug requires do a null comparison this way) */ | 497 | /* (att3b compiler bug requires do a null comparison this way) */ |
| @@ -494,7 +521,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 494 | SCHARS (encoded_file))) | 521 | SCHARS (encoded_file))) |
| 495 | continue; | 522 | continue; |
| 496 | 523 | ||
| 497 | if (file_name_completion_stat (encoded_dir, dp, &st) < 0) | 524 | if (file_name_completion_stat (fd, dp, &st) < 0) |
| 498 | continue; | 525 | continue; |
| 499 | 526 | ||
| 500 | directoryp = S_ISDIR (st.st_mode) != 0; | 527 | directoryp = S_ISDIR (st.st_mode) != 0; |
| @@ -671,10 +698,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 671 | name, zero, | 698 | name, zero, |
| 672 | make_number (compare), | 699 | make_number (compare), |
| 673 | completion_ignore_case ? Qt : Qnil); | 700 | completion_ignore_case ? Qt : Qnil); |
| 674 | ptrdiff_t matchsize | 701 | ptrdiff_t matchsize = EQ (cmp, Qt) ? compare : eabs (XINT (cmp)) - 1; |
| 675 | = (EQ (cmp, Qt) ? compare | ||
| 676 | : XINT (cmp) < 0 ? - XINT (cmp) - 1 | ||
| 677 | : XINT (cmp) - 1); | ||
| 678 | 702 | ||
| 679 | if (completion_ignore_case) | 703 | if (completion_ignore_case) |
| 680 | { | 704 | { |
| @@ -774,14 +798,9 @@ scmp (const char *s1, const char *s2, ptrdiff_t len) | |||
| 774 | } | 798 | } |
| 775 | 799 | ||
| 776 | static int | 800 | static int |
| 777 | file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, | 801 | file_name_completion_stat (int fd, struct dirent *dp, struct stat *st_addr) |
| 778 | struct stat *st_addr) | ||
| 779 | { | 802 | { |
| 780 | ptrdiff_t len = dirent_namelen (dp); | ||
| 781 | ptrdiff_t pos = SCHARS (dirname); | ||
| 782 | int value; | 803 | int value; |
| 783 | USE_SAFE_ALLOCA; | ||
| 784 | char *fullname = SAFE_ALLOCA (len + pos + 2); | ||
| 785 | 804 | ||
| 786 | #ifdef MSDOS | 805 | #ifdef MSDOS |
| 787 | /* Some fields of struct stat are *very* expensive to compute on MS-DOS, | 806 | /* Some fields of struct stat are *very* expensive to compute on MS-DOS, |
| @@ -794,23 +813,15 @@ file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, | |||
| 794 | _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; | 813 | _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; |
| 795 | #endif /* MSDOS */ | 814 | #endif /* MSDOS */ |
| 796 | 815 | ||
| 797 | memcpy (fullname, SDATA (dirname), pos); | ||
| 798 | if (!IS_DIRECTORY_SEP (fullname[pos - 1])) | ||
| 799 | fullname[pos++] = DIRECTORY_SEP; | ||
| 800 | |||
| 801 | memcpy (fullname + pos, dp->d_name, len); | ||
| 802 | fullname[pos + len] = 0; | ||
| 803 | |||
| 804 | /* We want to return success if a link points to a nonexistent file, | 816 | /* We want to return success if a link points to a nonexistent file, |
| 805 | but we want to return the status for what the link points to, | 817 | but we want to return the status for what the link points to, |
| 806 | in case it is a directory. */ | 818 | in case it is a directory. */ |
| 807 | value = lstat (fullname, st_addr); | 819 | value = fstatat (fd, dp->d_name, st_addr, AT_SYMLINK_NOFOLLOW); |
| 808 | if (value == 0 && S_ISLNK (st_addr->st_mode)) | 820 | if (value == 0 && S_ISLNK (st_addr->st_mode)) |
| 809 | stat (fullname, st_addr); | 821 | fstatat (fd, dp->d_name, st_addr, 0); |
| 810 | #ifdef MSDOS | 822 | #ifdef MSDOS |
| 811 | _djstat_flags = save_djstat_flags; | 823 | _djstat_flags = save_djstat_flags; |
| 812 | #endif /* MSDOS */ | 824 | #endif /* MSDOS */ |
| 813 | SAFE_FREE (); | ||
| 814 | return value; | 825 | return value; |
| 815 | } | 826 | } |
| 816 | 827 | ||
| @@ -869,7 +880,7 @@ Elements of the attribute list are: | |||
| 869 | 7. Size in bytes. | 880 | 7. Size in bytes. |
| 870 | This is a floating point number if the size is too large for an integer. | 881 | This is a floating point number if the size is too large for an integer. |
| 871 | 8. File modes, as a string of ten letters or dashes as in ls -l. | 882 | 8. File modes, as a string of ten letters or dashes as in ls -l. |
| 872 | 9. t if file's gid would change if file were deleted and recreated. | 883 | 9. An unspecified value, present only for backward compatibility. |
| 873 | 10. inode number. If it is larger than what an Emacs integer can hold, | 884 | 10. inode number. If it is larger than what an Emacs integer can hold, |
| 874 | this is of the form (HIGH . LOW): first the high bits, then the low 16 bits. | 885 | this is of the form (HIGH . LOW): first the high bits, then the low 16 bits. |
| 875 | If even HIGH is too large for an Emacs integer, this is instead of the form | 886 | If even HIGH is too large for an Emacs integer, this is instead of the form |
| @@ -888,21 +899,8 @@ On some FAT-based filesystems, only the date of last access is recorded, | |||
| 888 | so last access time will always be midnight of that day. */) | 899 | so last access time will always be midnight of that day. */) |
| 889 | (Lisp_Object filename, Lisp_Object id_format) | 900 | (Lisp_Object filename, Lisp_Object id_format) |
| 890 | { | 901 | { |
| 891 | Lisp_Object values[12]; | ||
| 892 | Lisp_Object encoded; | 902 | Lisp_Object encoded; |
| 893 | struct stat s; | ||
| 894 | #ifdef BSD4_2 | ||
| 895 | Lisp_Object dirname; | ||
| 896 | struct stat sdir; | ||
| 897 | #endif /* BSD4_2 */ | ||
| 898 | |||
| 899 | /* An array to hold the mode string generated by filemodestring, | ||
| 900 | including its terminating space and null byte. */ | ||
| 901 | char modes[sizeof "-rwxr-xr-x "]; | ||
| 902 | |||
| 903 | Lisp_Object handler; | 903 | Lisp_Object handler; |
| 904 | struct gcpro gcpro1; | ||
| 905 | char *uname = NULL, *gname = NULL; | ||
| 906 | 904 | ||
| 907 | filename = Fexpand_file_name (filename, Qnil); | 905 | filename = Fexpand_file_name (filename, Qnil); |
| 908 | 906 | ||
| @@ -918,14 +916,41 @@ so last access time will always be midnight of that day. */) | |||
| 918 | return call3 (handler, Qfile_attributes, filename, id_format); | 916 | return call3 (handler, Qfile_attributes, filename, id_format); |
| 919 | } | 917 | } |
| 920 | 918 | ||
| 921 | GCPRO1 (filename); | ||
| 922 | encoded = ENCODE_FILE (filename); | 919 | encoded = ENCODE_FILE (filename); |
| 923 | UNGCPRO; | 920 | return file_attributes (AT_FDCWD, SSDATA (encoded), id_format); |
| 921 | } | ||
| 922 | |||
| 923 | static Lisp_Object | ||
| 924 | file_attributes (int fd, char const *name, Lisp_Object id_format) | ||
| 925 | { | ||
| 926 | Lisp_Object values[12]; | ||
| 927 | struct stat s; | ||
| 928 | int lstat_result; | ||
| 929 | |||
| 930 | /* An array to hold the mode string generated by filemodestring, | ||
| 931 | including its terminating space and null byte. */ | ||
| 932 | char modes[sizeof "-rwxr-xr-x "]; | ||
| 933 | |||
| 934 | char *uname = NULL, *gname = NULL; | ||
| 935 | |||
| 936 | #ifdef WINDOWSNT | ||
| 937 | /* We usually don't request accurate owner and group info, because | ||
| 938 | it can be very expensive on Windows to get that, and most callers | ||
| 939 | of 'lstat' don't need that. But here we do want that information | ||
| 940 | to be accurate. */ | ||
| 941 | w32_stat_get_owner_group = 1; | ||
| 942 | #endif | ||
| 943 | |||
| 944 | lstat_result = fstatat (fd, name, &s, AT_SYMLINK_NOFOLLOW); | ||
| 945 | |||
| 946 | #ifdef WINDOWSNT | ||
| 947 | w32_stat_get_owner_group = 0; | ||
| 948 | #endif | ||
| 924 | 949 | ||
| 925 | if (lstat (SSDATA (encoded), &s) < 0) | 950 | if (lstat_result < 0) |
| 926 | return Qnil; | 951 | return Qnil; |
| 927 | 952 | ||
| 928 | values[0] = (S_ISLNK (s.st_mode) ? Ffile_symlink_p (filename) | 953 | values[0] = (S_ISLNK (s.st_mode) ? emacs_readlinkat (fd, name) |
| 929 | : S_ISDIR (s.st_mode) ? Qt : Qnil); | 954 | : S_ISDIR (s.st_mode) ? Qt : Qnil); |
| 930 | values[1] = make_number (s.st_nlink); | 955 | values[1] = make_number (s.st_nlink); |
| 931 | 956 | ||
| @@ -959,17 +984,7 @@ so last access time will always be midnight of that day. */) | |||
| 959 | 984 | ||
| 960 | filemodestring (&s, modes); | 985 | filemodestring (&s, modes); |
| 961 | values[8] = make_string (modes, 10); | 986 | values[8] = make_string (modes, 10); |
| 962 | #ifdef BSD4_2 /* file gid will be dir gid */ | 987 | values[9] = Qt; |
| 963 | dirname = Ffile_name_directory (filename); | ||
| 964 | if (! NILP (dirname)) | ||
| 965 | encoded = ENCODE_FILE (dirname); | ||
| 966 | if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0) | ||
| 967 | values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; | ||
| 968 | else /* if we can't tell, assume worst */ | ||
| 969 | values[9] = Qt; | ||
| 970 | #else /* file gid will be egid */ | ||
| 971 | values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; | ||
| 972 | #endif /* not BSD4_2 */ | ||
| 973 | values[10] = INTEGER_TO_CONS (s.st_ino); | 988 | values[10] = INTEGER_TO_CONS (s.st_ino); |
| 974 | values[11] = INTEGER_TO_CONS (s.st_dev); | 989 | values[11] = INTEGER_TO_CONS (s.st_dev); |
| 975 | 990 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index aa40f019fbe..46878745c07 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Interface definitions for display code. | 1 | /* Interface definitions for display code. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985, 1993-1994, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985, 1993-1994, 1997-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -317,13 +317,18 @@ struct glyph | |||
| 317 | Lisp string, this is a position in that string. If it is a | 317 | Lisp string, this is a position in that string. If it is a |
| 318 | buffer, this is a position in that buffer. A value of -1 | 318 | buffer, this is a position in that buffer. A value of -1 |
| 319 | together with a null object means glyph is a truncation glyph at | 319 | together with a null object means glyph is a truncation glyph at |
| 320 | the start of a row. */ | 320 | the start of a row. Right truncation and continuation glyphs at |
| 321 | the right edge of a row have their position set to the next | ||
| 322 | buffer position that is not shown on this row. Glyphs inserted | ||
| 323 | by redisplay, such as the empty space after the end of a line on | ||
| 324 | TTYs, or the overlay-arrow on a TTY, have this set to -1. */ | ||
| 321 | ptrdiff_t charpos; | 325 | ptrdiff_t charpos; |
| 322 | 326 | ||
| 323 | /* Lisp object source of this glyph. Currently either a buffer or | 327 | /* Lisp object source of this glyph. Currently either a buffer or a |
| 324 | a string, if the glyph was produced from characters which came from | 328 | string, if the glyph was produced from characters which came from |
| 325 | a buffer or a string; or 0 if the glyph was inserted by redisplay | 329 | a buffer or a string; or 0 if the glyph was inserted by redisplay |
| 326 | for its own purposes such as padding. */ | 330 | for its own purposes, such as padding or truncation/continuation |
| 331 | glyphs, or the overlay-arrow glyphs on TTYs. */ | ||
| 327 | Lisp_Object object; | 332 | Lisp_Object object; |
| 328 | 333 | ||
| 329 | /* Width in pixels. */ | 334 | /* Width in pixels. */ |
diff --git a/src/dispnew.c b/src/dispnew.c index 675c06c22e9..f9fed7de406 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Updating of data structures for redisplay. | 1 | /* Updating of data structures for redisplay. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -86,7 +87,6 @@ static void build_frame_matrix_from_window_tree (struct glyph_matrix *, | |||
| 86 | struct window *); | 87 | struct window *); |
| 87 | static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, | 88 | static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, |
| 88 | struct window *); | 89 | struct window *); |
| 89 | static void adjust_frame_message_buffer (struct frame *); | ||
| 90 | static void adjust_decode_mode_spec_buffer (struct frame *); | 90 | static void adjust_decode_mode_spec_buffer (struct frame *); |
| 91 | static void fill_up_glyph_row_with_spaces (struct glyph_row *); | 91 | static void fill_up_glyph_row_with_spaces (struct glyph_row *); |
| 92 | static void clear_window_matrices (struct window *, bool); | 92 | static void clear_window_matrices (struct window *, bool); |
| @@ -107,12 +107,6 @@ static void set_window_cursor_after_update (struct window *); | |||
| 107 | static void adjust_frame_glyphs_for_window_redisplay (struct frame *); | 107 | static void adjust_frame_glyphs_for_window_redisplay (struct frame *); |
| 108 | static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); | 108 | static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); |
| 109 | 109 | ||
| 110 | |||
| 111 | /* Redisplay preemption timers. */ | ||
| 112 | |||
| 113 | static EMACS_TIME preemption_period; | ||
| 114 | static EMACS_TIME preemption_next_check; | ||
| 115 | |||
| 116 | /* True upon entry to redisplay means do not assume anything about | 110 | /* True upon entry to redisplay means do not assume anything about |
| 117 | current contents of actual terminal frame; clear and redraw it. */ | 111 | current contents of actual terminal frame; clear and redraw it. */ |
| 118 | 112 | ||
| @@ -606,7 +600,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y | |||
| 606 | are invalidated below. */ | 600 | are invalidated below. */ |
| 607 | if (INTEGERP (w->window_end_vpos) | 601 | if (INTEGERP (w->window_end_vpos) |
| 608 | && XFASTINT (w->window_end_vpos) >= i) | 602 | && XFASTINT (w->window_end_vpos) >= i) |
| 609 | wset_window_end_valid (w, Qnil); | 603 | w->window_end_valid = 0; |
| 610 | 604 | ||
| 611 | while (i < matrix->nrows) | 605 | while (i < matrix->nrows) |
| 612 | matrix->rows[i++].enabled_p = 0; | 606 | matrix->rows[i++].enabled_p = 0; |
| @@ -861,7 +855,7 @@ clear_window_matrices (struct window *w, bool desired_p) | |||
| 861 | else | 855 | else |
| 862 | { | 856 | { |
| 863 | clear_glyph_matrix (w->current_matrix); | 857 | clear_glyph_matrix (w->current_matrix); |
| 864 | wset_window_end_valid (w, Qnil); | 858 | w->window_end_valid = 0; |
| 865 | } | 859 | } |
| 866 | } | 860 | } |
| 867 | 861 | ||
| @@ -1856,9 +1850,7 @@ adjust_frame_glyphs (struct frame *f) | |||
| 1856 | else | 1850 | else |
| 1857 | adjust_frame_glyphs_for_frame_redisplay (f); | 1851 | adjust_frame_glyphs_for_frame_redisplay (f); |
| 1858 | 1852 | ||
| 1859 | /* Don't forget the message buffer and the buffer for | 1853 | /* Don't forget the buffer for decode_mode_spec. */ |
| 1860 | decode_mode_spec. */ | ||
| 1861 | adjust_frame_message_buffer (f); | ||
| 1862 | adjust_decode_mode_spec_buffer (f); | 1854 | adjust_decode_mode_spec_buffer (f); |
| 1863 | 1855 | ||
| 1864 | f->glyphs_initialized_p = 1; | 1856 | f->glyphs_initialized_p = 1; |
| @@ -2158,23 +2150,6 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f) | |||
| 2158 | } | 2150 | } |
| 2159 | 2151 | ||
| 2160 | 2152 | ||
| 2161 | /* Adjust/ allocate message buffer of frame F. | ||
| 2162 | |||
| 2163 | Note that the message buffer is never freed. Since I could not | ||
| 2164 | find a free in 19.34, I assume that freeing it would be | ||
| 2165 | problematic in some way and don't do it either. | ||
| 2166 | |||
| 2167 | (Implementation note: It should be checked if we can free it | ||
| 2168 | eventually without causing trouble). */ | ||
| 2169 | |||
| 2170 | static void | ||
| 2171 | adjust_frame_message_buffer (struct frame *f) | ||
| 2172 | { | ||
| 2173 | FRAME_MESSAGE_BUF (f) = xrealloc (FRAME_MESSAGE_BUF (f), | ||
| 2174 | FRAME_MESSAGE_BUF_SIZE (f) + 1); | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | |||
| 2178 | /* Re-allocate buffer for decode_mode_spec on frame F. */ | 2153 | /* Re-allocate buffer for decode_mode_spec on frame F. */ |
| 2179 | 2154 | ||
| 2180 | static void | 2155 | static void |
| @@ -3099,21 +3074,10 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p) | |||
| 3099 | 3074 | ||
| 3100 | if (redisplay_dont_pause) | 3075 | if (redisplay_dont_pause) |
| 3101 | force_p = 1; | 3076 | force_p = 1; |
| 3102 | else if (NILP (Vredisplay_preemption_period)) | 3077 | else if (!force_p && detect_input_pending_ignore_squeezables ()) |
| 3103 | force_p = 1; | ||
| 3104 | else if (!force_p && NUMBERP (Vredisplay_preemption_period)) | ||
| 3105 | { | 3078 | { |
| 3106 | double p = XFLOATINT (Vredisplay_preemption_period); | 3079 | paused_p = 1; |
| 3107 | 3080 | goto do_pause; | |
| 3108 | if (detect_input_pending_ignore_squeezables ()) | ||
| 3109 | { | ||
| 3110 | paused_p = 1; | ||
| 3111 | goto do_pause; | ||
| 3112 | } | ||
| 3113 | |||
| 3114 | preemption_period = EMACS_TIME_FROM_DOUBLE (p); | ||
| 3115 | preemption_next_check = add_emacs_time (current_emacs_time (), | ||
| 3116 | preemption_period); | ||
| 3117 | } | 3081 | } |
| 3118 | 3082 | ||
| 3119 | if (FRAME_WINDOW_P (f)) | 3083 | if (FRAME_WINDOW_P (f)) |
| @@ -3251,15 +3215,6 @@ update_single_window (struct window *w, bool force_p) | |||
| 3251 | 3215 | ||
| 3252 | if (redisplay_dont_pause) | 3216 | if (redisplay_dont_pause) |
| 3253 | force_p = 1; | 3217 | force_p = 1; |
| 3254 | else if (NILP (Vredisplay_preemption_period)) | ||
| 3255 | force_p = 1; | ||
| 3256 | else if (!force_p && NUMBERP (Vredisplay_preemption_period)) | ||
| 3257 | { | ||
| 3258 | double p = XFLOATINT (Vredisplay_preemption_period); | ||
| 3259 | preemption_period = EMACS_TIME_FROM_DOUBLE (p); | ||
| 3260 | preemption_next_check = add_emacs_time (current_emacs_time (), | ||
| 3261 | preemption_period); | ||
| 3262 | } | ||
| 3263 | 3218 | ||
| 3264 | /* Update W. */ | 3219 | /* Update W. */ |
| 3265 | update_begin (f); | 3220 | update_begin (f); |
| @@ -3413,9 +3368,7 @@ update_window (struct window *w, bool force_p) | |||
| 3413 | { | 3368 | { |
| 3414 | struct glyph_matrix *desired_matrix = w->desired_matrix; | 3369 | struct glyph_matrix *desired_matrix = w->desired_matrix; |
| 3415 | bool paused_p; | 3370 | bool paused_p; |
| 3416 | #if !PERIODIC_PREEMPTION_CHECKING | ||
| 3417 | int preempt_count = baud_rate / 2400 + 1; | 3371 | int preempt_count = baud_rate / 2400 + 1; |
| 3418 | #endif | ||
| 3419 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3372 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3420 | #ifdef GLYPH_DEBUG | 3373 | #ifdef GLYPH_DEBUG |
| 3421 | /* Check that W's frame doesn't have glyph matrices. */ | 3374 | /* Check that W's frame doesn't have glyph matrices. */ |
| @@ -3423,10 +3376,8 @@ update_window (struct window *w, bool force_p) | |||
| 3423 | #endif | 3376 | #endif |
| 3424 | 3377 | ||
| 3425 | /* Check pending input the first time so that we can quickly return. */ | 3378 | /* Check pending input the first time so that we can quickly return. */ |
| 3426 | #if !PERIODIC_PREEMPTION_CHECKING | ||
| 3427 | if (!force_p) | 3379 | if (!force_p) |
| 3428 | detect_input_pending_ignore_squeezables (); | 3380 | detect_input_pending_ignore_squeezables (); |
| 3429 | #endif | ||
| 3430 | 3381 | ||
| 3431 | /* If forced to complete the update, or if no input is pending, do | 3382 | /* If forced to complete the update, or if no input is pending, do |
| 3432 | the update. */ | 3383 | the update. */ |
| @@ -3437,9 +3388,7 @@ update_window (struct window *w, bool force_p) | |||
| 3437 | struct glyph_row *header_line_row; | 3388 | struct glyph_row *header_line_row; |
| 3438 | int yb; | 3389 | int yb; |
| 3439 | bool changed_p = 0, mouse_face_overwritten_p = 0; | 3390 | bool changed_p = 0, mouse_face_overwritten_p = 0; |
| 3440 | #if ! PERIODIC_PREEMPTION_CHECKING | ||
| 3441 | int n_updated = 0; | 3391 | int n_updated = 0; |
| 3442 | #endif | ||
| 3443 | 3392 | ||
| 3444 | rif->update_window_begin_hook (w); | 3393 | rif->update_window_begin_hook (w); |
| 3445 | yb = window_text_bottom_y (w); | 3394 | yb = window_text_bottom_y (w); |
| @@ -3503,22 +3452,8 @@ update_window (struct window *w, bool force_p) | |||
| 3503 | detect_input_pending. If it's done too often, | 3452 | detect_input_pending. If it's done too often, |
| 3504 | scrolling large windows with repeated scroll-up | 3453 | scrolling large windows with repeated scroll-up |
| 3505 | commands will too quickly pause redisplay. */ | 3454 | commands will too quickly pause redisplay. */ |
| 3506 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 3507 | if (!force_p) | ||
| 3508 | { | ||
| 3509 | EMACS_TIME tm = current_emacs_time (); | ||
| 3510 | if (EMACS_TIME_LT (preemption_next_check, tm)) | ||
| 3511 | { | ||
| 3512 | preemption_next_check = add_emacs_time (tm, | ||
| 3513 | preemption_period); | ||
| 3514 | if (detect_input_pending_ignore_squeezables ()) | ||
| 3515 | break; | ||
| 3516 | } | ||
| 3517 | } | ||
| 3518 | #else | ||
| 3519 | if (!force_p && ++n_updated % preempt_count == 0) | 3455 | if (!force_p && ++n_updated % preempt_count == 0) |
| 3520 | detect_input_pending_ignore_squeezables (); | 3456 | detect_input_pending_ignore_squeezables (); |
| 3521 | #endif | ||
| 3522 | changed_p |= update_window_line (w, vpos, | 3457 | changed_p |= update_window_line (w, vpos, |
| 3523 | &mouse_face_overwritten_p); | 3458 | &mouse_face_overwritten_p); |
| 3524 | 3459 | ||
| @@ -4016,11 +3951,10 @@ set_window_cursor_after_update (struct window *w) | |||
| 4016 | vpos = w->cursor.vpos; | 3951 | vpos = w->cursor.vpos; |
| 4017 | } | 3952 | } |
| 4018 | 3953 | ||
| 4019 | /* Window cursor can be out of sync for horizontally split windows. */ | 3954 | /* Window cursor can be out of sync for horizontally split windows. |
| 4020 | hpos = max (-1, hpos); /* -1 is for when cursor is on the left fringe */ | 3955 | Horizontal position is -1 when cursor is on the left fringe. */ |
| 4021 | hpos = min (w->current_matrix->matrix_w - 1, hpos); | 3956 | hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1); |
| 4022 | vpos = max (0, vpos); | 3957 | vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1); |
| 4023 | vpos = min (w->current_matrix->nrows - 1, vpos); | ||
| 4024 | rif->cursor_to (vpos, hpos, cy, cx); | 3958 | rif->cursor_to (vpos, hpos, cy, cx); |
| 4025 | } | 3959 | } |
| 4026 | 3960 | ||
| @@ -4551,13 +4485,11 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) | |||
| 4551 | if (preempt_count <= 0) | 4485 | if (preempt_count <= 0) |
| 4552 | preempt_count = 1; | 4486 | preempt_count = 1; |
| 4553 | 4487 | ||
| 4554 | #if !PERIODIC_PREEMPTION_CHECKING | ||
| 4555 | if (!force_p && detect_input_pending_ignore_squeezables ()) | 4488 | if (!force_p && detect_input_pending_ignore_squeezables ()) |
| 4556 | { | 4489 | { |
| 4557 | pause_p = 1; | 4490 | pause_p = 1; |
| 4558 | goto do_pause; | 4491 | goto do_pause; |
| 4559 | } | 4492 | } |
| 4560 | #endif | ||
| 4561 | 4493 | ||
| 4562 | /* If we cannot insert/delete lines, it's no use trying it. */ | 4494 | /* If we cannot insert/delete lines, it's no use trying it. */ |
| 4563 | if (!FRAME_LINE_INS_DEL_OK (f)) | 4495 | if (!FRAME_LINE_INS_DEL_OK (f)) |
| @@ -4598,21 +4530,8 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) | |||
| 4598 | } | 4530 | } |
| 4599 | } | 4531 | } |
| 4600 | 4532 | ||
| 4601 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 4602 | if (!force_p) | ||
| 4603 | { | ||
| 4604 | EMACS_TIME tm = current_emacs_time (); | ||
| 4605 | if (EMACS_TIME_LT (preemption_next_check, tm)) | ||
| 4606 | { | ||
| 4607 | preemption_next_check = add_emacs_time (tm, preemption_period); | ||
| 4608 | if (detect_input_pending_ignore_squeezables ()) | ||
| 4609 | break; | ||
| 4610 | } | ||
| 4611 | } | ||
| 4612 | #else | ||
| 4613 | if (!force_p && (i - 1) % preempt_count == 0) | 4533 | if (!force_p && (i - 1) % preempt_count == 0) |
| 4614 | detect_input_pending_ignore_squeezables (); | 4534 | detect_input_pending_ignore_squeezables (); |
| 4615 | #endif | ||
| 4616 | 4535 | ||
| 4617 | update_frame_line (f, i); | 4536 | update_frame_line (f, i); |
| 4618 | } | 4537 | } |
| @@ -4718,9 +4637,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) | |||
| 4718 | } | 4637 | } |
| 4719 | } | 4638 | } |
| 4720 | 4639 | ||
| 4721 | #if !PERIODIC_PREEMPTION_CHECKING | ||
| 4722 | do_pause: | 4640 | do_pause: |
| 4723 | #endif | ||
| 4724 | 4641 | ||
| 4725 | clear_desired_matrices (f); | 4642 | clear_desired_matrices (f); |
| 4726 | return pause_p; | 4643 | return pause_p; |
| @@ -6097,7 +6014,6 @@ init_display (void) | |||
| 6097 | 6014 | ||
| 6098 | inverse_video = 0; | 6015 | inverse_video = 0; |
| 6099 | cursor_in_echo_area = 0; | 6016 | cursor_in_echo_area = 0; |
| 6100 | terminal_type = (char *) 0; | ||
| 6101 | 6017 | ||
| 6102 | /* Now is the time to initialize this; it's used by init_sys_modes | 6018 | /* Now is the time to initialize this; it's used by init_sys_modes |
| 6103 | during startup. */ | 6019 | during startup. */ |
| @@ -6192,8 +6108,7 @@ init_display (void) | |||
| 6192 | #ifdef WINDOWSNT | 6108 | #ifdef WINDOWSNT |
| 6193 | terminal_type = "w32console"; | 6109 | terminal_type = "w32console"; |
| 6194 | #else | 6110 | #else |
| 6195 | /* Look at the TERM variable. */ | 6111 | terminal_type = getenv ("TERM"); |
| 6196 | terminal_type = (char *) getenv ("TERM"); | ||
| 6197 | #endif | 6112 | #endif |
| 6198 | if (!terminal_type) | 6113 | if (!terminal_type) |
| 6199 | { | 6114 | { |
| @@ -6430,15 +6345,6 @@ See `buffer-display-table' for more information. */); | |||
| 6430 | doc: /* Non-nil means display update isn't paused when input is detected. */); | 6345 | doc: /* Non-nil means display update isn't paused when input is detected. */); |
| 6431 | redisplay_dont_pause = 1; | 6346 | redisplay_dont_pause = 1; |
| 6432 | 6347 | ||
| 6433 | #if PERIODIC_PREEMPTION_CHECKING | ||
| 6434 | DEFVAR_LISP ("redisplay-preemption-period", Vredisplay_preemption_period, | ||
| 6435 | doc: /* Period in seconds between checking for input during redisplay. | ||
| 6436 | This has an effect only if `redisplay-dont-pause' is nil; in that | ||
| 6437 | case, arriving input preempts redisplay until the input is processed. | ||
| 6438 | If the value is nil, redisplay is never preempted. */); | ||
| 6439 | Vredisplay_preemption_period = make_float (0.10); | ||
| 6440 | #endif | ||
| 6441 | |||
| 6442 | #ifdef CANNOT_DUMP | 6348 | #ifdef CANNOT_DUMP |
| 6443 | if (noninteractive) | 6349 | if (noninteractive) |
| 6444 | #endif | 6350 | #endif |
diff --git a/src/disptab.h b/src/disptab.h index 2e041707eea..e02bab04bbc 100644 --- a/src/disptab.h +++ b/src/disptab.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Things for GLYPHS and glyph tables. | 1 | /* Things for GLYPHS and glyph tables. |
| 2 | Copyright (C) 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Record indices of function doc strings stored in a file. | 1 | /* Record indices of function doc strings stored in a file. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -83,24 +84,23 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) | |||
| 83 | ptrdiff_t minsize; | 84 | ptrdiff_t minsize; |
| 84 | int offset; | 85 | int offset; |
| 85 | EMACS_INT position; | 86 | EMACS_INT position; |
| 86 | Lisp_Object file, tem; | 87 | Lisp_Object file, tem, pos; |
| 87 | USE_SAFE_ALLOCA; | 88 | USE_SAFE_ALLOCA; |
| 88 | 89 | ||
| 89 | if (INTEGERP (filepos)) | 90 | if (INTEGERP (filepos)) |
| 90 | { | 91 | { |
| 91 | file = Vdoc_file_name; | 92 | file = Vdoc_file_name; |
| 92 | position = XINT (filepos); | 93 | pos = filepos; |
| 93 | } | 94 | } |
| 94 | else if (CONSP (filepos)) | 95 | else if (CONSP (filepos)) |
| 95 | { | 96 | { |
| 96 | file = XCAR (filepos); | 97 | file = XCAR (filepos); |
| 97 | position = XINT (XCDR (filepos)); | 98 | pos = XCDR (filepos); |
| 98 | } | 99 | } |
| 99 | else | 100 | else |
| 100 | return Qnil; | 101 | return Qnil; |
| 101 | 102 | ||
| 102 | if (position < 0) | 103 | position = eabs (XINT (pos)); |
| 103 | position = - position; | ||
| 104 | 104 | ||
| 105 | if (!STRINGP (Vdoc_directory)) | 105 | if (!STRINGP (Vdoc_directory)) |
| 106 | return Qnil; | 106 | return Qnil; |
| @@ -176,9 +176,9 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) | |||
| 176 | if (space_left <= 0) | 176 | if (space_left <= 0) |
| 177 | { | 177 | { |
| 178 | ptrdiff_t in_buffer = p - get_doc_string_buffer; | 178 | ptrdiff_t in_buffer = p - get_doc_string_buffer; |
| 179 | get_doc_string_buffer = | 179 | get_doc_string_buffer |
| 180 | xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, | 180 | = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, |
| 181 | 16 * 1024, -1, 1); | 181 | 16 * 1024, -1, 1); |
| 182 | p = get_doc_string_buffer + in_buffer; | 182 | p = get_doc_string_buffer + in_buffer; |
| 183 | space_left = (get_doc_string_buffer_size - 1 | 183 | space_left = (get_doc_string_buffer_size - 1 |
| 184 | - (p - get_doc_string_buffer)); | 184 | - (p - get_doc_string_buffer)); |
| @@ -279,10 +279,10 @@ Invalid data in documentation file -- %c followed by code %03o", | |||
| 279 | else | 279 | else |
| 280 | { | 280 | { |
| 281 | /* The data determines whether the string is multibyte. */ | 281 | /* The data determines whether the string is multibyte. */ |
| 282 | ptrdiff_t nchars = | 282 | ptrdiff_t nchars |
| 283 | multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer | 283 | = multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer |
| 284 | + offset), | 284 | + offset), |
| 285 | to - (get_doc_string_buffer + offset)); | 285 | to - (get_doc_string_buffer + offset)); |
| 286 | return make_string_from_bytes (get_doc_string_buffer + offset, | 286 | return make_string_from_bytes (get_doc_string_buffer + offset, |
| 287 | nchars, | 287 | nchars, |
| 288 | to - (get_doc_string_buffer + offset)); | 288 | to - (get_doc_string_buffer + offset)); |
| @@ -630,11 +630,10 @@ the same file name is found in the `doc-directory'. */) | |||
| 630 | break; | 630 | break; |
| 631 | 631 | ||
| 632 | buf[filled] = 0; | 632 | buf[filled] = 0; |
| 633 | p = buf; | ||
| 634 | end = buf + (filled < 512 ? filled : filled - 128); | 633 | end = buf + (filled < 512 ? filled : filled - 128); |
| 635 | while (p != end && *p != '\037') p++; | 634 | p = memchr (buf, '\037', end - buf); |
| 636 | /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ | 635 | /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ |
| 637 | if (p != end) | 636 | if (p) |
| 638 | { | 637 | { |
| 639 | end = strchr (p, '\n'); | 638 | end = strchr (p, '\n'); |
| 640 | 639 | ||
diff --git a/src/doprnt.c b/src/doprnt.c index 8cab219aafa..471e35c7b43 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Output like sprintf to a buffer of specified size. | 1 | /* Output like sprintf to a buffer of specified size. |
| 2 | Also takes args differently: pass one pointer to the end | 2 | Also takes args differently: pass one pointer to the end |
| 3 | of the format string in addition to the format string itself. | 3 | of the format string in addition to the format string itself. |
| 4 | Copyright (C) 1985, 2001-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 1985, 2001-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -38,7 +38,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 38 | could include embedded null characters. | 38 | could include embedded null characters. |
| 39 | 39 | ||
| 40 | . It signals an error if the length of the formatted string is about to | 40 | . It signals an error if the length of the formatted string is about to |
| 41 | overflow MOST_POSITIVE_FIXNUM, to avoid producing strings longer than what | 41 | overflow ptrdiff_t or size_t, to avoid producing strings longer than what |
| 42 | Emacs can handle. | 42 | Emacs can handle. |
| 43 | 43 | ||
| 44 | OTOH, this function supports only a small subset of the standard C formatted | 44 | OTOH, this function supports only a small subset of the standard C formatted |
diff --git a/src/dosfns.c b/src/dosfns.c index ce1ec4a4f93..37d3998b5ee 100644 --- a/src/dosfns.c +++ b/src/dosfns.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991. | 1 | /* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991. |
| 2 | Major changes May-July 1993 Morten Welinder (only 10% original code left) | 2 | Major changes May-July 1993 Morten Welinder (only 10% original code left) |
| 3 | Copyright (C) 1991, 1993, 1996-1998, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1991, 1993, 1996-1998, 2001-2013 Free Software |
| 4 | Foundation, Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
diff --git a/src/dosfns.h b/src/dosfns.h index 9747c364d71..0bf0ae1f19b 100644 --- a/src/dosfns.h +++ b/src/dosfns.h | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | Coded by Manabu Higashida, 1991. | 2 | Coded by Manabu Higashida, 1991. |
| 3 | Modified by Morten Welinder, 1993-1994. | 3 | Modified by Morten Welinder, 1993-1994. |
| 4 | 4 | ||
| 5 | Copyright (C) 1991, 1994-1995, 1997, 1999, 2001-2012 | 5 | Copyright (C) 1991, 1994-1995, 1997, 1999, 2001-2013 Free Software |
| 6 | Free Software Foundation, Inc. | 6 | Foundation, Inc. |
| 7 | 7 | ||
| 8 | This file is part of GNU Emacs. | 8 | This file is part of GNU Emacs. |
| 9 | 9 | ||
diff --git a/src/editfns.c b/src/editfns.c index 7d179c8566a..bee0bcc158d 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Lisp functions pertaining to editing. | 1 | /* Lisp functions pertaining to editing. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1987, 1989, 1993-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1987, 1989, 1993-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 24 | 24 | ||
| 25 | #ifdef HAVE_PWD_H | 25 | #ifdef HAVE_PWD_H |
| 26 | #include <pwd.h> | 26 | #include <pwd.h> |
| 27 | #include <grp.h> | ||
| 27 | #endif | 28 | #endif |
| 28 | 29 | ||
| 29 | #include <unistd.h> | 30 | #include <unistd.h> |
| @@ -385,6 +386,7 @@ get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object o | |||
| 385 | ptrdiff_t noverlays; | 386 | ptrdiff_t noverlays; |
| 386 | Lisp_Object *overlay_vec, tem; | 387 | Lisp_Object *overlay_vec, tem; |
| 387 | struct buffer *obuf = current_buffer; | 388 | struct buffer *obuf = current_buffer; |
| 389 | USE_SAFE_ALLOCA; | ||
| 388 | 390 | ||
| 389 | set_buffer_temp (XBUFFER (object)); | 391 | set_buffer_temp (XBUFFER (object)); |
| 390 | 392 | ||
| @@ -397,7 +399,7 @@ get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object o | |||
| 397 | make enough space for all, and try again. */ | 399 | make enough space for all, and try again. */ |
| 398 | if (noverlays > 40) | 400 | if (noverlays > 40) |
| 399 | { | 401 | { |
| 400 | overlay_vec = alloca (noverlays * sizeof *overlay_vec); | 402 | SAFE_ALLOCA_LISP (overlay_vec, noverlays); |
| 401 | noverlays = overlays_around (posn, overlay_vec, noverlays); | 403 | noverlays = overlays_around (posn, overlay_vec, noverlays); |
| 402 | } | 404 | } |
| 403 | noverlays = sort_overlays (overlay_vec, noverlays, NULL); | 405 | noverlays = sort_overlays (overlay_vec, noverlays, NULL); |
| @@ -420,10 +422,12 @@ get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object o | |||
| 420 | ; /* The overlay will not cover a char inserted at point. */ | 422 | ; /* The overlay will not cover a char inserted at point. */ |
| 421 | else | 423 | else |
| 422 | { | 424 | { |
| 425 | SAFE_FREE (); | ||
| 423 | return tem; | 426 | return tem; |
| 424 | } | 427 | } |
| 425 | } | 428 | } |
| 426 | } | 429 | } |
| 430 | SAFE_FREE (); | ||
| 427 | 431 | ||
| 428 | { /* Now check the text properties. */ | 432 | { /* Now check the text properties. */ |
| 429 | int stickiness = text_property_stickiness (prop, position, object); | 433 | int stickiness = text_property_stickiness (prop, position, object); |
| @@ -731,9 +735,8 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */) | |||
| 731 | /* This is the ONLY_IN_LINE case, check that NEW_POS and | 735 | /* This is the ONLY_IN_LINE case, check that NEW_POS and |
| 732 | FIELD_BOUND are on the same line by seeing whether | 736 | FIELD_BOUND are on the same line by seeing whether |
| 733 | there's an intervening newline or not. */ | 737 | there's an intervening newline or not. */ |
| 734 | || (scan_buffer ('\n', | 738 | || (find_newline (XFASTINT (new_pos), XFASTINT (field_bound), |
| 735 | XFASTINT (new_pos), XFASTINT (field_bound), | 739 | fwd ? -1 : 1, &shortage, 1), |
| 736 | fwd ? -1 : 1, &shortage, 1), | ||
| 737 | shortage != 0))) | 740 | shortage != 0))) |
| 738 | /* Constrain NEW_POS to FIELD_BOUND. */ | 741 | /* Constrain NEW_POS to FIELD_BOUND. */ |
| 739 | new_pos = field_bound; | 742 | new_pos = field_bound; |
| @@ -832,21 +835,17 @@ This function does not move point. */) | |||
| 832 | Lisp_Object | 835 | Lisp_Object |
| 833 | save_excursion_save (void) | 836 | save_excursion_save (void) |
| 834 | { | 837 | { |
| 835 | Lisp_Object save, *data = xmalloc (word_size * 4); | 838 | return make_save_value |
| 836 | 839 | ("oooo", | |
| 837 | data[0] = Fpoint_marker (); | 840 | Fpoint_marker (), |
| 838 | /* Do not copy the mark if it points to nowhere. */ | 841 | /* Do not copy the mark if it points to nowhere. */ |
| 839 | data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer | 842 | (XMARKER (BVAR (current_buffer, mark))->buffer |
| 840 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) | 843 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) |
| 841 | : Qnil); | 844 | : Qnil), |
| 842 | /* Selected window if current buffer is shown in it, nil otherwise. */ | 845 | /* Selected window if current buffer is shown in it, nil otherwise. */ |
| 843 | data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) | 846 | ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) |
| 844 | ? selected_window : Qnil); | 847 | ? selected_window : Qnil), |
| 845 | data[3] = BVAR (current_buffer, mark_active); | 848 | BVAR (current_buffer, mark_active)); |
| 846 | |||
| 847 | save = make_save_value (data, 4); | ||
| 848 | XSAVE_VALUE (save)->dogc = 1; | ||
| 849 | return save; | ||
| 850 | } | 849 | } |
| 851 | 850 | ||
| 852 | /* Restore saved buffer before leaving `save-excursion' special form. */ | 851 | /* Restore saved buffer before leaving `save-excursion' special form. */ |
| @@ -854,10 +853,10 @@ save_excursion_save (void) | |||
| 854 | Lisp_Object | 853 | Lisp_Object |
| 855 | save_excursion_restore (Lisp_Object info) | 854 | save_excursion_restore (Lisp_Object info) |
| 856 | { | 855 | { |
| 857 | Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer; | 856 | Lisp_Object tem, tem1, omark, nmark; |
| 858 | struct gcpro gcpro1, gcpro2, gcpro3; | 857 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 859 | 858 | ||
| 860 | tem = Fmarker_buffer (data[0]); | 859 | tem = Fmarker_buffer (XSAVE_OBJECT (info, 0)); |
| 861 | /* If we're unwinding to top level, saved buffer may be deleted. This | 860 | /* If we're unwinding to top level, saved buffer may be deleted. This |
| 862 | means that all of its markers are unchained and so tem is nil. */ | 861 | means that all of its markers are unchained and so tem is nil. */ |
| 863 | if (NILP (tem)) | 862 | if (NILP (tem)) |
| @@ -869,12 +868,12 @@ save_excursion_restore (Lisp_Object info) | |||
| 869 | Fset_buffer (tem); | 868 | Fset_buffer (tem); |
| 870 | 869 | ||
| 871 | /* Point marker. */ | 870 | /* Point marker. */ |
| 872 | tem = data[0]; | 871 | tem = XSAVE_OBJECT (info, 0); |
| 873 | Fgoto_char (tem); | 872 | Fgoto_char (tem); |
| 874 | unchain_marker (XMARKER (tem)); | 873 | unchain_marker (XMARKER (tem)); |
| 875 | 874 | ||
| 876 | /* Mark marker. */ | 875 | /* Mark marker. */ |
| 877 | tem = data[1]; | 876 | tem = XSAVE_OBJECT (info, 1); |
| 878 | omark = Fmarker_position (BVAR (current_buffer, mark)); | 877 | omark = Fmarker_position (BVAR (current_buffer, mark)); |
| 879 | if (NILP (tem)) | 878 | if (NILP (tem)) |
| 880 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); | 879 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); |
| @@ -886,7 +885,7 @@ save_excursion_restore (Lisp_Object info) | |||
| 886 | } | 885 | } |
| 887 | 886 | ||
| 888 | /* Mark active. */ | 887 | /* Mark active. */ |
| 889 | tem = data[3]; | 888 | tem = XSAVE_OBJECT (info, 3); |
| 890 | tem1 = BVAR (current_buffer, mark_active); | 889 | tem1 = BVAR (current_buffer, mark_active); |
| 891 | bset_mark_active (current_buffer, tem); | 890 | bset_mark_active (current_buffer, tem); |
| 892 | 891 | ||
| @@ -910,7 +909,7 @@ save_excursion_restore (Lisp_Object info) | |||
| 910 | /* If buffer was visible in a window, and a different window was | 909 | /* If buffer was visible in a window, and a different window was |
| 911 | selected, and the old selected window is still showing this | 910 | selected, and the old selected window is still showing this |
| 912 | buffer, restore point in that window. */ | 911 | buffer, restore point in that window. */ |
| 913 | tem = data[2]; | 912 | tem = XSAVE_OBJECT (info, 2); |
| 914 | if (WINDOWP (tem) | 913 | if (WINDOWP (tem) |
| 915 | && !EQ (tem, selected_window) | 914 | && !EQ (tem, selected_window) |
| 916 | && (tem1 = XWINDOW (tem)->buffer, | 915 | && (tem1 = XWINDOW (tem)->buffer, |
| @@ -924,7 +923,7 @@ save_excursion_restore (Lisp_Object info) | |||
| 924 | 923 | ||
| 925 | out: | 924 | out: |
| 926 | 925 | ||
| 927 | free_save_value (info); | 926 | free_misc (info); |
| 928 | return Qnil; | 927 | return Qnil; |
| 929 | } | 928 | } |
| 930 | 929 | ||
| @@ -967,7 +966,7 @@ usage: (save-current-buffer &rest BODY) */) | |||
| 967 | return unbind_to (count, Fprogn (args)); | 966 | return unbind_to (count, Fprogn (args)); |
| 968 | } | 967 | } |
| 969 | 968 | ||
| 970 | DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 1, 0, | 969 | DEFUN ("buffer-size", Fbuffer_size, Sbuffer_size, 0, 1, 0, |
| 971 | doc: /* Return the number of characters in the current buffer. | 970 | doc: /* Return the number of characters in the current buffer. |
| 972 | If BUFFER, return the number of characters in that buffer instead. */) | 971 | If BUFFER, return the number of characters in that buffer instead. */) |
| 973 | (Lisp_Object buffer) | 972 | (Lisp_Object buffer) |
| @@ -1272,6 +1271,24 @@ Value is an integer or a float, depending on the value. */) | |||
| 1272 | return make_fixnum_or_float (uid); | 1271 | return make_fixnum_or_float (uid); |
| 1273 | } | 1272 | } |
| 1274 | 1273 | ||
| 1274 | DEFUN ("group-gid", Fgroup_gid, Sgroup_gid, 0, 0, 0, | ||
| 1275 | doc: /* Return the effective gid of Emacs. | ||
| 1276 | Value is an integer or a float, depending on the value. */) | ||
| 1277 | (void) | ||
| 1278 | { | ||
| 1279 | gid_t egid = getegid (); | ||
| 1280 | return make_fixnum_or_float (egid); | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | DEFUN ("group-real-gid", Fgroup_real_gid, Sgroup_real_gid, 0, 0, 0, | ||
| 1284 | doc: /* Return the real gid of Emacs. | ||
| 1285 | Value is an integer or a float, depending on the value. */) | ||
| 1286 | (void) | ||
| 1287 | { | ||
| 1288 | gid_t gid = getgid (); | ||
| 1289 | return make_fixnum_or_float (gid); | ||
| 1290 | } | ||
| 1291 | |||
| 1275 | DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 1, 0, | 1292 | DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 1, 0, |
| 1276 | doc: /* Return the full name of the user logged in, as a string. | 1293 | doc: /* Return the full name of the user logged in, as a string. |
| 1277 | If the full name corresponding to Emacs's userid is not known, | 1294 | If the full name corresponding to Emacs's userid is not known, |
| @@ -2169,6 +2186,7 @@ set_time_zone_rule (const char *tzstring) | |||
| 2169 | xputenv (set_time_zone_rule_tz[1]); | 2186 | xputenv (set_time_zone_rule_tz[1]); |
| 2170 | } | 2187 | } |
| 2171 | tzset (); | 2188 | tzset (); |
| 2189 | tzvalbuf_in_environ = 0; | ||
| 2172 | #endif | 2190 | #endif |
| 2173 | 2191 | ||
| 2174 | if (!tzstring) | 2192 | if (!tzstring) |
| @@ -2342,10 +2360,9 @@ usage: (insert-before-markers-and-inherit &rest ARGS) */) | |||
| 2342 | } | 2360 | } |
| 2343 | 2361 | ||
| 2344 | DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3, | 2362 | DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3, |
| 2345 | "(list (or (read-char-by-name \"Insert character (Unicode name or hex): \")\ | 2363 | "(list (read-char-by-name \"Insert character (Unicode name or hex): \")\ |
| 2346 | (error \"You did not specify a valid character\"))\ | 2364 | (prefix-numeric-value current-prefix-arg)\ |
| 2347 | (prefix-numeric-value current-prefix-arg)\ | 2365 | t))", |
| 2348 | t))", | ||
| 2349 | doc: /* Insert COUNT copies of CHARACTER. | 2366 | doc: /* Insert COUNT copies of CHARACTER. |
| 2350 | Interactively, prompt for CHARACTER. You can specify CHARACTER in one | 2367 | Interactively, prompt for CHARACTER. You can specify CHARACTER in one |
| 2351 | of these ways: | 2368 | of these ways: |
| @@ -2482,7 +2499,7 @@ make_buffer_string_both (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 2482 | Lisp_Object result, tem, tem1; | 2499 | Lisp_Object result, tem, tem1; |
| 2483 | 2500 | ||
| 2484 | if (start < GPT && GPT < end) | 2501 | if (start < GPT && GPT < end) |
| 2485 | move_gap (start); | 2502 | move_gap_both (start, start_byte); |
| 2486 | 2503 | ||
| 2487 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) | 2504 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) |
| 2488 | result = make_uninit_multibyte_string (end - start, end_byte - start_byte); | 2505 | result = make_uninit_multibyte_string (end - start, end_byte - start_byte); |
| @@ -2580,7 +2597,7 @@ If narrowing is in effect, this function returns only the visible part | |||
| 2580 | of the buffer. */) | 2597 | of the buffer. */) |
| 2581 | (void) | 2598 | (void) |
| 2582 | { | 2599 | { |
| 2583 | return make_buffer_string (BEGV, ZV, 1); | 2600 | return make_buffer_string_both (BEGV, BEGV_BYTE, ZV, ZV_BYTE, 1); |
| 2584 | } | 2601 | } |
| 2585 | 2602 | ||
| 2586 | DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring, | 2603 | DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring, |
| @@ -2635,10 +2652,10 @@ They default to the values of (point-min) and (point-max) in BUFFER. */) | |||
| 2635 | DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_substrings, | 2652 | DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_substrings, |
| 2636 | 6, 6, 0, | 2653 | 6, 6, 0, |
| 2637 | doc: /* Compare two substrings of two buffers; return result as number. | 2654 | doc: /* Compare two substrings of two buffers; return result as number. |
| 2638 | the value is -N if first string is less after N-1 chars, | 2655 | Return -N if first string is less after N-1 chars, +N if first string is |
| 2639 | +N if first string is greater after N-1 chars, or 0 if strings match. | 2656 | greater after N-1 chars, or 0 if strings match. Each substring is |
| 2640 | Each substring is represented as three arguments: BUFFER, START and END. | 2657 | represented as three arguments: BUFFER, START and END. That makes six |
| 2641 | That makes six args in all, three for each substring. | 2658 | args in all, three for each substring. |
| 2642 | 2659 | ||
| 2643 | The value of `case-fold-search' in the current buffer | 2660 | The value of `case-fold-search' in the current buffer |
| 2644 | determines whether case is significant or ignored. */) | 2661 | determines whether case is significant or ignored. */) |
| @@ -3411,12 +3428,6 @@ usage: (save-restriction &rest BODY) */) | |||
| 3411 | return unbind_to (count, val); | 3428 | return unbind_to (count, val); |
| 3412 | } | 3429 | } |
| 3413 | 3430 | ||
| 3414 | /* Buffer for the most recent text displayed by Fmessage_box. */ | ||
| 3415 | static char *message_text; | ||
| 3416 | |||
| 3417 | /* Allocated length of that buffer. */ | ||
| 3418 | static ptrdiff_t message_length; | ||
| 3419 | |||
| 3420 | DEFUN ("message", Fmessage, Smessage, 1, MANY, 0, | 3431 | DEFUN ("message", Fmessage, Smessage, 1, MANY, 0, |
| 3421 | doc: /* Display a message at the bottom of the screen. | 3432 | doc: /* Display a message at the bottom of the screen. |
| 3422 | The message also goes into the `*Messages*' buffer, if `message-log-max' | 3433 | The message also goes into the `*Messages*' buffer, if `message-log-max' |
| @@ -3440,14 +3451,14 @@ usage: (message FORMAT-STRING &rest ARGS) */) | |||
| 3440 | || (STRINGP (args[0]) | 3451 | || (STRINGP (args[0]) |
| 3441 | && SBYTES (args[0]) == 0)) | 3452 | && SBYTES (args[0]) == 0)) |
| 3442 | { | 3453 | { |
| 3443 | message (0); | 3454 | message1 (0); |
| 3444 | return args[0]; | 3455 | return args[0]; |
| 3445 | } | 3456 | } |
| 3446 | else | 3457 | else |
| 3447 | { | 3458 | { |
| 3448 | register Lisp_Object val; | 3459 | register Lisp_Object val; |
| 3449 | val = Fformat (nargs, args); | 3460 | val = Fformat (nargs, args); |
| 3450 | message3 (val, SBYTES (val), STRING_MULTIBYTE (val)); | 3461 | message3 (val); |
| 3451 | return val; | 3462 | return val; |
| 3452 | } | 3463 | } |
| 3453 | } | 3464 | } |
| @@ -3466,13 +3477,12 @@ usage: (message-box FORMAT-STRING &rest ARGS) */) | |||
| 3466 | { | 3477 | { |
| 3467 | if (NILP (args[0])) | 3478 | if (NILP (args[0])) |
| 3468 | { | 3479 | { |
| 3469 | message (0); | 3480 | message1 (0); |
| 3470 | return Qnil; | 3481 | return Qnil; |
| 3471 | } | 3482 | } |
| 3472 | else | 3483 | else |
| 3473 | { | 3484 | { |
| 3474 | register Lisp_Object val; | 3485 | Lisp_Object val = Fformat (nargs, args); |
| 3475 | val = Fformat (nargs, args); | ||
| 3476 | #ifdef HAVE_MENUS | 3486 | #ifdef HAVE_MENUS |
| 3477 | /* The MS-DOS frames support popup menus even though they are | 3487 | /* The MS-DOS frames support popup menus even though they are |
| 3478 | not FRAME_WINDOW_P. */ | 3488 | not FRAME_WINDOW_P. */ |
| @@ -3489,16 +3499,7 @@ usage: (message-box FORMAT-STRING &rest ARGS) */) | |||
| 3489 | return val; | 3499 | return val; |
| 3490 | } | 3500 | } |
| 3491 | #endif /* HAVE_MENUS */ | 3501 | #endif /* HAVE_MENUS */ |
| 3492 | /* Copy the data so that it won't move when we GC. */ | 3502 | message3 (val); |
| 3493 | if (SBYTES (val) > message_length) | ||
| 3494 | { | ||
| 3495 | ptrdiff_t new_length = SBYTES (val) + 80; | ||
| 3496 | message_text = xrealloc (message_text, new_length); | ||
| 3497 | message_length = new_length; | ||
| 3498 | } | ||
| 3499 | memcpy (message_text, SDATA (val), SBYTES (val)); | ||
| 3500 | message2 (message_text, SBYTES (val), | ||
| 3501 | STRING_MULTIBYTE (val)); | ||
| 3502 | return val; | 3503 | return val; |
| 3503 | } | 3504 | } |
| 3504 | } | 3505 | } |
| @@ -4234,12 +4235,12 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 4234 | { | 4235 | { |
| 4235 | buf = xmalloc (bufsize); | 4236 | buf = xmalloc (bufsize); |
| 4236 | sa_must_free = 1; | 4237 | sa_must_free = 1; |
| 4237 | buf_save_value = make_save_value (buf, 0); | 4238 | buf_save_value = make_save_pointer (buf); |
| 4238 | record_unwind_protect (safe_alloca_unwind, buf_save_value); | 4239 | record_unwind_protect (safe_alloca_unwind, buf_save_value); |
| 4239 | memcpy (buf, initial_buffer, used); | 4240 | memcpy (buf, initial_buffer, used); |
| 4240 | } | 4241 | } |
| 4241 | else | 4242 | else |
| 4242 | XSAVE_VALUE (buf_save_value)->pointer = buf = xrealloc (buf, bufsize); | 4243 | XSAVE_POINTER (buf_save_value, 0) = buf = xrealloc (buf, bufsize); |
| 4243 | 4244 | ||
| 4244 | p = buf + used; | 4245 | p = buf + used; |
| 4245 | } | 4246 | } |
| @@ -4504,7 +4505,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4504 | (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers) | 4505 | (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers) |
| 4505 | { | 4506 | { |
| 4506 | register ptrdiff_t start1, end1, start2, end2; | 4507 | register ptrdiff_t start1, end1, start2, end2; |
| 4507 | ptrdiff_t start1_byte, start2_byte, len1_byte, len2_byte; | 4508 | ptrdiff_t start1_byte, start2_byte, len1_byte, len2_byte, end2_byte; |
| 4508 | ptrdiff_t gap, len1, len_mid, len2; | 4509 | ptrdiff_t gap, len1, len_mid, len2; |
| 4509 | unsigned char *start1_addr, *start2_addr, *temp; | 4510 | unsigned char *start1_addr, *start2_addr, *temp; |
| 4510 | 4511 | ||
| @@ -4565,20 +4566,22 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4565 | the gap the minimum distance to get it out of the way, and then | 4566 | the gap the minimum distance to get it out of the way, and then |
| 4566 | deal with an unbroken array. */ | 4567 | deal with an unbroken array. */ |
| 4567 | 4568 | ||
| 4569 | start1_byte = CHAR_TO_BYTE (start1); | ||
| 4570 | end2_byte = CHAR_TO_BYTE (end2); | ||
| 4571 | |||
| 4568 | /* Make sure the gap won't interfere, by moving it out of the text | 4572 | /* Make sure the gap won't interfere, by moving it out of the text |
| 4569 | we will operate on. */ | 4573 | we will operate on. */ |
| 4570 | if (start1 < gap && gap < end2) | 4574 | if (start1 < gap && gap < end2) |
| 4571 | { | 4575 | { |
| 4572 | if (gap - start1 < end2 - gap) | 4576 | if (gap - start1 < end2 - gap) |
| 4573 | move_gap (start1); | 4577 | move_gap_both (start1, start1_byte); |
| 4574 | else | 4578 | else |
| 4575 | move_gap (end2); | 4579 | move_gap_both (end2, end2_byte); |
| 4576 | } | 4580 | } |
| 4577 | 4581 | ||
| 4578 | start1_byte = CHAR_TO_BYTE (start1); | ||
| 4579 | start2_byte = CHAR_TO_BYTE (start2); | 4582 | start2_byte = CHAR_TO_BYTE (start2); |
| 4580 | len1_byte = CHAR_TO_BYTE (end1) - start1_byte; | 4583 | len1_byte = CHAR_TO_BYTE (end1) - start1_byte; |
| 4581 | len2_byte = CHAR_TO_BYTE (end2) - start2_byte; | 4584 | len2_byte = end2_byte - start2_byte; |
| 4582 | 4585 | ||
| 4583 | #ifdef BYTE_COMBINING_DEBUG | 4586 | #ifdef BYTE_COMBINING_DEBUG |
| 4584 | if (end1 == start2) | 4587 | if (end1 == start2) |
| @@ -4865,12 +4868,10 @@ functions if all the text being accessed has this property. */); | |||
| 4865 | defsubr (&Sline_beginning_position); | 4868 | defsubr (&Sline_beginning_position); |
| 4866 | defsubr (&Sline_end_position); | 4869 | defsubr (&Sline_end_position); |
| 4867 | 4870 | ||
| 4868 | /* defsubr (&Smark); */ | ||
| 4869 | /* defsubr (&Sset_mark); */ | ||
| 4870 | defsubr (&Ssave_excursion); | 4871 | defsubr (&Ssave_excursion); |
| 4871 | defsubr (&Ssave_current_buffer); | 4872 | defsubr (&Ssave_current_buffer); |
| 4872 | 4873 | ||
| 4873 | defsubr (&Sbufsize); | 4874 | defsubr (&Sbuffer_size); |
| 4874 | defsubr (&Spoint_max); | 4875 | defsubr (&Spoint_max); |
| 4875 | defsubr (&Spoint_min); | 4876 | defsubr (&Spoint_min); |
| 4876 | defsubr (&Spoint_min_marker); | 4877 | defsubr (&Spoint_min_marker); |
| @@ -4899,6 +4900,8 @@ functions if all the text being accessed has this property. */); | |||
| 4899 | defsubr (&Suser_real_login_name); | 4900 | defsubr (&Suser_real_login_name); |
| 4900 | defsubr (&Suser_uid); | 4901 | defsubr (&Suser_uid); |
| 4901 | defsubr (&Suser_real_uid); | 4902 | defsubr (&Suser_real_uid); |
| 4903 | defsubr (&Sgroup_gid); | ||
| 4904 | defsubr (&Sgroup_real_gid); | ||
| 4902 | defsubr (&Suser_full_name); | 4905 | defsubr (&Suser_full_name); |
| 4903 | defsubr (&Semacs_pid); | 4906 | defsubr (&Semacs_pid); |
| 4904 | defsubr (&Scurrent_time); | 4907 | defsubr (&Scurrent_time); |
diff --git a/src/emacs-icon.h b/src/emacs-icon.h index 590d874ca82..8869f6d7d76 100644 --- a/src/emacs-icon.h +++ b/src/emacs-icon.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* XPM */ | 1 | /* XPM */ |
| 2 | /* Emacs icon | 2 | /* Emacs icon |
| 3 | 3 | ||
| 4 | Copyright (C) 2008-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 2008-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | Author: Kentaro Ohkouchi <nanasess@fsm.ne.jp> | 6 | Author: Kentaro Ohkouchi <nanasess@fsm.ne.jp> |
| 7 | 7 | ||
diff --git a/src/emacs.c b/src/emacs.c index fbaf0355000..c494dff8cac 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Fully extensible Emacs, running on Unix, intended for GNU. | 1 | /* Fully extensible Emacs, running on Unix, intended for GNU. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2012 | 3 | Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -41,6 +41,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #if defined WINDOWSNT || defined HAVE_NTGUI | 41 | #if defined WINDOWSNT || defined HAVE_NTGUI |
| 42 | #include "w32select.h" | 42 | #include "w32select.h" |
| 43 | #include "w32font.h" | 43 | #include "w32font.h" |
| 44 | #include "w32common.h" | ||
| 44 | #endif | 45 | #endif |
| 45 | 46 | ||
| 46 | #if defined HAVE_NTGUI && defined CYGWIN | 47 | #if defined HAVE_NTGUI && defined CYGWIN |
| @@ -133,6 +134,7 @@ Lisp_Object Qfile_name_handler_alist; | |||
| 133 | Lisp_Object Qrisky_local_variable; | 134 | Lisp_Object Qrisky_local_variable; |
| 134 | 135 | ||
| 135 | Lisp_Object Qkill_emacs; | 136 | Lisp_Object Qkill_emacs; |
| 137 | static Lisp_Object Qkill_emacs_hook; | ||
| 136 | 138 | ||
| 137 | /* If true, Emacs should not attempt to use a window-specific code, | 139 | /* If true, Emacs should not attempt to use a window-specific code, |
| 138 | but instead should use the virtual terminal under which it was started. */ | 140 | but instead should use the virtual terminal under which it was started. */ |
| @@ -343,25 +345,6 @@ terminate_due_to_signal (int sig, int backtrace_limit) | |||
| 343 | /* This shouldn't be executed, but it prevents a warning. */ | 345 | /* This shouldn't be executed, but it prevents a warning. */ |
| 344 | exit (1); | 346 | exit (1); |
| 345 | } | 347 | } |
| 346 | |||
| 347 | #ifdef SIGDANGER | ||
| 348 | |||
| 349 | /* Handler for SIGDANGER. */ | ||
| 350 | static void | ||
| 351 | handle_danger_signal (int sig) | ||
| 352 | { | ||
| 353 | malloc_warning ("Operating system warns that virtual memory is running low.\n"); | ||
| 354 | |||
| 355 | /* It might be unsafe to call do_auto_save now. */ | ||
| 356 | force_auto_save_soon (); | ||
| 357 | } | ||
| 358 | |||
| 359 | static void | ||
| 360 | deliver_danger_signal (int sig) | ||
| 361 | { | ||
| 362 | deliver_process_signal (sig, handle_danger_signal); | ||
| 363 | } | ||
| 364 | #endif | ||
| 365 | 348 | ||
| 366 | /* Code for dealing with Lisp access to the Unix command line. */ | 349 | /* Code for dealing with Lisp access to the Unix command line. */ |
| 367 | 350 | ||
| @@ -733,6 +716,13 @@ main (int argc, char **argv) | |||
| 733 | } | 716 | } |
| 734 | #endif | 717 | #endif |
| 735 | 718 | ||
| 719 | #if defined WINDOWSNT || defined HAVE_NTGUI | ||
| 720 | /* Set global variables used to detect Windows version. Do this as | ||
| 721 | early as possible. (unexw32.c calls this function as well, but | ||
| 722 | the additional call here is harmless.) */ | ||
| 723 | cache_system_info (); | ||
| 724 | #endif | ||
| 725 | |||
| 736 | #ifdef RUN_TIME_REMAP | 726 | #ifdef RUN_TIME_REMAP |
| 737 | if (initialized) | 727 | if (initialized) |
| 738 | run_time_remap (argv[0]); | 728 | run_time_remap (argv[0]); |
| @@ -1069,7 +1059,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1069 | 1059 | ||
| 1070 | argv[skip_args] = fdStr; | 1060 | argv[skip_args] = fdStr; |
| 1071 | 1061 | ||
| 1072 | execv (argv[0], argv); | 1062 | execvp (argv[0], argv); |
| 1073 | fprintf (stderr, "emacs daemon: exec failed: %d\n", errno); | 1063 | fprintf (stderr, "emacs daemon: exec failed: %d\n", errno); |
| 1074 | exit (1); | 1064 | exit (1); |
| 1075 | } | 1065 | } |
| @@ -1287,6 +1277,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1287 | 1277 | ||
| 1288 | #ifdef WINDOWSNT | 1278 | #ifdef WINDOWSNT |
| 1289 | globals_of_w32 (); | 1279 | globals_of_w32 (); |
| 1280 | globals_of_w32notify (); | ||
| 1290 | /* Initialize environment from registry settings. */ | 1281 | /* Initialize environment from registry settings. */ |
| 1291 | init_environment (argv); | 1282 | init_environment (argv); |
| 1292 | init_ntproc (dumping); /* must precede init_editfns. */ | 1283 | init_ntproc (dumping); /* must precede init_editfns. */ |
| @@ -1327,6 +1318,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1327 | } | 1318 | } |
| 1328 | 1319 | ||
| 1329 | init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */ | 1320 | init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */ |
| 1321 | init_fileio (); | ||
| 1330 | init_lread (); | 1322 | init_lread (); |
| 1331 | #ifdef WINDOWSNT | 1323 | #ifdef WINDOWSNT |
| 1332 | /* Check to see if Emacs has been installed correctly. */ | 1324 | /* Check to see if Emacs has been installed correctly. */ |
| @@ -1442,12 +1434,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1442 | syms_of_gnutls (); | 1434 | syms_of_gnutls (); |
| 1443 | #endif | 1435 | #endif |
| 1444 | 1436 | ||
| 1437 | #ifdef HAVE_INOTIFY | ||
| 1438 | syms_of_inotify (); | ||
| 1439 | #endif /* HAVE_INOTIFY */ | ||
| 1440 | |||
| 1445 | #ifdef HAVE_DBUS | 1441 | #ifdef HAVE_DBUS |
| 1446 | syms_of_dbusbind (); | 1442 | syms_of_dbusbind (); |
| 1447 | #endif /* HAVE_DBUS */ | 1443 | #endif /* HAVE_DBUS */ |
| 1448 | 1444 | ||
| 1449 | #ifdef WINDOWSNT | 1445 | #ifdef WINDOWSNT |
| 1450 | syms_of_ntterm (); | 1446 | syms_of_ntterm (); |
| 1447 | syms_of_w32notify (); | ||
| 1451 | #endif /* WINDOWSNT */ | 1448 | #endif /* WINDOWSNT */ |
| 1452 | 1449 | ||
| 1453 | syms_of_profiler (); | 1450 | syms_of_profiler (); |
| @@ -1845,7 +1842,6 @@ all of which are called before Emacs is actually killed. */) | |||
| 1845 | (Lisp_Object arg) | 1842 | (Lisp_Object arg) |
| 1846 | { | 1843 | { |
| 1847 | struct gcpro gcpro1; | 1844 | struct gcpro gcpro1; |
| 1848 | Lisp_Object hook; | ||
| 1849 | int exit_code; | 1845 | int exit_code; |
| 1850 | 1846 | ||
| 1851 | GCPRO1 (arg); | 1847 | GCPRO1 (arg); |
| @@ -1853,9 +1849,10 @@ all of which are called before Emacs is actually killed. */) | |||
| 1853 | if (feof (stdin)) | 1849 | if (feof (stdin)) |
| 1854 | arg = Qt; | 1850 | arg = Qt; |
| 1855 | 1851 | ||
| 1856 | hook = intern ("kill-emacs-hook"); | 1852 | /* Fsignal calls emacs_abort () if it sees that waiting_for_input is |
| 1857 | Frun_hooks (1, &hook); | 1853 | set. */ |
| 1858 | 1854 | waiting_for_input = 0; | |
| 1855 | Frun_hooks (1, &Qkill_emacs_hook); | ||
| 1859 | UNGCPRO; | 1856 | UNGCPRO; |
| 1860 | 1857 | ||
| 1861 | #ifdef HAVE_X_WINDOWS | 1858 | #ifdef HAVE_X_WINDOWS |
| @@ -2155,7 +2152,7 @@ decode_env_path (const char *evarname, const char *defalt) | |||
| 2155 | { | 2152 | { |
| 2156 | char *path_copy = alloca (strlen (path) + 1); | 2153 | char *path_copy = alloca (strlen (path) + 1); |
| 2157 | strcpy (path_copy, path); | 2154 | strcpy (path_copy, path); |
| 2158 | dostounix_filename (path_copy); | 2155 | dostounix_filename (path_copy, 0); |
| 2159 | path = path_copy; | 2156 | path = path_copy; |
| 2160 | } | 2157 | } |
| 2161 | #endif | 2158 | #endif |
| @@ -2267,6 +2264,7 @@ syms_of_emacs (void) | |||
| 2267 | DEFSYM (Qfile_name_handler_alist, "file-name-handler-alist"); | 2264 | DEFSYM (Qfile_name_handler_alist, "file-name-handler-alist"); |
| 2268 | DEFSYM (Qrisky_local_variable, "risky-local-variable"); | 2265 | DEFSYM (Qrisky_local_variable, "risky-local-variable"); |
| 2269 | DEFSYM (Qkill_emacs, "kill-emacs"); | 2266 | DEFSYM (Qkill_emacs, "kill-emacs"); |
| 2267 | DEFSYM (Qkill_emacs_hook, "kill-emacs-hook"); | ||
| 2270 | 2268 | ||
| 2271 | #ifndef CANNOT_DUMP | 2269 | #ifndef CANNOT_DUMP |
| 2272 | defsubr (&Sdump_emacs); | 2270 | defsubr (&Sdump_emacs); |
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c index d10185072cc..6a8c751e306 100644 --- a/src/emacsgtkfixed.c +++ b/src/emacsgtkfixed.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* A Gtk Widget that inherits GtkFixed, but can be shrunk. | 1 | /* A Gtk Widget that inherits GtkFixed, but can be shrunk. |
| 2 | This file is only use when compiling with Gtk+ 3. | 2 | This file is only use when compiling with Gtk+ 3. |
| 3 | 3 | ||
| 4 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/emacsgtkfixed.h b/src/emacsgtkfixed.h index 3fa294aa41e..d987797a934 100644 --- a/src/emacsgtkfixed.h +++ b/src/emacsgtkfixed.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* A Gtk Widget that inherits GtkFixed, but can be shrunk. | 1 | /* A Gtk Widget that inherits GtkFixed, but can be shrunk. |
| 2 | This file is only use when compiling with Gtk+ 3. | 2 | This file is only use when compiling with Gtk+ 3. |
| 3 | 3 | ||
| 4 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/epaths.in b/src/epaths.in index 705fe3aab1b..0cf8cc9ce5b 100644 --- a/src/epaths.in +++ b/src/epaths.in | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Hey Emacs, this is -*- C -*- code! */ | 1 | /* Hey Emacs, this is -*- C -*- code! */ |
| 2 | /* | 2 | /* |
| 3 | Copyright (C) 1993, 1995, 1997, 1999, 2001-2012 | 3 | Copyright (C) 1993, 1995, 1997, 1999, 2001-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/eval.c b/src/eval.c index 34b20f6fc8e..030bf14bcea 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Evaluator for GNU Emacs Lisp interpreter. | 1 | /* Evaluator for GNU Emacs Lisp interpreter. |
| 2 | Copyright (C) 1985-1987, 1993-1995, 1999-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1987, 1993-1995, 1999-2013 Free Software |
| 3 | Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -1930,7 +1931,10 @@ eval_sub (Lisp_Object form) | |||
| 1930 | return form; | 1931 | return form; |
| 1931 | 1932 | ||
| 1932 | QUIT; | 1933 | QUIT; |
| 1934 | |||
| 1935 | GCPRO1 (form); | ||
| 1933 | maybe_gc (); | 1936 | maybe_gc (); |
| 1937 | UNGCPRO; | ||
| 1934 | 1938 | ||
| 1935 | if (++lisp_eval_depth > max_lisp_eval_depth) | 1939 | if (++lisp_eval_depth > max_lisp_eval_depth) |
| 1936 | { | 1940 | { |
diff --git a/src/fileio.c b/src/fileio.c index de3b84ba95d..89ad3396464 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* File IO for GNU Emacs. | 1 | /* File IO for GNU Emacs. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1988, 1993-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1988, 1993-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -36,6 +36,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 36 | #include <selinux/context.h> | 36 | #include <selinux/context.h> |
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | #ifdef HAVE_POSIX_ACL | ||
| 40 | #include <sys/acl.h> | ||
| 41 | #endif | ||
| 42 | |||
| 39 | #include <c-ctype.h> | 43 | #include <c-ctype.h> |
| 40 | 44 | ||
| 41 | #include "lisp.h" | 45 | #include "lisp.h" |
| @@ -78,6 +82,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 78 | #endif | 82 | #endif |
| 79 | 83 | ||
| 80 | #include "systime.h" | 84 | #include "systime.h" |
| 85 | #include <allocator.h> | ||
| 86 | #include <careadlinkat.h> | ||
| 81 | #include <stat-time.h> | 87 | #include <stat-time.h> |
| 82 | 88 | ||
| 83 | #ifdef HPUX | 89 | #ifdef HPUX |
| @@ -99,6 +105,11 @@ static mode_t auto_save_mode_bits; | |||
| 99 | /* Set by auto_save_1 if an error occurred during the last auto-save. */ | 105 | /* Set by auto_save_1 if an error occurred during the last auto-save. */ |
| 100 | static bool auto_save_error_occurred; | 106 | static bool auto_save_error_occurred; |
| 101 | 107 | ||
| 108 | /* If VALID_TIMESTAMP_FILE_SYSTEM, then TIMESTAMP_FILE_SYSTEM is the device | ||
| 109 | number of a file system where time stamps were observed to to work. */ | ||
| 110 | static bool valid_timestamp_file_system; | ||
| 111 | static dev_t timestamp_file_system; | ||
| 112 | |||
| 102 | /* The symbol bound to coding-system-for-read when | 113 | /* The symbol bound to coding-system-for-read when |
| 103 | insert-file-contents is called for recovering a file. This is not | 114 | insert-file-contents is called for recovering a file. This is not |
| 104 | an actual coding system name, but just an indicator to tell | 115 | an actual coding system name, but just an indicator to tell |
| @@ -122,9 +133,6 @@ static Lisp_Object Qwrite_region_annotate_functions; | |||
| 122 | is added here. */ | 133 | is added here. */ |
| 123 | static Lisp_Object Vwrite_region_annotation_buffers; | 134 | static Lisp_Object Vwrite_region_annotation_buffers; |
| 124 | 135 | ||
| 125 | #ifdef HAVE_FSYNC | ||
| 126 | #endif | ||
| 127 | |||
| 128 | static Lisp_Object Qdelete_by_moving_to_trash; | 136 | static Lisp_Object Qdelete_by_moving_to_trash; |
| 129 | 137 | ||
| 130 | /* Lisp function for moving files to trash. */ | 138 | /* Lisp function for moving files to trash. */ |
| @@ -236,8 +244,11 @@ static Lisp_Object Qset_file_modes; | |||
| 236 | static Lisp_Object Qset_file_times; | 244 | static Lisp_Object Qset_file_times; |
| 237 | static Lisp_Object Qfile_selinux_context; | 245 | static Lisp_Object Qfile_selinux_context; |
| 238 | static Lisp_Object Qset_file_selinux_context; | 246 | static Lisp_Object Qset_file_selinux_context; |
| 247 | static Lisp_Object Qfile_acl; | ||
| 248 | static Lisp_Object Qset_file_acl; | ||
| 239 | static Lisp_Object Qfile_newer_than_file_p; | 249 | static Lisp_Object Qfile_newer_than_file_p; |
| 240 | Lisp_Object Qinsert_file_contents; | 250 | Lisp_Object Qinsert_file_contents; |
| 251 | static Lisp_Object Qchoose_write_coding_system; | ||
| 241 | Lisp_Object Qwrite_region; | 252 | Lisp_Object Qwrite_region; |
| 242 | static Lisp_Object Qverify_visited_file_modtime; | 253 | static Lisp_Object Qverify_visited_file_modtime; |
| 243 | static Lisp_Object Qset_visited_file_modtime; | 254 | static Lisp_Object Qset_visited_file_modtime; |
| @@ -369,16 +380,35 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 369 | 380 | ||
| 370 | if (getdefdir (c_toupper (*beg) - 'A' + 1, r)) | 381 | if (getdefdir (c_toupper (*beg) - 'A' + 1, r)) |
| 371 | { | 382 | { |
| 372 | if (!IS_DIRECTORY_SEP (res[strlen (res) - 1])) | 383 | size_t l = strlen (res); |
| 384 | |||
| 385 | if (l > 3 || !IS_DIRECTORY_SEP (res[l - 1])) | ||
| 373 | strcat (res, "/"); | 386 | strcat (res, "/"); |
| 374 | beg = res; | 387 | beg = res; |
| 375 | p = beg + strlen (beg); | 388 | p = beg + strlen (beg); |
| 389 | dostounix_filename (beg, 0); | ||
| 390 | tem_fn = make_specified_string (beg, -1, p - beg, | ||
| 391 | STRING_MULTIBYTE (filename)); | ||
| 376 | } | 392 | } |
| 393 | else | ||
| 394 | tem_fn = make_specified_string (beg - 2, -1, p - beg + 2, | ||
| 395 | STRING_MULTIBYTE (filename)); | ||
| 396 | } | ||
| 397 | else if (STRING_MULTIBYTE (filename)) | ||
| 398 | { | ||
| 399 | tem_fn = make_specified_string (beg, -1, p - beg, 1); | ||
| 400 | dostounix_filename (SSDATA (tem_fn), 1); | ||
| 401 | #ifdef WINDOWSNT | ||
| 402 | if (!NILP (Vw32_downcase_file_names)) | ||
| 403 | tem_fn = Fdowncase (tem_fn); | ||
| 404 | #endif | ||
| 405 | } | ||
| 406 | else | ||
| 407 | { | ||
| 408 | dostounix_filename (beg, 0); | ||
| 409 | tem_fn = make_specified_string (beg, -1, p - beg, 0); | ||
| 377 | } | 410 | } |
| 378 | tem_fn = ENCODE_FILE (make_specified_string (beg, -1, p - beg, | 411 | return tem_fn; |
| 379 | STRING_MULTIBYTE (filename))); | ||
| 380 | dostounix_filename (SSDATA (tem_fn)); | ||
| 381 | return DECODE_FILE (tem_fn); | ||
| 382 | #else /* DOS_NT */ | 412 | #else /* DOS_NT */ |
| 383 | return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); | 413 | return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); |
| 384 | #endif /* DOS_NT */ | 414 | #endif /* DOS_NT */ |
| @@ -453,12 +483,14 @@ get a current directory to run processes in. */) | |||
| 453 | return Ffile_name_directory (filename); | 483 | return Ffile_name_directory (filename); |
| 454 | } | 484 | } |
| 455 | 485 | ||
| 456 | /* Convert from file name SRC of length SRCLEN to directory name | 486 | /* Convert from file name SRC of length SRCLEN to directory name in |
| 457 | in DST. On UNIX, just make sure there is a terminating /. | 487 | DST. MULTIBYTE non-zero means the file name in SRC is a multibyte |
| 458 | Return the length of DST in bytes. */ | 488 | string. On UNIX, just make sure there is a terminating /. Return |
| 489 | the length of DST in bytes. */ | ||
| 459 | 490 | ||
| 460 | static ptrdiff_t | 491 | static ptrdiff_t |
| 461 | file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) | 492 | file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen, |
| 493 | bool multibyte) | ||
| 462 | { | 494 | { |
| 463 | if (srclen == 0) | 495 | if (srclen == 0) |
| 464 | { | 496 | { |
| @@ -477,14 +509,7 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) | |||
| 477 | srclen++; | 509 | srclen++; |
| 478 | } | 510 | } |
| 479 | #ifdef DOS_NT | 511 | #ifdef DOS_NT |
| 480 | { | 512 | dostounix_filename (dst, multibyte); |
| 481 | Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1); | ||
| 482 | |||
| 483 | tem_fn = ENCODE_FILE (tem_fn); | ||
| 484 | dostounix_filename (SSDATA (tem_fn)); | ||
| 485 | tem_fn = DECODE_FILE (tem_fn); | ||
| 486 | memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1); | ||
| 487 | } | ||
| 488 | #endif | 513 | #endif |
| 489 | return srclen; | 514 | return srclen; |
| 490 | } | 515 | } |
| @@ -519,17 +544,23 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 519 | error ("Invalid handler in `file-name-handler-alist'"); | 544 | error ("Invalid handler in `file-name-handler-alist'"); |
| 520 | } | 545 | } |
| 521 | 546 | ||
| 547 | #ifdef WINDOWSNT | ||
| 548 | if (!NILP (Vw32_downcase_file_names)) | ||
| 549 | file = Fdowncase (file); | ||
| 550 | #endif | ||
| 522 | buf = alloca (SBYTES (file) + 10); | 551 | buf = alloca (SBYTES (file) + 10); |
| 523 | length = file_name_as_directory (buf, SSDATA (file), SBYTES (file)); | 552 | length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), |
| 553 | STRING_MULTIBYTE (file)); | ||
| 524 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); | 554 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); |
| 525 | } | 555 | } |
| 526 | 556 | ||
| 527 | /* Convert from directory name SRC of length SRCLEN to | 557 | /* Convert from directory name SRC of length SRCLEN to file name in |
| 528 | file name in DST. On UNIX, just make sure there isn't | 558 | DST. MULTIBYTE non-zero means the file name in SRC is a multibyte |
| 529 | a terminating /. Return the length of DST in bytes. */ | 559 | string. On UNIX, just make sure there isn't a terminating /. |
| 560 | Return the length of DST in bytes. */ | ||
| 530 | 561 | ||
| 531 | static ptrdiff_t | 562 | static ptrdiff_t |
| 532 | directory_file_name (char *dst, char *src, ptrdiff_t srclen) | 563 | directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) |
| 533 | { | 564 | { |
| 534 | /* Process as Unix format: just remove any final slash. | 565 | /* Process as Unix format: just remove any final slash. |
| 535 | But leave "/" unchanged; do not change it to "". */ | 566 | But leave "/" unchanged; do not change it to "". */ |
| @@ -545,14 +576,7 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen) | |||
| 545 | srclen--; | 576 | srclen--; |
| 546 | } | 577 | } |
| 547 | #ifdef DOS_NT | 578 | #ifdef DOS_NT |
| 548 | { | 579 | dostounix_filename (dst, multibyte); |
| 549 | Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1); | ||
| 550 | |||
| 551 | tem_fn = ENCODE_FILE (tem_fn); | ||
| 552 | dostounix_filename (SSDATA (tem_fn)); | ||
| 553 | tem_fn = DECODE_FILE (tem_fn); | ||
| 554 | memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1); | ||
| 555 | } | ||
| 556 | #endif | 580 | #endif |
| 557 | return srclen; | 581 | return srclen; |
| 558 | } | 582 | } |
| @@ -587,8 +611,13 @@ In Unix-syntax, this function just removes the final slash. */) | |||
| 587 | error ("Invalid handler in `file-name-handler-alist'"); | 611 | error ("Invalid handler in `file-name-handler-alist'"); |
| 588 | } | 612 | } |
| 589 | 613 | ||
| 614 | #ifdef WINDOWSNT | ||
| 615 | if (!NILP (Vw32_downcase_file_names)) | ||
| 616 | directory = Fdowncase (directory); | ||
| 617 | #endif | ||
| 590 | buf = alloca (SBYTES (directory) + 20); | 618 | buf = alloca (SBYTES (directory) + 20); |
| 591 | length = directory_file_name (buf, SSDATA (directory), SBYTES (directory)); | 619 | length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), |
| 620 | STRING_MULTIBYTE (directory)); | ||
| 592 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); | 621 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); |
| 593 | } | 622 | } |
| 594 | 623 | ||
| @@ -886,6 +915,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 886 | } | 915 | } |
| 887 | } | 916 | } |
| 888 | 917 | ||
| 918 | #ifdef WINDOWSNT | ||
| 919 | if (!NILP (Vw32_downcase_file_names)) | ||
| 920 | default_directory = Fdowncase (default_directory); | ||
| 921 | #endif | ||
| 922 | |||
| 889 | /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ | 923 | /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ |
| 890 | nm = alloca (SBYTES (name) + 1); | 924 | nm = alloca (SBYTES (name) + 1); |
| 891 | memcpy (nm, SSDATA (name), SBYTES (name) + 1); | 925 | memcpy (nm, SSDATA (name), SBYTES (name) + 1); |
| @@ -969,18 +1003,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 969 | #ifdef DOS_NT | 1003 | #ifdef DOS_NT |
| 970 | /* Make sure directories are all separated with /, but | 1004 | /* Make sure directories are all separated with /, but |
| 971 | avoid allocation of a new string when not required. */ | 1005 | avoid allocation of a new string when not required. */ |
| 972 | if (multibyte) | 1006 | dostounix_filename (nm, multibyte); |
| 973 | { | ||
| 974 | Lisp_Object tem_name = make_specified_string (nm, -1, strlen (nm), | ||
| 975 | multibyte); | ||
| 976 | |||
| 977 | tem_name = ENCODE_FILE (tem_name); | ||
| 978 | dostounix_filename (SSDATA (tem_name)); | ||
| 979 | tem_name = DECODE_FILE (tem_name); | ||
| 980 | memcpy (nm, SSDATA (tem_name), SBYTES (tem_name) + 1); | ||
| 981 | } | ||
| 982 | else | ||
| 983 | dostounix_filename (nm); | ||
| 984 | #ifdef WINDOWSNT | 1007 | #ifdef WINDOWSNT |
| 985 | if (IS_DIRECTORY_SEP (nm[1])) | 1008 | if (IS_DIRECTORY_SEP (nm[1])) |
| 986 | { | 1009 | { |
| @@ -998,6 +1021,10 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 998 | temp[0] = DRIVE_LETTER (drive); | 1021 | temp[0] = DRIVE_LETTER (drive); |
| 999 | name = concat2 (build_string (temp), name); | 1022 | name = concat2 (build_string (temp), name); |
| 1000 | } | 1023 | } |
| 1024 | #ifdef WINDOWSNT | ||
| 1025 | if (!NILP (Vw32_downcase_file_names)) | ||
| 1026 | name = Fdowncase (name); | ||
| 1027 | #endif | ||
| 1001 | return name; | 1028 | return name; |
| 1002 | #else /* not DOS_NT */ | 1029 | #else /* not DOS_NT */ |
| 1003 | if (strcmp (nm, SSDATA (name)) == 0) | 1030 | if (strcmp (nm, SSDATA (name)) == 0) |
| @@ -1038,7 +1065,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1038 | /* `egetenv' may return a unibyte string, which will bite us since | 1065 | /* `egetenv' may return a unibyte string, which will bite us since |
| 1039 | we expect the directory to be multibyte. */ | 1066 | we expect the directory to be multibyte. */ |
| 1040 | tem = build_string (newdir); | 1067 | tem = build_string (newdir); |
| 1041 | if (!STRING_MULTIBYTE (tem)) | 1068 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1042 | { | 1069 | { |
| 1043 | hdir = DECODE_FILE (tem); | 1070 | hdir = DECODE_FILE (tem); |
| 1044 | newdir = SSDATA (hdir); | 1071 | newdir = SSDATA (hdir); |
| @@ -1060,7 +1087,18 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1060 | unblock_input (); | 1087 | unblock_input (); |
| 1061 | if (pw) | 1088 | if (pw) |
| 1062 | { | 1089 | { |
| 1090 | Lisp_Object tem; | ||
| 1091 | |||
| 1063 | newdir = pw->pw_dir; | 1092 | newdir = pw->pw_dir; |
| 1093 | /* `getpwnam' may return a unibyte string, which will | ||
| 1094 | bite us since we expect the directory to be | ||
| 1095 | multibyte. */ | ||
| 1096 | tem = build_string (newdir); | ||
| 1097 | if (multibyte && !STRING_MULTIBYTE (tem)) | ||
| 1098 | { | ||
| 1099 | hdir = DECODE_FILE (tem); | ||
| 1100 | newdir = SSDATA (hdir); | ||
| 1101 | } | ||
| 1064 | nm = p; | 1102 | nm = p; |
| 1065 | #ifdef DOS_NT | 1103 | #ifdef DOS_NT |
| 1066 | collapse_newdir = 0; | 1104 | collapse_newdir = 0; |
| @@ -1084,6 +1122,13 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1084 | adir = alloca (MAXPATHLEN + 1); | 1122 | adir = alloca (MAXPATHLEN + 1); |
| 1085 | if (!getdefdir (c_toupper (drive) - 'A' + 1, adir)) | 1123 | if (!getdefdir (c_toupper (drive) - 'A' + 1, adir)) |
| 1086 | adir = NULL; | 1124 | adir = NULL; |
| 1125 | else if (multibyte) | ||
| 1126 | { | ||
| 1127 | Lisp_Object tem = build_string (adir); | ||
| 1128 | |||
| 1129 | tem = DECODE_FILE (tem); | ||
| 1130 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); | ||
| 1131 | } | ||
| 1087 | } | 1132 | } |
| 1088 | if (!adir) | 1133 | if (!adir) |
| 1089 | { | 1134 | { |
| @@ -1142,6 +1187,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1142 | indirectly by prepending newdir to nm if necessary, and using | 1187 | indirectly by prepending newdir to nm if necessary, and using |
| 1143 | cwd (or the wd of newdir's drive) as the new newdir. */ | 1188 | cwd (or the wd of newdir's drive) as the new newdir. */ |
| 1144 | char *adir; | 1189 | char *adir; |
| 1190 | |||
| 1145 | if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) | 1191 | if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) |
| 1146 | { | 1192 | { |
| 1147 | drive = (unsigned char) newdir[0]; | 1193 | drive = (unsigned char) newdir[0]; |
| @@ -1151,7 +1197,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1151 | { | 1197 | { |
| 1152 | ptrdiff_t newlen = strlen (newdir); | 1198 | ptrdiff_t newlen = strlen (newdir); |
| 1153 | char *tmp = alloca (newlen + strlen (nm) + 2); | 1199 | char *tmp = alloca (newlen + strlen (nm) + 2); |
| 1154 | file_name_as_directory (tmp, newdir, newlen); | 1200 | file_name_as_directory (tmp, newdir, newlen, multibyte); |
| 1155 | strcat (tmp, nm); | 1201 | strcat (tmp, nm); |
| 1156 | nm = tmp; | 1202 | nm = tmp; |
| 1157 | } | 1203 | } |
| @@ -1159,10 +1205,17 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1159 | if (drive) | 1205 | if (drive) |
| 1160 | { | 1206 | { |
| 1161 | if (!getdefdir (c_toupper (drive) - 'A' + 1, adir)) | 1207 | if (!getdefdir (c_toupper (drive) - 'A' + 1, adir)) |
| 1162 | newdir = "/"; | 1208 | strcpy (adir, "/"); |
| 1163 | } | 1209 | } |
| 1164 | else | 1210 | else |
| 1165 | getcwd (adir, MAXPATHLEN + 1); | 1211 | getcwd (adir, MAXPATHLEN + 1); |
| 1212 | if (multibyte) | ||
| 1213 | { | ||
| 1214 | Lisp_Object tem = build_string (adir); | ||
| 1215 | |||
| 1216 | tem = DECODE_FILE (tem); | ||
| 1217 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); | ||
| 1218 | } | ||
| 1166 | newdir = adir; | 1219 | newdir = adir; |
| 1167 | } | 1220 | } |
| 1168 | 1221 | ||
| @@ -1249,7 +1302,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1249 | strcpy (target, newdir); | 1302 | strcpy (target, newdir); |
| 1250 | } | 1303 | } |
| 1251 | else | 1304 | else |
| 1252 | file_name_as_directory (target, newdir, length); | 1305 | file_name_as_directory (target, newdir, length, multibyte); |
| 1253 | } | 1306 | } |
| 1254 | 1307 | ||
| 1255 | strcat (target, nm); | 1308 | strcat (target, nm); |
| @@ -1292,8 +1345,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1292 | #ifdef WINDOWSNT | 1345 | #ifdef WINDOWSNT |
| 1293 | char *prev_o = o; | 1346 | char *prev_o = o; |
| 1294 | #endif | 1347 | #endif |
| 1295 | while (o != target && (--o) && !IS_DIRECTORY_SEP (*o)) | 1348 | while (o != target && (--o, !IS_DIRECTORY_SEP (*o))) |
| 1296 | ; | 1349 | continue; |
| 1297 | #ifdef WINDOWSNT | 1350 | #ifdef WINDOWSNT |
| 1298 | /* Don't go below server level in UNC filenames. */ | 1351 | /* Don't go below server level in UNC filenames. */ |
| 1299 | if (o == target + 1 && IS_DIRECTORY_SEP (*o) | 1352 | if (o == target + 1 && IS_DIRECTORY_SEP (*o) |
| @@ -1335,9 +1388,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1335 | target[1] = ':'; | 1388 | target[1] = ':'; |
| 1336 | } | 1389 | } |
| 1337 | result = make_specified_string (target, -1, o - target, multibyte); | 1390 | result = make_specified_string (target, -1, o - target, multibyte); |
| 1338 | result = ENCODE_FILE (result); | 1391 | dostounix_filename (SSDATA (result), multibyte); |
| 1339 | dostounix_filename (SSDATA (result)); | 1392 | #ifdef WINDOWSNT |
| 1340 | result = DECODE_FILE (result); | 1393 | if (!NILP (Vw32_downcase_file_names)) |
| 1394 | result = Fdowncase (result); | ||
| 1395 | #endif | ||
| 1341 | #else /* !DOS_NT */ | 1396 | #else /* !DOS_NT */ |
| 1342 | result = make_specified_string (target, -1, o - target, multibyte); | 1397 | result = make_specified_string (target, -1, o - target, multibyte); |
| 1343 | #endif /* !DOS_NT */ | 1398 | #endif /* !DOS_NT */ |
| @@ -1590,7 +1645,7 @@ those `/' is discarded. */) | |||
| 1590 | { | 1645 | { |
| 1591 | char *nm, *s, *p, *o, *x, *endp; | 1646 | char *nm, *s, *p, *o, *x, *endp; |
| 1592 | char *target = NULL; | 1647 | char *target = NULL; |
| 1593 | int total = 0; | 1648 | ptrdiff_t total = 0; |
| 1594 | bool substituted = 0; | 1649 | bool substituted = 0; |
| 1595 | bool multibyte; | 1650 | bool multibyte; |
| 1596 | char *xnm; | 1651 | char *xnm; |
| @@ -1619,18 +1674,8 @@ those `/' is discarded. */) | |||
| 1619 | memcpy (nm, SDATA (filename), SBYTES (filename) + 1); | 1674 | memcpy (nm, SDATA (filename), SBYTES (filename) + 1); |
| 1620 | 1675 | ||
| 1621 | #ifdef DOS_NT | 1676 | #ifdef DOS_NT |
| 1622 | { | 1677 | dostounix_filename (nm, multibyte); |
| 1623 | Lisp_Object encoded_filename = ENCODE_FILE (filename); | 1678 | substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0); |
| 1624 | Lisp_Object tem_fn; | ||
| 1625 | |||
| 1626 | dostounix_filename (SDATA (encoded_filename)); | ||
| 1627 | tem_fn = DECODE_FILE (encoded_filename); | ||
| 1628 | nm = alloca (SBYTES (tem_fn) + 1); | ||
| 1629 | memcpy (nm, SDATA (tem_fn), SBYTES (tem_fn) + 1); | ||
| 1630 | substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0); | ||
| 1631 | if (substituted) | ||
| 1632 | filename = tem_fn; | ||
| 1633 | } | ||
| 1634 | #endif | 1679 | #endif |
| 1635 | endp = nm + SBYTES (filename); | 1680 | endp = nm + SBYTES (filename); |
| 1636 | 1681 | ||
| @@ -1665,8 +1710,9 @@ those `/' is discarded. */) | |||
| 1665 | else if (*p == '{') | 1710 | else if (*p == '{') |
| 1666 | { | 1711 | { |
| 1667 | o = ++p; | 1712 | o = ++p; |
| 1668 | while (p != endp && *p != '}') p++; | 1713 | p = memchr (p, '}', endp - p); |
| 1669 | if (*p != '}') goto missingclose; | 1714 | if (! p) |
| 1715 | goto missingclose; | ||
| 1670 | s = p; | 1716 | s = p; |
| 1671 | } | 1717 | } |
| 1672 | else | 1718 | else |
| @@ -1704,7 +1750,13 @@ those `/' is discarded. */) | |||
| 1704 | } | 1750 | } |
| 1705 | 1751 | ||
| 1706 | if (!substituted) | 1752 | if (!substituted) |
| 1707 | return filename; | 1753 | { |
| 1754 | #ifdef WINDOWSNT | ||
| 1755 | if (!NILP (Vw32_downcase_file_names)) | ||
| 1756 | filename = Fdowncase (filename); | ||
| 1757 | #endif | ||
| 1758 | return filename; | ||
| 1759 | } | ||
| 1708 | 1760 | ||
| 1709 | /* If substitution required, recopy the string and do it. */ | 1761 | /* If substitution required, recopy the string and do it. */ |
| 1710 | /* Make space in stack frame for the new copy. */ | 1762 | /* Make space in stack frame for the new copy. */ |
| @@ -1728,8 +1780,9 @@ those `/' is discarded. */) | |||
| 1728 | else if (*p == '{') | 1780 | else if (*p == '{') |
| 1729 | { | 1781 | { |
| 1730 | o = ++p; | 1782 | o = ++p; |
| 1731 | while (p != endp && *p != '}') p++; | 1783 | p = memchr (p, '}', endp - p); |
| 1732 | if (*p != '}') goto missingclose; | 1784 | if (! p) |
| 1785 | goto missingclose; | ||
| 1733 | s = p++; | 1786 | s = p++; |
| 1734 | } | 1787 | } |
| 1735 | else | 1788 | else |
| @@ -1743,9 +1796,6 @@ those `/' is discarded. */) | |||
| 1743 | target = alloca (s - o + 1); | 1796 | target = alloca (s - o + 1); |
| 1744 | memcpy (target, o, s - o); | 1797 | memcpy (target, o, s - o); |
| 1745 | target[s - o] = 0; | 1798 | target[s - o] = 0; |
| 1746 | #ifdef DOS_NT | ||
| 1747 | strupr (target); /* $home == $HOME etc. */ | ||
| 1748 | #endif /* DOS_NT */ | ||
| 1749 | 1799 | ||
| 1750 | /* Get variable value. */ | 1800 | /* Get variable value. */ |
| 1751 | o = egetenv (target); | 1801 | o = egetenv (target); |
| @@ -1782,6 +1832,16 @@ those `/' is discarded. */) | |||
| 1782 | need to quote some $ to $$ first. */ | 1832 | need to quote some $ to $$ first. */ |
| 1783 | xnm = p; | 1833 | xnm = p; |
| 1784 | 1834 | ||
| 1835 | #ifdef WINDOWSNT | ||
| 1836 | if (!NILP (Vw32_downcase_file_names)) | ||
| 1837 | { | ||
| 1838 | Lisp_Object xname = make_specified_string (xnm, -1, x - xnm, multibyte); | ||
| 1839 | |||
| 1840 | xname = Fdowncase (xname); | ||
| 1841 | return xname; | ||
| 1842 | } | ||
| 1843 | else | ||
| 1844 | #endif | ||
| 1785 | return make_specified_string (xnm, -1, x - xnm, multibyte); | 1845 | return make_specified_string (xnm, -1, x - xnm, multibyte); |
| 1786 | 1846 | ||
| 1787 | badsubst: | 1847 | badsubst: |
| @@ -1895,9 +1955,10 @@ A prefix arg makes KEEP-TIME non-nil. | |||
| 1895 | If PRESERVE-UID-GID is non-nil, we try to transfer the | 1955 | If PRESERVE-UID-GID is non-nil, we try to transfer the |
| 1896 | uid and gid of FILE to NEWNAME. | 1956 | uid and gid of FILE to NEWNAME. |
| 1897 | 1957 | ||
| 1898 | If PRESERVE-SELINUX-CONTEXT is non-nil and SELinux is enabled | 1958 | If PRESERVE-EXTENDED-ATTRIBUTES is non-nil, we try to copy additional |
| 1899 | on the system, we copy the SELinux context of FILE to NEWNAME. */) | 1959 | attributes of FILE to NEWNAME, such as its SELinux context and ACL |
| 1900 | (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists, Lisp_Object keep_time, Lisp_Object preserve_uid_gid, Lisp_Object preserve_selinux_context) | 1960 | entries (depending on how Emacs was built). */) |
| 1961 | (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists, Lisp_Object keep_time, Lisp_Object preserve_uid_gid, Lisp_Object preserve_extended_attributes) | ||
| 1901 | { | 1962 | { |
| 1902 | int ifd, ofd; | 1963 | int ifd, ofd; |
| 1903 | int n; | 1964 | int n; |
| @@ -1906,12 +1967,14 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 1906 | Lisp_Object handler; | 1967 | Lisp_Object handler; |
| 1907 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1968 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1908 | ptrdiff_t count = SPECPDL_INDEX (); | 1969 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1909 | bool input_file_statable_p; | ||
| 1910 | Lisp_Object encoded_file, encoded_newname; | 1970 | Lisp_Object encoded_file, encoded_newname; |
| 1911 | #if HAVE_LIBSELINUX | 1971 | #if HAVE_LIBSELINUX |
| 1912 | security_context_t con; | 1972 | security_context_t con; |
| 1913 | int conlength = 0; | 1973 | int conlength = 0; |
| 1914 | #endif | 1974 | #endif |
| 1975 | #ifdef HAVE_POSIX_ACL | ||
| 1976 | acl_t acl = NULL; | ||
| 1977 | #endif | ||
| 1915 | 1978 | ||
| 1916 | encoded_file = encoded_newname = Qnil; | 1979 | encoded_file = encoded_newname = Qnil; |
| 1917 | GCPRO4 (file, newname, encoded_file, encoded_newname); | 1980 | GCPRO4 (file, newname, encoded_file, encoded_newname); |
| @@ -1934,7 +1997,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 1934 | if (!NILP (handler)) | 1997 | if (!NILP (handler)) |
| 1935 | RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname, | 1998 | RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname, |
| 1936 | ok_if_already_exists, keep_time, preserve_uid_gid, | 1999 | ok_if_already_exists, keep_time, preserve_uid_gid, |
| 1937 | preserve_selinux_context)); | 2000 | preserve_extended_attributes)); |
| 1938 | 2001 | ||
| 1939 | encoded_file = ENCODE_FILE (file); | 2002 | encoded_file = ENCODE_FILE (file); |
| 1940 | encoded_newname = ENCODE_FILE (newname); | 2003 | encoded_newname = ENCODE_FILE (newname); |
| @@ -1947,10 +2010,26 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 1947 | out_st.st_mode = 0; | 2010 | out_st.st_mode = 0; |
| 1948 | 2011 | ||
| 1949 | #ifdef WINDOWSNT | 2012 | #ifdef WINDOWSNT |
| 2013 | if (!NILP (preserve_extended_attributes)) | ||
| 2014 | { | ||
| 2015 | #ifdef HAVE_POSIX_ACL | ||
| 2016 | acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS); | ||
| 2017 | if (acl == NULL && errno != ENOTSUP) | ||
| 2018 | report_file_error ("Getting ACL", Fcons (file, Qnil)); | ||
| 2019 | #endif | ||
| 2020 | } | ||
| 1950 | if (!CopyFile (SDATA (encoded_file), | 2021 | if (!CopyFile (SDATA (encoded_file), |
| 1951 | SDATA (encoded_newname), | 2022 | SDATA (encoded_newname), |
| 1952 | FALSE)) | 2023 | FALSE)) |
| 1953 | report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil))); | 2024 | { |
| 2025 | /* CopyFile doesn't set errno when it fails. By far the most | ||
| 2026 | "popular" reason is that the target is read-only. */ | ||
| 2027 | if (GetLastError () == 5) | ||
| 2028 | errno = EACCES; | ||
| 2029 | else | ||
| 2030 | errno = EPERM; | ||
| 2031 | report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil))); | ||
| 2032 | } | ||
| 1954 | /* CopyFile retains the timestamp by default. */ | 2033 | /* CopyFile retains the timestamp by default. */ |
| 1955 | else if (NILP (keep_time)) | 2034 | else if (NILP (keep_time)) |
| 1956 | { | 2035 | { |
| @@ -1974,6 +2053,17 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 1974 | /* Restore original attributes. */ | 2053 | /* Restore original attributes. */ |
| 1975 | SetFileAttributes (filename, attributes); | 2054 | SetFileAttributes (filename, attributes); |
| 1976 | } | 2055 | } |
| 2056 | #ifdef HAVE_POSIX_ACL | ||
| 2057 | if (acl != NULL) | ||
| 2058 | { | ||
| 2059 | bool fail = | ||
| 2060 | acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0; | ||
| 2061 | if (fail && errno != ENOTSUP) | ||
| 2062 | report_file_error ("Setting ACL", Fcons (newname, Qnil)); | ||
| 2063 | |||
| 2064 | acl_free (acl); | ||
| 2065 | } | ||
| 2066 | #endif | ||
| 1977 | #else /* not WINDOWSNT */ | 2067 | #else /* not WINDOWSNT */ |
| 1978 | immediate_quit = 1; | 2068 | immediate_quit = 1; |
| 1979 | ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0); | 2069 | ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0); |
| @@ -1984,19 +2074,27 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 1984 | 2074 | ||
| 1985 | record_unwind_protect (close_file_unwind, make_number (ifd)); | 2075 | record_unwind_protect (close_file_unwind, make_number (ifd)); |
| 1986 | 2076 | ||
| 1987 | /* We can only copy regular files and symbolic links. Other files are not | 2077 | if (fstat (ifd, &st) != 0) |
| 1988 | copyable by us. */ | 2078 | report_file_error ("Input file status", Fcons (file, Qnil)); |
| 1989 | input_file_statable_p = (fstat (ifd, &st) >= 0); | ||
| 1990 | 2079 | ||
| 1991 | #if HAVE_LIBSELINUX | 2080 | if (!NILP (preserve_extended_attributes)) |
| 1992 | if (!NILP (preserve_selinux_context) && is_selinux_enabled ()) | ||
| 1993 | { | 2081 | { |
| 1994 | conlength = fgetfilecon (ifd, &con); | 2082 | #if HAVE_LIBSELINUX |
| 1995 | if (conlength == -1) | 2083 | if (is_selinux_enabled ()) |
| 1996 | report_file_error ("Doing fgetfilecon", Fcons (file, Qnil)); | 2084 | { |
| 1997 | } | 2085 | conlength = fgetfilecon (ifd, &con); |
| 2086 | if (conlength == -1) | ||
| 2087 | report_file_error ("Doing fgetfilecon", Fcons (file, Qnil)); | ||
| 2088 | } | ||
| 1998 | #endif | 2089 | #endif |
| 1999 | 2090 | ||
| 2091 | #ifdef HAVE_POSIX_ACL | ||
| 2092 | acl = acl_get_fd (ifd); | ||
| 2093 | if (acl == NULL && errno != ENOTSUP) | ||
| 2094 | report_file_error ("Getting ACL", Fcons (file, Qnil)); | ||
| 2095 | #endif | ||
| 2096 | } | ||
| 2097 | |||
| 2000 | if (out_st.st_mode != 0 | 2098 | if (out_st.st_mode != 0 |
| 2001 | && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) | 2099 | && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) |
| 2002 | { | 2100 | { |
| @@ -2005,14 +2103,12 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 2005 | Fcons (file, Fcons (newname, Qnil))); | 2103 | Fcons (file, Fcons (newname, Qnil))); |
| 2006 | } | 2104 | } |
| 2007 | 2105 | ||
| 2008 | if (input_file_statable_p) | 2106 | /* We can copy only regular files. */ |
| 2107 | if (!S_ISREG (st.st_mode)) | ||
| 2009 | { | 2108 | { |
| 2010 | if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode))) | 2109 | /* Get a better looking error message. */ |
| 2011 | { | 2110 | errno = S_ISDIR (st.st_mode) ? EISDIR : EINVAL; |
| 2012 | /* Get a better looking error message. */ | 2111 | report_file_error ("Non-regular file", Fcons (file, Qnil)); |
| 2013 | errno = EISDIR; | ||
| 2014 | report_file_error ("Non-regular file", Fcons (file, Qnil)); | ||
| 2015 | } | ||
| 2016 | } | 2112 | } |
| 2017 | 2113 | ||
| 2018 | #ifdef MSDOS | 2114 | #ifdef MSDOS |
| @@ -2023,13 +2119,8 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 2023 | S_IREAD | S_IWRITE); | 2119 | S_IREAD | S_IWRITE); |
| 2024 | #else /* not MSDOS */ | 2120 | #else /* not MSDOS */ |
| 2025 | { | 2121 | { |
| 2026 | mode_t new_mask = 0666; | 2122 | mode_t new_mask = !NILP (preserve_uid_gid) ? 0600 : 0666; |
| 2027 | if (input_file_statable_p) | 2123 | new_mask &= st.st_mode; |
| 2028 | { | ||
| 2029 | if (!NILP (preserve_uid_gid)) | ||
| 2030 | new_mask = 0600; | ||
| 2031 | new_mask &= st.st_mode; | ||
| 2032 | } | ||
| 2033 | ofd = emacs_open (SSDATA (encoded_newname), | 2124 | ofd = emacs_open (SSDATA (encoded_newname), |
| 2034 | (O_WRONLY | O_TRUNC | O_CREAT | 2125 | (O_WRONLY | O_TRUNC | O_CREAT |
| 2035 | | (NILP (ok_if_already_exists) ? O_EXCL : 0)), | 2126 | | (NILP (ok_if_already_exists) ? O_EXCL : 0)), |
| @@ -2051,25 +2142,24 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 2051 | #ifndef MSDOS | 2142 | #ifndef MSDOS |
| 2052 | /* Preserve the original file modes, and if requested, also its | 2143 | /* Preserve the original file modes, and if requested, also its |
| 2053 | owner and group. */ | 2144 | owner and group. */ |
| 2054 | if (input_file_statable_p) | 2145 | { |
| 2055 | { | 2146 | mode_t mode_mask = 07777; |
| 2056 | mode_t mode_mask = 07777; | 2147 | if (!NILP (preserve_uid_gid)) |
| 2057 | if (!NILP (preserve_uid_gid)) | 2148 | { |
| 2058 | { | 2149 | /* Attempt to change owner and group. If that doesn't work |
| 2059 | /* Attempt to change owner and group. If that doesn't work | 2150 | attempt to change just the group, as that is sometimes allowed. |
| 2060 | attempt to change just the group, as that is sometimes allowed. | 2151 | Adjust the mode mask to eliminate setuid or setgid bits |
| 2061 | Adjust the mode mask to eliminate setuid or setgid bits | 2152 | that are inappropriate if the owner and group are wrong. */ |
| 2062 | that are inappropriate if the owner and group are wrong. */ | 2153 | if (fchown (ofd, st.st_uid, st.st_gid) != 0) |
| 2063 | if (fchown (ofd, st.st_uid, st.st_gid) != 0) | 2154 | { |
| 2064 | { | 2155 | mode_mask &= ~06000; |
| 2065 | mode_mask &= ~06000; | 2156 | if (fchown (ofd, -1, st.st_gid) == 0) |
| 2066 | if (fchown (ofd, -1, st.st_gid) == 0) | 2157 | mode_mask |= 02000; |
| 2067 | mode_mask |= 02000; | 2158 | } |
| 2068 | } | 2159 | } |
| 2069 | } | 2160 | if (fchmod (ofd, st.st_mode & mode_mask) != 0) |
| 2070 | if (fchmod (ofd, st.st_mode & mode_mask) != 0) | 2161 | report_file_error ("Doing chmod", Fcons (newname, Qnil)); |
| 2071 | report_file_error ("Doing chmod", Fcons (newname, Qnil)); | 2162 | } |
| 2072 | } | ||
| 2073 | #endif /* not MSDOS */ | 2163 | #endif /* not MSDOS */ |
| 2074 | 2164 | ||
| 2075 | #if HAVE_LIBSELINUX | 2165 | #if HAVE_LIBSELINUX |
| @@ -2085,16 +2175,24 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 2085 | } | 2175 | } |
| 2086 | #endif | 2176 | #endif |
| 2087 | 2177 | ||
| 2088 | if (input_file_statable_p) | 2178 | #ifdef HAVE_POSIX_ACL |
| 2179 | if (acl != NULL) | ||
| 2089 | { | 2180 | { |
| 2090 | if (!NILP (keep_time)) | 2181 | bool fail = acl_set_fd (ofd, acl) != 0; |
| 2091 | { | 2182 | if (fail && errno != ENOTSUP) |
| 2092 | EMACS_TIME atime = get_stat_atime (&st); | 2183 | report_file_error ("Setting ACL", Fcons (newname, Qnil)); |
| 2093 | EMACS_TIME mtime = get_stat_mtime (&st); | 2184 | |
| 2094 | if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime)) | 2185 | acl_free (acl); |
| 2095 | xsignal2 (Qfile_date_error, | 2186 | } |
| 2096 | build_string ("Cannot set file date"), newname); | 2187 | #endif |
| 2097 | } | 2188 | |
| 2189 | if (!NILP (keep_time)) | ||
| 2190 | { | ||
| 2191 | EMACS_TIME atime = get_stat_atime (&st); | ||
| 2192 | EMACS_TIME mtime = get_stat_mtime (&st); | ||
| 2193 | if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime)) | ||
| 2194 | xsignal2 (Qfile_date_error, | ||
| 2195 | build_string ("Cannot set file date"), newname); | ||
| 2098 | } | 2196 | } |
| 2099 | 2197 | ||
| 2100 | if (emacs_close (ofd) < 0) | 2198 | if (emacs_close (ofd) < 0) |
| @@ -2103,15 +2201,12 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 2103 | emacs_close (ifd); | 2201 | emacs_close (ifd); |
| 2104 | 2202 | ||
| 2105 | #ifdef MSDOS | 2203 | #ifdef MSDOS |
| 2106 | if (input_file_statable_p) | 2204 | /* In DJGPP v2.0 and later, fstat usually returns true file mode bits, |
| 2107 | { | 2205 | and if it can't, it tells so. Otherwise, under MSDOS we usually |
| 2108 | /* In DJGPP v2.0 and later, fstat usually returns true file mode bits, | 2206 | get only the READ bit, which will make the copied file read-only, |
| 2109 | and if it can't, it tells so. Otherwise, under MSDOS we usually | 2207 | so it's better not to chmod at all. */ |
| 2110 | get only the READ bit, which will make the copied file read-only, | 2208 | if ((_djstat_flags & _STFAIL_WRITEBIT) == 0) |
| 2111 | so it's better not to chmod at all. */ | 2209 | chmod (SDATA (encoded_newname), st.st_mode & 07777); |
| 2112 | if ((_djstat_flags & _STFAIL_WRITEBIT) == 0) | ||
| 2113 | chmod (SDATA (encoded_newname), st.st_mode & 07777); | ||
| 2114 | } | ||
| 2115 | #endif /* MSDOS */ | 2210 | #endif /* MSDOS */ |
| 2116 | #endif /* not WINDOWSNT */ | 2211 | #endif /* not WINDOWSNT */ |
| 2117 | 2212 | ||
| @@ -2219,14 +2314,17 @@ internal_delete_file_1 (Lisp_Object ignore) | |||
| 2219 | return Qt; | 2314 | return Qt; |
| 2220 | } | 2315 | } |
| 2221 | 2316 | ||
| 2222 | /* Delete file FILENAME. | 2317 | /* Delete file FILENAME, returning true if successful. |
| 2223 | This ignores `delete-by-moving-to-trash'. */ | 2318 | This ignores `delete-by-moving-to-trash'. */ |
| 2224 | 2319 | ||
| 2225 | void | 2320 | bool |
| 2226 | internal_delete_file (Lisp_Object filename) | 2321 | internal_delete_file (Lisp_Object filename) |
| 2227 | { | 2322 | { |
| 2228 | internal_condition_case_2 (Fdelete_file, filename, Qnil, | 2323 | Lisp_Object tem; |
| 2229 | Qt, internal_delete_file_1); | 2324 | |
| 2325 | tem = internal_condition_case_2 (Fdelete_file, filename, Qnil, | ||
| 2326 | Qt, internal_delete_file_1); | ||
| 2327 | return NILP (tem); | ||
| 2230 | } | 2328 | } |
| 2231 | 2329 | ||
| 2232 | DEFUN ("rename-file", Frename_file, Srename_file, 2, 3, | 2330 | DEFUN ("rename-file", Frename_file, Srename_file, 2, 3, |
| @@ -2647,6 +2745,29 @@ If there is no error, returns nil. */) | |||
| 2647 | return Qnil; | 2745 | return Qnil; |
| 2648 | } | 2746 | } |
| 2649 | 2747 | ||
| 2748 | /* Relative to directory FD, return the symbolic link value of FILENAME. | ||
| 2749 | On failure, return nil. */ | ||
| 2750 | Lisp_Object | ||
| 2751 | emacs_readlinkat (int fd, char const *filename) | ||
| 2752 | { | ||
| 2753 | static struct allocator const emacs_norealloc_allocator = | ||
| 2754 | { xmalloc, NULL, xfree, memory_full }; | ||
| 2755 | Lisp_Object val; | ||
| 2756 | char readlink_buf[1024]; | ||
| 2757 | char *buf = careadlinkat (fd, filename, readlink_buf, sizeof readlink_buf, | ||
| 2758 | &emacs_norealloc_allocator, readlinkat); | ||
| 2759 | if (!buf) | ||
| 2760 | return Qnil; | ||
| 2761 | |||
| 2762 | val = build_string (buf); | ||
| 2763 | if (buf[0] == '/' && strchr (buf, ':')) | ||
| 2764 | val = concat2 (build_string ("/:"), val); | ||
| 2765 | if (buf != readlink_buf) | ||
| 2766 | xfree (buf); | ||
| 2767 | val = DECODE_FILE (val); | ||
| 2768 | return val; | ||
| 2769 | } | ||
| 2770 | |||
| 2650 | DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0, | 2771 | DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0, |
| 2651 | doc: /* Return non-nil if file FILENAME is the name of a symbolic link. | 2772 | doc: /* Return non-nil if file FILENAME is the name of a symbolic link. |
| 2652 | The value is the link target, as a string. | 2773 | The value is the link target, as a string. |
| @@ -2657,9 +2778,6 @@ points to a nonexistent file. */) | |||
| 2657 | (Lisp_Object filename) | 2778 | (Lisp_Object filename) |
| 2658 | { | 2779 | { |
| 2659 | Lisp_Object handler; | 2780 | Lisp_Object handler; |
| 2660 | char *buf; | ||
| 2661 | Lisp_Object val; | ||
| 2662 | char readlink_buf[READLINK_BUFSIZE]; | ||
| 2663 | 2781 | ||
| 2664 | CHECK_STRING (filename); | 2782 | CHECK_STRING (filename); |
| 2665 | filename = Fexpand_file_name (filename, Qnil); | 2783 | filename = Fexpand_file_name (filename, Qnil); |
| @@ -2672,17 +2790,7 @@ points to a nonexistent file. */) | |||
| 2672 | 2790 | ||
| 2673 | filename = ENCODE_FILE (filename); | 2791 | filename = ENCODE_FILE (filename); |
| 2674 | 2792 | ||
| 2675 | buf = emacs_readlink (SSDATA (filename), readlink_buf); | 2793 | return emacs_readlinkat (AT_FDCWD, SSDATA (filename)); |
| 2676 | if (! buf) | ||
| 2677 | return Qnil; | ||
| 2678 | |||
| 2679 | val = build_string (buf); | ||
| 2680 | if (buf[0] == '/' && strchr (buf, ':')) | ||
| 2681 | val = concat2 (build_string ("/:"), val); | ||
| 2682 | if (buf != readlink_buf) | ||
| 2683 | xfree (buf); | ||
| 2684 | val = DECODE_FILE (val); | ||
| 2685 | return val; | ||
| 2686 | } | 2794 | } |
| 2687 | 2795 | ||
| 2688 | DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0, | 2796 | DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0, |
| @@ -2898,8 +3006,10 @@ DEFUN ("set-file-selinux-context", Fset_file_selinux_context, | |||
| 2898 | CONTEXT should be a list (USER ROLE TYPE RANGE), where the list | 3006 | CONTEXT should be a list (USER ROLE TYPE RANGE), where the list |
| 2899 | elements are strings naming the components of a SELinux context. | 3007 | elements are strings naming the components of a SELinux context. |
| 2900 | 3008 | ||
| 2901 | This function does nothing if SELinux is disabled, or if Emacs was not | 3009 | Value is t if setting of SELinux context was successful, nil otherwise. |
| 2902 | compiled with SELinux support. */) | 3010 | |
| 3011 | This function does nothing and returns nil if SELinux is disabled, | ||
| 3012 | or if Emacs was not compiled with SELinux support. */) | ||
| 2903 | (Lisp_Object filename, Lisp_Object context) | 3013 | (Lisp_Object filename, Lisp_Object context) |
| 2904 | { | 3014 | { |
| 2905 | Lisp_Object absname; | 3015 | Lisp_Object absname; |
| @@ -2965,6 +3075,7 @@ compiled with SELinux support. */) | |||
| 2965 | 3075 | ||
| 2966 | context_free (parsed_con); | 3076 | context_free (parsed_con); |
| 2967 | freecon (con); | 3077 | freecon (con); |
| 3078 | return fail ? Qnil : Qt; | ||
| 2968 | } | 3079 | } |
| 2969 | else | 3080 | else |
| 2970 | report_file_error ("Doing lgetfilecon", Fcons (absname, Qnil)); | 3081 | report_file_error ("Doing lgetfilecon", Fcons (absname, Qnil)); |
| @@ -2974,6 +3085,109 @@ compiled with SELinux support. */) | |||
| 2974 | return Qnil; | 3085 | return Qnil; |
| 2975 | } | 3086 | } |
| 2976 | 3087 | ||
| 3088 | DEFUN ("file-acl", Ffile_acl, Sfile_acl, 1, 1, 0, | ||
| 3089 | doc: /* Return ACL entries of file named FILENAME. | ||
| 3090 | The entries are returned in a format suitable for use in `set-file-acl' | ||
| 3091 | but is otherwise undocumented and subject to change. | ||
| 3092 | Return nil if file does not exist or is not accessible, or if Emacs | ||
| 3093 | was unable to determine the ACL entries. */) | ||
| 3094 | (Lisp_Object filename) | ||
| 3095 | { | ||
| 3096 | Lisp_Object absname; | ||
| 3097 | Lisp_Object handler; | ||
| 3098 | #ifdef HAVE_POSIX_ACL | ||
| 3099 | acl_t acl; | ||
| 3100 | Lisp_Object acl_string; | ||
| 3101 | char *str; | ||
| 3102 | #endif | ||
| 3103 | |||
| 3104 | absname = expand_and_dir_to_file (filename, | ||
| 3105 | BVAR (current_buffer, directory)); | ||
| 3106 | |||
| 3107 | /* If the file name has special constructs in it, | ||
| 3108 | call the corresponding file handler. */ | ||
| 3109 | handler = Ffind_file_name_handler (absname, Qfile_acl); | ||
| 3110 | if (!NILP (handler)) | ||
| 3111 | return call2 (handler, Qfile_acl, absname); | ||
| 3112 | |||
| 3113 | #ifdef HAVE_POSIX_ACL | ||
| 3114 | absname = ENCODE_FILE (absname); | ||
| 3115 | |||
| 3116 | acl = acl_get_file (SSDATA (absname), ACL_TYPE_ACCESS); | ||
| 3117 | if (acl == NULL) | ||
| 3118 | return Qnil; | ||
| 3119 | |||
| 3120 | str = acl_to_text (acl, NULL); | ||
| 3121 | if (str == NULL) | ||
| 3122 | { | ||
| 3123 | acl_free (acl); | ||
| 3124 | return Qnil; | ||
| 3125 | } | ||
| 3126 | |||
| 3127 | acl_string = build_string (str); | ||
| 3128 | acl_free (str); | ||
| 3129 | acl_free (acl); | ||
| 3130 | |||
| 3131 | return acl_string; | ||
| 3132 | #endif | ||
| 3133 | |||
| 3134 | return Qnil; | ||
| 3135 | } | ||
| 3136 | |||
| 3137 | DEFUN ("set-file-acl", Fset_file_acl, Sset_file_acl, | ||
| 3138 | 2, 2, 0, | ||
| 3139 | doc: /* Set ACL of file named FILENAME to ACL-STRING. | ||
| 3140 | ACL-STRING should contain the textual representation of the ACL | ||
| 3141 | entries in a format suitable for the platform. | ||
| 3142 | |||
| 3143 | Value is t if setting of ACL was successful, nil otherwise. | ||
| 3144 | |||
| 3145 | Setting ACL for local files requires Emacs to be built with ACL | ||
| 3146 | support. */) | ||
| 3147 | (Lisp_Object filename, Lisp_Object acl_string) | ||
| 3148 | { | ||
| 3149 | Lisp_Object absname; | ||
| 3150 | Lisp_Object handler; | ||
| 3151 | #ifdef HAVE_POSIX_ACL | ||
| 3152 | Lisp_Object encoded_absname; | ||
| 3153 | acl_t acl; | ||
| 3154 | bool fail; | ||
| 3155 | #endif | ||
| 3156 | |||
| 3157 | absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); | ||
| 3158 | |||
| 3159 | /* If the file name has special constructs in it, | ||
| 3160 | call the corresponding file handler. */ | ||
| 3161 | handler = Ffind_file_name_handler (absname, Qset_file_acl); | ||
| 3162 | if (!NILP (handler)) | ||
| 3163 | return call3 (handler, Qset_file_acl, absname, acl_string); | ||
| 3164 | |||
| 3165 | #ifdef HAVE_POSIX_ACL | ||
| 3166 | if (STRINGP (acl_string)) | ||
| 3167 | { | ||
| 3168 | acl = acl_from_text (SSDATA (acl_string)); | ||
| 3169 | if (acl == NULL) | ||
| 3170 | { | ||
| 3171 | report_file_error ("Converting ACL", Fcons (absname, Qnil)); | ||
| 3172 | return Qnil; | ||
| 3173 | } | ||
| 3174 | |||
| 3175 | encoded_absname = ENCODE_FILE (absname); | ||
| 3176 | |||
| 3177 | fail = (acl_set_file (SSDATA (encoded_absname), ACL_TYPE_ACCESS, | ||
| 3178 | acl) | ||
| 3179 | != 0); | ||
| 3180 | if (fail && errno != ENOTSUP) | ||
| 3181 | report_file_error ("Setting ACL", Fcons (absname, Qnil)); | ||
| 3182 | |||
| 3183 | acl_free (acl); | ||
| 3184 | return fail ? Qnil : Qt; | ||
| 3185 | } | ||
| 3186 | #endif | ||
| 3187 | |||
| 3188 | return Qnil; | ||
| 3189 | } | ||
| 3190 | |||
| 2977 | DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0, | 3191 | DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0, |
| 2978 | doc: /* Return mode bits of file named FILENAME, as an integer. | 3192 | doc: /* Return mode bits of file named FILENAME, as an integer. |
| 2979 | Return nil, if file does not exist or is not accessible. */) | 3193 | Return nil, if file does not exist or is not accessible. */) |
| @@ -3196,31 +3410,25 @@ decide_coding_unwind (Lisp_Object unwind_data) | |||
| 3196 | return Qnil; | 3410 | return Qnil; |
| 3197 | } | 3411 | } |
| 3198 | 3412 | ||
| 3199 | 3413 | /* Read from a non-regular file. STATE is a Lisp_Save_Value | |
| 3200 | /* Used to pass values from insert-file-contents to read_non_regular. */ | 3414 | object where slot 0 is the file descriptor, slot 1 specifies |
| 3201 | 3415 | an offset to put the read bytes, and slot 2 is the maximum | |
| 3202 | static int non_regular_fd; | 3416 | amount of bytes to read. Value is the number of bytes read. */ |
| 3203 | static ptrdiff_t non_regular_inserted; | ||
| 3204 | static int non_regular_nbytes; | ||
| 3205 | |||
| 3206 | |||
| 3207 | /* Read from a non-regular file. | ||
| 3208 | Read non_regular_nbytes bytes max from non_regular_fd. | ||
| 3209 | Non_regular_inserted specifies where to put the read bytes. | ||
| 3210 | Value is the number of bytes read. */ | ||
| 3211 | 3417 | ||
| 3212 | static Lisp_Object | 3418 | static Lisp_Object |
| 3213 | read_non_regular (Lisp_Object ignore) | 3419 | read_non_regular (Lisp_Object state) |
| 3214 | { | 3420 | { |
| 3215 | int nbytes; | 3421 | int nbytes; |
| 3216 | 3422 | ||
| 3217 | immediate_quit = 1; | 3423 | immediate_quit = 1; |
| 3218 | QUIT; | 3424 | QUIT; |
| 3219 | nbytes = emacs_read (non_regular_fd, | 3425 | nbytes = emacs_read (XSAVE_INTEGER (state, 0), |
| 3220 | ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE | 3426 | ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE |
| 3221 | + non_regular_inserted), | 3427 | + XSAVE_INTEGER (state, 1)), |
| 3222 | non_regular_nbytes); | 3428 | XSAVE_INTEGER (state, 2)); |
| 3223 | immediate_quit = 0; | 3429 | immediate_quit = 0; |
| 3430 | /* Fast recycle this object for the likely next call. */ | ||
| 3431 | free_misc (state); | ||
| 3224 | return make_number (nbytes); | 3432 | return make_number (nbytes); |
| 3225 | } | 3433 | } |
| 3226 | 3434 | ||
| @@ -3234,19 +3442,25 @@ read_non_regular_quit (Lisp_Object ignore) | |||
| 3234 | return Qnil; | 3442 | return Qnil; |
| 3235 | } | 3443 | } |
| 3236 | 3444 | ||
| 3237 | /* Reposition FD to OFFSET, based on WHENCE. This acts like lseek | 3445 | /* Return the file offset that VAL represents, checking for type |
| 3238 | except that it also tests for OFFSET being out of lseek's range. */ | 3446 | errors and overflow. */ |
| 3239 | static off_t | 3447 | static off_t |
| 3240 | emacs_lseek (int fd, EMACS_INT offset, int whence) | 3448 | file_offset (Lisp_Object val) |
| 3241 | { | 3449 | { |
| 3242 | /* Use "&" rather than "&&" to suppress a bogus GCC warning; see | 3450 | if (RANGED_INTEGERP (0, val, TYPE_MAXIMUM (off_t))) |
| 3243 | <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772>. */ | 3451 | return XINT (val); |
| 3244 | if (! ((offset >= TYPE_MINIMUM (off_t)) & (offset <= TYPE_MAXIMUM (off_t)))) | 3452 | |
| 3453 | if (FLOATP (val)) | ||
| 3245 | { | 3454 | { |
| 3246 | errno = EINVAL; | 3455 | double v = XFLOAT_DATA (val); |
| 3247 | return -1; | 3456 | if (0 <= v |
| 3457 | && (sizeof (off_t) < sizeof v | ||
| 3458 | ? v <= TYPE_MAXIMUM (off_t) | ||
| 3459 | : v < TYPE_MAXIMUM (off_t))) | ||
| 3460 | return v; | ||
| 3248 | } | 3461 | } |
| 3249 | return lseek (fd, offset, whence); | 3462 | |
| 3463 | wrong_type_argument (intern ("file-offset"), val); | ||
| 3250 | } | 3464 | } |
| 3251 | 3465 | ||
| 3252 | /* Return a special time value indicating the error number ERRNUM. */ | 3466 | /* Return a special time value indicating the error number ERRNUM. */ |
| @@ -3281,11 +3495,13 @@ the number of characters that replace previous buffer contents. | |||
| 3281 | 3495 | ||
| 3282 | This function does code conversion according to the value of | 3496 | This function does code conversion according to the value of |
| 3283 | `coding-system-for-read' or `file-coding-system-alist', and sets the | 3497 | `coding-system-for-read' or `file-coding-system-alist', and sets the |
| 3284 | variable `last-coding-system-used' to the coding system actually used. */) | 3498 | variable `last-coding-system-used' to the coding system actually used. |
| 3499 | |||
| 3500 | In addition, this function decodes the inserted text from known formats | ||
| 3501 | by calling `format-decode', which see. */) | ||
| 3285 | (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) | 3502 | (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) |
| 3286 | { | 3503 | { |
| 3287 | struct stat st; | 3504 | struct stat st; |
| 3288 | int file_status; | ||
| 3289 | EMACS_TIME mtime; | 3505 | EMACS_TIME mtime; |
| 3290 | int fd; | 3506 | int fd; |
| 3291 | ptrdiff_t inserted = 0; | 3507 | ptrdiff_t inserted = 0; |
| @@ -3302,7 +3518,6 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3302 | int save_errno = 0; | 3518 | int save_errno = 0; |
| 3303 | char read_buf[READ_BUF_SIZE]; | 3519 | char read_buf[READ_BUF_SIZE]; |
| 3304 | struct coding_system coding; | 3520 | struct coding_system coding; |
| 3305 | char buffer[1 << 14]; | ||
| 3306 | bool replace_handled = 0; | 3521 | bool replace_handled = 0; |
| 3307 | bool set_coding_system = 0; | 3522 | bool set_coding_system = 0; |
| 3308 | Lisp_Object coding_system; | 3523 | Lisp_Object coding_system; |
| @@ -3347,37 +3562,29 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3347 | orig_filename = filename; | 3562 | orig_filename = filename; |
| 3348 | filename = ENCODE_FILE (filename); | 3563 | filename = ENCODE_FILE (filename); |
| 3349 | 3564 | ||
| 3350 | fd = -1; | 3565 | fd = emacs_open (SSDATA (filename), O_RDONLY, 0); |
| 3351 | 3566 | if (fd < 0) | |
| 3352 | #ifdef WINDOWSNT | ||
| 3353 | { | ||
| 3354 | Lisp_Object tem = Vw32_get_true_file_attributes; | ||
| 3355 | |||
| 3356 | /* Tell stat to use expensive method to get accurate info. */ | ||
| 3357 | Vw32_get_true_file_attributes = Qt; | ||
| 3358 | file_status = stat (SSDATA (filename), &st); | ||
| 3359 | Vw32_get_true_file_attributes = tem; | ||
| 3360 | } | ||
| 3361 | #else | ||
| 3362 | file_status = stat (SSDATA (filename), &st); | ||
| 3363 | #endif /* WINDOWSNT */ | ||
| 3364 | |||
| 3365 | if (file_status == 0) | ||
| 3366 | mtime = get_stat_mtime (&st); | ||
| 3367 | else | ||
| 3368 | { | 3567 | { |
| 3369 | badopen: | ||
| 3370 | save_errno = errno; | 3568 | save_errno = errno; |
| 3371 | if (NILP (visit)) | 3569 | if (NILP (visit)) |
| 3372 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); | 3570 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); |
| 3373 | mtime = time_error_value (save_errno); | 3571 | mtime = time_error_value (save_errno); |
| 3374 | st.st_size = -1; | 3572 | st.st_size = -1; |
| 3375 | how_much = 0; | ||
| 3376 | if (!NILP (Vcoding_system_for_read)) | 3573 | if (!NILP (Vcoding_system_for_read)) |
| 3377 | Fset (Qbuffer_file_coding_system, Vcoding_system_for_read); | 3574 | Fset (Qbuffer_file_coding_system, Vcoding_system_for_read); |
| 3378 | goto notfound; | 3575 | goto notfound; |
| 3379 | } | 3576 | } |
| 3380 | 3577 | ||
| 3578 | /* Replacement should preserve point as it preserves markers. */ | ||
| 3579 | if (!NILP (replace)) | ||
| 3580 | record_unwind_protect (restore_point_unwind, Fpoint_marker ()); | ||
| 3581 | |||
| 3582 | record_unwind_protect (close_file_unwind, make_number (fd)); | ||
| 3583 | |||
| 3584 | if (fstat (fd, &st) != 0) | ||
| 3585 | report_file_error ("Input file status", Fcons (orig_filename, Qnil)); | ||
| 3586 | mtime = get_stat_mtime (&st); | ||
| 3587 | |||
| 3381 | /* This code will need to be changed in order to work on named | 3588 | /* This code will need to be changed in order to work on named |
| 3382 | pipes, and it's probably just not worth it. So we should at | 3589 | pipes, and it's probably just not worth it. So we should at |
| 3383 | least signal an error. */ | 3590 | least signal an error. */ |
| @@ -3393,17 +3600,6 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3393 | build_string ("not a regular file"), orig_filename); | 3600 | build_string ("not a regular file"), orig_filename); |
| 3394 | } | 3601 | } |
| 3395 | 3602 | ||
| 3396 | if (fd < 0) | ||
| 3397 | if ((fd = emacs_open (SSDATA (filename), O_RDONLY, 0)) < 0) | ||
| 3398 | goto badopen; | ||
| 3399 | |||
| 3400 | /* Replacement should preserve point as it preserves markers. */ | ||
| 3401 | if (!NILP (replace)) | ||
| 3402 | record_unwind_protect (restore_point_unwind, Fpoint_marker ()); | ||
| 3403 | |||
| 3404 | record_unwind_protect (close_file_unwind, make_number (fd)); | ||
| 3405 | |||
| 3406 | |||
| 3407 | if (!NILP (visit)) | 3603 | if (!NILP (visit)) |
| 3408 | { | 3604 | { |
| 3409 | if (!NILP (beg) || !NILP (end)) | 3605 | if (!NILP (beg) || !NILP (end)) |
| @@ -3413,20 +3609,12 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3413 | } | 3609 | } |
| 3414 | 3610 | ||
| 3415 | if (!NILP (beg)) | 3611 | if (!NILP (beg)) |
| 3416 | { | 3612 | beg_offset = file_offset (beg); |
| 3417 | if (! RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t))) | ||
| 3418 | wrong_type_argument (intern ("file-offset"), beg); | ||
| 3419 | beg_offset = XFASTINT (beg); | ||
| 3420 | } | ||
| 3421 | else | 3613 | else |
| 3422 | beg_offset = 0; | 3614 | beg_offset = 0; |
| 3423 | 3615 | ||
| 3424 | if (!NILP (end)) | 3616 | if (!NILP (end)) |
| 3425 | { | 3617 | end_offset = file_offset (end); |
| 3426 | if (! RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t))) | ||
| 3427 | wrong_type_argument (intern ("file-offset"), end); | ||
| 3428 | end_offset = XFASTINT (end); | ||
| 3429 | } | ||
| 3430 | else | 3618 | else |
| 3431 | { | 3619 | { |
| 3432 | if (not_regular) | 3620 | if (not_regular) |
| @@ -3503,12 +3691,14 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3503 | else | 3691 | else |
| 3504 | { | 3692 | { |
| 3505 | nread = emacs_read (fd, read_buf, 1024); | 3693 | nread = emacs_read (fd, read_buf, 1024); |
| 3506 | if (nread >= 0) | 3694 | if (nread == 1024) |
| 3507 | { | 3695 | { |
| 3508 | if (lseek (fd, st.st_size - (1024 * 3), SEEK_SET) < 0) | 3696 | int ntail; |
| 3697 | if (lseek (fd, - (1024 * 3), SEEK_END) < 0) | ||
| 3509 | report_file_error ("Setting file position", | 3698 | report_file_error ("Setting file position", |
| 3510 | Fcons (orig_filename, Qnil)); | 3699 | Fcons (orig_filename, Qnil)); |
| 3511 | nread += emacs_read (fd, read_buf + nread, 1024 * 3); | 3700 | ntail = emacs_read (fd, read_buf + nread, 1024 * 3); |
| 3701 | nread = ntail < 0 ? ntail : nread + ntail; | ||
| 3512 | } | 3702 | } |
| 3513 | } | 3703 | } |
| 3514 | 3704 | ||
| @@ -3629,7 +3819,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3629 | { | 3819 | { |
| 3630 | int nread, bufpos; | 3820 | int nread, bufpos; |
| 3631 | 3821 | ||
| 3632 | nread = emacs_read (fd, buffer, sizeof buffer); | 3822 | nread = emacs_read (fd, read_buf, sizeof read_buf); |
| 3633 | if (nread < 0) | 3823 | if (nread < 0) |
| 3634 | error ("IO error reading %s: %s", | 3824 | error ("IO error reading %s: %s", |
| 3635 | SSDATA (orig_filename), emacs_strerror (errno)); | 3825 | SSDATA (orig_filename), emacs_strerror (errno)); |
| @@ -3638,7 +3828,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3638 | 3828 | ||
| 3639 | if (CODING_REQUIRE_DETECTION (&coding)) | 3829 | if (CODING_REQUIRE_DETECTION (&coding)) |
| 3640 | { | 3830 | { |
| 3641 | coding_system = detect_coding_system ((unsigned char *) buffer, | 3831 | coding_system = detect_coding_system ((unsigned char *) read_buf, |
| 3642 | nread, nread, 1, 0, | 3832 | nread, nread, 1, 0, |
| 3643 | coding_system); | 3833 | coding_system); |
| 3644 | setup_coding_system (coding_system, &coding); | 3834 | setup_coding_system (coding_system, &coding); |
| @@ -3654,7 +3844,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3654 | 3844 | ||
| 3655 | bufpos = 0; | 3845 | bufpos = 0; |
| 3656 | while (bufpos < nread && same_at_start < ZV_BYTE | 3846 | while (bufpos < nread && same_at_start < ZV_BYTE |
| 3657 | && FETCH_BYTE (same_at_start) == buffer[bufpos]) | 3847 | && FETCH_BYTE (same_at_start) == read_buf[bufpos]) |
| 3658 | same_at_start++, bufpos++; | 3848 | same_at_start++, bufpos++; |
| 3659 | /* If we found a discrepancy, stop the scan. | 3849 | /* If we found a discrepancy, stop the scan. |
| 3660 | Otherwise loop around and scan the next bufferful. */ | 3850 | Otherwise loop around and scan the next bufferful. */ |
| @@ -3688,7 +3878,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3688 | if (curpos == 0) | 3878 | if (curpos == 0) |
| 3689 | break; | 3879 | break; |
| 3690 | /* How much can we scan in the next step? */ | 3880 | /* How much can we scan in the next step? */ |
| 3691 | trial = min (curpos, sizeof buffer); | 3881 | trial = min (curpos, sizeof read_buf); |
| 3692 | if (lseek (fd, curpos - trial, SEEK_SET) < 0) | 3882 | if (lseek (fd, curpos - trial, SEEK_SET) < 0) |
| 3693 | report_file_error ("Setting file position", | 3883 | report_file_error ("Setting file position", |
| 3694 | Fcons (orig_filename, Qnil)); | 3884 | Fcons (orig_filename, Qnil)); |
| @@ -3696,7 +3886,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3696 | total_read = nread = 0; | 3886 | total_read = nread = 0; |
| 3697 | while (total_read < trial) | 3887 | while (total_read < trial) |
| 3698 | { | 3888 | { |
| 3699 | nread = emacs_read (fd, buffer + total_read, trial - total_read); | 3889 | nread = emacs_read (fd, read_buf + total_read, trial - total_read); |
| 3700 | if (nread < 0) | 3890 | if (nread < 0) |
| 3701 | error ("IO error reading %s: %s", | 3891 | error ("IO error reading %s: %s", |
| 3702 | SDATA (orig_filename), emacs_strerror (errno)); | 3892 | SDATA (orig_filename), emacs_strerror (errno)); |
| @@ -3712,7 +3902,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3712 | /* Compare with same_at_start to avoid counting some buffer text | 3902 | /* Compare with same_at_start to avoid counting some buffer text |
| 3713 | as matching both at the file's beginning and at the end. */ | 3903 | as matching both at the file's beginning and at the end. */ |
| 3714 | while (bufpos > 0 && same_at_end > same_at_start | 3904 | while (bufpos > 0 && same_at_end > same_at_start |
| 3715 | && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1]) | 3905 | && FETCH_BYTE (same_at_end - 1) == read_buf[bufpos - 1]) |
| 3716 | same_at_end--, bufpos--; | 3906 | same_at_end--, bufpos--; |
| 3717 | 3907 | ||
| 3718 | /* If we found a discrepancy, stop the scan. | 3908 | /* If we found a discrepancy, stop the scan. |
| @@ -3814,30 +4004,25 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3814 | report_file_error ("Setting file position", | 4004 | report_file_error ("Setting file position", |
| 3815 | Fcons (orig_filename, Qnil)); | 4005 | Fcons (orig_filename, Qnil)); |
| 3816 | 4006 | ||
| 3817 | total = st.st_size; /* Total bytes in the file. */ | ||
| 3818 | how_much = 0; /* Bytes read from file so far. */ | ||
| 3819 | inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ | 4007 | inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ |
| 3820 | unprocessed = 0; /* Bytes not processed in previous loop. */ | 4008 | unprocessed = 0; /* Bytes not processed in previous loop. */ |
| 3821 | 4009 | ||
| 3822 | GCPRO1 (conversion_buffer); | 4010 | GCPRO1 (conversion_buffer); |
| 3823 | while (how_much < total) | 4011 | while (1) |
| 3824 | { | 4012 | { |
| 3825 | /* We read one bunch by one (READ_BUF_SIZE bytes) to allow | 4013 | /* Read at most READ_BUF_SIZE bytes at a time, to allow |
| 3826 | quitting while reading a huge while. */ | 4014 | quitting while reading a huge file. */ |
| 3827 | /* `try'' is reserved in some compilers (Microsoft C). */ | ||
| 3828 | int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); | ||
| 3829 | 4015 | ||
| 3830 | /* Allow quitting out of the actual I/O. */ | 4016 | /* Allow quitting out of the actual I/O. */ |
| 3831 | immediate_quit = 1; | 4017 | immediate_quit = 1; |
| 3832 | QUIT; | 4018 | QUIT; |
| 3833 | this = emacs_read (fd, read_buf + unprocessed, trytry); | 4019 | this = emacs_read (fd, read_buf + unprocessed, |
| 4020 | READ_BUF_SIZE - unprocessed); | ||
| 3834 | immediate_quit = 0; | 4021 | immediate_quit = 0; |
| 3835 | 4022 | ||
| 3836 | if (this <= 0) | 4023 | if (this <= 0) |
| 3837 | break; | 4024 | break; |
| 3838 | 4025 | ||
| 3839 | how_much += this; | ||
| 3840 | |||
| 3841 | BUF_TEMP_SET_PT (XBUFFER (conversion_buffer), | 4026 | BUF_TEMP_SET_PT (XBUFFER (conversion_buffer), |
| 3842 | BUF_Z (XBUFFER (conversion_buffer))); | 4027 | BUF_Z (XBUFFER (conversion_buffer))); |
| 3843 | decode_coding_c_string (&coding, (unsigned char *) read_buf, | 4028 | decode_coding_c_string (&coding, (unsigned char *) read_buf, |
| @@ -3854,9 +4039,6 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3854 | so defer the removal till we reach the `handled' label. */ | 4039 | so defer the removal till we reach the `handled' label. */ |
| 3855 | deferred_remove_unwind_protect = 1; | 4040 | deferred_remove_unwind_protect = 1; |
| 3856 | 4041 | ||
| 3857 | /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0 | ||
| 3858 | if we couldn't read the file. */ | ||
| 3859 | |||
| 3860 | if (this < 0) | 4042 | if (this < 0) |
| 3861 | error ("IO error reading %s: %s", | 4043 | error ("IO error reading %s: %s", |
| 3862 | SDATA (orig_filename), emacs_strerror (errno)); | 4044 | SDATA (orig_filename), emacs_strerror (errno)); |
| @@ -3993,7 +4175,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 3993 | prepare_to_modify_buffer (GPT, GPT, NULL); | 4175 | prepare_to_modify_buffer (GPT, GPT, NULL); |
| 3994 | } | 4176 | } |
| 3995 | 4177 | ||
| 3996 | move_gap (PT); | 4178 | move_gap_both (PT, PT_BYTE); |
| 3997 | if (GAP_SIZE < total) | 4179 | if (GAP_SIZE < total) |
| 3998 | make_gap (total - GAP_SIZE); | 4180 | make_gap (total - GAP_SIZE); |
| 3999 | 4181 | ||
| @@ -4021,7 +4203,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4021 | while (how_much < total) | 4203 | while (how_much < total) |
| 4022 | { | 4204 | { |
| 4023 | /* try is reserved in some compilers (Microsoft C) */ | 4205 | /* try is reserved in some compilers (Microsoft C) */ |
| 4024 | int trytry = min (total - how_much, READ_BUF_SIZE); | 4206 | ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE); |
| 4025 | ptrdiff_t this; | 4207 | ptrdiff_t this; |
| 4026 | 4208 | ||
| 4027 | if (not_regular) | 4209 | if (not_regular) |
| @@ -4031,19 +4213,18 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4031 | /* Maybe make more room. */ | 4213 | /* Maybe make more room. */ |
| 4032 | if (gap_size < trytry) | 4214 | if (gap_size < trytry) |
| 4033 | { | 4215 | { |
| 4034 | make_gap (total - gap_size); | 4216 | make_gap (trytry - gap_size); |
| 4035 | gap_size = GAP_SIZE; | 4217 | gap_size = GAP_SIZE - inserted; |
| 4036 | } | 4218 | } |
| 4037 | 4219 | ||
| 4038 | /* Read from the file, capturing `quit'. When an | 4220 | /* Read from the file, capturing `quit'. When an |
| 4039 | error occurs, end the loop, and arrange for a quit | 4221 | error occurs, end the loop, and arrange for a quit |
| 4040 | to be signaled after decoding the text we read. */ | 4222 | to be signaled after decoding the text we read. */ |
| 4041 | non_regular_fd = fd; | 4223 | nbytes = internal_condition_case_1 |
| 4042 | non_regular_inserted = inserted; | 4224 | (read_non_regular, |
| 4043 | non_regular_nbytes = trytry; | 4225 | make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry), |
| 4044 | nbytes = internal_condition_case_1 (read_non_regular, | 4226 | Qerror, read_non_regular_quit); |
| 4045 | Qnil, Qerror, | 4227 | |
| 4046 | read_non_regular_quit); | ||
| 4047 | if (NILP (nbytes)) | 4228 | if (NILP (nbytes)) |
| 4048 | { | 4229 | { |
| 4049 | read_quit = 1; | 4230 | read_quit = 1; |
| @@ -4085,8 +4266,9 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4085 | } | 4266 | } |
| 4086 | } | 4267 | } |
| 4087 | 4268 | ||
| 4088 | /* Now we have read all the file data into the gap. | 4269 | /* Now we have either read all the file data into the gap, |
| 4089 | If it was empty, undo marking the buffer modified. */ | 4270 | or stop reading on I/O error or quit. If nothing was |
| 4271 | read, undo marking the buffer modified. */ | ||
| 4090 | 4272 | ||
| 4091 | if (inserted == 0) | 4273 | if (inserted == 0) |
| 4092 | { | 4274 | { |
| @@ -4099,6 +4281,15 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4099 | else | 4281 | else |
| 4100 | Vdeactivate_mark = Qt; | 4282 | Vdeactivate_mark = Qt; |
| 4101 | 4283 | ||
| 4284 | emacs_close (fd); | ||
| 4285 | |||
| 4286 | /* Discard the unwind protect for closing the file. */ | ||
| 4287 | specpdl_ptr--; | ||
| 4288 | |||
| 4289 | if (how_much < 0) | ||
| 4290 | error ("IO error reading %s: %s", | ||
| 4291 | SDATA (orig_filename), emacs_strerror (errno)); | ||
| 4292 | |||
| 4102 | /* Make the text read part of the buffer. */ | 4293 | /* Make the text read part of the buffer. */ |
| 4103 | GAP_SIZE -= inserted; | 4294 | GAP_SIZE -= inserted; |
| 4104 | GPT += inserted; | 4295 | GPT += inserted; |
| @@ -4112,15 +4303,6 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4112 | /* Put an anchor to ensure multi-byte form ends at gap. */ | 4303 | /* Put an anchor to ensure multi-byte form ends at gap. */ |
| 4113 | *GPT_ADDR = 0; | 4304 | *GPT_ADDR = 0; |
| 4114 | 4305 | ||
| 4115 | emacs_close (fd); | ||
| 4116 | |||
| 4117 | /* Discard the unwind protect for closing the file. */ | ||
| 4118 | specpdl_ptr--; | ||
| 4119 | |||
| 4120 | if (how_much < 0) | ||
| 4121 | error ("IO error reading %s: %s", | ||
| 4122 | SDATA (orig_filename), emacs_strerror (errno)); | ||
| 4123 | |||
| 4124 | notfound: | 4306 | notfound: |
| 4125 | 4307 | ||
| 4126 | if (NILP (coding_system)) | 4308 | if (NILP (coding_system)) |
| @@ -4412,11 +4594,9 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4412 | if (read_quit) | 4594 | if (read_quit) |
| 4413 | Fsignal (Qquit, Qnil); | 4595 | Fsignal (Qquit, Qnil); |
| 4414 | 4596 | ||
| 4415 | /* ??? Retval needs to be dealt with in all cases consistently. */ | 4597 | /* Retval needs to be dealt with in all cases consistently. */ |
| 4416 | if (NILP (val)) | 4598 | if (NILP (val)) |
| 4417 | val = Fcons (orig_filename, | 4599 | val = list2 (orig_filename, make_number (inserted)); |
| 4418 | Fcons (make_number (inserted), | ||
| 4419 | Qnil)); | ||
| 4420 | 4600 | ||
| 4421 | RETURN_UNGCPRO (unbind_to (count, val)); | 4601 | RETURN_UNGCPRO (unbind_to (count, val)); |
| 4422 | } | 4602 | } |
| @@ -4432,14 +4612,24 @@ build_annotations_unwind (Lisp_Object arg) | |||
| 4432 | 4612 | ||
| 4433 | /* Decide the coding-system to encode the data with. */ | 4613 | /* Decide the coding-system to encode the data with. */ |
| 4434 | 4614 | ||
| 4435 | static Lisp_Object | 4615 | DEFUN ("choose-write-coding-system", Fchoose_write_coding_system, |
| 4436 | choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object filename, | 4616 | Schoose_write_coding_system, 3, 6, 0, |
| 4437 | Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, | 4617 | doc: /* Choose the coding system for writing a file. |
| 4438 | struct coding_system *coding) | 4618 | Arguments are as for `write-region'. |
| 4619 | This function is for internal use only. It may prompt the user. */ ) | ||
| 4620 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, | ||
| 4621 | Lisp_Object append, Lisp_Object visit, Lisp_Object lockname) | ||
| 4439 | { | 4622 | { |
| 4440 | Lisp_Object val; | 4623 | Lisp_Object val; |
| 4441 | Lisp_Object eol_parent = Qnil; | 4624 | Lisp_Object eol_parent = Qnil; |
| 4442 | 4625 | ||
| 4626 | /* Mimic write-region behavior. */ | ||
| 4627 | if (NILP (start)) | ||
| 4628 | { | ||
| 4629 | XSETFASTINT (start, BEGV); | ||
| 4630 | XSETFASTINT (end, ZV); | ||
| 4631 | } | ||
| 4632 | |||
| 4443 | if (auto_saving | 4633 | if (auto_saving |
| 4444 | && NILP (Fstring_equal (BVAR (current_buffer, filename), | 4634 | && NILP (Fstring_equal (BVAR (current_buffer, filename), |
| 4445 | BVAR (current_buffer, auto_save_file_name)))) | 4635 | BVAR (current_buffer, auto_save_file_name)))) |
| @@ -4532,10 +4722,6 @@ choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object file | |||
| 4532 | } | 4722 | } |
| 4533 | 4723 | ||
| 4534 | val = coding_inherit_eol_type (val, eol_parent); | 4724 | val = coding_inherit_eol_type (val, eol_parent); |
| 4535 | setup_coding_system (val, coding); | ||
| 4536 | |||
| 4537 | if (!STRINGP (start) && !NILP (BVAR (current_buffer, selective_display))) | ||
| 4538 | coding->mode |= CODING_MODE_SELECTIVE_DISPLAY; | ||
| 4539 | return val; | 4725 | return val; |
| 4540 | } | 4726 | } |
| 4541 | 4727 | ||
| @@ -4550,7 +4736,7 @@ If START is a string, then output that string to the file | |||
| 4550 | instead of any buffer contents; END is ignored. | 4736 | instead of any buffer contents; END is ignored. |
| 4551 | 4737 | ||
| 4552 | Optional fourth argument APPEND if non-nil means | 4738 | Optional fourth argument APPEND if non-nil means |
| 4553 | append to existing file contents (if any). If it is an integer, | 4739 | append to existing file contents (if any). If it is a number, |
| 4554 | seek to that offset in the file before writing. | 4740 | seek to that offset in the file before writing. |
| 4555 | Optional fifth argument VISIT, if t or a string, means | 4741 | Optional fifth argument VISIT, if t or a string, means |
| 4556 | set the last-save-file-modtime of buffer to this file's modtime | 4742 | set the last-save-file-modtime of buffer to this file's modtime |
| @@ -4579,6 +4765,9 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4579 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) | 4765 | (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) |
| 4580 | { | 4766 | { |
| 4581 | int desc; | 4767 | int desc; |
| 4768 | int open_flags; | ||
| 4769 | int mode; | ||
| 4770 | off_t offset IF_LINT (= 0); | ||
| 4582 | bool ok; | 4771 | bool ok; |
| 4583 | int save_errno = 0; | 4772 | int save_errno = 0; |
| 4584 | const char *fn; | 4773 | const char *fn; |
| @@ -4688,9 +4877,14 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4688 | We used to make this choice before calling build_annotations, but that | 4877 | We used to make this choice before calling build_annotations, but that |
| 4689 | leads to problems when a write-annotate-function takes care of | 4878 | leads to problems when a write-annotate-function takes care of |
| 4690 | unsavable chars (as was the case with X-Symbol). */ | 4879 | unsavable chars (as was the case with X-Symbol). */ |
| 4691 | Vlast_coding_system_used | 4880 | Vlast_coding_system_used = |
| 4692 | = choose_write_coding_system (start, end, filename, | 4881 | Fchoose_write_coding_system (start, end, filename, |
| 4693 | append, visit, lockname, &coding); | 4882 | append, visit, lockname); |
| 4883 | |||
| 4884 | setup_coding_system (Vlast_coding_system_used, &coding); | ||
| 4885 | |||
| 4886 | if (!STRINGP (start) && !NILP (BVAR (current_buffer, selective_display))) | ||
| 4887 | coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; | ||
| 4694 | 4888 | ||
| 4695 | #ifdef CLASH_DETECTION | 4889 | #ifdef CLASH_DETECTION |
| 4696 | if (!auto_saving) | 4890 | if (!auto_saving) |
| @@ -4698,27 +4892,20 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4698 | #endif /* CLASH_DETECTION */ | 4892 | #endif /* CLASH_DETECTION */ |
| 4699 | 4893 | ||
| 4700 | encoded_filename = ENCODE_FILE (filename); | 4894 | encoded_filename = ENCODE_FILE (filename); |
| 4701 | |||
| 4702 | fn = SSDATA (encoded_filename); | 4895 | fn = SSDATA (encoded_filename); |
| 4703 | desc = -1; | 4896 | open_flags = O_WRONLY | O_BINARY | O_CREAT; |
| 4704 | if (!NILP (append)) | 4897 | open_flags |= EQ (mustbenew, Qexcl) ? O_EXCL : !NILP (append) ? 0 : O_TRUNC; |
| 4898 | if (NUMBERP (append)) | ||
| 4899 | offset = file_offset (append); | ||
| 4900 | else if (!NILP (append)) | ||
| 4901 | open_flags |= O_APPEND; | ||
| 4705 | #ifdef DOS_NT | 4902 | #ifdef DOS_NT |
| 4706 | desc = emacs_open (fn, O_WRONLY | O_BINARY, 0); | 4903 | mode = S_IREAD | S_IWRITE; |
| 4707 | #else /* not DOS_NT */ | 4904 | #else |
| 4708 | desc = emacs_open (fn, O_WRONLY, 0); | 4905 | mode = auto_saving ? auto_save_mode_bits : 0666; |
| 4709 | #endif /* not DOS_NT */ | 4906 | #endif |
| 4710 | 4907 | ||
| 4711 | if (desc < 0 && (NILP (append) || errno == ENOENT)) | 4908 | desc = emacs_open (fn, open_flags, mode); |
| 4712 | #ifdef DOS_NT | ||
| 4713 | desc = emacs_open (fn, | ||
| 4714 | O_WRONLY | O_CREAT | O_BINARY | ||
| 4715 | | (EQ (mustbenew, Qexcl) ? O_EXCL : O_TRUNC), | ||
| 4716 | S_IREAD | S_IWRITE); | ||
| 4717 | #else /* not DOS_NT */ | ||
| 4718 | desc = emacs_open (fn, O_WRONLY | O_TRUNC | O_CREAT | ||
| 4719 | | (EQ (mustbenew, Qexcl) ? O_EXCL : 0), | ||
| 4720 | auto_saving ? auto_save_mode_bits : 0666); | ||
| 4721 | #endif /* not DOS_NT */ | ||
| 4722 | 4909 | ||
| 4723 | if (desc < 0) | 4910 | if (desc < 0) |
| 4724 | { | 4911 | { |
| @@ -4733,14 +4920,9 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4733 | 4920 | ||
| 4734 | record_unwind_protect (close_file_unwind, make_number (desc)); | 4921 | record_unwind_protect (close_file_unwind, make_number (desc)); |
| 4735 | 4922 | ||
| 4736 | if (!NILP (append) && !NILP (Ffile_regular_p (filename))) | 4923 | if (NUMBERP (append)) |
| 4737 | { | 4924 | { |
| 4738 | off_t ret; | 4925 | off_t ret = lseek (desc, offset, SEEK_SET); |
| 4739 | |||
| 4740 | if (NUMBERP (append)) | ||
| 4741 | ret = emacs_lseek (desc, XINT (append), SEEK_CUR); | ||
| 4742 | else | ||
| 4743 | ret = lseek (desc, 0, SEEK_END); | ||
| 4744 | if (ret < 0) | 4926 | if (ret < 0) |
| 4745 | { | 4927 | { |
| 4746 | #ifdef CLASH_DETECTION | 4928 | #ifdef CLASH_DETECTION |
| @@ -4782,7 +4964,7 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4782 | immediate_quit = 0; | 4964 | immediate_quit = 0; |
| 4783 | 4965 | ||
| 4784 | #ifdef HAVE_FSYNC | 4966 | #ifdef HAVE_FSYNC |
| 4785 | /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun). | 4967 | /* fsync appears to change the modtime on BSD4.2. |
| 4786 | Disk full in NFS may be reported here. */ | 4968 | Disk full in NFS may be reported here. */ |
| 4787 | /* mib says that closing the file will try to write as fast as NFS can do | 4969 | /* mib says that closing the file will try to write as fast as NFS can do |
| 4788 | it, and that means the fsync here is not crucial for autosave files. */ | 4970 | it, and that means the fsync here is not crucial for autosave files. */ |
| @@ -4812,6 +4994,63 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4812 | /* Discard the unwind protect for close_file_unwind. */ | 4994 | /* Discard the unwind protect for close_file_unwind. */ |
| 4813 | specpdl_ptr = specpdl + count1; | 4995 | specpdl_ptr = specpdl + count1; |
| 4814 | 4996 | ||
| 4997 | /* Some file systems have a bug where st_mtime is not updated | ||
| 4998 | properly after a write. For example, CIFS might not see the | ||
| 4999 | st_mtime change until after the file is opened again. | ||
| 5000 | |||
| 5001 | Attempt to detect this file system bug, and update MODTIME to the | ||
| 5002 | newer st_mtime if the bug appears to be present. This introduces | ||
| 5003 | a race condition, so to avoid most instances of the race condition | ||
| 5004 | on non-buggy file systems, skip this check if the most recently | ||
| 5005 | encountered non-buggy file system was the current file system. | ||
| 5006 | |||
| 5007 | A race condition can occur if some other process modifies the | ||
| 5008 | file between the fstat above and the fstat below, but the race is | ||
| 5009 | unlikely and a similar race between the last write and the fstat | ||
| 5010 | above cannot possibly be closed anyway. */ | ||
| 5011 | |||
| 5012 | if (EMACS_TIME_VALID_P (modtime) | ||
| 5013 | && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system)) | ||
| 5014 | { | ||
| 5015 | int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0); | ||
| 5016 | if (0 <= desc1) | ||
| 5017 | { | ||
| 5018 | struct stat st1; | ||
| 5019 | if (fstat (desc1, &st1) == 0 | ||
| 5020 | && st.st_dev == st1.st_dev && st.st_ino == st1.st_ino) | ||
| 5021 | { | ||
| 5022 | /* Use the heuristic if it appears to be valid. With neither | ||
| 5023 | O_EXCL nor O_TRUNC, if Emacs happened to write nothing to the | ||
| 5024 | file, the time stamp won't change. Also, some non-POSIX | ||
| 5025 | systems don't update an empty file's time stamp when | ||
| 5026 | truncating it. Finally, file systems with 100 ns or worse | ||
| 5027 | resolution sometimes seem to have bugs: on a system with ns | ||
| 5028 | resolution, checking ns % 100 incorrectly avoids the heuristic | ||
| 5029 | 1% of the time, but the problem should be temporary as we will | ||
| 5030 | try again on the next time stamp. */ | ||
| 5031 | bool use_heuristic | ||
| 5032 | = ((open_flags & (O_EXCL | O_TRUNC)) != 0 | ||
| 5033 | && st.st_size != 0 | ||
| 5034 | && EMACS_NSECS (modtime) % 100 != 0); | ||
| 5035 | |||
| 5036 | EMACS_TIME modtime1 = get_stat_mtime (&st1); | ||
| 5037 | if (use_heuristic | ||
| 5038 | && EMACS_TIME_EQ (modtime, modtime1) | ||
| 5039 | && st.st_size == st1.st_size) | ||
| 5040 | { | ||
| 5041 | timestamp_file_system = st.st_dev; | ||
| 5042 | valid_timestamp_file_system = 1; | ||
| 5043 | } | ||
| 5044 | else | ||
| 5045 | { | ||
| 5046 | st.st_size = st1.st_size; | ||
| 5047 | modtime = modtime1; | ||
| 5048 | } | ||
| 5049 | } | ||
| 5050 | emacs_close (desc1); | ||
| 5051 | } | ||
| 5052 | } | ||
| 5053 | |||
| 4815 | /* Call write-region-post-annotation-function. */ | 5054 | /* Call write-region-post-annotation-function. */ |
| 4816 | while (CONSP (Vwrite_region_annotation_buffers)) | 5055 | while (CONSP (Vwrite_region_annotation_buffers)) |
| 4817 | { | 5056 | { |
| @@ -4864,7 +5103,7 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4864 | } | 5103 | } |
| 4865 | 5104 | ||
| 4866 | if (!auto_saving) | 5105 | if (!auto_saving) |
| 4867 | message_with_string ((INTEGERP (append) | 5106 | message_with_string ((NUMBERP (append) |
| 4868 | ? "Updated %s" | 5107 | ? "Updated %s" |
| 4869 | : ! NILP (append) | 5108 | : ! NILP (append) |
| 4870 | ? "Added to %s" | 5109 | ? "Added to %s" |
| @@ -5142,8 +5381,8 @@ See Info node `(elisp)Modification Time' for more details. */) | |||
| 5142 | ? get_stat_mtime (&st) | 5381 | ? get_stat_mtime (&st) |
| 5143 | : time_error_value (errno)); | 5382 | : time_error_value (errno)); |
| 5144 | if (EMACS_TIME_EQ (mtime, b->modtime) | 5383 | if (EMACS_TIME_EQ (mtime, b->modtime) |
| 5145 | && (st.st_size == b->modtime_size | 5384 | && (b->modtime_size < 0 |
| 5146 | || b->modtime_size < 0)) | 5385 | || st.st_size == b->modtime_size)) |
| 5147 | return Qt; | 5386 | return Qt; |
| 5148 | return Qnil; | 5387 | return Qnil; |
| 5149 | } | 5388 | } |
| @@ -5170,7 +5409,15 @@ See Info node `(elisp)Modification Time' for more details. */) | |||
| 5170 | (void) | 5409 | (void) |
| 5171 | { | 5410 | { |
| 5172 | if (EMACS_NSECS (current_buffer->modtime) < 0) | 5411 | if (EMACS_NSECS (current_buffer->modtime) < 0) |
| 5173 | return make_number (0); | 5412 | { |
| 5413 | if (EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) | ||
| 5414 | { | ||
| 5415 | /* make_lisp_time won't work here if time_t is unsigned. */ | ||
| 5416 | return list4 (make_number (-1), make_number (65535), | ||
| 5417 | make_number (0), make_number (0)); | ||
| 5418 | } | ||
| 5419 | return make_number (0); | ||
| 5420 | } | ||
| 5174 | return make_lisp_time (current_buffer->modtime); | 5421 | return make_lisp_time (current_buffer->modtime); |
| 5175 | } | 5422 | } |
| 5176 | 5423 | ||
| @@ -5220,10 +5467,8 @@ static Lisp_Object | |||
| 5220 | auto_save_error (Lisp_Object error_val) | 5467 | auto_save_error (Lisp_Object error_val) |
| 5221 | { | 5468 | { |
| 5222 | Lisp_Object args[3], msg; | 5469 | Lisp_Object args[3], msg; |
| 5223 | int i, nbytes; | 5470 | int i; |
| 5224 | struct gcpro gcpro1; | 5471 | struct gcpro gcpro1; |
| 5225 | char *msgbuf; | ||
| 5226 | USE_SAFE_ALLOCA; | ||
| 5227 | 5472 | ||
| 5228 | auto_save_error_occurred = 1; | 5473 | auto_save_error_occurred = 1; |
| 5229 | 5474 | ||
| @@ -5234,20 +5479,16 @@ auto_save_error (Lisp_Object error_val) | |||
| 5234 | args[2] = Ferror_message_string (error_val); | 5479 | args[2] = Ferror_message_string (error_val); |
| 5235 | msg = Fformat (3, args); | 5480 | msg = Fformat (3, args); |
| 5236 | GCPRO1 (msg); | 5481 | GCPRO1 (msg); |
| 5237 | nbytes = SBYTES (msg); | ||
| 5238 | msgbuf = SAFE_ALLOCA (nbytes); | ||
| 5239 | memcpy (msgbuf, SDATA (msg), nbytes); | ||
| 5240 | 5482 | ||
| 5241 | for (i = 0; i < 3; ++i) | 5483 | for (i = 0; i < 3; ++i) |
| 5242 | { | 5484 | { |
| 5243 | if (i == 0) | 5485 | if (i == 0) |
| 5244 | message2 (msgbuf, nbytes, STRING_MULTIBYTE (msg)); | 5486 | message3 (msg); |
| 5245 | else | 5487 | else |
| 5246 | message2_nolog (msgbuf, nbytes, STRING_MULTIBYTE (msg)); | 5488 | message3_nolog (msg); |
| 5247 | Fsleep_for (make_number (1), Qnil); | 5489 | Fsleep_for (make_number (1), Qnil); |
| 5248 | } | 5490 | } |
| 5249 | 5491 | ||
| 5250 | SAFE_FREE (); | ||
| 5251 | UNGCPRO; | 5492 | UNGCPRO; |
| 5252 | return Qnil; | 5493 | return Qnil; |
| 5253 | } | 5494 | } |
| @@ -5282,7 +5523,7 @@ static Lisp_Object | |||
| 5282 | do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ | 5523 | do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ |
| 5283 | 5524 | ||
| 5284 | { | 5525 | { |
| 5285 | FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer; | 5526 | FILE *stream = XSAVE_POINTER (arg, 0); |
| 5286 | auto_saving = 0; | 5527 | auto_saving = 0; |
| 5287 | if (stream != NULL) | 5528 | if (stream != NULL) |
| 5288 | { | 5529 | { |
| @@ -5392,7 +5633,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) | |||
| 5392 | } | 5633 | } |
| 5393 | 5634 | ||
| 5394 | record_unwind_protect (do_auto_save_unwind, | 5635 | record_unwind_protect (do_auto_save_unwind, |
| 5395 | make_save_value (stream, 0)); | 5636 | make_save_pointer (stream)); |
| 5396 | record_unwind_protect (do_auto_save_unwind_1, | 5637 | record_unwind_protect (do_auto_save_unwind_1, |
| 5397 | make_number (minibuffer_auto_raise)); | 5638 | make_number (minibuffer_auto_raise)); |
| 5398 | minibuffer_auto_raise = 0; | 5639 | minibuffer_auto_raise = 0; |
| @@ -5601,6 +5842,12 @@ Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filena | |||
| 5601 | 5842 | ||
| 5602 | 5843 | ||
| 5603 | void | 5844 | void |
| 5845 | init_fileio (void) | ||
| 5846 | { | ||
| 5847 | valid_timestamp_file_system = 0; | ||
| 5848 | } | ||
| 5849 | |||
| 5850 | void | ||
| 5604 | syms_of_fileio (void) | 5851 | syms_of_fileio (void) |
| 5605 | { | 5852 | { |
| 5606 | DEFSYM (Qoperations, "operations"); | 5853 | DEFSYM (Qoperations, "operations"); |
| @@ -5633,8 +5880,11 @@ syms_of_fileio (void) | |||
| 5633 | DEFSYM (Qset_file_times, "set-file-times"); | 5880 | DEFSYM (Qset_file_times, "set-file-times"); |
| 5634 | DEFSYM (Qfile_selinux_context, "file-selinux-context"); | 5881 | DEFSYM (Qfile_selinux_context, "file-selinux-context"); |
| 5635 | DEFSYM (Qset_file_selinux_context, "set-file-selinux-context"); | 5882 | DEFSYM (Qset_file_selinux_context, "set-file-selinux-context"); |
| 5883 | DEFSYM (Qfile_acl, "file-acl"); | ||
| 5884 | DEFSYM (Qset_file_acl, "set-file-acl"); | ||
| 5636 | DEFSYM (Qfile_newer_than_file_p, "file-newer-than-file-p"); | 5885 | DEFSYM (Qfile_newer_than_file_p, "file-newer-than-file-p"); |
| 5637 | DEFSYM (Qinsert_file_contents, "insert-file-contents"); | 5886 | DEFSYM (Qinsert_file_contents, "insert-file-contents"); |
| 5887 | DEFSYM (Qchoose_write_coding_system, "choose-write-coding-system"); | ||
| 5638 | DEFSYM (Qwrite_region, "write-region"); | 5888 | DEFSYM (Qwrite_region, "write-region"); |
| 5639 | DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime"); | 5889 | DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime"); |
| 5640 | DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime"); | 5890 | DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime"); |
| @@ -5852,11 +6102,14 @@ This includes interactive calls to `delete-file' and | |||
| 5852 | defsubr (&Sset_file_modes); | 6102 | defsubr (&Sset_file_modes); |
| 5853 | defsubr (&Sset_file_times); | 6103 | defsubr (&Sset_file_times); |
| 5854 | defsubr (&Sfile_selinux_context); | 6104 | defsubr (&Sfile_selinux_context); |
| 6105 | defsubr (&Sfile_acl); | ||
| 6106 | defsubr (&Sset_file_acl); | ||
| 5855 | defsubr (&Sset_file_selinux_context); | 6107 | defsubr (&Sset_file_selinux_context); |
| 5856 | defsubr (&Sset_default_file_modes); | 6108 | defsubr (&Sset_default_file_modes); |
| 5857 | defsubr (&Sdefault_file_modes); | 6109 | defsubr (&Sdefault_file_modes); |
| 5858 | defsubr (&Sfile_newer_than_file_p); | 6110 | defsubr (&Sfile_newer_than_file_p); |
| 5859 | defsubr (&Sinsert_file_contents); | 6111 | defsubr (&Sinsert_file_contents); |
| 6112 | defsubr (&Schoose_write_coding_system); | ||
| 5860 | defsubr (&Swrite_region); | 6113 | defsubr (&Swrite_region); |
| 5861 | defsubr (&Scar_less_than_car); | 6114 | defsubr (&Scar_less_than_car); |
| 5862 | defsubr (&Sverify_visited_file_modtime); | 6115 | defsubr (&Sverify_visited_file_modtime); |
diff --git a/src/filelock.c b/src/filelock.c index 17f3f253249..228fe98e8c7 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Lock files for editing. | 1 | /* Lock files for editing. |
| 2 | Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2012 | 2 | Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -390,12 +390,14 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 390 | lock_info_type local_owner; | 390 | lock_info_type local_owner; |
| 391 | intmax_t n; | 391 | intmax_t n; |
| 392 | char *at, *dot, *colon; | 392 | char *at, *dot, *colon; |
| 393 | char readlink_buf[READLINK_BUFSIZE]; | 393 | Lisp_Object lfinfo_object = emacs_readlinkat (AT_FDCWD, lfname); |
| 394 | char *lfinfo = emacs_readlink (lfname, readlink_buf); | 394 | char *lfinfo; |
| 395 | struct gcpro gcpro1; | ||
| 395 | 396 | ||
| 396 | /* If nonexistent lock file, all is well; otherwise, got strange error. */ | 397 | /* If nonexistent lock file, all is well; otherwise, got strange error. */ |
| 397 | if (!lfinfo) | 398 | if (NILP (lfinfo_object)) |
| 398 | return errno == ENOENT ? 0 : -1; | 399 | return errno == ENOENT ? 0 : -1; |
| 400 | lfinfo = SSDATA (lfinfo_object); | ||
| 399 | 401 | ||
| 400 | /* Even if the caller doesn't want the owner info, we still have to | 402 | /* Even if the caller doesn't want the owner info, we still have to |
| 401 | read it to determine return value. */ | 403 | read it to determine return value. */ |
| @@ -407,12 +409,9 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 407 | at = strrchr (lfinfo, '@'); | 409 | at = strrchr (lfinfo, '@'); |
| 408 | dot = strrchr (lfinfo, '.'); | 410 | dot = strrchr (lfinfo, '.'); |
| 409 | if (!at || !dot) | 411 | if (!at || !dot) |
| 410 | { | 412 | return -1; |
| 411 | if (lfinfo != readlink_buf) | ||
| 412 | xfree (lfinfo); | ||
| 413 | return -1; | ||
| 414 | } | ||
| 415 | len = at - lfinfo; | 413 | len = at - lfinfo; |
| 414 | GCPRO1 (lfinfo_object); | ||
| 416 | owner->user = xmalloc (len + 1); | 415 | owner->user = xmalloc (len + 1); |
| 417 | memcpy (owner->user, lfinfo, len); | 416 | memcpy (owner->user, lfinfo, len); |
| 418 | owner->user[len] = 0; | 417 | owner->user[len] = 0; |
| @@ -445,8 +444,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 445 | owner->host[len] = 0; | 444 | owner->host[len] = 0; |
| 446 | 445 | ||
| 447 | /* We're done looking at the link info. */ | 446 | /* We're done looking at the link info. */ |
| 448 | if (lfinfo != readlink_buf) | 447 | UNGCPRO; |
| 449 | xfree (lfinfo); | ||
| 450 | 448 | ||
| 451 | /* On current host? */ | 449 | /* On current host? */ |
| 452 | if (STRINGP (Fsystem_name ()) | 450 | if (STRINGP (Fsystem_name ()) |
diff --git a/src/firstfile.c b/src/firstfile.c index 444fb71b55d..80c936719d6 100644 --- a/src/firstfile.c +++ b/src/firstfile.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Mark beginning of data space to dump as pure, for GNU Emacs. | 1 | /* Mark beginning of data space to dump as pure, for GNU Emacs. |
| 2 | Copyright (C) 1997, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/floatfns.c b/src/floatfns.c index 645a5957609..43576a16248 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Primitive operations on floating point for GNU Emacs Lisp interpreter. | 1 | /* Primitive operations on floating point for GNU Emacs Lisp interpreter. |
| 2 | 2 | ||
| 3 | Copyright (C) 1988, 1993-1994, 1999, 2001-2012 | 3 | Copyright (C) 1988, 1993-1994, 1999, 2001-2013 Free Software Foundation, |
| 4 | Free Software Foundation, Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | Author: Wolfgang Rupprecht | 6 | Author: Wolfgang Rupprecht |
| 7 | (according to ack.texi) | 7 | (according to ack.texi) |
| @@ -399,8 +399,8 @@ round2 (EMACS_INT i1, EMACS_INT i2) | |||
| 399 | odd. */ | 399 | odd. */ |
| 400 | EMACS_INT q = i1 / i2; | 400 | EMACS_INT q = i1 / i2; |
| 401 | EMACS_INT r = i1 % i2; | 401 | EMACS_INT r = i1 % i2; |
| 402 | EMACS_INT abs_r = r < 0 ? -r : r; | 402 | EMACS_INT abs_r = eabs (r); |
| 403 | EMACS_INT abs_r1 = (i2 < 0 ? -i2 : i2) - abs_r; | 403 | EMACS_INT abs_r1 = eabs (i2) - abs_r; |
| 404 | return q + (abs_r + (q & 1) <= abs_r1 ? 0 : (i2 ^ r) < 0 ? -1 : 1); | 404 | return q + (abs_r + (q & 1) <= abs_r1 ? 0 : (i2 ^ r) < 0 ? -1 : 1); |
| 405 | } | 405 | } |
| 406 | 406 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Random utility Lisp functions. | 1 | /* Random utility Lisp functions. |
| 2 | Copyright (C) 1985-1987, 1993-1995, 1997-2012 | 2 | |
| 3 | Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1987, 1993-1995, 1997-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -66,7 +66,10 @@ and `most-positive-fixnum', inclusive, are equally likely. | |||
| 66 | 66 | ||
| 67 | With positive integer LIMIT, return random number in interval [0,LIMIT). | 67 | With positive integer LIMIT, return random number in interval [0,LIMIT). |
| 68 | With argument t, set the random number seed from the current time and pid. | 68 | With argument t, set the random number seed from the current time and pid. |
| 69 | Other values of LIMIT are ignored. */) | 69 | With a string argument, set the seed based on the string's contents. |
| 70 | Other values of LIMIT are ignored. | ||
| 71 | |||
| 72 | See Info node `(elisp)Random Numbers' for more details. */) | ||
| 70 | (Lisp_Object limit) | 73 | (Lisp_Object limit) |
| 71 | { | 74 | { |
| 72 | EMACS_INT val; | 75 | EMACS_INT val; |
| @@ -86,7 +89,7 @@ Other values of LIMIT are ignored. */) | |||
| 86 | before it's time to do a QUIT. This must be a power of 2. */ | 89 | before it's time to do a QUIT. This must be a power of 2. */ |
| 87 | enum { QUIT_COUNT_HEURISTIC = 1 << 16 }; | 90 | enum { QUIT_COUNT_HEURISTIC = 1 << 16 }; |
| 88 | 91 | ||
| 89 | /* Random data-structure functions */ | 92 | /* Random data-structure functions. */ |
| 90 | 93 | ||
| 91 | DEFUN ("length", Flength, Slength, 1, 1, 0, | 94 | DEFUN ("length", Flength, Slength, 1, 1, 0, |
| 92 | doc: /* Return the length of vector, list or string SEQUENCE. | 95 | doc: /* Return the length of vector, list or string SEQUENCE. |
| @@ -211,12 +214,18 @@ Symbols are also allowed; their print names are used instead. */) | |||
| 211 | 214 | ||
| 212 | DEFUN ("compare-strings", Fcompare_strings, Scompare_strings, 6, 7, 0, | 215 | DEFUN ("compare-strings", Fcompare_strings, Scompare_strings, 6, 7, 0, |
| 213 | doc: /* Compare the contents of two strings, converting to multibyte if needed. | 216 | doc: /* Compare the contents of two strings, converting to multibyte if needed. |
| 214 | In string STR1, skip the first START1 characters and stop at END1. | 217 | The arguments START1, END1, START2, and END2, if non-nil, are |
| 215 | In string STR2, skip the first START2 characters and stop at END2. | 218 | positions specifying which parts of STR1 or STR2 to compare. In |
| 216 | END1 and END2 default to the full lengths of the respective strings. | 219 | string STR1, compare the part between START1 (inclusive) and END1 |
| 217 | 220 | \(exclusive). If START1 is nil, it defaults to 0, the beginning of | |
| 218 | Case is significant in this comparison if IGNORE-CASE is nil. | 221 | the string; if END1 is nil, it defaults to the length of the string. |
| 219 | Unibyte strings are converted to multibyte for comparison. | 222 | Likewise, in string STR2, compare the part between START2 and END2. |
| 223 | |||
| 224 | The strings are compared by the numeric values of their characters. | ||
| 225 | For instance, STR1 is "less than" STR2 if its first differing | ||
| 226 | character has a smaller numeric value. If IGNORE-CASE is non-nil, | ||
| 227 | characters are converted to lower-case before comparing them. Unibyte | ||
| 228 | strings are converted to multibyte for comparison. | ||
| 220 | 229 | ||
| 221 | The value is t if the strings (or specified portions) match. | 230 | The value is t if the strings (or specified portions) match. |
| 222 | If string STR1 is less, the value is a negative number N; | 231 | If string STR1 is less, the value is a negative number N; |
| @@ -2476,7 +2485,7 @@ is nil, and `use-dialog-box' is non-nil. */) | |||
| 2476 | 2485 | ||
| 2477 | Fding (Qnil); | 2486 | Fding (Qnil); |
| 2478 | Fdiscard_input (); | 2487 | Fdiscard_input (); |
| 2479 | message ("Please answer yes or no."); | 2488 | message1 ("Please answer yes or no."); |
| 2480 | Fsleep_for (make_number (2), Qnil); | 2489 | Fsleep_for (make_number (2), Qnil); |
| 2481 | } | 2490 | } |
| 2482 | } | 2491 | } |
| @@ -2736,7 +2745,7 @@ ARGS are passed as extra arguments to the function. | |||
| 2736 | usage: (widget-apply WIDGET PROPERTY &rest ARGS) */) | 2745 | usage: (widget-apply WIDGET PROPERTY &rest ARGS) */) |
| 2737 | (ptrdiff_t nargs, Lisp_Object *args) | 2746 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2738 | { | 2747 | { |
| 2739 | /* This function can GC. */ | 2748 | /* This function can GC. */ |
| 2740 | Lisp_Object newargs[3]; | 2749 | Lisp_Object newargs[3]; |
| 2741 | struct gcpro gcpro1, gcpro2; | 2750 | struct gcpro gcpro1, gcpro2; |
| 2742 | Lisp_Object result; | 2751 | Lisp_Object result; |
| @@ -2798,9 +2807,8 @@ The data read from the system are decoded using `locale-coding-system'. */) | |||
| 2798 | val = build_unibyte_string (str); | 2807 | val = build_unibyte_string (str); |
| 2799 | /* Fixme: Is this coding system necessarily right, even if | 2808 | /* Fixme: Is this coding system necessarily right, even if |
| 2800 | it is consistent with CODESET? If not, what to do? */ | 2809 | it is consistent with CODESET? If not, what to do? */ |
| 2801 | Faset (v, make_number (i), | 2810 | ASET (v, i, code_convert_string_norecord (val, Vlocale_coding_system, |
| 2802 | code_convert_string_norecord (val, Vlocale_coding_system, | 2811 | 0)); |
| 2803 | 0)); | ||
| 2804 | } | 2812 | } |
| 2805 | UNGCPRO; | 2813 | UNGCPRO; |
| 2806 | return v; | 2814 | return v; |
| @@ -2820,8 +2828,8 @@ The data read from the system are decoded using `locale-coding-system'. */) | |||
| 2820 | { | 2828 | { |
| 2821 | str = nl_langinfo (months[i]); | 2829 | str = nl_langinfo (months[i]); |
| 2822 | val = build_unibyte_string (str); | 2830 | val = build_unibyte_string (str); |
| 2823 | Faset (v, make_number (i), | 2831 | ASET (v, i, code_convert_string_norecord (val, Vlocale_coding_system, |
| 2824 | code_convert_string_norecord (val, Vlocale_coding_system, 0)); | 2832 | 0)); |
| 2825 | } | 2833 | } |
| 2826 | UNGCPRO; | 2834 | UNGCPRO; |
| 2827 | return v; | 2835 | return v; |
| @@ -4037,10 +4045,6 @@ sweep_weak_hash_tables (void) | |||
| 4037 | 4045 | ||
| 4038 | #define SXHASH_MAX_LEN 7 | 4046 | #define SXHASH_MAX_LEN 7 |
| 4039 | 4047 | ||
| 4040 | /* Hash X, returning a value that fits into a Lisp integer. */ | ||
| 4041 | #define SXHASH_REDUCE(X) \ | ||
| 4042 | ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK) | ||
| 4043 | |||
| 4044 | /* Return a hash for string PTR which has length LEN. The hash value | 4048 | /* Return a hash for string PTR which has length LEN. The hash value |
| 4045 | can be any EMACS_UINT value. */ | 4049 | can be any EMACS_UINT value. */ |
| 4046 | 4050 | ||
| @@ -4073,7 +4077,7 @@ sxhash_string (char const *ptr, ptrdiff_t len) | |||
| 4073 | 4077 | ||
| 4074 | /* Return a hash for the floating point value VAL. */ | 4078 | /* Return a hash for the floating point value VAL. */ |
| 4075 | 4079 | ||
| 4076 | static EMACS_INT | 4080 | static EMACS_UINT |
| 4077 | sxhash_float (double val) | 4081 | sxhash_float (double val) |
| 4078 | { | 4082 | { |
| 4079 | EMACS_UINT hash = 0; | 4083 | EMACS_UINT hash = 0; |
diff --git a/src/font.c b/src/font.c index f6b6fa026c0..e2ea7262397 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* font.c -- "Font" primitives. | 1 | /* font.c -- "Font" primitives. |
| 2 | 2 | ||
| 3 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 4 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | 4 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 6 | Registration Number H13PRO009 | 6 | Registration Number H13PRO009 |
| @@ -717,7 +717,7 @@ font_put_extra (Lisp_Object font, Lisp_Object prop, Lisp_Object val) | |||
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | 719 | ||
| 720 | /* Font name parser and unparser */ | 720 | /* Font name parser and unparser. */ |
| 721 | 721 | ||
| 722 | static int parse_matrix (const char *); | 722 | static int parse_matrix (const char *); |
| 723 | static int font_expand_wildcards (Lisp_Object *, int); | 723 | static int font_expand_wildcards (Lisp_Object *, int); |
| @@ -1746,7 +1746,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec | |||
| 1746 | /* This part (through the next ^L) is still experimental and not | 1746 | /* This part (through the next ^L) is still experimental and not |
| 1747 | tested much. We may drastically change codes. */ | 1747 | tested much. We may drastically change codes. */ |
| 1748 | 1748 | ||
| 1749 | /* OTF handler */ | 1749 | /* OTF handler. */ |
| 1750 | 1750 | ||
| 1751 | #if 0 | 1751 | #if 0 |
| 1752 | 1752 | ||
| @@ -1857,11 +1857,11 @@ otf_open (Lisp_Object file) | |||
| 1857 | OTF *otf; | 1857 | OTF *otf; |
| 1858 | 1858 | ||
| 1859 | if (! NILP (val)) | 1859 | if (! NILP (val)) |
| 1860 | otf = XSAVE_VALUE (XCDR (val))->pointer; | 1860 | otf = XSAVE_POINTER (XCDR (val), 0); |
| 1861 | else | 1861 | else |
| 1862 | { | 1862 | { |
| 1863 | otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; | 1863 | otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; |
| 1864 | val = make_save_value (otf, 0); | 1864 | val = make_save_pointer (otf); |
| 1865 | otf_list = Fcons (Fcons (file, val), otf_list); | 1865 | otf_list = Fcons (Fcons (file, val), otf_list); |
| 1866 | } | 1866 | } |
| 1867 | return otf; | 1867 | return otf; |
| @@ -2035,7 +2035,7 @@ font_otf_Anchor (OTF_Anchor *anchor) | |||
| 2035 | #endif /* 0 */ | 2035 | #endif /* 0 */ |
| 2036 | 2036 | ||
| 2037 | 2037 | ||
| 2038 | /* Font sorting */ | 2038 | /* Font sorting. */ |
| 2039 | 2039 | ||
| 2040 | static unsigned font_score (Lisp_Object, Lisp_Object *); | 2040 | static unsigned font_score (Lisp_Object, Lisp_Object *); |
| 2041 | static int font_compare (const void *, const void *); | 2041 | static int font_compare (const void *, const void *); |
| @@ -2101,9 +2101,7 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop) | |||
| 2101 | { | 2101 | { |
| 2102 | EMACS_INT diff = ((XINT (AREF (entity, i)) >> 8) | 2102 | EMACS_INT diff = ((XINT (AREF (entity, i)) >> 8) |
| 2103 | - (XINT (spec_prop[i]) >> 8)); | 2103 | - (XINT (spec_prop[i]) >> 8)); |
| 2104 | if (diff < 0) | 2104 | score |= min (eabs (diff), 127) << sort_shift_bits[i]; |
| 2105 | diff = - diff; | ||
| 2106 | score |= min (diff, 127) << sort_shift_bits[i]; | ||
| 2107 | } | 2105 | } |
| 2108 | 2106 | ||
| 2109 | /* Score the size. Maximum difference is 127. */ | 2107 | /* Score the size. Maximum difference is 127. */ |
| @@ -2118,10 +2116,7 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop) | |||
| 2118 | 2116 | ||
| 2119 | if (CONSP (Vface_font_rescale_alist)) | 2117 | if (CONSP (Vface_font_rescale_alist)) |
| 2120 | pixel_size *= font_rescale_ratio (entity); | 2118 | pixel_size *= font_rescale_ratio (entity); |
| 2121 | diff = pixel_size - XINT (AREF (entity, FONT_SIZE_INDEX)); | 2119 | diff = eabs (pixel_size - XINT (AREF (entity, FONT_SIZE_INDEX))) << 1; |
| 2122 | if (diff < 0) | ||
| 2123 | diff = - diff; | ||
| 2124 | diff <<= 1; | ||
| 2125 | if (! NILP (spec_prop[FONT_DPI_INDEX]) | 2120 | if (! NILP (spec_prop[FONT_DPI_INDEX]) |
| 2126 | && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX))) | 2121 | && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX))) |
| 2127 | diff |= 1; | 2122 | diff |= 1; |
| @@ -2570,7 +2565,6 @@ font_get_cache (FRAME_PTR f, struct font_driver *driver) | |||
| 2570 | return val; | 2565 | return val; |
| 2571 | } | 2566 | } |
| 2572 | 2567 | ||
| 2573 | static int num_fonts; | ||
| 2574 | 2568 | ||
| 2575 | static void | 2569 | static void |
| 2576 | font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver) | 2570 | font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver) |
| @@ -2603,7 +2597,6 @@ font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver) | |||
| 2603 | { | 2597 | { |
| 2604 | eassert (font && driver == font->driver); | 2598 | eassert (font && driver == font->driver); |
| 2605 | driver->close (f, font); | 2599 | driver->close (f, font); |
| 2606 | num_fonts--; | ||
| 2607 | } | 2600 | } |
| 2608 | } | 2601 | } |
| 2609 | if (driver->free_entity) | 2602 | if (driver->free_entity) |
| @@ -2671,9 +2664,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) | |||
| 2671 | { | 2664 | { |
| 2672 | int diff = XINT (AREF (entity, FONT_SIZE_INDEX)) - size; | 2665 | int diff = XINT (AREF (entity, FONT_SIZE_INDEX)) - size; |
| 2673 | 2666 | ||
| 2674 | if (diff != 0 | 2667 | if (eabs (diff) > FONT_PIXEL_SIZE_QUANTUM) |
| 2675 | && (diff < 0 ? -diff > FONT_PIXEL_SIZE_QUANTUM | ||
| 2676 | : diff > FONT_PIXEL_SIZE_QUANTUM)) | ||
| 2677 | prop = FONT_SPEC_MAX; | 2668 | prop = FONT_SPEC_MAX; |
| 2678 | } | 2669 | } |
| 2679 | if (prop < FONT_SPEC_MAX | 2670 | if (prop < FONT_SPEC_MAX |
| @@ -2863,7 +2854,6 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size) | |||
| 2863 | return Qnil; | 2854 | return Qnil; |
| 2864 | ASET (entity, FONT_OBJLIST_INDEX, | 2855 | ASET (entity, FONT_OBJLIST_INDEX, |
| 2865 | Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); | 2856 | Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); |
| 2866 | num_fonts++; | ||
| 2867 | 2857 | ||
| 2868 | font = XFONT_OBJECT (font_object); | 2858 | font = XFONT_OBJECT (font_object); |
| 2869 | min_width = (font->min_width ? font->min_width | 2859 | min_width = (font->min_width ? font->min_width |
| @@ -2908,7 +2898,6 @@ font_close_object (FRAME_PTR f, Lisp_Object font_object) | |||
| 2908 | eassert (FRAME_X_DISPLAY_INFO (f)->n_fonts); | 2898 | eassert (FRAME_X_DISPLAY_INFO (f)->n_fonts); |
| 2909 | FRAME_X_DISPLAY_INFO (f)->n_fonts--; | 2899 | FRAME_X_DISPLAY_INFO (f)->n_fonts--; |
| 2910 | #endif | 2900 | #endif |
| 2911 | num_fonts--; | ||
| 2912 | } | 2901 | } |
| 2913 | 2902 | ||
| 2914 | 2903 | ||
| @@ -3585,7 +3574,7 @@ font_filter_properties (Lisp_Object font, | |||
| 3585 | Lisp_Object it; | 3574 | Lisp_Object it; |
| 3586 | int i; | 3575 | int i; |
| 3587 | 3576 | ||
| 3588 | /* Set boolean values to Qt or Qnil */ | 3577 | /* Set boolean values to Qt or Qnil. */ |
| 3589 | for (i = 0; boolean_properties[i] != NULL; ++i) | 3578 | for (i = 0; boolean_properties[i] != NULL; ++i) |
| 3590 | for (it = alist; ! NILP (it); it = XCDR (it)) | 3579 | for (it = alist; ! NILP (it); it = XCDR (it)) |
| 3591 | { | 3580 | { |
| @@ -3700,11 +3689,11 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, | |||
| 3700 | 3689 | ||
| 3701 | #ifdef HAVE_WINDOW_SYSTEM | 3690 | #ifdef HAVE_WINDOW_SYSTEM |
| 3702 | 3691 | ||
| 3703 | /* Check how many characters after POS (at most to *LIMIT) can be | 3692 | /* Check how many characters after character/byte position POS/POS_BYTE |
| 3704 | displayed by the same font in the window W. FACE, if non-NULL, is | 3693 | (at most to *LIMIT) can be displayed by the same font in the window W. |
| 3705 | the face selected for the character at POS. If STRING is not nil, | 3694 | FACE, if non-NULL, is the face selected for the character at POS. |
| 3706 | it is the string to check instead of the current buffer. In that | 3695 | If STRING is not nil, it is the string to check instead of the current |
| 3707 | case, FACE must be not NULL. | 3696 | buffer. In that case, FACE must be not NULL. |
| 3708 | 3697 | ||
| 3709 | The return value is the font-object for the character at POS. | 3698 | The return value is the font-object for the character at POS. |
| 3710 | *LIMIT is set to the position where that font can't be used. | 3699 | *LIMIT is set to the position where that font can't be used. |
| @@ -3712,15 +3701,15 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, | |||
| 3712 | It is assured that the current buffer (or STRING) is multibyte. */ | 3701 | It is assured that the current buffer (or STRING) is multibyte. */ |
| 3713 | 3702 | ||
| 3714 | Lisp_Object | 3703 | Lisp_Object |
| 3715 | font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face, Lisp_Object string) | 3704 | font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, |
| 3705 | struct window *w, struct face *face, Lisp_Object string) | ||
| 3716 | { | 3706 | { |
| 3717 | ptrdiff_t pos_byte, ignore; | 3707 | ptrdiff_t ignore; |
| 3718 | int c; | 3708 | int c; |
| 3719 | Lisp_Object font_object = Qnil; | 3709 | Lisp_Object font_object = Qnil; |
| 3720 | 3710 | ||
| 3721 | if (NILP (string)) | 3711 | if (NILP (string)) |
| 3722 | { | 3712 | { |
| 3723 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 3724 | if (! face) | 3713 | if (! face) |
| 3725 | { | 3714 | { |
| 3726 | int face_id; | 3715 | int face_id; |
| @@ -3731,10 +3720,7 @@ font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face | |||
| 3731 | } | 3720 | } |
| 3732 | } | 3721 | } |
| 3733 | else | 3722 | else |
| 3734 | { | 3723 | eassert (face); |
| 3735 | eassert (face); | ||
| 3736 | pos_byte = string_char_to_byte (string, pos); | ||
| 3737 | } | ||
| 3738 | 3724 | ||
| 3739 | while (pos < *limit) | 3725 | while (pos < *limit) |
| 3740 | { | 3726 | { |
| @@ -3764,7 +3750,7 @@ font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face | |||
| 3764 | #endif | 3750 | #endif |
| 3765 | 3751 | ||
| 3766 | 3752 | ||
| 3767 | /* Lisp API */ | 3753 | /* Lisp API. */ |
| 3768 | 3754 | ||
| 3769 | DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0, | 3755 | DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0, |
| 3770 | doc: /* Return t if OBJECT is a font-spec, font-entity, or font-object. | 3756 | doc: /* Return t if OBJECT is a font-spec, font-entity, or font-object. |
| @@ -4614,7 +4600,7 @@ If the font is not OpenType font, CAPABILITY is nil. */) | |||
| 4614 | 4600 | ||
| 4615 | CHECK_FONT_GET_OBJECT (font_object, font); | 4601 | CHECK_FONT_GET_OBJECT (font_object, font); |
| 4616 | 4602 | ||
| 4617 | val = Fmake_vector (make_number (9), Qnil); | 4603 | val = make_uninit_vector (9); |
| 4618 | ASET (val, 0, AREF (font_object, FONT_NAME_INDEX)); | 4604 | ASET (val, 0, AREF (font_object, FONT_NAME_INDEX)); |
| 4619 | ASET (val, 1, AREF (font_object, FONT_FILE_INDEX)); | 4605 | ASET (val, 1, AREF (font_object, FONT_FILE_INDEX)); |
| 4620 | ASET (val, 2, make_number (font->pixel_size)); | 4606 | ASET (val, 2, make_number (font->pixel_size)); |
| @@ -4625,6 +4611,8 @@ If the font is not OpenType font, CAPABILITY is nil. */) | |||
| 4625 | ASET (val, 7, make_number (font->average_width)); | 4611 | ASET (val, 7, make_number (font->average_width)); |
| 4626 | if (font->driver->otf_capability) | 4612 | if (font->driver->otf_capability) |
| 4627 | ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font))); | 4613 | ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font))); |
| 4614 | else | ||
| 4615 | ASET (val, 8, Qnil); | ||
| 4628 | return val; | 4616 | return val; |
| 4629 | } | 4617 | } |
| 4630 | 4618 | ||
| @@ -4840,7 +4828,7 @@ where | |||
| 4840 | OPENED-NAME is the name used for opening the font, | 4828 | OPENED-NAME is the name used for opening the font, |
| 4841 | FULL-NAME is the full name of the font, | 4829 | FULL-NAME is the full name of the font, |
| 4842 | SIZE is the pixelsize of the font, | 4830 | SIZE is the pixelsize of the font, |
| 4843 | HEIGHT is the pixel-height of the font (i.e ascent + descent), | 4831 | HEIGHT is the pixel-height of the font (i.e., ascent + descent), |
| 4844 | BASELINE-OFFSET is the upward offset pixels from ASCII baseline, | 4832 | BASELINE-OFFSET is the upward offset pixels from ASCII baseline, |
| 4845 | RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling | 4833 | RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling |
| 4846 | how to compose characters. | 4834 | how to compose characters. |
| @@ -4881,7 +4869,7 @@ If the named font is not yet loaded, return nil. */) | |||
| 4881 | return Qnil; | 4869 | return Qnil; |
| 4882 | font = XFONT_OBJECT (font_object); | 4870 | font = XFONT_OBJECT (font_object); |
| 4883 | 4871 | ||
| 4884 | info = Fmake_vector (make_number (7), Qnil); | 4872 | info = make_uninit_vector (7); |
| 4885 | ASET (info, 0, AREF (font_object, FONT_NAME_INDEX)); | 4873 | ASET (info, 0, AREF (font_object, FONT_NAME_INDEX)); |
| 4886 | ASET (info, 1, AREF (font_object, FONT_FULLNAME_INDEX)); | 4874 | ASET (info, 1, AREF (font_object, FONT_FULLNAME_INDEX)); |
| 4887 | ASET (info, 2, make_number (font->pixel_size)); | 4875 | ASET (info, 2, make_number (font->pixel_size)); |
| @@ -5174,7 +5162,7 @@ See `font-weight-table' for the format of the vector. */); | |||
| 5174 | XSYMBOL (intern_c_string ("font-width-table"))->constant = 1; | 5162 | XSYMBOL (intern_c_string ("font-width-table"))->constant = 1; |
| 5175 | 5163 | ||
| 5176 | staticpro (&font_style_table); | 5164 | staticpro (&font_style_table); |
| 5177 | font_style_table = Fmake_vector (make_number (3), Qnil); | 5165 | font_style_table = make_uninit_vector (3); |
| 5178 | ASET (font_style_table, 0, Vfont_weight_table); | 5166 | ASET (font_style_table, 0, Vfont_weight_table); |
| 5179 | ASET (font_style_table, 1, Vfont_slant_table); | 5167 | ASET (font_style_table, 1, Vfont_slant_table); |
| 5180 | ASET (font_style_table, 2, Vfont_width_table); | 5168 | ASET (font_style_table, 2, Vfont_width_table); |
diff --git a/src/font.h b/src/font.h index 3035a909efc..ffed0461ff7 100644 --- a/src/font.h +++ b/src/font.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* font.h -- Interface definition for font handling. | 1 | /* font.h -- Interface definition for font handling. |
| 2 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H13PRO009 | 5 | Registration Number H13PRO009 |
| @@ -781,7 +781,7 @@ extern int font_unparse_fcname (Lisp_Object font, int pixel_size, | |||
| 781 | extern void register_font_driver (struct font_driver *driver, FRAME_PTR f); | 781 | extern void register_font_driver (struct font_driver *driver, FRAME_PTR f); |
| 782 | extern void free_font_driver_list (FRAME_PTR f); | 782 | extern void free_font_driver_list (FRAME_PTR f); |
| 783 | extern Lisp_Object font_update_drivers (FRAME_PTR f, Lisp_Object list); | 783 | extern Lisp_Object font_update_drivers (FRAME_PTR f, Lisp_Object list); |
| 784 | extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t *, | 784 | extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *, |
| 785 | struct window *, struct face *, | 785 | struct window *, struct face *, |
| 786 | Lisp_Object); | 786 | Lisp_Object); |
| 787 | extern void font_fill_lglyph_metrics (Lisp_Object, Lisp_Object); | 787 | extern void font_fill_lglyph_metrics (Lisp_Object, Lisp_Object); |
diff --git a/src/fontset.c b/src/fontset.c index 660ca432fad..3578bc9403d 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Fontset handler. | 1 | /* Fontset handler. |
| 2 | 2 | ||
| 3 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 4 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 4 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 5 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 5 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 6 | National Institute of Advanced Industrial Science and Technology (AIST) | 6 | National Institute of Advanced Industrial Science and Technology (AIST) |
| @@ -271,7 +271,8 @@ set_fontset_fallback (Lisp_Object fontset, Lisp_Object fallback) | |||
| 271 | /* Macros for FONT-DEF and RFONT-DEF of fontset. */ | 271 | /* Macros for FONT-DEF and RFONT-DEF of fontset. */ |
| 272 | #define FONT_DEF_NEW(font_def, font_spec, encoding, repertory) \ | 272 | #define FONT_DEF_NEW(font_def, font_spec, encoding, repertory) \ |
| 273 | do { \ | 273 | do { \ |
| 274 | (font_def) = Fmake_vector (make_number (3), (font_spec)); \ | 274 | (font_def) = make_uninit_vector (3); \ |
| 275 | ASET ((font_def), 0, font_spec); \ | ||
| 275 | ASET ((font_def), 1, encoding); \ | 276 | ASET ((font_def), 1, encoding); \ |
| 276 | ASET ((font_def), 2, repertory); \ | 277 | ASET ((font_def), 2, repertory); \ |
| 277 | } while (0) | 278 | } while (0) |
| @@ -1591,7 +1592,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */) | |||
| 1591 | { | 1592 | { |
| 1592 | Lisp_Object arg; | 1593 | Lisp_Object arg; |
| 1593 | 1594 | ||
| 1594 | arg = Fmake_vector (make_number (5), Qnil); | 1595 | arg = make_uninit_vector (5); |
| 1595 | ASET (arg, 0, fontset); | 1596 | ASET (arg, 0, fontset); |
| 1596 | ASET (arg, 1, font_def); | 1597 | ASET (arg, 1, font_def); |
| 1597 | ASET (arg, 2, add); | 1598 | ASET (arg, 2, add); |
diff --git a/src/fontset.h b/src/fontset.h index 3eb8d633b6c..07ee5d65c25 100644 --- a/src/fontset.h +++ b/src/fontset.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Header for fontset handler. | 1 | /* Header for fontset handler. |
| 2 | Copyright (C) 1998, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1998, 2001-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | 3 | Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 4 | 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | 5 | National Institute of Advanced Industrial Science and Technology (AIST) |
diff --git a/src/frame.c b/src/frame.c index 5cefad6ca46..0fa821682f3 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Generic frame functions. | 1 | /* Generic frame functions. |
| 2 | 2 | ||
| 3 | Copyright (C) 1993-1995, 1997, 1999-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1993-1995, 1997, 1999-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -60,7 +60,7 @@ Lisp_Object Qns_parse_geometry; | |||
| 60 | Lisp_Object Qframep, Qframe_live_p; | 60 | Lisp_Object Qframep, Qframe_live_p; |
| 61 | Lisp_Object Qicon, Qmodeline; | 61 | Lisp_Object Qicon, Qmodeline; |
| 62 | Lisp_Object Qonly, Qnone; | 62 | Lisp_Object Qonly, Qnone; |
| 63 | Lisp_Object Qx, Qw32, Qmac, Qpc, Qns; | 63 | Lisp_Object Qx, Qw32, Qpc, Qns; |
| 64 | Lisp_Object Qvisible; | 64 | Lisp_Object Qvisible; |
| 65 | Lisp_Object Qdisplay_type; | 65 | Lisp_Object Qdisplay_type; |
| 66 | static Lisp_Object Qbackground_mode; | 66 | static Lisp_Object Qbackground_mode; |
| @@ -225,8 +225,6 @@ See also `frame-live-p'. */) | |||
| 225 | return Qw32; | 225 | return Qw32; |
| 226 | case output_msdos_raw: | 226 | case output_msdos_raw: |
| 227 | return Qpc; | 227 | return Qpc; |
| 228 | case output_mac: | ||
| 229 | return Qmac; | ||
| 230 | case output_ns: | 228 | case output_ns: |
| 231 | return Qns; | 229 | return Qns; |
| 232 | default: | 230 | default: |
| @@ -502,8 +500,7 @@ make_initial_frame (void) | |||
| 502 | tty_frame_count = 1; | 500 | tty_frame_count = 1; |
| 503 | fset_name (f, build_pure_c_string ("F1")); | 501 | fset_name (f, build_pure_c_string ("F1")); |
| 504 | 502 | ||
| 505 | f->visible = 1; | 503 | SET_FRAME_VISIBLE (f, 1); |
| 506 | f->async_visible = 1; | ||
| 507 | 504 | ||
| 508 | f->output_method = terminal->type; | 505 | f->output_method = terminal->type; |
| 509 | f->terminal = terminal; | 506 | f->terminal = terminal; |
| @@ -542,8 +539,8 @@ make_terminal_frame (struct terminal *terminal) | |||
| 542 | 539 | ||
| 543 | fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count)); | 540 | fset_name (f, make_formatted_string (name, "F%"pMd, ++tty_frame_count)); |
| 544 | 541 | ||
| 545 | f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */ | 542 | SET_FRAME_VISIBLE (f, 1); |
| 546 | f->async_visible = 1; /* Don't let visible be cleared later. */ | 543 | |
| 547 | f->terminal = terminal; | 544 | f->terminal = terminal; |
| 548 | f->terminal->reference_count++; | 545 | f->terminal->reference_count++; |
| 549 | #ifdef MSDOS | 546 | #ifdef MSDOS |
| @@ -567,7 +564,7 @@ make_terminal_frame (struct terminal *terminal) | |||
| 567 | /* Set the top frame to the newly created frame. */ | 564 | /* Set the top frame to the newly created frame. */ |
| 568 | if (FRAMEP (FRAME_TTY (f)->top_frame) | 565 | if (FRAMEP (FRAME_TTY (f)->top_frame) |
| 569 | && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))) | 566 | && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))) |
| 570 | XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */ | 567 | SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */ |
| 571 | 568 | ||
| 572 | FRAME_TTY (f)->top_frame = frame; | 569 | FRAME_TTY (f)->top_frame = frame; |
| 573 | 570 | ||
| @@ -808,8 +805,8 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor | |||
| 808 | { | 805 | { |
| 809 | if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame)) | 806 | if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame)) |
| 810 | /* Mark previously displayed frame as now obscured. */ | 807 | /* Mark previously displayed frame as now obscured. */ |
| 811 | XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2; | 808 | SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (XFRAME (frame))->top_frame), 2); |
| 812 | XFRAME (frame)->async_visible = 1; | 809 | SET_FRAME_VISIBLE (XFRAME (frame), 1); |
| 813 | FRAME_TTY (XFRAME (frame))->top_frame = frame; | 810 | FRAME_TTY (XFRAME (frame))->top_frame = frame; |
| 814 | } | 811 | } |
| 815 | 812 | ||
| @@ -916,7 +913,6 @@ candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf) | |||
| 916 | } | 913 | } |
| 917 | else if (EQ (minibuf, Qvisible)) | 914 | else if (EQ (minibuf, Qvisible)) |
| 918 | { | 915 | { |
| 919 | FRAME_SAMPLE_VISIBILITY (c); | ||
| 920 | if (FRAME_VISIBLE_P (c)) | 916 | if (FRAME_VISIBLE_P (c)) |
| 921 | return candidate; | 917 | return candidate; |
| 922 | } | 918 | } |
| @@ -930,7 +926,6 @@ candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf) | |||
| 930 | } | 926 | } |
| 931 | else if (XFASTINT (minibuf) == 0) | 927 | else if (XFASTINT (minibuf) == 0) |
| 932 | { | 928 | { |
| 933 | FRAME_SAMPLE_VISIBILITY (c); | ||
| 934 | if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c)) | 929 | if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c)) |
| 935 | return candidate; | 930 | return candidate; |
| 936 | } | 931 | } |
| @@ -1054,10 +1049,7 @@ other_visible_frames (FRAME_PTR f) | |||
| 1054 | and note any recent change in visibility. */ | 1049 | and note any recent change in visibility. */ |
| 1055 | #ifdef HAVE_WINDOW_SYSTEM | 1050 | #ifdef HAVE_WINDOW_SYSTEM |
| 1056 | if (FRAME_WINDOW_P (XFRAME (this))) | 1051 | if (FRAME_WINDOW_P (XFRAME (this))) |
| 1057 | { | 1052 | x_sync (XFRAME (this)); |
| 1058 | x_sync (XFRAME (this)); | ||
| 1059 | FRAME_SAMPLE_VISIBILITY (XFRAME (this)); | ||
| 1060 | } | ||
| 1061 | #endif | 1053 | #endif |
| 1062 | 1054 | ||
| 1063 | if (FRAME_VISIBLE_P (XFRAME (this)) | 1055 | if (FRAME_VISIBLE_P (XFRAME (this)) |
| @@ -1233,7 +1225,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1233 | fset_root_window (f, Qnil); | 1225 | fset_root_window (f, Qnil); |
| 1234 | 1226 | ||
| 1235 | Vframe_list = Fdelq (frame, Vframe_list); | 1227 | Vframe_list = Fdelq (frame, Vframe_list); |
| 1236 | FRAME_SET_VISIBLE (f, 0); | 1228 | SET_FRAME_VISIBLE (f, 0); |
| 1237 | 1229 | ||
| 1238 | /* Allow the vector of menu bar contents to be freed in the next | 1230 | /* Allow the vector of menu bar contents to be freed in the next |
| 1239 | garbage collection. The frame object itself may not be garbage | 1231 | garbage collection. The frame object itself may not be garbage |
| @@ -1253,7 +1245,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1253 | xfree (FRAME_DELETEN_COST (f)); | 1245 | xfree (FRAME_DELETEN_COST (f)); |
| 1254 | xfree (FRAME_INSERTN_COST (f)); | 1246 | xfree (FRAME_INSERTN_COST (f)); |
| 1255 | xfree (FRAME_DELETE_COST (f)); | 1247 | xfree (FRAME_DELETE_COST (f)); |
| 1256 | xfree (FRAME_MESSAGE_BUF (f)); | ||
| 1257 | 1248 | ||
| 1258 | /* Since some events are handled at the interrupt level, we may get | 1249 | /* Since some events are handled at the interrupt level, we may get |
| 1259 | an event for f at any time; if we zero out the frame's terminal | 1250 | an event for f at any time; if we zero out the frame's terminal |
| @@ -1268,10 +1259,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force) | |||
| 1268 | { | 1259 | { |
| 1269 | struct terminal *terminal = FRAME_TERMINAL (f); | 1260 | struct terminal *terminal = FRAME_TERMINAL (f); |
| 1270 | f->output_data.nothing = 0; | 1261 | f->output_data.nothing = 0; |
| 1271 | f->terminal = 0; /* Now the frame is dead. */ | 1262 | f->terminal = 0; /* Now the frame is dead. */ |
| 1272 | 1263 | ||
| 1273 | /* If needed, delete the terminal that this frame was on. | 1264 | /* If needed, delete the terminal that this frame was on. |
| 1274 | (This must be done after the frame is killed.) */ | 1265 | (This must be done after the frame is killed.) */ |
| 1275 | terminal->reference_count--; | 1266 | terminal->reference_count--; |
| 1276 | #ifdef USE_GTK | 1267 | #ifdef USE_GTK |
| 1277 | /* FIXME: Deleting the terminal crashes emacs because of a GTK | 1268 | /* FIXME: Deleting the terminal crashes emacs because of a GTK |
| @@ -1582,10 +1573,7 @@ If omitted, FRAME defaults to the currently selected frame. */) | |||
| 1582 | /* I think this should be done with a hook. */ | 1573 | /* I think this should be done with a hook. */ |
| 1583 | #ifdef HAVE_WINDOW_SYSTEM | 1574 | #ifdef HAVE_WINDOW_SYSTEM |
| 1584 | if (FRAME_WINDOW_P (f)) | 1575 | if (FRAME_WINDOW_P (f)) |
| 1585 | { | 1576 | x_make_frame_visible (f); |
| 1586 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 1587 | x_make_frame_visible (f); | ||
| 1588 | } | ||
| 1589 | #endif | 1577 | #endif |
| 1590 | 1578 | ||
| 1591 | make_frame_visible_1 (f->root_window); | 1579 | make_frame_visible_1 (f->root_window); |
| @@ -1708,8 +1696,6 @@ currently being displayed on the terminal. */) | |||
| 1708 | { | 1696 | { |
| 1709 | CHECK_LIVE_FRAME (frame); | 1697 | CHECK_LIVE_FRAME (frame); |
| 1710 | 1698 | ||
| 1711 | FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); | ||
| 1712 | |||
| 1713 | if (FRAME_VISIBLE_P (XFRAME (frame))) | 1699 | if (FRAME_VISIBLE_P (XFRAME (frame))) |
| 1714 | return Qt; | 1700 | return Qt; |
| 1715 | if (FRAME_ICONIFIED_P (XFRAME (frame))) | 1701 | if (FRAME_ICONIFIED_P (XFRAME (frame))) |
| @@ -2894,7 +2880,6 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr) | |||
| 2894 | make_formatted_string (buf, "%"pMu, w)); | 2880 | make_formatted_string (buf, "%"pMu, w)); |
| 2895 | #endif | 2881 | #endif |
| 2896 | store_in_alist (alistptr, Qicon_name, f->icon_name); | 2882 | store_in_alist (alistptr, Qicon_name, f->icon_name); |
| 2897 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 2898 | store_in_alist (alistptr, Qvisibility, | 2883 | store_in_alist (alistptr, Qvisibility, |
| 2899 | (FRAME_VISIBLE_P (f) ? Qt | 2884 | (FRAME_VISIBLE_P (f) ? Qt |
| 2900 | : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); | 2885 | : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); |
| @@ -4248,6 +4233,16 @@ Setting this variable does not affect existing frames, only new ones. */); | |||
| 4248 | Vdefault_frame_scroll_bars = Qnil; | 4233 | Vdefault_frame_scroll_bars = Qnil; |
| 4249 | #endif | 4234 | #endif |
| 4250 | 4235 | ||
| 4236 | DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion", | ||
| 4237 | scroll_bar_adjust_thumb_portion_p, | ||
| 4238 | doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF. | ||
| 4239 | Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards | ||
| 4240 | even if the end of the buffer is shown (i.e. overscrolling). | ||
| 4241 | Set to nil if you want the thumb to be at the bottom when the end of the buffer | ||
| 4242 | is shown. Also, the thumb fills the whole scroll bar when the entire buffer | ||
| 4243 | is visible. In this case you can not overscroll. */); | ||
| 4244 | scroll_bar_adjust_thumb_portion_p = 1; | ||
| 4245 | |||
| 4251 | DEFVAR_LISP ("terminal-frame", Vterminal_frame, | 4246 | DEFVAR_LISP ("terminal-frame", Vterminal_frame, |
| 4252 | doc: /* The initial frame-object, which represents Emacs's stdout. */); | 4247 | doc: /* The initial frame-object, which represents Emacs's stdout. */); |
| 4253 | 4248 | ||
diff --git a/src/frame.h b/src/frame.h index 589b45fc0ff..c18b7662079 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Define frame-object for GNU Emacs. | 1 | /* Define frame-object for GNU Emacs. |
| 2 | Copyright (C) 1993-1994, 1999-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1994, 1999-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -18,7 +18,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 18 | 18 | ||
| 19 | /* Don't multiply include: dispextern.h includes macterm.h which | 19 | /* Don't multiply include: dispextern.h includes macterm.h which |
| 20 | includes frame.h some emacs source includes both dispextern.h and | 20 | includes frame.h some emacs source includes both dispextern.h and |
| 21 | frame.h */ | 21 | frame.h. */ |
| 22 | 22 | ||
| 23 | #ifndef EMACS_FRAME_H | 23 | #ifndef EMACS_FRAME_H |
| 24 | #define EMACS_FRAME_H | 24 | #define EMACS_FRAME_H |
| @@ -33,7 +33,7 @@ INLINE_HEADER_BEGIN | |||
| 33 | 33 | ||
| 34 | /* Miscellanea. */ | 34 | /* Miscellanea. */ |
| 35 | 35 | ||
| 36 | /* Nonzero means there is at least one garbaged frame. */ | 36 | /* Nonzero means there is at least one garbaged frame. */ |
| 37 | extern bool frame_garbaged; | 37 | extern bool frame_garbaged; |
| 38 | 38 | ||
| 39 | 39 | ||
| @@ -46,7 +46,6 @@ enum output_method | |||
| 46 | output_x_window, | 46 | output_x_window, |
| 47 | output_msdos_raw, | 47 | output_msdos_raw, |
| 48 | output_w32, | 48 | output_w32, |
| 49 | output_mac, | ||
| 50 | output_ns | 49 | output_ns |
| 51 | }; | 50 | }; |
| 52 | 51 | ||
| @@ -201,7 +200,7 @@ struct frame | |||
| 201 | string's pointer (`name', above) because it might get relocated. */ | 200 | string's pointer (`name', above) because it might get relocated. */ |
| 202 | char *namebuf; | 201 | char *namebuf; |
| 203 | 202 | ||
| 204 | /* Glyph pool and matrix. */ | 203 | /* Glyph pool and matrix. */ |
| 205 | struct glyph_pool *current_pool; | 204 | struct glyph_pool *current_pool; |
| 206 | struct glyph_pool *desired_pool; | 205 | struct glyph_pool *desired_pool; |
| 207 | struct glyph_matrix *desired_matrix; | 206 | struct glyph_matrix *desired_matrix; |
| @@ -354,46 +353,30 @@ struct frame | |||
| 354 | unsigned int external_menu_bar : 1; | 353 | unsigned int external_menu_bar : 1; |
| 355 | #endif | 354 | #endif |
| 356 | 355 | ||
| 357 | /* visible is nonzero if the frame is currently displayed; we check | 356 | /* Next two bitfields are mutually exclusive. They might both be |
| 357 | zero if the frame has been made invisible without an icon. */ | ||
| 358 | |||
| 359 | /* Nonzero if the frame is currently displayed; we check | ||
| 358 | it to see if we should bother updating the frame's contents. | 360 | it to see if we should bother updating the frame's contents. |
| 359 | DON'T SET IT DIRECTLY; instead, use FRAME_SET_VISIBLE. | ||
| 360 | 361 | ||
| 361 | Note that, since invisible frames aren't updated, whenever a | 362 | Note that, since invisible frames aren't updated, whenever a |
| 362 | frame becomes visible again, it must be marked as garbaged. The | 363 | frame becomes visible again, it must be marked as garbaged. |
| 363 | FRAME_SAMPLE_VISIBILITY macro takes care of this. | ||
| 364 | 364 | ||
| 365 | On ttys and on Windows NT/9X, to avoid wasting effort updating | 365 | On ttys and on Windows NT/9X, to avoid wasting effort updating |
| 366 | visible frames that are actually completely obscured by other | 366 | visible frames that are actually completely obscured by other |
| 367 | windows on the display, we bend the meaning of visible slightly: | 367 | windows on the display, we bend the meaning of visible slightly: |
| 368 | if greater than 1, then the frame is obscured - we still consider | 368 | if equal to 2, then the frame is obscured - we still consider |
| 369 | it to be "visible" as seen from lisp, but we don't bother | 369 | it to be "visible" as seen from lisp, but we don't bother |
| 370 | updating it. We must take care to garbage the frame when it | 370 | updating it. We must take care to garbage the frame when it |
| 371 | ceases to be obscured though. | 371 | ceases to be obscured though. See SET_FRAME_VISIBLE below. */ |
| 372 | |||
| 373 | iconified is nonzero if the frame is currently iconified. | ||
| 374 | |||
| 375 | Asynchronous input handlers should NOT change these directly; | ||
| 376 | instead, they should change async_visible or async_iconified, and | ||
| 377 | let the FRAME_SAMPLE_VISIBILITY macro set visible and iconified | ||
| 378 | at the next redisplay. | ||
| 379 | |||
| 380 | These should probably be considered read-only by everyone except | ||
| 381 | FRAME_SAMPLE_VISIBILITY. | ||
| 382 | |||
| 383 | These two are mutually exclusive. They might both be zero, if the | ||
| 384 | frame has been made invisible without an icon. */ | ||
| 385 | unsigned visible : 2; | 372 | unsigned visible : 2; |
| 386 | unsigned iconified : 1; | ||
| 387 | 373 | ||
| 388 | /* Let's not use bitfields for volatile variables. */ | 374 | /* Nonzero if the frame is currently iconified. Do not |
| 389 | 375 | set this directly, use SET_FRAME_ICONIFIED instead. */ | |
| 390 | /* Asynchronous input handlers change these, and | 376 | unsigned iconified : 1; |
| 391 | FRAME_SAMPLE_VISIBILITY copies them into visible and iconified. | ||
| 392 | See FRAME_SAMPLE_VISIBILITY, below. */ | ||
| 393 | volatile char async_visible, async_iconified; | ||
| 394 | 377 | ||
| 395 | /* Nonzero if this frame should be redrawn. */ | 378 | /* Nonzero if this frame should be redrawn. */ |
| 396 | volatile char garbaged; | 379 | unsigned garbaged : 1; |
| 397 | 380 | ||
| 398 | /* True if frame actually has a minibuffer window on it. | 381 | /* True if frame actually has a minibuffer window on it. |
| 399 | 0 if using a minibuffer window that isn't on this frame. */ | 382 | 0 if using a minibuffer window that isn't on this frame. */ |
| @@ -445,9 +428,6 @@ struct frame | |||
| 445 | /* Width of bar cursor (if we are using that) for blink-off state. */ | 428 | /* Width of bar cursor (if we are using that) for blink-off state. */ |
| 446 | int blink_off_cursor_width; | 429 | int blink_off_cursor_width; |
| 447 | 430 | ||
| 448 | /* Storage for messages to this frame. */ | ||
| 449 | char *message_buf; | ||
| 450 | |||
| 451 | /* Nonnegative if current redisplay should not do scroll computation | 431 | /* Nonnegative if current redisplay should not do scroll computation |
| 452 | for lines beyond a certain vpos. This is the vpos. */ | 432 | for lines beyond a certain vpos. This is the vpos. */ |
| 453 | int scroll_bottom_vpos; | 433 | int scroll_bottom_vpos; |
| @@ -715,7 +695,7 @@ typedef struct frame *FRAME_PTR; | |||
| 715 | #else | 695 | #else |
| 716 | #define FRAME_EXTERNAL_MENU_BAR(f) 0 | 696 | #define FRAME_EXTERNAL_MENU_BAR(f) 0 |
| 717 | #endif | 697 | #endif |
| 718 | #define FRAME_VISIBLE_P(f) ((f)->visible != 0) | 698 | #define FRAME_VISIBLE_P(f) (f)->visible |
| 719 | 699 | ||
| 720 | /* Nonzero if frame F is currently visible but hidden. */ | 700 | /* Nonzero if frame F is currently visible but hidden. */ |
| 721 | #define FRAME_OBSCURED_P(f) ((f)->visible > 1) | 701 | #define FRAME_OBSCURED_P(f) ((f)->visible > 1) |
| @@ -723,9 +703,10 @@ typedef struct frame *FRAME_PTR; | |||
| 723 | /* Nonzero if frame F is currently iconified. */ | 703 | /* Nonzero if frame F is currently iconified. */ |
| 724 | #define FRAME_ICONIFIED_P(f) (f)->iconified | 704 | #define FRAME_ICONIFIED_P(f) (f)->iconified |
| 725 | 705 | ||
| 726 | #define FRAME_SET_VISIBLE(f,p) \ | 706 | /* Mark frame F as currently garbaged. */ |
| 727 | ((f)->async_visible = (p), FRAME_SAMPLE_VISIBILITY (f)) | ||
| 728 | #define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1) | 707 | #define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1) |
| 708 | |||
| 709 | /* Nonzero if frame F is currently garbaged. */ | ||
| 729 | #define FRAME_GARBAGED_P(f) (f)->garbaged | 710 | #define FRAME_GARBAGED_P(f) (f)->garbaged |
| 730 | 711 | ||
| 731 | /* Nonzero means do not allow splitting this frame's window. */ | 712 | /* Nonzero means do not allow splitting this frame's window. */ |
| @@ -752,7 +733,6 @@ typedef struct frame *FRAME_PTR; | |||
| 752 | #define FRAME_DELETE_COST(f) (f)->delete_line_cost | 733 | #define FRAME_DELETE_COST(f) (f)->delete_line_cost |
| 753 | #define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost | 734 | #define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost |
| 754 | #define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost | 735 | #define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost |
| 755 | #define FRAME_MESSAGE_BUF(f) (f)->message_buf | ||
| 756 | #define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos | 736 | #define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos |
| 757 | #define FRAME_FOCUS_FRAME(f) f->focus_frame | 737 | #define FRAME_FOCUS_FRAME(f) f->focus_frame |
| 758 | 738 | ||
| @@ -871,39 +851,6 @@ typedef struct frame *FRAME_PTR; | |||
| 871 | 851 | ||
| 872 | #define FRAME_MESSAGE_BUF_SIZE(f) (((int) FRAME_COLS (f)) * 4) | 852 | #define FRAME_MESSAGE_BUF_SIZE(f) (((int) FRAME_COLS (f)) * 4) |
| 873 | 853 | ||
| 874 | /* Emacs's redisplay code could become confused if a frame's | ||
| 875 | visibility changes at arbitrary times. For example, if a frame is | ||
| 876 | visible while the desired glyphs are being built, but becomes | ||
| 877 | invisible before they are updated, then some rows of the | ||
| 878 | desired_glyphs will be left marked as enabled after redisplay is | ||
| 879 | complete, which should never happen. The next time the frame | ||
| 880 | becomes visible, redisplay will probably barf. | ||
| 881 | |||
| 882 | Currently, there are no similar situations involving iconified, but | ||
| 883 | the principle is the same. | ||
| 884 | |||
| 885 | So instead of having asynchronous input handlers directly set and | ||
| 886 | clear the frame's visibility and iconification flags, they just set | ||
| 887 | the async_visible and async_iconified flags; the redisplay code | ||
| 888 | calls the FRAME_SAMPLE_VISIBILITY macro before doing any redisplay, | ||
| 889 | which sets visible and iconified from their asynchronous | ||
| 890 | counterparts. | ||
| 891 | |||
| 892 | Synchronous code must use the FRAME_SET_VISIBLE macro. | ||
| 893 | |||
| 894 | Also, if a frame used to be invisible, but has just become visible, | ||
| 895 | it must be marked as garbaged, since redisplay hasn't been keeping | ||
| 896 | up its contents. | ||
| 897 | |||
| 898 | Note that a tty frame is visible if and only if it is the topmost | ||
| 899 | frame. */ | ||
| 900 | |||
| 901 | #define FRAME_SAMPLE_VISIBILITY(f) \ | ||
| 902 | (((f)->async_visible && (f)->visible != (f)->async_visible) ? \ | ||
| 903 | SET_FRAME_GARBAGED (f) : 0, \ | ||
| 904 | (f)->visible = (f)->async_visible, \ | ||
| 905 | (f)->iconified = (f)->async_iconified) | ||
| 906 | |||
| 907 | #define CHECK_FRAME(x) \ | 854 | #define CHECK_FRAME(x) \ |
| 908 | CHECK_TYPE (FRAMEP (x), Qframep, x) | 855 | CHECK_TYPE (FRAMEP (x), Qframep, x) |
| 909 | 856 | ||
| @@ -937,12 +884,24 @@ typedef struct frame *FRAME_PTR; | |||
| 937 | block_input (); \ | 884 | block_input (); \ |
| 938 | if (hlinfo->mouse_face_mouse_frame) \ | 885 | if (hlinfo->mouse_face_mouse_frame) \ |
| 939 | note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \ | 886 | note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \ |
| 940 | hlinfo->mouse_face_mouse_x, \ | 887 | hlinfo->mouse_face_mouse_x, \ |
| 941 | hlinfo->mouse_face_mouse_y); \ | 888 | hlinfo->mouse_face_mouse_y); \ |
| 942 | unblock_input (); \ | 889 | unblock_input (); \ |
| 943 | } \ | 890 | } \ |
| 944 | } while (0) | 891 | } while (0) |
| 945 | 892 | ||
| 893 | /* Set visibility of frame F, marking F as garbaged if needed. */ | ||
| 894 | |||
| 895 | #define SET_FRAME_VISIBLE(f, v) \ | ||
| 896 | (((f)->visible == 0 || ((f)->visible == 2)) \ | ||
| 897 | && ((v) == 1) ? SET_FRAME_GARBAGED (f) : 0, \ | ||
| 898 | (f)->visible = (eassert (0 <= (v) && (v) <= 2), (v))) | ||
| 899 | |||
| 900 | /* Set iconify of frame F. */ | ||
| 901 | |||
| 902 | #define SET_FRAME_ICONIFIED(f, i) \ | ||
| 903 | (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i)) | ||
| 904 | |||
| 946 | extern Lisp_Object Qframep, Qframe_live_p; | 905 | extern Lisp_Object Qframep, Qframe_live_p; |
| 947 | extern Lisp_Object Qtty, Qtty_type; | 906 | extern Lisp_Object Qtty, Qtty_type; |
| 948 | extern Lisp_Object Qtty_color_mode; | 907 | extern Lisp_Object Qtty_color_mode; |
| @@ -1178,7 +1137,7 @@ extern Lisp_Object Qalpha; | |||
| 1178 | extern Lisp_Object Qleft_fringe, Qright_fringe; | 1137 | extern Lisp_Object Qleft_fringe, Qright_fringe; |
| 1179 | extern Lisp_Object Qheight, Qwidth; | 1138 | extern Lisp_Object Qheight, Qwidth; |
| 1180 | extern Lisp_Object Qminibuffer, Qmodeline; | 1139 | extern Lisp_Object Qminibuffer, Qmodeline; |
| 1181 | extern Lisp_Object Qx, Qw32, Qmac, Qpc, Qns; | 1140 | extern Lisp_Object Qx, Qw32, Qpc, Qns; |
| 1182 | extern Lisp_Object Qvisible; | 1141 | extern Lisp_Object Qvisible; |
| 1183 | extern Lisp_Object Qdisplay_type; | 1142 | extern Lisp_Object Qdisplay_type; |
| 1184 | 1143 | ||
diff --git a/src/fringe.c b/src/fringe.c index a126292e1ff..fa6f889ba69 100644 --- a/src/fringe.c +++ b/src/fringe.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Fringe handling (split from xdisp.c). | 1 | /* Fringe handling (split from xdisp.c). |
| 2 | Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software |
| 3 | Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -1360,8 +1361,8 @@ compute_fringe_widths (struct frame *f, int redraw) | |||
| 1360 | 1361 | ||
| 1361 | if (left_fringe_width || right_fringe_width) | 1362 | if (left_fringe_width || right_fringe_width) |
| 1362 | { | 1363 | { |
| 1363 | int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width; | 1364 | int left_wid = eabs (left_fringe_width); |
| 1364 | int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width; | 1365 | int right_wid = eabs (right_fringe_width); |
| 1365 | int conf_wid = left_wid + right_wid; | 1366 | int conf_wid = left_wid + right_wid; |
| 1366 | int font_wid = FRAME_COLUMN_WIDTH (f); | 1367 | int font_wid = FRAME_COLUMN_WIDTH (f); |
| 1367 | int cols = (left_wid + right_wid + font_wid-1) / font_wid; | 1368 | int cols = (left_wid + right_wid + font_wid-1) / font_wid; |
| @@ -1744,7 +1745,7 @@ Return nil if POS is not visible in WINDOW. */) | |||
| 1744 | else if (w == XWINDOW (selected_window)) | 1745 | else if (w == XWINDOW (selected_window)) |
| 1745 | textpos = PT; | 1746 | textpos = PT; |
| 1746 | else | 1747 | else |
| 1747 | textpos = XMARKER (w->pointm)->charpos; | 1748 | textpos = marker_position (w->pointm); |
| 1748 | 1749 | ||
| 1749 | row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | 1750 | row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
| 1750 | row = row_containing_pos (w, textpos, row, NULL, 0); | 1751 | row = row_containing_pos (w, textpos, row, NULL, 0); |
diff --git a/src/ftfont.c b/src/ftfont.c index f07ad6f33c7..1fb1b574a1c 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* ftfont.c -- FreeType font driver. | 1 | /* ftfont.c -- FreeType font driver. |
| 2 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H13PRO009 | 5 | Registration Number H13PRO009 |
| @@ -393,16 +393,14 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for) | |||
| 393 | cache_data = xmalloc (sizeof *cache_data); | 393 | cache_data = xmalloc (sizeof *cache_data); |
| 394 | cache_data->ft_face = NULL; | 394 | cache_data->ft_face = NULL; |
| 395 | cache_data->fc_charset = NULL; | 395 | cache_data->fc_charset = NULL; |
| 396 | val = make_save_value (NULL, 0); | 396 | val = make_save_value ("pi", cache_data, 0); |
| 397 | XSAVE_VALUE (val)->integer = 0; | ||
| 398 | XSAVE_VALUE (val)->pointer = cache_data; | ||
| 399 | cache = Fcons (Qnil, val); | 397 | cache = Fcons (Qnil, val); |
| 400 | Fputhash (key, cache, ft_face_cache); | 398 | Fputhash (key, cache, ft_face_cache); |
| 401 | } | 399 | } |
| 402 | else | 400 | else |
| 403 | { | 401 | { |
| 404 | val = XCDR (cache); | 402 | val = XCDR (cache); |
| 405 | cache_data = XSAVE_VALUE (val)->pointer; | 403 | cache_data = XSAVE_POINTER (val, 0); |
| 406 | } | 404 | } |
| 407 | 405 | ||
| 408 | if (cache_for == FTFONT_CACHE_FOR_ENTITY) | 406 | if (cache_for == FTFONT_CACHE_FOR_ENTITY) |
| @@ -468,7 +466,7 @@ ftfont_get_fc_charset (Lisp_Object entity) | |||
| 468 | 466 | ||
| 469 | cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET); | 467 | cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET); |
| 470 | val = XCDR (cache); | 468 | val = XCDR (cache); |
| 471 | cache_data = XSAVE_VALUE (val)->pointer; | 469 | cache_data = XSAVE_POINTER (val, 0); |
| 472 | return cache_data->fc_charset; | 470 | return cache_data->fc_charset; |
| 473 | } | 471 | } |
| 474 | 472 | ||
| @@ -1200,9 +1198,9 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) | |||
| 1200 | filename = XCAR (val); | 1198 | filename = XCAR (val); |
| 1201 | idx = XCDR (val); | 1199 | idx = XCDR (val); |
| 1202 | val = XCDR (cache); | 1200 | val = XCDR (cache); |
| 1203 | cache_data = XSAVE_VALUE (XCDR (cache))->pointer; | 1201 | cache_data = XSAVE_POINTER (XCDR (cache), 0); |
| 1204 | ft_face = cache_data->ft_face; | 1202 | ft_face = cache_data->ft_face; |
| 1205 | if (XSAVE_VALUE (val)->integer > 0) | 1203 | if (XSAVE_INTEGER (val, 1) > 0) |
| 1206 | { | 1204 | { |
| 1207 | /* FT_Face in this cache is already used by the different size. */ | 1205 | /* FT_Face in this cache is already used by the different size. */ |
| 1208 | if (FT_New_Size (ft_face, &ft_size) != 0) | 1206 | if (FT_New_Size (ft_face, &ft_size) != 0) |
| @@ -1213,13 +1211,13 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) | |||
| 1213 | return Qnil; | 1211 | return Qnil; |
| 1214 | } | 1212 | } |
| 1215 | } | 1213 | } |
| 1216 | XSAVE_VALUE (val)->integer++; | 1214 | XSAVE_INTEGER (val, 1)++; |
| 1217 | size = XINT (AREF (entity, FONT_SIZE_INDEX)); | 1215 | size = XINT (AREF (entity, FONT_SIZE_INDEX)); |
| 1218 | if (size == 0) | 1216 | if (size == 0) |
| 1219 | size = pixel_size; | 1217 | size = pixel_size; |
| 1220 | if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) | 1218 | if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) |
| 1221 | { | 1219 | { |
| 1222 | if (XSAVE_VALUE (val)->integer == 0) | 1220 | if (XSAVE_INTEGER (val, 1) == 0) |
| 1223 | FT_Done_Face (ft_face); | 1221 | FT_Done_Face (ft_face); |
| 1224 | return Qnil; | 1222 | return Qnil; |
| 1225 | } | 1223 | } |
| @@ -1328,10 +1326,10 @@ ftfont_close (FRAME_PTR f, struct font *font) | |||
| 1328 | cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE); | 1326 | cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE); |
| 1329 | eassert (CONSP (cache)); | 1327 | eassert (CONSP (cache)); |
| 1330 | val = XCDR (cache); | 1328 | val = XCDR (cache); |
| 1331 | (XSAVE_VALUE (val)->integer)--; | 1329 | XSAVE_INTEGER (val, 1)--; |
| 1332 | if (XSAVE_VALUE (val)->integer == 0) | 1330 | if (XSAVE_INTEGER (val, 1) == 0) |
| 1333 | { | 1331 | { |
| 1334 | struct ftfont_cache_data *cache_data = XSAVE_VALUE (val)->pointer; | 1332 | struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0); |
| 1335 | 1333 | ||
| 1336 | FT_Done_Face (cache_data->ft_face); | 1334 | FT_Done_Face (cache_data->ft_face); |
| 1337 | #ifdef HAVE_LIBOTF | 1335 | #ifdef HAVE_LIBOTF |
| @@ -2557,9 +2555,8 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, | |||
| 2557 | LGLYPH_SET_DESCENT (lglyph, g->descent >> 6); | 2555 | LGLYPH_SET_DESCENT (lglyph, g->descent >> 6); |
| 2558 | if (g->adjusted) | 2556 | if (g->adjusted) |
| 2559 | { | 2557 | { |
| 2560 | Lisp_Object vec; | 2558 | Lisp_Object vec = make_uninit_vector (3); |
| 2561 | 2559 | ||
| 2562 | vec = Fmake_vector (make_number (3), Qnil); | ||
| 2563 | ASET (vec, 0, make_number (g->xoff >> 6)); | 2560 | ASET (vec, 0, make_number (g->xoff >> 6)); |
| 2564 | ASET (vec, 1, make_number (g->yoff >> 6)); | 2561 | ASET (vec, 1, make_number (g->yoff >> 6)); |
| 2565 | ASET (vec, 2, make_number (g->xadv >> 6)); | 2562 | ASET (vec, 2, make_number (g->xadv >> 6)); |
diff --git a/src/ftxfont.c b/src/ftxfont.c index 5effe6e9104..8c56ee05adc 100644 --- a/src/ftxfont.c +++ b/src/ftxfont.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* ftxfont.c -- FreeType font driver on X (without using XFT). | 1 | /* ftxfont.c -- FreeType font driver on X (without using XFT). |
| 2 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H13PRO009 | 5 | Registration Number H13PRO009 |
diff --git a/src/getpagesize.h b/src/getpagesize.h index 545082b2e78..6d0932abf1b 100644 --- a/src/getpagesize.h +++ b/src/getpagesize.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Emulate getpagesize on systems that lack it. | 1 | /* Emulate getpagesize on systems that lack it. |
| 2 | Copyright (C) 1986, 1992, 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1986, 1992, 1995, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
diff --git a/src/gmalloc.c b/src/gmalloc.c index c325ca79910..bc1d85ac5fb 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Declarations for `malloc' and friends. | 1 | /* Declarations for `malloc' and friends. |
| 2 | Copyright (C) 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2002, 2003, 2004, | 2 | Copyright (C) 1990-1993, 1995-1996, 1999, 2002-2007, 2013 Free |
| 3 | 2005, 2006, 2007 Free Software Foundation, Inc. | 3 | Software Foundation, Inc. |
| 4 | Written May 1989 by Mike Haertel. | 4 | Written May 1989 by Mike Haertel. |
| 5 | 5 | ||
| 6 | This library is free software; you can redistribute it and/or | 6 | This library is free software; you can redistribute it and/or |
| @@ -14,9 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 14 | General Public License for more details. | 14 | General Public License for more details. |
| 15 | 15 | ||
| 16 | You should have received a copy of the GNU General Public | 16 | You should have received a copy of the GNU General Public |
| 17 | License along with this library; see the file COPYING. If | 17 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 18 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | 18 | ||
| 21 | The author may be reached (Email) at the address mike@ai.mit.edu, | 19 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 22 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 20 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| @@ -292,9 +290,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 292 | General Public License for more details. | 290 | General Public License for more details. |
| 293 | 291 | ||
| 294 | You should have received a copy of the GNU General Public | 292 | You should have received a copy of the GNU General Public |
| 295 | License along with this library; see the file COPYING. If | 293 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 296 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 297 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 298 | 294 | ||
| 299 | The author may be reached (Email) at the address mike@ai.mit.edu, | 295 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 300 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 296 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| @@ -972,9 +968,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 972 | General Public License for more details. | 968 | General Public License for more details. |
| 973 | 969 | ||
| 974 | You should have received a copy of the GNU General Public | 970 | You should have received a copy of the GNU General Public |
| 975 | License along with this library; see the file COPYING. If | 971 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 976 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 977 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 978 | 972 | ||
| 979 | The author may be reached (Email) at the address mike@ai.mit.edu, | 973 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 980 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 974 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| @@ -1286,9 +1280,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 1286 | General Public License for more details. | 1280 | General Public License for more details. |
| 1287 | 1281 | ||
| 1288 | You should have received a copy of the GNU General Public | 1282 | You should have received a copy of the GNU General Public |
| 1289 | License along with this library; see the file COPYING. If | 1283 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 1290 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 1291 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 1292 | 1284 | ||
| 1293 | The author may be reached (Email) at the address mike@ai.mit.edu, | 1285 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 1294 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 1286 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| @@ -1487,9 +1479,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 1487 | General Public License for more details. | 1479 | General Public License for more details. |
| 1488 | 1480 | ||
| 1489 | You should have received a copy of the GNU General Public | 1481 | You should have received a copy of the GNU General Public |
| 1490 | License along with this library; see the file COPYING. If | 1482 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 1491 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 1492 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 1493 | 1483 | ||
| 1494 | The author may be reached (Email) at the address mike@ai.mit.edu, | 1484 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 1495 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 1485 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| @@ -1520,9 +1510,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 1520 | GNU General Public License for more details. | 1510 | GNU General Public License for more details. |
| 1521 | 1511 | ||
| 1522 | You should have received a copy of the GNU General Public License | 1512 | You should have received a copy of the GNU General Public License |
| 1523 | along with the GNU C Library; see the file COPYING. If not, write to | 1513 | along with the GNU C Library. If not, see <http://www.gnu.org/licenses/>. */ |
| 1524 | the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, | ||
| 1525 | MA 02110-1301, USA. */ | ||
| 1526 | 1514 | ||
| 1527 | /* uClibc defines __GNU_LIBRARY__, but it is not completely | 1515 | /* uClibc defines __GNU_LIBRARY__, but it is not completely |
| 1528 | compatible. */ | 1516 | compatible. */ |
| @@ -1566,9 +1554,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 1566 | General Public License for more details. | 1554 | General Public License for more details. |
| 1567 | 1555 | ||
| 1568 | You should have received a copy of the GNU General Public | 1556 | You should have received a copy of the GNU General Public |
| 1569 | License along with this library; see the file COPYING. If | 1557 | License along with this library. If not, see <http://www.gnu.org/licenses/>. */ |
| 1570 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 1571 | Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
| 1572 | 1558 | ||
| 1573 | void *(*__memalign_hook) (size_t size, size_t alignment); | 1559 | void *(*__memalign_hook) (size_t size, size_t alignment); |
| 1574 | 1560 | ||
| @@ -1678,9 +1664,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 1678 | General Public License for more details. | 1664 | General Public License for more details. |
| 1679 | 1665 | ||
| 1680 | You should have received a copy of the GNU General Public | 1666 | You should have received a copy of the GNU General Public |
| 1681 | License along with this library; see the file COPYING. If | 1667 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 1682 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 1683 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 1684 | 1668 | ||
| 1685 | The author may be reached (Email) at the address mike@ai.mit.edu, | 1669 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 1686 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 1670 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| @@ -1722,9 +1706,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 1722 | General Public License for more details. | 1706 | General Public License for more details. |
| 1723 | 1707 | ||
| 1724 | You should have received a copy of the GNU General Public | 1708 | You should have received a copy of the GNU General Public |
| 1725 | License along with this library; see the file COPYING. If | 1709 | License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 1726 | not, write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 1727 | Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 1728 | 1710 | ||
| 1729 | The author may be reached (Email) at the address mike@ai.mit.edu, | 1711 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 1730 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 1712 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
diff --git a/src/gnutls.c b/src/gnutls.c index 03f753fa8cc..db0a6dac01c 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* GnuTLS glue for GNU Emacs. | 1 | /* GnuTLS glue for GNU Emacs. |
| 2 | Copyright (C) 2010-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2010-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/gnutls.h b/src/gnutls.h index 2b13908a748..f1a337e7b3e 100644 --- a/src/gnutls.h +++ b/src/gnutls.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* GnuTLS glue for GNU Emacs. | 1 | /* GnuTLS glue for GNU Emacs. |
| 2 | Copyright (C) 2010-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2010-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/gtkutil.c b/src/gtkutil.c index 52a6c37b0d5..d6e4dcebcd3 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Functions for creating and updating GTK widgets. | 1 | /* Functions for creating and updating GTK widgets. |
| 2 | 2 | ||
| 3 | Copyright (C) 2003-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2003-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -983,7 +983,7 @@ xg_frame_set_char_size (FRAME_PTR f, int cols, int rows) | |||
| 983 | size as fast as possible. | 983 | size as fast as possible. |
| 984 | For unmapped windows, we can set rows/cols. When | 984 | For unmapped windows, we can set rows/cols. When |
| 985 | the frame is mapped again we will (hopefully) get the correct size. */ | 985 | the frame is mapped again we will (hopefully) get the correct size. */ |
| 986 | if (f->async_visible) | 986 | if (FRAME_VISIBLE_P (f)) |
| 987 | { | 987 | { |
| 988 | /* Must call this to flush out events */ | 988 | /* Must call this to flush out events */ |
| 989 | (void)gtk_events_pending (); | 989 | (void)gtk_events_pending (); |
| @@ -1650,8 +1650,7 @@ xg_dialog_response_cb (GtkDialog *w, | |||
| 1650 | static Lisp_Object | 1650 | static Lisp_Object |
| 1651 | pop_down_dialog (Lisp_Object arg) | 1651 | pop_down_dialog (Lisp_Object arg) |
| 1652 | { | 1652 | { |
| 1653 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 1653 | struct xg_dialog_data *dd = XSAVE_POINTER (arg, 0); |
| 1654 | struct xg_dialog_data *dd = (struct xg_dialog_data *) p->pointer; | ||
| 1655 | 1654 | ||
| 1656 | block_input (); | 1655 | block_input (); |
| 1657 | if (dd->w) gtk_widget_destroy (dd->w); | 1656 | if (dd->w) gtk_widget_destroy (dd->w); |
| @@ -1717,7 +1716,7 @@ xg_dialog_run (FRAME_PTR f, GtkWidget *w) | |||
| 1717 | g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL); | 1716 | g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL); |
| 1718 | gtk_widget_show (w); | 1717 | gtk_widget_show (w); |
| 1719 | 1718 | ||
| 1720 | record_unwind_protect (pop_down_dialog, make_save_value (&dd, 0)); | 1719 | record_unwind_protect (pop_down_dialog, make_save_pointer (&dd)); |
| 1721 | 1720 | ||
| 1722 | (void) xg_maybe_add_timer (&dd); | 1721 | (void) xg_maybe_add_timer (&dd); |
| 1723 | g_main_loop_run (dd.loop); | 1722 | g_main_loop_run (dd.loop); |
| @@ -2416,6 +2415,8 @@ make_menu_item (const char *utf8_label, | |||
| 2416 | return w; | 2415 | return w; |
| 2417 | } | 2416 | } |
| 2418 | 2417 | ||
| 2418 | #ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW | ||
| 2419 | |||
| 2419 | static int xg_detached_menus; | 2420 | static int xg_detached_menus; |
| 2420 | 2421 | ||
| 2421 | /* Return true if there are detached menus. */ | 2422 | /* Return true if there are detached menus. */ |
| @@ -2454,7 +2455,13 @@ tearoff_activate (GtkWidget *widget, gpointer client_data) | |||
| 2454 | G_CALLBACK (tearoff_remove), 0); | 2455 | G_CALLBACK (tearoff_remove), 0); |
| 2455 | } | 2456 | } |
| 2456 | } | 2457 | } |
| 2457 | 2458 | #else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */ | |
| 2459 | bool | ||
| 2460 | xg_have_tear_offs (void) | ||
| 2461 | { | ||
| 2462 | return false; | ||
| 2463 | } | ||
| 2464 | #endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */ | ||
| 2458 | 2465 | ||
| 2459 | /* Create a menu item widget, and connect the callbacks. | 2466 | /* Create a menu item widget, and connect the callbacks. |
| 2460 | ITEM describes the menu item. | 2467 | ITEM describes the menu item. |
| @@ -2526,7 +2533,8 @@ xg_create_one_menuitem (widget_value *item, | |||
| 2526 | HIGHLIGHT_CB is the callback to call when entering/leaving menu items. | 2533 | HIGHLIGHT_CB is the callback to call when entering/leaving menu items. |
| 2527 | If POP_UP_P, create a popup menu. | 2534 | If POP_UP_P, create a popup menu. |
| 2528 | If MENU_BAR_P, create a menu bar. | 2535 | If MENU_BAR_P, create a menu bar. |
| 2529 | If ADD_TEAROFF_P, add a tearoff menu item. Ignored if MENU_BAR_P. | 2536 | If ADD_TEAROFF_P, add a tearoff menu item. Ignored if MENU_BAR_P or |
| 2537 | the Gtk+ version used does not have tearoffs. | ||
| 2530 | TOPMENU is the topmost GtkWidget that others shall be placed under. | 2538 | TOPMENU is the topmost GtkWidget that others shall be placed under. |
| 2531 | It may be NULL, in that case we create the appropriate widget | 2539 | It may be NULL, in that case we create the appropriate widget |
| 2532 | (menu bar or menu item depending on POP_UP_P and MENU_BAR_P) | 2540 | (menu bar or menu item depending on POP_UP_P and MENU_BAR_P) |
| @@ -2599,6 +2607,7 @@ create_menus (widget_value *data, | |||
| 2599 | "selection-done", deactivate_cb, 0); | 2607 | "selection-done", deactivate_cb, 0); |
| 2600 | } | 2608 | } |
| 2601 | 2609 | ||
| 2610 | #ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW | ||
| 2602 | if (! menu_bar_p && add_tearoff_p) | 2611 | if (! menu_bar_p && add_tearoff_p) |
| 2603 | { | 2612 | { |
| 2604 | GtkWidget *tearoff = gtk_tearoff_menu_item_new (); | 2613 | GtkWidget *tearoff = gtk_tearoff_menu_item_new (); |
| @@ -2607,6 +2616,7 @@ create_menus (widget_value *data, | |||
| 2607 | g_signal_connect (G_OBJECT (tearoff), "activate", | 2616 | g_signal_connect (G_OBJECT (tearoff), "activate", |
| 2608 | G_CALLBACK (tearoff_activate), 0); | 2617 | G_CALLBACK (tearoff_activate), 0); |
| 2609 | } | 2618 | } |
| 2619 | #endif | ||
| 2610 | 2620 | ||
| 2611 | for (item = data; item; item = item->next) | 2621 | for (item = data; item; item = item->next) |
| 2612 | { | 2622 | { |
| @@ -2897,11 +2907,13 @@ xg_update_menubar (GtkWidget *menubar, | |||
| 2897 | 2907 | ||
| 2898 | gtk_label_set_text (wlabel, utf8_label); | 2908 | gtk_label_set_text (wlabel, utf8_label); |
| 2899 | 2909 | ||
| 2910 | #ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW | ||
| 2900 | /* If this item has a submenu that has been detached, change | 2911 | /* If this item has a submenu that has been detached, change |
| 2901 | the title in the WM decorations also. */ | 2912 | the title in the WM decorations also. */ |
| 2902 | if (submenu && gtk_menu_get_tearoff_state (GTK_MENU (submenu))) | 2913 | if (submenu && gtk_menu_get_tearoff_state (GTK_MENU (submenu))) |
| 2903 | /* Set the title of the detached window. */ | 2914 | /* Set the title of the detached window. */ |
| 2904 | gtk_menu_set_title (GTK_MENU (submenu), utf8_label); | 2915 | gtk_menu_set_title (GTK_MENU (submenu), utf8_label); |
| 2916 | #endif | ||
| 2905 | 2917 | ||
| 2906 | if (utf8_label) g_free (utf8_label); | 2918 | if (utf8_label) g_free (utf8_label); |
| 2907 | iter = g_list_next (iter); | 2919 | iter = g_list_next (iter); |
| @@ -3129,7 +3141,8 @@ xg_update_submenu (GtkWidget *submenu, | |||
| 3129 | { | 3141 | { |
| 3130 | GtkWidget *w = GTK_WIDGET (iter->data); | 3142 | GtkWidget *w = GTK_WIDGET (iter->data); |
| 3131 | 3143 | ||
| 3132 | /* Skip tearoff items, they have no counterpart in val. */ | 3144 | #ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW |
| 3145 | /* Skip tearoff items, they have no counterpart in val. */ | ||
| 3133 | if (GTK_IS_TEAROFF_MENU_ITEM (w)) | 3146 | if (GTK_IS_TEAROFF_MENU_ITEM (w)) |
| 3134 | { | 3147 | { |
| 3135 | has_tearoff_p = 1; | 3148 | has_tearoff_p = 1; |
| @@ -3137,6 +3150,7 @@ xg_update_submenu (GtkWidget *submenu, | |||
| 3137 | if (iter) w = GTK_WIDGET (iter->data); | 3150 | if (iter) w = GTK_WIDGET (iter->data); |
| 3138 | else break; | 3151 | else break; |
| 3139 | } | 3152 | } |
| 3153 | #endif | ||
| 3140 | 3154 | ||
| 3141 | /* Remember first radio button in a group. If we get a mismatch in | 3155 | /* Remember first radio button in a group. If we get a mismatch in |
| 3142 | a radio group we must rebuild the whole group so that the connections | 3156 | a radio group we must rebuild the whole group so that the connections |
| @@ -3780,13 +3794,17 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, | |||
| 3780 | 3794 | ||
| 3781 | adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); | 3795 | adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); |
| 3782 | 3796 | ||
| 3783 | /* We do the same as for MOTIF in xterm.c, assume 30 chars per line | 3797 | if (scroll_bar_adjust_thumb_portion_p) |
| 3784 | rather than the real portion value. This makes the thumb less likely | 3798 | { |
| 3785 | to resize and that looks better. */ | 3799 | /* We do the same as for MOTIF in xterm.c, use 30 chars per |
| 3786 | portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; | 3800 | line rather than the real portion value. This makes the |
| 3787 | /* When the thumb is at the bottom, position == whole. | 3801 | thumb less likely to resize and that looks better. */ |
| 3788 | So we need to increase `whole' to make space for the thumb. */ | 3802 | portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; |
| 3789 | whole += portion; | 3803 | |
| 3804 | /* When the thumb is at the bottom, position == whole. | ||
| 3805 | So we need to increase `whole' to make space for the thumb. */ | ||
| 3806 | whole += portion; | ||
| 3807 | } | ||
| 3790 | 3808 | ||
| 3791 | if (whole <= 0) | 3809 | if (whole <= 0) |
| 3792 | top = 0, shown = 1; | 3810 | top = 0, shown = 1; |
| @@ -3796,13 +3814,8 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, | |||
| 3796 | shown = (gdouble) portion / whole; | 3814 | shown = (gdouble) portion / whole; |
| 3797 | } | 3815 | } |
| 3798 | 3816 | ||
| 3799 | size = shown * XG_SB_RANGE; | 3817 | size = clip_to_bounds (1, shown * XG_SB_RANGE, XG_SB_RANGE); |
| 3800 | size = min (size, XG_SB_RANGE); | 3818 | value = clip_to_bounds (XG_SB_MIN, top * XG_SB_RANGE, XG_SB_MAX - size); |
| 3801 | size = max (size, 1); | ||
| 3802 | |||
| 3803 | value = top * XG_SB_RANGE; | ||
| 3804 | value = min (value, XG_SB_MAX - size); | ||
| 3805 | value = max (value, XG_SB_MIN); | ||
| 3806 | 3819 | ||
| 3807 | /* Assume all lines are of equal size. */ | 3820 | /* Assume all lines are of equal size. */ |
| 3808 | new_step = size / max (1, FRAME_LINES (f)); | 3821 | new_step = size / max (1, FRAME_LINES (f)); |
| @@ -4143,7 +4156,7 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox, | |||
| 4143 | if (f) | 4156 | if (f) |
| 4144 | { | 4157 | { |
| 4145 | GtkRequisition req, req2; | 4158 | GtkRequisition req, req2; |
| 4146 | FRAME_X_OUTPUT (f)->toolbar_detached = 1; | 4159 | |
| 4147 | gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req); | 4160 | gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req); |
| 4148 | gtk_widget_get_preferred_size (w, NULL, &req2); | 4161 | gtk_widget_get_preferred_size (w, NULL, &req2); |
| 4149 | req.width -= req2.width; | 4162 | req.width -= req2.width; |
| @@ -4178,7 +4191,7 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox, | |||
| 4178 | if (f) | 4191 | if (f) |
| 4179 | { | 4192 | { |
| 4180 | GtkRequisition req, req2; | 4193 | GtkRequisition req, req2; |
| 4181 | FRAME_X_OUTPUT (f)->toolbar_detached = 0; | 4194 | |
| 4182 | gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req); | 4195 | gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req); |
| 4183 | gtk_widget_get_preferred_size (w, NULL, &req2); | 4196 | gtk_widget_get_preferred_size (w, NULL, &req2); |
| 4184 | req.width += req2.width; | 4197 | req.width += req2.width; |
| @@ -4274,6 +4287,12 @@ xg_tool_bar_item_expose_callback (GtkWidget *w, | |||
| 4274 | gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o) | 4287 | gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o) |
| 4275 | #endif | 4288 | #endif |
| 4276 | 4289 | ||
| 4290 | #ifdef HAVE_GTK_HANDLE_BOX_NEW | ||
| 4291 | #define TOOLBAR_TOP_WIDGET(x) ((x)->handlebox_widget) | ||
| 4292 | #else | ||
| 4293 | #define TOOLBAR_TOP_WIDGET(x) ((x)->toolbar_widget) | ||
| 4294 | #endif | ||
| 4295 | |||
| 4277 | /* Attach a tool bar to frame F. */ | 4296 | /* Attach a tool bar to frame F. */ |
| 4278 | 4297 | ||
| 4279 | static void | 4298 | static void |
| @@ -4281,14 +4300,16 @@ xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos) | |||
| 4281 | { | 4300 | { |
| 4282 | struct x_output *x = f->output_data.x; | 4301 | struct x_output *x = f->output_data.x; |
| 4283 | bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright); | 4302 | bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright); |
| 4303 | GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); | ||
| 4284 | 4304 | ||
| 4285 | toolbar_set_orientation (x->toolbar_widget, | 4305 | toolbar_set_orientation (x->toolbar_widget, |
| 4286 | into_hbox | 4306 | into_hbox |
| 4287 | ? GTK_ORIENTATION_VERTICAL | 4307 | ? GTK_ORIENTATION_VERTICAL |
| 4288 | : GTK_ORIENTATION_HORIZONTAL); | 4308 | : GTK_ORIENTATION_HORIZONTAL); |
| 4309 | #ifdef HAVE_GTK_HANDLE_BOX_NEW | ||
| 4289 | if (!x->handlebox_widget) | 4310 | if (!x->handlebox_widget) |
| 4290 | { | 4311 | { |
| 4291 | x->handlebox_widget = gtk_handle_box_new (); | 4312 | top_widget = x->handlebox_widget = gtk_handle_box_new (); |
| 4292 | g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached", | 4313 | g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached", |
| 4293 | G_CALLBACK (xg_tool_bar_detach_callback), f); | 4314 | G_CALLBACK (xg_tool_bar_detach_callback), f); |
| 4294 | g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached", | 4315 | g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached", |
| @@ -4296,34 +4317,55 @@ xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos) | |||
| 4296 | gtk_container_add (GTK_CONTAINER (x->handlebox_widget), | 4317 | gtk_container_add (GTK_CONTAINER (x->handlebox_widget), |
| 4297 | x->toolbar_widget); | 4318 | x->toolbar_widget); |
| 4298 | } | 4319 | } |
| 4320 | #endif | ||
| 4299 | 4321 | ||
| 4300 | if (into_hbox) | 4322 | if (into_hbox) |
| 4301 | { | 4323 | { |
| 4324 | #ifdef HAVE_GTK_HANDLE_BOX_NEW | ||
| 4302 | gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget), | 4325 | gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget), |
| 4303 | GTK_POS_TOP); | 4326 | GTK_POS_TOP); |
| 4304 | gtk_box_pack_start (GTK_BOX (x->hbox_widget), x->handlebox_widget, | 4327 | #endif |
| 4328 | gtk_box_pack_start (GTK_BOX (x->hbox_widget), top_widget, | ||
| 4305 | FALSE, FALSE, 0); | 4329 | FALSE, FALSE, 0); |
| 4306 | 4330 | ||
| 4307 | if (EQ (pos, Qleft)) | 4331 | if (EQ (pos, Qleft)) |
| 4308 | gtk_box_reorder_child (GTK_BOX (x->hbox_widget), | 4332 | gtk_box_reorder_child (GTK_BOX (x->hbox_widget), |
| 4309 | x->handlebox_widget, | 4333 | top_widget, |
| 4310 | 0); | 4334 | 0); |
| 4311 | x->toolbar_in_hbox = 1; | 4335 | x->toolbar_in_hbox = true; |
| 4312 | } | 4336 | } |
| 4313 | else | 4337 | else |
| 4314 | { | 4338 | { |
| 4315 | bool vbox_pos = x->menubar_widget != 0; | 4339 | bool vbox_pos = x->menubar_widget != 0; |
| 4340 | #ifdef HAVE_GTK_HANDLE_BOX_NEW | ||
| 4316 | gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget), | 4341 | gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget), |
| 4317 | GTK_POS_LEFT); | 4342 | GTK_POS_LEFT); |
| 4318 | gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget, | 4343 | #endif |
| 4344 | gtk_box_pack_start (GTK_BOX (x->vbox_widget), top_widget, | ||
| 4319 | FALSE, FALSE, 0); | 4345 | FALSE, FALSE, 0); |
| 4320 | 4346 | ||
| 4321 | if (EQ (pos, Qtop)) | 4347 | if (EQ (pos, Qtop)) |
| 4322 | gtk_box_reorder_child (GTK_BOX (x->vbox_widget), | 4348 | gtk_box_reorder_child (GTK_BOX (x->vbox_widget), |
| 4323 | x->handlebox_widget, | 4349 | top_widget, |
| 4324 | vbox_pos); | 4350 | vbox_pos); |
| 4325 | x->toolbar_in_hbox = 0; | 4351 | x->toolbar_in_hbox = false; |
| 4326 | } | 4352 | } |
| 4353 | x->toolbar_is_packed = true; | ||
| 4354 | } | ||
| 4355 | |||
| 4356 | static bool xg_update_tool_bar_sizes (FRAME_PTR f); | ||
| 4357 | |||
| 4358 | static void | ||
| 4359 | tb_size_cb (GtkWidget *widget, | ||
| 4360 | GdkRectangle *allocation, | ||
| 4361 | gpointer user_data) | ||
| 4362 | { | ||
| 4363 | /* When tool bar is created it has one preferred size. But when size is | ||
| 4364 | allocated between widgets, it may get another. So we must update | ||
| 4365 | size hints if tool bar size changes. Seen on Fedora 18 at least. */ | ||
| 4366 | FRAME_PTR f = (FRAME_PTR) user_data; | ||
| 4367 | if (xg_update_tool_bar_sizes (f)) | ||
| 4368 | x_wm_set_size_hint (f, 0, 0); | ||
| 4327 | } | 4369 | } |
| 4328 | 4370 | ||
| 4329 | /* Create a tool bar for frame F. */ | 4371 | /* Create a tool bar for frame F. */ |
| @@ -4352,12 +4394,13 @@ xg_create_tool_bar (FRAME_PTR f) | |||
| 4352 | } | 4394 | } |
| 4353 | 4395 | ||
| 4354 | x->toolbar_widget = gtk_toolbar_new (); | 4396 | x->toolbar_widget = gtk_toolbar_new (); |
| 4355 | x->toolbar_detached = 0; | ||
| 4356 | 4397 | ||
| 4357 | gtk_widget_set_name (x->toolbar_widget, "emacs-toolbar"); | 4398 | gtk_widget_set_name (x->toolbar_widget, "emacs-toolbar"); |
| 4358 | 4399 | ||
| 4359 | gtk_toolbar_set_style (GTK_TOOLBAR (x->toolbar_widget), GTK_TOOLBAR_ICONS); | 4400 | gtk_toolbar_set_style (GTK_TOOLBAR (x->toolbar_widget), GTK_TOOLBAR_ICONS); |
| 4360 | toolbar_set_orientation (x->toolbar_widget, GTK_ORIENTATION_HORIZONTAL); | 4401 | toolbar_set_orientation (x->toolbar_widget, GTK_ORIENTATION_HORIZONTAL); |
| 4402 | g_signal_connect (x->toolbar_widget, "size-allocate", | ||
| 4403 | G_CALLBACK (tb_size_cb), f); | ||
| 4361 | #if GTK_CHECK_VERSION (3, 3, 6) | 4404 | #if GTK_CHECK_VERSION (3, 3, 6) |
| 4362 | gsty = gtk_widget_get_style_context (x->toolbar_widget); | 4405 | gsty = gtk_widget_get_style_context (x->toolbar_widget); |
| 4363 | gtk_style_context_add_class (gsty, "primary-toolbar"); | 4406 | gtk_style_context_add_class (gsty, "primary-toolbar"); |
| @@ -4567,13 +4610,14 @@ xg_update_tool_bar_sizes (FRAME_PTR f) | |||
| 4567 | struct x_output *x = f->output_data.x; | 4610 | struct x_output *x = f->output_data.x; |
| 4568 | GtkRequisition req; | 4611 | GtkRequisition req; |
| 4569 | int nl = 0, nr = 0, nt = 0, nb = 0; | 4612 | int nl = 0, nr = 0, nt = 0, nb = 0; |
| 4613 | GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); | ||
| 4570 | 4614 | ||
| 4571 | gtk_widget_get_preferred_size (GTK_WIDGET (x->handlebox_widget), NULL, &req); | 4615 | gtk_widget_get_preferred_size (GTK_WIDGET (top_widget), NULL, &req); |
| 4572 | if (x->toolbar_in_hbox) | 4616 | if (x->toolbar_in_hbox) |
| 4573 | { | 4617 | { |
| 4574 | int pos; | 4618 | int pos; |
| 4575 | gtk_container_child_get (GTK_CONTAINER (x->hbox_widget), | 4619 | gtk_container_child_get (GTK_CONTAINER (x->hbox_widget), |
| 4576 | x->handlebox_widget, | 4620 | top_widget, |
| 4577 | "position", &pos, NULL); | 4621 | "position", &pos, NULL); |
| 4578 | if (pos == 0) nl = req.width; | 4622 | if (pos == 0) nl = req.width; |
| 4579 | else nr = req.width; | 4623 | else nr = req.width; |
| @@ -4582,7 +4626,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f) | |||
| 4582 | { | 4626 | { |
| 4583 | int pos; | 4627 | int pos; |
| 4584 | gtk_container_child_get (GTK_CONTAINER (x->vbox_widget), | 4628 | gtk_container_child_get (GTK_CONTAINER (x->vbox_widget), |
| 4585 | x->handlebox_widget, | 4629 | top_widget, |
| 4586 | "position", &pos, NULL); | 4630 | "position", &pos, NULL); |
| 4587 | if (pos == 0 || (pos == 1 && x->menubar_widget)) nt = req.height; | 4631 | if (pos == 0 || (pos == 1 && x->menubar_widget)) nt = req.height; |
| 4588 | else nb = req.height; | 4632 | else nb = req.height; |
| @@ -4617,7 +4661,6 @@ update_frame_tool_bar (FRAME_PTR f) | |||
| 4617 | GtkToolbar *wtoolbar; | 4661 | GtkToolbar *wtoolbar; |
| 4618 | GtkToolItem *ti; | 4662 | GtkToolItem *ti; |
| 4619 | GtkTextDirection dir; | 4663 | GtkTextDirection dir; |
| 4620 | bool pack_tool_bar = x->handlebox_widget == NULL; | ||
| 4621 | Lisp_Object style; | 4664 | Lisp_Object style; |
| 4622 | bool text_image, horiz; | 4665 | bool text_image, horiz; |
| 4623 | struct xg_frame_tb_info *tbinfo; | 4666 | struct xg_frame_tb_info *tbinfo; |
| @@ -4871,9 +4914,9 @@ update_frame_tool_bar (FRAME_PTR f) | |||
| 4871 | 4914 | ||
| 4872 | if (f->n_tool_bar_items != 0) | 4915 | if (f->n_tool_bar_items != 0) |
| 4873 | { | 4916 | { |
| 4874 | if (pack_tool_bar) | 4917 | if (! x->toolbar_is_packed) |
| 4875 | xg_pack_tool_bar (f, f->tool_bar_position); | 4918 | xg_pack_tool_bar (f, f->tool_bar_position); |
| 4876 | gtk_widget_show_all (GTK_WIDGET (x->handlebox_widget)); | 4919 | gtk_widget_show_all (TOOLBAR_TOP_WIDGET (x)); |
| 4877 | if (xg_update_tool_bar_sizes (f)) | 4920 | if (xg_update_tool_bar_sizes (f)) |
| 4878 | xg_height_or_width_changed (f); | 4921 | xg_height_or_width_changed (f); |
| 4879 | } | 4922 | } |
| @@ -4892,24 +4935,26 @@ free_frame_tool_bar (FRAME_PTR f) | |||
| 4892 | if (x->toolbar_widget) | 4935 | if (x->toolbar_widget) |
| 4893 | { | 4936 | { |
| 4894 | struct xg_frame_tb_info *tbinfo; | 4937 | struct xg_frame_tb_info *tbinfo; |
| 4895 | bool is_packed = x->handlebox_widget != 0; | 4938 | GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); |
| 4939 | |||
| 4896 | block_input (); | 4940 | block_input (); |
| 4897 | /* We may have created the toolbar_widget in xg_create_tool_bar, but | 4941 | /* We may have created the toolbar_widget in xg_create_tool_bar, but |
| 4898 | not the x->handlebox_widget which is created in xg_pack_tool_bar. */ | 4942 | not the x->handlebox_widget which is created in xg_pack_tool_bar. */ |
| 4899 | if (is_packed) | 4943 | if (x->toolbar_is_packed) |
| 4900 | { | 4944 | { |
| 4901 | if (x->toolbar_in_hbox) | 4945 | if (x->toolbar_in_hbox) |
| 4902 | gtk_container_remove (GTK_CONTAINER (x->hbox_widget), | 4946 | gtk_container_remove (GTK_CONTAINER (x->hbox_widget), |
| 4903 | x->handlebox_widget); | 4947 | top_widget); |
| 4904 | else | 4948 | else |
| 4905 | gtk_container_remove (GTK_CONTAINER (x->vbox_widget), | 4949 | gtk_container_remove (GTK_CONTAINER (x->vbox_widget), |
| 4906 | x->handlebox_widget); | 4950 | top_widget); |
| 4907 | } | 4951 | } |
| 4908 | else | 4952 | else |
| 4909 | gtk_widget_destroy (x->toolbar_widget); | 4953 | gtk_widget_destroy (x->toolbar_widget); |
| 4910 | 4954 | ||
| 4911 | x->toolbar_widget = 0; | 4955 | x->toolbar_widget = 0; |
| 4912 | x->handlebox_widget = 0; | 4956 | TOOLBAR_TOP_WIDGET (x) = 0; |
| 4957 | x->toolbar_is_packed = false; | ||
| 4913 | FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0; | 4958 | FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0; |
| 4914 | FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0; | 4959 | FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0; |
| 4915 | 4960 | ||
| @@ -4933,20 +4978,25 @@ void | |||
| 4933 | xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos) | 4978 | xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos) |
| 4934 | { | 4979 | { |
| 4935 | struct x_output *x = f->output_data.x; | 4980 | struct x_output *x = f->output_data.x; |
| 4981 | GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); | ||
| 4936 | 4982 | ||
| 4937 | if (! x->toolbar_widget || ! x->handlebox_widget) | 4983 | if (! x->toolbar_widget || ! top_widget) |
| 4938 | return; | 4984 | return; |
| 4939 | 4985 | ||
| 4940 | block_input (); | 4986 | block_input (); |
| 4941 | g_object_ref (x->handlebox_widget); | 4987 | g_object_ref (top_widget); |
| 4942 | if (x->toolbar_in_hbox) | 4988 | if (x->toolbar_is_packed) |
| 4943 | gtk_container_remove (GTK_CONTAINER (x->hbox_widget), | 4989 | { |
| 4944 | x->handlebox_widget); | 4990 | if (x->toolbar_in_hbox) |
| 4945 | else | 4991 | gtk_container_remove (GTK_CONTAINER (x->hbox_widget), |
| 4946 | gtk_container_remove (GTK_CONTAINER (x->vbox_widget), | 4992 | top_widget); |
| 4947 | x->handlebox_widget); | 4993 | else |
| 4994 | gtk_container_remove (GTK_CONTAINER (x->vbox_widget), | ||
| 4995 | top_widget); | ||
| 4996 | } | ||
| 4997 | |||
| 4948 | xg_pack_tool_bar (f, pos); | 4998 | xg_pack_tool_bar (f, pos); |
| 4949 | g_object_unref (x->handlebox_widget); | 4999 | g_object_unref (top_widget); |
| 4950 | if (xg_update_tool_bar_sizes (f)) | 5000 | if (xg_update_tool_bar_sizes (f)) |
| 4951 | xg_height_or_width_changed (f); | 5001 | xg_height_or_width_changed (f); |
| 4952 | 5002 | ||
| @@ -4972,7 +5022,9 @@ xg_initialize (void) | |||
| 4972 | 5022 | ||
| 4973 | gdpy_def = NULL; | 5023 | gdpy_def = NULL; |
| 4974 | xg_ignore_gtk_scrollbar = 0; | 5024 | xg_ignore_gtk_scrollbar = 0; |
| 5025 | #ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW | ||
| 4975 | xg_detached_menus = 0; | 5026 | xg_detached_menus = 0; |
| 5027 | #endif | ||
| 4976 | xg_menu_cb_list.prev = xg_menu_cb_list.next = | 5028 | xg_menu_cb_list.prev = xg_menu_cb_list.next = |
| 4977 | xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0; | 5029 | xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0; |
| 4978 | 5030 | ||
| @@ -5009,7 +5061,9 @@ xg_initialize (void) | |||
| 5009 | "cancel", 0); | 5061 | "cancel", 0); |
| 5010 | update_theme_scrollbar_width (); | 5062 | update_theme_scrollbar_width (); |
| 5011 | 5063 | ||
| 5064 | #ifdef HAVE_FREETYPE | ||
| 5012 | x_last_font_name = NULL; | 5065 | x_last_font_name = NULL; |
| 5066 | #endif | ||
| 5013 | } | 5067 | } |
| 5014 | 5068 | ||
| 5015 | #endif /* USE_GTK */ | 5069 | #endif /* USE_GTK */ |
diff --git a/src/gtkutil.h b/src/gtkutil.h index 43f2b237a68..288b3e99299 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Definitions and headers for GTK widgets. | 1 | /* Definitions and headers for GTK widgets. |
| 2 | 2 | ||
| 3 | Copyright (C) 2003-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2003-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/image.c b/src/image.c index 07db6cece1f..726b65d7338 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Functions for image support on window system. | 1 | /* Functions for image support on window system. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1989, 1992-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/indent.c b/src/indent.c index a3abf88feeb..ce1639eae1e 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Indentation functions. | 1 | /* Indentation functions. |
| 2 | Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2012 | 2 | Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -138,7 +138,7 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) | |||
| 138 | struct Lisp_Vector *widthtab; | 138 | struct Lisp_Vector *widthtab; |
| 139 | 139 | ||
| 140 | if (!VECTORP (BVAR (buf, width_table))) | 140 | if (!VECTORP (BVAR (buf, width_table))) |
| 141 | bset_width_table (buf, Fmake_vector (make_number (256), make_number (0))); | 141 | bset_width_table (buf, make_uninit_vector (256)); |
| 142 | widthtab = XVECTOR (BVAR (buf, width_table)); | 142 | widthtab = XVECTOR (BVAR (buf, width_table)); |
| 143 | eassert (widthtab->header.size == 256); | 143 | eassert (widthtab->header.size == 256); |
| 144 | 144 | ||
| @@ -291,7 +291,7 @@ DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0, | |||
| 291 | doc: /* Return the horizontal position of point. Beginning of line is column 0. | 291 | doc: /* Return the horizontal position of point. Beginning of line is column 0. |
| 292 | This is calculated by adding together the widths of all the displayed | 292 | This is calculated by adding together the widths of all the displayed |
| 293 | representations of the character between the start of the previous line | 293 | representations of the character between the start of the previous line |
| 294 | and point (eg. control characters will have a width of 2 or 4, tabs | 294 | and point (e.g., control characters will have a width of 2 or 4, tabs |
| 295 | will have a variable width). | 295 | will have a variable width). |
| 296 | Ignores finite width of frame, which means that this function may return | 296 | Ignores finite width of frame, which means that this function may return |
| 297 | values greater than (frame-width). | 297 | values greater than (frame-width). |
| @@ -571,7 +571,8 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol) | |||
| 571 | col += width; | 571 | col += width; |
| 572 | if (endp > scan) /* Avoid infinite loops with 0-width overlays. */ | 572 | if (endp > scan) /* Avoid infinite loops with 0-width overlays. */ |
| 573 | { | 573 | { |
| 574 | scan = endp; scan_byte = charpos_to_bytepos (scan); | 574 | scan = endp; |
| 575 | scan_byte = CHAR_TO_BYTE (scan); | ||
| 575 | continue; | 576 | continue; |
| 576 | } | 577 | } |
| 577 | } | 578 | } |
| @@ -1969,7 +1970,7 @@ whether or not it is currently displayed in some window. */) | |||
| 1969 | struct window *w; | 1970 | struct window *w; |
| 1970 | Lisp_Object old_buffer; | 1971 | Lisp_Object old_buffer; |
| 1971 | EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0); | 1972 | EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0); |
| 1972 | struct gcpro gcpro1, gcpro2, gcpro3; | 1973 | struct gcpro gcpro1; |
| 1973 | Lisp_Object lcols = Qnil; | 1974 | Lisp_Object lcols = Qnil; |
| 1974 | double cols IF_LINT (= 0); | 1975 | double cols IF_LINT (= 0); |
| 1975 | void *itdata = NULL; | 1976 | void *itdata = NULL; |
| @@ -1986,13 +1987,13 @@ whether or not it is currently displayed in some window. */) | |||
| 1986 | w = decode_live_window (window); | 1987 | w = decode_live_window (window); |
| 1987 | 1988 | ||
| 1988 | old_buffer = Qnil; | 1989 | old_buffer = Qnil; |
| 1989 | GCPRO3 (old_buffer, old_charpos, old_bytepos); | 1990 | GCPRO1 (old_buffer); |
| 1990 | if (XBUFFER (w->buffer) != current_buffer) | 1991 | if (XBUFFER (w->buffer) != current_buffer) |
| 1991 | { | 1992 | { |
| 1992 | /* Set the window's buffer temporarily to the current buffer. */ | 1993 | /* Set the window's buffer temporarily to the current buffer. */ |
| 1993 | old_buffer = w->buffer; | 1994 | old_buffer = w->buffer; |
| 1994 | old_charpos = XMARKER (w->pointm)->charpos; | 1995 | old_charpos = marker_position (w->pointm); |
| 1995 | old_bytepos = XMARKER (w->pointm)->bytepos; | 1996 | old_bytepos = marker_byte_position (w->pointm); |
| 1996 | wset_buffer (w, Fcurrent_buffer ()); | 1997 | wset_buffer (w, Fcurrent_buffer ()); |
| 1997 | set_marker_both (w->pointm, w->buffer, | 1998 | set_marker_both (w->pointm, w->buffer, |
| 1998 | BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); | 1999 | BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); |
| @@ -2025,7 +2026,11 @@ whether or not it is currently displayed in some window. */) | |||
| 2025 | const char *s = SSDATA (it.string); | 2026 | const char *s = SSDATA (it.string); |
| 2026 | const char *e = s + SBYTES (it.string); | 2027 | const char *e = s + SBYTES (it.string); |
| 2027 | 2028 | ||
| 2028 | disp_string_at_start_p = it.string_from_display_prop_p; | 2029 | /* If it.area is anything but TEXT_AREA, we need not bother |
| 2030 | about the display string, as it doesn't affect cursor | ||
| 2031 | positioning. */ | ||
| 2032 | disp_string_at_start_p = | ||
| 2033 | it.string_from_display_prop_p && it.area == TEXT_AREA; | ||
| 2029 | while (s < e) | 2034 | while (s < e) |
| 2030 | { | 2035 | { |
| 2031 | if (*s++ == '\n') | 2036 | if (*s++ == '\n') |
diff --git a/src/indent.h b/src/indent.h index abcd06036d1..acfd952754e 100644 --- a/src/indent.h +++ b/src/indent.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions for interface to indent.c | 1 | /* Definitions for interface to indent.c |
| 2 | Copyright (C) 1985-1986, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1986, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/inotify.c b/src/inotify.c new file mode 100644 index 00000000000..4efef9e55b7 --- /dev/null +++ b/src/inotify.c | |||
| @@ -0,0 +1,436 @@ | |||
| 1 | /* Inotify support for Emacs | ||
| 2 | |||
| 3 | Copyright (C) 2012-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 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/>. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | #ifdef HAVE_INOTIFY | ||
| 23 | |||
| 24 | #include "lisp.h" | ||
| 25 | #include "coding.h" | ||
| 26 | #include "process.h" | ||
| 27 | #include "keyboard.h" | ||
| 28 | #include "character.h" | ||
| 29 | #include "frame.h" /* Required for termhooks.h. */ | ||
| 30 | #include "termhooks.h" | ||
| 31 | |||
| 32 | static Lisp_Object Qaccess; /* IN_ACCESS */ | ||
| 33 | static Lisp_Object Qattrib; /* IN_ATTRIB */ | ||
| 34 | static Lisp_Object Qclose_write; /* IN_CLOSE_WRITE */ | ||
| 35 | static Lisp_Object Qclose_nowrite; /* IN_CLOSE_NOWRITE */ | ||
| 36 | static Lisp_Object Qcreate; /* IN_CREATE */ | ||
| 37 | static Lisp_Object Qdelete; /* IN_DELETE */ | ||
| 38 | static Lisp_Object Qdelete_self; /* IN_DELETE_SELF */ | ||
| 39 | static Lisp_Object Qmodify; /* IN_MODIFY */ | ||
| 40 | static Lisp_Object Qmove_self; /* IN_MOVE_SELF */ | ||
| 41 | static Lisp_Object Qmoved_from; /* IN_MOVED_FROM */ | ||
| 42 | static Lisp_Object Qmoved_to; /* IN_MOVED_TO */ | ||
| 43 | static Lisp_Object Qopen; /* IN_OPEN */ | ||
| 44 | |||
| 45 | static Lisp_Object Qall_events; /* IN_ALL_EVENTS */ | ||
| 46 | static Lisp_Object Qmove; /* IN_MOVE */ | ||
| 47 | static Lisp_Object Qclose; /* IN_CLOSE */ | ||
| 48 | |||
| 49 | static Lisp_Object Qdont_follow; /* IN_DONT_FOLLOW */ | ||
| 50 | static Lisp_Object Qexcl_unlink; /* IN_EXCL_UNLINK */ | ||
| 51 | static Lisp_Object Qmask_add; /* IN_MASK_ADD */ | ||
| 52 | static Lisp_Object Qoneshot; /* IN_ONESHOT */ | ||
| 53 | static Lisp_Object Qonlydir; /* IN_ONLYDIR */ | ||
| 54 | |||
| 55 | static Lisp_Object Qignored; /* IN_IGNORED */ | ||
| 56 | static Lisp_Object Qisdir; /* IN_ISDIR */ | ||
| 57 | static Lisp_Object Qq_overflow; /* IN_Q_OVERFLOW */ | ||
| 58 | static Lisp_Object Qunmount; /* IN_UNMOUNT */ | ||
| 59 | |||
| 60 | #include <sys/inotify.h> | ||
| 61 | #include <sys/ioctl.h> | ||
| 62 | |||
| 63 | /* Ignore bits that might be undefined on old GNU/Linux systems. */ | ||
| 64 | #ifndef IN_EXCL_UNLINK | ||
| 65 | # define IN_EXCL_UNLINK 0 | ||
| 66 | #endif | ||
| 67 | #ifndef IN_DONT_FOLLOW | ||
| 68 | # define IN_DONT_FOLLOW 0 | ||
| 69 | #endif | ||
| 70 | #ifndef IN_ONLYDIR | ||
| 71 | # define IN_ONLYDIR 0 | ||
| 72 | #endif | ||
| 73 | |||
| 74 | enum { uninitialized = -100 }; | ||
| 75 | /* File handle for inotify. */ | ||
| 76 | static int inotifyfd = uninitialized; | ||
| 77 | |||
| 78 | /* Assoc list of files being watched. | ||
| 79 | Format: | ||
| 80 | (watch-descriptor . callback) | ||
| 81 | */ | ||
| 82 | static Lisp_Object watch_list; | ||
| 83 | |||
| 84 | static Lisp_Object | ||
| 85 | make_watch_descriptor (int wd) | ||
| 86 | { | ||
| 87 | /* TODO replace this with a Misc Object! */ | ||
| 88 | return make_number (wd); | ||
| 89 | } | ||
| 90 | |||
| 91 | static Lisp_Object | ||
| 92 | mask_to_aspects (uint32_t mask) { | ||
| 93 | Lisp_Object aspects = Qnil; | ||
| 94 | if (mask & IN_ACCESS) | ||
| 95 | aspects = Fcons (Qaccess, aspects); | ||
| 96 | if (mask & IN_ATTRIB) | ||
| 97 | aspects = Fcons (Qattrib, aspects); | ||
| 98 | if (mask & IN_CLOSE_WRITE) | ||
| 99 | aspects = Fcons (Qclose_write, aspects); | ||
| 100 | if (mask & IN_CLOSE_NOWRITE) | ||
| 101 | aspects = Fcons (Qclose_nowrite, aspects); | ||
| 102 | if (mask & IN_CREATE) | ||
| 103 | aspects = Fcons (Qcreate, aspects); | ||
| 104 | if (mask & IN_DELETE) | ||
| 105 | aspects = Fcons (Qdelete, aspects); | ||
| 106 | if (mask & IN_DELETE_SELF) | ||
| 107 | aspects = Fcons (Qdelete_self, aspects); | ||
| 108 | if (mask & IN_MODIFY) | ||
| 109 | aspects = Fcons (Qmodify, aspects); | ||
| 110 | if (mask & IN_MOVE_SELF) | ||
| 111 | aspects = Fcons (Qmove_self, aspects); | ||
| 112 | if (mask & IN_MOVED_FROM) | ||
| 113 | aspects = Fcons (Qmoved_from, aspects); | ||
| 114 | if (mask & IN_MOVED_TO) | ||
| 115 | aspects = Fcons (Qmoved_to, aspects); | ||
| 116 | if (mask & IN_OPEN) | ||
| 117 | aspects = Fcons (Qopen, aspects); | ||
| 118 | if (mask & IN_IGNORED) | ||
| 119 | aspects = Fcons (Qignored, aspects); | ||
| 120 | if (mask & IN_ISDIR) | ||
| 121 | aspects = Fcons (Qisdir, aspects); | ||
| 122 | if (mask & IN_Q_OVERFLOW) | ||
| 123 | aspects = Fcons (Qq_overflow, aspects); | ||
| 124 | if (mask & IN_UNMOUNT) | ||
| 125 | aspects = Fcons (Qunmount, aspects); | ||
| 126 | return aspects; | ||
| 127 | } | ||
| 128 | |||
| 129 | static Lisp_Object | ||
| 130 | inotifyevent_to_event (Lisp_Object watch_object, struct inotify_event const *ev) | ||
| 131 | { | ||
| 132 | Lisp_Object name = Qnil; | ||
| 133 | if (ev->len > 0) | ||
| 134 | { | ||
| 135 | size_t const len = strlen (ev->name); | ||
| 136 | name = make_unibyte_string (ev->name, min (len, ev->len)); | ||
| 137 | name = DECODE_FILE (name); | ||
| 138 | } | ||
| 139 | |||
| 140 | return list2 (list4 (make_watch_descriptor (ev->wd), | ||
| 141 | mask_to_aspects (ev->mask), | ||
| 142 | make_number (ev->cookie), | ||
| 143 | name), | ||
| 144 | XCDR (watch_object)); | ||
| 145 | } | ||
| 146 | |||
| 147 | /* This callback is called when the FD is available for read. The inotify | ||
| 148 | events are read from FD and converted into input_events. */ | ||
| 149 | static void | ||
| 150 | inotify_callback (int fd, void *_) | ||
| 151 | { | ||
| 152 | struct input_event event; | ||
| 153 | Lisp_Object watch_object; | ||
| 154 | int to_read; | ||
| 155 | char *buffer; | ||
| 156 | ssize_t n; | ||
| 157 | size_t i; | ||
| 158 | |||
| 159 | to_read = 0; | ||
| 160 | if (ioctl (fd, FIONREAD, &to_read) == -1) | ||
| 161 | report_file_error ("Error while trying to retrieve file system events", | ||
| 162 | Qnil); | ||
| 163 | buffer = xmalloc (to_read); | ||
| 164 | n = read (fd, buffer, to_read); | ||
| 165 | if (n < 0) | ||
| 166 | { | ||
| 167 | xfree (buffer); | ||
| 168 | report_file_error ("Error while trying to read file system events", | ||
| 169 | Qnil); | ||
| 170 | } | ||
| 171 | |||
| 172 | EVENT_INIT (event); | ||
| 173 | event.kind = FILE_NOTIFY_EVENT; | ||
| 174 | |||
| 175 | i = 0; | ||
| 176 | while (i < (size_t)n) | ||
| 177 | { | ||
| 178 | struct inotify_event *ev = (struct inotify_event*)&buffer[i]; | ||
| 179 | |||
| 180 | watch_object = Fassoc (make_watch_descriptor (ev->wd), watch_list); | ||
| 181 | if (!NILP (watch_object)) | ||
| 182 | { | ||
| 183 | event.arg = inotifyevent_to_event (watch_object, ev); | ||
| 184 | |||
| 185 | /* If event was removed automatically: Drop it from watch list. */ | ||
| 186 | if (ev->mask & IN_IGNORED) | ||
| 187 | watch_list = Fdelete (watch_object, watch_list); | ||
| 188 | |||
| 189 | if (!NILP (event.arg)) | ||
| 190 | kbd_buffer_store_event (&event); | ||
| 191 | } | ||
| 192 | |||
| 193 | i += sizeof (*ev) + ev->len; | ||
| 194 | } | ||
| 195 | |||
| 196 | xfree (buffer); | ||
| 197 | } | ||
| 198 | |||
| 199 | static uint32_t | ||
| 200 | symbol_to_inotifymask (Lisp_Object symb) | ||
| 201 | { | ||
| 202 | if (EQ (symb, Qaccess)) | ||
| 203 | return IN_ACCESS; | ||
| 204 | else if (EQ (symb, Qattrib)) | ||
| 205 | return IN_ATTRIB; | ||
| 206 | else if (EQ (symb, Qclose_write)) | ||
| 207 | return IN_CLOSE_WRITE; | ||
| 208 | else if (EQ (symb, Qclose_nowrite)) | ||
| 209 | return IN_CLOSE_NOWRITE; | ||
| 210 | else if (EQ (symb, Qcreate)) | ||
| 211 | return IN_CREATE; | ||
| 212 | else if (EQ (symb, Qdelete)) | ||
| 213 | return IN_DELETE; | ||
| 214 | else if (EQ (symb, Qdelete_self)) | ||
| 215 | return IN_DELETE_SELF; | ||
| 216 | else if (EQ (symb, Qmodify)) | ||
| 217 | return IN_MODIFY; | ||
| 218 | else if (EQ (symb, Qmove_self)) | ||
| 219 | return IN_MOVE_SELF; | ||
| 220 | else if (EQ (symb, Qmoved_from)) | ||
| 221 | return IN_MOVED_FROM; | ||
| 222 | else if (EQ (symb, Qmoved_to)) | ||
| 223 | return IN_MOVED_TO; | ||
| 224 | else if (EQ (symb, Qopen)) | ||
| 225 | return IN_OPEN; | ||
| 226 | else if (EQ (symb, Qmove)) | ||
| 227 | return IN_MOVE; | ||
| 228 | else if (EQ (symb, Qclose)) | ||
| 229 | return IN_CLOSE; | ||
| 230 | |||
| 231 | else if (EQ (symb, Qdont_follow)) | ||
| 232 | return IN_DONT_FOLLOW; | ||
| 233 | else if (EQ (symb, Qexcl_unlink)) | ||
| 234 | return IN_EXCL_UNLINK; | ||
| 235 | else if (EQ (symb, Qmask_add)) | ||
| 236 | return IN_MASK_ADD; | ||
| 237 | else if (EQ (symb, Qoneshot)) | ||
| 238 | return IN_ONESHOT; | ||
| 239 | else if (EQ (symb, Qonlydir)) | ||
| 240 | return IN_ONLYDIR; | ||
| 241 | |||
| 242 | else if (EQ (symb, Qt) || EQ (symb, Qall_events)) | ||
| 243 | return IN_ALL_EVENTS; | ||
| 244 | else | ||
| 245 | signal_error ("Unknown aspect", symb); | ||
| 246 | } | ||
| 247 | |||
| 248 | static uint32_t | ||
| 249 | aspect_to_inotifymask (Lisp_Object aspect) | ||
| 250 | { | ||
| 251 | if (CONSP (aspect)) | ||
| 252 | { | ||
| 253 | Lisp_Object x = aspect; | ||
| 254 | uint32_t mask = 0; | ||
| 255 | while (CONSP (x)) | ||
| 256 | { | ||
| 257 | mask |= symbol_to_inotifymask (XCAR (x)); | ||
| 258 | x = XCDR (x); | ||
| 259 | } | ||
| 260 | return mask; | ||
| 261 | } | ||
| 262 | else | ||
| 263 | return symbol_to_inotifymask (aspect); | ||
| 264 | } | ||
| 265 | |||
| 266 | DEFUN ("inotify-add-watch", Finotify_add_watch, Sinotify_add_watch, 3, 3, 0, | ||
| 267 | doc: /* Add a watch for FILE-NAME to inotify. | ||
| 268 | |||
| 269 | A WATCH-DESCRIPTOR is returned on success. ASPECT might be one of the following | ||
| 270 | symbols or a list of those symbols: | ||
| 271 | |||
| 272 | access | ||
| 273 | attrib | ||
| 274 | close-write | ||
| 275 | close-nowrite | ||
| 276 | create | ||
| 277 | delete | ||
| 278 | delete-self | ||
| 279 | modify | ||
| 280 | move-self | ||
| 281 | moved-from | ||
| 282 | moved-to | ||
| 283 | open | ||
| 284 | |||
| 285 | all-events or t | ||
| 286 | move | ||
| 287 | close | ||
| 288 | |||
| 289 | The following symbols can also be added to a list of aspects | ||
| 290 | |||
| 291 | dont-follow | ||
| 292 | excl-unlink | ||
| 293 | mask-add | ||
| 294 | oneshot | ||
| 295 | onlydir | ||
| 296 | |||
| 297 | Watching a directory is not recursive. CALLBACK gets called in case of an | ||
| 298 | event. It gets passed a single argument EVENT which contains an event structure | ||
| 299 | of the format | ||
| 300 | |||
| 301 | (WATCH-DESCRIPTOR ASPECTS COOKIE NAME) | ||
| 302 | |||
| 303 | WATCH-DESCRIPTOR is the same object that was returned by this function. It can | ||
| 304 | be tested for equality using `equal'. ASPECTS describes the event. It is a | ||
| 305 | list of ASPECT symbols described above and can also contain one of the following | ||
| 306 | symbols | ||
| 307 | |||
| 308 | ignored | ||
| 309 | isdir | ||
| 310 | q-overflow | ||
| 311 | unmount | ||
| 312 | |||
| 313 | COOKIE is an object that can be compared using `equal' to identify two matching | ||
| 314 | renames (moved-from and moved-to). | ||
| 315 | |||
| 316 | If a directory is watched then NAME is the name of file that caused the event. | ||
| 317 | |||
| 318 | See inotify(7) and inotify_add_watch(2) for further information. The inotify fd | ||
| 319 | is managed internally and there is no corresponding inotify_init. Use | ||
| 320 | `inotify-rm-watch' to remove a watch. | ||
| 321 | */) | ||
| 322 | (Lisp_Object file_name, Lisp_Object aspect, Lisp_Object callback) | ||
| 323 | { | ||
| 324 | uint32_t mask; | ||
| 325 | Lisp_Object watch_object; | ||
| 326 | Lisp_Object encoded_file_name; | ||
| 327 | Lisp_Object watch_descriptor; | ||
| 328 | int watchdesc = -1; | ||
| 329 | |||
| 330 | CHECK_STRING (file_name); | ||
| 331 | |||
| 332 | if (inotifyfd == uninitialized) | ||
| 333 | { | ||
| 334 | inotifyfd = inotify_init1 (IN_NONBLOCK|IN_CLOEXEC); | ||
| 335 | if (inotifyfd == -1) | ||
| 336 | { | ||
| 337 | inotifyfd = uninitialized; | ||
| 338 | report_file_error ("File watching feature (inotify) is not available", | ||
| 339 | Qnil); | ||
| 340 | } | ||
| 341 | watch_list = Qnil; | ||
| 342 | add_read_fd (inotifyfd, &inotify_callback, NULL); | ||
| 343 | } | ||
| 344 | |||
| 345 | mask = aspect_to_inotifymask (aspect); | ||
| 346 | encoded_file_name = ENCODE_FILE (file_name); | ||
| 347 | watchdesc = inotify_add_watch (inotifyfd, SSDATA (encoded_file_name), mask); | ||
| 348 | if (watchdesc == -1) | ||
| 349 | report_file_error ("Could not add watch for file", Fcons (file_name, Qnil)); | ||
| 350 | |||
| 351 | watch_descriptor = make_watch_descriptor (watchdesc); | ||
| 352 | |||
| 353 | /* Delete existing watch object. */ | ||
| 354 | watch_object = Fassoc (watch_descriptor, watch_list); | ||
| 355 | if (!NILP (watch_object)) | ||
| 356 | watch_list = Fdelete (watch_object, watch_list); | ||
| 357 | |||
| 358 | /* Store watch object in watch list. */ | ||
| 359 | watch_object = Fcons (watch_descriptor, callback); | ||
| 360 | watch_list = Fcons (watch_object, watch_list); | ||
| 361 | |||
| 362 | return watch_descriptor; | ||
| 363 | } | ||
| 364 | |||
| 365 | DEFUN ("inotify-rm-watch", Finotify_rm_watch, Sinotify_rm_watch, 1, 1, 0, | ||
| 366 | doc: /* Remove an existing WATCH-DESCRIPTOR. | ||
| 367 | |||
| 368 | WATCH-DESCRIPTOR should be an object returned by `inotify-add-watch'. | ||
| 369 | |||
| 370 | See inotify_rm_watch(2) for more information. | ||
| 371 | */) | ||
| 372 | (Lisp_Object watch_descriptor) | ||
| 373 | { | ||
| 374 | Lisp_Object watch_object; | ||
| 375 | int wd = XINT (watch_descriptor); | ||
| 376 | |||
| 377 | if (inotify_rm_watch (inotifyfd, wd) == -1) | ||
| 378 | report_file_error ("Could not rm watch", Fcons (watch_descriptor, | ||
| 379 | Qnil)); | ||
| 380 | |||
| 381 | /* Remove watch descriptor from watch list. */ | ||
| 382 | watch_object = Fassoc (watch_descriptor, watch_list); | ||
| 383 | if (!NILP (watch_object)) | ||
| 384 | watch_list = Fdelete (watch_object, watch_list); | ||
| 385 | |||
| 386 | /* Cleanup if no more files are watched. */ | ||
| 387 | if (NILP (watch_list)) | ||
| 388 | { | ||
| 389 | close (inotifyfd); | ||
| 390 | delete_read_fd (inotifyfd); | ||
| 391 | inotifyfd = uninitialized; | ||
| 392 | } | ||
| 393 | |||
| 394 | return Qt; | ||
| 395 | } | ||
| 396 | |||
| 397 | void | ||
| 398 | syms_of_inotify (void) | ||
| 399 | { | ||
| 400 | DEFSYM (Qaccess, "access"); | ||
| 401 | DEFSYM (Qattrib, "attrib"); | ||
| 402 | DEFSYM (Qclose_write, "close-write"); | ||
| 403 | DEFSYM (Qclose_nowrite, "close-nowrite"); | ||
| 404 | DEFSYM (Qcreate, "create"); | ||
| 405 | DEFSYM (Qdelete, "delete"); | ||
| 406 | DEFSYM (Qdelete_self, "delete-self"); | ||
| 407 | DEFSYM (Qmodify, "modify"); | ||
| 408 | DEFSYM (Qmove_self, "move-self"); | ||
| 409 | DEFSYM (Qmoved_from, "moved-from"); | ||
| 410 | DEFSYM (Qmoved_to, "moved-to"); | ||
| 411 | DEFSYM (Qopen, "open"); | ||
| 412 | |||
| 413 | DEFSYM (Qall_events, "all-events"); | ||
| 414 | DEFSYM (Qmove, "move"); | ||
| 415 | DEFSYM (Qclose, "close"); | ||
| 416 | |||
| 417 | DEFSYM (Qdont_follow, "dont-follow"); | ||
| 418 | DEFSYM (Qexcl_unlink, "excl-unlink"); | ||
| 419 | DEFSYM (Qmask_add, "mask-add"); | ||
| 420 | DEFSYM (Qoneshot, "oneshot"); | ||
| 421 | DEFSYM (Qonlydir, "onlydir"); | ||
| 422 | |||
| 423 | DEFSYM (Qignored, "ignored"); | ||
| 424 | DEFSYM (Qisdir, "isdir"); | ||
| 425 | DEFSYM (Qq_overflow, "q-overflow"); | ||
| 426 | DEFSYM (Qunmount, "unmount"); | ||
| 427 | |||
| 428 | defsubr (&Sinotify_add_watch); | ||
| 429 | defsubr (&Sinotify_rm_watch); | ||
| 430 | |||
| 431 | staticpro (&watch_list); | ||
| 432 | |||
| 433 | Fprovide (intern_c_string ("inotify"), Qnil); | ||
| 434 | } | ||
| 435 | |||
| 436 | #endif /* HAVE_INOTIFY */ | ||
diff --git a/src/insdel.c b/src/insdel.c index 892ca3d5216..4cf4e6452a1 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Buffer insertion/deletion and gap motion for GNU Emacs. | 1 | /* Buffer insertion/deletion and gap motion for GNU Emacs. |
| 2 | Copyright (C) 1985-1986, 1993-1995, 1997-2012 | 2 | Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -84,21 +84,14 @@ check_markers (void) | |||
| 84 | 84 | ||
| 85 | #endif /* MARKER_DEBUG */ | 85 | #endif /* MARKER_DEBUG */ |
| 86 | 86 | ||
| 87 | /* Move gap to position CHARPOS. | ||
| 88 | Note that this can quit! */ | ||
| 89 | |||
| 90 | void | ||
| 91 | move_gap (ptrdiff_t charpos) | ||
| 92 | { | ||
| 93 | move_gap_both (charpos, charpos_to_bytepos (charpos)); | ||
| 94 | } | ||
| 95 | |||
| 96 | /* Move gap to byte position BYTEPOS, which is also char position CHARPOS. | 87 | /* Move gap to byte position BYTEPOS, which is also char position CHARPOS. |
| 97 | Note that this can quit! */ | 88 | Note that this can quit! */ |
| 98 | 89 | ||
| 99 | void | 90 | void |
| 100 | move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos) | 91 | move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos) |
| 101 | { | 92 | { |
| 93 | eassert (charpos == BYTE_TO_CHAR (bytepos) | ||
| 94 | && bytepos == CHAR_TO_BYTE (charpos)); | ||
| 102 | if (bytepos < GPT_BYTE) | 95 | if (bytepos < GPT_BYTE) |
| 103 | gap_left (charpos, bytepos, 0); | 96 | gap_left (charpos, bytepos, 0); |
| 104 | else if (bytepos > GPT_BYTE) | 97 | else if (bytepos > GPT_BYTE) |
| @@ -388,14 +381,13 @@ make_gap_larger (ptrdiff_t nbytes_added) | |||
| 388 | ptrdiff_t real_gap_loc_byte; | 381 | ptrdiff_t real_gap_loc_byte; |
| 389 | ptrdiff_t old_gap_size; | 382 | ptrdiff_t old_gap_size; |
| 390 | ptrdiff_t current_size = Z_BYTE - BEG_BYTE + GAP_SIZE; | 383 | ptrdiff_t current_size = Z_BYTE - BEG_BYTE + GAP_SIZE; |
| 391 | enum { enough_for_a_while = 2000 }; | ||
| 392 | 384 | ||
| 393 | if (BUF_BYTES_MAX - current_size < nbytes_added) | 385 | if (BUF_BYTES_MAX - current_size < nbytes_added) |
| 394 | buffer_overflow (); | 386 | buffer_overflow (); |
| 395 | 387 | ||
| 396 | /* If we have to get more space, get enough to last a while; | 388 | /* If we have to get more space, get enough to last a while; |
| 397 | but do not exceed the maximum buffer size. */ | 389 | but do not exceed the maximum buffer size. */ |
| 398 | nbytes_added = min (nbytes_added + enough_for_a_while, | 390 | nbytes_added = min (nbytes_added + GAP_BYTES_DFL, |
| 399 | BUF_BYTES_MAX - current_size); | 391 | BUF_BYTES_MAX - current_size); |
| 400 | 392 | ||
| 401 | enlarge_buffer_text (current_buffer, nbytes_added); | 393 | enlarge_buffer_text (current_buffer, nbytes_added); |
| @@ -413,8 +405,7 @@ make_gap_larger (ptrdiff_t nbytes_added) | |||
| 413 | GPT_BYTE = Z_BYTE + GAP_SIZE; | 405 | GPT_BYTE = Z_BYTE + GAP_SIZE; |
| 414 | GAP_SIZE = nbytes_added; | 406 | GAP_SIZE = nbytes_added; |
| 415 | 407 | ||
| 416 | /* Move the new gap down to be consecutive with the end of the old one. | 408 | /* Move the new gap down to be consecutive with the end of the old one. */ |
| 417 | This adjusts the markers properly too. */ | ||
| 418 | gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1); | 409 | gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1); |
| 419 | 410 | ||
| 420 | /* Now combine the two into one large gap. */ | 411 | /* Now combine the two into one large gap. */ |
| @@ -443,9 +434,9 @@ make_gap_smaller (ptrdiff_t nbytes_removed) | |||
| 443 | ptrdiff_t real_beg_unchanged; | 434 | ptrdiff_t real_beg_unchanged; |
| 444 | ptrdiff_t new_gap_size; | 435 | ptrdiff_t new_gap_size; |
| 445 | 436 | ||
| 446 | /* Make sure the gap is at least 20 bytes. */ | 437 | /* Make sure the gap is at least GAP_BYTES_MIN bytes. */ |
| 447 | if (GAP_SIZE - nbytes_removed < 20) | 438 | if (GAP_SIZE - nbytes_removed < GAP_BYTES_MIN) |
| 448 | nbytes_removed = GAP_SIZE - 20; | 439 | nbytes_removed = GAP_SIZE - GAP_BYTES_MIN; |
| 449 | 440 | ||
| 450 | /* Prevent quitting in move_gap. */ | 441 | /* Prevent quitting in move_gap. */ |
| 451 | tem = Vinhibit_quit; | 442 | tem = Vinhibit_quit; |
| @@ -468,8 +459,7 @@ make_gap_smaller (ptrdiff_t nbytes_removed) | |||
| 468 | Z_BYTE += new_gap_size; | 459 | Z_BYTE += new_gap_size; |
| 469 | GAP_SIZE = nbytes_removed; | 460 | GAP_SIZE = nbytes_removed; |
| 470 | 461 | ||
| 471 | /* Move the unwanted pretend gap to the end of the buffer. This | 462 | /* Move the unwanted pretend gap to the end of the buffer. */ |
| 472 | adjusts the markers properly too. */ | ||
| 473 | gap_right (Z, Z_BYTE); | 463 | gap_right (Z, Z_BYTE); |
| 474 | 464 | ||
| 475 | enlarge_buffer_text (current_buffer, -nbytes_removed); | 465 | enlarge_buffer_text (current_buffer, -nbytes_removed); |
| @@ -500,7 +490,20 @@ make_gap (ptrdiff_t nbytes_added) | |||
| 500 | make_gap_smaller (-nbytes_added); | 490 | make_gap_smaller (-nbytes_added); |
| 501 | #endif | 491 | #endif |
| 502 | } | 492 | } |
| 503 | 493 | ||
| 494 | /* Add NBYTES to B's gap. It's enough to temporarily | ||
| 495 | fake current_buffer and avoid real switch to B. */ | ||
| 496 | |||
| 497 | void | ||
| 498 | make_gap_1 (struct buffer *b, ptrdiff_t nbytes) | ||
| 499 | { | ||
| 500 | struct buffer *oldb = current_buffer; | ||
| 501 | |||
| 502 | current_buffer = b; | ||
| 503 | make_gap (nbytes); | ||
| 504 | current_buffer = oldb; | ||
| 505 | } | ||
| 506 | |||
| 504 | /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR. | 507 | /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR. |
| 505 | FROM_MULTIBYTE says whether the incoming text is multibyte. | 508 | FROM_MULTIBYTE says whether the incoming text is multibyte. |
| 506 | TO_MULTIBYTE says whether to store the text as multibyte. | 509 | TO_MULTIBYTE says whether to store the text as multibyte. |
| @@ -655,17 +658,6 @@ insert_before_markers_and_inherit (const char *string, | |||
| 655 | } | 658 | } |
| 656 | } | 659 | } |
| 657 | 660 | ||
| 658 | /* Subroutine used by the insert functions above. */ | ||
| 659 | |||
| 660 | void | ||
| 661 | insert_1 (const char *string, ptrdiff_t nbytes, | ||
| 662 | bool inherit, bool prepare, bool before_markers) | ||
| 663 | { | ||
| 664 | insert_1_both (string, chars_in_text ((unsigned char *) string, nbytes), | ||
| 665 | nbytes, inherit, prepare, before_markers); | ||
| 666 | } | ||
| 667 | |||
| 668 | |||
| 669 | #ifdef BYTE_COMBINING_DEBUG | 661 | #ifdef BYTE_COMBINING_DEBUG |
| 670 | 662 | ||
| 671 | /* See if the bytes before POS/POS_BYTE combine with bytes | 663 | /* See if the bytes before POS/POS_BYTE combine with bytes |
| @@ -1800,9 +1792,10 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | |||
| 1800 | if (!NILP (BVAR (current_buffer, read_only))) | 1792 | if (!NILP (BVAR (current_buffer, read_only))) |
| 1801 | Fbarf_if_buffer_read_only (); | 1793 | Fbarf_if_buffer_read_only (); |
| 1802 | 1794 | ||
| 1803 | /* Let redisplay consider other windows than selected_window | 1795 | /* If we're modifying the buffer other than shown in a selected window, |
| 1804 | if modifying another buffer. */ | 1796 | let redisplay consider other windows if this buffer is visible. */ |
| 1805 | if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) | 1797 | if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer |
| 1798 | && buffer_window_count (current_buffer)) | ||
| 1806 | ++windows_or_buffers_changed; | 1799 | ++windows_or_buffers_changed; |
| 1807 | 1800 | ||
| 1808 | if (buffer_intervals (current_buffer)) | 1801 | if (buffer_intervals (current_buffer)) |
| @@ -1854,7 +1847,7 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | |||
| 1854 | : (!NILP (Vselect_active_regions) | 1847 | : (!NILP (Vselect_active_regions) |
| 1855 | && !NILP (Vtransient_mark_mode)))) | 1848 | && !NILP (Vtransient_mark_mode)))) |
| 1856 | { | 1849 | { |
| 1857 | ptrdiff_t b = XMARKER (BVAR (current_buffer, mark))->charpos; | 1850 | ptrdiff_t b = marker_position (BVAR (current_buffer, mark)); |
| 1858 | ptrdiff_t e = PT; | 1851 | ptrdiff_t e = PT; |
| 1859 | if (b < e) | 1852 | if (b < e) |
| 1860 | Vsaved_region_selection = make_buffer_string (b, e, 0); | 1853 | Vsaved_region_selection = make_buffer_string (b, e, 0); |
| @@ -2080,7 +2073,7 @@ Fcombine_after_change_execute_1 (Lisp_Object val) | |||
| 2080 | 2073 | ||
| 2081 | DEFUN ("combine-after-change-execute", Fcombine_after_change_execute, | 2074 | DEFUN ("combine-after-change-execute", Fcombine_after_change_execute, |
| 2082 | Scombine_after_change_execute, 0, 0, 0, | 2075 | Scombine_after_change_execute, 0, 0, 0, |
| 2083 | doc: /* This function is for use internally in `combine-after-change-calls'. */) | 2076 | doc: /* This function is for use internally in the function `combine-after-change-calls'. */) |
| 2084 | (void) | 2077 | (void) |
| 2085 | { | 2078 | { |
| 2086 | ptrdiff_t count = SPECPDL_INDEX (); | 2079 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -2172,7 +2165,7 @@ syms_of_insdel (void) | |||
| 2172 | combine_after_change_buffer = Qnil; | 2165 | combine_after_change_buffer = Qnil; |
| 2173 | 2166 | ||
| 2174 | DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls, | 2167 | DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls, |
| 2175 | doc: /* Used internally by the `combine-after-change-calls' macro. */); | 2168 | doc: /* Used internally by the function `combine-after-change-calls' macro. */); |
| 2176 | Vcombine_after_change_calls = Qnil; | 2169 | Vcombine_after_change_calls = Qnil; |
| 2177 | 2170 | ||
| 2178 | DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks, | 2171 | DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks, |
diff --git a/src/intervals.c b/src/intervals.c index 1ed93e1302d..db38c86c00b 100644 --- a/src/intervals.c +++ b/src/intervals.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Code for doing intervals. | 1 | /* Code for doing intervals. |
| 2 | Copyright (C) 1993-1995, 1997-1998, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1995, 1997-1998, 2001-2013 Free Software |
| 3 | Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -1624,7 +1625,8 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position, | |||
| 1624 | XSETBUFFER (buf, buffer); | 1625 | XSETBUFFER (buf, buffer); |
| 1625 | set_text_properties_1 (make_number (position), | 1626 | set_text_properties_1 (make_number (position), |
| 1626 | make_number (position + length), | 1627 | make_number (position + length), |
| 1627 | Qnil, buf, 0); | 1628 | Qnil, buf, |
| 1629 | find_interval (tree, position)); | ||
| 1628 | } | 1630 | } |
| 1629 | /* Shouldn't be necessary. --Stef */ | 1631 | /* Shouldn't be necessary. --Stef */ |
| 1630 | buffer_balance_intervals (buffer); | 1632 | buffer_balance_intervals (buffer); |
diff --git a/src/intervals.h b/src/intervals.h index 2b30101d0fa..cded8c0abb2 100644 --- a/src/intervals.h +++ b/src/intervals.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions and global variables for intervals. | 1 | /* Definitions and global variables for intervals. |
| 2 | Copyright (C) 1993-1994, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1994, 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index fc155c5a5f7..77037f647e9 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Keyboard and mouse input; editor command loop. | 1 | /* Keyboard and mouse input; editor command loop. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1989, 1993-1997, 1999-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1989, 1993-1997, 1999-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -313,12 +314,18 @@ static Lisp_Object Qfunction_key; | |||
| 313 | Lisp_Object Qmouse_click; | 314 | Lisp_Object Qmouse_click; |
| 314 | #ifdef HAVE_NTGUI | 315 | #ifdef HAVE_NTGUI |
| 315 | Lisp_Object Qlanguage_change; | 316 | Lisp_Object Qlanguage_change; |
| 317 | #ifdef WINDOWSNT | ||
| 318 | Lisp_Object Qfile_w32notify; | ||
| 319 | #endif | ||
| 316 | #endif | 320 | #endif |
| 317 | static Lisp_Object Qdrag_n_drop; | 321 | static Lisp_Object Qdrag_n_drop; |
| 318 | static Lisp_Object Qsave_session; | 322 | static Lisp_Object Qsave_session; |
| 319 | #ifdef HAVE_DBUS | 323 | #ifdef HAVE_DBUS |
| 320 | static Lisp_Object Qdbus_event; | 324 | static Lisp_Object Qdbus_event; |
| 321 | #endif | 325 | #endif |
| 326 | #ifdef HAVE_INOTIFY | ||
| 327 | static Lisp_Object Qfile_inotify; | ||
| 328 | #endif /* HAVE_INOTIFY */ | ||
| 322 | static Lisp_Object Qconfig_changed_event; | 329 | static Lisp_Object Qconfig_changed_event; |
| 323 | 330 | ||
| 324 | /* Lisp_Object Qmouse_movement; - also an event header */ | 331 | /* Lisp_Object Qmouse_movement; - also an event header */ |
| @@ -410,10 +417,9 @@ static void (*keyboard_init_hook) (void); | |||
| 410 | 417 | ||
| 411 | static bool get_input_pending (int); | 418 | static bool get_input_pending (int); |
| 412 | static bool readable_events (int); | 419 | static bool readable_events (int); |
| 413 | static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *, | 420 | static Lisp_Object read_char_x_menu_prompt (Lisp_Object, |
| 414 | Lisp_Object, bool *); | 421 | Lisp_Object, bool *); |
| 415 | static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t, | 422 | static Lisp_Object read_char_minibuf_menu_prompt (int, Lisp_Object); |
| 416 | Lisp_Object *); | ||
| 417 | static Lisp_Object make_lispy_event (struct input_event *); | 423 | static Lisp_Object make_lispy_event (struct input_event *); |
| 418 | static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, | 424 | static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, |
| 419 | enum scroll_bar_part, | 425 | enum scroll_bar_part, |
| @@ -490,97 +496,103 @@ kset_system_key_syms (struct kboard *kb, Lisp_Object val) | |||
| 490 | } | 496 | } |
| 491 | 497 | ||
| 492 | 498 | ||
| 493 | /* Add C to the echo string, if echoing is going on. | 499 | /* Add C to the echo string, without echoing it immediately. C can be |
| 494 | C can be a character, which is printed prettily ("M-C-x" and all that | 500 | a character, which is pretty-printed, or a symbol, whose name is |
| 495 | jazz), or a symbol, whose name is printed. */ | 501 | printed. */ |
| 496 | 502 | ||
| 497 | static void | 503 | static void |
| 498 | echo_char (Lisp_Object c) | 504 | echo_add_key (Lisp_Object c) |
| 499 | { | 505 | { |
| 500 | if (current_kboard->immediate_echo) | 506 | int size = KEY_DESCRIPTION_SIZE + 100; |
| 501 | { | 507 | char *buffer = alloca (size); |
| 502 | int size = KEY_DESCRIPTION_SIZE + 100; | 508 | char *ptr = buffer; |
| 503 | char *buffer = alloca (size); | 509 | Lisp_Object echo_string; |
| 504 | char *ptr = buffer; | ||
| 505 | Lisp_Object echo_string; | ||
| 506 | 510 | ||
| 507 | echo_string = KVAR (current_kboard, echo_string); | 511 | echo_string = KVAR (current_kboard, echo_string); |
| 508 | 512 | ||
| 509 | /* If someone has passed us a composite event, use its head symbol. */ | 513 | /* If someone has passed us a composite event, use its head symbol. */ |
| 510 | c = EVENT_HEAD (c); | 514 | c = EVENT_HEAD (c); |
| 511 | 515 | ||
| 512 | if (INTEGERP (c)) | 516 | if (INTEGERP (c)) |
| 517 | ptr = push_key_description (XINT (c), ptr); | ||
| 518 | else if (SYMBOLP (c)) | ||
| 519 | { | ||
| 520 | Lisp_Object name = SYMBOL_NAME (c); | ||
| 521 | int nbytes = SBYTES (name); | ||
| 522 | |||
| 523 | if (size - (ptr - buffer) < nbytes) | ||
| 513 | { | 524 | { |
| 514 | ptr = push_key_description (XINT (c), ptr); | 525 | int offset = ptr - buffer; |
| 526 | size = max (2 * size, size + nbytes); | ||
| 527 | buffer = alloca (size); | ||
| 528 | ptr = buffer + offset; | ||
| 515 | } | 529 | } |
| 516 | else if (SYMBOLP (c)) | ||
| 517 | { | ||
| 518 | Lisp_Object name = SYMBOL_NAME (c); | ||
| 519 | int nbytes = SBYTES (name); | ||
| 520 | 530 | ||
| 521 | if (size - (ptr - buffer) < nbytes) | 531 | ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes, |
| 522 | { | 532 | STRING_MULTIBYTE (name), 1); |
| 523 | int offset = ptr - buffer; | 533 | } |
| 524 | size = max (2 * size, size + nbytes); | ||
| 525 | buffer = alloca (size); | ||
| 526 | ptr = buffer + offset; | ||
| 527 | } | ||
| 528 | 534 | ||
| 529 | ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes, | 535 | if ((NILP (echo_string) || SCHARS (echo_string) == 0) |
| 530 | STRING_MULTIBYTE (name), 1); | 536 | && help_char_p (c)) |
| 531 | } | 537 | { |
| 538 | const char *text = " (Type ? for further options)"; | ||
| 539 | int len = strlen (text); | ||
| 532 | 540 | ||
| 533 | if ((NILP (echo_string) || SCHARS (echo_string) == 0) | 541 | if (size - (ptr - buffer) < len) |
| 534 | && help_char_p (c)) | ||
| 535 | { | 542 | { |
| 536 | const char *text = " (Type ? for further options)"; | 543 | int offset = ptr - buffer; |
| 537 | int len = strlen (text); | 544 | size += len; |
| 538 | 545 | buffer = alloca (size); | |
| 539 | if (size - (ptr - buffer) < len) | 546 | ptr = buffer + offset; |
| 540 | { | ||
| 541 | int offset = ptr - buffer; | ||
| 542 | size += len; | ||
| 543 | buffer = alloca (size); | ||
| 544 | ptr = buffer + offset; | ||
| 545 | } | ||
| 546 | |||
| 547 | memcpy (ptr, text, len); | ||
| 548 | ptr += len; | ||
| 549 | } | 547 | } |
| 550 | 548 | ||
| 551 | /* Replace a dash from echo_dash with a space, otherwise | 549 | memcpy (ptr, text, len); |
| 552 | add a space at the end as a separator between keys. */ | 550 | ptr += len; |
| 553 | if (STRINGP (echo_string) | 551 | } |
| 554 | && SCHARS (echo_string) > 1) | ||
| 555 | { | ||
| 556 | Lisp_Object last_char, prev_char, idx; | ||
| 557 | 552 | ||
| 558 | idx = make_number (SCHARS (echo_string) - 2); | 553 | /* Replace a dash from echo_dash with a space, otherwise add a space |
| 559 | prev_char = Faref (echo_string, idx); | 554 | at the end as a separator between keys. */ |
| 555 | if (STRINGP (echo_string) && SCHARS (echo_string) > 1) | ||
| 556 | { | ||
| 557 | Lisp_Object last_char, prev_char, idx; | ||
| 560 | 558 | ||
| 561 | idx = make_number (SCHARS (echo_string) - 1); | 559 | idx = make_number (SCHARS (echo_string) - 2); |
| 562 | last_char = Faref (echo_string, idx); | 560 | prev_char = Faref (echo_string, idx); |
| 563 | 561 | ||
| 564 | /* We test PREV_CHAR to make sure this isn't the echoing | 562 | idx = make_number (SCHARS (echo_string) - 1); |
| 565 | of a minus-sign. */ | 563 | last_char = Faref (echo_string, idx); |
| 566 | if (XINT (last_char) == '-' && XINT (prev_char) != ' ') | 564 | |
| 567 | Faset (echo_string, idx, make_number (' ')); | 565 | /* We test PREV_CHAR to make sure this isn't the echoing of a |
| 568 | else | 566 | minus-sign. */ |
| 569 | echo_string = concat2 (echo_string, build_string (" ")); | 567 | if (XINT (last_char) == '-' && XINT (prev_char) != ' ') |
| 570 | } | 568 | Faset (echo_string, idx, make_number (' ')); |
| 571 | else if (STRINGP (echo_string)) | 569 | else |
| 572 | echo_string = concat2 (echo_string, build_string (" ")); | 570 | echo_string = concat2 (echo_string, build_string (" ")); |
| 571 | } | ||
| 572 | else if (STRINGP (echo_string) && SCHARS (echo_string) > 0) | ||
| 573 | echo_string = concat2 (echo_string, build_string (" ")); | ||
| 574 | |||
| 575 | kset_echo_string | ||
| 576 | (current_kboard, | ||
| 577 | concat2 (echo_string, make_string (buffer, ptr - buffer))); | ||
| 578 | } | ||
| 573 | 579 | ||
| 574 | kset_echo_string | 580 | /* Add C to the echo string, if echoing is going on. C can be a |
| 575 | (current_kboard, | 581 | character or a symbol. */ |
| 576 | concat2 (echo_string, make_string (buffer, ptr - buffer))); | ||
| 577 | 582 | ||
| 583 | static void | ||
| 584 | echo_char (Lisp_Object c) | ||
| 585 | { | ||
| 586 | if (current_kboard->immediate_echo) | ||
| 587 | { | ||
| 588 | echo_add_key (c); | ||
| 578 | echo_now (); | 589 | echo_now (); |
| 579 | } | 590 | } |
| 580 | } | 591 | } |
| 581 | 592 | ||
| 582 | /* Temporarily add a dash to the end of the echo string if it's not | 593 | /* Temporarily add a dash to the end of the echo string if it's not |
| 583 | empty, so that it serves as a mini-prompt for the very next character. */ | 594 | empty, so that it serves as a mini-prompt for the very next |
| 595 | character. */ | ||
| 584 | 596 | ||
| 585 | static void | 597 | static void |
| 586 | echo_dash (void) | 598 | echo_dash (void) |
| @@ -662,9 +674,8 @@ echo_now (void) | |||
| 662 | } | 674 | } |
| 663 | 675 | ||
| 664 | echoing = 1; | 676 | echoing = 1; |
| 665 | message3_nolog (KVAR (current_kboard, echo_string), | 677 | /* FIXME: Use call (Qmessage) so it can be advised (e.g. emacspeak). */ |
| 666 | SBYTES (KVAR (current_kboard, echo_string)), | 678 | message3_nolog (KVAR (current_kboard, echo_string)); |
| 667 | STRING_MULTIBYTE (KVAR (current_kboard, echo_string))); | ||
| 668 | echoing = 0; | 679 | echoing = 0; |
| 669 | 680 | ||
| 670 | /* Record in what buffer we echoed, and from which kboard. */ | 681 | /* Record in what buffer we echoed, and from which kboard. */ |
| @@ -1174,13 +1185,13 @@ top_level_2 (void) | |||
| 1174 | static Lisp_Object | 1185 | static Lisp_Object |
| 1175 | top_level_1 (Lisp_Object ignore) | 1186 | top_level_1 (Lisp_Object ignore) |
| 1176 | { | 1187 | { |
| 1177 | /* On entry to the outer level, run the startup file */ | 1188 | /* On entry to the outer level, run the startup file. */ |
| 1178 | if (!NILP (Vtop_level)) | 1189 | if (!NILP (Vtop_level)) |
| 1179 | internal_condition_case (top_level_2, Qerror, cmd_error); | 1190 | internal_condition_case (top_level_2, Qerror, cmd_error); |
| 1180 | else if (!NILP (Vpurify_flag)) | 1191 | else if (!NILP (Vpurify_flag)) |
| 1181 | message ("Bare impure Emacs (standard Lisp code not loaded)"); | 1192 | message1 ("Bare impure Emacs (standard Lisp code not loaded)"); |
| 1182 | else | 1193 | else |
| 1183 | message ("Bare Emacs (standard Lisp code not loaded)"); | 1194 | message1 ("Bare Emacs (standard Lisp code not loaded)"); |
| 1184 | return Qnil; | 1195 | return Qnil; |
| 1185 | } | 1196 | } |
| 1186 | 1197 | ||
| @@ -1416,7 +1427,7 @@ command_loop_1 (void) | |||
| 1416 | sit_for (Vminibuffer_message_timeout, 0, 2); | 1427 | sit_for (Vminibuffer_message_timeout, 0, 2); |
| 1417 | 1428 | ||
| 1418 | /* Clear the echo area. */ | 1429 | /* Clear the echo area. */ |
| 1419 | message2 (0, 0, 0); | 1430 | message1 (0); |
| 1420 | safe_run_hooks (Qecho_area_clear_hook); | 1431 | safe_run_hooks (Qecho_area_clear_hook); |
| 1421 | 1432 | ||
| 1422 | unbind_to (count, Qnil); | 1433 | unbind_to (count, Qnil); |
| @@ -2219,13 +2230,12 @@ do { if (! polling_stopped_here) stop_polling (); \ | |||
| 2219 | do { if (polling_stopped_here) start_polling (); \ | 2230 | do { if (polling_stopped_here) start_polling (); \ |
| 2220 | polling_stopped_here = 0; } while (0) | 2231 | polling_stopped_here = 0; } while (0) |
| 2221 | 2232 | ||
| 2222 | /* read a character from the keyboard; call the redisplay if needed */ | 2233 | /* Read a character from the keyboard; call the redisplay if needed. */ |
| 2223 | /* commandflag 0 means do not autosave, but do redisplay. | 2234 | /* commandflag 0 means do not autosave, but do redisplay. |
| 2224 | -1 means do not redisplay, but do autosave. | 2235 | -1 means do not redisplay, but do autosave. |
| 2225 | 1 means do both. */ | 2236 | 1 means do both. */ |
| 2226 | 2237 | ||
| 2227 | /* The arguments MAPS and NMAPS are for menu prompting. | 2238 | /* The arguments MAP is for menu prompting. MAP is a keymap. |
| 2228 | MAPS is an array of keymaps; NMAPS is the length of MAPS. | ||
| 2229 | 2239 | ||
| 2230 | PREV_EVENT is the previous input event, or nil if we are reading | 2240 | PREV_EVENT is the previous input event, or nil if we are reading |
| 2231 | the first event of a key sequence (or not reading a key sequence). | 2241 | the first event of a key sequence (or not reading a key sequence). |
| @@ -2247,7 +2257,7 @@ do { if (polling_stopped_here) start_polling (); \ | |||
| 2247 | Value is t if we showed a menu and the user rejected it. */ | 2257 | Value is t if we showed a menu and the user rejected it. */ |
| 2248 | 2258 | ||
| 2249 | Lisp_Object | 2259 | Lisp_Object |
| 2250 | read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | 2260 | read_char (int commandflag, Lisp_Object map, |
| 2251 | Lisp_Object prev_event, | 2261 | Lisp_Object prev_event, |
| 2252 | bool *used_mouse_menu, EMACS_TIME *end_time) | 2262 | bool *used_mouse_menu, EMACS_TIME *end_time) |
| 2253 | { | 2263 | { |
| @@ -2395,7 +2405,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2395 | goto reread_first; | 2405 | goto reread_first; |
| 2396 | } | 2406 | } |
| 2397 | 2407 | ||
| 2398 | /* if redisplay was requested */ | 2408 | /* If redisplay was requested. */ |
| 2399 | if (commandflag >= 0) | 2409 | if (commandflag >= 0) |
| 2400 | { | 2410 | { |
| 2401 | bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]); | 2411 | bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]); |
| @@ -2404,7 +2414,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2404 | user-visible, such as X selection_request events. */ | 2414 | user-visible, such as X selection_request events. */ |
| 2405 | if (input_pending | 2415 | if (input_pending |
| 2406 | || detect_input_pending_run_timers (0)) | 2416 | || detect_input_pending_run_timers (0)) |
| 2407 | swallow_events (0); /* may clear input_pending */ | 2417 | swallow_events (0); /* May clear input_pending. */ |
| 2408 | 2418 | ||
| 2409 | /* Redisplay if no pending input. */ | 2419 | /* Redisplay if no pending input. */ |
| 2410 | while (!input_pending) | 2420 | while (!input_pending) |
| @@ -2474,13 +2484,13 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2474 | menu prompting. If EVENT_HAS_PARAMETERS then we are reading | 2484 | menu prompting. If EVENT_HAS_PARAMETERS then we are reading |
| 2475 | after a mouse event so don't try a minibuf menu. */ | 2485 | after a mouse event so don't try a minibuf menu. */ |
| 2476 | c = Qnil; | 2486 | c = Qnil; |
| 2477 | if (nmaps > 0 && INTERACTIVE | 2487 | if (KEYMAPP (map) && INTERACTIVE |
| 2478 | && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event) | 2488 | && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event) |
| 2479 | /* Don't bring up a menu if we already have another event. */ | 2489 | /* Don't bring up a menu if we already have another event. */ |
| 2480 | && NILP (Vunread_command_events) | 2490 | && NILP (Vunread_command_events) |
| 2481 | && !detect_input_pending_run_timers (0)) | 2491 | && !detect_input_pending_run_timers (0)) |
| 2482 | { | 2492 | { |
| 2483 | c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps); | 2493 | c = read_char_minibuf_menu_prompt (commandflag, map); |
| 2484 | 2494 | ||
| 2485 | if (INTEGERP (c) && XINT (c) == -2) | 2495 | if (INTEGERP (c) && XINT (c) == -2) |
| 2486 | return c; /* wrong_kboard_jmpbuf */ | 2496 | return c; /* wrong_kboard_jmpbuf */ |
| @@ -2604,7 +2614,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2604 | because the recursive call of read_char in read_char_minibuf_menu_prompt | 2614 | because the recursive call of read_char in read_char_minibuf_menu_prompt |
| 2605 | does not pass on any keymaps. */ | 2615 | does not pass on any keymaps. */ |
| 2606 | 2616 | ||
| 2607 | if (nmaps > 0 && INTERACTIVE | 2617 | if (KEYMAPP (map) && INTERACTIVE |
| 2608 | && !NILP (prev_event) | 2618 | && !NILP (prev_event) |
| 2609 | && EVENT_HAS_PARAMETERS (prev_event) | 2619 | && EVENT_HAS_PARAMETERS (prev_event) |
| 2610 | && !EQ (XCAR (prev_event), Qmenu_bar) | 2620 | && !EQ (XCAR (prev_event), Qmenu_bar) |
| @@ -2612,7 +2622,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2612 | /* Don't bring up a menu if we already have another event. */ | 2622 | /* Don't bring up a menu if we already have another event. */ |
| 2613 | && NILP (Vunread_command_events)) | 2623 | && NILP (Vunread_command_events)) |
| 2614 | { | 2624 | { |
| 2615 | c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu); | 2625 | c = read_char_x_menu_prompt (map, prev_event, used_mouse_menu); |
| 2616 | 2626 | ||
| 2617 | /* Now that we have read an event, Emacs is not idle. */ | 2627 | /* Now that we have read an event, Emacs is not idle. */ |
| 2618 | if (!end_time) | 2628 | if (!end_time) |
| @@ -2647,9 +2657,10 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2647 | && XINT (Vauto_save_timeout) > 0) | 2657 | && XINT (Vauto_save_timeout) > 0) |
| 2648 | { | 2658 | { |
| 2649 | Lisp_Object tem0; | 2659 | Lisp_Object tem0; |
| 2650 | EMACS_INT timeout = (delay_level | 2660 | EMACS_INT timeout = XFASTINT (Vauto_save_timeout); |
| 2651 | * min (XFASTINT (Vauto_save_timeout) / 4, | 2661 | |
| 2652 | MOST_POSITIVE_FIXNUM / delay_level)); | 2662 | timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4); |
| 2663 | timeout = delay_level * timeout / 4; | ||
| 2653 | save_getcjmp (save_jump); | 2664 | save_getcjmp (save_jump); |
| 2654 | restore_getcjmp (local_getcjmp); | 2665 | restore_getcjmp (local_getcjmp); |
| 2655 | tem0 = sit_for (make_number (timeout), 1, 1); | 2666 | tem0 = sit_for (make_number (timeout), 1, 1); |
| @@ -2990,7 +3001,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 2990 | 3001 | ||
| 2991 | /* If we are not reading a key sequence, | 3002 | /* If we are not reading a key sequence, |
| 2992 | never use the echo area. */ | 3003 | never use the echo area. */ |
| 2993 | if (maps == 0) | 3004 | if (!KEYMAPP (map)) |
| 2994 | { | 3005 | { |
| 2995 | specbind (Qinput_method_use_echo_area, Qt); | 3006 | specbind (Qinput_method_use_echo_area, Qt); |
| 2996 | } | 3007 | } |
| @@ -3083,7 +3094,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 3083 | last_input_event = c; | 3094 | last_input_event = c; |
| 3084 | num_input_events++; | 3095 | num_input_events++; |
| 3085 | 3096 | ||
| 3086 | /* Process the help character specially if enabled */ | 3097 | /* Process the help character specially if enabled. */ |
| 3087 | if (!NILP (Vhelp_form) && help_char_p (c)) | 3098 | if (!NILP (Vhelp_form) && help_char_p (c)) |
| 3088 | { | 3099 | { |
| 3089 | ptrdiff_t count = SPECPDL_INDEX (); | 3100 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -3097,13 +3108,13 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 3097 | cancel_echoing (); | 3108 | cancel_echoing (); |
| 3098 | do | 3109 | do |
| 3099 | { | 3110 | { |
| 3100 | c = read_char (0, 0, 0, Qnil, 0, NULL); | 3111 | c = read_char (0, Qnil, Qnil, 0, NULL); |
| 3101 | if (EVENT_HAS_PARAMETERS (c) | 3112 | if (EVENT_HAS_PARAMETERS (c) |
| 3102 | && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click)) | 3113 | && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click)) |
| 3103 | XSETCAR (help_form_saved_window_configs, Qnil); | 3114 | XSETCAR (help_form_saved_window_configs, Qnil); |
| 3104 | } | 3115 | } |
| 3105 | while (BUFFERP (c)); | 3116 | while (BUFFERP (c)); |
| 3106 | /* Remove the help from the frame */ | 3117 | /* Remove the help from the frame. */ |
| 3107 | unbind_to (count, Qnil); | 3118 | unbind_to (count, Qnil); |
| 3108 | 3119 | ||
| 3109 | redisplay (); | 3120 | redisplay (); |
| @@ -3111,7 +3122,7 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 3111 | { | 3122 | { |
| 3112 | cancel_echoing (); | 3123 | cancel_echoing (); |
| 3113 | do | 3124 | do |
| 3114 | c = read_char (0, 0, 0, Qnil, 0, NULL); | 3125 | c = read_char (0, Qnil, Qnil, 0, NULL); |
| 3115 | while (BUFFERP (c)); | 3126 | while (BUFFERP (c)); |
| 3116 | } | 3127 | } |
| 3117 | } | 3128 | } |
| @@ -3904,6 +3915,18 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3904 | kbd_fetch_ptr = event + 1; | 3915 | kbd_fetch_ptr = event + 1; |
| 3905 | } | 3916 | } |
| 3906 | #endif | 3917 | #endif |
| 3918 | #ifdef WINDOWSNT | ||
| 3919 | else if (event->kind == FILE_NOTIFY_EVENT) | ||
| 3920 | { | ||
| 3921 | /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */ | ||
| 3922 | obj = Fcons (Qfile_w32notify, | ||
| 3923 | list2 (list3 (make_number (event->code), | ||
| 3924 | XCAR (event->arg), | ||
| 3925 | XCDR (event->arg)), | ||
| 3926 | event->frame_or_window)); | ||
| 3927 | kbd_fetch_ptr = event + 1; | ||
| 3928 | } | ||
| 3929 | #endif | ||
| 3907 | else if (event->kind == SAVE_SESSION_EVENT) | 3930 | else if (event->kind == SAVE_SESSION_EVENT) |
| 3908 | { | 3931 | { |
| 3909 | obj = Fcons (Qsave_session, Fcons (event->arg, Qnil)); | 3932 | obj = Fcons (Qsave_session, Fcons (event->arg, Qnil)); |
| @@ -3961,6 +3984,13 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3961 | kbd_fetch_ptr = event + 1; | 3984 | kbd_fetch_ptr = event + 1; |
| 3962 | } | 3985 | } |
| 3963 | #endif | 3986 | #endif |
| 3987 | #ifdef HAVE_INOTIFY | ||
| 3988 | else if (event->kind == FILE_NOTIFY_EVENT) | ||
| 3989 | { | ||
| 3990 | obj = make_lispy_event (event); | ||
| 3991 | kbd_fetch_ptr = event + 1; | ||
| 3992 | } | ||
| 3993 | #endif | ||
| 3964 | else if (event->kind == CONFIG_CHANGED_EVENT) | 3994 | else if (event->kind == CONFIG_CHANGED_EVENT) |
| 3965 | { | 3995 | { |
| 3966 | obj = make_lispy_event (event); | 3996 | obj = make_lispy_event (event); |
| @@ -5113,7 +5143,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, | |||
| 5113 | string_info = Fcons (string, make_number (charpos)); | 5143 | string_info = Fcons (string, make_number (charpos)); |
| 5114 | textpos = (w == XWINDOW (selected_window) | 5144 | textpos = (w == XWINDOW (selected_window) |
| 5115 | && current_buffer == XBUFFER (w->buffer)) | 5145 | && current_buffer == XBUFFER (w->buffer)) |
| 5116 | ? PT : XMARKER (w->pointm)->charpos; | 5146 | ? PT : marker_position (w->pointm); |
| 5117 | 5147 | ||
| 5118 | xret = wx; | 5148 | xret = wx; |
| 5119 | yret = wy; | 5149 | yret = wy; |
| @@ -5874,6 +5904,13 @@ make_lispy_event (struct input_event *event) | |||
| 5874 | } | 5904 | } |
| 5875 | #endif /* HAVE_DBUS */ | 5905 | #endif /* HAVE_DBUS */ |
| 5876 | 5906 | ||
| 5907 | #ifdef HAVE_INOTIFY | ||
| 5908 | case FILE_NOTIFY_EVENT: | ||
| 5909 | { | ||
| 5910 | return Fcons (Qfile_inotify, event->arg); | ||
| 5911 | } | ||
| 5912 | #endif /* HAVE_INOTIFY */ | ||
| 5913 | |||
| 5877 | case CONFIG_CHANGED_EVENT: | 5914 | case CONFIG_CHANGED_EVENT: |
| 5878 | return Fcons (Qconfig_changed_event, | 5915 | return Fcons (Qconfig_changed_event, |
| 5879 | Fcons (event->arg, | 5916 | Fcons (event->arg, |
| @@ -6668,37 +6705,35 @@ get_input_pending (int flags) | |||
| 6668 | void | 6705 | void |
| 6669 | record_asynch_buffer_change (void) | 6706 | record_asynch_buffer_change (void) |
| 6670 | { | 6707 | { |
| 6671 | struct input_event event; | ||
| 6672 | Lisp_Object tem; | ||
| 6673 | EVENT_INIT (event); | ||
| 6674 | |||
| 6675 | event.kind = BUFFER_SWITCH_EVENT; | ||
| 6676 | event.frame_or_window = Qnil; | ||
| 6677 | event.arg = Qnil; | ||
| 6678 | |||
| 6679 | /* We don't need a buffer-switch event unless Emacs is waiting for input. | 6708 | /* We don't need a buffer-switch event unless Emacs is waiting for input. |
| 6680 | The purpose of the event is to make read_key_sequence look up the | 6709 | The purpose of the event is to make read_key_sequence look up the |
| 6681 | keymaps again. If we aren't in read_key_sequence, we don't need one, | 6710 | keymaps again. If we aren't in read_key_sequence, we don't need one, |
| 6682 | and the event could cause trouble by messing up (input-pending-p). | 6711 | and the event could cause trouble by messing up (input-pending-p). |
| 6683 | Note: Fwaiting_for_user_input_p always returns nil when async | 6712 | Note: Fwaiting_for_user_input_p always returns nil when async |
| 6684 | subprocesses aren't supported. */ | 6713 | subprocesses aren't supported. */ |
| 6685 | tem = Fwaiting_for_user_input_p (); | 6714 | if (!NILP (Fwaiting_for_user_input_p ())) |
| 6686 | if (NILP (tem)) | 6715 | { |
| 6687 | return; | 6716 | struct input_event event; |
| 6717 | |||
| 6718 | EVENT_INIT (event); | ||
| 6719 | event.kind = BUFFER_SWITCH_EVENT; | ||
| 6720 | event.frame_or_window = Qnil; | ||
| 6721 | event.arg = Qnil; | ||
| 6688 | 6722 | ||
| 6689 | /* Make sure no interrupt happens while storing the event. */ | 6723 | /* Make sure no interrupt happens while storing the event. */ |
| 6690 | #ifdef USABLE_SIGIO | 6724 | #ifdef USABLE_SIGIO |
| 6691 | if (interrupt_input) | 6725 | if (interrupt_input) |
| 6692 | kbd_buffer_store_event (&event); | 6726 | kbd_buffer_store_event (&event); |
| 6693 | else | 6727 | else |
| 6694 | #endif | 6728 | #endif |
| 6695 | { | 6729 | { |
| 6696 | stop_polling (); | 6730 | stop_polling (); |
| 6697 | kbd_buffer_store_event (&event); | 6731 | kbd_buffer_store_event (&event); |
| 6698 | start_polling (); | 6732 | start_polling (); |
| 6733 | } | ||
| 6699 | } | 6734 | } |
| 6700 | } | 6735 | } |
| 6701 | 6736 | ||
| 6702 | /* Read any terminal input already buffered up by the system | 6737 | /* Read any terminal input already buffered up by the system |
| 6703 | into the kbd_buffer, but do not wait. | 6738 | into the kbd_buffer, but do not wait. |
| 6704 | 6739 | ||
| @@ -8277,9 +8312,9 @@ init_tool_bar_items (Lisp_Object reuse) | |||
| 8277 | static void | 8312 | static void |
| 8278 | append_tool_bar_item (void) | 8313 | append_tool_bar_item (void) |
| 8279 | { | 8314 | { |
| 8280 | ptrdiff_t incr = | 8315 | ptrdiff_t incr |
| 8281 | (ntool_bar_items | 8316 | = (ntool_bar_items |
| 8282 | - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS)); | 8317 | - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS)); |
| 8283 | 8318 | ||
| 8284 | /* Enlarge tool_bar_items_vector if necessary. */ | 8319 | /* Enlarge tool_bar_items_vector if necessary. */ |
| 8285 | if (0 < incr) | 8320 | if (0 < incr) |
| @@ -8297,8 +8332,8 @@ append_tool_bar_item (void) | |||
| 8297 | 8332 | ||
| 8298 | 8333 | ||
| 8299 | 8334 | ||
| 8300 | /* Read a character using menus based on maps in the array MAPS. | 8335 | /* Read a character using menus based on the keymap MAP. |
| 8301 | NMAPS is the length of MAPS. Return nil if there are no menus in the maps. | 8336 | Return nil if there are no menus in the maps. |
| 8302 | Return t if we displayed a menu but the user rejected it. | 8337 | Return t if we displayed a menu but the user rejected it. |
| 8303 | 8338 | ||
| 8304 | PREV_EVENT is the previous input event, or nil if we are reading | 8339 | PREV_EVENT is the previous input event, or nil if we are reading |
| @@ -8318,28 +8353,17 @@ append_tool_bar_item (void) | |||
| 8318 | and do auto-saving in the inner call of read_char. */ | 8353 | and do auto-saving in the inner call of read_char. */ |
| 8319 | 8354 | ||
| 8320 | static Lisp_Object | 8355 | static Lisp_Object |
| 8321 | read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, | 8356 | read_char_x_menu_prompt (Lisp_Object map, |
| 8322 | Lisp_Object prev_event, bool *used_mouse_menu) | 8357 | Lisp_Object prev_event, bool *used_mouse_menu) |
| 8323 | { | 8358 | { |
| 8324 | #ifdef HAVE_MENUS | ||
| 8325 | ptrdiff_t mapno; | ||
| 8326 | #endif | ||
| 8327 | |||
| 8328 | if (used_mouse_menu) | 8359 | if (used_mouse_menu) |
| 8329 | *used_mouse_menu = 0; | 8360 | *used_mouse_menu = 0; |
| 8330 | 8361 | ||
| 8331 | /* Use local over global Menu maps */ | 8362 | /* Use local over global Menu maps. */ |
| 8332 | 8363 | ||
| 8333 | if (! menu_prompting) | 8364 | if (! menu_prompting) |
| 8334 | return Qnil; | 8365 | return Qnil; |
| 8335 | 8366 | ||
| 8336 | /* Optionally disregard all but the global map. */ | ||
| 8337 | if (inhibit_local_menu_bar_menus) | ||
| 8338 | { | ||
| 8339 | maps += (nmaps - 1); | ||
| 8340 | nmaps = 1; | ||
| 8341 | } | ||
| 8342 | |||
| 8343 | #ifdef HAVE_MENUS | 8367 | #ifdef HAVE_MENUS |
| 8344 | /* If we got to this point via a mouse click, | 8368 | /* If we got to this point via a mouse click, |
| 8345 | use a real menu for mouse selection. */ | 8369 | use a real menu for mouse selection. */ |
| @@ -8348,16 +8372,9 @@ read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 8348 | && !EQ (XCAR (prev_event), Qtool_bar)) | 8372 | && !EQ (XCAR (prev_event), Qtool_bar)) |
| 8349 | { | 8373 | { |
| 8350 | /* Display the menu and get the selection. */ | 8374 | /* Display the menu and get the selection. */ |
| 8351 | Lisp_Object *realmaps = alloca (nmaps * sizeof *realmaps); | ||
| 8352 | Lisp_Object value; | 8375 | Lisp_Object value; |
| 8353 | ptrdiff_t nmaps1 = 0; | ||
| 8354 | 8376 | ||
| 8355 | /* Use the maps that are not nil. */ | 8377 | value = Fx_popup_menu (prev_event, get_keymap (map, 0, 1)); |
| 8356 | for (mapno = 0; mapno < nmaps; mapno++) | ||
| 8357 | if (!NILP (maps[mapno])) | ||
| 8358 | realmaps[nmaps1++] = maps[mapno]; | ||
| 8359 | |||
| 8360 | value = Fx_popup_menu (prev_event, Flist (nmaps1, realmaps)); | ||
| 8361 | if (CONSP (value)) | 8378 | if (CONSP (value)) |
| 8362 | { | 8379 | { |
| 8363 | Lisp_Object tem; | 8380 | Lisp_Object tem; |
| @@ -8397,17 +8414,10 @@ read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, | |||
| 8397 | return Qnil ; | 8414 | return Qnil ; |
| 8398 | } | 8415 | } |
| 8399 | 8416 | ||
| 8400 | /* Buffer in use so far for the minibuf prompts for menu keymaps. | ||
| 8401 | We make this bigger when necessary, and never free it. */ | ||
| 8402 | static char *read_char_minibuf_menu_text; | ||
| 8403 | /* Size of that buffer. */ | ||
| 8404 | static ptrdiff_t read_char_minibuf_menu_width; | ||
| 8405 | |||
| 8406 | static Lisp_Object | 8417 | static Lisp_Object |
| 8407 | read_char_minibuf_menu_prompt (int commandflag, | 8418 | read_char_minibuf_menu_prompt (int commandflag, |
| 8408 | ptrdiff_t nmaps, Lisp_Object *maps) | 8419 | Lisp_Object map) |
| 8409 | { | 8420 | { |
| 8410 | ptrdiff_t mapno; | ||
| 8411 | register Lisp_Object name; | 8421 | register Lisp_Object name; |
| 8412 | ptrdiff_t nlength; | 8422 | ptrdiff_t nlength; |
| 8413 | /* FIXME: Use the minibuffer's frame width. */ | 8423 | /* FIXME: Use the minibuffer's frame width. */ |
| @@ -8415,53 +8425,35 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8415 | ptrdiff_t idx = -1; | 8425 | ptrdiff_t idx = -1; |
| 8416 | bool nobindings = 1; | 8426 | bool nobindings = 1; |
| 8417 | Lisp_Object rest, vector; | 8427 | Lisp_Object rest, vector; |
| 8418 | char *menu; | 8428 | Lisp_Object prompt_strings = Qnil; |
| 8419 | 8429 | ||
| 8420 | vector = Qnil; | 8430 | vector = Qnil; |
| 8421 | name = Qnil; | ||
| 8422 | 8431 | ||
| 8423 | if (! menu_prompting) | 8432 | if (! menu_prompting) |
| 8424 | return Qnil; | 8433 | return Qnil; |
| 8425 | 8434 | ||
| 8426 | /* Get the menu name from the first map that has one (a prompt string). */ | 8435 | map = get_keymap (map, 0, 1); |
| 8427 | for (mapno = 0; mapno < nmaps; mapno++) | 8436 | name = Fkeymap_prompt (map); |
| 8428 | { | ||
| 8429 | name = Fkeymap_prompt (maps[mapno]); | ||
| 8430 | if (!NILP (name)) | ||
| 8431 | break; | ||
| 8432 | } | ||
| 8433 | 8437 | ||
| 8434 | /* If we don't have any menus, just read a character normally. */ | 8438 | /* If we don't have any menus, just read a character normally. */ |
| 8435 | if (!STRINGP (name)) | 8439 | if (!STRINGP (name)) |
| 8436 | return Qnil; | 8440 | return Qnil; |
| 8437 | 8441 | ||
| 8438 | /* Make sure we have a big enough buffer for the menu text. */ | 8442 | #define PUSH_C_STR(str, listvar) \ |
| 8439 | width = max (width, SBYTES (name)); | 8443 | listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar) |
| 8440 | if (STRING_BYTES_BOUND - 4 < width) | ||
| 8441 | memory_full (SIZE_MAX); | ||
| 8442 | if (width + 4 > read_char_minibuf_menu_width) | ||
| 8443 | { | ||
| 8444 | read_char_minibuf_menu_text | ||
| 8445 | = xrealloc (read_char_minibuf_menu_text, width + 4); | ||
| 8446 | read_char_minibuf_menu_width = width + 4; | ||
| 8447 | } | ||
| 8448 | menu = read_char_minibuf_menu_text; | ||
| 8449 | 8444 | ||
| 8450 | /* Prompt string always starts with map's prompt, and a space. */ | 8445 | /* Prompt string always starts with map's prompt, and a space. */ |
| 8451 | strcpy (menu, SSDATA (name)); | 8446 | prompt_strings = Fcons (name, prompt_strings); |
| 8452 | nlength = SBYTES (name); | 8447 | PUSH_C_STR (": ", prompt_strings); |
| 8453 | menu[nlength++] = ':'; | 8448 | nlength = SCHARS (name) + 2; |
| 8454 | menu[nlength++] = ' '; | ||
| 8455 | menu[nlength] = 0; | ||
| 8456 | 8449 | ||
| 8457 | /* Start prompting at start of first map. */ | 8450 | rest = map; |
| 8458 | mapno = 0; | ||
| 8459 | rest = maps[mapno]; | ||
| 8460 | 8451 | ||
| 8461 | /* Present the documented bindings, a line at a time. */ | 8452 | /* Present the documented bindings, a line at a time. */ |
| 8462 | while (1) | 8453 | while (1) |
| 8463 | { | 8454 | { |
| 8464 | bool notfirst = 0; | 8455 | bool notfirst = 0; |
| 8456 | Lisp_Object menu_strings = prompt_strings; | ||
| 8465 | ptrdiff_t i = nlength; | 8457 | ptrdiff_t i = nlength; |
| 8466 | Lisp_Object obj; | 8458 | Lisp_Object obj; |
| 8467 | Lisp_Object orig_defn_macro; | 8459 | Lisp_Object orig_defn_macro; |
| @@ -8471,18 +8463,16 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8471 | { | 8463 | { |
| 8472 | Lisp_Object elt; | 8464 | Lisp_Object elt; |
| 8473 | 8465 | ||
| 8474 | /* If reached end of map, start at beginning of next map. */ | 8466 | /* FIXME: Use map_keymap to handle new keymap formats. */ |
| 8467 | |||
| 8468 | /* At end of map, wrap around if just starting, | ||
| 8469 | or end this line if already have something on it. */ | ||
| 8475 | if (NILP (rest)) | 8470 | if (NILP (rest)) |
| 8476 | { | 8471 | { |
| 8477 | mapno++; | 8472 | if (notfirst || nobindings) |
| 8478 | /* At end of last map, wrap around to first map if just starting, | 8473 | break; |
| 8479 | or end this line if already have something on it. */ | 8474 | else |
| 8480 | if (mapno == nmaps) | 8475 | rest = map; |
| 8481 | { | ||
| 8482 | mapno = 0; | ||
| 8483 | if (notfirst || nobindings) break; | ||
| 8484 | } | ||
| 8485 | rest = maps[mapno]; | ||
| 8486 | } | 8476 | } |
| 8487 | 8477 | ||
| 8488 | /* Look at the next element of the map. */ | 8478 | /* Look at the next element of the map. */ |
| @@ -8566,7 +8556,7 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8566 | /* Punctuate between strings. */ | 8556 | /* Punctuate between strings. */ |
| 8567 | if (notfirst) | 8557 | if (notfirst) |
| 8568 | { | 8558 | { |
| 8569 | strcpy (menu + i, ", "); | 8559 | PUSH_C_STR (", ", menu_strings); |
| 8570 | i += 2; | 8560 | i += 2; |
| 8571 | } | 8561 | } |
| 8572 | notfirst = 1; | 8562 | notfirst = 1; |
| @@ -8578,23 +8568,28 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8578 | { | 8568 | { |
| 8579 | /* Add as much of string as fits. */ | 8569 | /* Add as much of string as fits. */ |
| 8580 | thiswidth = min (SCHARS (desc), width - i); | 8570 | thiswidth = min (SCHARS (desc), width - i); |
| 8581 | memcpy (menu + i, SDATA (desc), thiswidth); | 8571 | menu_strings |
| 8572 | = Fcons (Fsubstring (desc, make_number (0), | ||
| 8573 | make_number (thiswidth)), | ||
| 8574 | menu_strings); | ||
| 8582 | i += thiswidth; | 8575 | i += thiswidth; |
| 8583 | strcpy (menu + i, " = "); | 8576 | PUSH_C_STR (" = ", menu_strings); |
| 8584 | i += 3; | 8577 | i += 3; |
| 8585 | } | 8578 | } |
| 8586 | 8579 | ||
| 8587 | /* Add as much of string as fits. */ | 8580 | /* Add as much of string as fits. */ |
| 8588 | thiswidth = min (SCHARS (s), width - i); | 8581 | thiswidth = min (SCHARS (s), width - i); |
| 8589 | memcpy (menu + i, SDATA (s), thiswidth); | 8582 | menu_strings |
| 8583 | = Fcons (Fsubstring (s, make_number (0), | ||
| 8584 | make_number (thiswidth)), | ||
| 8585 | menu_strings); | ||
| 8590 | i += thiswidth; | 8586 | i += thiswidth; |
| 8591 | menu[i] = 0; | ||
| 8592 | } | 8587 | } |
| 8593 | else | 8588 | else |
| 8594 | { | 8589 | { |
| 8595 | /* If this element does not fit, end the line now, | 8590 | /* If this element does not fit, end the line now, |
| 8596 | and save the element for the next line. */ | 8591 | and save the element for the next line. */ |
| 8597 | strcpy (menu + i, "..."); | 8592 | PUSH_C_STR ("...", menu_strings); |
| 8598 | break; | 8593 | break; |
| 8599 | } | 8594 | } |
| 8600 | } | 8595 | } |
| @@ -8611,23 +8606,19 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8611 | } | 8606 | } |
| 8612 | 8607 | ||
| 8613 | /* Prompt with that and read response. */ | 8608 | /* Prompt with that and read response. */ |
| 8614 | message2_nolog (menu, strlen (menu), | 8609 | message3_nolog (apply1 (intern ("concat"), Fnreverse (menu_strings))); |
| 8615 | ! NILP (BVAR (current_buffer, enable_multibyte_characters))); | ||
| 8616 | 8610 | ||
| 8617 | /* Make believe its not a keyboard macro in case the help char | 8611 | /* Make believe it's not a keyboard macro in case the help char |
| 8618 | is pressed. Help characters are not recorded because menu prompting | 8612 | is pressed. Help characters are not recorded because menu prompting |
| 8619 | is not used on replay. | 8613 | is not used on replay. */ |
| 8620 | */ | ||
| 8621 | orig_defn_macro = KVAR (current_kboard, defining_kbd_macro); | 8614 | orig_defn_macro = KVAR (current_kboard, defining_kbd_macro); |
| 8622 | kset_defining_kbd_macro (current_kboard, Qnil); | 8615 | kset_defining_kbd_macro (current_kboard, Qnil); |
| 8623 | do | 8616 | do |
| 8624 | obj = read_char (commandflag, 0, 0, Qt, 0, NULL); | 8617 | obj = read_char (commandflag, Qnil, Qt, 0, NULL); |
| 8625 | while (BUFFERP (obj)); | 8618 | while (BUFFERP (obj)); |
| 8626 | kset_defining_kbd_macro (current_kboard, orig_defn_macro); | 8619 | kset_defining_kbd_macro (current_kboard, orig_defn_macro); |
| 8627 | 8620 | ||
| 8628 | if (!INTEGERP (obj)) | 8621 | if (!INTEGERP (obj) || XINT (obj) == -2) |
| 8629 | return obj; | ||
| 8630 | else if (XINT (obj) == -2) | ||
| 8631 | return obj; | 8622 | return obj; |
| 8632 | 8623 | ||
| 8633 | if (! EQ (obj, menu_prompt_more_char) | 8624 | if (! EQ (obj, menu_prompt_more_char) |
| @@ -8638,52 +8629,25 @@ read_char_minibuf_menu_prompt (int commandflag, | |||
| 8638 | store_kbd_macro_char (obj); | 8629 | store_kbd_macro_char (obj); |
| 8639 | return obj; | 8630 | return obj; |
| 8640 | } | 8631 | } |
| 8641 | /* Help char - go round again */ | 8632 | /* Help char - go round again. */ |
| 8642 | } | 8633 | } |
| 8643 | } | 8634 | } |
| 8644 | 8635 | ||
| 8645 | /* Reading key sequences. */ | 8636 | /* Reading key sequences. */ |
| 8646 | 8637 | ||
| 8647 | /* Follow KEY in the maps in CURRENT[0..NMAPS-1], placing its bindings | 8638 | static Lisp_Object |
| 8648 | in DEFS[0..NMAPS-1]. Set NEXT[i] to DEFS[i] if DEFS[i] is a | 8639 | follow_key (Lisp_Object keymap, Lisp_Object key) |
| 8649 | keymap, or nil otherwise. Return the index of the first keymap in | ||
| 8650 | which KEY has any binding, or NMAPS if no map has a binding. | ||
| 8651 | |||
| 8652 | If KEY is a meta ASCII character, treat it like meta-prefix-char | ||
| 8653 | followed by the corresponding non-meta character. Keymaps in | ||
| 8654 | CURRENT with non-prefix bindings for meta-prefix-char become nil in | ||
| 8655 | NEXT. | ||
| 8656 | |||
| 8657 | If KEY has no bindings in any of the CURRENT maps, NEXT is left | ||
| 8658 | unmodified. | ||
| 8659 | |||
| 8660 | NEXT may be the same array as CURRENT. */ | ||
| 8661 | |||
| 8662 | static int | ||
| 8663 | follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current, | ||
| 8664 | Lisp_Object *defs, Lisp_Object *next) | ||
| 8665 | { | 8640 | { |
| 8666 | ptrdiff_t i, first_binding; | 8641 | return access_keymap (get_keymap (keymap, 0, 1), |
| 8667 | 8642 | key, 1, 0, 1); | |
| 8668 | first_binding = nmaps; | 8643 | } |
| 8669 | for (i = nmaps - 1; i >= 0; i--) | ||
| 8670 | { | ||
| 8671 | if (! NILP (current[i])) | ||
| 8672 | { | ||
| 8673 | defs[i] = access_keymap (current[i], key, 1, 0, 1); | ||
| 8674 | if (! NILP (defs[i])) | ||
| 8675 | first_binding = i; | ||
| 8676 | } | ||
| 8677 | else | ||
| 8678 | defs[i] = Qnil; | ||
| 8679 | } | ||
| 8680 | |||
| 8681 | /* Given the set of bindings we've found, produce the next set of maps. */ | ||
| 8682 | if (first_binding < nmaps) | ||
| 8683 | for (i = 0; i < nmaps; i++) | ||
| 8684 | next[i] = NILP (defs[i]) ? Qnil : get_keymap (defs[i], 0, 1); | ||
| 8685 | 8644 | ||
| 8686 | return first_binding; | 8645 | static Lisp_Object |
| 8646 | active_maps (Lisp_Object first_event) | ||
| 8647 | { | ||
| 8648 | Lisp_Object position | ||
| 8649 | = CONSP (first_event) ? CAR_SAFE (XCDR (first_event)) : Qnil; | ||
| 8650 | return Fcons (Qkeymap, Fcurrent_active_maps (Qt, position)); | ||
| 8687 | } | 8651 | } |
| 8688 | 8652 | ||
| 8689 | /* Structure used to keep track of partial application of key remapping | 8653 | /* Structure used to keep track of partial application of key remapping |
| @@ -8815,8 +8779,9 @@ keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey, | |||
| 8815 | static bool | 8779 | static bool |
| 8816 | test_undefined (Lisp_Object binding) | 8780 | test_undefined (Lisp_Object binding) |
| 8817 | { | 8781 | { |
| 8818 | return (EQ (binding, Qundefined) | 8782 | return (NILP (binding) |
| 8819 | || (!NILP (binding) && SYMBOLP (binding) | 8783 | || EQ (binding, Qundefined) |
| 8784 | || (SYMBOLP (binding) | ||
| 8820 | && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); | 8785 | && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); |
| 8821 | } | 8786 | } |
| 8822 | 8787 | ||
| @@ -8862,7 +8827,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8862 | bool dont_downcase_last, bool can_return_switch_frame, | 8827 | bool dont_downcase_last, bool can_return_switch_frame, |
| 8863 | bool fix_current_buffer) | 8828 | bool fix_current_buffer) |
| 8864 | { | 8829 | { |
| 8865 | Lisp_Object from_string; | ||
| 8866 | ptrdiff_t count = SPECPDL_INDEX (); | 8830 | ptrdiff_t count = SPECPDL_INDEX (); |
| 8867 | 8831 | ||
| 8868 | /* How many keys there are in the current key sequence. */ | 8832 | /* How many keys there are in the current key sequence. */ |
| @@ -8873,34 +8837,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8873 | ptrdiff_t echo_start IF_LINT (= 0); | 8837 | ptrdiff_t echo_start IF_LINT (= 0); |
| 8874 | ptrdiff_t keys_start; | 8838 | ptrdiff_t keys_start; |
| 8875 | 8839 | ||
| 8876 | /* The number of keymaps we're scanning right now, and the number of | 8840 | Lisp_Object current_binding = Qnil; |
| 8877 | keymaps we have allocated space for. */ | 8841 | Lisp_Object first_event = Qnil; |
| 8878 | ptrdiff_t nmaps; | ||
| 8879 | ptrdiff_t nmaps_allocated = 0; | ||
| 8880 | |||
| 8881 | /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in | ||
| 8882 | the current keymaps. */ | ||
| 8883 | Lisp_Object *defs = NULL; | ||
| 8884 | 8842 | ||
| 8885 | /* submaps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1] | ||
| 8886 | in the current keymaps, or nil where it is not a prefix. */ | ||
| 8887 | Lisp_Object *submaps = NULL; | ||
| 8888 | |||
| 8889 | /* The local map to start out with at start of key sequence. */ | ||
| 8890 | Lisp_Object orig_local_map; | ||
| 8891 | |||
| 8892 | /* The map from the `keymap' property to start out with at start of | ||
| 8893 | key sequence. */ | ||
| 8894 | Lisp_Object orig_keymap; | ||
| 8895 | |||
| 8896 | /* Positive if we have already considered switching to the local-map property | ||
| 8897 | of the place where a mouse click occurred. */ | ||
| 8898 | int localized_local_map = 0; | ||
| 8899 | |||
| 8900 | /* The index in submaps[] of the first keymap that has a binding for | ||
| 8901 | this key sequence. In other words, the lowest i such that | ||
| 8902 | submaps[i] is non-nil. */ | ||
| 8903 | ptrdiff_t first_binding; | ||
| 8904 | /* Index of the first key that has no binding. | 8843 | /* Index of the first key that has no binding. |
| 8905 | It is useless to try fkey.start larger than that. */ | 8844 | It is useless to try fkey.start larger than that. */ |
| 8906 | int first_unbound; | 8845 | int first_unbound; |
| @@ -8943,11 +8882,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8943 | While we're reading, we keep the event here. */ | 8882 | While we're reading, we keep the event here. */ |
| 8944 | Lisp_Object delayed_switch_frame; | 8883 | Lisp_Object delayed_switch_frame; |
| 8945 | 8884 | ||
| 8946 | /* See the comment below... */ | ||
| 8947 | #if defined (GOBBLE_FIRST_EVENT) | ||
| 8948 | Lisp_Object first_event; | ||
| 8949 | #endif | ||
| 8950 | |||
| 8951 | Lisp_Object original_uppercase IF_LINT (= Qnil); | 8885 | Lisp_Object original_uppercase IF_LINT (= Qnil); |
| 8952 | int original_uppercase_position = -1; | 8886 | int original_uppercase_position = -1; |
| 8953 | 8887 | ||
| @@ -8959,10 +8893,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8959 | /* List of events for which a fake prefix key has been generated. */ | 8893 | /* List of events for which a fake prefix key has been generated. */ |
| 8960 | Lisp_Object fake_prefixed_keys = Qnil; | 8894 | Lisp_Object fake_prefixed_keys = Qnil; |
| 8961 | 8895 | ||
| 8962 | #if defined (GOBBLE_FIRST_EVENT) | ||
| 8963 | int junk; | ||
| 8964 | #endif | ||
| 8965 | |||
| 8966 | struct gcpro gcpro1; | 8896 | struct gcpro gcpro1; |
| 8967 | 8897 | ||
| 8968 | GCPRO1 (fake_prefixed_keys); | 8898 | GCPRO1 (fake_prefixed_keys); |
| @@ -8998,21 +8928,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 8998 | keys_start = this_command_key_count; | 8928 | keys_start = this_command_key_count; |
| 8999 | this_single_command_key_start = keys_start; | 8929 | this_single_command_key_start = keys_start; |
| 9000 | 8930 | ||
| 9001 | #if defined (GOBBLE_FIRST_EVENT) | ||
| 9002 | /* This doesn't quite work, because some of the things that read_char | ||
| 9003 | does cannot safely be bypassed. It seems too risky to try to make | ||
| 9004 | this work right. */ | ||
| 9005 | |||
| 9006 | /* Read the first char of the sequence specially, before setting | ||
| 9007 | up any keymaps, in case a filter runs and switches buffers on us. */ | ||
| 9008 | first_event = read_char (NILP (prompt), 0, submaps, last_nonmenu_event, | ||
| 9009 | &junk, NULL); | ||
| 9010 | #endif /* GOBBLE_FIRST_EVENT */ | ||
| 9011 | |||
| 9012 | orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); | ||
| 9013 | orig_keymap = get_local_map (PT, current_buffer, Qkeymap); | ||
| 9014 | from_string = Qnil; | ||
| 9015 | |||
| 9016 | /* We jump here when we need to reinitialize fkey and keytran; this | 8931 | /* We jump here when we need to reinitialize fkey and keytran; this |
| 9017 | happens if we switch keyboards between rescans. */ | 8932 | happens if we switch keyboards between rescans. */ |
| 9018 | replay_entire_sequence: | 8933 | replay_entire_sequence: |
| @@ -9037,59 +8952,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9037 | keybuf with its symbol, or if the sequence starts with a mouse | 8952 | keybuf with its symbol, or if the sequence starts with a mouse |
| 9038 | click and we need to switch buffers, we jump back here to rebuild | 8953 | click and we need to switch buffers, we jump back here to rebuild |
| 9039 | the initial keymaps from the current buffer. */ | 8954 | the initial keymaps from the current buffer. */ |
| 9040 | nmaps = 0; | 8955 | current_binding = active_maps (first_event); |
| 9041 | |||
| 9042 | if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) | ||
| 9043 | { | ||
| 9044 | if (2 > nmaps_allocated) | ||
| 9045 | { | ||
| 9046 | submaps = alloca (2 * sizeof *submaps); | ||
| 9047 | defs = alloca (2 * sizeof *defs); | ||
| 9048 | nmaps_allocated = 2; | ||
| 9049 | } | ||
| 9050 | submaps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map); | ||
| 9051 | } | ||
| 9052 | else if (!NILP (Voverriding_local_map)) | ||
| 9053 | { | ||
| 9054 | if (2 > nmaps_allocated) | ||
| 9055 | { | ||
| 9056 | submaps = alloca (2 * sizeof *submaps); | ||
| 9057 | defs = alloca (2 * sizeof *defs); | ||
| 9058 | nmaps_allocated = 2; | ||
| 9059 | } | ||
| 9060 | submaps[nmaps++] = Voverriding_local_map; | ||
| 9061 | } | ||
| 9062 | else | ||
| 9063 | { | ||
| 9064 | ptrdiff_t nminor; | ||
| 9065 | ptrdiff_t total; | ||
| 9066 | Lisp_Object *maps; | ||
| 9067 | |||
| 9068 | nminor = current_minor_maps (0, &maps); | ||
| 9069 | total = nminor + (!NILP (orig_keymap) ? 3 : 2); | ||
| 9070 | |||
| 9071 | if (total > nmaps_allocated) | ||
| 9072 | { | ||
| 9073 | submaps = alloca (total * sizeof *submaps); | ||
| 9074 | defs = alloca (total * sizeof *defs); | ||
| 9075 | nmaps_allocated = total; | ||
| 9076 | } | ||
| 9077 | |||
| 9078 | if (!NILP (orig_keymap)) | ||
| 9079 | submaps[nmaps++] = orig_keymap; | ||
| 9080 | |||
| 9081 | memcpy (submaps + nmaps, maps, nminor * sizeof (submaps[0])); | ||
| 9082 | |||
| 9083 | nmaps += nminor; | ||
| 9084 | |||
| 9085 | submaps[nmaps++] = orig_local_map; | ||
| 9086 | } | ||
| 9087 | submaps[nmaps++] = current_global_map; | ||
| 9088 | |||
| 9089 | /* Find an accurate initial value for first_binding. */ | ||
| 9090 | for (first_binding = 0; first_binding < nmaps; first_binding++) | ||
| 9091 | if (! NILP (submaps[first_binding])) | ||
| 9092 | break; | ||
| 9093 | 8956 | ||
| 9094 | /* Start from the beginning in keybuf. */ | 8957 | /* Start from the beginning in keybuf. */ |
| 9095 | t = 0; | 8958 | t = 0; |
| @@ -9103,9 +8966,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9103 | /* If the best binding for the current key sequence is a keymap, or | 8966 | /* If the best binding for the current key sequence is a keymap, or |
| 9104 | we may be looking at a function key's escape sequence, keep on | 8967 | we may be looking at a function key's escape sequence, keep on |
| 9105 | reading. */ | 8968 | reading. */ |
| 9106 | while (first_binding < nmaps | 8969 | while (!NILP (current_binding) |
| 9107 | /* Keep reading as long as there's a prefix binding. */ | 8970 | /* Keep reading as long as there's a prefix binding. */ |
| 9108 | ? !NILP (submaps[first_binding]) | 8971 | ? KEYMAPP (current_binding) |
| 9109 | /* Don't return in the middle of a possible function key sequence, | 8972 | /* Don't return in the middle of a possible function key sequence, |
| 9110 | if the only bindings we found were via case conversion. | 8973 | if the only bindings we found were via case conversion. |
| 9111 | Thus, if ESC O a has a function-key-map translation | 8974 | Thus, if ESC O a has a function-key-map translation |
| @@ -9129,7 +8992,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9129 | just one key. */ | 8992 | just one key. */ |
| 9130 | ptrdiff_t echo_local_start IF_LINT (= 0); | 8993 | ptrdiff_t echo_local_start IF_LINT (= 0); |
| 9131 | int keys_local_start; | 8994 | int keys_local_start; |
| 9132 | ptrdiff_t local_first_binding; | 8995 | Lisp_Object new_binding; |
| 9133 | 8996 | ||
| 9134 | eassert (indec.end == t || (indec.end > t && indec.end <= mock_input)); | 8997 | eassert (indec.end == t || (indec.end > t && indec.end <= mock_input)); |
| 9135 | eassert (indec.start <= indec.end); | 8998 | eassert (indec.start <= indec.end); |
| @@ -9166,7 +9029,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9166 | if (INTERACTIVE) | 9029 | if (INTERACTIVE) |
| 9167 | echo_local_start = echo_length (); | 9030 | echo_local_start = echo_length (); |
| 9168 | keys_local_start = this_command_key_count; | 9031 | keys_local_start = this_command_key_count; |
| 9169 | local_first_binding = first_binding; | ||
| 9170 | 9032 | ||
| 9171 | replay_key: | 9033 | replay_key: |
| 9172 | /* These are no-ops, unless we throw away a keystroke below and | 9034 | /* These are no-ops, unless we throw away a keystroke below and |
| @@ -9176,7 +9038,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9176 | if (INTERACTIVE && t < mock_input) | 9038 | if (INTERACTIVE && t < mock_input) |
| 9177 | echo_truncate (echo_local_start); | 9039 | echo_truncate (echo_local_start); |
| 9178 | this_command_key_count = keys_local_start; | 9040 | this_command_key_count = keys_local_start; |
| 9179 | first_binding = local_first_binding; | ||
| 9180 | 9041 | ||
| 9181 | /* By default, assume each event is "real". */ | 9042 | /* By default, assume each event is "real". */ |
| 9182 | last_real_key_start = t; | 9043 | last_real_key_start = t; |
| @@ -9187,8 +9048,12 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9187 | key = keybuf[t]; | 9048 | key = keybuf[t]; |
| 9188 | add_command_key (key); | 9049 | add_command_key (key); |
| 9189 | if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) | 9050 | if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) |
| 9190 | && NILP (Fzerop (Vecho_keystrokes))) | 9051 | && NILP (Fzerop (Vecho_keystrokes)) |
| 9191 | echo_char (key); | 9052 | && current_kboard->immediate_echo) |
| 9053 | { | ||
| 9054 | echo_add_key (key); | ||
| 9055 | echo_dash (); | ||
| 9056 | } | ||
| 9192 | } | 9057 | } |
| 9193 | 9058 | ||
| 9194 | /* If not, we should actually read a character. */ | 9059 | /* If not, we should actually read a character. */ |
| @@ -9197,8 +9062,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9197 | { | 9062 | { |
| 9198 | KBOARD *interrupted_kboard = current_kboard; | 9063 | KBOARD *interrupted_kboard = current_kboard; |
| 9199 | struct frame *interrupted_frame = SELECTED_FRAME (); | 9064 | struct frame *interrupted_frame = SELECTED_FRAME (); |
| 9200 | key = read_char (NILP (prompt), nmaps, | 9065 | key = read_char (NILP (prompt), |
| 9201 | (Lisp_Object *) submaps, last_nonmenu_event, | 9066 | current_binding, last_nonmenu_event, |
| 9202 | &used_mouse_menu, NULL); | 9067 | &used_mouse_menu, NULL); |
| 9203 | if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ | 9068 | if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ |
| 9204 | /* When switching to a new tty (with a new keyboard), | 9069 | /* When switching to a new tty (with a new keyboard), |
| @@ -9253,8 +9118,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9253 | KVAR (interrupted_kboard, kbd_queue))); | 9118 | KVAR (interrupted_kboard, kbd_queue))); |
| 9254 | } | 9119 | } |
| 9255 | mock_input = 0; | 9120 | mock_input = 0; |
| 9256 | orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); | ||
| 9257 | orig_keymap = get_local_map (PT, current_buffer, Qkeymap); | ||
| 9258 | goto replay_entire_sequence; | 9121 | goto replay_entire_sequence; |
| 9259 | } | 9122 | } |
| 9260 | } | 9123 | } |
| @@ -9295,12 +9158,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9295 | { | 9158 | { |
| 9296 | if (! FRAME_LIVE_P (XFRAME (selected_frame))) | 9159 | if (! FRAME_LIVE_P (XFRAME (selected_frame))) |
| 9297 | Fkill_emacs (Qnil); | 9160 | Fkill_emacs (Qnil); |
| 9298 | if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) | 9161 | if (XBUFFER (XWINDOW (selected_window)->buffer) |
| 9162 | != current_buffer) | ||
| 9299 | Fset_buffer (XWINDOW (selected_window)->buffer); | 9163 | Fset_buffer (XWINDOW (selected_window)->buffer); |
| 9300 | } | 9164 | } |
| 9301 | 9165 | ||
| 9302 | orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); | ||
| 9303 | orig_keymap = get_local_map (PT, current_buffer, Qkeymap); | ||
| 9304 | goto replay_sequence; | 9166 | goto replay_sequence; |
| 9305 | } | 9167 | } |
| 9306 | 9168 | ||
| @@ -9317,8 +9179,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9317 | keybuf[t++] = key; | 9179 | keybuf[t++] = key; |
| 9318 | mock_input = t; | 9180 | mock_input = t; |
| 9319 | Vquit_flag = Qnil; | 9181 | Vquit_flag = Qnil; |
| 9320 | orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); | ||
| 9321 | orig_keymap = get_local_map (PT, current_buffer, Qkeymap); | ||
| 9322 | goto replay_sequence; | 9182 | goto replay_sequence; |
| 9323 | } | 9183 | } |
| 9324 | 9184 | ||
| @@ -9338,6 +9198,22 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9338 | } | 9198 | } |
| 9339 | } | 9199 | } |
| 9340 | 9200 | ||
| 9201 | if (NILP (first_event)) | ||
| 9202 | { | ||
| 9203 | first_event = key; | ||
| 9204 | /* Even if first_event does not specify a particular | ||
| 9205 | window/position, it's important to recompute the maps here | ||
| 9206 | since a long time might have passed since we entered | ||
| 9207 | read_key_sequence, and a timer (or process-filter or | ||
| 9208 | special-event-map, ...) might have switched the current buffer | ||
| 9209 | or the selected window from under us in the mean time. */ | ||
| 9210 | if (fix_current_buffer | ||
| 9211 | && (XBUFFER (XWINDOW (selected_window)->buffer) | ||
| 9212 | != current_buffer)) | ||
| 9213 | Fset_buffer (XWINDOW (selected_window)->buffer); | ||
| 9214 | current_binding = active_maps (first_event); | ||
| 9215 | } | ||
| 9216 | |||
| 9341 | GROW_RAW_KEYBUF; | 9217 | GROW_RAW_KEYBUF; |
| 9342 | ASET (raw_keybuf, raw_keybuf_count, key); | 9218 | ASET (raw_keybuf, raw_keybuf_count, key); |
| 9343 | raw_keybuf_count++; | 9219 | raw_keybuf_count++; |
| @@ -9359,16 +9235,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9359 | or when user programs play with this-command-keys. */ | 9235 | or when user programs play with this-command-keys. */ |
| 9360 | if (EVENT_HAS_PARAMETERS (key)) | 9236 | if (EVENT_HAS_PARAMETERS (key)) |
| 9361 | { | 9237 | { |
| 9362 | Lisp_Object kind; | 9238 | Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); |
| 9363 | Lisp_Object string; | ||
| 9364 | |||
| 9365 | kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); | ||
| 9366 | if (EQ (kind, Qmouse_click)) | 9239 | if (EQ (kind, Qmouse_click)) |
| 9367 | { | 9240 | { |
| 9368 | Lisp_Object window, posn; | 9241 | Lisp_Object window = POSN_WINDOW (EVENT_START (key)); |
| 9369 | 9242 | Lisp_Object posn = POSN_POSN (EVENT_START (key)); | |
| 9370 | window = POSN_WINDOW (EVENT_START (key)); | ||
| 9371 | posn = POSN_POSN (EVENT_START (key)); | ||
| 9372 | 9243 | ||
| 9373 | if (CONSP (posn) | 9244 | if (CONSP (posn) |
| 9374 | || (!NILP (fake_prefixed_keys) | 9245 | || (!NILP (fake_prefixed_keys) |
| @@ -9411,58 +9282,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9411 | if (! FRAME_LIVE_P (XFRAME (selected_frame))) | 9282 | if (! FRAME_LIVE_P (XFRAME (selected_frame))) |
| 9412 | Fkill_emacs (Qnil); | 9283 | Fkill_emacs (Qnil); |
| 9413 | set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); | 9284 | set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); |
| 9414 | orig_local_map = get_local_map (PT, current_buffer, | ||
| 9415 | Qlocal_map); | ||
| 9416 | orig_keymap = get_local_map (PT, current_buffer, | ||
| 9417 | Qkeymap); | ||
| 9418 | goto replay_sequence; | 9285 | goto replay_sequence; |
| 9419 | } | 9286 | } |
| 9420 | |||
| 9421 | /* For a mouse click, get the local text-property keymap | ||
| 9422 | of the place clicked on, rather than point. */ | ||
| 9423 | if (CONSP (XCDR (key)) | ||
| 9424 | && ! localized_local_map) | ||
| 9425 | { | ||
| 9426 | Lisp_Object map_here, start, pos; | ||
| 9427 | |||
| 9428 | localized_local_map = 1; | ||
| 9429 | start = EVENT_START (key); | ||
| 9430 | |||
| 9431 | if (CONSP (start) && POSN_INBUFFER_P (start)) | ||
| 9432 | { | ||
| 9433 | pos = POSN_BUFFER_POSN (start); | ||
| 9434 | if (INTEGERP (pos) | ||
| 9435 | && XINT (pos) >= BEGV | ||
| 9436 | && XINT (pos) <= ZV) | ||
| 9437 | { | ||
| 9438 | map_here = get_local_map (XINT (pos), | ||
| 9439 | current_buffer, | ||
| 9440 | Qlocal_map); | ||
| 9441 | if (!EQ (map_here, orig_local_map)) | ||
| 9442 | { | ||
| 9443 | orig_local_map = map_here; | ||
| 9444 | ++localized_local_map; | ||
| 9445 | } | ||
| 9446 | |||
| 9447 | map_here = get_local_map (XINT (pos), | ||
| 9448 | current_buffer, | ||
| 9449 | Qkeymap); | ||
| 9450 | if (!EQ (map_here, orig_keymap)) | ||
| 9451 | { | ||
| 9452 | orig_keymap = map_here; | ||
| 9453 | ++localized_local_map; | ||
| 9454 | } | ||
| 9455 | |||
| 9456 | if (localized_local_map > 1) | ||
| 9457 | { | ||
| 9458 | keybuf[t] = key; | ||
| 9459 | mock_input = t + 1; | ||
| 9460 | |||
| 9461 | goto replay_sequence; | ||
| 9462 | } | ||
| 9463 | } | ||
| 9464 | } | ||
| 9465 | } | ||
| 9466 | } | 9287 | } |
| 9467 | 9288 | ||
| 9468 | /* Expand mode-line and scroll-bar events into two events: | 9289 | /* Expand mode-line and scroll-bar events into two events: |
| @@ -9483,63 +9304,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9483 | prevent proper action when the event is pushed | 9304 | prevent proper action when the event is pushed |
| 9484 | back into unread-command-events. */ | 9305 | back into unread-command-events. */ |
| 9485 | fake_prefixed_keys = Fcons (key, fake_prefixed_keys); | 9306 | fake_prefixed_keys = Fcons (key, fake_prefixed_keys); |
| 9486 | |||
| 9487 | /* If on a mode line string with a local keymap, | ||
| 9488 | reconsider the key sequence with that keymap. */ | ||
| 9489 | if (string = POSN_STRING (EVENT_START (key)), | ||
| 9490 | (CONSP (string) && STRINGP (XCAR (string)))) | ||
| 9491 | { | ||
| 9492 | Lisp_Object pos, map, map2; | ||
| 9493 | |||
| 9494 | pos = XCDR (string); | ||
| 9495 | string = XCAR (string); | ||
| 9496 | if (XINT (pos) >= 0 | ||
| 9497 | && XINT (pos) < SCHARS (string)) | ||
| 9498 | { | ||
| 9499 | map = Fget_text_property (pos, Qlocal_map, string); | ||
| 9500 | if (!NILP (map)) | ||
| 9501 | orig_local_map = map; | ||
| 9502 | map2 = Fget_text_property (pos, Qkeymap, string); | ||
| 9503 | if (!NILP (map2)) | ||
| 9504 | orig_keymap = map2; | ||
| 9505 | if (!NILP (map) || !NILP (map2)) | ||
| 9506 | goto replay_sequence; | ||
| 9507 | } | ||
| 9508 | } | ||
| 9509 | |||
| 9510 | goto replay_key; | 9307 | goto replay_key; |
| 9511 | } | 9308 | } |
| 9512 | else if (NILP (from_string) | ||
| 9513 | && (string = POSN_STRING (EVENT_START (key)), | ||
| 9514 | (CONSP (string) && STRINGP (XCAR (string))))) | ||
| 9515 | { | ||
| 9516 | /* For a click on a string, i.e. overlay string or a | ||
| 9517 | string displayed via the `display' property, | ||
| 9518 | consider `local-map' and `keymap' properties of | ||
| 9519 | that string. */ | ||
| 9520 | Lisp_Object pos, map, map2; | ||
| 9521 | |||
| 9522 | pos = XCDR (string); | ||
| 9523 | string = XCAR (string); | ||
| 9524 | if (XINT (pos) >= 0 | ||
| 9525 | && XINT (pos) < SCHARS (string)) | ||
| 9526 | { | ||
| 9527 | map = Fget_text_property (pos, Qlocal_map, string); | ||
| 9528 | if (!NILP (map)) | ||
| 9529 | orig_local_map = map; | ||
| 9530 | map2 = Fget_text_property (pos, Qkeymap, string); | ||
| 9531 | if (!NILP (map2)) | ||
| 9532 | orig_keymap = map2; | ||
| 9533 | |||
| 9534 | if (!NILP (map) || !NILP (map2)) | ||
| 9535 | { | ||
| 9536 | from_string = string; | ||
| 9537 | keybuf[t++] = key; | ||
| 9538 | mock_input = t; | ||
| 9539 | goto replay_sequence; | ||
| 9540 | } | ||
| 9541 | } | ||
| 9542 | } | ||
| 9543 | } | 9309 | } |
| 9544 | else if (CONSP (XCDR (key)) | 9310 | else if (CONSP (XCDR (key)) |
| 9545 | && CONSP (EVENT_START (key)) | 9311 | && CONSP (EVENT_START (key)) |
| @@ -9555,7 +9321,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9555 | if (bufsize - t <= 1) | 9321 | if (bufsize - t <= 1) |
| 9556 | error ("Key sequence too long"); | 9322 | error ("Key sequence too long"); |
| 9557 | keybuf[t] = posn; | 9323 | keybuf[t] = posn; |
| 9558 | keybuf[t+1] = key; | 9324 | keybuf[t + 1] = key; |
| 9559 | 9325 | ||
| 9560 | /* Zap the position in key, so we know that we've | 9326 | /* Zap the position in key, so we know that we've |
| 9561 | expanded it, and don't try to do so again. */ | 9327 | expanded it, and don't try to do so again. */ |
| @@ -9578,15 +9344,10 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9578 | 9344 | ||
| 9579 | /* We have finally decided that KEY is something we might want | 9345 | /* We have finally decided that KEY is something we might want |
| 9580 | to look up. */ | 9346 | to look up. */ |
| 9581 | first_binding = (follow_key (key, | 9347 | new_binding = follow_key (current_binding, key); |
| 9582 | nmaps - first_binding, | ||
| 9583 | submaps + first_binding, | ||
| 9584 | defs + first_binding, | ||
| 9585 | submaps + first_binding) | ||
| 9586 | + first_binding); | ||
| 9587 | 9348 | ||
| 9588 | /* If KEY wasn't bound, we'll try some fallbacks. */ | 9349 | /* If KEY wasn't bound, we'll try some fallbacks. */ |
| 9589 | if (first_binding < nmaps) | 9350 | if (!NILP (new_binding)) |
| 9590 | /* This is needed for the following scenario: | 9351 | /* This is needed for the following scenario: |
| 9591 | event 0: a down-event that gets dropped by calling replay_key. | 9352 | event 0: a down-event that gets dropped by calling replay_key. |
| 9592 | event 1: some normal prefix like C-h. | 9353 | event 1: some normal prefix like C-h. |
| @@ -9723,20 +9484,13 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9723 | new_click | 9484 | new_click |
| 9724 | = Fcons (new_head, Fcons (EVENT_START (key), Qnil)); | 9485 | = Fcons (new_head, Fcons (EVENT_START (key), Qnil)); |
| 9725 | 9486 | ||
| 9726 | /* Look for a binding for this new key. follow_key | 9487 | /* Look for a binding for this new key. */ |
| 9727 | promises that it didn't munge submaps the | 9488 | new_binding = follow_key (current_binding, new_click); |
| 9728 | last time we called it, since key was unbound. */ | ||
| 9729 | first_binding | ||
| 9730 | = (follow_key (new_click, | ||
| 9731 | nmaps - local_first_binding, | ||
| 9732 | submaps + local_first_binding, | ||
| 9733 | defs + local_first_binding, | ||
| 9734 | submaps + local_first_binding) | ||
| 9735 | + local_first_binding); | ||
| 9736 | 9489 | ||
| 9737 | /* If that click is bound, go for it. */ | 9490 | /* If that click is bound, go for it. */ |
| 9738 | if (first_binding < nmaps) | 9491 | if (!NILP (new_binding)) |
| 9739 | { | 9492 | { |
| 9493 | current_binding = new_binding; | ||
| 9740 | key = new_click; | 9494 | key = new_click; |
| 9741 | break; | 9495 | break; |
| 9742 | } | 9496 | } |
| @@ -9745,6 +9499,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9745 | } | 9499 | } |
| 9746 | } | 9500 | } |
| 9747 | } | 9501 | } |
| 9502 | current_binding = new_binding; | ||
| 9748 | 9503 | ||
| 9749 | keybuf[t++] = key; | 9504 | keybuf[t++] = key; |
| 9750 | /* Normally, last_nonmenu_event gets the previous key we read. | 9505 | /* Normally, last_nonmenu_event gets the previous key we read. |
| @@ -9776,9 +9531,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9776 | } | 9531 | } |
| 9777 | } | 9532 | } |
| 9778 | 9533 | ||
| 9779 | if (first_binding < nmaps | 9534 | if (!KEYMAPP (current_binding) |
| 9780 | && NILP (submaps[first_binding]) | 9535 | && !test_undefined (current_binding) |
| 9781 | && !test_undefined (defs[first_binding]) | ||
| 9782 | && indec.start >= t) | 9536 | && indec.start >= t) |
| 9783 | /* There is a binding and it's not a prefix. | 9537 | /* There is a binding and it's not a prefix. |
| 9784 | (and it doesn't have any input-decode-map translation pending). | 9538 | (and it doesn't have any input-decode-map translation pending). |
| @@ -9807,8 +9561,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9807 | first_binding >= nmaps) we don't want | 9561 | first_binding >= nmaps) we don't want |
| 9808 | to apply this function-key-mapping. */ | 9562 | to apply this function-key-mapping. */ |
| 9809 | fkey.end + 1 == t | 9563 | fkey.end + 1 == t |
| 9810 | && (first_binding >= nmaps | 9564 | && (test_undefined (current_binding)), |
| 9811 | || test_undefined (defs[first_binding])), | ||
| 9812 | &diff, prompt); | 9565 | &diff, prompt); |
| 9813 | UNGCPRO; | 9566 | UNGCPRO; |
| 9814 | if (done) | 9567 | if (done) |
| @@ -9851,7 +9604,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9851 | and cannot be part of a function key or translation, | 9604 | and cannot be part of a function key or translation, |
| 9852 | and is an upper case letter | 9605 | and is an upper case letter |
| 9853 | use the corresponding lower-case letter instead. */ | 9606 | use the corresponding lower-case letter instead. */ |
| 9854 | if (first_binding >= nmaps | 9607 | if (NILP (current_binding) |
| 9855 | && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t | 9608 | && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t |
| 9856 | && INTEGERP (key) | 9609 | && INTEGERP (key) |
| 9857 | && ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK)) | 9610 | && ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK)) |
| @@ -9882,7 +9635,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9882 | and cannot be part of a function key or translation, | 9635 | and cannot be part of a function key or translation, |
| 9883 | and is a shifted function key, | 9636 | and is a shifted function key, |
| 9884 | use the corresponding unshifted function key instead. */ | 9637 | use the corresponding unshifted function key instead. */ |
| 9885 | if (first_binding >= nmaps | 9638 | if (NILP (current_binding) |
| 9886 | && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t) | 9639 | && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t) |
| 9887 | { | 9640 | { |
| 9888 | Lisp_Object breakdown = parse_modifiers (key); | 9641 | Lisp_Object breakdown = parse_modifiers (key); |
| @@ -9923,9 +9676,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9923 | } | 9676 | } |
| 9924 | } | 9677 | } |
| 9925 | if (!dummyflag) | 9678 | if (!dummyflag) |
| 9926 | read_key_sequence_cmd = (first_binding < nmaps | 9679 | read_key_sequence_cmd = current_binding; |
| 9927 | ? defs[first_binding] | ||
| 9928 | : Qnil); | ||
| 9929 | read_key_sequence_remapped | 9680 | read_key_sequence_remapped |
| 9930 | /* Remap command through active keymaps. | 9681 | /* Remap command through active keymaps. |
| 9931 | Do the remapping here, before the unbind_to so it uses the keymaps | 9682 | Do the remapping here, before the unbind_to so it uses the keymaps |
| @@ -9939,7 +9690,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9939 | 9690 | ||
| 9940 | /* Don't downcase the last character if the caller says don't. | 9691 | /* Don't downcase the last character if the caller says don't. |
| 9941 | Don't downcase it if the result is undefined, either. */ | 9692 | Don't downcase it if the result is undefined, either. */ |
| 9942 | if ((dont_downcase_last || first_binding >= nmaps) | 9693 | if ((dont_downcase_last || NILP (current_binding)) |
| 9943 | && t > 0 | 9694 | && t > 0 |
| 9944 | && t - 1 == original_uppercase_position) | 9695 | && t - 1 == original_uppercase_position) |
| 9945 | { | 9696 | { |
| @@ -10036,7 +9787,7 @@ will read just one key sequence. */) | |||
| 10036 | 9787 | ||
| 10037 | memset (keybuf, 0, sizeof keybuf); | 9788 | memset (keybuf, 0, sizeof keybuf); |
| 10038 | GCPRO1 (keybuf[0]); | 9789 | GCPRO1 (keybuf[0]); |
| 10039 | gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0])); | 9790 | gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0])); |
| 10040 | 9791 | ||
| 10041 | if (NILP (continue_echo)) | 9792 | if (NILP (continue_echo)) |
| 10042 | { | 9793 | { |
| @@ -10050,7 +9801,7 @@ will read just one key sequence. */) | |||
| 10050 | cancel_hourglass (); | 9801 | cancel_hourglass (); |
| 10051 | #endif | 9802 | #endif |
| 10052 | 9803 | ||
| 10053 | i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])), | 9804 | i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), |
| 10054 | prompt, ! NILP (dont_downcase_last), | 9805 | prompt, ! NILP (dont_downcase_last), |
| 10055 | ! NILP (can_return_switch_frame), 0); | 9806 | ! NILP (can_return_switch_frame), 0); |
| 10056 | 9807 | ||
| @@ -10129,7 +9880,7 @@ DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0, | |||
| 10129 | doc: /* Execute CMD as an editor command. | 9880 | doc: /* Execute CMD as an editor command. |
| 10130 | CMD must be a symbol that satisfies the `commandp' predicate. | 9881 | CMD must be a symbol that satisfies the `commandp' predicate. |
| 10131 | Optional second arg RECORD-FLAG non-nil | 9882 | Optional second arg RECORD-FLAG non-nil |
| 10132 | means unconditionally put this command in `command-history'. | 9883 | means unconditionally put this command in the variable `command-history'. |
| 10133 | Otherwise, that is done only if an arg is read using the minibuffer. | 9884 | Otherwise, that is done only if an arg is read using the minibuffer. |
| 10134 | The argument KEYS specifies the value to use instead of (this-command-keys) | 9885 | The argument KEYS specifies the value to use instead of (this-command-keys) |
| 10135 | when reading the arguments; if it is nil, (this-command-keys) is used. | 9886 | when reading the arguments; if it is nil, (this-command-keys) is used. |
| @@ -11333,10 +11084,18 @@ syms_of_keyboard (void) | |||
| 11333 | DEFSYM (Qlanguage_change, "language-change"); | 11084 | DEFSYM (Qlanguage_change, "language-change"); |
| 11334 | #endif | 11085 | #endif |
| 11335 | 11086 | ||
| 11087 | #ifdef WINDOWSNT | ||
| 11088 | DEFSYM (Qfile_w32notify, "file-w32notify"); | ||
| 11089 | #endif | ||
| 11090 | |||
| 11336 | #ifdef HAVE_DBUS | 11091 | #ifdef HAVE_DBUS |
| 11337 | DEFSYM (Qdbus_event, "dbus-event"); | 11092 | DEFSYM (Qdbus_event, "dbus-event"); |
| 11338 | #endif | 11093 | #endif |
| 11339 | 11094 | ||
| 11095 | #ifdef HAVE_INOTIFY | ||
| 11096 | DEFSYM (Qfile_inotify, "file-inotify"); | ||
| 11097 | #endif /* HAVE_INOTIFY */ | ||
| 11098 | |||
| 11340 | DEFSYM (QCenable, ":enable"); | 11099 | DEFSYM (QCenable, ":enable"); |
| 11341 | DEFSYM (QCvisible, ":visible"); | 11100 | DEFSYM (QCvisible, ":visible"); |
| 11342 | DEFSYM (QChelp, ":help"); | 11101 | DEFSYM (QChelp, ":help"); |
| @@ -11634,10 +11393,6 @@ This variable is also the threshold for motion of the mouse | |||
| 11634 | to count as a drag. */); | 11393 | to count as a drag. */); |
| 11635 | double_click_fuzz = 3; | 11394 | double_click_fuzz = 3; |
| 11636 | 11395 | ||
| 11637 | DEFVAR_BOOL ("inhibit-local-menu-bar-menus", inhibit_local_menu_bar_menus, | ||
| 11638 | doc: /* Non-nil means inhibit local map menu bar menus. */); | ||
| 11639 | inhibit_local_menu_bar_menus = 0; | ||
| 11640 | |||
| 11641 | DEFVAR_INT ("num-input-keys", num_input_keys, | 11396 | DEFVAR_INT ("num-input-keys", num_input_keys, |
| 11642 | doc: /* Number of complete key sequences read as input so far. | 11397 | doc: /* Number of complete key sequences read as input so far. |
| 11643 | This includes key sequences read from keyboard macros. | 11398 | This includes key sequences read from keyboard macros. |
| @@ -11865,9 +11620,7 @@ If the binding is a function, it is called with one argument (the prompt) | |||
| 11865 | and its return value (a key sequence) is used. | 11620 | and its return value (a key sequence) is used. |
| 11866 | 11621 | ||
| 11867 | The events that come from bindings in `input-decode-map' are not | 11622 | The events that come from bindings in `input-decode-map' are not |
| 11868 | themselves looked up in `input-decode-map'. | 11623 | themselves looked up in `input-decode-map'. */); |
| 11869 | |||
| 11870 | This variable is keyboard-local. */); | ||
| 11871 | 11624 | ||
| 11872 | DEFVAR_LISP ("function-key-map", Vfunction_key_map, | 11625 | DEFVAR_LISP ("function-key-map", Vfunction_key_map, |
| 11873 | doc: /* The parent keymap of all `local-function-key-map' instances. | 11626 | doc: /* The parent keymap of all `local-function-key-map' instances. |
| @@ -11879,9 +11632,8 @@ definition will take precedence. */); | |||
| 11879 | 11632 | ||
| 11880 | DEFVAR_LISP ("key-translation-map", Vkey_translation_map, | 11633 | DEFVAR_LISP ("key-translation-map", Vkey_translation_map, |
| 11881 | doc: /* Keymap of key translations that can override keymaps. | 11634 | doc: /* Keymap of key translations that can override keymaps. |
| 11882 | This keymap works like `function-key-map', but comes after that, | 11635 | This keymap works like `input-decode-map', but comes after `function-key-map'. |
| 11883 | and its non-prefix bindings override ordinary bindings. | 11636 | Another difference is that it is global rather than terminal-local. */); |
| 11884 | Another difference is that it is global rather than keyboard-local. */); | ||
| 11885 | Vkey_translation_map = Fmake_sparse_keymap (Qnil); | 11637 | Vkey_translation_map = Fmake_sparse_keymap (Qnil); |
| 11886 | 11638 | ||
| 11887 | DEFVAR_LISP ("deferred-action-list", Vdeferred_action_list, | 11639 | DEFVAR_LISP ("deferred-action-list", Vdeferred_action_list, |
| @@ -12006,8 +11758,8 @@ This takes effect only when Transient Mark mode is enabled. */); | |||
| 12006 | Vsaved_region_selection, | 11758 | Vsaved_region_selection, |
| 12007 | doc: /* Contents of active region prior to buffer modification. | 11759 | doc: /* Contents of active region prior to buffer modification. |
| 12008 | If `select-active-regions' is non-nil, Emacs sets this to the | 11760 | If `select-active-regions' is non-nil, Emacs sets this to the |
| 12009 | text in the region before modifying the buffer. The next | 11761 | text in the region before modifying the buffer. The next call to |
| 12010 | `deactivate-mark' call uses this to set the window selection. */); | 11762 | the function `deactivate-mark' uses this to set the window selection. */); |
| 12011 | Vsaved_region_selection = Qnil; | 11763 | Vsaved_region_selection = Qnil; |
| 12012 | 11764 | ||
| 12013 | DEFVAR_LISP ("selection-inhibit-update-commands", | 11765 | DEFVAR_LISP ("selection-inhibit-update-commands", |
| @@ -12093,11 +11845,20 @@ keys_of_keyboard (void) | |||
| 12093 | "dbus-handle-event"); | 11845 | "dbus-handle-event"); |
| 12094 | #endif | 11846 | #endif |
| 12095 | 11847 | ||
| 11848 | #ifdef HAVE_INOTIFY | ||
| 11849 | /* Define a special event which is raised for inotify callback | ||
| 11850 | functions. */ | ||
| 11851 | initial_define_lispy_key (Vspecial_event_map, "file-inotify", | ||
| 11852 | "inotify-handle-event"); | ||
| 11853 | #endif /* HAVE_INOTIFY */ | ||
| 11854 | |||
| 12096 | initial_define_lispy_key (Vspecial_event_map, "config-changed-event", | 11855 | initial_define_lispy_key (Vspecial_event_map, "config-changed-event", |
| 12097 | "ignore"); | 11856 | "ignore"); |
| 12098 | #if defined (WINDOWSNT) | 11857 | #if defined (WINDOWSNT) |
| 12099 | initial_define_lispy_key (Vspecial_event_map, "language-change", | 11858 | initial_define_lispy_key (Vspecial_event_map, "language-change", |
| 12100 | "ignore"); | 11859 | "ignore"); |
| 11860 | initial_define_lispy_key (Vspecial_event_map, "file-w32notify", | ||
| 11861 | "w32notify-handle-event"); | ||
| 12101 | #endif | 11862 | #endif |
| 12102 | } | 11863 | } |
| 12103 | 11864 | ||
diff --git a/src/keyboard.h b/src/keyboard.h index e57c8cc7193..c6ade35dd52 100644 --- a/src/keyboard.h +++ b/src/keyboard.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Declarations useful when processing input. | 1 | /* Declarations useful when processing input. |
| 2 | Copyright (C) 1985-1987, 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1987, 1993, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -481,7 +482,7 @@ struct input_event; | |||
| 481 | 482 | ||
| 482 | extern Lisp_Object parse_modifiers (Lisp_Object); | 483 | extern Lisp_Object parse_modifiers (Lisp_Object); |
| 483 | extern Lisp_Object reorder_modifiers (Lisp_Object); | 484 | extern Lisp_Object reorder_modifiers (Lisp_Object); |
| 484 | extern Lisp_Object read_char (int, ptrdiff_t, Lisp_Object *, Lisp_Object, | 485 | extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object, |
| 485 | bool *, EMACS_TIME *); | 486 | bool *, EMACS_TIME *); |
| 486 | extern int parse_solitary_modifier (Lisp_Object symbol); | 487 | extern int parse_solitary_modifier (Lisp_Object symbol); |
| 487 | 488 | ||
diff --git a/src/keymap.c b/src/keymap.c index fbdd31e0de3..922c1703edf 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Manipulation of keymaps | 1 | /* Manipulation of keymaps |
| 2 | Copyright (C) 1985-1988, 1993-1995, 1998-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1988, 1993-1995, 1998-2013 Free Software |
| 3 | Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -564,15 +565,13 @@ map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val) | |||
| 564 | { | 565 | { |
| 565 | if (!NILP (val)) | 566 | if (!NILP (val)) |
| 566 | { | 567 | { |
| 567 | map_keymap_function_t fun | 568 | map_keymap_function_t fun = XSAVE_POINTER (args, 0); |
| 568 | = (map_keymap_function_t) XSAVE_VALUE (XCAR (args))->pointer; | ||
| 569 | args = XCDR (args); | ||
| 570 | /* If the key is a range, make a copy since map_char_table modifies | 569 | /* If the key is a range, make a copy since map_char_table modifies |
| 571 | it in place. */ | 570 | it in place. */ |
| 572 | if (CONSP (key)) | 571 | if (CONSP (key)) |
| 573 | key = Fcons (XCAR (key), XCDR (key)); | 572 | key = Fcons (XCAR (key), XCDR (key)); |
| 574 | map_keymap_item (fun, XCDR (args), key, val, | 573 | map_keymap_item (fun, XSAVE_OBJECT (args, 2), key, |
| 575 | XSAVE_VALUE (XCAR (args))->pointer); | 574 | val, XSAVE_POINTER (args, 1)); |
| 576 | } | 575 | } |
| 577 | } | 576 | } |
| 578 | 577 | ||
| @@ -610,12 +609,8 @@ map_keymap_internal (Lisp_Object map, | |||
| 610 | } | 609 | } |
| 611 | } | 610 | } |
| 612 | else if (CHAR_TABLE_P (binding)) | 611 | else if (CHAR_TABLE_P (binding)) |
| 613 | { | 612 | map_char_table (map_keymap_char_table_item, Qnil, binding, |
| 614 | map_char_table (map_keymap_char_table_item, Qnil, binding, | 613 | make_save_value ("ppo", fun, data, args)); |
| 615 | Fcons (make_save_value ((void *) fun, 0), | ||
| 616 | Fcons (make_save_value (data, 0), | ||
| 617 | args))); | ||
| 618 | } | ||
| 619 | } | 614 | } |
| 620 | UNGCPRO; | 615 | UNGCPRO; |
| 621 | return tail; | 616 | return tail; |
| @@ -1249,7 +1244,7 @@ remapping in all currently active keymaps. */) | |||
| 1249 | return INTEGERP (command) ? Qnil : command; | 1244 | return INTEGERP (command) ? Qnil : command; |
| 1250 | } | 1245 | } |
| 1251 | 1246 | ||
| 1252 | /* Value is number if KEY is too long; nil if valid but has no definition. */ | 1247 | /* Value is number if KEY is too long; nil if valid but has no definition. */ |
| 1253 | /* GC is possible in this function. */ | 1248 | /* GC is possible in this function. */ |
| 1254 | 1249 | ||
| 1255 | DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0, | 1250 | DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0, |
| @@ -1541,7 +1536,7 @@ DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps, | |||
| 1541 | doc: /* Return a list of the currently active keymaps. | 1536 | doc: /* Return a list of the currently active keymaps. |
| 1542 | OLP if non-nil indicates that we should obey `overriding-local-map' and | 1537 | OLP if non-nil indicates that we should obey `overriding-local-map' and |
| 1543 | `overriding-terminal-local-map'. POSITION can specify a click position | 1538 | `overriding-terminal-local-map'. POSITION can specify a click position |
| 1544 | like in the respective argument of `key-binding'. */) | 1539 | like in the respective argument of `key-binding'. */) |
| 1545 | (Lisp_Object olp, Lisp_Object position) | 1540 | (Lisp_Object olp, Lisp_Object position) |
| 1546 | { | 1541 | { |
| 1547 | ptrdiff_t count = SPECPDL_INDEX (); | 1542 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -1550,7 +1545,7 @@ like in the respective argument of `key-binding'. */) | |||
| 1550 | 1545 | ||
| 1551 | /* If a mouse click position is given, our variables are based on | 1546 | /* If a mouse click position is given, our variables are based on |
| 1552 | the buffer clicked on, not the current buffer. So we may have to | 1547 | the buffer clicked on, not the current buffer. So we may have to |
| 1553 | switch the buffer here. */ | 1548 | switch the buffer here. */ |
| 1554 | 1549 | ||
| 1555 | if (CONSP (position)) | 1550 | if (CONSP (position)) |
| 1556 | { | 1551 | { |
| @@ -2047,7 +2042,7 @@ DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0, | |||
| 2047 | Optional arg PREFIX is the sequence of keys leading up to KEYS. | 2042 | Optional arg PREFIX is the sequence of keys leading up to KEYS. |
| 2048 | For example, [?\C-x ?l] is converted into the string \"C-x l\". | 2043 | For example, [?\C-x ?l] is converted into the string \"C-x l\". |
| 2049 | 2044 | ||
| 2050 | The `kbd' macro is an approximate inverse of this. */) | 2045 | For an approximate inverse of this, see `kbd'. */) |
| 2051 | (Lisp_Object keys, Lisp_Object prefix) | 2046 | (Lisp_Object keys, Lisp_Object prefix) |
| 2052 | { | 2047 | { |
| 2053 | ptrdiff_t len = 0; | 2048 | ptrdiff_t len = 0; |
diff --git a/src/keymap.h b/src/keymap.h index c704ee0b050..eca0f1b4108 100644 --- a/src/keymap.h +++ b/src/keymap.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Functions to manipulate keymaps. | 1 | /* Functions to manipulate keymaps. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/lastfile.c b/src/lastfile.c index f8a64797362..019a6a99763 100644 --- a/src/lastfile.c +++ b/src/lastfile.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Mark end of data space to dump as pure, for GNU Emacs. | 1 | /* Mark end of data space to dump as pure, for GNU Emacs. |
| 2 | Copyright (C) 1985, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/lisp.h b/src/lisp.h index 91fc3dfa1c6..44a5bd571ff 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Fundamental definitions for GNU Emacs Lisp interpreter. | 1 | /* Fundamental definitions for GNU Emacs Lisp interpreter. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1987, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1987, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -226,7 +227,7 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; | |||
| 226 | 227 | ||
| 227 | /* Lisp integers use 2 tags, to give them one extra bit, thus | 228 | /* Lisp integers use 2 tags, to give them one extra bit, thus |
| 228 | extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ | 229 | extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ |
| 229 | static EMACS_INT const INTMASK = EMACS_INT_MAX >> (INTTYPEBITS - 1); | 230 | #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) |
| 230 | #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 | 231 | #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 |
| 231 | #define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) | 232 | #define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) |
| 232 | 233 | ||
| @@ -325,6 +326,10 @@ enum Lisp_Fwd_Type | |||
| 325 | members that are accessible only from C. A Lisp_Misc object is a | 326 | members that are accessible only from C. A Lisp_Misc object is a |
| 326 | wrapper for a C struct that can contain anything you like. | 327 | wrapper for a C struct that can contain anything you like. |
| 327 | 328 | ||
| 329 | Explicit freeing is discouraged for Lisp objects in general. But if | ||
| 330 | you really need to exploit this, use Lisp_Misc (check free_misc in | ||
| 331 | alloc.c to see why). There is no way to free a vectorlike object. | ||
| 332 | |||
| 328 | To add a new pseudovector type, extend the pvec_type enumeration; | 333 | To add a new pseudovector type, extend the pvec_type enumeration; |
| 329 | to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration. | 334 | to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration. |
| 330 | 335 | ||
| @@ -334,6 +339,10 @@ enum Lisp_Fwd_Type | |||
| 334 | enumeration and a 1-bit GC markbit) and make sure the overall size | 339 | enumeration and a 1-bit GC markbit) and make sure the overall size |
| 335 | of the union is not increased by your addition. | 340 | of the union is not increased by your addition. |
| 336 | 341 | ||
| 342 | For a new pseudovector, it's highly desirable to limit the size | ||
| 343 | of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c). | ||
| 344 | Otherwise you will need to change sweep_vectors (also in alloc.c). | ||
| 345 | |||
| 337 | Then you will need to add switch branches in print.c (in | 346 | Then you will need to add switch branches in print.c (in |
| 338 | print_object, to print your object, and possibly also in | 347 | print_object, to print your object, and possibly also in |
| 339 | print_preprocess) and to alloc.c, to mark your object (in | 348 | print_preprocess) and to alloc.c, to mark your object (in |
| @@ -496,13 +505,9 @@ static EMACS_INT const VALMASK | |||
| 496 | (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ | 505 | (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ |
| 497 | + ((intptr_t) (ptr) & VALMASK))) | 506 | + ((intptr_t) (ptr) & VALMASK))) |
| 498 | 507 | ||
| 499 | #if DATA_SEG_BITS | ||
| 500 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers | 508 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers |
| 501 | which were stored in a Lisp_Object. */ | 509 | which were stored in a Lisp_Object. */ |
| 502 | #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) | 510 | #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) |
| 503 | #else | ||
| 504 | #define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK)) | ||
| 505 | #endif | ||
| 506 | 511 | ||
| 507 | #endif /* not USE_LSB_TAG */ | 512 | #endif /* not USE_LSB_TAG */ |
| 508 | 513 | ||
| @@ -1295,6 +1300,14 @@ sxhash_combine (EMACS_UINT x, EMACS_UINT y) | |||
| 1295 | return (x << 4) + (x >> (BITS_PER_EMACS_INT - 4)) + y; | 1300 | return (x << 4) + (x >> (BITS_PER_EMACS_INT - 4)) + y; |
| 1296 | } | 1301 | } |
| 1297 | 1302 | ||
| 1303 | /* Hash X, returning a value that fits into a fixnum. */ | ||
| 1304 | |||
| 1305 | LISP_INLINE EMACS_UINT | ||
| 1306 | SXHASH_REDUCE (EMACS_UINT x) | ||
| 1307 | { | ||
| 1308 | return (x ^ x >> (BITS_PER_EMACS_INT - FIXNUM_BITS)) & INTMASK; | ||
| 1309 | } | ||
| 1310 | |||
| 1298 | /* These structures are used for various misc types. */ | 1311 | /* These structures are used for various misc types. */ |
| 1299 | 1312 | ||
| 1300 | struct Lisp_Misc_Any /* Supertype of all Misc types. */ | 1313 | struct Lisp_Misc_Any /* Supertype of all Misc types. */ |
| @@ -1369,20 +1382,103 @@ struct Lisp_Overlay | |||
| 1369 | Lisp_Object plist; | 1382 | Lisp_Object plist; |
| 1370 | }; | 1383 | }; |
| 1371 | 1384 | ||
| 1372 | /* Hold a C pointer for later use. | 1385 | /* Types of data which may be saved in a Lisp_Save_Value. */ |
| 1373 | This type of object is used in the arg to record_unwind_protect. */ | 1386 | |
| 1387 | enum | ||
| 1388 | { | ||
| 1389 | SAVE_UNUSED, | ||
| 1390 | SAVE_INTEGER, | ||
| 1391 | SAVE_POINTER, | ||
| 1392 | SAVE_OBJECT | ||
| 1393 | }; | ||
| 1394 | |||
| 1395 | /* Special object used to hold a different values for later use. | ||
| 1396 | |||
| 1397 | This is mostly used to package C integers and pointers to call | ||
| 1398 | record_unwind_protect. Typical task is to pass just one C pointer | ||
| 1399 | to unwind function. You should pack pointer with make_save_pointer | ||
| 1400 | and then get it back with XSAVE_POINTER, e.g.: | ||
| 1401 | |||
| 1402 | ... | ||
| 1403 | struct my_data *md = get_my_data (); | ||
| 1404 | record_unwind_protect (my_unwind, make_save_pointer (md)); | ||
| 1405 | ... | ||
| 1406 | |||
| 1407 | Lisp_Object my_unwind (Lisp_Object arg) | ||
| 1408 | { | ||
| 1409 | struct my_data *md = XSAVE_POINTER (arg, 0); | ||
| 1410 | ... | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | If yon need to pass more than just one C pointer, you should | ||
| 1414 | use make_save_value. This function allows you to pack up to | ||
| 1415 | 4 integers, pointers or Lisp_Objects and conveniently get them | ||
| 1416 | back with XSAVE_POINTER, XSAVE_INTEGER and XSAVE_OBJECT macros: | ||
| 1417 | |||
| 1418 | ... | ||
| 1419 | struct my_data *md = get_my_data (); | ||
| 1420 | ptrdiff_t my_offset = get_my_offset (); | ||
| 1421 | Lisp_Object my_object = get_my_object (); | ||
| 1422 | record_unwind_protect | ||
| 1423 | (my_unwind, make_save_value ("pio", md, my_offset, my_object)); | ||
| 1424 | ... | ||
| 1425 | |||
| 1426 | Lisp_Object my_unwind (Lisp_Object arg) | ||
| 1427 | { | ||
| 1428 | struct my_data *md = XSAVE_POINTER (arg, 0); | ||
| 1429 | ptrdiff_t my_offset = XSAVE_INTEGER (arg, 1); | ||
| 1430 | Lisp_Object my_object = XSAVE_OBJECT (arg, 2); | ||
| 1431 | ... | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the | ||
| 1435 | saved objects and raise eassert if type of the saved object doesn't match | ||
| 1436 | the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) | ||
| 1437 | or XSAVE_OBJECT (arg, 1) are wrong because integer was saved in slot 1 and | ||
| 1438 | Lisp_Object was saved in slot 2 of ARG. */ | ||
| 1439 | |||
| 1374 | struct Lisp_Save_Value | 1440 | struct Lisp_Save_Value |
| 1375 | { | 1441 | { |
| 1376 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ | 1442 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ |
| 1377 | unsigned gcmarkbit : 1; | 1443 | unsigned gcmarkbit : 1; |
| 1378 | int spacer : 14; | 1444 | int spacer : 6; |
| 1379 | /* If DOGC is set, POINTER is the address of a memory | 1445 | /* If `area' is nonzero, `data[0].pointer' is the address of a memory area |
| 1380 | area containing INTEGER potential Lisp_Objects. */ | 1446 | containing `data[1].integer' potential Lisp_Objects. The rest of `data' |
| 1381 | unsigned int dogc : 1; | 1447 | fields are unused. */ |
| 1382 | void *pointer; | 1448 | unsigned area : 1; |
| 1383 | ptrdiff_t integer; | 1449 | /* If `area' is zero, `data[N]' may hold different objects which type is |
| 1450 | encoded in `typeN' fields as described by the anonymous enum above. | ||
| 1451 | E.g. if `type0' is SAVE_INTEGER, `data[0].integer' is in use. */ | ||
| 1452 | unsigned type0 : 2; | ||
| 1453 | unsigned type1 : 2; | ||
| 1454 | unsigned type2 : 2; | ||
| 1455 | unsigned type3 : 2; | ||
| 1456 | union { | ||
| 1457 | void *pointer; | ||
| 1458 | ptrdiff_t integer; | ||
| 1459 | Lisp_Object object; | ||
| 1460 | } data[4]; | ||
| 1384 | }; | 1461 | }; |
| 1385 | 1462 | ||
| 1463 | /* Macro to set and extract Nth saved pointer. Type | ||
| 1464 | checking is ugly because it's used as an lvalue. */ | ||
| 1465 | |||
| 1466 | #define XSAVE_POINTER(obj, n) \ | ||
| 1467 | XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \ | ||
| 1468 | ## n == SAVE_POINTER), n)].pointer | ||
| 1469 | |||
| 1470 | /* Likewise for the saved integer. */ | ||
| 1471 | |||
| 1472 | #define XSAVE_INTEGER(obj, n) \ | ||
| 1473 | XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \ | ||
| 1474 | ## n == SAVE_INTEGER), n)].integer | ||
| 1475 | |||
| 1476 | /* Macro to extract Nth saved object. This is never used as | ||
| 1477 | an lvalue, so we can do more convenient type checking. */ | ||
| 1478 | |||
| 1479 | #define XSAVE_OBJECT(obj, n) \ | ||
| 1480 | (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \ | ||
| 1481 | XSAVE_VALUE (obj)->data[n].object) | ||
| 1386 | 1482 | ||
| 1387 | /* A miscellaneous object, when it's on the free list. */ | 1483 | /* A miscellaneous object, when it's on the free list. */ |
| 1388 | struct Lisp_Free | 1484 | struct Lisp_Free |
| @@ -1441,7 +1537,8 @@ struct Lisp_Buffer_Objfwd | |||
| 1441 | { | 1537 | { |
| 1442 | enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Buffer_Obj */ | 1538 | enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Buffer_Obj */ |
| 1443 | int offset; | 1539 | int offset; |
| 1444 | Lisp_Object slottype; /* Qnil, Lisp_Int, Lisp_Symbol, or Lisp_String. */ | 1540 | /* One of Qnil, Qintegerp, Qsymbolp, Qstringp, Qfloatp or Qnumberp. */ |
| 1541 | Lisp_Object predicate; | ||
| 1445 | }; | 1542 | }; |
| 1446 | 1543 | ||
| 1447 | /* struct Lisp_Buffer_Local_Value is used in a symbol value cell when | 1544 | /* struct Lisp_Buffer_Local_Value is used in a symbol value cell when |
| @@ -2207,8 +2304,12 @@ struct gcpro | |||
| 2207 | 2 Mark the stack, and check that everything GCPRO'd is | 2304 | 2 Mark the stack, and check that everything GCPRO'd is |
| 2208 | marked. | 2305 | marked. |
| 2209 | 3 Mark using GCPRO's, mark stack last, and count how many | 2306 | 3 Mark using GCPRO's, mark stack last, and count how many |
| 2210 | dead objects are kept alive. */ | 2307 | dead objects are kept alive. |
| 2211 | 2308 | ||
| 2309 | Formerly, method 0 was used. Currently, method 1 is used unless | ||
| 2310 | otherwise specified by hand when building, e.g., | ||
| 2311 | "make CPPFLAGS='-DGC_MARK_STACK=GC_USE_GCPROS_AS_BEFORE'". | ||
| 2312 | Methods 2 and 3 are present mainly to debug the transition from 0 to 1. */ | ||
| 2212 | 2313 | ||
| 2213 | #define GC_USE_GCPROS_AS_BEFORE 0 | 2314 | #define GC_USE_GCPROS_AS_BEFORE 0 |
| 2214 | #define GC_MAKE_GCPROS_NOOPS 1 | 2315 | #define GC_MAKE_GCPROS_NOOPS 1 |
| @@ -2765,10 +2866,10 @@ extern void syms_of_image (void); | |||
| 2765 | 2866 | ||
| 2766 | /* Defined in insdel.c. */ | 2867 | /* Defined in insdel.c. */ |
| 2767 | extern Lisp_Object Qinhibit_modification_hooks; | 2868 | extern Lisp_Object Qinhibit_modification_hooks; |
| 2768 | extern void move_gap (ptrdiff_t); | ||
| 2769 | extern void move_gap_both (ptrdiff_t, ptrdiff_t); | 2869 | extern void move_gap_both (ptrdiff_t, ptrdiff_t); |
| 2770 | extern _Noreturn void buffer_overflow (void); | 2870 | extern _Noreturn void buffer_overflow (void); |
| 2771 | extern void make_gap (ptrdiff_t); | 2871 | extern void make_gap (ptrdiff_t); |
| 2872 | extern void make_gap_1 (struct buffer *, ptrdiff_t); | ||
| 2772 | extern ptrdiff_t copy_text (const unsigned char *, unsigned char *, | 2873 | extern ptrdiff_t copy_text (const unsigned char *, unsigned char *, |
| 2773 | ptrdiff_t, bool, bool); | 2874 | ptrdiff_t, bool, bool); |
| 2774 | extern int count_combining_before (const unsigned char *, | 2875 | extern int count_combining_before (const unsigned char *, |
| @@ -2777,7 +2878,6 @@ extern int count_combining_after (const unsigned char *, | |||
| 2777 | ptrdiff_t, ptrdiff_t, ptrdiff_t); | 2878 | ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 2778 | extern void insert (const char *, ptrdiff_t); | 2879 | extern void insert (const char *, ptrdiff_t); |
| 2779 | extern void insert_and_inherit (const char *, ptrdiff_t); | 2880 | extern void insert_and_inherit (const char *, ptrdiff_t); |
| 2780 | extern void insert_1 (const char *, ptrdiff_t, bool, bool, bool); | ||
| 2781 | extern void insert_1_both (const char *, ptrdiff_t, ptrdiff_t, | 2881 | extern void insert_1_both (const char *, ptrdiff_t, ptrdiff_t, |
| 2782 | bool, bool, bool); | 2882 | bool, bool, bool); |
| 2783 | extern void insert_from_gap (ptrdiff_t, ptrdiff_t); | 2883 | extern void insert_from_gap (ptrdiff_t, ptrdiff_t); |
| @@ -2851,11 +2951,9 @@ extern void clear_message (int, int); | |||
| 2851 | extern void message (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); | 2951 | extern void message (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); |
| 2852 | extern void message1 (const char *); | 2952 | extern void message1 (const char *); |
| 2853 | extern void message1_nolog (const char *); | 2953 | extern void message1_nolog (const char *); |
| 2854 | extern void message2 (const char *, ptrdiff_t, int); | 2954 | extern void message3 (Lisp_Object); |
| 2855 | extern void message2_nolog (const char *, ptrdiff_t, int); | 2955 | extern void message3_nolog (Lisp_Object); |
| 2856 | extern void message3 (Lisp_Object, ptrdiff_t, int); | 2956 | extern void message_dolog (const char *, ptrdiff_t, bool, bool); |
| 2857 | extern void message3_nolog (Lisp_Object, ptrdiff_t, int); | ||
| 2858 | extern void message_dolog (const char *, ptrdiff_t, int, int); | ||
| 2859 | extern void message_with_string (const char *, Lisp_Object, int); | 2957 | extern void message_with_string (const char *, Lisp_Object, int); |
| 2860 | extern void message_log_maybe_newline (void); | 2958 | extern void message_log_maybe_newline (void); |
| 2861 | extern void update_echo_area (void); | 2959 | extern void update_echo_area (void); |
| @@ -2879,6 +2977,7 @@ extern void memory_warnings (void *, void (*warnfun) (const char *)); | |||
| 2879 | 2977 | ||
| 2880 | /* Defined in alloc.c. */ | 2978 | /* Defined in alloc.c. */ |
| 2881 | extern void check_pure_size (void); | 2979 | extern void check_pure_size (void); |
| 2980 | extern void free_misc (Lisp_Object); | ||
| 2882 | extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); | 2981 | extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); |
| 2883 | extern void malloc_warning (const char *); | 2982 | extern void malloc_warning (const char *); |
| 2884 | extern _Noreturn void memory_full (size_t); | 2983 | extern _Noreturn void memory_full (size_t); |
| @@ -2948,6 +3047,27 @@ extern void make_byte_code (struct Lisp_Vector *); | |||
| 2948 | extern Lisp_Object Qautomatic_gc; | 3047 | extern Lisp_Object Qautomatic_gc; |
| 2949 | extern Lisp_Object Qchar_table_extra_slots; | 3048 | extern Lisp_Object Qchar_table_extra_slots; |
| 2950 | extern struct Lisp_Vector *allocate_vector (EMACS_INT); | 3049 | extern struct Lisp_Vector *allocate_vector (EMACS_INT); |
| 3050 | |||
| 3051 | /* Make an unitialized vector for SIZE objects. NOTE: you must | ||
| 3052 | be sure that GC cannot happen until the vector is completely | ||
| 3053 | initialized. E.g. the following code is likely to crash: | ||
| 3054 | |||
| 3055 | v = make_uninit_vector (3); | ||
| 3056 | ASET (v, 0, obj0); | ||
| 3057 | ASET (v, 1, Ffunction_can_gc ()); | ||
| 3058 | ASET (v, 2, obj1); */ | ||
| 3059 | |||
| 3060 | LISP_INLINE Lisp_Object | ||
| 3061 | make_uninit_vector (ptrdiff_t size) | ||
| 3062 | { | ||
| 3063 | Lisp_Object v; | ||
| 3064 | struct Lisp_Vector *p; | ||
| 3065 | |||
| 3066 | p = allocate_vector (size); | ||
| 3067 | XSETVECTOR (v, p); | ||
| 3068 | return v; | ||
| 3069 | } | ||
| 3070 | |||
| 2951 | extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type); | 3071 | extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type); |
| 2952 | #define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ | 3072 | #define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ |
| 2953 | ((typ*) \ | 3073 | ((typ*) \ |
| @@ -2963,8 +3083,8 @@ extern bool abort_on_gc; | |||
| 2963 | extern Lisp_Object make_float (double); | 3083 | extern Lisp_Object make_float (double); |
| 2964 | extern void display_malloc_warning (void); | 3084 | extern void display_malloc_warning (void); |
| 2965 | extern ptrdiff_t inhibit_garbage_collection (void); | 3085 | extern ptrdiff_t inhibit_garbage_collection (void); |
| 2966 | extern Lisp_Object make_save_value (void *, ptrdiff_t); | 3086 | extern Lisp_Object make_save_value (const char *, ...); |
| 2967 | extern void free_save_value (Lisp_Object); | 3087 | extern Lisp_Object make_save_pointer (void *); |
| 2968 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); | 3088 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); |
| 2969 | extern void free_marker (Lisp_Object); | 3089 | extern void free_marker (Lisp_Object); |
| 2970 | extern void free_cons (struct Lisp_Cons *); | 3090 | extern void free_cons (struct Lisp_Cons *); |
| @@ -3176,7 +3296,6 @@ extern void keys_of_buffer (void); | |||
| 3176 | extern ptrdiff_t marker_position (Lisp_Object); | 3296 | extern ptrdiff_t marker_position (Lisp_Object); |
| 3177 | extern ptrdiff_t marker_byte_position (Lisp_Object); | 3297 | extern ptrdiff_t marker_byte_position (Lisp_Object); |
| 3178 | extern void clear_charpos_cache (struct buffer *); | 3298 | extern void clear_charpos_cache (struct buffer *); |
| 3179 | extern ptrdiff_t charpos_to_bytepos (ptrdiff_t); | ||
| 3180 | extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); | 3299 | extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); |
| 3181 | extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); | 3300 | extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); |
| 3182 | extern void unchain_marker (struct Lisp_Marker *marker); | 3301 | extern void unchain_marker (struct Lisp_Marker *marker); |
| @@ -3199,9 +3318,11 @@ EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ | |||
| 3199 | extern Lisp_Object close_file_unwind (Lisp_Object); | 3318 | extern Lisp_Object close_file_unwind (Lisp_Object); |
| 3200 | extern Lisp_Object restore_point_unwind (Lisp_Object); | 3319 | extern Lisp_Object restore_point_unwind (Lisp_Object); |
| 3201 | extern _Noreturn void report_file_error (const char *, Lisp_Object); | 3320 | extern _Noreturn void report_file_error (const char *, Lisp_Object); |
| 3202 | extern void internal_delete_file (Lisp_Object); | 3321 | extern bool internal_delete_file (Lisp_Object); |
| 3322 | extern Lisp_Object emacs_readlinkat (int, const char *); | ||
| 3203 | extern bool file_directory_p (const char *); | 3323 | extern bool file_directory_p (const char *); |
| 3204 | extern bool file_accessible_directory_p (const char *); | 3324 | extern bool file_accessible_directory_p (const char *); |
| 3325 | extern void init_fileio (void); | ||
| 3205 | extern void syms_of_fileio (void); | 3326 | extern void syms_of_fileio (void); |
| 3206 | extern Lisp_Object make_temp_name (Lisp_Object, bool); | 3327 | extern Lisp_Object make_temp_name (Lisp_Object, bool); |
| 3207 | extern Lisp_Object Qdelete_file; | 3328 | extern Lisp_Object Qdelete_file; |
| @@ -3214,15 +3335,15 @@ extern void record_unwind_save_match_data (void); | |||
| 3214 | struct re_registers; | 3335 | struct re_registers; |
| 3215 | extern struct re_pattern_buffer *compile_pattern (Lisp_Object, | 3336 | extern struct re_pattern_buffer *compile_pattern (Lisp_Object, |
| 3216 | struct re_registers *, | 3337 | struct re_registers *, |
| 3217 | Lisp_Object, int, int); | 3338 | Lisp_Object, int, bool); |
| 3218 | extern ptrdiff_t fast_string_match (Lisp_Object, Lisp_Object); | 3339 | extern ptrdiff_t fast_string_match (Lisp_Object, Lisp_Object); |
| 3219 | extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *, | 3340 | extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *, |
| 3220 | ptrdiff_t); | 3341 | ptrdiff_t); |
| 3221 | extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); | 3342 | extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); |
| 3222 | extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, | 3343 | extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 3223 | ptrdiff_t, ptrdiff_t, Lisp_Object); | 3344 | ptrdiff_t, ptrdiff_t, Lisp_Object); |
| 3224 | extern ptrdiff_t scan_buffer (int, ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3345 | extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3225 | ptrdiff_t *, bool); | 3346 | ptrdiff_t *, bool); |
| 3226 | extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3347 | extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3227 | EMACS_INT, bool); | 3348 | EMACS_INT, bool); |
| 3228 | extern ptrdiff_t find_next_newline (ptrdiff_t, int); | 3349 | extern ptrdiff_t find_next_newline (ptrdiff_t, int); |
| @@ -3452,6 +3573,8 @@ extern void init_sigio (int); | |||
| 3452 | extern void sys_subshell (void); | 3573 | extern void sys_subshell (void); |
| 3453 | extern void sys_suspend (void); | 3574 | extern void sys_suspend (void); |
| 3454 | extern void discard_tty_input (void); | 3575 | extern void discard_tty_input (void); |
| 3576 | extern void block_tty_out_signal (void); | ||
| 3577 | extern void unblock_tty_out_signal (void); | ||
| 3455 | extern void init_sys_modes (struct tty_display_info *); | 3578 | extern void init_sys_modes (struct tty_display_info *); |
| 3456 | extern void reset_sys_modes (struct tty_display_info *); | 3579 | extern void reset_sys_modes (struct tty_display_info *); |
| 3457 | extern void init_all_sys_modes (void); | 3580 | extern void init_all_sys_modes (void); |
| @@ -3469,8 +3592,6 @@ extern int emacs_open (const char *, int, int); | |||
| 3469 | extern int emacs_close (int); | 3592 | extern int emacs_close (int); |
| 3470 | extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); | 3593 | extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); |
| 3471 | extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); | 3594 | extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); |
| 3472 | enum { READLINK_BUFSIZE = 1024 }; | ||
| 3473 | extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]); | ||
| 3474 | 3595 | ||
| 3475 | extern void unlock_all_files (void); | 3596 | extern void unlock_all_files (void); |
| 3476 | extern void lock_file (Lisp_Object); | 3597 | extern void lock_file (Lisp_Object); |
| @@ -3516,6 +3637,16 @@ extern void syms_of_fontset (void); | |||
| 3516 | extern Lisp_Object Qfont_param; | 3637 | extern Lisp_Object Qfont_param; |
| 3517 | #endif | 3638 | #endif |
| 3518 | 3639 | ||
| 3640 | #ifdef WINDOWSNT | ||
| 3641 | /* Defined on w32notify.c. */ | ||
| 3642 | extern void syms_of_w32notify (void); | ||
| 3643 | #endif | ||
| 3644 | |||
| 3645 | /* Defined in inotify.c */ | ||
| 3646 | #ifdef HAVE_INOTIFY | ||
| 3647 | extern void syms_of_inotify (void); | ||
| 3648 | #endif | ||
| 3649 | |||
| 3519 | /* Defined in xfaces.c. */ | 3650 | /* Defined in xfaces.c. */ |
| 3520 | extern Lisp_Object Qdefault, Qtool_bar, Qfringe; | 3651 | extern Lisp_Object Qdefault, Qtool_bar, Qfringe; |
| 3521 | extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; | 3652 | extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; |
| @@ -3601,12 +3732,11 @@ extern char *egetenv (const char *); | |||
| 3601 | /* Set up the name of the machine we're running on. */ | 3732 | /* Set up the name of the machine we're running on. */ |
| 3602 | extern void init_system_name (void); | 3733 | extern void init_system_name (void); |
| 3603 | 3734 | ||
| 3604 | /* We used to use `abs', but that clashes with system headers on some | 3735 | /* Return the absolute value of X. X should be a signed integer |
| 3605 | platforms, and using a name reserved by Standard C is a bad idea | 3736 | expression without side effects, and X's absolute value should not |
| 3606 | anyway. */ | 3737 | exceed the maximum for its promoted type. This is called 'eabs' |
| 3607 | #if !defined (eabs) | 3738 | because 'abs' is reserved by the C standard. */ |
| 3608 | #define eabs(x) ((x) < 0 ? -(x) : (x)) | 3739 | #define eabs(x) ((x) < 0 ? -(x) : (x)) |
| 3609 | #endif | ||
| 3610 | 3740 | ||
| 3611 | /* Return a fixnum or float, depending on whether VAL fits in a Lisp | 3741 | /* Return a fixnum or float, depending on whether VAL fits in a Lisp |
| 3612 | fixnum. */ | 3742 | fixnum. */ |
| @@ -3635,16 +3765,16 @@ extern void *record_xmalloc (size_t); | |||
| 3635 | NITEMS items, each of the same type as *BUF. MULTIPLIER must | 3765 | NITEMS items, each of the same type as *BUF. MULTIPLIER must |
| 3636 | positive. The code is tuned for MULTIPLIER being a constant. */ | 3766 | positive. The code is tuned for MULTIPLIER being a constant. */ |
| 3637 | 3767 | ||
| 3638 | #define SAFE_NALLOCA(buf, multiplier, nitems) \ | 3768 | #define SAFE_NALLOCA(buf, multiplier, nitems) \ |
| 3639 | do { \ | 3769 | do { \ |
| 3640 | if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ | 3770 | if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ |
| 3641 | (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ | 3771 | (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ |
| 3642 | else \ | 3772 | else \ |
| 3643 | { \ | 3773 | { \ |
| 3644 | (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ | 3774 | (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ |
| 3645 | sa_must_free = 1; \ | 3775 | sa_must_free = 1; \ |
| 3646 | record_unwind_protect (safe_alloca_unwind, \ | 3776 | record_unwind_protect (safe_alloca_unwind, \ |
| 3647 | make_save_value (buf, 0)); \ | 3777 | make_save_pointer (buf)); \ |
| 3648 | } \ | 3778 | } \ |
| 3649 | } while (0) | 3779 | } while (0) |
| 3650 | 3780 | ||
| @@ -3669,8 +3799,8 @@ extern void *record_xmalloc (size_t); | |||
| 3669 | { \ | 3799 | { \ |
| 3670 | Lisp_Object arg_; \ | 3800 | Lisp_Object arg_; \ |
| 3671 | buf = xmalloc ((nelt) * word_size); \ | 3801 | buf = xmalloc ((nelt) * word_size); \ |
| 3672 | arg_ = make_save_value (buf, nelt); \ | 3802 | arg_ = make_save_value ("pi", buf, nelt); \ |
| 3673 | XSAVE_VALUE (arg_)->dogc = 1; \ | 3803 | XSAVE_VALUE (arg_)->area = 1; \ |
| 3674 | sa_must_free = 1; \ | 3804 | sa_must_free = 1; \ |
| 3675 | record_unwind_protect (safe_alloca_unwind, arg_); \ | 3805 | record_unwind_protect (safe_alloca_unwind, arg_); \ |
| 3676 | } \ | 3806 | } \ |
diff --git a/src/lisp.mk b/src/lisp.mk index 8c2710110e3..174e53ed561 100644 --- a/src/lisp.mk +++ b/src/lisp.mk | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ### lisp.mk --- src/Makefile fragment for GNU Emacs | 1 | ### lisp.mk --- src/Makefile fragment for GNU Emacs |
| 2 | 2 | ||
| 3 | ## Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2012 | 3 | ## Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2013 Free Software |
| 4 | ## Free Software Foundation, Inc. | 4 | ## Foundation, Inc. |
| 5 | 5 | ||
| 6 | ## This file is part of GNU Emacs. | 6 | ## This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/lread.c b/src/lread.c index 6647382a254..e7af86aa664 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Lisp parsing and input streams. | 1 | /* Lisp parsing and input streams. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1989, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -95,11 +96,6 @@ static Lisp_Object Qload_in_progress; | |||
| 95 | It must be set to nil before all top-level calls to read0. */ | 96 | It must be set to nil before all top-level calls to read0. */ |
| 96 | static Lisp_Object read_objects; | 97 | static Lisp_Object read_objects; |
| 97 | 98 | ||
| 98 | /* True means READCHAR should read bytes one by one (not character) | ||
| 99 | when READCHARFUN is Qget_file_char or Qget_emacs_mule_file_char. | ||
| 100 | This is set by read1 temporarily while handling #@NUMBER. */ | ||
| 101 | static bool load_each_byte; | ||
| 102 | |||
| 103 | /* List of descriptors now open for Fload. */ | 99 | /* List of descriptors now open for Fload. */ |
| 104 | static Lisp_Object load_descriptor_list; | 100 | static Lisp_Object load_descriptor_list; |
| 105 | 101 | ||
| @@ -327,7 +323,7 @@ readchar (Lisp_Object readcharfun, bool *multibyte) | |||
| 327 | return c; | 323 | return c; |
| 328 | } | 324 | } |
| 329 | c = (*readbyte) (-1, readcharfun); | 325 | c = (*readbyte) (-1, readcharfun); |
| 330 | if (c < 0 || load_each_byte) | 326 | if (c < 0) |
| 331 | return c; | 327 | return c; |
| 332 | if (multibyte) | 328 | if (multibyte) |
| 333 | *multibyte = 1; | 329 | *multibyte = 1; |
| @@ -352,6 +348,30 @@ readchar (Lisp_Object readcharfun, bool *multibyte) | |||
| 352 | return STRING_CHAR (buf); | 348 | return STRING_CHAR (buf); |
| 353 | } | 349 | } |
| 354 | 350 | ||
| 351 | static void | ||
| 352 | skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n) | ||
| 353 | { | ||
| 354 | if (EQ (readcharfun, Qget_file_char) | ||
| 355 | || EQ (readcharfun, Qget_emacs_mule_file_char)) | ||
| 356 | { | ||
| 357 | block_input (); /* FIXME: Not sure if it's needed. */ | ||
| 358 | fseek (instream, n, SEEK_CUR); | ||
| 359 | unblock_input (); | ||
| 360 | } | ||
| 361 | else | ||
| 362 | { /* We're not reading directly from a file. In that case, it's difficult | ||
| 363 | to reliably count bytes, since these are usually meant for the file's | ||
| 364 | encoding, whereas we're now typically in the internal encoding. | ||
| 365 | But luckily, skip_dyn_bytes is used to skip over a single | ||
| 366 | dynamic-docstring (or dynamic byte-code) which is always quoted such | ||
| 367 | that \037 is the final char. */ | ||
| 368 | int c; | ||
| 369 | do { | ||
| 370 | c = READCHAR; | ||
| 371 | } while (c >= 0 && c != '\037'); | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 355 | /* Unread the character C in the way appropriate for the stream READCHARFUN. | 375 | /* Unread the character C in the way appropriate for the stream READCHARFUN. |
| 356 | If the stream is a user function, call it with the char as argument. */ | 376 | If the stream is a user function, call it with the char as argument. */ |
| 357 | 377 | ||
| @@ -406,14 +426,7 @@ unreadchar (Lisp_Object readcharfun, int c) | |||
| 406 | else if (EQ (readcharfun, Qget_file_char) | 426 | else if (EQ (readcharfun, Qget_file_char) |
| 407 | || EQ (readcharfun, Qget_emacs_mule_file_char)) | 427 | || EQ (readcharfun, Qget_emacs_mule_file_char)) |
| 408 | { | 428 | { |
| 409 | if (load_each_byte) | 429 | unread_char = c; |
| 410 | { | ||
| 411 | block_input (); | ||
| 412 | ungetc (c, instream); | ||
| 413 | unblock_input (); | ||
| 414 | } | ||
| 415 | else | ||
| 416 | unread_char = c; | ||
| 417 | } | 430 | } |
| 418 | else | 431 | else |
| 419 | call1 (readcharfun, make_number (c)); | 432 | call1 (readcharfun, make_number (c)); |
| @@ -601,17 +614,17 @@ read_filtered_event (bool no_switch_frame, bool ascii_required, | |||
| 601 | end_time = add_emacs_time (current_emacs_time (), wait_time); | 614 | end_time = add_emacs_time (current_emacs_time (), wait_time); |
| 602 | } | 615 | } |
| 603 | 616 | ||
| 604 | /* Read until we get an acceptable event. */ | 617 | /* Read until we get an acceptable event. */ |
| 605 | retry: | 618 | retry: |
| 606 | do | 619 | do |
| 607 | val = read_char (0, 0, 0, (input_method ? Qnil : Qt), 0, | 620 | val = read_char (0, Qnil, (input_method ? Qnil : Qt), 0, |
| 608 | NUMBERP (seconds) ? &end_time : NULL); | 621 | NUMBERP (seconds) ? &end_time : NULL); |
| 609 | while (INTEGERP (val) && XINT (val) == -2); /* wrong_kboard_jmpbuf */ | 622 | while (INTEGERP (val) && XINT (val) == -2); /* wrong_kboard_jmpbuf */ |
| 610 | 623 | ||
| 611 | if (BUFFERP (val)) | 624 | if (BUFFERP (val)) |
| 612 | goto retry; | 625 | goto retry; |
| 613 | 626 | ||
| 614 | /* switch-frame events are put off until after the next ASCII | 627 | /* `switch-frame' events are put off until after the next ASCII |
| 615 | character. This is better than signaling an error just because | 628 | character. This is better than signaling an error just because |
| 616 | the last characters were typed to a separate minibuffer frame, | 629 | the last characters were typed to a separate minibuffer frame, |
| 617 | for example. Eventually, some code which can deal with | 630 | for example. Eventually, some code which can deal with |
| @@ -1297,7 +1310,7 @@ Return t if the file exists and loads successfully. */) | |||
| 1297 | message_with_string ("Loading %s...", file, 1); | 1310 | message_with_string ("Loading %s...", file, 1); |
| 1298 | } | 1311 | } |
| 1299 | 1312 | ||
| 1300 | record_unwind_protect (load_unwind, make_save_value (stream, 0)); | 1313 | record_unwind_protect (load_unwind, make_save_pointer (stream)); |
| 1301 | record_unwind_protect (load_descriptor_unwind, load_descriptor_list); | 1314 | record_unwind_protect (load_descriptor_unwind, load_descriptor_list); |
| 1302 | specbind (Qload_file_name, found); | 1315 | specbind (Qload_file_name, found); |
| 1303 | specbind (Qinhibit_file_name_operation, Qnil); | 1316 | specbind (Qinhibit_file_name_operation, Qnil); |
| @@ -1356,7 +1369,7 @@ Return t if the file exists and loads successfully. */) | |||
| 1356 | static Lisp_Object | 1369 | static Lisp_Object |
| 1357 | load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */ | 1370 | load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */ |
| 1358 | { | 1371 | { |
| 1359 | FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer; | 1372 | FILE *stream = XSAVE_POINTER (arg, 0); |
| 1360 | if (stream != NULL) | 1373 | if (stream != NULL) |
| 1361 | { | 1374 | { |
| 1362 | block_input (); | 1375 | block_input (); |
| @@ -2387,7 +2400,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2387 | bool multibyte; | 2400 | bool multibyte; |
| 2388 | 2401 | ||
| 2389 | *pch = 0; | 2402 | *pch = 0; |
| 2390 | load_each_byte = 0; | ||
| 2391 | 2403 | ||
| 2392 | retry: | 2404 | retry: |
| 2393 | 2405 | ||
| @@ -2597,7 +2609,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2597 | return tmp; | 2609 | return tmp; |
| 2598 | } | 2610 | } |
| 2599 | 2611 | ||
| 2600 | /* #@NUMBER is used to skip NUMBER following characters. | 2612 | /* #@NUMBER is used to skip NUMBER following bytes. |
| 2601 | That's used in .elc files to skip over doc strings | 2613 | That's used in .elc files to skip over doc strings |
| 2602 | and function definitions. */ | 2614 | and function definitions. */ |
| 2603 | if (c == '@') | 2615 | if (c == '@') |
| @@ -2605,7 +2617,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2605 | enum { extra = 100 }; | 2617 | enum { extra = 100 }; |
| 2606 | ptrdiff_t i, nskip = 0; | 2618 | ptrdiff_t i, nskip = 0; |
| 2607 | 2619 | ||
| 2608 | load_each_byte = 1; | ||
| 2609 | /* Read a decimal integer. */ | 2620 | /* Read a decimal integer. */ |
| 2610 | while ((c = READCHAR) >= 0 | 2621 | while ((c = READCHAR) >= 0 |
| 2611 | && c >= '0' && c <= '9') | 2622 | && c >= '0' && c <= '9') |
| @@ -2615,8 +2626,15 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2615 | nskip *= 10; | 2626 | nskip *= 10; |
| 2616 | nskip += c - '0'; | 2627 | nskip += c - '0'; |
| 2617 | } | 2628 | } |
| 2618 | UNREAD (c); | 2629 | if (nskip > 0) |
| 2619 | 2630 | /* We can't use UNREAD here, because in the code below we side-step | |
| 2631 | READCHAR. Instead, assume the first char after #@NNN occupies | ||
| 2632 | a single byte, which is the case normally since it's just | ||
| 2633 | a space. */ | ||
| 2634 | nskip--; | ||
| 2635 | else | ||
| 2636 | UNREAD (c); | ||
| 2637 | |||
| 2620 | if (load_force_doc_strings | 2638 | if (load_force_doc_strings |
| 2621 | && (EQ (readcharfun, Qget_file_char) | 2639 | && (EQ (readcharfun, Qget_file_char) |
| 2622 | || EQ (readcharfun, Qget_emacs_mule_file_char))) | 2640 | || EQ (readcharfun, Qget_emacs_mule_file_char))) |
| @@ -2658,19 +2676,17 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2658 | saved_doc_string_position = file_tell (instream); | 2676 | saved_doc_string_position = file_tell (instream); |
| 2659 | 2677 | ||
| 2660 | /* Copy that many characters into saved_doc_string. */ | 2678 | /* Copy that many characters into saved_doc_string. */ |
| 2679 | block_input (); | ||
| 2661 | for (i = 0; i < nskip && c >= 0; i++) | 2680 | for (i = 0; i < nskip && c >= 0; i++) |
| 2662 | saved_doc_string[i] = c = READCHAR; | 2681 | saved_doc_string[i] = c = getc (instream); |
| 2682 | unblock_input (); | ||
| 2663 | 2683 | ||
| 2664 | saved_doc_string_length = i; | 2684 | saved_doc_string_length = i; |
| 2665 | } | 2685 | } |
| 2666 | else | 2686 | else |
| 2667 | { | 2687 | /* Skip that many bytes. */ |
| 2668 | /* Skip that many characters. */ | 2688 | skip_dyn_bytes (readcharfun, nskip); |
| 2669 | for (i = 0; i < nskip && c >= 0; i++) | ||
| 2670 | c = READCHAR; | ||
| 2671 | } | ||
| 2672 | 2689 | ||
| 2673 | load_each_byte = 0; | ||
| 2674 | goto retry; | 2690 | goto retry; |
| 2675 | } | 2691 | } |
| 2676 | if (c == '!') | 2692 | if (c == '!') |
| @@ -3569,9 +3585,8 @@ read_list (bool flag, Lisp_Object readcharfun) | |||
| 3569 | doc string, caller must make it | 3585 | doc string, caller must make it |
| 3570 | multibyte. */ | 3586 | multibyte. */ |
| 3571 | 3587 | ||
| 3572 | EMACS_INT pos = XINT (XCDR (val)); | ||
| 3573 | /* Position is negative for user variables. */ | 3588 | /* Position is negative for user variables. */ |
| 3574 | if (pos < 0) pos = -pos; | 3589 | EMACS_INT pos = eabs (XINT (XCDR (val))); |
| 3575 | if (pos >= saved_doc_string_position | 3590 | if (pos >= saved_doc_string_position |
| 3576 | && pos < (saved_doc_string_position | 3591 | && pos < (saved_doc_string_position |
| 3577 | + saved_doc_string_length)) | 3592 | + saved_doc_string_length)) |
| @@ -4525,12 +4540,16 @@ The default is nil, which means use the function `read'. */); | |||
| 4525 | Vload_read_function = Qnil; | 4540 | Vload_read_function = Qnil; |
| 4526 | 4541 | ||
| 4527 | DEFVAR_LISP ("load-source-file-function", Vload_source_file_function, | 4542 | DEFVAR_LISP ("load-source-file-function", Vload_source_file_function, |
| 4528 | doc: /* Function called in `load' for loading an Emacs Lisp source file. | 4543 | doc: /* Function called in `load' to load an Emacs Lisp source file. |
| 4529 | This function is for doing code conversion before reading the source file. | 4544 | The value should be a function for doing code conversion before |
| 4530 | If nil, loading is done without any code conversion. | 4545 | reading a source file. It can also be nil, in which case loading is |
| 4531 | Arguments are FULLNAME, FILE, NOERROR, NOMESSAGE, where | 4546 | done without any code conversion. |
| 4532 | FULLNAME is the full name of FILE. | 4547 | |
| 4533 | See `load' for the meaning of the remaining arguments. */); | 4548 | If the value is a function, it is called with four arguments, |
| 4549 | FULLNAME, FILE, NOERROR, NOMESSAGE. FULLNAME is the absolute name of | ||
| 4550 | the file to load, FILE is the non-absolute name (for messages etc.), | ||
| 4551 | and NOERROR and NOMESSAGE are the corresponding arguments passed to | ||
| 4552 | `load'. The function should return t if the file was loaded. */); | ||
| 4534 | Vload_source_file_function = Qnil; | 4553 | Vload_source_file_function = Qnil; |
| 4535 | 4554 | ||
| 4536 | DEFVAR_BOOL ("load-force-doc-strings", load_force_doc_strings, | 4555 | DEFVAR_BOOL ("load-force-doc-strings", load_force_doc_strings, |
diff --git a/src/macros.c b/src/macros.c index 632c851ee8c..0dcfbe5532c 100644 --- a/src/macros.c +++ b/src/macros.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Keyboard macros. | 1 | /* Keyboard macros. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993, 2000-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1986, 1993, 2000-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -78,7 +78,7 @@ macro before appending to it. */) | |||
| 78 | } | 78 | } |
| 79 | current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer; | 79 | current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer; |
| 80 | current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer; | 80 | current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer; |
| 81 | message ("Defining kbd macro..."); | 81 | message1 ("Defining kbd macro..."); |
| 82 | } | 82 | } |
| 83 | else | 83 | else |
| 84 | { | 84 | { |
| @@ -125,7 +125,7 @@ macro before appending to it. */) | |||
| 125 | Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), | 125 | Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), |
| 126 | make_number (1), Qnil); | 126 | make_number (1), Qnil); |
| 127 | 127 | ||
| 128 | message ("Appending to kbd macro..."); | 128 | message1 ("Appending to kbd macro..."); |
| 129 | } | 129 | } |
| 130 | kset_defining_kbd_macro (current_kboard, Qt); | 130 | kset_defining_kbd_macro (current_kboard, Qt); |
| 131 | 131 | ||
| @@ -172,21 +172,21 @@ each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) | |||
| 172 | if (!NILP (KVAR (current_kboard, defining_kbd_macro))) | 172 | if (!NILP (KVAR (current_kboard, defining_kbd_macro))) |
| 173 | { | 173 | { |
| 174 | end_kbd_macro (); | 174 | end_kbd_macro (); |
| 175 | message ("Keyboard macro defined"); | 175 | message1 ("Keyboard macro defined"); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | if (XFASTINT (repeat) == 0) | 178 | if (XFASTINT (repeat) == 0) |
| 179 | Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc); | 179 | Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc); |
| 180 | else if (XINT (repeat) > 1) | 180 | else if (XINT (repeat) > 1) |
| 181 | { | 181 | { |
| 182 | XSETINT (repeat, XINT (repeat)-1); | 182 | XSETINT (repeat, XINT (repeat) - 1); |
| 183 | Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), | 183 | Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), |
| 184 | repeat, loopfunc); | 184 | repeat, loopfunc); |
| 185 | } | 185 | } |
| 186 | return Qnil; | 186 | return Qnil; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | /* Store character c into kbd macro being defined */ | 189 | /* Store character c into kbd macro being defined. */ |
| 190 | 190 | ||
| 191 | void | 191 | void |
| 192 | store_kbd_macro_char (Lisp_Object c) | 192 | store_kbd_macro_char (Lisp_Object c) |
diff --git a/src/macros.h b/src/macros.h index d66784a0246..57cd1c4f2fd 100644 --- a/src/macros.h +++ b/src/macros.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions for keyboard macro interpretation in GNU Emacs. | 1 | /* Definitions for keyboard macro interpretation in GNU Emacs. |
| 2 | Copyright (C) 1985, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/makefile.w32-in b/src/makefile.w32-in index a296f6eb393..6e1873f8e49 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | # -*- Makefile -*- for GNU Emacs on the Microsoft Windows API. | 1 | # -*- Makefile -*- for GNU Emacs on the Microsoft Windows API. |
| 2 | # Copyright (C) 2000-2012 Free Software Foundation, Inc. | 2 | # Copyright (C) 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | # This file is part of GNU Emacs. | 4 | # This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -134,6 +134,7 @@ OBJ2 = $(BLD)/sysdep.$(O) \ | |||
| 134 | $(BLD)/w32menu.$(O) \ | 134 | $(BLD)/w32menu.$(O) \ |
| 135 | $(BLD)/w32reg.$(O) \ | 135 | $(BLD)/w32reg.$(O) \ |
| 136 | $(BLD)/w32font.$(O) \ | 136 | $(BLD)/w32font.$(O) \ |
| 137 | $(BLD)/w32notify.$(O) \ | ||
| 137 | $(BLD)/w32uniscribe.$(O) | 138 | $(BLD)/w32uniscribe.$(O) |
| 138 | 139 | ||
| 139 | LIBS = $(TLIB0) \ | 140 | LIBS = $(TLIB0) \ |
| @@ -209,7 +210,7 @@ GLOBAL_SOURCES = dosfns.c msdos.c \ | |||
| 209 | fontset.c menu.c dbusbind.c \ | 210 | fontset.c menu.c dbusbind.c \ |
| 210 | w32.c w32console.c w32fns.c w32heap.c w32inevt.c cygw32.c \ | 211 | w32.c w32console.c w32fns.c w32heap.c w32inevt.c cygw32.c \ |
| 211 | w32menu.c w32proc.c w32reg.c w32select.c w32term.c w32xfns.c \ | 212 | w32menu.c w32proc.c w32reg.c w32select.c w32term.c w32xfns.c \ |
| 212 | font.c w32font.c w32uniscribe.c \ | 213 | font.c w32font.c w32uniscribe.c w32notify.c \ |
| 213 | dispnew.c frame.c scroll.c xdisp.c window.c bidi.c \ | 214 | dispnew.c frame.c scroll.c xdisp.c window.c bidi.c \ |
| 214 | charset.c coding.c category.c ccl.c character.c chartab.c \ | 215 | charset.c coding.c category.c ccl.c character.c chartab.c \ |
| 215 | cm.c term.c terminal.c xfaces.c \ | 216 | cm.c term.c terminal.c xfaces.c \ |
| @@ -461,6 +462,8 @@ U64_H = $(GNU_LIB)/u64.h \ | |||
| 461 | $(NT_INC)/stdint.h | 462 | $(NT_INC)/stdint.h |
| 462 | SHA512_H = $(GNU_LIB)/sha512.h \ | 463 | SHA512_H = $(GNU_LIB)/sha512.h \ |
| 463 | $(U64_H) | 464 | $(U64_H) |
| 465 | SIG2STR_H = $(GNU_LIB)/sig2str.h \ | ||
| 466 | $(GNU_LIB)/intprops.h | ||
| 464 | SOCKET_H = $(NT_INC)/sys/socket.h \ | 467 | SOCKET_H = $(NT_INC)/sys/socket.h \ |
| 465 | $(SRC)/w32.h | 468 | $(SRC)/w32.h |
| 466 | STAT_TIME_H = $(GNU_LIB)/stat-time.h \ | 469 | STAT_TIME_H = $(GNU_LIB)/stat-time.h \ |
| @@ -471,6 +474,7 @@ SYSTTY_H = $(SRC)/systty.h \ | |||
| 471 | $(NT_INC)/sys/ioctl.h \ | 474 | $(NT_INC)/sys/ioctl.h \ |
| 472 | $(NT_INC)/unistd.h | 475 | $(NT_INC)/unistd.h |
| 473 | SYSWAIT_H = $(SRC)/syswait.h \ | 476 | SYSWAIT_H = $(SRC)/syswait.h \ |
| 477 | $(NT_INC)/stdbool.h \ | ||
| 474 | $(NT_INC)/sys/wait.h | 478 | $(NT_INC)/sys/wait.h |
| 475 | TERMHOOKS_H = $(SRC)/termhooks.h \ | 479 | TERMHOOKS_H = $(SRC)/termhooks.h \ |
| 476 | $(SYSTIME_H) | 480 | $(SYSTIME_H) |
| @@ -786,6 +790,7 @@ $(BLD)/editfns.$(O) : \ | |||
| 786 | $(CODING_H) \ | 790 | $(CODING_H) \ |
| 787 | $(CONFIG_H) \ | 791 | $(CONFIG_H) \ |
| 788 | $(FRAME_H) \ | 792 | $(FRAME_H) \ |
| 793 | $(GRP_H) \ | ||
| 789 | $(INTERVALS_H) \ | 794 | $(INTERVALS_H) \ |
| 790 | $(LISP_H) \ | 795 | $(LISP_H) \ |
| 791 | $(SYSTIME_H) \ | 796 | $(SYSTIME_H) \ |
| @@ -799,6 +804,7 @@ $(BLD)/emacs.$(O) : \ | |||
| 799 | $(SRC)/keymap.h \ | 804 | $(SRC)/keymap.h \ |
| 800 | $(SRC)/unexec.h \ | 805 | $(SRC)/unexec.h \ |
| 801 | $(SRC)/w32.h \ | 806 | $(SRC)/w32.h \ |
| 807 | $(SRC)/w32common.h \ | ||
| 802 | $(SRC)/w32heap.h \ | 808 | $(SRC)/w32heap.h \ |
| 803 | $(SRC)/w32select.h \ | 809 | $(SRC)/w32select.h \ |
| 804 | $(NT_INC)/sys/file.h \ | 810 | $(NT_INC)/sys/file.h \ |
| @@ -837,10 +843,13 @@ $(BLD)/fileio.$(O) : \ | |||
| 837 | $(SRC)/commands.h \ | 843 | $(SRC)/commands.h \ |
| 838 | $(SRC)/w32.h \ | 844 | $(SRC)/w32.h \ |
| 839 | $(NT_INC)/pwd.h \ | 845 | $(NT_INC)/pwd.h \ |
| 846 | $(NT_INC)/sys/acl.h \ | ||
| 840 | $(NT_INC)/sys/file.h \ | 847 | $(NT_INC)/sys/file.h \ |
| 841 | $(NT_INC)/sys/stat.h \ | 848 | $(NT_INC)/sys/stat.h \ |
| 842 | $(NT_INC)/unistd.h \ | 849 | $(NT_INC)/unistd.h \ |
| 850 | $(GNU_LIB)/allocator.h \ | ||
| 843 | $(BUFFER_H) \ | 851 | $(BUFFER_H) \ |
| 852 | $(CAREADLINKAT_H) \ | ||
| 844 | $(CHARACTER_H) \ | 853 | $(CHARACTER_H) \ |
| 845 | $(CODING_H) \ | 854 | $(CODING_H) \ |
| 846 | $(CONFIG_H) \ | 855 | $(CONFIG_H) \ |
| @@ -1179,6 +1188,7 @@ $(BLD)/w32.$(O) : \ | |||
| 1179 | $(SRC)/w32select.h \ | 1188 | $(SRC)/w32select.h \ |
| 1180 | $(NT_INC)/dirent.h \ | 1189 | $(NT_INC)/dirent.h \ |
| 1181 | $(NT_INC)/pwd.h \ | 1190 | $(NT_INC)/pwd.h \ |
| 1191 | $(NT_INC)/sys/acl.h \ | ||
| 1182 | $(NT_INC)/sys/file.h \ | 1192 | $(NT_INC)/sys/file.h \ |
| 1183 | $(NT_INC)/sys/time.h \ | 1193 | $(NT_INC)/sys/time.h \ |
| 1184 | $(GNU_LIB)/allocator.h \ | 1194 | $(GNU_LIB)/allocator.h \ |
| @@ -1287,11 +1297,13 @@ $(BLD)/process.$(O) : \ | |||
| 1287 | $(CHARACTER_H) \ | 1297 | $(CHARACTER_H) \ |
| 1288 | $(CODING_H) \ | 1298 | $(CODING_H) \ |
| 1289 | $(CONFIG_H) \ | 1299 | $(CONFIG_H) \ |
| 1300 | $(C_CTYPE_H) \ | ||
| 1290 | $(DISPEXTERN_H) \ | 1301 | $(DISPEXTERN_H) \ |
| 1291 | $(FRAME_H) \ | 1302 | $(FRAME_H) \ |
| 1292 | $(KEYBOARD_H) \ | 1303 | $(KEYBOARD_H) \ |
| 1293 | $(LISP_H) \ | 1304 | $(LISP_H) \ |
| 1294 | $(PROCESS_H) \ | 1305 | $(PROCESS_H) \ |
| 1306 | $(SIG2STR_H) \ | ||
| 1295 | $(SOCKET_H) \ | 1307 | $(SOCKET_H) \ |
| 1296 | $(SYSSIGNAL_H) \ | 1308 | $(SYSSIGNAL_H) \ |
| 1297 | $(SYSTIME_H) \ | 1309 | $(SYSTIME_H) \ |
| @@ -1387,11 +1399,9 @@ $(BLD)/sysdep.$(O) : \ | |||
| 1387 | $(NT_INC)/sys/file.h \ | 1399 | $(NT_INC)/sys/file.h \ |
| 1388 | $(NT_INC)/sys/stat.h \ | 1400 | $(NT_INC)/sys/stat.h \ |
| 1389 | $(NT_INC)/unistd.h \ | 1401 | $(NT_INC)/unistd.h \ |
| 1390 | $(GNU_LIB)/allocator.h \ | ||
| 1391 | $(GNU_LIB)/execinfo.h \ | 1402 | $(GNU_LIB)/execinfo.h \ |
| 1392 | $(GNU_LIB)/ignore-value.h \ | 1403 | $(GNU_LIB)/ignore-value.h \ |
| 1393 | $(GNU_LIB)/utimens.h \ | 1404 | $(GNU_LIB)/utimens.h \ |
| 1394 | $(CAREADLINKAT_H) \ | ||
| 1395 | $(CONFIG_H) \ | 1405 | $(CONFIG_H) \ |
| 1396 | $(C_CTYPE_H) \ | 1406 | $(C_CTYPE_H) \ |
| 1397 | $(DISPEXTERN_H) \ | 1407 | $(DISPEXTERN_H) \ |
| @@ -1693,6 +1703,18 @@ $(BLD)/w32uniscribe.$(O) : \ | |||
| 1693 | $(W32FONT_H) \ | 1703 | $(W32FONT_H) \ |
| 1694 | $(W32TERM_H) | 1704 | $(W32TERM_H) |
| 1695 | 1705 | ||
| 1706 | $(BLD)/w32notify.$(O) : \ | ||
| 1707 | $(SRC)/w32notify.c \ | ||
| 1708 | $(SRC)/w32.h \ | ||
| 1709 | $(SRC)/w32common.h \ | ||
| 1710 | $(CODING_H) \ | ||
| 1711 | $(CONFIG_H) \ | ||
| 1712 | $(FRAME_H) \ | ||
| 1713 | $(KEYBOARD_H) \ | ||
| 1714 | $(LISP_H) \ | ||
| 1715 | $(TERMHOOKS_H) \ | ||
| 1716 | $(W32TERM_H) | ||
| 1717 | |||
| 1696 | # Each object file depends on stamp_BLD, because in parallel builds we must | 1718 | # Each object file depends on stamp_BLD, because in parallel builds we must |
| 1697 | # make sure $(BLD) exists before starting compilations. | 1719 | # make sure $(BLD) exists before starting compilations. |
| 1698 | # | 1720 | # |
diff --git a/src/marker.c b/src/marker.c index 69be4faec3a..0d992c0abfa 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Markers: examining, setting and deleting. | 1 | /* Markers: examining, setting and deleting. |
| 2 | Copyright (C) 1985, 1997-1998, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 1997-1998, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -82,9 +83,7 @@ clear_charpos_cache (struct buffer *b) | |||
| 82 | and everywhere there is a marker. So we find the one of these places | 83 | and everywhere there is a marker. So we find the one of these places |
| 83 | that is closest to the specified position, and scan from there. */ | 84 | that is closest to the specified position, and scan from there. */ |
| 84 | 85 | ||
| 85 | /* charpos_to_bytepos returns the byte position corresponding to CHARPOS. */ | 86 | /* This macro is a subroutine of buf_charpos_to_bytepos. |
| 86 | |||
| 87 | /* This macro is a subroutine of charpos_to_bytepos. | ||
| 88 | Note that it is desirable that BYTEPOS is not evaluated | 87 | Note that it is desirable that BYTEPOS is not evaluated |
| 89 | except when we really want its value. */ | 88 | except when we really want its value. */ |
| 90 | 89 | ||
| @@ -128,11 +127,7 @@ clear_charpos_cache (struct buffer *b) | |||
| 128 | } \ | 127 | } \ |
| 129 | } | 128 | } |
| 130 | 129 | ||
| 131 | ptrdiff_t | 130 | /* Return the byte position corresponding to CHARPOS in B. */ |
| 132 | charpos_to_bytepos (ptrdiff_t charpos) | ||
| 133 | { | ||
| 134 | return buf_charpos_to_bytepos (current_buffer, charpos); | ||
| 135 | } | ||
| 136 | 131 | ||
| 137 | ptrdiff_t | 132 | ptrdiff_t |
| 138 | buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) | 133 | buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) |
| @@ -141,8 +136,7 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) | |||
| 141 | ptrdiff_t best_above, best_above_byte; | 136 | ptrdiff_t best_above, best_above_byte; |
| 142 | ptrdiff_t best_below, best_below_byte; | 137 | ptrdiff_t best_below, best_below_byte; |
| 143 | 138 | ||
| 144 | if (charpos < BUF_BEG (b) || charpos > BUF_Z (b)) | 139 | eassert (BUF_BEG (b) <= charpos && charpos <= BUF_Z (b)); |
| 145 | emacs_abort (); | ||
| 146 | 140 | ||
| 147 | best_above = BUF_Z (b); | 141 | best_above = BUF_Z (b); |
| 148 | best_above_byte = BUF_Z_BYTE (b); | 142 | best_above_byte = BUF_Z_BYTE (b); |
| @@ -242,9 +236,6 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) | |||
| 242 | 236 | ||
| 243 | #undef CONSIDER | 237 | #undef CONSIDER |
| 244 | 238 | ||
| 245 | /* buf_bytepos_to_charpos returns the char position corresponding to | ||
| 246 | BYTEPOS. */ | ||
| 247 | |||
| 248 | /* This macro is a subroutine of buf_bytepos_to_charpos. | 239 | /* This macro is a subroutine of buf_bytepos_to_charpos. |
| 249 | It is used when BYTEPOS is actually the byte position. */ | 240 | It is used when BYTEPOS is actually the byte position. */ |
| 250 | 241 | ||
| @@ -288,6 +279,8 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) | |||
| 288 | } \ | 279 | } \ |
| 289 | } | 280 | } |
| 290 | 281 | ||
| 282 | /* Return the character position corresponding to BYTEPOS in B. */ | ||
| 283 | |||
| 291 | ptrdiff_t | 284 | ptrdiff_t |
| 292 | buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) | 285 | buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) |
| 293 | { | 286 | { |
| @@ -295,8 +288,7 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) | |||
| 295 | ptrdiff_t best_above, best_above_byte; | 288 | ptrdiff_t best_above, best_above_byte; |
| 296 | ptrdiff_t best_below, best_below_byte; | 289 | ptrdiff_t best_below, best_below_byte; |
| 297 | 290 | ||
| 298 | if (bytepos < BUF_BEG_BYTE (b) || bytepos > BUF_Z_BYTE (b)) | 291 | eassert (BUF_BEG_BYTE (b) <= bytepos && bytepos <= BUF_Z_BYTE (b)); |
| 299 | emacs_abort (); | ||
| 300 | 292 | ||
| 301 | best_above = BUF_Z (b); | 293 | best_above = BUF_Z (b); |
| 302 | best_above_byte = BUF_Z_BYTE (b); | 294 | best_above_byte = BUF_Z_BYTE (b); |
| @@ -507,11 +499,29 @@ set_marker_internal (Lisp_Object marker, Lisp_Object position, | |||
| 507 | { | 499 | { |
| 508 | register ptrdiff_t charpos, bytepos; | 500 | register ptrdiff_t charpos, bytepos; |
| 509 | 501 | ||
| 510 | CHECK_NUMBER_COERCE_MARKER (position); | 502 | /* Do not use CHECK_NUMBER_COERCE_MARKER because we |
| 511 | charpos = clip_to_bounds (restricted ? BUF_BEGV (b) : BUF_BEG (b), | 503 | don't want to call buf_charpos_to_bytepos if POSTION |
| 512 | XINT (position), | 504 | is a marker and so we know the bytepos already. */ |
| 513 | restricted ? BUF_ZV (b) : BUF_Z (b)); | 505 | if (INTEGERP (position)) |
| 514 | bytepos = buf_charpos_to_bytepos (b, charpos); | 506 | charpos = XINT (position), bytepos = -1; |
| 507 | else if (MARKERP (position)) | ||
| 508 | { | ||
| 509 | charpos = XMARKER (position)->charpos; | ||
| 510 | bytepos = XMARKER (position)->bytepos; | ||
| 511 | } | ||
| 512 | else | ||
| 513 | wrong_type_argument (Qinteger_or_marker_p, position); | ||
| 514 | |||
| 515 | charpos = clip_to_bounds | ||
| 516 | (restricted ? BUF_BEGV (b) : BUF_BEG (b), charpos, | ||
| 517 | restricted ? BUF_ZV (b) : BUF_Z (b)); | ||
| 518 | if (bytepos == -1) | ||
| 519 | bytepos = buf_charpos_to_bytepos (b, charpos); | ||
| 520 | else | ||
| 521 | bytepos = clip_to_bounds | ||
| 522 | (restricted ? BUF_BEGV_BYTE (b) : BUF_BEG_BYTE (b), | ||
| 523 | bytepos, restricted ? BUF_ZV_BYTE (b) : BUF_Z_BYTE (b)); | ||
| 524 | |||
| 515 | attach_marker (m, b, charpos, bytepos); | 525 | attach_marker (m, b, charpos, bytepos); |
| 516 | } | 526 | } |
| 517 | return marker; | 527 | return marker; |
diff --git a/src/mem-limits.h b/src/mem-limits.h index 57a0ca6fefd..941ccf5f121 100644 --- a/src/mem-limits.h +++ b/src/mem-limits.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Includes for memory limit warnings. | 1 | /* Includes for memory limit warnings. |
| 2 | Copyright (C) 1990, 1993-1996, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1990, 1993-1996, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
diff --git a/src/menu.c b/src/menu.c index 7cc110ce7e2..fdef54dd657 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Platform-independent code for terminal communications. | 1 | /* Platform-independent code for terminal communications. |
| 2 | 2 | ||
| 3 | Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2012 | 3 | Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/menu.h b/src/menu.h index 67934c42d76..f60873eadb3 100644 --- a/src/menu.h +++ b/src/menu.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Functions to manipulate menus. | 1 | /* Functions to manipulate menus. |
| 2 | Copyright (C) 2008-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/minibuf.c b/src/minibuf.c index dcc4af37c13..25425cb97dc 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Minibuffer input and completion. | 1 | /* Minibuffer input and completion. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1986, 1993-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -1398,12 +1398,7 @@ is used to further constrain the set of candidates. */) | |||
| 1398 | eltstring, zero, | 1398 | eltstring, zero, |
| 1399 | make_number (compare), | 1399 | make_number (compare), |
| 1400 | completion_ignore_case ? Qt : Qnil); | 1400 | completion_ignore_case ? Qt : Qnil); |
| 1401 | if (EQ (tem, Qt)) | 1401 | matchsize = EQ (tem, Qt) ? compare : eabs (XINT (tem)) - 1; |
| 1402 | matchsize = compare; | ||
| 1403 | else if (XINT (tem) < 0) | ||
| 1404 | matchsize = - XINT (tem) - 1; | ||
| 1405 | else | ||
| 1406 | matchsize = XINT (tem) - 1; | ||
| 1407 | 1402 | ||
| 1408 | if (completion_ignore_case) | 1403 | if (completion_ignore_case) |
| 1409 | { | 1404 | { |
diff --git a/src/msdos.c b/src/msdos.c index 433bf1074d8..ac8c90455d7 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* MS-DOS specific C utilities. -*- coding: raw-text -*- | 1 | /* MS-DOS specific C utilities. -*- coding: raw-text -*- |
| 2 | 2 | ||
| 3 | Copyright (C) 1993-1997, 1999-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1993-1997, 1999-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -3281,10 +3281,10 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx, | |||
| 3281 | erasing it works correctly... */ | 3281 | erasing it works correctly... */ |
| 3282 | if (! NILP (saved_echo_area_message)) | 3282 | if (! NILP (saved_echo_area_message)) |
| 3283 | message_with_string ("%s", saved_echo_area_message, 0); | 3283 | message_with_string ("%s", saved_echo_area_message, 0); |
| 3284 | message (0); | 3284 | message1 (0); |
| 3285 | while (statecount--) | 3285 | while (statecount--) |
| 3286 | xfree (state[statecount].screen_behind); | 3286 | xfree (state[statecount].screen_behind); |
| 3287 | IT_display_cursor (1); /* turn cursor back on */ | 3287 | IT_display_cursor (1); /* Turn cursor back on. */ |
| 3288 | /* Clean up any mouse events that are waiting inside Emacs event queue. | 3288 | /* Clean up any mouse events that are waiting inside Emacs event queue. |
| 3289 | These events are likely to be generated before the menu was even | 3289 | These events are likely to be generated before the menu was even |
| 3290 | displayed, probably because the user pressed and released the button | 3290 | displayed, probably because the user pressed and released the button |
| @@ -3339,7 +3339,7 @@ void msdos_downcase_filename (unsigned char *); | |||
| 3339 | /* Destructively turn backslashes into slashes. */ | 3339 | /* Destructively turn backslashes into slashes. */ |
| 3340 | 3340 | ||
| 3341 | void | 3341 | void |
| 3342 | dostounix_filename (char *p) | 3342 | dostounix_filename (char *p, int ignore) |
| 3343 | { | 3343 | { |
| 3344 | msdos_downcase_filename (p); | 3344 | msdos_downcase_filename (p); |
| 3345 | 3345 | ||
| @@ -3603,7 +3603,7 @@ init_environment (int argc, char **argv, int skip_args) | |||
| 3603 | if (!s) s = "c:/command.com"; | 3603 | if (!s) s = "c:/command.com"; |
| 3604 | t = alloca (strlen (s) + 1); | 3604 | t = alloca (strlen (s) + 1); |
| 3605 | strcpy (t, s); | 3605 | strcpy (t, s); |
| 3606 | dostounix_filename (t); | 3606 | dostounix_filename (t, 0); |
| 3607 | setenv ("SHELL", t, 0); | 3607 | setenv ("SHELL", t, 0); |
| 3608 | 3608 | ||
| 3609 | /* PATH is also downcased and backslashes mirrored. */ | 3609 | /* PATH is also downcased and backslashes mirrored. */ |
| @@ -3613,7 +3613,7 @@ init_environment (int argc, char **argv, int skip_args) | |||
| 3613 | /* Current directory is always considered part of MsDos's path but it is | 3613 | /* Current directory is always considered part of MsDos's path but it is |
| 3614 | not normally mentioned. Now it is. */ | 3614 | not normally mentioned. Now it is. */ |
| 3615 | strcat (strcpy (t, ".;"), s); | 3615 | strcat (strcpy (t, ".;"), s); |
| 3616 | dostounix_filename (t); /* Not a single file name, but this should work. */ | 3616 | dostounix_filename (t, 0); /* Not a single file name, but this should work. */ |
| 3617 | setenv ("PATH", t, 1); | 3617 | setenv ("PATH", t, 1); |
| 3618 | 3618 | ||
| 3619 | /* In some sense all dos users have root privileges, so... */ | 3619 | /* In some sense all dos users have root privileges, so... */ |
| @@ -3957,14 +3957,6 @@ careadlinkat (int fd, char const *filename, | |||
| 3957 | return buffer; | 3957 | return buffer; |
| 3958 | } | 3958 | } |
| 3959 | 3959 | ||
| 3960 | ssize_t | ||
| 3961 | careadlinkatcwd (int fd, char const *filename, char *buffer, | ||
| 3962 | size_t buffer_size) | ||
| 3963 | { | ||
| 3964 | (void) fd; | ||
| 3965 | return readlink (filename, buffer, buffer_size); | ||
| 3966 | } | ||
| 3967 | |||
| 3968 | 3960 | ||
| 3969 | #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2 | 3961 | #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2 |
| 3970 | 3962 | ||
diff --git a/src/msdos.h b/src/msdos.h index a73c1f2901f..ee0d49464ae 100644 --- a/src/msdos.h +++ b/src/msdos.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* MS-DOS specific C utilities, interface. | 1 | /* MS-DOS specific C utilities, interface. |
| 2 | Copyright (C) 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -29,7 +29,7 @@ void dos_set_window_size (int *, int *); | |||
| 29 | 29 | ||
| 30 | int getdefdir (int, char*); | 30 | int getdefdir (int, char*); |
| 31 | void unixtodos_filename (char *); | 31 | void unixtodos_filename (char *); |
| 32 | void dostounix_filename (char *); | 32 | void dostounix_filename (char *, int); |
| 33 | char *rootrelativepath (char *); | 33 | char *rootrelativepath (char *); |
| 34 | void init_environment (int, char **, int); | 34 | void init_environment (int, char **, int); |
| 35 | void internal_terminal_init (void); | 35 | void internal_terminal_init (void); |
diff --git a/src/nsfns.m b/src/nsfns.m index 428cfcb9a10..fac61d2ab53 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Functions for the NeXT/Open/GNUstep and MacOSX window system. | 1 | /* Functions for the NeXT/Open/GNUstep and MacOSX window system. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2012 | 3 | Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -1503,12 +1503,12 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) | |||
| 1503 | [panel setDelegate: fileDelegate]; | 1503 | [panel setDelegate: fileDelegate]; |
| 1504 | 1504 | ||
| 1505 | panelOK = 0; | 1505 | panelOK = 0; |
| 1506 | if (! NILP (dir_only_p)) | 1506 | if (! NILP (dir_only_p)) |
| 1507 | { | 1507 | { |
| 1508 | [panel setCanChooseDirectories: YES]; | 1508 | [panel setCanChooseDirectories: YES]; |
| 1509 | [panel setCanChooseFiles: NO]; | 1509 | [panel setCanChooseFiles: NO]; |
| 1510 | } | 1510 | } |
| 1511 | 1511 | ||
| 1512 | block_input (); | 1512 | block_input (); |
| 1513 | #if defined (NS_IMPL_COCOA) && \ | 1513 | #if defined (NS_IMPL_COCOA) && \ |
| 1514 | MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 | 1514 | MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 |
| @@ -1519,7 +1519,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) | |||
| 1519 | [panel setNameFieldStringValue: [initS lastPathComponent]]; | 1519 | [panel setNameFieldStringValue: [initS lastPathComponent]]; |
| 1520 | else | 1520 | else |
| 1521 | [panel setNameFieldStringValue: @""]; | 1521 | [panel setNameFieldStringValue: @""]; |
| 1522 | 1522 | ||
| 1523 | ret = [panel runModal]; | 1523 | ret = [panel runModal]; |
| 1524 | #else | 1524 | #else |
| 1525 | if (NILP (mustmatch) && NILP (dir_only_p)) | 1525 | if (NILP (mustmatch) && NILP (dir_only_p)) |
| @@ -2106,7 +2106,9 @@ ns_do_applescript (Lisp_Object script, Lisp_Object *result) | |||
| 2106 | void | 2106 | void |
| 2107 | ns_run_ascript (void) | 2107 | ns_run_ascript (void) |
| 2108 | { | 2108 | { |
| 2109 | as_status = ns_do_applescript (as_script, as_result); | 2109 | if (! NILP (as_script)) |
| 2110 | as_status = ns_do_applescript (as_script, as_result); | ||
| 2111 | as_script = Qnil; | ||
| 2110 | } | 2112 | } |
| 2111 | 2113 | ||
| 2112 | DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0, | 2114 | DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0, |
| @@ -2143,11 +2145,14 @@ In case the execution fails, an error is signaled. */) | |||
| 2143 | data2: NSAPP_DATA2_RUNASSCRIPT]; | 2145 | data2: NSAPP_DATA2_RUNASSCRIPT]; |
| 2144 | 2146 | ||
| 2145 | [NSApp postEvent: nxev atStart: NO]; | 2147 | [NSApp postEvent: nxev atStart: NO]; |
| 2146 | [NSApp run]; | 2148 | |
| 2149 | // If there are other events, the event loop may exit. Keep running | ||
| 2150 | // until the script has been handled. */ | ||
| 2151 | while (! NILP (as_script)) | ||
| 2152 | [NSApp run]; | ||
| 2147 | 2153 | ||
| 2148 | status = as_status; | 2154 | status = as_status; |
| 2149 | as_status = 0; | 2155 | as_status = 0; |
| 2150 | as_script = Qnil; | ||
| 2151 | as_result = 0; | 2156 | as_result = 0; |
| 2152 | unblock_input (); | 2157 | unblock_input (); |
| 2153 | if (status == 0) | 2158 | if (status == 0) |
diff --git a/src/nsfont.m b/src/nsfont.m index 2ba38b7570e..ebee363651f 100644 --- a/src/nsfont.m +++ b/src/nsfont.m | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system. | 1 | /* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system. |
| 2 | See font.h | 2 | See font.h |
| 3 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -44,6 +44,7 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu) | |||
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #define NSFONT_TRACE 0 | 46 | #define NSFONT_TRACE 0 |
| 47 | #define LCD_SMOOTHING_MARGIN 2 | ||
| 47 | 48 | ||
| 48 | extern Lisp_Object Qns; | 49 | extern Lisp_Object Qns; |
| 49 | extern Lisp_Object Qnormal, Qbold, Qitalic; | 50 | extern Lisp_Object Qnormal, Qbold, Qitalic; |
| @@ -74,10 +75,9 @@ static void ns_glyph_metrics (struct nsfont_info *font_info, | |||
| 74 | static void | 75 | static void |
| 75 | ns_escape_name (char *name) | 76 | ns_escape_name (char *name) |
| 76 | { | 77 | { |
| 77 | int i =0, len =strlen (name); | 78 | for (; *name; name++) |
| 78 | for ( ; i<len; i++) | 79 | if (*name == ' ') |
| 79 | if (name[i] == ' ') | 80 | *name = '_'; |
| 80 | name[i] = '_'; | ||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | 83 | ||
| @@ -85,10 +85,9 @@ ns_escape_name (char *name) | |||
| 85 | static void | 85 | static void |
| 86 | ns_unescape_name (char *name) | 86 | ns_unescape_name (char *name) |
| 87 | { | 87 | { |
| 88 | int i =0, len =strlen (name); | 88 | for (; *name; name++) |
| 89 | for ( ; i<len; i++) | 89 | if (*name == '_') |
| 90 | if (name[i] == '_') | 90 | *name = ' '; |
| 91 | name[i] = ' '; | ||
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | 93 | ||
| @@ -363,7 +362,7 @@ static NSString | |||
| 363 | while CONSP (rts) | 362 | while CONSP (rts) |
| 364 | { | 363 | { |
| 365 | r = XCAR (XCAR (rts)); | 364 | r = XCAR (XCAR (rts)); |
| 366 | if (!strncmp(SSDATA(r), reg, strlen(SSDATA(r)))) | 365 | if (!strncmp (SSDATA (r), reg, SBYTES (r))) |
| 367 | { | 366 | { |
| 368 | script = XCDR (XCAR (rts)); | 367 | script = XCDR (XCAR (rts)); |
| 369 | return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (script))]; | 368 | return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (script))]; |
| @@ -546,6 +545,7 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch) | |||
| 546 | NSSet *cFamilies; | 545 | NSSet *cFamilies; |
| 547 | BOOL foundItal = NO; | 546 | BOOL foundItal = NO; |
| 548 | 547 | ||
| 548 | block_input (); | ||
| 549 | if (NSFONT_TRACE) | 549 | if (NSFONT_TRACE) |
| 550 | { | 550 | { |
| 551 | fprintf (stderr, "nsfont: %s for fontspec:\n ", | 551 | fprintf (stderr, "nsfont: %s for fontspec:\n ", |
| @@ -560,10 +560,7 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch) | |||
| 560 | if (isMatch) | 560 | if (isMatch) |
| 561 | [fkeys removeObject: NSFontFamilyAttribute]; | 561 | [fkeys removeObject: NSFontFamilyAttribute]; |
| 562 | 562 | ||
| 563 | if ([fkeys count] > 0) | 563 | matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys]; |
| 564 | matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys]; | ||
| 565 | else | ||
| 566 | matchingDescs = [NSMutableArray array]; | ||
| 567 | 564 | ||
| 568 | if (NSFONT_TRACE) | 565 | if (NSFONT_TRACE) |
| 569 | NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc, | 566 | NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc, |
| @@ -598,6 +595,8 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch) | |||
| 598 | [s1 release]; | 595 | [s1 release]; |
| 599 | } | 596 | } |
| 600 | 597 | ||
| 598 | unblock_input (); | ||
| 599 | |||
| 601 | /* Return something if was a match and nothing found. */ | 600 | /* Return something if was a match and nothing found. */ |
| 602 | if (isMatch) | 601 | if (isMatch) |
| 603 | return ns_fallback_entity (); | 602 | return ns_fallback_entity (); |
| @@ -701,10 +700,12 @@ static Lisp_Object | |||
| 701 | nsfont_list_family (Lisp_Object frame) | 700 | nsfont_list_family (Lisp_Object frame) |
| 702 | { | 701 | { |
| 703 | Lisp_Object list = Qnil; | 702 | Lisp_Object list = Qnil; |
| 704 | NSEnumerator *families = | 703 | NSEnumerator *families; |
| 705 | [[[NSFontManager sharedFontManager] availableFontFamilies] | ||
| 706 | objectEnumerator]; | ||
| 707 | NSString *family; | 704 | NSString *family; |
| 705 | |||
| 706 | block_input (); | ||
| 707 | families = [[[NSFontManager sharedFontManager] availableFontFamilies] | ||
| 708 | objectEnumerator]; | ||
| 708 | while ((family = [families nextObject])) | 709 | while ((family = [families nextObject])) |
| 709 | list = Fcons (intern ([family UTF8String]), list); | 710 | list = Fcons (intern ([family UTF8String]), list); |
| 710 | /* FIXME: escape the name? */ | 711 | /* FIXME: escape the name? */ |
| @@ -713,6 +714,7 @@ nsfont_list_family (Lisp_Object frame) | |||
| 713 | fprintf (stderr, "nsfont: list families returning %"pI"d entries\n", | 714 | fprintf (stderr, "nsfont: list families returning %"pI"d entries\n", |
| 714 | XINT (Flength (list))); | 715 | XINT (Flength (list))); |
| 715 | 716 | ||
| 717 | unblock_input (); | ||
| 716 | return list; | 718 | return list; |
| 717 | } | 719 | } |
| 718 | 720 | ||
| @@ -735,6 +737,8 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) | |||
| 735 | Lisp_Object font_object; | 737 | Lisp_Object font_object; |
| 736 | int fixLeopardBug; | 738 | int fixLeopardBug; |
| 737 | 739 | ||
| 740 | block_input (); | ||
| 741 | |||
| 738 | if (NSFONT_TRACE) | 742 | if (NSFONT_TRACE) |
| 739 | { | 743 | { |
| 740 | fprintf (stderr, "nsfont: open size %d of fontentity:\n ", pixel_size); | 744 | fprintf (stderr, "nsfont: open size %d of fontentity:\n ", pixel_size); |
| @@ -794,13 +798,14 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) | |||
| 794 | font_info = (struct nsfont_info *) XFONT_OBJECT (font_object); | 798 | font_info = (struct nsfont_info *) XFONT_OBJECT (font_object); |
| 795 | font = (struct font *) font_info; | 799 | font = (struct font *) font_info; |
| 796 | if (!font) | 800 | if (!font) |
| 797 | return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */ | 801 | { |
| 802 | unblock_input (); | ||
| 803 | return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */ | ||
| 804 | } | ||
| 798 | 805 | ||
| 799 | font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs); | 806 | font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs); |
| 800 | font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics); | 807 | font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics); |
| 801 | 808 | ||
| 802 | block_input (); | ||
| 803 | |||
| 804 | /* for metrics */ | 809 | /* for metrics */ |
| 805 | #ifdef NS_IMPL_COCOA | 810 | #ifdef NS_IMPL_COCOA |
| 806 | sfont = [nsfont screenFontWithRenderingMode: | 811 | sfont = [nsfont screenFontWithRenderingMode: |
| @@ -1051,6 +1056,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, | |||
| 1051 | char isComposite = s->first_glyph->type == COMPOSITE_GLYPH; | 1056 | char isComposite = s->first_glyph->type == COMPOSITE_GLYPH; |
| 1052 | int end = isComposite ? s->cmp_to : s->nchars; | 1057 | int end = isComposite ? s->cmp_to : s->nchars; |
| 1053 | 1058 | ||
| 1059 | block_input (); | ||
| 1054 | /* Select face based on input flags */ | 1060 | /* Select face based on input flags */ |
| 1055 | switch (ns_tmp_flags) | 1061 | switch (ns_tmp_flags) |
| 1056 | { | 1062 | { |
| @@ -1240,7 +1246,6 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, | |||
| 1240 | else | 1246 | else |
| 1241 | CGContextSetShouldAntialias (gcontext, 1); | 1247 | CGContextSetShouldAntialias (gcontext, 1); |
| 1242 | 1248 | ||
| 1243 | CGContextSetShouldSmoothFonts (gcontext, NO); | ||
| 1244 | CGContextSetTextMatrix (gcontext, fliptf); | 1249 | CGContextSetTextMatrix (gcontext, fliptf); |
| 1245 | 1250 | ||
| 1246 | if (bgCol != nil) | 1251 | if (bgCol != nil) |
| @@ -1273,6 +1278,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, | |||
| 1273 | /* Draw underline, overline, strike-through. */ | 1278 | /* Draw underline, overline, strike-through. */ |
| 1274 | ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x); | 1279 | ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x); |
| 1275 | 1280 | ||
| 1281 | unblock_input (); | ||
| 1276 | return to-from; | 1282 | return to-from; |
| 1277 | } | 1283 | } |
| 1278 | 1284 | ||
| @@ -1406,11 +1412,12 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block) | |||
| 1406 | 1412 | ||
| 1407 | lb = r.origin.x; | 1413 | lb = r.origin.x; |
| 1408 | rb = r.size.width - w; | 1414 | rb = r.size.width - w; |
| 1415 | // Add to bearing for LCD smoothing. We don't know if it is there. | ||
| 1409 | if (lb < 0) | 1416 | if (lb < 0) |
| 1410 | metrics->lbearing = round (lb); | 1417 | metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN); |
| 1411 | if (font_info->ital) | 1418 | if (font_info->ital) |
| 1412 | rb += 0.22 * font_info->height; | 1419 | rb += 0.22 * font_info->height; |
| 1413 | metrics->rbearing = lrint (w + rb); | 1420 | metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN); |
| 1414 | 1421 | ||
| 1415 | metrics->descent = r.origin.y < 0 ? -r.origin.y : 0; | 1422 | metrics->descent = r.origin.y < 0 ? -r.origin.y : 0; |
| 1416 | /*lrint (hshrink * [sfont ascender] + expand * hd/2); */ | 1423 | /*lrint (hshrink * [sfont ascender] + expand * hd/2); */ |
diff --git a/src/nsgui.h b/src/nsgui.h index 60c38b221fb..53d0c8b7c8d 100644 --- a/src/nsgui.h +++ b/src/nsgui.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions and headers for communication on the NeXT/Open/GNUstep API. | 1 | /* Definitions and headers for communication on the NeXT/Open/GNUstep API. |
| 2 | Copyright (C) 1995, 2005, 2008-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1995, 2005, 2008-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/nsimage.m b/src/nsimage.m index 884c0763fd4..9d21ba8afca 100644 --- a/src/nsimage.m +++ b/src/nsimage.m | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Image support for the NeXT/Open/GNUstep and MacOSX window system. | 1 | /* Image support for the NeXT/Open/GNUstep and MacOSX window system. |
| 2 | Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2012 | 2 | Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/nsmenu.m b/src/nsmenu.m index d0ea8f5a47a..22ff4dd0b53 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module. | 1 | /* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module. |
| 2 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -1110,6 +1110,8 @@ update_frame_tool_bar (FRAME_PTR f) | |||
| 1110 | FRAME_TOOLBAR_HEIGHT (f) = | 1110 | FRAME_TOOLBAR_HEIGHT (f) = |
| 1111 | NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) | 1111 | NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) |
| 1112 | - FRAME_NS_TITLEBAR_HEIGHT (f); | 1112 | - FRAME_NS_TITLEBAR_HEIGHT (f); |
| 1113 | if (FRAME_TOOLBAR_HEIGHT (f) < 0) // happens if frame is fullscreen. | ||
| 1114 | FRAME_TOOLBAR_HEIGHT (f) = 0; | ||
| 1113 | unblock_input (); | 1115 | unblock_input (); |
| 1114 | } | 1116 | } |
| 1115 | 1117 | ||
| @@ -1347,8 +1349,7 @@ struct Popdown_data | |||
| 1347 | static Lisp_Object | 1349 | static Lisp_Object |
| 1348 | pop_down_menu (Lisp_Object arg) | 1350 | pop_down_menu (Lisp_Object arg) |
| 1349 | { | 1351 | { |
| 1350 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 1352 | struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0); |
| 1351 | struct Popdown_data *unwind_data = (struct Popdown_data *) p->pointer; | ||
| 1352 | 1353 | ||
| 1353 | block_input (); | 1354 | block_input (); |
| 1354 | if (popup_activated_flag) | 1355 | if (popup_activated_flag) |
| @@ -1441,7 +1442,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | |||
| 1441 | unwind_data->pool = pool; | 1442 | unwind_data->pool = pool; |
| 1442 | unwind_data->dialog = dialog; | 1443 | unwind_data->dialog = dialog; |
| 1443 | 1444 | ||
| 1444 | record_unwind_protect (pop_down_menu, make_save_value (unwind_data, 0)); | 1445 | record_unwind_protect (pop_down_menu, make_save_pointer (unwind_data)); |
| 1445 | popup_activated_flag = 1; | 1446 | popup_activated_flag = 1; |
| 1446 | tem = [dialog runDialogAt: p]; | 1447 | tem = [dialog runDialogAt: p]; |
| 1447 | unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */ | 1448 | unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */ |
diff --git a/src/nsselect.m b/src/nsselect.m index c0c412c6fb2..49380f87945 100644 --- a/src/nsselect.m +++ b/src/nsselect.m | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* NeXT/Open/GNUstep / MacOSX Cocoa selection processing for emacs. | 1 | /* NeXT/Open/GNUstep / MacOSX Cocoa selection processing for emacs. |
| 2 | Copyright (C) 1993-1994, 2005-2006, 2008-2012 | 2 | Copyright (C) 1993-1994, 2005-2006, 2008-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -117,7 +117,7 @@ clean_local_selection_data (Lisp_Object obj) | |||
| 117 | 117 | ||
| 118 | if (size == 1) | 118 | if (size == 1) |
| 119 | return clean_local_selection_data (AREF (obj, 0)); | 119 | return clean_local_selection_data (AREF (obj, 0)); |
| 120 | copy = Fmake_vector (make_number (size), Qnil); | 120 | copy = make_uninit_vector (size); |
| 121 | for (i = 0; i < size; i++) | 121 | for (i = 0; i < size; i++) |
| 122 | ASET (copy, i, clean_local_selection_data (AREF (obj, i))); | 122 | ASET (copy, i, clean_local_selection_data (AREF (obj, i))); |
| 123 | return copy; | 123 | return copy; |
diff --git a/src/nsterm.h b/src/nsterm.h index 005701ed415..41dbaf3c0f7 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Definitions and headers for communication with NeXT/Open/GNUstep API. | 1 | /* Definitions and headers for communication with NeXT/Open/GNUstep API. |
| 2 | Copyright (C) 1989, 1993, 2005, 2008-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1989, 1993, 2005, 2008-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -41,6 +42,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #ifndef MAC_OS_X_VERSION_10_8 | 42 | #ifndef MAC_OS_X_VERSION_10_8 |
| 42 | #define MAC_OS_X_VERSION_10_8 1080 | 43 | #define MAC_OS_X_VERSION_10_8 1080 |
| 43 | #endif | 44 | #endif |
| 45 | |||
| 46 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 | ||
| 47 | #define HAVE_NATIVE_FS | ||
| 48 | #endif | ||
| 49 | |||
| 44 | #endif /* NS_IMPL_COCOA */ | 50 | #endif /* NS_IMPL_COCOA */ |
| 45 | 51 | ||
| 46 | #ifdef __OBJC__ | 52 | #ifdef __OBJC__ |
| @@ -87,6 +93,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 87 | int tibar_height, tobar_height, bwidth; | 93 | int tibar_height, tobar_height, bwidth; |
| 88 | int maximized_width, maximized_height; | 94 | int maximized_width, maximized_height; |
| 89 | NSWindow *nonfs_window; | 95 | NSWindow *nonfs_window; |
| 96 | BOOL fs_is_native; | ||
| 90 | @public | 97 | @public |
| 91 | struct frame *emacsframe; | 98 | struct frame *emacsframe; |
| 92 | int rows, cols; | 99 | int rows, cols; |
| @@ -114,6 +121,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 114 | - (void) handleFS; | 121 | - (void) handleFS; |
| 115 | - (void) setFSValue: (int)value; | 122 | - (void) setFSValue: (int)value; |
| 116 | - (void) toggleFullScreen: (id) sender; | 123 | - (void) toggleFullScreen: (id) sender; |
| 124 | - (BOOL) fsIsNative; | ||
| 125 | - (BOOL) isFullscreen; | ||
| 126 | #ifdef HAVE_NATIVE_FS | ||
| 127 | - (void) updateCollectionBehaviour; | ||
| 128 | #endif | ||
| 117 | 129 | ||
| 118 | #ifdef NS_IMPL_GNUSTEP | 130 | #ifdef NS_IMPL_GNUSTEP |
| 119 | /* Not declared, but useful. */ | 131 | /* Not declared, but useful. */ |
| @@ -674,9 +686,9 @@ struct x_output | |||
| 674 | #define FRAME_FONT(f) ((f)->output_data.ns->font) | 686 | #define FRAME_FONT(f) ((f)->output_data.ns->font) |
| 675 | 687 | ||
| 676 | #ifdef __OBJC__ | 688 | #ifdef __OBJC__ |
| 677 | #define XNS_SCROLL_BAR(vec) ((id) XSAVE_VALUE (vec)->pointer) | 689 | #define XNS_SCROLL_BAR(vec) ((id) XSAVE_POINTER (vec, 0)) |
| 678 | #else | 690 | #else |
| 679 | #define XNS_SCROLL_BAR(vec) XSAVE_VALUE (vec)->pointer | 691 | #define XNS_SCROLL_BAR(vec) XSAVE_POINTER (vec, 0) |
| 680 | #endif | 692 | #endif |
| 681 | 693 | ||
| 682 | /* Compute pixel size for vertical scroll bars */ | 694 | /* Compute pixel size for vertical scroll bars */ |
diff --git a/src/nsterm.m b/src/nsterm.m index 55a106b7e03..1f09e031592 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* NeXT/Open/GNUstep / MacOSX communication module. | 1 | /* NeXT/Open/GNUstep / MacOSX communication module. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2012 | 3 | Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -69,11 +69,6 @@ int term_trace_num = 0; | |||
| 69 | #define NSTRACE(x) | 69 | #define NSTRACE(x) |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | #if defined (NS_IMPL_COCOA) && \ | ||
| 73 | MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 | ||
| 74 | #define NEW_STYLE_FS | ||
| 75 | #endif | ||
| 76 | |||
| 77 | extern NSString *NSMenuDidBeginTrackingNotification; | 72 | extern NSString *NSMenuDidBeginTrackingNotification; |
| 78 | 73 | ||
| 79 | /* ========================================================================== | 74 | /* ========================================================================== |
| @@ -224,6 +219,7 @@ static int n_emacs_events_pending = 0; | |||
| 224 | static NSMutableArray *ns_pending_files, *ns_pending_service_names, | 219 | static NSMutableArray *ns_pending_files, *ns_pending_service_names, |
| 225 | *ns_pending_service_args; | 220 | *ns_pending_service_args; |
| 226 | static BOOL ns_do_open_file = NO; | 221 | static BOOL ns_do_open_file = NO; |
| 222 | static BOOL ns_last_use_native_fullscreen; | ||
| 227 | 223 | ||
| 228 | static struct { | 224 | static struct { |
| 229 | struct input_event *q; | 225 | struct input_event *q; |
| @@ -1000,11 +996,8 @@ ns_raise_frame (struct frame *f) | |||
| 1000 | NSView *view = FRAME_NS_VIEW (f); | 996 | NSView *view = FRAME_NS_VIEW (f); |
| 1001 | check_ns (); | 997 | check_ns (); |
| 1002 | block_input (); | 998 | block_input (); |
| 1003 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 1004 | if (FRAME_VISIBLE_P (f)) | 999 | if (FRAME_VISIBLE_P (f)) |
| 1005 | { | 1000 | [[view window] makeKeyAndOrderFront: NSApp]; |
| 1006 | [[view window] makeKeyAndOrderFront: NSApp]; | ||
| 1007 | } | ||
| 1008 | unblock_input (); | 1001 | unblock_input (); |
| 1009 | } | 1002 | } |
| 1010 | 1003 | ||
| @@ -1093,16 +1086,16 @@ x_make_frame_visible (struct frame *f) | |||
| 1093 | if (!FRAME_VISIBLE_P (f)) | 1086 | if (!FRAME_VISIBLE_P (f)) |
| 1094 | { | 1087 | { |
| 1095 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); | 1088 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); |
| 1096 | f->async_visible = 1; | 1089 | |
| 1090 | SET_FRAME_VISIBLE (f, 1); | ||
| 1097 | ns_raise_frame (f); | 1091 | ns_raise_frame (f); |
| 1098 | 1092 | ||
| 1099 | #ifdef NEW_STYLE_FS | ||
| 1100 | /* Making a new frame from a fullscreen frame will make the new frame | 1093 | /* Making a new frame from a fullscreen frame will make the new frame |
| 1101 | fullscreen also. So skip handleFS as this will print an error. */ | 1094 | fullscreen also. So skip handleFS as this will print an error. */ |
| 1102 | if (f->want_fullscreen == FULLSCREEN_BOTH | 1095 | if ([view fsIsNative] && f->want_fullscreen == FULLSCREEN_BOTH |
| 1103 | && ([[view window] styleMask] & NSFullScreenWindowMask) != 0) | 1096 | && [view isFullscreen]) |
| 1104 | return; | 1097 | return; |
| 1105 | #endif | 1098 | |
| 1106 | if (f->want_fullscreen != FULLSCREEN_NONE) | 1099 | if (f->want_fullscreen != FULLSCREEN_NONE) |
| 1107 | { | 1100 | { |
| 1108 | block_input (); | 1101 | block_input (); |
| @@ -1123,8 +1116,8 @@ x_make_frame_invisible (struct frame *f) | |||
| 1123 | NSTRACE (x_make_frame_invisible); | 1116 | NSTRACE (x_make_frame_invisible); |
| 1124 | check_ns (); | 1117 | check_ns (); |
| 1125 | [[view window] orderOut: NSApp]; | 1118 | [[view window] orderOut: NSApp]; |
| 1126 | f->async_visible = 0; | 1119 | SET_FRAME_VISIBLE (f, 0); |
| 1127 | f->async_iconified = 0; | 1120 | SET_FRAME_ICONIFIED (f, 0); |
| 1128 | } | 1121 | } |
| 1129 | 1122 | ||
| 1130 | 1123 | ||
| @@ -1294,7 +1287,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) | |||
| 1294 | pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); | 1287 | pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); |
| 1295 | 1288 | ||
| 1296 | /* If we have a toolbar, take its height into account. */ | 1289 | /* If we have a toolbar, take its height into account. */ |
| 1297 | if (tb) | 1290 | if (tb && ! [view isFullscreen]) |
| 1298 | /* NOTE: previously this would generate wrong result if toolbar not | 1291 | /* NOTE: previously this would generate wrong result if toolbar not |
| 1299 | yet displayed and fixing toolbar_height=32 helped, but | 1292 | yet displayed and fixing toolbar_height=32 helped, but |
| 1300 | now (200903) seems no longer needed */ | 1293 | now (200903) seems no longer needed */ |
| @@ -1305,8 +1298,10 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) | |||
| 1305 | FRAME_TOOLBAR_HEIGHT (f) = 0; | 1298 | FRAME_TOOLBAR_HEIGHT (f) = 0; |
| 1306 | 1299 | ||
| 1307 | wr.size.width = pixelwidth + f->border_width; | 1300 | wr.size.width = pixelwidth + f->border_width; |
| 1308 | wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f) | 1301 | wr.size.height = pixelheight; |
| 1309 | + FRAME_TOOLBAR_HEIGHT (f); | 1302 | if (! [view isFullscreen]) |
| 1303 | wr.size.height += FRAME_NS_TITLEBAR_HEIGHT (f) | ||
| 1304 | + FRAME_TOOLBAR_HEIGHT (f); | ||
| 1310 | 1305 | ||
| 1311 | /* Do not try to constrain to this screen. We may have multiple | 1306 | /* Do not try to constrain to this screen. We may have multiple |
| 1312 | screens, and want Emacs to span those. Constraining to screen | 1307 | screens, and want Emacs to span those. Constraining to screen |
| @@ -1354,9 +1349,10 @@ ns_fullscreen_hook (FRAME_PTR f) | |||
| 1354 | { | 1349 | { |
| 1355 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); | 1350 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); |
| 1356 | 1351 | ||
| 1357 | if (! f->async_visible) return; | 1352 | if (!FRAME_VISIBLE_P (f)) |
| 1358 | #ifndef NEW_STYLE_FS | 1353 | return; |
| 1359 | if (f->want_fullscreen == FULLSCREEN_BOTH) | 1354 | |
| 1355 | if (! [view fsIsNative] && f->want_fullscreen == FULLSCREEN_BOTH) | ||
| 1360 | { | 1356 | { |
| 1361 | /* Old style fs don't initiate correctly if created from | 1357 | /* Old style fs don't initiate correctly if created from |
| 1362 | init/default-frame alist, so use a timer (not nice...). | 1358 | init/default-frame alist, so use a timer (not nice...). |
| @@ -1366,7 +1362,6 @@ ns_fullscreen_hook (FRAME_PTR f) | |||
| 1366 | userInfo: nil repeats: NO]; | 1362 | userInfo: nil repeats: NO]; |
| 1367 | return; | 1363 | return; |
| 1368 | } | 1364 | } |
| 1369 | #endif | ||
| 1370 | 1365 | ||
| 1371 | block_input (); | 1366 | block_input (); |
| 1372 | [view handleFS]; | 1367 | [view handleFS]; |
| @@ -2566,7 +2561,7 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr) | |||
| 2566 | Draw a wavy line under glyph string s. The wave fills wave_height | 2561 | Draw a wavy line under glyph string s. The wave fills wave_height |
| 2567 | pixels from y. | 2562 | pixels from y. |
| 2568 | 2563 | ||
| 2569 | x wave_length = 3 | 2564 | x wave_length = 2 |
| 2570 | -- | 2565 | -- |
| 2571 | y * * * * * | 2566 | y * * * * * |
| 2572 | |* * * * * * * * * | 2567 | |* * * * * * * * * |
| @@ -2576,14 +2571,14 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr) | |||
| 2576 | static void | 2571 | static void |
| 2577 | ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) | 2572 | ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) |
| 2578 | { | 2573 | { |
| 2579 | int wave_height = 3, wave_length = 3; | 2574 | int wave_height = 3, wave_length = 2; |
| 2580 | int y, dx, dy, odd, xmax; | 2575 | int y, dx, dy, odd, xmax; |
| 2581 | NSPoint a, b; | 2576 | NSPoint a, b; |
| 2582 | NSRect waveClip; | 2577 | NSRect waveClip; |
| 2583 | 2578 | ||
| 2584 | dx = wave_length; | 2579 | dx = wave_length; |
| 2585 | dy = wave_height - 1; | 2580 | dy = wave_height - 1; |
| 2586 | y = s->ybase + 1; | 2581 | y = s->ybase - wave_height + 3; |
| 2587 | xmax = x + width; | 2582 | xmax = x + width; |
| 2588 | 2583 | ||
| 2589 | /* Find and set clipping rectangle */ | 2584 | /* Find and set clipping rectangle */ |
| @@ -2592,10 +2587,10 @@ ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) | |||
| 2592 | NSRectClip (waveClip); | 2587 | NSRectClip (waveClip); |
| 2593 | 2588 | ||
| 2594 | /* Draw the waves */ | 2589 | /* Draw the waves */ |
| 2595 | a.x = x - ((int)(x) % dx); | 2590 | a.x = x - ((int)(x) % dx) + 0.5; |
| 2596 | b.x = a.x + dx; | 2591 | b.x = a.x + dx; |
| 2597 | odd = (int)(a.x/dx) % 2; | 2592 | odd = (int)(a.x/dx) % 2; |
| 2598 | a.y = b.y = y; | 2593 | a.y = b.y = y + 0.5; |
| 2599 | 2594 | ||
| 2600 | if (odd) | 2595 | if (odd) |
| 2601 | a.y += dy; | 2596 | a.y += dy; |
| @@ -2606,7 +2601,7 @@ ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) | |||
| 2606 | { | 2601 | { |
| 2607 | [NSBezierPath strokeLineFromPoint:a toPoint:b]; | 2602 | [NSBezierPath strokeLineFromPoint:a toPoint:b]; |
| 2608 | a.x = b.x, a.y = b.y; | 2603 | a.x = b.x, a.y = b.y; |
| 2609 | b.x += dx, b.y = y + odd*dy; | 2604 | b.x += dx, b.y = y + 0.5 + odd*dy; |
| 2610 | odd = !odd; | 2605 | odd = !odd; |
| 2611 | } | 2606 | } |
| 2612 | 2607 | ||
| @@ -2646,6 +2641,7 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, | |||
| 2646 | 2641 | ||
| 2647 | /* If the prev was underlined, match its appearance. */ | 2642 | /* If the prev was underlined, match its appearance. */ |
| 2648 | if (s->prev && s->prev->face->underline_p | 2643 | if (s->prev && s->prev->face->underline_p |
| 2644 | && s->prev->face->underline_type == FACE_UNDER_LINE | ||
| 2649 | && s->prev->underline_thickness > 0) | 2645 | && s->prev->underline_thickness > 0) |
| 2650 | { | 2646 | { |
| 2651 | thickness = s->prev->underline_thickness; | 2647 | thickness = s->prev->underline_thickness; |
| @@ -3368,6 +3364,30 @@ ns_send_appdefined (int value) | |||
| 3368 | } | 3364 | } |
| 3369 | } | 3365 | } |
| 3370 | 3366 | ||
| 3367 | #ifdef HAVE_NATIVE_FS | ||
| 3368 | static void | ||
| 3369 | check_native_fs () | ||
| 3370 | { | ||
| 3371 | Lisp_Object frame, tail; | ||
| 3372 | |||
| 3373 | if (ns_last_use_native_fullscreen == ns_use_native_fullscreen) | ||
| 3374 | return; | ||
| 3375 | |||
| 3376 | ns_last_use_native_fullscreen = ns_use_native_fullscreen; | ||
| 3377 | |||
| 3378 | /* Clear the mouse-moved flag for every frame on this display. */ | ||
| 3379 | FOR_EACH_FRAME (tail, frame) | ||
| 3380 | { | ||
| 3381 | struct frame *f = XFRAME (frame); | ||
| 3382 | if (FRAME_NS_P (f)) | ||
| 3383 | { | ||
| 3384 | EmacsView *view = FRAME_NS_VIEW (f); | ||
| 3385 | [view updateCollectionBehaviour]; | ||
| 3386 | } | ||
| 3387 | } | ||
| 3388 | } | ||
| 3389 | #endif | ||
| 3390 | |||
| 3371 | static int | 3391 | static int |
| 3372 | ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | 3392 | ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) |
| 3373 | /* -------------------------------------------------------------------------- | 3393 | /* -------------------------------------------------------------------------- |
| @@ -3381,6 +3401,10 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 3381 | 3401 | ||
| 3382 | /* NSTRACE (ns_read_socket); */ | 3402 | /* NSTRACE (ns_read_socket); */ |
| 3383 | 3403 | ||
| 3404 | #ifdef HAVE_NATIVE_FS | ||
| 3405 | check_native_fs (); | ||
| 3406 | #endif | ||
| 3407 | |||
| 3384 | if ([NSApp modalWindow] != nil) | 3408 | if ([NSApp modalWindow] != nil) |
| 3385 | return -1; | 3409 | return -1; |
| 3386 | 3410 | ||
| @@ -3458,6 +3482,10 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 3458 | 3482 | ||
| 3459 | /* NSTRACE (ns_select); */ | 3483 | /* NSTRACE (ns_select); */ |
| 3460 | 3484 | ||
| 3485 | #ifdef HAVE_NATIVE_FS | ||
| 3486 | check_native_fs (); | ||
| 3487 | #endif | ||
| 3488 | |||
| 3461 | if (hold_event_q.nr > 0) | 3489 | if (hold_event_q.nr > 0) |
| 3462 | { | 3490 | { |
| 3463 | /* We already have events pending. */ | 3491 | /* We already have events pending. */ |
| @@ -3676,7 +3704,7 @@ ns_set_vertical_scroll_bar (struct window *window, | |||
| 3676 | } | 3704 | } |
| 3677 | 3705 | ||
| 3678 | bar = [[EmacsScroller alloc] initFrame: r window: win]; | 3706 | bar = [[EmacsScroller alloc] initFrame: r window: win]; |
| 3679 | wset_vertical_scroll_bar (window, make_save_value (bar, 0)); | 3707 | wset_vertical_scroll_bar (window, make_save_pointer (bar)); |
| 3680 | } | 3708 | } |
| 3681 | else | 3709 | else |
| 3682 | { | 3710 | { |
| @@ -4237,11 +4265,9 @@ ns_term_init (Lisp_Object display_name) | |||
| 4237 | NSColorPboardType, | 4265 | NSColorPboardType, |
| 4238 | NSFontPboardType, nil] retain]; | 4266 | NSFontPboardType, nil] retain]; |
| 4239 | 4267 | ||
| 4240 | #ifndef NEW_STYLE_FS | ||
| 4241 | /* If fullscreen is in init/default-frame-alist, focus isn't set | 4268 | /* If fullscreen is in init/default-frame-alist, focus isn't set |
| 4242 | right for fullscreen windows, so set this. */ | 4269 | right for fullscreen windows, so set this. */ |
| 4243 | [NSApp activateIgnoringOtherApps:YES]; | 4270 | [NSApp activateIgnoringOtherApps:YES]; |
| 4244 | #endif | ||
| 4245 | 4271 | ||
| 4246 | [NSApp run]; | 4272 | [NSApp run]; |
| 4247 | ns_do_open_file = YES; | 4273 | ns_do_open_file = YES; |
| @@ -4575,7 +4601,7 @@ not_in_argv (NSString *arg) | |||
| 4575 | if (waiting) | 4601 | if (waiting) |
| 4576 | { | 4602 | { |
| 4577 | SELECT_TYPE fds; | 4603 | SELECT_TYPE fds; |
| 4578 | 4604 | FD_ZERO (&fds); | |
| 4579 | FD_SET (selfds[0], &fds); | 4605 | FD_SET (selfds[0], &fds); |
| 4580 | result = select (selfds[0]+1, &fds, NULL, NULL, NULL); | 4606 | result = select (selfds[0]+1, &fds, NULL, NULL, NULL); |
| 4581 | if (result > 0 && read (selfds[0], &c, 1) == 1 && c == 'g') | 4607 | if (result > 0 && read (selfds[0], &c, 1) == 1 && c == 'g') |
| @@ -4980,6 +5006,7 @@ not_in_argv (NSString *arg) | |||
| 4980 | 5006 | ||
| 4981 | emacs_event->code = code; | 5007 | emacs_event->code = code; |
| 4982 | EV_TRAILER (theEvent); | 5008 | EV_TRAILER (theEvent); |
| 5009 | processingCompose = NO; | ||
| 4983 | return; | 5010 | return; |
| 4984 | } | 5011 | } |
| 4985 | } | 5012 | } |
| @@ -5170,6 +5197,7 @@ not_in_argv (NSString *arg) | |||
| 5170 | if (NS_KEYLOG) | 5197 | if (NS_KEYLOG) |
| 5171 | NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector)); | 5198 | NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector)); |
| 5172 | 5199 | ||
| 5200 | processingCompose = NO; | ||
| 5173 | if (aSelector == @selector (deleteBackward:)) | 5201 | if (aSelector == @selector (deleteBackward:)) |
| 5174 | { | 5202 | { |
| 5175 | /* happens when user backspaces over an ongoing composition: | 5203 | /* happens when user backspaces over an ongoing composition: |
| @@ -5388,10 +5416,10 @@ not_in_argv (NSString *arg) | |||
| 5388 | { | 5416 | { |
| 5389 | NSWindow *window = [self window]; | 5417 | NSWindow *window = [self window]; |
| 5390 | NSRect wr = [window frame]; | 5418 | NSRect wr = [window frame]; |
| 5391 | #ifdef NS_IMPL_GNUSTEP | ||
| 5392 | int extra = 3; | ||
| 5393 | #else | ||
| 5394 | int extra = 0; | 5419 | int extra = 0; |
| 5420 | int gsextra = 0; | ||
| 5421 | #ifdef NS_IMPL_GNUSTEP | ||
| 5422 | gsextra = 3; | ||
| 5395 | #endif | 5423 | #endif |
| 5396 | 5424 | ||
| 5397 | int oldc = cols, oldr = rows; | 5425 | int oldc = cols, oldr = rows; |
| @@ -5399,23 +5427,24 @@ not_in_argv (NSString *arg) | |||
| 5399 | oldh = FRAME_PIXEL_HEIGHT (emacsframe); | 5427 | oldh = FRAME_PIXEL_HEIGHT (emacsframe); |
| 5400 | int neww, newh; | 5428 | int neww, newh; |
| 5401 | 5429 | ||
| 5402 | cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, wr.size.width + extra); | 5430 | cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, wr.size.width + gsextra); |
| 5403 | 5431 | ||
| 5404 | if (cols < MINWIDTH) | 5432 | if (cols < MINWIDTH) |
| 5405 | cols = MINWIDTH; | 5433 | cols = MINWIDTH; |
| 5406 | 5434 | ||
| 5407 | rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES | 5435 | if (! [self isFullscreen]) |
| 5408 | (emacsframe, wr.size.height | 5436 | { |
| 5409 | - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) + extra | 5437 | extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) |
| 5410 | - FRAME_TOOLBAR_HEIGHT (emacsframe)); | 5438 | + FRAME_TOOLBAR_HEIGHT (emacsframe) - gsextra; |
| 5439 | } | ||
| 5440 | |||
| 5441 | rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, wr.size.height - extra); | ||
| 5411 | 5442 | ||
| 5412 | if (rows < MINHEIGHT) | 5443 | if (rows < MINHEIGHT) |
| 5413 | rows = MINHEIGHT; | 5444 | rows = MINHEIGHT; |
| 5414 | 5445 | ||
| 5415 | neww = (int)wr.size.width - emacsframe->border_width; | 5446 | neww = (int)wr.size.width - emacsframe->border_width; |
| 5416 | newh = ((int)wr.size.height | 5447 | newh = (int)wr.size.height - extra; |
| 5417 | - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) | ||
| 5418 | - FRAME_TOOLBAR_HEIGHT (emacsframe)); | ||
| 5419 | 5448 | ||
| 5420 | if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) | 5449 | if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) |
| 5421 | { | 5450 | { |
| @@ -5433,6 +5462,12 @@ not_in_argv (NSString *arg) | |||
| 5433 | - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize | 5462 | - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize |
| 5434 | /* normalize frame to gridded text size */ | 5463 | /* normalize frame to gridded text size */ |
| 5435 | { | 5464 | { |
| 5465 | int extra = 0; | ||
| 5466 | int gsextra = 0; | ||
| 5467 | #ifdef NS_IMPL_GNUSTEP | ||
| 5468 | gsextra = 3; | ||
| 5469 | #endif | ||
| 5470 | |||
| 5436 | NSTRACE (windowWillResize); | 5471 | NSTRACE (windowWillResize); |
| 5437 | /*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */ | 5472 | /*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */ |
| 5438 | 5473 | ||
| @@ -5450,22 +5485,12 @@ not_in_argv (NSString *arg) | |||
| 5450 | maximized_width = maximized_height = -1; | 5485 | maximized_width = maximized_height = -1; |
| 5451 | 5486 | ||
| 5452 | cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, | 5487 | cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, |
| 5453 | #ifdef NS_IMPL_GNUSTEP | 5488 | frameSize.width + gsextra); |
| 5454 | frameSize.width + 3); | ||
| 5455 | #else | ||
| 5456 | frameSize.width); | ||
| 5457 | #endif | ||
| 5458 | if (cols < MINWIDTH) | 5489 | if (cols < MINWIDTH) |
| 5459 | cols = MINWIDTH; | 5490 | cols = MINWIDTH; |
| 5460 | 5491 | ||
| 5461 | rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, frameSize.height | 5492 | rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, |
| 5462 | #ifdef NS_IMPL_GNUSTEP | 5493 | frameSize.height - extra); |
| 5463 | - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) + 3 | ||
| 5464 | - FRAME_TOOLBAR_HEIGHT (emacsframe)); | ||
| 5465 | #else | ||
| 5466 | - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) | ||
| 5467 | - FRAME_TOOLBAR_HEIGHT (emacsframe)); | ||
| 5468 | #endif | ||
| 5469 | if (rows < MINHEIGHT) | 5494 | if (rows < MINHEIGHT) |
| 5470 | rows = MINHEIGHT; | 5495 | rows = MINHEIGHT; |
| 5471 | #ifdef NS_IMPL_COCOA | 5496 | #ifdef NS_IMPL_COCOA |
| @@ -5508,12 +5533,13 @@ not_in_argv (NSString *arg) | |||
| 5508 | 5533 | ||
| 5509 | - (void)windowDidResize: (NSNotification *)notification | 5534 | - (void)windowDidResize: (NSNotification *)notification |
| 5510 | { | 5535 | { |
| 5511 | 5536 | if (! [self fsIsNative]) | |
| 5512 | #if !defined (NEW_STYLE_FS) && ! defined (NS_IMPL_GNUSTEP) | 5537 | { |
| 5513 | NSWindow *theWindow = [notification object]; | 5538 | NSWindow *theWindow = [notification object]; |
| 5514 | /* We can get notification on the non-FS window when in fullscreen mode. */ | 5539 | /* We can get notification on the non-FS window when in |
| 5515 | if ([self window] != theWindow) return; | 5540 | fullscreen mode. */ |
| 5516 | #endif | 5541 | if ([self window] != theWindow) return; |
| 5542 | } | ||
| 5517 | 5543 | ||
| 5518 | #ifdef NS_IMPL_GNUSTEP | 5544 | #ifdef NS_IMPL_GNUSTEP |
| 5519 | NSWindow *theWindow = [notification object]; | 5545 | NSWindow *theWindow = [notification object]; |
| @@ -5629,6 +5655,11 @@ not_in_argv (NSString *arg) | |||
| 5629 | scrollbarsNeedingUpdate = 0; | 5655 | scrollbarsNeedingUpdate = 0; |
| 5630 | fs_state = FULLSCREEN_NONE; | 5656 | fs_state = FULLSCREEN_NONE; |
| 5631 | fs_before_fs = next_maximized = -1; | 5657 | fs_before_fs = next_maximized = -1; |
| 5658 | #ifdef HAVE_NATIVE_FS | ||
| 5659 | fs_is_native = ns_use_native_fullscreen; | ||
| 5660 | #else | ||
| 5661 | fs_is_native = NO; | ||
| 5662 | #endif | ||
| 5632 | maximized_width = maximized_height = -1; | 5663 | maximized_width = maximized_height = -1; |
| 5633 | nonfs_window = nil; | 5664 | nonfs_window = nil; |
| 5634 | 5665 | ||
| @@ -5655,7 +5686,7 @@ not_in_argv (NSString *arg) | |||
| 5655 | backing: NSBackingStoreBuffered | 5686 | backing: NSBackingStoreBuffered |
| 5656 | defer: YES]; | 5687 | defer: YES]; |
| 5657 | 5688 | ||
| 5658 | #ifdef NEW_STYLE_FS | 5689 | #ifdef HAVE_NATIVE_FS |
| 5659 | [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; | 5690 | [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; |
| 5660 | #endif | 5691 | #endif |
| 5661 | 5692 | ||
| @@ -5821,13 +5852,14 @@ not_in_argv (NSString *arg) | |||
| 5821 | NSTRACE (windowDidDeminiaturize); | 5852 | NSTRACE (windowDidDeminiaturize); |
| 5822 | if (!emacsframe->output_data.ns) | 5853 | if (!emacsframe->output_data.ns) |
| 5823 | return; | 5854 | return; |
| 5824 | emacsframe->async_iconified = 0; | 5855 | |
| 5825 | emacsframe->async_visible = 1; | 5856 | SET_FRAME_ICONIFIED (emacsframe, 0); |
| 5857 | SET_FRAME_VISIBLE (emacsframe, 1); | ||
| 5826 | windows_or_buffers_changed++; | 5858 | windows_or_buffers_changed++; |
| 5827 | 5859 | ||
| 5828 | if (emacs_event) | 5860 | if (emacs_event) |
| 5829 | { | 5861 | { |
| 5830 | emacs_event->kind = ICONIFY_EVENT; | 5862 | emacs_event->kind = DEICONIFY_EVENT; |
| 5831 | EV_TRAILER ((id)nil); | 5863 | EV_TRAILER ((id)nil); |
| 5832 | } | 5864 | } |
| 5833 | } | 5865 | } |
| @@ -5838,7 +5870,8 @@ not_in_argv (NSString *arg) | |||
| 5838 | NSTRACE (windowDidExpose); | 5870 | NSTRACE (windowDidExpose); |
| 5839 | if (!emacsframe->output_data.ns) | 5871 | if (!emacsframe->output_data.ns) |
| 5840 | return; | 5872 | return; |
| 5841 | emacsframe->async_visible = 1; | 5873 | |
| 5874 | SET_FRAME_VISIBLE (emacsframe, 1); | ||
| 5842 | SET_FRAME_GARBAGED (emacsframe); | 5875 | SET_FRAME_GARBAGED (emacsframe); |
| 5843 | 5876 | ||
| 5844 | if (send_appdefined) | 5877 | if (send_appdefined) |
| @@ -5852,8 +5885,8 @@ not_in_argv (NSString *arg) | |||
| 5852 | if (!emacsframe->output_data.ns) | 5885 | if (!emacsframe->output_data.ns) |
| 5853 | return; | 5886 | return; |
| 5854 | 5887 | ||
| 5855 | emacsframe->async_iconified = 1; | 5888 | SET_FRAME_ICONIFIED (emacsframe, 1); |
| 5856 | emacsframe->async_visible = 0; | 5889 | SET_FRAME_VISIBLE (emacsframe, 0); |
| 5857 | 5890 | ||
| 5858 | if (emacs_event) | 5891 | if (emacs_event) |
| 5859 | { | 5892 | { |
| @@ -5862,6 +5895,15 @@ not_in_argv (NSString *arg) | |||
| 5862 | } | 5895 | } |
| 5863 | } | 5896 | } |
| 5864 | 5897 | ||
| 5898 | #ifdef HAVE_NATIVE_FS | ||
| 5899 | - (NSApplicationPresentationOptions)window:(NSWindow *)window | ||
| 5900 | willUseFullScreenPresentationOptions: | ||
| 5901 | (NSApplicationPresentationOptions)proposedOptions | ||
| 5902 | { | ||
| 5903 | return proposedOptions|NSApplicationPresentationAutoHideToolbar; | ||
| 5904 | } | ||
| 5905 | #endif | ||
| 5906 | |||
| 5865 | - (void)windowWillEnterFullScreen:(NSNotification *)notification | 5907 | - (void)windowWillEnterFullScreen:(NSNotification *)notification |
| 5866 | { | 5908 | { |
| 5867 | fs_before_fs = fs_state; | 5909 | fs_before_fs = fs_state; |
| @@ -5870,17 +5912,13 @@ not_in_argv (NSString *arg) | |||
| 5870 | - (void)windowDidEnterFullScreen:(NSNotification *)notification | 5912 | - (void)windowDidEnterFullScreen:(NSNotification *)notification |
| 5871 | { | 5913 | { |
| 5872 | [self setFSValue: FULLSCREEN_BOTH]; | 5914 | [self setFSValue: FULLSCREEN_BOTH]; |
| 5873 | #ifdef NEW_STYLE_FS | 5915 | if (! [self fsIsNative]) |
| 5874 | // Fix bad background. | ||
| 5875 | if ([toolbar isVisible]) | ||
| 5876 | { | 5916 | { |
| 5877 | [toolbar setVisible:NO]; | 5917 | [self windowDidBecomeKey:notification]; |
| 5878 | [toolbar setVisible:YES]; | 5918 | [nonfs_window orderOut:self]; |
| 5879 | } | 5919 | } |
| 5880 | #else | 5920 | else if (! FRAME_EXTERNAL_TOOL_BAR (emacsframe)) |
| 5881 | [self windowDidBecomeKey:notification]; | 5921 | [toolbar setVisible:NO]; |
| 5882 | [nonfs_window orderOut:self]; | ||
| 5883 | #endif | ||
| 5884 | } | 5922 | } |
| 5885 | 5923 | ||
| 5886 | - (void)windowWillExitFullScreen:(NSNotification *)notification | 5924 | - (void)windowWillExitFullScreen:(NSNotification *)notification |
| @@ -5893,24 +5931,76 @@ not_in_argv (NSString *arg) | |||
| 5893 | { | 5931 | { |
| 5894 | [self setFSValue: fs_before_fs]; | 5932 | [self setFSValue: fs_before_fs]; |
| 5895 | fs_before_fs = -1; | 5933 | fs_before_fs = -1; |
| 5934 | [self updateCollectionBehaviour]; | ||
| 5935 | if (FRAME_EXTERNAL_TOOL_BAR (emacsframe)) | ||
| 5936 | { | ||
| 5937 | [toolbar setVisible:YES]; | ||
| 5938 | update_frame_tool_bar (emacsframe); | ||
| 5939 | [self updateFrameSize:YES]; | ||
| 5940 | [[self window] display]; | ||
| 5941 | } | ||
| 5942 | else | ||
| 5943 | [toolbar setVisible:NO]; | ||
| 5944 | |||
| 5896 | if (next_maximized != -1) | 5945 | if (next_maximized != -1) |
| 5897 | [[self window] performZoom:self]; | 5946 | [[self window] performZoom:self]; |
| 5898 | } | 5947 | } |
| 5899 | 5948 | ||
| 5900 | - (void)toggleFullScreen: (id)sender | 5949 | - (BOOL)fsIsNative |
| 5950 | { | ||
| 5951 | return fs_is_native; | ||
| 5952 | } | ||
| 5953 | |||
| 5954 | - (BOOL)isFullscreen | ||
| 5901 | { | 5955 | { |
| 5902 | #ifdef NEW_STYLE_FS | 5956 | if (! fs_is_native) return nonfs_window != nil; |
| 5903 | [[self window] toggleFullScreen:sender]; | 5957 | #ifdef HAVE_NATIVE_FS |
| 5958 | return ([[self window] styleMask] & NSFullScreenWindowMask) != 0; | ||
| 5904 | #else | 5959 | #else |
| 5905 | NSWindow *w = [self window], *fw; | 5960 | return NO; |
| 5906 | BOOL onFirstScreen = [[w screen] | 5961 | #endif |
| 5907 | isEqual:[[NSScreen screens] objectAtIndex:0]]; | 5962 | } |
| 5908 | struct frame *f = emacsframe; | 5963 | |
| 5964 | #ifdef HAVE_NATIVE_FS | ||
| 5965 | - (void)updateCollectionBehaviour | ||
| 5966 | { | ||
| 5967 | if (! [self isFullscreen]) | ||
| 5968 | { | ||
| 5969 | NSWindow *win = [self window]; | ||
| 5970 | NSWindowCollectionBehavior b = [win collectionBehavior]; | ||
| 5971 | if (ns_use_native_fullscreen) | ||
| 5972 | b |= NSWindowCollectionBehaviorFullScreenPrimary; | ||
| 5973 | else | ||
| 5974 | b &= ~NSWindowCollectionBehaviorFullScreenPrimary; | ||
| 5975 | |||
| 5976 | [win setCollectionBehavior: b]; | ||
| 5977 | fs_is_native = ns_use_native_fullscreen; | ||
| 5978 | } | ||
| 5979 | } | ||
| 5980 | #endif | ||
| 5981 | |||
| 5982 | - (void)toggleFullScreen: (id)sender | ||
| 5983 | { | ||
| 5984 | NSWindow *w, *fw; | ||
| 5985 | BOOL onFirstScreen; | ||
| 5986 | struct frame *f; | ||
| 5909 | NSSize sz; | 5987 | NSSize sz; |
| 5910 | NSRect r, wr = [w frame]; | 5988 | NSRect r, wr; |
| 5911 | NSColor *col = ns_lookup_indexed_color (NS_FACE_BACKGROUND | 5989 | NSColor *col; |
| 5912 | (FRAME_DEFAULT_FACE (f)), | 5990 | |
| 5913 | f); | 5991 | if (fs_is_native) |
| 5992 | { | ||
| 5993 | [[self window] toggleFullScreen:sender]; | ||
| 5994 | return; | ||
| 5995 | } | ||
| 5996 | |||
| 5997 | w = [self window]; | ||
| 5998 | onFirstScreen = [[w screen] isEqual:[[NSScreen screens] objectAtIndex:0]]; | ||
| 5999 | f = emacsframe; | ||
| 6000 | wr = [w frame]; | ||
| 6001 | col = ns_lookup_indexed_color (NS_FACE_BACKGROUND | ||
| 6002 | (FRAME_DEFAULT_FACE (f)), | ||
| 6003 | f); | ||
| 5914 | 6004 | ||
| 5915 | sz.width = FRAME_COLUMN_WIDTH (f); | 6005 | sz.width = FRAME_COLUMN_WIDTH (f); |
| 5916 | sz.height = FRAME_LINE_HEIGHT (f); | 6006 | sz.height = FRAME_LINE_HEIGHT (f); |
| @@ -5953,7 +6043,6 @@ not_in_argv (NSString *arg) | |||
| 5953 | FRAME_NS_TITLEBAR_HEIGHT (f) = 0; | 6043 | FRAME_NS_TITLEBAR_HEIGHT (f) = 0; |
| 5954 | tobar_height = FRAME_TOOLBAR_HEIGHT (f); | 6044 | tobar_height = FRAME_TOOLBAR_HEIGHT (f); |
| 5955 | FRAME_TOOLBAR_HEIGHT (f) = 0; | 6045 | FRAME_TOOLBAR_HEIGHT (f) = 0; |
| 5956 | FRAME_EXTERNAL_TOOL_BAR (f) = 0; | ||
| 5957 | 6046 | ||
| 5958 | nonfs_window = w; | 6047 | nonfs_window = w; |
| 5959 | 6048 | ||
| @@ -5990,17 +6079,16 @@ not_in_argv (NSString *arg) | |||
| 5990 | 6079 | ||
| 5991 | f->border_width = bwidth; | 6080 | f->border_width = bwidth; |
| 5992 | FRAME_NS_TITLEBAR_HEIGHT (f) = tibar_height; | 6081 | FRAME_NS_TITLEBAR_HEIGHT (f) = tibar_height; |
| 5993 | FRAME_TOOLBAR_HEIGHT (f) = tobar_height; | 6082 | if (FRAME_EXTERNAL_TOOL_BAR (f)) |
| 5994 | if (tobar_height) | 6083 | FRAME_TOOLBAR_HEIGHT (f) = tobar_height; |
| 5995 | FRAME_EXTERNAL_TOOL_BAR (f) = 1; | ||
| 5996 | 6084 | ||
| 5997 | [self windowWillExitFullScreen:nil]; | 6085 | [self windowWillExitFullScreen:nil]; |
| 5998 | [fw setFrame: [w frame] display:YES animate:YES]; | 6086 | [fw setFrame: [w frame] display:YES animate:YES]; |
| 5999 | [fw close]; | 6087 | [fw close]; |
| 6000 | [w makeKeyAndOrderFront:NSApp]; | 6088 | [w makeKeyAndOrderFront:NSApp]; |
| 6001 | [self windowDidExitFullScreen:nil]; | 6089 | [self windowDidExitFullScreen:nil]; |
| 6090 | [self updateFrameSize:YES]; | ||
| 6002 | } | 6091 | } |
| 6003 | #endif | ||
| 6004 | } | 6092 | } |
| 6005 | 6093 | ||
| 6006 | - (void)handleFS | 6094 | - (void)handleFS |
| @@ -7154,6 +7242,18 @@ allowing it to be used at a lower level for accented character entry."); | |||
| 7154 | Only works on OSX 10.6 or later. */); | 7242 | Only works on OSX 10.6 or later. */); |
| 7155 | ns_auto_hide_menu_bar = Qnil; | 7243 | ns_auto_hide_menu_bar = Qnil; |
| 7156 | 7244 | ||
| 7245 | DEFVAR_BOOL ("ns-use-native-fullscreen", ns_use_native_fullscreen, | ||
| 7246 | doc: /*Non-nil means to use native fullscreen on OSX >= 10.7. | ||
| 7247 | Nil means use fullscreen the old (< 10.7) way. The old way works better with | ||
| 7248 | multiple monitors, but lacks tool bar. This variable is ignored on OSX < 10.7. | ||
| 7249 | Default is t for OSX >= 10.7, nil otherwise. */); | ||
| 7250 | #ifdef HAVE_NATIVE_FS | ||
| 7251 | ns_use_native_fullscreen = YES; | ||
| 7252 | #else | ||
| 7253 | ns_use_native_fullscreen = NO; | ||
| 7254 | #endif | ||
| 7255 | ns_last_use_native_fullscreen = ns_use_native_fullscreen; | ||
| 7256 | |||
| 7157 | /* TODO: move to common code */ | 7257 | /* TODO: move to common code */ |
| 7158 | DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars, | 7258 | DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars, |
| 7159 | doc: /* Which toolkit scroll bars Emacs uses, if any. | 7259 | doc: /* Which toolkit scroll bars Emacs uses, if any. |
diff --git a/src/pre-crt0.c b/src/pre-crt0.c index ea5736eba2a..6b9618c8dc3 100644 --- a/src/pre-crt0.c +++ b/src/pre-crt0.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | that make environ an initialized variable. However, we do | 4 | that make environ an initialized variable. However, we do |
| 5 | need to make sure the label data_start exists anyway. */ | 5 | need to make sure the label data_start exists anyway. */ |
| 6 | 6 | ||
| 7 | /* Create a label to appear at the beginning of data space. */ | 7 | /* Create a label to appear at the beginning of data space. |
| 8 | 8 | Its value is nonzero so that it cannot be put into bss. */ | |
| 9 | int data_start = 0; | ||
| 10 | 9 | ||
| 10 | int data_start = 1; | ||
diff --git a/src/print.c b/src/print.c index bf86be5622e..4aae4118152 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Lisp object printing and output streams. | 1 | /* Lisp object printing and output streams. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2012 | 3 | Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -102,7 +102,8 @@ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; | |||
| 102 | ptrdiff_t old_point_byte = -1, start_point_byte = -1; \ | 102 | ptrdiff_t old_point_byte = -1, start_point_byte = -1; \ |
| 103 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); \ | 103 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); \ |
| 104 | int free_print_buffer = 0; \ | 104 | int free_print_buffer = 0; \ |
| 105 | int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); \ | 105 | bool multibyte \ |
| 106 | = !NILP (BVAR (current_buffer, enable_multibyte_characters)); \ | ||
| 106 | Lisp_Object original | 107 | Lisp_Object original |
| 107 | 108 | ||
| 108 | #define PRINTPREPARE \ | 109 | #define PRINTPREPARE \ |
| @@ -1396,7 +1397,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag | |||
| 1396 | /* 1 means we must ensure that the next character we output | 1397 | /* 1 means we must ensure that the next character we output |
| 1397 | cannot be taken as part of a hex character escape. */ | 1398 | cannot be taken as part of a hex character escape. */ |
| 1398 | int need_nonhex = 0; | 1399 | int need_nonhex = 0; |
| 1399 | int multibyte = STRING_MULTIBYTE (obj); | 1400 | bool multibyte = STRING_MULTIBYTE (obj); |
| 1400 | 1401 | ||
| 1401 | GCPRO1 (obj); | 1402 | GCPRO1 (obj); |
| 1402 | 1403 | ||
| @@ -1766,7 +1767,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag | |||
| 1766 | { | 1767 | { |
| 1767 | int len; | 1768 | int len; |
| 1768 | strout ("#<window ", -1, -1, printcharfun); | 1769 | strout ("#<window ", -1, -1, printcharfun); |
| 1769 | len = sprintf (buf, "%d", XWINDOW (obj)->sequence_number); | 1770 | len = sprintf (buf, "%p", XWINDOW (obj)); |
| 1770 | strout (buf, len, len, printcharfun); | 1771 | strout (buf, len, len, printcharfun); |
| 1771 | if (!NILP (XWINDOW (obj)->buffer)) | 1772 | if (!NILP (XWINDOW (obj)->buffer)) |
| 1772 | { | 1773 | { |
| @@ -2027,21 +2028,96 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag | |||
| 2027 | PRINTCHAR ('>'); | 2028 | PRINTCHAR ('>'); |
| 2028 | break; | 2029 | break; |
| 2029 | 2030 | ||
| 2030 | /* Remaining cases shouldn't happen in normal usage, but let's print | 2031 | /* Remaining cases shouldn't happen in normal usage, but let's |
| 2031 | them anyway for the benefit of the debugger. */ | 2032 | print them anyway for the benefit of the debugger. */ |
| 2033 | |||
| 2032 | case Lisp_Misc_Free: | 2034 | case Lisp_Misc_Free: |
| 2033 | strout ("#<misc free cell>", -1, -1, printcharfun); | 2035 | strout ("#<misc free cell>", -1, -1, printcharfun); |
| 2034 | break; | 2036 | break; |
| 2035 | 2037 | ||
| 2036 | case Lisp_Misc_Save_Value: | 2038 | case Lisp_Misc_Save_Value: |
| 2037 | strout ("#<save_value ", -1, -1, printcharfun); | ||
| 2038 | { | 2039 | { |
| 2039 | int len = sprintf (buf, "ptr=%p int=%"pD"d", | 2040 | int i; |
| 2040 | XSAVE_VALUE (obj)->pointer, | 2041 | struct Lisp_Save_Value *v = XSAVE_VALUE (obj); |
| 2041 | XSAVE_VALUE (obj)->integer); | 2042 | |
| 2042 | strout (buf, len, len, printcharfun); | 2043 | strout ("#<save-value ", -1, -1, printcharfun); |
| 2044 | |||
| 2045 | if (v->area) | ||
| 2046 | { | ||
| 2047 | ptrdiff_t amount = v->data[1].integer; | ||
| 2048 | |||
| 2049 | #if GC_MARK_STACK | ||
| 2050 | |||
| 2051 | /* If GC_MARK_STACK, valid_lisp_object_p is quite reliable, | ||
| 2052 | and so we try to print up to 8 objects we have saved. | ||
| 2053 | Although valid_lisp_object_p is slow, this shouldn't be | ||
| 2054 | a real bottleneck because we do not use this code under | ||
| 2055 | normal circumstances. */ | ||
| 2056 | |||
| 2057 | int limit = min (amount, 8); | ||
| 2058 | Lisp_Object *area = v->data[0].pointer; | ||
| 2059 | |||
| 2060 | i = sprintf (buf, "with %"pD"d objects", amount); | ||
| 2061 | strout (buf, i, i, printcharfun); | ||
| 2062 | |||
| 2063 | for (i = 0; i < limit; i++) | ||
| 2064 | { | ||
| 2065 | Lisp_Object maybe = area[i]; | ||
| 2066 | |||
| 2067 | if (valid_lisp_object_p (maybe) > 0) | ||
| 2068 | { | ||
| 2069 | PRINTCHAR (' '); | ||
| 2070 | print_object (maybe, printcharfun, escapeflag); | ||
| 2071 | } | ||
| 2072 | else | ||
| 2073 | strout (" <invalid>", -1, -1, printcharfun); | ||
| 2074 | } | ||
| 2075 | if (i == limit && i < amount) | ||
| 2076 | strout (" ...", 4, 4, printcharfun); | ||
| 2077 | |||
| 2078 | #else /* not GC_MARK_STACK */ | ||
| 2079 | |||
| 2080 | /* If !GC_MARK_STACK, we have no reliable way to find | ||
| 2081 | whether Lisp_Object pointers points to an initialized | ||
| 2082 | objects, and so we do not ever trying to print them. */ | ||
| 2083 | |||
| 2084 | i = sprintf (buf, "with %"pD"d objects", amount); | ||
| 2085 | strout (buf, i, i, printcharfun); | ||
| 2086 | |||
| 2087 | #endif /* GC_MARK_STACK */ | ||
| 2088 | } | ||
| 2089 | else | ||
| 2090 | { | ||
| 2091 | /* Print each `data[N]' slot according to its type. */ | ||
| 2092 | |||
| 2093 | #define PRINTX(index) \ | ||
| 2094 | do { \ | ||
| 2095 | i = 0; \ | ||
| 2096 | if (v->type ## index == SAVE_UNUSED) \ | ||
| 2097 | i = sprintf (buf, "<unused>"); \ | ||
| 2098 | else if (v->type ## index == SAVE_INTEGER) \ | ||
| 2099 | i = sprintf (buf, "<integer %"pD"d>", v->data[index].integer); \ | ||
| 2100 | else if (v->type ## index == SAVE_POINTER) \ | ||
| 2101 | i = sprintf (buf, "<pointer %p>", v->data[index].pointer); \ | ||
| 2102 | else /* SAVE_OBJECT */ \ | ||
| 2103 | print_object (v->data[index].object, printcharfun, escapeflag); \ | ||
| 2104 | if (i) \ | ||
| 2105 | strout (buf, i, i, printcharfun); \ | ||
| 2106 | } while (0) | ||
| 2107 | |||
| 2108 | PRINTX (0); | ||
| 2109 | PRINTCHAR (' '); | ||
| 2110 | PRINTX (1); | ||
| 2111 | PRINTCHAR (' '); | ||
| 2112 | PRINTX (2); | ||
| 2113 | PRINTCHAR (' '); | ||
| 2114 | PRINTX (3); | ||
| 2115 | |||
| 2116 | #undef PRINTX | ||
| 2117 | |||
| 2118 | } | ||
| 2119 | PRINTCHAR ('>'); | ||
| 2043 | } | 2120 | } |
| 2044 | PRINTCHAR ('>'); | ||
| 2045 | break; | 2121 | break; |
| 2046 | 2122 | ||
| 2047 | default: | 2123 | default: |
diff --git a/src/process.c b/src/process.c index 7b21d060cf8..5b15ade1122 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Asynchronous subprocess control for GNU Emacs. | 1 | /* Asynchronous subprocess control for GNU Emacs. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2012 | 3 | Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -180,10 +180,6 @@ static Lisp_Object Qlast_nonmenu_event; | |||
| 180 | #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial)) | 180 | #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial)) |
| 181 | #define SERIALCONN1_P(p) (EQ (p->type, Qserial)) | 181 | #define SERIALCONN1_P(p) (EQ (p->type, Qserial)) |
| 182 | 182 | ||
| 183 | #ifndef HAVE_H_ERRNO | ||
| 184 | extern int h_errno; | ||
| 185 | #endif | ||
| 186 | |||
| 187 | /* Number of events of change of status of a process. */ | 183 | /* Number of events of change of status of a process. */ |
| 188 | static EMACS_INT process_tick; | 184 | static EMACS_INT process_tick; |
| 189 | /* Number of events for which the user or sentinel has been notified. */ | 185 | /* Number of events for which the user or sentinel has been notified. */ |
| @@ -4222,7 +4218,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4222 | if (time_limit == 0 && nsecs == 0 && wait_proc && !NILP (Vinhibit_quit) | 4218 | if (time_limit == 0 && nsecs == 0 && wait_proc && !NILP (Vinhibit_quit) |
| 4223 | && !(CONSP (wait_proc->status) | 4219 | && !(CONSP (wait_proc->status) |
| 4224 | && EQ (XCAR (wait_proc->status), Qexit))) | 4220 | && EQ (XCAR (wait_proc->status), Qexit))) |
| 4225 | message ("Blocking call to accept-process-output with quit inhibited!!"); | 4221 | message1 ("Blocking call to accept-process-output with quit inhibited!!"); |
| 4226 | 4222 | ||
| 4227 | /* If wait_proc is a process to watch, set wait_channel accordingly. */ | 4223 | /* If wait_proc is a process to watch, set wait_channel accordingly. */ |
| 4228 | if (wait_proc != NULL) | 4224 | if (wait_proc != NULL) |
| @@ -4773,11 +4769,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4773 | Therefore, if we get an error reading and errno = | 4769 | Therefore, if we get an error reading and errno = |
| 4774 | EIO, just continue, because the child process has | 4770 | EIO, just continue, because the child process has |
| 4775 | exited and should clean itself up soon (e.g. when we | 4771 | exited and should clean itself up soon (e.g. when we |
| 4776 | get a SIGCHLD). | 4772 | get a SIGCHLD). */ |
| 4777 | |||
| 4778 | However, it has been known to happen that the SIGCHLD | ||
| 4779 | got lost. So raise the signal again just in case. | ||
| 4780 | It can't hurt. */ | ||
| 4781 | else if (nread == -1 && errno == EIO) | 4773 | else if (nread == -1 && errno == EIO) |
| 4782 | { | 4774 | { |
| 4783 | struct Lisp_Process *p = XPROCESS (proc); | 4775 | struct Lisp_Process *p = XPROCESS (proc); |
| @@ -4795,8 +4787,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4795 | p->tick = ++process_tick; | 4787 | p->tick = ++process_tick; |
| 4796 | pset_status (p, Qfailed); | 4788 | pset_status (p, Qfailed); |
| 4797 | } | 4789 | } |
| 4798 | else | ||
| 4799 | handle_child_signal (SIGCHLD); | ||
| 4800 | } | 4790 | } |
| 4801 | #endif /* HAVE_PTYS */ | 4791 | #endif /* HAVE_PTYS */ |
| 4802 | /* If we can detect process termination, don't consider the | 4792 | /* If we can detect process termination, don't consider the |
| @@ -5562,19 +5552,19 @@ it is sent in several bunches. This may happen even for shorter regions. | |||
| 5562 | Output from processes can arrive in between bunches. */) | 5552 | Output from processes can arrive in between bunches. */) |
| 5563 | (Lisp_Object process, Lisp_Object start, Lisp_Object end) | 5553 | (Lisp_Object process, Lisp_Object start, Lisp_Object end) |
| 5564 | { | 5554 | { |
| 5565 | Lisp_Object proc; | 5555 | Lisp_Object proc = get_process (process); |
| 5566 | ptrdiff_t start1, end1; | 5556 | ptrdiff_t start_byte, end_byte; |
| 5567 | 5557 | ||
| 5568 | proc = get_process (process); | ||
| 5569 | validate_region (&start, &end); | 5558 | validate_region (&start, &end); |
| 5570 | 5559 | ||
| 5560 | start_byte = CHAR_TO_BYTE (XINT (start)); | ||
| 5561 | end_byte = CHAR_TO_BYTE (XINT (end)); | ||
| 5562 | |||
| 5571 | if (XINT (start) < GPT && XINT (end) > GPT) | 5563 | if (XINT (start) < GPT && XINT (end) > GPT) |
| 5572 | move_gap (XINT (start)); | 5564 | move_gap_both (XINT (start), start_byte); |
| 5573 | 5565 | ||
| 5574 | start1 = CHAR_TO_BYTE (XINT (start)); | 5566 | send_process (proc, (char *) BYTE_POS_ADDR (start_byte), |
| 5575 | end1 = CHAR_TO_BYTE (XINT (end)); | 5567 | end_byte - start_byte, Fcurrent_buffer ()); |
| 5576 | send_process (proc, (char *) BYTE_POS_ADDR (start1), end1 - start1, | ||
| 5577 | Fcurrent_buffer ()); | ||
| 5578 | 5568 | ||
| 5579 | return Qnil; | 5569 | return Qnil; |
| 5580 | } | 5570 | } |
diff --git a/src/process.h b/src/process.h index a0521689abf..a003ffa147f 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions for asynchronous process control in GNU Emacs. | 1 | /* Definitions for asynchronous process control in GNU Emacs. |
| 2 | Copyright (C) 1985, 1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/profiler.c b/src/profiler.c index 3d8f7243d2f..85d9c1ca88a 100644 --- a/src/profiler.c +++ b/src/profiler.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Profiler implementation. | 1 | /* Profiler implementation. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -560,7 +560,7 @@ hashfn_profiler (struct hash_table_test *ht, Lisp_Object bt) | |||
| 560 | ? XHASH (XCDR (XCDR (f))) : XHASH (f)); | 560 | ? XHASH (XCDR (XCDR (f))) : XHASH (f)); |
| 561 | hash = sxhash_combine (hash, hash1); | 561 | hash = sxhash_combine (hash, hash1); |
| 562 | } | 562 | } |
| 563 | return (hash & INTMASK); | 563 | return SXHASH_REDUCE (hash); |
| 564 | } | 564 | } |
| 565 | else | 565 | else |
| 566 | return XHASH (bt); | 566 | return XHASH (bt); |
diff --git a/src/puresize.h b/src/puresize.h index 26395a5729d..2f717571c7c 100644 --- a/src/puresize.h +++ b/src/puresize.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* How much read-only Lisp storage a dumped Emacs needs. | 1 | /* How much read-only Lisp storage a dumped Emacs needs. |
| 2 | Copyright (C) 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/ralloc.c b/src/ralloc.c index e5bf76b0e6d..ec1ac40414c 100644 --- a/src/ralloc.c +++ b/src/ralloc.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Block-relocating memory allocator. | 1 | /* Block-relocating memory allocator. |
| 2 | Copyright (C) 1993, 1995, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 1995, 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/regex.c b/src/regex.c index 1473551e6cc..051a4fdc26b 100644 --- a/src/regex.c +++ b/src/regex.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 0.12. (Implements POSIX draft P1003.2/D11.2, except for some of the | 2 | 0.12. (Implements POSIX draft P1003.2/D11.2, except for some of the |
| 3 | internationalization features.) | 3 | internationalization features.) |
| 4 | 4 | ||
| 5 | Copyright (C) 1993-2012 Free Software Foundation, Inc. | 5 | Copyright (C) 1993-2013 Free Software Foundation, Inc. |
| 6 | 6 | ||
| 7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by |
| @@ -15,9 +15,7 @@ | |||
| 15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. |
| 16 | 16 | ||
| 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 this program; if not, write to the Free Software | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
| 20 | USA. */ | ||
| 21 | 19 | ||
| 22 | /* TODO: | 20 | /* TODO: |
| 23 | - structure the opcode space into opcode+flag. | 21 | - structure the opcode space into opcode+flag. |
diff --git a/src/regex.h b/src/regex.h index e0ede012b20..f1fd837bd6f 100644 --- a/src/regex.h +++ b/src/regex.h | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* Definitions for data structures and routines for the regular | 1 | /* Definitions for data structures and routines for the regular |
| 2 | expression library, version 0.12. | 2 | expression library, version 0.12. |
| 3 | 3 | ||
| 4 | Copyright (C) 1985, 1989-1993, 1995, 2000-2012 | 4 | Copyright (C) 1985, 1989-1993, 1995, 2000-2013 Free Software |
| 5 | Free Software Foundation, Inc. | 5 | Foundation, Inc. |
| 6 | 6 | ||
| 7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by |
| @@ -15,9 +15,7 @@ | |||
| 15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. |
| 16 | 16 | ||
| 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 this program; if not, write to the Free Software | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
| 20 | USA. */ | ||
| 21 | 19 | ||
| 22 | #ifndef _REGEX_H | 20 | #ifndef _REGEX_H |
| 23 | #define _REGEX_H 1 | 21 | #define _REGEX_H 1 |
diff --git a/src/region-cache.c b/src/region-cache.c index 832f4bfd214..14e6982cd9a 100644 --- a/src/region-cache.c +++ b/src/region-cache.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Caching facts about regions of the buffer, for optimization. | 1 | /* Caching facts about regions of the buffer, for optimization. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1989, 1993, 1995, 2001-2012 | 3 | Copyright (C) 1985-1989, 1993, 1995, 2001-2013 Free Software Foundation, |
| 4 | Free Software Foundation, Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/region-cache.h b/src/region-cache.h index 7aebdbec262..e4c6b59ee95 100644 --- a/src/region-cache.h +++ b/src/region-cache.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Header file: Caching facts about regions of the buffer, for optimization. | 1 | /* Header file: Caching facts about regions of the buffer, for optimization. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993, 1995, 2001-2012 | 3 | Copyright (C) 1985-1986, 1993, 1995, 2001-2013 Free Software Foundation, |
| 4 | Free Software Foundation, Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -40,7 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 40 | existing data structure, and disturb as little of the existing code | 40 | existing data structure, and disturb as little of the existing code |
| 41 | as possible. | 41 | as possible. |
| 42 | 42 | ||
| 43 | So here's the tack. We add some caching to the scan_buffer | 43 | So here's the tack. We add some caching to the find_newline |
| 44 | function, so that when it searches for a newline, it notes that the | 44 | function, so that when it searches for a newline, it notes that the |
| 45 | region between the start and end of the search contained no | 45 | region between the start and end of the search contained no |
| 46 | newlines; then, the next time around, it consults this cache to see | 46 | newlines; then, the next time around, it consults this cache to see |
diff --git a/src/scroll.c b/src/scroll.c index 71ce43b2e48..9e11feb64d4 100644 --- a/src/scroll.c +++ b/src/scroll.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Calculate what line insertion or deletion to do, and do it | 1 | /* Calculate what line insertion or deletion to do, and do it |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1990, 1993-1994, 2001-2012 | 3 | Copyright (C) 1985-1986, 1990, 1993-1994, 2001-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/search.c b/src/search.c index aacdbe33eef..d4508004bf6 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* String search routines for GNU Emacs. | 1 | /* String search routines for GNU Emacs. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1987, 1993-1994, 1997-1999, 2001-2012 | 3 | Copyright (C) 1985-1987, 1993-1994, 1997-1999, 2001-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -209,7 +209,8 @@ clear_regexp_cache (void) | |||
| 209 | for this pattern. 0 means backtrack only enough to get a valid match. */ | 209 | for this pattern. 0 means backtrack only enough to get a valid match. */ |
| 210 | 210 | ||
| 211 | struct re_pattern_buffer * | 211 | struct re_pattern_buffer * |
| 212 | compile_pattern (Lisp_Object pattern, struct re_registers *regp, Lisp_Object translate, int posix, int multibyte) | 212 | compile_pattern (Lisp_Object pattern, struct re_registers *regp, |
| 213 | Lisp_Object translate, int posix, bool multibyte) | ||
| 213 | { | 214 | { |
| 214 | struct regexp_cache *cp, **cpp; | 215 | struct regexp_cache *cp, **cpp; |
| 215 | 216 | ||
| @@ -534,9 +535,10 @@ fast_string_match_ignore_case (Lisp_Object regexp, Lisp_Object string) | |||
| 534 | data. */ | 535 | data. */ |
| 535 | 536 | ||
| 536 | ptrdiff_t | 537 | ptrdiff_t |
| 537 | fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t limit, ptrdiff_t limit_byte, Lisp_Object string) | 538 | fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, |
| 539 | ptrdiff_t limit, ptrdiff_t limit_byte, Lisp_Object string) | ||
| 538 | { | 540 | { |
| 539 | int multibyte; | 541 | bool multibyte; |
| 540 | struct re_pattern_buffer *buf; | 542 | struct re_pattern_buffer *buf; |
| 541 | unsigned char *p1, *p2; | 543 | unsigned char *p1, *p2; |
| 542 | ptrdiff_t s1, s2; | 544 | ptrdiff_t s1, s2; |
| @@ -619,7 +621,7 @@ newline_cache_on_off (struct buffer *buf) | |||
| 619 | } | 621 | } |
| 620 | 622 | ||
| 621 | 623 | ||
| 622 | /* Search for COUNT instances of the character TARGET between START and END. | 624 | /* Search for COUNT newlines between START and END. |
| 623 | 625 | ||
| 624 | If COUNT is positive, search forwards; END must be >= START. | 626 | If COUNT is positive, search forwards; END must be >= START. |
| 625 | If COUNT is negative, search backwards for the -COUNTth instance; | 627 | If COUNT is negative, search backwards for the -COUNTth instance; |
| @@ -634,28 +636,33 @@ newline_cache_on_off (struct buffer *buf) | |||
| 634 | this is not the same as the usual convention for Emacs motion commands. | 636 | this is not the same as the usual convention for Emacs motion commands. |
| 635 | 637 | ||
| 636 | If we don't find COUNT instances before reaching END, set *SHORTAGE | 638 | If we don't find COUNT instances before reaching END, set *SHORTAGE |
| 637 | to the number of TARGETs left unfound, and return END. | 639 | to the number of newlines left unfound, and return END. |
| 638 | 640 | ||
| 639 | If ALLOW_QUIT, set immediate_quit. That's good to do | 641 | If ALLOW_QUIT, set immediate_quit. That's good to do |
| 640 | except when inside redisplay. */ | 642 | except when inside redisplay. */ |
| 641 | 643 | ||
| 642 | ptrdiff_t | 644 | ptrdiff_t |
| 643 | scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | 645 | find_newline (ptrdiff_t start, ptrdiff_t end, |
| 644 | ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) | 646 | ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) |
| 645 | { | 647 | { |
| 646 | struct region_cache *newline_cache; | 648 | struct region_cache *newline_cache; |
| 649 | ptrdiff_t end_byte = -1; | ||
| 647 | int direction; | 650 | int direction; |
| 648 | 651 | ||
| 649 | if (count > 0) | 652 | if (count > 0) |
| 650 | { | 653 | { |
| 651 | direction = 1; | 654 | direction = 1; |
| 652 | if (! end) end = ZV; | 655 | if (!end) |
| 656 | end = ZV, end_byte = ZV_BYTE; | ||
| 653 | } | 657 | } |
| 654 | else | 658 | else |
| 655 | { | 659 | { |
| 656 | direction = -1; | 660 | direction = -1; |
| 657 | if (! end) end = BEGV; | 661 | if (!end) |
| 662 | end = BEGV, end_byte = BEGV_BYTE; | ||
| 658 | } | 663 | } |
| 664 | if (end_byte == -1) | ||
| 665 | end_byte = CHAR_TO_BYTE (end); | ||
| 659 | 666 | ||
| 660 | newline_cache_on_off (current_buffer); | 667 | newline_cache_on_off (current_buffer); |
| 661 | newline_cache = current_buffer->newline_cache; | 668 | newline_cache = current_buffer->newline_cache; |
| @@ -673,13 +680,13 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 673 | the position of the last character before the next such | 680 | the position of the last character before the next such |
| 674 | obstacle --- the last character the dumb search loop should | 681 | obstacle --- the last character the dumb search loop should |
| 675 | examine. */ | 682 | examine. */ |
| 676 | ptrdiff_t ceiling_byte = CHAR_TO_BYTE (end) - 1; | 683 | ptrdiff_t ceiling_byte = end_byte - 1; |
| 677 | ptrdiff_t start_byte; | 684 | ptrdiff_t start_byte; |
| 678 | ptrdiff_t tem; | 685 | ptrdiff_t tem; |
| 679 | 686 | ||
| 680 | /* If we're looking for a newline, consult the newline cache | 687 | /* If we're looking for a newline, consult the newline cache |
| 681 | to see where we can avoid some scanning. */ | 688 | to see where we can avoid some scanning. */ |
| 682 | if (target == '\n' && newline_cache) | 689 | if (newline_cache) |
| 683 | { | 690 | { |
| 684 | ptrdiff_t next_change; | 691 | ptrdiff_t next_change; |
| 685 | immediate_quit = 0; | 692 | immediate_quit = 0; |
| @@ -718,44 +725,44 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 718 | 725 | ||
| 719 | while (cursor < ceiling_addr) | 726 | while (cursor < ceiling_addr) |
| 720 | { | 727 | { |
| 721 | unsigned char *scan_start = cursor; | ||
| 722 | |||
| 723 | /* The dumb loop. */ | 728 | /* The dumb loop. */ |
| 724 | while (*cursor != target && ++cursor < ceiling_addr) | 729 | unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); |
| 725 | ; | ||
| 726 | 730 | ||
| 727 | /* If we're looking for newlines, cache the fact that | 731 | /* If we're looking for newlines, cache the fact that |
| 728 | the region from start to cursor is free of them. */ | 732 | the region from start to cursor is free of them. */ |
| 729 | if (target == '\n' && newline_cache) | 733 | if (newline_cache) |
| 730 | know_region_cache (current_buffer, newline_cache, | 734 | { |
| 731 | BYTE_TO_CHAR (start_byte + scan_start - base), | 735 | unsigned char *low = cursor; |
| 732 | BYTE_TO_CHAR (start_byte + cursor - base)); | 736 | unsigned char *lim = nl ? nl : ceiling_addr; |
| 733 | 737 | know_region_cache (current_buffer, newline_cache, | |
| 734 | /* Did we find the target character? */ | 738 | BYTE_TO_CHAR (low - base + start_byte), |
| 735 | if (cursor < ceiling_addr) | 739 | BYTE_TO_CHAR (lim - base + start_byte)); |
| 736 | { | 740 | } |
| 737 | if (--count == 0) | 741 | |
| 738 | { | 742 | if (! nl) |
| 739 | immediate_quit = 0; | 743 | break; |
| 740 | return BYTE_TO_CHAR (start_byte + cursor - base + 1); | 744 | |
| 741 | } | 745 | if (--count == 0) |
| 742 | cursor++; | 746 | { |
| 743 | } | 747 | immediate_quit = 0; |
| 748 | return BYTE_TO_CHAR (nl + 1 - base + start_byte); | ||
| 749 | } | ||
| 750 | cursor = nl + 1; | ||
| 744 | } | 751 | } |
| 745 | 752 | ||
| 746 | start = BYTE_TO_CHAR (start_byte + cursor - base); | 753 | start = BYTE_TO_CHAR (ceiling_addr - base + start_byte); |
| 747 | } | 754 | } |
| 748 | } | 755 | } |
| 749 | else | 756 | else |
| 750 | while (start > end) | 757 | while (start > end) |
| 751 | { | 758 | { |
| 752 | /* The last character to check before the next obstacle. */ | 759 | /* The last character to check before the next obstacle. */ |
| 753 | ptrdiff_t ceiling_byte = CHAR_TO_BYTE (end); | 760 | ptrdiff_t ceiling_byte = end_byte; |
| 754 | ptrdiff_t start_byte; | 761 | ptrdiff_t start_byte; |
| 755 | ptrdiff_t tem; | 762 | ptrdiff_t tem; |
| 756 | 763 | ||
| 757 | /* Consult the newline cache, if appropriate. */ | 764 | /* Consult the newline cache, if appropriate. */ |
| 758 | if (target == '\n' && newline_cache) | 765 | if (newline_cache) |
| 759 | { | 766 | { |
| 760 | ptrdiff_t next_change; | 767 | ptrdiff_t next_change; |
| 761 | immediate_quit = 0; | 768 | immediate_quit = 0; |
| @@ -789,31 +796,32 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 789 | 796 | ||
| 790 | while (cursor >= ceiling_addr) | 797 | while (cursor >= ceiling_addr) |
| 791 | { | 798 | { |
| 792 | unsigned char *scan_start = cursor; | 799 | unsigned char *nl = memrchr (ceiling_addr, '\n', |
| 793 | 800 | cursor + 1 - ceiling_addr); | |
| 794 | while (*cursor != target && --cursor >= ceiling_addr) | ||
| 795 | ; | ||
| 796 | 801 | ||
| 797 | /* If we're looking for newlines, cache the fact that | 802 | /* If we're looking for newlines, cache the fact that |
| 798 | the region from after the cursor to start is free of them. */ | 803 | the region from after the cursor to start is free of them. */ |
| 799 | if (target == '\n' && newline_cache) | 804 | if (newline_cache) |
| 800 | know_region_cache (current_buffer, newline_cache, | 805 | { |
| 801 | BYTE_TO_CHAR (start_byte + cursor - base), | 806 | unsigned char *low = nl ? nl : ceiling_addr - 1; |
| 802 | BYTE_TO_CHAR (start_byte + scan_start - base)); | 807 | unsigned char *lim = cursor; |
| 803 | 808 | know_region_cache (current_buffer, newline_cache, | |
| 804 | /* Did we find the target character? */ | 809 | BYTE_TO_CHAR (low - base + start_byte), |
| 805 | if (cursor >= ceiling_addr) | 810 | BYTE_TO_CHAR (lim - base + start_byte)); |
| 806 | { | 811 | } |
| 807 | if (++count >= 0) | 812 | |
| 808 | { | 813 | if (! nl) |
| 809 | immediate_quit = 0; | 814 | break; |
| 810 | return BYTE_TO_CHAR (start_byte + cursor - base); | 815 | |
| 811 | } | 816 | if (++count >= 0) |
| 812 | cursor--; | 817 | { |
| 813 | } | 818 | immediate_quit = 0; |
| 819 | return BYTE_TO_CHAR (nl - base + start_byte); | ||
| 820 | } | ||
| 821 | cursor = nl - 1; | ||
| 814 | } | 822 | } |
| 815 | 823 | ||
| 816 | start = BYTE_TO_CHAR (start_byte + cursor - base); | 824 | start = BYTE_TO_CHAR (ceiling_addr - 1 - base + start_byte); |
| 817 | } | 825 | } |
| 818 | } | 826 | } |
| 819 | 827 | ||
| @@ -823,8 +831,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 823 | return start; | 831 | return start; |
| 824 | } | 832 | } |
| 825 | 833 | ||
| 826 | /* Search for COUNT instances of a line boundary, which means either a | 834 | /* Search for COUNT instances of a line boundary. |
| 827 | newline or (if selective display enabled) a carriage return. | ||
| 828 | Start at START. If COUNT is negative, search backwards. | 835 | Start at START. If COUNT is negative, search backwards. |
| 829 | 836 | ||
| 830 | We report the resulting position by calling TEMP_SET_PT_BOTH. | 837 | We report the resulting position by calling TEMP_SET_PT_BOTH. |
| @@ -855,14 +862,9 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 855 | 862 | ||
| 856 | bool old_immediate_quit = immediate_quit; | 863 | bool old_immediate_quit = immediate_quit; |
| 857 | 864 | ||
| 858 | /* The code that follows is like scan_buffer | ||
| 859 | but checks for either newline or carriage return. */ | ||
| 860 | |||
| 861 | if (allow_quit) | 865 | if (allow_quit) |
| 862 | immediate_quit++; | 866 | immediate_quit++; |
| 863 | 867 | ||
| 864 | start_byte = CHAR_TO_BYTE (start); | ||
| 865 | |||
| 866 | if (count > 0) | 868 | if (count > 0) |
| 867 | { | 869 | { |
| 868 | while (start_byte < limit_byte) | 870 | while (start_byte < limit_byte) |
| @@ -871,29 +873,25 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 871 | ceiling = min (limit_byte - 1, ceiling); | 873 | ceiling = min (limit_byte - 1, ceiling); |
| 872 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; | 874 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; |
| 873 | base = (cursor = BYTE_POS_ADDR (start_byte)); | 875 | base = (cursor = BYTE_POS_ADDR (start_byte)); |
| 874 | while (1) | ||
| 875 | { | ||
| 876 | while (*cursor != '\n' && ++cursor != ceiling_addr) | ||
| 877 | ; | ||
| 878 | 876 | ||
| 879 | if (cursor != ceiling_addr) | 877 | do |
| 878 | { | ||
| 879 | unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); | ||
| 880 | if (! nl) | ||
| 881 | break; | ||
| 882 | if (--count == 0) | ||
| 880 | { | 883 | { |
| 881 | if (--count == 0) | 884 | immediate_quit = old_immediate_quit; |
| 882 | { | 885 | start_byte += nl - base + 1; |
| 883 | immediate_quit = old_immediate_quit; | 886 | start = BYTE_TO_CHAR (start_byte); |
| 884 | start_byte = start_byte + cursor - base + 1; | 887 | TEMP_SET_PT_BOTH (start, start_byte); |
| 885 | start = BYTE_TO_CHAR (start_byte); | 888 | return 0; |
| 886 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 887 | return 0; | ||
| 888 | } | ||
| 889 | else | ||
| 890 | if (++cursor == ceiling_addr) | ||
| 891 | break; | ||
| 892 | } | 889 | } |
| 893 | else | 890 | cursor = nl + 1; |
| 894 | break; | ||
| 895 | } | 891 | } |
| 896 | start_byte += cursor - base; | 892 | while (cursor < ceiling_addr); |
| 893 | |||
| 894 | start_byte += ceiling_addr - base; | ||
| 897 | } | 895 | } |
| 898 | } | 896 | } |
| 899 | else | 897 | else |
| @@ -902,31 +900,28 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 902 | { | 900 | { |
| 903 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); | 901 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); |
| 904 | ceiling = max (limit_byte, ceiling); | 902 | ceiling = max (limit_byte, ceiling); |
| 905 | ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; | 903 | ceiling_addr = BYTE_POS_ADDR (ceiling); |
| 906 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); | 904 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); |
| 907 | while (1) | 905 | while (1) |
| 908 | { | 906 | { |
| 909 | while (--cursor != ceiling_addr && *cursor != '\n') | 907 | unsigned char *nl = memrchr (ceiling_addr, '\n', |
| 910 | ; | 908 | cursor - ceiling_addr); |
| 909 | if (! nl) | ||
| 910 | break; | ||
| 911 | 911 | ||
| 912 | if (cursor != ceiling_addr) | 912 | if (++count == 0) |
| 913 | { | 913 | { |
| 914 | if (++count == 0) | 914 | immediate_quit = old_immediate_quit; |
| 915 | { | 915 | /* Return the position AFTER the match we found. */ |
| 916 | immediate_quit = old_immediate_quit; | 916 | start_byte += nl - base + 1; |
| 917 | /* Return the position AFTER the match we found. */ | 917 | start = BYTE_TO_CHAR (start_byte); |
| 918 | start_byte = start_byte + cursor - base + 1; | 918 | TEMP_SET_PT_BOTH (start, start_byte); |
| 919 | start = BYTE_TO_CHAR (start_byte); | 919 | return 0; |
| 920 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 921 | return 0; | ||
| 922 | } | ||
| 923 | } | 920 | } |
| 924 | else | 921 | |
| 925 | break; | 922 | cursor = nl; |
| 926 | } | 923 | } |
| 927 | /* Here we add 1 to compensate for the last decrement | 924 | start_byte += ceiling_addr - base; |
| 928 | of CURSOR, which took it past the valid range. */ | ||
| 929 | start_byte += cursor - base + 1; | ||
| 930 | } | 925 | } |
| 931 | } | 926 | } |
| 932 | 927 | ||
| @@ -939,7 +934,7 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 939 | ptrdiff_t | 934 | ptrdiff_t |
| 940 | find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) | 935 | find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) |
| 941 | { | 936 | { |
| 942 | return scan_buffer ('\n', from, 0, cnt, (ptrdiff_t *) 0, 0); | 937 | return find_newline (from, 0, cnt, (ptrdiff_t *) 0, 0); |
| 943 | } | 938 | } |
| 944 | 939 | ||
| 945 | /* Like find_next_newline, but returns position before the newline, | 940 | /* Like find_next_newline, but returns position before the newline, |
| @@ -950,7 +945,7 @@ ptrdiff_t | |||
| 950 | find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) | 945 | find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) |
| 951 | { | 946 | { |
| 952 | ptrdiff_t shortage; | 947 | ptrdiff_t shortage; |
| 953 | ptrdiff_t pos = scan_buffer ('\n', from, to, cnt, &shortage, 1); | 948 | ptrdiff_t pos = find_newline (from, to, cnt, &shortage, 1); |
| 954 | 949 | ||
| 955 | if (shortage == 0) | 950 | if (shortage == 0) |
| 956 | pos--; | 951 | pos--; |
| @@ -1016,8 +1011,7 @@ search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, | |||
| 1016 | 1011 | ||
| 1017 | if (!EQ (noerror, Qt)) | 1012 | if (!EQ (noerror, Qt)) |
| 1018 | { | 1013 | { |
| 1019 | if (lim < BEGV || lim > ZV) | 1014 | eassert (BEGV <= lim && lim <= ZV); |
| 1020 | emacs_abort (); | ||
| 1021 | SET_PT_BOTH (lim, lim_byte); | 1015 | SET_PT_BOTH (lim, lim_byte); |
| 1022 | return Qnil; | 1016 | return Qnil; |
| 1023 | #if 0 /* This would be clean, but maybe programs depend on | 1017 | #if 0 /* This would be clean, but maybe programs depend on |
| @@ -1029,9 +1023,7 @@ search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, | |||
| 1029 | return Qnil; | 1023 | return Qnil; |
| 1030 | } | 1024 | } |
| 1031 | 1025 | ||
| 1032 | if (np < BEGV || np > ZV) | 1026 | eassert (BEGV <= np && np <= ZV); |
| 1033 | emacs_abort (); | ||
| 1034 | |||
| 1035 | SET_PT (np); | 1027 | SET_PT (np); |
| 1036 | 1028 | ||
| 1037 | return make_number (np); | 1029 | return make_number (np); |
| @@ -1258,7 +1250,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1258 | ptrdiff_t raw_pattern_size; | 1250 | ptrdiff_t raw_pattern_size; |
| 1259 | ptrdiff_t raw_pattern_size_byte; | 1251 | ptrdiff_t raw_pattern_size_byte; |
| 1260 | unsigned char *patbuf; | 1252 | unsigned char *patbuf; |
| 1261 | int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 1253 | bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 1262 | unsigned char *base_pat; | 1254 | unsigned char *base_pat; |
| 1263 | /* Set to positive if we find a non-ASCII char that need | 1255 | /* Set to positive if we find a non-ASCII char that need |
| 1264 | translation. Otherwise set to zero later. */ | 1256 | translation. Otherwise set to zero later. */ |
| @@ -1313,8 +1305,11 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1313 | non-nil, we can use boyer-moore search only if TRT can be | 1305 | non-nil, we can use boyer-moore search only if TRT can be |
| 1314 | represented by the byte array of 256 elements. For that, | 1306 | represented by the byte array of 256 elements. For that, |
| 1315 | all non-ASCII case-equivalents of all case-sensitive | 1307 | all non-ASCII case-equivalents of all case-sensitive |
| 1316 | characters in STRING must belong to the same charset and | 1308 | characters in STRING must belong to the same character |
| 1317 | row. */ | 1309 | group (two characters belong to the same group iff their |
| 1310 | multibyte forms are the same except for the last byte; | ||
| 1311 | i.e. every 64 characters form a group; U+0000..U+003F, | ||
| 1312 | U+0040..U+007F, U+0080..U+00BF, ...). */ | ||
| 1318 | 1313 | ||
| 1319 | while (--len >= 0) | 1314 | while (--len >= 0) |
| 1320 | { | 1315 | { |
| @@ -1406,7 +1401,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1406 | char_base = 0; | 1401 | char_base = 0; |
| 1407 | while (--len >= 0) | 1402 | while (--len >= 0) |
| 1408 | { | 1403 | { |
| 1409 | int c, translated; | 1404 | int c, translated, inverse; |
| 1410 | 1405 | ||
| 1411 | /* If we got here and the RE flag is set, it's because we're | 1406 | /* If we got here and the RE flag is set, it's because we're |
| 1412 | dealing with a regexp known to be trivial, so the backslash | 1407 | dealing with a regexp known to be trivial, so the backslash |
| @@ -1420,6 +1415,20 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1420 | c = *base_pat++; | 1415 | c = *base_pat++; |
| 1421 | TRANSLATE (translated, trt, c); | 1416 | TRANSLATE (translated, trt, c); |
| 1422 | *pat++ = translated; | 1417 | *pat++ = translated; |
| 1418 | /* Check that none of C's equivalents violates the | ||
| 1419 | assumptions of boyer_moore. */ | ||
| 1420 | TRANSLATE (inverse, inverse_trt, c); | ||
| 1421 | while (1) | ||
| 1422 | { | ||
| 1423 | if (inverse >= 0200) | ||
| 1424 | { | ||
| 1425 | boyer_moore_ok = 0; | ||
| 1426 | break; | ||
| 1427 | } | ||
| 1428 | if (c == inverse) | ||
| 1429 | break; | ||
| 1430 | TRANSLATE (inverse, inverse_trt, inverse); | ||
| 1431 | } | ||
| 1423 | } | 1432 | } |
| 1424 | } | 1433 | } |
| 1425 | 1434 | ||
| @@ -1454,8 +1463,8 @@ simple_search (EMACS_INT n, unsigned char *pat, | |||
| 1454 | ptrdiff_t pos, ptrdiff_t pos_byte, | 1463 | ptrdiff_t pos, ptrdiff_t pos_byte, |
| 1455 | ptrdiff_t lim, ptrdiff_t lim_byte) | 1464 | ptrdiff_t lim, ptrdiff_t lim_byte) |
| 1456 | { | 1465 | { |
| 1457 | int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 1466 | bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 1458 | int forward = n > 0; | 1467 | bool forward = n > 0; |
| 1459 | /* Number of buffer bytes matched. Note that this may be different | 1468 | /* Number of buffer bytes matched. Note that this may be different |
| 1460 | from len_byte in a multibyte buffer. */ | 1469 | from len_byte in a multibyte buffer. */ |
| 1461 | ptrdiff_t match_byte = PTRDIFF_MIN; | 1470 | ptrdiff_t match_byte = PTRDIFF_MIN; |
| @@ -1674,7 +1683,7 @@ boyer_moore (EMACS_INT n, unsigned char *base_pat, | |||
| 1674 | register ptrdiff_t i; | 1683 | register ptrdiff_t i; |
| 1675 | register int j; | 1684 | register int j; |
| 1676 | unsigned char *pat, *pat_end; | 1685 | unsigned char *pat, *pat_end; |
| 1677 | int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 1686 | bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 1678 | 1687 | ||
| 1679 | unsigned char simple_translate[0400]; | 1688 | unsigned char simple_translate[0400]; |
| 1680 | /* These are set to the preceding bytes of a byte to be translated | 1689 | /* These are set to the preceding bytes of a byte to be translated |
| @@ -2500,8 +2509,8 @@ since only regular expressions have distinguished subexpressions. */) | |||
| 2500 | ptrdiff_t length = SBYTES (newtext); | 2509 | ptrdiff_t length = SBYTES (newtext); |
| 2501 | unsigned char *substed; | 2510 | unsigned char *substed; |
| 2502 | ptrdiff_t substed_alloc_size, substed_len; | 2511 | ptrdiff_t substed_alloc_size, substed_len; |
| 2503 | int buf_multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 2512 | bool buf_multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 2504 | int str_multibyte = STRING_MULTIBYTE (newtext); | 2513 | bool str_multibyte = STRING_MULTIBYTE (newtext); |
| 2505 | int really_changed = 0; | 2514 | int really_changed = 0; |
| 2506 | 2515 | ||
| 2507 | substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length | 2516 | substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length |
| @@ -2585,7 +2594,7 @@ since only regular expressions have distinguished subexpressions. */) | |||
| 2585 | ptrdiff_t begbyte = CHAR_TO_BYTE (search_regs.start[idx]); | 2594 | ptrdiff_t begbyte = CHAR_TO_BYTE (search_regs.start[idx]); |
| 2586 | add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte; | 2595 | add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte; |
| 2587 | if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx]) | 2596 | if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx]) |
| 2588 | move_gap (search_regs.start[idx]); | 2597 | move_gap_both (search_regs.start[idx], begbyte); |
| 2589 | add_stuff = BYTE_POS_ADDR (begbyte); | 2598 | add_stuff = BYTE_POS_ADDR (begbyte); |
| 2590 | } | 2599 | } |
| 2591 | 2600 | ||
diff --git a/src/sheap.c b/src/sheap.c index f6022ea3ce7..06e205bc0e5 100644 --- a/src/sheap.c +++ b/src/sheap.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* simulate `sbrk' with an array in .bss, for `unexec' support for Cygwin; | 1 | /* simulate `sbrk' with an array in .bss, for `unexec' support for Cygwin; |
| 2 | complete rewrite of xemacs Cygwin `unexec' code | 2 | complete rewrite of xemacs Cygwin `unexec' code |
| 3 | 3 | ||
| 4 | Copyright (C) 2004-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 2004-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -91,5 +91,5 @@ report_sheap_usage (int die_if_pure_storage_exceeded) | |||
| 91 | char buf[200]; | 91 | char buf[200]; |
| 92 | sprintf (buf, "Static heap usage: %d of %d bytes", | 92 | sprintf (buf, "Static heap usage: %d of %d bytes", |
| 93 | bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); | 93 | bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); |
| 94 | message ("%s", buf); | 94 | message1 (buf); |
| 95 | } | 95 | } |
diff --git a/src/sound.c b/src/sound.c index 0ee85312fd3..9c472fb0263 100644 --- a/src/sound.c +++ b/src/sound.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* sound.c -- sound support. | 1 | /* sound.c -- sound support. |
| 2 | 2 | ||
| 3 | Copyright (C) 1998-1999, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1998-1999, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -334,7 +334,7 @@ sound_perror (const char *msg) | |||
| 334 | static void | 334 | static void |
| 335 | sound_warning (const char *msg) | 335 | sound_warning (const char *msg) |
| 336 | { | 336 | { |
| 337 | message ("%s", msg); | 337 | message1 (msg); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | 340 | ||
diff --git a/src/syntax.c b/src/syntax.c index d3cafcc472e..390d732944d 100644 --- a/src/syntax.c +++ b/src/syntax.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* GNU Emacs routines to deal with syntax tables; also word and list parsing. | 1 | /* GNU Emacs routines to deal with syntax tables; also word and list parsing. |
| 2 | Copyright (C) 1985, 1987, 1993-1995, 1997-1999, 2001-2012 | 2 | Copyright (C) 1985, 1987, 1993-1995, 1997-1999, 2001-2013 Free |
| 3 | Free Software Foundation, Inc. | 3 | Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -121,6 +121,7 @@ struct lisp_parse_state | |||
| 121 | /* Char number of start of containing expression */ | 121 | /* Char number of start of containing expression */ |
| 122 | ptrdiff_t prevlevelstart; | 122 | ptrdiff_t prevlevelstart; |
| 123 | ptrdiff_t location; /* Char number at which parsing stopped. */ | 123 | ptrdiff_t location; /* Char number at which parsing stopped. */ |
| 124 | ptrdiff_t location_byte; /* Corresponding byte position. */ | ||
| 124 | ptrdiff_t comstr_start; /* Position of last comment/string starter. */ | 125 | ptrdiff_t comstr_start; /* Position of last comment/string starter. */ |
| 125 | Lisp_Object levelstarts; /* Char numbers of starts-of-expression | 126 | Lisp_Object levelstarts; /* Char numbers of starts-of-expression |
| 126 | of levels (starting from outermost). */ | 127 | of levels (starting from outermost). */ |
| @@ -3277,6 +3278,7 @@ do { prev_from = from; \ | |||
| 3277 | 3278 | ||
| 3278 | stop: /* Here if stopping before start of sexp. */ | 3279 | stop: /* Here if stopping before start of sexp. */ |
| 3279 | from = prev_from; /* We have just fetched the char that starts it; */ | 3280 | from = prev_from; /* We have just fetched the char that starts it; */ |
| 3281 | from_byte = prev_from_byte; | ||
| 3280 | goto done; /* but return the position before it. */ | 3282 | goto done; /* but return the position before it. */ |
| 3281 | 3283 | ||
| 3282 | endquoted: | 3284 | endquoted: |
| @@ -3288,6 +3290,7 @@ do { prev_from = from; \ | |||
| 3288 | state.prevlevelstart | 3290 | state.prevlevelstart |
| 3289 | = (curlevel == levelstart) ? -1 : (curlevel - 1)->last; | 3291 | = (curlevel == levelstart) ? -1 : (curlevel - 1)->last; |
| 3290 | state.location = from; | 3292 | state.location = from; |
| 3293 | state.location_byte = from_byte; | ||
| 3291 | state.levelstarts = Qnil; | 3294 | state.levelstarts = Qnil; |
| 3292 | while (curlevel > levelstart) | 3295 | while (curlevel > levelstart) |
| 3293 | state.levelstarts = Fcons (make_number ((--curlevel)->last), | 3296 | state.levelstarts = Fcons (make_number ((--curlevel)->last), |
| @@ -3327,7 +3330,8 @@ Fifth arg OLDSTATE is a list like what this function returns. | |||
| 3327 | Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. | 3330 | Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. |
| 3328 | If it is symbol `syntax-table', stop after the start of a comment or a | 3331 | If it is symbol `syntax-table', stop after the start of a comment or a |
| 3329 | string, or after end of a comment or a string. */) | 3332 | string, or after end of a comment or a string. */) |
| 3330 | (Lisp_Object from, Lisp_Object to, Lisp_Object targetdepth, Lisp_Object stopbefore, Lisp_Object oldstate, Lisp_Object commentstop) | 3333 | (Lisp_Object from, Lisp_Object to, Lisp_Object targetdepth, |
| 3334 | Lisp_Object stopbefore, Lisp_Object oldstate, Lisp_Object commentstop) | ||
| 3331 | { | 3335 | { |
| 3332 | struct lisp_parse_state state; | 3336 | struct lisp_parse_state state; |
| 3333 | EMACS_INT target; | 3337 | EMACS_INT target; |
| @@ -3347,7 +3351,7 @@ Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. | |||
| 3347 | (NILP (commentstop) | 3351 | (NILP (commentstop) |
| 3348 | ? 0 : (EQ (commentstop, Qsyntax_table) ? -1 : 1))); | 3352 | ? 0 : (EQ (commentstop, Qsyntax_table) ? -1 : 1))); |
| 3349 | 3353 | ||
| 3350 | SET_PT (state.location); | 3354 | SET_PT_BOTH (state.location, state.location_byte); |
| 3351 | 3355 | ||
| 3352 | return Fcons (make_number (state.depth), | 3356 | return Fcons (make_number (state.depth), |
| 3353 | Fcons (state.prevlevelstart < 0 | 3357 | Fcons (state.prevlevelstart < 0 |
| @@ -3389,8 +3393,8 @@ init_syntax_once (void) | |||
| 3389 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); | 3393 | Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); |
| 3390 | 3394 | ||
| 3391 | /* Create objects which can be shared among syntax tables. */ | 3395 | /* Create objects which can be shared among syntax tables. */ |
| 3392 | Vsyntax_code_object = Fmake_vector (make_number (Smax), Qnil); | 3396 | Vsyntax_code_object = make_uninit_vector (Smax); |
| 3393 | for (i = 0; i < ASIZE (Vsyntax_code_object); i++) | 3397 | for (i = 0; i < Smax; i++) |
| 3394 | ASET (Vsyntax_code_object, i, Fcons (make_number (i), Qnil)); | 3398 | ASET (Vsyntax_code_object, i, Fcons (make_number (i), Qnil)); |
| 3395 | 3399 | ||
| 3396 | /* Now we are ready to set up this property, so we can | 3400 | /* Now we are ready to set up this property, so we can |
diff --git a/src/syntax.h b/src/syntax.h index 6edb1585795..c9af240df0c 100644 --- a/src/syntax.h +++ b/src/syntax.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Declarations having to do with GNU Emacs syntax tables. | 1 | /* Declarations having to do with GNU Emacs syntax tables. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985, 1993-1994, 1997-1998, 2001-2012 | 3 | Copyright (C) 1985, 1993-1994, 1997-1998, 2001-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/sysdep.c b/src/sysdep.c index 5291c5d59aa..606a5b038ca 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Interfaces to system-dependent kernel and library entries. | 1 | /* Interfaces to system-dependent kernel and library entries. |
| 2 | Copyright (C) 1985-1988, 1993-1995, 1999-2012 | 2 | Copyright (C) 1985-1988, 1993-1995, 1999-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -30,9 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 30 | #include <limits.h> | 30 | #include <limits.h> |
| 31 | #include <unistd.h> | 31 | #include <unistd.h> |
| 32 | 32 | ||
| 33 | #include <allocator.h> | ||
| 34 | #include <c-ctype.h> | 33 | #include <c-ctype.h> |
| 35 | #include <careadlinkat.h> | ||
| 36 | #include <ignore-value.h> | 34 | #include <ignore-value.h> |
| 37 | #include <utimens.h> | 35 | #include <utimens.h> |
| 38 | 36 | ||
| @@ -529,10 +527,10 @@ sys_subshell (void) | |||
| 529 | #ifdef DOS_NT /* MW, Aug 1993 */ | 527 | #ifdef DOS_NT /* MW, Aug 1993 */ |
| 530 | getcwd (oldwd, sizeof oldwd); | 528 | getcwd (oldwd, sizeof oldwd); |
| 531 | if (sh == 0) | 529 | if (sh == 0) |
| 532 | sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */ | 530 | sh = egetenv ("SUSPEND"); /* KFS, 1994-12-14 */ |
| 533 | #endif | 531 | #endif |
| 534 | if (sh == 0) | 532 | if (sh == 0) |
| 535 | sh = (char *) egetenv ("SHELL"); | 533 | sh = egetenv ("SHELL"); |
| 536 | if (sh == 0) | 534 | if (sh == 0) |
| 537 | sh = "sh"; | 535 | sh = "sh"; |
| 538 | 536 | ||
| @@ -714,6 +712,27 @@ init_foreground_group (void) | |||
| 714 | inherited_pgroup = getpid () == pgrp ? 0 : pgrp; | 712 | inherited_pgroup = getpid () == pgrp ? 0 : pgrp; |
| 715 | } | 713 | } |
| 716 | 714 | ||
| 715 | /* Block and unblock SIGTTOU. */ | ||
| 716 | |||
| 717 | void | ||
| 718 | block_tty_out_signal (void) | ||
| 719 | { | ||
| 720 | #ifdef SIGTTOU | ||
| 721 | sigset_t blocked; | ||
| 722 | sigemptyset (&blocked); | ||
| 723 | sigaddset (&blocked, SIGTTOU); | ||
| 724 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 725 | #endif | ||
| 726 | } | ||
| 727 | |||
| 728 | void | ||
| 729 | unblock_tty_out_signal (void) | ||
| 730 | { | ||
| 731 | #ifdef SIGTTOU | ||
| 732 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | ||
| 733 | #endif | ||
| 734 | } | ||
| 735 | |||
| 717 | /* Safely set a controlling terminal FD's process group to PGID. | 736 | /* Safely set a controlling terminal FD's process group to PGID. |
| 718 | If we are not in the foreground already, POSIX requires tcsetpgrp | 737 | If we are not in the foreground already, POSIX requires tcsetpgrp |
| 719 | to deliver a SIGTTOU signal, which would stop us. This is an | 738 | to deliver a SIGTTOU signal, which would stop us. This is an |
| @@ -725,11 +744,10 @@ static void | |||
| 725 | tcsetpgrp_without_stopping (int fd, pid_t pgid) | 744 | tcsetpgrp_without_stopping (int fd, pid_t pgid) |
| 726 | { | 745 | { |
| 727 | #ifdef SIGTTOU | 746 | #ifdef SIGTTOU |
| 728 | signal_handler_t handler; | ||
| 729 | block_input (); | 747 | block_input (); |
| 730 | handler = signal (SIGTTOU, SIG_IGN); | 748 | block_tty_out_signal (); |
| 731 | tcsetpgrp (fd, pgid); | 749 | tcsetpgrp (fd, pgid); |
| 732 | signal (SIGTTOU, handler); | 750 | unblock_tty_out_signal (); |
| 733 | unblock_input (); | 751 | unblock_input (); |
| 734 | #endif | 752 | #endif |
| 735 | } | 753 | } |
| @@ -1658,6 +1676,25 @@ deliver_arith_signal (int sig) | |||
| 1658 | deliver_thread_signal (sig, handle_arith_signal); | 1676 | deliver_thread_signal (sig, handle_arith_signal); |
| 1659 | } | 1677 | } |
| 1660 | 1678 | ||
| 1679 | #ifdef SIGDANGER | ||
| 1680 | |||
| 1681 | /* Handler for SIGDANGER. */ | ||
| 1682 | static void | ||
| 1683 | handle_danger_signal (int sig) | ||
| 1684 | { | ||
| 1685 | malloc_warning ("Operating system warns that virtual memory is running low.\n"); | ||
| 1686 | |||
| 1687 | /* It might be unsafe to call do_auto_save now. */ | ||
| 1688 | force_auto_save_soon (); | ||
| 1689 | } | ||
| 1690 | |||
| 1691 | static void | ||
| 1692 | deliver_danger_signal (int sig) | ||
| 1693 | { | ||
| 1694 | deliver_process_signal (sig, handle_danger_signal); | ||
| 1695 | } | ||
| 1696 | #endif | ||
| 1697 | |||
| 1661 | /* Treat SIG as a terminating signal, unless it is already ignored and | 1698 | /* Treat SIG as a terminating signal, unless it is already ignored and |
| 1662 | we are in --batch mode. Among other things, this makes nohup work. */ | 1699 | we are in --batch mode. Among other things, this makes nohup work. */ |
| 1663 | static void | 1700 | static void |
| @@ -2110,7 +2147,7 @@ emacs_backtrace (int backtrace_limit) | |||
| 2110 | void | 2147 | void |
| 2111 | emacs_abort (void) | 2148 | emacs_abort (void) |
| 2112 | { | 2149 | { |
| 2113 | terminate_due_to_signal (SIGABRT, 10); | 2150 | terminate_due_to_signal (SIGABRT, 40); |
| 2114 | } | 2151 | } |
| 2115 | #endif | 2152 | #endif |
| 2116 | 2153 | ||
| @@ -2208,22 +2245,6 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte) | |||
| 2208 | 2245 | ||
| 2209 | return (bytes_written); | 2246 | return (bytes_written); |
| 2210 | } | 2247 | } |
| 2211 | |||
| 2212 | static struct allocator const emacs_norealloc_allocator = | ||
| 2213 | { xmalloc, NULL, xfree, memory_full }; | ||
| 2214 | |||
| 2215 | /* Get the symbolic link value of FILENAME. Return a pointer to a | ||
| 2216 | NUL-terminated string. If readlink fails, return NULL and set | ||
| 2217 | errno. If the value fits in INITIAL_BUF, return INITIAL_BUF. | ||
| 2218 | Otherwise, allocate memory and return a pointer to that memory. If | ||
| 2219 | memory allocation fails, diagnose and fail without returning. If | ||
| 2220 | successful, store the length of the symbolic link into *LINKLEN. */ | ||
| 2221 | char * | ||
| 2222 | emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE]) | ||
| 2223 | { | ||
| 2224 | return careadlinkat (AT_FDCWD, filename, initial_buf, READLINK_BUFSIZE, | ||
| 2225 | &emacs_norealloc_allocator, careadlinkatcwd); | ||
| 2226 | } | ||
| 2227 | 2248 | ||
| 2228 | /* Return a struct timeval that is roughly equivalent to T. | 2249 | /* Return a struct timeval that is roughly equivalent to T. |
| 2229 | Use the least timeval not less than T. | 2250 | Use the least timeval not less than T. |
diff --git a/src/sysselect.h b/src/sysselect.h index 24bdf469ced..0a4f7e3ad96 100644 --- a/src/sysselect.h +++ b/src/sysselect.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* sysselect.h - System-dependent definitions for the select function. | 1 | /* sysselect.h - System-dependent definitions for the select function. |
| 2 | Copyright (C) 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1995, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/syssignal.h b/src/syssignal.h index 8f9b5f0546a..d7399c6cb8c 100644 --- a/src/syssignal.h +++ b/src/syssignal.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* syssignal.h - System-dependent definitions for signals. | 1 | /* syssignal.h - System-dependent definitions for signals. |
| 2 | 2 | ||
| 3 | Copyright (C) 1993, 1999, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1993, 1999, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/systime.h b/src/systime.h index 9ce7ce646fb..fa5e7270cb5 100644 --- a/src/systime.h +++ b/src/systime.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* systime.h - System-dependent definitions for time manipulations. | 1 | /* systime.h - System-dependent definitions for time manipulations. |
| 2 | Copyright (C) 1993-1994, 2002-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1994, 2002-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/systty.h b/src/systty.h index 80bcaedf740..6d38c980725 100644 --- a/src/systty.h +++ b/src/systty.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* systty.h - System-dependent definitions for terminals. | 1 | /* systty.h - System-dependent definitions for terminals. |
| 2 | Copyright (C) 1993-1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/syswait.h b/src/syswait.h index 360407d558e..03e5cb5fe2e 100644 --- a/src/syswait.h +++ b/src/syswait.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Define wait system call interface for Emacs. | 1 | /* Define wait system call interface for Emacs. |
| 2 | Copyright (C) 1993-1995, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1995, 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/term.c b/src/term.c index 241875de52f..a31fd51084e 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Terminal control module for terminals described by TERMCAP | 1 | /* Terminal control module for terminals described by TERMCAP |
| 2 | Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012 | 2 | Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -953,8 +953,8 @@ tty_ins_del_lines (struct frame *f, int vpos, int n) | |||
| 953 | const char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line; | 953 | const char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line; |
| 954 | const char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll; | 954 | const char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll; |
| 955 | 955 | ||
| 956 | register int i = n > 0 ? n : -n; | 956 | int i = eabs (n); |
| 957 | register char *buf; | 957 | char *buf; |
| 958 | 958 | ||
| 959 | /* If the lines below the insertion are being pushed | 959 | /* If the lines below the insertion are being pushed |
| 960 | into the end of the window, this is the same as clearing; | 960 | into the end of the window, this is the same as clearing; |
| @@ -2374,7 +2374,7 @@ A suspended tty may be resumed by calling `resume-tty' on it. */) | |||
| 2374 | t->display_info.tty->output = 0; | 2374 | t->display_info.tty->output = 0; |
| 2375 | 2375 | ||
| 2376 | if (FRAMEP (t->display_info.tty->top_frame)) | 2376 | if (FRAMEP (t->display_info.tty->top_frame)) |
| 2377 | FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); | 2377 | SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); |
| 2378 | 2378 | ||
| 2379 | } | 2379 | } |
| 2380 | 2380 | ||
| @@ -2423,7 +2423,7 @@ frame's terminal). */) | |||
| 2423 | if (fd == -1) | 2423 | if (fd == -1) |
| 2424 | error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); | 2424 | error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); |
| 2425 | 2425 | ||
| 2426 | if (strcmp (t->display_info.tty->name, DEV_TTY)) | 2426 | if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0) |
| 2427 | dissociate_if_controlling_tty (fd); | 2427 | dissociate_if_controlling_tty (fd); |
| 2428 | 2428 | ||
| 2429 | t->display_info.tty->output = fdopen (fd, "w+"); | 2429 | t->display_info.tty->output = fdopen (fd, "w+"); |
| @@ -2444,7 +2444,7 @@ frame's terminal). */) | |||
| 2444 | get_tty_size (fileno (t->display_info.tty->input), &width, &height); | 2444 | get_tty_size (fileno (t->display_info.tty->input), &width, &height); |
| 2445 | if (width != old_width || height != old_height) | 2445 | if (width != old_width || height != old_height) |
| 2446 | change_frame_size (f, height, width, 0, 0, 0); | 2446 | change_frame_size (f, height, width, 0, 0, 0); |
| 2447 | FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); | 2447 | SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); |
| 2448 | } | 2448 | } |
| 2449 | 2449 | ||
| 2450 | set_tty_hooks (t); | 2450 | set_tty_hooks (t); |
| @@ -2903,13 +2903,23 @@ set_tty_hooks (struct terminal *terminal) | |||
| 2903 | terminal->delete_terminal_hook = &delete_tty; | 2903 | terminal->delete_terminal_hook = &delete_tty; |
| 2904 | } | 2904 | } |
| 2905 | 2905 | ||
| 2906 | /* Drop the controlling terminal if fd is the same device. */ | 2906 | /* If FD is the controlling terminal, drop it. */ |
| 2907 | static void | 2907 | static void |
| 2908 | dissociate_if_controlling_tty (int fd) | 2908 | dissociate_if_controlling_tty (int fd) |
| 2909 | { | 2909 | { |
| 2910 | pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ | 2910 | /* If tcgetpgrp succeeds, fd is the controlling terminal, |
| 2911 | if (0 <= pgid) | 2911 | so dissociate it by invoking setsid. */ |
| 2912 | setsid (); | 2912 | if (0 <= tcgetpgrp (fd) && setsid () < 0) |
| 2913 | { | ||
| 2914 | #ifdef TIOCNOTTY | ||
| 2915 | /* setsid failed, presumably because Emacs is already a process | ||
| 2916 | group leader. Fall back on the obsolescent way to dissociate | ||
| 2917 | a controlling tty. */ | ||
| 2918 | block_tty_out_signal (); | ||
| 2919 | ioctl (fd, TIOCNOTTY, 0); | ||
| 2920 | unblock_tty_out_signal (); | ||
| 2921 | #endif | ||
| 2922 | } | ||
| 2913 | } | 2923 | } |
| 2914 | 2924 | ||
| 2915 | /* Create a termcap display on the tty device with the given name and | 2925 | /* Create a termcap display on the tty device with the given name and |
| @@ -3030,14 +3040,9 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) | |||
| 3030 | 3040 | ||
| 3031 | /* On some systems, tgetent tries to access the controlling | 3041 | /* On some systems, tgetent tries to access the controlling |
| 3032 | terminal. */ | 3042 | terminal. */ |
| 3033 | { | 3043 | block_tty_out_signal (); |
| 3034 | sigset_t blocked; | 3044 | status = tgetent (tty->termcap_term_buffer, terminal_type); |
| 3035 | sigemptyset (&blocked); | 3045 | unblock_tty_out_signal (); |
| 3036 | sigaddset (&blocked, SIGTTOU); | ||
| 3037 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 3038 | status = tgetent (tty->termcap_term_buffer, terminal_type); | ||
| 3039 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | ||
| 3040 | } | ||
| 3041 | 3046 | ||
| 3042 | if (status < 0) | 3047 | if (status < 0) |
| 3043 | { | 3048 | { |
diff --git a/src/termcap.c b/src/termcap.c index e494cd113d9..99bbfce27f5 100644 --- a/src/termcap.c +++ b/src/termcap.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Work-alike for termcap, plus extra features. | 1 | /* Work-alike for termcap, plus extra features. |
| 2 | Copyright (C) 1985, 1986, 1993, 1994, 1995, 2000, 2001, 2002, 2003, | 2 | Copyright (C) 1985-1986, 1993-1995, 2000-2008, 2011, 2013 Free |
| 3 | 2004, 2005, 2006, 2007, 2008, 2011 Free Software Foundation, Inc. | 3 | Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
| @@ -13,9 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 13 | GNU General Public License for more details. | 13 | GNU General Public License for more details. |
| 14 | 14 | ||
| 15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
| 16 | along with this program; see the file COPYING. If not, write to | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| 18 | Boston, MA 02110-1301, USA. */ | ||
| 19 | 17 | ||
| 20 | /* Emacs config.h may rename various library functions such as malloc. */ | 18 | /* Emacs config.h may rename various library functions such as malloc. */ |
| 21 | #include <config.h> | 19 | #include <config.h> |
| @@ -395,7 +393,7 @@ tgetent (char *bp, const char *name) | |||
| 395 | if (termcap_name && (*termcap_name == '\\' | 393 | if (termcap_name && (*termcap_name == '\\' |
| 396 | || *termcap_name == '/' | 394 | || *termcap_name == '/' |
| 397 | || termcap_name[1] == ':')) | 395 | || termcap_name[1] == ':')) |
| 398 | dostounix_filename (termcap_name); | 396 | dostounix_filename (termcap_name, 0); |
| 399 | #endif | 397 | #endif |
| 400 | 398 | ||
| 401 | filep = termcap_name && valid_filename_p (termcap_name); | 399 | filep = termcap_name && valid_filename_p (termcap_name); |
diff --git a/src/termchar.h b/src/termchar.h index 8bffd3e546b..1c8e8646d4e 100644 --- a/src/termchar.h +++ b/src/termchar.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Flags and parameters describing terminal's characteristics. | 1 | /* Flags and parameters describing terminal's characteristics. |
| 2 | Copyright (C) 1985-1986, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1986, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/termhooks.h b/src/termhooks.h index b35c927fc53..7385298d3d4 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Parameters and display hooks for terminal devices. | 1 | /* Parameters and display hooks for terminal devices. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993-1994, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1986, 1993-1994, 2001-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -211,6 +212,11 @@ enum event_kind | |||
| 211 | , NS_NONKEY_EVENT | 212 | , NS_NONKEY_EVENT |
| 212 | #endif | 213 | #endif |
| 213 | 214 | ||
| 215 | #if defined (HAVE_INOTIFY) || defined (HAVE_NTGUI) | ||
| 216 | /* File or directory was changed. */ | ||
| 217 | , FILE_NOTIFY_EVENT | ||
| 218 | #endif | ||
| 219 | |||
| 214 | }; | 220 | }; |
| 215 | 221 | ||
| 216 | /* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT | 222 | /* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT |
diff --git a/src/terminal.c b/src/terminal.c index 854ca61f19c..5e1f1ff77f7 100644 --- a/src/terminal.c +++ b/src/terminal.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Functions related to terminal devices. | 1 | /* Functions related to terminal devices. |
| 2 | Copyright (C) 2005-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -398,8 +398,6 @@ possible return values. */) | |||
| 398 | return Qw32; | 398 | return Qw32; |
| 399 | case output_msdos_raw: | 399 | case output_msdos_raw: |
| 400 | return Qpc; | 400 | return Qpc; |
| 401 | case output_mac: | ||
| 402 | return Qmac; | ||
| 403 | case output_ns: | 401 | case output_ns: |
| 404 | return Qns; | 402 | return Qns; |
| 405 | default: | 403 | default: |
diff --git a/src/terminfo.c b/src/terminfo.c index 124c452a4a9..0e5e1985461 100644 --- a/src/terminfo.c +++ b/src/terminfo.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Interface from Emacs to terminfo. | 1 | /* Interface from Emacs to terminfo. |
| 2 | Copyright (C) 1985-1986, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1986, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/termopts.h b/src/termopts.h index 05fa0a52eee..8b702b9bf6d 100644 --- a/src/termopts.h +++ b/src/termopts.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Flags and parameters describing user options for handling the terminal. | 1 | /* Flags and parameters describing user options for handling the terminal. |
| 2 | Copyright (C) 1985-1986, 1990, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1986, 1990, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
diff --git a/src/textprop.c b/src/textprop.c index 1ce44ad60ac..c1f6e59bf2e 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Interface code for dealing with text properties. | 1 | /* Interface code for dealing with text properties. |
| 2 | Copyright (C) 1993-1995, 1997, 1999-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1995, 1997, 1999-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -1323,14 +1324,13 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1323 | } | 1324 | } |
| 1324 | 1325 | ||
| 1325 | /* Replace properties of text from START to END with new list of | 1326 | /* Replace properties of text from START to END with new list of |
| 1326 | properties PROPERTIES. BUFFER is the buffer containing | 1327 | properties PROPERTIES. OBJECT is the buffer or string containing |
| 1327 | the text. This does not obey any hooks. | 1328 | the text. This does not obey any hooks. |
| 1328 | You can provide the interval that START is located in as I, | 1329 | You should provide the interval that START is located in as I. |
| 1329 | or pass NULL for I and this function will find it. | ||
| 1330 | START and END can be in any order. */ | 1330 | START and END can be in any order. */ |
| 1331 | 1331 | ||
| 1332 | void | 1332 | void |
| 1333 | set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object buffer, INTERVAL i) | 1333 | set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, INTERVAL i) |
| 1334 | { | 1334 | { |
| 1335 | register INTERVAL prev_changed = NULL; | 1335 | register INTERVAL prev_changed = NULL; |
| 1336 | register ptrdiff_t s, len; | 1336 | register ptrdiff_t s, len; |
| @@ -1349,8 +1349,7 @@ set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object propertie | |||
| 1349 | else | 1349 | else |
| 1350 | return; | 1350 | return; |
| 1351 | 1351 | ||
| 1352 | if (i == NULL) | 1352 | eassert (i); |
| 1353 | i = find_interval (buffer_intervals (XBUFFER (buffer)), s); | ||
| 1354 | 1353 | ||
| 1355 | if (i->position != s) | 1354 | if (i->position != s) |
| 1356 | { | 1355 | { |
| @@ -1361,11 +1360,11 @@ set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object propertie | |||
| 1361 | { | 1360 | { |
| 1362 | copy_properties (unchanged, i); | 1361 | copy_properties (unchanged, i); |
| 1363 | i = split_interval_left (i, len); | 1362 | i = split_interval_left (i, len); |
| 1364 | set_properties (properties, i, buffer); | 1363 | set_properties (properties, i, object); |
| 1365 | return; | 1364 | return; |
| 1366 | } | 1365 | } |
| 1367 | 1366 | ||
| 1368 | set_properties (properties, i, buffer); | 1367 | set_properties (properties, i, object); |
| 1369 | 1368 | ||
| 1370 | if (LENGTH (i) == len) | 1369 | if (LENGTH (i) == len) |
| 1371 | return; | 1370 | return; |
| @@ -1388,7 +1387,7 @@ set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object propertie | |||
| 1388 | /* We have to call set_properties even if we are going to | 1387 | /* We have to call set_properties even if we are going to |
| 1389 | merge the intervals, so as to make the undo records | 1388 | merge the intervals, so as to make the undo records |
| 1390 | and cause redisplay to happen. */ | 1389 | and cause redisplay to happen. */ |
| 1391 | set_properties (properties, i, buffer); | 1390 | set_properties (properties, i, object); |
| 1392 | if (prev_changed) | 1391 | if (prev_changed) |
| 1393 | merge_interval_left (i); | 1392 | merge_interval_left (i); |
| 1394 | return; | 1393 | return; |
| @@ -1399,7 +1398,7 @@ set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object propertie | |||
| 1399 | /* We have to call set_properties even if we are going to | 1398 | /* We have to call set_properties even if we are going to |
| 1400 | merge the intervals, so as to make the undo records | 1399 | merge the intervals, so as to make the undo records |
| 1401 | and cause redisplay to happen. */ | 1400 | and cause redisplay to happen. */ |
| 1402 | set_properties (properties, i, buffer); | 1401 | set_properties (properties, i, object); |
| 1403 | if (!prev_changed) | 1402 | if (!prev_changed) |
| 1404 | prev_changed = i; | 1403 | prev_changed = i; |
| 1405 | else | 1404 | else |
diff --git a/src/tparam.c b/src/tparam.c index 164f61d471b..c3ecfb9e3a3 100644 --- a/src/tparam.c +++ b/src/tparam.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Merge parameters into a termcap entry string. | 1 | /* Merge parameters into a termcap entry string. |
| 2 | Copyright (C) 1985, 1987, 1993, 1995, 2000, 2001, 2002, 2003, 2004, | 2 | Copyright (C) 1985, 1987, 1993, 1995, 2000-2008, 2013 Free Software |
| 3 | 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
| @@ -13,9 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 13 | GNU General Public License for more details. | 13 | GNU General Public License for more details. |
| 14 | 14 | ||
| 15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
| 16 | along with this program; see the file COPYING. If not, write to | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| 18 | Boston, MA 02110-1301, USA. */ | ||
| 19 | 17 | ||
| 20 | /* Emacs config.h may rename various library functions such as malloc. */ | 18 | /* Emacs config.h may rename various library functions such as malloc. */ |
| 21 | #include <config.h> | 19 | #include <config.h> |
diff --git a/src/tparam.h b/src/tparam.h index e845f3e8202..94f226d7d6a 100644 --- a/src/tparam.h +++ b/src/tparam.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Interface definitions for termcap entries. | 1 | /* Interface definitions for termcap entries. |
| 2 | 2 | ||
| 3 | Copyright (C) 2011-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2011-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/undo.c b/src/undo.c index e878ef4dcf9..63edc8e9b8d 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* undo handling for GNU Emacs. | 1 | /* undo handling for GNU Emacs. |
| 2 | Copyright (C) 1990, 1993-1994, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1990, 1993-1994, 2000-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -451,217 +452,6 @@ user_error (const char *msg) | |||
| 451 | } | 452 | } |
| 452 | 453 | ||
| 453 | 454 | ||
| 454 | DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, | ||
| 455 | doc: /* Undo N records from the front of the list LIST. | ||
| 456 | Return what remains of the list. */) | ||
| 457 | (Lisp_Object n, Lisp_Object list) | ||
| 458 | { | ||
| 459 | struct gcpro gcpro1, gcpro2; | ||
| 460 | Lisp_Object next; | ||
| 461 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 462 | register EMACS_INT arg; | ||
| 463 | Lisp_Object oldlist; | ||
| 464 | int did_apply = 0; | ||
| 465 | |||
| 466 | #if 0 /* This is a good feature, but would make undo-start | ||
| 467 | unable to do what is expected. */ | ||
| 468 | Lisp_Object tem; | ||
| 469 | |||
| 470 | /* If the head of the list is a boundary, it is the boundary | ||
| 471 | preceding this command. Get rid of it and don't count it. */ | ||
| 472 | tem = Fcar (list); | ||
| 473 | if (NILP (tem)) | ||
| 474 | list = Fcdr (list); | ||
| 475 | #endif | ||
| 476 | |||
| 477 | CHECK_NUMBER (n); | ||
| 478 | arg = XINT (n); | ||
| 479 | next = Qnil; | ||
| 480 | GCPRO2 (next, list); | ||
| 481 | /* I don't think we need to gcpro oldlist, as we use it only | ||
| 482 | to check for EQ. ++kfs */ | ||
| 483 | |||
| 484 | /* In a writable buffer, enable undoing read-only text that is so | ||
| 485 | because of text properties. */ | ||
| 486 | if (NILP (BVAR (current_buffer, read_only))) | ||
| 487 | specbind (Qinhibit_read_only, Qt); | ||
| 488 | |||
| 489 | /* Don't let `intangible' properties interfere with undo. */ | ||
| 490 | specbind (Qinhibit_point_motion_hooks, Qt); | ||
| 491 | |||
| 492 | oldlist = BVAR (current_buffer, undo_list); | ||
| 493 | |||
| 494 | while (arg > 0) | ||
| 495 | { | ||
| 496 | while (CONSP (list)) | ||
| 497 | { | ||
| 498 | next = XCAR (list); | ||
| 499 | list = XCDR (list); | ||
| 500 | /* Exit inner loop at undo boundary. */ | ||
| 501 | if (NILP (next)) | ||
| 502 | break; | ||
| 503 | /* Handle an integer by setting point to that value. */ | ||
| 504 | if (INTEGERP (next)) | ||
| 505 | SET_PT (clip_to_bounds (BEGV, XINT (next), ZV)); | ||
| 506 | else if (CONSP (next)) | ||
| 507 | { | ||
| 508 | Lisp_Object car, cdr; | ||
| 509 | |||
| 510 | car = XCAR (next); | ||
| 511 | cdr = XCDR (next); | ||
| 512 | if (EQ (car, Qt)) | ||
| 513 | { | ||
| 514 | /* Element (t . TIME) records previous modtime. | ||
| 515 | Preserve any flag of NONEXISTENT_MODTIME_NSECS or | ||
| 516 | UNKNOWN_MODTIME_NSECS. */ | ||
| 517 | struct buffer *base_buffer = current_buffer; | ||
| 518 | EMACS_TIME mod_time; | ||
| 519 | |||
| 520 | if (CONSP (cdr) | ||
| 521 | && CONSP (XCDR (cdr)) | ||
| 522 | && CONSP (XCDR (XCDR (cdr))) | ||
| 523 | && CONSP (XCDR (XCDR (XCDR (cdr)))) | ||
| 524 | && INTEGERP (XCAR (XCDR (XCDR (XCDR (cdr))))) | ||
| 525 | && XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) < 0) | ||
| 526 | mod_time = | ||
| 527 | (make_emacs_time | ||
| 528 | (0, XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000)); | ||
| 529 | else | ||
| 530 | mod_time = lisp_time_argument (cdr); | ||
| 531 | |||
| 532 | if (current_buffer->base_buffer) | ||
| 533 | base_buffer = current_buffer->base_buffer; | ||
| 534 | |||
| 535 | /* If this records an obsolete save | ||
| 536 | (not matching the actual disk file) | ||
| 537 | then don't mark unmodified. */ | ||
| 538 | if (EMACS_TIME_NE (mod_time, base_buffer->modtime)) | ||
| 539 | continue; | ||
| 540 | #ifdef CLASH_DETECTION | ||
| 541 | Funlock_buffer (); | ||
| 542 | #endif /* CLASH_DETECTION */ | ||
| 543 | Fset_buffer_modified_p (Qnil); | ||
| 544 | } | ||
| 545 | else if (EQ (car, Qnil)) | ||
| 546 | { | ||
| 547 | /* Element (nil PROP VAL BEG . END) is property change. */ | ||
| 548 | Lisp_Object beg, end, prop, val; | ||
| 549 | |||
| 550 | prop = Fcar (cdr); | ||
| 551 | cdr = Fcdr (cdr); | ||
| 552 | val = Fcar (cdr); | ||
| 553 | cdr = Fcdr (cdr); | ||
| 554 | beg = Fcar (cdr); | ||
| 555 | end = Fcdr (cdr); | ||
| 556 | |||
| 557 | if (XINT (beg) < BEGV || XINT (end) > ZV) | ||
| 558 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 559 | Fput_text_property (beg, end, prop, val, Qnil); | ||
| 560 | } | ||
| 561 | else if (INTEGERP (car) && INTEGERP (cdr)) | ||
| 562 | { | ||
| 563 | /* Element (BEG . END) means range was inserted. */ | ||
| 564 | |||
| 565 | if (XINT (car) < BEGV | ||
| 566 | || XINT (cdr) > ZV) | ||
| 567 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 568 | /* Set point first thing, so that undoing this undo | ||
| 569 | does not send point back to where it is now. */ | ||
| 570 | Fgoto_char (car); | ||
| 571 | Fdelete_region (car, cdr); | ||
| 572 | } | ||
| 573 | else if (EQ (car, Qapply)) | ||
| 574 | { | ||
| 575 | /* Element (apply FUN . ARGS) means call FUN to undo. */ | ||
| 576 | struct buffer *save_buffer = current_buffer; | ||
| 577 | |||
| 578 | car = Fcar (cdr); | ||
| 579 | cdr = Fcdr (cdr); | ||
| 580 | if (INTEGERP (car)) | ||
| 581 | { | ||
| 582 | /* Long format: (apply DELTA START END FUN . ARGS). */ | ||
| 583 | Lisp_Object delta = car; | ||
| 584 | Lisp_Object start = Fcar (cdr); | ||
| 585 | Lisp_Object end = Fcar (Fcdr (cdr)); | ||
| 586 | Lisp_Object start_mark = Fcopy_marker (start, Qnil); | ||
| 587 | Lisp_Object end_mark = Fcopy_marker (end, Qt); | ||
| 588 | |||
| 589 | cdr = Fcdr (Fcdr (cdr)); | ||
| 590 | apply1 (Fcar (cdr), Fcdr (cdr)); | ||
| 591 | |||
| 592 | /* Check that the function did what the entry said it | ||
| 593 | would do. */ | ||
| 594 | if (!EQ (start, Fmarker_position (start_mark)) | ||
| 595 | || (XINT (delta) + XINT (end) | ||
| 596 | != marker_position (end_mark))) | ||
| 597 | error ("Changes to be undone by function different than announced"); | ||
| 598 | Fset_marker (start_mark, Qnil, Qnil); | ||
| 599 | Fset_marker (end_mark, Qnil, Qnil); | ||
| 600 | } | ||
| 601 | else | ||
| 602 | apply1 (car, cdr); | ||
| 603 | |||
| 604 | if (save_buffer != current_buffer) | ||
| 605 | error ("Undo function switched buffer"); | ||
| 606 | did_apply = 1; | ||
| 607 | } | ||
| 608 | else if (STRINGP (car) && INTEGERP (cdr)) | ||
| 609 | { | ||
| 610 | /* Element (STRING . POS) means STRING was deleted. */ | ||
| 611 | Lisp_Object membuf; | ||
| 612 | EMACS_INT pos = XINT (cdr); | ||
| 613 | |||
| 614 | membuf = car; | ||
| 615 | if (pos < 0) | ||
| 616 | { | ||
| 617 | if (-pos < BEGV || -pos > ZV) | ||
| 618 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 619 | SET_PT (-pos); | ||
| 620 | Finsert (1, &membuf); | ||
| 621 | } | ||
| 622 | else | ||
| 623 | { | ||
| 624 | if (pos < BEGV || pos > ZV) | ||
| 625 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 626 | SET_PT (pos); | ||
| 627 | |||
| 628 | /* Now that we record marker adjustments | ||
| 629 | (caused by deletion) for undo, | ||
| 630 | we should always insert after markers, | ||
| 631 | so that undoing the marker adjustments | ||
| 632 | put the markers back in the right place. */ | ||
| 633 | Finsert (1, &membuf); | ||
| 634 | SET_PT (pos); | ||
| 635 | } | ||
| 636 | } | ||
| 637 | else if (MARKERP (car) && INTEGERP (cdr)) | ||
| 638 | { | ||
| 639 | /* (MARKER . INTEGER) means a marker MARKER | ||
| 640 | was adjusted by INTEGER. */ | ||
| 641 | if (XMARKER (car)->buffer) | ||
| 642 | Fset_marker (car, | ||
| 643 | make_number (marker_position (car) - XINT (cdr)), | ||
| 644 | Fmarker_buffer (car)); | ||
| 645 | } | ||
| 646 | } | ||
| 647 | } | ||
| 648 | arg--; | ||
| 649 | } | ||
| 650 | |||
| 651 | |||
| 652 | /* Make sure an apply entry produces at least one undo entry, | ||
| 653 | so the test in `undo' for continuing an undo series | ||
| 654 | will work right. */ | ||
| 655 | if (did_apply | ||
| 656 | && EQ (oldlist, BVAR (current_buffer, undo_list))) | ||
| 657 | bset_undo_list | ||
| 658 | (current_buffer, | ||
| 659 | Fcons (list3 (Qapply, Qcdr, Qnil), BVAR (current_buffer, undo_list))); | ||
| 660 | |||
| 661 | UNGCPRO; | ||
| 662 | return unbind_to (count, list); | ||
| 663 | } | ||
| 664 | |||
| 665 | void | 455 | void |
| 666 | syms_of_undo (void) | 456 | syms_of_undo (void) |
| 667 | { | 457 | { |
| @@ -674,7 +464,6 @@ syms_of_undo (void) | |||
| 674 | last_undo_buffer = NULL; | 464 | last_undo_buffer = NULL; |
| 675 | last_boundary_buffer = NULL; | 465 | last_boundary_buffer = NULL; |
| 676 | 466 | ||
| 677 | defsubr (&Sprimitive_undo); | ||
| 678 | defsubr (&Sundo_boundary); | 467 | defsubr (&Sundo_boundary); |
| 679 | 468 | ||
| 680 | DEFVAR_INT ("undo-limit", undo_limit, | 469 | DEFVAR_INT ("undo-limit", undo_limit, |
diff --git a/src/unexaix.c b/src/unexaix.c index c01a22a79f6..da44480fdca 100644 --- a/src/unexaix.c +++ b/src/unexaix.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Dump an executable image. | 1 | /* Dump an executable image. |
| 2 | Copyright (C) 1985-1988, 1999, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1988, 1999, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -50,6 +51,8 @@ what you give them. Help stamp out software-hoarding! */ | |||
| 50 | #include "getpagesize.h" | 51 | #include "getpagesize.h" |
| 51 | 52 | ||
| 52 | #include <sys/types.h> | 53 | #include <sys/types.h> |
| 54 | #include <inttypes.h> | ||
| 55 | #include <stdarg.h> | ||
| 53 | #include <stdio.h> | 56 | #include <stdio.h> |
| 54 | #include <sys/stat.h> | 57 | #include <sys/stat.h> |
| 55 | #include <errno.h> | 58 | #include <errno.h> |
| @@ -58,10 +61,8 @@ what you give them. Help stamp out software-hoarding! */ | |||
| 58 | 61 | ||
| 59 | #include "mem-limits.h" | 62 | #include "mem-limits.h" |
| 60 | 63 | ||
| 61 | char *start_of_text (void); /* Start of text */ | 64 | extern char _data[]; |
| 62 | 65 | extern char _text[]; | |
| 63 | extern int _data; | ||
| 64 | extern int _text; | ||
| 65 | 66 | ||
| 66 | #include <filehdr.h> | 67 | #include <filehdr.h> |
| 67 | #include <aouthdr.h> | 68 | #include <aouthdr.h> |
| @@ -70,15 +71,15 @@ extern int _text; | |||
| 70 | 71 | ||
| 71 | static struct filehdr f_hdr; /* File header */ | 72 | static struct filehdr f_hdr; /* File header */ |
| 72 | static struct aouthdr f_ohdr; /* Optional file header (a.out) */ | 73 | static struct aouthdr f_ohdr; /* Optional file header (a.out) */ |
| 73 | static long bias; /* Bias to add for growth */ | 74 | static off_t bias; /* Bias to add for growth */ |
| 74 | static long lnnoptr; /* Pointer to line-number info within file */ | 75 | static off_t lnnoptr; /* Pointer to line-number info within file */ |
| 75 | 76 | ||
| 76 | static long text_scnptr; | 77 | static off_t text_scnptr; |
| 77 | static long data_scnptr; | 78 | static off_t data_scnptr; |
| 78 | #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) | 79 | #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) |
| 79 | static long load_scnptr; | 80 | static off_t load_scnptr; |
| 80 | static long orig_load_scnptr; | 81 | static off_t orig_load_scnptr; |
| 81 | static long orig_data_scnptr; | 82 | static off_t orig_data_scnptr; |
| 82 | static int unrelocate_symbols (int, int, const char *, const char *); | 83 | static int unrelocate_symbols (int, int, const char *, const char *); |
| 83 | 84 | ||
| 84 | #ifndef MAX_SECTIONS | 85 | #ifndef MAX_SECTIONS |
| @@ -91,23 +92,30 @@ static int pagemask; | |||
| 91 | 92 | ||
| 92 | #include "lisp.h" | 93 | #include "lisp.h" |
| 93 | 94 | ||
| 94 | static void | 95 | static _Noreturn void |
| 95 | report_error (const char *file, int fd) | 96 | report_error (const char *file, int fd) |
| 96 | { | 97 | { |
| 97 | if (fd) | 98 | if (fd) |
| 98 | close (fd); | 99 | { |
| 100 | int failed_errno = errno; | ||
| 101 | close (fd); | ||
| 102 | errno = failed_errno; | ||
| 103 | } | ||
| 99 | report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); | 104 | report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); |
| 100 | } | 105 | } |
| 101 | 106 | ||
| 102 | #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 | 107 | #define ERROR0(msg) report_error_1 (new, msg) |
| 103 | #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 | 108 | #define ERROR1(msg,x) report_error_1 (new, msg, x) |
| 104 | #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 | 109 | #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y) |
| 105 | 110 | ||
| 106 | static void | 111 | static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) |
| 107 | report_error_1 (int fd, const char *msg, int a1, int a2) | 112 | report_error_1 (int fd, const char *msg, ...) |
| 108 | { | 113 | { |
| 114 | va_list ap; | ||
| 109 | close (fd); | 115 | close (fd); |
| 110 | error (msg, a1, a2); | 116 | va_start (ap, msg); |
| 117 | verror (msg, ap); | ||
| 118 | va_end (ap); | ||
| 111 | } | 119 | } |
| 112 | 120 | ||
| 113 | static int make_hdr (int, int, const char *, const char *); | 121 | static int make_hdr (int, int, const char *, const char *); |
| @@ -162,8 +170,8 @@ make_hdr (int new, int a_out, | |||
| 162 | const char *a_name, const char *new_name) | 170 | const char *a_name, const char *new_name) |
| 163 | { | 171 | { |
| 164 | int scns; | 172 | int scns; |
| 165 | unsigned int bss_start; | 173 | uintptr_t bss_start; |
| 166 | unsigned int data_start; | 174 | uintptr_t data_start; |
| 167 | 175 | ||
| 168 | struct scnhdr section[MAX_SECTIONS]; | 176 | struct scnhdr section[MAX_SECTIONS]; |
| 169 | struct scnhdr * f_thdr; /* Text section header */ | 177 | struct scnhdr * f_thdr; /* Text section header */ |
| @@ -178,17 +186,17 @@ make_hdr (int new, int a_out, | |||
| 178 | pagemask = getpagesize () - 1; | 186 | pagemask = getpagesize () - 1; |
| 179 | 187 | ||
| 180 | /* Adjust text/data boundary. */ | 188 | /* Adjust text/data boundary. */ |
| 181 | data_start = (long) start_of_data (); | 189 | data_start = (uintptr_t) _data; |
| 182 | data_start = ADDR_CORRECT (data_start); | ||
| 183 | 190 | ||
| 184 | data_start = data_start & ~pagemask; /* (Down) to page boundary. */ | 191 | data_start = data_start & ~pagemask; /* (Down) to page boundary. */ |
| 185 | 192 | ||
| 186 | bss_start = ADDR_CORRECT (sbrk (0)) + pagemask; | 193 | bss_start = (uintptr_t) sbrk (0) + pagemask; |
| 187 | bss_start &= ~ pagemask; | 194 | bss_start &= ~ pagemask; |
| 188 | 195 | ||
| 189 | if (data_start > bss_start) /* Can't have negative data size. */ | 196 | if (data_start > bss_start) /* Can't have negative data size. */ |
| 190 | { | 197 | { |
| 191 | ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)", | 198 | ERROR2 (("unexec: data_start (0x%"PRIxPTR |
| 199 | ") can't be greater than bss_start (0x%"PRIxPTR")"), | ||
| 192 | data_start, bss_start); | 200 | data_start, bss_start); |
| 193 | } | 201 | } |
| 194 | 202 | ||
| @@ -278,7 +286,7 @@ make_hdr (int new, int a_out, | |||
| 278 | 286 | ||
| 279 | /* fix scnptr's */ | 287 | /* fix scnptr's */ |
| 280 | { | 288 | { |
| 281 | ulong ptr = section[0].s_scnptr; | 289 | off_t ptr = section[0].s_scnptr; |
| 282 | 290 | ||
| 283 | bias = -1; | 291 | bias = -1; |
| 284 | for (scns = 0; scns < f_hdr.f_nscns; scns++) | 292 | for (scns = 0; scns < f_hdr.f_nscns; scns++) |
| @@ -374,12 +382,12 @@ copy_text_and_data (int new) | |||
| 374 | char *end; | 382 | char *end; |
| 375 | char *ptr; | 383 | char *ptr; |
| 376 | 384 | ||
| 377 | lseek (new, (long) text_scnptr, SEEK_SET); | 385 | lseek (new, text_scnptr, SEEK_SET); |
| 378 | ptr = start_of_text () + text_scnptr; | 386 | ptr = _text + text_scnptr; |
| 379 | end = ptr + f_ohdr.tsize; | 387 | end = ptr + f_ohdr.tsize; |
| 380 | write_segment (new, ptr, end); | 388 | write_segment (new, ptr, end); |
| 381 | 389 | ||
| 382 | lseek (new, (long) data_scnptr, SEEK_SET); | 390 | lseek (new, data_scnptr, SEEK_SET); |
| 383 | ptr = (char *) f_ohdr.data_start; | 391 | ptr = (char *) f_ohdr.data_start; |
| 384 | end = ptr + f_ohdr.dsize; | 392 | end = ptr + f_ohdr.dsize; |
| 385 | write_segment (new, ptr, end); | 393 | write_segment (new, ptr, end); |
| @@ -392,7 +400,6 @@ static void | |||
| 392 | write_segment (int new, char *ptr, char *end) | 400 | write_segment (int new, char *ptr, char *end) |
| 393 | { | 401 | { |
| 394 | int i, nwrite, ret; | 402 | int i, nwrite, ret; |
| 395 | char buf[80]; | ||
| 396 | char zeros[UnexBlockSz]; | 403 | char zeros[UnexBlockSz]; |
| 397 | 404 | ||
| 398 | for (i = 0; ptr < end;) | 405 | for (i = 0; ptr < end;) |
| @@ -413,9 +420,13 @@ write_segment (int new, char *ptr, char *end) | |||
| 413 | } | 420 | } |
| 414 | else if (nwrite != ret) | 421 | else if (nwrite != ret) |
| 415 | { | 422 | { |
| 423 | int write_errno = errno; | ||
| 424 | char buf[1000]; | ||
| 425 | void *addr = ptr; | ||
| 416 | sprintf (buf, | 426 | sprintf (buf, |
| 417 | "unexec write failure: addr 0x%lx, fileno %d, size 0x%x, wrote 0x%x, errno %d", | 427 | "unexec write failure: addr %p, fileno %d, size 0x%x, wrote 0x%x, errno %d", |
| 418 | (unsigned long)ptr, new, nwrite, ret, errno); | 428 | addr, new, nwrite, ret, errno); |
| 429 | errno = write_errno; | ||
| 419 | PERROR (buf); | 430 | PERROR (buf); |
| 420 | } | 431 | } |
| 421 | i += nwrite; | 432 | i += nwrite; |
| @@ -536,13 +547,13 @@ unrelocate_symbols (int new, int a_out, | |||
| 536 | int i; | 547 | int i; |
| 537 | LDHDR ldhdr; | 548 | LDHDR ldhdr; |
| 538 | LDREL ldrel; | 549 | LDREL ldrel; |
| 539 | ulong t_reloc = (ulong) &_text - f_ohdr.text_start; | 550 | off_t t_reloc = (intptr_t) _text - f_ohdr.text_start; |
| 540 | #ifndef ALIGN_DATA_RELOC | 551 | #ifndef ALIGN_DATA_RELOC |
| 541 | ulong d_reloc = (ulong) &_data - f_ohdr.data_start; | 552 | off_t d_reloc = (intptr_t) _data - f_ohdr.data_start; |
| 542 | #else | 553 | #else |
| 543 | /* This worked (and was needed) before AIX 4.2. | 554 | /* This worked (and was needed) before AIX 4.2. |
| 544 | I have no idea why. -- Mike */ | 555 | I have no idea why. -- Mike */ |
| 545 | ulong d_reloc = (ulong) &_data - ALIGN (f_ohdr.data_start, 2); | 556 | off_t d_reloc = (intptr_t) _data - ALIGN (f_ohdr.data_start, 2); |
| 546 | #endif | 557 | #endif |
| 547 | int * p; | 558 | int * p; |
| 548 | 559 | ||
| @@ -627,16 +638,3 @@ unrelocate_symbols (int new, int a_out, | |||
| 627 | } | 638 | } |
| 628 | return 0; | 639 | return 0; |
| 629 | } | 640 | } |
| 630 | |||
| 631 | /* | ||
| 632 | * Return the address of the start of the text segment prior to | ||
| 633 | * doing an unexec. After unexec the return value is undefined. | ||
| 634 | * See crt0.c for further explanation and _start. | ||
| 635 | * | ||
| 636 | */ | ||
| 637 | |||
| 638 | char * | ||
| 639 | start_of_text (void) | ||
| 640 | { | ||
| 641 | return ((char *) 0x10000000); | ||
| 642 | } | ||
diff --git a/src/unexcoff.c b/src/unexcoff.c index 6e29951a962..466a5c0e491 100644 --- a/src/unexcoff.c +++ b/src/unexcoff.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | /* Copyright (C) 1985-1988, 1992-1994, 2001-2012 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1985-1988, 1992-1994, 2001-2013 Free Software |
| 2 | * Foundation, Inc. | ||
| 2 | 3 | ||
| 3 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 4 | 5 | ||
diff --git a/src/unexcw.c b/src/unexcw.c index 8c5d574530d..af93e158e14 100644 --- a/src/unexcw.c +++ b/src/unexcw.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* unexec() support for Cygwin; | 1 | /* unexec() support for Cygwin; |
| 2 | complete rewrite of xemacs Cygwin unexec() code | 2 | complete rewrite of xemacs Cygwin unexec() code |
| 3 | 3 | ||
| 4 | Copyright (C) 2004-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 2004-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -183,6 +183,19 @@ fixup_executable (int fd) | |||
| 183 | exe_header->file_optional_header.FileAlignment * | 183 | exe_header->file_optional_header.FileAlignment * |
| 184 | exe_header->file_optional_header.FileAlignment; | 184 | exe_header->file_optional_header.FileAlignment; |
| 185 | 185 | ||
| 186 | /* Make sure the generated bootstrap binary isn't | ||
| 187 | * sparse. NT doesn't use a file cache for sparse | ||
| 188 | * executables, so if we bootstrap Emacs using a sparse | ||
| 189 | * bootstrap-emacs.exe, bootstrap takes about twenty | ||
| 190 | * times longer than it would otherwise. */ | ||
| 191 | |||
| 192 | ret = posix_fallocate (fd, | ||
| 193 | ( exe_header->section_header[i].s_scnptr + | ||
| 194 | exe_header->section_header[i].s_size ), | ||
| 195 | 1); | ||
| 196 | |||
| 197 | assert (ret != -1); | ||
| 198 | |||
| 186 | ret = | 199 | ret = |
| 187 | lseek (fd, | 200 | lseek (fd, |
| 188 | (long) (exe_header->section_header[i].s_scnptr + | 201 | (long) (exe_header->section_header[i].s_scnptr + |
diff --git a/src/unexelf.c b/src/unexelf.c index b9f8e05e959..d3659404f9c 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Copyright (C) 1985-1988, 1990, 1992, 1999-2012 | 1 | /* Copyright (C) 1985-1988, 1990, 1992, 1999-2013 Free Software |
| 2 | Free Software Foundation, Inc. | 2 | Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/unexmacosx.c b/src/unexmacosx.c index d304e85d490..8d4e636fa5c 100644 --- a/src/unexmacosx.c +++ b/src/unexmacosx.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Dump Emacs in Mach-O format for use on Mac OS X. | 1 | /* Dump Emacs in Mach-O format for use on Mac OS X. |
| 2 | Copyright (C) 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/unexw32.c b/src/unexw32.c index 1e591a78b73..e8b553a87d3 100644 --- a/src/unexw32.c +++ b/src/unexw32.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* unexec for GNU Emacs on Windows NT. | 1 | /* unexec for GNU Emacs on Windows NT. |
| 2 | Copyright (C) 1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -85,13 +85,6 @@ DWORD_PTR extra_bss_size_static = 0; | |||
| 85 | 85 | ||
| 86 | PIMAGE_SECTION_HEADER heap_section; | 86 | PIMAGE_SECTION_HEADER heap_section; |
| 87 | 87 | ||
| 88 | #ifdef HAVE_NTGUI | ||
| 89 | extern HINSTANCE hinst; | ||
| 90 | HINSTANCE hprevinst = NULL; | ||
| 91 | LPSTR lpCmdLine = ""; | ||
| 92 | int nCmdShow = 0; | ||
| 93 | #endif /* HAVE_NTGUI */ | ||
| 94 | |||
| 95 | /* Startup code for running on NT. When we are running as the dumped | 88 | /* Startup code for running on NT. When we are running as the dumped |
| 96 | version, we need to bootstrap our heap and .bss section into our | 89 | version, we need to bootstrap our heap and .bss section into our |
| 97 | address space before we can actually hand off control to the startup | 90 | address space before we can actually hand off control to the startup |
| @@ -121,15 +114,6 @@ _start (void) | |||
| 121 | /* Prevent Emacs from being locked up (eg. in batch mode) when | 114 | /* Prevent Emacs from being locked up (eg. in batch mode) when |
| 122 | accessing devices that aren't mounted (eg. removable media drives). */ | 115 | accessing devices that aren't mounted (eg. removable media drives). */ |
| 123 | SetErrorMode (SEM_FAILCRITICALERRORS); | 116 | SetErrorMode (SEM_FAILCRITICALERRORS); |
| 124 | |||
| 125 | /* Invoke the NT CRT startup routine now that our housecleaning | ||
| 126 | is finished. */ | ||
| 127 | #ifdef HAVE_NTGUI | ||
| 128 | /* determine WinMain args like crt0.c does */ | ||
| 129 | hinst = GetModuleHandle (NULL); | ||
| 130 | lpCmdLine = GetCommandLine (); | ||
| 131 | nCmdShow = SW_SHOWDEFAULT; | ||
| 132 | #endif | ||
| 133 | mainCRTStartup (); | 117 | mainCRTStartup (); |
| 134 | } | 118 | } |
| 135 | 119 | ||
| @@ -738,7 +722,7 @@ unexec (const char *new_name, const char *old_name) | |||
| 738 | /* Ignore old_name, and get our actual location from the OS. */ | 722 | /* Ignore old_name, and get our actual location from the OS. */ |
| 739 | if (!GetModuleFileName (NULL, in_filename, MAX_PATH)) | 723 | if (!GetModuleFileName (NULL, in_filename, MAX_PATH)) |
| 740 | abort (); | 724 | abort (); |
| 741 | dostounix_filename (in_filename); | 725 | dostounix_filename (in_filename, 0); |
| 742 | strcpy (out_filename, in_filename); | 726 | strcpy (out_filename, in_filename); |
| 743 | 727 | ||
| 744 | /* Change the base of the output filename to match the requested name. */ | 728 | /* Change the base of the output filename to match the requested name. */ |
diff --git a/src/vm-limit.c b/src/vm-limit.c index befc01d400f..9dbb1b884b7 100644 --- a/src/vm-limit.c +++ b/src/vm-limit.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Functions for memory limit warnings. | 1 | /* Functions for memory limit warnings. |
| 2 | Copyright (C) 1990, 1992, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1990, 1992, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/w16select.c b/src/w16select.c index b8aaa3619ba..3bcc663e565 100644 --- a/src/w16select.c +++ b/src/w16select.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* 16-bit Windows Selection processing for emacs on MS-Windows | 1 | /* 16-bit Windows Selection processing for emacs on MS-Windows |
| 2 | 2 | ||
| 3 | Copyright (C) 1996-1997, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1996-1997, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -532,13 +532,13 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat | |||
| 532 | switch (put_status) | 532 | switch (put_status) |
| 533 | { | 533 | { |
| 534 | case 1: | 534 | case 1: |
| 535 | message2 (no_mem_msg, sizeof (no_mem_msg) - 1, 0); | 535 | message3 (make_unibyte_string (no_mem_msg, sizeof (no_mem_msg) - 1)); |
| 536 | break; | 536 | break; |
| 537 | case 2: | 537 | case 2: |
| 538 | message2 (binary_msg, sizeof (binary_msg) - 1, 0); | 538 | message3 (make_unibyte_string (binary_msg, sizeof (binary_msg) - 1)); |
| 539 | break; | 539 | break; |
| 540 | case 3: | 540 | case 3: |
| 541 | message2 (system_error_msg, sizeof (system_error_msg) - 1, 0); | 541 | message3 (make_unibyte_string (system_error_msg, sizeof (system_error_msg) - 1)); |
| 542 | break; | 542 | break; |
| 543 | } | 543 | } |
| 544 | sit_for (make_number (2), 0, 2); | 544 | sit_for (make_number (2), 0, 2); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Utility and Unix shadow routines for GNU Emacs on the Microsoft Windows API. | 1 | /* Utility and Unix shadow routines for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1994-1995, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1994-1995, 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -37,7 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 37 | /* must include CRT headers *before* config.h */ | 37 | /* must include CRT headers *before* config.h */ |
| 38 | 38 | ||
| 39 | #include <config.h> | 39 | #include <config.h> |
| 40 | #include <mbstring.h> /* for _mbspbrk */ | 40 | #include <mbstring.h> /* for _mbspbrk, _mbslwr, _mbsrchr, ... */ |
| 41 | 41 | ||
| 42 | #undef access | 42 | #undef access |
| 43 | #undef chdir | 43 | #undef chdir |
| @@ -101,22 +101,31 @@ typedef struct _MEMORY_STATUS_EX { | |||
| 101 | _WIN32_WINNT than what we use. w32api supplied with MinGW 3.15 | 101 | _WIN32_WINNT than what we use. w32api supplied with MinGW 3.15 |
| 102 | defines it in psapi.h */ | 102 | defines it in psapi.h */ |
| 103 | typedef struct _PROCESS_MEMORY_COUNTERS_EX { | 103 | typedef struct _PROCESS_MEMORY_COUNTERS_EX { |
| 104 | DWORD cb; | 104 | DWORD cb; |
| 105 | DWORD PageFaultCount; | 105 | DWORD PageFaultCount; |
| 106 | DWORD PeakWorkingSetSize; | 106 | SIZE_T PeakWorkingSetSize; |
| 107 | DWORD WorkingSetSize; | 107 | SIZE_T WorkingSetSize; |
| 108 | DWORD QuotaPeakPagedPoolUsage; | 108 | SIZE_T QuotaPeakPagedPoolUsage; |
| 109 | DWORD QuotaPagedPoolUsage; | 109 | SIZE_T QuotaPagedPoolUsage; |
| 110 | DWORD QuotaPeakNonPagedPoolUsage; | 110 | SIZE_T QuotaPeakNonPagedPoolUsage; |
| 111 | DWORD QuotaNonPagedPoolUsage; | 111 | SIZE_T QuotaNonPagedPoolUsage; |
| 112 | DWORD PagefileUsage; | 112 | SIZE_T PagefileUsage; |
| 113 | DWORD PeakPagefileUsage; | 113 | SIZE_T PeakPagefileUsage; |
| 114 | DWORD PrivateUsage; | 114 | SIZE_T PrivateUsage; |
| 115 | } PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX; | 115 | } PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX; |
| 116 | #endif | 116 | #endif |
| 117 | 117 | ||
| 118 | #include <winioctl.h> | 118 | #include <winioctl.h> |
| 119 | #include <aclapi.h> | 119 | #include <aclapi.h> |
| 120 | #include <sddl.h> | ||
| 121 | |||
| 122 | #include <sys/acl.h> | ||
| 123 | |||
| 124 | /* This is not in MinGW's sddl.h (but they are in MSVC headers), so we | ||
| 125 | define them by hand if not already defined. */ | ||
| 126 | #ifndef SDDL_REVISION_1 | ||
| 127 | #define SDDL_REVISION_1 1 | ||
| 128 | #endif /* SDDL_REVISION_1 */ | ||
| 120 | 129 | ||
| 121 | #ifdef _MSC_VER | 130 | #ifdef _MSC_VER |
| 122 | /* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the | 131 | /* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the |
| @@ -257,6 +266,11 @@ static BOOL g_b_init_copy_sid; | |||
| 257 | static BOOL g_b_init_get_native_system_info; | 266 | static BOOL g_b_init_get_native_system_info; |
| 258 | static BOOL g_b_init_get_system_times; | 267 | static BOOL g_b_init_get_system_times; |
| 259 | static BOOL g_b_init_create_symbolic_link; | 268 | static BOOL g_b_init_create_symbolic_link; |
| 269 | static BOOL g_b_init_get_security_descriptor_dacl; | ||
| 270 | static BOOL g_b_init_convert_sd_to_sddl; | ||
| 271 | static BOOL g_b_init_convert_sddl_to_sd; | ||
| 272 | static BOOL g_b_init_is_valid_security_descriptor; | ||
| 273 | static BOOL g_b_init_set_file_security; | ||
| 260 | 274 | ||
| 261 | /* | 275 | /* |
| 262 | BEGIN: Wrapper functions around OpenProcessToken | 276 | BEGIN: Wrapper functions around OpenProcessToken |
| @@ -286,9 +300,11 @@ GetProcessTimes_Proc get_process_times_fn = NULL; | |||
| 286 | #ifdef _UNICODE | 300 | #ifdef _UNICODE |
| 287 | const char * const LookupAccountSid_Name = "LookupAccountSidW"; | 301 | const char * const LookupAccountSid_Name = "LookupAccountSidW"; |
| 288 | const char * const GetFileSecurity_Name = "GetFileSecurityW"; | 302 | const char * const GetFileSecurity_Name = "GetFileSecurityW"; |
| 303 | const char * const SetFileSecurity_Name = "SetFileSecurityW"; | ||
| 289 | #else | 304 | #else |
| 290 | const char * const LookupAccountSid_Name = "LookupAccountSidA"; | 305 | const char * const LookupAccountSid_Name = "LookupAccountSidA"; |
| 291 | const char * const GetFileSecurity_Name = "GetFileSecurityA"; | 306 | const char * const GetFileSecurity_Name = "GetFileSecurityA"; |
| 307 | const char * const SetFileSecurity_Name = "SetFileSecurityA"; | ||
| 292 | #endif | 308 | #endif |
| 293 | typedef BOOL (WINAPI * LookupAccountSid_Proc) ( | 309 | typedef BOOL (WINAPI * LookupAccountSid_Proc) ( |
| 294 | LPCTSTR lpSystemName, | 310 | LPCTSTR lpSystemName, |
| @@ -318,6 +334,10 @@ typedef BOOL (WINAPI * GetFileSecurity_Proc) ( | |||
| 318 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | 334 | PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 319 | DWORD nLength, | 335 | DWORD nLength, |
| 320 | LPDWORD lpnLengthNeeded); | 336 | LPDWORD lpnLengthNeeded); |
| 337 | typedef BOOL (WINAPI *SetFileSecurity_Proc) ( | ||
| 338 | LPCTSTR lpFileName, | ||
| 339 | SECURITY_INFORMATION SecurityInformation, | ||
| 340 | PSECURITY_DESCRIPTOR pSecurityDescriptor); | ||
| 321 | typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) ( | 341 | typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) ( |
| 322 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | 342 | PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 323 | PSID *pOwner, | 343 | PSID *pOwner, |
| @@ -326,6 +346,11 @@ typedef BOOL (WINAPI * GetSecurityDescriptorGroup_Proc) ( | |||
| 326 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | 346 | PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 327 | PSID *pGroup, | 347 | PSID *pGroup, |
| 328 | LPBOOL lpbGroupDefaulted); | 348 | LPBOOL lpbGroupDefaulted); |
| 349 | typedef BOOL (WINAPI *GetSecurityDescriptorDacl_Proc) ( | ||
| 350 | PSECURITY_DESCRIPTOR pSecurityDescriptor, | ||
| 351 | LPBOOL lpbDaclPresent, | ||
| 352 | PACL *pDacl, | ||
| 353 | LPBOOL lpbDaclDefaulted); | ||
| 329 | typedef BOOL (WINAPI * IsValidSid_Proc) ( | 354 | typedef BOOL (WINAPI * IsValidSid_Proc) ( |
| 330 | PSID sid); | 355 | PSID sid); |
| 331 | typedef HANDLE (WINAPI * CreateToolhelp32Snapshot_Proc) ( | 356 | typedef HANDLE (WINAPI * CreateToolhelp32Snapshot_Proc) ( |
| @@ -351,8 +376,8 @@ typedef BOOL (WINAPI * GetProcessMemoryInfo_Proc) ( | |||
| 351 | DWORD cb); | 376 | DWORD cb); |
| 352 | typedef BOOL (WINAPI * GetProcessWorkingSetSize_Proc) ( | 377 | typedef BOOL (WINAPI * GetProcessWorkingSetSize_Proc) ( |
| 353 | HANDLE hProcess, | 378 | HANDLE hProcess, |
| 354 | DWORD * lpMinimumWorkingSetSize, | 379 | PSIZE_T lpMinimumWorkingSetSize, |
| 355 | DWORD * lpMaximumWorkingSetSize); | 380 | PSIZE_T lpMaximumWorkingSetSize); |
| 356 | typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) ( | 381 | typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) ( |
| 357 | LPMEMORYSTATUS lpBuffer); | 382 | LPMEMORYSTATUS lpBuffer); |
| 358 | typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( | 383 | typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( |
| @@ -376,6 +401,18 @@ typedef BOOLEAN (WINAPI *CreateSymbolicLink_Proc) ( | |||
| 376 | LPTSTR lpSymlinkFileName, | 401 | LPTSTR lpSymlinkFileName, |
| 377 | LPTSTR lpTargetFileName, | 402 | LPTSTR lpTargetFileName, |
| 378 | DWORD dwFlags); | 403 | DWORD dwFlags); |
| 404 | typedef BOOL (WINAPI *ConvertStringSecurityDescriptorToSecurityDescriptor_Proc) ( | ||
| 405 | LPCTSTR StringSecurityDescriptor, | ||
| 406 | DWORD StringSDRevision, | ||
| 407 | PSECURITY_DESCRIPTOR *SecurityDescriptor, | ||
| 408 | PULONG SecurityDescriptorSize); | ||
| 409 | typedef BOOL (WINAPI *ConvertSecurityDescriptorToStringSecurityDescriptor_Proc) ( | ||
| 410 | PSECURITY_DESCRIPTOR SecurityDescriptor, | ||
| 411 | DWORD RequestedStringSDRevision, | ||
| 412 | SECURITY_INFORMATION SecurityInformation, | ||
| 413 | LPTSTR *StringSecurityDescriptor, | ||
| 414 | PULONG StringSecurityDescriptorLen); | ||
| 415 | typedef BOOL (WINAPI *IsValidSecurityDescriptor_Proc) (PSECURITY_DESCRIPTOR); | ||
| 379 | 416 | ||
| 380 | /* ** A utility function ** */ | 417 | /* ** A utility function ** */ |
| 381 | static BOOL | 418 | static BOOL |
| @@ -621,6 +658,7 @@ get_file_security (LPCTSTR lpFileName, | |||
| 621 | HMODULE hm_advapi32 = NULL; | 658 | HMODULE hm_advapi32 = NULL; |
| 622 | if (is_windows_9x () == TRUE) | 659 | if (is_windows_9x () == TRUE) |
| 623 | { | 660 | { |
| 661 | errno = ENOTSUP; | ||
| 624 | return FALSE; | 662 | return FALSE; |
| 625 | } | 663 | } |
| 626 | if (g_b_init_get_file_security == 0) | 664 | if (g_b_init_get_file_security == 0) |
| @@ -633,6 +671,7 @@ get_file_security (LPCTSTR lpFileName, | |||
| 633 | } | 671 | } |
| 634 | if (s_pfn_Get_File_Security == NULL) | 672 | if (s_pfn_Get_File_Security == NULL) |
| 635 | { | 673 | { |
| 674 | errno = ENOTSUP; | ||
| 636 | return FALSE; | 675 | return FALSE; |
| 637 | } | 676 | } |
| 638 | return (s_pfn_Get_File_Security (lpFileName, RequestedInformation, | 677 | return (s_pfn_Get_File_Security (lpFileName, RequestedInformation, |
| @@ -641,6 +680,35 @@ get_file_security (LPCTSTR lpFileName, | |||
| 641 | } | 680 | } |
| 642 | 681 | ||
| 643 | static BOOL WINAPI | 682 | static BOOL WINAPI |
| 683 | set_file_security (LPCTSTR lpFileName, | ||
| 684 | SECURITY_INFORMATION SecurityInformation, | ||
| 685 | PSECURITY_DESCRIPTOR pSecurityDescriptor) | ||
| 686 | { | ||
| 687 | static SetFileSecurity_Proc s_pfn_Set_File_Security = NULL; | ||
| 688 | HMODULE hm_advapi32 = NULL; | ||
| 689 | if (is_windows_9x () == TRUE) | ||
| 690 | { | ||
| 691 | errno = ENOTSUP; | ||
| 692 | return FALSE; | ||
| 693 | } | ||
| 694 | if (g_b_init_set_file_security == 0) | ||
| 695 | { | ||
| 696 | g_b_init_set_file_security = 1; | ||
| 697 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 698 | s_pfn_Set_File_Security = | ||
| 699 | (SetFileSecurity_Proc) GetProcAddress ( | ||
| 700 | hm_advapi32, SetFileSecurity_Name); | ||
| 701 | } | ||
| 702 | if (s_pfn_Set_File_Security == NULL) | ||
| 703 | { | ||
| 704 | errno = ENOTSUP; | ||
| 705 | return FALSE; | ||
| 706 | } | ||
| 707 | return (s_pfn_Set_File_Security (lpFileName, SecurityInformation, | ||
| 708 | pSecurityDescriptor)); | ||
| 709 | } | ||
| 710 | |||
| 711 | static BOOL WINAPI | ||
| 644 | get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, | 712 | get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, |
| 645 | PSID *pOwner, | 713 | PSID *pOwner, |
| 646 | LPBOOL lpbOwnerDefaulted) | 714 | LPBOOL lpbOwnerDefaulted) |
| @@ -649,6 +717,7 @@ get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 649 | HMODULE hm_advapi32 = NULL; | 717 | HMODULE hm_advapi32 = NULL; |
| 650 | if (is_windows_9x () == TRUE) | 718 | if (is_windows_9x () == TRUE) |
| 651 | { | 719 | { |
| 720 | errno = ENOTSUP; | ||
| 652 | return FALSE; | 721 | return FALSE; |
| 653 | } | 722 | } |
| 654 | if (g_b_init_get_security_descriptor_owner == 0) | 723 | if (g_b_init_get_security_descriptor_owner == 0) |
| @@ -661,6 +730,7 @@ get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 661 | } | 730 | } |
| 662 | if (s_pfn_Get_Security_Descriptor_Owner == NULL) | 731 | if (s_pfn_Get_Security_Descriptor_Owner == NULL) |
| 663 | { | 732 | { |
| 733 | errno = ENOTSUP; | ||
| 664 | return FALSE; | 734 | return FALSE; |
| 665 | } | 735 | } |
| 666 | return (s_pfn_Get_Security_Descriptor_Owner (pSecurityDescriptor, pOwner, | 736 | return (s_pfn_Get_Security_Descriptor_Owner (pSecurityDescriptor, pOwner, |
| @@ -676,6 +746,7 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 676 | HMODULE hm_advapi32 = NULL; | 746 | HMODULE hm_advapi32 = NULL; |
| 677 | if (is_windows_9x () == TRUE) | 747 | if (is_windows_9x () == TRUE) |
| 678 | { | 748 | { |
| 749 | errno = ENOTSUP; | ||
| 679 | return FALSE; | 750 | return FALSE; |
| 680 | } | 751 | } |
| 681 | if (g_b_init_get_security_descriptor_group == 0) | 752 | if (g_b_init_get_security_descriptor_group == 0) |
| @@ -688,6 +759,7 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 688 | } | 759 | } |
| 689 | if (s_pfn_Get_Security_Descriptor_Group == NULL) | 760 | if (s_pfn_Get_Security_Descriptor_Group == NULL) |
| 690 | { | 761 | { |
| 762 | errno = ENOTSUP; | ||
| 691 | return FALSE; | 763 | return FALSE; |
| 692 | } | 764 | } |
| 693 | return (s_pfn_Get_Security_Descriptor_Group (pSecurityDescriptor, pGroup, | 765 | return (s_pfn_Get_Security_Descriptor_Group (pSecurityDescriptor, pGroup, |
| @@ -695,6 +767,37 @@ get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor, | |||
| 695 | } | 767 | } |
| 696 | 768 | ||
| 697 | static BOOL WINAPI | 769 | static BOOL WINAPI |
| 770 | get_security_descriptor_dacl (PSECURITY_DESCRIPTOR pSecurityDescriptor, | ||
| 771 | LPBOOL lpbDaclPresent, | ||
| 772 | PACL *pDacl, | ||
| 773 | LPBOOL lpbDaclDefaulted) | ||
| 774 | { | ||
| 775 | static GetSecurityDescriptorDacl_Proc s_pfn_Get_Security_Descriptor_Dacl = NULL; | ||
| 776 | HMODULE hm_advapi32 = NULL; | ||
| 777 | if (is_windows_9x () == TRUE) | ||
| 778 | { | ||
| 779 | errno = ENOTSUP; | ||
| 780 | return FALSE; | ||
| 781 | } | ||
| 782 | if (g_b_init_get_security_descriptor_dacl == 0) | ||
| 783 | { | ||
| 784 | g_b_init_get_security_descriptor_dacl = 1; | ||
| 785 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 786 | s_pfn_Get_Security_Descriptor_Dacl = | ||
| 787 | (GetSecurityDescriptorDacl_Proc) GetProcAddress ( | ||
| 788 | hm_advapi32, "GetSecurityDescriptorDacl"); | ||
| 789 | } | ||
| 790 | if (s_pfn_Get_Security_Descriptor_Dacl == NULL) | ||
| 791 | { | ||
| 792 | errno = ENOTSUP; | ||
| 793 | return FALSE; | ||
| 794 | } | ||
| 795 | return (s_pfn_Get_Security_Descriptor_Dacl (pSecurityDescriptor, | ||
| 796 | lpbDaclPresent, pDacl, | ||
| 797 | lpbDaclDefaulted)); | ||
| 798 | } | ||
| 799 | |||
| 800 | static BOOL WINAPI | ||
| 698 | is_valid_sid (PSID sid) | 801 | is_valid_sid (PSID sid) |
| 699 | { | 802 | { |
| 700 | static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL; | 803 | static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL; |
| @@ -888,6 +991,120 @@ create_symbolic_link (LPTSTR lpSymlinkFilename, | |||
| 888 | } | 991 | } |
| 889 | return retval; | 992 | return retval; |
| 890 | } | 993 | } |
| 994 | |||
| 995 | static BOOL WINAPI | ||
| 996 | is_valid_security_descriptor (PSECURITY_DESCRIPTOR pSecurityDescriptor) | ||
| 997 | { | ||
| 998 | static IsValidSecurityDescriptor_Proc s_pfn_Is_Valid_Security_Descriptor_Proc = NULL; | ||
| 999 | |||
| 1000 | if (is_windows_9x () == TRUE) | ||
| 1001 | { | ||
| 1002 | errno = ENOTSUP; | ||
| 1003 | return FALSE; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | if (g_b_init_is_valid_security_descriptor == 0) | ||
| 1007 | { | ||
| 1008 | g_b_init_is_valid_security_descriptor = 1; | ||
| 1009 | s_pfn_Is_Valid_Security_Descriptor_Proc = | ||
| 1010 | (IsValidSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1011 | "IsValidSecurityDescriptor"); | ||
| 1012 | } | ||
| 1013 | if (s_pfn_Is_Valid_Security_Descriptor_Proc == NULL) | ||
| 1014 | { | ||
| 1015 | errno = ENOTSUP; | ||
| 1016 | return FALSE; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | return s_pfn_Is_Valid_Security_Descriptor_Proc (pSecurityDescriptor); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | static BOOL WINAPI | ||
| 1023 | convert_sd_to_sddl (PSECURITY_DESCRIPTOR SecurityDescriptor, | ||
| 1024 | DWORD RequestedStringSDRevision, | ||
| 1025 | SECURITY_INFORMATION SecurityInformation, | ||
| 1026 | LPTSTR *StringSecurityDescriptor, | ||
| 1027 | PULONG StringSecurityDescriptorLen) | ||
| 1028 | { | ||
| 1029 | static ConvertSecurityDescriptorToStringSecurityDescriptor_Proc s_pfn_Convert_SD_To_SDDL = NULL; | ||
| 1030 | BOOL retval; | ||
| 1031 | |||
| 1032 | if (is_windows_9x () == TRUE) | ||
| 1033 | { | ||
| 1034 | errno = ENOTSUP; | ||
| 1035 | return FALSE; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | if (g_b_init_convert_sd_to_sddl == 0) | ||
| 1039 | { | ||
| 1040 | g_b_init_convert_sd_to_sddl = 1; | ||
| 1041 | #ifdef _UNICODE | ||
| 1042 | s_pfn_Convert_SD_To_SDDL = | ||
| 1043 | (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1044 | "ConvertSecurityDescriptorToStringSecurityDescriptorW"); | ||
| 1045 | #else | ||
| 1046 | s_pfn_Convert_SD_To_SDDL = | ||
| 1047 | (ConvertSecurityDescriptorToStringSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1048 | "ConvertSecurityDescriptorToStringSecurityDescriptorA"); | ||
| 1049 | #endif | ||
| 1050 | } | ||
| 1051 | if (s_pfn_Convert_SD_To_SDDL == NULL) | ||
| 1052 | { | ||
| 1053 | errno = ENOTSUP; | ||
| 1054 | return FALSE; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | retval = s_pfn_Convert_SD_To_SDDL (SecurityDescriptor, | ||
| 1058 | RequestedStringSDRevision, | ||
| 1059 | SecurityInformation, | ||
| 1060 | StringSecurityDescriptor, | ||
| 1061 | StringSecurityDescriptorLen); | ||
| 1062 | |||
| 1063 | return retval; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | static BOOL WINAPI | ||
| 1067 | convert_sddl_to_sd (LPCTSTR StringSecurityDescriptor, | ||
| 1068 | DWORD StringSDRevision, | ||
| 1069 | PSECURITY_DESCRIPTOR *SecurityDescriptor, | ||
| 1070 | PULONG SecurityDescriptorSize) | ||
| 1071 | { | ||
| 1072 | static ConvertStringSecurityDescriptorToSecurityDescriptor_Proc s_pfn_Convert_SDDL_To_SD = NULL; | ||
| 1073 | BOOL retval; | ||
| 1074 | |||
| 1075 | if (is_windows_9x () == TRUE) | ||
| 1076 | { | ||
| 1077 | errno = ENOTSUP; | ||
| 1078 | return FALSE; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | if (g_b_init_convert_sddl_to_sd == 0) | ||
| 1082 | { | ||
| 1083 | g_b_init_convert_sddl_to_sd = 1; | ||
| 1084 | #ifdef _UNICODE | ||
| 1085 | s_pfn_Convert_SDDL_To_SD = | ||
| 1086 | (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1087 | "ConvertStringSecurityDescriptorToSecurityDescriptorW"); | ||
| 1088 | #else | ||
| 1089 | s_pfn_Convert_SDDL_To_SD = | ||
| 1090 | (ConvertStringSecurityDescriptorToSecurityDescriptor_Proc)GetProcAddress (GetModuleHandle ("Advapi32.dll"), | ||
| 1091 | "ConvertStringSecurityDescriptorToSecurityDescriptorA"); | ||
| 1092 | #endif | ||
| 1093 | } | ||
| 1094 | if (s_pfn_Convert_SDDL_To_SD == NULL) | ||
| 1095 | { | ||
| 1096 | errno = ENOTSUP; | ||
| 1097 | return FALSE; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | retval = s_pfn_Convert_SDDL_To_SD (StringSecurityDescriptor, | ||
| 1101 | StringSDRevision, | ||
| 1102 | SecurityDescriptor, | ||
| 1103 | SecurityDescriptorSize); | ||
| 1104 | |||
| 1105 | return retval; | ||
| 1106 | } | ||
| 1107 | |||
| 891 | 1108 | ||
| 892 | 1109 | ||
| 893 | /* Return 1 if P is a valid pointer to an object of size SIZE. Return | 1110 | /* Return 1 if P is a valid pointer to an object of size SIZE. Return |
| @@ -1314,35 +1531,110 @@ srandom (int seed) | |||
| 1314 | srand (seed); | 1531 | srand (seed); |
| 1315 | } | 1532 | } |
| 1316 | 1533 | ||
| 1534 | /* Current codepage for encoding file names. */ | ||
| 1535 | static int file_name_codepage; | ||
| 1536 | |||
| 1537 | /* Return the maximum length in bytes of a multibyte character | ||
| 1538 | sequence encoded in the current ANSI codepage. This is required to | ||
| 1539 | correctly walk the encoded file names one character at a time. */ | ||
| 1540 | static int | ||
| 1541 | max_filename_mbslen (void) | ||
| 1542 | { | ||
| 1543 | /* A simple cache to avoid calling GetCPInfo every time we need to | ||
| 1544 | normalize a file name. The file-name encoding is not supposed to | ||
| 1545 | be changed too frequently, if ever. */ | ||
| 1546 | static Lisp_Object last_file_name_encoding; | ||
| 1547 | static int last_max_mbslen; | ||
| 1548 | Lisp_Object current_encoding; | ||
| 1549 | |||
| 1550 | current_encoding = Vfile_name_coding_system; | ||
| 1551 | if (NILP (current_encoding)) | ||
| 1552 | current_encoding = Vdefault_file_name_coding_system; | ||
| 1553 | |||
| 1554 | if (!EQ (last_file_name_encoding, current_encoding)) | ||
| 1555 | { | ||
| 1556 | CPINFO cp_info; | ||
| 1557 | |||
| 1558 | last_file_name_encoding = current_encoding; | ||
| 1559 | /* Default to the current ANSI codepage. */ | ||
| 1560 | file_name_codepage = w32_ansi_code_page; | ||
| 1561 | if (!NILP (current_encoding)) | ||
| 1562 | { | ||
| 1563 | char *cpname = SDATA (SYMBOL_NAME (current_encoding)); | ||
| 1564 | char *cp = NULL, *end; | ||
| 1565 | int cpnum; | ||
| 1566 | |||
| 1567 | if (strncmp (cpname, "cp", 2) == 0) | ||
| 1568 | cp = cpname + 2; | ||
| 1569 | else if (strncmp (cpname, "windows-", 8) == 0) | ||
| 1570 | cp = cpname + 8; | ||
| 1571 | |||
| 1572 | if (cp) | ||
| 1573 | { | ||
| 1574 | end = cp; | ||
| 1575 | cpnum = strtol (cp, &end, 10); | ||
| 1576 | if (cpnum && *end == '\0' && end - cp >= 2) | ||
| 1577 | file_name_codepage = cpnum; | ||
| 1578 | } | ||
| 1579 | } | ||
| 1580 | |||
| 1581 | if (!file_name_codepage) | ||
| 1582 | file_name_codepage = CP_ACP; /* CP_ACP = 0, but let's not assume that */ | ||
| 1583 | |||
| 1584 | if (!GetCPInfo (file_name_codepage, &cp_info)) | ||
| 1585 | { | ||
| 1586 | file_name_codepage = CP_ACP; | ||
| 1587 | if (!GetCPInfo (file_name_codepage, &cp_info)) | ||
| 1588 | emacs_abort (); | ||
| 1589 | } | ||
| 1590 | last_max_mbslen = cp_info.MaxCharSize; | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | return last_max_mbslen; | ||
| 1594 | } | ||
| 1317 | 1595 | ||
| 1318 | /* Normalize filename by converting all path separators to | 1596 | /* Normalize filename by converting all path separators to |
| 1319 | the specified separator. Also conditionally convert upper | 1597 | the specified separator. Also conditionally convert upper |
| 1320 | case path name components to lower case. */ | 1598 | case path name components to lower case. */ |
| 1321 | 1599 | ||
| 1322 | static void | 1600 | static void |
| 1323 | normalize_filename (register char *fp, char path_sep) | 1601 | normalize_filename (register char *fp, char path_sep, int multibyte) |
| 1324 | { | 1602 | { |
| 1325 | char sep; | 1603 | char sep; |
| 1326 | char *elem; | 1604 | char *elem, *p2; |
| 1605 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 1606 | |||
| 1607 | /* Multibyte file names are in the Emacs internal representation, so | ||
| 1608 | we can traverse them by bytes with no problems. */ | ||
| 1609 | if (multibyte) | ||
| 1610 | dbcs_p = 0; | ||
| 1327 | 1611 | ||
| 1328 | /* Always lower-case drive letters a-z, even if the filesystem | 1612 | /* Always lower-case drive letters a-z, even if the filesystem |
| 1329 | preserves case in filenames. | 1613 | preserves case in filenames. |
| 1330 | This is so filenames can be compared by string comparison | 1614 | This is so filenames can be compared by string comparison |
| 1331 | functions that are case-sensitive. Even case-preserving filesystems | 1615 | functions that are case-sensitive. Even case-preserving filesystems |
| 1332 | do not distinguish case in drive letters. */ | 1616 | do not distinguish case in drive letters. */ |
| 1333 | if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z') | 1617 | if (dbcs_p) |
| 1618 | p2 = CharNextExA (file_name_codepage, fp, 0); | ||
| 1619 | else | ||
| 1620 | p2 = fp + 1; | ||
| 1621 | |||
| 1622 | if (*p2 == ':' && *fp >= 'A' && *fp <= 'Z') | ||
| 1334 | { | 1623 | { |
| 1335 | *fp += 'a' - 'A'; | 1624 | *fp += 'a' - 'A'; |
| 1336 | fp += 2; | 1625 | fp += 2; |
| 1337 | } | 1626 | } |
| 1338 | 1627 | ||
| 1339 | if (NILP (Vw32_downcase_file_names)) | 1628 | if (multibyte || NILP (Vw32_downcase_file_names)) |
| 1340 | { | 1629 | { |
| 1341 | while (*fp) | 1630 | while (*fp) |
| 1342 | { | 1631 | { |
| 1343 | if (*fp == '/' || *fp == '\\') | 1632 | if (*fp == '/' || *fp == '\\') |
| 1344 | *fp = path_sep; | 1633 | *fp = path_sep; |
| 1345 | fp++; | 1634 | if (!dbcs_p) |
| 1635 | fp++; | ||
| 1636 | else | ||
| 1637 | fp = CharNextExA (file_name_codepage, fp, 0); | ||
| 1346 | } | 1638 | } |
| 1347 | return; | 1639 | return; |
| 1348 | } | 1640 | } |
| @@ -1365,27 +1657,36 @@ normalize_filename (register char *fp, char path_sep) | |||
| 1365 | if (elem && elem != fp) | 1657 | if (elem && elem != fp) |
| 1366 | { | 1658 | { |
| 1367 | *fp = 0; /* temporary end of string */ | 1659 | *fp = 0; /* temporary end of string */ |
| 1368 | _strlwr (elem); /* while we convert to lower case */ | 1660 | _mbslwr (elem); /* while we convert to lower case */ |
| 1369 | } | 1661 | } |
| 1370 | *fp = sep; /* convert (or restore) path separator */ | 1662 | *fp = sep; /* convert (or restore) path separator */ |
| 1371 | elem = fp + 1; /* next element starts after separator */ | 1663 | elem = fp + 1; /* next element starts after separator */ |
| 1372 | sep = path_sep; | 1664 | sep = path_sep; |
| 1373 | } | 1665 | } |
| 1374 | } while (*fp++); | 1666 | if (*fp) |
| 1667 | { | ||
| 1668 | if (!dbcs_p) | ||
| 1669 | fp++; | ||
| 1670 | else | ||
| 1671 | fp = CharNextExA (file_name_codepage, fp, 0); | ||
| 1672 | } | ||
| 1673 | } while (*fp); | ||
| 1375 | } | 1674 | } |
| 1376 | 1675 | ||
| 1377 | /* Destructively turn backslashes into slashes. */ | 1676 | /* Destructively turn backslashes into slashes. MULTIBYTE non-zero |
| 1677 | means the file name is a multibyte string in Emacs's internal | ||
| 1678 | representation. */ | ||
| 1378 | void | 1679 | void |
| 1379 | dostounix_filename (register char *p) | 1680 | dostounix_filename (register char *p, int multibyte) |
| 1380 | { | 1681 | { |
| 1381 | normalize_filename (p, '/'); | 1682 | normalize_filename (p, '/', multibyte); |
| 1382 | } | 1683 | } |
| 1383 | 1684 | ||
| 1384 | /* Destructively turn slashes into backslashes. */ | 1685 | /* Destructively turn slashes into backslashes. */ |
| 1385 | void | 1686 | void |
| 1386 | unixtodos_filename (register char *p) | 1687 | unixtodos_filename (register char *p) |
| 1387 | { | 1688 | { |
| 1388 | normalize_filename (p, '\\'); | 1689 | normalize_filename (p, '\\', 0); |
| 1389 | } | 1690 | } |
| 1390 | 1691 | ||
| 1391 | /* Remove all CR's that are followed by a LF. | 1692 | /* Remove all CR's that are followed by a LF. |
| @@ -1436,12 +1737,17 @@ parse_root (char * name, char ** pPath) | |||
| 1436 | else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) | 1737 | else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) |
| 1437 | { | 1738 | { |
| 1438 | int slashes = 2; | 1739 | int slashes = 2; |
| 1740 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 1741 | |||
| 1439 | name += 2; | 1742 | name += 2; |
| 1440 | do | 1743 | do |
| 1441 | { | 1744 | { |
| 1442 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) | 1745 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) |
| 1443 | break; | 1746 | break; |
| 1444 | name++; | 1747 | if (dbcs_p) |
| 1748 | name = CharNextExA (file_name_codepage, name, 0); | ||
| 1749 | else | ||
| 1750 | name++; | ||
| 1445 | } | 1751 | } |
| 1446 | while ( *name ); | 1752 | while ( *name ); |
| 1447 | if (IS_DIRECTORY_SEP (name[0])) | 1753 | if (IS_DIRECTORY_SEP (name[0])) |
| @@ -1506,7 +1812,7 @@ w32_get_long_filename (char * name, char * buf, int size) | |||
| 1506 | while (p != NULL && *p) | 1812 | while (p != NULL && *p) |
| 1507 | { | 1813 | { |
| 1508 | q = p; | 1814 | q = p; |
| 1509 | p = strchr (q, '\\'); | 1815 | p = _mbschr (q, '\\'); |
| 1510 | if (p) *p = '\0'; | 1816 | if (p) *p = '\0'; |
| 1511 | len = get_long_basename (full, o, size); | 1817 | len = get_long_basename (full, o, size); |
| 1512 | if (len > 0) | 1818 | if (len > 0) |
| @@ -1567,6 +1873,7 @@ unsetenv (const char *name) | |||
| 1567 | /* It is safe to use 'alloca' with 32K size, since the stack is at | 1873 | /* It is safe to use 'alloca' with 32K size, since the stack is at |
| 1568 | least 2MB, and we set it to 8MB in the link command line. */ | 1874 | least 2MB, and we set it to 8MB in the link command line. */ |
| 1569 | var = alloca (name_len + 2); | 1875 | var = alloca (name_len + 2); |
| 1876 | strncpy (var, name, name_len); | ||
| 1570 | var[name_len++] = '='; | 1877 | var[name_len++] = '='; |
| 1571 | var[name_len] = '\0'; | 1878 | var[name_len] = '\0'; |
| 1572 | return _putenv (var); | 1879 | return _putenv (var); |
| @@ -1777,16 +2084,16 @@ init_environment (char ** argv) | |||
| 1777 | 2084 | ||
| 1778 | if (!GetModuleFileName (NULL, modname, MAX_PATH)) | 2085 | if (!GetModuleFileName (NULL, modname, MAX_PATH)) |
| 1779 | emacs_abort (); | 2086 | emacs_abort (); |
| 1780 | if ((p = strrchr (modname, '\\')) == NULL) | 2087 | if ((p = _mbsrchr (modname, '\\')) == NULL) |
| 1781 | emacs_abort (); | 2088 | emacs_abort (); |
| 1782 | *p = 0; | 2089 | *p = 0; |
| 1783 | 2090 | ||
| 1784 | if ((p = strrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) | 2091 | if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) |
| 1785 | { | 2092 | { |
| 1786 | char buf[SET_ENV_BUF_SIZE]; | 2093 | char buf[SET_ENV_BUF_SIZE]; |
| 1787 | 2094 | ||
| 1788 | *p = 0; | 2095 | *p = 0; |
| 1789 | for (p = modname; *p; p++) | 2096 | for (p = modname; *p; p = CharNext (p)) |
| 1790 | if (*p == '\\') *p = '/'; | 2097 | if (*p == '\\') *p = '/'; |
| 1791 | 2098 | ||
| 1792 | _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); | 2099 | _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); |
| @@ -1801,17 +2108,17 @@ init_environment (char ** argv) | |||
| 1801 | || xstrcasecmp (p, "\\AMD64") == 0)) | 2108 | || xstrcasecmp (p, "\\AMD64") == 0)) |
| 1802 | { | 2109 | { |
| 1803 | *p = 0; | 2110 | *p = 0; |
| 1804 | p = strrchr (modname, '\\'); | 2111 | p = _mbsrchr (modname, '\\'); |
| 1805 | if (p != NULL) | 2112 | if (p != NULL) |
| 1806 | { | 2113 | { |
| 1807 | *p = 0; | 2114 | *p = 0; |
| 1808 | p = strrchr (modname, '\\'); | 2115 | p = _mbsrchr (modname, '\\'); |
| 1809 | if (p && xstrcasecmp (p, "\\src") == 0) | 2116 | if (p && xstrcasecmp (p, "\\src") == 0) |
| 1810 | { | 2117 | { |
| 1811 | char buf[SET_ENV_BUF_SIZE]; | 2118 | char buf[SET_ENV_BUF_SIZE]; |
| 1812 | 2119 | ||
| 1813 | *p = 0; | 2120 | *p = 0; |
| 1814 | for (p = modname; *p; p++) | 2121 | for (p = modname; *p; p = CharNext (p)) |
| 1815 | if (*p == '\\') *p = '/'; | 2122 | if (*p == '\\') *p = '/'; |
| 1816 | 2123 | ||
| 1817 | _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); | 2124 | _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); |
| @@ -1922,7 +2229,7 @@ emacs_root_dir (void) | |||
| 1922 | emacs_abort (); | 2229 | emacs_abort (); |
| 1923 | strcpy (root_dir, p); | 2230 | strcpy (root_dir, p); |
| 1924 | root_dir[parse_root (root_dir, NULL)] = '\0'; | 2231 | root_dir[parse_root (root_dir, NULL)] = '\0'; |
| 1925 | dostounix_filename (root_dir); | 2232 | dostounix_filename (root_dir, 0); |
| 1926 | return root_dir; | 2233 | return root_dir; |
| 1927 | } | 2234 | } |
| 1928 | 2235 | ||
| @@ -2346,12 +2653,23 @@ get_volume_info (const char * name, const char ** pPath) | |||
| 2346 | { | 2653 | { |
| 2347 | char *str = temp; | 2654 | char *str = temp; |
| 2348 | int slashes = 4; | 2655 | int slashes = 4; |
| 2656 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 2657 | |||
| 2349 | rootname = temp; | 2658 | rootname = temp; |
| 2350 | do | 2659 | do |
| 2351 | { | 2660 | { |
| 2352 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) | 2661 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) |
| 2353 | break; | 2662 | break; |
| 2354 | *str++ = *name++; | 2663 | if (!dbcs_p) |
| 2664 | *str++ = *name++; | ||
| 2665 | else | ||
| 2666 | { | ||
| 2667 | const char *p = name; | ||
| 2668 | |||
| 2669 | name = CharNextExA (file_name_codepage, name, 0); | ||
| 2670 | memcpy (str, p, name - p); | ||
| 2671 | str += name - p; | ||
| 2672 | } | ||
| 2355 | } | 2673 | } |
| 2356 | while ( *name ); | 2674 | while ( *name ); |
| 2357 | 2675 | ||
| @@ -2514,7 +2832,7 @@ static char *read_unc_volume (HANDLE, char *, int); | |||
| 2514 | static void close_unc_volume (HANDLE); | 2832 | static void close_unc_volume (HANDLE); |
| 2515 | 2833 | ||
| 2516 | DIR * | 2834 | DIR * |
| 2517 | opendir (char *filename) | 2835 | opendir (const char *filename) |
| 2518 | { | 2836 | { |
| 2519 | DIR *dirp; | 2837 | DIR *dirp; |
| 2520 | 2838 | ||
| @@ -2587,11 +2905,23 @@ readdir (DIR *dirp) | |||
| 2587 | { | 2905 | { |
| 2588 | char filename[MAXNAMLEN + 3]; | 2906 | char filename[MAXNAMLEN + 3]; |
| 2589 | int ln; | 2907 | int ln; |
| 2908 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 2590 | 2909 | ||
| 2591 | strcpy (filename, dir_pathname); | 2910 | strcpy (filename, dir_pathname); |
| 2592 | ln = strlen (filename) - 1; | 2911 | ln = strlen (filename) - 1; |
| 2593 | if (!IS_DIRECTORY_SEP (filename[ln])) | 2912 | if (!dbcs_p) |
| 2594 | strcat (filename, "\\"); | 2913 | { |
| 2914 | if (!IS_DIRECTORY_SEP (filename[ln])) | ||
| 2915 | strcat (filename, "\\"); | ||
| 2916 | } | ||
| 2917 | else | ||
| 2918 | { | ||
| 2919 | char *end = filename + ln + 1; | ||
| 2920 | char *last_char = CharPrevExA (file_name_codepage, filename, end, 0); | ||
| 2921 | |||
| 2922 | if (!IS_DIRECTORY_SEP (*last_char)) | ||
| 2923 | strcat (filename, "\\"); | ||
| 2924 | } | ||
| 2595 | strcat (filename, "*"); | 2925 | strcat (filename, "*"); |
| 2596 | 2926 | ||
| 2597 | /* Note: No need to resolve symlinks in FILENAME, because | 2927 | /* Note: No need to resolve symlinks in FILENAME, because |
| @@ -2642,15 +2972,22 @@ readdir (DIR *dirp) | |||
| 2642 | strcpy (dir_static.d_name, dir_find_data.cFileName); | 2972 | strcpy (dir_static.d_name, dir_find_data.cFileName); |
| 2643 | dir_static.d_namlen = strlen (dir_static.d_name); | 2973 | dir_static.d_namlen = strlen (dir_static.d_name); |
| 2644 | if (dir_is_fat) | 2974 | if (dir_is_fat) |
| 2645 | _strlwr (dir_static.d_name); | 2975 | _mbslwr (dir_static.d_name); |
| 2646 | else if (downcase) | 2976 | else if (downcase) |
| 2647 | { | 2977 | { |
| 2648 | register char *p; | 2978 | register char *p; |
| 2649 | for (p = dir_static.d_name; *p; p++) | 2979 | int dbcs_p = max_filename_mbslen () > 1; |
| 2650 | if (*p >= 'a' && *p <= 'z') | 2980 | for (p = dir_static.d_name; *p; ) |
| 2651 | break; | 2981 | { |
| 2982 | if (*p >= 'a' && *p <= 'z') | ||
| 2983 | break; | ||
| 2984 | if (dbcs_p) | ||
| 2985 | p = CharNextExA (file_name_codepage, p, 0); | ||
| 2986 | else | ||
| 2987 | p++; | ||
| 2988 | } | ||
| 2652 | if (!*p) | 2989 | if (!*p) |
| 2653 | _strlwr (dir_static.d_name); | 2990 | _mbslwr (dir_static.d_name); |
| 2654 | } | 2991 | } |
| 2655 | 2992 | ||
| 2656 | return &dir_static; | 2993 | return &dir_static; |
| @@ -2689,6 +3026,7 @@ read_unc_volume (HANDLE henum, char *readbuf, int size) | |||
| 2689 | DWORD bufsize = 512; | 3026 | DWORD bufsize = 512; |
| 2690 | char *buffer; | 3027 | char *buffer; |
| 2691 | char *ptr; | 3028 | char *ptr; |
| 3029 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 2692 | 3030 | ||
| 2693 | count = 1; | 3031 | count = 1; |
| 2694 | buffer = alloca (bufsize); | 3032 | buffer = alloca (bufsize); |
| @@ -2699,7 +3037,13 @@ read_unc_volume (HANDLE henum, char *readbuf, int size) | |||
| 2699 | /* WNetEnumResource returns \\resource\share...skip forward to "share". */ | 3037 | /* WNetEnumResource returns \\resource\share...skip forward to "share". */ |
| 2700 | ptr = ((LPNETRESOURCE) buffer)->lpRemoteName; | 3038 | ptr = ((LPNETRESOURCE) buffer)->lpRemoteName; |
| 2701 | ptr += 2; | 3039 | ptr += 2; |
| 2702 | while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++; | 3040 | if (!dbcs_p) |
| 3041 | while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++; | ||
| 3042 | else | ||
| 3043 | { | ||
| 3044 | while (*ptr && !IS_DIRECTORY_SEP (*ptr)) | ||
| 3045 | ptr = CharNextExA (file_name_codepage, ptr, 0); | ||
| 3046 | } | ||
| 2703 | ptr++; | 3047 | ptr++; |
| 2704 | 3048 | ||
| 2705 | strncpy (readbuf, ptr, size); | 3049 | strncpy (readbuf, ptr, size); |
| @@ -2736,9 +3080,11 @@ logon_network_drive (const char *path) | |||
| 2736 | { | 3080 | { |
| 2737 | NETRESOURCE resource; | 3081 | NETRESOURCE resource; |
| 2738 | char share[MAX_PATH]; | 3082 | char share[MAX_PATH]; |
| 2739 | int i, n_slashes; | 3083 | int n_slashes; |
| 2740 | char drive[4]; | 3084 | char drive[4]; |
| 2741 | UINT drvtype; | 3085 | UINT drvtype; |
| 3086 | char *p; | ||
| 3087 | int dbcs_p; | ||
| 2742 | 3088 | ||
| 2743 | if (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1])) | 3089 | if (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1])) |
| 2744 | drvtype = DRIVE_REMOTE; | 3090 | drvtype = DRIVE_REMOTE; |
| @@ -2760,13 +3106,18 @@ logon_network_drive (const char *path) | |||
| 2760 | n_slashes = 2; | 3106 | n_slashes = 2; |
| 2761 | strncpy (share, path, MAX_PATH); | 3107 | strncpy (share, path, MAX_PATH); |
| 2762 | /* Truncate to just server and share name. */ | 3108 | /* Truncate to just server and share name. */ |
| 2763 | for (i = 2; i < MAX_PATH; i++) | 3109 | dbcs_p = max_filename_mbslen () > 1; |
| 3110 | for (p = share + 2; *p && p < share + MAX_PATH; ) | ||
| 2764 | { | 3111 | { |
| 2765 | if (IS_DIRECTORY_SEP (share[i]) && ++n_slashes > 3) | 3112 | if (IS_DIRECTORY_SEP (*p) && ++n_slashes > 3) |
| 2766 | { | 3113 | { |
| 2767 | share[i] = '\0'; | 3114 | *p = '\0'; |
| 2768 | break; | 3115 | break; |
| 2769 | } | 3116 | } |
| 3117 | if (dbcs_p) | ||
| 3118 | p = CharNextExA (file_name_codepage, p, 0); | ||
| 3119 | else | ||
| 3120 | p++; | ||
| 2770 | } | 3121 | } |
| 2771 | 3122 | ||
| 2772 | resource.dwType = RESOURCETYPE_DISK; | 3123 | resource.dwType = RESOURCETYPE_DISK; |
| @@ -2869,14 +3220,6 @@ sys_chmod (const char * path, int mode) | |||
| 2869 | } | 3220 | } |
| 2870 | 3221 | ||
| 2871 | int | 3222 | int |
| 2872 | sys_chown (const char *path, uid_t owner, gid_t group) | ||
| 2873 | { | ||
| 2874 | if (sys_chmod (path, S_IREAD) == -1) /* check if file exists */ | ||
| 2875 | return -1; | ||
| 2876 | return 0; | ||
| 2877 | } | ||
| 2878 | |||
| 2879 | int | ||
| 2880 | sys_creat (const char * path, int mode) | 3223 | sys_creat (const char * path, int mode) |
| 2881 | { | 3224 | { |
| 2882 | return _creat (map_w32_filename (path, NULL), mode); | 3225 | return _creat (map_w32_filename (path, NULL), mode); |
| @@ -3063,9 +3406,12 @@ sys_open (const char * path, int oflag, int mode) | |||
| 3063 | and system files. Force all file handles to be | 3406 | and system files. Force all file handles to be |
| 3064 | non-inheritable. */ | 3407 | non-inheritable. */ |
| 3065 | int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); | 3408 | int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); |
| 3066 | if (res >= 0) | 3409 | if (res < 0) |
| 3067 | return res; | 3410 | res = _open (mpath, oflag | _O_NOINHERIT, mode); |
| 3068 | return _open (mpath, oflag | _O_NOINHERIT, mode); | 3411 | if (res >= 0 && res < MAXDESC) |
| 3412 | fd_info[res].flags = 0; | ||
| 3413 | |||
| 3414 | return res; | ||
| 3069 | } | 3415 | } |
| 3070 | 3416 | ||
| 3071 | int | 3417 | int |
| @@ -3427,18 +3773,15 @@ w32_add_to_cache (PSID sid, unsigned id, char *name) | |||
| 3427 | #define GID 2 | 3773 | #define GID 2 |
| 3428 | 3774 | ||
| 3429 | static int | 3775 | static int |
| 3430 | get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname, | 3776 | get_name_and_id (PSECURITY_DESCRIPTOR psd, unsigned *id, char *nm, int what) |
| 3431 | unsigned *id, char *nm, int what) | ||
| 3432 | { | 3777 | { |
| 3433 | PSID sid = NULL; | 3778 | PSID sid = NULL; |
| 3434 | char machine[MAX_COMPUTERNAME_LENGTH+1]; | ||
| 3435 | BOOL dflt; | 3779 | BOOL dflt; |
| 3436 | SID_NAME_USE ignore; | 3780 | SID_NAME_USE ignore; |
| 3437 | char name[UNLEN+1]; | 3781 | char name[UNLEN+1]; |
| 3438 | DWORD name_len = sizeof (name); | 3782 | DWORD name_len = sizeof (name); |
| 3439 | char domain[1024]; | 3783 | char domain[1024]; |
| 3440 | DWORD domain_len = sizeof (domain); | 3784 | DWORD domain_len = sizeof (domain); |
| 3441 | char *mp = NULL; | ||
| 3442 | int use_dflt = 0; | 3785 | int use_dflt = 0; |
| 3443 | int result; | 3786 | int result; |
| 3444 | 3787 | ||
| @@ -3453,22 +3796,7 @@ get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname, | |||
| 3453 | use_dflt = 1; | 3796 | use_dflt = 1; |
| 3454 | else if (!w32_cached_id (sid, id, nm)) | 3797 | else if (!w32_cached_id (sid, id, nm)) |
| 3455 | { | 3798 | { |
| 3456 | /* If FNAME is a UNC, we need to lookup account on the | 3799 | if (!lookup_account_sid (NULL, sid, name, &name_len, |
| 3457 | specified machine. */ | ||
| 3458 | if (IS_DIRECTORY_SEP (fname[0]) && IS_DIRECTORY_SEP (fname[1]) | ||
| 3459 | && fname[2] != '\0') | ||
| 3460 | { | ||
| 3461 | const char *s; | ||
| 3462 | char *p; | ||
| 3463 | |||
| 3464 | for (s = fname + 2, p = machine; | ||
| 3465 | *s && !IS_DIRECTORY_SEP (*s); s++, p++) | ||
| 3466 | *p = *s; | ||
| 3467 | *p = '\0'; | ||
| 3468 | mp = machine; | ||
| 3469 | } | ||
| 3470 | |||
| 3471 | if (!lookup_account_sid (mp, sid, name, &name_len, | ||
| 3472 | domain, &domain_len, &ignore) | 3800 | domain, &domain_len, &ignore) |
| 3473 | || name_len > UNLEN+1) | 3801 | || name_len > UNLEN+1) |
| 3474 | use_dflt = 1; | 3802 | use_dflt = 1; |
| @@ -3483,9 +3811,7 @@ get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname, | |||
| 3483 | } | 3811 | } |
| 3484 | 3812 | ||
| 3485 | static void | 3813 | static void |
| 3486 | get_file_owner_and_group (PSECURITY_DESCRIPTOR psd, | 3814 | get_file_owner_and_group (PSECURITY_DESCRIPTOR psd, struct stat *st) |
| 3487 | const char *fname, | ||
| 3488 | struct stat *st) | ||
| 3489 | { | 3815 | { |
| 3490 | int dflt_usr = 0, dflt_grp = 0; | 3816 | int dflt_usr = 0, dflt_grp = 0; |
| 3491 | 3817 | ||
| @@ -3496,9 +3822,9 @@ get_file_owner_and_group (PSECURITY_DESCRIPTOR psd, | |||
| 3496 | } | 3822 | } |
| 3497 | else | 3823 | else |
| 3498 | { | 3824 | { |
| 3499 | if (get_name_and_id (psd, fname, &st->st_uid, st->st_uname, UID)) | 3825 | if (get_name_and_id (psd, &st->st_uid, st->st_uname, UID)) |
| 3500 | dflt_usr = 1; | 3826 | dflt_usr = 1; |
| 3501 | if (get_name_and_id (psd, fname, &st->st_gid, st->st_gname, GID)) | 3827 | if (get_name_and_id (psd, &st->st_gid, st->st_gname, GID)) |
| 3502 | dflt_grp = 1; | 3828 | dflt_grp = 1; |
| 3503 | } | 3829 | } |
| 3504 | /* Consider files to belong to current user/group, if we cannot get | 3830 | /* Consider files to belong to current user/group, if we cannot get |
| @@ -3537,6 +3863,10 @@ is_slow_fs (const char *name) | |||
| 3537 | return !(devtype == DRIVE_FIXED || devtype == DRIVE_RAMDISK); | 3863 | return !(devtype == DRIVE_FIXED || devtype == DRIVE_RAMDISK); |
| 3538 | } | 3864 | } |
| 3539 | 3865 | ||
| 3866 | /* If this is non-zero, the caller wants accurate information about | ||
| 3867 | file's owner and group, which could be expensive to get. */ | ||
| 3868 | int w32_stat_get_owner_group; | ||
| 3869 | |||
| 3540 | /* MSVC stat function can't cope with UNC names and has other bugs, so | 3870 | /* MSVC stat function can't cope with UNC names and has other bugs, so |
| 3541 | replace it with our own. This also allows us to calculate consistent | 3871 | replace it with our own. This also allows us to calculate consistent |
| 3542 | inode values and owner/group without hacks in the main Emacs code. */ | 3872 | inode values and owner/group without hacks in the main Emacs code. */ |
| @@ -3557,6 +3887,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3557 | DWORD access_rights = 0; | 3887 | DWORD access_rights = 0; |
| 3558 | DWORD fattrs = 0, serialnum = 0, fs_high = 0, fs_low = 0, nlinks = 1; | 3888 | DWORD fattrs = 0, serialnum = 0, fs_high = 0, fs_low = 0, nlinks = 1; |
| 3559 | FILETIME ctime, atime, wtime; | 3889 | FILETIME ctime, atime, wtime; |
| 3890 | int dbcs_p; | ||
| 3560 | 3891 | ||
| 3561 | if (path == NULL || buf == NULL) | 3892 | if (path == NULL || buf == NULL) |
| 3562 | { | 3893 | { |
| @@ -3708,6 +4039,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3708 | /* We produce the fallback owner and group data, based on the | 4039 | /* We produce the fallback owner and group data, based on the |
| 3709 | current user that runs Emacs, in the following cases: | 4040 | current user that runs Emacs, in the following cases: |
| 3710 | 4041 | ||
| 4042 | . caller didn't request owner and group info | ||
| 3711 | . this is Windows 9X | 4043 | . this is Windows 9X |
| 3712 | . getting security by handle failed, and we need to produce | 4044 | . getting security by handle failed, and we need to produce |
| 3713 | information for the target of a symlink (this is better | 4045 | information for the target of a symlink (this is better |
| @@ -3716,23 +4048,25 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3716 | 4048 | ||
| 3717 | If getting security by handle fails, and we don't need to | 4049 | If getting security by handle fails, and we don't need to |
| 3718 | resolve symlinks, we try getting security by name. */ | 4050 | resolve symlinks, we try getting security by name. */ |
| 3719 | if (is_windows_9x () != TRUE) | 4051 | if (!w32_stat_get_owner_group || is_windows_9x () == TRUE) |
| 3720 | psd = get_file_security_desc_by_handle (fh); | 4052 | get_file_owner_and_group (NULL, buf); |
| 3721 | if (psd) | 4053 | else |
| 3722 | { | ||
| 3723 | get_file_owner_and_group (psd, name, buf); | ||
| 3724 | LocalFree (psd); | ||
| 3725 | } | ||
| 3726 | else if (is_windows_9x () == TRUE) | ||
| 3727 | get_file_owner_and_group (NULL, name, buf); | ||
| 3728 | else if (!(is_a_symlink && follow_symlinks)) | ||
| 3729 | { | 4054 | { |
| 3730 | psd = get_file_security_desc_by_name (name); | 4055 | psd = get_file_security_desc_by_handle (fh); |
| 3731 | get_file_owner_and_group (psd, name, buf); | 4056 | if (psd) |
| 3732 | xfree (psd); | 4057 | { |
| 4058 | get_file_owner_and_group (psd, buf); | ||
| 4059 | LocalFree (psd); | ||
| 4060 | } | ||
| 4061 | else if (!(is_a_symlink && follow_symlinks)) | ||
| 4062 | { | ||
| 4063 | psd = get_file_security_desc_by_name (name); | ||
| 4064 | get_file_owner_and_group (psd, buf); | ||
| 4065 | xfree (psd); | ||
| 4066 | } | ||
| 4067 | else | ||
| 4068 | get_file_owner_and_group (NULL, buf); | ||
| 3733 | } | 4069 | } |
| 3734 | else | ||
| 3735 | get_file_owner_and_group (NULL, name, buf); | ||
| 3736 | CloseHandle (fh); | 4070 | CloseHandle (fh); |
| 3737 | } | 4071 | } |
| 3738 | else | 4072 | else |
| @@ -3751,6 +4085,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3751 | did not ask for extra precision, resolving symlinks will fly | 4085 | did not ask for extra precision, resolving symlinks will fly |
| 3752 | in the face of that request, since the user then wants the | 4086 | in the face of that request, since the user then wants the |
| 3753 | lightweight version of the code. */ | 4087 | lightweight version of the code. */ |
| 4088 | dbcs_p = max_filename_mbslen () > 1; | ||
| 3754 | rootdir = (path >= save_name + len - 1 | 4089 | rootdir = (path >= save_name + len - 1 |
| 3755 | && (IS_DIRECTORY_SEP (*path) || *path == 0)); | 4090 | && (IS_DIRECTORY_SEP (*path) || *path == 0)); |
| 3756 | 4091 | ||
| @@ -3778,8 +4113,19 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3778 | } | 4113 | } |
| 3779 | else if (rootdir) | 4114 | else if (rootdir) |
| 3780 | { | 4115 | { |
| 3781 | if (!IS_DIRECTORY_SEP (name[len-1])) | 4116 | if (!dbcs_p) |
| 3782 | strcat (name, "\\"); | 4117 | { |
| 4118 | if (!IS_DIRECTORY_SEP (name[len-1])) | ||
| 4119 | strcat (name, "\\"); | ||
| 4120 | } | ||
| 4121 | else | ||
| 4122 | { | ||
| 4123 | char *end = name + len; | ||
| 4124 | char *n = CharPrevExA (file_name_codepage, name, end, 0); | ||
| 4125 | |||
| 4126 | if (!IS_DIRECTORY_SEP (*n)) | ||
| 4127 | strcat (name, "\\"); | ||
| 4128 | } | ||
| 3783 | if (GetDriveType (name) < 2) | 4129 | if (GetDriveType (name) < 2) |
| 3784 | { | 4130 | { |
| 3785 | errno = ENOENT; | 4131 | errno = ENOENT; |
| @@ -3791,15 +4137,37 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3791 | } | 4137 | } |
| 3792 | else | 4138 | else |
| 3793 | { | 4139 | { |
| 3794 | if (IS_DIRECTORY_SEP (name[len-1])) | 4140 | if (!dbcs_p) |
| 3795 | name[len - 1] = 0; | 4141 | { |
| 4142 | if (IS_DIRECTORY_SEP (name[len-1])) | ||
| 4143 | name[len - 1] = 0; | ||
| 4144 | } | ||
| 4145 | else | ||
| 4146 | { | ||
| 4147 | char *end = name + len; | ||
| 4148 | char *n = CharPrevExA (file_name_codepage, name, end, 0); | ||
| 4149 | |||
| 4150 | if (IS_DIRECTORY_SEP (*n)) | ||
| 4151 | *n = 0; | ||
| 4152 | } | ||
| 3796 | 4153 | ||
| 3797 | /* (This is hacky, but helps when doing file completions on | 4154 | /* (This is hacky, but helps when doing file completions on |
| 3798 | network drives.) Optimize by using information available from | 4155 | network drives.) Optimize by using information available from |
| 3799 | active readdir if possible. */ | 4156 | active readdir if possible. */ |
| 3800 | len = strlen (dir_pathname); | 4157 | len = strlen (dir_pathname); |
| 3801 | if (IS_DIRECTORY_SEP (dir_pathname[len-1])) | 4158 | if (!dbcs_p) |
| 3802 | len--; | 4159 | { |
| 4160 | if (IS_DIRECTORY_SEP (dir_pathname[len-1])) | ||
| 4161 | len--; | ||
| 4162 | } | ||
| 4163 | else | ||
| 4164 | { | ||
| 4165 | char *end = dir_pathname + len; | ||
| 4166 | char *n = CharPrevExA (file_name_codepage, dir_pathname, end, 0); | ||
| 4167 | |||
| 4168 | if (IS_DIRECTORY_SEP (*n)) | ||
| 4169 | len--; | ||
| 4170 | } | ||
| 3803 | if (dir_find_handle != INVALID_HANDLE_VALUE | 4171 | if (dir_find_handle != INVALID_HANDLE_VALUE |
| 3804 | && !(is_a_symlink && follow_symlinks) | 4172 | && !(is_a_symlink && follow_symlinks) |
| 3805 | && strnicmp (save_name, dir_pathname, len) == 0 | 4173 | && strnicmp (save_name, dir_pathname, len) == 0 |
| @@ -3840,7 +4208,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks) | |||
| 3840 | else | 4208 | else |
| 3841 | buf->st_mode = S_IFREG; | 4209 | buf->st_mode = S_IFREG; |
| 3842 | 4210 | ||
| 3843 | get_file_owner_and_group (NULL, name, buf); | 4211 | get_file_owner_and_group (NULL, buf); |
| 3844 | } | 4212 | } |
| 3845 | 4213 | ||
| 3846 | #if 0 | 4214 | #if 0 |
| @@ -3905,6 +4273,30 @@ lstat (const char * path, struct stat * buf) | |||
| 3905 | return stat_worker (path, buf, 0); | 4273 | return stat_worker (path, buf, 0); |
| 3906 | } | 4274 | } |
| 3907 | 4275 | ||
| 4276 | int | ||
| 4277 | fstatat (int fd, char const *name, struct stat *st, int flags) | ||
| 4278 | { | ||
| 4279 | /* Rely on a hack: an open directory is modeled as file descriptor 0. | ||
| 4280 | This is good enough for the current usage in Emacs, but is fragile. | ||
| 4281 | |||
| 4282 | FIXME: Add proper support for fdopendir, fstatat, readlinkat. | ||
| 4283 | Gnulib does this and can serve as a model. */ | ||
| 4284 | char fullname[MAX_PATH]; | ||
| 4285 | |||
| 4286 | if (fd != AT_FDCWD) | ||
| 4287 | { | ||
| 4288 | if (_snprintf (fullname, sizeof fullname, "%s/%s", dir_pathname, name) | ||
| 4289 | < 0) | ||
| 4290 | { | ||
| 4291 | errno = ENAMETOOLONG; | ||
| 4292 | return -1; | ||
| 4293 | } | ||
| 4294 | name = fullname; | ||
| 4295 | } | ||
| 4296 | |||
| 4297 | return stat_worker (name, st, ! (flags & AT_SYMLINK_NOFOLLOW)); | ||
| 4298 | } | ||
| 4299 | |||
| 3908 | /* Provide fstat and utime as well as stat for consistent handling of | 4300 | /* Provide fstat and utime as well as stat for consistent handling of |
| 3909 | file timestamps. */ | 4301 | file timestamps. */ |
| 3910 | int | 4302 | int |
| @@ -3959,13 +4351,23 @@ fstat (int desc, struct stat * buf) | |||
| 3959 | else | 4351 | else |
| 3960 | buf->st_ino = fake_inode; | 4352 | buf->st_ino = fake_inode; |
| 3961 | 4353 | ||
| 3962 | /* Consider files to belong to current user. | 4354 | /* If the caller so requested, get the true file owner and group. |
| 3963 | FIXME: this should use GetSecurityInfo API, but it is only | 4355 | Otherwise, consider the file to belong to the current user. */ |
| 3964 | available for _WIN32_WINNT >= 0x501. */ | 4356 | if (!w32_stat_get_owner_group || is_windows_9x () == TRUE) |
| 3965 | buf->st_uid = dflt_passwd.pw_uid; | 4357 | get_file_owner_and_group (NULL, buf); |
| 3966 | buf->st_gid = dflt_passwd.pw_gid; | 4358 | else |
| 3967 | strcpy (buf->st_uname, dflt_passwd.pw_name); | 4359 | { |
| 3968 | strcpy (buf->st_gname, dflt_group.gr_name); | 4360 | PSECURITY_DESCRIPTOR psd = NULL; |
| 4361 | |||
| 4362 | psd = get_file_security_desc_by_handle (fh); | ||
| 4363 | if (psd) | ||
| 4364 | { | ||
| 4365 | get_file_owner_and_group (psd, buf); | ||
| 4366 | LocalFree (psd); | ||
| 4367 | } | ||
| 4368 | else | ||
| 4369 | get_file_owner_and_group (NULL, buf); | ||
| 4370 | } | ||
| 3969 | 4371 | ||
| 3970 | buf->st_dev = info.dwVolumeSerialNumber; | 4372 | buf->st_dev = info.dwVolumeSerialNumber; |
| 3971 | buf->st_rdev = info.dwVolumeSerialNumber; | 4373 | buf->st_rdev = info.dwVolumeSerialNumber; |
| @@ -4060,6 +4462,7 @@ symlink (char const *filename, char const *linkname) | |||
| 4060 | char linkfn[MAX_PATH], *tgtfn; | 4462 | char linkfn[MAX_PATH], *tgtfn; |
| 4061 | DWORD flags = 0; | 4463 | DWORD flags = 0; |
| 4062 | int dir_access, filename_ends_in_slash; | 4464 | int dir_access, filename_ends_in_slash; |
| 4465 | int dbcs_p; | ||
| 4063 | 4466 | ||
| 4064 | /* Diagnostics follows Posix as much as possible. */ | 4467 | /* Diagnostics follows Posix as much as possible. */ |
| 4065 | if (filename == NULL || linkname == NULL) | 4468 | if (filename == NULL || linkname == NULL) |
| @@ -4085,6 +4488,8 @@ symlink (char const *filename, char const *linkname) | |||
| 4085 | return -1; | 4488 | return -1; |
| 4086 | } | 4489 | } |
| 4087 | 4490 | ||
| 4491 | dbcs_p = max_filename_mbslen () > 1; | ||
| 4492 | |||
| 4088 | /* Note: since empty FILENAME was already rejected, we can safely | 4493 | /* Note: since empty FILENAME was already rejected, we can safely |
| 4089 | refer to FILENAME[1]. */ | 4494 | refer to FILENAME[1]. */ |
| 4090 | if (!(IS_DIRECTORY_SEP (filename[0]) || IS_DEVICE_SEP (filename[1]))) | 4495 | if (!(IS_DIRECTORY_SEP (filename[0]) || IS_DEVICE_SEP (filename[1]))) |
| @@ -4099,8 +4504,21 @@ symlink (char const *filename, char const *linkname) | |||
| 4099 | char tem[MAX_PATH]; | 4504 | char tem[MAX_PATH]; |
| 4100 | char *p = linkfn + strlen (linkfn); | 4505 | char *p = linkfn + strlen (linkfn); |
| 4101 | 4506 | ||
| 4102 | while (p > linkfn && !IS_ANY_SEP (p[-1])) | 4507 | if (!dbcs_p) |
| 4103 | p--; | 4508 | { |
| 4509 | while (p > linkfn && !IS_ANY_SEP (p[-1])) | ||
| 4510 | p--; | ||
| 4511 | } | ||
| 4512 | else | ||
| 4513 | { | ||
| 4514 | char *p1 = CharPrevExA (file_name_codepage, linkfn, p, 0); | ||
| 4515 | |||
| 4516 | while (p > linkfn && !IS_ANY_SEP (*p1)) | ||
| 4517 | { | ||
| 4518 | p = p1; | ||
| 4519 | p1 = CharPrevExA (file_name_codepage, linkfn, p1, 0); | ||
| 4520 | } | ||
| 4521 | } | ||
| 4104 | if (p > linkfn) | 4522 | if (p > linkfn) |
| 4105 | strncpy (tem, linkfn, p - linkfn); | 4523 | strncpy (tem, linkfn, p - linkfn); |
| 4106 | tem[p - linkfn] = '\0'; | 4524 | tem[p - linkfn] = '\0'; |
| @@ -4115,7 +4533,15 @@ symlink (char const *filename, char const *linkname) | |||
| 4115 | exist, but ends in a slash, we create a symlink to directory. If | 4533 | exist, but ends in a slash, we create a symlink to directory. If |
| 4116 | FILENAME exists and is a directory, we always create a symlink to | 4534 | FILENAME exists and is a directory, we always create a symlink to |
| 4117 | directory. */ | 4535 | directory. */ |
| 4118 | filename_ends_in_slash = IS_DIRECTORY_SEP (filename[strlen (filename) - 1]); | 4536 | if (!dbcs_p) |
| 4537 | filename_ends_in_slash = IS_DIRECTORY_SEP (filename[strlen (filename) - 1]); | ||
| 4538 | else | ||
| 4539 | { | ||
| 4540 | const char *end = filename + strlen (filename); | ||
| 4541 | const char *n = CharPrevExA (file_name_codepage, filename, end, 0); | ||
| 4542 | |||
| 4543 | filename_ends_in_slash = IS_DIRECTORY_SEP (*n); | ||
| 4544 | } | ||
| 4119 | if (dir_access == 0 || filename_ends_in_slash) | 4545 | if (dir_access == 0 || filename_ends_in_slash) |
| 4120 | flags = SYMBOLIC_LINK_FLAG_DIRECTORY; | 4546 | flags = SYMBOLIC_LINK_FLAG_DIRECTORY; |
| 4121 | 4547 | ||
| @@ -4294,7 +4720,7 @@ readlink (const char *name, char *buf, size_t buf_size) | |||
| 4294 | errno = EINVAL; | 4720 | errno = EINVAL; |
| 4295 | else | 4721 | else |
| 4296 | { | 4722 | { |
| 4297 | /* Copy the link target name, in wide characters, fro | 4723 | /* Copy the link target name, in wide characters, from |
| 4298 | reparse_data, then convert it to multibyte encoding in | 4724 | reparse_data, then convert it to multibyte encoding in |
| 4299 | the current locale's codepage. */ | 4725 | the current locale's codepage. */ |
| 4300 | WCHAR *lwname; | 4726 | WCHAR *lwname; |
| @@ -4305,6 +4731,8 @@ readlink (const char *name, char *buf, size_t buf_size) | |||
| 4305 | WCHAR *lwname_src = | 4731 | WCHAR *lwname_src = |
| 4306 | reparse_data->SymbolicLinkReparseBuffer.PathBuffer | 4732 | reparse_data->SymbolicLinkReparseBuffer.PathBuffer |
| 4307 | + reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); | 4733 | + reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); |
| 4734 | /* This updates file_name_codepage which we need below. */ | ||
| 4735 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 4308 | 4736 | ||
| 4309 | /* According to MSDN, PrintNameLength does not include the | 4737 | /* According to MSDN, PrintNameLength does not include the |
| 4310 | terminating null character. */ | 4738 | terminating null character. */ |
| @@ -4312,9 +4740,7 @@ readlink (const char *name, char *buf, size_t buf_size) | |||
| 4312 | memcpy (lwname, lwname_src, lwname_len); | 4740 | memcpy (lwname, lwname_src, lwname_len); |
| 4313 | lwname[lwname_len/sizeof(WCHAR)] = 0; /* null-terminate */ | 4741 | lwname[lwname_len/sizeof(WCHAR)] = 0; /* null-terminate */ |
| 4314 | 4742 | ||
| 4315 | /* FIXME: Should we use the current file-name coding system | 4743 | lname_len = WideCharToMultiByte (file_name_codepage, 0, lwname, -1, |
| 4316 | instead of the fixed value of the ANSI codepage? */ | ||
| 4317 | lname_len = WideCharToMultiByte (w32_ansi_code_page, 0, lwname, -1, | ||
| 4318 | lname, MAX_PATH, NULL, NULL); | 4744 | lname, MAX_PATH, NULL, NULL); |
| 4319 | if (!lname_len) | 4745 | if (!lname_len) |
| 4320 | { | 4746 | { |
| @@ -4340,18 +4766,33 @@ readlink (const char *name, char *buf, size_t buf_size) | |||
| 4340 | else | 4766 | else |
| 4341 | { | 4767 | { |
| 4342 | size_t size_to_copy = buf_size; | 4768 | size_t size_to_copy = buf_size; |
| 4343 | BYTE *p = lname; | 4769 | BYTE *p = lname, *p2; |
| 4344 | BYTE *pend = p + lname_len; | 4770 | BYTE *pend = p + lname_len; |
| 4345 | 4771 | ||
| 4346 | /* Normalize like dostounix_filename does, but we don't | 4772 | /* Normalize like dostounix_filename does, but we don't |
| 4347 | want to assume that lname is null-terminated. */ | 4773 | want to assume that lname is null-terminated. */ |
| 4348 | if (*p && p[1] == ':' && *p >= 'A' && *p <= 'Z') | 4774 | if (dbcs_p) |
| 4349 | *p += 'a' - 'A'; | 4775 | p2 = CharNextExA (file_name_codepage, p, 0); |
| 4776 | else | ||
| 4777 | p2 = p + 1; | ||
| 4778 | if (*p && *p2 == ':' && *p >= 'A' && *p <= 'Z') | ||
| 4779 | { | ||
| 4780 | *p += 'a' - 'A'; | ||
| 4781 | p += 2; | ||
| 4782 | } | ||
| 4350 | while (p <= pend) | 4783 | while (p <= pend) |
| 4351 | { | 4784 | { |
| 4352 | if (*p == '\\') | 4785 | if (*p == '\\') |
| 4353 | *p = '/'; | 4786 | *p = '/'; |
| 4354 | ++p; | 4787 | if (dbcs_p) |
| 4788 | { | ||
| 4789 | p = CharNextExA (file_name_codepage, p, 0); | ||
| 4790 | /* CharNextExA doesn't advance at null character. */ | ||
| 4791 | if (!*p) | ||
| 4792 | break; | ||
| 4793 | } | ||
| 4794 | else | ||
| 4795 | ++p; | ||
| 4355 | } | 4796 | } |
| 4356 | /* Testing for null-terminated LNAME is paranoia: | 4797 | /* Testing for null-terminated LNAME is paranoia: |
| 4357 | WideCharToMultiByte should always return a | 4798 | WideCharToMultiByte should always return a |
| @@ -4398,6 +4839,28 @@ readlink (const char *name, char *buf, size_t buf_size) | |||
| 4398 | return retval; | 4839 | return retval; |
| 4399 | } | 4840 | } |
| 4400 | 4841 | ||
| 4842 | ssize_t | ||
| 4843 | readlinkat (int fd, char const *name, char *buffer, | ||
| 4844 | size_t buffer_size) | ||
| 4845 | { | ||
| 4846 | /* Rely on a hack: an open directory is modeled as file descriptor 0, | ||
| 4847 | as in fstatat. FIXME: Add proper support for readlinkat. */ | ||
| 4848 | char fullname[MAX_PATH]; | ||
| 4849 | |||
| 4850 | if (fd != AT_FDCWD) | ||
| 4851 | { | ||
| 4852 | if (_snprintf (fullname, sizeof fullname, "%s/%s", dir_pathname, name) | ||
| 4853 | < 0) | ||
| 4854 | { | ||
| 4855 | errno = ENAMETOOLONG; | ||
| 4856 | return -1; | ||
| 4857 | } | ||
| 4858 | name = fullname; | ||
| 4859 | } | ||
| 4860 | |||
| 4861 | return readlink (name, buffer, buffer_size); | ||
| 4862 | } | ||
| 4863 | |||
| 4401 | /* If FILE is a symlink, return its target (stored in a static | 4864 | /* If FILE is a symlink, return its target (stored in a static |
| 4402 | buffer); otherwise return FILE. | 4865 | buffer); otherwise return FILE. |
| 4403 | 4866 | ||
| @@ -4425,6 +4888,7 @@ chase_symlinks (const char *file) | |||
| 4425 | char link[MAX_PATH]; | 4888 | char link[MAX_PATH]; |
| 4426 | ssize_t res, link_len; | 4889 | ssize_t res, link_len; |
| 4427 | int loop_count = 0; | 4890 | int loop_count = 0; |
| 4891 | int dbcs_p; | ||
| 4428 | 4892 | ||
| 4429 | if (is_windows_9x () == TRUE || !is_symlink (file)) | 4893 | if (is_windows_9x () == TRUE || !is_symlink (file)) |
| 4430 | return (char *)file; | 4894 | return (char *)file; |
| @@ -4432,13 +4896,27 @@ chase_symlinks (const char *file) | |||
| 4432 | if ((link_len = GetFullPathName (file, MAX_PATH, link, NULL)) == 0) | 4896 | if ((link_len = GetFullPathName (file, MAX_PATH, link, NULL)) == 0) |
| 4433 | return (char *)file; | 4897 | return (char *)file; |
| 4434 | 4898 | ||
| 4899 | dbcs_p = max_filename_mbslen () > 1; | ||
| 4435 | target[0] = '\0'; | 4900 | target[0] = '\0'; |
| 4436 | do { | 4901 | do { |
| 4437 | 4902 | ||
| 4438 | /* Remove trailing slashes, as we want to resolve the last | 4903 | /* Remove trailing slashes, as we want to resolve the last |
| 4439 | non-trivial part of the link name. */ | 4904 | non-trivial part of the link name. */ |
| 4440 | while (link_len > 3 && IS_DIRECTORY_SEP (link[link_len-1])) | 4905 | if (!dbcs_p) |
| 4441 | link[link_len--] = '\0'; | 4906 | { |
| 4907 | while (link_len > 3 && IS_DIRECTORY_SEP (link[link_len-1])) | ||
| 4908 | link[link_len--] = '\0'; | ||
| 4909 | } | ||
| 4910 | else if (link_len > 3) | ||
| 4911 | { | ||
| 4912 | char *n = CharPrevExA (file_name_codepage, link, link + link_len, 0); | ||
| 4913 | |||
| 4914 | while (n >= link + 2 && IS_DIRECTORY_SEP (*n)) | ||
| 4915 | { | ||
| 4916 | n[1] = '\0'; | ||
| 4917 | n = CharPrevExA (file_name_codepage, link, n, 0); | ||
| 4918 | } | ||
| 4919 | } | ||
| 4442 | 4920 | ||
| 4443 | res = readlink (link, target, MAX_PATH); | 4921 | res = readlink (link, target, MAX_PATH); |
| 4444 | if (res > 0) | 4922 | if (res > 0) |
| @@ -4451,8 +4929,21 @@ chase_symlinks (const char *file) | |||
| 4451 | the symlink, then copy the result back to target. */ | 4929 | the symlink, then copy the result back to target. */ |
| 4452 | char *p = link + link_len; | 4930 | char *p = link + link_len; |
| 4453 | 4931 | ||
| 4454 | while (p > link && !IS_ANY_SEP (p[-1])) | 4932 | if (!dbcs_p) |
| 4455 | p--; | 4933 | { |
| 4934 | while (p > link && !IS_ANY_SEP (p[-1])) | ||
| 4935 | p--; | ||
| 4936 | } | ||
| 4937 | else | ||
| 4938 | { | ||
| 4939 | char *p1 = CharPrevExA (file_name_codepage, link, p, 0); | ||
| 4940 | |||
| 4941 | while (p > link && !IS_ANY_SEP (*p1)) | ||
| 4942 | { | ||
| 4943 | p = p1; | ||
| 4944 | p1 = CharPrevExA (file_name_codepage, link, p1, 0); | ||
| 4945 | } | ||
| 4946 | } | ||
| 4456 | strcpy (p, target); | 4947 | strcpy (p, target); |
| 4457 | strcpy (target, link); | 4948 | strcpy (target, link); |
| 4458 | } | 4949 | } |
| @@ -4470,6 +4961,245 @@ chase_symlinks (const char *file) | |||
| 4470 | return target; | 4961 | return target; |
| 4471 | } | 4962 | } |
| 4472 | 4963 | ||
| 4964 | |||
| 4965 | /* Posix ACL emulation. */ | ||
| 4966 | |||
| 4967 | int | ||
| 4968 | acl_valid (acl_t acl) | ||
| 4969 | { | ||
| 4970 | return is_valid_security_descriptor ((PSECURITY_DESCRIPTOR)acl) ? 0 : -1; | ||
| 4971 | } | ||
| 4972 | |||
| 4973 | char * | ||
| 4974 | acl_to_text (acl_t acl, ssize_t *size) | ||
| 4975 | { | ||
| 4976 | LPTSTR str_acl; | ||
| 4977 | SECURITY_INFORMATION flags = | ||
| 4978 | OWNER_SECURITY_INFORMATION | | ||
| 4979 | GROUP_SECURITY_INFORMATION | | ||
| 4980 | DACL_SECURITY_INFORMATION; | ||
| 4981 | char *retval = NULL; | ||
| 4982 | ULONG local_size; | ||
| 4983 | int e = errno; | ||
| 4984 | |||
| 4985 | errno = 0; | ||
| 4986 | |||
| 4987 | if (convert_sd_to_sddl ((PSECURITY_DESCRIPTOR)acl, SDDL_REVISION_1, flags, &str_acl, &local_size)) | ||
| 4988 | { | ||
| 4989 | errno = e; | ||
| 4990 | /* We don't want to mix heaps, so we duplicate the string in our | ||
| 4991 | heap and free the one allocated by the API. */ | ||
| 4992 | retval = xstrdup (str_acl); | ||
| 4993 | if (size) | ||
| 4994 | *size = local_size; | ||
| 4995 | LocalFree (str_acl); | ||
| 4996 | } | ||
| 4997 | else if (errno != ENOTSUP) | ||
| 4998 | errno = EINVAL; | ||
| 4999 | |||
| 5000 | return retval; | ||
| 5001 | } | ||
| 5002 | |||
| 5003 | acl_t | ||
| 5004 | acl_from_text (const char *acl_str) | ||
| 5005 | { | ||
| 5006 | PSECURITY_DESCRIPTOR psd, retval = NULL; | ||
| 5007 | ULONG sd_size; | ||
| 5008 | int e = errno; | ||
| 5009 | |||
| 5010 | errno = 0; | ||
| 5011 | |||
| 5012 | if (convert_sddl_to_sd (acl_str, SDDL_REVISION_1, &psd, &sd_size)) | ||
| 5013 | { | ||
| 5014 | errno = e; | ||
| 5015 | retval = xmalloc (sd_size); | ||
| 5016 | memcpy (retval, psd, sd_size); | ||
| 5017 | LocalFree (psd); | ||
| 5018 | } | ||
| 5019 | else if (errno != ENOTSUP) | ||
| 5020 | errno = EINVAL; | ||
| 5021 | |||
| 5022 | return retval; | ||
| 5023 | } | ||
| 5024 | |||
| 5025 | int | ||
| 5026 | acl_free (void *ptr) | ||
| 5027 | { | ||
| 5028 | xfree (ptr); | ||
| 5029 | return 0; | ||
| 5030 | } | ||
| 5031 | |||
| 5032 | acl_t | ||
| 5033 | acl_get_file (const char *fname, acl_type_t type) | ||
| 5034 | { | ||
| 5035 | PSECURITY_DESCRIPTOR psd = NULL; | ||
| 5036 | const char *filename; | ||
| 5037 | |||
| 5038 | if (type == ACL_TYPE_ACCESS) | ||
| 5039 | { | ||
| 5040 | DWORD sd_len, err; | ||
| 5041 | SECURITY_INFORMATION si = | ||
| 5042 | OWNER_SECURITY_INFORMATION | | ||
| 5043 | GROUP_SECURITY_INFORMATION | | ||
| 5044 | DACL_SECURITY_INFORMATION ; | ||
| 5045 | int e = errno; | ||
| 5046 | |||
| 5047 | filename = map_w32_filename (fname, NULL); | ||
| 5048 | if ((volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0) | ||
| 5049 | fname = chase_symlinks (filename); | ||
| 5050 | else | ||
| 5051 | fname = filename; | ||
| 5052 | |||
| 5053 | errno = 0; | ||
| 5054 | if (!get_file_security (fname, si, psd, 0, &sd_len) | ||
| 5055 | && errno != ENOTSUP) | ||
| 5056 | { | ||
| 5057 | err = GetLastError (); | ||
| 5058 | if (err == ERROR_INSUFFICIENT_BUFFER) | ||
| 5059 | { | ||
| 5060 | psd = xmalloc (sd_len); | ||
| 5061 | if (!get_file_security (fname, si, psd, sd_len, &sd_len)) | ||
| 5062 | { | ||
| 5063 | xfree (psd); | ||
| 5064 | errno = EIO; | ||
| 5065 | psd = NULL; | ||
| 5066 | } | ||
| 5067 | } | ||
| 5068 | else if (err == ERROR_FILE_NOT_FOUND | ||
| 5069 | || err == ERROR_PATH_NOT_FOUND) | ||
| 5070 | errno = ENOENT; | ||
| 5071 | else | ||
| 5072 | errno = EIO; | ||
| 5073 | } | ||
| 5074 | else if (!errno) | ||
| 5075 | errno = e; | ||
| 5076 | } | ||
| 5077 | else if (type != ACL_TYPE_DEFAULT) | ||
| 5078 | errno = EINVAL; | ||
| 5079 | |||
| 5080 | return psd; | ||
| 5081 | } | ||
| 5082 | |||
| 5083 | int | ||
| 5084 | acl_set_file (const char *fname, acl_type_t type, acl_t acl) | ||
| 5085 | { | ||
| 5086 | TOKEN_PRIVILEGES old1, old2; | ||
| 5087 | DWORD err; | ||
| 5088 | int st = 0, retval = -1; | ||
| 5089 | SECURITY_INFORMATION flags = 0; | ||
| 5090 | PSID psid; | ||
| 5091 | PACL pacl; | ||
| 5092 | BOOL dflt; | ||
| 5093 | BOOL dacl_present; | ||
| 5094 | int e; | ||
| 5095 | const char *filename; | ||
| 5096 | |||
| 5097 | if (acl_valid (acl) != 0 | ||
| 5098 | || (type != ACL_TYPE_DEFAULT && type != ACL_TYPE_ACCESS)) | ||
| 5099 | { | ||
| 5100 | errno = EINVAL; | ||
| 5101 | return -1; | ||
| 5102 | } | ||
| 5103 | |||
| 5104 | if (type == ACL_TYPE_DEFAULT) | ||
| 5105 | { | ||
| 5106 | errno = ENOSYS; | ||
| 5107 | return -1; | ||
| 5108 | } | ||
| 5109 | |||
| 5110 | filename = map_w32_filename (fname, NULL); | ||
| 5111 | if ((volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0) | ||
| 5112 | fname = chase_symlinks (filename); | ||
| 5113 | else | ||
| 5114 | fname = filename; | ||
| 5115 | |||
| 5116 | if (get_security_descriptor_owner ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt) | ||
| 5117 | && psid) | ||
| 5118 | flags |= OWNER_SECURITY_INFORMATION; | ||
| 5119 | if (get_security_descriptor_group ((PSECURITY_DESCRIPTOR)acl, &psid, &dflt) | ||
| 5120 | && psid) | ||
| 5121 | flags |= GROUP_SECURITY_INFORMATION; | ||
| 5122 | if (get_security_descriptor_dacl ((PSECURITY_DESCRIPTOR)acl, &dacl_present, | ||
| 5123 | &pacl, &dflt) | ||
| 5124 | && dacl_present) | ||
| 5125 | flags |= DACL_SECURITY_INFORMATION; | ||
| 5126 | if (!flags) | ||
| 5127 | return 0; | ||
| 5128 | |||
| 5129 | /* According to KB-245153, setting the owner will succeed if either: | ||
| 5130 | (1) the caller is the user who will be the new owner, and has the | ||
| 5131 | SE_TAKE_OWNERSHIP privilege, or | ||
| 5132 | (2) the caller has the SE_RESTORE privilege, in which case she can | ||
| 5133 | set any valid user or group as the owner | ||
| 5134 | |||
| 5135 | We request below both SE_TAKE_OWNERSHIP and SE_RESTORE | ||
| 5136 | privileges, and disregard any failures in obtaining them. If | ||
| 5137 | these privileges cannot be obtained, and do not already exist in | ||
| 5138 | the calling thread's security token, this function could fail | ||
| 5139 | with EPERM. */ | ||
| 5140 | if (enable_privilege (SE_TAKE_OWNERSHIP_NAME, TRUE, &old1)) | ||
| 5141 | st++; | ||
| 5142 | if (enable_privilege (SE_RESTORE_NAME, TRUE, &old2)) | ||
| 5143 | st++; | ||
| 5144 | |||
| 5145 | e = errno; | ||
| 5146 | errno = 0; | ||
| 5147 | if (!set_file_security ((char *)fname, flags, (PSECURITY_DESCRIPTOR)acl)) | ||
| 5148 | { | ||
| 5149 | err = GetLastError (); | ||
| 5150 | |||
| 5151 | if (errno == ENOTSUP) | ||
| 5152 | ; | ||
| 5153 | else if (err == ERROR_INVALID_OWNER | ||
| 5154 | || err == ERROR_NOT_ALL_ASSIGNED | ||
| 5155 | || err == ERROR_ACCESS_DENIED) | ||
| 5156 | { | ||
| 5157 | /* Maybe the requested ACL and the one the file already has | ||
| 5158 | are identical, in which case we can silently ignore the | ||
| 5159 | failure. (And no, Windows doesn't.) */ | ||
| 5160 | acl_t current_acl = acl_get_file (fname, ACL_TYPE_ACCESS); | ||
| 5161 | |||
| 5162 | errno = EPERM; | ||
| 5163 | if (current_acl) | ||
| 5164 | { | ||
| 5165 | char *acl_from = acl_to_text (current_acl, NULL); | ||
| 5166 | char *acl_to = acl_to_text (acl, NULL); | ||
| 5167 | |||
| 5168 | if (acl_from && acl_to && xstrcasecmp (acl_from, acl_to) == 0) | ||
| 5169 | { | ||
| 5170 | retval = 0; | ||
| 5171 | errno = e; | ||
| 5172 | } | ||
| 5173 | if (acl_from) | ||
| 5174 | acl_free (acl_from); | ||
| 5175 | if (acl_to) | ||
| 5176 | acl_free (acl_to); | ||
| 5177 | acl_free (current_acl); | ||
| 5178 | } | ||
| 5179 | } | ||
| 5180 | else if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) | ||
| 5181 | errno = ENOENT; | ||
| 5182 | else | ||
| 5183 | errno = EACCES; | ||
| 5184 | } | ||
| 5185 | else | ||
| 5186 | { | ||
| 5187 | retval = 0; | ||
| 5188 | errno = e; | ||
| 5189 | } | ||
| 5190 | |||
| 5191 | if (st) | ||
| 5192 | { | ||
| 5193 | if (st >= 2) | ||
| 5194 | restore_privilege (&old2); | ||
| 5195 | restore_privilege (&old1); | ||
| 5196 | revert_to_self (); | ||
| 5197 | } | ||
| 5198 | |||
| 5199 | return retval; | ||
| 5200 | } | ||
| 5201 | |||
| 5202 | |||
| 4473 | /* MS-Windows version of careadlinkat (cf. ../lib/careadlinkat.c). We | 5203 | /* MS-Windows version of careadlinkat (cf. ../lib/careadlinkat.c). We |
| 4474 | have a fixed max size for file names, so we don't need the kind of | 5204 | have a fixed max size for file names, so we don't need the kind of |
| 4475 | alloc/malloc/realloc dance the gnulib version does. We also don't | 5205 | alloc/malloc/realloc dance the gnulib version does. We also don't |
| @@ -4483,12 +5213,6 @@ careadlinkat (int fd, char const *filename, | |||
| 4483 | char linkname[MAX_PATH]; | 5213 | char linkname[MAX_PATH]; |
| 4484 | ssize_t link_size; | 5214 | ssize_t link_size; |
| 4485 | 5215 | ||
| 4486 | if (fd != AT_FDCWD) | ||
| 4487 | { | ||
| 4488 | errno = EINVAL; | ||
| 4489 | return NULL; | ||
| 4490 | } | ||
| 4491 | |||
| 4492 | link_size = preadlinkat (fd, filename, linkname, sizeof(linkname)); | 5216 | link_size = preadlinkat (fd, filename, linkname, sizeof(linkname)); |
| 4493 | 5217 | ||
| 4494 | if (link_size > 0) | 5218 | if (link_size > 0) |
| @@ -4506,14 +5230,6 @@ careadlinkat (int fd, char const *filename, | |||
| 4506 | return NULL; | 5230 | return NULL; |
| 4507 | } | 5231 | } |
| 4508 | 5232 | ||
| 4509 | ssize_t | ||
| 4510 | careadlinkatcwd (int fd, char const *filename, char *buffer, | ||
| 4511 | size_t buffer_size) | ||
| 4512 | { | ||
| 4513 | (void) fd; | ||
| 4514 | return readlink (filename, buffer, buffer_size); | ||
| 4515 | } | ||
| 4516 | |||
| 4517 | 5233 | ||
| 4518 | /* Support for browsing other processes and their attributes. See | 5234 | /* Support for browsing other processes and their attributes. See |
| 4519 | process.c for the Lisp bindings. */ | 5235 | process.c for the Lisp bindings. */ |
| @@ -4685,8 +5401,8 @@ get_process_memory_info (HANDLE h_proc, | |||
| 4685 | 5401 | ||
| 4686 | static BOOL WINAPI | 5402 | static BOOL WINAPI |
| 4687 | get_process_working_set_size (HANDLE h_proc, | 5403 | get_process_working_set_size (HANDLE h_proc, |
| 4688 | DWORD *minrss, | 5404 | PSIZE_T minrss, |
| 4689 | DWORD *maxrss) | 5405 | PSIZE_T maxrss) |
| 4690 | { | 5406 | { |
| 4691 | static GetProcessWorkingSetSize_Proc | 5407 | static GetProcessWorkingSetSize_Proc |
| 4692 | s_pfn_Get_Process_Working_Set_Size = NULL; | 5408 | s_pfn_Get_Process_Working_Set_Size = NULL; |
| @@ -4931,7 +5647,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 4931 | unsigned egid; | 5647 | unsigned egid; |
| 4932 | PROCESS_MEMORY_COUNTERS mem; | 5648 | PROCESS_MEMORY_COUNTERS mem; |
| 4933 | PROCESS_MEMORY_COUNTERS_EX mem_ex; | 5649 | PROCESS_MEMORY_COUNTERS_EX mem_ex; |
| 4934 | DWORD minrss, maxrss; | 5650 | SIZE_T minrss, maxrss; |
| 4935 | MEMORYSTATUS memst; | 5651 | MEMORYSTATUS memst; |
| 4936 | MEMORY_STATUS_EX memstex; | 5652 | MEMORY_STATUS_EX memstex; |
| 4937 | double totphys = 0.0; | 5653 | double totphys = 0.0; |
| @@ -5159,7 +5875,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 5159 | && get_process_memory_info (h_proc, (PROCESS_MEMORY_COUNTERS *)&mem_ex, | 5875 | && get_process_memory_info (h_proc, (PROCESS_MEMORY_COUNTERS *)&mem_ex, |
| 5160 | sizeof (mem_ex))) | 5876 | sizeof (mem_ex))) |
| 5161 | { | 5877 | { |
| 5162 | DWORD rss = mem_ex.WorkingSetSize / 1024; | 5878 | SIZE_T rss = mem_ex.WorkingSetSize / 1024; |
| 5163 | 5879 | ||
| 5164 | attrs = Fcons (Fcons (Qmajflt, | 5880 | attrs = Fcons (Fcons (Qmajflt, |
| 5165 | make_fixnum_or_float (mem_ex.PageFaultCount)), | 5881 | make_fixnum_or_float (mem_ex.PageFaultCount)), |
| @@ -5174,7 +5890,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 5174 | else if (h_proc | 5890 | else if (h_proc |
| 5175 | && get_process_memory_info (h_proc, &mem, sizeof (mem))) | 5891 | && get_process_memory_info (h_proc, &mem, sizeof (mem))) |
| 5176 | { | 5892 | { |
| 5177 | DWORD rss = mem_ex.WorkingSetSize / 1024; | 5893 | SIZE_T rss = mem_ex.WorkingSetSize / 1024; |
| 5178 | 5894 | ||
| 5179 | attrs = Fcons (Fcons (Qmajflt, | 5895 | attrs = Fcons (Fcons (Qmajflt, |
| 5180 | make_fixnum_or_float (mem.PageFaultCount)), | 5896 | make_fixnum_or_float (mem.PageFaultCount)), |
| @@ -5368,35 +6084,39 @@ init_winsock (int load_now) | |||
| 5368 | 6084 | ||
| 5369 | int h_errno = 0; | 6085 | int h_errno = 0; |
| 5370 | 6086 | ||
| 5371 | /* function to set h_errno for compatibility; map winsock error codes to | 6087 | /* Function to map winsock error codes to errno codes for those errno |
| 5372 | normal system codes where they overlap (non-overlapping definitions | 6088 | code defined in errno.h (errno values not defined by errno.h are |
| 5373 | are already in <sys/socket.h> */ | 6089 | already in nt/inc/sys/socket.h). */ |
| 5374 | static void | 6090 | static void |
| 5375 | set_errno (void) | 6091 | set_errno (void) |
| 5376 | { | 6092 | { |
| 6093 | int wsa_err; | ||
| 6094 | |||
| 6095 | h_errno = 0; | ||
| 5377 | if (winsock_lib == NULL) | 6096 | if (winsock_lib == NULL) |
| 5378 | h_errno = EINVAL; | 6097 | wsa_err = EINVAL; |
| 5379 | else | 6098 | else |
| 5380 | h_errno = pfn_WSAGetLastError (); | 6099 | wsa_err = pfn_WSAGetLastError (); |
| 5381 | 6100 | ||
| 5382 | switch (h_errno) | 6101 | switch (wsa_err) |
| 5383 | { | 6102 | { |
| 5384 | case WSAEACCES: h_errno = EACCES; break; | 6103 | case WSAEACCES: errno = EACCES; break; |
| 5385 | case WSAEBADF: h_errno = EBADF; break; | 6104 | case WSAEBADF: errno = EBADF; break; |
| 5386 | case WSAEFAULT: h_errno = EFAULT; break; | 6105 | case WSAEFAULT: errno = EFAULT; break; |
| 5387 | case WSAEINTR: h_errno = EINTR; break; | 6106 | case WSAEINTR: errno = EINTR; break; |
| 5388 | case WSAEINVAL: h_errno = EINVAL; break; | 6107 | case WSAEINVAL: errno = EINVAL; break; |
| 5389 | case WSAEMFILE: h_errno = EMFILE; break; | 6108 | case WSAEMFILE: errno = EMFILE; break; |
| 5390 | case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break; | 6109 | case WSAENAMETOOLONG: errno = ENAMETOOLONG; break; |
| 5391 | case WSAENOTEMPTY: h_errno = ENOTEMPTY; break; | 6110 | case WSAENOTEMPTY: errno = ENOTEMPTY; break; |
| 6111 | default: errno = wsa_err; break; | ||
| 5392 | } | 6112 | } |
| 5393 | errno = h_errno; | ||
| 5394 | } | 6113 | } |
| 5395 | 6114 | ||
| 5396 | static void | 6115 | static void |
| 5397 | check_errno (void) | 6116 | check_errno (void) |
| 5398 | { | 6117 | { |
| 5399 | if (h_errno == 0 && winsock_lib != NULL) | 6118 | h_errno = 0; |
| 6119 | if (winsock_lib != NULL) | ||
| 5400 | pfn_WSASetLastError (0); | 6120 | pfn_WSASetLastError (0); |
| 5401 | } | 6121 | } |
| 5402 | 6122 | ||
| @@ -5508,7 +6228,7 @@ sys_socket (int af, int type, int protocol) | |||
| 5508 | 6228 | ||
| 5509 | if (winsock_lib == NULL) | 6229 | if (winsock_lib == NULL) |
| 5510 | { | 6230 | { |
| 5511 | h_errno = ENETDOWN; | 6231 | errno = ENETDOWN; |
| 5512 | return INVALID_SOCKET; | 6232 | return INVALID_SOCKET; |
| 5513 | } | 6233 | } |
| 5514 | 6234 | ||
| @@ -5585,6 +6305,7 @@ socket_to_fd (SOCKET s) | |||
| 5585 | } | 6305 | } |
| 5586 | } | 6306 | } |
| 5587 | } | 6307 | } |
| 6308 | eassert (fd < MAXDESC); | ||
| 5588 | fd_info[fd].hnd = (HANDLE) s; | 6309 | fd_info[fd].hnd = (HANDLE) s; |
| 5589 | 6310 | ||
| 5590 | /* set our own internal flags */ | 6311 | /* set our own internal flags */ |
| @@ -5613,8 +6334,9 @@ socket_to_fd (SOCKET s) | |||
| 5613 | /* clean up */ | 6334 | /* clean up */ |
| 5614 | _close (fd); | 6335 | _close (fd); |
| 5615 | } | 6336 | } |
| 6337 | else | ||
| 5616 | pfn_closesocket (s); | 6338 | pfn_closesocket (s); |
| 5617 | h_errno = EMFILE; | 6339 | errno = EMFILE; |
| 5618 | return -1; | 6340 | return -1; |
| 5619 | } | 6341 | } |
| 5620 | 6342 | ||
| @@ -5623,7 +6345,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) | |||
| 5623 | { | 6345 | { |
| 5624 | if (winsock_lib == NULL) | 6346 | if (winsock_lib == NULL) |
| 5625 | { | 6347 | { |
| 5626 | h_errno = ENOTSOCK; | 6348 | errno = ENOTSOCK; |
| 5627 | return SOCKET_ERROR; | 6349 | return SOCKET_ERROR; |
| 5628 | } | 6350 | } |
| 5629 | 6351 | ||
| @@ -5635,7 +6357,7 @@ sys_bind (int s, const struct sockaddr * addr, int namelen) | |||
| 5635 | set_errno (); | 6357 | set_errno (); |
| 5636 | return rc; | 6358 | return rc; |
| 5637 | } | 6359 | } |
| 5638 | h_errno = ENOTSOCK; | 6360 | errno = ENOTSOCK; |
| 5639 | return SOCKET_ERROR; | 6361 | return SOCKET_ERROR; |
| 5640 | } | 6362 | } |
| 5641 | 6363 | ||
| @@ -5644,7 +6366,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen) | |||
| 5644 | { | 6366 | { |
| 5645 | if (winsock_lib == NULL) | 6367 | if (winsock_lib == NULL) |
| 5646 | { | 6368 | { |
| 5647 | h_errno = ENOTSOCK; | 6369 | errno = ENOTSOCK; |
| 5648 | return SOCKET_ERROR; | 6370 | return SOCKET_ERROR; |
| 5649 | } | 6371 | } |
| 5650 | 6372 | ||
| @@ -5656,7 +6378,7 @@ sys_connect (int s, const struct sockaddr * name, int namelen) | |||
| 5656 | set_errno (); | 6378 | set_errno (); |
| 5657 | return rc; | 6379 | return rc; |
| 5658 | } | 6380 | } |
| 5659 | h_errno = ENOTSOCK; | 6381 | errno = ENOTSOCK; |
| 5660 | return SOCKET_ERROR; | 6382 | return SOCKET_ERROR; |
| 5661 | } | 6383 | } |
| 5662 | 6384 | ||
| @@ -5685,12 +6407,20 @@ int | |||
| 5685 | sys_gethostname (char * name, int namelen) | 6407 | sys_gethostname (char * name, int namelen) |
| 5686 | { | 6408 | { |
| 5687 | if (winsock_lib != NULL) | 6409 | if (winsock_lib != NULL) |
| 5688 | return pfn_gethostname (name, namelen); | 6410 | { |
| 6411 | int retval; | ||
| 6412 | |||
| 6413 | check_errno (); | ||
| 6414 | retval = pfn_gethostname (name, namelen); | ||
| 6415 | if (retval == SOCKET_ERROR) | ||
| 6416 | set_errno (); | ||
| 6417 | return retval; | ||
| 6418 | } | ||
| 5689 | 6419 | ||
| 5690 | if (namelen > MAX_COMPUTERNAME_LENGTH) | 6420 | if (namelen > MAX_COMPUTERNAME_LENGTH) |
| 5691 | return !GetComputerName (name, (DWORD *)&namelen); | 6421 | return !GetComputerName (name, (DWORD *)&namelen); |
| 5692 | 6422 | ||
| 5693 | h_errno = EFAULT; | 6423 | errno = EFAULT; |
| 5694 | return SOCKET_ERROR; | 6424 | return SOCKET_ERROR; |
| 5695 | } | 6425 | } |
| 5696 | 6426 | ||
| @@ -5698,17 +6428,24 @@ struct hostent * | |||
| 5698 | sys_gethostbyname (const char * name) | 6428 | sys_gethostbyname (const char * name) |
| 5699 | { | 6429 | { |
| 5700 | struct hostent * host; | 6430 | struct hostent * host; |
| 6431 | int h_err = h_errno; | ||
| 5701 | 6432 | ||
| 5702 | if (winsock_lib == NULL) | 6433 | if (winsock_lib == NULL) |
| 5703 | { | 6434 | { |
| 5704 | h_errno = ENETDOWN; | 6435 | h_errno = NO_RECOVERY; |
| 6436 | errno = ENETDOWN; | ||
| 5705 | return NULL; | 6437 | return NULL; |
| 5706 | } | 6438 | } |
| 5707 | 6439 | ||
| 5708 | check_errno (); | 6440 | check_errno (); |
| 5709 | host = pfn_gethostbyname (name); | 6441 | host = pfn_gethostbyname (name); |
| 5710 | if (!host) | 6442 | if (!host) |
| 5711 | set_errno (); | 6443 | { |
| 6444 | set_errno (); | ||
| 6445 | h_errno = errno; | ||
| 6446 | } | ||
| 6447 | else | ||
| 6448 | h_errno = h_err; | ||
| 5712 | return host; | 6449 | return host; |
| 5713 | } | 6450 | } |
| 5714 | 6451 | ||
| @@ -5719,7 +6456,7 @@ sys_getservbyname (const char * name, const char * proto) | |||
| 5719 | 6456 | ||
| 5720 | if (winsock_lib == NULL) | 6457 | if (winsock_lib == NULL) |
| 5721 | { | 6458 | { |
| 5722 | h_errno = ENETDOWN; | 6459 | errno = ENETDOWN; |
| 5723 | return NULL; | 6460 | return NULL; |
| 5724 | } | 6461 | } |
| 5725 | 6462 | ||
| @@ -5735,7 +6472,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen) | |||
| 5735 | { | 6472 | { |
| 5736 | if (winsock_lib == NULL) | 6473 | if (winsock_lib == NULL) |
| 5737 | { | 6474 | { |
| 5738 | h_errno = ENETDOWN; | 6475 | errno = ENETDOWN; |
| 5739 | return SOCKET_ERROR; | 6476 | return SOCKET_ERROR; |
| 5740 | } | 6477 | } |
| 5741 | 6478 | ||
| @@ -5747,7 +6484,7 @@ sys_getpeername (int s, struct sockaddr *addr, int * namelen) | |||
| 5747 | set_errno (); | 6484 | set_errno (); |
| 5748 | return rc; | 6485 | return rc; |
| 5749 | } | 6486 | } |
| 5750 | h_errno = ENOTSOCK; | 6487 | errno = ENOTSOCK; |
| 5751 | return SOCKET_ERROR; | 6488 | return SOCKET_ERROR; |
| 5752 | } | 6489 | } |
| 5753 | 6490 | ||
| @@ -5756,7 +6493,7 @@ sys_shutdown (int s, int how) | |||
| 5756 | { | 6493 | { |
| 5757 | if (winsock_lib == NULL) | 6494 | if (winsock_lib == NULL) |
| 5758 | { | 6495 | { |
| 5759 | h_errno = ENETDOWN; | 6496 | errno = ENETDOWN; |
| 5760 | return SOCKET_ERROR; | 6497 | return SOCKET_ERROR; |
| 5761 | } | 6498 | } |
| 5762 | 6499 | ||
| @@ -5768,7 +6505,7 @@ sys_shutdown (int s, int how) | |||
| 5768 | set_errno (); | 6505 | set_errno (); |
| 5769 | return rc; | 6506 | return rc; |
| 5770 | } | 6507 | } |
| 5771 | h_errno = ENOTSOCK; | 6508 | errno = ENOTSOCK; |
| 5772 | return SOCKET_ERROR; | 6509 | return SOCKET_ERROR; |
| 5773 | } | 6510 | } |
| 5774 | 6511 | ||
| @@ -5777,7 +6514,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen) | |||
| 5777 | { | 6514 | { |
| 5778 | if (winsock_lib == NULL) | 6515 | if (winsock_lib == NULL) |
| 5779 | { | 6516 | { |
| 5780 | h_errno = ENETDOWN; | 6517 | errno = ENETDOWN; |
| 5781 | return SOCKET_ERROR; | 6518 | return SOCKET_ERROR; |
| 5782 | } | 6519 | } |
| 5783 | 6520 | ||
| @@ -5790,7 +6527,7 @@ sys_setsockopt (int s, int level, int optname, const void * optval, int optlen) | |||
| 5790 | set_errno (); | 6527 | set_errno (); |
| 5791 | return rc; | 6528 | return rc; |
| 5792 | } | 6529 | } |
| 5793 | h_errno = ENOTSOCK; | 6530 | errno = ENOTSOCK; |
| 5794 | return SOCKET_ERROR; | 6531 | return SOCKET_ERROR; |
| 5795 | } | 6532 | } |
| 5796 | 6533 | ||
| @@ -5799,7 +6536,7 @@ sys_listen (int s, int backlog) | |||
| 5799 | { | 6536 | { |
| 5800 | if (winsock_lib == NULL) | 6537 | if (winsock_lib == NULL) |
| 5801 | { | 6538 | { |
| 5802 | h_errno = ENETDOWN; | 6539 | errno = ENETDOWN; |
| 5803 | return SOCKET_ERROR; | 6540 | return SOCKET_ERROR; |
| 5804 | } | 6541 | } |
| 5805 | 6542 | ||
| @@ -5813,7 +6550,7 @@ sys_listen (int s, int backlog) | |||
| 5813 | fd_info[s].flags |= FILE_LISTEN; | 6550 | fd_info[s].flags |= FILE_LISTEN; |
| 5814 | return rc; | 6551 | return rc; |
| 5815 | } | 6552 | } |
| 5816 | h_errno = ENOTSOCK; | 6553 | errno = ENOTSOCK; |
| 5817 | return SOCKET_ERROR; | 6554 | return SOCKET_ERROR; |
| 5818 | } | 6555 | } |
| 5819 | 6556 | ||
| @@ -5822,7 +6559,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen) | |||
| 5822 | { | 6559 | { |
| 5823 | if (winsock_lib == NULL) | 6560 | if (winsock_lib == NULL) |
| 5824 | { | 6561 | { |
| 5825 | h_errno = ENETDOWN; | 6562 | errno = ENETDOWN; |
| 5826 | return SOCKET_ERROR; | 6563 | return SOCKET_ERROR; |
| 5827 | } | 6564 | } |
| 5828 | 6565 | ||
| @@ -5834,7 +6571,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen) | |||
| 5834 | set_errno (); | 6571 | set_errno (); |
| 5835 | return rc; | 6572 | return rc; |
| 5836 | } | 6573 | } |
| 5837 | h_errno = ENOTSOCK; | 6574 | errno = ENOTSOCK; |
| 5838 | return SOCKET_ERROR; | 6575 | return SOCKET_ERROR; |
| 5839 | } | 6576 | } |
| 5840 | 6577 | ||
| @@ -5843,7 +6580,7 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) | |||
| 5843 | { | 6580 | { |
| 5844 | if (winsock_lib == NULL) | 6581 | if (winsock_lib == NULL) |
| 5845 | { | 6582 | { |
| 5846 | h_errno = ENETDOWN; | 6583 | errno = ENETDOWN; |
| 5847 | return -1; | 6584 | return -1; |
| 5848 | } | 6585 | } |
| 5849 | 6586 | ||
| @@ -5857,11 +6594,14 @@ sys_accept (int s, struct sockaddr * addr, int * addrlen) | |||
| 5857 | else | 6594 | else |
| 5858 | fd = socket_to_fd (t); | 6595 | fd = socket_to_fd (t); |
| 5859 | 6596 | ||
| 5860 | fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED; | 6597 | if (fd >= 0) |
| 5861 | ResetEvent (fd_info[s].cp->char_avail); | 6598 | { |
| 6599 | fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED; | ||
| 6600 | ResetEvent (fd_info[s].cp->char_avail); | ||
| 6601 | } | ||
| 5862 | return fd; | 6602 | return fd; |
| 5863 | } | 6603 | } |
| 5864 | h_errno = ENOTSOCK; | 6604 | errno = ENOTSOCK; |
| 5865 | return -1; | 6605 | return -1; |
| 5866 | } | 6606 | } |
| 5867 | 6607 | ||
| @@ -5871,7 +6611,7 @@ sys_recvfrom (int s, char * buf, int len, int flags, | |||
| 5871 | { | 6611 | { |
| 5872 | if (winsock_lib == NULL) | 6612 | if (winsock_lib == NULL) |
| 5873 | { | 6613 | { |
| 5874 | h_errno = ENETDOWN; | 6614 | errno = ENETDOWN; |
| 5875 | return SOCKET_ERROR; | 6615 | return SOCKET_ERROR; |
| 5876 | } | 6616 | } |
| 5877 | 6617 | ||
| @@ -5883,7 +6623,7 @@ sys_recvfrom (int s, char * buf, int len, int flags, | |||
| 5883 | set_errno (); | 6623 | set_errno (); |
| 5884 | return rc; | 6624 | return rc; |
| 5885 | } | 6625 | } |
| 5886 | h_errno = ENOTSOCK; | 6626 | errno = ENOTSOCK; |
| 5887 | return SOCKET_ERROR; | 6627 | return SOCKET_ERROR; |
| 5888 | } | 6628 | } |
| 5889 | 6629 | ||
| @@ -5893,7 +6633,7 @@ sys_sendto (int s, const char * buf, int len, int flags, | |||
| 5893 | { | 6633 | { |
| 5894 | if (winsock_lib == NULL) | 6634 | if (winsock_lib == NULL) |
| 5895 | { | 6635 | { |
| 5896 | h_errno = ENETDOWN; | 6636 | errno = ENETDOWN; |
| 5897 | return SOCKET_ERROR; | 6637 | return SOCKET_ERROR; |
| 5898 | } | 6638 | } |
| 5899 | 6639 | ||
| @@ -5905,7 +6645,7 @@ sys_sendto (int s, const char * buf, int len, int flags, | |||
| 5905 | set_errno (); | 6645 | set_errno (); |
| 5906 | return rc; | 6646 | return rc; |
| 5907 | } | 6647 | } |
| 5908 | h_errno = ENOTSOCK; | 6648 | errno = ENOTSOCK; |
| 5909 | return SOCKET_ERROR; | 6649 | return SOCKET_ERROR; |
| 5910 | } | 6650 | } |
| 5911 | 6651 | ||
| @@ -5916,7 +6656,7 @@ fcntl (int s, int cmd, int options) | |||
| 5916 | { | 6656 | { |
| 5917 | if (winsock_lib == NULL) | 6657 | if (winsock_lib == NULL) |
| 5918 | { | 6658 | { |
| 5919 | h_errno = ENETDOWN; | 6659 | errno = ENETDOWN; |
| 5920 | return -1; | 6660 | return -1; |
| 5921 | } | 6661 | } |
| 5922 | 6662 | ||
| @@ -5935,11 +6675,11 @@ fcntl (int s, int cmd, int options) | |||
| 5935 | } | 6675 | } |
| 5936 | else | 6676 | else |
| 5937 | { | 6677 | { |
| 5938 | h_errno = EINVAL; | 6678 | errno = EINVAL; |
| 5939 | return SOCKET_ERROR; | 6679 | return SOCKET_ERROR; |
| 5940 | } | 6680 | } |
| 5941 | } | 6681 | } |
| 5942 | h_errno = ENOTSOCK; | 6682 | errno = ENOTSOCK; |
| 5943 | return SOCKET_ERROR; | 6683 | return SOCKET_ERROR; |
| 5944 | } | 6684 | } |
| 5945 | 6685 | ||
| @@ -5986,20 +6726,34 @@ sys_close (int fd) | |||
| 5986 | 6726 | ||
| 5987 | winsock_inuse--; /* count open sockets */ | 6727 | winsock_inuse--; /* count open sockets */ |
| 5988 | } | 6728 | } |
| 5989 | delete_child (cp); | 6729 | /* If the process handle is NULL, it's either a socket |
| 6730 | or serial connection, or a subprocess that was | ||
| 6731 | already reaped by reap_subprocess, but whose | ||
| 6732 | resources were not yet freed, because its output was | ||
| 6733 | not fully read yet by the time it was reaped. (This | ||
| 6734 | usually happens with async subprocesses whose output | ||
| 6735 | is being read by Emacs.) Otherwise, this process was | ||
| 6736 | not reaped yet, so we set its FD to a negative value | ||
| 6737 | to make sure sys_select will eventually get to | ||
| 6738 | calling the SIGCHLD handler for it, which will then | ||
| 6739 | invoke waitpid and reap_subprocess. */ | ||
| 6740 | if (cp->procinfo.hProcess == NULL) | ||
| 6741 | delete_child (cp); | ||
| 6742 | else | ||
| 6743 | cp->fd = -1; | ||
| 5990 | } | 6744 | } |
| 5991 | } | 6745 | } |
| 5992 | } | 6746 | } |
| 5993 | 6747 | ||
| 6748 | if (fd >= 0 && fd < MAXDESC) | ||
| 6749 | fd_info[fd].flags = 0; | ||
| 6750 | |||
| 5994 | /* Note that sockets do not need special treatment here (at least on | 6751 | /* Note that sockets do not need special treatment here (at least on |
| 5995 | NT and Windows 95 using the standard tcp/ip stacks) - it appears that | 6752 | NT and Windows 95 using the standard tcp/ip stacks) - it appears that |
| 5996 | closesocket is equivalent to CloseHandle, which is to be expected | 6753 | closesocket is equivalent to CloseHandle, which is to be expected |
| 5997 | because socket handles are fully fledged kernel handles. */ | 6754 | because socket handles are fully fledged kernel handles. */ |
| 5998 | rc = _close (fd); | 6755 | rc = _close (fd); |
| 5999 | 6756 | ||
| 6000 | if (rc == 0 && fd < MAXDESC) | ||
| 6001 | fd_info[fd].flags = 0; | ||
| 6002 | |||
| 6003 | return rc; | 6757 | return rc; |
| 6004 | } | 6758 | } |
| 6005 | 6759 | ||
| @@ -6062,6 +6816,7 @@ sys_pipe (int * phandles) | |||
| 6062 | { | 6816 | { |
| 6063 | _close (phandles[0]); | 6817 | _close (phandles[0]); |
| 6064 | _close (phandles[1]); | 6818 | _close (phandles[1]); |
| 6819 | errno = EMFILE; | ||
| 6065 | rc = -1; | 6820 | rc = -1; |
| 6066 | } | 6821 | } |
| 6067 | else | 6822 | else |
| @@ -6078,7 +6833,8 @@ sys_pipe (int * phandles) | |||
| 6078 | } | 6833 | } |
| 6079 | 6834 | ||
| 6080 | /* Function to do blocking read of one byte, needed to implement | 6835 | /* Function to do blocking read of one byte, needed to implement |
| 6081 | select. It is only allowed on sockets and pipes. */ | 6836 | select. It is only allowed on communication ports, sockets, or |
| 6837 | pipes. */ | ||
| 6082 | int | 6838 | int |
| 6083 | _sys_read_ahead (int fd) | 6839 | _sys_read_ahead (int fd) |
| 6084 | { | 6840 | { |
| @@ -6134,19 +6890,31 @@ _sys_read_ahead (int fd) | |||
| 6134 | 6890 | ||
| 6135 | /* Configure timeouts for blocking read. */ | 6891 | /* Configure timeouts for blocking read. */ |
| 6136 | if (!GetCommTimeouts (hnd, &ct)) | 6892 | if (!GetCommTimeouts (hnd, &ct)) |
| 6137 | return STATUS_READ_ERROR; | 6893 | { |
| 6894 | cp->status = STATUS_READ_ERROR; | ||
| 6895 | return STATUS_READ_ERROR; | ||
| 6896 | } | ||
| 6138 | ct.ReadIntervalTimeout = 0; | 6897 | ct.ReadIntervalTimeout = 0; |
| 6139 | ct.ReadTotalTimeoutMultiplier = 0; | 6898 | ct.ReadTotalTimeoutMultiplier = 0; |
| 6140 | ct.ReadTotalTimeoutConstant = 0; | 6899 | ct.ReadTotalTimeoutConstant = 0; |
| 6141 | if (!SetCommTimeouts (hnd, &ct)) | 6900 | if (!SetCommTimeouts (hnd, &ct)) |
| 6142 | return STATUS_READ_ERROR; | 6901 | { |
| 6902 | cp->status = STATUS_READ_ERROR; | ||
| 6903 | return STATUS_READ_ERROR; | ||
| 6904 | } | ||
| 6143 | 6905 | ||
| 6144 | if (!ReadFile (hnd, &cp->chr, sizeof (char), (DWORD*) &rc, ovl)) | 6906 | if (!ReadFile (hnd, &cp->chr, sizeof (char), (DWORD*) &rc, ovl)) |
| 6145 | { | 6907 | { |
| 6146 | if (GetLastError () != ERROR_IO_PENDING) | 6908 | if (GetLastError () != ERROR_IO_PENDING) |
| 6147 | return STATUS_READ_ERROR; | 6909 | { |
| 6910 | cp->status = STATUS_READ_ERROR; | ||
| 6911 | return STATUS_READ_ERROR; | ||
| 6912 | } | ||
| 6148 | if (!GetOverlappedResult (hnd, ovl, (DWORD*) &rc, TRUE)) | 6913 | if (!GetOverlappedResult (hnd, ovl, (DWORD*) &rc, TRUE)) |
| 6149 | return STATUS_READ_ERROR; | 6914 | { |
| 6915 | cp->status = STATUS_READ_ERROR; | ||
| 6916 | return STATUS_READ_ERROR; | ||
| 6917 | } | ||
| 6150 | } | 6918 | } |
| 6151 | } | 6919 | } |
| 6152 | else if (fd_info[fd].flags & FILE_SOCKET) | 6920 | else if (fd_info[fd].flags & FILE_SOCKET) |
| @@ -6342,7 +7110,7 @@ sys_read (int fd, char * buffer, unsigned int count) | |||
| 6342 | pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); | 7110 | pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); |
| 6343 | if (waiting == 0 && nchars == 0) | 7111 | if (waiting == 0 && nchars == 0) |
| 6344 | { | 7112 | { |
| 6345 | h_errno = errno = EWOULDBLOCK; | 7113 | errno = EWOULDBLOCK; |
| 6346 | return -1; | 7114 | return -1; |
| 6347 | } | 7115 | } |
| 6348 | 7116 | ||
| @@ -6840,6 +7608,11 @@ globals_of_w32 (void) | |||
| 6840 | g_b_init_get_native_system_info = 0; | 7608 | g_b_init_get_native_system_info = 0; |
| 6841 | g_b_init_get_system_times = 0; | 7609 | g_b_init_get_system_times = 0; |
| 6842 | g_b_init_create_symbolic_link = 0; | 7610 | g_b_init_create_symbolic_link = 0; |
| 7611 | g_b_init_get_security_descriptor_dacl = 0; | ||
| 7612 | g_b_init_convert_sd_to_sddl = 0; | ||
| 7613 | g_b_init_convert_sddl_to_sd = 0; | ||
| 7614 | g_b_init_is_valid_security_descriptor = 0; | ||
| 7615 | g_b_init_set_file_security = 0; | ||
| 6843 | num_of_processors = 0; | 7616 | num_of_processors = 0; |
| 6844 | /* The following sets a handler for shutdown notifications for | 7617 | /* The following sets a handler for shutdown notifications for |
| 6845 | console apps. This actually applies to Emacs in both console and | 7618 | console apps. This actually applies to Emacs in both console and |
| @@ -6849,6 +7622,9 @@ globals_of_w32 (void) | |||
| 6849 | 7622 | ||
| 6850 | /* "None" is the default group name on standalone workstations. */ | 7623 | /* "None" is the default group name on standalone workstations. */ |
| 6851 | strcpy (dflt_group_name, "None"); | 7624 | strcpy (dflt_group_name, "None"); |
| 7625 | |||
| 7626 | /* Reset, in case it has some value inherited from dump time. */ | ||
| 7627 | w32_stat_get_owner_group = 0; | ||
| 6852 | } | 7628 | } |
| 6853 | 7629 | ||
| 6854 | /* For make-serial-process */ | 7630 | /* For make-serial-process */ |
| @@ -2,7 +2,7 @@ | |||
| 2 | #define EMACS_W32_H | 2 | #define EMACS_W32_H |
| 3 | 3 | ||
| 4 | /* Support routines for the NT version of Emacs. | 4 | /* Support routines for the NT version of Emacs. |
| 5 | Copyright (C) 1994, 2001-2012 Free Software Foundation, Inc. | 5 | Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc. |
| 6 | 6 | ||
| 7 | This file is part of GNU Emacs. | 7 | This file is part of GNU Emacs. |
| 8 | 8 | ||
| @@ -68,17 +68,47 @@ enum { | |||
| 68 | a socket, the process handle in pi is NULL. */ | 68 | a socket, the process handle in pi is NULL. */ |
| 69 | typedef struct _child_process | 69 | typedef struct _child_process |
| 70 | { | 70 | { |
| 71 | int fd; | 71 | /* File descriptor for sockets and serial port connections, and for |
| 72 | int pid; | 72 | reading output from async subprocesses; otherwise -1. */ |
| 73 | HANDLE char_avail; | 73 | int fd; |
| 74 | HANDLE char_consumed; | 74 | /* PID for subprocess, either async or not; otherwise -1. */ |
| 75 | HANDLE thrd; | 75 | int pid; |
| 76 | HWND hwnd; | 76 | /* Handle to an event object that is signaled when a read operation |
| 77 | PROCESS_INFORMATION procinfo; | 77 | is completed, either successfully (in which case there're indeed |
| 78 | volatile int status; | 78 | "characters available") or not. Used by sys_select to wait for |
| 79 | char chr; | 79 | output from subprocesses or socket/serial connections. */ |
| 80 | OVERLAPPED ovl_read; | 80 | HANDLE char_avail; |
| 81 | OVERLAPPED ovl_write; | 81 | /* Handle to an event that is signaled to wake up the reader thread |
| 82 | and tell it to try reading more output from a subprocess. */ | ||
| 83 | HANDLE char_consumed; | ||
| 84 | /* Handle to the reader thread to read output from a subprocess or a | ||
| 85 | socket or a comm port. */ | ||
| 86 | HANDLE thrd; | ||
| 87 | /* Handle to the console window of a subprocess. Used to forcibly | ||
| 88 | terminate it by sys_kill. */ | ||
| 89 | HWND hwnd; | ||
| 90 | /* Information about subprocess returned by CreateProcess. Includes | ||
| 91 | handles to the subprocess and its primary thread, and the | ||
| 92 | corresponding process ID and thread ID numbers. The PID is | ||
| 93 | mirrored by the 'pid' member above. The process handle is used | ||
| 94 | to wait on it. */ | ||
| 95 | PROCESS_INFORMATION procinfo; | ||
| 96 | /* Status of subprocess/connection and of reading its output. For | ||
| 97 | values, see the enumeration above. */ | ||
| 98 | volatile int status; | ||
| 99 | /* Holds a single character read by _sys_read_ahead, when a | ||
| 100 | subprocess has some output ready. */ | ||
| 101 | char chr; | ||
| 102 | /* Used for async read operations on serial comm ports. */ | ||
| 103 | OVERLAPPED ovl_read; | ||
| 104 | /* Used for async write operations on serial comm ports. */ | ||
| 105 | OVERLAPPED ovl_write; | ||
| 106 | /* Input file, if any, for this subprocess. Should only be non-NULL | ||
| 107 | for async subprocesses. */ | ||
| 108 | char *input_file; | ||
| 109 | /* If non-zero, the subprocess input file is temporary and should be | ||
| 110 | deleted when the subprocess exits. */ | ||
| 111 | int pending_deletion; | ||
| 82 | } child_process; | 112 | } child_process; |
| 83 | 113 | ||
| 84 | #define MAXDESC FD_SETSIZE | 114 | #define MAXDESC FD_SETSIZE |
| @@ -150,7 +180,7 @@ extern void init_environment (char **); | |||
| 150 | extern void check_windows_init_file (void); | 180 | extern void check_windows_init_file (void); |
| 151 | extern void syms_of_ntproc (void); | 181 | extern void syms_of_ntproc (void); |
| 152 | extern void syms_of_ntterm (void); | 182 | extern void syms_of_ntterm (void); |
| 153 | extern void dostounix_filename (register char *); | 183 | extern void dostounix_filename (register char *, int); |
| 154 | extern void unixtodos_filename (register char *); | 184 | extern void unixtodos_filename (register char *); |
| 155 | extern BOOL init_winsock (int load_now); | 185 | extern BOOL init_winsock (int load_now); |
| 156 | extern void srandom (int); | 186 | extern void srandom (int); |
| @@ -160,7 +190,9 @@ extern int sys_pipe (int *); | |||
| 160 | 190 | ||
| 161 | extern void set_process_dir (char *); | 191 | extern void set_process_dir (char *); |
| 162 | extern int sys_spawnve (int, char *, char **, char **); | 192 | extern int sys_spawnve (int, char *, char **, char **); |
| 163 | extern void register_child (int, int); | 193 | extern void register_child (pid_t, int); |
| 194 | extern void record_infile (pid_t, char *); | ||
| 195 | extern void record_pending_deletion (char *); | ||
| 164 | 196 | ||
| 165 | extern void sys_sleep (int); | 197 | extern void sys_sleep (int); |
| 166 | extern int sys_link (const char *, const char *); | 198 | extern int sys_link (const char *, const char *); |
diff --git a/src/w32common.h b/src/w32common.h index 5e9b61824ae..79fe5cc367c 100644 --- a/src/w32common.h +++ b/src/w32common.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Common functions for Microsoft Windows builds of Emacs | 1 | /* Common functions for Microsoft Windows builds of Emacs |
| 2 | Copyright (C) 2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2012-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/w32console.c b/src/w32console.c index f0574689bf1..06b2c7aa24e 100644 --- a/src/w32console.c +++ b/src/w32console.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Terminal hooks for GNU Emacs on the Microsoft Windows API. | 1 | /* Terminal hooks for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1992, 1999, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1992, 1999, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -746,6 +746,9 @@ initialize_w32_display (struct terminal *term) | |||
| 746 | else | 746 | else |
| 747 | w32_console_unicode_input = 0; | 747 | w32_console_unicode_input = 0; |
| 748 | 748 | ||
| 749 | /* This is needed by w32notify.c:send_notifications. */ | ||
| 750 | dwMainThreadId = GetCurrentThreadId (); | ||
| 751 | |||
| 749 | /* Setup w32_display_info structure for this frame. */ | 752 | /* Setup w32_display_info structure for this frame. */ |
| 750 | 753 | ||
| 751 | w32_initialize_display_info (build_string ("Console")); | 754 | w32_initialize_display_info (build_string ("Console")); |
diff --git a/src/w32fns.c b/src/w32fns.c index 1a181079c82..5fab2c9a3df 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Graphical user interface functions for the Microsoft Windows API. | 1 | /* Graphical user interface functions for the Microsoft Windows API. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1989, 1992-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -1821,7 +1821,6 @@ static LRESULT CALLBACK w32_wnd_proc (HWND, UINT, WPARAM, LPARAM); | |||
| 1821 | static BOOL | 1821 | static BOOL |
| 1822 | w32_init_class (HINSTANCE hinst) | 1822 | w32_init_class (HINSTANCE hinst) |
| 1823 | { | 1823 | { |
| 1824 | |||
| 1825 | if (w32_unicode_gui) | 1824 | if (w32_unicode_gui) |
| 1826 | { | 1825 | { |
| 1827 | WNDCLASSW uwc; | 1826 | WNDCLASSW uwc; |
| @@ -3957,6 +3956,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 3957 | 3956 | ||
| 3958 | return retval; | 3957 | return retval; |
| 3959 | } | 3958 | } |
| 3959 | case WM_EMACS_FILENOTIFY: | ||
| 3960 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | ||
| 3961 | return 1; | ||
| 3960 | 3962 | ||
| 3961 | default: | 3963 | default: |
| 3962 | /* Check for messages registered at runtime. */ | 3964 | /* Check for messages registered at runtime. */ |
| @@ -5941,7 +5943,7 @@ Text larger than the specified size is clipped. */) | |||
| 5941 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | 5943 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); |
| 5942 | 5944 | ||
| 5943 | /* Let redisplay know that we have made the frame visible already. */ | 5945 | /* Let redisplay know that we have made the frame visible already. */ |
| 5944 | f->async_visible = 1; | 5946 | SET_FRAME_VISIBLE (f, 1); |
| 5945 | 5947 | ||
| 5946 | ShowWindow (FRAME_W32_WINDOW (f), SW_SHOWNOACTIVATE); | 5948 | ShowWindow (FRAME_W32_WINDOW (f), SW_SHOWNOACTIVATE); |
| 5947 | } | 5949 | } |
| @@ -6252,7 +6254,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6252 | /* we get one of the two final 0 bytes for free. */ | 6254 | /* we get one of the two final 0 bytes for free. */ |
| 6253 | 1 + sizeof (wchar_t) * wcslen (filename_buf))); | 6255 | 1 + sizeof (wchar_t) * wcslen (filename_buf))); |
| 6254 | #else /* !NTGUI_UNICODE */ | 6256 | #else /* !NTGUI_UNICODE */ |
| 6255 | dostounix_filename (filename_buf); | 6257 | dostounix_filename (filename_buf, 0); |
| 6256 | filename = DECODE_FILE (build_string (filename_buf)); | 6258 | filename = DECODE_FILE (build_string (filename_buf)); |
| 6257 | #endif /* NTGUI_UNICODE */ | 6259 | #endif /* NTGUI_UNICODE */ |
| 6258 | 6260 | ||
| @@ -6482,12 +6484,12 @@ w32_parse_hot_key (Lisp_Object key) | |||
| 6482 | 6484 | ||
| 6483 | CHECK_VECTOR (key); | 6485 | CHECK_VECTOR (key); |
| 6484 | 6486 | ||
| 6485 | if (XFASTINT (Flength (key)) != 1) | 6487 | if (ASIZE (key) != 1) |
| 6486 | return Qnil; | 6488 | return Qnil; |
| 6487 | 6489 | ||
| 6488 | GCPRO1 (key); | 6490 | GCPRO1 (key); |
| 6489 | 6491 | ||
| 6490 | c = Faref (key, make_number (0)); | 6492 | c = AREF (key, 0); |
| 6491 | 6493 | ||
| 6492 | if (CONSP (c) && lucid_event_type_list_p (c)) | 6494 | if (CONSP (c) && lucid_event_type_list_p (c)) |
| 6493 | c = Fevent_convert_list (c); | 6495 | c = Fevent_convert_list (c); |
| @@ -7024,6 +7026,9 @@ cache_system_info (void) | |||
| 7024 | DWORD data; | 7026 | DWORD data; |
| 7025 | } version; | 7027 | } version; |
| 7026 | 7028 | ||
| 7029 | /* Cache the module handle of Emacs itself. */ | ||
| 7030 | hinst = GetModuleHandle (NULL); | ||
| 7031 | |||
| 7027 | /* Cache the version of the operating system. */ | 7032 | /* Cache the version of the operating system. */ |
| 7028 | version.data = GetVersion (); | 7033 | version.data = GetVersion (); |
| 7029 | w32_major_version = version.info.major; | 7034 | w32_major_version = version.info.major; |
| @@ -7036,7 +7041,7 @@ cache_system_info (void) | |||
| 7036 | 7041 | ||
| 7037 | /* Cache page size, allocation unit, processor type, etc. */ | 7042 | /* Cache page size, allocation unit, processor type, etc. */ |
| 7038 | GetSystemInfo (&sysinfo_cache); | 7043 | GetSystemInfo (&sysinfo_cache); |
| 7039 | syspage_mask = sysinfo_cache.dwPageSize - 1; | 7044 | syspage_mask = (DWORD_PTR)sysinfo_cache.dwPageSize - 1; |
| 7040 | 7045 | ||
| 7041 | /* Cache os info. */ | 7046 | /* Cache os info. */ |
| 7042 | osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); | 7047 | osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); |
diff --git a/src/w32font.c b/src/w32font.c index d7d25d89939..5c5a15cc340 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Font backend for the Microsoft Windows API. | 1 | /* Font backend for the Microsoft Windows API. |
| 2 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/w32font.h b/src/w32font.h index 8fa00a9b524..b4345478a22 100644 --- a/src/w32font.h +++ b/src/w32font.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Shared GDI and Uniscribe Font backend declarations for the Windows API. | 1 | /* Shared GDI and Uniscribe Font backend declarations for the Windows API. |
| 2 | Copyright (C) 2007-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/w32gui.h b/src/w32gui.h index 0da8de97f23..739ff3c92e9 100644 --- a/src/w32gui.h +++ b/src/w32gui.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions and headers for communication on the Microsoft Windows API. | 1 | /* Definitions and headers for communication on the Microsoft Windows API. |
| 2 | Copyright (C) 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1995, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -79,9 +79,6 @@ typedef struct _XImage | |||
| 79 | #define FACE_DEFAULT (~0) | 79 | #define FACE_DEFAULT (~0) |
| 80 | 80 | ||
| 81 | extern HINSTANCE hinst; | 81 | extern HINSTANCE hinst; |
| 82 | extern HINSTANCE hprevinst; | ||
| 83 | extern LPSTR lpCmdLine; | ||
| 84 | extern int nCmdShow; | ||
| 85 | 82 | ||
| 86 | /* Bit Gravity */ | 83 | /* Bit Gravity */ |
| 87 | 84 | ||
diff --git a/src/w32heap.c b/src/w32heap.c index 311e1064434..81206ce2834 100644 --- a/src/w32heap.c +++ b/src/w32heap.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Heap management routines for GNU Emacs on the Microsoft Windows API. | 1 | /* Heap management routines for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -98,7 +98,11 @@ allocate_heap (void) | |||
| 98 | #ifdef _WIN64 | 98 | #ifdef _WIN64 |
| 99 | size_t size = 0x4000000000i64; /* start by asking for 32GB */ | 99 | size_t size = 0x4000000000i64; /* start by asking for 32GB */ |
| 100 | #else | 100 | #else |
| 101 | size_t size = 0x80000000; /* start by asking for 2GB */ | 101 | /* We used to start with 2GB here, but on Windows 7 that would leave |
| 102 | too little room in the address space for threads started by | ||
| 103 | Windows on our behalf, e.g. when we pop up the file selection | ||
| 104 | dialog. */ | ||
| 105 | size_t size = 0x68000000; /* start by asking for 1.7GB */ | ||
| 102 | #endif | 106 | #endif |
| 103 | void *ptr = NULL; | 107 | void *ptr = NULL; |
| 104 | 108 | ||
diff --git a/src/w32heap.h b/src/w32heap.h index 1630864875f..82b59dd027f 100644 --- a/src/w32heap.h +++ b/src/w32heap.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Heap management routines (including unexec) for GNU Emacs on Windows NT. | 1 | /* Heap management routines (including unexec) for GNU Emacs on Windows NT. |
| 2 | Copyright (C) 1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/w32inevt.c b/src/w32inevt.c index 899a6fb89bf..3c38cf806e8 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Input event support for Emacs on the Microsoft Windows API. | 1 | /* Input event support for Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1992-1993, 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1992-1993, 1995, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -576,6 +577,74 @@ maybe_generate_resize_event (void) | |||
| 576 | 0, 0, 0); | 577 | 0, 0, 0); |
| 577 | } | 578 | } |
| 578 | 579 | ||
| 580 | static int | ||
| 581 | handle_file_notifications (struct input_event *hold_quit) | ||
| 582 | { | ||
| 583 | BYTE *p = file_notifications; | ||
| 584 | FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p; | ||
| 585 | const DWORD min_size | ||
| 586 | = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t); | ||
| 587 | struct input_event inev; | ||
| 588 | int nevents = 0; | ||
| 589 | |||
| 590 | /* We cannot process notification before Emacs is fully initialized, | ||
| 591 | since we need the UTF-16LE coding-system to be set up. */ | ||
| 592 | if (!initialized) | ||
| 593 | { | ||
| 594 | notification_buffer_in_use = 0; | ||
| 595 | return nevents; | ||
| 596 | } | ||
| 597 | |||
| 598 | enter_crit (); | ||
| 599 | if (notification_buffer_in_use) | ||
| 600 | { | ||
| 601 | DWORD info_size = notifications_size; | ||
| 602 | Lisp_Object cs = intern ("utf-16le"); | ||
| 603 | Lisp_Object obj = w32_get_watch_object (notifications_desc); | ||
| 604 | |||
| 605 | /* notifications_size could be zero when the buffer of | ||
| 606 | notifications overflowed on the OS level, or when the | ||
| 607 | directory being watched was itself deleted. Do nothing in | ||
| 608 | that case. */ | ||
| 609 | if (info_size | ||
| 610 | && !NILP (obj) && CONSP (obj)) | ||
| 611 | { | ||
| 612 | Lisp_Object callback = XCDR (obj); | ||
| 613 | |||
| 614 | EVENT_INIT (inev); | ||
| 615 | |||
| 616 | while (info_size >= min_size) | ||
| 617 | { | ||
| 618 | Lisp_Object utf_16_fn | ||
| 619 | = make_unibyte_string ((char *)fni->FileName, | ||
| 620 | fni->FileNameLength); | ||
| 621 | /* Note: mule-conf is preloaded, so utf-16le must | ||
| 622 | already be defined at this point. */ | ||
| 623 | Lisp_Object fname | ||
| 624 | = code_convert_string_norecord (utf_16_fn, cs, 0); | ||
| 625 | Lisp_Object action = lispy_file_action (fni->Action); | ||
| 626 | |||
| 627 | inev.kind = FILE_NOTIFY_EVENT; | ||
| 628 | inev.code = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc)); | ||
| 629 | inev.timestamp = GetTickCount (); | ||
| 630 | inev.modifiers = 0; | ||
| 631 | inev.frame_or_window = callback; | ||
| 632 | inev.arg = Fcons (action, fname); | ||
| 633 | kbd_buffer_store_event_hold (&inev, hold_quit); | ||
| 634 | |||
| 635 | if (!fni->NextEntryOffset) | ||
| 636 | break; | ||
| 637 | p += fni->NextEntryOffset; | ||
| 638 | fni = (PFILE_NOTIFY_INFORMATION)p; | ||
| 639 | info_size -= fni->NextEntryOffset; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | notification_buffer_in_use = 0; | ||
| 643 | } | ||
| 644 | leave_crit (); | ||
| 645 | return nevents; | ||
| 646 | } | ||
| 647 | |||
| 579 | /* Here's an overview of how Emacs input works in non-GUI sessions on | 648 | /* Here's an overview of how Emacs input works in non-GUI sessions on |
| 580 | MS-Windows. (For description of the GUI input, see the commentary | 649 | MS-Windows. (For description of the GUI input, see the commentary |
| 581 | before w32_msg_pump in w32fns.c.) | 650 | before w32_msg_pump in w32fns.c.) |
| @@ -619,12 +688,16 @@ w32_console_read_socket (struct terminal *terminal, | |||
| 619 | 688 | ||
| 620 | for (;;) | 689 | for (;;) |
| 621 | { | 690 | { |
| 691 | int nfnotify = handle_file_notifications (hold_quit); | ||
| 692 | |||
| 622 | nev = fill_queue (0); | 693 | nev = fill_queue (0); |
| 623 | if (nev <= 0) | 694 | if (nev <= 0) |
| 624 | { | 695 | { |
| 625 | /* If nev == -1, there was some kind of error | 696 | /* If nev == -1, there was some kind of error |
| 626 | If nev == 0 then waitp must be zero and no events were available | 697 | If nev == 0 then no events were available |
| 627 | so return. */ | 698 | so return. */ |
| 699 | if (nfnotify) | ||
| 700 | nev = 0; | ||
| 628 | break; | 701 | break; |
| 629 | } | 702 | } |
| 630 | 703 | ||
diff --git a/src/w32inevt.h b/src/w32inevt.h index 319688b877b..8a7e4fed06a 100644 --- a/src/w32inevt.h +++ b/src/w32inevt.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Input routines for GNU Emacs on the Microsoft Windows API. | 1 | /* Input routines for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1995, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/w32menu.c b/src/w32menu.c index 84fb1bdc71e..03904cf20b8 100644 --- a/src/w32menu.c +++ b/src/w32menu.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Menu support for GNU Emacs on the Microsoft Windows API. | 1 | /* Menu support for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2012 | 2 | Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2013 Free |
| 3 | Free Software Foundation, Inc. | 3 | Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/w32notify.c b/src/w32notify.c new file mode 100644 index 00000000000..1bcaa794565 --- /dev/null +++ b/src/w32notify.c | |||
| @@ -0,0 +1,637 @@ | |||
| 1 | /* Filesystem notifications support for GNU Emacs on the Microsoft Windows API. | ||
| 2 | Copyright (C) 2012-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 | /* Written by Eli Zaretskii <eliz@gnu.org>. | ||
| 20 | |||
| 21 | Design overview: | ||
| 22 | |||
| 23 | For each watch request, we launch a separate worker thread. The | ||
| 24 | worker thread runs the watch_worker function, which issues an | ||
| 25 | asynchronous call to ReadDirectoryChangesW, and then waits in | ||
| 26 | SleepEx for that call to complete. Waiting in SleepEx puts the | ||
| 27 | thread in an "alertable" state, so it wakes up when either (a) the | ||
| 28 | call to ReadDirectoryChangesW completes, or (b) the main thread | ||
| 29 | instructs the worker thread to terminate by sending it an APC, see | ||
| 30 | below. | ||
| 31 | |||
| 32 | When the ReadDirectoryChangesW call completes, its completion | ||
| 33 | routine watch_completion is automatically called. watch_completion | ||
| 34 | stashes the received file events in a buffer used to communicate | ||
| 35 | them to the main thread (using a critical section, so that several | ||
| 36 | threads could use the same buffer), posts a special message, | ||
| 37 | WM_EMACS_FILENOTIFY, to the Emacs's message queue, and returns. | ||
| 38 | That causes the SleepEx function call inside watch_worker to | ||
| 39 | return, and watch_worker then issues another call to | ||
| 40 | ReadDirectoryChangesW. (Except when it does not, see below.) | ||
| 41 | |||
| 42 | In a GUI session, The WM_EMACS_FILENOTIFY message, posted to the | ||
| 43 | message queue gets dispatched to the main Emacs window procedure, | ||
| 44 | which queues it for processing by w32_read_socket. When | ||
| 45 | w32_read_socket sees this message, it accesses the buffer with file | ||
| 46 | notifications (using a critical section), extracts the information, | ||
| 47 | converts it to a series of FILE_NOTIFY_EVENT events, and stuffs | ||
| 48 | them into the input event queue to be processed by keyboard.c input | ||
| 49 | machinery (read_char via a call to kbd_buffer_get_event). | ||
| 50 | |||
| 51 | In a non-GUI session, we send the WM_EMACS_FILENOTIFY message to | ||
| 52 | the main (a.k.a. "Lisp") thread instead, since there are no window | ||
| 53 | procedures in console programs. That message wakes up | ||
| 54 | MsgWaitForMultipleObjects inside sys_select, which then signals to | ||
| 55 | its caller that some keyboard input is available. This causes | ||
| 56 | w32_console_read_socket to be called, which accesses the buffer | ||
| 57 | with file notifications and stuffs them into the input event queue | ||
| 58 | for keyboard.c to process. | ||
| 59 | |||
| 60 | When the FILE_NOTIFY_EVENT event is processed by keyboard.c's | ||
| 61 | kbd_buffer_get_event, it is converted to a Lispy event that can be | ||
| 62 | bound to a command. The default binding is w32notify-handle-event, | ||
| 63 | defined on subr.el. | ||
| 64 | |||
| 65 | After w32_read_socket or w32_console_read_socket are done | ||
| 66 | processing the notifications, they reset a flag signaling to all | ||
| 67 | watch worker threads that the notifications buffer is available for | ||
| 68 | more input. | ||
| 69 | |||
| 70 | When the watch is removed by a call to w32notify-rm-watch, the main | ||
| 71 | thread requests that the worker thread terminates by queuing an APC | ||
| 72 | for the worker thread. The APC specifies the watch_end function to | ||
| 73 | be called. watch_end calls CancelIo on the outstanding | ||
| 74 | ReadDirectoryChangesW call and closes the handle on which the | ||
| 75 | watched directory was open. When watch_end returns, the | ||
| 76 | watch_completion function is called one last time with the | ||
| 77 | ERROR_OPERATION_ABORTED status, which causes it to clean up and set | ||
| 78 | a flag telling watch_worker to exit without issuing another | ||
| 79 | ReadDirectoryChangesW call. Since watch_worker is the thread | ||
| 80 | procedure of the worker thread, exiting it causes the thread to | ||
| 81 | exit. The main thread waits for some time for the worker thread to | ||
| 82 | exit, and if it doesn't, terminates it forcibly. */ | ||
| 83 | |||
| 84 | #include <stddef.h> | ||
| 85 | #include <errno.h> | ||
| 86 | |||
| 87 | /* must include CRT headers *before* config.h */ | ||
| 88 | #include <config.h> | ||
| 89 | |||
| 90 | #include <windows.h> | ||
| 91 | |||
| 92 | #include "lisp.h" | ||
| 93 | #include "w32term.h" /* for enter_crit/leave_crit and WM_EMACS_FILENOTIFY */ | ||
| 94 | #include "w32common.h" /* for OS version data */ | ||
| 95 | #include "w32.h" /* for w32_strerror */ | ||
| 96 | #include "coding.h" | ||
| 97 | #include "keyboard.h" | ||
| 98 | #include "frame.h" /* needed by termhooks.h */ | ||
| 99 | #include "termhooks.h" /* for FILE_NOTIFY_EVENT */ | ||
| 100 | |||
| 101 | #define DIRWATCH_SIGNATURE 0x01233210 | ||
| 102 | |||
| 103 | struct notification { | ||
| 104 | BYTE *buf; /* buffer for ReadDirectoryChangesW */ | ||
| 105 | OVERLAPPED *io_info; /* the OVERLAPPED structure for async I/O */ | ||
| 106 | BOOL subtree; /* whether to watch subdirectories */ | ||
| 107 | DWORD filter; /* bit mask for events to watch */ | ||
| 108 | char *watchee; /* the file we are interested in */ | ||
| 109 | HANDLE dir; /* handle to the watched directory */ | ||
| 110 | HANDLE thr; /* handle to the thread that watches */ | ||
| 111 | volatile int terminate; /* if non-zero, request for the thread to terminate */ | ||
| 112 | unsigned signature; | ||
| 113 | }; | ||
| 114 | |||
| 115 | /* Used for communicating notifications to the main thread. */ | ||
| 116 | volatile int notification_buffer_in_use; | ||
| 117 | BYTE file_notifications[16384]; | ||
| 118 | DWORD notifications_size; | ||
| 119 | void *notifications_desc; | ||
| 120 | |||
| 121 | static Lisp_Object Qfile_name, Qdirectory_name, Qattributes, Qsize; | ||
| 122 | static Lisp_Object Qlast_write_time, Qlast_access_time, Qcreation_time; | ||
| 123 | static Lisp_Object Qsecurity_desc, Qsubtree, watch_list; | ||
| 124 | |||
| 125 | /* Signal to the main thread that we have file notifications for it to | ||
| 126 | process. */ | ||
| 127 | static void | ||
| 128 | send_notifications (BYTE *info, DWORD info_size, void *desc, | ||
| 129 | volatile int *terminate) | ||
| 130 | { | ||
| 131 | int done = 0; | ||
| 132 | FRAME_PTR f = SELECTED_FRAME (); | ||
| 133 | |||
| 134 | /* A single buffer is used to communicate all notifications to the | ||
| 135 | main thread. Since both the main thread and several watcher | ||
| 136 | threads could be active at the same time, we use a critical area | ||
| 137 | and an "in-use" flag to synchronize them. A watcher thread can | ||
| 138 | only put its notifications in the buffer if it acquires the | ||
| 139 | critical area and finds the "in-use" flag reset. The main thread | ||
| 140 | resets the flag after it is done processing notifications. | ||
| 141 | |||
| 142 | FIXME: is there a better way of dealing with this? */ | ||
| 143 | while (!done && !*terminate) | ||
| 144 | { | ||
| 145 | enter_crit (); | ||
| 146 | if (!notification_buffer_in_use) | ||
| 147 | { | ||
| 148 | if (info_size) | ||
| 149 | memcpy (file_notifications, info, info_size); | ||
| 150 | notifications_size = info_size; | ||
| 151 | notifications_desc = desc; | ||
| 152 | /* If PostMessage fails, the message queue is full. If that | ||
| 153 | happens, the last thing they will worry about is file | ||
| 154 | notifications. So we effectively discard the | ||
| 155 | notification in that case. */ | ||
| 156 | if ((FRAME_TERMCAP_P (f) | ||
| 157 | /* We send the message to the main (a.k.a. "Lisp") | ||
| 158 | thread, where it will wake up MsgWaitForMultipleObjects | ||
| 159 | inside sys_select, causing it to report that there's | ||
| 160 | some keyboard input available. This will in turn cause | ||
| 161 | w32_console_read_socket to be called, which will pick | ||
| 162 | up the file notifications. */ | ||
| 163 | && PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0)) | ||
| 164 | || (FRAME_W32_P (f) | ||
| 165 | && PostMessage (FRAME_W32_WINDOW (f), | ||
| 166 | WM_EMACS_FILENOTIFY, 0, 0))) | ||
| 167 | notification_buffer_in_use = 1; | ||
| 168 | done = 1; | ||
| 169 | } | ||
| 170 | leave_crit (); | ||
| 171 | if (!done) | ||
| 172 | Sleep (5); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | /* An APC routine to cancel outstanding directory watch. Invoked by | ||
| 177 | the main thread via QueueUserAPC. This is needed because only the | ||
| 178 | thread that issued the ReadDirectoryChangesW call can call CancelIo | ||
| 179 | to cancel that. (CancelIoEx is only available since Vista, so we | ||
| 180 | cannot use it on XP.) */ | ||
| 181 | VOID CALLBACK | ||
| 182 | watch_end (ULONG_PTR arg) | ||
| 183 | { | ||
| 184 | HANDLE hdir = (HANDLE)arg; | ||
| 185 | |||
| 186 | if (hdir && hdir != INVALID_HANDLE_VALUE) | ||
| 187 | { | ||
| 188 | CancelIo (hdir); | ||
| 189 | CloseHandle (hdir); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | /* A completion routine (a.k.a. "APC function") for handling events | ||
| 194 | read by ReadDirectoryChangesW. Called by the OS when the thread | ||
| 195 | which issued the asynchronous ReadDirectoryChangesW call is in the | ||
| 196 | "alertable state", i.e. waiting inside SleepEx call. */ | ||
| 197 | VOID CALLBACK | ||
| 198 | watch_completion (DWORD status, DWORD bytes_ret, OVERLAPPED *io_info) | ||
| 199 | { | ||
| 200 | struct notification *dirwatch; | ||
| 201 | |||
| 202 | /* Who knows what happened? Perhaps the OVERLAPPED structure was | ||
| 203 | freed by someone already? In any case, we cannot do anything | ||
| 204 | with this request, so just punt and skip it. FIXME: should we | ||
| 205 | raise the 'terminate' flag in this case? */ | ||
| 206 | if (!io_info) | ||
| 207 | return; | ||
| 208 | |||
| 209 | /* We have a pointer to our dirwatch structure conveniently stashed | ||
| 210 | away in the hEvent member of the OVERLAPPED struct. According to | ||
| 211 | MSDN documentation of ReadDirectoryChangesW: "The hEvent member | ||
| 212 | of the OVERLAPPED structure is not used by the system, so you can | ||
| 213 | use it yourself." */ | ||
| 214 | dirwatch = (struct notification *)io_info->hEvent; | ||
| 215 | if (status == ERROR_OPERATION_ABORTED) | ||
| 216 | { | ||
| 217 | /* We've been called because the main thread told us to issue | ||
| 218 | CancelIo on the directory we watch, and watch_end did so. | ||
| 219 | The directory handle is already closed. We should clean up | ||
| 220 | and exit, signaling to the thread worker routine not to | ||
| 221 | issue another call to ReadDirectoryChangesW. Note that we | ||
| 222 | don't free the dirwatch object itself nor the memory consumed | ||
| 223 | by its buffers; this is done by the main thread in | ||
| 224 | remove_watch. Calling malloc/free from a thread other than | ||
| 225 | the main thread is a no-no. */ | ||
| 226 | dirwatch->dir = NULL; | ||
| 227 | dirwatch->terminate = 1; | ||
| 228 | } | ||
| 229 | else | ||
| 230 | { | ||
| 231 | /* Tell the main thread we have notifications for it. */ | ||
| 232 | send_notifications (dirwatch->buf, bytes_ret, dirwatch, | ||
| 233 | &dirwatch->terminate); | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | /* Worker routine for the watch thread. */ | ||
| 238 | static DWORD WINAPI | ||
| 239 | watch_worker (LPVOID arg) | ||
| 240 | { | ||
| 241 | struct notification *dirwatch = (struct notification *)arg; | ||
| 242 | |||
| 243 | do { | ||
| 244 | BOOL status; | ||
| 245 | DWORD sleep_result; | ||
| 246 | DWORD bytes_ret = 0; | ||
| 247 | |||
| 248 | if (dirwatch->dir) | ||
| 249 | { | ||
| 250 | status = ReadDirectoryChangesW (dirwatch->dir, dirwatch->buf, 16384, | ||
| 251 | dirwatch->subtree, dirwatch->filter, | ||
| 252 | &bytes_ret, | ||
| 253 | dirwatch->io_info, watch_completion); | ||
| 254 | if (!status) | ||
| 255 | { | ||
| 256 | DebPrint (("watch_worker, abnormal exit: %lu\n", GetLastError ())); | ||
| 257 | /* We cannot remove the dirwatch object from watch_list, | ||
| 258 | because we are in a separate thread. For the same | ||
| 259 | reason, we also cannot free memory consumed by the | ||
| 260 | buffers allocated for the dirwatch object. So we close | ||
| 261 | the directory handle, but do not free the object itself | ||
| 262 | or its buffers. We also don't touch the signature. | ||
| 263 | This way, remove_watch can still identify the object, | ||
| 264 | remove it, and free its memory. */ | ||
| 265 | CloseHandle (dirwatch->dir); | ||
| 266 | dirwatch->dir = NULL; | ||
| 267 | return 1; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | /* Sleep indefinitely until awoken by the I/O completion, which | ||
| 271 | could be either a change notification or a cancellation of the | ||
| 272 | watch. */ | ||
| 273 | sleep_result = SleepEx (INFINITE, TRUE); | ||
| 274 | } while (!dirwatch->terminate); | ||
| 275 | |||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | |||
| 279 | /* Launch a thread to watch changes to FILE in a directory open on | ||
| 280 | handle HDIR. */ | ||
| 281 | static struct notification * | ||
| 282 | start_watching (const char *file, HANDLE hdir, BOOL subdirs, DWORD flags) | ||
| 283 | { | ||
| 284 | struct notification *dirwatch = xzalloc (sizeof (struct notification)); | ||
| 285 | HANDLE thr; | ||
| 286 | |||
| 287 | dirwatch->signature = DIRWATCH_SIGNATURE; | ||
| 288 | dirwatch->buf = xmalloc (16384); | ||
| 289 | dirwatch->io_info = xzalloc (sizeof(OVERLAPPED)); | ||
| 290 | /* Stash a pointer to dirwatch structure for use by the completion | ||
| 291 | routine. According to MSDN documentation of ReadDirectoryChangesW: | ||
| 292 | "The hEvent member of the OVERLAPPED structure is not used by the | ||
| 293 | system, so you can use it yourself." */ | ||
| 294 | dirwatch->io_info->hEvent = dirwatch; | ||
| 295 | dirwatch->subtree = subdirs; | ||
| 296 | dirwatch->filter = flags; | ||
| 297 | dirwatch->watchee = xstrdup (file); | ||
| 298 | dirwatch->terminate = 0; | ||
| 299 | dirwatch->dir = hdir; | ||
| 300 | |||
| 301 | /* See w32proc.c where it calls CreateThread for the story behind | ||
| 302 | the 2nd and 5th argument in the call to CreateThread. */ | ||
| 303 | dirwatch->thr = CreateThread (NULL, 64 * 1024, watch_worker, (void *)dirwatch, | ||
| 304 | 0x00010000, NULL); | ||
| 305 | |||
| 306 | if (!dirwatch->thr) | ||
| 307 | { | ||
| 308 | xfree (dirwatch->buf); | ||
| 309 | xfree (dirwatch->io_info); | ||
| 310 | xfree (dirwatch->watchee); | ||
| 311 | xfree (dirwatch); | ||
| 312 | dirwatch = NULL; | ||
| 313 | } | ||
| 314 | return dirwatch; | ||
| 315 | } | ||
| 316 | |||
| 317 | /* Called from the main thread to start watching FILE in PARENT_DIR, | ||
| 318 | subject to FLAGS. If SUBDIRS is TRUE, watch the subdirectories of | ||
| 319 | PARENT_DIR as well. Value is a pointer to 'struct notification' | ||
| 320 | used by the thread that watches the changes. */ | ||
| 321 | static struct notification * | ||
| 322 | add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags) | ||
| 323 | { | ||
| 324 | HANDLE hdir; | ||
| 325 | struct notification *dirwatch = NULL; | ||
| 326 | |||
| 327 | if (!file || !*file) | ||
| 328 | return NULL; | ||
| 329 | |||
| 330 | hdir = CreateFile (parent_dir, | ||
| 331 | FILE_LIST_DIRECTORY, | ||
| 332 | /* FILE_SHARE_DELETE doesn't preclude other | ||
| 333 | processes from deleting files inside | ||
| 334 | parent_dir. */ | ||
| 335 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | ||
| 336 | NULL, OPEN_EXISTING, | ||
| 337 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, | ||
| 338 | NULL); | ||
| 339 | if (hdir == INVALID_HANDLE_VALUE) | ||
| 340 | return NULL; | ||
| 341 | |||
| 342 | if ((dirwatch = start_watching (file, hdir, subdirs, flags)) == NULL) | ||
| 343 | CloseHandle (hdir); | ||
| 344 | |||
| 345 | return dirwatch; | ||
| 346 | } | ||
| 347 | |||
| 348 | /* Stop watching a directory specified by a pointer to its dirwatch object. */ | ||
| 349 | static int | ||
| 350 | remove_watch (struct notification *dirwatch) | ||
| 351 | { | ||
| 352 | if (dirwatch && dirwatch->signature == DIRWATCH_SIGNATURE) | ||
| 353 | { | ||
| 354 | int i; | ||
| 355 | BOOL status; | ||
| 356 | DWORD exit_code, err; | ||
| 357 | |||
| 358 | /* Only the thread that issued the outstanding I/O call can call | ||
| 359 | CancelIo on it. (CancelIoEx is available only since Vista.) | ||
| 360 | So we need to queue an APC for the worker thread telling it | ||
| 361 | to terminate. */ | ||
| 362 | if (!QueueUserAPC (watch_end, dirwatch->thr, (ULONG_PTR)dirwatch->dir)) | ||
| 363 | DebPrint (("QueueUserAPC failed (%lu)!\n", GetLastError ())); | ||
| 364 | /* We also set the terminate flag, for when the thread is | ||
| 365 | waiting on the critical section that never gets acquired. | ||
| 366 | FIXME: is there a cleaner method? Using SleepEx there is a | ||
| 367 | no-no, as that will lead to recursive APC invocations and | ||
| 368 | stack overflow. */ | ||
| 369 | dirwatch->terminate = 1; | ||
| 370 | /* Wait for the thread to exit. FIXME: is there a better method | ||
| 371 | that is not overly complex? */ | ||
| 372 | for (i = 0; i < 50; i++) | ||
| 373 | { | ||
| 374 | if (!((status = GetExitCodeThread (dirwatch->thr, &exit_code)) | ||
| 375 | && exit_code == STILL_ACTIVE)) | ||
| 376 | break; | ||
| 377 | Sleep (10); | ||
| 378 | } | ||
| 379 | if ((status == FALSE && (err = GetLastError ()) == ERROR_INVALID_HANDLE) | ||
| 380 | || exit_code == STILL_ACTIVE) | ||
| 381 | { | ||
| 382 | if (!(status == FALSE && err == ERROR_INVALID_HANDLE)) | ||
| 383 | { | ||
| 384 | TerminateThread (dirwatch->thr, 0); | ||
| 385 | if (dirwatch->dir) | ||
| 386 | CloseHandle (dirwatch->dir); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | /* Clean up. */ | ||
| 391 | if (dirwatch->thr) | ||
| 392 | { | ||
| 393 | CloseHandle (dirwatch->thr); | ||
| 394 | dirwatch->thr = NULL; | ||
| 395 | } | ||
| 396 | xfree (dirwatch->buf); | ||
| 397 | xfree (dirwatch->io_info); | ||
| 398 | xfree (dirwatch->watchee); | ||
| 399 | xfree (dirwatch); | ||
| 400 | |||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | else | ||
| 404 | { | ||
| 405 | DebPrint (("Unknown dirwatch object!\n")); | ||
| 406 | return -1; | ||
| 407 | } | ||
| 408 | } | ||
| 409 | |||
| 410 | static DWORD | ||
| 411 | filter_list_to_flags (Lisp_Object filter_list) | ||
| 412 | { | ||
| 413 | DWORD flags = 0; | ||
| 414 | |||
| 415 | if (NILP (filter_list)) | ||
| 416 | return flags; | ||
| 417 | |||
| 418 | if (!NILP (Fmember (Qfile_name, filter_list))) | ||
| 419 | flags |= FILE_NOTIFY_CHANGE_FILE_NAME; | ||
| 420 | if (!NILP (Fmember (Qdirectory_name, filter_list))) | ||
| 421 | flags |= FILE_NOTIFY_CHANGE_DIR_NAME; | ||
| 422 | if (!NILP (Fmember (Qattributes, filter_list))) | ||
| 423 | flags |= FILE_NOTIFY_CHANGE_ATTRIBUTES; | ||
| 424 | if (!NILP (Fmember (Qsize, filter_list))) | ||
| 425 | flags |= FILE_NOTIFY_CHANGE_SIZE; | ||
| 426 | if (!NILP (Fmember (Qlast_write_time, filter_list))) | ||
| 427 | flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; | ||
| 428 | if (!NILP (Fmember (Qlast_access_time, filter_list))) | ||
| 429 | flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; | ||
| 430 | if (!NILP (Fmember (Qcreation_time, filter_list))) | ||
| 431 | flags |= FILE_NOTIFY_CHANGE_CREATION; | ||
| 432 | if (!NILP (Fmember (Qsecurity_desc, filter_list))) | ||
| 433 | flags |= FILE_NOTIFY_CHANGE_SECURITY; | ||
| 434 | |||
| 435 | return flags; | ||
| 436 | } | ||
| 437 | |||
| 438 | DEFUN ("w32notify-add-watch", Fw32notify_add_watch, | ||
| 439 | Sw32notify_add_watch, 3, 3, 0, | ||
| 440 | doc: /* Add a watch for filesystem events pertaining to FILE. | ||
| 441 | |||
| 442 | This arranges for filesystem events pertaining to FILE to be reported | ||
| 443 | to Emacs. Use `w32notify-rm-watch' to cancel the watch. | ||
| 444 | |||
| 445 | Value is a descriptor for the added watch. If the file cannot be | ||
| 446 | watched for some reason, this function signals a `file-error' error. | ||
| 447 | |||
| 448 | FILTER is a list of conditions for reporting an event. It can include | ||
| 449 | the following symbols: | ||
| 450 | |||
| 451 | 'file-name' -- report file creation, deletion, or renaming | ||
| 452 | 'directory-name' -- report directory creation, deletion, or renaming | ||
| 453 | 'attributes' -- report changes in attributes | ||
| 454 | 'size' -- report changes in file-size | ||
| 455 | 'last-write-time' -- report changes in last-write time | ||
| 456 | 'last-access-time' -- report changes in last-access time | ||
| 457 | 'creation-time' -- report changes in creation time | ||
| 458 | 'security-desc' -- report changes in security descriptor | ||
| 459 | |||
| 460 | If FILE is a directory, and FILTER includes 'subtree', then all the | ||
| 461 | subdirectories will also be watched and changes in them reported. | ||
| 462 | |||
| 463 | When any event happens that satisfies the conditions specified by | ||
| 464 | FILTER, Emacs will call the CALLBACK function passing it a single | ||
| 465 | argument EVENT, which is of the form | ||
| 466 | |||
| 467 | (DESCRIPTOR ACTION FILE) | ||
| 468 | |||
| 469 | DESCRIPTOR is the same object as the one returned by this function. | ||
| 470 | ACTION is the description of the event. It could be any one of the | ||
| 471 | following: | ||
| 472 | |||
| 473 | 'added' -- FILE was added | ||
| 474 | 'removed' -- FILE was deleted | ||
| 475 | 'modified' -- FILE's contents or its attributes were modified | ||
| 476 | 'renamed-from' -- a file was renamed whose old name was FILE | ||
| 477 | 'renamed-to' -- a file was renamed and its new name is FILE | ||
| 478 | |||
| 479 | FILE is the name of the file whose event is being reported. | ||
| 480 | |||
| 481 | Note that some networked filesystems, such as Samba-mounted Unix | ||
| 482 | volumes, might not send notifications about file changes. In these | ||
| 483 | cases, this function will return a valid descriptor, but notifications | ||
| 484 | will never come in. Volumes shared from remote Windows machines do | ||
| 485 | generate notifications correctly, though. */) | ||
| 486 | (Lisp_Object file, Lisp_Object filter, Lisp_Object callback) | ||
| 487 | { | ||
| 488 | Lisp_Object encoded_file, watch_object, watch_descriptor; | ||
| 489 | char parent_dir[MAX_PATH], *basename; | ||
| 490 | size_t fn_len; | ||
| 491 | DWORD flags; | ||
| 492 | BOOL subdirs = FALSE; | ||
| 493 | struct notification *dirwatch = NULL; | ||
| 494 | Lisp_Object lisp_errstr; | ||
| 495 | char *errstr; | ||
| 496 | |||
| 497 | CHECK_LIST (filter); | ||
| 498 | |||
| 499 | /* The underlying features are available only since XP. */ | ||
| 500 | if (os_subtype == OS_9X | ||
| 501 | || (w32_major_version == 5 && w32_major_version < 1)) | ||
| 502 | { | ||
| 503 | errno = ENOSYS; | ||
| 504 | report_file_error ("Watching filesystem events is not supported", | ||
| 505 | Qnil); | ||
| 506 | } | ||
| 507 | |||
| 508 | /* We need a full absolute file name of FILE, and we need to remove | ||
| 509 | any trailing slashes from it, so that GetFullPathName below gets | ||
| 510 | the basename part correctly. */ | ||
| 511 | file = Fdirectory_file_name (Fexpand_file_name (file, Qnil)); | ||
| 512 | encoded_file = ENCODE_FILE (file); | ||
| 513 | |||
| 514 | fn_len = GetFullPathName (SDATA (encoded_file), MAX_PATH, parent_dir, | ||
| 515 | &basename); | ||
| 516 | if (!fn_len) | ||
| 517 | { | ||
| 518 | errstr = w32_strerror (0); | ||
| 519 | errno = EINVAL; | ||
| 520 | if (!NILP (Vlocale_coding_system)) | ||
| 521 | lisp_errstr | ||
| 522 | = code_convert_string_norecord (build_unibyte_string (errstr), | ||
| 523 | Vlocale_coding_system, 0); | ||
| 524 | else | ||
| 525 | lisp_errstr = build_string (errstr); | ||
| 526 | report_file_error ("GetFullPathName failed", | ||
| 527 | Fcons (lisp_errstr, Fcons (file, Qnil))); | ||
| 528 | } | ||
| 529 | /* We need the parent directory without the slash that follows it. | ||
| 530 | If BASENAME is NULL, the argument was the root directory on its | ||
| 531 | drive. */ | ||
| 532 | if (basename) | ||
| 533 | basename[-1] = '\0'; | ||
| 534 | else | ||
| 535 | subdirs = TRUE; | ||
| 536 | |||
| 537 | if (!NILP (Fmember (Qsubtree, filter))) | ||
| 538 | subdirs = TRUE; | ||
| 539 | |||
| 540 | flags = filter_list_to_flags (filter); | ||
| 541 | |||
| 542 | dirwatch = add_watch (parent_dir, basename, subdirs, flags); | ||
| 543 | if (!dirwatch) | ||
| 544 | { | ||
| 545 | DWORD err = GetLastError (); | ||
| 546 | |||
| 547 | errno = EINVAL; | ||
| 548 | if (err) | ||
| 549 | { | ||
| 550 | errstr = w32_strerror (err); | ||
| 551 | if (!NILP (Vlocale_coding_system)) | ||
| 552 | lisp_errstr | ||
| 553 | = code_convert_string_norecord (build_unibyte_string (errstr), | ||
| 554 | Vlocale_coding_system, 0); | ||
| 555 | else | ||
| 556 | lisp_errstr = build_string (errstr); | ||
| 557 | report_file_error ("Cannot watch file", | ||
| 558 | Fcons (lisp_errstr, Fcons (file, Qnil))); | ||
| 559 | } | ||
| 560 | else | ||
| 561 | report_file_error ("Cannot watch file", Fcons (file, Qnil)); | ||
| 562 | } | ||
| 563 | /* Store watch object in watch list. */ | ||
| 564 | watch_descriptor = XIL ((EMACS_INT)dirwatch); | ||
| 565 | watch_object = Fcons (watch_descriptor, callback); | ||
| 566 | watch_list = Fcons (watch_object, watch_list); | ||
| 567 | |||
| 568 | return watch_descriptor; | ||
| 569 | } | ||
| 570 | |||
| 571 | DEFUN ("w32notify-rm-watch", Fw32notify_rm_watch, | ||
| 572 | Sw32notify_rm_watch, 1, 1, 0, | ||
| 573 | doc: /* Remove an existing watch specified by its WATCH-DESCRIPTOR. | ||
| 574 | |||
| 575 | WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. */) | ||
| 576 | (Lisp_Object watch_descriptor) | ||
| 577 | { | ||
| 578 | Lisp_Object watch_object; | ||
| 579 | struct notification *dirwatch; | ||
| 580 | int status = -1; | ||
| 581 | |||
| 582 | /* Remove the watch object from watch list. Do this before freeing | ||
| 583 | the object, do that even if we fail to free it, watch_list is | ||
| 584 | kept free of junk. */ | ||
| 585 | watch_object = Fassoc (watch_descriptor, watch_list); | ||
| 586 | if (!NILP (watch_object)) | ||
| 587 | { | ||
| 588 | watch_list = Fdelete (watch_object, watch_list); | ||
| 589 | dirwatch = (struct notification *)XLI (watch_descriptor); | ||
| 590 | if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))) | ||
| 591 | status = remove_watch (dirwatch); | ||
| 592 | } | ||
| 593 | |||
| 594 | if (status == -1) | ||
| 595 | report_file_error ("Invalid watch descriptor", Fcons (watch_descriptor, | ||
| 596 | Qnil)); | ||
| 597 | |||
| 598 | return Qnil; | ||
| 599 | } | ||
| 600 | |||
| 601 | Lisp_Object | ||
| 602 | w32_get_watch_object (void *desc) | ||
| 603 | { | ||
| 604 | Lisp_Object descriptor = XIL ((EMACS_INT)desc); | ||
| 605 | |||
| 606 | /* This is called from the input queue handling code, inside a | ||
| 607 | critical section, so we cannot possibly QUIT if watch_list is not | ||
| 608 | in the right condition. */ | ||
| 609 | return NILP (watch_list) ? Qnil : assoc_no_quit (descriptor, watch_list); | ||
| 610 | } | ||
| 611 | |||
| 612 | void | ||
| 613 | globals_of_w32notify (void) | ||
| 614 | { | ||
| 615 | watch_list = Qnil; | ||
| 616 | } | ||
| 617 | |||
| 618 | void | ||
| 619 | syms_of_w32notify (void) | ||
| 620 | { | ||
| 621 | DEFSYM (Qfile_name, "file-name"); | ||
| 622 | DEFSYM (Qdirectory_name, "directory-name"); | ||
| 623 | DEFSYM (Qattributes, "attributes"); | ||
| 624 | DEFSYM (Qsize, "size"); | ||
| 625 | DEFSYM (Qlast_write_time, "last-write-time"); | ||
| 626 | DEFSYM (Qlast_access_time, "last-access-time"); | ||
| 627 | DEFSYM (Qcreation_time, "creation-time"); | ||
| 628 | DEFSYM (Qsecurity_desc, "security-desc"); | ||
| 629 | DEFSYM (Qsubtree, "subtree"); | ||
| 630 | |||
| 631 | defsubr (&Sw32notify_add_watch); | ||
| 632 | defsubr (&Sw32notify_rm_watch); | ||
| 633 | |||
| 634 | staticpro (&watch_list); | ||
| 635 | |||
| 636 | Fprovide (intern_c_string ("w32notify"), Qnil); | ||
| 637 | } | ||
diff --git a/src/w32proc.c b/src/w32proc.c index d888200c556..3f3e97c77a0 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Process support for GNU Emacs on the Microsoft Windows API. | 1 | /* Process support for GNU Emacs on the Microsoft Windows API. |
| 2 | Copyright (C) 1992, 1995, 1999-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1992, 1995, 1999-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -800,9 +800,51 @@ new_child (void) | |||
| 800 | DWORD id; | 800 | DWORD id; |
| 801 | 801 | ||
| 802 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | 802 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) |
| 803 | if (!CHILD_ACTIVE (cp)) | 803 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) |
| 804 | goto Initialize; | 804 | goto Initialize; |
| 805 | if (child_proc_count == MAX_CHILDREN) | 805 | if (child_proc_count == MAX_CHILDREN) |
| 806 | { | ||
| 807 | int i = 0; | ||
| 808 | child_process *dead_cp = NULL; | ||
| 809 | |||
| 810 | DebPrint (("new_child: No vacant slots, looking for dead processes\n")); | ||
| 811 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | ||
| 812 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess) | ||
| 813 | { | ||
| 814 | DWORD status = 0; | ||
| 815 | |||
| 816 | if (!GetExitCodeProcess (cp->procinfo.hProcess, &status)) | ||
| 817 | { | ||
| 818 | DebPrint (("new_child.GetExitCodeProcess: error %lu for PID %lu\n", | ||
| 819 | GetLastError (), cp->procinfo.dwProcessId)); | ||
| 820 | status = STILL_ACTIVE; | ||
| 821 | } | ||
| 822 | if (status != STILL_ACTIVE | ||
| 823 | || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0) | ||
| 824 | { | ||
| 825 | DebPrint (("new_child: Freeing slot of dead process %d, fd %d\n", | ||
| 826 | cp->procinfo.dwProcessId, cp->fd)); | ||
| 827 | CloseHandle (cp->procinfo.hProcess); | ||
| 828 | cp->procinfo.hProcess = NULL; | ||
| 829 | CloseHandle (cp->procinfo.hThread); | ||
| 830 | cp->procinfo.hThread = NULL; | ||
| 831 | /* Free up to 2 dead slots at a time, so that if we | ||
| 832 | have a lot of them, they will eventually all be | ||
| 833 | freed when the tornado ends. */ | ||
| 834 | if (i == 0) | ||
| 835 | dead_cp = cp; | ||
| 836 | else | ||
| 837 | break; | ||
| 838 | i++; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | if (dead_cp) | ||
| 842 | { | ||
| 843 | cp = dead_cp; | ||
| 844 | goto Initialize; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | if (child_proc_count == MAX_CHILDREN) | ||
| 806 | return NULL; | 848 | return NULL; |
| 807 | cp = &child_procs[child_proc_count++]; | 849 | cp = &child_procs[child_proc_count++]; |
| 808 | 850 | ||
| @@ -812,6 +854,8 @@ new_child (void) | |||
| 812 | cp->pid = -1; | 854 | cp->pid = -1; |
| 813 | cp->procinfo.hProcess = NULL; | 855 | cp->procinfo.hProcess = NULL; |
| 814 | cp->status = STATUS_READ_ERROR; | 856 | cp->status = STATUS_READ_ERROR; |
| 857 | cp->input_file = NULL; | ||
| 858 | cp->pending_deletion = 0; | ||
| 815 | 859 | ||
| 816 | /* use manual reset event so that select() will function properly */ | 860 | /* use manual reset event so that select() will function properly */ |
| 817 | cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL); | 861 | cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL); |
| @@ -857,9 +901,24 @@ delete_child (child_process *cp) | |||
| 857 | if (fd_info[i].cp == cp) | 901 | if (fd_info[i].cp == cp) |
| 858 | emacs_abort (); | 902 | emacs_abort (); |
| 859 | 903 | ||
| 860 | if (!CHILD_ACTIVE (cp)) | 904 | if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) |
| 861 | return; | 905 | return; |
| 862 | 906 | ||
| 907 | /* Delete the child's temporary input file, if any, that is pending | ||
| 908 | deletion. */ | ||
| 909 | if (cp->input_file) | ||
| 910 | { | ||
| 911 | if (cp->pending_deletion) | ||
| 912 | { | ||
| 913 | if (unlink (cp->input_file)) | ||
| 914 | DebPrint (("delete_child.unlink (%s) failed, errno: %d\n", | ||
| 915 | cp->input_file, errno)); | ||
| 916 | cp->pending_deletion = 0; | ||
| 917 | } | ||
| 918 | xfree (cp->input_file); | ||
| 919 | cp->input_file = NULL; | ||
| 920 | } | ||
| 921 | |||
| 863 | /* reap thread if necessary */ | 922 | /* reap thread if necessary */ |
| 864 | if (cp->thrd) | 923 | if (cp->thrd) |
| 865 | { | 924 | { |
| @@ -901,7 +960,8 @@ delete_child (child_process *cp) | |||
| 901 | if (cp == child_procs + child_proc_count - 1) | 960 | if (cp == child_procs + child_proc_count - 1) |
| 902 | { | 961 | { |
| 903 | for (i = child_proc_count-1; i >= 0; i--) | 962 | for (i = child_proc_count-1; i >= 0; i--) |
| 904 | if (CHILD_ACTIVE (&child_procs[i])) | 963 | if (CHILD_ACTIVE (&child_procs[i]) |
| 964 | || child_procs[i].procinfo.hProcess != NULL) | ||
| 905 | { | 965 | { |
| 906 | child_proc_count = i + 1; | 966 | child_proc_count = i + 1; |
| 907 | break; | 967 | break; |
| @@ -918,7 +978,8 @@ find_child_pid (DWORD pid) | |||
| 918 | child_process *cp; | 978 | child_process *cp; |
| 919 | 979 | ||
| 920 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | 980 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) |
| 921 | if (CHILD_ACTIVE (cp) && pid == cp->pid) | 981 | if ((CHILD_ACTIVE (cp) || cp->procinfo.hProcess != NULL) |
| 982 | && pid == cp->pid) | ||
| 922 | return cp; | 983 | return cp; |
| 923 | return NULL; | 984 | return NULL; |
| 924 | } | 985 | } |
| @@ -946,17 +1007,23 @@ reader_thread (void *arg) | |||
| 946 | { | 1007 | { |
| 947 | int rc; | 1008 | int rc; |
| 948 | 1009 | ||
| 949 | if (fd_info[cp->fd].flags & FILE_LISTEN) | 1010 | if (cp->fd >= 0 && fd_info[cp->fd].flags & FILE_LISTEN) |
| 950 | rc = _sys_wait_accept (cp->fd); | 1011 | rc = _sys_wait_accept (cp->fd); |
| 951 | else | 1012 | else |
| 952 | rc = _sys_read_ahead (cp->fd); | 1013 | rc = _sys_read_ahead (cp->fd); |
| 953 | 1014 | ||
| 1015 | /* Don't bother waiting for the event if we already have been | ||
| 1016 | told to exit by delete_child. */ | ||
| 1017 | if (cp->status == STATUS_READ_ERROR || !cp->char_avail) | ||
| 1018 | break; | ||
| 1019 | |||
| 954 | /* The name char_avail is a misnomer - it really just means the | 1020 | /* The name char_avail is a misnomer - it really just means the |
| 955 | read-ahead has completed, whether successfully or not. */ | 1021 | read-ahead has completed, whether successfully or not. */ |
| 956 | if (!SetEvent (cp->char_avail)) | 1022 | if (!SetEvent (cp->char_avail)) |
| 957 | { | 1023 | { |
| 958 | DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n", | 1024 | DebPrint (("reader_thread.SetEvent(0x%x) failed with %lu for fd %ld (PID %d)\n", |
| 959 | GetLastError (), cp->fd)); | 1025 | (DWORD_PTR)cp->char_avail, GetLastError (), |
| 1026 | cp->fd, cp->pid)); | ||
| 960 | return 1; | 1027 | return 1; |
| 961 | } | 1028 | } |
| 962 | 1029 | ||
| @@ -967,6 +1034,11 @@ reader_thread (void *arg) | |||
| 967 | if (rc == STATUS_READ_FAILED) | 1034 | if (rc == STATUS_READ_FAILED) |
| 968 | break; | 1035 | break; |
| 969 | 1036 | ||
| 1037 | /* Don't bother waiting for the acknowledge if we already have | ||
| 1038 | been told to exit by delete_child. */ | ||
| 1039 | if (cp->status == STATUS_READ_ERROR || !cp->char_consumed) | ||
| 1040 | break; | ||
| 1041 | |||
| 970 | /* Wait until our input is acknowledged before reading again */ | 1042 | /* Wait until our input is acknowledged before reading again */ |
| 971 | if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) | 1043 | if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) |
| 972 | { | 1044 | { |
| @@ -974,6 +1046,10 @@ reader_thread (void *arg) | |||
| 974 | "%lu for fd %ld\n", GetLastError (), cp->fd)); | 1046 | "%lu for fd %ld\n", GetLastError (), cp->fd)); |
| 975 | break; | 1047 | break; |
| 976 | } | 1048 | } |
| 1049 | /* delete_child sets status to STATUS_READ_ERROR when it wants | ||
| 1050 | us to exit. */ | ||
| 1051 | if (cp->status == STATUS_READ_ERROR) | ||
| 1052 | break; | ||
| 977 | } | 1053 | } |
| 978 | return 0; | 1054 | return 0; |
| 979 | } | 1055 | } |
| @@ -1056,11 +1132,11 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app, | |||
| 1056 | This way the select emulator knows how to match file handles with | 1132 | This way the select emulator knows how to match file handles with |
| 1057 | entries in child_procs. */ | 1133 | entries in child_procs. */ |
| 1058 | void | 1134 | void |
| 1059 | register_child (int pid, int fd) | 1135 | register_child (pid_t pid, int fd) |
| 1060 | { | 1136 | { |
| 1061 | child_process *cp; | 1137 | child_process *cp; |
| 1062 | 1138 | ||
| 1063 | cp = find_child_pid (pid); | 1139 | cp = find_child_pid ((DWORD)pid); |
| 1064 | if (cp == NULL) | 1140 | if (cp == NULL) |
| 1065 | { | 1141 | { |
| 1066 | DebPrint (("register_child unable to find pid %lu\n", pid)); | 1142 | DebPrint (("register_child unable to find pid %lu\n", pid)); |
| @@ -1087,10 +1163,46 @@ register_child (int pid, int fd) | |||
| 1087 | fd_info[fd].cp = cp; | 1163 | fd_info[fd].cp = cp; |
| 1088 | } | 1164 | } |
| 1089 | 1165 | ||
| 1090 | /* When a process dies its pipe will break so the reader thread will | 1166 | /* Record INFILE as an input file for process PID. */ |
| 1091 | signal failure to the select emulator. | 1167 | void |
| 1092 | The select emulator then calls this routine to clean up. | 1168 | record_infile (pid_t pid, char *infile) |
| 1093 | Since the thread signaled failure we can assume it is exiting. */ | 1169 | { |
| 1170 | child_process *cp; | ||
| 1171 | |||
| 1172 | /* INFILE should never be NULL, since xstrdup would have signaled | ||
| 1173 | memory full condition in that case, see callproc.c where this | ||
| 1174 | function is called. */ | ||
| 1175 | eassert (infile); | ||
| 1176 | |||
| 1177 | cp = find_child_pid ((DWORD)pid); | ||
| 1178 | if (cp == NULL) | ||
| 1179 | { | ||
| 1180 | DebPrint (("record_infile is unable to find pid %lu\n", pid)); | ||
| 1181 | return; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | cp->input_file = infile; | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | /* Mark the input file INFILE of the corresponding subprocess as | ||
| 1188 | temporary, to be deleted when the subprocess exits. */ | ||
| 1189 | void | ||
| 1190 | record_pending_deletion (char *infile) | ||
| 1191 | { | ||
| 1192 | child_process *cp; | ||
| 1193 | |||
| 1194 | eassert (infile); | ||
| 1195 | |||
| 1196 | for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) | ||
| 1197 | if (CHILD_ACTIVE (cp) | ||
| 1198 | && cp->input_file && xstrcasecmp (cp->input_file, infile) == 0) | ||
| 1199 | { | ||
| 1200 | cp->pending_deletion = 1; | ||
| 1201 | break; | ||
| 1202 | } | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | /* Called from waitpid when a process exits. */ | ||
| 1094 | static void | 1206 | static void |
| 1095 | reap_subprocess (child_process *cp) | 1207 | reap_subprocess (child_process *cp) |
| 1096 | { | 1208 | { |
| @@ -1100,7 +1212,7 @@ reap_subprocess (child_process *cp) | |||
| 1100 | #ifdef FULL_DEBUG | 1212 | #ifdef FULL_DEBUG |
| 1101 | /* Process should have already died before we are called. */ | 1213 | /* Process should have already died before we are called. */ |
| 1102 | if (WaitForSingleObject (cp->procinfo.hProcess, 0) != WAIT_OBJECT_0) | 1214 | if (WaitForSingleObject (cp->procinfo.hProcess, 0) != WAIT_OBJECT_0) |
| 1103 | DebPrint (("reap_subprocess: child fpr fd %d has not died yet!", cp->fd)); | 1215 | DebPrint (("reap_subprocess: child for fd %d has not died yet!", cp->fd)); |
| 1104 | #endif | 1216 | #endif |
| 1105 | CloseHandle (cp->procinfo.hProcess); | 1217 | CloseHandle (cp->procinfo.hProcess); |
| 1106 | cp->procinfo.hProcess = NULL; | 1218 | cp->procinfo.hProcess = NULL; |
| @@ -1108,11 +1220,11 @@ reap_subprocess (child_process *cp) | |||
| 1108 | cp->procinfo.hThread = NULL; | 1220 | cp->procinfo.hThread = NULL; |
| 1109 | } | 1221 | } |
| 1110 | 1222 | ||
| 1111 | /* For asynchronous children, the child_proc resources will be freed | 1223 | /* If cp->fd was not closed yet, we might be still reading the |
| 1112 | when the last pipe read descriptor is closed; for synchronous | 1224 | process output, so don't free its resources just yet. The call |
| 1113 | children, we must explicitly free the resources now because | 1225 | to delete_child on behalf of this subprocess will be made by |
| 1114 | register_child has not been called. */ | 1226 | sys_read when the subprocess output is fully read. */ |
| 1115 | if (cp->fd == -1) | 1227 | if (cp->fd < 0) |
| 1116 | delete_child (cp); | 1228 | delete_child (cp); |
| 1117 | } | 1229 | } |
| 1118 | 1230 | ||
| @@ -1468,11 +1580,10 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1468 | Lisp_Object program, full; | 1580 | Lisp_Object program, full; |
| 1469 | char *cmdline, *env, *parg, **targ; | 1581 | char *cmdline, *env, *parg, **targ; |
| 1470 | int arglen, numenv; | 1582 | int arglen, numenv; |
| 1471 | int pid; | 1583 | pid_t pid; |
| 1472 | child_process *cp; | 1584 | child_process *cp; |
| 1473 | int is_dos_app, is_cygnus_app, is_gui_app; | 1585 | int is_dos_app, is_cygnus_app, is_gui_app; |
| 1474 | int do_quoting = 0; | 1586 | int do_quoting = 0; |
| 1475 | char escape_char; | ||
| 1476 | /* We pass our process ID to our children by setting up an environment | 1587 | /* We pass our process ID to our children by setting up an environment |
| 1477 | variable in their environment. */ | 1588 | variable in their environment. */ |
| 1478 | char ppid_env_var_buffer[64]; | 1589 | char ppid_env_var_buffer[64]; |
| @@ -1485,6 +1596,8 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) | |||
| 1485 | Some extra whitespace characters need quoting in Cygwin programs, | 1596 | Some extra whitespace characters need quoting in Cygwin programs, |
| 1486 | so this list is conditionally modified below. */ | 1597 | so this list is conditionally modified below. */ |
| 1487 | char *sepchars = " \t*?"; | 1598 | char *sepchars = " \t*?"; |
| 1599 | /* This is for native w32 apps; modified below for Cygwin apps. */ | ||
| 1600 | char escape_char = '\\'; | ||
| 1488 | 1601 | ||
| 1489 | /* We don't care about the other modes */ | 1602 | /* We don't care about the other modes */ |
| 1490 | if (mode != _P_NOWAIT) | 1603 | if (mode != _P_NOWAIT) |
| @@ -1857,7 +1970,7 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 1857 | } | 1970 | } |
| 1858 | else | 1971 | else |
| 1859 | { | 1972 | { |
| 1860 | /* Child process and socket input */ | 1973 | /* Child process and socket/comm port input. */ |
| 1861 | cp = fd_info[i].cp; | 1974 | cp = fd_info[i].cp; |
| 1862 | if (cp) | 1975 | if (cp) |
| 1863 | { | 1976 | { |
| @@ -1870,7 +1983,7 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 1870 | /* Wake up the reader thread for this process */ | 1983 | /* Wake up the reader thread for this process */ |
| 1871 | cp->status = STATUS_READ_READY; | 1984 | cp->status = STATUS_READ_READY; |
| 1872 | if (!SetEvent (cp->char_consumed)) | 1985 | if (!SetEvent (cp->char_consumed)) |
| 1873 | DebPrint (("nt_select.SetEvent failed with " | 1986 | DebPrint (("sys_select.SetEvent failed with " |
| 1874 | "%lu for fd %ld\n", GetLastError (), i)); | 1987 | "%lu for fd %ld\n", GetLastError (), i)); |
| 1875 | } | 1988 | } |
| 1876 | 1989 | ||
| @@ -1938,7 +2051,7 @@ count_children: | |||
| 1938 | /* Some child_procs might be sockets; ignore them. Also some | 2051 | /* Some child_procs might be sockets; ignore them. Also some |
| 1939 | children may have died already, but we haven't finished reading | 2052 | children may have died already, but we haven't finished reading |
| 1940 | the process output; ignore them too. */ | 2053 | the process output; ignore them too. */ |
| 1941 | if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess | 2054 | if ((CHILD_ACTIVE (cp) && cp->procinfo.hProcess) |
| 1942 | && (cp->fd < 0 | 2055 | && (cp->fd < 0 |
| 1943 | || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 | 2056 | || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0 |
| 1944 | || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) | 2057 | || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) |
| @@ -2018,7 +2131,24 @@ count_children: | |||
| 2018 | (*) Note that MsgWaitForMultipleObjects above is an | 2131 | (*) Note that MsgWaitForMultipleObjects above is an |
| 2019 | internal dispatch point for messages that are sent to | 2132 | internal dispatch point for messages that are sent to |
| 2020 | windows created by this thread. */ | 2133 | windows created by this thread. */ |
| 2021 | drain_message_queue (); | 2134 | if (drain_message_queue () |
| 2135 | /* If drain_message_queue returns non-zero, that means | ||
| 2136 | we received a WM_EMACS_FILENOTIFY message. If this | ||
| 2137 | is a TTY frame, we must signal the caller that keyboard | ||
| 2138 | input is available, so that w32_console_read_socket | ||
| 2139 | will be called to pick up the notifications. If we | ||
| 2140 | don't do that, file notifications will only work when | ||
| 2141 | the Emacs TTY frame has focus. */ | ||
| 2142 | && FRAME_TERMCAP_P (SELECTED_FRAME ()) | ||
| 2143 | /* they asked for stdin reads */ | ||
| 2144 | && FD_ISSET (0, &orfds) | ||
| 2145 | /* the stdin handle is valid */ | ||
| 2146 | && keyboard_handle) | ||
| 2147 | { | ||
| 2148 | FD_SET (0, rfds); | ||
| 2149 | if (nr == 0) | ||
| 2150 | nr = 1; | ||
| 2151 | } | ||
| 2022 | } | 2152 | } |
| 2023 | else if (active >= nh) | 2153 | else if (active >= nh) |
| 2024 | { | 2154 | { |
| @@ -2115,7 +2245,7 @@ find_child_console (HWND hwnd, LPARAM arg) | |||
| 2115 | 2245 | ||
| 2116 | /* Emulate 'kill', but only for other processes. */ | 2246 | /* Emulate 'kill', but only for other processes. */ |
| 2117 | int | 2247 | int |
| 2118 | sys_kill (int pid, int sig) | 2248 | sys_kill (pid_t pid, int sig) |
| 2119 | { | 2249 | { |
| 2120 | child_process *cp; | 2250 | child_process *cp; |
| 2121 | HANDLE proc_hand; | 2251 | HANDLE proc_hand; |
| @@ -2471,8 +2601,9 @@ All path elements in FILENAME are converted to their short names. */) | |||
| 2471 | if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname, MAX_PATH) == 0) | 2601 | if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname, MAX_PATH) == 0) |
| 2472 | return Qnil; | 2602 | return Qnil; |
| 2473 | 2603 | ||
| 2474 | dostounix_filename (shortname); | 2604 | dostounix_filename (shortname, 0); |
| 2475 | 2605 | ||
| 2606 | /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */ | ||
| 2476 | return build_string (shortname); | 2607 | return build_string (shortname); |
| 2477 | } | 2608 | } |
| 2478 | 2609 | ||
| @@ -2499,7 +2630,7 @@ All path elements in FILENAME are converted to their long names. */) | |||
| 2499 | if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, MAX_PATH)) | 2630 | if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, MAX_PATH)) |
| 2500 | return Qnil; | 2631 | return Qnil; |
| 2501 | 2632 | ||
| 2502 | dostounix_filename (longname); | 2633 | dostounix_filename (longname, 0); |
| 2503 | 2634 | ||
| 2504 | /* If we were passed only a drive, make sure that a slash is not appended | 2635 | /* If we were passed only a drive, make sure that a slash is not appended |
| 2505 | for consistency with directories. Allow for drive mapping via SUBST | 2636 | for consistency with directories. Allow for drive mapping via SUBST |
diff --git a/src/w32reg.c b/src/w32reg.c index 8b6c76503a6..e7c4e9ea351 100644 --- a/src/w32reg.c +++ b/src/w32reg.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Emulate the X Resource Manager through the registry. | 1 | /* Emulate the X Resource Manager through the registry. |
| 2 | Copyright (C) 1990, 1993-1994, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1990, 1993-1994, 2001-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
diff --git a/src/w32select.c b/src/w32select.c index 6a2a840f914..3c966595d6d 100644 --- a/src/w32select.c +++ b/src/w32select.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Selection processing for Emacs on the Microsoft Windows API. | 1 | /* Selection processing for Emacs on the Microsoft Windows API. |
| 2 | 2 | ||
| 3 | Copyright (C) 1993-1994, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1993-1994, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/w32select.h b/src/w32select.h index 4f4de59f7fe..f6223b881d2 100644 --- a/src/w32select.h +++ b/src/w32select.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Selection processing for Emacs on the Microsoft W32 API. | 1 | /* Selection processing for Emacs on the Microsoft W32 API. |
| 2 | 2 | ||
| 3 | Copyright (C) 1993-1994, 2001-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1993-1994, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/w32term.c b/src/w32term.c index e26777543fb..170f33ecd67 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Implementation of GUI terminal on the Microsoft Windows API. | 1 | /* Implementation of GUI terminal on the Microsoft Windows API. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1989, 1993-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -191,11 +191,7 @@ static Time last_mouse_movement_time; | |||
| 191 | 191 | ||
| 192 | /* Incremented by w32_read_socket whenever it really tries to read | 192 | /* Incremented by w32_read_socket whenever it really tries to read |
| 193 | events. */ | 193 | events. */ |
| 194 | #ifdef __STDC__ | ||
| 195 | static int volatile input_signal_count; | 194 | static int volatile input_signal_count; |
| 196 | #else | ||
| 197 | static int input_signal_count; | ||
| 198 | #endif | ||
| 199 | 195 | ||
| 200 | #ifdef CYGWIN | 196 | #ifdef CYGWIN |
| 201 | int w32_message_fd = -1; | 197 | int w32_message_fd = -1; |
| @@ -246,6 +242,8 @@ static void x_check_font (struct frame *, struct font *); | |||
| 246 | #endif | 242 | #endif |
| 247 | 243 | ||
| 248 | static Lisp_Object Qvendor_specific_keysyms; | 244 | static Lisp_Object Qvendor_specific_keysyms; |
| 245 | static Lisp_Object Qadded, Qremoved, Qmodified; | ||
| 246 | static Lisp_Object Qrenamed_from, Qrenamed_to; | ||
| 249 | 247 | ||
| 250 | 248 | ||
| 251 | /*********************************************************************** | 249 | /*********************************************************************** |
| @@ -356,7 +354,7 @@ w32_restore_glyph_string_clip (struct glyph_string *s) | |||
| 356 | void | 354 | void |
| 357 | w32_draw_underwave (struct glyph_string *s, COLORREF color) | 355 | w32_draw_underwave (struct glyph_string *s, COLORREF color) |
| 358 | { | 356 | { |
| 359 | int wave_height = 2, wave_length = 3; | 357 | int wave_height = 3, wave_length = 2; |
| 360 | int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax; | 358 | int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax; |
| 361 | XRectangle wave_clip, string_clip, final_clip; | 359 | XRectangle wave_clip, string_clip, final_clip; |
| 362 | RECT w32_final_clip, w32_string_clip; | 360 | RECT w32_final_clip, w32_string_clip; |
| @@ -365,7 +363,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color) | |||
| 365 | dx = wave_length; | 363 | dx = wave_length; |
| 366 | dy = wave_height - 1; | 364 | dy = wave_height - 1; |
| 367 | x0 = s->x; | 365 | x0 = s->x; |
| 368 | y0 = s->ybase + 1; | 366 | y0 = s->ybase - wave_height + 3; |
| 369 | width = s->width; | 367 | width = s->width; |
| 370 | xmax = x0 + width; | 368 | xmax = x0 + width; |
| 371 | 369 | ||
| @@ -2454,7 +2452,8 @@ x_draw_glyph_string (struct glyph_string *s) | |||
| 2454 | unsigned long thickness, position; | 2452 | unsigned long thickness, position; |
| 2455 | int y; | 2453 | int y; |
| 2456 | 2454 | ||
| 2457 | if (s->prev && s->prev->face->underline_p) | 2455 | if (s->prev && s->prev->face->underline_p |
| 2456 | && s->prev->face->underline_type == FACE_UNDER_LINE) | ||
| 2458 | { | 2457 | { |
| 2459 | /* We use the same underline style as the previous one. */ | 2458 | /* We use the same underline style as the previous one. */ |
| 2460 | thickness = s->prev->underline_thickness; | 2459 | thickness = s->prev->underline_thickness; |
| @@ -3204,6 +3203,124 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f) | |||
| 3204 | } | 3203 | } |
| 3205 | 3204 | ||
| 3206 | 3205 | ||
| 3206 | /* File event notifications (see w32notify.c). */ | ||
| 3207 | |||
| 3208 | Lisp_Object | ||
| 3209 | lispy_file_action (DWORD action) | ||
| 3210 | { | ||
| 3211 | static char unknown_fmt[] = "unknown-action(%d)"; | ||
| 3212 | Lisp_Object retval; | ||
| 3213 | |||
| 3214 | switch (action) | ||
| 3215 | { | ||
| 3216 | case FILE_ACTION_ADDED: | ||
| 3217 | retval = Qadded; | ||
| 3218 | break; | ||
| 3219 | case FILE_ACTION_REMOVED: | ||
| 3220 | retval = Qremoved; | ||
| 3221 | break; | ||
| 3222 | case FILE_ACTION_MODIFIED: | ||
| 3223 | retval = Qmodified; | ||
| 3224 | break; | ||
| 3225 | case FILE_ACTION_RENAMED_OLD_NAME: | ||
| 3226 | retval = Qrenamed_from; | ||
| 3227 | break; | ||
| 3228 | case FILE_ACTION_RENAMED_NEW_NAME: | ||
| 3229 | retval = Qrenamed_to; | ||
| 3230 | break; | ||
| 3231 | default: | ||
| 3232 | { | ||
| 3233 | char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)]; | ||
| 3234 | |||
| 3235 | sprintf (buf, unknown_fmt, action); | ||
| 3236 | retval = intern (buf); | ||
| 3237 | } | ||
| 3238 | break; | ||
| 3239 | } | ||
| 3240 | |||
| 3241 | return retval; | ||
| 3242 | } | ||
| 3243 | |||
| 3244 | #ifdef WINDOWSNT | ||
| 3245 | /* Put file notifications into the Emacs input event queue. This | ||
| 3246 | function runs when the WM_EMACS_FILENOTIFY message arrives from a | ||
| 3247 | watcher thread. */ | ||
| 3248 | static void | ||
| 3249 | queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f, | ||
| 3250 | int *evcount) | ||
| 3251 | { | ||
| 3252 | BYTE *p = file_notifications; | ||
| 3253 | FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p; | ||
| 3254 | const DWORD min_size | ||
| 3255 | = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t); | ||
| 3256 | Lisp_Object frame; | ||
| 3257 | |||
| 3258 | /* We cannot process notification before Emacs is fully initialized, | ||
| 3259 | since we need the UTF-16LE coding-system to be set up. */ | ||
| 3260 | if (!initialized) | ||
| 3261 | { | ||
| 3262 | notification_buffer_in_use = 0; | ||
| 3263 | return; | ||
| 3264 | } | ||
| 3265 | |||
| 3266 | XSETFRAME (frame, f); | ||
| 3267 | |||
| 3268 | enter_crit (); | ||
| 3269 | if (notification_buffer_in_use) | ||
| 3270 | { | ||
| 3271 | DWORD info_size = notifications_size; | ||
| 3272 | Lisp_Object cs = intern ("utf-16le"); | ||
| 3273 | Lisp_Object obj = w32_get_watch_object (notifications_desc); | ||
| 3274 | |||
| 3275 | /* notifications_size could be zero when the buffer of | ||
| 3276 | notifications overflowed on the OS level, or when the | ||
| 3277 | directory being watched was itself deleted. Do nothing in | ||
| 3278 | that case. */ | ||
| 3279 | if (info_size | ||
| 3280 | && !NILP (obj) && CONSP (obj)) | ||
| 3281 | { | ||
| 3282 | Lisp_Object callback = XCDR (obj); | ||
| 3283 | |||
| 3284 | while (info_size >= min_size) | ||
| 3285 | { | ||
| 3286 | Lisp_Object utf_16_fn | ||
| 3287 | = make_unibyte_string ((char *)fni->FileName, | ||
| 3288 | fni->FileNameLength); | ||
| 3289 | /* Note: mule-conf is preloaded, so utf-16le must | ||
| 3290 | already be defined at this point. */ | ||
| 3291 | Lisp_Object fname | ||
| 3292 | = code_convert_string_norecord (utf_16_fn, cs, 0); | ||
| 3293 | Lisp_Object action = lispy_file_action (fni->Action); | ||
| 3294 | |||
| 3295 | event->kind = FILE_NOTIFY_EVENT; | ||
| 3296 | event->code | ||
| 3297 | = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc)); | ||
| 3298 | event->timestamp = msg->msg.time; | ||
| 3299 | event->modifiers = 0; | ||
| 3300 | event->frame_or_window = callback; | ||
| 3301 | event->arg = Fcons (action, fname); | ||
| 3302 | kbd_buffer_store_event (event); | ||
| 3303 | (*evcount)++; | ||
| 3304 | |||
| 3305 | if (!fni->NextEntryOffset) | ||
| 3306 | break; | ||
| 3307 | p += fni->NextEntryOffset; | ||
| 3308 | fni = (PFILE_NOTIFY_INFORMATION)p; | ||
| 3309 | info_size -= fni->NextEntryOffset; | ||
| 3310 | } | ||
| 3311 | } | ||
| 3312 | notification_buffer_in_use = 0; | ||
| 3313 | } | ||
| 3314 | else | ||
| 3315 | DebPrint (("We were promised notifications, but in-use flag is zero!\n")); | ||
| 3316 | leave_crit (); | ||
| 3317 | |||
| 3318 | /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */ | ||
| 3319 | event->kind = NO_EVENT; | ||
| 3320 | } | ||
| 3321 | #endif | ||
| 3322 | |||
| 3323 | |||
| 3207 | /* Function to report a mouse movement to the mainstream Emacs code. | 3324 | /* Function to report a mouse movement to the mainstream Emacs code. |
| 3208 | The input handler calls this. | 3325 | The input handler calls this. |
| 3209 | 3326 | ||
| @@ -4198,24 +4315,25 @@ w32_read_socket (struct terminal *terminal, | |||
| 4198 | DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f, | 4315 | DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f, |
| 4199 | SDATA (f->name))); | 4316 | SDATA (f->name))); |
| 4200 | } | 4317 | } |
| 4201 | else if (f->async_visible != 1) | 4318 | else if (FRAME_VISIBLE_P (f) != 1) |
| 4202 | { | 4319 | { |
| 4320 | bool iconified = FRAME_ICONIFIED_P (f); | ||
| 4321 | |||
| 4203 | /* Definitely not obscured, so mark as visible. */ | 4322 | /* Definitely not obscured, so mark as visible. */ |
| 4204 | f->async_visible = 1; | 4323 | SET_FRAME_VISIBLE (f, 1); |
| 4205 | f->async_iconified = 0; | 4324 | SET_FRAME_ICONIFIED (f, 0); |
| 4206 | SET_FRAME_GARBAGED (f); | 4325 | SET_FRAME_GARBAGED (f); |
| 4207 | DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, | 4326 | DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, |
| 4208 | SDATA (f->name))); | 4327 | SDATA (f->name))); |
| 4209 | 4328 | ||
| 4210 | /* WM_PAINT serves as MapNotify as well, so report | 4329 | /* WM_PAINT serves as MapNotify as well, so report |
| 4211 | visibility changes properly. */ | 4330 | visibility changes properly. */ |
| 4212 | if (f->iconified) | 4331 | if (iconified) |
| 4213 | { | 4332 | { |
| 4214 | inev.kind = DEICONIFY_EVENT; | 4333 | inev.kind = DEICONIFY_EVENT; |
| 4215 | XSETFRAME (inev.frame_or_window, f); | 4334 | XSETFRAME (inev.frame_or_window, f); |
| 4216 | } | 4335 | } |
| 4217 | else if (! NILP (Vframe_list) | 4336 | else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list))) |
| 4218 | && ! NILP (XCDR (Vframe_list))) | ||
| 4219 | /* Force a redisplay sooner or later to update the | 4337 | /* Force a redisplay sooner or later to update the |
| 4220 | frame titles in case this is the second frame. */ | 4338 | frame titles in case this is the second frame. */ |
| 4221 | record_asynch_buffer_change (); | 4339 | record_asynch_buffer_change (); |
| @@ -4258,7 +4376,7 @@ w32_read_socket (struct terminal *terminal, | |||
| 4258 | case WM_SYSKEYDOWN: | 4376 | case WM_SYSKEYDOWN: |
| 4259 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); | 4377 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); |
| 4260 | 4378 | ||
| 4261 | if (f && !f->iconified) | 4379 | if (f && !FRAME_ICONIFIED_P (f)) |
| 4262 | { | 4380 | { |
| 4263 | if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) | 4381 | if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) |
| 4264 | && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) | 4382 | && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) |
| @@ -4283,7 +4401,7 @@ w32_read_socket (struct terminal *terminal, | |||
| 4283 | case WM_CHAR: | 4401 | case WM_CHAR: |
| 4284 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); | 4402 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); |
| 4285 | 4403 | ||
| 4286 | if (f && !f->iconified) | 4404 | if (f && !FRAME_ICONIFIED_P (f)) |
| 4287 | { | 4405 | { |
| 4288 | if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) | 4406 | if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) |
| 4289 | && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) | 4407 | && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) |
| @@ -4361,7 +4479,7 @@ w32_read_socket (struct terminal *terminal, | |||
| 4361 | case WM_APPCOMMAND: | 4479 | case WM_APPCOMMAND: |
| 4362 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); | 4480 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); |
| 4363 | 4481 | ||
| 4364 | if (f && !f->iconified) | 4482 | if (f && !FRAME_ICONIFIED_P (f)) |
| 4365 | { | 4483 | { |
| 4366 | if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) | 4484 | if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) |
| 4367 | && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) | 4485 | && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) |
| @@ -4601,7 +4719,7 @@ w32_read_socket (struct terminal *terminal, | |||
| 4601 | case WM_MOVE: | 4719 | case WM_MOVE: |
| 4602 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); | 4720 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); |
| 4603 | 4721 | ||
| 4604 | if (f && !f->async_iconified) | 4722 | if (f && !FRAME_ICONIFIED_P (f)) |
| 4605 | { | 4723 | { |
| 4606 | int x, y; | 4724 | int x, y; |
| 4607 | 4725 | ||
| @@ -4649,8 +4767,8 @@ w32_read_socket (struct terminal *terminal, | |||
| 4649 | switch (msg.msg.wParam) | 4767 | switch (msg.msg.wParam) |
| 4650 | { | 4768 | { |
| 4651 | case SIZE_MINIMIZED: | 4769 | case SIZE_MINIMIZED: |
| 4652 | f->async_visible = 0; | 4770 | SET_FRAME_VISIBLE (f, 0); |
| 4653 | f->async_iconified = 1; | 4771 | SET_FRAME_ICONIFIED (f, 1); |
| 4654 | 4772 | ||
| 4655 | inev.kind = ICONIFY_EVENT; | 4773 | inev.kind = ICONIFY_EVENT; |
| 4656 | XSETFRAME (inev.frame_or_window, f); | 4774 | XSETFRAME (inev.frame_or_window, f); |
| @@ -4658,40 +4776,44 @@ w32_read_socket (struct terminal *terminal, | |||
| 4658 | 4776 | ||
| 4659 | case SIZE_MAXIMIZED: | 4777 | case SIZE_MAXIMIZED: |
| 4660 | case SIZE_RESTORED: | 4778 | case SIZE_RESTORED: |
| 4661 | f->async_visible = 1; | 4779 | { |
| 4662 | f->async_iconified = 0; | 4780 | bool iconified = FRAME_ICONIFIED_P (f); |
| 4663 | |||
| 4664 | /* wait_reading_process_output will notice this and update | ||
| 4665 | the frame's display structures. */ | ||
| 4666 | SET_FRAME_GARBAGED (f); | ||
| 4667 | 4781 | ||
| 4668 | if (f->iconified) | 4782 | SET_FRAME_VISIBLE (f, 1); |
| 4669 | { | 4783 | SET_FRAME_ICONIFIED (f, 0); |
| 4670 | int x, y; | ||
| 4671 | 4784 | ||
| 4672 | /* Reset top and left positions of the Window | 4785 | /* wait_reading_process_output will notice this |
| 4673 | here since Windows sends a WM_MOVE message | 4786 | and update the frame's display structures. */ |
| 4674 | BEFORE telling us the Window is minimized | 4787 | SET_FRAME_GARBAGED (f); |
| 4675 | when the Window is iconified, with 3000,3000 | ||
| 4676 | as the co-ords. */ | ||
| 4677 | x_real_positions (f, &x, &y); | ||
| 4678 | f->left_pos = x; | ||
| 4679 | f->top_pos = y; | ||
| 4680 | 4788 | ||
| 4681 | inev.kind = DEICONIFY_EVENT; | 4789 | if (iconified) |
| 4682 | XSETFRAME (inev.frame_or_window, f); | 4790 | { |
| 4683 | } | 4791 | int x, y; |
| 4684 | else if (! NILP (Vframe_list) | 4792 | |
| 4685 | && ! NILP (XCDR (Vframe_list))) | 4793 | /* Reset top and left positions of the Window |
| 4686 | /* Force a redisplay sooner or later | 4794 | here since Windows sends a WM_MOVE message |
| 4687 | to update the frame titles | 4795 | BEFORE telling us the Window is minimized |
| 4688 | in case this is the second frame. */ | 4796 | when the Window is iconified, with 3000,3000 |
| 4689 | record_asynch_buffer_change (); | 4797 | as the co-ords. */ |
| 4798 | x_real_positions (f, &x, &y); | ||
| 4799 | f->left_pos = x; | ||
| 4800 | f->top_pos = y; | ||
| 4801 | |||
| 4802 | inev.kind = DEICONIFY_EVENT; | ||
| 4803 | XSETFRAME (inev.frame_or_window, f); | ||
| 4804 | } | ||
| 4805 | else if (! NILP (Vframe_list) | ||
| 4806 | && ! NILP (XCDR (Vframe_list))) | ||
| 4807 | /* Force a redisplay sooner or later | ||
| 4808 | to update the frame titles | ||
| 4809 | in case this is the second frame. */ | ||
| 4810 | record_asynch_buffer_change (); | ||
| 4811 | } | ||
| 4690 | break; | 4812 | break; |
| 4691 | } | 4813 | } |
| 4692 | } | 4814 | } |
| 4693 | 4815 | ||
| 4694 | if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED) | 4816 | if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED) |
| 4695 | { | 4817 | { |
| 4696 | RECT rect; | 4818 | RECT rect; |
| 4697 | int rows; | 4819 | int rows; |
| @@ -4836,6 +4958,14 @@ w32_read_socket (struct terminal *terminal, | |||
| 4836 | check_visibility = 1; | 4958 | check_visibility = 1; |
| 4837 | break; | 4959 | break; |
| 4838 | 4960 | ||
| 4961 | #ifdef WINDOWSNT | ||
| 4962 | case WM_EMACS_FILENOTIFY: | ||
| 4963 | f = x_window_to_frame (dpyinfo, msg.msg.hwnd); | ||
| 4964 | if (f) | ||
| 4965 | queue_notifications (&inev, &msg, f, &count); | ||
| 4966 | break; | ||
| 4967 | #endif | ||
| 4968 | |||
| 4839 | default: | 4969 | default: |
| 4840 | /* Check for messages registered at runtime. */ | 4970 | /* Check for messages registered at runtime. */ |
| 4841 | if (msg.msg.message == msh_mousewheel) | 4971 | if (msg.msg.message == msh_mousewheel) |
| @@ -4911,12 +5041,13 @@ w32_read_socket (struct terminal *terminal, | |||
| 4911 | continue; | 5041 | continue; |
| 4912 | 5042 | ||
| 4913 | /* Check "visible" frames and mark each as obscured or not. | 5043 | /* Check "visible" frames and mark each as obscured or not. |
| 4914 | Note that async_visible is nonzero for unobscured and | 5044 | Note that visible is nonzero for unobscured and obscured |
| 4915 | obscured frames, but zero for hidden and iconified frames. */ | 5045 | frames, but zero for hidden and iconified frames. */ |
| 4916 | if (FRAME_W32_P (f) && f->async_visible) | 5046 | if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f)) |
| 4917 | { | 5047 | { |
| 4918 | RECT clipbox; | 5048 | RECT clipbox; |
| 4919 | HDC hdc; | 5049 | HDC hdc; |
| 5050 | bool obscured; | ||
| 4920 | 5051 | ||
| 4921 | enter_crit (); | 5052 | enter_crit (); |
| 4922 | /* Query clipping rectangle for the entire window area | 5053 | /* Query clipping rectangle for the entire window area |
| @@ -4930,31 +5061,28 @@ w32_read_socket (struct terminal *terminal, | |||
| 4930 | ReleaseDC (FRAME_W32_WINDOW (f), hdc); | 5061 | ReleaseDC (FRAME_W32_WINDOW (f), hdc); |
| 4931 | leave_crit (); | 5062 | leave_crit (); |
| 4932 | 5063 | ||
| 4933 | if (clipbox.right == clipbox.left | 5064 | obscured = FRAME_OBSCURED_P (f); |
| 4934 | || clipbox.bottom == clipbox.top) | 5065 | |
| 5066 | if (clipbox.right == clipbox.left || clipbox.bottom == clipbox.top) | ||
| 4935 | { | 5067 | { |
| 4936 | /* Frame has become completely obscured so mark as | 5068 | /* Frame has become completely obscured so mark as such (we |
| 4937 | such (we do this by setting async_visible to 2 so | 5069 | do this by setting visible to 2 so that FRAME_VISIBLE_P |
| 4938 | that FRAME_VISIBLE_P is still true, but redisplay | 5070 | is still true, but redisplay will skip it). */ |
| 4939 | will skip it). */ | 5071 | SET_FRAME_VISIBLE (f, 2); |
| 4940 | f->async_visible = 2; | ||
| 4941 | 5072 | ||
| 4942 | if (!FRAME_OBSCURED_P (f)) | 5073 | if (!obscured) |
| 4943 | { | 5074 | DebPrint (("frame %p (%s) obscured\n", f, SDATA (f->name))); |
| 4944 | DebPrint (("frame %p (%s) obscured\n", f, | ||
| 4945 | SDATA (f->name))); | ||
| 4946 | } | ||
| 4947 | } | 5075 | } |
| 4948 | else | 5076 | else |
| 4949 | { | 5077 | { |
| 4950 | /* Frame is not obscured, so mark it as such. */ | 5078 | /* Frame is not obscured, so mark it as such. */ |
| 4951 | f->async_visible = 1; | 5079 | SET_FRAME_VISIBLE (f, 1); |
| 4952 | 5080 | ||
| 4953 | if (FRAME_OBSCURED_P (f)) | 5081 | if (obscured) |
| 4954 | { | 5082 | { |
| 4955 | SET_FRAME_GARBAGED (f); | 5083 | SET_FRAME_GARBAGED (f); |
| 4956 | DebPrint (("obscured frame %p (%s) found to be visible\n", f, | 5084 | DebPrint (("obscured frame %p (%s) found to be visible\n", |
| 4957 | SDATA (f->name))); | 5085 | f, SDATA (f->name))); |
| 4958 | 5086 | ||
| 4959 | /* Force a redisplay sooner or later. */ | 5087 | /* Force a redisplay sooner or later. */ |
| 4960 | record_asynch_buffer_change (); | 5088 | record_asynch_buffer_change (); |
| @@ -5520,6 +5648,86 @@ x_check_fullscreen (struct frame *f) | |||
| 5520 | } | 5648 | } |
| 5521 | } | 5649 | } |
| 5522 | 5650 | ||
| 5651 | static void | ||
| 5652 | w32fullscreen_hook (FRAME_PTR f) | ||
| 5653 | { | ||
| 5654 | static int normal_width, normal_height; | ||
| 5655 | |||
| 5656 | if (FRAME_VISIBLE_P (f)) | ||
| 5657 | { | ||
| 5658 | int width, height, top_pos, left_pos, pixel_height, pixel_width; | ||
| 5659 | int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f); | ||
| 5660 | RECT workarea_rect; | ||
| 5661 | |||
| 5662 | block_input (); | ||
| 5663 | if (normal_height <= 0) | ||
| 5664 | normal_height = cur_h; | ||
| 5665 | if (normal_width <= 0) | ||
| 5666 | normal_width = cur_w; | ||
| 5667 | x_real_positions (f, &f->left_pos, &f->top_pos); | ||
| 5668 | x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos); | ||
| 5669 | |||
| 5670 | SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); | ||
| 5671 | pixel_height = workarea_rect.bottom - workarea_rect.top; | ||
| 5672 | pixel_width = workarea_rect.right - workarea_rect.left; | ||
| 5673 | |||
| 5674 | switch (f->want_fullscreen) | ||
| 5675 | { | ||
| 5676 | case FULLSCREEN_MAXIMIZED: | ||
| 5677 | PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0); | ||
| 5678 | break; | ||
| 5679 | case FULLSCREEN_BOTH: | ||
| 5680 | height = | ||
| 5681 | FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) | ||
| 5682 | - XINT (Ftool_bar_lines_needed (selected_frame)) | ||
| 5683 | + (NILP (Vmenu_bar_mode) ? 1 : 0); | ||
| 5684 | width = | ||
| 5685 | FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) | ||
| 5686 | - FRAME_SCROLL_BAR_COLS (f); | ||
| 5687 | left_pos = workarea_rect.left; | ||
| 5688 | top_pos = workarea_rect.top; | ||
| 5689 | break; | ||
| 5690 | case FULLSCREEN_WIDTH: | ||
| 5691 | width = | ||
| 5692 | FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) | ||
| 5693 | - FRAME_SCROLL_BAR_COLS (f); | ||
| 5694 | if (normal_height > 0) | ||
| 5695 | height = normal_height; | ||
| 5696 | left_pos = workarea_rect.left; | ||
| 5697 | break; | ||
| 5698 | case FULLSCREEN_HEIGHT: | ||
| 5699 | height = | ||
| 5700 | FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) | ||
| 5701 | - XINT (Ftool_bar_lines_needed (selected_frame)) | ||
| 5702 | + (NILP (Vmenu_bar_mode) ? 1 : 0); | ||
| 5703 | if (normal_width > 0) | ||
| 5704 | width = normal_width; | ||
| 5705 | top_pos = workarea_rect.top; | ||
| 5706 | break; | ||
| 5707 | case FULLSCREEN_NONE: | ||
| 5708 | if (normal_height > 0) | ||
| 5709 | height = normal_height; | ||
| 5710 | else | ||
| 5711 | normal_height = height; | ||
| 5712 | if (normal_width > 0) | ||
| 5713 | width = normal_width; | ||
| 5714 | else | ||
| 5715 | normal_width = width; | ||
| 5716 | /* FIXME: Should restore the original position of the frame. */ | ||
| 5717 | top_pos = left_pos = 0; | ||
| 5718 | break; | ||
| 5719 | } | ||
| 5720 | |||
| 5721 | if (cur_w != width || cur_h != height) | ||
| 5722 | { | ||
| 5723 | x_set_offset (f, left_pos, top_pos, 1); | ||
| 5724 | x_set_window_size (f, 1, width, height); | ||
| 5725 | do_pending_window_change (0); | ||
| 5726 | } | ||
| 5727 | unblock_input (); | ||
| 5728 | } | ||
| 5729 | } | ||
| 5730 | |||
| 5523 | /* Call this to change the size of frame F's x-window. | 5731 | /* Call this to change the size of frame F's x-window. |
| 5524 | If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity | 5732 | If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity |
| 5525 | for this size change and subsequent size changes. | 5733 | for this size change and subsequent size changes. |
| @@ -5814,11 +6022,11 @@ x_make_frame_visible (struct frame *f) | |||
| 5814 | causes unexpected behavior when unminimizing frames that were | 6022 | causes unexpected behavior when unminimizing frames that were |
| 5815 | previously maximized. But only SW_SHOWNORMAL works properly for | 6023 | previously maximized. But only SW_SHOWNORMAL works properly for |
| 5816 | frames that were truely hidden (using make-frame-invisible), so | 6024 | frames that were truely hidden (using make-frame-invisible), so |
| 5817 | we need it to avoid Bug#5482. It seems that async_iconified | 6025 | we need it to avoid Bug#5482. It seems that iconified is only |
| 5818 | is only set for minimized windows that are still visible, so | 6026 | set for minimized windows that are still visible, so use that to |
| 5819 | use that to determine the appropriate flag to pass ShowWindow. */ | 6027 | determine the appropriate flag to pass ShowWindow. */ |
| 5820 | my_show_window (f, FRAME_W32_WINDOW (f), | 6028 | my_show_window (f, FRAME_W32_WINDOW (f), |
| 5821 | f->async_iconified ? SW_RESTORE : SW_SHOWNORMAL); | 6029 | FRAME_ICONIFIED_P (f) ? SW_RESTORE : SW_SHOWNORMAL); |
| 5822 | } | 6030 | } |
| 5823 | 6031 | ||
| 5824 | /* Synchronize to ensure Emacs knows the frame is visible | 6032 | /* Synchronize to ensure Emacs knows the frame is visible |
| @@ -5857,7 +6065,6 @@ x_make_frame_visible (struct frame *f) | |||
| 5857 | poll_suppress_count = old_poll_suppress_count; | 6065 | poll_suppress_count = old_poll_suppress_count; |
| 5858 | } | 6066 | } |
| 5859 | } | 6067 | } |
| 5860 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 5861 | } | 6068 | } |
| 5862 | } | 6069 | } |
| 5863 | 6070 | ||
| @@ -5881,10 +6088,8 @@ x_make_frame_invisible (struct frame *f) | |||
| 5881 | So we can't win using the usual strategy of letting | 6088 | So we can't win using the usual strategy of letting |
| 5882 | FRAME_SAMPLE_VISIBILITY set this. So do it by hand, | 6089 | FRAME_SAMPLE_VISIBILITY set this. So do it by hand, |
| 5883 | and synchronize with the server to make sure we agree. */ | 6090 | and synchronize with the server to make sure we agree. */ |
| 5884 | f->visible = 0; | 6091 | SET_FRAME_VISIBLE (f, 0); |
| 5885 | FRAME_ICONIFIED_P (f) = 0; | 6092 | SET_FRAME_ICONIFIED (f, 0); |
| 5886 | f->async_visible = 0; | ||
| 5887 | f->async_iconified = 0; | ||
| 5888 | 6093 | ||
| 5889 | unblock_input (); | 6094 | unblock_input (); |
| 5890 | } | 6095 | } |
| @@ -5900,7 +6105,7 @@ x_iconify_frame (struct frame *f) | |||
| 5900 | if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f) | 6105 | if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f) |
| 5901 | FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0; | 6106 | FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0; |
| 5902 | 6107 | ||
| 5903 | if (f->async_iconified) | 6108 | if (FRAME_ICONIFIED_P (f)) |
| 5904 | return; | 6109 | return; |
| 5905 | 6110 | ||
| 5906 | block_input (); | 6111 | block_input (); |
| @@ -6210,7 +6415,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo) | |||
| 6210 | terminal->mouse_position_hook = w32_mouse_position; | 6415 | terminal->mouse_position_hook = w32_mouse_position; |
| 6211 | terminal->frame_rehighlight_hook = w32_frame_rehighlight; | 6416 | terminal->frame_rehighlight_hook = w32_frame_rehighlight; |
| 6212 | terminal->frame_raise_lower_hook = w32_frame_raise_lower; | 6417 | terminal->frame_raise_lower_hook = w32_frame_raise_lower; |
| 6213 | /* terminal->fullscreen_hook = XTfullscreen_hook; */ | 6418 | terminal->fullscreen_hook = w32fullscreen_hook; |
| 6214 | terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar; | 6419 | terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar; |
| 6215 | terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars; | 6420 | terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars; |
| 6216 | terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; | 6421 | terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; |
| @@ -6503,6 +6708,12 @@ syms_of_w32term (void) | |||
| 6503 | 6708 | ||
| 6504 | DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); | 6709 | DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); |
| 6505 | 6710 | ||
| 6711 | DEFSYM (Qadded, "added"); | ||
| 6712 | DEFSYM (Qremoved, "removed"); | ||
| 6713 | DEFSYM (Qmodified, "modified"); | ||
| 6714 | DEFSYM (Qrenamed_from, "renamed-from"); | ||
| 6715 | DEFSYM (Qrenamed_to, "renamed-to"); | ||
| 6716 | |||
| 6506 | DEFVAR_INT ("w32-num-mouse-buttons", | 6717 | DEFVAR_INT ("w32-num-mouse-buttons", |
| 6507 | w32_num_mouse_buttons, | 6718 | w32_num_mouse_buttons, |
| 6508 | doc: /* Number of physical mouse buttons. */); | 6719 | doc: /* Number of physical mouse buttons. */); |
diff --git a/src/w32term.h b/src/w32term.h index af1a79e21c9..7154d549f21 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Definitions and headers for communication on the Microsoft Windows API. | 1 | /* Definitions and headers for communication on the Microsoft Windows API. |
| 2 | Copyright (C) 1995, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1995, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -602,7 +602,8 @@ do { \ | |||
| 602 | #define WM_EMACS_PAINT (WM_EMACS_START + 20) | 602 | #define WM_EMACS_PAINT (WM_EMACS_START + 20) |
| 603 | #define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21) | 603 | #define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21) |
| 604 | #define WM_EMACS_INPUT_READY (WM_EMACS_START + 22) | 604 | #define WM_EMACS_INPUT_READY (WM_EMACS_START + 22) |
| 605 | #define WM_EMACS_END (WM_EMACS_START + 23) | 605 | #define WM_EMACS_FILENOTIFY (WM_EMACS_START + 23) |
| 606 | #define WM_EMACS_END (WM_EMACS_START + 24) | ||
| 606 | 607 | ||
| 607 | #define WND_FONTWIDTH_INDEX (0) | 608 | #define WND_FONTWIDTH_INDEX (0) |
| 608 | #define WND_LINEHEIGHT_INDEX (4) | 609 | #define WND_LINEHEIGHT_INDEX (4) |
| @@ -652,7 +653,7 @@ extern void deselect_palette (struct frame * f, HDC hdc); | |||
| 652 | extern HDC get_frame_dc (struct frame * f); | 653 | extern HDC get_frame_dc (struct frame * f); |
| 653 | extern int release_frame_dc (struct frame * f, HDC hDC); | 654 | extern int release_frame_dc (struct frame * f, HDC hDC); |
| 654 | 655 | ||
| 655 | extern void drain_message_queue (void); | 656 | extern int drain_message_queue (void); |
| 656 | 657 | ||
| 657 | extern BOOL get_next_msg (W32Msg *, BOOL); | 658 | extern BOOL get_next_msg (W32Msg *, BOOL); |
| 658 | extern BOOL post_msg (W32Msg *); | 659 | extern BOOL post_msg (W32Msg *); |
| @@ -662,10 +663,17 @@ extern BOOL parse_button (int, int, int *, int *); | |||
| 662 | 663 | ||
| 663 | extern void w32_sys_ring_bell (struct frame *f); | 664 | extern void w32_sys_ring_bell (struct frame *f); |
| 664 | extern void x_delete_display (struct w32_display_info *dpyinfo); | 665 | extern void x_delete_display (struct w32_display_info *dpyinfo); |
| 666 | |||
| 667 | extern volatile int notification_buffer_in_use; | ||
| 668 | extern BYTE file_notifications[16384]; | ||
| 669 | extern DWORD notifications_size; | ||
| 670 | extern void *notifications_desc; | ||
| 671 | extern Lisp_Object w32_get_watch_object (void *); | ||
| 672 | extern Lisp_Object lispy_file_action (DWORD); | ||
| 673 | |||
| 665 | extern void w32_initialize_display_info (Lisp_Object); | 674 | extern void w32_initialize_display_info (Lisp_Object); |
| 666 | extern void initialize_w32_display (struct terminal *); | 675 | extern void initialize_w32_display (struct terminal *); |
| 667 | 676 | ||
| 668 | |||
| 669 | /* Keypad command key support. W32 doesn't have virtual keys defined | 677 | /* Keypad command key support. W32 doesn't have virtual keys defined |
| 670 | for the function keys on the keypad (they are mapped to the standard | 678 | for the function keys on the keypad (they are mapped to the standard |
| 671 | function keys), so we define our own. */ | 679 | function keys), so we define our own. */ |
| @@ -759,6 +767,7 @@ extern void syms_of_w32fns (void); | |||
| 759 | 767 | ||
| 760 | extern void globals_of_w32menu (void); | 768 | extern void globals_of_w32menu (void); |
| 761 | extern void globals_of_w32fns (void); | 769 | extern void globals_of_w32fns (void); |
| 770 | extern void globals_of_w32notify (void); | ||
| 762 | 771 | ||
| 763 | #ifdef CYGWIN | 772 | #ifdef CYGWIN |
| 764 | extern int w32_message_fd; | 773 | extern int w32_message_fd; |
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index 5d160b9d42f..56931adfac5 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Font backend for the Microsoft W32 Uniscribe API. | 1 | /* Font backend for the Microsoft W32 Uniscribe API. |
| 2 | Copyright (C) 2008-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -435,8 +435,8 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 435 | are zero. */ | 435 | are zero. */ |
| 436 | || (!attributes[j].fClusterStart && items[i].a.fRTL)) | 436 | || (!attributes[j].fClusterStart && items[i].a.fRTL)) |
| 437 | { | 437 | { |
| 438 | Lisp_Object vec; | 438 | Lisp_Object vec = make_uninit_vector (3); |
| 439 | vec = Fmake_vector (make_number (3), Qnil); | 439 | |
| 440 | if (items[i].a.fRTL) | 440 | if (items[i].a.fRTL) |
| 441 | { | 441 | { |
| 442 | /* Empirically, it looks like Uniscribe | 442 | /* Empirically, it looks like Uniscribe |
diff --git a/src/w32xfns.c b/src/w32xfns.c index cb452571665..03611e19768 100644 --- a/src/w32xfns.c +++ b/src/w32xfns.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Functions taken directly from X sources for use with the Microsoft Windows API. | 1 | /* Functions taken directly from X sources for use with the Microsoft Windows API. |
| 2 | Copyright (C) 1989, 1992-1995, 1999, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1989, 1992-1995, 1999, 2001-2013 Free Software |
| 3 | Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -315,16 +316,22 @@ prepend_msg (W32Msg *lpmsg) | |||
| 315 | return (TRUE); | 316 | return (TRUE); |
| 316 | } | 317 | } |
| 317 | 318 | ||
| 318 | /* Process all messages in the current thread's queue. */ | 319 | /* Process all messages in the current thread's queue. Value is 1 if |
| 319 | void | 320 | one of these messages was WM_EMACS_FILENOTIFY, zero otherwise. */ |
| 321 | int | ||
| 320 | drain_message_queue (void) | 322 | drain_message_queue (void) |
| 321 | { | 323 | { |
| 322 | MSG msg; | 324 | MSG msg; |
| 325 | int retval = 0; | ||
| 326 | |||
| 323 | while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) | 327 | while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) |
| 324 | { | 328 | { |
| 329 | if (msg.message == WM_EMACS_FILENOTIFY) | ||
| 330 | retval = 1; | ||
| 325 | TranslateMessage (&msg); | 331 | TranslateMessage (&msg); |
| 326 | DispatchMessage (&msg); | 332 | DispatchMessage (&msg); |
| 327 | } | 333 | } |
| 334 | return retval; | ||
| 328 | } | 335 | } |
| 329 | 336 | ||
| 330 | /* x_sync is a no-op on W32. */ | 337 | /* x_sync is a no-op on W32. */ |
diff --git a/src/widget.c b/src/widget.c index b4f7335c652..28e9fc29a91 100644 --- a/src/widget.c +++ b/src/widget.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* The emacs frame widget. | 1 | /* The emacs frame widget. |
| 2 | Copyright (C) 1992-1993, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1992-1993, 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/widget.h b/src/widget.h index 03838a01415..e04c31c259b 100644 --- a/src/widget.h +++ b/src/widget.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* The emacs frame widget public header file. | 1 | /* The emacs frame widget public header file. |
| 2 | Copyright (C) 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/widgetprv.h b/src/widgetprv.h index 00e3eeb1ee1..b617654e7f2 100644 --- a/src/widgetprv.h +++ b/src/widgetprv.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* The emacs frame widget private header file. | 1 | /* The emacs frame widget private header file. |
| 2 | Copyright (C) 1993, 2001-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
diff --git a/src/window.c b/src/window.c index d7c2e8b236e..ea1dd93711c 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Window creation, deletion and examination for GNU Emacs. | 1 | /* Window creation, deletion and examination for GNU Emacs. |
| 2 | Does not include redisplay. | 2 | Does not include redisplay. |
| 3 | Copyright (C) 1985-1987, 1993-1998, 2000-2012 | 3 | Copyright (C) 1985-1987, 1993-1998, 2000-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -87,6 +87,7 @@ static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); | |||
| 87 | static int window_resize_check (struct window *, int); | 87 | static int window_resize_check (struct window *, int); |
| 88 | static void window_resize_apply (struct window *, int); | 88 | static void window_resize_apply (struct window *, int); |
| 89 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); | 89 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); |
| 90 | static void select_window_1 (Lisp_Object, bool); | ||
| 90 | 91 | ||
| 91 | /* This is the window in which the terminal's cursor should | 92 | /* This is the window in which the terminal's cursor should |
| 92 | be left when nothing is being done with it. This must | 93 | be left when nothing is being done with it. This must |
| @@ -115,9 +116,6 @@ Lisp_Object minibuf_selected_window; | |||
| 115 | /* Hook run at end of temp_output_buffer_show. */ | 116 | /* Hook run at end of temp_output_buffer_show. */ |
| 116 | static Lisp_Object Qtemp_buffer_show_hook; | 117 | static Lisp_Object Qtemp_buffer_show_hook; |
| 117 | 118 | ||
| 118 | /* Incremented for each window created. */ | ||
| 119 | static int sequence_number; | ||
| 120 | |||
| 121 | /* Nonzero after init_window_once has finished. */ | 119 | /* Nonzero after init_window_once has finished. */ |
| 122 | static int window_initialized; | 120 | static int window_initialized; |
| 123 | 121 | ||
| @@ -270,6 +268,38 @@ decode_valid_window (register Lisp_Object window) | |||
| 270 | return w; | 268 | return w; |
| 271 | } | 269 | } |
| 272 | 270 | ||
| 271 | /* Called when W's buffer slot is changed. ARG -1 means that W is about to | ||
| 272 | cease its buffer, and 1 means that W is about to set up the new one. */ | ||
| 273 | |||
| 274 | static void | ||
| 275 | adjust_window_count (struct window *w, int arg) | ||
| 276 | { | ||
| 277 | eassert (eabs (arg) == 1); | ||
| 278 | if (BUFFERP (w->buffer)) | ||
| 279 | { | ||
| 280 | struct buffer *b = XBUFFER (w->buffer); | ||
| 281 | |||
| 282 | if (b->base_buffer) | ||
| 283 | b = b->base_buffer; | ||
| 284 | b->window_count += arg; | ||
| 285 | eassert (b->window_count >= 0); | ||
| 286 | /* These should be recalculated by redisplay code. */ | ||
| 287 | w->window_end_valid = 0; | ||
| 288 | w->base_line_pos = 0; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | /* Set W's buffer slot to VAL and recompute number | ||
| 293 | of windows showing VAL if it is a buffer. */ | ||
| 294 | |||
| 295 | void | ||
| 296 | wset_buffer (struct window *w, Lisp_Object val) | ||
| 297 | { | ||
| 298 | adjust_window_count (w, -1); | ||
| 299 | w->buffer = val; | ||
| 300 | adjust_window_count (w, 1); | ||
| 301 | } | ||
| 302 | |||
| 273 | /* Build a frequently used 4-integer (X Y W H) list. */ | 303 | /* Build a frequently used 4-integer (X Y W H) list. */ |
| 274 | 304 | ||
| 275 | static Lisp_Object | 305 | static Lisp_Object |
| @@ -458,7 +488,6 @@ static Lisp_Object | |||
| 458 | select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) | 488 | select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) |
| 459 | { | 489 | { |
| 460 | register struct window *w; | 490 | register struct window *w; |
| 461 | register struct window *ow; | ||
| 462 | struct frame *sf; | 491 | struct frame *sf; |
| 463 | 492 | ||
| 464 | CHECK_LIVE_WINDOW (window); | 493 | CHECK_LIVE_WINDOW (window); |
| @@ -494,12 +523,25 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) | |||
| 494 | else | 523 | else |
| 495 | fset_selected_window (sf, window); | 524 | fset_selected_window (sf, window); |
| 496 | 525 | ||
| 526 | select_window_1 (window, inhibit_point_swap); | ||
| 527 | |||
| 528 | bset_last_selected_window (XBUFFER (w->buffer), window); | ||
| 529 | windows_or_buffers_changed++; | ||
| 530 | return window; | ||
| 531 | } | ||
| 532 | |||
| 533 | /* Select window with a minimum of fuss, i.e. don't record the change anywhere | ||
| 534 | (not even for redisplay's benefit), and assume that the window's frame is | ||
| 535 | already selected. */ | ||
| 536 | static void | ||
| 537 | select_window_1 (Lisp_Object window, bool inhibit_point_swap) | ||
| 538 | { | ||
| 497 | /* Store the old selected window's buffer's point in pointm of the old | 539 | /* Store the old selected window's buffer's point in pointm of the old |
| 498 | selected window. It belongs to that window, and when the window is | 540 | selected window. It belongs to that window, and when the window is |
| 499 | not selected, must be in the window. */ | 541 | not selected, must be in the window. */ |
| 500 | if (!inhibit_point_swap) | 542 | if (!inhibit_point_swap) |
| 501 | { | 543 | { |
| 502 | ow = XWINDOW (selected_window); | 544 | struct window *ow = XWINDOW (selected_window); |
| 503 | if (! NILP (ow->buffer)) | 545 | if (! NILP (ow->buffer)) |
| 504 | set_marker_both (ow->pointm, ow->buffer, | 546 | set_marker_both (ow->pointm, ow->buffer, |
| 505 | BUF_PT (XBUFFER (ow->buffer)), | 547 | BUF_PT (XBUFFER (ow->buffer)), |
| @@ -507,7 +549,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) | |||
| 507 | } | 549 | } |
| 508 | 550 | ||
| 509 | selected_window = window; | 551 | selected_window = window; |
| 510 | bset_last_selected_window (XBUFFER (w->buffer), window); | ||
| 511 | 552 | ||
| 512 | /* Go to the point recorded in the window. | 553 | /* Go to the point recorded in the window. |
| 513 | This is important when the buffer is in more | 554 | This is important when the buffer is in more |
| @@ -515,7 +556,7 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) | |||
| 515 | redisplay_window has altered point after scrolling, | 556 | redisplay_window has altered point after scrolling, |
| 516 | because it makes the change only in the window. */ | 557 | because it makes the change only in the window. */ |
| 517 | { | 558 | { |
| 518 | register ptrdiff_t new_point = marker_position (w->pointm); | 559 | register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm); |
| 519 | if (new_point < BEGV) | 560 | if (new_point < BEGV) |
| 520 | SET_PT (BEGV); | 561 | SET_PT (BEGV); |
| 521 | else if (new_point > ZV) | 562 | else if (new_point > ZV) |
| @@ -523,15 +564,14 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) | |||
| 523 | else | 564 | else |
| 524 | SET_PT (new_point); | 565 | SET_PT (new_point); |
| 525 | } | 566 | } |
| 526 | |||
| 527 | windows_or_buffers_changed++; | ||
| 528 | return window; | ||
| 529 | } | 567 | } |
| 530 | 568 | ||
| 531 | DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, | 569 | DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, |
| 532 | doc: /* Select WINDOW. Most editing will apply to WINDOW's buffer. | 570 | doc: /* Select WINDOW which must be a live window. |
| 533 | Also make WINDOW's buffer current and make WINDOW the frame's selected | 571 | Also make WINDOW's frame the selected frame and WINDOW that frame's |
| 534 | window. Return WINDOW. | 572 | selected window. In addition, make WINDOW's buffer current and set that |
| 573 | buffer's value of `point' to the value of WINDOW's `window-point'. | ||
| 574 | Return WINDOW. | ||
| 535 | 575 | ||
| 536 | Optional second arg NORECORD non-nil means do not put this buffer at the | 576 | Optional second arg NORECORD non-nil means do not put this buffer at the |
| 537 | front of the buffer list and do not make this window the most recently | 577 | front of the buffer list and do not make this window the most recently |
| @@ -762,12 +802,12 @@ window_body_cols (struct window *w) | |||
| 762 | occupies one column only. */ | 802 | occupies one column only. */ |
| 763 | width -= 1; | 803 | width -= 1; |
| 764 | 804 | ||
| 805 | /* Display margins cannot be used for normal text. */ | ||
| 806 | width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w); | ||
| 807 | |||
| 765 | if (FRAME_WINDOW_P (f)) | 808 | if (FRAME_WINDOW_P (f)) |
| 766 | /* On window-systems, fringes and display margins cannot be | 809 | /* On window-systems, fringes cannot be used for normal text. */ |
| 767 | used for normal text. */ | 810 | width -= WINDOW_FRINGE_COLS (w); |
| 768 | width -= (WINDOW_FRINGE_COLS (w) | ||
| 769 | + WINDOW_LEFT_MARGIN_COLS (w) | ||
| 770 | + WINDOW_RIGHT_MARGIN_COLS (w)); | ||
| 771 | 811 | ||
| 772 | return width; | 812 | return width; |
| 773 | } | 813 | } |
| @@ -1396,7 +1436,7 @@ window were selected. | |||
| 1396 | 1436 | ||
| 1397 | Note that, when WINDOW is selected, the value returned is the same as | 1437 | Note that, when WINDOW is selected, the value returned is the same as |
| 1398 | that returned by `point' for WINDOW's buffer. It would be more strictly | 1438 | that returned by `point' for WINDOW's buffer. It would be more strictly |
| 1399 | correct to return the `top-level' value of `point', outside of any | 1439 | correct to return the top-level value of `point', outside of any |
| 1400 | `save-excursion' forms. But that is hard to define. */) | 1440 | `save-excursion' forms. But that is hard to define. */) |
| 1401 | (Lisp_Object window) | 1441 | (Lisp_Object window) |
| 1402 | { | 1442 | { |
| @@ -1449,20 +1489,12 @@ if it isn't already recorded. */) | |||
| 1449 | CHECK_BUFFER (buf); | 1489 | CHECK_BUFFER (buf); |
| 1450 | b = XBUFFER (buf); | 1490 | b = XBUFFER (buf); |
| 1451 | 1491 | ||
| 1452 | #if 0 /* This change broke some things. We should make it later. */ | ||
| 1453 | /* If we don't know the end position, return nil. | ||
| 1454 | The user can compute it with vertical-motion if he wants to. | ||
| 1455 | It would be nicer to do it automatically, | ||
| 1456 | but that's so slow that it would probably bother people. */ | ||
| 1457 | if (NILP (w->window_end_valid)) | ||
| 1458 | return Qnil; | ||
| 1459 | #endif | ||
| 1460 | |||
| 1461 | if (! NILP (update) | 1492 | if (! NILP (update) |
| 1462 | && (windows_or_buffers_changed || NILP (w->window_end_valid)) | 1493 | && (windows_or_buffers_changed || !w->window_end_valid) |
| 1463 | && !noninteractive) | 1494 | && !noninteractive) |
| 1464 | { | 1495 | { |
| 1465 | struct text_pos startp; | 1496 | struct text_pos startp; |
| 1497 | ptrdiff_t charpos = marker_position (w->start); | ||
| 1466 | struct it it; | 1498 | struct it it; |
| 1467 | struct buffer *old_buffer = NULL; | 1499 | struct buffer *old_buffer = NULL; |
| 1468 | void *itdata = NULL; | 1500 | void *itdata = NULL; |
| @@ -1480,9 +1512,9 @@ if it isn't already recorded. */) | |||
| 1480 | `-l' containing a call to `rmail' with subsequent other | 1512 | `-l' containing a call to `rmail' with subsequent other |
| 1481 | commands. At the end, W->start happened to be BEG, while | 1513 | commands. At the end, W->start happened to be BEG, while |
| 1482 | rmail had already narrowed the buffer. */ | 1514 | rmail had already narrowed the buffer. */ |
| 1483 | if (XMARKER (w->start)->charpos < BEGV) | 1515 | if (charpos < BEGV) |
| 1484 | SET_TEXT_POS (startp, BEGV, BEGV_BYTE); | 1516 | SET_TEXT_POS (startp, BEGV, BEGV_BYTE); |
| 1485 | else if (XMARKER (w->start)->charpos > ZV) | 1517 | else if (charpos > ZV) |
| 1486 | SET_TEXT_POS (startp, ZV, ZV_BYTE); | 1518 | SET_TEXT_POS (startp, ZV, ZV_BYTE); |
| 1487 | else | 1519 | else |
| 1488 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 1520 | SET_TEXT_POS_FROM_MARKER (startp, w->start); |
| @@ -1512,7 +1544,7 @@ Return POS. */) | |||
| 1512 | { | 1544 | { |
| 1513 | register struct window *w = decode_live_window (window); | 1545 | register struct window *w = decode_live_window (window); |
| 1514 | 1546 | ||
| 1515 | CHECK_NUMBER_COERCE_MARKER (pos); | 1547 | /* Type of POS is checked by Fgoto_char or set_marker_restricted ... */ |
| 1516 | 1548 | ||
| 1517 | if (w == XWINDOW (selected_window)) | 1549 | if (w == XWINDOW (selected_window)) |
| 1518 | { | 1550 | { |
| @@ -1522,6 +1554,8 @@ Return POS. */) | |||
| 1522 | { | 1554 | { |
| 1523 | struct buffer *old_buffer = current_buffer; | 1555 | struct buffer *old_buffer = current_buffer; |
| 1524 | 1556 | ||
| 1557 | /* ... but here we want to catch type error before buffer change. */ | ||
| 1558 | CHECK_NUMBER_COERCE_MARKER (pos); | ||
| 1525 | set_buffer_internal (XBUFFER (w->buffer)); | 1559 | set_buffer_internal (XBUFFER (w->buffer)); |
| 1526 | Fgoto_char (pos); | 1560 | Fgoto_char (pos); |
| 1527 | set_buffer_internal (old_buffer); | 1561 | set_buffer_internal (old_buffer); |
| @@ -1547,9 +1581,8 @@ overriding motion of point in order to display at this exact start. */) | |||
| 1547 | { | 1581 | { |
| 1548 | register struct window *w = decode_live_window (window); | 1582 | register struct window *w = decode_live_window (window); |
| 1549 | 1583 | ||
| 1550 | CHECK_NUMBER_COERCE_MARKER (pos); | ||
| 1551 | set_marker_restricted (w->start, pos, w->buffer); | 1584 | set_marker_restricted (w->start, pos, w->buffer); |
| 1552 | /* this is not right, but much easier than doing what is right. */ | 1585 | /* This is not right, but much easier than doing what is right. */ |
| 1553 | w->start_at_line_beg = 0; | 1586 | w->start_at_line_beg = 0; |
| 1554 | if (NILP (noforce)) | 1587 | if (NILP (noforce)) |
| 1555 | w->force_start = 1; | 1588 | w->force_start = 1; |
| @@ -1605,7 +1638,7 @@ display row, and VPOS is the row number (0-based) containing POS. */) | |||
| 1605 | else if (w == XWINDOW (selected_window)) | 1638 | else if (w == XWINDOW (selected_window)) |
| 1606 | posint = PT; | 1639 | posint = PT; |
| 1607 | else | 1640 | else |
| 1608 | posint = XMARKER (w->pointm)->charpos; | 1641 | posint = marker_position (w->pointm); |
| 1609 | 1642 | ||
| 1610 | /* If position is above window start or outside buffer boundaries, | 1643 | /* If position is above window start or outside buffer boundaries, |
| 1611 | or if window start is out of range, position is not visible. */ | 1644 | or if window start is out of range, position is not visible. */ |
| @@ -1665,7 +1698,7 @@ Return nil if window display is not up-to-date. In that case, use | |||
| 1665 | b = XBUFFER (w->buffer); | 1698 | b = XBUFFER (w->buffer); |
| 1666 | 1699 | ||
| 1667 | /* Fail if current matrix is not up-to-date. */ | 1700 | /* Fail if current matrix is not up-to-date. */ |
| 1668 | if (NILP (w->window_end_valid) | 1701 | if (!w->window_end_valid |
| 1669 | || current_buffer->clip_changed | 1702 | || current_buffer->clip_changed |
| 1670 | || current_buffer->prevent_redisplay_optimizations_p | 1703 | || current_buffer->prevent_redisplay_optimizations_p |
| 1671 | || w->last_modified < BUF_MODIFF (b) | 1704 | || w->last_modified < BUF_MODIFF (b) |
| @@ -1951,7 +1984,7 @@ unshow_buffer (register struct window *w) | |||
| 1951 | && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer))) | 1984 | && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer))) |
| 1952 | temp_set_point_both (b, | 1985 | temp_set_point_both (b, |
| 1953 | clip_to_bounds (BUF_BEGV (b), | 1986 | clip_to_bounds (BUF_BEGV (b), |
| 1954 | XMARKER (w->pointm)->charpos, | 1987 | marker_position (w->pointm), |
| 1955 | BUF_ZV (b)), | 1988 | BUF_ZV (b)), |
| 1956 | clip_to_bounds (BUF_BEGV_BYTE (b), | 1989 | clip_to_bounds (BUF_BEGV_BYTE (b), |
| 1957 | marker_byte_position (w->pointm), | 1990 | marker_byte_position (w->pointm), |
| @@ -1997,7 +2030,7 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag) | |||
| 1997 | n->pseudo_window_p = 0; | 2030 | n->pseudo_window_p = 0; |
| 1998 | wset_window_end_vpos (n, make_number (0)); | 2031 | wset_window_end_vpos (n, make_number (0)); |
| 1999 | wset_window_end_pos (n, make_number (0)); | 2032 | wset_window_end_pos (n, make_number (0)); |
| 2000 | wset_window_end_valid (n, Qnil); | 2033 | n->window_end_valid = 0; |
| 2001 | n->frozen_window_start_p = 0; | 2034 | n->frozen_window_start_p = 0; |
| 2002 | } | 2035 | } |
| 2003 | 2036 | ||
| @@ -2197,7 +2230,6 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf | |||
| 2197 | } | 2230 | } |
| 2198 | else if (EQ (all_frames, Qvisible)) | 2231 | else if (EQ (all_frames, Qvisible)) |
| 2199 | { | 2232 | { |
| 2200 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 2201 | candidate_p = FRAME_VISIBLE_P (f) | 2233 | candidate_p = FRAME_VISIBLE_P (f) |
| 2202 | && (FRAME_TERMINAL (XFRAME (w->frame)) | 2234 | && (FRAME_TERMINAL (XFRAME (w->frame)) |
| 2203 | == FRAME_TERMINAL (XFRAME (selected_frame))); | 2235 | == FRAME_TERMINAL (XFRAME (selected_frame))); |
| @@ -2205,7 +2237,6 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf | |||
| 2205 | } | 2237 | } |
| 2206 | else if (INTEGERP (all_frames) && XINT (all_frames) == 0) | 2238 | else if (INTEGERP (all_frames) && XINT (all_frames) == 0) |
| 2207 | { | 2239 | { |
| 2208 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 2209 | candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f) | 2240 | candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f) |
| 2210 | #ifdef HAVE_X_WINDOWS | 2241 | #ifdef HAVE_X_WINDOWS |
| 2211 | /* Yuck!! If we've just created the frame and the | 2242 | /* Yuck!! If we've just created the frame and the |
| @@ -2932,7 +2963,7 @@ window-start value is reasonable when this function is called. */) | |||
| 2932 | pos = *vmotion (startpos, -top, w); | 2963 | pos = *vmotion (startpos, -top, w); |
| 2933 | 2964 | ||
| 2934 | set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); | 2965 | set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); |
| 2935 | wset_window_end_valid (w, Qnil); | 2966 | w->window_end_valid = 0; |
| 2936 | w->start_at_line_beg = (pos.bytepos == BEGV_BYTE | 2967 | w->start_at_line_beg = (pos.bytepos == BEGV_BYTE |
| 2937 | || FETCH_BYTE (pos.bytepos - 1) == '\n'); | 2968 | || FETCH_BYTE (pos.bytepos - 1) == '\n'); |
| 2938 | /* We need to do this, so that the window-scroll-functions | 2969 | /* We need to do this, so that the window-scroll-functions |
| @@ -2958,22 +2989,24 @@ replace_buffer_in_windows (Lisp_Object buffer) | |||
| 2958 | call1 (Qreplace_buffer_in_windows, buffer); | 2989 | call1 (Qreplace_buffer_in_windows, buffer); |
| 2959 | } | 2990 | } |
| 2960 | 2991 | ||
| 2961 | 2992 | /* If BUFFER is shown in a window, safely replace it with some other | |
| 2962 | /* Safely replace BUFFER with some other buffer in all windows of all | 2993 | buffer in all windows of all frames, even those on other keyboards. */ |
| 2963 | frames, even those on other keyboards. */ | ||
| 2964 | 2994 | ||
| 2965 | void | 2995 | void |
| 2966 | replace_buffer_in_windows_safely (Lisp_Object buffer) | 2996 | replace_buffer_in_windows_safely (Lisp_Object buffer) |
| 2967 | { | 2997 | { |
| 2968 | Lisp_Object tail, frame; | 2998 | if (buffer_window_count (XBUFFER (buffer))) |
| 2999 | { | ||
| 3000 | Lisp_Object tail, frame; | ||
| 2969 | 3001 | ||
| 2970 | /* A single call to window_loop won't do the job because it only | 3002 | /* A single call to window_loop won't do the job because it only |
| 2971 | considers frames on the current keyboard. So loop manually over | 3003 | considers frames on the current keyboard. So loop manually over |
| 2972 | frames, and handle each one. */ | 3004 | frames, and handle each one. */ |
| 2973 | FOR_EACH_FRAME (tail, frame) | 3005 | FOR_EACH_FRAME (tail, frame) |
| 2974 | window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame); | 3006 | window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame); |
| 3007 | } | ||
| 2975 | } | 3008 | } |
| 2976 | 3009 | ||
| 2977 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the | 3010 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
| 2978 | minimum allowable size. */ | 3011 | minimum allowable size. */ |
| 2979 | 3012 | ||
| @@ -3146,7 +3179,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int | |||
| 3146 | wset_window_end_pos (w, make_number (0)); | 3179 | wset_window_end_pos (w, make_number (0)); |
| 3147 | wset_window_end_vpos (w, make_number (0)); | 3180 | wset_window_end_vpos (w, make_number (0)); |
| 3148 | memset (&w->last_cursor, 0, sizeof w->last_cursor); | 3181 | memset (&w->last_cursor, 0, sizeof w->last_cursor); |
| 3149 | wset_window_end_valid (w, Qnil); | 3182 | |
| 3150 | if (!(keep_margins_p && samebuf)) | 3183 | if (!(keep_margins_p && samebuf)) |
| 3151 | { /* If we're not actually changing the buffer, don't reset hscroll and | 3184 | { /* If we're not actually changing the buffer, don't reset hscroll and |
| 3152 | vscroll. This case happens for example when called from | 3185 | vscroll. This case happens for example when called from |
| @@ -3308,11 +3341,11 @@ displaying that buffer. */) | |||
| 3308 | 3341 | ||
| 3309 | if (STRINGP (object)) | 3342 | if (STRINGP (object)) |
| 3310 | object = Fget_buffer (object); | 3343 | object = Fget_buffer (object); |
| 3311 | if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object))) | 3344 | if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)) |
| 3345 | && buffer_window_count (XBUFFER (object))) | ||
| 3312 | { | 3346 | { |
| 3313 | /* Walk all windows looking for buffer, and force update | 3347 | /* If buffer is live and shown in at least one window, find |
| 3314 | of each of those windows. */ | 3348 | all windows showing this buffer and force update of them. */ |
| 3315 | |||
| 3316 | object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, 0, Qvisible); | 3349 | object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, 0, Qvisible); |
| 3317 | return NILP (object) ? Qnil : Qt; | 3350 | return NILP (object) ? Qnil : Qt; |
| 3318 | } | 3351 | } |
| @@ -3391,10 +3424,10 @@ make_parent_window (Lisp_Object window, int horflag) | |||
| 3391 | memcpy ((char *) p + sizeof (struct vectorlike_header), | 3424 | memcpy ((char *) p + sizeof (struct vectorlike_header), |
| 3392 | (char *) o + sizeof (struct vectorlike_header), | 3425 | (char *) o + sizeof (struct vectorlike_header), |
| 3393 | word_size * VECSIZE (struct window)); | 3426 | word_size * VECSIZE (struct window)); |
| 3427 | /* P's buffer slot may change from nil to a buffer. */ | ||
| 3428 | adjust_window_count (p, 1); | ||
| 3394 | XSETWINDOW (parent, p); | 3429 | XSETWINDOW (parent, p); |
| 3395 | 3430 | ||
| 3396 | p->sequence_number = ++sequence_number; | ||
| 3397 | |||
| 3398 | replace_window (window, parent, 1); | 3431 | replace_window (window, parent, 1); |
| 3399 | 3432 | ||
| 3400 | wset_next (o, Qnil); | 3433 | wset_next (o, Qnil); |
| @@ -3443,7 +3476,7 @@ make_window (void) | |||
| 3443 | w->nrows_scale_factor = w->ncols_scale_factor = 1; | 3476 | w->nrows_scale_factor = w->ncols_scale_factor = 1; |
| 3444 | w->phys_cursor_type = -1; | 3477 | w->phys_cursor_type = -1; |
| 3445 | w->phys_cursor_width = -1; | 3478 | w->phys_cursor_width = -1; |
| 3446 | w->sequence_number = ++sequence_number; | 3479 | w->column_number_displayed = -1; |
| 3447 | 3480 | ||
| 3448 | /* Reset window_list. */ | 3481 | /* Reset window_list. */ |
| 3449 | Vwindow_list = Qnil; | 3482 | Vwindow_list = Qnil; |
| @@ -3913,7 +3946,7 @@ set correctly. See the code of `split-window' for how this is done. */) | |||
| 3913 | wset_next (o, new); | 3946 | wset_next (o, new); |
| 3914 | } | 3947 | } |
| 3915 | 3948 | ||
| 3916 | wset_window_end_valid (n, Qnil); | 3949 | n->window_end_valid = 0; |
| 3917 | memset (&n->last_cursor, 0, sizeof n->last_cursor); | 3950 | memset (&n->last_cursor, 0, sizeof n->last_cursor); |
| 3918 | 3951 | ||
| 3919 | /* Get special geometry settings from reference window. */ | 3952 | /* Get special geometry settings from reference window. */ |
| @@ -4583,9 +4616,9 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4583 | } | 4616 | } |
| 4584 | 4617 | ||
| 4585 | /* Set the window start, and set up the window for redisplay. */ | 4618 | /* Set the window start, and set up the window for redisplay. */ |
| 4586 | set_marker_restricted (w->start, make_number (pos), | 4619 | set_marker_restricted_both (w->start, w->buffer, IT_CHARPOS (it), |
| 4587 | w->buffer); | 4620 | IT_BYTEPOS (it)); |
| 4588 | bytepos = XMARKER (w->start)->bytepos; | 4621 | bytepos = marker_byte_position (w->start); |
| 4589 | w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); | 4622 | w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); |
| 4590 | w->update_mode_line = 1; | 4623 | w->update_mode_line = 1; |
| 4591 | w->last_modified = 0; | 4624 | w->last_modified = 0; |
| @@ -5085,6 +5118,7 @@ displayed_window_lines (struct window *w) | |||
| 5085 | { | 5118 | { |
| 5086 | struct it it; | 5119 | struct it it; |
| 5087 | struct text_pos start; | 5120 | struct text_pos start; |
| 5121 | ptrdiff_t charpos = marker_position (w->start); | ||
| 5088 | int height = window_box_height (w); | 5122 | int height = window_box_height (w); |
| 5089 | struct buffer *old_buffer; | 5123 | struct buffer *old_buffer; |
| 5090 | int bottom_y; | 5124 | int bottom_y; |
| @@ -5101,9 +5135,9 @@ displayed_window_lines (struct window *w) | |||
| 5101 | /* In case W->start is out of the accessible range, do something | 5135 | /* In case W->start is out of the accessible range, do something |
| 5102 | reasonable. This happens in Info mode when Info-scroll-down | 5136 | reasonable. This happens in Info mode when Info-scroll-down |
| 5103 | calls (recenter -1) while W->start is 1. */ | 5137 | calls (recenter -1) while W->start is 1. */ |
| 5104 | if (XMARKER (w->start)->charpos < BEGV) | 5138 | if (charpos < BEGV) |
| 5105 | SET_TEXT_POS (start, BEGV, BEGV_BYTE); | 5139 | SET_TEXT_POS (start, BEGV, BEGV_BYTE); |
| 5106 | else if (XMARKER (w->start)->charpos > ZV) | 5140 | else if (charpos > ZV) |
| 5107 | SET_TEXT_POS (start, ZV, ZV_BYTE); | 5141 | SET_TEXT_POS (start, ZV, ZV_BYTE); |
| 5108 | else | 5142 | else |
| 5109 | SET_TEXT_POS_FROM_MARKER (start, w->start); | 5143 | SET_TEXT_POS_FROM_MARKER (start, w->start); |
| @@ -5312,8 +5346,8 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5312 | iarg += ht; | 5346 | iarg += ht; |
| 5313 | 5347 | ||
| 5314 | /* Don't let it get into the margin at either top or bottom. */ | 5348 | /* Don't let it get into the margin at either top or bottom. */ |
| 5315 | iarg = max (iarg, this_scroll_margin); | 5349 | iarg = clip_to_bounds (this_scroll_margin, iarg, |
| 5316 | iarg = min (iarg, ht - this_scroll_margin - 1); | 5350 | ht - this_scroll_margin - 1); |
| 5317 | 5351 | ||
| 5318 | pos = *vmotion (PT, - iarg, w); | 5352 | pos = *vmotion (PT, - iarg, w); |
| 5319 | charpos = pos.bufpos; | 5353 | charpos = pos.bufpos; |
| @@ -5322,7 +5356,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5322 | 5356 | ||
| 5323 | /* Set the new window start. */ | 5357 | /* Set the new window start. */ |
| 5324 | set_marker_both (w->start, w->buffer, charpos, bytepos); | 5358 | set_marker_both (w->start, w->buffer, charpos, bytepos); |
| 5325 | wset_window_end_valid (w, Qnil); | 5359 | w->window_end_valid = 0; |
| 5326 | 5360 | ||
| 5327 | w->optional_new_start = 1; | 5361 | w->optional_new_start = 1; |
| 5328 | 5362 | ||
| @@ -5531,7 +5565,7 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5531 | && WINDOWP (selected_window) | 5565 | && WINDOWP (selected_window) |
| 5532 | && EQ (XWINDOW (selected_window)->buffer, new_current_buffer) | 5566 | && EQ (XWINDOW (selected_window)->buffer, new_current_buffer) |
| 5533 | && !EQ (selected_window, data->current_window)) | 5567 | && !EQ (selected_window, data->current_window)) |
| 5534 | old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos; | 5568 | old_point = marker_position (XWINDOW (data->current_window)->pointm); |
| 5535 | else | 5569 | else |
| 5536 | old_point = PT; | 5570 | old_point = PT; |
| 5537 | else | 5571 | else |
| @@ -5546,7 +5580,7 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5546 | if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) | 5580 | if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) |
| 5547 | /* If current_window = selected_window, its point is in BUF_PT. */ | 5581 | /* If current_window = selected_window, its point is in BUF_PT. */ |
| 5548 | && !EQ (selected_window, data->current_window)) | 5582 | && !EQ (selected_window, data->current_window)) |
| 5549 | old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos; | 5583 | old_point = marker_position (XWINDOW (data->current_window)->pointm); |
| 5550 | else | 5584 | else |
| 5551 | old_point = BUF_PT (XBUFFER (new_current_buffer)); | 5585 | old_point = BUF_PT (XBUFFER (new_current_buffer)); |
| 5552 | } | 5586 | } |
| @@ -5762,8 +5796,7 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5762 | { | 5796 | { |
| 5763 | /* Set window markers at start of visible range. */ | 5797 | /* Set window markers at start of visible range. */ |
| 5764 | if (XMARKER (w->start)->buffer == 0) | 5798 | if (XMARKER (w->start)->buffer == 0) |
| 5765 | set_marker_restricted (w->start, make_number (0), | 5799 | set_marker_restricted_both (w->start, w->buffer, 0, 0); |
| 5766 | w->buffer); | ||
| 5767 | if (XMARKER (w->pointm)->buffer == 0) | 5800 | if (XMARKER (w->pointm)->buffer == 0) |
| 5768 | set_marker_restricted_both | 5801 | set_marker_restricted_both |
| 5769 | (w->pointm, w->buffer, | 5802 | (w->pointm, w->buffer, |
| @@ -5781,10 +5814,8 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5781 | wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); | 5814 | wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); |
| 5782 | /* This will set the markers to beginning of visible | 5815 | /* This will set the markers to beginning of visible |
| 5783 | range. */ | 5816 | range. */ |
| 5784 | set_marker_restricted (w->start, | 5817 | set_marker_restricted_both (w->start, w->buffer, 0, 0); |
| 5785 | make_number (0), w->buffer); | 5818 | set_marker_restricted_both (w->pointm, w->buffer, 0, 0); |
| 5786 | set_marker_restricted (w->pointm, | ||
| 5787 | make_number (0), w->buffer); | ||
| 5788 | w->start_at_line_beg = 1; | 5819 | w->start_at_line_beg = 1; |
| 5789 | if (!NILP (w->dedicated)) | 5820 | if (!NILP (w->dedicated)) |
| 5790 | /* Record this window as dead. */ | 5821 | /* Record this window as dead. */ |
| @@ -6157,11 +6188,11 @@ saved by this function. */) | |||
| 6157 | data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil; | 6188 | data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil; |
| 6158 | data->root_window = FRAME_ROOT_WINDOW (f); | 6189 | data->root_window = FRAME_ROOT_WINDOW (f); |
| 6159 | data->focus_frame = FRAME_FOCUS_FRAME (f); | 6190 | data->focus_frame = FRAME_FOCUS_FRAME (f); |
| 6160 | tem = Fmake_vector (make_number (n_windows), Qnil); | 6191 | tem = make_uninit_vector (n_windows); |
| 6161 | data->saved_windows = tem; | 6192 | data->saved_windows = tem; |
| 6162 | for (i = 0; i < n_windows; i++) | 6193 | for (i = 0; i < n_windows; i++) |
| 6163 | ASET (tem, i, | 6194 | ASET (tem, i, |
| 6164 | Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil)); | 6195 | Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil)); |
| 6165 | save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0); | 6196 | save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0); |
| 6166 | XSETWINDOW_CONFIGURATION (tem, data); | 6197 | XSETWINDOW_CONFIGURATION (tem, data); |
| 6167 | return (tem); | 6198 | return (tem); |
| @@ -6273,7 +6304,7 @@ display marginal areas and the text area. */) | |||
| 6273 | adjust_window_margins (w); | 6304 | adjust_window_margins (w); |
| 6274 | 6305 | ||
| 6275 | clear_glyph_matrix (w->current_matrix); | 6306 | clear_glyph_matrix (w->current_matrix); |
| 6276 | wset_window_end_valid (w, Qnil); | 6307 | w->window_end_valid = 0; |
| 6277 | 6308 | ||
| 6278 | ++windows_or_buffers_changed; | 6309 | ++windows_or_buffers_changed; |
| 6279 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); | 6310 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); |
| @@ -6343,7 +6374,7 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */) | |||
| 6343 | adjust_window_margins (w); | 6374 | adjust_window_margins (w); |
| 6344 | 6375 | ||
| 6345 | clear_glyph_matrix (w->current_matrix); | 6376 | clear_glyph_matrix (w->current_matrix); |
| 6346 | wset_window_end_valid (w, Qnil); | 6377 | w->window_end_valid = 0; |
| 6347 | 6378 | ||
| 6348 | ++windows_or_buffers_changed; | 6379 | ++windows_or_buffers_changed; |
| 6349 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); | 6380 | adjust_glyphs (XFRAME (WINDOW_FRAME (w))); |
| @@ -6747,7 +6778,8 @@ same combination. | |||
| 6747 | 6778 | ||
| 6748 | Other values are reserved for future use. | 6779 | Other values are reserved for future use. |
| 6749 | 6780 | ||
| 6750 | This variable takes no effect if `window-combination-limit' is non-nil. */); | 6781 | This variable takes no effect if the variable `window-combination-limit' is |
| 6782 | non-nil. */); | ||
| 6751 | Vwindow_combination_resize = Qnil; | 6783 | Vwindow_combination_resize = Qnil; |
| 6752 | 6784 | ||
| 6753 | DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit, | 6785 | DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit, |
diff --git a/src/window.h b/src/window.h index 2a12226c0aa..dcef37abb4c 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Window definitions for GNU Emacs. | 1 | /* Window definitions for GNU Emacs. |
| 2 | Copyright (C) 1985-1986, 1993, 1995, 1997-2012 | 2 | Copyright (C) 1985-1986, 1993, 1995, 1997-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -175,17 +175,13 @@ struct window | |||
| 175 | no scroll bar. A value of t means use frame value. */ | 175 | no scroll bar. A value of t means use frame value. */ |
| 176 | Lisp_Object vertical_scroll_bar_type; | 176 | Lisp_Object vertical_scroll_bar_type; |
| 177 | 177 | ||
| 178 | /* Z - the buffer position of the last glyph in the current matrix | 178 | /* Z - the buffer position of the last glyph in the current |
| 179 | of W. Only valid if WINDOW_END_VALID is not nil. */ | 179 | matrix of W. Only valid if window_end_valid is nonzero. */ |
| 180 | Lisp_Object window_end_pos; | 180 | Lisp_Object window_end_pos; |
| 181 | |||
| 181 | /* Glyph matrix row of the last glyph in the current matrix | 182 | /* Glyph matrix row of the last glyph in the current matrix |
| 182 | of W. Only valid if WINDOW_END_VALID is not nil. */ | 183 | of W. Only valid if window_end_valid is nonzero. */ |
| 183 | Lisp_Object window_end_vpos; | 184 | Lisp_Object window_end_vpos; |
| 184 | /* t if window_end_pos is truly valid. | ||
| 185 | This is nil if nontrivial redisplay is preempted | ||
| 186 | since in that case the frame image that window_end_pos | ||
| 187 | did not get onto the frame. */ | ||
| 188 | Lisp_Object window_end_valid; | ||
| 189 | 185 | ||
| 190 | /* Display-table to use for displaying chars in this window. | 186 | /* Display-table to use for displaying chars in this window. |
| 191 | Nil means use the buffer's own display-table. */ | 187 | Nil means use the buffer's own display-table. */ |
| @@ -196,23 +192,6 @@ struct window | |||
| 196 | and Qt, so bitfield can't be used here. */ | 192 | and Qt, so bitfield can't be used here. */ |
| 197 | Lisp_Object dedicated; | 193 | Lisp_Object dedicated; |
| 198 | 194 | ||
| 199 | /* Line number and position of a line somewhere above the top of the | ||
| 200 | screen. If this field is nil, it means we don't have a base | ||
| 201 | line. */ | ||
| 202 | Lisp_Object base_line_number; | ||
| 203 | /* If this field is nil, it means we don't have a base line. | ||
| 204 | If it is a buffer, it means don't display the line number | ||
| 205 | as long as the window shows that buffer. */ | ||
| 206 | Lisp_Object base_line_pos; | ||
| 207 | |||
| 208 | /* If we have highlighted the region (or any part of it), | ||
| 209 | this is the mark position that we used, as an integer. */ | ||
| 210 | Lisp_Object region_showing; | ||
| 211 | |||
| 212 | /* The column number currently displayed in this window's mode line, | ||
| 213 | or nil if column numbers are not being displayed. */ | ||
| 214 | Lisp_Object column_number_displayed; | ||
| 215 | |||
| 216 | /* If redisplay in this window goes beyond this buffer position, | 195 | /* If redisplay in this window goes beyond this buffer position, |
| 217 | must run the redisplay-end-trigger-hook. */ | 196 | must run the redisplay-end-trigger-hook. */ |
| 218 | Lisp_Object redisplay_end_trigger; | 197 | Lisp_Object redisplay_end_trigger; |
| @@ -242,9 +221,6 @@ struct window | |||
| 242 | /* Number saying how recently window was selected. */ | 221 | /* Number saying how recently window was selected. */ |
| 243 | int use_time; | 222 | int use_time; |
| 244 | 223 | ||
| 245 | /* Unique number of window assigned when it was created. */ | ||
| 246 | int sequence_number; | ||
| 247 | |||
| 248 | /* Number of columns display within the window is scrolled to the left. */ | 224 | /* Number of columns display within the window is scrolled to the left. */ |
| 249 | ptrdiff_t hscroll; | 225 | ptrdiff_t hscroll; |
| 250 | 226 | ||
| @@ -261,9 +237,22 @@ struct window | |||
| 261 | EMACS_INT last_overlay_modified; | 237 | EMACS_INT last_overlay_modified; |
| 262 | 238 | ||
| 263 | /* Value of point at that time. Since this is a position in a buffer, | 239 | /* Value of point at that time. Since this is a position in a buffer, |
| 264 | it should be positive. */ | 240 | it should be positive. */ |
| 265 | ptrdiff_t last_point; | 241 | ptrdiff_t last_point; |
| 266 | 242 | ||
| 243 | /* Line number and position of a line somewhere above the top of the | ||
| 244 | screen. If this field is zero, it means we don't have a base line. */ | ||
| 245 | ptrdiff_t base_line_number; | ||
| 246 | |||
| 247 | /* If this field is zero, it means we don't have a base line. | ||
| 248 | If it is -1, it means don't display the line number as long | ||
| 249 | as the window shows its buffer. */ | ||
| 250 | ptrdiff_t base_line_pos; | ||
| 251 | |||
| 252 | /* The column number currently displayed in this window's mode | ||
| 253 | line, or -1 if column numbers are not being displayed. */ | ||
| 254 | ptrdiff_t column_number_displayed; | ||
| 255 | |||
| 267 | /* Scaling factor for the glyph_matrix size calculation in this window. | 256 | /* Scaling factor for the glyph_matrix size calculation in this window. |
| 268 | Used if window contains many small images or uses proportional fonts, | 257 | Used if window contains many small images or uses proportional fonts, |
| 269 | as the normal may yield a matrix which is too small. */ | 258 | as the normal may yield a matrix which is too small. */ |
| @@ -290,7 +279,7 @@ struct window | |||
| 290 | /* Non-zero if this window is a minibuffer window. */ | 279 | /* Non-zero if this window is a minibuffer window. */ |
| 291 | unsigned mini : 1; | 280 | unsigned mini : 1; |
| 292 | 281 | ||
| 293 | /* Non-zero means must regenerate mode line of this window */ | 282 | /* Non-zero means must regenerate mode line of this window. */ |
| 294 | unsigned update_mode_line : 1; | 283 | unsigned update_mode_line : 1; |
| 295 | 284 | ||
| 296 | /* Non-nil if the buffer was "modified" when the window | 285 | /* Non-nil if the buffer was "modified" when the window |
| @@ -339,23 +328,27 @@ struct window | |||
| 339 | Otherwise draw them between margin areas and text. */ | 328 | Otherwise draw them between margin areas and text. */ |
| 340 | unsigned fringes_outside_margins : 1; | 329 | unsigned fringes_outside_margins : 1; |
| 341 | 330 | ||
| 331 | /* Nonzero if window_end_pos and window_end_vpos are truly valid. | ||
| 332 | This is zero if nontrivial redisplay is preempted since in that case | ||
| 333 | the frame image that window_end_pos did not get onto the frame. */ | ||
| 334 | unsigned window_end_valid : 1; | ||
| 335 | |||
| 342 | /* Amount by which lines of this window are scrolled in | 336 | /* Amount by which lines of this window are scrolled in |
| 343 | y-direction (smooth scrolling). */ | 337 | y-direction (smooth scrolling). */ |
| 344 | int vscroll; | 338 | int vscroll; |
| 345 | 339 | ||
| 346 | /* Z_BYTE - the buffer position of the last glyph in the current matrix of W. | 340 | /* If we have highlighted the region (or any part of it), the mark |
| 347 | Should be nonnegative, and only valid if window_end_valid is not nil. */ | 341 | (region start) position; otherwise zero. */ |
| 342 | ptrdiff_t region_showing; | ||
| 343 | |||
| 344 | /* Z_BYTE - buffer position of the last glyph in the current matrix of W. | ||
| 345 | Should be nonnegative, and only valid if window_end_valid is nonzero. */ | ||
| 348 | ptrdiff_t window_end_bytepos; | 346 | ptrdiff_t window_end_bytepos; |
| 349 | }; | 347 | }; |
| 350 | 348 | ||
| 351 | /* Most code should use these functions to set Lisp fields in struct | 349 | /* Most code should use these functions to set Lisp fields in struct |
| 352 | window. */ | 350 | window. */ |
| 353 | WINDOW_INLINE void | 351 | WINDOW_INLINE void |
| 354 | wset_buffer (struct window *w, Lisp_Object val) | ||
| 355 | { | ||
| 356 | w->buffer = val; | ||
| 357 | } | ||
| 358 | WINDOW_INLINE void | ||
| 359 | wset_frame (struct window *w, Lisp_Object val) | 352 | wset_frame (struct window *w, Lisp_Object val) |
| 360 | { | 353 | { |
| 361 | w->frame = val; | 354 | w->frame = val; |
| @@ -406,11 +399,6 @@ wset_window_end_pos (struct window *w, Lisp_Object val) | |||
| 406 | w->window_end_pos = val; | 399 | w->window_end_pos = val; |
| 407 | } | 400 | } |
| 408 | WINDOW_INLINE void | 401 | WINDOW_INLINE void |
| 409 | wset_window_end_valid (struct window *w, Lisp_Object val) | ||
| 410 | { | ||
| 411 | w->window_end_valid = val; | ||
| 412 | } | ||
| 413 | WINDOW_INLINE void | ||
| 414 | wset_window_end_vpos (struct window *w, Lisp_Object val) | 402 | wset_window_end_vpos (struct window *w, Lisp_Object val) |
| 415 | { | 403 | { |
| 416 | w->window_end_vpos = val; | 404 | w->window_end_vpos = val; |
| @@ -939,7 +927,7 @@ extern EMACS_INT minibuf_level; | |||
| 939 | extern int update_mode_lines; | 927 | extern int update_mode_lines; |
| 940 | 928 | ||
| 941 | /* Nonzero if window sizes or contents have changed since last | 929 | /* Nonzero if window sizes or contents have changed since last |
| 942 | redisplay that finished */ | 930 | redisplay that finished. */ |
| 943 | 931 | ||
| 944 | extern int windows_or_buffers_changed; | 932 | extern int windows_or_buffers_changed; |
| 945 | 933 | ||
| @@ -947,11 +935,6 @@ extern int windows_or_buffers_changed; | |||
| 947 | 935 | ||
| 948 | extern int cursor_type_changed; | 936 | extern int cursor_type_changed; |
| 949 | 937 | ||
| 950 | /* Number of windows displaying the selected buffer. Normally this is | ||
| 951 | 1, but it can be more. */ | ||
| 952 | |||
| 953 | extern int buffer_shared; | ||
| 954 | |||
| 955 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the | 938 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
| 956 | minimum allowable size. */ | 939 | minimum allowable size. */ |
| 957 | 940 | ||
| @@ -997,6 +980,8 @@ extern int window_body_cols (struct window *w); | |||
| 997 | extern void temp_output_buffer_show (Lisp_Object); | 980 | extern void temp_output_buffer_show (Lisp_Object); |
| 998 | extern void replace_buffer_in_windows (Lisp_Object); | 981 | extern void replace_buffer_in_windows (Lisp_Object); |
| 999 | extern void replace_buffer_in_windows_safely (Lisp_Object); | 982 | extern void replace_buffer_in_windows_safely (Lisp_Object); |
| 983 | /* This looks like a setter, but it is a bit special. */ | ||
| 984 | extern void wset_buffer (struct window *, Lisp_Object); | ||
| 1000 | extern void init_window_once (void); | 985 | extern void init_window_once (void); |
| 1001 | extern void init_window (void); | 986 | extern void init_window (void); |
| 1002 | extern void syms_of_window (void); | 987 | extern void syms_of_window (void); |
diff --git a/src/xdisp.c b/src/xdisp.c index 9464e87b362..08958f44575 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Display generation from window structure and buffer text. | 1 | /* Display generation from window structure and buffer text. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -366,28 +367,6 @@ Lisp_Object Qcenter; | |||
| 366 | static Lisp_Object Qmargin, Qpointer; | 367 | static Lisp_Object Qmargin, Qpointer; |
| 367 | static Lisp_Object Qline_height; | 368 | static Lisp_Object Qline_height; |
| 368 | 369 | ||
| 369 | /* These setters are used only in this file, so they can be private. */ | ||
| 370 | static void | ||
| 371 | wset_base_line_number (struct window *w, Lisp_Object val) | ||
| 372 | { | ||
| 373 | w->base_line_number = val; | ||
| 374 | } | ||
| 375 | static void | ||
| 376 | wset_base_line_pos (struct window *w, Lisp_Object val) | ||
| 377 | { | ||
| 378 | w->base_line_pos = val; | ||
| 379 | } | ||
| 380 | static void | ||
| 381 | wset_column_number_displayed (struct window *w, Lisp_Object val) | ||
| 382 | { | ||
| 383 | w->column_number_displayed = val; | ||
| 384 | } | ||
| 385 | static void | ||
| 386 | wset_region_showing (struct window *w, Lisp_Object val) | ||
| 387 | { | ||
| 388 | w->region_showing = val; | ||
| 389 | } | ||
| 390 | |||
| 391 | #ifdef HAVE_WINDOW_SYSTEM | 370 | #ifdef HAVE_WINDOW_SYSTEM |
| 392 | 371 | ||
| 393 | /* Test if overflow newline into fringe. Called with iterator IT | 372 | /* Test if overflow newline into fringe. Called with iterator IT |
| @@ -515,11 +494,6 @@ Lisp_Object Qmenu_bar_update_hook; | |||
| 515 | 494 | ||
| 516 | static int overlay_arrow_seen; | 495 | static int overlay_arrow_seen; |
| 517 | 496 | ||
| 518 | /* Number of windows showing the buffer of the selected | ||
| 519 | window (or another buffer with the same base buffer). */ | ||
| 520 | |||
| 521 | int buffer_shared; | ||
| 522 | |||
| 523 | /* Vector containing glyphs for an ellipsis `...'. */ | 497 | /* Vector containing glyphs for an ellipsis `...'. */ |
| 524 | 498 | ||
| 525 | static Lisp_Object default_invis_vector[3]; | 499 | static Lisp_Object default_invis_vector[3]; |
| @@ -844,17 +818,17 @@ static void ensure_echo_area_buffers (void); | |||
| 844 | static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object); | 818 | static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object); |
| 845 | static Lisp_Object with_echo_area_buffer_unwind_data (struct window *); | 819 | static Lisp_Object with_echo_area_buffer_unwind_data (struct window *); |
| 846 | static int with_echo_area_buffer (struct window *, int, | 820 | static int with_echo_area_buffer (struct window *, int, |
| 847 | int (*) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t), | 821 | int (*) (ptrdiff_t, Lisp_Object), |
| 848 | ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t); | 822 | ptrdiff_t, Lisp_Object); |
| 849 | static void clear_garbaged_frames (void); | 823 | static void clear_garbaged_frames (void); |
| 850 | static int current_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t); | 824 | static int current_message_1 (ptrdiff_t, Lisp_Object); |
| 851 | static void pop_message (void); | 825 | static void pop_message (void); |
| 852 | static int truncate_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t); | 826 | static int truncate_message_1 (ptrdiff_t, Lisp_Object); |
| 853 | static void set_message (const char *, Lisp_Object, ptrdiff_t, int); | 827 | static void set_message (Lisp_Object); |
| 854 | static int set_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t); | 828 | static int set_message_1 (ptrdiff_t, Lisp_Object); |
| 855 | static int display_echo_area (struct window *); | 829 | static int display_echo_area (struct window *); |
| 856 | static int display_echo_area_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t); | 830 | static int display_echo_area_1 (ptrdiff_t, Lisp_Object); |
| 857 | static int resize_mini_window_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t); | 831 | static int resize_mini_window_1 (ptrdiff_t, Lisp_Object); |
| 858 | static Lisp_Object unwind_redisplay (Lisp_Object); | 832 | static Lisp_Object unwind_redisplay (Lisp_Object); |
| 859 | static int string_char_and_length (const unsigned char *, int *); | 833 | static int string_char_and_length (const unsigned char *, int *); |
| 860 | static struct text_pos display_prop_end (struct it *, Lisp_Object, | 834 | static struct text_pos display_prop_end (struct it *, Lisp_Object, |
| @@ -874,7 +848,6 @@ static void push_it (struct it *, struct text_pos *); | |||
| 874 | static void iterate_out_of_display_property (struct it *); | 848 | static void iterate_out_of_display_property (struct it *); |
| 875 | static void pop_it (struct it *); | 849 | static void pop_it (struct it *); |
| 876 | static void sync_frame_with_window_matrix_rows (struct window *); | 850 | static void sync_frame_with_window_matrix_rows (struct window *); |
| 877 | static void select_frame_for_redisplay (Lisp_Object); | ||
| 878 | static void redisplay_internal (void); | 851 | static void redisplay_internal (void); |
| 879 | static int echo_area_display (int); | 852 | static int echo_area_display (int); |
| 880 | static void redisplay_windows (Lisp_Object); | 853 | static void redisplay_windows (Lisp_Object); |
| @@ -937,8 +910,8 @@ static int forward_to_next_line_start (struct it *, int *, struct bidi_it *); | |||
| 937 | static struct text_pos string_pos_nchars_ahead (struct text_pos, | 910 | static struct text_pos string_pos_nchars_ahead (struct text_pos, |
| 938 | Lisp_Object, ptrdiff_t); | 911 | Lisp_Object, ptrdiff_t); |
| 939 | static struct text_pos string_pos (ptrdiff_t, Lisp_Object); | 912 | static struct text_pos string_pos (ptrdiff_t, Lisp_Object); |
| 940 | static struct text_pos c_string_pos (ptrdiff_t, const char *, int); | 913 | static struct text_pos c_string_pos (ptrdiff_t, const char *, bool); |
| 941 | static ptrdiff_t number_of_chars (const char *, int); | 914 | static ptrdiff_t number_of_chars (const char *, bool); |
| 942 | static void compute_stop_pos (struct it *); | 915 | static void compute_stop_pos (struct it *); |
| 943 | static void compute_string_pos (struct text_pos *, struct text_pos, | 916 | static void compute_string_pos (struct text_pos *, struct text_pos, |
| 944 | Lisp_Object); | 917 | Lisp_Object); |
| @@ -1335,7 +1308,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, | |||
| 1335 | BVAR (current_buffer, header_line_format)); | 1308 | BVAR (current_buffer, header_line_format)); |
| 1336 | 1309 | ||
| 1337 | start_display (&it, w, top); | 1310 | start_display (&it, w, top); |
| 1338 | move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, | 1311 | move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1, |
| 1339 | (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); | 1312 | (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); |
| 1340 | 1313 | ||
| 1341 | if (charpos >= 0 | 1314 | if (charpos >= 0 |
| @@ -1343,7 +1316,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, | |||
| 1343 | && IT_CHARPOS (it) >= charpos) | 1316 | && IT_CHARPOS (it) >= charpos) |
| 1344 | /* When scanning backwards under bidi iteration, move_it_to | 1317 | /* When scanning backwards under bidi iteration, move_it_to |
| 1345 | stops at or _before_ CHARPOS, because it stops at or to | 1318 | stops at or _before_ CHARPOS, because it stops at or to |
| 1346 | the _right_ of the character at CHARPOS. */ | 1319 | the _right_ of the character at CHARPOS. */ |
| 1347 | || (it.bidi_p && it.bidi_it.scan_dir == -1 | 1320 | || (it.bidi_p && it.bidi_it.scan_dir == -1 |
| 1348 | && IT_CHARPOS (it) <= charpos))) | 1321 | && IT_CHARPOS (it) <= charpos))) |
| 1349 | { | 1322 | { |
| @@ -1419,21 +1392,9 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, | |||
| 1419 | Lisp_Object cpos = make_number (charpos); | 1392 | Lisp_Object cpos = make_number (charpos); |
| 1420 | Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil); | 1393 | Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil); |
| 1421 | Lisp_Object string = string_from_display_spec (spec); | 1394 | Lisp_Object string = string_from_display_spec (spec); |
| 1422 | int newline_in_string = 0; | 1395 | bool newline_in_string |
| 1423 | 1396 | = (STRINGP (string) | |
| 1424 | if (STRINGP (string)) | 1397 | && memchr (SDATA (string), '\n', SBYTES (string))); |
| 1425 | { | ||
| 1426 | const char *s = SSDATA (string); | ||
| 1427 | const char *e = s + SBYTES (string); | ||
| 1428 | while (s < e) | ||
| 1429 | { | ||
| 1430 | if (*s++ == '\n') | ||
| 1431 | { | ||
| 1432 | newline_in_string = 1; | ||
| 1433 | break; | ||
| 1434 | } | ||
| 1435 | } | ||
| 1436 | } | ||
| 1437 | /* The tricky code below is needed because there's a | 1398 | /* The tricky code below is needed because there's a |
| 1438 | discrepancy between move_it_to and how we set cursor | 1399 | discrepancy between move_it_to and how we set cursor |
| 1439 | when the display line ends in a newline from a | 1400 | when the display line ends in a newline from a |
| @@ -1689,7 +1650,7 @@ string_pos (ptrdiff_t charpos, Lisp_Object string) | |||
| 1689 | means recognize multibyte characters. */ | 1650 | means recognize multibyte characters. */ |
| 1690 | 1651 | ||
| 1691 | static struct text_pos | 1652 | static struct text_pos |
| 1692 | c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p) | 1653 | c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p) |
| 1693 | { | 1654 | { |
| 1694 | struct text_pos pos; | 1655 | struct text_pos pos; |
| 1695 | 1656 | ||
| @@ -1720,7 +1681,7 @@ c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p) | |||
| 1720 | non-zero means recognize multibyte characters. */ | 1681 | non-zero means recognize multibyte characters. */ |
| 1721 | 1682 | ||
| 1722 | static ptrdiff_t | 1683 | static ptrdiff_t |
| 1723 | number_of_chars (const char *s, int multibyte_p) | 1684 | number_of_chars (const char *s, bool multibyte_p) |
| 1724 | { | 1685 | { |
| 1725 | ptrdiff_t nchars; | 1686 | ptrdiff_t nchars; |
| 1726 | 1687 | ||
| @@ -2544,8 +2505,7 @@ check_it (struct it *it) | |||
| 2544 | static void | 2505 | static void |
| 2545 | check_window_end (struct window *w) | 2506 | check_window_end (struct window *w) |
| 2546 | { | 2507 | { |
| 2547 | if (!MINI_WINDOW_P (w) | 2508 | if (!MINI_WINDOW_P (w) && w->window_end_valid) |
| 2548 | && !NILP (w->window_end_valid)) | ||
| 2549 | { | 2509 | { |
| 2550 | struct glyph_row *row; | 2510 | struct glyph_row *row; |
| 2551 | eassert ((row = MATRIX_ROW (w->current_matrix, | 2511 | eassert ((row = MATRIX_ROW (w->current_matrix, |
| @@ -2564,8 +2524,24 @@ check_window_end (struct window *w) | |||
| 2564 | 2524 | ||
| 2565 | #endif /* GLYPH_DEBUG and ENABLE_CHECKING */ | 2525 | #endif /* GLYPH_DEBUG and ENABLE_CHECKING */ |
| 2566 | 2526 | ||
| 2527 | /* Return mark position if current buffer has the region of non-zero length, | ||
| 2528 | or -1 otherwise. */ | ||
| 2529 | |||
| 2530 | static ptrdiff_t | ||
| 2531 | markpos_of_region (void) | ||
| 2532 | { | ||
| 2533 | if (!NILP (Vtransient_mark_mode) | ||
| 2534 | && !NILP (BVAR (current_buffer, mark_active)) | ||
| 2535 | && XMARKER (BVAR (current_buffer, mark))->buffer != NULL) | ||
| 2536 | { | ||
| 2537 | ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos; | ||
| 2538 | |||
| 2539 | if (markpos != PT) | ||
| 2540 | return markpos; | ||
| 2541 | } | ||
| 2542 | return -1; | ||
| 2543 | } | ||
| 2567 | 2544 | ||
| 2568 | |||
| 2569 | /*********************************************************************** | 2545 | /*********************************************************************** |
| 2570 | Iterator initialization | 2546 | Iterator initialization |
| 2571 | ***********************************************************************/ | 2547 | ***********************************************************************/ |
| @@ -2594,7 +2570,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2594 | ptrdiff_t charpos, ptrdiff_t bytepos, | 2570 | ptrdiff_t charpos, ptrdiff_t bytepos, |
| 2595 | struct glyph_row *row, enum face_id base_face_id) | 2571 | struct glyph_row *row, enum face_id base_face_id) |
| 2596 | { | 2572 | { |
| 2597 | int highlight_region_p; | 2573 | ptrdiff_t markpos; |
| 2598 | enum face_id remapped_base_face_id = base_face_id; | 2574 | enum face_id remapped_base_face_id = base_face_id; |
| 2599 | 2575 | ||
| 2600 | /* Some precondition checks. */ | 2576 | /* Some precondition checks. */ |
| @@ -2697,16 +2673,11 @@ init_iterator (struct it *it, struct window *w, | |||
| 2697 | /* Are multibyte characters enabled in current_buffer? */ | 2673 | /* Are multibyte characters enabled in current_buffer? */ |
| 2698 | it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 2674 | it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 2699 | 2675 | ||
| 2700 | /* Non-zero if we should highlight the region. */ | 2676 | /* If visible region is of non-zero length, set IT->region_beg_charpos |
| 2701 | highlight_region_p | 2677 | and IT->region_end_charpos to the start and end of a visible region |
| 2702 | = (!NILP (Vtransient_mark_mode) | 2678 | in window IT->w. Set both to -1 to indicate no region. */ |
| 2703 | && !NILP (BVAR (current_buffer, mark_active)) | 2679 | markpos = markpos_of_region (); |
| 2704 | && XMARKER (BVAR (current_buffer, mark))->buffer != 0); | 2680 | if (0 <= markpos |
| 2705 | |||
| 2706 | /* Set IT->region_beg_charpos and IT->region_end_charpos to the | ||
| 2707 | start and end of a visible region in window IT->w. Set both to | ||
| 2708 | -1 to indicate no region. */ | ||
| 2709 | if (highlight_region_p | ||
| 2710 | /* Maybe highlight only in selected window. */ | 2681 | /* Maybe highlight only in selected window. */ |
| 2711 | && (/* Either show region everywhere. */ | 2682 | && (/* Either show region everywhere. */ |
| 2712 | highlight_nonselected_windows | 2683 | highlight_nonselected_windows |
| @@ -2718,7 +2689,6 @@ init_iterator (struct it *it, struct window *w, | |||
| 2718 | && WINDOWP (minibuf_selected_window) | 2689 | && WINDOWP (minibuf_selected_window) |
| 2719 | && w == XWINDOW (minibuf_selected_window)))) | 2690 | && w == XWINDOW (minibuf_selected_window)))) |
| 2720 | { | 2691 | { |
| 2721 | ptrdiff_t markpos = marker_position (BVAR (current_buffer, mark)); | ||
| 2722 | it->region_beg_charpos = min (PT, markpos); | 2692 | it->region_beg_charpos = min (PT, markpos); |
| 2723 | it->region_end_charpos = max (PT, markpos); | 2693 | it->region_end_charpos = max (PT, markpos); |
| 2724 | } | 2694 | } |
| @@ -3760,18 +3730,26 @@ handle_face_prop (struct it *it) | |||
| 3760 | if (new_face_id != it->face_id) | 3730 | if (new_face_id != it->face_id) |
| 3761 | { | 3731 | { |
| 3762 | struct face *new_face = FACE_FROM_ID (it->f, new_face_id); | 3732 | struct face *new_face = FACE_FROM_ID (it->f, new_face_id); |
| 3733 | /* If it->face_id is -1, old_face below will be NULL, see | ||
| 3734 | the definition of FACE_FROM_ID. This will happen if this | ||
| 3735 | is the initial call that gets the face. */ | ||
| 3736 | struct face *old_face = FACE_FROM_ID (it->f, it->face_id); | ||
| 3763 | 3737 | ||
| 3764 | /* If new face has a box but old face has not, this is | 3738 | /* If the value of face_id of the iterator is -1, we have to |
| 3765 | the start of a run of characters with box, i.e. it has | 3739 | look in front of IT's position and see whether there is a |
| 3766 | a shadow on the left side. The value of face_id of the | 3740 | face there that's different from new_face_id. */ |
| 3767 | iterator will be -1 if this is the initial call that gets | 3741 | if (!old_face && IT_CHARPOS (*it) > BEG) |
| 3768 | the face. In this case, we have to look in front of IT's | 3742 | { |
| 3769 | position and see whether there is a face != new_face_id. */ | 3743 | int prev_face_id = face_before_it_pos (it); |
| 3770 | it->start_of_box_run_p | 3744 | |
| 3771 | = (new_face->box != FACE_NO_BOX | 3745 | old_face = FACE_FROM_ID (it->f, prev_face_id); |
| 3772 | && (it->face_id >= 0 | 3746 | } |
| 3773 | || IT_CHARPOS (*it) == BEG | 3747 | |
| 3774 | || new_face_id != face_before_it_pos (it))); | 3748 | /* If the new face has a box, but the old face does not, |
| 3749 | this is the start of a run of characters with box face, | ||
| 3750 | i.e. this character has a shadow on the left side. */ | ||
| 3751 | it->start_of_box_run_p = (new_face->box != FACE_NO_BOX | ||
| 3752 | && (old_face == NULL || !old_face->box)); | ||
| 3775 | it->face_box_p = new_face->box != FACE_NO_BOX; | 3753 | it->face_box_p = new_face->box != FACE_NO_BOX; |
| 3776 | } | 3754 | } |
| 3777 | } | 3755 | } |
| @@ -9002,6 +8980,9 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 9002 | struct it it2, it3; | 8980 | struct it it2, it3; |
| 9003 | void *it2data = NULL, *it3data = NULL; | 8981 | void *it2data = NULL, *it3data = NULL; |
| 9004 | ptrdiff_t start_pos; | 8982 | ptrdiff_t start_pos; |
| 8983 | int nchars_per_row | ||
| 8984 | = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f); | ||
| 8985 | ptrdiff_t pos_limit; | ||
| 9005 | 8986 | ||
| 9006 | move_further_back: | 8987 | move_further_back: |
| 9007 | eassert (dy >= 0); | 8988 | eassert (dy >= 0); |
| @@ -9010,9 +8991,15 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 9010 | 8991 | ||
| 9011 | /* Estimate how many newlines we must move back. */ | 8992 | /* Estimate how many newlines we must move back. */ |
| 9012 | nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f)); | 8993 | nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f)); |
| 8994 | if (it->line_wrap == TRUNCATE) | ||
| 8995 | pos_limit = BEGV; | ||
| 8996 | else | ||
| 8997 | pos_limit = max (start_pos - nlines * nchars_per_row, BEGV); | ||
| 9013 | 8998 | ||
| 9014 | /* Set the iterator's position that many lines back. */ | 8999 | /* Set the iterator's position that many lines back. But don't go |
| 9015 | while (nlines-- && IT_CHARPOS (*it) > BEGV) | 9000 | back more than NLINES full screen lines -- this wins a day with |
| 9001 | buffers which have very long lines. */ | ||
| 9002 | while (nlines-- && IT_CHARPOS (*it) > pos_limit) | ||
| 9016 | back_to_previous_visible_line_start (it); | 9003 | back_to_previous_visible_line_start (it); |
| 9017 | 9004 | ||
| 9018 | /* Reseat the iterator here. When moving backward, we don't want | 9005 | /* Reseat the iterator here. When moving backward, we don't want |
| @@ -9243,6 +9230,9 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos) | |||
| 9243 | struct it it2; | 9230 | struct it it2; |
| 9244 | void *it2data = NULL; | 9231 | void *it2data = NULL; |
| 9245 | ptrdiff_t start_charpos, i; | 9232 | ptrdiff_t start_charpos, i; |
| 9233 | int nchars_per_row | ||
| 9234 | = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f); | ||
| 9235 | ptrdiff_t pos_limit; | ||
| 9246 | 9236 | ||
| 9247 | /* Start at the beginning of the screen line containing IT's | 9237 | /* Start at the beginning of the screen line containing IT's |
| 9248 | position. This may actually move vertically backwards, | 9238 | position. This may actually move vertically backwards, |
| @@ -9251,9 +9241,14 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos) | |||
| 9251 | move_it_vertically_backward (it, 0); | 9241 | move_it_vertically_backward (it, 0); |
| 9252 | dvpos -= it->vpos; | 9242 | dvpos -= it->vpos; |
| 9253 | 9243 | ||
| 9254 | /* Go back -DVPOS visible lines and reseat the iterator there. */ | 9244 | /* Go back -DVPOS buffer lines, but no farther than -DVPOS full |
| 9245 | screen lines, and reseat the iterator there. */ | ||
| 9255 | start_charpos = IT_CHARPOS (*it); | 9246 | start_charpos = IT_CHARPOS (*it); |
| 9256 | for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i) | 9247 | if (it->line_wrap == TRUNCATE) |
| 9248 | pos_limit = BEGV; | ||
| 9249 | else | ||
| 9250 | pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV); | ||
| 9251 | for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i) | ||
| 9257 | back_to_previous_visible_line_start (it); | 9252 | back_to_previous_visible_line_start (it); |
| 9258 | reseat (it, it->current.pos, 1); | 9253 | reseat (it, it->current.pos, 1); |
| 9259 | 9254 | ||
| @@ -9362,8 +9357,8 @@ message_log_maybe_newline (void) | |||
| 9362 | 9357 | ||
| 9363 | 9358 | ||
| 9364 | /* Add a string M of length NBYTES to the message log, optionally | 9359 | /* Add a string M of length NBYTES to the message log, optionally |
| 9365 | terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if | 9360 | terminated with a newline when NLFLAG is true. MULTIBYTE, if |
| 9366 | nonzero, means interpret the contents of M as multibyte. This | 9361 | true, means interpret the contents of M as multibyte. This |
| 9367 | function calls low-level routines in order to bypass text property | 9362 | function calls low-level routines in order to bypass text property |
| 9368 | hooks, etc. which might not be safe to run. | 9363 | hooks, etc. which might not be safe to run. |
| 9369 | 9364 | ||
| @@ -9371,7 +9366,7 @@ message_log_maybe_newline (void) | |||
| 9371 | so the buffer M must NOT point to a Lisp string. */ | 9366 | so the buffer M must NOT point to a Lisp string. */ |
| 9372 | 9367 | ||
| 9373 | void | 9368 | void |
| 9374 | message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | 9369 | message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte) |
| 9375 | { | 9370 | { |
| 9376 | const unsigned char *msg = (const unsigned char *) m; | 9371 | const unsigned char *msg = (const unsigned char *) m; |
| 9377 | 9372 | ||
| @@ -9385,7 +9380,8 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9385 | int old_windows_or_buffers_changed = windows_or_buffers_changed; | 9380 | int old_windows_or_buffers_changed = windows_or_buffers_changed; |
| 9386 | ptrdiff_t point_at_end = 0; | 9381 | ptrdiff_t point_at_end = 0; |
| 9387 | ptrdiff_t zv_at_end = 0; | 9382 | ptrdiff_t zv_at_end = 0; |
| 9388 | Lisp_Object old_deactivate_mark, tem; | 9383 | Lisp_Object old_deactivate_mark; |
| 9384 | bool shown; | ||
| 9389 | struct gcpro gcpro1; | 9385 | struct gcpro gcpro1; |
| 9390 | 9386 | ||
| 9391 | old_deactivate_mark = Vdeactivate_mark; | 9387 | old_deactivate_mark = Vdeactivate_mark; |
| @@ -9394,11 +9390,11 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9394 | bset_undo_list (current_buffer, Qt); | 9390 | bset_undo_list (current_buffer, Qt); |
| 9395 | 9391 | ||
| 9396 | oldpoint = message_dolog_marker1; | 9392 | oldpoint = message_dolog_marker1; |
| 9397 | set_marker_restricted (oldpoint, make_number (PT), Qnil); | 9393 | set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE); |
| 9398 | oldbegv = message_dolog_marker2; | 9394 | oldbegv = message_dolog_marker2; |
| 9399 | set_marker_restricted (oldbegv, make_number (BEGV), Qnil); | 9395 | set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE); |
| 9400 | oldzv = message_dolog_marker3; | 9396 | oldzv = message_dolog_marker3; |
| 9401 | set_marker_restricted (oldzv, make_number (ZV), Qnil); | 9397 | set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE); |
| 9402 | GCPRO1 (old_deactivate_mark); | 9398 | GCPRO1 (old_deactivate_mark); |
| 9403 | 9399 | ||
| 9404 | if (PT == Z) | 9400 | if (PT == Z) |
| @@ -9449,13 +9445,14 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9449 | } | 9445 | } |
| 9450 | } | 9446 | } |
| 9451 | else if (nbytes) | 9447 | else if (nbytes) |
| 9452 | insert_1 (m, nbytes, 1, 0, 0); | 9448 | insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0); |
| 9453 | 9449 | ||
| 9454 | if (nlflag) | 9450 | if (nlflag) |
| 9455 | { | 9451 | { |
| 9456 | ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte; | 9452 | ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte; |
| 9457 | printmax_t dups; | 9453 | printmax_t dups; |
| 9458 | insert_1 ("\n", 1, 1, 0, 0); | 9454 | |
| 9455 | insert_1_both ("\n", 1, 1, 1, 0, 0); | ||
| 9459 | 9456 | ||
| 9460 | scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0); | 9457 | scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0); |
| 9461 | this_bol = PT; | 9458 | this_bol = PT; |
| @@ -9484,7 +9481,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9484 | change message_log_check_duplicate. */ | 9481 | change message_log_check_duplicate. */ |
| 9485 | int duplen = sprintf (dupstr, " [%"pMd" times]", dups); | 9482 | int duplen = sprintf (dupstr, " [%"pMd" times]", dups); |
| 9486 | TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1); | 9483 | TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1); |
| 9487 | insert_1 (dupstr, duplen, 1, 0, 1); | 9484 | insert_1_both (dupstr, duplen, duplen, 1, 0, 1); |
| 9488 | } | 9485 | } |
| 9489 | } | 9486 | } |
| 9490 | } | 9487 | } |
| @@ -9500,7 +9497,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9500 | del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0); | 9497 | del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0); |
| 9501 | } | 9498 | } |
| 9502 | } | 9499 | } |
| 9503 | BEGV = XMARKER (oldbegv)->charpos; | 9500 | BEGV = marker_position (oldbegv); |
| 9504 | BEGV_BYTE = marker_byte_position (oldbegv); | 9501 | BEGV_BYTE = marker_byte_position (oldbegv); |
| 9505 | 9502 | ||
| 9506 | if (zv_at_end) | 9503 | if (zv_at_end) |
| @@ -9510,7 +9507,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9510 | } | 9507 | } |
| 9511 | else | 9508 | else |
| 9512 | { | 9509 | { |
| 9513 | ZV = XMARKER (oldzv)->charpos; | 9510 | ZV = marker_position (oldzv); |
| 9514 | ZV_BYTE = marker_byte_position (oldzv); | 9511 | ZV_BYTE = marker_byte_position (oldzv); |
| 9515 | } | 9512 | } |
| 9516 | 9513 | ||
| @@ -9519,17 +9516,17 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) | |||
| 9519 | else | 9516 | else |
| 9520 | /* We can't do Fgoto_char (oldpoint) because it will run some | 9517 | /* We can't do Fgoto_char (oldpoint) because it will run some |
| 9521 | Lisp code. */ | 9518 | Lisp code. */ |
| 9522 | TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos, | 9519 | TEMP_SET_PT_BOTH (marker_position (oldpoint), |
| 9523 | XMARKER (oldpoint)->bytepos); | 9520 | marker_byte_position (oldpoint)); |
| 9524 | 9521 | ||
| 9525 | UNGCPRO; | 9522 | UNGCPRO; |
| 9526 | unchain_marker (XMARKER (oldpoint)); | 9523 | unchain_marker (XMARKER (oldpoint)); |
| 9527 | unchain_marker (XMARKER (oldbegv)); | 9524 | unchain_marker (XMARKER (oldbegv)); |
| 9528 | unchain_marker (XMARKER (oldzv)); | 9525 | unchain_marker (XMARKER (oldzv)); |
| 9529 | 9526 | ||
| 9530 | tem = Fget_buffer_window (Fcurrent_buffer (), Qt); | 9527 | shown = buffer_window_count (current_buffer) > 0; |
| 9531 | set_buffer_internal (oldbuf); | 9528 | set_buffer_internal (oldbuf); |
| 9532 | if (NILP (tem)) | 9529 | if (!shown) |
| 9533 | windows_or_buffers_changed = old_windows_or_buffers_changed; | 9530 | windows_or_buffers_changed = old_windows_or_buffers_changed; |
| 9534 | message_log_need_newline = !nlflag; | 9531 | message_log_need_newline = !nlflag; |
| 9535 | Vdeactivate_mark = old_deactivate_mark; | 9532 | Vdeactivate_mark = old_deactivate_mark; |
| @@ -9554,7 +9551,7 @@ message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte) | |||
| 9554 | 9551 | ||
| 9555 | for (i = 0; i < len; i++) | 9552 | for (i = 0; i < len; i++) |
| 9556 | { | 9553 | { |
| 9557 | if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.') | 9554 | if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.') |
| 9558 | seen_dots = 1; | 9555 | seen_dots = 1; |
| 9559 | if (p1[i] != p2[i]) | 9556 | if (p1[i] != p2[i]) |
| 9560 | return seen_dots; | 9557 | return seen_dots; |
| @@ -9567,88 +9564,13 @@ message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte) | |||
| 9567 | char *pend; | 9564 | char *pend; |
| 9568 | intmax_t n = strtoimax ((char *) p1, &pend, 10); | 9565 | intmax_t n = strtoimax ((char *) p1, &pend, 10); |
| 9569 | if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0) | 9566 | if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0) |
| 9570 | return n+1; | 9567 | return n + 1; |
| 9571 | } | 9568 | } |
| 9572 | return 0; | 9569 | return 0; |
| 9573 | } | 9570 | } |
| 9574 | 9571 | ||
| 9575 | 9572 | ||
| 9576 | /* Display an echo area message M with a specified length of NBYTES | 9573 | /* Display an echo area message M with a specified length of NBYTES |
| 9577 | bytes. The string may include null characters. If M is 0, clear | ||
| 9578 | out any existing message, and let the mini-buffer text show | ||
| 9579 | through. | ||
| 9580 | |||
| 9581 | This may GC, so the buffer M must NOT point to a Lisp string. */ | ||
| 9582 | |||
| 9583 | void | ||
| 9584 | message2 (const char *m, ptrdiff_t nbytes, int multibyte) | ||
| 9585 | { | ||
| 9586 | /* First flush out any partial line written with print. */ | ||
| 9587 | message_log_maybe_newline (); | ||
| 9588 | if (m) | ||
| 9589 | message_dolog (m, nbytes, 1, multibyte); | ||
| 9590 | message2_nolog (m, nbytes, multibyte); | ||
| 9591 | } | ||
| 9592 | |||
| 9593 | |||
| 9594 | /* The non-logging counterpart of message2. */ | ||
| 9595 | |||
| 9596 | void | ||
| 9597 | message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte) | ||
| 9598 | { | ||
| 9599 | struct frame *sf = SELECTED_FRAME (); | ||
| 9600 | message_enable_multibyte = multibyte; | ||
| 9601 | |||
| 9602 | if (FRAME_INITIAL_P (sf)) | ||
| 9603 | { | ||
| 9604 | if (noninteractive_need_newline) | ||
| 9605 | putc ('\n', stderr); | ||
| 9606 | noninteractive_need_newline = 0; | ||
| 9607 | if (m) | ||
| 9608 | fwrite (m, nbytes, 1, stderr); | ||
| 9609 | if (cursor_in_echo_area == 0) | ||
| 9610 | fprintf (stderr, "\n"); | ||
| 9611 | fflush (stderr); | ||
| 9612 | } | ||
| 9613 | /* A null message buffer means that the frame hasn't really been | ||
| 9614 | initialized yet. Error messages get reported properly by | ||
| 9615 | cmd_error, so this must be just an informative message; toss it. */ | ||
| 9616 | else if (INTERACTIVE | ||
| 9617 | && sf->glyphs_initialized_p | ||
| 9618 | && FRAME_MESSAGE_BUF (sf)) | ||
| 9619 | { | ||
| 9620 | Lisp_Object mini_window; | ||
| 9621 | struct frame *f; | ||
| 9622 | |||
| 9623 | /* Get the frame containing the mini-buffer | ||
| 9624 | that the selected frame is using. */ | ||
| 9625 | mini_window = FRAME_MINIBUF_WINDOW (sf); | ||
| 9626 | f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); | ||
| 9627 | |||
| 9628 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 9629 | if (FRAME_VISIBLE_P (sf) | ||
| 9630 | && ! FRAME_VISIBLE_P (f)) | ||
| 9631 | Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window))); | ||
| 9632 | |||
| 9633 | if (m) | ||
| 9634 | { | ||
| 9635 | set_message (m, Qnil, nbytes, multibyte); | ||
| 9636 | if (minibuffer_auto_raise) | ||
| 9637 | Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); | ||
| 9638 | } | ||
| 9639 | else | ||
| 9640 | clear_message (1, 1); | ||
| 9641 | |||
| 9642 | do_pending_window_change (0); | ||
| 9643 | echo_area_display (1); | ||
| 9644 | do_pending_window_change (0); | ||
| 9645 | if (FRAME_TERMINAL (f)->frame_up_to_date_hook) | ||
| 9646 | (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f); | ||
| 9647 | } | ||
| 9648 | } | ||
| 9649 | |||
| 9650 | |||
| 9651 | /* Display an echo area message M with a specified length of NBYTES | ||
| 9652 | bytes. The string may include null characters. If M is not a | 9574 | bytes. The string may include null characters. If M is not a |
| 9653 | string, clear out any existing message, and let the mini-buffer | 9575 | string, clear out any existing message, and let the mini-buffer |
| 9654 | text show through. | 9576 | text show through. |
| @@ -9656,7 +9578,7 @@ message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte) | |||
| 9656 | This function cancels echoing. */ | 9578 | This function cancels echoing. */ |
| 9657 | 9579 | ||
| 9658 | void | 9580 | void |
| 9659 | message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte) | 9581 | message3 (Lisp_Object m) |
| 9660 | { | 9582 | { |
| 9661 | struct gcpro gcpro1; | 9583 | struct gcpro gcpro1; |
| 9662 | 9584 | ||
| @@ -9668,13 +9590,15 @@ message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte) | |||
| 9668 | message_log_maybe_newline (); | 9590 | message_log_maybe_newline (); |
| 9669 | if (STRINGP (m)) | 9591 | if (STRINGP (m)) |
| 9670 | { | 9592 | { |
| 9593 | ptrdiff_t nbytes = SBYTES (m); | ||
| 9594 | bool multibyte = STRING_MULTIBYTE (m); | ||
| 9671 | USE_SAFE_ALLOCA; | 9595 | USE_SAFE_ALLOCA; |
| 9672 | char *buffer = SAFE_ALLOCA (nbytes); | 9596 | char *buffer = SAFE_ALLOCA (nbytes); |
| 9673 | memcpy (buffer, SDATA (m), nbytes); | 9597 | memcpy (buffer, SDATA (m), nbytes); |
| 9674 | message_dolog (buffer, nbytes, 1, multibyte); | 9598 | message_dolog (buffer, nbytes, 1, multibyte); |
| 9675 | SAFE_FREE (); | 9599 | SAFE_FREE (); |
| 9676 | } | 9600 | } |
| 9677 | message3_nolog (m, nbytes, multibyte); | 9601 | message3_nolog (m); |
| 9678 | 9602 | ||
| 9679 | UNGCPRO; | 9603 | UNGCPRO; |
| 9680 | } | 9604 | } |
| @@ -9686,10 +9610,9 @@ message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte) | |||
| 9686 | and make this cancel echoing. */ | 9610 | and make this cancel echoing. */ |
| 9687 | 9611 | ||
| 9688 | void | 9612 | void |
| 9689 | message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte) | 9613 | message3_nolog (Lisp_Object m) |
| 9690 | { | 9614 | { |
| 9691 | struct frame *sf = SELECTED_FRAME (); | 9615 | struct frame *sf = SELECTED_FRAME (); |
| 9692 | message_enable_multibyte = multibyte; | ||
| 9693 | 9616 | ||
| 9694 | if (FRAME_INITIAL_P (sf)) | 9617 | if (FRAME_INITIAL_P (sf)) |
| 9695 | { | 9618 | { |
| @@ -9697,36 +9620,28 @@ message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte) | |||
| 9697 | putc ('\n', stderr); | 9620 | putc ('\n', stderr); |
| 9698 | noninteractive_need_newline = 0; | 9621 | noninteractive_need_newline = 0; |
| 9699 | if (STRINGP (m)) | 9622 | if (STRINGP (m)) |
| 9700 | fwrite (SDATA (m), nbytes, 1, stderr); | 9623 | fwrite (SDATA (m), SBYTES (m), 1, stderr); |
| 9701 | if (cursor_in_echo_area == 0) | 9624 | if (cursor_in_echo_area == 0) |
| 9702 | fprintf (stderr, "\n"); | 9625 | fprintf (stderr, "\n"); |
| 9703 | fflush (stderr); | 9626 | fflush (stderr); |
| 9704 | } | 9627 | } |
| 9705 | /* A null message buffer means that the frame hasn't really been | 9628 | /* Error messages get reported properly by cmd_error, so this must be just an |
| 9706 | initialized yet. Error messages get reported properly by | 9629 | informative message; if the frame hasn't really been initialized yet, just |
| 9707 | cmd_error, so this must be just an informative message; toss it. */ | 9630 | toss it. */ |
| 9708 | else if (INTERACTIVE | 9631 | else if (INTERACTIVE && sf->glyphs_initialized_p) |
| 9709 | && sf->glyphs_initialized_p | ||
| 9710 | && FRAME_MESSAGE_BUF (sf)) | ||
| 9711 | { | 9632 | { |
| 9712 | Lisp_Object mini_window; | ||
| 9713 | Lisp_Object frame; | ||
| 9714 | struct frame *f; | ||
| 9715 | |||
| 9716 | /* Get the frame containing the mini-buffer | 9633 | /* Get the frame containing the mini-buffer |
| 9717 | that the selected frame is using. */ | 9634 | that the selected frame is using. */ |
| 9718 | mini_window = FRAME_MINIBUF_WINDOW (sf); | 9635 | Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf); |
| 9719 | frame = XWINDOW (mini_window)->frame; | 9636 | Lisp_Object frame = XWINDOW (mini_window)->frame; |
| 9720 | f = XFRAME (frame); | 9637 | struct frame *f = XFRAME (frame); |
| 9721 | 9638 | ||
| 9722 | FRAME_SAMPLE_VISIBILITY (f); | 9639 | if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f)) |
| 9723 | if (FRAME_VISIBLE_P (sf) | ||
| 9724 | && !FRAME_VISIBLE_P (f)) | ||
| 9725 | Fmake_frame_visible (frame); | 9640 | Fmake_frame_visible (frame); |
| 9726 | 9641 | ||
| 9727 | if (STRINGP (m) && SCHARS (m) > 0) | 9642 | if (STRINGP (m) && SCHARS (m) > 0) |
| 9728 | { | 9643 | { |
| 9729 | set_message (NULL, m, nbytes, multibyte); | 9644 | set_message (m); |
| 9730 | if (minibuffer_auto_raise) | 9645 | if (minibuffer_auto_raise) |
| 9731 | Fraise_frame (frame); | 9646 | Fraise_frame (frame); |
| 9732 | /* Assume we are not echoing. | 9647 | /* Assume we are not echoing. |
| @@ -9756,7 +9671,7 @@ message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte) | |||
| 9756 | void | 9671 | void |
| 9757 | message1 (const char *m) | 9672 | message1 (const char *m) |
| 9758 | { | 9673 | { |
| 9759 | message2 (m, (m ? strlen (m) : 0), 0); | 9674 | message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil); |
| 9760 | } | 9675 | } |
| 9761 | 9676 | ||
| 9762 | 9677 | ||
| @@ -9765,7 +9680,7 @@ message1 (const char *m) | |||
| 9765 | void | 9680 | void |
| 9766 | message1_nolog (const char *m) | 9681 | message1_nolog (const char *m) |
| 9767 | { | 9682 | { |
| 9768 | message2_nolog (m, (m ? strlen (m) : 0), 0); | 9683 | message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil); |
| 9769 | } | 9684 | } |
| 9770 | 9685 | ||
| 9771 | /* Display a message M which contains a single %s | 9686 | /* Display a message M which contains a single %s |
| @@ -9802,10 +9717,10 @@ message_with_string (const char *m, Lisp_Object string, int log) | |||
| 9802 | mini_window = FRAME_MINIBUF_WINDOW (sf); | 9717 | mini_window = FRAME_MINIBUF_WINDOW (sf); |
| 9803 | f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); | 9718 | f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); |
| 9804 | 9719 | ||
| 9805 | /* A null message buffer means that the frame hasn't really been | 9720 | /* Error messages get reported properly by cmd_error, so this must be |
| 9806 | initialized yet. Error messages get reported properly by | 9721 | just an informative message; if the frame hasn't really been |
| 9807 | cmd_error, so this must be just an informative message; toss it. */ | 9722 | initialized yet, just toss it. */ |
| 9808 | if (FRAME_MESSAGE_BUF (f)) | 9723 | if (f->glyphs_initialized_p) |
| 9809 | { | 9724 | { |
| 9810 | Lisp_Object args[2], msg; | 9725 | Lisp_Object args[2], msg; |
| 9811 | struct gcpro gcpro1, gcpro2; | 9726 | struct gcpro gcpro1, gcpro2; |
| @@ -9818,9 +9733,9 @@ message_with_string (const char *m, Lisp_Object string, int log) | |||
| 9818 | msg = Fformat (2, args); | 9733 | msg = Fformat (2, args); |
| 9819 | 9734 | ||
| 9820 | if (log) | 9735 | if (log) |
| 9821 | message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg)); | 9736 | message3 (msg); |
| 9822 | else | 9737 | else |
| 9823 | message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg)); | 9738 | message3_nolog (msg); |
| 9824 | 9739 | ||
| 9825 | UNGCPRO; | 9740 | UNGCPRO; |
| 9826 | 9741 | ||
| @@ -9864,20 +9779,20 @@ vmessage (const char *m, va_list ap) | |||
| 9864 | mini_window = FRAME_MINIBUF_WINDOW (sf); | 9779 | mini_window = FRAME_MINIBUF_WINDOW (sf); |
| 9865 | f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); | 9780 | f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); |
| 9866 | 9781 | ||
| 9867 | /* A null message buffer means that the frame hasn't really been | 9782 | /* Error messages get reported properly by cmd_error, so this must be |
| 9868 | initialized yet. Error messages get reported properly by | 9783 | just an informative message; if the frame hasn't really been |
| 9869 | cmd_error, so this must be just an informative message; toss | 9784 | initialized yet, just toss it. */ |
| 9870 | it. */ | 9785 | if (f->glyphs_initialized_p) |
| 9871 | if (FRAME_MESSAGE_BUF (f)) | ||
| 9872 | { | 9786 | { |
| 9873 | if (m) | 9787 | if (m) |
| 9874 | { | 9788 | { |
| 9875 | ptrdiff_t len; | 9789 | ptrdiff_t len; |
| 9790 | ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f); | ||
| 9791 | char *message_buf = alloca (maxsize + 1); | ||
| 9876 | 9792 | ||
| 9877 | len = doprnt (FRAME_MESSAGE_BUF (f), | 9793 | len = doprnt (message_buf, maxsize, m, (char *)0, ap); |
| 9878 | FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap); | ||
| 9879 | 9794 | ||
| 9880 | message2 (FRAME_MESSAGE_BUF (f), len, 1); | 9795 | message3 (make_string (message_buf, len)); |
| 9881 | } | 9796 | } |
| 9882 | else | 9797 | else |
| 9883 | message1 (0); | 9798 | message1 (0); |
| @@ -9928,8 +9843,7 @@ update_echo_area (void) | |||
| 9928 | { | 9843 | { |
| 9929 | Lisp_Object string; | 9844 | Lisp_Object string; |
| 9930 | string = Fcurrent_message (); | 9845 | string = Fcurrent_message (); |
| 9931 | message3 (string, SBYTES (string), | 9846 | message3 (string); |
| 9932 | !NILP (BVAR (current_buffer, enable_multibyte_characters))); | ||
| 9933 | } | 9847 | } |
| 9934 | } | 9848 | } |
| 9935 | 9849 | ||
| @@ -9965,7 +9879,7 @@ ensure_echo_area_buffers (void) | |||
| 9965 | } | 9879 | } |
| 9966 | 9880 | ||
| 9967 | 9881 | ||
| 9968 | /* Call FN with args A1..A4 with either the current or last displayed | 9882 | /* Call FN with args A1..A2 with either the current or last displayed |
| 9969 | echo_area_buffer as current buffer. | 9883 | echo_area_buffer as current buffer. |
| 9970 | 9884 | ||
| 9971 | WHICH zero means use the current message buffer | 9885 | WHICH zero means use the current message buffer |
| @@ -9983,8 +9897,8 @@ ensure_echo_area_buffers (void) | |||
| 9983 | 9897 | ||
| 9984 | static int | 9898 | static int |
| 9985 | with_echo_area_buffer (struct window *w, int which, | 9899 | with_echo_area_buffer (struct window *w, int which, |
| 9986 | int (*fn) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t), | 9900 | int (*fn) (ptrdiff_t, Lisp_Object), |
| 9987 | ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4) | 9901 | ptrdiff_t a1, Lisp_Object a2) |
| 9988 | { | 9902 | { |
| 9989 | Lisp_Object buffer; | 9903 | Lisp_Object buffer; |
| 9990 | int this_one, the_other, clear_buffer_p, rc; | 9904 | int this_one, the_other, clear_buffer_p, rc; |
| @@ -10057,7 +9971,7 @@ with_echo_area_buffer (struct window *w, int which, | |||
| 10057 | eassert (BEGV >= BEG); | 9971 | eassert (BEGV >= BEG); |
| 10058 | eassert (ZV <= Z && ZV >= BEGV); | 9972 | eassert (ZV <= Z && ZV >= BEGV); |
| 10059 | 9973 | ||
| 10060 | rc = fn (a1, a2, a3, a4); | 9974 | rc = fn (a1, a2); |
| 10061 | 9975 | ||
| 10062 | eassert (BEGV >= BEG); | 9976 | eassert (BEGV >= BEG); |
| 10063 | eassert (ZV <= Z && ZV >= BEGV); | 9977 | eassert (ZV <= Z && ZV >= BEGV); |
| @@ -10092,8 +10006,8 @@ with_echo_area_buffer_unwind_data (struct window *w) | |||
| 10092 | { | 10006 | { |
| 10093 | XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i; | 10007 | XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i; |
| 10094 | ASET (vector, i, w->buffer); ++i; | 10008 | ASET (vector, i, w->buffer); ++i; |
| 10095 | ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i; | 10009 | ASET (vector, i, make_number (marker_position (w->pointm))); ++i; |
| 10096 | ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i; | 10010 | ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i; |
| 10097 | } | 10011 | } |
| 10098 | else | 10012 | else |
| 10099 | { | 10013 | { |
| @@ -10236,7 +10150,7 @@ display_echo_area (struct window *w) | |||
| 10236 | window_height_changed_p | 10150 | window_height_changed_p |
| 10237 | = with_echo_area_buffer (w, display_last_displayed_message_p, | 10151 | = with_echo_area_buffer (w, display_last_displayed_message_p, |
| 10238 | display_echo_area_1, | 10152 | display_echo_area_1, |
| 10239 | (intptr_t) w, Qnil, 0, 0); | 10153 | (intptr_t) w, Qnil); |
| 10240 | 10154 | ||
| 10241 | if (no_message_p) | 10155 | if (no_message_p) |
| 10242 | echo_area_buffer[i] = Qnil; | 10156 | echo_area_buffer[i] = Qnil; |
| @@ -10253,7 +10167,7 @@ display_echo_area (struct window *w) | |||
| 10253 | Value is non-zero if height of W was changed. */ | 10167 | Value is non-zero if height of W was changed. */ |
| 10254 | 10168 | ||
| 10255 | static int | 10169 | static int |
| 10256 | display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4) | 10170 | display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2) |
| 10257 | { | 10171 | { |
| 10258 | intptr_t i1 = a1; | 10172 | intptr_t i1 = a1; |
| 10259 | struct window *w = (struct window *) i1; | 10173 | struct window *w = (struct window *) i1; |
| @@ -10298,8 +10212,7 @@ resize_echo_area_exactly (void) | |||
| 10298 | resize_exactly = Qnil; | 10212 | resize_exactly = Qnil; |
| 10299 | 10213 | ||
| 10300 | resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1, | 10214 | resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1, |
| 10301 | (intptr_t) w, resize_exactly, | 10215 | (intptr_t) w, resize_exactly); |
| 10302 | 0, 0); | ||
| 10303 | if (resized_p) | 10216 | if (resized_p) |
| 10304 | { | 10217 | { |
| 10305 | ++windows_or_buffers_changed; | 10218 | ++windows_or_buffers_changed; |
| @@ -10317,7 +10230,7 @@ resize_echo_area_exactly (void) | |||
| 10317 | resize_mini_window returns. */ | 10230 | resize_mini_window returns. */ |
| 10318 | 10231 | ||
| 10319 | static int | 10232 | static int |
| 10320 | resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly, ptrdiff_t a3, ptrdiff_t a4) | 10233 | resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly) |
| 10321 | { | 10234 | { |
| 10322 | intptr_t i1 = a1; | 10235 | intptr_t i1 = a1; |
| 10323 | return resize_mini_window ((struct window *) i1, !NILP (exactly)); | 10236 | return resize_mini_window ((struct window *) i1, !NILP (exactly)); |
| @@ -10390,8 +10303,7 @@ resize_mini_window (struct window *w, int exact_p) | |||
| 10390 | max_height = total_height / 4; | 10303 | max_height = total_height / 4; |
| 10391 | 10304 | ||
| 10392 | /* Correct that max. height if it's bogus. */ | 10305 | /* Correct that max. height if it's bogus. */ |
| 10393 | max_height = max (1, max_height); | 10306 | max_height = clip_to_bounds (1, max_height, total_height); |
| 10394 | max_height = min (total_height, max_height); | ||
| 10395 | 10307 | ||
| 10396 | /* Find out the height of the text in the window. */ | 10308 | /* Find out the height of the text in the window. */ |
| 10397 | if (it.line_wrap == TRUNCATE) | 10309 | if (it.line_wrap == TRUNCATE) |
| @@ -10487,7 +10399,7 @@ current_message (void) | |||
| 10487 | else | 10399 | else |
| 10488 | { | 10400 | { |
| 10489 | with_echo_area_buffer (0, 0, current_message_1, | 10401 | with_echo_area_buffer (0, 0, current_message_1, |
| 10490 | (intptr_t) &msg, Qnil, 0, 0); | 10402 | (intptr_t) &msg, Qnil); |
| 10491 | if (NILP (msg)) | 10403 | if (NILP (msg)) |
| 10492 | echo_area_buffer[0] = Qnil; | 10404 | echo_area_buffer[0] = Qnil; |
| 10493 | } | 10405 | } |
| @@ -10497,7 +10409,7 @@ current_message (void) | |||
| 10497 | 10409 | ||
| 10498 | 10410 | ||
| 10499 | static int | 10411 | static int |
| 10500 | current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4) | 10412 | current_message_1 (ptrdiff_t a1, Lisp_Object a2) |
| 10501 | { | 10413 | { |
| 10502 | intptr_t i1 = a1; | 10414 | intptr_t i1 = a1; |
| 10503 | Lisp_Object *msg = (Lisp_Object *) i1; | 10415 | Lisp_Object *msg = (Lisp_Object *) i1; |
| @@ -10529,14 +10441,8 @@ push_message (void) | |||
| 10529 | void | 10441 | void |
| 10530 | restore_message (void) | 10442 | restore_message (void) |
| 10531 | { | 10443 | { |
| 10532 | Lisp_Object msg; | ||
| 10533 | |||
| 10534 | eassert (CONSP (Vmessage_stack)); | 10444 | eassert (CONSP (Vmessage_stack)); |
| 10535 | msg = XCAR (Vmessage_stack); | 10445 | message3_nolog (XCAR (Vmessage_stack)); |
| 10536 | if (STRINGP (msg)) | ||
| 10537 | message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg)); | ||
| 10538 | else | ||
| 10539 | message3_nolog (msg, 0, 0); | ||
| 10540 | } | 10446 | } |
| 10541 | 10447 | ||
| 10542 | 10448 | ||
| @@ -10579,16 +10485,16 @@ truncate_echo_area (ptrdiff_t nchars) | |||
| 10579 | { | 10485 | { |
| 10580 | if (nchars == 0) | 10486 | if (nchars == 0) |
| 10581 | echo_area_buffer[0] = Qnil; | 10487 | echo_area_buffer[0] = Qnil; |
| 10582 | /* A null message buffer means that the frame hasn't really been | ||
| 10583 | initialized yet. Error messages get reported properly by | ||
| 10584 | cmd_error, so this must be just an informative message; toss it. */ | ||
| 10585 | else if (!noninteractive | 10488 | else if (!noninteractive |
| 10586 | && INTERACTIVE | 10489 | && INTERACTIVE |
| 10587 | && !NILP (echo_area_buffer[0])) | 10490 | && !NILP (echo_area_buffer[0])) |
| 10588 | { | 10491 | { |
| 10589 | struct frame *sf = SELECTED_FRAME (); | 10492 | struct frame *sf = SELECTED_FRAME (); |
| 10590 | if (FRAME_MESSAGE_BUF (sf)) | 10493 | /* Error messages get reported properly by cmd_error, so this must be |
| 10591 | with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0); | 10494 | just an informative message; if the frame hasn't really been |
| 10495 | initialized yet, just toss it. */ | ||
| 10496 | if (sf->glyphs_initialized_p) | ||
| 10497 | with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil); | ||
| 10592 | } | 10498 | } |
| 10593 | } | 10499 | } |
| 10594 | 10500 | ||
| @@ -10597,7 +10503,7 @@ truncate_echo_area (ptrdiff_t nchars) | |||
| 10597 | message to at most NCHARS characters. */ | 10503 | message to at most NCHARS characters. */ |
| 10598 | 10504 | ||
| 10599 | static int | 10505 | static int |
| 10600 | truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4) | 10506 | truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2) |
| 10601 | { | 10507 | { |
| 10602 | if (BEG + nchars < Z) | 10508 | if (BEG + nchars < Z) |
| 10603 | del_range (BEG + nchars, Z); | 10509 | del_range (BEG + nchars, Z); |
| @@ -10606,30 +10512,16 @@ truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4 | |||
| 10606 | return 0; | 10512 | return 0; |
| 10607 | } | 10513 | } |
| 10608 | 10514 | ||
| 10609 | /* Set the current message to a substring of S or STRING. | 10515 | /* Set the current message to STRING. */ |
| 10610 | |||
| 10611 | If STRING is a Lisp string, set the message to the first NBYTES | ||
| 10612 | bytes from STRING. NBYTES zero means use the whole string. If | ||
| 10613 | STRING is multibyte, the message will be displayed multibyte. | ||
| 10614 | |||
| 10615 | If S is not null, set the message to the first LEN bytes of S. LEN | ||
| 10616 | zero means use the whole string. MULTIBYTE_P non-zero means S is | ||
| 10617 | multibyte. Display the message multibyte in that case. | ||
| 10618 | |||
| 10619 | Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks | ||
| 10620 | to t before calling set_message_1 (which calls insert). | ||
| 10621 | */ | ||
| 10622 | 10516 | ||
| 10623 | static void | 10517 | static void |
| 10624 | set_message (const char *s, Lisp_Object string, | 10518 | set_message (Lisp_Object string) |
| 10625 | ptrdiff_t nbytes, int multibyte_p) | ||
| 10626 | { | 10519 | { |
| 10627 | message_enable_multibyte | 10520 | eassert (STRINGP (string)); |
| 10628 | = ((s && multibyte_p) | 10521 | |
| 10629 | || (STRINGP (string) && STRING_MULTIBYTE (string))); | 10522 | message_enable_multibyte = STRING_MULTIBYTE (string); |
| 10630 | 10523 | ||
| 10631 | with_echo_area_buffer (0, -1, set_message_1, | 10524 | with_echo_area_buffer (0, -1, set_message_1, 0, string); |
| 10632 | (intptr_t) s, string, nbytes, multibyte_p); | ||
| 10633 | message_buf_print = 0; | 10525 | message_buf_print = 0; |
| 10634 | help_echo_showing_p = 0; | 10526 | help_echo_showing_p = 0; |
| 10635 | 10527 | ||
| @@ -10639,18 +10531,14 @@ set_message (const char *s, Lisp_Object string, | |||
| 10639 | } | 10531 | } |
| 10640 | 10532 | ||
| 10641 | 10533 | ||
| 10642 | /* Helper function for set_message. Arguments have the same meaning | 10534 | /* Helper function for set_message. First argument is ignored and second |
| 10643 | as there, with A1 corresponding to S and A2 corresponding to STRING | 10535 | argument has the same meaning as for set_message. |
| 10644 | This function is called with the echo area buffer being | 10536 | This function is called with the echo area buffer being current. */ |
| 10645 | current. */ | ||
| 10646 | 10537 | ||
| 10647 | static int | 10538 | static int |
| 10648 | set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multibyte_p) | 10539 | set_message_1 (ptrdiff_t a1, Lisp_Object string) |
| 10649 | { | 10540 | { |
| 10650 | intptr_t i1 = a1; | 10541 | eassert (STRINGP (string)); |
| 10651 | const char *s = (const char *) i1; | ||
| 10652 | const unsigned char *msg = (const unsigned char *) s; | ||
| 10653 | Lisp_Object string = a2; | ||
| 10654 | 10542 | ||
| 10655 | /* Change multibyteness of the echo buffer appropriately. */ | 10543 | /* Change multibyteness of the echo buffer appropriately. */ |
| 10656 | if (message_enable_multibyte | 10544 | if (message_enable_multibyte |
| @@ -10664,61 +10552,10 @@ set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multiby | |||
| 10664 | /* Insert new message at BEG. */ | 10552 | /* Insert new message at BEG. */ |
| 10665 | TEMP_SET_PT_BOTH (BEG, BEG_BYTE); | 10553 | TEMP_SET_PT_BOTH (BEG, BEG_BYTE); |
| 10666 | 10554 | ||
| 10667 | if (STRINGP (string)) | 10555 | /* This function takes care of single/multibyte conversion. |
| 10668 | { | 10556 | We just have to ensure that the echo area buffer has the right |
| 10669 | ptrdiff_t nchars; | 10557 | setting of enable_multibyte_characters. */ |
| 10670 | 10558 | insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1); | |
| 10671 | if (nbytes == 0) | ||
| 10672 | nbytes = SBYTES (string); | ||
| 10673 | nchars = string_byte_to_char (string, nbytes); | ||
| 10674 | |||
| 10675 | /* This function takes care of single/multibyte conversion. We | ||
| 10676 | just have to ensure that the echo area buffer has the right | ||
| 10677 | setting of enable_multibyte_characters. */ | ||
| 10678 | insert_from_string (string, 0, 0, nchars, nbytes, 1); | ||
| 10679 | } | ||
| 10680 | else if (s) | ||
| 10681 | { | ||
| 10682 | if (nbytes == 0) | ||
| 10683 | nbytes = strlen (s); | ||
| 10684 | |||
| 10685 | if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters))) | ||
| 10686 | { | ||
| 10687 | /* Convert from multi-byte to single-byte. */ | ||
| 10688 | ptrdiff_t i; | ||
| 10689 | int c, n; | ||
| 10690 | char work[1]; | ||
| 10691 | |||
| 10692 | /* Convert a multibyte string to single-byte. */ | ||
| 10693 | for (i = 0; i < nbytes; i += n) | ||
| 10694 | { | ||
| 10695 | c = string_char_and_length (msg + i, &n); | ||
| 10696 | work[0] = (ASCII_CHAR_P (c) | ||
| 10697 | ? c | ||
| 10698 | : multibyte_char_to_unibyte (c)); | ||
| 10699 | insert_1_both (work, 1, 1, 1, 0, 0); | ||
| 10700 | } | ||
| 10701 | } | ||
| 10702 | else if (!multibyte_p | ||
| 10703 | && !NILP (BVAR (current_buffer, enable_multibyte_characters))) | ||
| 10704 | { | ||
| 10705 | /* Convert from single-byte to multi-byte. */ | ||
| 10706 | ptrdiff_t i; | ||
| 10707 | int c, n; | ||
| 10708 | unsigned char str[MAX_MULTIBYTE_LENGTH]; | ||
| 10709 | |||
| 10710 | /* Convert a single-byte string to multibyte. */ | ||
| 10711 | for (i = 0; i < nbytes; i++) | ||
| 10712 | { | ||
| 10713 | c = msg[i]; | ||
| 10714 | MAKE_CHAR_MULTIBYTE (c); | ||
| 10715 | n = CHAR_STRING (c, str); | ||
| 10716 | insert_1_both ((char *) str, 1, n, 1, 0, 0); | ||
| 10717 | } | ||
| 10718 | } | ||
| 10719 | else | ||
| 10720 | insert_1 (s, nbytes, 1, 0, 0); | ||
| 10721 | } | ||
| 10722 | 10559 | ||
| 10723 | return 0; | 10560 | return 0; |
| 10724 | } | 10561 | } |
| @@ -10894,9 +10731,8 @@ echo_area_display (int update_frame_p) | |||
| 10894 | static int | 10731 | static int |
| 10895 | buffer_shared_and_changed (void) | 10732 | buffer_shared_and_changed (void) |
| 10896 | { | 10733 | { |
| 10897 | /* The variable buffer_shared is set in redisplay_window and | 10734 | return (buffer_window_count (current_buffer) > 1 |
| 10898 | indicates that we redisplay a buffer in different windows. */ | 10735 | && UNCHANGED_MODIFIED < MODIFF); |
| 10899 | return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); | ||
| 10900 | } | 10736 | } |
| 10901 | 10737 | ||
| 10902 | /* Nonzero if W doesn't reflect the actual state of current buffer due | 10738 | /* Nonzero if W doesn't reflect the actual state of current buffer due |
| @@ -10906,7 +10742,7 @@ buffer_shared_and_changed (void) | |||
| 10906 | static int | 10742 | static int |
| 10907 | window_outdated (struct window *w) | 10743 | window_outdated (struct window *w) |
| 10908 | { | 10744 | { |
| 10909 | return (w->last_modified < MODIFF | 10745 | return (w->last_modified < MODIFF |
| 10910 | || w->last_overlay_modified < OVERLAY_MODIFF); | 10746 | || w->last_overlay_modified < OVERLAY_MODIFF); |
| 10911 | } | 10747 | } |
| 10912 | 10748 | ||
| @@ -10922,7 +10758,7 @@ window_buffer_changed (struct window *w) | |||
| 10922 | 10758 | ||
| 10923 | return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star) | 10759 | return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star) |
| 10924 | || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active))) | 10760 | || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active))) |
| 10925 | != !NILP (w->region_showing))); | 10761 | != (w->region_showing != 0))); |
| 10926 | } | 10762 | } |
| 10927 | 10763 | ||
| 10928 | /* Nonzero if W has %c in its mode line and mode line should be updated. */ | 10764 | /* Nonzero if W has %c in its mode line and mode line should be updated. */ |
| @@ -10930,9 +10766,9 @@ window_buffer_changed (struct window *w) | |||
| 10930 | static int | 10766 | static int |
| 10931 | mode_line_update_needed (struct window *w) | 10767 | mode_line_update_needed (struct window *w) |
| 10932 | { | 10768 | { |
| 10933 | return (!NILP (w->column_number_displayed) | 10769 | return (w->column_number_displayed != -1 |
| 10934 | && !(PT == w->last_point && !window_outdated (w)) | 10770 | && !(PT == w->last_point && !window_outdated (w)) |
| 10935 | && (XFASTINT (w->column_number_displayed) != current_column ())); | 10771 | && (w->column_number_displayed != current_column ())); |
| 10936 | } | 10772 | } |
| 10937 | 10773 | ||
| 10938 | /*********************************************************************** | 10774 | /*********************************************************************** |
| @@ -12494,11 +12330,7 @@ hscroll_window_tree (Lisp_Object window) | |||
| 12494 | if (w == XWINDOW (selected_window)) | 12330 | if (w == XWINDOW (selected_window)) |
| 12495 | pt = PT; | 12331 | pt = PT; |
| 12496 | else | 12332 | else |
| 12497 | { | 12333 | pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV); |
| 12498 | pt = marker_position (w->pointm); | ||
| 12499 | pt = max (BEGV, pt); | ||
| 12500 | pt = min (ZV, pt); | ||
| 12501 | } | ||
| 12502 | 12334 | ||
| 12503 | /* Move iterator to pt starting at cursor_row->start in | 12335 | /* Move iterator to pt starting at cursor_row->start in |
| 12504 | a line with infinite width. */ | 12336 | a line with infinite width. */ |
| @@ -12914,10 +12746,10 @@ static void | |||
| 12914 | reconsider_clip_changes (struct window *w, struct buffer *b) | 12746 | reconsider_clip_changes (struct window *w, struct buffer *b) |
| 12915 | { | 12747 | { |
| 12916 | if (b->clip_changed | 12748 | if (b->clip_changed |
| 12917 | && !NILP (w->window_end_valid) | 12749 | && w->window_end_valid |
| 12918 | && w->current_matrix->buffer == b | 12750 | && w->current_matrix->buffer == b |
| 12919 | && w->current_matrix->zv == BUF_ZV (b) | 12751 | && w->current_matrix->zv == BUF_ZV (b) |
| 12920 | && w->current_matrix->begv == BUF_BEGV (b)) | 12752 | && w->current_matrix->begv == BUF_BEGV (b)) |
| 12921 | b->clip_changed = 0; | 12753 | b->clip_changed = 0; |
| 12922 | 12754 | ||
| 12923 | /* If display wasn't paused, and W is not a tool bar window, see if | 12755 | /* If display wasn't paused, and W is not a tool bar window, see if |
| @@ -12925,8 +12757,7 @@ reconsider_clip_changes (struct window *w, struct buffer *b) | |||
| 12925 | we set b->clip_changed to 1 to force updating the screen. If | 12757 | we set b->clip_changed to 1 to force updating the screen. If |
| 12926 | b->clip_changed has already been set to 1, we can skip this | 12758 | b->clip_changed has already been set to 1, we can skip this |
| 12927 | check. */ | 12759 | check. */ |
| 12928 | if (!b->clip_changed | 12760 | if (!b->clip_changed && BUFFERP (w->buffer) && w->window_end_valid) |
| 12929 | && BUFFERP (w->buffer) && !NILP (w->window_end_valid)) | ||
| 12930 | { | 12761 | { |
| 12931 | ptrdiff_t pt; | 12762 | ptrdiff_t pt; |
| 12932 | 12763 | ||
| @@ -12945,46 +12776,6 @@ reconsider_clip_changes (struct window *w, struct buffer *b) | |||
| 12945 | } | 12776 | } |
| 12946 | 12777 | ||
| 12947 | 12778 | ||
| 12948 | /* Select FRAME to forward the values of frame-local variables into C | ||
| 12949 | variables so that the redisplay routines can access those values | ||
| 12950 | directly. */ | ||
| 12951 | |||
| 12952 | static void | ||
| 12953 | select_frame_for_redisplay (Lisp_Object frame) | ||
| 12954 | { | ||
| 12955 | Lisp_Object tail, tem; | ||
| 12956 | Lisp_Object old = selected_frame; | ||
| 12957 | struct Lisp_Symbol *sym; | ||
| 12958 | |||
| 12959 | eassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame))); | ||
| 12960 | |||
| 12961 | selected_frame = frame; | ||
| 12962 | |||
| 12963 | do { | ||
| 12964 | for (tail = XFRAME (frame)->param_alist; | ||
| 12965 | CONSP (tail); tail = XCDR (tail)) | ||
| 12966 | if (CONSP (XCAR (tail)) | ||
| 12967 | && (tem = XCAR (XCAR (tail)), | ||
| 12968 | SYMBOLP (tem)) | ||
| 12969 | && (sym = indirect_variable (XSYMBOL (tem)), | ||
| 12970 | sym->redirect == SYMBOL_LOCALIZED) | ||
| 12971 | && sym->val.blv->frame_local) | ||
| 12972 | /* Use find_symbol_value rather than Fsymbol_value | ||
| 12973 | to avoid an error if it is void. */ | ||
| 12974 | find_symbol_value (tem); | ||
| 12975 | } while (!EQ (frame, old) && (frame = old, 1)); | ||
| 12976 | } | ||
| 12977 | |||
| 12978 | /* Make sure that previously selected OLD_FRAME is selected unless it has been | ||
| 12979 | deleted (by an X connection failure during redisplay, for example). */ | ||
| 12980 | |||
| 12981 | static void | ||
| 12982 | ensure_selected_frame (Lisp_Object old_frame) | ||
| 12983 | { | ||
| 12984 | if (!EQ (old_frame, selected_frame) && FRAME_LIVE_P (XFRAME (old_frame))) | ||
| 12985 | select_frame_for_redisplay (old_frame); | ||
| 12986 | } | ||
| 12987 | |||
| 12988 | #define STOP_POLLING \ | 12779 | #define STOP_POLLING \ |
| 12989 | do { if (! polling_stopped_here) stop_polling (); \ | 12780 | do { if (! polling_stopped_here) stop_polling (); \ |
| 12990 | polling_stopped_here = 1; } while (0) | 12781 | polling_stopped_here = 1; } while (0) |
| @@ -13010,7 +12801,7 @@ redisplay_internal (void) | |||
| 13010 | ptrdiff_t count, count1; | 12801 | ptrdiff_t count, count1; |
| 13011 | struct frame *sf; | 12802 | struct frame *sf; |
| 13012 | int polling_stopped_here = 0; | 12803 | int polling_stopped_here = 0; |
| 13013 | Lisp_Object tail, frame, old_frame = selected_frame; | 12804 | Lisp_Object tail, frame; |
| 13014 | struct backtrace backtrace; | 12805 | struct backtrace backtrace; |
| 13015 | 12806 | ||
| 13016 | /* Non-zero means redisplay has to consider all windows on all | 12807 | /* Non-zero means redisplay has to consider all windows on all |
| @@ -13069,12 +12860,6 @@ redisplay_internal (void) | |||
| 13069 | /* Remember the currently selected window. */ | 12860 | /* Remember the currently selected window. */ |
| 13070 | sw = w; | 12861 | sw = w; |
| 13071 | 12862 | ||
| 13072 | /* When running redisplay, we play a bit fast-and-loose and allow e.g. | ||
| 13073 | selected_frame and selected_window to be temporarily out-of-sync so | ||
| 13074 | when we come back here via `goto retry', we need to resync because we | ||
| 13075 | may need to run Elisp code (via prepare_menu_bars). */ | ||
| 13076 | ensure_selected_frame (old_frame); | ||
| 13077 | |||
| 13078 | pending = 0; | 12863 | pending = 0; |
| 13079 | reconsider_clip_changes (w, current_buffer); | 12864 | reconsider_clip_changes (w, current_buffer); |
| 13080 | last_escape_glyph_frame = NULL; | 12865 | last_escape_glyph_frame = NULL; |
| @@ -13120,7 +12905,6 @@ redisplay_internal (void) | |||
| 13120 | { | 12905 | { |
| 13121 | struct frame *f = XFRAME (frame); | 12906 | struct frame *f = XFRAME (frame); |
| 13122 | 12907 | ||
| 13123 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 13124 | if (FRAME_VISIBLE_P (f)) | 12908 | if (FRAME_VISIBLE_P (f)) |
| 13125 | ++number_of_visible_frames; | 12909 | ++number_of_visible_frames; |
| 13126 | clear_desired_matrices (f); | 12910 | clear_desired_matrices (f); |
| @@ -13237,16 +13021,15 @@ redisplay_internal (void) | |||
| 13237 | clear_garbaged_frames (); | 13021 | clear_garbaged_frames (); |
| 13238 | } | 13022 | } |
| 13239 | 13023 | ||
| 13240 | |||
| 13241 | /* If showing the region, and mark has changed, we must redisplay | 13024 | /* If showing the region, and mark has changed, we must redisplay |
| 13242 | the whole window. The assignment to this_line_start_pos prevents | 13025 | the whole window. The assignment to this_line_start_pos prevents |
| 13243 | the optimization directly below this if-statement. */ | 13026 | the optimization directly below this if-statement. */ |
| 13244 | if (((!NILP (Vtransient_mark_mode) | 13027 | if (((!NILP (Vtransient_mark_mode) |
| 13245 | && !NILP (BVAR (XBUFFER (w->buffer), mark_active))) | 13028 | && !NILP (BVAR (XBUFFER (w->buffer), mark_active))) |
| 13246 | != !NILP (w->region_showing)) | 13029 | != (w->region_showing > 0)) |
| 13247 | || (!NILP (w->region_showing) | 13030 | || (w->region_showing |
| 13248 | && !EQ (w->region_showing, | 13031 | && w->region_showing |
| 13249 | Fmarker_position (BVAR (XBUFFER (w->buffer), mark))))) | 13032 | != XINT (Fmarker_position (BVAR (XBUFFER (w->buffer), mark))))) |
| 13250 | CHARPOS (this_line_start_pos) = 0; | 13033 | CHARPOS (this_line_start_pos) = 0; |
| 13251 | 13034 | ||
| 13252 | /* Optimize the case that only the line containing the cursor in the | 13035 | /* Optimize the case that only the line containing the cursor in the |
| @@ -13366,7 +13149,7 @@ redisplay_internal (void) | |||
| 13366 | else if (XFASTINT (w->window_end_vpos) == this_line_vpos | 13149 | else if (XFASTINT (w->window_end_vpos) == this_line_vpos |
| 13367 | && this_line_vpos > 0) | 13150 | && this_line_vpos > 0) |
| 13368 | wset_window_end_vpos (w, make_number (this_line_vpos - 1)); | 13151 | wset_window_end_vpos (w, make_number (this_line_vpos - 1)); |
| 13369 | wset_window_end_valid (w, Qnil); | 13152 | w->window_end_valid = 0; |
| 13370 | 13153 | ||
| 13371 | /* Update hint: No need to try to scroll in update_window. */ | 13154 | /* Update hint: No need to try to scroll in update_window. */ |
| 13372 | w->desired_matrix->no_scrolling_p = 1; | 13155 | w->desired_matrix->no_scrolling_p = 1; |
| @@ -13412,7 +13195,7 @@ redisplay_internal (void) | |||
| 13412 | && (EQ (selected_window, | 13195 | && (EQ (selected_window, |
| 13413 | BVAR (current_buffer, last_selected_window)) | 13196 | BVAR (current_buffer, last_selected_window)) |
| 13414 | || highlight_nonselected_windows) | 13197 | || highlight_nonselected_windows) |
| 13415 | && NILP (w->region_showing) | 13198 | && !w->region_showing |
| 13416 | && NILP (Vshow_trailing_whitespace) | 13199 | && NILP (Vshow_trailing_whitespace) |
| 13417 | && !cursor_in_echo_area) | 13200 | && !cursor_in_echo_area) |
| 13418 | { | 13201 | { |
| @@ -13470,10 +13253,6 @@ redisplay_internal (void) | |||
| 13470 | FOR_EACH_FRAME (tail, frame) | 13253 | FOR_EACH_FRAME (tail, frame) |
| 13471 | XFRAME (frame)->updated_p = 0; | 13254 | XFRAME (frame)->updated_p = 0; |
| 13472 | 13255 | ||
| 13473 | /* Recompute # windows showing selected buffer. This will be | ||
| 13474 | incremented each time such a window is displayed. */ | ||
| 13475 | buffer_shared = 0; | ||
| 13476 | |||
| 13477 | FOR_EACH_FRAME (tail, frame) | 13256 | FOR_EACH_FRAME (tail, frame) |
| 13478 | { | 13257 | { |
| 13479 | struct frame *f = XFRAME (frame); | 13258 | struct frame *f = XFRAME (frame); |
| @@ -13486,11 +13265,6 @@ redisplay_internal (void) | |||
| 13486 | 13265 | ||
| 13487 | if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) | 13266 | if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) |
| 13488 | { | 13267 | { |
| 13489 | if (! EQ (frame, selected_frame)) | ||
| 13490 | /* Select the frame, for the sake of frame-local | ||
| 13491 | variables. */ | ||
| 13492 | select_frame_for_redisplay (frame); | ||
| 13493 | |||
| 13494 | /* Mark all the scroll bars to be removed; we'll redeem | 13268 | /* Mark all the scroll bars to be removed; we'll redeem |
| 13495 | the ones we want when we redisplay their windows. */ | 13269 | the ones we want when we redisplay their windows. */ |
| 13496 | if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook) | 13270 | if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook) |
| @@ -13540,10 +13314,6 @@ redisplay_internal (void) | |||
| 13540 | } | 13314 | } |
| 13541 | } | 13315 | } |
| 13542 | 13316 | ||
| 13543 | /* We played a bit fast-and-loose above and allowed selected_frame | ||
| 13544 | and selected_window to be temporarily out-of-sync but let's make | ||
| 13545 | sure this stays contained. */ | ||
| 13546 | ensure_selected_frame (old_frame); | ||
| 13547 | eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); | 13317 | eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); |
| 13548 | 13318 | ||
| 13549 | if (!pending) | 13319 | if (!pending) |
| @@ -13681,9 +13451,6 @@ redisplay_internal (void) | |||
| 13681 | 13451 | ||
| 13682 | if (XFRAME (frame)->visible) | 13452 | if (XFRAME (frame)->visible) |
| 13683 | this_is_visible = 1; | 13453 | this_is_visible = 1; |
| 13684 | FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); | ||
| 13685 | if (XFRAME (frame)->visible) | ||
| 13686 | this_is_visible = 1; | ||
| 13687 | 13454 | ||
| 13688 | if (this_is_visible) | 13455 | if (this_is_visible) |
| 13689 | new_count++; | 13456 | new_count++; |
| @@ -13769,55 +13536,47 @@ static Lisp_Object | |||
| 13769 | unwind_redisplay (Lisp_Object old_frame) | 13536 | unwind_redisplay (Lisp_Object old_frame) |
| 13770 | { | 13537 | { |
| 13771 | redisplaying_p = 0; | 13538 | redisplaying_p = 0; |
| 13772 | ensure_selected_frame (old_frame); | ||
| 13773 | return Qnil; | 13539 | return Qnil; |
| 13774 | } | 13540 | } |
| 13775 | 13541 | ||
| 13776 | 13542 | ||
| 13777 | /* Mark the display of window W as accurate or inaccurate. If | 13543 | /* Mark the display of leaf window W as accurate or inaccurate. |
| 13778 | ACCURATE_P is non-zero mark display of W as accurate. If | 13544 | If ACCURATE_P is non-zero mark display of W as accurate. If |
| 13779 | ACCURATE_P is zero, arrange for W to be redisplayed the next time | 13545 | ACCURATE_P is zero, arrange for W to be redisplayed the next |
| 13780 | redisplay_internal is called. */ | 13546 | time redisplay_internal is called. */ |
| 13781 | 13547 | ||
| 13782 | static void | 13548 | static void |
| 13783 | mark_window_display_accurate_1 (struct window *w, int accurate_p) | 13549 | mark_window_display_accurate_1 (struct window *w, int accurate_p) |
| 13784 | { | 13550 | { |
| 13785 | if (BUFFERP (w->buffer)) | 13551 | struct buffer *b = XBUFFER (w->buffer); |
| 13786 | { | ||
| 13787 | struct buffer *b = XBUFFER (w->buffer); | ||
| 13788 | 13552 | ||
| 13789 | w->last_modified = accurate_p ? BUF_MODIFF(b) : 0; | 13553 | w->last_modified = accurate_p ? BUF_MODIFF (b) : 0; |
| 13790 | w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF(b) : 0; | 13554 | w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0; |
| 13791 | w->last_had_star | 13555 | w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b); |
| 13792 | = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b); | ||
| 13793 | 13556 | ||
| 13794 | if (accurate_p) | 13557 | if (accurate_p) |
| 13795 | { | 13558 | { |
| 13796 | b->clip_changed = 0; | 13559 | b->clip_changed = 0; |
| 13797 | b->prevent_redisplay_optimizations_p = 0; | 13560 | b->prevent_redisplay_optimizations_p = 0; |
| 13798 | 13561 | ||
| 13799 | BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b); | 13562 | BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b); |
| 13800 | BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b); | 13563 | BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b); |
| 13801 | BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b); | 13564 | BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b); |
| 13802 | BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b); | 13565 | BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b); |
| 13803 | 13566 | ||
| 13804 | w->current_matrix->buffer = b; | 13567 | w->current_matrix->buffer = b; |
| 13805 | w->current_matrix->begv = BUF_BEGV (b); | 13568 | w->current_matrix->begv = BUF_BEGV (b); |
| 13806 | w->current_matrix->zv = BUF_ZV (b); | 13569 | w->current_matrix->zv = BUF_ZV (b); |
| 13807 | 13570 | ||
| 13808 | w->last_cursor = w->cursor; | 13571 | w->last_cursor = w->cursor; |
| 13809 | w->last_cursor_off_p = w->cursor_off_p; | 13572 | w->last_cursor_off_p = w->cursor_off_p; |
| 13810 | 13573 | ||
| 13811 | if (w == XWINDOW (selected_window)) | 13574 | if (w == XWINDOW (selected_window)) |
| 13812 | w->last_point = BUF_PT (b); | 13575 | w->last_point = BUF_PT (b); |
| 13813 | else | 13576 | else |
| 13814 | w->last_point = XMARKER (w->pointm)->charpos; | 13577 | w->last_point = marker_position (w->pointm); |
| 13815 | } | ||
| 13816 | } | ||
| 13817 | 13578 | ||
| 13818 | if (accurate_p) | 13579 | w->window_end_valid = 1; |
| 13819 | { | ||
| 13820 | wset_window_end_valid (w, w->buffer); | ||
| 13821 | w->update_mode_line = 0; | 13580 | w->update_mode_line = 0; |
| 13822 | } | 13581 | } |
| 13823 | } | 13582 | } |
| @@ -13836,25 +13595,21 @@ mark_window_display_accurate (Lisp_Object window, int accurate_p) | |||
| 13836 | for (; !NILP (window); window = w->next) | 13595 | for (; !NILP (window); window = w->next) |
| 13837 | { | 13596 | { |
| 13838 | w = XWINDOW (window); | 13597 | w = XWINDOW (window); |
| 13839 | mark_window_display_accurate_1 (w, accurate_p); | ||
| 13840 | |||
| 13841 | if (!NILP (w->vchild)) | 13598 | if (!NILP (w->vchild)) |
| 13842 | mark_window_display_accurate (w->vchild, accurate_p); | 13599 | mark_window_display_accurate (w->vchild, accurate_p); |
| 13843 | if (!NILP (w->hchild)) | 13600 | else if (!NILP (w->hchild)) |
| 13844 | mark_window_display_accurate (w->hchild, accurate_p); | 13601 | mark_window_display_accurate (w->hchild, accurate_p); |
| 13602 | else if (BUFFERP (w->buffer)) | ||
| 13603 | mark_window_display_accurate_1 (w, accurate_p); | ||
| 13845 | } | 13604 | } |
| 13846 | 13605 | ||
| 13847 | if (accurate_p) | 13606 | if (accurate_p) |
| 13848 | { | 13607 | update_overlay_arrows (1); |
| 13849 | update_overlay_arrows (1); | ||
| 13850 | } | ||
| 13851 | else | 13608 | else |
| 13852 | { | 13609 | /* Force a thorough redisplay the next time by setting |
| 13853 | /* Force a thorough redisplay the next time by setting | 13610 | last_arrow_position and last_arrow_string to t, which is |
| 13854 | last_arrow_position and last_arrow_string to t, which is | 13611 | unequal to any useful value of Voverlay_arrow_... */ |
| 13855 | unequal to any useful value of Voverlay_arrow_... */ | 13612 | update_overlay_arrows (-1); |
| 13856 | update_overlay_arrows (-1); | ||
| 13857 | } | ||
| 13858 | } | 13613 | } |
| 13859 | 13614 | ||
| 13860 | 13615 | ||
| @@ -14242,7 +13997,12 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 14242 | CHARPOS is zero or negative. */ | 13997 | CHARPOS is zero or negative. */ |
| 14243 | int empty_line_p = | 13998 | int empty_line_p = |
| 14244 | (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) | 13999 | (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) |
| 14245 | && INTEGERP (glyph->object) && glyph->charpos > 0; | 14000 | && INTEGERP (glyph->object) && glyph->charpos > 0 |
| 14001 | /* On a TTY, continued and truncated rows also have a glyph at | ||
| 14002 | their end whose OBJECT is zero and whose CHARPOS is | ||
| 14003 | positive (the continuation and truncation glyphs), but such | ||
| 14004 | rows are obviously not "empty". */ | ||
| 14005 | && !(row->continued_p || row->truncated_on_right_p); | ||
| 14246 | 14006 | ||
| 14247 | if (row->ends_in_ellipsis_p && pos_after == last_pos) | 14007 | if (row->ends_in_ellipsis_p && pos_after == last_pos) |
| 14248 | { | 14008 | { |
| @@ -14844,14 +14604,24 @@ try_scrolling (Lisp_Object window, int just_this_one_p, | |||
| 14844 | else | 14604 | else |
| 14845 | { | 14605 | { |
| 14846 | struct text_pos scroll_margin_pos = startp; | 14606 | struct text_pos scroll_margin_pos = startp; |
| 14607 | int y_offset = 0; | ||
| 14847 | 14608 | ||
| 14848 | /* See if point is inside the scroll margin at the top of the | 14609 | /* See if point is inside the scroll margin at the top of the |
| 14849 | window. */ | 14610 | window. */ |
| 14850 | if (this_scroll_margin) | 14611 | if (this_scroll_margin) |
| 14851 | { | 14612 | { |
| 14613 | int y_start; | ||
| 14614 | |||
| 14852 | start_display (&it, w, startp); | 14615 | start_display (&it, w, startp); |
| 14616 | y_start = it.current_y; | ||
| 14853 | move_it_vertically (&it, this_scroll_margin); | 14617 | move_it_vertically (&it, this_scroll_margin); |
| 14854 | scroll_margin_pos = it.current.pos; | 14618 | scroll_margin_pos = it.current.pos; |
| 14619 | /* If we didn't move enough before hitting ZV, request | ||
| 14620 | additional amount of scroll, to move point out of the | ||
| 14621 | scroll margin. */ | ||
| 14622 | if (IT_CHARPOS (it) == ZV | ||
| 14623 | && it.current_y - y_start < this_scroll_margin) | ||
| 14624 | y_offset = this_scroll_margin - (it.current_y - y_start); | ||
| 14855 | } | 14625 | } |
| 14856 | 14626 | ||
| 14857 | if (PT < CHARPOS (scroll_margin_pos)) | 14627 | if (PT < CHARPOS (scroll_margin_pos)) |
| @@ -14878,6 +14648,9 @@ try_scrolling (Lisp_Object window, int just_this_one_p, | |||
| 14878 | || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos)) | 14648 | || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos)) |
| 14879 | return SCROLLING_FAILED; | 14649 | return SCROLLING_FAILED; |
| 14880 | 14650 | ||
| 14651 | /* Additional scroll for when ZV was too close to point. */ | ||
| 14652 | dy += y_offset; | ||
| 14653 | |||
| 14881 | /* Compute new window start. */ | 14654 | /* Compute new window start. */ |
| 14882 | start_display (&it, w, startp); | 14655 | start_display (&it, w, startp); |
| 14883 | 14656 | ||
| @@ -14932,7 +14705,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p, | |||
| 14932 | if (!just_this_one_p | 14705 | if (!just_this_one_p |
| 14933 | || current_buffer->clip_changed | 14706 | || current_buffer->clip_changed |
| 14934 | || BEG_UNCHANGED < CHARPOS (startp)) | 14707 | || BEG_UNCHANGED < CHARPOS (startp)) |
| 14935 | wset_base_line_number (w, Qnil); | 14708 | w->base_line_number = 0; |
| 14936 | 14709 | ||
| 14937 | /* If cursor ends up on a partially visible line, | 14710 | /* If cursor ends up on a partially visible line, |
| 14938 | treat that as being off the bottom of the screen. */ | 14711 | treat that as being off the bottom of the screen. */ |
| @@ -14985,7 +14758,7 @@ compute_window_start_on_continuation_line (struct window *w) | |||
| 14985 | SET_TEXT_POS (start_pos, ZV, ZV_BYTE); | 14758 | SET_TEXT_POS (start_pos, ZV, ZV_BYTE); |
| 14986 | 14759 | ||
| 14987 | /* Find the start of the continued line. This should be fast | 14760 | /* Find the start of the continued line. This should be fast |
| 14988 | because scan_buffer is fast (newline cache). */ | 14761 | because find_newline is fast (newline cache). */ |
| 14989 | row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); | 14762 | row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); |
| 14990 | init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), | 14763 | init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), |
| 14991 | row, DEFAULT_FACE_ID); | 14764 | row, DEFAULT_FACE_ID); |
| @@ -15080,9 +14853,8 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste | |||
| 15080 | /* Can't use this case if highlighting a region. When a | 14853 | /* Can't use this case if highlighting a region. When a |
| 15081 | region exists, cursor movement has to do more than just | 14854 | region exists, cursor movement has to do more than just |
| 15082 | set the cursor. */ | 14855 | set the cursor. */ |
| 15083 | && !(!NILP (Vtransient_mark_mode) | 14856 | && markpos_of_region () < 0 |
| 15084 | && !NILP (BVAR (current_buffer, mark_active))) | 14857 | && !w->region_showing |
| 15085 | && NILP (w->region_showing) | ||
| 15086 | && NILP (Vshow_trailing_whitespace) | 14858 | && NILP (Vshow_trailing_whitespace) |
| 15087 | /* This code is not used for mini-buffer for the sake of the case | 14859 | /* This code is not used for mini-buffer for the sake of the case |
| 15088 | of redisplaying to replace an echo area message; since in | 14860 | of redisplaying to replace an echo area message; since in |
| @@ -15519,7 +15291,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15519 | set_buffer_internal_1 (XBUFFER (w->buffer)); | 15291 | set_buffer_internal_1 (XBUFFER (w->buffer)); |
| 15520 | 15292 | ||
| 15521 | current_matrix_up_to_date_p | 15293 | current_matrix_up_to_date_p |
| 15522 | = (!NILP (w->window_end_valid) | 15294 | = (w->window_end_valid |
| 15523 | && !current_buffer->clip_changed | 15295 | && !current_buffer->clip_changed |
| 15524 | && !current_buffer->prevent_redisplay_optimizations_p | 15296 | && !current_buffer->prevent_redisplay_optimizations_p |
| 15525 | && !window_outdated (w)); | 15297 | && !window_outdated (w)); |
| @@ -15542,7 +15314,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15542 | specbind (Qinhibit_point_motion_hooks, Qt); | 15314 | specbind (Qinhibit_point_motion_hooks, Qt); |
| 15543 | 15315 | ||
| 15544 | buffer_unchanged_p | 15316 | buffer_unchanged_p |
| 15545 | = (!NILP (w->window_end_valid) | 15317 | = (w->window_end_valid |
| 15546 | && !current_buffer->clip_changed | 15318 | && !current_buffer->clip_changed |
| 15547 | && !window_outdated (w)); | 15319 | && !window_outdated (w)); |
| 15548 | 15320 | ||
| @@ -15555,7 +15327,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15555 | if (XMARKER (w->start)->buffer == current_buffer) | 15327 | if (XMARKER (w->start)->buffer == current_buffer) |
| 15556 | compute_window_start_on_continuation_line (w); | 15328 | compute_window_start_on_continuation_line (w); |
| 15557 | 15329 | ||
| 15558 | wset_window_end_valid (w, Qnil); | 15330 | w->window_end_valid = 0; |
| 15559 | } | 15331 | } |
| 15560 | 15332 | ||
| 15561 | /* Some sanity checks. */ | 15333 | /* Some sanity checks. */ |
| @@ -15568,26 +15340,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15568 | if (mode_line_update_needed (w)) | 15340 | if (mode_line_update_needed (w)) |
| 15569 | update_mode_line = 1; | 15341 | update_mode_line = 1; |
| 15570 | 15342 | ||
| 15571 | /* Count number of windows showing the selected buffer. An indirect | ||
| 15572 | buffer counts as its base buffer. */ | ||
| 15573 | if (!just_this_one_p) | ||
| 15574 | { | ||
| 15575 | struct buffer *current_base, *window_base; | ||
| 15576 | current_base = current_buffer; | ||
| 15577 | window_base = XBUFFER (XWINDOW (selected_window)->buffer); | ||
| 15578 | if (current_base->base_buffer) | ||
| 15579 | current_base = current_base->base_buffer; | ||
| 15580 | if (window_base->base_buffer) | ||
| 15581 | window_base = window_base->base_buffer; | ||
| 15582 | if (current_base == window_base) | ||
| 15583 | buffer_shared++; | ||
| 15584 | } | ||
| 15585 | |||
| 15586 | /* Point refers normally to the selected window. For any other | 15343 | /* Point refers normally to the selected window. For any other |
| 15587 | window, set up appropriate value. */ | 15344 | window, set up appropriate value. */ |
| 15588 | if (!EQ (window, selected_window)) | 15345 | if (!EQ (window, selected_window)) |
| 15589 | { | 15346 | { |
| 15590 | ptrdiff_t new_pt = XMARKER (w->pointm)->charpos; | 15347 | ptrdiff_t new_pt = marker_position (w->pointm); |
| 15591 | ptrdiff_t new_pt_byte = marker_byte_position (w->pointm); | 15348 | ptrdiff_t new_pt_byte = marker_byte_position (w->pointm); |
| 15592 | if (new_pt < BEGV) | 15349 | if (new_pt < BEGV) |
| 15593 | { | 15350 | { |
| @@ -15659,11 +15416,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15659 | 15416 | ||
| 15660 | w->force_start = 0; | 15417 | w->force_start = 0; |
| 15661 | w->vscroll = 0; | 15418 | w->vscroll = 0; |
| 15662 | wset_window_end_valid (w, Qnil); | 15419 | w->window_end_valid = 0; |
| 15663 | 15420 | ||
| 15664 | /* Forget any recorded base line for line number display. */ | 15421 | /* Forget any recorded base line for line number display. */ |
| 15665 | if (!buffer_unchanged_p) | 15422 | if (!buffer_unchanged_p) |
| 15666 | wset_base_line_number (w, Qnil); | 15423 | w->base_line_number = 0; |
| 15667 | 15424 | ||
| 15668 | /* Redisplay the mode line. Select the buffer properly for that. | 15425 | /* Redisplay the mode line. Select the buffer properly for that. |
| 15669 | Also, run the hook window-scroll-functions | 15426 | Also, run the hook window-scroll-functions |
| @@ -15718,7 +15475,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15718 | /* Some people insist on not letting point enter the scroll | 15475 | /* Some people insist on not letting point enter the scroll |
| 15719 | margin, even though this part handles windows that didn't | 15476 | margin, even though this part handles windows that didn't |
| 15720 | scroll at all. */ | 15477 | scroll at all. */ |
| 15721 | struct frame *f = XFRAME (w->frame); | ||
| 15722 | int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); | 15478 | int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); |
| 15723 | int pixel_margin = margin * FRAME_LINE_HEIGHT (f); | 15479 | int pixel_margin = margin * FRAME_LINE_HEIGHT (f); |
| 15724 | bool header_line = WINDOW_WANTS_HEADER_LINE_P (w); | 15480 | bool header_line = WINDOW_WANTS_HEADER_LINE_P (w); |
| @@ -15765,8 +15521,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15765 | 15521 | ||
| 15766 | /* If we are highlighting the region, then we just changed | 15522 | /* If we are highlighting the region, then we just changed |
| 15767 | the region, so redisplay to show it. */ | 15523 | the region, so redisplay to show it. */ |
| 15768 | if (!NILP (Vtransient_mark_mode) | 15524 | if (0 <= markpos_of_region ()) |
| 15769 | && !NILP (BVAR (current_buffer, mark_active))) | ||
| 15770 | { | 15525 | { |
| 15771 | clear_glyph_matrix (w->desired_matrix); | 15526 | clear_glyph_matrix (w->desired_matrix); |
| 15772 | if (!try_window (window, startp, 0)) | 15527 | if (!try_window (window, startp, 0)) |
| @@ -15905,7 +15660,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15905 | || current_buffer->clip_changed | 15660 | || current_buffer->clip_changed |
| 15906 | || BEG_UNCHANGED < CHARPOS (startp)) | 15661 | || BEG_UNCHANGED < CHARPOS (startp)) |
| 15907 | /* Forget any recorded base line for line number display. */ | 15662 | /* Forget any recorded base line for line number display. */ |
| 15908 | wset_base_line_number (w, Qnil); | 15663 | w->base_line_number = 0; |
| 15909 | 15664 | ||
| 15910 | if (!cursor_row_fully_visible_p (w, 1, 0)) | 15665 | if (!cursor_row_fully_visible_p (w, 1, 0)) |
| 15911 | { | 15666 | { |
| @@ -15972,11 +15727,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15972 | debug_method_add (w, "recenter"); | 15727 | debug_method_add (w, "recenter"); |
| 15973 | #endif | 15728 | #endif |
| 15974 | 15729 | ||
| 15975 | /* w->vscroll = 0; */ | ||
| 15976 | |||
| 15977 | /* Forget any previously recorded base line for line number display. */ | 15730 | /* Forget any previously recorded base line for line number display. */ |
| 15978 | if (!buffer_unchanged_p) | 15731 | if (!buffer_unchanged_p) |
| 15979 | wset_base_line_number (w, Qnil); | 15732 | w->base_line_number = 0; |
| 15980 | 15733 | ||
| 15981 | /* Determine the window start relative to point. */ | 15734 | /* Determine the window start relative to point. */ |
| 15982 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); | 15735 | init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); |
| @@ -16110,8 +15863,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 16110 | line.) */ | 15863 | line.) */ |
| 16111 | if (w->cursor.vpos < 0) | 15864 | if (w->cursor.vpos < 0) |
| 16112 | { | 15865 | { |
| 16113 | if (!NILP (w->window_end_valid) | 15866 | if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos)) |
| 16114 | && PT >= Z - XFASTINT (w->window_end_pos)) | ||
| 16115 | { | 15867 | { |
| 16116 | clear_glyph_matrix (w->desired_matrix); | 15868 | clear_glyph_matrix (w->desired_matrix); |
| 16117 | move_it_by_lines (&it, 1); | 15869 | move_it_by_lines (&it, 1); |
| @@ -16197,10 +15949,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 16197 | && !FRAME_WINDOW_P (f) | 15949 | && !FRAME_WINDOW_P (f) |
| 16198 | && !WINDOW_FULL_WIDTH_P (w)) | 15950 | && !WINDOW_FULL_WIDTH_P (w)) |
| 16199 | /* Line number to display. */ | 15951 | /* Line number to display. */ |
| 16200 | || INTEGERP (w->base_line_pos) | 15952 | || w->base_line_pos > 0 |
| 16201 | /* Column number is displayed and different from the one displayed. */ | 15953 | /* Column number is displayed and different from the one displayed. */ |
| 16202 | || (!NILP (w->column_number_displayed) | 15954 | || (w->column_number_displayed != -1 |
| 16203 | && (XFASTINT (w->column_number_displayed) != current_column ()))) | 15955 | && (w->column_number_displayed != current_column ()))) |
| 16204 | /* This means that the window has a mode line. */ | 15956 | /* This means that the window has a mode line. */ |
| 16205 | && (WINDOW_WANTS_MODELINE_P (w) | 15957 | && (WINDOW_WANTS_MODELINE_P (w) |
| 16206 | || WINDOW_WANTS_HEADER_LINE_P (w))) | 15958 | || WINDOW_WANTS_HEADER_LINE_P (w))) |
| @@ -16231,11 +15983,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 16231 | goto need_larger_matrices; | 15983 | goto need_larger_matrices; |
| 16232 | } | 15984 | } |
| 16233 | 15985 | ||
| 16234 | if (!line_number_displayed | 15986 | if (!line_number_displayed && w->base_line_pos != -1) |
| 16235 | && !BUFFERP (w->base_line_pos)) | ||
| 16236 | { | 15987 | { |
| 16237 | wset_base_line_pos (w, Qnil); | 15988 | w->base_line_pos = 0; |
| 16238 | wset_base_line_number (w, Qnil); | 15989 | w->base_line_number = 0; |
| 16239 | } | 15990 | } |
| 16240 | 15991 | ||
| 16241 | finish_menu_bars: | 15992 | finish_menu_bars: |
| @@ -16428,7 +16179,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) | |||
| 16428 | } | 16179 | } |
| 16429 | 16180 | ||
| 16430 | /* But that is not valid info until redisplay finishes. */ | 16181 | /* But that is not valid info until redisplay finishes. */ |
| 16431 | wset_window_end_valid (w, Qnil); | 16182 | w->window_end_valid = 0; |
| 16432 | return 1; | 16183 | return 1; |
| 16433 | } | 16184 | } |
| 16434 | 16185 | ||
| @@ -16471,9 +16222,8 @@ try_window_reusing_current_matrix (struct window *w) | |||
| 16471 | return 0; | 16222 | return 0; |
| 16472 | 16223 | ||
| 16473 | /* Can't do this if region may have changed. */ | 16224 | /* Can't do this if region may have changed. */ |
| 16474 | if ((!NILP (Vtransient_mark_mode) | 16225 | if (0 <= markpos_of_region () |
| 16475 | && !NILP (BVAR (current_buffer, mark_active))) | 16226 | || w->region_showing |
| 16476 | || !NILP (w->region_showing) | ||
| 16477 | || !NILP (Vshow_trailing_whitespace)) | 16227 | || !NILP (Vshow_trailing_whitespace)) |
| 16478 | return 0; | 16228 | return 0; |
| 16479 | 16229 | ||
| @@ -16676,7 +16426,7 @@ try_window_reusing_current_matrix (struct window *w) | |||
| 16676 | wset_window_end_pos (w, make_number (Z - ZV)); | 16426 | wset_window_end_pos (w, make_number (Z - ZV)); |
| 16677 | wset_window_end_vpos (w, make_number (0)); | 16427 | wset_window_end_vpos (w, make_number (0)); |
| 16678 | } | 16428 | } |
| 16679 | wset_window_end_valid (w, Qnil); | 16429 | w->window_end_valid = 0; |
| 16680 | 16430 | ||
| 16681 | /* Update hint: don't try scrolling again in update_window. */ | 16431 | /* Update hint: don't try scrolling again in update_window. */ |
| 16682 | w->desired_matrix->no_scrolling_p = 1; | 16432 | w->desired_matrix->no_scrolling_p = 1; |
| @@ -16874,7 +16624,7 @@ try_window_reusing_current_matrix (struct window *w) | |||
| 16874 | (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled)); | 16624 | (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled)); |
| 16875 | } | 16625 | } |
| 16876 | 16626 | ||
| 16877 | wset_window_end_valid (w, Qnil); | 16627 | w->window_end_valid = 0; |
| 16878 | w->desired_matrix->no_scrolling_p = 1; | 16628 | w->desired_matrix->no_scrolling_p = 1; |
| 16879 | 16629 | ||
| 16880 | #ifdef GLYPH_DEBUG | 16630 | #ifdef GLYPH_DEBUG |
| @@ -17007,7 +16757,7 @@ find_first_unchanged_at_end_row (struct window *w, | |||
| 17007 | 16757 | ||
| 17008 | /* Display must not have been paused, otherwise the current matrix | 16758 | /* Display must not have been paused, otherwise the current matrix |
| 17009 | is not up to date. */ | 16759 | is not up to date. */ |
| 17010 | eassert (!NILP (w->window_end_valid)); | 16760 | eassert (w->window_end_valid); |
| 17011 | 16761 | ||
| 17012 | /* A value of window_end_pos >= END_UNCHANGED means that the window | 16762 | /* A value of window_end_pos >= END_UNCHANGED means that the window |
| 17013 | end is in the range of changed text. If so, there is no | 16763 | end is in the range of changed text. If so, there is no |
| @@ -17191,7 +16941,7 @@ row_containing_pos (struct window *w, ptrdiff_t charpos, | |||
| 17191 | 16941 | ||
| 17192 | /* Try to redisplay window W by reusing its existing display. W's | 16942 | /* Try to redisplay window W by reusing its existing display. W's |
| 17193 | current matrix must be up to date when this function is called, | 16943 | current matrix must be up to date when this function is called, |
| 17194 | i.e. window_end_valid must not be nil. | 16944 | i.e. window_end_valid must be nonzero. |
| 17195 | 16945 | ||
| 17196 | Value is | 16946 | Value is |
| 17197 | 16947 | ||
| @@ -17299,13 +17049,12 @@ try_window_id (struct window *w) | |||
| 17299 | GIVE_UP (7); | 17049 | GIVE_UP (7); |
| 17300 | 17050 | ||
| 17301 | /* Verify that display wasn't paused. */ | 17051 | /* Verify that display wasn't paused. */ |
| 17302 | if (NILP (w->window_end_valid)) | 17052 | if (!w->window_end_valid) |
| 17303 | GIVE_UP (8); | 17053 | GIVE_UP (8); |
| 17304 | 17054 | ||
| 17305 | /* Can't use this if highlighting a region because a cursor movement | 17055 | /* Can't use this if highlighting a region because a cursor movement |
| 17306 | will do more than just set the cursor. */ | 17056 | will do more than just set the cursor. */ |
| 17307 | if (!NILP (Vtransient_mark_mode) | 17057 | if (0 <= markpos_of_region ()) |
| 17308 | && !NILP (BVAR (current_buffer, mark_active))) | ||
| 17309 | GIVE_UP (9); | 17058 | GIVE_UP (9); |
| 17310 | 17059 | ||
| 17311 | /* Likewise if highlighting trailing whitespace. */ | 17060 | /* Likewise if highlighting trailing whitespace. */ |
| @@ -17313,7 +17062,7 @@ try_window_id (struct window *w) | |||
| 17313 | GIVE_UP (11); | 17062 | GIVE_UP (11); |
| 17314 | 17063 | ||
| 17315 | /* Likewise if showing a region. */ | 17064 | /* Likewise if showing a region. */ |
| 17316 | if (!NILP (w->region_showing)) | 17065 | if (w->region_showing) |
| 17317 | GIVE_UP (10); | 17066 | GIVE_UP (10); |
| 17318 | 17067 | ||
| 17319 | /* Can't use this if overlay arrow position and/or string have | 17068 | /* Can't use this if overlay arrow position and/or string have |
| @@ -17951,7 +17700,7 @@ try_window_id (struct window *w) | |||
| 17951 | debug_end_vpos = XFASTINT (w->window_end_vpos)); | 17700 | debug_end_vpos = XFASTINT (w->window_end_vpos)); |
| 17952 | 17701 | ||
| 17953 | /* Record that display has not been completed. */ | 17702 | /* Record that display has not been completed. */ |
| 17954 | wset_window_end_valid (w, Qnil); | 17703 | w->window_end_valid = 0; |
| 17955 | w->desired_matrix->no_scrolling_p = 1; | 17704 | w->desired_matrix->no_scrolling_p = 1; |
| 17956 | return 3; | 17705 | return 3; |
| 17957 | 17706 | ||
| @@ -17992,18 +17741,23 @@ dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs) | |||
| 17992 | void | 17741 | void |
| 17993 | dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | 17742 | dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) |
| 17994 | { | 17743 | { |
| 17995 | if (glyph->type == CHAR_GLYPH) | 17744 | if (glyph->type == CHAR_GLYPH |
| 17745 | || glyph->type == GLYPHLESS_GLYPH) | ||
| 17996 | { | 17746 | { |
| 17997 | fprintf (stderr, | 17747 | fprintf (stderr, |
| 17998 | " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", | 17748 | " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n", |
| 17999 | glyph - row->glyphs[TEXT_AREA], | 17749 | glyph - row->glyphs[TEXT_AREA], |
| 18000 | 'C', | 17750 | (glyph->type == CHAR_GLYPH |
| 17751 | ? 'C' | ||
| 17752 | : 'G'), | ||
| 18001 | glyph->charpos, | 17753 | glyph->charpos, |
| 18002 | (BUFFERP (glyph->object) | 17754 | (BUFFERP (glyph->object) |
| 18003 | ? 'B' | 17755 | ? 'B' |
| 18004 | : (STRINGP (glyph->object) | 17756 | : (STRINGP (glyph->object) |
| 18005 | ? 'S' | 17757 | ? 'S' |
| 18006 | : '-')), | 17758 | : (INTEGERP (glyph->object) |
| 17759 | ? '0' | ||
| 17760 | : '-'))), | ||
| 18007 | glyph->pixel_width, | 17761 | glyph->pixel_width, |
| 18008 | glyph->u.ch, | 17762 | glyph->u.ch, |
| 18009 | (glyph->u.ch < 0x80 && glyph->u.ch >= ' ' | 17763 | (glyph->u.ch < 0x80 && glyph->u.ch >= ' ' |
| @@ -18016,7 +17770,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | |||
| 18016 | else if (glyph->type == STRETCH_GLYPH) | 17770 | else if (glyph->type == STRETCH_GLYPH) |
| 18017 | { | 17771 | { |
| 18018 | fprintf (stderr, | 17772 | fprintf (stderr, |
| 18019 | " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", | 17773 | " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n", |
| 18020 | glyph - row->glyphs[TEXT_AREA], | 17774 | glyph - row->glyphs[TEXT_AREA], |
| 18021 | 'S', | 17775 | 'S', |
| 18022 | glyph->charpos, | 17776 | glyph->charpos, |
| @@ -18024,10 +17778,12 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | |||
| 18024 | ? 'B' | 17778 | ? 'B' |
| 18025 | : (STRINGP (glyph->object) | 17779 | : (STRINGP (glyph->object) |
| 18026 | ? 'S' | 17780 | ? 'S' |
| 18027 | : '-')), | 17781 | : (INTEGERP (glyph->object) |
| 17782 | ? '0' | ||
| 17783 | : '-'))), | ||
| 18028 | glyph->pixel_width, | 17784 | glyph->pixel_width, |
| 18029 | 0, | 17785 | 0, |
| 18030 | '.', | 17786 | ' ', |
| 18031 | glyph->face_id, | 17787 | glyph->face_id, |
| 18032 | glyph->left_box_line_p, | 17788 | glyph->left_box_line_p, |
| 18033 | glyph->right_box_line_p); | 17789 | glyph->right_box_line_p); |
| @@ -18035,7 +17791,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | |||
| 18035 | else if (glyph->type == IMAGE_GLYPH) | 17791 | else if (glyph->type == IMAGE_GLYPH) |
| 18036 | { | 17792 | { |
| 18037 | fprintf (stderr, | 17793 | fprintf (stderr, |
| 18038 | " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", | 17794 | " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n", |
| 18039 | glyph - row->glyphs[TEXT_AREA], | 17795 | glyph - row->glyphs[TEXT_AREA], |
| 18040 | 'I', | 17796 | 'I', |
| 18041 | glyph->charpos, | 17797 | glyph->charpos, |
| @@ -18043,7 +17799,9 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | |||
| 18043 | ? 'B' | 17799 | ? 'B' |
| 18044 | : (STRINGP (glyph->object) | 17800 | : (STRINGP (glyph->object) |
| 18045 | ? 'S' | 17801 | ? 'S' |
| 18046 | : '-')), | 17802 | : (INTEGERP (glyph->object) |
| 17803 | ? '0' | ||
| 17804 | : '-'))), | ||
| 18047 | glyph->pixel_width, | 17805 | glyph->pixel_width, |
| 18048 | glyph->u.img_id, | 17806 | glyph->u.img_id, |
| 18049 | '.', | 17807 | '.', |
| @@ -18054,7 +17812,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | |||
| 18054 | else if (glyph->type == COMPOSITE_GLYPH) | 17812 | else if (glyph->type == COMPOSITE_GLYPH) |
| 18055 | { | 17813 | { |
| 18056 | fprintf (stderr, | 17814 | fprintf (stderr, |
| 18057 | " %5td %4c %6"pI"d %c %3d 0x%05x", | 17815 | " %5"pD"d %c %9"pI"d %c %3d 0x%06x", |
| 18058 | glyph - row->glyphs[TEXT_AREA], | 17816 | glyph - row->glyphs[TEXT_AREA], |
| 18059 | '+', | 17817 | '+', |
| 18060 | glyph->charpos, | 17818 | glyph->charpos, |
| @@ -18062,7 +17820,9 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) | |||
| 18062 | ? 'B' | 17820 | ? 'B' |
| 18063 | : (STRINGP (glyph->object) | 17821 | : (STRINGP (glyph->object) |
| 18064 | ? 'S' | 17822 | ? 'S' |
| 18065 | : '-')), | 17823 | : (INTEGERP (glyph->object) |
| 17824 | ? '0' | ||
| 17825 | : '-'))), | ||
| 18066 | glyph->pixel_width, | 17826 | glyph->pixel_width, |
| 18067 | glyph->u.cmp.id); | 17827 | glyph->u.cmp.id); |
| 18068 | if (glyph->u.cmp.automatic) | 17828 | if (glyph->u.cmp.automatic) |
| @@ -18087,10 +17847,10 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) | |||
| 18087 | { | 17847 | { |
| 18088 | if (glyphs != 1) | 17848 | if (glyphs != 1) |
| 18089 | { | 17849 | { |
| 18090 | fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n"); | 17850 | fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n"); |
| 18091 | fprintf (stderr, "======================================================================\n"); | 17851 | fprintf (stderr, "==============================================================================\n"); |
| 18092 | 17852 | ||
| 18093 | fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\ | 17853 | fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\ |
| 18094 | %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n", | 17854 | %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n", |
| 18095 | vpos, | 17855 | vpos, |
| 18096 | MATRIX_ROW_START_CHARPOS (row), | 17856 | MATRIX_ROW_START_CHARPOS (row), |
| @@ -18115,13 +17875,14 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) | |||
| 18115 | row->visible_height, | 17875 | row->visible_height, |
| 18116 | row->ascent, | 17876 | row->ascent, |
| 18117 | row->phys_ascent); | 17877 | row->phys_ascent); |
| 18118 | fprintf (stderr, "%9"pD"d %5"pD"d\t%5d\n", row->start.overlay_string_index, | 17878 | /* The next 3 lines should align to "Start" in the header. */ |
| 17879 | fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index, | ||
| 18119 | row->end.overlay_string_index, | 17880 | row->end.overlay_string_index, |
| 18120 | row->continuation_lines_width); | 17881 | row->continuation_lines_width); |
| 18121 | fprintf (stderr, "%9"pI"d %5"pI"d\n", | 17882 | fprintf (stderr, " %9"pI"d %9"pI"d\n", |
| 18122 | CHARPOS (row->start.string_pos), | 17883 | CHARPOS (row->start.string_pos), |
| 18123 | CHARPOS (row->end.string_pos)); | 17884 | CHARPOS (row->end.string_pos)); |
| 18124 | fprintf (stderr, "%9d %5d\n", row->start.dpvec_index, | 17885 | fprintf (stderr, " %9d %9d\n", row->start.dpvec_index, |
| 18125 | row->end.dpvec_index); | 17886 | row->end.dpvec_index); |
| 18126 | } | 17887 | } |
| 18127 | 17888 | ||
| @@ -18139,7 +17900,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) | |||
| 18139 | ++glyph_end; | 17900 | ++glyph_end; |
| 18140 | 17901 | ||
| 18141 | if (glyph < glyph_end) | 17902 | if (glyph < glyph_end) |
| 18142 | fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n"); | 17903 | fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n"); |
| 18143 | 17904 | ||
| 18144 | for (; glyph < glyph_end; ++glyph) | 17905 | for (; glyph < glyph_end; ++glyph) |
| 18145 | dump_glyph (row, glyph, area); | 17906 | dump_glyph (row, glyph, area); |
| @@ -18151,15 +17912,24 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) | |||
| 18151 | 17912 | ||
| 18152 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | 17913 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) |
| 18153 | { | 17914 | { |
| 18154 | char *s = alloca (row->used[area] + 1); | 17915 | char *s = alloca (row->used[area] + 4); |
| 18155 | int i; | 17916 | int i; |
| 18156 | 17917 | ||
| 18157 | for (i = 0; i < row->used[area]; ++i) | 17918 | for (i = 0; i < row->used[area]; ++i) |
| 18158 | { | 17919 | { |
| 18159 | struct glyph *glyph = row->glyphs[area] + i; | 17920 | struct glyph *glyph = row->glyphs[area] + i; |
| 18160 | if (glyph->type == CHAR_GLYPH | 17921 | if (i == row->used[area] - 1 |
| 18161 | && glyph->u.ch < 0x80 | 17922 | && area == TEXT_AREA |
| 18162 | && glyph->u.ch >= ' ') | 17923 | && INTEGERP (glyph->object) |
| 17924 | && glyph->type == CHAR_GLYPH | ||
| 17925 | && glyph->u.ch == ' ') | ||
| 17926 | { | ||
| 17927 | strcpy (&s[i], "[\\n]"); | ||
| 17928 | i += 4; | ||
| 17929 | } | ||
| 17930 | else if (glyph->type == CHAR_GLYPH | ||
| 17931 | && glyph->u.ch < 0x80 | ||
| 17932 | && glyph->u.ch >= ' ') | ||
| 18163 | s[i] = glyph->u.ch; | 17933 | s[i] = glyph->u.ch; |
| 18164 | else | 17934 | else |
| 18165 | s[i] = '.'; | 17935 | s[i] = '.'; |
| @@ -18294,7 +18064,7 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string) | |||
| 18294 | const unsigned char *arrow_end = arrow_string + arrow_len; | 18064 | const unsigned char *arrow_end = arrow_string + arrow_len; |
| 18295 | const unsigned char *p; | 18065 | const unsigned char *p; |
| 18296 | struct it it; | 18066 | struct it it; |
| 18297 | int multibyte_p; | 18067 | bool multibyte_p; |
| 18298 | int n_glyphs_before; | 18068 | int n_glyphs_before; |
| 18299 | 18069 | ||
| 18300 | set_buffer_temp (buffer); | 18070 | set_buffer_temp (buffer); |
| @@ -18638,6 +18408,7 @@ append_space_for_newline (struct it *it, int default_face_p) | |||
| 18638 | int saved_char_to_display = it->char_to_display; | 18408 | int saved_char_to_display = it->char_to_display; |
| 18639 | int saved_x = it->current_x; | 18409 | int saved_x = it->current_x; |
| 18640 | int saved_face_id = it->face_id; | 18410 | int saved_face_id = it->face_id; |
| 18411 | int saved_box_end = it->end_of_box_run_p; | ||
| 18641 | struct text_pos saved_pos; | 18412 | struct text_pos saved_pos; |
| 18642 | Lisp_Object saved_object; | 18413 | Lisp_Object saved_object; |
| 18643 | struct face *face; | 18414 | struct face *face; |
| @@ -18659,6 +18430,16 @@ append_space_for_newline (struct it *it, int default_face_p) | |||
| 18659 | it->face_id = it->saved_face_id; | 18430 | it->face_id = it->saved_face_id; |
| 18660 | face = FACE_FROM_ID (it->f, it->face_id); | 18431 | face = FACE_FROM_ID (it->f, it->face_id); |
| 18661 | it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); | 18432 | it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); |
| 18433 | /* In R2L rows, we will prepend a stretch glyph that will | ||
| 18434 | have the end_of_box_run_p flag set for it, so there's no | ||
| 18435 | need for the appended newline glyph to have that flag | ||
| 18436 | set. */ | ||
| 18437 | if (it->glyph_row->reversed_p | ||
| 18438 | /* But if the appended newline glyph goes all the way to | ||
| 18439 | the end of the row, there will be no stretch glyph, | ||
| 18440 | so leave the box flag set. */ | ||
| 18441 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) | ||
| 18442 | it->end_of_box_run_p = 0; | ||
| 18662 | 18443 | ||
| 18663 | PRODUCE_GLYPHS (it); | 18444 | PRODUCE_GLYPHS (it); |
| 18664 | 18445 | ||
| @@ -18672,6 +18453,7 @@ append_space_for_newline (struct it *it, int default_face_p) | |||
| 18672 | it->len = saved_len; | 18453 | it->len = saved_len; |
| 18673 | it->c = saved_c; | 18454 | it->c = saved_c; |
| 18674 | it->char_to_display = saved_char_to_display; | 18455 | it->char_to_display = saved_char_to_display; |
| 18456 | it->end_of_box_run_p = saved_box_end; | ||
| 18675 | return 1; | 18457 | return 1; |
| 18676 | } | 18458 | } |
| 18677 | } | 18459 | } |
| @@ -18761,7 +18543,7 @@ extend_face_to_end_of_line (struct it *it) | |||
| 18761 | struct glyph *g; | 18543 | struct glyph *g; |
| 18762 | int row_width, stretch_ascent, stretch_width; | 18544 | int row_width, stretch_ascent, stretch_width; |
| 18763 | struct text_pos saved_pos; | 18545 | struct text_pos saved_pos; |
| 18764 | int saved_face_id, saved_avoid_cursor; | 18546 | int saved_face_id, saved_avoid_cursor, saved_box_start; |
| 18765 | 18547 | ||
| 18766 | for (row_width = 0, g = row_start; g < row_end; g++) | 18548 | for (row_width = 0, g = row_start; g < row_end; g++) |
| 18767 | row_width += g->pixel_width; | 18549 | row_width += g->pixel_width; |
| @@ -18776,6 +18558,7 @@ extend_face_to_end_of_line (struct it *it) | |||
| 18776 | saved_avoid_cursor = it->avoid_cursor_p; | 18558 | saved_avoid_cursor = it->avoid_cursor_p; |
| 18777 | it->avoid_cursor_p = 1; | 18559 | it->avoid_cursor_p = 1; |
| 18778 | saved_face_id = it->face_id; | 18560 | saved_face_id = it->face_id; |
| 18561 | saved_box_start = it->start_of_box_run_p; | ||
| 18779 | /* The last row's stretch glyph should get the default | 18562 | /* The last row's stretch glyph should get the default |
| 18780 | face, to avoid painting the rest of the window with | 18563 | face, to avoid painting the rest of the window with |
| 18781 | the region face, if the region ends at ZV. */ | 18564 | the region face, if the region ends at ZV. */ |
| @@ -18783,11 +18566,13 @@ extend_face_to_end_of_line (struct it *it) | |||
| 18783 | it->face_id = default_face->id; | 18566 | it->face_id = default_face->id; |
| 18784 | else | 18567 | else |
| 18785 | it->face_id = face->id; | 18568 | it->face_id = face->id; |
| 18569 | it->start_of_box_run_p = 0; | ||
| 18786 | append_stretch_glyph (it, make_number (0), stretch_width, | 18570 | append_stretch_glyph (it, make_number (0), stretch_width, |
| 18787 | it->ascent + it->descent, stretch_ascent); | 18571 | it->ascent + it->descent, stretch_ascent); |
| 18788 | it->position = saved_pos; | 18572 | it->position = saved_pos; |
| 18789 | it->avoid_cursor_p = saved_avoid_cursor; | 18573 | it->avoid_cursor_p = saved_avoid_cursor; |
| 18790 | it->face_id = saved_face_id; | 18574 | it->face_id = saved_face_id; |
| 18575 | it->start_of_box_run_p = saved_box_start; | ||
| 18791 | } | 18576 | } |
| 18792 | } | 18577 | } |
| 18793 | #endif /* HAVE_WINDOW_SYSTEM */ | 18578 | #endif /* HAVE_WINDOW_SYSTEM */ |
| @@ -19364,7 +19149,7 @@ display_line (struct it *it) | |||
| 19364 | } | 19149 | } |
| 19365 | 19150 | ||
| 19366 | /* Is IT->w showing the region? */ | 19151 | /* Is IT->w showing the region? */ |
| 19367 | wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil); | 19152 | it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0; |
| 19368 | 19153 | ||
| 19369 | /* Clear the result glyph row and enable it. */ | 19154 | /* Clear the result glyph row and enable it. */ |
| 19370 | prepare_desired_row (row); | 19155 | prepare_desired_row (row); |
| @@ -20354,17 +20139,21 @@ redisplay_mode_lines (Lisp_Object window, int force) | |||
| 20354 | static int | 20139 | static int |
| 20355 | display_mode_lines (struct window *w) | 20140 | display_mode_lines (struct window *w) |
| 20356 | { | 20141 | { |
| 20357 | Lisp_Object old_selected_window, old_selected_frame; | 20142 | Lisp_Object old_selected_window = selected_window; |
| 20143 | Lisp_Object old_selected_frame = selected_frame; | ||
| 20144 | Lisp_Object new_frame = w->frame; | ||
| 20145 | Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window; | ||
| 20358 | int n = 0; | 20146 | int n = 0; |
| 20359 | 20147 | ||
| 20360 | old_selected_frame = selected_frame; | 20148 | selected_frame = new_frame; |
| 20361 | selected_frame = w->frame; | 20149 | /* FIXME: If we were to allow the mode-line's computation changing the buffer |
| 20362 | old_selected_window = selected_window; | 20150 | or window's point, then we'd need select_window_1 here as well. */ |
| 20363 | XSETWINDOW (selected_window, w); | 20151 | XSETWINDOW (selected_window, w); |
| 20152 | XFRAME (new_frame)->selected_window = selected_window; | ||
| 20364 | 20153 | ||
| 20365 | /* These will be set while the mode line specs are processed. */ | 20154 | /* These will be set while the mode line specs are processed. */ |
| 20366 | line_number_displayed = 0; | 20155 | line_number_displayed = 0; |
| 20367 | wset_column_number_displayed (w, Qnil); | 20156 | w->column_number_displayed = -1; |
| 20368 | 20157 | ||
| 20369 | if (WINDOW_WANTS_MODELINE_P (w)) | 20158 | if (WINDOW_WANTS_MODELINE_P (w)) |
| 20370 | { | 20159 | { |
| @@ -20383,6 +20172,7 @@ display_mode_lines (struct window *w) | |||
| 20383 | ++n; | 20172 | ++n; |
| 20384 | } | 20173 | } |
| 20385 | 20174 | ||
| 20175 | XFRAME (new_frame)->selected_window = old_frame_selected_window; | ||
| 20386 | selected_frame = old_selected_frame; | 20176 | selected_frame = old_selected_frame; |
| 20387 | selected_window = old_selected_window; | 20177 | selected_window = old_selected_window; |
| 20388 | return n; | 20178 | return n; |
| @@ -20705,7 +20495,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, | |||
| 20705 | risky); | 20495 | risky); |
| 20706 | else if (c != 0) | 20496 | else if (c != 0) |
| 20707 | { | 20497 | { |
| 20708 | int multibyte; | 20498 | bool multibyte; |
| 20709 | ptrdiff_t bytepos, charpos; | 20499 | ptrdiff_t bytepos, charpos; |
| 20710 | const char *spec; | 20500 | const char *spec; |
| 20711 | Lisp_Object string; | 20501 | Lisp_Object string; |
| @@ -21310,7 +21100,7 @@ static char * | |||
| 21310 | decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag) | 21100 | decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag) |
| 21311 | { | 21101 | { |
| 21312 | Lisp_Object val; | 21102 | Lisp_Object val; |
| 21313 | int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 21103 | bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 21314 | const unsigned char *eol_str; | 21104 | const unsigned char *eol_str; |
| 21315 | int eol_str_len; | 21105 | int eol_str_len; |
| 21316 | /* The EOL conversion we are using. */ | 21106 | /* The EOL conversion we are using. */ |
| @@ -21386,8 +21176,7 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_ | |||
| 21386 | returned with spaces to that value. Return a Lisp string in | 21176 | returned with spaces to that value. Return a Lisp string in |
| 21387 | *STRING if the resulting string is taken from that Lisp string. | 21177 | *STRING if the resulting string is taken from that Lisp string. |
| 21388 | 21178 | ||
| 21389 | Note we operate on the current buffer for most purposes, | 21179 | Note we operate on the current buffer for most purposes. */ |
| 21390 | the exception being w->base_line_pos. */ | ||
| 21391 | 21180 | ||
| 21392 | static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------"; | 21181 | static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------"; |
| 21393 | 21182 | ||
| @@ -21468,8 +21257,8 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21468 | register int i; | 21257 | register int i; |
| 21469 | 21258 | ||
| 21470 | /* Let lots_of_dashes be a string of infinite length. */ | 21259 | /* Let lots_of_dashes be a string of infinite length. */ |
| 21471 | if (mode_line_target == MODE_LINE_NOPROP || | 21260 | if (mode_line_target == MODE_LINE_NOPROP |
| 21472 | mode_line_target == MODE_LINE_STRING) | 21261 | || mode_line_target == MODE_LINE_STRING) |
| 21473 | return "--"; | 21262 | return "--"; |
| 21474 | if (field_width <= 0 | 21263 | if (field_width <= 0 |
| 21475 | || field_width > sizeof (lots_of_dashes)) | 21264 | || field_width > sizeof (lots_of_dashes)) |
| @@ -21498,7 +21287,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21498 | else | 21287 | else |
| 21499 | { | 21288 | { |
| 21500 | ptrdiff_t col = current_column (); | 21289 | ptrdiff_t col = current_column (); |
| 21501 | wset_column_number_displayed (w, make_number (col)); | 21290 | w->column_number_displayed = col; |
| 21502 | pint2str (decode_mode_spec_buf, width, col); | 21291 | pint2str (decode_mode_spec_buf, width, col); |
| 21503 | return decode_mode_spec_buf; | 21292 | return decode_mode_spec_buf; |
| 21504 | } | 21293 | } |
| @@ -21551,33 +21340,30 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21551 | if (mode_line_target == MODE_LINE_TITLE) | 21340 | if (mode_line_target == MODE_LINE_TITLE) |
| 21552 | return ""; | 21341 | return ""; |
| 21553 | 21342 | ||
| 21554 | startpos = XMARKER (w->start)->charpos; | 21343 | startpos = marker_position (w->start); |
| 21555 | startpos_byte = marker_byte_position (w->start); | 21344 | startpos_byte = marker_byte_position (w->start); |
| 21556 | height = WINDOW_TOTAL_LINES (w); | 21345 | height = WINDOW_TOTAL_LINES (w); |
| 21557 | 21346 | ||
| 21558 | /* If we decided that this buffer isn't suitable for line numbers, | 21347 | /* If we decided that this buffer isn't suitable for line numbers, |
| 21559 | don't forget that too fast. */ | 21348 | don't forget that too fast. */ |
| 21560 | if (EQ (w->base_line_pos, w->buffer)) | 21349 | if (w->base_line_pos == -1) |
| 21561 | goto no_value; | 21350 | goto no_value; |
| 21562 | /* But do forget it, if the window shows a different buffer now. */ | ||
| 21563 | else if (BUFFERP (w->base_line_pos)) | ||
| 21564 | wset_base_line_pos (w, Qnil); | ||
| 21565 | 21351 | ||
| 21566 | /* If the buffer is very big, don't waste time. */ | 21352 | /* If the buffer is very big, don't waste time. */ |
| 21567 | if (INTEGERP (Vline_number_display_limit) | 21353 | if (INTEGERP (Vline_number_display_limit) |
| 21568 | && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit)) | 21354 | && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit)) |
| 21569 | { | 21355 | { |
| 21570 | wset_base_line_pos (w, Qnil); | 21356 | w->base_line_pos = 0; |
| 21571 | wset_base_line_number (w, Qnil); | 21357 | w->base_line_number = 0; |
| 21572 | goto no_value; | 21358 | goto no_value; |
| 21573 | } | 21359 | } |
| 21574 | 21360 | ||
| 21575 | if (INTEGERP (w->base_line_number) | 21361 | if (w->base_line_number > 0 |
| 21576 | && INTEGERP (w->base_line_pos) | 21362 | && w->base_line_pos > 0 |
| 21577 | && XFASTINT (w->base_line_pos) <= startpos) | 21363 | && w->base_line_pos <= startpos) |
| 21578 | { | 21364 | { |
| 21579 | line = XFASTINT (w->base_line_number); | 21365 | line = w->base_line_number; |
| 21580 | linepos = XFASTINT (w->base_line_pos); | 21366 | linepos = w->base_line_pos; |
| 21581 | linepos_byte = buf_charpos_to_bytepos (b, linepos); | 21367 | linepos_byte = buf_charpos_to_bytepos (b, linepos); |
| 21582 | } | 21368 | } |
| 21583 | else | 21369 | else |
| @@ -21600,8 +21386,8 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21600 | go back past it. */ | 21386 | go back past it. */ |
| 21601 | if (startpos == BUF_BEGV (b)) | 21387 | if (startpos == BUF_BEGV (b)) |
| 21602 | { | 21388 | { |
| 21603 | wset_base_line_number (w, make_number (topline)); | 21389 | w->base_line_number = topline; |
| 21604 | wset_base_line_pos (w, make_number (BUF_BEGV (b))); | 21390 | w->base_line_pos = BUF_BEGV (b); |
| 21605 | } | 21391 | } |
| 21606 | else if (nlines < height + 25 || nlines > height * 3 + 50 | 21392 | else if (nlines < height + 25 || nlines > height * 3 + 50 |
| 21607 | || linepos == BUF_BEGV (b)) | 21393 | || linepos == BUF_BEGV (b)) |
| @@ -21627,13 +21413,13 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21627 | give up on line numbers for this window. */ | 21413 | give up on line numbers for this window. */ |
| 21628 | if (position == limit_byte && limit == startpos - distance) | 21414 | if (position == limit_byte && limit == startpos - distance) |
| 21629 | { | 21415 | { |
| 21630 | wset_base_line_pos (w, w->buffer); | 21416 | w->base_line_pos = -1; |
| 21631 | wset_base_line_number (w, Qnil); | 21417 | w->base_line_number = 0; |
| 21632 | goto no_value; | 21418 | goto no_value; |
| 21633 | } | 21419 | } |
| 21634 | 21420 | ||
| 21635 | wset_base_line_number (w, make_number (topline - nlines)); | 21421 | w->base_line_number = topline - nlines; |
| 21636 | wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position))); | 21422 | w->base_line_pos = BYTE_TO_CHAR (position); |
| 21637 | } | 21423 | } |
| 21638 | 21424 | ||
| 21639 | /* Now count lines from the start pos to point. */ | 21425 | /* Now count lines from the start pos to point. */ |
| @@ -21755,9 +21541,6 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21755 | return "@"; | 21541 | return "@"; |
| 21756 | } | 21542 | } |
| 21757 | 21543 | ||
| 21758 | case 't': /* indicate TEXT or BINARY */ | ||
| 21759 | return "T"; | ||
| 21760 | |||
| 21761 | case 'z': | 21544 | case 'z': |
| 21762 | /* coding-system (not including end-of-line format) */ | 21545 | /* coding-system (not including end-of-line format) */ |
| 21763 | case 'Z': | 21546 | case 'Z': |
| @@ -21807,11 +21590,15 @@ decode_mode_spec (struct window *w, register int c, int field_width, | |||
| 21807 | } | 21590 | } |
| 21808 | 21591 | ||
| 21809 | 21592 | ||
| 21810 | /* Count up to COUNT lines starting from START_BYTE. | 21593 | /* Count up to COUNT lines starting from START_BYTE. COUNT negative |
| 21811 | But don't go beyond LIMIT_BYTE. | 21594 | means count lines back from START_BYTE. But don't go beyond |
| 21812 | Return the number of lines thus found (always nonnegative). | 21595 | LIMIT_BYTE. Return the number of lines thus found (always |
| 21596 | nonnegative). | ||
| 21813 | 21597 | ||
| 21814 | Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */ | 21598 | Set *BYTE_POS_PTR to the byte position where we stopped. This is |
| 21599 | either the position COUNT lines after/before START_BYTE, if we | ||
| 21600 | found COUNT lines, or LIMIT_BYTE if we hit the limit before finding | ||
| 21601 | COUNT lines. */ | ||
| 21815 | 21602 | ||
| 21816 | static ptrdiff_t | 21603 | static ptrdiff_t |
| 21817 | display_count_lines (ptrdiff_t start_byte, | 21604 | display_count_lines (ptrdiff_t start_byte, |
| @@ -21838,31 +21625,36 @@ display_count_lines (ptrdiff_t start_byte, | |||
| 21838 | ceiling = min (limit_byte - 1, ceiling); | 21625 | ceiling = min (limit_byte - 1, ceiling); |
| 21839 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; | 21626 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; |
| 21840 | base = (cursor = BYTE_POS_ADDR (start_byte)); | 21627 | base = (cursor = BYTE_POS_ADDR (start_byte)); |
| 21841 | while (1) | 21628 | |
| 21629 | do | ||
| 21842 | { | 21630 | { |
| 21843 | if (selective_display) | 21631 | if (selective_display) |
| 21844 | while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) | 21632 | { |
| 21845 | ; | 21633 | while (*cursor != '\n' && *cursor != 015 |
| 21634 | && ++cursor != ceiling_addr) | ||
| 21635 | continue; | ||
| 21636 | if (cursor == ceiling_addr) | ||
| 21637 | break; | ||
| 21638 | } | ||
| 21846 | else | 21639 | else |
| 21847 | while (*cursor != '\n' && ++cursor != ceiling_addr) | 21640 | { |
| 21848 | ; | 21641 | cursor = memchr (cursor, '\n', ceiling_addr - cursor); |
| 21642 | if (! cursor) | ||
| 21643 | break; | ||
| 21644 | } | ||
| 21849 | 21645 | ||
| 21850 | if (cursor != ceiling_addr) | 21646 | cursor++; |
| 21647 | |||
| 21648 | if (--count == 0) | ||
| 21851 | { | 21649 | { |
| 21852 | if (--count == 0) | 21650 | start_byte += cursor - base; |
| 21853 | { | 21651 | *byte_pos_ptr = start_byte; |
| 21854 | start_byte += cursor - base + 1; | 21652 | return orig_count; |
| 21855 | *byte_pos_ptr = start_byte; | ||
| 21856 | return orig_count; | ||
| 21857 | } | ||
| 21858 | else | ||
| 21859 | if (++cursor == ceiling_addr) | ||
| 21860 | break; | ||
| 21861 | } | 21653 | } |
| 21862 | else | ||
| 21863 | break; | ||
| 21864 | } | 21654 | } |
| 21865 | start_byte += cursor - base; | 21655 | while (cursor < ceiling_addr); |
| 21656 | |||
| 21657 | start_byte += ceiling_addr - base; | ||
| 21866 | } | 21658 | } |
| 21867 | } | 21659 | } |
| 21868 | else | 21660 | else |
| @@ -21871,35 +21663,35 @@ display_count_lines (ptrdiff_t start_byte, | |||
| 21871 | { | 21663 | { |
| 21872 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); | 21664 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); |
| 21873 | ceiling = max (limit_byte, ceiling); | 21665 | ceiling = max (limit_byte, ceiling); |
| 21874 | ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; | 21666 | ceiling_addr = BYTE_POS_ADDR (ceiling); |
| 21875 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); | 21667 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); |
| 21876 | while (1) | 21668 | while (1) |
| 21877 | { | 21669 | { |
| 21878 | if (selective_display) | 21670 | if (selective_display) |
| 21879 | while (--cursor != ceiling_addr | 21671 | { |
| 21880 | && *cursor != '\n' && *cursor != 015) | 21672 | while (--cursor >= ceiling_addr |
| 21881 | ; | 21673 | && *cursor != '\n' && *cursor != 015) |
| 21674 | continue; | ||
| 21675 | if (cursor < ceiling_addr) | ||
| 21676 | break; | ||
| 21677 | } | ||
| 21882 | else | 21678 | else |
| 21883 | while (--cursor != ceiling_addr && *cursor != '\n') | 21679 | { |
| 21884 | ; | 21680 | cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr); |
| 21681 | if (! cursor) | ||
| 21682 | break; | ||
| 21683 | } | ||
| 21885 | 21684 | ||
| 21886 | if (cursor != ceiling_addr) | 21685 | if (++count == 0) |
| 21887 | { | 21686 | { |
| 21888 | if (++count == 0) | 21687 | start_byte += cursor - base + 1; |
| 21889 | { | 21688 | *byte_pos_ptr = start_byte; |
| 21890 | start_byte += cursor - base + 1; | 21689 | /* When scanning backwards, we should |
| 21891 | *byte_pos_ptr = start_byte; | 21690 | not count the newline posterior to which we stop. */ |
| 21892 | /* When scanning backwards, we should | 21691 | return - orig_count - 1; |
| 21893 | not count the newline posterior to which we stop. */ | ||
| 21894 | return - orig_count - 1; | ||
| 21895 | } | ||
| 21896 | } | 21692 | } |
| 21897 | else | ||
| 21898 | break; | ||
| 21899 | } | 21693 | } |
| 21900 | /* Here we add 1 to compensate for the last decrement | 21694 | start_byte += ceiling_addr - base; |
| 21901 | of CURSOR, which took it past the valid range. */ | ||
| 21902 | start_byte += cursor - base + 1; | ||
| 21903 | } | 21695 | } |
| 21904 | } | 21696 | } |
| 21905 | 21697 | ||
| @@ -23487,8 +23279,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, | |||
| 23487 | 23279 | ||
| 23488 | /* Let's rather be paranoid than getting a SEGV. */ | 23280 | /* Let's rather be paranoid than getting a SEGV. */ |
| 23489 | end = min (end, row->used[area]); | 23281 | end = min (end, row->used[area]); |
| 23490 | start = max (0, start); | 23282 | start = clip_to_bounds (0, start, end); |
| 23491 | start = min (end, start); | ||
| 23492 | 23283 | ||
| 23493 | /* Translate X to frame coordinates. Set last_x to the right | 23284 | /* Translate X to frame coordinates. Set last_x to the right |
| 23494 | end of the drawing area. */ | 23285 | end of the drawing area. */ |
| @@ -23767,8 +23558,18 @@ append_glyph (struct it *it) | |||
| 23767 | glyph->type = CHAR_GLYPH; | 23558 | glyph->type = CHAR_GLYPH; |
| 23768 | glyph->avoid_cursor_p = it->avoid_cursor_p; | 23559 | glyph->avoid_cursor_p = it->avoid_cursor_p; |
| 23769 | glyph->multibyte_p = it->multibyte_p; | 23560 | glyph->multibyte_p = it->multibyte_p; |
| 23770 | glyph->left_box_line_p = it->start_of_box_run_p; | 23561 | if (it->glyph_row->reversed_p && area == TEXT_AREA) |
| 23771 | glyph->right_box_line_p = it->end_of_box_run_p; | 23562 | { |
| 23563 | /* In R2L rows, the left and the right box edges need to be | ||
| 23564 | drawn in reverse direction. */ | ||
| 23565 | glyph->right_box_line_p = it->start_of_box_run_p; | ||
| 23566 | glyph->left_box_line_p = it->end_of_box_run_p; | ||
| 23567 | } | ||
| 23568 | else | ||
| 23569 | { | ||
| 23570 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 23571 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 23572 | } | ||
| 23772 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | 23573 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent |
| 23773 | || it->phys_descent > it->descent); | 23574 | || it->phys_descent > it->descent); |
| 23774 | glyph->glyph_not_available_p = it->glyph_not_available_p; | 23575 | glyph->glyph_not_available_p = it->glyph_not_available_p; |
| @@ -23842,8 +23643,18 @@ append_composite_glyph (struct it *it) | |||
| 23842 | } | 23643 | } |
| 23843 | glyph->avoid_cursor_p = it->avoid_cursor_p; | 23644 | glyph->avoid_cursor_p = it->avoid_cursor_p; |
| 23844 | glyph->multibyte_p = it->multibyte_p; | 23645 | glyph->multibyte_p = it->multibyte_p; |
| 23845 | glyph->left_box_line_p = it->start_of_box_run_p; | 23646 | if (it->glyph_row->reversed_p && area == TEXT_AREA) |
| 23846 | glyph->right_box_line_p = it->end_of_box_run_p; | 23647 | { |
| 23648 | /* In R2L rows, the left and the right box edges need to be | ||
| 23649 | drawn in reverse direction. */ | ||
| 23650 | glyph->right_box_line_p = it->start_of_box_run_p; | ||
| 23651 | glyph->left_box_line_p = it->end_of_box_run_p; | ||
| 23652 | } | ||
| 23653 | else | ||
| 23654 | { | ||
| 23655 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 23656 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 23657 | } | ||
| 23847 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | 23658 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent |
| 23848 | || it->phys_descent > it->descent); | 23659 | || it->phys_descent > it->descent); |
| 23849 | glyph->padding_p = 0; | 23660 | glyph->padding_p = 0; |
| @@ -24020,8 +23831,18 @@ produce_image_glyph (struct it *it) | |||
| 24020 | glyph->type = IMAGE_GLYPH; | 23831 | glyph->type = IMAGE_GLYPH; |
| 24021 | glyph->avoid_cursor_p = it->avoid_cursor_p; | 23832 | glyph->avoid_cursor_p = it->avoid_cursor_p; |
| 24022 | glyph->multibyte_p = it->multibyte_p; | 23833 | glyph->multibyte_p = it->multibyte_p; |
| 24023 | glyph->left_box_line_p = it->start_of_box_run_p; | 23834 | if (it->glyph_row->reversed_p && area == TEXT_AREA) |
| 24024 | glyph->right_box_line_p = it->end_of_box_run_p; | 23835 | { |
| 23836 | /* In R2L rows, the left and the right box edges need to be | ||
| 23837 | drawn in reverse direction. */ | ||
| 23838 | glyph->right_box_line_p = it->start_of_box_run_p; | ||
| 23839 | glyph->left_box_line_p = it->end_of_box_run_p; | ||
| 23840 | } | ||
| 23841 | else | ||
| 23842 | { | ||
| 23843 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 23844 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 23845 | } | ||
| 24025 | glyph->overlaps_vertically_p = 0; | 23846 | glyph->overlaps_vertically_p = 0; |
| 24026 | glyph->padding_p = 0; | 23847 | glyph->padding_p = 0; |
| 24027 | glyph->glyph_not_available_p = 0; | 23848 | glyph->glyph_not_available_p = 0; |
| @@ -24080,8 +23901,18 @@ append_stretch_glyph (struct it *it, Lisp_Object object, | |||
| 24080 | glyph->type = STRETCH_GLYPH; | 23901 | glyph->type = STRETCH_GLYPH; |
| 24081 | glyph->avoid_cursor_p = it->avoid_cursor_p; | 23902 | glyph->avoid_cursor_p = it->avoid_cursor_p; |
| 24082 | glyph->multibyte_p = it->multibyte_p; | 23903 | glyph->multibyte_p = it->multibyte_p; |
| 24083 | glyph->left_box_line_p = it->start_of_box_run_p; | 23904 | if (it->glyph_row->reversed_p && area == TEXT_AREA) |
| 24084 | glyph->right_box_line_p = it->end_of_box_run_p; | 23905 | { |
| 23906 | /* In R2L rows, the left and the right box edges need to be | ||
| 23907 | drawn in reverse direction. */ | ||
| 23908 | glyph->right_box_line_p = it->start_of_box_run_p; | ||
| 23909 | glyph->left_box_line_p = it->end_of_box_run_p; | ||
| 23910 | } | ||
| 23911 | else | ||
| 23912 | { | ||
| 23913 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 23914 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 23915 | } | ||
| 24085 | glyph->overlaps_vertically_p = 0; | 23916 | glyph->overlaps_vertically_p = 0; |
| 24086 | glyph->padding_p = 0; | 23917 | glyph->padding_p = 0; |
| 24087 | glyph->glyph_not_available_p = 0; | 23918 | glyph->glyph_not_available_p = 0; |
| @@ -24533,8 +24364,18 @@ append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len, | |||
| 24533 | glyph->slice.glyphless.lower_yoff = lower_yoff; | 24364 | glyph->slice.glyphless.lower_yoff = lower_yoff; |
| 24534 | glyph->avoid_cursor_p = it->avoid_cursor_p; | 24365 | glyph->avoid_cursor_p = it->avoid_cursor_p; |
| 24535 | glyph->multibyte_p = it->multibyte_p; | 24366 | glyph->multibyte_p = it->multibyte_p; |
| 24536 | glyph->left_box_line_p = it->start_of_box_run_p; | 24367 | if (it->glyph_row->reversed_p && area == TEXT_AREA) |
| 24537 | glyph->right_box_line_p = it->end_of_box_run_p; | 24368 | { |
| 24369 | /* In R2L rows, the left and the right box edges need to be | ||
| 24370 | drawn in reverse direction. */ | ||
| 24371 | glyph->right_box_line_p = it->start_of_box_run_p; | ||
| 24372 | glyph->left_box_line_p = it->end_of_box_run_p; | ||
| 24373 | } | ||
| 24374 | else | ||
| 24375 | { | ||
| 24376 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 24377 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 24378 | } | ||
| 24538 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | 24379 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent |
| 24539 | || it->phys_descent > it->descent); | 24380 | || it->phys_descent > it->descent); |
| 24540 | glyph->padding_p = 0; | 24381 | glyph->padding_p = 0; |
| @@ -27770,7 +27611,7 @@ note_mouse_highlight (struct frame *f, int x, int y) | |||
| 27770 | And verify the buffer's text has not changed. */ | 27611 | And verify the buffer's text has not changed. */ |
| 27771 | b = XBUFFER (w->buffer); | 27612 | b = XBUFFER (w->buffer); |
| 27772 | if (part == ON_TEXT | 27613 | if (part == ON_TEXT |
| 27773 | && EQ (w->window_end_valid, w->buffer) | 27614 | && w->window_end_valid |
| 27774 | && w->last_modified == BUF_MODIFF (b) | 27615 | && w->last_modified == BUF_MODIFF (b) |
| 27775 | && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b)) | 27616 | && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b)) |
| 27776 | { | 27617 | { |
| @@ -28403,6 +28244,9 @@ x_draw_vertical_border (struct window *w) | |||
| 28403 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame))) | 28244 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame))) |
| 28404 | return; | 28245 | return; |
| 28405 | 28246 | ||
| 28247 | /* Note: It is necessary to redraw bot the left and the right | ||
| 28248 | borders, for when only this single window W is being | ||
| 28249 | redisplayed. */ | ||
| 28406 | if (!WINDOW_RIGHTMOST_P (w) | 28250 | if (!WINDOW_RIGHTMOST_P (w) |
| 28407 | && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)) | 28251 | && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)) |
| 28408 | { | 28252 | { |
| @@ -28416,8 +28260,8 @@ x_draw_vertical_border (struct window *w) | |||
| 28416 | 28260 | ||
| 28417 | FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1); | 28261 | FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1); |
| 28418 | } | 28262 | } |
| 28419 | else if (!WINDOW_LEFTMOST_P (w) | 28263 | if (!WINDOW_LEFTMOST_P (w) |
| 28420 | && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) | 28264 | && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) |
| 28421 | { | 28265 | { |
| 28422 | int x0, x1, y0, y1; | 28266 | int x0, x1, y0, y1; |
| 28423 | 28267 | ||
diff --git a/src/xfaces.c b/src/xfaces.c index 1e27d5cc043..71709446c1d 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* xfaces.c -- "Face" primitives. | 1 | /* xfaces.c -- "Face" primitives. |
| 2 | 2 | ||
| 3 | Copyright (C) 1993-1994, 1998-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1993-1994, 1998-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -1585,7 +1585,7 @@ the face font sort order. */) | |||
| 1585 | for (i = nfonts - 1; i >= 0; --i) | 1585 | for (i = nfonts - 1; i >= 0; --i) |
| 1586 | { | 1586 | { |
| 1587 | Lisp_Object font = AREF (vec, i); | 1587 | Lisp_Object font = AREF (vec, i); |
| 1588 | Lisp_Object v = Fmake_vector (make_number (8), Qnil); | 1588 | Lisp_Object v = make_uninit_vector (8); |
| 1589 | int point; | 1589 | int point; |
| 1590 | Lisp_Object spacing; | 1590 | Lisp_Object spacing; |
| 1591 | 1591 | ||
| @@ -4877,6 +4877,8 @@ tty_supports_face_attributes_p (struct frame *f, | |||
| 4877 | { | 4877 | { |
| 4878 | if (STRINGP (val)) | 4878 | if (STRINGP (val)) |
| 4879 | return 0; /* ttys can't use colored underlines */ | 4879 | return 0; /* ttys can't use colored underlines */ |
| 4880 | else if (EQ (CAR_SAFE (val), QCstyle) && EQ (CAR_SAFE (CDR_SAFE (val)), Qwave)) | ||
| 4881 | return 0; /* ttys can't use wave underlines */ | ||
| 4880 | else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX])) | 4882 | else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX])) |
| 4881 | return 0; /* same as default */ | 4883 | return 0; /* same as default */ |
| 4882 | else | 4884 | else |
| @@ -6150,7 +6152,7 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6150 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 6152 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 6151 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6153 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 6152 | struct face *base_face; | 6154 | struct face *base_face; |
| 6153 | int multibyte_p = STRING_MULTIBYTE (string); | 6155 | bool multibyte_p = STRING_MULTIBYTE (string); |
| 6154 | Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface; | 6156 | Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface; |
| 6155 | 6157 | ||
| 6156 | /* Get the value of the face property at the current position within | 6158 | /* Get the value of the face property at the current position within |
diff --git a/src/xfns.c b/src/xfns.c index 7e832c3a95f..f01983fea4d 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Functions for the X window system. | 1 | /* Functions for the X window system. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1989, 1992-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -5292,8 +5292,7 @@ file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data) | |||
| 5292 | static Lisp_Object | 5292 | static Lisp_Object |
| 5293 | clean_up_file_dialog (Lisp_Object arg) | 5293 | clean_up_file_dialog (Lisp_Object arg) |
| 5294 | { | 5294 | { |
| 5295 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 5295 | Widget dialog = XSAVE_POINTER (arg, 0); |
| 5296 | Widget dialog = (Widget) p->pointer; | ||
| 5297 | 5296 | ||
| 5298 | /* Clean up. */ | 5297 | /* Clean up. */ |
| 5299 | block_input (); | 5298 | block_input (); |
| @@ -5417,7 +5416,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 5417 | XmStringFree (default_xmstring); | 5416 | XmStringFree (default_xmstring); |
| 5418 | } | 5417 | } |
| 5419 | 5418 | ||
| 5420 | record_unwind_protect (clean_up_file_dialog, make_save_value (dialog, 0)); | 5419 | record_unwind_protect (clean_up_file_dialog, make_save_pointer (dialog)); |
| 5421 | 5420 | ||
| 5422 | /* Process events until the user presses Cancel or OK. */ | 5421 | /* Process events until the user presses Cancel or OK. */ |
| 5423 | x_menu_set_in_use (1); | 5422 | x_menu_set_in_use (1); |
diff --git a/src/xfont.c b/src/xfont.c index 2d493088b0b..9978aba76de 100644 --- a/src/xfont.c +++ b/src/xfont.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* xfont.c -- X core font driver. | 1 | /* xfont.c -- X core font driver. |
| 2 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H13PRO009 | 5 | Registration Number H13PRO009 |
diff --git a/src/xftfont.c b/src/xftfont.c index 181a1da9b38..166a70acd85 100644 --- a/src/xftfont.c +++ b/src/xftfont.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* xftfont.c -- XFT font driver. | 1 | /* xftfont.c -- XFT font driver. |
| 2 | Copyright (C) 2006-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2006-2013 Free Software Foundation, Inc. |
| 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | 3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) | 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H13PRO009 | 5 | Registration Number H13PRO009 |
diff --git a/src/xgselect.c b/src/xgselect.c index c161564a322..db7dce10ad0 100644 --- a/src/xgselect.c +++ b/src/xgselect.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Function for handling the GLib event loop. | 1 | /* Function for handling the GLib event loop. |
| 2 | 2 | ||
| 3 | Copyright (C) 2009-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2009-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/xgselect.h b/src/xgselect.h index 5509e23c5c0..f142e85d877 100644 --- a/src/xgselect.h +++ b/src/xgselect.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Header for xg_select. | 1 | /* Header for xg_select. |
| 2 | 2 | ||
| 3 | Copyright (C) 2009-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2009-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/xmenu.c b/src/xmenu.c index b585df2125b..958cd220393 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* X Communication module for terminals which understand the X protocol. | 1 | /* X Communication module for terminals which understand the X protocol. |
| 2 | 2 | ||
| 3 | Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2012 | 3 | Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2013 Free Software |
| 4 | Free Software Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -1411,11 +1411,9 @@ popup_selection_callback (GtkWidget *widget, gpointer client_data) | |||
| 1411 | static Lisp_Object | 1411 | static Lisp_Object |
| 1412 | pop_down_menu (Lisp_Object arg) | 1412 | pop_down_menu (Lisp_Object arg) |
| 1413 | { | 1413 | { |
| 1414 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | ||
| 1415 | |||
| 1416 | popup_activated_flag = 0; | 1414 | popup_activated_flag = 0; |
| 1417 | block_input (); | 1415 | block_input (); |
| 1418 | gtk_widget_destroy (GTK_WIDGET (p->pointer)); | 1416 | gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg, 0))); |
| 1419 | unblock_input (); | 1417 | unblock_input (); |
| 1420 | return Qnil; | 1418 | return Qnil; |
| 1421 | } | 1419 | } |
| @@ -1479,7 +1477,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, | |||
| 1479 | gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, | 1477 | gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, |
| 1480 | timestamp ? timestamp : gtk_get_current_event_time ()); | 1478 | timestamp ? timestamp : gtk_get_current_event_time ()); |
| 1481 | 1479 | ||
| 1482 | record_unwind_protect (pop_down_menu, make_save_value (menu, 0)); | 1480 | record_unwind_protect (pop_down_menu, make_save_pointer (menu)); |
| 1483 | 1481 | ||
| 1484 | if (gtk_widget_get_mapped (menu)) | 1482 | if (gtk_widget_get_mapped (menu)) |
| 1485 | { | 1483 | { |
| @@ -1612,11 +1610,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, | |||
| 1612 | static Lisp_Object | 1610 | static Lisp_Object |
| 1613 | cleanup_widget_value_tree (Lisp_Object arg) | 1611 | cleanup_widget_value_tree (Lisp_Object arg) |
| 1614 | { | 1612 | { |
| 1615 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 1613 | free_menubar_widget_value_tree (XSAVE_POINTER (arg, 0)); |
| 1616 | widget_value *wv = p->pointer; | ||
| 1617 | |||
| 1618 | free_menubar_widget_value_tree (wv); | ||
| 1619 | |||
| 1620 | return Qnil; | 1614 | return Qnil; |
| 1621 | } | 1615 | } |
| 1622 | 1616 | ||
| @@ -1832,7 +1826,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, | |||
| 1832 | /* Make sure to free the widget_value objects we used to specify the | 1826 | /* Make sure to free the widget_value objects we used to specify the |
| 1833 | contents even with longjmp. */ | 1827 | contents even with longjmp. */ |
| 1834 | record_unwind_protect (cleanup_widget_value_tree, | 1828 | record_unwind_protect (cleanup_widget_value_tree, |
| 1835 | make_save_value (first_wv, 0)); | 1829 | make_save_pointer (first_wv)); |
| 1836 | 1830 | ||
| 1837 | /* Actually create and show the menu until popped down. */ | 1831 | /* Actually create and show the menu until popped down. */ |
| 1838 | create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp); | 1832 | create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp); |
| @@ -1931,7 +1925,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv) | |||
| 1931 | if (menu) | 1925 | if (menu) |
| 1932 | { | 1926 | { |
| 1933 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); | 1927 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); |
| 1934 | record_unwind_protect (pop_down_menu, make_save_value (menu, 0)); | 1928 | record_unwind_protect (pop_down_menu, make_save_pointer (menu)); |
| 1935 | 1929 | ||
| 1936 | /* Display the menu. */ | 1930 | /* Display the menu. */ |
| 1937 | gtk_widget_show_all (menu); | 1931 | gtk_widget_show_all (menu); |
| @@ -2142,7 +2136,7 @@ xdialog_show (FRAME_PTR f, | |||
| 2142 | /* Make sure to free the widget_value objects we used to specify the | 2136 | /* Make sure to free the widget_value objects we used to specify the |
| 2143 | contents even with longjmp. */ | 2137 | contents even with longjmp. */ |
| 2144 | record_unwind_protect (cleanup_widget_value_tree, | 2138 | record_unwind_protect (cleanup_widget_value_tree, |
| 2145 | make_save_value (first_wv, 0)); | 2139 | make_save_pointer (first_wv)); |
| 2146 | 2140 | ||
| 2147 | /* Actually create and show the dialog. */ | 2141 | /* Actually create and show the dialog. */ |
| 2148 | create_and_show_dialog (f, first_wv); | 2142 | create_and_show_dialog (f, first_wv); |
| @@ -2242,11 +2236,8 @@ menu_help_callback (char const *help_string, int pane, int item) | |||
| 2242 | static Lisp_Object | 2236 | static Lisp_Object |
| 2243 | pop_down_menu (Lisp_Object arg) | 2237 | pop_down_menu (Lisp_Object arg) |
| 2244 | { | 2238 | { |
| 2245 | struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg)); | 2239 | FRAME_PTR f = XSAVE_POINTER (arg, 0); |
| 2246 | struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg)); | 2240 | XMenu *menu = XSAVE_POINTER (arg, 1); |
| 2247 | |||
| 2248 | FRAME_PTR f = p1->pointer; | ||
| 2249 | XMenu *menu = p2->pointer; | ||
| 2250 | 2241 | ||
| 2251 | block_input (); | 2242 | block_input (); |
| 2252 | #ifndef MSDOS | 2243 | #ifndef MSDOS |
| @@ -2488,8 +2479,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, | |||
| 2488 | #endif | 2479 | #endif |
| 2489 | 2480 | ||
| 2490 | record_unwind_protect (pop_down_menu, | 2481 | record_unwind_protect (pop_down_menu, |
| 2491 | Fcons (make_save_value (f, 0), | 2482 | make_save_value ("pp", f, menu)); |
| 2492 | make_save_value (menu, 0))); | ||
| 2493 | 2483 | ||
| 2494 | /* Help display under X won't work because XMenuActivate contains | 2484 | /* Help display under X won't work because XMenuActivate contains |
| 2495 | a loop that doesn't give Emacs a chance to process it. */ | 2485 | a loop that doesn't give Emacs a chance to process it. */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Interface to libxml2. | 1 | /* Interface to libxml2. |
| 2 | Copyright (C) 2010-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 2010-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -93,7 +93,7 @@ init_libxml2_functions (void) | |||
| 93 | 93 | ||
| 94 | if (!(library = w32_delayed_load (Qlibxml2_dll))) | 94 | if (!(library = w32_delayed_load (Qlibxml2_dll))) |
| 95 | { | 95 | { |
| 96 | message ("%s", "libxml2 library not found"); | 96 | message1 ("libxml2 library not found"); |
| 97 | return 0; | 97 | return 0; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| @@ -180,8 +180,7 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html | |||
| 180 | xmlDoc *doc; | 180 | xmlDoc *doc; |
| 181 | Lisp_Object result = Qnil; | 181 | Lisp_Object result = Qnil; |
| 182 | const char *burl = ""; | 182 | const char *burl = ""; |
| 183 | ptrdiff_t bytes; | 183 | ptrdiff_t istart, iend, istart_byte, iend_byte; |
| 184 | ptrdiff_t istart, iend; | ||
| 185 | 184 | ||
| 186 | fn_xmlCheckVersion (LIBXML_VERSION); | 185 | fn_xmlCheckVersion (LIBXML_VERSION); |
| 187 | 186 | ||
| @@ -189,9 +188,11 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html | |||
| 189 | 188 | ||
| 190 | istart = XINT (start); | 189 | istart = XINT (start); |
| 191 | iend = XINT (end); | 190 | iend = XINT (end); |
| 191 | istart_byte = CHAR_TO_BYTE (istart); | ||
| 192 | iend_byte = CHAR_TO_BYTE (iend); | ||
| 192 | 193 | ||
| 193 | if (istart < GPT && GPT < iend) | 194 | if (istart < GPT && GPT < iend) |
| 194 | move_gap (iend); | 195 | move_gap_both (iend, iend_byte); |
| 195 | 196 | ||
| 196 | if (! NILP (base_url)) | 197 | if (! NILP (base_url)) |
| 197 | { | 198 | { |
| @@ -199,17 +200,15 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html | |||
| 199 | burl = SSDATA (base_url); | 200 | burl = SSDATA (base_url); |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 202 | bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart); | ||
| 203 | |||
| 204 | if (htmlp) | 203 | if (htmlp) |
| 205 | doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), | 204 | doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (istart_byte), |
| 206 | bytes, burl, "utf-8", | 205 | iend_byte - istart_byte, burl, "utf-8", |
| 207 | HTML_PARSE_RECOVER|HTML_PARSE_NONET| | 206 | HTML_PARSE_RECOVER|HTML_PARSE_NONET| |
| 208 | HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| | 207 | HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| |
| 209 | HTML_PARSE_NOBLANKS); | 208 | HTML_PARSE_NOBLANKS); |
| 210 | else | 209 | else |
| 211 | doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), | 210 | doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (istart_byte), |
| 212 | bytes, burl, "utf-8", | 211 | iend_byte - istart_byte, burl, "utf-8", |
| 213 | XML_PARSE_NONET|XML_PARSE_NOWARNING| | 212 | XML_PARSE_NONET|XML_PARSE_NOWARNING| |
| 214 | XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); | 213 | XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); |
| 215 | 214 | ||
diff --git a/src/xrdb.c b/src/xrdb.c index 59b0876ebf8..c25c25d6f33 100644 --- a/src/xrdb.c +++ b/src/xrdb.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Deal with the X Resource Manager. | 1 | /* Deal with the X Resource Manager. |
| 2 | Copyright (C) 1990, 1993-1994, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1990, 1993-1994, 2000-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | Author: Joseph Arceneaux | 5 | Author: Joseph Arceneaux |
| 5 | Created: 4/90 | 6 | Created: 4/90 |
diff --git a/src/xselect.c b/src/xselect.c index 64c64fa0c76..decea696bfd 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* X Selection processing for Emacs. | 1 | /* X Selection processing for Emacs. |
| 2 | Copyright (C) 1993-1997, 2000-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-1997, 2000-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -1120,7 +1120,7 @@ unexpect_property_change (struct prop_location *location) | |||
| 1120 | static Lisp_Object | 1120 | static Lisp_Object |
| 1121 | wait_for_property_change_unwind (Lisp_Object loc) | 1121 | wait_for_property_change_unwind (Lisp_Object loc) |
| 1122 | { | 1122 | { |
| 1123 | struct prop_location *location = XSAVE_VALUE (loc)->pointer; | 1123 | struct prop_location *location = XSAVE_POINTER (loc, 0); |
| 1124 | 1124 | ||
| 1125 | unexpect_property_change (location); | 1125 | unexpect_property_change (location); |
| 1126 | if (location == property_change_reply_object) | 1126 | if (location == property_change_reply_object) |
| @@ -1141,7 +1141,7 @@ wait_for_property_change (struct prop_location *location) | |||
| 1141 | 1141 | ||
| 1142 | /* Make sure to do unexpect_property_change if we quit or err. */ | 1142 | /* Make sure to do unexpect_property_change if we quit or err. */ |
| 1143 | record_unwind_protect (wait_for_property_change_unwind, | 1143 | record_unwind_protect (wait_for_property_change_unwind, |
| 1144 | make_save_value (location, 0)); | 1144 | make_save_pointer (location)); |
| 1145 | 1145 | ||
| 1146 | XSETCAR (property_change_reply, Qnil); | 1146 | XSETCAR (property_change_reply, Qnil); |
| 1147 | property_change_reply_object = location; | 1147 | property_change_reply_object = location; |
| @@ -1670,11 +1670,10 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1670 | return x_atom_to_symbol (display, (Atom) idata[0]); | 1670 | return x_atom_to_symbol (display, (Atom) idata[0]); |
| 1671 | else | 1671 | else |
| 1672 | { | 1672 | { |
| 1673 | Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)), | 1673 | Lisp_Object v = make_uninit_vector (size / sizeof (int)); |
| 1674 | make_number (0)); | 1674 | |
| 1675 | for (i = 0; i < size / sizeof (int); i++) | 1675 | for (i = 0; i < size / sizeof (int); i++) |
| 1676 | Faset (v, make_number (i), | 1676 | ASET (v, i, x_atom_to_symbol (display, (Atom) idata[i])); |
| 1677 | x_atom_to_symbol (display, (Atom) idata[i])); | ||
| 1678 | return v; | 1677 | return v; |
| 1679 | } | 1678 | } |
| 1680 | } | 1679 | } |
| @@ -1694,24 +1693,24 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1694 | else if (format == 16) | 1693 | else if (format == 16) |
| 1695 | { | 1694 | { |
| 1696 | ptrdiff_t i; | 1695 | ptrdiff_t i; |
| 1697 | Lisp_Object v; | 1696 | Lisp_Object v = make_uninit_vector (size / 2); |
| 1698 | v = Fmake_vector (make_number (size / 2), make_number (0)); | 1697 | |
| 1699 | for (i = 0; i < size / 2; i++) | 1698 | for (i = 0; i < size / 2; i++) |
| 1700 | { | 1699 | { |
| 1701 | short j = ((short *) data) [i]; | 1700 | short j = ((short *) data) [i]; |
| 1702 | Faset (v, make_number (i), make_number (j)); | 1701 | ASET (v, i, make_number (j)); |
| 1703 | } | 1702 | } |
| 1704 | return v; | 1703 | return v; |
| 1705 | } | 1704 | } |
| 1706 | else | 1705 | else |
| 1707 | { | 1706 | { |
| 1708 | ptrdiff_t i; | 1707 | ptrdiff_t i; |
| 1709 | Lisp_Object v = Fmake_vector (make_number (size / X_LONG_SIZE), | 1708 | Lisp_Object v = make_uninit_vector (size / X_LONG_SIZE); |
| 1710 | make_number (0)); | 1709 | |
| 1711 | for (i = 0; i < size / X_LONG_SIZE; i++) | 1710 | for (i = 0; i < size / X_LONG_SIZE; i++) |
| 1712 | { | 1711 | { |
| 1713 | int j = ((int *) data) [i]; | 1712 | int j = ((int *) data) [i]; |
| 1714 | Faset (v, make_number (i), INTEGER_TO_CONS (j)); | 1713 | ASET (v, i, INTEGER_TO_CONS (j)); |
| 1715 | } | 1714 | } |
| 1716 | return v; | 1715 | return v; |
| 1717 | } | 1716 | } |
diff --git a/src/xsettings.c b/src/xsettings.c index d23070791d8..576a5032eac 100644 --- a/src/xsettings.c +++ b/src/xsettings.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Functions for handling font and other changes dynamically. | 1 | /* Functions for handling font and other changes dynamically. |
| 2 | 2 | ||
| 3 | Copyright (C) 2009-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2009-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/xsettings.h b/src/xsettings.h index 10dc7ef926a..e3738c593bd 100644 --- a/src/xsettings.h +++ b/src/xsettings.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Functions for handle font changes dynamically. | 1 | /* Functions for handle font changes dynamically. |
| 2 | 2 | ||
| 3 | Copyright (C) 2009-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 2009-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
diff --git a/src/xsmfns.c b/src/xsmfns.c index 289aac8492b..fe2dfbaf83e 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Session management module for systems which understand the X Session | 1 | /* Session management module for systems which understand the X Session |
| 2 | management protocol. | 2 | management protocol. |
| 3 | 3 | ||
| 4 | Copyright (C) 2002-2012 Free Software Foundation, Inc. | 4 | Copyright (C) 2002-2013 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
diff --git a/src/xterm.c b/src/xterm.c index e9e99574663..b5274992293 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* X Communication module for terminals which understand the X protocol. | 1 | /* X Communication module for terminals which understand the X protocol. |
| 2 | 2 | ||
| 3 | Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1989, 1993-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -2236,8 +2236,7 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 2236 | nothing here for mouse-face. */ | 2236 | nothing here for mouse-face. */ |
| 2237 | if (s->hl == DRAW_CURSOR) | 2237 | if (s->hl == DRAW_CURSOR) |
| 2238 | { | 2238 | { |
| 2239 | int relief = s->img->relief; | 2239 | int relief = eabs (s->img->relief); |
| 2240 | if (relief < 0) relief = -relief; | ||
| 2241 | XDrawRectangle (s->display, s->window, s->gc, | 2240 | XDrawRectangle (s->display, s->window, s->gc, |
| 2242 | x - relief, y - relief, | 2241 | x - relief, y - relief, |
| 2243 | s->slice.width + relief*2 - 1, | 2242 | s->slice.width + relief*2 - 1, |
| @@ -2368,8 +2367,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap) | |||
| 2368 | nothing here for mouse-face. */ | 2367 | nothing here for mouse-face. */ |
| 2369 | if (s->hl == DRAW_CURSOR) | 2368 | if (s->hl == DRAW_CURSOR) |
| 2370 | { | 2369 | { |
| 2371 | int r = s->img->relief; | 2370 | int r = eabs (s->img->relief); |
| 2372 | if (r < 0) r = -r; | ||
| 2373 | XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, | 2371 | XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, |
| 2374 | s->slice.width + r*2 - 1, | 2372 | s->slice.width + r*2 - 1, |
| 2375 | s->slice.height + r*2 - 1); | 2373 | s->slice.height + r*2 - 1); |
| @@ -2633,14 +2631,14 @@ x_draw_stretch_glyph_string (struct glyph_string *s) | |||
| 2633 | static void | 2631 | static void |
| 2634 | x_draw_underwave (struct glyph_string *s) | 2632 | x_draw_underwave (struct glyph_string *s) |
| 2635 | { | 2633 | { |
| 2636 | int wave_height = 2, wave_length = 3; | 2634 | int wave_height = 3, wave_length = 2; |
| 2637 | int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax; | 2635 | int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax; |
| 2638 | XRectangle wave_clip, string_clip, final_clip; | 2636 | XRectangle wave_clip, string_clip, final_clip; |
| 2639 | 2637 | ||
| 2640 | dx = wave_length; | 2638 | dx = wave_length; |
| 2641 | dy = wave_height - 1; | 2639 | dy = wave_height - 1; |
| 2642 | x0 = s->x; | 2640 | x0 = s->x; |
| 2643 | y0 = s->ybase + 1; | 2641 | y0 = s->ybase - wave_height + 3; |
| 2644 | width = s->width; | 2642 | width = s->width; |
| 2645 | xmax = x0 + width; | 2643 | xmax = x0 + width; |
| 2646 | 2644 | ||
| @@ -2802,7 +2800,8 @@ x_draw_glyph_string (struct glyph_string *s) | |||
| 2802 | unsigned long thickness, position; | 2800 | unsigned long thickness, position; |
| 2803 | int y; | 2801 | int y; |
| 2804 | 2802 | ||
| 2805 | if (s->prev && s->prev->face->underline_p) | 2803 | if (s->prev && s->prev->face->underline_p |
| 2804 | && s->prev->face->underline_type == FACE_UNDER_LINE) | ||
| 2806 | { | 2805 | { |
| 2807 | /* We use the same underline style as the previous one. */ | 2806 | /* We use the same underline style as the previous one. */ |
| 2808 | thickness = s->prev->underline_thickness; | 2807 | thickness = s->prev->underline_thickness; |
| @@ -4803,21 +4802,24 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4803 | 4802 | ||
| 4804 | #ifdef USE_MOTIF | 4803 | #ifdef USE_MOTIF |
| 4805 | 4804 | ||
| 4806 | /* We use an estimate of 30 chars per line rather than the real | 4805 | if (scroll_bar_adjust_thumb_portion_p) |
| 4807 | `portion' value. This has the disadvantage that the thumb size | 4806 | { |
| 4808 | is not very representative, but it makes our life a lot easier. | 4807 | /* We use an estimate of 30 chars per line rather than the real |
| 4809 | Otherwise, we have to constantly adjust the thumb size, which | 4808 | `portion' value. This has the disadvantage that the thumb size |
| 4810 | we can't always do quickly enough: while dragging, the size of | 4809 | is not very representative, but it makes our life a lot easier. |
| 4811 | the thumb might prevent the user from dragging the thumb all the | 4810 | Otherwise, we have to constantly adjust the thumb size, which |
| 4812 | way to the end. but Motif and some versions of Xaw3d don't allow | 4811 | we can't always do quickly enough: while dragging, the size of |
| 4813 | updating the thumb size while dragging. Also, even if we can update | 4812 | the thumb might prevent the user from dragging the thumb all the |
| 4814 | its size, the update will often happen too late. | 4813 | way to the end. but Motif and some versions of Xaw3d don't allow |
| 4815 | If you don't believe it, check out revision 1.650 of xterm.c to see | 4814 | updating the thumb size while dragging. Also, even if we can update |
| 4816 | what hoops we were going through and the still poor behavior we got. */ | 4815 | its size, the update will often happen too late. |
| 4817 | portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; | 4816 | If you don't believe it, check out revision 1.650 of xterm.c to see |
| 4818 | /* When the thumb is at the bottom, position == whole. | 4817 | what hoops we were going through and the still poor behavior we got. */ |
| 4819 | So we need to increase `whole' to make space for the thumb. */ | 4818 | portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; |
| 4820 | whole += portion; | 4819 | /* When the thumb is at the bottom, position == whole. |
| 4820 | So we need to increase `whole' to make space for the thumb. */ | ||
| 4821 | whole += portion; | ||
| 4822 | } | ||
| 4821 | 4823 | ||
| 4822 | if (whole <= 0) | 4824 | if (whole <= 0) |
| 4823 | top = 0, shown = 1; | 4825 | top = 0, shown = 1; |
| @@ -4834,9 +4836,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio | |||
| 4834 | /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX | 4836 | /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX |
| 4835 | is the scroll bar's maximum and MIN is the scroll bar's minimum | 4837 | is the scroll bar's maximum and MIN is the scroll bar's minimum |
| 4836 | value. */ | 4838 | value. */ |
| 4837 | size = shown * XM_SB_MAX; | 4839 | size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX); |
| 4838 | size = min (size, XM_SB_MAX); | ||
| 4839 | size = max (size, 1); | ||
| 4840 | 4840 | ||
| 4841 | /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ | 4841 | /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ |
| 4842 | value = top * XM_SB_MAX; | 4842 | value = top * XM_SB_MAX; |
| @@ -6102,16 +6102,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6102 | last_user_time = event.xproperty.time; | 6102 | last_user_time = event.xproperty.time; |
| 6103 | f = x_top_window_to_frame (dpyinfo, event.xproperty.window); | 6103 | f = x_top_window_to_frame (dpyinfo, event.xproperty.window); |
| 6104 | if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state) | 6104 | if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state) |
| 6105 | if (x_handle_net_wm_state (f, &event.xproperty) && f->iconified | 6105 | if (x_handle_net_wm_state (f, &event.xproperty) |
| 6106 | && f->output_data.x->net_wm_state_hidden_seen) | 6106 | && FRAME_ICONIFIED_P (f) |
| 6107 | && f->output_data.x->net_wm_state_hidden_seen) | ||
| 6107 | { | 6108 | { |
| 6108 | /* Gnome shell does not iconify us when C-z is pressed. It hides | 6109 | /* Gnome shell does not iconify us when C-z is pressed. |
| 6109 | the frame. So if our state says we aren't hidden anymore, | 6110 | It hides the frame. So if our state says we aren't |
| 6110 | treat it as deiconified. */ | 6111 | hidden anymore, treat it as deiconified. */ |
| 6111 | if (! f->async_iconified) | 6112 | SET_FRAME_VISIBLE (f, 1); |
| 6112 | SET_FRAME_GARBAGED (f); | 6113 | SET_FRAME_ICONIFIED (f, 0); |
| 6113 | f->async_visible = 1; | ||
| 6114 | f->async_iconified = 0; | ||
| 6115 | f->output_data.x->has_been_visible = 1; | 6114 | f->output_data.x->has_been_visible = 1; |
| 6116 | f->output_data.x->net_wm_state_hidden_seen = 0; | 6115 | f->output_data.x->net_wm_state_hidden_seen = 0; |
| 6117 | inev.ie.kind = DEICONIFY_EVENT; | 6116 | inev.ie.kind = DEICONIFY_EVENT; |
| @@ -6152,10 +6151,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6152 | event.xexpose.width, event.xexpose.height, | 6151 | event.xexpose.width, event.xexpose.height, |
| 6153 | FALSE); | 6152 | FALSE); |
| 6154 | #endif | 6153 | #endif |
| 6155 | if (f->async_visible == 0) | 6154 | if (!FRAME_VISIBLE_P (f)) |
| 6156 | { | 6155 | { |
| 6157 | f->async_visible = 1; | 6156 | SET_FRAME_VISIBLE (f, 1); |
| 6158 | f->async_iconified = 0; | 6157 | SET_FRAME_ICONIFIED (f, 0); |
| 6159 | f->output_data.x->has_been_visible = 1; | 6158 | f->output_data.x->has_been_visible = 1; |
| 6160 | SET_FRAME_GARBAGED (f); | 6159 | SET_FRAME_GARBAGED (f); |
| 6161 | } | 6160 | } |
| @@ -6232,20 +6231,20 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6232 | if (f) /* F may no longer exist if | 6231 | if (f) /* F may no longer exist if |
| 6233 | the frame was deleted. */ | 6232 | the frame was deleted. */ |
| 6234 | { | 6233 | { |
| 6234 | bool visible = FRAME_VISIBLE_P (f); | ||
| 6235 | /* While a frame is unmapped, display generation is | 6235 | /* While a frame is unmapped, display generation is |
| 6236 | disabled; you don't want to spend time updating a | 6236 | disabled; you don't want to spend time updating a |
| 6237 | display that won't ever be seen. */ | 6237 | display that won't ever be seen. */ |
| 6238 | f->async_visible = 0; | 6238 | SET_FRAME_VISIBLE (f, 0); |
| 6239 | /* We can't distinguish, from the event, whether the window | 6239 | /* We can't distinguish, from the event, whether the window |
| 6240 | has become iconified or invisible. So assume, if it | 6240 | has become iconified or invisible. So assume, if it |
| 6241 | was previously visible, than now it is iconified. | 6241 | was previously visible, than now it is iconified. |
| 6242 | But x_make_frame_invisible clears both | 6242 | But x_make_frame_invisible clears both |
| 6243 | the visible flag and the iconified flag; | 6243 | the visible flag and the iconified flag; |
| 6244 | and that way, we know the window is not iconified now. */ | 6244 | and that way, we know the window is not iconified now. */ |
| 6245 | if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)) | 6245 | if (visible || FRAME_ICONIFIED_P (f)) |
| 6246 | { | 6246 | { |
| 6247 | f->async_iconified = 1; | 6247 | SET_FRAME_ICONIFIED (f, 1); |
| 6248 | |||
| 6249 | inev.ie.kind = ICONIFY_EVENT; | 6248 | inev.ie.kind = ICONIFY_EVENT; |
| 6250 | XSETFRAME (inev.ie.frame_or_window, f); | 6249 | XSETFRAME (inev.ie.frame_or_window, f); |
| 6251 | } | 6250 | } |
| @@ -6264,13 +6263,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6264 | f = x_top_window_to_frame (dpyinfo, event.xmap.window); | 6263 | f = x_top_window_to_frame (dpyinfo, event.xmap.window); |
| 6265 | if (f) | 6264 | if (f) |
| 6266 | { | 6265 | { |
| 6266 | bool iconified = FRAME_ICONIFIED_P (f); | ||
| 6267 | /* wait_reading_process_output will notice this and update | 6267 | /* wait_reading_process_output will notice this and update |
| 6268 | the frame's display structures. | 6268 | the frame's display structures. |
| 6269 | If we where iconified, we should not set garbaged, | 6269 | If we where iconified, we should not set garbaged, |
| 6270 | because that stops redrawing on Expose events. This looks | 6270 | because that stops redrawing on Expose events. This looks |
| 6271 | bad if we are called from a recursive event loop | 6271 | bad if we are called from a recursive event loop |
| 6272 | (x_dispatch_event), for example when a dialog is up. */ | 6272 | (x_dispatch_event), for example when a dialog is up. */ |
| 6273 | if (! f->async_iconified) | 6273 | if (!iconified) |
| 6274 | SET_FRAME_GARBAGED (f); | 6274 | SET_FRAME_GARBAGED (f); |
| 6275 | 6275 | ||
| 6276 | /* Check if fullscreen was specified before we where mapped the | 6276 | /* Check if fullscreen was specified before we where mapped the |
| @@ -6278,20 +6278,18 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, | |||
| 6278 | if (!f->output_data.x->has_been_visible) | 6278 | if (!f->output_data.x->has_been_visible) |
| 6279 | x_check_fullscreen (f); | 6279 | x_check_fullscreen (f); |
| 6280 | 6280 | ||
| 6281 | f->async_visible = 1; | 6281 | SET_FRAME_VISIBLE (f, 1); |
| 6282 | f->async_iconified = 0; | 6282 | SET_FRAME_ICONIFIED (f, 0); |
| 6283 | f->output_data.x->has_been_visible = 1; | 6283 | f->output_data.x->has_been_visible = 1; |
| 6284 | 6284 | ||
| 6285 | if (f->iconified) | 6285 | if (iconified) |
| 6286 | { | 6286 | { |
| 6287 | inev.ie.kind = DEICONIFY_EVENT; | 6287 | inev.ie.kind = DEICONIFY_EVENT; |
| 6288 | XSETFRAME (inev.ie.frame_or_window, f); | 6288 | XSETFRAME (inev.ie.frame_or_window, f); |
| 6289 | } | 6289 | } |
| 6290 | else if (! NILP (Vframe_list) | 6290 | else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list))) |
| 6291 | && ! NILP (XCDR (Vframe_list))) | 6291 | /* Force a redisplay sooner or later to update the |
| 6292 | /* Force a redisplay sooner or later | 6292 | frame titles in case this is the second frame. */ |
| 6293 | to update the frame titles | ||
| 6294 | in case this is the second frame. */ | ||
| 6295 | record_asynch_buffer_change (); | 6293 | record_asynch_buffer_change (); |
| 6296 | 6294 | ||
| 6297 | #ifdef USE_GTK | 6295 | #ifdef USE_GTK |
| @@ -8417,7 +8415,7 @@ get_current_wm_state (struct frame *f, | |||
| 8417 | if (tmp_data) XFree (tmp_data); | 8415 | if (tmp_data) XFree (tmp_data); |
| 8418 | x_uncatch_errors (); | 8416 | x_uncatch_errors (); |
| 8419 | unblock_input (); | 8417 | unblock_input (); |
| 8420 | return ! f->iconified; | 8418 | return !FRAME_ICONIFIED_P (f); |
| 8421 | } | 8419 | } |
| 8422 | 8420 | ||
| 8423 | x_uncatch_errors (); | 8421 | x_uncatch_errors (); |
| @@ -8529,7 +8527,7 @@ do_ewmh_fullscreen (struct frame *f) | |||
| 8529 | static void | 8527 | static void |
| 8530 | XTfullscreen_hook (FRAME_PTR f) | 8528 | XTfullscreen_hook (FRAME_PTR f) |
| 8531 | { | 8529 | { |
| 8532 | if (f->async_visible) | 8530 | if (FRAME_VISIBLE_P (f)) |
| 8533 | { | 8531 | { |
| 8534 | block_input (); | 8532 | block_input (); |
| 8535 | x_check_fullscreen (f); | 8533 | x_check_fullscreen (f); |
| @@ -8793,7 +8791,7 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows) | |||
| 8793 | /* But the ConfigureNotify may in fact never arrive, and then this is | 8791 | /* But the ConfigureNotify may in fact never arrive, and then this is |
| 8794 | not right if the frame is visible. Instead wait (with timeout) | 8792 | not right if the frame is visible. Instead wait (with timeout) |
| 8795 | for the ConfigureNotify. */ | 8793 | for the ConfigureNotify. */ |
| 8796 | if (f->async_visible) | 8794 | if (FRAME_VISIBLE_P (f)) |
| 8797 | x_wait_for_event (f, ConfigureNotify); | 8795 | x_wait_for_event (f, ConfigureNotify); |
| 8798 | else | 8796 | else |
| 8799 | { | 8797 | { |
| @@ -8905,9 +8903,8 @@ void | |||
| 8905 | x_raise_frame (struct frame *f) | 8903 | x_raise_frame (struct frame *f) |
| 8906 | { | 8904 | { |
| 8907 | block_input (); | 8905 | block_input (); |
| 8908 | if (f->async_visible) | 8906 | if (FRAME_VISIBLE_P (f)) |
| 8909 | XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | 8907 | XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); |
| 8910 | |||
| 8911 | XFlush (FRAME_X_DISPLAY (f)); | 8908 | XFlush (FRAME_X_DISPLAY (f)); |
| 8912 | unblock_input (); | 8909 | unblock_input (); |
| 8913 | } | 8910 | } |
| @@ -8917,7 +8914,7 @@ x_raise_frame (struct frame *f) | |||
| 8917 | static void | 8914 | static void |
| 8918 | x_lower_frame (struct frame *f) | 8915 | x_lower_frame (struct frame *f) |
| 8919 | { | 8916 | { |
| 8920 | if (f->async_visible) | 8917 | if (FRAME_VISIBLE_P (f)) |
| 8921 | { | 8918 | { |
| 8922 | block_input (); | 8919 | block_input (); |
| 8923 | XLowerWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | 8920 | XLowerWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); |
| @@ -8933,7 +8930,7 @@ xembed_request_focus (FRAME_PTR f) | |||
| 8933 | { | 8930 | { |
| 8934 | /* See XEmbed Protocol Specification at | 8931 | /* See XEmbed Protocol Specification at |
| 8935 | http://freedesktop.org/wiki/Specifications/xembed-spec */ | 8932 | http://freedesktop.org/wiki/Specifications/xembed-spec */ |
| 8936 | if (f->async_visible) | 8933 | if (FRAME_VISIBLE_P (f)) |
| 8937 | xembed_send_message (f, CurrentTime, | 8934 | xembed_send_message (f, CurrentTime, |
| 8938 | XEMBED_REQUEST_FOCUS, 0, 0, 0); | 8935 | XEMBED_REQUEST_FOCUS, 0, 0, 0); |
| 8939 | } | 8936 | } |
| @@ -8947,7 +8944,8 @@ x_ewmh_activate_frame (FRAME_PTR f) | |||
| 8947 | http://freedesktop.org/wiki/Specifications/wm-spec */ | 8944 | http://freedesktop.org/wiki/Specifications/wm-spec */ |
| 8948 | 8945 | ||
| 8949 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 8946 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); |
| 8950 | if (f->async_visible && wm_supports (f, dpyinfo->Xatom_net_active_window)) | 8947 | |
| 8948 | if (FRAME_VISIBLE_P (f) && wm_supports (f, dpyinfo->Xatom_net_active_window)) | ||
| 8951 | { | 8949 | { |
| 8952 | Lisp_Object frame; | 8950 | Lisp_Object frame; |
| 8953 | XSETFRAME (frame, f); | 8951 | XSETFRAME (frame, f); |
| @@ -9159,9 +9157,6 @@ x_make_frame_visible (struct frame *f) | |||
| 9159 | poll_for_input_1 (); | 9157 | poll_for_input_1 (); |
| 9160 | poll_suppress_count = old_poll_suppress_count; | 9158 | poll_suppress_count = old_poll_suppress_count; |
| 9161 | } | 9159 | } |
| 9162 | |||
| 9163 | /* See if a MapNotify event has been processed. */ | ||
| 9164 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 9165 | } | 9160 | } |
| 9166 | 9161 | ||
| 9167 | /* 2000-09-28: In | 9162 | /* 2000-09-28: In |
| @@ -9229,10 +9224,8 @@ x_make_frame_invisible (struct frame *f) | |||
| 9229 | So we can't win using the usual strategy of letting | 9224 | So we can't win using the usual strategy of letting |
| 9230 | FRAME_SAMPLE_VISIBILITY set this. So do it by hand, | 9225 | FRAME_SAMPLE_VISIBILITY set this. So do it by hand, |
| 9231 | and synchronize with the server to make sure we agree. */ | 9226 | and synchronize with the server to make sure we agree. */ |
| 9232 | f->visible = 0; | 9227 | SET_FRAME_VISIBLE (f, 0); |
| 9233 | FRAME_ICONIFIED_P (f) = 0; | 9228 | SET_FRAME_ICONIFIED (f, 0); |
| 9234 | f->async_visible = 0; | ||
| 9235 | f->async_iconified = 0; | ||
| 9236 | 9229 | ||
| 9237 | x_sync (f); | 9230 | x_sync (f); |
| 9238 | 9231 | ||
| @@ -9253,13 +9246,11 @@ x_iconify_frame (struct frame *f) | |||
| 9253 | if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f) | 9246 | if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f) |
| 9254 | FRAME_X_DISPLAY_INFO (f)->x_highlight_frame = 0; | 9247 | FRAME_X_DISPLAY_INFO (f)->x_highlight_frame = 0; |
| 9255 | 9248 | ||
| 9256 | if (f->async_iconified) | 9249 | if (FRAME_ICONIFIED_P (f)) |
| 9257 | return; | 9250 | return; |
| 9258 | 9251 | ||
| 9259 | block_input (); | 9252 | block_input (); |
| 9260 | 9253 | ||
| 9261 | FRAME_SAMPLE_VISIBILITY (f); | ||
| 9262 | |||
| 9263 | type = x_icon_type (f); | 9254 | type = x_icon_type (f); |
| 9264 | if (!NILP (type)) | 9255 | if (!NILP (type)) |
| 9265 | x_bitmap_icon (f, type); | 9256 | x_bitmap_icon (f, type); |
| @@ -9271,10 +9262,8 @@ x_iconify_frame (struct frame *f) | |||
| 9271 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | 9262 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); |
| 9272 | 9263 | ||
| 9273 | gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); | 9264 | gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); |
| 9274 | f->iconified = 1; | 9265 | SET_FRAME_VISIBLE (f, 0); |
| 9275 | f->visible = 1; | 9266 | SET_FRAME_ICONIFIED (f, 1); |
| 9276 | f->async_iconified = 1; | ||
| 9277 | f->async_visible = 0; | ||
| 9278 | unblock_input (); | 9267 | unblock_input (); |
| 9279 | return; | 9268 | return; |
| 9280 | } | 9269 | } |
| @@ -9291,10 +9280,8 @@ x_iconify_frame (struct frame *f) | |||
| 9291 | /* The server won't give us any event to indicate | 9280 | /* The server won't give us any event to indicate |
| 9292 | that an invisible frame was changed to an icon, | 9281 | that an invisible frame was changed to an icon, |
| 9293 | so we have to record it here. */ | 9282 | so we have to record it here. */ |
| 9294 | f->iconified = 1; | 9283 | SET_FRAME_VISIBLE (f, 0); |
| 9295 | f->visible = 1; | 9284 | SET_FRAME_ICONIFIED (f, 1); |
| 9296 | f->async_iconified = 1; | ||
| 9297 | f->async_visible = 0; | ||
| 9298 | unblock_input (); | 9285 | unblock_input (); |
| 9299 | return; | 9286 | return; |
| 9300 | } | 9287 | } |
| @@ -9307,9 +9294,8 @@ x_iconify_frame (struct frame *f) | |||
| 9307 | if (!result) | 9294 | if (!result) |
| 9308 | error ("Can't notify window manager of iconification"); | 9295 | error ("Can't notify window manager of iconification"); |
| 9309 | 9296 | ||
| 9310 | f->async_iconified = 1; | 9297 | SET_FRAME_ICONIFIED (f, 1); |
| 9311 | f->async_visible = 0; | 9298 | SET_FRAME_VISIBLE (f, 0); |
| 9312 | |||
| 9313 | 9299 | ||
| 9314 | block_input (); | 9300 | block_input (); |
| 9315 | XFlush (FRAME_X_DISPLAY (f)); | 9301 | XFlush (FRAME_X_DISPLAY (f)); |
| @@ -9358,8 +9344,8 @@ x_iconify_frame (struct frame *f) | |||
| 9358 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); | 9344 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| 9359 | } | 9345 | } |
| 9360 | 9346 | ||
| 9361 | f->async_iconified = 1; | 9347 | SET_FRAME_ICONIFIED (f, 1); |
| 9362 | f->async_visible = 0; | 9348 | SET_FRAME_VISIBLE (f, 0); |
| 9363 | 9349 | ||
| 9364 | XFlush (FRAME_X_DISPLAY (f)); | 9350 | XFlush (FRAME_X_DISPLAY (f)); |
| 9365 | unblock_input (); | 9351 | unblock_input (); |
diff --git a/src/xterm.h b/src/xterm.h index d63ed1c4583..b241ff23559 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Definitions and headers for communication with X protocol. | 1 | /* Definitions and headers for communication with X protocol. |
| 2 | Copyright (C) 1989, 1993-1994, 1998-2012 Free Software Foundation, Inc. | 2 | Copyright (C) 1989, 1993-1994, 1998-2013 Free Software Foundation, |
| 3 | Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -473,12 +474,13 @@ struct x_output | |||
| 473 | GtkWidget *menubar_widget; | 474 | GtkWidget *menubar_widget; |
| 474 | /* The tool bar in this frame */ | 475 | /* The tool bar in this frame */ |
| 475 | GtkWidget *toolbar_widget; | 476 | GtkWidget *toolbar_widget; |
| 476 | /* The handle box that makes the tool bar detachable. */ | 477 | #ifdef HAVE_GTK_HANDLE_BOX_NEW |
| 478 | /* The handle box that makes the tool bar detachable. */ | ||
| 477 | GtkWidget *handlebox_widget; | 479 | GtkWidget *handlebox_widget; |
| 478 | /* Non-zero if the tool bar is detached. */ | 480 | #endif |
| 479 | int toolbar_detached; | ||
| 480 | /* Non-zero if tool bar is packed into the hbox widget (i.e. vertical). */ | 481 | /* Non-zero if tool bar is packed into the hbox widget (i.e. vertical). */ |
| 481 | int toolbar_in_hbox; | 482 | bool toolbar_in_hbox; |
| 483 | bool toolbar_is_packed; | ||
| 482 | 484 | ||
| 483 | /* The last size hints set. */ | 485 | /* The last size hints set. */ |
| 484 | GdkGeometry size_hints; | 486 | GdkGeometry size_hints; |