diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 1104 | ||||
| -rw-r--r-- | src/ChangeLog.9 | 2 | ||||
| -rw-r--r-- | src/Makefile.in | 6 | ||||
| -rw-r--r-- | src/alloc.c | 29 | ||||
| -rw-r--r-- | src/bidi.c | 39 | ||||
| -rw-r--r-- | src/buffer.c | 94 | ||||
| -rw-r--r-- | src/buffer.h | 19 | ||||
| -rw-r--r-- | src/callint.c | 11 | ||||
| -rw-r--r-- | src/callproc.c | 773 | ||||
| -rw-r--r-- | src/casefiddle.c | 2 | ||||
| -rw-r--r-- | src/cmds.c | 2 | ||||
| -rw-r--r-- | src/coding.c | 2 | ||||
| -rw-r--r-- | src/composite.c | 30 | ||||
| -rw-r--r-- | src/composite.h | 88 | ||||
| -rw-r--r-- | src/data.c | 17 | ||||
| -rw-r--r-- | src/decompress.c | 231 | ||||
| -rw-r--r-- | src/dispextern.h | 30 | ||||
| -rw-r--r-- | src/dispnew.c | 135 | ||||
| -rw-r--r-- | src/doc.c | 2 | ||||
| -rw-r--r-- | src/editfns.c | 18 | ||||
| -rw-r--r-- | src/emacs.c | 10 | ||||
| -rw-r--r-- | src/eval.c | 163 | ||||
| -rw-r--r-- | src/fileio.c | 88 | ||||
| -rw-r--r-- | src/filelock.c | 33 | ||||
| -rw-r--r-- | src/fns.c | 4 | ||||
| -rw-r--r-- | src/font.c | 155 | ||||
| -rw-r--r-- | src/font.h | 60 | ||||
| -rw-r--r-- | src/fontset.c | 21 | ||||
| -rw-r--r-- | src/fontset.h | 6 | ||||
| -rw-r--r-- | src/frame.c | 131 | ||||
| -rw-r--r-- | src/frame.h | 33 | ||||
| -rw-r--r-- | src/fringe.c | 43 | ||||
| -rw-r--r-- | src/ftfont.c | 24 | ||||
| -rw-r--r-- | src/ftxfont.c | 22 | ||||
| -rw-r--r-- | src/gtkutil.c | 149 | ||||
| -rw-r--r-- | src/gtkutil.h | 46 | ||||
| -rw-r--r-- | src/image.c | 362 | ||||
| -rw-r--r-- | src/indent.c | 6 | ||||
| -rw-r--r-- | src/insdel.c | 58 | ||||
| -rw-r--r-- | src/keyboard.c | 16 | ||||
| -rw-r--r-- | src/keymap.c | 3 | ||||
| -rw-r--r-- | src/lisp.h | 31 | ||||
| -rw-r--r-- | src/lisp.mk | 1 | ||||
| -rw-r--r-- | src/marker.c | 6 | ||||
| -rw-r--r-- | src/menu.c | 9 | ||||
| -rw-r--r-- | src/menu.h | 10 | ||||
| -rw-r--r-- | src/minibuf.c | 27 | ||||
| -rw-r--r-- | src/msdos.c | 18 | ||||
| -rw-r--r-- | src/msdos.h | 2 | ||||
| -rw-r--r-- | src/nsfns.m | 43 | ||||
| -rw-r--r-- | src/nsfont.m | 31 | ||||
| -rw-r--r-- | src/nsmenu.m | 66 | ||||
| -rw-r--r-- | src/nsterm.h | 47 | ||||
| -rw-r--r-- | src/nsterm.m | 124 | ||||
| -rw-r--r-- | src/process.c | 289 | ||||
| -rw-r--r-- | src/process.h | 15 | ||||
| -rw-r--r-- | src/regex.c | 9 | ||||
| -rw-r--r-- | src/scroll.c | 20 | ||||
| -rw-r--r-- | src/search.c | 4 | ||||
| -rw-r--r-- | src/sheap.c | 17 | ||||
| -rw-r--r-- | src/syntax.c | 1 | ||||
| -rw-r--r-- | src/sysdep.c | 12 | ||||
| -rw-r--r-- | src/syswait.h | 3 | ||||
| -rw-r--r-- | src/term.c | 43 | ||||
| -rw-r--r-- | src/termcap.c | 4 | ||||
| -rw-r--r-- | src/terminal.c | 4 | ||||
| -rw-r--r-- | src/textprop.c | 41 | ||||
| -rw-r--r-- | src/w16select.c | 12 | ||||
| -rw-r--r-- | src/w32.c | 99 | ||||
| -rw-r--r-- | src/w32fns.c | 60 | ||||
| -rw-r--r-- | src/w32font.c | 41 | ||||
| -rw-r--r-- | src/w32font.h | 10 | ||||
| -rw-r--r-- | src/w32inevt.c | 12 | ||||
| -rw-r--r-- | src/w32inevt.h | 2 | ||||
| -rw-r--r-- | src/w32menu.c | 32 | ||||
| -rw-r--r-- | src/w32notify.c | 2 | ||||
| -rw-r--r-- | src/w32term.c | 129 | ||||
| -rw-r--r-- | src/w32term.h | 10 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 23 | ||||
| -rw-r--r-- | src/w32xfns.c | 8 | ||||
| -rw-r--r-- | src/widget.c | 36 | ||||
| -rw-r--r-- | src/window.c | 437 | ||||
| -rw-r--r-- | src/window.h | 134 | ||||
| -rw-r--r-- | src/xdisp.c | 509 | ||||
| -rw-r--r-- | src/xfaces.c | 63 | ||||
| -rw-r--r-- | src/xfns.c | 102 | ||||
| -rw-r--r-- | src/xfont.c | 41 | ||||
| -rw-r--r-- | src/xftfont.c | 28 | ||||
| -rw-r--r-- | src/xmenu.c | 125 | ||||
| -rw-r--r-- | src/xrdb.c | 18 | ||||
| -rw-r--r-- | src/xselect.c | 28 | ||||
| -rw-r--r-- | src/xsettings.c | 9 | ||||
| -rw-r--r-- | src/xsmfns.c | 3 | ||||
| -rw-r--r-- | src/xterm.c | 200 | ||||
| -rw-r--r-- | src/xterm.h | 10 |
95 files changed, 4242 insertions, 2885 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 38fa72b0506..e21d82bdc09 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,1099 @@ +2013-08-20 Paul Eggert <eggert@cs.ucla.edu> + + * image.c (SIGNATURE_DIGESTSIZE): Remove. + (struct animation_cache): Make signature a flexible array member. + All uses changed. This is a tad slower but may insulate us better + from future changes to ImageMagick. + +2013-08-19 Paul Eggert <eggert@cs.ucla.edu> + + * image.c: Shrink memory needed for animation cache. + (SIGNATURE_DIGESTSIZE): New constant. + (struct animation_cache): Make 'signature' a fixed size array of bytes. + (imagemagick_create_cache): Copy the signature. This saves + several KB of memory that ImageMagick wastes per signature. + Don't bother updating the update_time, as the caller does that now. + (imagemagick_prune_animation_cache): Don't destroy the signature, as + it's a fixed size struct member now. + (imagemagick_get_animation_cache): Always destroy the signature, + as it's now imagemagick_create_cache's responsibility to copy it. + Avoid duplicate calls to strcmp and to imagemagick_create_cache, + and use memcmp rather than strcmp. + eassert that ImageMagick returns a signature of the specified length. + +2013-08-19 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_get_animation_cache): Don't segfault on + each invocation. + (imagemagick_get_animation_cache): Revert to previous definition + so that it actually works. But keep the memory leak fix. + (imagemagick_get_animation_cache): Fix memory leak. + +2013-08-19 Paul Eggert <eggert@cs.ucla.edu> + + * image.c: Fix animation cache signature memory leak. + Fix some other minor performance problems while we're at it. + (imagemagick_create_cache): Clear just the members that + need clearing. Don't set update_time, as caller does that now. + (imagemagick_prune_animation_cache, imagemagick_get_animation_cache): + Simplify by using pointer-to-pointer instead of a prev pointer. + (imagemagick_prune_animation_cache): Use make_emacs_time rather + than EMACS_TIME_FROM_DOUBLE, and DestroyString rather than free. + (imagemagick_get_animation_cache): Don't xstrdup the image signature; + it's already a copy. Free the signature probe unless it's cached. + + * process.c (handle_child_signal): Fix crash; deleted pid (Bug#15106). + This was introduced by my 2013-08-12 fix for Bug#15035. + +2013-08-19 Dmitry Antipov <dmantipov@yandex.ru> + + * image.c (imagemagick_create_cache, imagemagick_get_animation_cache) + (imagemagick_prune_animation_cache): Now static. + +2013-08-18 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_get_animation_cache): Don't segfault when + pruning all entries. + +2013-08-18 Ken Brown <kbrown@cornell.edu> + + * sheap.c (STATIC_HEAP_SIZE): Adjust to current needs; use bigger + static heap if ENABLE_CHECKING is defined. + (max_bss_sbrk_ptr): New variable. + (bss_sbrk): Use it. + (report_sheap_usage): Report maximum static heap usage instead of + ending static heap usage. + +2013-08-17 Eli Zaretskii <eliz@gnu.org> + + * decompress.c (Fzlib_available_p) [WINDOWSNT]: Update the value + of zlib_initialized according to the results of calling + init_zlib_functions. + +2013-08-16 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c: Implement an ImageMagick per-image cache. + (imagemagick_get_animation_cache): Fix a double-free error. + (imagemagick_load_image): Remove the ping_wand code, which only + apparently saved time on invalid animated images, and slowed down + everything else. Optimise for the common case. + +2013-08-16 Xue Fuqiao <xfq.free@gmail.com> + + * buffer.c (syms_of_buffer) <buffer-undo-list>: Doc fix. + + * editfns.c (insert_before_markers): Mention overlay in the doc string. + + * marker.c (set_marker): Remove documentation of undefined behavior. + +2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_compute_animated_image): Animate correctly + when sub-images are smaller than the main image. + (imagemagick_compute_animated_image): Setting the iterator row to + zero is apparently not allowed. + (imagemagick_compute_animated_image): Allow images that say they + have sub-images that are bigger than the main image, but just crop + them. + +2013-08-15 Jan Djärv <jan.h.d@swipnet.se> + + * nsmenu.m (menuWillOpen:): Fix preprocessor test (Bug#15001). + +2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_compute_animated_image): Respect the GIF + disposal methods. + +2013-08-15 Ken Brown <kbrown@cornell.edu> + + * emacs.c (main): Update comment about G_SLICE_ALWAYS_MALLOC. + * gmalloc.c (memalign) [CYGWIN]: Revert last change; it's not + needed. + +2013-08-15 Paul Eggert <eggert@cs.ucla.edu> + + Fix minor problems found by static checking. + * frame.c (delete_frame): + * xdisp.c (next_element_from_display_vector): + Avoid uninitialized local. + * image.c (imagemagick_compute_animated_image): Port to C89. + Prefer usual GNU indentation style for loops. + Be more careful about bizarrely large sizes, by using ptrdiff_t + instead of int. + +2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> + + Fix infinite frame selection loop (Bug#15025). + * frame.c (delete_frame): Prefer fast ad-hoc loop to next_frame. + +2013-08-15 Eli Zaretskii <eliz@gnu.org> + + * xdisp.c (compute_window_start_on_continuation_line): When + WORD_WRAP is in effect, use move_it_to instead of move_it_by_lines + to make sure we end up setting the window start at the leftmost + visible character of the display line. This avoids funky + horizontal shifting because the window start is not kept on the + same position. (Bug#15090) + (next_element_from_display_vector): Support 'box' face attribute + in the face definitions of a display vector. (Bug#15099) + +2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_compute_animated_image): Implement animated + images (bug#14700). + (imagemagick_compute_animated_image): Fix some compilation + warnings. Implement a very simple cache to make the animation + usable at all, but it should be replaced with a per-image cache. + +2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> + + * lisp.h (FOR_EACH_ALIST_VALUE): New macro + to do `for' loops over alist values. + * buffer.h (FOR_EACH_BUFFER): + * process.c (FOR_EACH_PROCESS): Use it. + (handle_child_signal, status_notify, Fget_buffer_process) + (kill_buffer_processes): Use FOR_EACH_PROCESS. + +2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> + + * term.c (get_named_tty, create_tty_output, tty_free_frame_resources) + (tty_free_frame_resources, delete_tty): Prefer eassert to emacs_abort. + * image.c (make_image_cache): For struct image_cache, prefer xmalloc + to xzalloc and so avoid redundant call to memset. + * xterm.c (x_term_init): Avoid unnecessary initializations of dpyinfo + members because it is allocated with xzalloc and so already zeroed. + +2013-08-14 Ken Brown <kbrown@cornell.edu> + + * gmalloc.c (memalign) [CYGWIN]: Rename to emacs_memalign + (Bug#15094). + +2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> + + Utility function and macro to copy Lisp string to C string. + * lisp.h (xlispstrdupa): New macro. + (xlispstrdup): New prototype. + * alloc.c (xlispstrdup): New function. + * callint.c (Fcall_interactively): + * fileio.c (Ffile_name_directory, Fexpand_file_name) + (Fsubstitute_in_file_name): + * frame.c (Fmake_terminal_frame): Use xlispstrdupa. + * image.c (x_create_bitmap_from_file): + * w32term.c (w32_term_init): + * xterm.c (x_term_init): Use xlispstrdup. + +2013-08-14 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_load_image): Make animated pictures work. + There's still some problems with background color settings, though + (bug#14700). + + * decompress.c (unwind_decompress): Always restore point. + +2013-08-14 Xue Fuqiao <xfq.free@gmail.com> + + * marker.c (set_marker): Reformat documentation. + +2013-08-14 Paul Eggert <eggert@cs.ucla.edu> + + * xdisp.c (cursor_type_changed): Now static. + + * image.c (imagemagick_filename_hint): New arg HINT_BUFFER. + Use changed. This avoids the need to call xmalloc and for the + caller to call xfree, and avoids memory leaks in some situations. + +2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> + + * xdisp.c (adjust_window_ends): Move duplicated code to new function. + (try_window, try_window_reusing_current_matrix, try_window_id): Use it. + (redisplay_window): If window_end_valid is cleared due to non-zero + windows_or_buffers_changed, clear current_matrix_up_to_date_p and + so do not call to try_cursor_movement for that window. + +2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> + + * window.h (struct window): Convert window_end_pos and + window_end_vpos from Lisp_Object to ptrdiff_t and int, respectively. + (wset_window_end_pos, wset_window_end_vpos): Remove. + * dispnew.c (adjust_glyph_matrix): + * window.c (Fwindow_end, replace_window, set_window_buffer) + (make_window): + * xdisp.c (check_window_end, move_it_to, redisplay_internal) + (set_vertical_scroll_bar, redisplay_window, try_window) + (try_window_reusing_current_matrix, find_first_unchanged_at_end_row) + (try_window_id, decode_mode_spec, mouse_face_from_buffer_pos) + (note_mouse_highlight): Adjust users. + (try_cursor_movement): Likewise. Convert old precondition to eassert. + Add comment. + +2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> + + Fix --enable-gcc-warnings errors introduced in 2013-08-13 commit. + * image.c (imagemagick_filename_hint): Use `const char *' and + prefer SSDATA to SDATA to avoid warnings. + +2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> + + Cleanup window fringes, margins and scroll bars adjustments. + * window.c (set_window_fringes, set_window_margins) + (set_window_scroll_bars, apply_window_adjustment): New functions. + (set_window_buffer, Fset_window_margins, Fset_window_fringes) + (Fset_window_scroll_bars): Use them. + +2013-08-14 Dmitry Antipov <dmantipov@yandex.ru> + + * window.h (struct window): Convert scroll_bar_width + from Lisp_Object to integer. Adjust comment. + (WINDOW_CONFIG_SCROLL_BAR_WIDTH, WINDOW_CONFIG_SCROLL_BAR_COLS): + Adjust users. + * window.c (wset_scroll_bar_width): Remove. + (make_window): Initialize scroll_bar_width. + (Fsplit_window_internal): Use direct assignment. + (Fset_window_configuration, save_window_save): + Convert Lisp_Object to integer and back where appropriate. + (Fset_window_scroll_bars): Adjust user. Return t if any scroll + bar was actually changed, and mention this in docstring. + +2013-08-13 Paul Eggert <eggert@cs.ucla.edu> + + * decompress.c: Minor simplifications. + (Fzlib_decompress_region): Don't bother verifying + that avail_out <= UINT_MAX, as that was confusing. + Mention the restriction in a comment instead. + Prefer 'int' to 'ptrdiff_t' when 'int' is wide enough. + +2013-08-13 Jan Djärv <jan.h.d@swipnet.se> + + * nsmenu.m (x_activate_menubar): Check for OSX >= 10.5 + (trackingNotification:): Call ns_check_menu_open only for OSX >= 10.5. + +2013-08-13 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_filename_hint): Check for errors in the + alist structure. + +2013-08-13 Eli Zaretskii <eliz@gnu.org> + + * window.c (Fwindow_margins): Return nil when there's no marginal + area, as per the documented API. + + * w32term.c (x_scroll_bar_create): Use ALLOCATE_PSEUDOVECTOR, not + Fmake_vector, as scroll bar's struct members are not all Lisp + objects now. This avoids crashes in GC. + + * w32term.h (struct scroll_bar): Convert fringe_extended_p to a + bool, so its address could be taken. + +2013-08-13 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * image.c (imagemagick_filename_hint): New function to possibly + apply `image-content-type-suffixes'. + (imagemagick_load_image): Use it. + +2013-08-13 Eli Zaretskii <eliz@gnu.org> + + * decompress.c (Fzlib_decompress_region) [WINDOWSNT]: Return Qnil + if loading zlib failed. + +2013-08-13 Jan Djärv <jan.h.d@swipnet.se> + + * nsterm.m (ns_set_vertical_scroll_bar): Fix breakage intruduced by + 2013-08-13 checkin below. Change bool to BOOL, rule is: + All Obj-C code uses BOOL, except for interfaces callable from C. + + * nsterm.h: Fix CGFloat for OSX 10.4 (Bug#15086). + +2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> + + * window.h (WINDOW_FRINGE_EXTENDED_P): New macro. + * nsterm.m (ns_set_vertical_scroll_bar): Use it. Use convenient + bool instead of BOOL. + * w32term.h (struct scroll_bar): Convert fringe_extended_p + from Lisp_Object to bitfield. Adjust comment. + * w32term.c (x_scroll_bar_create): Adjust user. + Use WINDOW_FRINGE_EXTENDED_P and bool for boolean. + * xterm.c (XTset_vertical_scroll_bar): Likewise. + Use bool for boolean. + * xterm.h (struct scroll_bar): Prefer commonly used `unsigned' + to `unsigned int' when defining a bitfield. + +2013-08-13 Paul Eggert <eggert@cs.ucla.edu> + + * decompress.c (Fzlib_decompress_region): Try to clarify 'avail_out'. + +2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> + + * window.h (struct window): Convert left_margin_cols and + right_margin_cols from Lisp_Objects to integers. Adjust comment. + (WINDOW_LEFT_MARGIN_COLS, WINDOW_RIGHT_MARGIN_COLS) + (WINDOW_LEFT_MARGIN_WIDTH, WINDOW_RIGHT_MARGIN_WIDTH): + Adjust users. + * dispnew.c (margin_glyphs_to_reserve): Convert 3rd arg to int. + Adjust comment. + (showing_window_margins_p, update_window_line, update_frame_1): + * fringe.c (draw_fringe_bitmap_1): + * xdisp.c (window_box_width): Adjust users. + * window.c (wset_left_margin_cols, wset_right_margin_cols): Remove. + (adjust_window_margins, set_window_buffer, Fsplit_window_internal): + Use direct assignment. + (Fset_window_configuration, save_window_save, Fwindow_margins): + Convert Lisp_Object to integer and back where appropriate. + (Fset_window_margins): Adjust user. Return t if any margin + was actually changed, and mention this in docstring. + +2013-08-13 Xue Fuqiao <xfq.free@gmail.com> + + * syntax.c (forward_word): + * cmds.c (forward_char, backward_char): Mention the optional argument. + +2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> + + * window.h (struct window): Convert left_fringe_width + and right_fringe_width from Lisp_Objects to integers. + Adjust comment. + (WINDOW_FRINGE_COLS, WINDOW_LEFT_FRINGE_WIDTH) + (WINDOW_RIGHT_FRINGE_WIDTH): Adjust users. + * window.c (wset_left_fringe_width, wset_right_fringe_width): + Remove. + (make_window): Initialize new integer fields to -1. + (Fsplit_window_internal): Use direct assignment. + (Fset_window_configuration, save_window_save): Convert + Lisp_Object to integer and back where appropriate. + (Fset_window_fringes): Adjust user. Return t if any fringe + was actually changed, and mention this in docstring. + +2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> + + * keyboard.c (Fdiscard_input): Do not increment update_mode_lines. + * nsfns.m (x_set_cursor_type): + * w32fns.c (x_set_cursor_type): + * xfns.m (x_set_cursor_type): Do not set cursor_type_changed here... + * xdisp.c (set_frame_cursor_types): ...but in common code. + +2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> + + * font.c (clear_font_cache): New function, stripped from... + (Fclear_font_cache): ...here, which now uses the function + above. Adjust comment. + * font.h (clear_font_cache): Add prototype. + * xfaces.c (clear_face_cache): Use clear_font_cache. + +2013-08-13 Dmitry Antipov <dmantipov@yandex.ru> + + * window.c (Fset_window_start): Compare `w', not `window' because + `w' might not be equal to `window' after call to decode_live_window. + +2013-08-12 Paul Eggert <eggert@cs.ucla.edu> + + * process.c (deactivate_process): Reset fds to -1 (Bug#15035). + This fixes a problem introduced by the Bug#15035 patch + when using GPG. Reported by Herbert J. Skuhra. + +2013-08-12 Eli Zaretskii <eliz@gnu.org> + + * decompress.c <zlib_initialized> [WINDOWSNT]: New static variable. + (Fzlib_decompress_region) [WINDOWSNT]: Call init_zlib_functions if + not yet initialized. + +2013-08-12 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * decompress.c (Fzlib_decompress_region): Support zlib + decompression, too, and rename. + +2013-08-12 Paul Eggert <eggert@cs.ucla.edu> + + Minor zlib configuration tweaks. + * decompress.c (fn_inflateInit2) [!WINDOWSNT]: + Don't assume presence of fn_inflateInit2_ zlib internal function. + +2013-08-12 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * decompress.c (Fzlib_decompress_gzipped_region): Rename to + include the zlib prefix. + +2013-08-12 Eli Zaretskii <eliz@gnu.org> + + * decompress.c [WINDOWSNT]: Include windows.h and w32.h. + (DEF_ZLIB_FN, LOAD_ZLIB_FN) [WINDOWSNT]: New macros. Use them to + define static variables that are pointers to zlib functions to be + dynamically loaded. + (init_zlib_functions) [WINDOWSNT]: New function. + (fn_inflateInit2_, fn_inflate, fn_inflateEnd, fn_inflateInit2): + New macros. + (Fdecompress_gzipped_region, unwind_decompress): Use the fn_* + macros instead of invoking the zlib functions directly. + (syms_of_decompress): DEFSYM Qzlib_dll. Staticpro + Szlib_available_p. + +2013-08-12 Dmitry Antipov <dmantipov@yandex.ru> + + Avoid looping over all frame windows to freeze and unfreeze. + * window.h (struct window): Drop frozen_window_start_p. + (freeze_window_starts): Drop prototype. + * frame.h (struct frame): New frozen_window_starts flag. + (FRAME_WINDOWS_FROZEN): New macro. + * window.c (freeze_window_start, freeze_window_starts): + Remove. + (select_window, replace_window): Adjust users. + * xdisp.c (resize_mini_window): Use FRAME_WINDOWS_FROZEN. + (window_frozen_p): New function. + (redisplay_window): Use it. + +2013-08-12 Paul Eggert <eggert@cs.ucla.edu> + + Fix some fd issues when running subprocesses (Bug#15035). + Fix bugs that can leak files or file descriptors on errors. + Don't unlink open temp files, as that's hard for users to diagnose + when things go awry (e.g., temp disk exhausted). + Don't bother to lock temp files. Check for invalid recursion. + * callproc.c (synch_process_fd): Remove. All uses removed. + (synch_process_tempfile): New var or macro. + (CALLPROC_STDOUT, CALLPROC_STDERR, CALLPROC_PIPEREAD, CALLPROC_FDS): + New constants. + (record_kill_process): New arg, the temp name. All callers changed. + (delete_temp_file): Now just a simple wrapper around unlink. + (call_process_kill): New arg, the call_process_fd array. + Close them all. Clear synch_process_pid. Remove the temp file, + or arrange for it to be removed. + (call_process_cleanup) [MSDOS]: Arg no longer contains file name; + that's been moved to synch_process_tempfile. Caller changed. + Do not remove the tempfile; that's now call_process_kill's + responsibility. + (call_process_cleanup) [!MSDOS]: Do not record unwind-protect for + call_process_kill; the caller now does that. + (call_process_cleanup): Do not close the process fd; that's now + call_process_kill's responsibility. + (Fcall_process): Implement via new function call_process, which + has most of the old body of Fcall_process, but with a different API. + (call_process): New function that does not open or close filefd if + it is nonnegative. Record which fds need to be closed, and let + call_process_kill close (and remove the tempfile, on MSDOS) on error. + Signal an error if invoked recursively (could be done via a hook). + Simplify creation of the tempfile in the MSDOS case. + Don't create the output file until after checking for the executable. + Report any failure to open /dev/null. + Don't open /dev/null for writing twice; once is enough. + Don't create pipe if all output is being discarded or sent to file. + Don't worry about setting up the coding system or reading from the + pipe if all output is being discarded. + Hoist fd_error local into top level, to lessen block nesting. + Don't record deleted pid here; now done by Fcall_process_region. + (Fcall_process) [MSDOS]: Report mktemp failure immediately, + and note its success in synch_process_tempfile. + Do not leak resources when child_setup fails. + (Fcall_process) [!MSDOS && !WINDOWSNT]: Remove duplicate assignment + to child_errno. Remove unnecessary close of fd0; it's close-on-exec. + (create_temp_file): Now returns open fd, with an additional + Lisp_Object * argument to return the name. All callers changed. + Do not close the file; rewind it instead, and leave it open for + the caller. Do not lock the temp file. Unwind-protect the file + and the file-descriptor. + (Fcall_process_region): If the input is /dev/null, unwind-protect it. + If an asynchrounous process, record it here, not in call_process. + (syms_of_callproc) [MSDOS]: Initialize synch_process_tempfile. + * eval.c (set_unwind_protect): New function. + * fileio.c (write_region): New function, generalized from the + old Fwrite_region. Do not lock temp files. + (Fwrite_region): Use it. + * lisp.h (set_unwind_protect, write_region): New decls. + * process.c: Include <verify.h>. + (make_process): Mark fds as initially closed. + (deleted_pid_list): Now a list of pid-filename pairs. + All uses changed. + (close_process_fd): New function. + (SUBPROCESS_STDIN, WRITE_TO_SUBPROCESS, READ_FROM_SUBPROCESS) + (SUBPROCESS_STDOUT, READ_FROM_EXEC_MONITOR, EXEC_MONITOR_OUTPUT): + New constants. Verify that their number matches PROCESS_OPEN_FDS. + (create_process, create_pty, Fmake_serial_process) + (server_accept_connection): Record which fds need to be closed, + and let deactivate_process close them. + (Fmake_network_process): Do not discard the unwind-protect + until it's safe to do so. + (deactivate_process): Close the fds opened by create_process etc. + (Fprocess_send_eof): Adjust to new way of recording open fds. + Report an error if /dev/null can't be opened, instead of aborting. + * process.h (PROCESS_OPEN_FDS): New constant. + (struct Lisp_Process): New member open_fds. + (record_kill_process, record_deleted_pid): Adjust signatures. + (record_deleted_pid): Move decl here ... + * syswait.h (record_deleted_pid): ... from here. + +2013-08-11 Paul Eggert <eggert@cs.ucla.edu> + + * decompress.c: Fix bugs with large buffers and weird inputs. + Tune a bit. Reindent as per usual Emacs style. + (BUFFER_SIZE): Remove. + (Fdecompress_gzipped_region): Do not mishandle input buffers with + more than UINT_MAX bytes. Decompress into the gap instead of into + an auto buffer, as this should avoid copying. Return nil if + 'inflate' returns Z_NEED_DICT, as we have no dictionary. Do not + set immediate_quit; we shouldn't trust zlib code that much. + +2013-08-11 Lars Magne Ingebrigtsen <larsi@gnus.org> + + * decompress.c (Fdecompress_gzipped_region): Respect all zlib + errors, and really move the gap to where we want it. + + * lisp.h: Include decompress.c support. + + * emacs.c (main): Include decompress.c support. + + * Makefile.in: Include -lz if present. + +2013-08-11 Jan Djärv <jan.h.d@swipnet.se> + + * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:frame: + (initWithTitle:): Initialize frame to 0. + (fillWithWidgetValue:): Call fillWithWidgetValue:frame. + (fillWithWidgetValue:frame:): Renamed from + fillWithWidgetValue:setDelegate, call initWithTile:frame: if f. + + * nsterm.h (EmacsMenu): fillWithWidgetValue:setDelegate renamed to + fillWithWidgetValue:frame: + + * nsfns.m (Fns_convert_utf8_nfd_to_nfc): Allocate and release pool to + remove memory leak warnings. + + * nsterm.m (menu_pending_title, ns_get_pending_menu_title): Remove. + (ns_check_menu_open): Handle menu == nil. Remove assignment to + menu_pending_title. + + * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:setDelegate. + (x_activate_menubar): Update the whole menu. + (trackingNotification:): Call ns_check_menu_open if tracking ends. + (menuWillOpen:): Increment trackingMenu. For OSX <= 10.6, exit if + current event is not NSSystemDefined (Bug#15001). + Call ns_check_menu_open only if trackingMenu is 2. + (menuDidClose:): New method, decrease trackingMenu. + (fillWithWidgetValue:setDelegate:): New method. + (fillWithWidgetValue:): Call the above. + + * nsterm.h (EmacsMenu): Add fillWithWidgetValue:setDelegate: + +2013-08-11 Paul Eggert <eggert@cs.ucla.edu> + + Omit some unnecessary casts. + Many of these go back to the old pre-C89 days, when they may have + been needed, but we've been assuming C89 or later for a while now. + * alloc.c (live_string_p, live_cons_p, live_symbol_p) + (live_float_p, live_misc_p, live_vector_p): + * buffer.c (compare_overlays, cmp_for_strings, mmap_find) + (mmap_alloc, alloc_buffer_text, enlarge_buffer_text) + (defvar_per_buffer): + * callint.c (Fcall_interactively): + * doc.c (Fsubstitute_command_keys): + * filelock.c (get_boot_time): + * frame.c (xrdb_get_resource): + * gtkutil.c (hierarchy_ch_cb, qttip_cb, style_changed_cb) + (delete_cb, xg_dialog_response_cb, xg_maybe_add_timer) + (xg_get_file_name_from_selector, menuitem_destroy_callback) + (menuitem_highlight_callback, menu_destroy_callback) + (xg_update_menu_item, xg_modify_menubar_widgets, menubar_map_cb) + (xg_tool_bar_callback, xg_get_tool_bar_widgets) + (xg_tool_bar_detach_callback, xg_tool_bar_attach_callback) + (xg_tool_bar_help_callback, tb_size_cb): + * image.c (xpm_alloc_color, png_read_from_memory) + (png_read_from_file, png_load_body, our_memory_skip_input_data) + (jpeg_memory_src, jpeg_file_src, imagemagick_load_image) + (syms_of_image): + * keymap.c (describe_map): + * nsfns.m (Fns_display_monitor_attributes_list): + * nsmenu.m (process_dialog:): + * nsterm.m (hold_event): + * process.c (wait_reading_process_output): + * regex.c (REGEX_REALLOCATE, re_set_registers, re_exec, regexec): + * scroll.c (do_direct_scrolling, scrolling_1): + * termcap.c (tgetent): + * window.c (check_window_containing, add_window_to_list) + (freeze_window_starts): + * xdisp.c (compare_overlay_entries, vmessage): + * xfns.c (x_window, x_get_monitor_attributes_xinerama) + (x_get_monitor_attributes_xrandr) + (Fx_display_monitor_attributes_list, x_display_info_for_name) + (Fx_open_connection, file_dialog_cb, file_dialog_unmap_cb): + * xfont.c (xfont_match, xfont_open): + * xmenu.c (x_menu_wait_for_event, menu_highlight_callback) + (menubar_selection_callback, menu_position_func) + (popup_selection_callback, create_and_show_popup_menu) + (dialog_selection_callback, create_and_show_dialog): + * xrdb.c (x_get_string_resource): + (main) [TESTRM]: + * xsmfns.c (x_session_check_input): + * xterm.c (x_draw_glyphless_glyph_string_foreground) + (xm_scroll_callback, xg_scroll_callback, xg_end_scroll_callback) + (xaw_jump_callback, xaw_scroll_callback): + Omit unnecessary casts. + +2013-08-10 Paul Eggert <eggert@cs.ucla.edu> + + Minor string-length refactoring. + * alloc.c (xstrdup): Use memcpy, not strcpy, since the length's known. + * frame.c (make_monitor_attribute_list): + Prefer build_string to strlen + make_string. + +2013-08-10 Jan Djärv <jan.h.d@swipnet.se> + + * xterm.c (x_error_handler): Also ignore BadWindow for X_SetInputFocus, + don't check minor_code (Bug#14417). + +2013-08-09 Eli Zaretskii <eliz@gnu.org> + + * xdisp.c (draw_glyphs): Don't compare row pointers, compare row + vertical positions instead. This avoids calling MATRIX_ROW with + row numbers that are possibly beyond valid limits. (Bug#15064) + +2013-08-09 Dmitry Antipov <dmantipov@yandex.ru> + + Use xstrdup and build_unibyte_string where applicable. + * alloc.c (xstrdup): Tiny cleanup. Add eassert. + * xfns.c (x_window): + * xrdb.c (x_get_customization_string): + * xterm.c (xim_initialize): + * w32fns.c (w32_window): Use xstrdup. + (w32_display_monitor_attributes_list): + * emacs.c (init_cmdargs): + * keyboard.c (PUSH_C_STR): + * nsfont.m (nsfont_open): + * sysdep.c (system_process_attributes): + * w32.c (system_process_attributes): + * xdisp.c (message1, message1_nolog): Use build_unibyte_string. + +2013-08-09 Eli Zaretskii <eliz@gnu.org> + + * w32.c (PEXCEPTION_POINTERS, PEXCEPTION_RECORD, PCONTEXT): Define + variables of these types so that GDB would know about them, as aid + for debugging fatal exceptions. (Bug#15024) See also + http://sourceware.org/ml/gdb/2013-08/msg00010.html for related + discussions. + +2013-08-08 Jan Djärv <jan.h.d@swipnet.se> + + * nsterm.m (ns_update_begin): Don't change clip path if it would be + larger than the NSWindow (Bug#14934). + +2013-08-08 Dmitry Antipov <dmantipov@yandex.ru> + + Redesign redisplay interface to drop global variable updated_window. + Always pass currently updated window as a parameter to update routines. + * dispextern.h (updated_window): Remove declaration. + (struct redisplay_interface): Pass window parameter to + write_glyphs, insert_glyphs, clear_end_of_line, cursor_to + and after_update_window_hook. + (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to): + Adjust prototypes. + * dispnew.c (updated_window): Remove. + (redraw_overlapped_rows, update_marginal_area, update_text_area) + (update_window_line): Adjust to match redisplay interface changes. + * nsterm.m (ns_update_window_begin, ns_update_window_end) + (ns_scroll_run, ns_after_update_window_line): + * w32term.c (x_update_window_begin, x_update_window_end) + (x_after_update_window_line, x_scroll_run): + * xterm.c (x_update_window_begin, x_update_window_end) + (x_after_update_window_line, x_scroll_run): + * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): + Likewise. Adjust comments where appropriate. + (x_cursor_to): Simplify because this is always called during window + update (but install debugging check anyway). + (expose_window): Check must_be_updated_p flag to see whether this + function is called during window update. + +2013-08-08 Dmitry Antipov <dmantipov@yandex.ru> + + Do not reset window modification event counters excessively. + These leftovers and poor man's tricky methods to catch extra + redisplay's attention are no longer needed. + * frame.c (set_menu_bar_lines_1): + * minibuf.c (read_minibuf_unwind): + * window.c (Fset_window_start, set_window_buffer, window_resize_apply) + (grow_mini_window, shrink_mini_window, window_scroll_pixel_based) + (window_scroll_line_based, Fset_window_configuration): + * xdisp.c (redisplay_window): Do not reset last_modified and + last_overlay_modified counters. + +2013-08-07 Jan Djärv <jan.h.d@swipnet.se> + + * xselect.c (x_send_client_event): Set send_event and serial, memset + data.l as it might be bigger than data.b. Use 24 bit mask to + XSendEvent (Bug#15034). + +2013-08-07 Eli Zaretskii <eliz@gnu.org> + + * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title + for TTY frames that are not the top frame on their console. + (Bug#14616) + +2013-08-07 Martin Rudalics <rudalics@gmx.at> + + * w32term.c (w32fullscreen_hook): Really maximize frame when + asked for (Bug#14841). + +2013-08-07 Dmitry Antipov <dmantipov@yandex.ru> + + Prefer selected_window to Fselected_window, likewise for frames. + * buffer.c (Fbuffer_swap_text): + * data.c (Fvariable_binding_locus): + * window.c (run_window_configuration_change_hook): Adjust users. + * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data): + Use decode_live_frame. + +2013-08-07 Dmitry Antipov <dmantipov@yandex.ru> + + Be more careful if selected window shows the buffer other than current, + use window_outdated only if this is not so. This change should also + address some weird issues discussed in Bug#13012. + * window.h (window_outdated): New prototype. + * window.c (window_outdated): Now here. Convert from static and + always assume window's buffer. + (Fwindow_end, Fwindow_line_height): Use it. + * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg + and always assume window's buffer. + (redisplay_window): Adjust user. + (redisplay_internal): Call to reconsider_clip_changes once and + check whether mode line should be updated only if selected window + shows current buffer. + (run_window_scroll_functions): Use eassert for debugging check. + (Fmove_point_visually, note_mouse_highlight): Use window_outdated. + +2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> + + * window.c (window_scroll, window_scroll_pixel_based) + (window_scroll_line_based): Use bool for booleans. + +2013-08-06 Paul Eggert <eggert@cs.ucla.edu> + + * process.c: Fix minor off-by-one issues in descriptor counts. + This shouldn't fix any real bugs, but it cleans up the code a bit. + (max_process_desc, max_input_desc): -1, not 0, means none. + All uses changed. + (delete_input_desc): New function. + (delete_write_fd, delete_keyboard_wait_descriptor): Use it. + (deactivate_process): Scan backwards when recomuting max_process_desc; + that should be faster. + (init_process_emacs): Initialize max_input_desc. + +2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> + + Use region cache to speedup bidi_find_paragraph_start. + * buffer.h (struct buffer): New member bidi_paragraph_cache. + Rename cache_long_line_scans to cache_long_scans. + * buffer.c (bset_cache_long_line_scans): Rename to + bset_cache_long_scans. + (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer) + (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache + into account. + (syms_of_buffer): Rename cache-long-line-scans to + cache-long-scans. Adjust docstring. + * search.c (newline_cache_on_off): + * indent.c (width_run_cache_on_off): Adjust users. + * bidi.c (bidi_paragraph_cache_on_off): New function. + (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed. + * insdel.c (prepare_to_modify_buffer): Invalidate + bidi_paragraph_cache if enabled. + +2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> + + Invalidate region caches only if buffer text is going to be changed. + * lisp.h (modify_region_1): Remove 3rd arg and rename to... + (modify_text): ...new prototype. + (prepare_to_modify_buffer_1): New prototype. + * textprop.c (modify_region): Rename to... + (modify_text_properties): ...new function. + (add_text_properties_1, set_text_properties, Fremove_text_properties) + (Fremove_list_of_text_properties): Adjust users. + * insdel.c (modify_region_1): Remove 3rd arg and reimplement as... + (modify_text): ...new function. + (prepare_to_modify_buffer): Reimplement mostly as a wrapper for... + (prepare_to_modify_buffer_1): ...new function. + * casefiddle.c (casify_region): + * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) + (Ftranspose_regions): Use modify_text. + +2013-08-05 Stefan Monnier <monnier@iro.umontreal.ca> + + * lisp.mk (lisp): Add nadvice.elc. + +2013-08-05 Dmitry Antipov <dmantipov@yandex.ru> + + New macro to iterate over live buffers similar to frames. + * buffer.h (FOR_EACH_LIVE_BUFFER): New macro. + (Vbuffer_alist, Qpriority, Qbefore_string, Qafter_string): + Declare buffer-related variables here to offload lisp.h. + * buffer.c (Vbuffer_alist): Adjust comment. + (Fget_file_buffer, get_truename_buffer, Fother_buffer) + (other_buffer_safely): + * data.c (store_symval_forwarding): + * dispnew.c (Fframe_or_buffer_changed_p): + * fileio.c (Fdo_auto_save): + * filelock.c (unlock_all_files): + * minibuf.c (read_minibuf): Use FOR_EACH_LIVE_BUFFER. + +2013-08-04 Paul Eggert <eggert@cs.ucla.edu> + + Fix some minor races in hosts lacking mkostemp (Bug#15015). + * callproc.c (create_temp_file): + * filelock.c (create_lock_file): + Assume mkostemp, since it's now provided by Gnulib. + +2013-08-04 Eli Zaretskii <eliz@gnu.org> + + * w32.c (mkostemp): New function. + (mktemp): Remove, no longer used. Most of the code reused in + mkostemp. (Bug#15015) + (mktemp): Don't undef. + +2013-08-04 Dmitry Antipov <dmantipov@yandex.ru> + + * dispnew.c (glyph_matrix_count, glyph_pool_count): + Move under GLYPH_DEBUG and ENABLE_CHECKING. + (new_glyph_matrix, free_glyph_matrix, new_glyph_pool) + (free_glyph_pool, check_glyph_memory): Likewise for + all users. Adjust comments where appropriate. + +2013-08-03 Paul Eggert <eggert@cs.ucla.edu> + + * composite.h: Minor fixups. + (composition_registered_p): Rename from COMPOSITION_REGISTERD_P + to fix a misspelling, and change it to an inline function while + we're at it (it need not be a macro). All uses changed. + (composition_method, composition_valid_p): + Rewrite to avoid assignments in if-conditions. + +2013-08-03 Dmitry Antipov <dmantipov@yandex.ru> + + Do not use global Lisp_Object in composition macros. + * composite.h (composition_temp): Remove declaration. + (COMPOSITION_METHOD, COMPOSITION_VALID_P): Replace with... + (composition_method, composition_valid_p): ...inline functions. + (compose_region): Remove the leftover. + * composite.c (composition_temp): Remove. + (run_composition_function, update_compositions) + (composition_compute_stop_pos, composition_adjust_point) + (Ffind_composition_internal): + * coding.c (handle_composition_annotation): + * xdisp.c (handle_composition_prop, check_point_in_composition): + Related users changed. + +2013-08-03 Dmitry Antipov <dmantipov@yandex.ru> + + Drop FRAME_PTR typedef. + * composite.c, font.c, font.h, fontset.c, fontset.h, frame.c, frame.h: + * ftfont.c, ftxfont.c, gtkutil.c, gtkutil.h, image.c, keyboard.c: + * menu.c, menu.h, msdos.c, nsfns.m, nsfont.m, nsmenu.m, nsterm.h: + * nsterm.m, scroll.c, term.c, w32fns.c, w32font.c, w32font.h: + * w32inevt.c, w32inevt.h, w32menu.c, w32notify.c, w32term.c, w32term.h: + * w32uniscribe.c, w32xfns.c, widget.c, window.c, xdisp.c, xfaces.c: + * xfns.c, xfont.c, xftfont.c, xmenu.c, xselect.c, xterm.c: + All related users changed. + +2013-08-02 Stefan Monnier <monnier@iro.umontreal.ca> + + * eval.c (default_toplevel_binding): New function. + (Fdefvar): Use it. + (unbind_to, backtrace_eval_unrewind): Do a bit of CSE simplification. + (Fdefault_toplevel_value, Fset_default_toplevel_value): New subrs. + (syms_of_eval): Export them. + * data.c (Fdefault_value): Micro cleanup. + * term.c (init_tty): Use "false". + +2013-08-02 Dmitry Antipov <dmantipov@yandex.ru> + + Fix X GC leak in GTK and raw (no toolkit) X ports. + * xterm.c (x_free_frame_resources): If white and black relief + GCs are allocated, always free them here. + * xfns.c (x_make_gc): Omit redundant initialization. + * widget.c (create_frame_gcs): Remove the leftover. + (EmacsFrameDestroy): Do nothing because all GCs are now freed + in x_free_frame_resources. + +2013-08-02 Jan Djärv <jan.h.d@swipnet.se> + + * nsterm.m (windowWillResize:toSize:): Only change title if + ! maximizing_resize && FULLSCREEN_NONE (Bug#15005). strdup title before + modifying it. + (viewDidEndLiveResize): New method. + + * nsterm.h (EmacsView): Add maximizing_resize, put it and old_title + inside NS_IMPL_COCOA. + +2013-08-02 Dmitry Antipov <dmantipov@yandex.ru> + + * insdel.c (adjust_after_replace, replace_range, del_range_2): + Do not check whether undo is enabled because record_insert and + record_delete does that themselves. + +2013-08-02 Dmitry Antipov <dmantipov@yandex.ru> + + * xterm.h (struct x_output) [HAVE_X_I18N]: Remove xic_base_fontname + member which is not really used any more. + (FRAME_XIC_BASE_FONTNAME): Remove. + * xfns.c (xic_free_fontset): Adjust user. + * xmenu.c (mouse_position_for_popup, x_activate_menubar) + (update_frame_menubar, set_frame_menubar, free_frame_menubar) + (create_and_show_popup_menu, xmenu_show, create_and_show_dialog) + (xdialog_show): Use eassert for debugging check. + * w32term.c (x_unfocus_frame): Remove unused dummy function. + +2013-08-01 Paul Eggert <eggert@cs.ucla.edu> + + * fileio.c, fns.c (merge): Move extern decl from here ... + * lisp.h (merge): ... to here. + +2013-08-01 Dmitry Antipov <dmantipov@yandex.ru> + + Fix last font-related change. + * w32font.h (w32font_list_internal, w32font_match_internal): + Fix prototype. + * w32uniscribe.c (uniscribe_list, uniscribe_match): + (uniscribe_list_family): Adjust to match font API change. + MS-Windows breakage reported by Juanma Barranquero <lekktu@gmail.com> + at http://lists.gnu.org/archive/html/emacs-devel/2013-08/msg00006.html. + +2013-08-01 Dmitry Antipov <dmantipov@yandex.ru> + + * frame.h (FRAME_MOUSE_UPDATE): + * nsterm.m (ns_frame_up_to_date): Omit redundant check + whether hlinfo->mouse_face_mouse_frame is non-NULL. + +2013-08-01 Dmitry Antipov <dmantipov@yandex.ru> + + Avoid redundant Lisp_Object <-> struct frame conversions in font API. + * font.h (struct font_driver): Change list, match, and list_family + functions to accept struct frame * as first arg. + * font.c (font_score, font_compare, font_sort_entities): Remove + prototypes. + (font_sort_entities, font_list_entities, font_select_entity): + (font_find_for_lface, Flist_fonts, Ffont_family_list): Adjust to + match font API change. + * xfont.c (xfont_list, xfont_match, xfont_list_family): + * ftfont.c (ftfont_list, ftfont_match, ftfont_list_family): + * ftxfont.c (ftxfont_list, ftxfont_match): + * xftfont.c (xftfont_list, xftfont_match): + * nsfont.m (nsfont_list, nsfont_match, nsfont_list_family): + * w32font.c (w32font_list, w32font_match, w32font_list): + (w32font_list_internal, w32_font_match_internal): Likewise. + * xfaces.c (Fx_family_fonts): Adjust user. + +2013-08-01 Dmitry Antipov <dmantipov@yandex.ru> + + Do not use pure Xism x_wm_set_icon_position in non-X ports. + * frame.c (x_set_frame_parameters): Call to x_wm_set_icon_position + only if HAVE_X_WINDOWS is in use. + * frame.h (x_set_frame_parameters): Move under HAVE_X_WINDOWS. + * nsterm.m (x_wm_set_icon_position): Remove no-op. + * w32term.c (x_wm_set_icon_position): Likewise. + * w32fns.c (x_icon): Adjust user. + +2013-08-01 Dmitry Antipov <dmantipov@yandex.ru> + + * xterm.c (last_mouse_press_frame): Remove the + leftover which is not really used any more. + (handle_one_xevent, syms_of_xterm): Adjust users. + (x_flush): Call XFlush once per each X display, not frame. + This is better because this code always unconditionally skips + non-X frames in Vframe_list and issues the only XFlush if we + have more than one X frame on the same X display. + (any_help_event_p, x_draw_glyph_string_background, x_display_ok): + Use bool for booleans. + (x_draw_glyph_string_background, cvt_string_to_pixel): + (cvt_pixel_dtor): Drop unnecessary prototypes. + * xterm.h (x_display_ok): Adjust prototype. + +2013-07-31 Dmitry Antipov <dmantipov@yandex.ru> + + Drop unnecessary functions that deals with frame pixel size. + * frame.h, msdos.h, w32term.h, xterm.h (x_pixel_width) + (x_pixel_height): Drop prototypes. + * msdos.c, nsfns.m, w32fns.c, xfns.c (x_pixel_width) + (x_pixel_height): Drop implementations. + * frame.c (Fframe_pixel_height): Use FRAME_PIXEL_HEIGHT + which should be always valid for window frame. + (Frame_pixel_width): Likewise with FRAME_PIXEL_WIDTH. + * w32menu.c (Fx_popup_dialog): + * xmenu.c (Fx_popup_dialog): Likewise for both. + +2013-07-31 Dmitry Antipov <dmantipov@yandex.ru> + + * frame.c (Fmake_terminal_frame): Use store_in_alist to setup + frame parameters and call to Fmodify_frame_parameters just once. + (Fset_frame_height, Fset_frame_width): Mention nil frame in docstring. + (Fset_frame_size, Fset_frame_position): Use decode_live_frame + and mention nil frame in docstring. + +2013-07-31 Dmitry Antipov <dmantipov@yandex.ru> + + * frame.c (make_frame, x_set_frame_parameters): Use bool for boolean. + (x_figure_window_size): Likewise. Adjust to return long. + (syms_of_frame): Do not DEFSYM Qterminal_live_p. + (toplevel): Move Qterminal_live_p to... + * terminal.c (toplevel): ...here, make it static, and... + (syms_of_terminal): ...DEFSYM here. + * frame.h (Qterminal_live_p): Remove declaration. + (make_frame, x_figure_window_size): Adjust prototype. + * nsfns.m (Fx_create_frame): Use long for window flags. + +2013-07-30 Paul Eggert <eggert@cs.ucla.edu> + + Fix tempfile bug on platforms lacking mkostemp and mkstemp (Bug#14986). + * callproc.c (create_temp_file) [! (HAVE_MKOSTEMP || HAVE_MKSTEMP)]: + Do not assume that emacs_close (INT_MAX) is a no-op. + +2013-07-30 Dmitry Antipov <dmantipov@yandex.ru> + + * xfaces.c (make_face_cache): For struct face_cache, prefer + xmalloc to xzalloc and so avoid redundant call to memset. + (Finternal_set_lisp_face_attribute): Fix comment typo and style. + +2013-07-30 Dmitry Antipov <dmantipov@yandex.ru> + + * fringe.c (draw_window_fringes, update_window_fringes) + (compute_fringe_widths): + * w32term.c (x_draw_glyph_string): + * window.c (candidate_window_p, Frecenter): + * xfaces.c (realize_basic_faces, realize_default_face) + (Fbitmap_space_p, Finternal_set_lisp_face_attribute) + (x_update_menu_appearance, face_attr_equal_p, lface_equal_p): + * xfns.c (x_set_cursor_color, xic_free_xfontset): + * xmenu.c (Fx_menu_bar_open_internal): + * xselect.c (x_reply_selection_request, Fx_get_atom_name): + * xsettings.c (xft_settings_event): + * xterm.c (x_draw_glyph_string, x_had_errors_p): + Use bool for booleans. Adjust style and comments where + appropriate. + * dispextern.h (draw_window_fringes, update_window_fringes) + (compute_fringe_widths): + * xterm.h (x_had_errors_p): Adjust prototype. + +2013-07-30 Dmitry Antipov <dmantipov@yandex.ru> + + * frame.c (Fmodify_frame_parameters): Always check 2nd arg with + CHECK_LIST. Rewrite the loop to avoid useless local variable. + +2013-07-29 Dmitry Antipov <dmantipov@yandex.ru> + + * fns.c (toplevel): Remove comment before Fsafe_length because + it checks for QUIT. + +2013-07-28 Paul Eggert <eggert@cs.ucla.edu> + + * frame.c (delete_frame): Avoid unnecessary 'this_f' test (Bug#14970). + +2013-07-28 Eli Zaretskii <eliz@gnu.org> + + * w32fns.c (w32_wnd_proc) <WM_IME_STARTCOMPOSITION>: Make sure the + frame which got the message is still alive, before dereferencing + its pointer. (Bug#14970) + + * frame.c (delete_frame): Test "this" frame's minibuffer window to + be a live window, before using it as such. (Bug#14970) + +2013-07-27 Eli Zaretskii <eliz@gnu.org> + + * w32term.c (w32_read_socket) <WM_KILLFOCUS>: Call + w32_detect_focus_change instead of doing part of its job by hand. + This fixes the problem whereby FOCUS_OUT events were not sent to + the event queue. + 2013-07-26 Eli Zaretskii <eliz@gnu.org> * process.c (Fprocess_list): Doc fix. @@ -269,7 +1365,7 @@ code a bit. It makes no difference on POSIXish platforms but apparently it fixes a bug on w32. - Fix bug where insert-file-contents closes a file twice. (Bug#14839). + Fix bug where insert-file-contents closes a file twice (Bug#14839). * fileio.c (close_file_unwind): Don't close if FD is negative; this can happen when unwinding a zapped file descriptor. (Finsert_file_contents): Unwind-protect the fd before the point marker, @@ -422,7 +1518,7 @@ (make_lispy_focus_in, make_lispy_focus_out): Declare and define. (kbd_buffer_get_event): For FOCUS_IN, make a focus_in event if no switch frame event is made. Check ! NILP (event->arg) if X11 (moved - from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11 + from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11 and there is a focused frame. (head_table): Add focus-in and focus-out. (keys_of_keyboard): Add focus-in and focus-out to Vspecial_event_map, @@ -795,7 +1891,7 @@ (emacswrite_sig, emacs_perror): New functions. * xrdb.c (fatal): Don't invoke perror, since errno might be garbage. -2013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change). +2013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change) * image.c (imagemagick_load_image): Do not use MagickExportImagePixels on NS even if it is present. Pixmap on NS is a void*. @@ -1470,7 +2566,7 @@ Now static. * lisp.h: Remove the abovementioned defns and decls. - Use functions, not macros, for XINT etc. (Bug#11935). + Use functions, not macros, for XINT etc (Bug#11935). In lisp.h, prefer functions to function-like macros, and constants to object-like macros, when either will do. This: . simplifies use, as there's no more need to worry about diff --git a/src/ChangeLog.9 b/src/ChangeLog.9 index b451b78944f..2e1d41b2495 100644 --- a/src/ChangeLog.9 +++ b/src/ChangeLog.9 @@ -10644,7 +10644,7 @@ (syms_of_xfns) [GLYPH_DEBUG]: Don't defsubr removed functions. (syms_of_xfns): Initialize Qcenter. - * eval.c (Fsignal): If lisp_eval_depth or spepdl_size are near + * eval.c (Fsignal): If lisp_eval_depth or specpdl_size are near to the limits, increase the limits. 2000-05-01 Kenichi Handa <handa@etl.go.jp> diff --git a/src/Makefile.in b/src/Makefile.in index ce709a6bc44..5b1a7b525d0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -243,6 +243,8 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBZ = @LIBZ@ + XRANDR_LIBS = @XRANDR_LIBS@ XRANDR_CFLAGS = @XRANDR_CFLAGS@ @@ -374,7 +376,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ process.o gnutls.o callproc.o \ region-cache.o sound.o atimer.o \ doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \ - profiler.o \ + profiler.o decompress.o \ thread.o systhread.o \ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) @@ -430,7 +432,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ - $(GFILENOTIFY_LIBS) $(LIB_MATH) + $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) all: emacs$(EXEEXT) $(OTHER_FILES) .PHONY: all diff --git a/src/alloc.c b/src/alloc.c index 0eb54f8b271..4cc9b3e1a13 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -788,10 +788,19 @@ xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, char * xstrdup (const char *s) { - size_t len = strlen (s) + 1; - char *p = xmalloc (len); - memcpy (p, s, len); - return p; + ptrdiff_t size; + eassert (s); + size = strlen (s) + 1; + return memcpy (xmalloc (size), s, size); +} + +/* Like above, but duplicates Lisp string to C string. */ + +char * +xlispstrdup (Lisp_Object string) +{ + ptrdiff_t size = SBYTES (string) + 1; + return memcpy (xmalloc (size), SSDATA (string), size); } /* Like putenv, but (1) use the equivalent of xmalloc and (2) the @@ -4057,7 +4066,7 @@ live_string_p (struct mem_node *m, void *p) { if (m->type == MEM_TYPE_STRING) { - struct string_block *b = (struct string_block *) m->start; + struct string_block *b = m->start; ptrdiff_t offset = (char *) p - (char *) &b->strings[0]; /* P must point to the start of a Lisp_String structure, and it @@ -4080,7 +4089,7 @@ live_cons_p (struct mem_node *m, void *p) { if (m->type == MEM_TYPE_CONS) { - struct cons_block *b = (struct cons_block *) m->start; + struct cons_block *b = m->start; ptrdiff_t offset = (char *) p - (char *) &b->conses[0]; /* P must point to the start of a Lisp_Cons, not be @@ -4106,7 +4115,7 @@ live_symbol_p (struct mem_node *m, void *p) { if (m->type == MEM_TYPE_SYMBOL) { - struct symbol_block *b = (struct symbol_block *) m->start; + struct symbol_block *b = m->start; ptrdiff_t offset = (char *) p - (char *) &b->symbols[0]; /* P must point to the start of a Lisp_Symbol, not be @@ -4132,7 +4141,7 @@ live_float_p (struct mem_node *m, void *p) { if (m->type == MEM_TYPE_FLOAT) { - struct float_block *b = (struct float_block *) m->start; + struct float_block *b = m->start; ptrdiff_t offset = (char *) p - (char *) &b->floats[0]; /* P must point to the start of a Lisp_Float and not be @@ -4156,7 +4165,7 @@ live_misc_p (struct mem_node *m, void *p) { if (m->type == MEM_TYPE_MISC) { - struct marker_block *b = (struct marker_block *) m->start; + struct marker_block *b = m->start; ptrdiff_t offset = (char *) p - (char *) &b->markers[0]; /* P must point to the start of a Lisp_Misc, not be @@ -4183,7 +4192,7 @@ live_vector_p (struct mem_node *m, void *p) if (m->type == MEM_TYPE_VECTOR_BLOCK) { /* This memory node corresponds to a vector block. */ - struct vector_block *block = (struct vector_block *) m->start; + struct vector_block *block = m->start; struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; /* P is in the block's allocation range. Scan the block diff --git a/src/bidi.c b/src/bidi.c index c31d208ecbc..7d082a94997 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -61,6 +61,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "character.h" #include "buffer.h" #include "dispextern.h" +#include "region-cache.h" static bool bidi_initialized = 0; @@ -1085,6 +1086,29 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos) return val; } +/* If the user has requested the long scans caching, make sure that + BIDI cache is enabled. Otherwise, make sure it's disabled. */ + +static struct region_cache * +bidi_paragraph_cache_on_off (void) +{ + if (NILP (BVAR (current_buffer, cache_long_scans))) + { + if (current_buffer->bidi_paragraph_cache) + { + free_region_cache (current_buffer->bidi_paragraph_cache); + current_buffer->bidi_paragraph_cache = 0; + } + return NULL; + } + else + { + if (!current_buffer->bidi_paragraph_cache) + current_buffer->bidi_paragraph_cache = new_region_cache (); + return current_buffer->bidi_paragraph_cache; + } +} + /* On my 2005-vintage machine, searching back for paragraph start takes ~1 ms per line. And bidi_paragraph_init is called 4 times when user types C-p. The number below limits each call to @@ -1100,7 +1124,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) { Lisp_Object re = paragraph_start_re; ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; - ptrdiff_t n = 0; + struct region_cache *bpc = bidi_paragraph_cache_on_off (); + ptrdiff_t n = 0, oldpos = pos, next; while (pos_byte > BEGV_BYTE && n++ < MAX_PARAGRAPH_SEARCH @@ -1111,10 +1136,18 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) of the text over which we scan back includes paragraph_start_re? */ DEC_BOTH (pos, pos_byte); - pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); + if (bpc && region_cache_backward (current_buffer, bpc, pos, &next)) + { + pos = next, pos_byte = CHAR_TO_BYTE (pos); + break; + } + else + pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); } if (n >= MAX_PARAGRAPH_SEARCH) - pos_byte = BEGV_BYTE; + pos = BEGV, pos_byte = BEGV_BYTE; + if (bpc) + know_region_cache (current_buffer, bpc, pos, oldpos); return pos_byte; } diff --git a/src/buffer.c b/src/buffer.c index 3ca1bd98b29..8a1ad607e0b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -106,9 +106,9 @@ static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, static void swap_out_buffer_local_variables (struct buffer *b); static void reset_buffer_local_variables (struct buffer *, bool); -/* Alist of all buffer names vs the buffers. */ -/* This used to be a variable, but is no longer, - to prevent lossage due to user rplac'ing this alist or its elements. */ +/* Alist of all buffer names vs the buffers. This used to be + a Lisp-visible variable, but is no longer, to prevent lossage + due to user rplac'ing this alist or its elements. */ Lisp_Object Vbuffer_alist; static Lisp_Object Qkill_buffer_query_functions; @@ -201,9 +201,9 @@ bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val) b->INTERNAL_FIELD (buffer_file_coding_system) = val; } static void -bset_cache_long_line_scans (struct buffer *b, Lisp_Object val) +bset_cache_long_scans (struct buffer *b, Lisp_Object val) { - b->INTERNAL_FIELD (cache_long_line_scans) = val; + b->INTERNAL_FIELD (cache_long_scans) = val; } static void bset_case_fold_search (struct buffer *b, Lisp_Object val) @@ -476,8 +476,7 @@ If there is no such live buffer, return nil. See also `find-buffer-visiting'. */) (register Lisp_Object filename) { - register Lisp_Object tail, buf, tem; - Lisp_Object handler; + register Lisp_Object tail, buf, handler; CHECK_STRING (filename); filename = Fexpand_file_name (filename, Qnil); @@ -492,13 +491,10 @@ See also `find-buffer-visiting'. */) return BUFFERP (handled_buf) ? handled_buf : Qnil; } - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = Fcdr (XCAR (tail)); - if (!BUFFERP (buf)) continue; if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue; - tem = Fstring_equal (BVAR (XBUFFER (buf), filename), filename); - if (!NILP (tem)) + if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), filename), filename))) return buf; } return Qnil; @@ -507,15 +503,12 @@ See also `find-buffer-visiting'. */) Lisp_Object get_truename_buffer (register Lisp_Object filename) { - register Lisp_Object tail, buf, tem; + register Lisp_Object tail, buf; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = Fcdr (XCAR (tail)); - if (!BUFFERP (buf)) continue; if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue; - tem = Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename); - if (!NILP (tem)) + if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename))) return buf; } return Qnil; @@ -588,6 +581,7 @@ even if it is dead. The return value is never nil. */) b->newline_cache = 0; b->width_run_cache = 0; + b->bidi_paragraph_cache = 0; bset_width_table (b, Qnil); b->prevent_redisplay_optimizations_p = 1; @@ -811,6 +805,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) b->newline_cache = 0; b->width_run_cache = 0; + b->bidi_paragraph_cache = 0; bset_width_table (b, Qnil); name = Fcopy_sequence (name); @@ -1579,10 +1574,8 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) } /* Consider alist of all buffers next. */ - tail = Vbuffer_alist; - for (; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = Fcdr (XCAR (tail)); if (candidate_buffer (buf, buffer) /* If the frame has a buffer_predicate, disregard buffers that don't fit the predicate. */ @@ -1619,12 +1612,9 @@ other_buffer_safely (Lisp_Object buffer) { Lisp_Object tail, buf; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) - { - buf = Fcdr (XCAR (tail)); - if (candidate_buffer (buf, buffer)) - return buf; - } + FOR_EACH_LIVE_BUFFER (tail, buf) + if (candidate_buffer (buf, buffer)) + return buf; buf = Fget_buffer (build_string ("*scratch*")); if (NILP (buf)) @@ -1958,6 +1948,11 @@ cleaning up all windows currently displaying the buffer to be killed. */) free_region_cache (b->width_run_cache); b->width_run_cache = 0; } + if (b->bidi_paragraph_cache) + { + free_region_cache (b->bidi_paragraph_cache); + b->bidi_paragraph_cache = 0; + } bset_width_table (b, Qnil); unblock_input (); bset_undo_list (b, Qnil); @@ -2368,6 +2363,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; swapfield (newline_cache, struct region_cache *); swapfield (width_run_cache, struct region_cache *); + swapfield (bidi_paragraph_cache, struct region_cache *); current_buffer->prevent_redisplay_optimizations_p = 1; other_buffer->prevent_redisplay_optimizations_p = 1; swapfield (overlays_before, struct Lisp_Overlay *); @@ -2414,7 +2410,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, live window points to that window's buffer. So since we just swapped the markers between the two buffers, we need to undo the effect of this swap for window markers. */ - Lisp_Object w = Fselected_window (), ws = Qnil; + Lisp_Object w = selected_window, ws = Qnil; Lisp_Object buf1, buf2; XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer); @@ -3151,8 +3147,8 @@ struct sortvec static int compare_overlays (const void *v1, const void *v2) { - const struct sortvec *s1 = (const struct sortvec *) v1; - const struct sortvec *s2 = (const struct sortvec *) v2; + const struct sortvec *s1 = v1; + const struct sortvec *s2 = v2; if (s1->priority != s2->priority) return s1->priority < s2->priority ? -1 : 1; if (s1->beg != s2->beg) @@ -3258,8 +3254,8 @@ static ptrdiff_t overlay_str_len; static int cmp_for_strings (const void *as1, const void *as2) { - struct sortstr *s1 = (struct sortstr *)as1; - struct sortstr *s2 = (struct sortstr *)as2; + struct sortstr const *s1 = as1; + struct sortstr const *s2 = as2; if (s1->size != s2->size) return s2->size < s1->size ? -1 : 1; if (s1->priority != s2->priority) @@ -4757,7 +4753,7 @@ static struct mmap_region * mmap_find (void *start, void *end) { struct mmap_region *r; - char *s = (char *) start, *e = (char *) end; + char *s = start, *e = end; for (r = mmap_regions; r; r = r->next) { @@ -4916,7 +4912,7 @@ mmap_alloc (void **var, size_t nbytes) } else { - struct mmap_region *r = (struct mmap_region *) p; + struct mmap_region *r = p; r->nbytes_specified = nbytes; r->nbytes_mapped = map; @@ -5056,7 +5052,7 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes) memory_full (nbytes); } - b->text->beg = (unsigned char *) p; + b->text->beg = p; unblock_input (); } @@ -5084,7 +5080,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta) memory_full (nbytes); } - BUF_BEG_ADDR (b) = (unsigned char *) p; + BUF_BEG_ADDR (b) = p; unblock_input (); } @@ -5182,7 +5178,7 @@ init_buffer_once (void) bset_buffer_file_coding_system (&buffer_defaults, Qnil); XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70); XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0); - bset_cache_long_line_scans (&buffer_defaults, Qnil); + bset_cache_long_scans (&buffer_defaults, Qnil); bset_file_truename (&buffer_defaults, Qnil); XSETFASTINT (BVAR (&buffer_defaults, display_count), 0); XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0); @@ -5246,7 +5242,7 @@ init_buffer_once (void) XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx; - XSETFASTINT (BVAR (&buffer_local_flags, cache_long_line_scans), idx); ++idx; + XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx; @@ -5402,11 +5398,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, bo_fwd->predicate = predicate; sym->declared_special = 1; sym->redirect = SYMBOL_FORWARDED; - { - /* I tried to do the job without a cast, but it seems impossible. - union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */ - SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd); - } + SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); if (PER_BUFFER_IDX (offset) == 0) @@ -6115,7 +6107,7 @@ An entry (apply FUN-NAME . ARGS) means undo the change with An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo in the active region. BEG and END is the range affected by this entry -and DELTA is the number of bytes added or deleted in that range by +and DELTA is the number of characters added or deleted in that range by this change. An entry (MARKER . DISTANCE) indicates that the marker MARKER @@ -6133,8 +6125,8 @@ If the value of the variable is t, undo information is not recorded. */); DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil, doc: /* Non-nil means the mark and region are currently active in this buffer. */); - DEFVAR_PER_BUFFER ("cache-long-line-scans", &BVAR (current_buffer, cache_long_line_scans), Qnil, - doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly. + DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, cache_long_scans), Qnil, + doc: /* Non-nil means that Emacs should use caches in attempt to speedup buffer scans. Normally, the line-motion functions work by scanning the buffer for newlines. Columnar operations (like `move-to-column' and @@ -6144,18 +6136,24 @@ buffer's lines are very long (say, more than 500 characters), these motion functions will take longer to execute. Emacs may also take longer to update the display. -If `cache-long-line-scans' is non-nil, these motion functions cache the +If `cache-long-scans' is non-nil, these motion functions cache the results of their scans, and consult the cache to avoid rescanning regions of the buffer until the text is modified. The caches are most beneficial when they prevent the most searching---that is, when the buffer contains long lines and large regions of characters with the same, fixed screen width. -When `cache-long-line-scans' is non-nil, processing short lines will +When `cache-long-scans' is non-nil, processing short lines will become slightly slower (because of the overhead of consulting the cache), and the caches will use memory roughly proportional to the number of newlines and characters whose screen width varies. +Bidirectional editing also requires buffer scans to find paragraph +separators. If you have large paragraphs or no paragraph separators +at all, these scans may be slow. If `cache-long-scans' is non-nil, +results of these scans are cached. This doesn't help too much if +paragraphs are of the reasonable (few thousands of characters) size. + The caches require no explicit maintenance; their accuracy is maintained internally by the Emacs primitives. Enabling or disabling the cache should not affect the behavior of any of the motion diff --git a/src/buffer.h b/src/buffer.h index 6c0058ee8f3..a2645981e01 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -632,9 +632,9 @@ struct buffer /* List of symbols naming the file format used for auto-save file. */ Lisp_Object INTERNAL_FIELD (auto_save_file_format); - /* True if the newline position cache and width run cache are - enabled. See search.c and indent.c. */ - Lisp_Object INTERNAL_FIELD (cache_long_line_scans); + /* True if the newline position cache, width run cache and BIDI paragraph + cache are enabled. See search.c, indent.c and bidi.c for details. */ + Lisp_Object INTERNAL_FIELD (cache_long_scans); /* If the width run cache is enabled, this table contains the character widths width_run_cache (see above) assumes. When we @@ -839,9 +839,12 @@ struct buffer the character's width; if it maps a character to zero, we don't know what its width is. This allows compute_motion to process such regions very quickly, using algebra instead of inspecting - each character. See also width_table, below. */ + each character. See also width_table, below. + + The latter cache is used to speedup bidi_find_paragraph_start. */ struct region_cache *newline_cache; struct region_cache *width_run_cache; + struct region_cache *bidi_paragraph_cache; /* Non-zero means don't use redisplay optimizations for displaying this buffer. */ @@ -1116,9 +1119,17 @@ record_unwind_current_buffer (void) } \ } while (0) +extern Lisp_Object Vbuffer_alist; extern Lisp_Object Qbefore_change_functions; extern Lisp_Object Qafter_change_functions; extern Lisp_Object Qfirst_change_hook; +extern Lisp_Object Qpriority, Qbefore_string, Qafter_string; + +/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is + a `for' loop which iterates over the buffers from Vbuffer_alist. */ + +#define FOR_EACH_LIVE_BUFFER(list_var, buf_var) \ + FOR_EACH_ALIST_VALUE (Vbuffer_alist, list_var, buf_var) /* Get text properties of B. */ diff --git a/src/callint.c b/src/callint.c index 38431226508..25096af5068 100644 --- a/src/callint.c +++ b/src/callint.c @@ -331,12 +331,9 @@ invoke it. If KEYS is omitted or nil, the return value of /* If SPECS is set to a string, use it as an interactive prompt. */ if (STRINGP (specs)) - { - /* Make a copy of string so that if a GC relocates specs, - `string' will still be valid. */ - string = alloca (SBYTES (specs) + 1); - memcpy (string, SSDATA (specs), SBYTES (specs) + 1); - } + /* Make a copy of string so that if a GC relocates specs, + `string' will still be valid. */ + string = xlispstrdupa (specs); else { Lisp_Object input; @@ -529,7 +526,7 @@ invoke it. If KEYS is omitted or nil, the return value of make_number (SCHARS (callint_message)), Qface, Qminibuffer_prompt, callint_message); args[i] = Fread_char (callint_message, Qnil, Qnil); - message1_nolog ((char *) 0); + message1_nolog (0); /* Passing args[i] directly stimulates compiler bug. */ teml = args[i]; /* See bug#8479. */ diff --git a/src/callproc.c b/src/callproc.c index 91f29bd589b..2a9162cb5cc 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -68,9 +68,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ /* Pattern used by call-process-region to make temp files. */ static Lisp_Object Vtemp_file_name_pattern; -/* The next two variables are valid only while record-unwind-protect - is in place during call-process for a synchronous subprocess. At - other times, their contents are irrelevant. Doing this via static +/* The next two variables are used while record-unwind-protect is in place + during call-process for a subprocess for which record_deleted_pid has + not yet been called. At other times, synch_process_pid is zero and + synch_process_tempfile's contents are irrelevant. Doing this via static C variables is more convenient than putting them into the arguments of record-unwind-protect, as they need to be updated at randomish times in the code, and Lisp cannot always store these values as @@ -80,8 +81,28 @@ static Lisp_Object Vtemp_file_name_pattern; /* If nonzero, a process-ID that has not been reaped. */ static pid_t synch_process_pid; -/* If nonnegative, a file descriptor that has not been closed. */ -static int synch_process_fd; +/* If a string, the name of a temp file that has not been removed. */ +#ifdef MSDOS +static Lisp_Object synch_process_tempfile; +#else +# define synch_process_tempfile make_number (0) +#endif + +/* Indexes of file descriptors that need closing on call_process_kill. */ +enum + { + /* The subsidiary process's stdout and stderr. stdin is handled + separately, in either Fcall_process_region or create_temp_file. */ + CALLPROC_STDOUT, CALLPROC_STDERR, + + /* How to read from a pipe (or substitute) from the subsidiary process. */ + CALLPROC_PIPEREAD, + + /* A bound on the number of file descriptors. */ + CALLPROC_FDS + }; + +static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int); /* Block SIGCHLD. */ @@ -107,80 +128,68 @@ unblock_child_signal (void) reaped on receipt of the first SIGCHLD after the critical section. */ void -record_kill_process (struct Lisp_Process *p) +record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) { block_child_signal (); if (p->alive) { + record_deleted_pid (p->pid, tempfile); p->alive = 0; - record_deleted_pid (p->pid); kill (- p->pid, SIGKILL); } unblock_child_signal (); } -/* Clean up when exiting call_process_cleanup. */ +/* Clean up files, file descriptors and processes created by Fcall_process. */ static void -call_process_kill (void) +delete_temp_file (Lisp_Object name) { - if (synch_process_fd >= 0) - emacs_close (synch_process_fd); + unlink (SSDATA (name)); +} + +static void +call_process_kill (void *ptr) +{ + int *callproc_fd = ptr; + int i; + for (i = 0; i < CALLPROC_FDS; i++) + if (0 <= callproc_fd[i]) + emacs_close (callproc_fd[i]); if (synch_process_pid) { struct Lisp_Process proc; proc.alive = 1; proc.pid = synch_process_pid; - record_kill_process (&proc); + record_kill_process (&proc, synch_process_tempfile); + synch_process_pid = 0; } + else if (STRINGP (synch_process_tempfile)) + delete_temp_file (synch_process_tempfile); } -/* Clean up when exiting Fcall_process. - On MSDOS, delete the temporary file on any kind of termination. - On Unix, kill the process and any children on termination by signal. */ +/* Clean up when exiting Fcall_process: restore the buffer, and + kill the subsidiary process group if the process still exists. */ static void -call_process_cleanup (Lisp_Object arg) +call_process_cleanup (Lisp_Object buffer) { -#ifdef MSDOS - Lisp_Object buffer = Fcar (arg); - Lisp_Object file = Fcdr (arg); -#else - Lisp_Object buffer = arg; -#endif - Fset_buffer (buffer); -#ifndef MSDOS - /* If the process still exists, kill its process group. */ if (synch_process_pid) { - ptrdiff_t count = SPECPDL_INDEX (); kill (-synch_process_pid, SIGINT); - record_unwind_protect_void (call_process_kill); message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); immediate_quit = 1; QUIT; wait_for_termination (synch_process_pid, 0, 1); synch_process_pid = 0; immediate_quit = 0; - specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ message1 ("Waiting for process to die...done"); } -#endif - - if (synch_process_fd >= 0) - emacs_close (synch_process_fd); - -#ifdef MSDOS - /* FILE is "" when we didn't actually create a temporary file in - call-process. */ - if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) - unlink (SDATA (file)); -#endif } #ifdef DOS_NT @@ -218,10 +227,42 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) (ptrdiff_t nargs, Lisp_Object *args) { - Lisp_Object infile, buffer, current_dir, path; + Lisp_Object infile, encoded_infile; + int filefd; + struct gcpro gcpro1; + ptrdiff_t count = SPECPDL_INDEX (); + + if (nargs >= 2 && ! NILP (args[1])) + { + infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); + CHECK_STRING (infile); + } + else + infile = build_string (NULL_DEVICE); + + GCPRO1 (infile); + encoded_infile = STRING_MULTIBYTE (infile) ? ENCODE_FILE (infile) : infile; + + filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0); + if (filefd < 0) + report_file_error ("Opening process input file", infile); + record_unwind_protect_int (close_file_unwind, filefd); + UNGCPRO; + return unbind_to (count, call_process (nargs, args, filefd)); +} + +/* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. + At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ + +static Lisp_Object +call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) +{ + Lisp_Object buffer, current_dir, path; bool display_p; - int fd0, fd1, filefd; + int fd0; + int callproc_fd[CALLPROC_FDS]; int status; + ptrdiff_t i; ptrdiff_t count = SPECPDL_INDEX (); USE_SAFE_ALLOCA; @@ -231,19 +272,21 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * Lisp_Object error_file; Lisp_Object output_file = Qnil; #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ - char *outf, *tempfile = NULL; - int outfilefd; + char *tempfile = NULL; int pid; #else pid_t pid; #endif int child_errno; - int fd_output = -1; + int fd_output, fd_error; struct coding_system process_coding; /* coding-system of process output */ struct coding_system argument_coding; /* coding-system of arguments */ /* Set to the return value of Ffind_operation_coding_system. */ Lisp_Object coding_systems; - bool output_to_buffer = 1; + bool discard_output; + + if (synch_process_pid) + error ("call-process invoked recursively"); /* Qt denotes that Ffind_operation_coding_system is not yet called. */ coding_systems = Qt; @@ -262,7 +305,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * /* Decide the coding-system for giving arguments. */ { Lisp_Object val, *args2; - ptrdiff_t i; /* If arguments are supplied, we may have to encode them. */ if (nargs >= 5) @@ -301,24 +343,16 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * } } - if (nargs >= 2 && ! NILP (args[1])) - { - infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); - CHECK_STRING (infile); - } + if (nargs < 3) + buffer = Qnil; else - infile = build_string (NULL_DEVICE); - - if (nargs >= 3) { buffer = args[2]; /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT FILE-FOR-STDERR), unless the first element is :file, in which case see the next paragraph. */ - if (CONSP (buffer) - && (! SYMBOLP (XCAR (buffer)) - || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))) + if (CONSP (buffer) && !EQ (XCAR (buffer), QCfile)) { if (CONSP (XCDR (buffer))) { @@ -335,9 +369,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * } /* If the buffer is (still) a list, it might be a (:file "file") spec. */ - if (CONSP (buffer) - && SYMBOLP (XCAR (buffer)) - && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")) + if (CONSP (buffer) && EQ (XCAR (buffer), QCfile)) { output_file = Fexpand_file_name (XCAR (XCDR (buffer)), BVAR (current_buffer, directory)); @@ -345,9 +377,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * buffer = Qnil; } - if (!(EQ (buffer, Qnil) - || EQ (buffer, Qt) - || INTEGERP (buffer))) + if (! (NILP (buffer) || EQ (buffer, Qt) || INTEGERP (buffer))) { Lisp_Object spec_buffer; spec_buffer = buffer; @@ -358,8 +388,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * CHECK_BUFFER (buffer); } } - else - buffer = Qnil; /* Make sure that the child will be able to chdir to the current buffer's current directory, or its unhandled equivalent. We @@ -372,11 +400,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * protected by the caller, so all we really have to worry about is buffer. */ { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; current_dir = BVAR (current_buffer, directory); - GCPRO5 (infile, buffer, current_dir, error_file, output_file); + GCPRO4 (buffer, current_dir, error_file, output_file); current_dir = Funhandled_file_name_directory (current_dir); if (NILP (current_dir)) @@ -390,8 +418,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * report_file_error ("Setting current directory", BVAR (current_buffer, directory)); - if (STRING_MULTIBYTE (infile)) - infile = ENCODE_FILE (infile); if (STRING_MULTIBYTE (current_dir)) current_dir = ENCODE_FILE (current_dir); if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) @@ -403,44 +429,23 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); - filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); - if (filefd < 0) - { - int open_errno = errno; - report_file_errno ("Opening process input file", DECODE_FILE (infile), - open_errno); - } - - if (STRINGP (output_file)) - { - fd_output = emacs_open (SSDATA (output_file), - O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, - default_output_mode); - if (fd_output < 0) - { - int open_errno = errno; - output_file = DECODE_FILE (output_file); - report_file_errno ("Opening process output file", - output_file, open_errno); - } - if (STRINGP (error_file) || NILP (error_file)) - output_to_buffer = 0; - } + for (i = 0; i < CALLPROC_FDS; i++) + callproc_fd[i] = -1; +#ifdef MSDOS + synch_process_tempfile = make_number (0); +#endif + record_unwind_protect_ptr (call_process_kill, callproc_fd); /* Search for program; barf if not found. */ { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + struct gcpro gcpro1, gcpro2, gcpro3; int ok; - GCPRO4 (infile, buffer, current_dir, error_file); + GCPRO3 (buffer, current_dir, error_file); ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); UNGCPRO; if (ok < 0) - { - int openp_errno = errno; - emacs_close (filefd); - report_file_errno ("Searching for program", args[0], openp_errno); - } + report_file_error ("Searching for program", args[0]); } /* If program file name starts with /: for quoting a magic name, @@ -452,9 +457,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); { - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; - GCPRO5 (infile, buffer, current_dir, path, error_file); + GCPRO4 (buffer, current_dir, path, error_file); if (nargs > 4) { ptrdiff_t i; @@ -479,254 +484,213 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * UNGCPRO; } -#ifdef MSDOS /* MW, July 1993 */ + discard_output = INTEGERP (buffer) || (NILP (buffer) && NILP (output_file)); - /* If we're redirecting STDOUT to a file, that file is already open - on fd_output. */ - if (fd_output < 0) +#ifdef MSDOS + if (! discard_output && ! STRINGP (output_file)) { - if ((outf = egetenv ("TMPDIR"))) - strcpy (tempfile = alloca (strlen (outf) + 20), outf); - else - { - tempfile = alloca (20); - *tempfile = '\0'; - } + char const *tmpdir = egetenv ("TMPDIR"); + char const *outf = tmpdir ? tmpdir : ""; + tempfile = alloca (strlen (outf) + 20); + strcpy (tempfile, outf); dostounix_filename (tempfile, 0); if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') strcat (tempfile, "/"); strcat (tempfile, "detmp.XXX"); mktemp (tempfile); - outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, - S_IREAD | S_IWRITE); - if (outfilefd < 0) + if (!*tempfile) + report_file_error ("Opening process output file", Qnil); + output_file = build_string (tempfile); + synch_process_tempfile = output_file; + } +#endif + + if (discard_output) + { + fd_output = emacs_open (NULL_DEVICE, O_WRONLY, 0); + if (fd_output < 0) + report_file_error ("Opening null device", Qnil); + } + else if (STRINGP (output_file)) + { + fd_output = emacs_open (SSDATA (output_file), + O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, + default_output_mode); + if (fd_output < 0) { int open_errno = errno; - emacs_close (filefd); + output_file = DECODE_FILE (output_file); report_file_errno ("Opening process output file", - build_string (tempfile), open_errno); + output_file, open_errno); } } else - outfilefd = fd_output; - fd0 = filefd; - fd1 = outfilefd; -#endif /* MSDOS */ - - if (INTEGERP (buffer)) { - fd0 = -1; - fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0); - } - else - { -#ifndef MSDOS int fd[2]; if (emacs_pipe (fd) != 0) - { - int pipe_errno = errno; - emacs_close (filefd); - report_file_errno ("Creating process pipe", Qnil, pipe_errno); - } - fd0 = fd[0]; - fd1 = fd[1]; -#endif + report_file_error ("Creating process pipe", Qnil); + callproc_fd[CALLPROC_PIPEREAD] = fd[0]; + fd_output = fd[1]; } + callproc_fd[CALLPROC_STDOUT] = fd_output; - { - int fd_error = fd1; - - if (fd_output >= 0) - fd1 = fd_output; + fd_error = fd_output; - if (NILP (error_file)) - fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); - else if (STRINGP (error_file)) - fd_error = emacs_open (SSDATA (error_file), + if (STRINGP (error_file) || (NILP (error_file) && !discard_output)) + { + fd_error = emacs_open ((STRINGP (error_file) + ? SSDATA (error_file) + : NULL_DEVICE), O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, default_output_mode); - - if (fd_error < 0) - { - int open_errno = errno; - emacs_close (filefd); - if (fd0 != filefd) - emacs_close (fd0); - if (fd1 >= 0) - emacs_close (fd1); -#ifdef MSDOS - unlink (tempfile); -#endif - if (NILP (error_file)) - error_file = build_string (NULL_DEVICE); - else if (STRINGP (error_file)) - error_file = DECODE_FILE (error_file); - report_file_errno ("Cannot redirect stderr", error_file, open_errno); - } + if (fd_error < 0) + { + int open_errno = errno; + report_file_errno ("Cannot redirect stderr", + (STRINGP (error_file) + ? DECODE_FILE (error_file) + : build_string (NULL_DEVICE)), + open_errno); + } + callproc_fd[CALLPROC_STDERR] = fd_error; + } #ifdef MSDOS /* MW, July 1993 */ - /* Note that on MSDOS `child_setup' actually returns the child process - exit status, not its PID, so assign it to status below. */ - pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); - child_errno = errno; - - emacs_close (outfilefd); - if (fd_error != outfilefd) - emacs_close (fd_error); - if (pid < 0) - { - synchronize_system_messages_locale (); - return - code_convert_string_norecord (build_string (strerror (child_errno)), - Vlocale_coding_system, 0); - } - status = pid; - fd1 = -1; /* No harm in closing that one! */ - if (tempfile) + /* Note that on MSDOS `child_setup' actually returns the child process + exit status, not its PID, so assign it to status below. */ + pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); + + if (pid < 0) + { + child_errno = errno; + unbind_to (count, Qnil); + synchronize_system_messages_locale (); + return + code_convert_string_norecord (build_string (strerror (child_errno)), + Vlocale_coding_system, 0); + } + status = pid; + + for (i = 0; i < CALLPROC_FDS; i++) + if (0 <= callproc_fd[i]) { - /* Since CRLF is converted to LF within `decode_coding', we - can always open a file with binary mode. */ - fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); - if (fd0 < 0) - { - int open_errno = errno; - unlink (tempfile); - emacs_close (filefd); - report_file_errno ("Cannot re-open temporary file", - build_string (tempfile), open_errno); - } + emacs_close (callproc_fd[i]); + callproc_fd[i] = -1; } - else - fd0 = -1; /* We are not going to read from tempfile. */ + emacs_close (filefd); + clear_unwind_protect (count - 1); + + if (tempfile) + { + /* Since CRLF is converted to LF within `decode_coding', we + can always open a file with binary mode. */ + callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile, + O_RDONLY | O_BINARY, 0); + if (callproc_fd[CALLPROC_PIPEREAD] < 0) + { + int open_errno = errno; + report_file_errno ("Cannot re-open temporary file", + build_string (tempfile), open_errno); + } + } + #endif /* MSDOS */ - /* Do the unwind-protect now, even though the pid is not known, so - that no storage allocation is done in the critical section. - The actual PID will be filled in during the critical section. */ - synch_process_pid = 0; - synch_process_fd = fd0; + /* Do the unwind-protect now, even though the pid is not known, so + that no storage allocation is done in the critical section. + The actual PID will be filled in during the critical section. */ + record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); -#ifdef MSDOS - /* MSDOS needs different cleanup information. */ - record_unwind_protect (call_process_cleanup, - Fcons (Fcurrent_buffer (), - build_string (tempfile ? tempfile : ""))); -#else - record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); +#ifndef MSDOS - block_input (); - block_child_signal (); + block_input (); + block_child_signal (); #ifdef WINDOWSNT - pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); - /* We need to record the input file of this child, for when we are - called from call-process-region to create an async subprocess. - That's because call-process-region's unwind procedure will - attempt to delete the temporary input file, which will fail - because that file is still in use. Recording it with the child - will allow us to delete the file when the subprocess exits. - The second part of this is in delete_temp_file, q.v. */ - if (pid > 0 && INTEGERP (buffer) && nargs >= 2 && !NILP (args[1])) - record_infile (pid, xstrdup (SSDATA (infile))); + pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); #else /* not WINDOWSNT */ - /* vfork, and prevent local vars from being clobbered by the vfork. */ - { - Lisp_Object volatile buffer_volatile = buffer; - Lisp_Object volatile coding_systems_volatile = coding_systems; - Lisp_Object volatile current_dir_volatile = current_dir; - bool volatile display_p_volatile = display_p; - bool volatile output_to_buffer_volatile = output_to_buffer; - bool volatile sa_must_free_volatile = sa_must_free; - int volatile fd1_volatile = fd1; - int volatile fd_error_volatile = fd_error; - int volatile fd_output_volatile = fd_output; - int volatile filefd_volatile = filefd; - ptrdiff_t volatile count_volatile = count; - ptrdiff_t volatile sa_count_volatile = sa_count; - char **volatile new_argv_volatile = new_argv; - - pid = vfork (); - child_errno = errno; - - buffer = buffer_volatile; - coding_systems = coding_systems_volatile; - current_dir = current_dir_volatile; - display_p = display_p_volatile; - output_to_buffer = output_to_buffer_volatile; - sa_must_free = sa_must_free_volatile; - fd1 = fd1_volatile; - fd_error = fd_error_volatile; - fd_output = fd_output_volatile; - filefd = filefd_volatile; - count = count_volatile; - sa_count = sa_count_volatile; - new_argv = new_argv_volatile; - - fd0 = synch_process_fd; - } - - if (pid == 0) - { - unblock_child_signal (); + /* vfork, and prevent local vars from being clobbered by the vfork. */ + { + Lisp_Object volatile buffer_volatile = buffer; + Lisp_Object volatile coding_systems_volatile = coding_systems; + Lisp_Object volatile current_dir_volatile = current_dir; + bool volatile display_p_volatile = display_p; + bool volatile sa_must_free_volatile = sa_must_free; + int volatile fd_error_volatile = fd_error; + int volatile filefd_volatile = filefd; + ptrdiff_t volatile count_volatile = count; + ptrdiff_t volatile sa_count_volatile = sa_count; + char **volatile new_argv_volatile = new_argv; + int volatile callproc_fd_volatile[CALLPROC_FDS]; + for (i = 0; i < CALLPROC_FDS; i++) + callproc_fd_volatile[i] = callproc_fd[i]; + + pid = vfork (); + + buffer = buffer_volatile; + coding_systems = coding_systems_volatile; + current_dir = current_dir_volatile; + display_p = display_p_volatile; + sa_must_free = sa_must_free_volatile; + fd_error = fd_error_volatile; + filefd = filefd_volatile; + count = count_volatile; + sa_count = sa_count_volatile; + new_argv = new_argv_volatile; + + for (i = 0; i < CALLPROC_FDS; i++) + callproc_fd[i] = callproc_fd_volatile[i]; + fd_output = callproc_fd[CALLPROC_STDOUT]; + } - if (fd0 >= 0) - emacs_close (fd0); + if (pid == 0) + { + unblock_child_signal (); - setsid (); + setsid (); - /* Emacs ignores SIGPIPE, but the child should not. */ - signal (SIGPIPE, SIG_DFL); + /* Emacs ignores SIGPIPE, but the child should not. */ + signal (SIGPIPE, SIG_DFL); - child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); - } + child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); + } #endif /* not WINDOWSNT */ - child_errno = errno; + child_errno = errno; - if (pid > 0) - { - if (INTEGERP (buffer)) - record_deleted_pid (pid); - else - synch_process_pid = pid; - } + if (pid > 0) + synch_process_pid = pid; - unblock_child_signal (); - unblock_input (); + unblock_child_signal (); + unblock_input (); - /* The MSDOS case did this already. */ - if (fd_error >= 0) - emacs_close (fd_error); #endif /* not MSDOS */ - /* Close most of our file descriptors, but not fd0 - since we will use that to read input from. */ - emacs_close (filefd); - if (fd_output >= 0) - emacs_close (fd_output); - if (fd1 >= 0 && fd1 != fd_error) - emacs_close (fd1); - } - if (pid < 0) report_file_errno ("Doing vfork", Qnil, child_errno); + /* Close our file descriptors, except for callproc_fd[CALLPROC_PIPEREAD] + since we will use that to read input from. */ + for (i = 0; i < CALLPROC_FDS; i++) + if (i != CALLPROC_PIPEREAD && 0 <= callproc_fd[i]) + { + emacs_close (callproc_fd[i]); + callproc_fd[i] = -1; + } + emacs_close (filefd); + clear_unwind_protect (count - 1); + if (INTEGERP (buffer)) return unbind_to (count, Qnil); if (BUFFERP (buffer)) Fset_buffer (buffer); - if (NILP (buffer)) - { - /* If BUFFER is nil, we must read process output once and then - discard it, so setup coding system but with nil. */ - setup_coding_system (Qnil, &process_coding); - process_coding.dst_multibyte = 0; - } - else + fd0 = callproc_fd[CALLPROC_PIPEREAD]; + + if (0 <= fd0) { Lisp_Object val, *args2; @@ -762,13 +726,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * setup_coding_system (val, &process_coding); process_coding.dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); + process_coding.src_multibyte = 0; } - process_coding.src_multibyte = 0; immediate_quit = 1; QUIT; - if (output_to_buffer) + if (0 <= fd0) { enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; @@ -779,9 +743,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * EMACS_INT total_read = 0; int carryover = 0; bool display_on_the_fly = display_p; - struct coding_system saved_coding; + struct coding_system saved_coding = process_coding; - saved_coding = process_coding; while (1) { /* Repeatedly read until we've filled as much as possible @@ -812,58 +775,54 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * /* Now NREAD is the total amount of data in the buffer. */ immediate_quit = 0; - if (!NILP (buffer)) - { - if (NILP (BVAR (current_buffer, enable_multibyte_characters)) - && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) - insert_1_both (buf, nread, nread, 0, 1, 0); - else - { /* We have to decode the input. */ - Lisp_Object curbuf; - ptrdiff_t count1 = SPECPDL_INDEX (); - - XSETBUFFER (curbuf, current_buffer); - /* We cannot allow after-change-functions be run - during decoding, because that might modify the - buffer, while we rely on process_coding.produced to - faithfully reflect inserted text until we - TEMP_SET_PT_BOTH below. */ - specbind (Qinhibit_modification_hooks, Qt); - decode_coding_c_string (&process_coding, - (unsigned char *) buf, nread, curbuf); - unbind_to (count1, Qnil); - if (display_on_the_fly - && CODING_REQUIRE_DETECTION (&saved_coding) - && ! CODING_REQUIRE_DETECTION (&process_coding)) - { - /* We have detected some coding system. But, - there's a possibility that the detection was - done by insufficient data. So, we give up - displaying on the fly. */ - if (process_coding.produced > 0) - del_range_2 (process_coding.dst_pos, - process_coding.dst_pos_byte, - process_coding.dst_pos - + process_coding.produced_char, - process_coding.dst_pos_byte - + process_coding.produced, 0); - display_on_the_fly = 0; - process_coding = saved_coding; - carryover = nread; - /* This is to make the above condition always - fails in the future. */ - saved_coding.common_flags - &= ~CODING_REQUIRE_DETECTION_MASK; - continue; - } - - TEMP_SET_PT_BOTH (PT + process_coding.produced_char, - PT_BYTE + process_coding.produced); - carryover = process_coding.carryover_bytes; - if (carryover > 0) - memcpy (buf, process_coding.carryover, - process_coding.carryover_bytes); + if (NILP (BVAR (current_buffer, enable_multibyte_characters)) + && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) + insert_1_both (buf, nread, nread, 0, 1, 0); + else + { /* We have to decode the input. */ + Lisp_Object curbuf; + ptrdiff_t count1 = SPECPDL_INDEX (); + + XSETBUFFER (curbuf, current_buffer); + /* We cannot allow after-change-functions be run + during decoding, because that might modify the + buffer, while we rely on process_coding.produced to + faithfully reflect inserted text until we + TEMP_SET_PT_BOTH below. */ + specbind (Qinhibit_modification_hooks, Qt); + decode_coding_c_string (&process_coding, + (unsigned char *) buf, nread, curbuf); + unbind_to (count1, Qnil); + if (display_on_the_fly + && CODING_REQUIRE_DETECTION (&saved_coding) + && ! CODING_REQUIRE_DETECTION (&process_coding)) + { + /* We have detected some coding system, but the + detection may have been via insufficient data. + So give up displaying on the fly. */ + if (process_coding.produced > 0) + del_range_2 (process_coding.dst_pos, + process_coding.dst_pos_byte, + (process_coding.dst_pos + + process_coding.produced_char), + (process_coding.dst_pos_byte + + process_coding.produced), + 0); + display_on_the_fly = 0; + process_coding = saved_coding; + carryover = nread; + /* Make the above condition always fail in the future. */ + saved_coding.common_flags + &= ~CODING_REQUIRE_DETECTION_MASK; + continue; } + + TEMP_SET_PT_BOTH (PT + process_coding.produced_char, + PT_BYTE + process_coding.produced); + carryover = process_coding.carryover_bytes; + if (carryover > 0) + memcpy (buf, process_coding.carryover, + process_coding.carryover_bytes); } if (process_coding.mode & CODING_MODE_LAST_BLOCK) @@ -882,7 +841,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * first = 0; redisplay_preserve_echo_area (1); /* This variable might have been set to 0 for code - detection. In that case, we set it back to 1 because + detection. In that case, set it back to 1 because we should have already detected a coding system. */ display_on_the_fly = 1; } @@ -901,7 +860,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * #ifndef MSDOS /* Wait for it to terminate, unless it already has. */ - wait_for_termination (pid, &status, !output_to_buffer); + wait_for_termination (pid, &status, fd0 < 0); #endif immediate_quit = 0; @@ -931,37 +890,18 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * return make_number (WEXITSTATUS (status)); } -static void -delete_temp_file (Lisp_Object name) -{ - /* Suppress jka-compr handling, etc. */ - ptrdiff_t count = SPECPDL_INDEX (); - specbind (intern ("file-name-handler-alist"), Qnil); -#ifdef WINDOWSNT - /* If this is called when the subprocess didn't exit yet, the - attempt to delete its input file will fail. In that case, we - schedule the file for deletion when the subprocess exits. This - is the 2nd part of handling this situation; see the call to - record_infile in call-process above, for the first part. */ - if (!internal_delete_file (name)) - { - Lisp_Object encoded_file = ENCODE_FILE (name); - - record_pending_deletion (SSDATA (encoded_file)); - } -#else - internal_delete_file (name); -#endif - unbind_to (count, Qnil); -} - /* Create a temporary file suitable for storing the input data of call-process-region. NARGS and ARGS are the same as for - call-process-region. */ + call-process-region. Store into *FILENAME_STRING_PTR a Lisp string + naming the file, and return a file descriptor for reading. + Unwind-protect the file, so that the file descriptor will be closed + and the file removed when the caller unwinds the specpdl stack. */ -static Lisp_Object -create_temp_file (ptrdiff_t nargs, Lisp_Object *args) +static int +create_temp_file (ptrdiff_t nargs, Lisp_Object *args, + Lisp_Object *filename_string_ptr) { + int fd; struct gcpro gcpro1; Lisp_Object filename_string; Lisp_Object val, start, end; @@ -988,6 +928,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) { Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); char *tempfile; + ptrdiff_t count; #ifdef WINDOWSNT /* Cannot use the result of Fexpand_file_name, because it @@ -1008,26 +949,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) GCPRO1 (filename_string); tempfile = SSDATA (filename_string); - { - int fd; - -#ifdef HAVE_MKOSTEMP - fd = mkostemp (tempfile, O_CLOEXEC); -#elif defined HAVE_MKSTEMP - fd = mkstemp (tempfile); -#else - errno = EEXIST; - mktemp (tempfile); - /* INT_MAX denotes success, because close (INT_MAX) does nothing. */ - fd = *tempfile ? INT_MAX : -1; -#endif - if (fd < 0) - report_file_error ("Failed to open temporary file using pattern", - pattern); - emacs_close (fd); - } - - record_unwind_protect (delete_temp_file, filename_string); + count = SPECPDL_INDEX (); + record_unwind_protect_nothing (); + fd = mkostemp (tempfile, O_CLOEXEC); + if (fd < 0) + report_file_error ("Failed to open temporary file using pattern", + pattern); + set_unwind_protect (count, delete_temp_file, filename_string); + record_unwind_protect_int (close_file_unwind, fd); } start = args[0]; @@ -1058,15 +987,20 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we happen to get a ".Z" suffix. */ specbind (intern ("file-name-handler-alist"), Qnil); - Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil); + write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd); unbind_to (count1, Qnil); } + if (lseek (fd, 0, SEEK_SET) < 0) + report_file_error ("Setting file position", filename_string); + /* Note that Fcall_process takes care of binding coding-system-for-read. */ - RETURN_UNGCPRO (filename_string); + *filename_string_ptr = filename_string; + UNGCPRO; + return fd; } DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, @@ -1096,12 +1030,13 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) (ptrdiff_t nargs, Lisp_Object *args) { - struct gcpro gcpro1; - Lisp_Object infile; + struct gcpro gcpro1, gcpro2; + Lisp_Object infile, val; ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object start = args[0]; Lisp_Object end = args[1]; bool empty_input; + int fd; if (STRINGP (start)) empty_input = SCHARS (start) == 0; @@ -1115,8 +1050,19 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r empty_input = XINT (start) == XINT (end); } - infile = empty_input ? Qnil : create_temp_file (nargs, args); - GCPRO1 (infile); + if (!empty_input) + fd = create_temp_file (nargs, args, &infile); + else + { + infile = Qnil; + fd = emacs_open (NULL_DEVICE, O_RDONLY, 0); + if (fd < 0) + report_file_error ("Opening null device", Qnil); + record_unwind_protect_int (close_file_unwind, fd); + } + + val = infile; + GCPRO2 (infile, val); if (nargs > 3 && !NILP (args[3])) Fdelete_region (start, end); @@ -1133,7 +1079,17 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r } args[1] = infile; - RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); + val = call_process (nargs, args, fd); + + if (!empty_input && 4 < nargs + && (INTEGERP (CONSP (args[4]) ? XCAR (args[4]) : args[4]))) + { + record_deleted_pid (synch_process_pid, infile); + synch_process_pid = 0; + clear_unwind_protect (count); + } + + RETURN_UNGCPRO (unbind_to (count, val)); } #ifndef WINDOWSNT @@ -1694,6 +1650,11 @@ syms_of_callproc (void) #endif staticpro (&Vtemp_file_name_pattern); +#ifdef MSDOS + synch_process_tempfile = make_number (0); + staticpro (&synch_process_tempfile); +#endif + DEFVAR_LISP ("shell-file-name", Vshell_file_name, doc: /* File name to load inferior shells from. Initialized from the SHELL environment variable, or to a system-dependent diff --git a/src/casefiddle.c b/src/casefiddle.c index 7f5b99752fa..5a40790f87f 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -214,7 +214,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) validate_region (&b, &e); start = XFASTINT (b); end = XFASTINT (e); - modify_region_1 (start, end, false); + modify_text (start, end); record_change (start, end - start); start_byte = CHAR_TO_BYTE (start); diff --git a/src/cmds.c b/src/cmds.c index 3ebad50184a..ce91877f85e 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -86,6 +86,7 @@ DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p", doc: /* Move point N characters forward (backward if N is negative). On reaching end or beginning of buffer, stop and signal error. Interactively, N is the numeric prefix argument. +If N is omitted or nil, move point 1 character forward. Depending on the bidirectional context, the movement may be to the right or to the left on the screen. This is in contrast with @@ -99,6 +100,7 @@ DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p", doc: /* Move point N characters backward (forward if N is negative). On attempt to pass beginning or end of buffer, stop and signal error. Interactively, N is the numeric prefix argument. +If N is omitted or nil, move point 1 character backward. Depending on the bidirectional context, the movement may be to the right or to the left on the screen. This is in contrast with diff --git a/src/coding.c b/src/coding.c index 0cdd8f9cd9e..5b637627763 100644 --- a/src/coding.c +++ b/src/coding.c @@ -7497,7 +7497,7 @@ handle_composition_annotation (ptrdiff_t pos, ptrdiff_t limit, /* We found a composition. Store the corresponding annotation data in BUF. */ int *head = buf; - enum composition_method method = COMPOSITION_METHOD (prop); + enum composition_method method = composition_method (prop); int nchars = COMPOSITION_LENGTH (prop); ADD_COMPOSITION_DATA (buf, nchars, 0, method); diff --git a/src/composite.c b/src/composite.c index 99b5da22af5..28942fe4f74 100644 --- a/src/composite.c +++ b/src/composite.c @@ -160,10 +160,6 @@ static Lisp_Object Qauto_composition_function; auto-compositions. */ #define MAX_AUTO_COMPOSITION_LOOKBACK 3 -/* Temporary variable used in macros COMPOSITION_XXX. */ -Lisp_Object composition_temp; - - /* Return COMPOSITION-ID of a composition at buffer position CHARPOS/BYTEPOS and length NCHARS. The `composition' property of the sequence is PROP. STRING, if non-nil, is a string that @@ -478,11 +474,11 @@ run_composition_function (ptrdiff_t from, ptrdiff_t to, Lisp_Object prop) valid too. */ if (from > BEGV && find_composition (from - 1, -1, &start, &end, &prop, Qnil) - && !COMPOSITION_VALID_P (start, end, prop)) + && !composition_valid_p (start, end, prop)) from = start; if (to < ZV && find_composition (to, -1, &start, &end, &prop, Qnil) - && !COMPOSITION_VALID_P (start, end, prop)) + && !composition_valid_p (start, end, prop)) to = end; if (!NILP (Ffboundp (func))) call2 (func, make_number (from), make_number (to)); @@ -524,7 +520,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask) latter to the copy of it. */ if (from > BEGV && find_composition (from - 1, -1, &start, &end, &prop, Qnil) - && COMPOSITION_VALID_P (start, end, prop)) + && composition_valid_p (start, end, prop)) { min_pos = start; if (end > to) @@ -538,7 +534,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask) } else if (from < ZV && find_composition (from, -1, &start, &from, &prop, Qnil) - && COMPOSITION_VALID_P (start, from, prop)) + && composition_valid_p (start, from, prop)) { if (from > to) max_pos = from; @@ -553,7 +549,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask) (to - 1). */ while (from < to - 1 && find_composition (from, to, &start, &from, &prop, Qnil) - && COMPOSITION_VALID_P (start, from, prop) + && composition_valid_p (start, from, prop) && from < to - 1) run_composition_function (start, from, prop); } @@ -562,7 +558,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask) { if (from < to && find_composition (to - 1, -1, &start, &end, &prop, Qnil) - && COMPOSITION_VALID_P (start, end, prop)) + && composition_valid_p (start, end, prop)) { /* TO should be also at composition boundary. But, insertion or deletion will make two compositions adjacent @@ -580,7 +576,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask) } else if (to < ZV && find_composition (to, -1, &start, &end, &prop, Qnil) - && COMPOSITION_VALID_P (start, end, prop)) + && composition_valid_p (start, end, prop)) { run_composition_function (start, end, prop); max_pos = end; @@ -901,7 +897,7 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, Lisp_Object string) { ptrdiff_t count = SPECPDL_INDEX (); - FRAME_PTR f = XFRAME (win->frame); + struct frame *f = XFRAME (win->frame); Lisp_Object pos = make_number (charpos); ptrdiff_t to; ptrdiff_t pt = PT, pt_byte = PT_BYTE; @@ -1012,7 +1008,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, if (charpos < endpos && find_composition (charpos, endpos, &start, &end, &prop, string) && start >= charpos - && COMPOSITION_VALID_P (start, end, prop)) + && composition_valid_p (start, end, prop)) { cmp_it->stop_pos = endpos = start; cmp_it->ch = -1; @@ -1672,7 +1668,7 @@ composition_adjust_point (ptrdiff_t last_pt, ptrdiff_t new_pt) /* At first check the static composition. */ if (get_property_and_range (new_pt, Qcomposition, &val, &beg, &end, Qnil) - && COMPOSITION_VALID_P (beg, end, val)) + && composition_valid_p (beg, end, val)) { if (beg < new_pt /* && end > new_pt <- It's always the case. */ && (last_pt <= beg || last_pt >= end)) @@ -1872,12 +1868,12 @@ See `find-composition' for more details. */) && (e <= XINT (pos) ? e > end : s < start)) return list3 (make_number (s), make_number (e), gstring); } - if (!COMPOSITION_VALID_P (start, end, prop)) + if (!composition_valid_p (start, end, prop)) return list3 (make_number (start), make_number (end), Qnil); if (NILP (detail_p)) return list3 (make_number (start), make_number (end), Qt); - if (COMPOSITION_REGISTERD_P (prop)) + if (composition_registered_p (prop)) id = COMPOSITION_ID (prop); else { @@ -1890,7 +1886,7 @@ See `find-composition' for more details. */) if (id >= 0) { Lisp_Object components, relative_p, mod_func; - enum composition_method method = COMPOSITION_METHOD (prop); + enum composition_method method = composition_method (prop); int width = composition_table[id]->width; components = Fcopy_sequence (COMPOSITION_COMPONENTS (prop)); diff --git a/src/composite.h b/src/composite.h index 603291044bc..53665b36bd1 100644 --- a/src/composite.h +++ b/src/composite.h @@ -49,69 +49,41 @@ enum composition_method { /* Maximum number of components a single composition can have. */ #define MAX_COMPOSITION_COMPONENTS 16 -/* These macros access information about a composition that +/* These operations access information about a composition that has `composition' property PROP. PROP is: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) or (COMPOSITION-ID . (LENGTH COMPONENTS . MODIFICATION-FUNC)) They don't check validity of PROP. */ -/* Temporary variable used only in the following macros. */ -extern Lisp_Object composition_temp; - -/* Return 1 if the composition is already registered. */ -#define COMPOSITION_REGISTERD_P(prop) INTEGERP (XCAR (prop)) +/* Return true if PROP is already registered. */ +COMPOSITE_INLINE bool +composition_registered_p (Lisp_Object prop) +{ + return INTEGERP (XCAR (prop)); +} /* Return ID number of the already registered composition. */ #define COMPOSITION_ID(prop) XINT (XCAR (prop)) /* Return length of the composition. */ #define COMPOSITION_LENGTH(prop) \ - (COMPOSITION_REGISTERD_P (prop) \ + (composition_registered_p (prop) \ ? XINT (XCAR (XCDR (prop))) \ : XINT (XCAR (XCAR (prop)))) /* Return components of the composition. */ #define COMPOSITION_COMPONENTS(prop) \ - (COMPOSITION_REGISTERD_P (prop) \ + (composition_registered_p (prop) \ ? XCAR (XCDR (XCDR (prop))) \ : XCDR (XCAR (prop))) /* Return modification function of the composition. */ #define COMPOSITION_MODIFICATION_FUNC(prop) \ - (COMPOSITION_REGISTERD_P (prop) \ + (composition_registered_p (prop) \ ? XCDR (XCDR (XCDR (prop))) \ : CONSP (prop) ? XCDR (prop) : Qnil) -/* Return the method of composition. */ -#define COMPOSITION_METHOD(prop) \ - (COMPOSITION_REGISTERD_P (prop) \ - ? composition_table[COMPOSITION_ID (prop)]->method \ - : (composition_temp = XCDR (XCAR (prop)), \ - (NILP (composition_temp) \ - ? COMPOSITION_RELATIVE \ - : (INTEGERP (composition_temp) || STRINGP (composition_temp)) \ - ? COMPOSITION_WITH_ALTCHARS \ - : COMPOSITION_WITH_RULE_ALTCHARS))) - -/* Return 1 if the composition is valid. It is valid if length of - the composition equals to (END - START). */ -#define COMPOSITION_VALID_P(start, end, prop) \ - (CONSP (prop) \ - && (COMPOSITION_REGISTERD_P (prop) \ - ? (COMPOSITION_ID (prop) >= 0 \ - && COMPOSITION_ID (prop) <= n_compositions \ - && CONSP (XCDR (prop))) \ - : (composition_temp = XCAR (prop), \ - (CONSP (composition_temp) \ - && (composition_temp = XCDR (composition_temp), \ - (NILP (composition_temp) \ - || STRINGP (composition_temp) \ - || VECTORP (composition_temp) \ - || INTEGERP (composition_temp) \ - || CONSP (composition_temp)))))) \ - && (end - start) == COMPOSITION_LENGTH (prop)) - /* Return the Nth glyph of composition specified by CMP. CMP is a pointer to `struct composition'. */ #define COMPOSITION_GLYPH(cmp, n) \ @@ -227,12 +199,48 @@ extern bool find_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *, ptrdiff_t *, Lisp_Object *, Lisp_Object); extern void update_compositions (ptrdiff_t, ptrdiff_t, int); extern void make_composition_value_copy (Lisp_Object); -extern void compose_region (int, int, Lisp_Object, Lisp_Object, - Lisp_Object); extern void syms_of_composite (void); extern void compose_text (ptrdiff_t, ptrdiff_t, Lisp_Object, Lisp_Object, Lisp_Object); +/* Return the method of a composition with property PROP. */ + +COMPOSITE_INLINE enum composition_method +composition_method (Lisp_Object prop) +{ + if (composition_registered_p (prop)) + return composition_table[COMPOSITION_ID (prop)]->method; + else + { + Lisp_Object temp = XCDR (XCAR (prop)); + return (NILP (temp) + ? COMPOSITION_RELATIVE + : INTEGERP (temp) || STRINGP (temp) + ? COMPOSITION_WITH_ALTCHARS + : COMPOSITION_WITH_RULE_ALTCHARS); + } +} + +/* Given offsets START and END, return true if PROP is a valid composition + property with length END - START. */ + +COMPOSITE_INLINE bool +composition_valid_p (ptrdiff_t start, ptrdiff_t end, Lisp_Object prop) +{ + return (CONSP (prop) + && (composition_registered_p (prop) + ? (COMPOSITION_ID (prop) >= 0 + && COMPOSITION_ID (prop) <= n_compositions + && CONSP (XCDR (prop))) + : (CONSP (XCAR (prop)) + && (NILP (XCDR (XCAR (prop))) + || STRINGP (XCDR (XCAR (prop))) + || VECTORP (XCDR (XCAR (prop))) + || INTEGERP (XCDR (XCAR (prop))) + || CONSP (XCDR (XCAR (prop)))))) + && COMPOSITION_LENGTH (prop) == end - start); +} + /* Macros for lispy glyph-string. This is completely different from struct glyph_string. */ diff --git a/src/data.c b/src/data.c index 25a9e698481..95cbd471d33 100644 --- a/src/data.c +++ b/src/data.c @@ -1018,19 +1018,14 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva - (char *) &buffer_defaults); int idx = PER_BUFFER_IDX (offset); - Lisp_Object tail; + Lisp_Object tail, buf; if (idx <= 0) break; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - Lisp_Object lbuf; - struct buffer *b; - - lbuf = Fcdr (XCAR (tail)); - if (!BUFFERP (lbuf)) continue; - b = XBUFFER (lbuf); + struct buffer *b = XBUFFER (buf); if (! PER_BUFFER_VALUE_P (b, idx)) set_per_buffer_value (b, offset, newval); @@ -1421,9 +1416,7 @@ for this variable. The default value is meaningful for variables with local bindings in certain buffers. */) (Lisp_Object symbol) { - register Lisp_Object value; - - value = default_value (symbol); + Lisp_Object value = default_value (symbol); if (!EQ (value, Qunbound)) return value; @@ -2019,7 +2012,7 @@ If the current binding is global (the default), the value is nil. */) { union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); if (KBOARD_OBJFWDP (valcontents)) - return Fframe_terminal (Fselected_frame ()); + return Fframe_terminal (selected_frame); else if (!BUFFER_OBJFWDP (valcontents)) return Qnil; } diff --git a/src/decompress.c b/src/decompress.c new file mode 100644 index 00000000000..c49f39a8ba1 --- /dev/null +++ b/src/decompress.c @@ -0,0 +1,231 @@ +/* Interface to zlib. + Copyright (C) 2013 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#ifdef HAVE_ZLIB + +#include <zlib.h> + +#include "lisp.h" +#include "character.h" +#include "buffer.h" + +#include <verify.h> + +static Lisp_Object Qzlib_dll; + +#ifdef WINDOWSNT +#include <windows.h> +#include "w32.h" + +/* Macro for defining functions that will be loaded from the zlib DLL. */ +#define DEF_ZLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args + +/* Macro for loading zlib functions from the library. */ +#define LOAD_ZLIB_FN(lib,func) { \ + fn_##func = (void *) GetProcAddress (lib, #func); \ + if (!fn_##func) return false; \ + } + +DEF_ZLIB_FN (int, inflateInit2_, + (z_streamp strm, int windowBits, const char *version, int stream_size)); + +DEF_ZLIB_FN (int, inflate, + (z_streamp strm, int flush)); + +DEF_ZLIB_FN (int, inflateEnd, + (z_streamp strm)); + +static bool zlib_initialized; + +static bool +init_zlib_functions (void) +{ + HMODULE library = w32_delayed_load (Qzlib_dll); + + if (!library) + { + message1 ("zlib library not found"); + return false; + } + + LOAD_ZLIB_FN (library, inflateInit2_); + LOAD_ZLIB_FN (library, inflate); + LOAD_ZLIB_FN (library, inflateEnd); + return true; +} + +#define fn_inflateInit2(strm, windowBits) \ + fn_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + +#else /* !WINDOWSNT */ + +#define fn_inflateInit2 inflateInit2 +#define fn_inflate inflate +#define fn_inflateEnd inflateEnd + +#endif /* WINDOWSNT */ + + +struct decompress_unwind_data +{ + ptrdiff_t old_point, start; + z_stream *stream; +}; + +static void +unwind_decompress (void *ddata) +{ + struct decompress_unwind_data *data = ddata; + fn_inflateEnd (data->stream); + + /* Delete any uncompressed data already inserted on error. */ + if (data->start) + del_range (data->start, PT); + + /* Put point where it was, or if the buffer has shrunk because the + compressed data is bigger than the uncompressed, at + point-max. */ + SET_PT (min (data->old_point, ZV)); +} + +DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, + doc: /* Return t if zlib decompression is available in this instance of Emacs. */) + (void) +{ +#ifdef WINDOWSNT + Lisp_Object found = Fassq (Qzlib_dll, Vlibrary_cache); + if (CONSP (found)) + return XCDR (found); + else + { + Lisp_Object status; + zlib_initialized = init_zlib_functions (); + status = zlib_initialized ? Qt : Qnil; + Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache); + return status; + } +#else + return Qt; +#endif +} + +DEFUN ("zlib-decompress-region", Fzlib_decompress_region, + Szlib_decompress_region, + 2, 2, 0, + doc: /* Decompress a gzip- or zlib-compressed region. +Replace the text in the region by the decompressed data. +On failure, return nil and leave the data in place. +This function can be called only in unibyte buffers. */) + (Lisp_Object start, Lisp_Object end) +{ + ptrdiff_t istart, iend, pos_byte; + z_stream stream; + int inflate_status; + struct decompress_unwind_data unwind_data; + ptrdiff_t count = SPECPDL_INDEX (); + + validate_region (&start, &end); + + if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) + error ("This function can be called only in unibyte buffers"); + +#ifdef WINDOWSNT + if (!zlib_initialized) + zlib_initialized = init_zlib_functions (); + if (!zlib_initialized) + return Qnil; +#endif + + /* This is a unibyte buffer, so character positions and bytes are + the same. */ + istart = XINT (start); + iend = XINT (end); + move_gap_both (iend, iend); + + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = 0; + stream.next_in = Z_NULL; + + /* The magic number 32 apparently means "autodetect both the gzip and + zlib formats" according to zlib.h. */ + if (fn_inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) + return Qnil; + + unwind_data.start = iend; + unwind_data.stream = &stream; + unwind_data.old_point = PT; + + record_unwind_protect_ptr (unwind_decompress, &unwind_data); + + /* Insert the decompressed data at the end of the compressed data. */ + SET_PT (iend); + + pos_byte = istart; + + /* Keep calling 'inflate' until it reports an error or end-of-input. */ + do + { + /* Maximum number of bytes that one 'inflate' call should read and write. + Do not make avail_out too large, as that might unduly delay C-g. + zlib requires that avail_in and avail_out not exceed UINT_MAX. */ + ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); + int avail_out = 16 * 1024; + int decompressed; + + if (GAP_SIZE < avail_out) + make_gap (avail_out - GAP_SIZE); + stream.next_in = BYTE_POS_ADDR (pos_byte); + stream.avail_in = avail_in; + stream.next_out = GPT_ADDR; + stream.avail_out = avail_out; + inflate_status = fn_inflate (&stream, Z_NO_FLUSH); + pos_byte += avail_in - stream.avail_in; + decompressed = avail_out - stream.avail_out; + insert_from_gap (decompressed, decompressed, 0); + QUIT; + } + while (inflate_status == Z_OK); + + if (inflate_status != Z_STREAM_END) + return unbind_to (count, Qnil); + + unwind_data.start = 0; + + /* Delete the compressed data. */ + del_range (istart, iend); + + return unbind_to (count, Qt); +} + + +/*********************************************************************** + Initialization + ***********************************************************************/ +void +syms_of_decompress (void) +{ + DEFSYM (Qzlib_dll, "zlib"); + defsubr (&Szlib_decompress_region); + defsubr (&Szlib_available_p); +} + +#endif /* HAVE_ZLIB */ diff --git a/src/dispextern.h b/src/dispextern.h index e0d04231d3a..7a4fa2ea774 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1197,11 +1197,6 @@ extern bool fonts_changed_p; extern struct glyph space_glyph; -/* Window being updated by update_window. This is non-null as long as - update_window has not finished, and null otherwise. */ - -extern struct window *updated_window; - /* Glyph row and area updated by update_window_line. */ extern struct glyph_row *updated_row; @@ -2718,12 +2713,12 @@ struct redisplay_interface /* Write or insert LEN glyphs from STRING at the nominal output position. */ - void (*write_glyphs) (struct glyph *string, int len); - void (*insert_glyphs) (struct glyph *start, int len); + void (*write_glyphs) (struct window *w, struct glyph *string, int len); + void (*insert_glyphs) (struct window *w, struct glyph *start, int len); /* Clear from nominal output position to X. X < 0 means clear to right end of display. */ - void (*clear_end_of_line) (int x); + void (*clear_end_of_line) (struct window *w, int x); /* Function to call to scroll the display as described by RUN on window W. */ @@ -2732,7 +2727,8 @@ struct redisplay_interface /* Function to call after a line in a display has been completely updated. Used to draw truncation marks and alike. DESIRED_ROW is the desired row which has been updated. */ - void (*after_update_window_line_hook) (struct glyph_row *desired_row); + void (*after_update_window_line_hook) (struct window *w, + struct glyph_row *desired_row); /* Function to call before beginning to update window W in window-based redisplay. */ @@ -2749,7 +2745,7 @@ struct redisplay_interface /* Move cursor to row/column position VPOS/HPOS, pixel coordinates Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y are window-relative pixel positions. */ - void (*cursor_to) (int vpos, int hpos, int y, int x); + void (*cursor_to) (struct window *w, int vpos, int hpos, int y, int x); /* Flush the display of frame F. For X, this is XFlush. */ void (*flush_display) (struct frame *f); @@ -3182,9 +3178,9 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *, int *, int *); extern void x_produce_glyphs (struct it *); -extern void x_write_glyphs (struct glyph *, int); -extern void x_insert_glyphs (struct glyph *, int len); -extern void x_clear_end_of_line (int); +extern void x_write_glyphs (struct window *, struct glyph *, int); +extern void x_insert_glyphs (struct window *, struct glyph *, int len); +extern void x_clear_end_of_line (struct window *, int); extern struct cursor_pos output_cursor; @@ -3200,7 +3196,7 @@ extern void display_and_set_cursor (struct window *, int, int, int, int, int); extern void set_output_cursor (struct cursor_pos *); -extern void x_cursor_to (int, int, int, int); +extern void x_cursor_to (struct window *, int, int, int, int); extern void x_update_cursor (struct frame *, int); extern void x_clear_cursor (struct window *); @@ -3235,9 +3231,9 @@ extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *, int lookup_fringe_bitmap (Lisp_Object); void draw_fringe_bitmap (struct window *, struct glyph_row *, int); void draw_row_fringe_bitmaps (struct window *, struct glyph_row *); -int draw_window_fringes (struct window *, int); -int update_window_fringes (struct window *, int); -void compute_fringe_widths (struct frame *, int); +bool draw_window_fringes (struct window *, bool); +bool update_window_fringes (struct window *, bool); +void compute_fringe_widths (struct frame *, bool); #ifdef HAVE_NTGUI void w32_init_fringe (struct redisplay_interface *); diff --git a/src/dispnew.c b/src/dispnew.c index 522a0e6a30d..b7e44e425bf 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -135,10 +135,6 @@ struct frame *last_nonminibuf_frame; static bool delayed_size_change; -/* Updated window if != 0. Set by update_window. */ - -struct window *updated_window; - /* Glyph row updated in update_window_line, and area that is updated. */ struct glyph_row *updated_row; @@ -148,12 +144,16 @@ int updated_area; struct glyph space_glyph; +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING + /* Counts of allocated structures. These counts serve to diagnose memory leaks and double frees. */ static int glyph_matrix_count; static int glyph_pool_count; +#endif /* GLYPH_DEBUG and ENABLE_CHECKING */ + /* If non-null, the frame whose frame matrices are manipulated. If null, window matrices are worked on. */ @@ -307,9 +307,11 @@ new_glyph_matrix (struct glyph_pool *pool) { struct glyph_matrix *result = xzalloc (sizeof *result); +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Increment number of allocated matrices. This count is used to detect memory leaks. */ ++glyph_matrix_count; +#endif /* Set pool and return. */ result->pool = pool; @@ -319,10 +321,10 @@ new_glyph_matrix (struct glyph_pool *pool) /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed. - The global counter glyph_matrix_count is decremented when a matrix - is freed. If the count gets negative, more structures were freed - than allocated, i.e. one matrix was freed more than once or a bogus - pointer was passed to this function. + If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global counter + glyph_matrix_count is decremented when a matrix is freed. If the count + gets negative, more structures were freed than allocated, i.e. one matrix + was freed more than once or a bogus pointer was passed to this function. If MATRIX->pool is null, this means that the matrix manages its own glyph memory---this is done for matrices on X frames. Freeing the @@ -335,10 +337,12 @@ free_glyph_matrix (struct glyph_matrix *matrix) { int i; +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Detect the case that more matrices are freed than were allocated. */ - if (--glyph_matrix_count < 0) - emacs_abort (); + --glyph_matrix_count; + eassert (glyph_matrix_count >= 0); +#endif /* Free glyph memory if MATRIX owns it. */ if (matrix->pool == NULL) @@ -355,25 +359,19 @@ free_glyph_matrix (struct glyph_matrix *matrix) /* Return the number of glyphs to reserve for a marginal area of window W. TOTAL_GLYPHS is the number of glyphs in a complete display line of window W. MARGIN gives the width of the marginal - area in canonical character units. MARGIN should be an integer - or a float. */ + area in canonical character units. */ static int -margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin) +margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin) { - int n; - - if (NUMBERP (margin)) + if (margin > 0) { int width = w->total_cols; - double d = max (0, XFLOATINT (margin)); + double d = max (0, margin); d = min (width / 2 - 1, d); - n = (int) ((double) total_glyphs / width * d); + return (int) ((double) total_glyphs / width * d); } - else - n = 0; - - return n; + return 0; } /* Return true if ROW's hash value is correct. @@ -600,8 +598,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y /* Window end is invalid, if inside of the rows that are invalidated below. */ - if (INTEGERP (w->window_end_vpos) - && XFASTINT (w->window_end_vpos) >= i) + if (w->window_end_vpos >= i) w->window_end_valid = 0; while (i < matrix->nrows) @@ -1310,38 +1307,41 @@ row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p) See dispextern.h for an overall explanation of glyph pools. ***********************************************************************/ -/* Allocate a glyph_pool structure. The structure returned is - initialized with zeros. The global variable glyph_pool_count is - incremented for each pool allocated. */ +/* Allocate a glyph_pool structure. The structure returned is initialized + with zeros. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global + variable glyph_pool_count is incremented for each pool allocated. */ static struct glyph_pool * new_glyph_pool (void) { struct glyph_pool *result = xzalloc (sizeof *result); +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* For memory leak and double deletion checking. */ ++glyph_pool_count; +#endif return result; } /* Free a glyph_pool structure POOL. The function may be called with - a null POOL pointer. The global variable glyph_pool_count is - decremented with every pool structure freed. If this count gets - negative, more structures were freed than allocated, i.e. one - structure must have been freed more than once or a bogus pointer - was passed to free_glyph_pool. */ + a null POOL pointer. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, + global variable glyph_pool_count is decremented with every pool structure + freed. If this count gets negative, more structures were freed than + allocated, i.e. one structure must have been freed more than once or + a bogus pointer was passed to free_glyph_pool. */ static void free_glyph_pool (struct glyph_pool *pool) { if (pool) { +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* More freed than allocated? */ --glyph_pool_count; eassert (glyph_pool_count >= 0); - +#endif xfree (pool->glyphs); xfree (pool); } @@ -1860,7 +1860,7 @@ showing_window_margins_p (struct window *w) if (showing_window_margins_p (XWINDOW (w->contents))) return 1; } - else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols)) + else if (w->left_margin_cols > 0 || w->right_margin_cols > 0) return 1; w = NILP (w->next) ? 0 : XWINDOW (w->next); @@ -2254,11 +2254,11 @@ check_glyph_memory (void) FOR_EACH_FRAME (tail, frame) free_glyphs (XFRAME (frame)); +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Check that nothing is left allocated. */ - if (glyph_matrix_count) - emacs_abort (); - if (glyph_pool_count) - emacs_abort (); + eassert (glyph_matrix_count == 0); + eassert (glyph_pool_count == 0); +#endif } @@ -2275,7 +2275,7 @@ check_glyph_memory (void) screen. We build such a view by constructing a frame matrix from window matrices in this section. - Windows that must be updated have their must_be_update_p flag set. + Windows that must be updated have their must_be_updated_p flag set. For all such windows, their desired matrix is made part of the desired frame matrix. For other windows, their current matrix is made part of the desired frame matrix. @@ -3232,12 +3232,12 @@ redraw_overlapped_rows (struct window *w, int yb) { updated_row = row; updated_area = area; - FRAME_RIF (f)->cursor_to (i, 0, row->y, + FRAME_RIF (f)->cursor_to (w, i, 0, row->y, area == TEXT_AREA ? row->x : 0); if (row->used[area]) - FRAME_RIF (f)->write_glyphs (row->glyphs[area], + FRAME_RIF (f)->write_glyphs (w, row->glyphs[area], row->used[area]); - FRAME_RIF (f)->clear_end_of_line (-1); + FRAME_RIF (f)->clear_end_of_line (w, -1); } row->overlapped_p = 0; @@ -3523,10 +3523,10 @@ update_marginal_area (struct window *w, int area, int vpos) /* Set cursor to start of glyphs, write them, and clear to the end of the area. I don't think that something more sophisticated is necessary here, since marginal areas will not be the default. */ - rif->cursor_to (vpos, 0, desired_row->y, 0); + rif->cursor_to (w, vpos, 0, desired_row->y, 0); if (desired_row->used[area]) - rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]); - rif->clear_end_of_line (-1); + rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]); + rif->clear_end_of_line (w, -1); } @@ -3564,14 +3564,14 @@ update_text_area (struct window *w, int vpos) && !(current_row->mode_line_p && vpos > 0)) || current_row->x != desired_row->x) { - rif->cursor_to (vpos, 0, desired_row->y, desired_row->x); + rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x); if (desired_row->used[TEXT_AREA]) - rif->write_glyphs (desired_row->glyphs[TEXT_AREA], + rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA], desired_row->used[TEXT_AREA]); /* Clear to end of window. */ - rif->clear_end_of_line (-1); + rif->clear_end_of_line (w, -1); changed_p = 1; /* This erases the cursor. We do this here because @@ -3707,8 +3707,8 @@ update_text_area (struct window *w, int vpos) break; } - rif->cursor_to (vpos, start_hpos, desired_row->y, start_x); - rif->write_glyphs (start, i - start_hpos); + rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x); + rif->write_glyphs (w, start, i - start_hpos); changed_p = 1; } } @@ -3716,8 +3716,8 @@ update_text_area (struct window *w, int vpos) /* Write the rest. */ if (i < desired_row->used[TEXT_AREA]) { - rif->cursor_to (vpos, i, desired_row->y, x); - rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i); + rif->cursor_to (w, vpos, i, desired_row->y, x); + rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i); changed_p = 1; } @@ -3737,9 +3737,9 @@ update_text_area (struct window *w, int vpos) { /* If old row extends to the end of the text area, clear. */ if (i >= desired_row->used[TEXT_AREA]) - rif->cursor_to (vpos, i, desired_row->y, + rif->cursor_to (w, vpos, i, desired_row->y, desired_row->pixel_width); - rif->clear_end_of_line (-1); + rif->clear_end_of_line (w, -1); changed_p = 1; } else if (desired_row->pixel_width < current_row->pixel_width) @@ -3749,7 +3749,7 @@ update_text_area (struct window *w, int vpos) int xlim; if (i >= desired_row->used[TEXT_AREA]) - rif->cursor_to (vpos, i, desired_row->y, + rif->cursor_to (w, vpos, i, desired_row->y, desired_row->pixel_width); /* If cursor is displayed at the end of the line, make sure @@ -3767,7 +3767,7 @@ update_text_area (struct window *w, int vpos) } else xlim = current_row->pixel_width; - rif->clear_end_of_line (xlim); + rif->clear_end_of_line (w, xlim); changed_p = 1; } } @@ -3800,8 +3800,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) eassert (desired_row->enabled_p); /* Update display of the left margin area, if there is one. */ - if (!desired_row->full_width_p - && !NILP (w->left_margin_cols)) + if (!desired_row->full_width_p && w->left_margin_cols > 0) { changed_p = 1; update_marginal_area (w, LEFT_MARGIN_AREA, vpos); @@ -3821,8 +3820,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) } /* Update display of the right margin area, if there is one. */ - if (!desired_row->full_width_p - && !NILP (w->right_margin_cols)) + if (!desired_row->full_width_p && w->right_margin_cols > 0) { changed_p = 1; update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); @@ -3839,7 +3837,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row) != MATRIX_ROW_CONTINUATION_LINE_P (current_row))) - rif->after_update_window_line_hook (desired_row); + rif->after_update_window_line_hook (w, desired_row); } /* Update current_row from desired_row. */ @@ -3928,7 +3926,7 @@ set_window_cursor_after_update (struct window *w) Horizontal position is -1 when cursor is on the left fringe. */ hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1); vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1); - rif->cursor_to (vpos, hpos, cy, cx); + rif->cursor_to (w, vpos, hpos, cy, cx); } @@ -4599,10 +4597,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos); int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); - if (INTEGERP (w->left_margin_cols)) - x += XFASTINT (w->left_margin_cols); - - /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */ + x += max (0, w->left_margin_cols); cursor_to (f, y, x); } } @@ -5884,9 +5879,8 @@ pass nil for VARIABLE. */) goto changed; } /* Check that the buffer info matches. */ - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = XCDR (XCAR (tail)); /* Ignore buffers that aren't included in buffer lists. */ if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') continue; @@ -5916,7 +5910,7 @@ pass nil for VARIABLE. */) n = 1; FOR_EACH_FRAME (tail, frame) n += 2; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) n += 3; /* Reallocate the vector if data has grown to need it, or if it has shrunk a lot. */ @@ -5941,9 +5935,8 @@ pass nil for VARIABLE. */) ASET (state, idx, XFRAME (frame)->name); idx++; } - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = XCDR (XCAR (tail)); /* Ignore buffers that aren't included in buffer lists. */ if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') continue; diff --git a/src/doc.c b/src/doc.c index 009616f4f87..d3f8fde08f6 100644 --- a/src/doc.c +++ b/src/doc.c @@ -905,7 +905,7 @@ Otherwise, return a new string, without any text properties. */) If this one's not active, get nil. */ earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps))); describe_map_tree (tem, 1, Fnreverse (earlier_maps), - Qnil, (char *)0, 1, 0, 0, 1); + Qnil, 0, 1, 0, 0, 1); } tem = Fbuffer_string (); Ferase_buffer (); diff --git a/src/editfns.c b/src/editfns.c index 50bde90788d..bbaeaea5240 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2330,6 +2330,10 @@ to multibyte for insertion (see `unibyte-char-to-multibyte'). If the current buffer is unibyte, multibyte strings are converted to unibyte for insertion. +If an overlay begins at the insertion point, the inserted text falls +outside the overlay; if a nonempty overlay ends at the insertion +point, the inserted text falls inside that overlay. + usage: (insert-before-markers &rest ARGS) */) (ptrdiff_t nargs, Lisp_Object *args) { @@ -2928,7 +2932,7 @@ Both characters must have the same length of multi-byte form. */) else if (!changed) { changed = -1; - modify_region_1 (pos, XINT (end), false); + modify_text (pos, XINT (end)); if (! NILP (noundo)) { @@ -3104,7 +3108,7 @@ It returns the number of characters changed. */) pos = XINT (start); pos_byte = CHAR_TO_BYTE (pos); end_pos = XINT (end); - modify_region_1 (pos, end_pos, false); + modify_text (pos, end_pos); cnt = 0; for (; pos < end_pos; ) @@ -4615,7 +4619,7 @@ Transposing beyond buffer boundaries is an error. */) if (end1 == start2) /* adjacent regions */ { - modify_region_1 (start1, end2, false); + modify_text (start1, end2); record_change (start1, len1 + len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4674,8 +4678,8 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region_1 (start1, end1, false); - modify_region_1 (start2, end2, false); + modify_text (start1, end1); + modify_text (start2, end2); record_change (start1, len1); record_change (start2, len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4708,7 +4712,7 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region_1 (start1, end2, false); + modify_text (start1, end2); record_change (start1, (end2 - start1)); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); @@ -4741,7 +4745,7 @@ Transposing beyond buffer boundaries is an error. */) USE_SAFE_ALLOCA; record_change (start1, (end2 - start1)); - modify_region_1 (start1, end2, false); + modify_text (start1, end2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); diff --git a/src/emacs.c b/src/emacs.c index 6d406407a9d..e6d612b8417 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -513,8 +513,7 @@ init_cmdargs (int argc, char **argv, int skip_args) They are decoded in the function command-line after we know locale-coding-system. */ Vcommand_line_args - = Fcons (make_unibyte_string (argv[i], strlen (argv[i])), - Vcommand_line_args); + = Fcons (build_unibyte_string (argv[i]), Vcommand_line_args); } unbind_to (count, Qnil); @@ -689,7 +688,8 @@ main (int argc, char **argv) stack_bottom = &stack_bottom_variable; #ifdef G_SLICE_ALWAYS_MALLOC - /* This is used by the Cygwin build. */ + /* This is used by the Cygwin build. It's not needed starting with + cygwin-1.7.24, but it doesn't do any harm. */ xputenv ("G_SLICE=always-malloc"); #endif @@ -1398,6 +1398,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem syms_of_xml (); #endif +#ifdef HAVE_ZLIB + syms_of_decompress (); +#endif + syms_of_menu (); #ifdef HAVE_NTGUI diff --git a/src/eval.c b/src/eval.c index e93c3473ae8..d36defc8fe4 100644 --- a/src/eval.c +++ b/src/eval.c @@ -678,6 +678,51 @@ The return value is BASE-VARIABLE. */) return base_variable; } +static union specbinding * +default_toplevel_binding (Lisp_Object symbol) +{ + union specbinding *binding = NULL; + union specbinding *pdl = specpdl_ptr; + while (pdl > specpdl) + { + switch ((--pdl)->kind) + { + case SPECPDL_LET_DEFAULT: + case SPECPDL_LET: + if (EQ (specpdl_symbol (pdl), symbol)) + binding = pdl; + break; + } + } + return binding; +} + +DEFUN ("default-toplevel-value", Fdefault_toplevel_value, Sdefault_toplevel_value, 1, 1, 0, + doc: /* Return SYMBOL's toplevel default value. +"Toplevel" means outside of any let binding. */) + (Lisp_Object symbol) +{ + union specbinding *binding = default_toplevel_binding (symbol); + Lisp_Object value + = binding ? specpdl_old_value (binding) : Fdefault_value (symbol); + if (!EQ (value, Qunbound)) + return value; + xsignal1 (Qvoid_variable, symbol); +} + +DEFUN ("set-default-toplevel-value", Fset_default_toplevel_value, + Sset_default_toplevel_value, 2, 2, 0, + doc: /* Set SYMBOL's toplevel default value to VALUE. +"Toplevel" means outside of any let binding. */) + (Lisp_Object symbol, Lisp_Object value) +{ + union specbinding *binding = default_toplevel_binding (symbol); + if (binding) + set_specpdl_old_value (binding, value); + else + Fset_default (symbol, value); + return Qnil; +} DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0, doc: /* Define SYMBOL as a variable, and return SYMBOL. @@ -726,18 +771,10 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) else { /* Check if there is really a global binding rather than just a let binding that shadows the global unboundness of the var. */ - union specbinding *pdl = specpdl_ptr; - while (pdl > specpdl) + union specbinding *binding = default_toplevel_binding (sym); + if (binding && EQ (specpdl_old_value (binding), Qunbound)) { - if ((--pdl)->kind >= SPECPDL_LET - && EQ (specpdl_symbol (pdl), sym) - && EQ (specpdl_old_value (pdl), Qunbound)) - { - message_with_string - ("Warning: defvar ignored because %s is let-bound", - SYMBOL_NAME (sym), 1); - break; - } + set_specpdl_old_value (binding, eval_sub (XCAR (tail))); } } tail = XCDR (tail); @@ -3325,53 +3362,50 @@ do_one_unbind (union specbinding *this_binding, int unwinding) switch (this_binding->kind) { case SPECPDL_UNWIND: - specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg); + this_binding->unwind.func (this_binding->unwind.arg); break; case SPECPDL_UNWIND_PTR: - specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg); + this_binding->unwind_ptr.func (this_binding->unwind_ptr.arg); break; case SPECPDL_UNWIND_INT: - specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg); + this_binding->unwind_int.func (this_binding->unwind_int.arg); break; case SPECPDL_UNWIND_VOID: - specpdl_ptr->unwind_void.func (); + this_binding->unwind_void.func (); break; case SPECPDL_BACKTRACE: break; case SPECPDL_LET: - /* If variable has a trivial value (no forwarding), we can - just set it. No need to check for constant symbols here, - since that was already done by specbind. */ - if (XSYMBOL (specpdl_symbol (this_binding))->redirect - == SYMBOL_PLAINVAL) - SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (this_binding)), - specpdl_old_value (this_binding)); - else - /* NOTE: we only ever come here if make_local_foo was used for - the first time on this var within this let. */ - Fset_default (specpdl_symbol (this_binding), - specpdl_old_value (this_binding)); + { /* If variable has a trivial value (no forwarding), we can + just set it. No need to check for constant symbols here, + since that was already done by specbind. */ + struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (this_binding)); + if (sym->redirect == SYMBOL_PLAINVAL) + { + SET_SYMBOL_VAL (sym, specpdl_old_value (this_binding)); + break; + } + else + { /* FALLTHROUGH!! + NOTE: we only ever come here if make_local_foo was used for + the first time on this var within this let. */ + } + } + case SPECPDL_LET_DEFAULT: + Fset_default (specpdl_symbol (this_binding), + specpdl_old_value (this_binding)); break; case SPECPDL_LET_LOCAL: - case SPECPDL_LET_DEFAULT: - { /* If the symbol is a list, it is really (SYMBOL WHERE - . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a - frame. If WHERE is a buffer or frame, this indicates we - bound a variable that had a buffer-local or frame-local - binding. WHERE nil means that the variable had the default - value when it was bound. CURRENT-BUFFER is the buffer that - was current when the variable was bound. */ + { Lisp_Object symbol = specpdl_symbol (this_binding); Lisp_Object where = specpdl_where (this_binding); + Lisp_Object old_value = specpdl_old_value (this_binding); eassert (BUFFERP (where)); - if (this_binding->kind == SPECPDL_LET_DEFAULT) - Fset_default (symbol, specpdl_old_value (this_binding)); /* If this was a local binding, reset the value in the appropriate buffer, but only if that buffer's binding still exists. */ - else if (!NILP (Flocal_variable_p (symbol, where))) - set_internal (symbol, specpdl_old_value (this_binding), - where, 1); + if (!NILP (Flocal_variable_p (symbol, where))) + set_internal (symbol, old_value, where, 1); } break; } @@ -3406,6 +3440,16 @@ clear_unwind_protect (ptrdiff_t count) previous value without invoking it. */ void +set_unwind_protect (ptrdiff_t count, void (*func) (Lisp_Object), + Lisp_Object arg) +{ + union specbinding *p = specpdl + count; + p->unwind.kind = SPECPDL_UNWIND; + p->unwind.func = func; + p->unwind.arg = arg; +} + +void set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg) { union specbinding *p = specpdl + count; @@ -3592,7 +3636,7 @@ nearest activation frame. */) directly in the pre-existing specpdl elements (i.e. we swap the current value and the old value stored in the specpdl), kind of like the inplace pointer-reversal trick. As it turns out, the rewind does the same as the - unwind, except it starts from the other end of the spepdl stack, so we use + unwind, except it starts from the other end of the specpdl stack, so we use the same function for both unwind and rewind. */ static void backtrace_eval_unrewind (int distance) @@ -3622,24 +3666,23 @@ backtrace_eval_unrewind (int distance) case SPECPDL_BACKTRACE: break; case SPECPDL_LET: - /* If variable has a trivial value (no forwarding), we can - just set it. No need to check for constant symbols here, - since that was already done by specbind. */ - if (XSYMBOL (specpdl_symbol (tmp))->redirect - == SYMBOL_PLAINVAL) - { - struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp)); - Lisp_Object old_value = specpdl_old_value (tmp); - set_specpdl_old_value (tmp, SYMBOL_VAL (sym)); - SET_SYMBOL_VAL (sym, old_value); - break; - } - else - { - /* FALLTHROUGH! - NOTE: we only ever come here if make_local_foo was used for - the first time on this var within this let. */ - } + { /* If variable has a trivial value (no forwarding), we can + just set it. No need to check for constant symbols here, + since that was already done by specbind. */ + struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp)); + if (sym->redirect == SYMBOL_PLAINVAL) + { + Lisp_Object old_value = specpdl_old_value (tmp); + set_specpdl_old_value (tmp, SYMBOL_VAL (sym)); + SET_SYMBOL_VAL (sym, old_value); + break; + } + else + { /* FALLTHROUGH!! + NOTE: we only ever come here if make_local_foo was used for + the first time on this var within this let. */ + } + } case SPECPDL_LET_DEFAULT: { Lisp_Object sym = specpdl_symbol (tmp); @@ -3908,6 +3951,8 @@ alist of active lexical bindings. */); defsubr (&Ssetq); defsubr (&Squote); defsubr (&Sfunction); + defsubr (&Sdefault_toplevel_value); + defsubr (&Sset_default_toplevel_value); defsubr (&Sdefvar); defsubr (&Sdefvaralias); defsubr (&Sdefconst); diff --git a/src/fileio.c b/src/fileio.c index c47b3533145..08caf102266 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -366,8 +366,7 @@ Given a Unix syntax file name, returns a string ending in slash. */) } #ifdef DOS_NT - beg = alloca (SBYTES (filename) + 1); - memcpy (beg, SSDATA (filename), SBYTES (filename) + 1); + beg = xlispstrdupa (filename); #else beg = SSDATA (filename); #endif @@ -944,8 +943,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) #endif /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ - nm = alloca (SBYTES (name) + 1); - memcpy (nm, SSDATA (name), SBYTES (name) + 1); + nm = xlispstrdupa (name); #ifdef DOS_NT /* Note if special escape prefix is present, but remove for now. */ @@ -1693,8 +1691,7 @@ those `/' is discarded. */) /* Always work on a copy of the string, in case GC happens during decode of environment variables, causing the original Lisp_String data to be relocated. */ - nm = alloca (SBYTES (filename) + 1); - memcpy (nm, SDATA (filename), SBYTES (filename) + 1); + nm = xlispstrdupa (filename); #ifdef DOS_NT dostounix_filename (nm, multibyte); @@ -4746,25 +4743,39 @@ This does code conversion according to the value of This calls `write-region-annotate-functions' at the start, and `write-region-post-annotation-function' at the end. */) - (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) + (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, + Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) +{ + return write_region (start, end, filename, append, visit, lockname, mustbenew, + -1); +} + +/* Like Fwrite_region, except that if DESC is nonnegative, it is a file + descriptor for FILENAME, so do not open or close FILENAME. */ + +Lisp_Object +write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, + Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, + Lisp_Object mustbenew, int desc) { - int desc; int open_flags; int mode; off_t offset IF_LINT (= 0); + bool open_and_close_file = desc < 0; bool ok; int save_errno = 0; const char *fn; struct stat st; EMACS_TIME modtime; ptrdiff_t count = SPECPDL_INDEX (); - ptrdiff_t count1; + ptrdiff_t count1 IF_LINT (= 0); Lisp_Object handler; Lisp_Object visit_file; Lisp_Object annotations; Lisp_Object encoded_filename; bool visiting = (EQ (visit, Qt) || STRINGP (visit)); bool quietly = !NILP (visit); + bool file_locked = 0; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; struct buffer *given_buffer; struct coding_system coding; @@ -4832,7 +4843,6 @@ This calls `write-region-annotate-functions' at the start, and record_unwind_protect (build_annotations_unwind, Vwrite_region_annotation_buffers); Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ()); - count1 = SPECPDL_INDEX (); given_buffer = current_buffer; @@ -4871,8 +4881,11 @@ This calls `write-region-annotate-functions' at the start, and coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; #ifdef CLASH_DETECTION - if (!auto_saving) - lock_file (lockname); + if (open_and_close_file && !auto_saving) + { + lock_file (lockname); + file_locked = 1; + } #endif /* CLASH_DETECTION */ encoded_filename = ENCODE_FILE (filename); @@ -4889,19 +4902,23 @@ This calls `write-region-annotate-functions' at the start, and mode = auto_saving ? auto_save_mode_bits : 0666; #endif - desc = emacs_open (fn, open_flags, mode); - - if (desc < 0) + if (open_and_close_file) { - int open_errno = errno; + desc = emacs_open (fn, open_flags, mode); + if (desc < 0) + { + int open_errno = errno; #ifdef CLASH_DETECTION - if (!auto_saving) unlock_file (lockname); + if (file_locked) + unlock_file (lockname); #endif /* CLASH_DETECTION */ - UNGCPRO; - report_file_errno ("Opening output file", filename, open_errno); - } + UNGCPRO; + report_file_errno ("Opening output file", filename, open_errno); + } - record_unwind_protect_int (close_file_unwind, desc); + count1 = SPECPDL_INDEX (); + record_unwind_protect_int (close_file_unwind, desc); + } if (NUMBERP (append)) { @@ -4910,7 +4927,8 @@ This calls `write-region-annotate-functions' at the start, and { int lseek_errno = errno; #ifdef CLASH_DETECTION - if (!auto_saving) unlock_file (lockname); + if (file_locked) + unlock_file (lockname); #endif /* CLASH_DETECTION */ UNGCPRO; report_file_errno ("Lseek error", filename, lseek_errno); @@ -4945,9 +4963,9 @@ This calls `write-region-annotate-functions' at the start, and immediate_quit = 0; - /* fsync is not crucial for auto-save files, since they might lose - some work anyway. */ - if (!auto_saving && !write_region_inhibit_fsync) + /* fsync is not crucial for temporary files. Nor for auto-save + files, since they might lose some work anyway. */ + if (open_and_close_file && !auto_saving && !write_region_inhibit_fsync) { /* Transfer data and metadata to disk, retrying if interrupted. fsync can report a write failure here, e.g., due to disk full @@ -4971,12 +4989,15 @@ This calls `write-region-annotate-functions' at the start, and ok = 0, save_errno = errno; } - /* NFS can report a write failure now. */ - if (emacs_close (desc) < 0) - ok = 0, save_errno = errno; + if (open_and_close_file) + { + /* NFS can report a write failure now. */ + if (emacs_close (desc) < 0) + ok = 0, save_errno = errno; - /* Discard the unwind protect for close_file_unwind. */ - specpdl_ptr = specpdl + count1; + /* Discard the unwind protect for close_file_unwind. */ + specpdl_ptr = specpdl + count1; + } /* Some file systems have a bug where st_mtime is not updated properly after a write. For example, CIFS might not see the @@ -5052,7 +5073,7 @@ This calls `write-region-annotate-functions' at the start, and unbind_to (count, Qnil); #ifdef CLASH_DETECTION - if (!auto_saving) + if (file_locked) unlock_file (lockname); #endif /* CLASH_DETECTION */ @@ -5096,8 +5117,6 @@ This calls `write-region-annotate-functions' at the start, and return Qnil; } -Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object); - DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0, doc: /* Return t if (car A) is numerically less than (car B). */) (Lisp_Object a, Lisp_Object b) @@ -5620,9 +5639,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) couldn't handle some ange-ftp'd file. */ for (do_handled_files = 0; do_handled_files < 2; do_handled_files++) - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = XCDR (XCAR (tail)); b = XBUFFER (buf); /* Record all the buffers that have auto save mode diff --git a/src/filelock.c b/src/filelock.c index b9c991e4baf..df72eff5950 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -181,7 +181,7 @@ get_boot_time (void) since utmp is typically much smaller than wtmp. Passing a null pointer causes get_boot_time_1 to inspect the default file, namely utmp. */ - get_boot_time_1 ((char *) 0, 0); + get_boot_time_1 (0, 0); if (boot_time) return boot_time; @@ -411,28 +411,14 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) memcpy (nonce, lfname, lfdirlen); strcpy (nonce + lfdirlen, nonce_base); -#if HAVE_MKOSTEMP - /* Prefer mkostemp to mkstemp, as it avoids a window where FD is - temporarily open without close-on-exec. */ fd = mkostemp (nonce, O_BINARY | O_CLOEXEC); -#elif HAVE_MKSTEMP - /* Prefer mkstemp to mktemp, as it avoids a race between - mktemp and emacs_open. */ - fd = mkstemp (nonce); -#else - mktemp (nonce); - fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, - S_IRUSR | S_IWUSR); -#endif - if (fd < 0) err = errno; else { ptrdiff_t lock_info_len; -#if ! (HAVE_MKOSTEMP && O_CLOEXEC) - fcntl (fd, F_SETFD, FD_CLOEXEC); -#endif + if (! O_CLOEXEC) + fcntl (fd, F_SETFD, FD_CLOEXEC); lock_info_len = strlen (lock_info_str); err = 0; /* Use 'write', not 'emacs_write', as garbage collection @@ -759,16 +745,15 @@ unlock_file (Lisp_Object fn) void unlock_all_files (void) { - register Lisp_Object tail; + register Lisp_Object tail, buf; register struct buffer *b; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - b = XBUFFER (XCDR (XCAR (tail))); - if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) - { - unlock_file (BVAR (b, file_truename)); - } + b = XBUFFER (buf); + if (STRINGP (BVAR (b, file_truename)) + && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) + unlock_file (BVAR (b, file_truename)); } } diff --git a/src/fns.c b/src/fns.c index 9fd0ad2a9d1..de90fd731fb 100644 --- a/src/fns.c +++ b/src/fns.c @@ -146,8 +146,6 @@ To get the number of bytes, use `string-bytes'. */) return val; } -/* This does not check for quits. That is safe since it must terminate. */ - DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0, doc: /* Return the length of a list, but avoid error or infinite loop. This function never gets an error. If LIST is not really a list, @@ -1740,8 +1738,6 @@ See also the function `nreverse', which is used more often. */) return new; } -Lisp_Object merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred); - DEFUN ("sort", Fsort, Ssort, 2, 2, 0, doc: /* Sort LIST, stably, comparing elements using PREDICATE. Returns the sorted list. LIST is modified by side effects. diff --git a/src/font.c b/src/font.c index 124d5f9bd9e..6a8262623dc 100644 --- a/src/font.c +++ b/src/font.c @@ -204,9 +204,9 @@ font_make_object (int size, Lisp_Object entity, int pixelsize) -static int font_pixel_size (FRAME_PTR f, Lisp_Object); -static Lisp_Object font_open_entity (FRAME_PTR, Lisp_Object, int); -static Lisp_Object font_matching_entity (FRAME_PTR, Lisp_Object *, +static int font_pixel_size (struct frame *f, Lisp_Object); +static Lisp_Object font_open_entity (struct frame *, Lisp_Object, int); +static Lisp_Object font_matching_entity (struct frame *, Lisp_Object *, Lisp_Object); static unsigned font_encode_char (Lisp_Object, int); @@ -269,7 +269,7 @@ font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol) /* Return a pixel size of font-spec SPEC on frame F. */ static int -font_pixel_size (FRAME_PTR f, Lisp_Object spec) +font_pixel_size (struct frame *f, Lisp_Object spec) { #ifdef HAVE_WINDOW_SYSTEM Lisp_Object size = AREF (spec, FONT_SIZE_INDEX); @@ -2037,11 +2037,6 @@ font_otf_Anchor (OTF_Anchor *anchor) /* Font sorting. */ -static unsigned font_score (Lisp_Object, Lisp_Object *); -static int font_compare (const void *, const void *); -static Lisp_Object font_sort_entities (Lisp_Object, Lisp_Object, - Lisp_Object, int); - static double font_rescale_ratio (Lisp_Object font_entity) { @@ -2186,14 +2181,14 @@ font_compare (const void *d1, const void *d2) such a case. */ static Lisp_Object -font_sort_entities (Lisp_Object list, Lisp_Object prefer, Lisp_Object frame, int best_only) +font_sort_entities (Lisp_Object list, Lisp_Object prefer, + struct frame *f, int best_only) { Lisp_Object prefer_prop[FONT_SPEC_MAX]; int len, maxlen, i; struct font_sort_data *data; unsigned best_score; Lisp_Object best_entity; - struct frame *f = XFRAME (frame); Lisp_Object tail, vec IF_LINT (= Qnil); USE_SAFE_ALLOCA; @@ -2201,7 +2196,7 @@ font_sort_entities (Lisp_Object list, Lisp_Object prefer, Lisp_Object frame, int prefer_prop[i] = AREF (prefer, i); if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) prefer_prop[FONT_SIZE_INDEX] - = make_number (font_pixel_size (XFRAME (frame), prefer)); + = make_number (font_pixel_size (f, prefer)); if (NILP (XCDR (list))) { @@ -2502,14 +2497,14 @@ font_match_p (Lisp_Object spec, Lisp_Object font) is a number frames sharing this cache, and FONT-CACHE-DATA is a cons (FONT-SPEC FONT-ENTITY ...). */ -static void font_prepare_cache (FRAME_PTR, struct font_driver *); -static void font_finish_cache (FRAME_PTR, struct font_driver *); -static Lisp_Object font_get_cache (FRAME_PTR, struct font_driver *); -static void font_clear_cache (FRAME_PTR, Lisp_Object, +static void font_prepare_cache (struct frame *, struct font_driver *); +static void font_finish_cache (struct frame *, struct font_driver *); +static Lisp_Object font_get_cache (struct frame *, struct font_driver *); +static void font_clear_cache (struct frame *, Lisp_Object, struct font_driver *); static void -font_prepare_cache (FRAME_PTR f, struct font_driver *driver) +font_prepare_cache (struct frame *f, struct font_driver *driver) { Lisp_Object cache, val; @@ -2531,7 +2526,7 @@ font_prepare_cache (FRAME_PTR f, struct font_driver *driver) static void -font_finish_cache (FRAME_PTR f, struct font_driver *driver) +font_finish_cache (struct frame *f, struct font_driver *driver) { Lisp_Object cache, val, tmp; @@ -2552,7 +2547,7 @@ font_finish_cache (FRAME_PTR f, struct font_driver *driver) static Lisp_Object -font_get_cache (FRAME_PTR f, struct font_driver *driver) +font_get_cache (struct frame *f, struct font_driver *driver) { Lisp_Object val = driver->get_cache (f); Lisp_Object type = driver->type; @@ -2567,7 +2562,7 @@ font_get_cache (FRAME_PTR f, struct font_driver *driver) static void -font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver) +font_clear_cache (struct frame *f, Lisp_Object cache, struct font_driver *driver) { Lisp_Object tail, elt; Lisp_Object tail2, entity; @@ -2692,9 +2687,8 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) same font-driver. */ Lisp_Object -font_list_entities (Lisp_Object frame, Lisp_Object spec) +font_list_entities (struct frame *f, Lisp_Object spec) { - FRAME_PTR f = XFRAME (frame); struct font_driver_list *driver_list = f->font_driver_list; Lisp_Object ftype, val; Lisp_Object list = Qnil; @@ -2738,7 +2732,7 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec) { Lisp_Object copy; - val = driver_list->driver->list (frame, scratch_font_spec); + val = driver_list->driver->list (f, scratch_font_spec); if (NILP (val)) val = zero_vector; else @@ -2766,14 +2760,12 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec) font-related attributes. */ static Lisp_Object -font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec) +font_matching_entity (struct frame *f, Lisp_Object *attrs, Lisp_Object spec) { struct font_driver_list *driver_list = f->font_driver_list; Lisp_Object ftype, size, entity; - Lisp_Object frame; Lisp_Object work = copy_font_spec (spec); - XSETFRAME (frame, f); ftype = AREF (spec, FONT_TYPE_INDEX); size = AREF (spec, FONT_SIZE_INDEX); @@ -2797,7 +2789,7 @@ font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec) entity = XCDR (entity); else { - entity = driver_list->driver->match (frame, work); + entity = driver_list->driver->match (f, work); copy = copy_font_spec (work); ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); XSETCDR (cache, Fcons (Fcons (copy, entity), XCDR (cache))); @@ -2814,7 +2806,7 @@ font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec) opened font object. */ static Lisp_Object -font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size) +font_open_entity (struct frame *f, Lisp_Object entity, int pixel_size) { struct font_driver_list *driver_list; Lisp_Object objlist, size, val, font_object; @@ -2892,7 +2884,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size) /* Close FONT_OBJECT that is opened on frame F. */ static void -font_close_object (FRAME_PTR f, Lisp_Object font_object) +font_close_object (struct frame *f, Lisp_Object font_object) { struct font *font = XFONT_OBJECT (font_object); @@ -2912,7 +2904,7 @@ font_close_object (FRAME_PTR f, Lisp_Object font_object) FONT is a font-entity and it must be opened to check. */ int -font_has_char (FRAME_PTR f, Lisp_Object font, int c) +font_has_char (struct frame *f, Lisp_Object font, int c) { struct font *fontp; @@ -3039,12 +3031,12 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop) supports C and is the best match for ATTRS and PIXEL_SIZE. */ static Lisp_Object -font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs, int pixel_size, int c) +font_select_entity (struct frame *f, Lisp_Object entities, + Lisp_Object *attrs, int pixel_size, int c) { Lisp_Object font_entity; Lisp_Object prefer; int i; - FRAME_PTR f = XFRAME (frame); if (NILP (XCDR (entities)) && ASIZE (XCAR (entities)) == 1) @@ -3075,7 +3067,7 @@ font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs, FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]); ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size)); - return font_sort_entities (entities, prefer, frame, c); + return font_sort_entities (entities, prefer, f, c); } /* Return a font-entity that satisfies SPEC and is the best match for @@ -3083,10 +3075,10 @@ font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs, character that the entity must support. */ Lisp_Object -font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) +font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int c) { Lisp_Object work; - Lisp_Object frame, entities, val; + Lisp_Object entities, val; Lisp_Object foundry[3], *family, registry[3], adstyle[3]; int pixel_size; int i, j, k, l; @@ -3118,7 +3110,6 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) work = copy_font_spec (spec); ASET (work, FONT_TYPE_INDEX, AREF (spec, FONT_TYPE_INDEX)); - XSETFRAME (frame, f); pixel_size = font_pixel_size (f, spec); if (pixel_size == 0 && INTEGERP (attrs[LFACE_HEIGHT_INDEX])) { @@ -3212,10 +3203,10 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) for (l = 0; SYMBOLP (adstyle[l]); l++) { ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]); - entities = font_list_entities (frame, work); + entities = font_list_entities (f, work); if (! NILP (entities)) { - val = font_select_entity (frame, entities, + val = font_select_entity (f, entities, attrs, pixel_size, c); if (! NILP (val)) return val; @@ -3231,7 +3222,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) Lisp_Object -font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_Object spec) +font_open_for_lface (struct frame *f, Lisp_Object entity, Lisp_Object *attrs, Lisp_Object spec) { int size; @@ -3278,7 +3269,7 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O font-object. */ Lisp_Object -font_load_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec) +font_load_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec) { Lisp_Object entity, name; @@ -3307,7 +3298,7 @@ font_load_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec) /* Make FACE on frame F ready to use the font opened for FACE. */ void -font_prepare_for_face (FRAME_PTR f, struct face *face) +font_prepare_for_face (struct frame *f, struct face *face) { if (face->font->driver->prepare_face) face->font->driver->prepare_face (f, face); @@ -3317,7 +3308,7 @@ font_prepare_for_face (FRAME_PTR f, struct face *face) /* Make FACE on frame F stop using the font opened for FACE. */ void -font_done_for_face (FRAME_PTR f, struct face *face) +font_done_for_face (struct frame *f, struct face *face) { if (face->font->driver->done_face) face->font->driver->done_face (f, face); @@ -3329,7 +3320,7 @@ font_done_for_face (FRAME_PTR f, struct face *face) font is found, return Qnil. */ Lisp_Object -font_open_by_spec (FRAME_PTR f, Lisp_Object spec) +font_open_by_spec (struct frame *f, Lisp_Object spec) { Lisp_Object attrs[LFACE_VECTOR_SIZE]; @@ -3353,7 +3344,7 @@ font_open_by_spec (FRAME_PTR f, Lisp_Object spec) found, return Qnil. */ Lisp_Object -font_open_by_name (FRAME_PTR f, Lisp_Object name) +font_open_by_name (struct frame *f, Lisp_Object name) { Lisp_Object args[2]; Lisp_Object spec, ret; @@ -3383,7 +3374,7 @@ font_open_by_name (FRAME_PTR f, Lisp_Object name) (e.g. syms_of_xfont). */ void -register_font_driver (struct font_driver *driver, FRAME_PTR f) +register_font_driver (struct font_driver *driver, struct frame *f) { struct font_driver_list *root = f ? f->font_driver_list : font_driver_list; struct font_driver_list *prev, *list; @@ -3411,7 +3402,7 @@ register_font_driver (struct font_driver *driver, FRAME_PTR f) } void -free_font_driver_list (FRAME_PTR f) +free_font_driver_list (struct frame *f) { struct font_driver_list *list, *next; @@ -3433,7 +3424,7 @@ free_font_driver_list (FRAME_PTR f) F. */ Lisp_Object -font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers) +font_update_drivers (struct frame *f, Lisp_Object new_drivers) { Lisp_Object active_drivers = Qnil; struct font_driver_list *list; @@ -3522,7 +3513,7 @@ font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers) } int -font_put_frame_data (FRAME_PTR f, struct font_driver *driver, void *data) +font_put_frame_data (struct frame *f, struct font_driver *driver, void *data) { struct font_data_list *list, *prev; @@ -3556,7 +3547,7 @@ font_put_frame_data (FRAME_PTR f, struct font_driver *driver, void *data) void * -font_get_frame_data (FRAME_PTR f, struct font_driver *driver) +font_get_frame_data (struct frame *f, struct font_driver *driver) { struct font_data_list *list; @@ -3630,7 +3621,7 @@ static Lisp_Object font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, Lisp_Object string) { - FRAME_PTR f; + struct frame *f; bool multibyte; Lisp_Object font_object; @@ -4110,12 +4101,10 @@ control the order of the returned list. Fonts are sorted by how close they are to PREFER. */) (Lisp_Object font_spec, Lisp_Object frame, Lisp_Object num, Lisp_Object prefer) { + struct frame *f = decode_live_frame (frame); Lisp_Object vec, list; EMACS_INT n = 0; - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); CHECK_FONT_SPEC (font_spec); if (! NILP (num)) { @@ -4127,7 +4116,7 @@ how close they are to PREFER. */) if (! NILP (prefer)) CHECK_FONT_SPEC (prefer); - list = font_list_entities (frame, font_spec); + list = font_list_entities (f, font_spec); if (NILP (list)) return Qnil; if (NILP (XCDR (list)) @@ -4135,7 +4124,7 @@ how close they are to PREFER. */) return list1 (AREF (XCAR (list), 0)); if (! NILP (prefer)) - vec = font_sort_entities (list, prefer, frame, 0); + vec = font_sort_entities (list, prefer, f, 0); else vec = font_vconcat_entity_vectors (list); if (n == 0 || n >= ASIZE (vec)) @@ -4163,13 +4152,11 @@ If FRAME is omitted or nil, the selected frame is used. */) struct font_driver_list *driver_list; Lisp_Object list = Qnil; - XSETFRAME (frame, f); - for (driver_list = f->font_driver_list; driver_list; driver_list = driver_list->next) if (driver_list->driver->list_family) { - Lisp_Object val = driver_list->driver->list_family (frame); + Lisp_Object val = driver_list->driver->list_family (f); Lisp_Object tail = list; for (; CONSP (val); val = XCDR (val)) @@ -4239,36 +4226,38 @@ the consecutive wildcards are folded into one. */) return make_string (name, namelen); } +void +clear_font_cache (struct frame *f) +{ + struct font_driver_list *driver_list = f->font_driver_list; + + for (; driver_list; driver_list = driver_list->next) + if (driver_list->on) + { + Lisp_Object val, tmp, cache = driver_list->driver->get_cache (f); + + val = XCDR (cache); + while (! NILP (val) + && ! EQ (XCAR (XCAR (val)), driver_list->driver->type)) + val = XCDR (val); + eassert (! NILP (val)); + tmp = XCDR (XCAR (val)); + if (XINT (XCAR (tmp)) == 0) + { + font_clear_cache (f, XCAR (val), driver_list->driver); + XSETCDR (cache, XCDR (val)); + } + } +} + DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0, - doc: /* Clear font cache. */) + doc: /* Clear font cache of each frame. */) (void) { Lisp_Object list, frame; FOR_EACH_FRAME (list, frame) - { - FRAME_PTR f = XFRAME (frame); - struct font_driver_list *driver_list = f->font_driver_list; - - for (; driver_list; driver_list = driver_list->next) - if (driver_list->on) - { - Lisp_Object cache = driver_list->driver->get_cache (f); - Lisp_Object val, tmp; - - val = XCDR (cache); - while (! NILP (val) - && ! EQ (XCAR (XCAR (val)), driver_list->driver->type)) - val = XCDR (val); - eassert (! NILP (val)); - tmp = XCDR (XCAR (val)); - if (XINT (XCAR (tmp)) == 0) - { - font_clear_cache (f, XCAR (val), driver_list->driver); - XSETCDR (cache, XCDR (val)); - } - } - } + clear_font_cache (XFRAME (frame)); return Qnil; } @@ -4795,7 +4784,7 @@ Type C-l to recover what previously shown. */) (Lisp_Object font_object, Lisp_Object string) { Lisp_Object frame = selected_frame; - FRAME_PTR f = XFRAME (frame); + struct frame *f = XFRAME (frame); struct font *font; struct face *face; int i, len, width; diff --git a/src/font.h b/src/font.h index ffed0461ff7..adb4a582fd8 100644 --- a/src/font.h +++ b/src/font.h @@ -504,7 +504,7 @@ struct font_driver /* Return a cache of font-entities on frame F. The cache must be a cons whose cdr part is the actual cache area. */ - Lisp_Object (*get_cache) (FRAME_PTR F); + Lisp_Object (*get_cache) (struct frame *f); /* List fonts exactly matching with FONT_SPEC on FRAME. The value is a list of font-entities. The font properties to be considered @@ -527,7 +527,7 @@ struct font_driver This and the following `match' are the only APIs that allocate font-entities. */ - Lisp_Object (*list) (Lisp_Object frame, Lisp_Object font_spec); + Lisp_Object (*list) (struct frame *frame, Lisp_Object font_spec); /* Return a font-entity most closely matching with FONT_SPEC on FRAME. Which font property to consider, and how to calculate the @@ -536,12 +536,12 @@ struct font_driver The properties that the font-entity has is the same as `list' method. */ - Lisp_Object (*match) (Lisp_Object frame, Lisp_Object font_spec); + Lisp_Object (*match) (struct frame *f, Lisp_Object spec); /* Optional. List available families. The value is a list of family names (symbols). */ - Lisp_Object (*list_family) (Lisp_Object frame); + Lisp_Object (*list_family) (struct frame *f); /* Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value). Free FONT_EXTRA_INDEX field of FONT_ENTITY. */ @@ -549,21 +549,21 @@ struct font_driver /* Open a font specified by FONT_ENTITY on frame F. If the font is scalable, open it with PIXEL_SIZE. */ - Lisp_Object (*open) (FRAME_PTR f, Lisp_Object font_entity, + Lisp_Object (*open) (struct frame *f, Lisp_Object font_entity, int pixel_size); /* Close FONT on frame F. */ - void (*close) (FRAME_PTR f, struct font *font); + void (*close) (struct frame *f, struct font *font); /* Optional (if FACE->extra is not used). Prepare FACE for displaying characters by FONT on frame F by storing some data in FACE->extra. If successful, return 0. Otherwise, return -1. */ - int (*prepare_face) (FRAME_PTR f, struct face *face); + int (*prepare_face) (struct frame *f, struct face *face); /* Optional. Done FACE for displaying characters by FACE->font on frame F. */ - void (*done_face) (FRAME_PTR f, struct face *face); + void (*done_face) (struct frame *f, struct face *face); /* Optional. If FONT (FONT-ENTITY or FONT-OBJECT) has a glyph for character C @@ -646,12 +646,12 @@ struct font_driver Make the font driver ready for frame F. Usually this function makes some data specific to F and stores it in F by calling font_put_frame_data (). */ - int (*start_for_frame) (FRAME_PTR f); + int (*start_for_frame) (struct frame *f); /* Optional. End using the driver for frame F. Usually this function free some data stored for F. */ - int (*end_for_frame) (FRAME_PTR f); + int (*end_for_frame) (struct frame *f); /* Optional. @@ -674,7 +674,7 @@ struct font_driver If FONT is usable on frame F, return 0. Otherwise return -1. This method is used only for debugging. If this method is NULL, Emacs assumes that the font is usable on any frame. */ - int (*check) (FRAME_PTR F, struct font *font); + int (*check) (struct frame *f, struct font *font); /* Optional. @@ -698,8 +698,8 @@ struct font_driver /* Chain of font drivers. There's one global font driver list - (font_driver_list in font.c). In addition, each frame has its own - font driver list at FRAME_PTR->font_driver_list. */ + (font_driver_list in font.c). In addition, each frame has + its own font driver list at F->font_driver_list. */ struct font_driver_list { @@ -713,8 +713,8 @@ struct font_driver_list }; -/* Chain of arbitrary data specific to each font driver. Each frame - has its own font data list at FRAME_PTR->font_data_list. */ +/* Chain of arbitrary data specific to each font driver. + Each frame has its own font data list at F->font_data_list. */ struct font_data_list { @@ -742,28 +742,28 @@ extern Lisp_Object font_style_symbolic (Lisp_Object font, bool for_face); extern bool font_match_p (Lisp_Object spec, Lisp_Object font); -extern Lisp_Object font_list_entities (Lisp_Object frame, - Lisp_Object spec); +extern Lisp_Object font_list_entities (struct frame *, Lisp_Object); extern Lisp_Object font_get_name (Lisp_Object font_object); extern Lisp_Object font_spec_from_name (Lisp_Object font_name); extern Lisp_Object font_get_frame (Lisp_Object font_object); -extern int font_has_char (FRAME_PTR, Lisp_Object, int); +extern int font_has_char (struct frame *, Lisp_Object, int); extern void font_clear_prop (Lisp_Object *attrs, enum font_property_index prop); -extern Lisp_Object font_find_for_lface (FRAME_PTR f, Lisp_Object *lface, +extern Lisp_Object font_find_for_lface (struct frame *f, Lisp_Object *lface, Lisp_Object spec, int c); -extern Lisp_Object font_open_for_lface (FRAME_PTR f, Lisp_Object entity, +extern Lisp_Object font_open_for_lface (struct frame *f, Lisp_Object entity, Lisp_Object *lface, Lisp_Object spec); -extern Lisp_Object font_load_for_lface (FRAME_PTR f, Lisp_Object *lface, +extern Lisp_Object font_load_for_lface (struct frame *f, Lisp_Object *lface, Lisp_Object spec); -extern void font_prepare_for_face (FRAME_PTR f, struct face *face); -extern void font_done_for_face (FRAME_PTR f, struct face *face); +extern void font_prepare_for_face (struct frame *f, struct face *face); +extern void font_done_for_face (struct frame *f, struct face *face); +extern void clear_font_cache (struct frame *); -extern Lisp_Object font_open_by_spec (FRAME_PTR f, Lisp_Object spec); -extern Lisp_Object font_open_by_name (FRAME_PTR f, Lisp_Object name); +extern Lisp_Object font_open_by_spec (struct frame *f, Lisp_Object spec); +extern Lisp_Object font_open_by_name (struct frame *f, Lisp_Object name); extern Lisp_Object font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol); @@ -778,9 +778,9 @@ extern ptrdiff_t font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int bytes); extern int font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int bytes); -extern void register_font_driver (struct font_driver *driver, FRAME_PTR f); -extern void free_font_driver_list (FRAME_PTR f); -extern Lisp_Object font_update_drivers (FRAME_PTR f, Lisp_Object list); +extern void register_font_driver (struct font_driver *driver, struct frame *f); +extern void free_font_driver_list (struct frame *f); +extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list); extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *, struct window *, struct face *, Lisp_Object); @@ -789,10 +789,10 @@ extern void font_fill_lglyph_metrics (Lisp_Object, Lisp_Object); extern Lisp_Object font_put_extra (Lisp_Object font, Lisp_Object prop, Lisp_Object val); -extern int font_put_frame_data (FRAME_PTR f, +extern int font_put_frame_data (struct frame *f, struct font_driver *driver, void *data); -extern void *font_get_frame_data (FRAME_PTR f, +extern void *font_get_frame_data (struct frame *f, struct font_driver *driver); extern void font_filter_properties (Lisp_Object font, diff --git a/src/fontset.c b/src/fontset.c index 6a6a434add0..0bf716bf1b2 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -539,8 +539,9 @@ fontset_find_font (Lisp_Object fontset, int c, struct face *face, int id, { Lisp_Object vec, font_group; int i, charset_matched = 0, found_index; - FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)) - ? XFRAME (FONTSET_FRAME (fontset)) : XFRAME (selected_frame)); + struct frame *f = (FRAMEP (FONTSET_FRAME (fontset)) + ? XFRAME (FONTSET_FRAME (fontset)) + : XFRAME (selected_frame)); Lisp_Object rfont_def; font_group = fontset_get_font_group (fontset, fallback ? -1 : c); @@ -859,7 +860,7 @@ fontset_ascii (int id) } static void -free_realized_fontset (FRAME_PTR f, Lisp_Object fontset) +free_realized_fontset (struct frame *f, Lisp_Object fontset) { #if 0 Lisp_Object tail; @@ -877,7 +878,7 @@ free_realized_fontset (FRAME_PTR f, Lisp_Object fontset) free_realized_face. */ void -free_face_fontset (FRAME_PTR f, struct face *face) +free_face_fontset (struct frame *f, struct face *face) { Lisp_Object fontset; @@ -930,7 +931,7 @@ face_suitable_for_char_p (struct face *face, int c) the macro FACE_FOR_CHAR. */ int -face_for_char (FRAME_PTR f, struct face *face, int c, int pos, Lisp_Object object) +face_for_char (struct frame *f, struct face *face, int c, int pos, Lisp_Object object) { Lisp_Object fontset, rfont_def, charset; int face_id; @@ -1048,7 +1049,7 @@ font_for_char (struct face *face, int c, int pos, Lisp_Object object) Called from realize_x_face. */ int -make_fontset_for_ascii_face (FRAME_PTR f, int base_fontset_id, struct face *face) +make_fontset_for_ascii_face (struct frame *f, int base_fontset_id, struct face *face) { Lisp_Object base_fontset, fontset, frame; @@ -1227,7 +1228,7 @@ If REGEXPP is non-nil, PATTERN is a regular expression. */) /* Return a list of base fontset names matching PATTERN on frame F. */ Lisp_Object -list_fontsets (FRAME_PTR f, Lisp_Object pattern, int size) +list_fontsets (struct frame *f, Lisp_Object pattern, int size) { Lisp_Object frame, regexp, val; int id; @@ -1284,7 +1285,7 @@ free_realized_fontsets (Lisp_Object base) for (tail = FONTSET_FACE_ALIST (this); CONSP (tail); tail = XCDR (tail)) { - FRAME_PTR f = XFRAME (FONTSET_FRAME (this)); + struct frame *f = XFRAME (FONTSET_FRAME (this)); int face_id = XINT (XCDR (XCAR (tail))); struct face *face = FACE_FROM_ID (f, face_id); @@ -1612,7 +1613,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */) name = FONTSET_NAME (fontset); FOR_EACH_FRAME (tail, fr) { - FRAME_PTR f = XFRAME (fr); + struct frame *f = XFRAME (fr); Lisp_Object font_object; struct face *face; @@ -2140,7 +2141,7 @@ dump_fontset (Lisp_Object fontset) frame = FONTSET_FRAME (fontset); if (FRAMEP (frame)) { - FRAME_PTR f = XFRAME (frame); + struct frame *f = XFRAME (frame); if (FRAME_LIVE_P (f)) ASET (vec, 1, diff --git a/src/fontset.h b/src/fontset.h index 926520c8001..fd16c7178f5 100644 --- a/src/fontset.h +++ b/src/fontset.h @@ -28,12 +28,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ struct face; -extern void free_face_fontset (FRAME_PTR, struct face *); -extern int face_for_char (FRAME_PTR, struct face *, int, +extern void free_face_fontset (struct frame *, struct face *); +extern int face_for_char (struct frame *, struct face *, int, int, Lisp_Object); extern Lisp_Object font_for_char (struct face *, int, int, Lisp_Object); -extern int make_fontset_for_ascii_face (FRAME_PTR, int, struct face *); +extern int make_fontset_for_ascii_face (struct frame *, int, struct face *); extern int fontset_from_font (Lisp_Object); extern int fs_query_fontset (Lisp_Object, int); extern Lisp_Object list_fontsets (struct frame *, Lisp_Object, int); diff --git a/src/frame.c b/src/frame.c index 5fa54052cd2..5ee001f4d98 100644 --- a/src/frame.c +++ b/src/frame.c @@ -69,7 +69,6 @@ Lisp_Object Qnoelisp; static Lisp_Object Qx_frame_parameter; Lisp_Object Qx_resource_name; Lisp_Object Qterminal; -Lisp_Object Qterminal_live_p; /* Frame parameters (set or reported). */ @@ -186,7 +185,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n) { struct window *w = XWINDOW (window); - w->last_modified = 0; w->top_line += n; w->total_lines -= n; @@ -310,7 +308,7 @@ predicates which report frame's specific UI-related capabilities. */) } struct frame * -make_frame (int mini_p) +make_frame (bool mini_p) { Lisp_Object frame; register struct frame *f; @@ -694,24 +692,16 @@ affects all frames on the same terminal device. */) ? FRAME_TTY (XFRAME (selected_frame))->name : NULL)); if (!NILP (tty)) - { - name = alloca (SBYTES (tty) + 1); - memcpy (name, SSDATA (tty), SBYTES (tty)); - name[SBYTES (tty)] = 0; - } + name = xlispstrdupa (tty); tty_type = get_future_frame_param (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) ? FRAME_TTY (XFRAME (selected_frame))->type : NULL)); if (!NILP (tty_type)) - { - type = alloca (SBYTES (tty_type) + 1); - memcpy (type, SSDATA (tty_type), SBYTES (tty_type)); - type[SBYTES (tty_type)] = 0; - } + type = xlispstrdupa (tty_type); - t = init_tty (name, type, 0); /* Errors are not fatal. */ + t = init_tty (name, type, 0); /* Errors are not fatal. */ } f = make_terminal_frame (t); @@ -725,16 +715,13 @@ affects all frames on the same terminal device. */) adjust_glyphs (f); calculate_costs (f); XSETFRAME (frame, f); + + store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); + store_in_alist (&parms, Qtty, + (t->display_info.tty->name + ? build_string (t->display_info.tty->name) + : Qnil)); Fmodify_frame_parameters (frame, parms); - Fmodify_frame_parameters - (frame, list1 (Fcons (Qtty_type, - build_string (t->display_info.tty->type)))); - if (t->display_info.tty->name != NULL) - Fmodify_frame_parameters - (frame, list1 (Fcons (Qtty, - build_string (t->display_info.tty->name)))); - else - Fmodify_frame_parameters (frame, list1 (Fcons (Qtty, Qnil))); /* Make the frame face alist be frame-specific, so that each frame could change its face definitions independently. */ @@ -1097,7 +1084,7 @@ Otherwise, include all frames. */) (Exception: if F is the terminal frame, and we are using X, return 1.) */ static int -other_visible_frames (FRAME_PTR f) +other_visible_frames (struct frame *f) { Lisp_Object frames, this; @@ -1157,10 +1144,14 @@ delete_frame (Lisp_Object frame, Lisp_Object force) FOR_EACH_FRAME (frames, this) { - if (! EQ (this, frame) - && EQ (frame, - WINDOW_FRAME (XWINDOW - (FRAME_MINIBUF_WINDOW (XFRAME (this)))))) + Lisp_Object fminiw; + + if (EQ (this, frame)) + continue; + + fminiw = FRAME_MINIBUF_WINDOW (XFRAME (this)); + + if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw)))) { /* If we MUST delete this frame, delete the other first. But do this only if FORCE equals `noelisp'. */ @@ -1206,10 +1197,18 @@ delete_frame (Lisp_Object frame, Lisp_Object force) /* Don't let the frame remain selected. */ if (f == sf) { - Lisp_Object tail, frame1; - - /* Look for another visible frame on the same terminal. */ - frame1 = next_frame (frame, Qvisible); + Lisp_Object tail; + Lisp_Object frame1 = Qnil; + + /* Look for another visible frame on the same terminal. + Do not call next_frame here because it may loop forever. + See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */ + FOR_EACH_FRAME (tail, frame1) + if (!EQ (frame, frame1) + && (FRAME_TERMINAL (XFRAME (frame)) + == FRAME_TERMINAL (XFRAME (frame1))) + && FRAME_VISIBLE_P (XFRAME (frame1))) + break; /* If there is none, find *some* other frame. */ if (NILP (frame1) || EQ (frame1, frame)) @@ -1467,7 +1466,7 @@ passing the normal return value to that function as an argument, and returns whatever that function returns. */) (void) { - FRAME_PTR f; + struct frame *f; Lisp_Object lispy_dummy; Lisp_Object x, y, retval; struct gcpro gcpro1; @@ -1513,7 +1512,7 @@ to read the mouse position, it returns the selected frame for FRAME and nil for X and Y. */) (void) { - FRAME_PTR f; + struct frame *f; Lisp_Object lispy_dummy; Lisp_Object x, y; @@ -2249,7 +2248,9 @@ use is not recommended. Explicitly check for a frame-parameter instead. */) (Lisp_Object frame, Lisp_Object alist) { struct frame *f = decode_live_frame (frame); - register Lisp_Object tail, prop, val; + register Lisp_Object prop, val; + + CHECK_LIST (alist); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2274,12 +2275,11 @@ use is not recommended. Explicitly check for a frame-parameter instead. */) /* Extract parm names and values into those vectors. */ - i = 0; - for (tail = alist; CONSP (tail); tail = XCDR (tail)) + for (i = 0; CONSP (alist); alist = XCDR (alist)) { Lisp_Object elt; - elt = XCAR (tail); + elt = XCAR (alist); parms[i] = Fcar (elt); values[i] = Fcdr (elt); i++; @@ -2360,7 +2360,7 @@ to `frame-height'). */) #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) - return make_number (x_pixel_height (f)); + return make_number (FRAME_PIXEL_HEIGHT (f)); else #endif return make_number (FRAME_LINES (f)); @@ -2377,7 +2377,7 @@ If FRAME is omitted or nil, the selected frame is used. */) #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f)) - return make_number (x_pixel_width (f)); + return make_number (FRAME_PIXEL_WIDTH (f)); else #endif return make_number (FRAME_COLS (f)); @@ -2402,8 +2402,9 @@ is used. */) DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0, doc: /* Specify that the frame FRAME has LINES lines. -Optional third arg non-nil means that redisplay should use LINES lines -but that the idea of the actual height of the frame should not be changed. */) +If FRAME is nil, the selected frame is used. Optional third arg +non-nil means that redisplay should use LINES lines but that the +idea of the actual height of the frame should not be changed. */) (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend) { register struct frame *f = decode_live_frame (frame); @@ -2426,8 +2427,9 @@ but that the idea of the actual height of the frame should not be changed. */) DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0, doc: /* Specify that the frame FRAME has COLS columns. -Optional third arg non-nil means that redisplay should use COLS columns -but that the idea of the actual width of the frame should not be changed. */) +If FRAME is nil, the selected frame is used. Optional third arg +non-nil means that redisplay should use COLS columns but that the +idea of the actual width of the frame should not be changed. */) (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend) { register struct frame *f = decode_live_frame (frame); @@ -2449,15 +2451,14 @@ but that the idea of the actual width of the frame should not be changed. */) } DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, - doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */) + doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. +If FRAME is nil, the selected frame is used. */) (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows) { - register struct frame *f; + register struct frame *f = decode_live_frame (frame); - CHECK_LIVE_FRAME (frame); CHECK_TYPE_RANGED_INTEGER (int, cols); CHECK_TYPE_RANGED_INTEGER (int, rows); - f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2479,17 +2480,16 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, DEFUN ("set-frame-position", Fset_frame_position, Sset_frame_position, 3, 3, 0, doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET. -This is actually the position of the upper left corner of the frame. -Negative values for XOFFSET or YOFFSET are interpreted relative to -the rightmost or bottommost possible position (that stays within the screen). */) +If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are +actually the position of the upper left corner of the frame. Negative +values for XOFFSET or YOFFSET are interpreted relative to the rightmost +or bottommost possible position (that stays within the screen). */) (Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset) { - register struct frame *f; + register struct frame *f = decode_live_frame (frame); - CHECK_LIVE_FRAME (frame); CHECK_TYPE_RANGED_INTEGER (int, xoffset); CHECK_TYPE_RANGED_INTEGER (int, yoffset); - f = XFRAME (frame); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2609,7 +2609,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int to store the new value in the parameter alist. */ void -x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) +x_set_frame_parameters (struct frame *f, Lisp_Object alist) { Lisp_Object tail; @@ -2628,9 +2628,9 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) Lisp_Object *parms; Lisp_Object *values; ptrdiff_t i, p; - int left_no_change = 0, top_no_change = 0; - int icon_left_no_change = 0, icon_top_no_change = 0; - int size_changed = 0; + bool left_no_change = 0, top_no_change = 0; + bool icon_left_no_change = 0, icon_top_no_change = 0; + bool size_changed = 0; struct gcpro gcpro1, gcpro2; i = 0; @@ -2866,10 +2866,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) /* Actually set that position, and convert to absolute. */ x_set_offset (f, leftpos, toppos, -1); } - +#ifdef HAVE_X_WINDOWS if ((!NILP (icon_left) || !NILP (icon_top)) && ! (icon_left_no_change && icon_top_no_change)) x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); +#endif /* HAVE_X_WINDOWS */ } UNGCPRO; @@ -3346,7 +3347,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) /* Return non-nil if frame F wants a bitmap icon. */ Lisp_Object -x_icon_type (FRAME_PTR f) +x_icon_type (struct frame *f) { Lisp_Object tem; @@ -3543,7 +3544,7 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li value = x_get_string_resource (rdb, name_key, class_key); - if (value != (char *) 0 && *value) + if (value && *value) return build_string (value); else return Qnil; @@ -3934,8 +3935,8 @@ On Nextstep, this just calls `ns-parse-geometry'. */) #define DEFAULT_ROWS 35 #define DEFAULT_COLS 80 -int -x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p) +long +x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) { register Lisp_Object tem0, tem1, tem2; long window_prompting = 0; @@ -4202,8 +4203,7 @@ make_monitor_attribute_list (struct MonitorInfo *monitors, mi->work.width, mi->work.height); geometry = list4i (mi->geom.x, mi->geom.y, mi->geom.width, mi->geom.height); - attributes = Fcons (Fcons (Qsource, - make_string (source, strlen (source))), + attributes = Fcons (Fcons (Qsource, build_string (source)), attributes); attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), attributes); @@ -4286,7 +4286,6 @@ syms_of_frame (void) DEFSYM (Qx_frame_parameter, "x-frame-parameter"); DEFSYM (Qterminal, "terminal"); - DEFSYM (Qterminal_live_p, "terminal-live-p"); DEFSYM (Qgeometry, "geometry"); DEFSYM (Qworkarea, "workarea"); diff --git a/src/frame.h b/src/frame.h index 31d3e73c3c3..e44003b15ca 100644 --- a/src/frame.h +++ b/src/frame.h @@ -410,6 +410,10 @@ struct frame /* Nonzero means that the pointer is invisible. */ unsigned pointer_invisible :1; + /* Nonzero means that all windows except mini-window and + selected window on this frame have frozen window starts. */ + unsigned frozen_window_starts : 1; + /* Nonzero if we should actually display the scroll bars on this frame. */ enum vertical_scroll_bar_type vertical_scroll_bar_type; @@ -591,8 +595,6 @@ default_pixels_per_inch_y (void) /* Return a pointer to the image cache of frame F. */ #define FRAME_IMAGE_CACHE(F) ((F)->terminal->image_cache) -typedef struct frame *FRAME_PTR; - #define XFRAME(p) \ (eassert (FRAMEP (p)), (struct frame *) XUNTAG (p, Lisp_Vectorlike)) #define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME)) @@ -763,6 +765,10 @@ typedef struct frame *FRAME_PTR; /* Not really implemented. */ #define FRAME_WANTS_MODELINE_P(f) (f)->wants_modeline +/* Nonzero if all windows except selected window and mini window + are frozen on frame F. */ +#define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts + /* Nonzero if a size change has been requested for frame F but not yet really put into effect. This can be true temporarily when an X event comes in at a bad time. */ @@ -929,10 +935,9 @@ typedef struct frame *FRAME_PTR; if (frame == hlinfo->mouse_face_mouse_frame) \ { \ block_input (); \ - if (hlinfo->mouse_face_mouse_frame) \ - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \ - hlinfo->mouse_face_mouse_x, \ - hlinfo->mouse_face_mouse_y); \ + note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \ + hlinfo->mouse_face_mouse_x, \ + hlinfo->mouse_face_mouse_y); \ unblock_input (); \ } \ } while (0) @@ -952,7 +957,7 @@ typedef struct frame *FRAME_PTR; extern Lisp_Object Qframep, Qframe_live_p; extern Lisp_Object Qtty, Qtty_type; extern Lisp_Object Qtty_color_mode; -extern Lisp_Object Qterminal, Qterminal_live_p; +extern Lisp_Object Qterminal; extern Lisp_Object Qnoelisp; extern struct frame *last_nonminibuf_frame; @@ -962,7 +967,7 @@ extern struct frame *decode_window_system_frame (Lisp_Object); extern struct frame *decode_live_frame (Lisp_Object); extern struct frame *decode_any_frame (Lisp_Object); extern struct frame *make_initial_frame (void); -extern struct frame *make_frame (int); +extern struct frame *make_frame (bool); #ifdef HAVE_WINDOW_SYSTEM extern struct frame *make_minibuffer_frame (void); extern struct frame *make_frame_without_minibuffer (Lisp_Object, @@ -1207,8 +1212,7 @@ extern Lisp_Object Qrun_hook_with_args; extern void x_set_scroll_bar_default_width (struct frame *); extern void x_set_offset (struct frame *, int, int, int); -extern void x_wm_set_icon_position (struct frame *, int, int); -extern void x_wm_set_size_hint (FRAME_PTR f, long flags, bool user_position); +extern void x_wm_set_size_hint (struct frame *f, long flags, bool user_position); extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int); @@ -1242,7 +1246,7 @@ extern void x_set_scroll_bar_width (struct frame *, Lisp_Object, extern Lisp_Object x_icon_type (struct frame *); -extern int x_figure_window_size (struct frame *, Lisp_Object, int); +extern long x_figure_window_size (struct frame *, Lisp_Object, bool); extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object); @@ -1264,8 +1268,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); extern void x_make_frame_visible (struct frame *f); extern void x_make_frame_invisible (struct frame *f); extern void x_iconify_frame (struct frame *f); -extern int x_pixel_width (struct frame *f); -extern int x_pixel_height (struct frame *f); extern void x_set_frame_alpha (struct frame *f); extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); extern void x_set_tool_bar_lines (struct frame *f, @@ -1280,9 +1282,12 @@ extern void x_set_menu_bar_lines (struct frame *, extern void free_frame_menubar (struct frame *); extern void x_free_frame_resources (struct frame *); -#if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT +#if defined HAVE_X_WINDOWS +extern void x_wm_set_icon_position (struct frame *, int, int); +#if !defined USE_X_TOOLKIT extern char *x_get_resource_string (const char *, const char *); #endif +#endif extern void x_query_colors (struct frame *f, XColor *, int); extern void x_query_color (struct frame *f, XColor *); diff --git a/src/fringe.c b/src/fringe.c index f728cd6d5ff..492eddae8d4 100644 --- a/src/fringe.c +++ b/src/fringe.c @@ -666,7 +666,7 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o and OTOH leaving out that one pixel leaves behind traces of the cursor, if it was in column zero before drawing non-empty margin area. */ - && NILP (w->left_margin_cols)) + && w->left_margin_cols == 0) ? 1 : 0); p.bx = x - wd; p.nx = wd; @@ -890,31 +890,32 @@ draw_row_fringe_bitmaps (struct window *w, struct glyph_row *row) /* Draw the fringes of window W. Only fringes for rows marked for update in redraw_fringe_bitmaps_p are drawn. - Return >0 if left or right fringe was redrawn in any way. + Return nonzero if left or right fringe was redrawn in any way. - If NO_FRINGE is non-zero, also return >0 if either fringe has zero width. + If NO_FRINGE_P is non-zero, also return nonzero if either fringe + has zero width. - A return value >0 indicates that the vertical line between windows - needs update (as it may be drawn in the fringe). + A return nonzero value indicates that the vertical line between + windows needs update (as it may be drawn in the fringe). */ -int -draw_window_fringes (struct window *w, int no_fringe) +bool +draw_window_fringes (struct window *w, bool no_fringe_p) { struct glyph_row *row; int yb = window_text_bottom_y (w); int nrows = w->current_matrix->nrows; int y, rn; - int updated = 0; + bool updated_p = 0; if (w->pseudo_window_p) - return 0; + return updated_p; /* Must draw line if no fringe */ - if (no_fringe + if (no_fringe_p && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)) - updated++; + updated_p = 1; for (y = w->vscroll, rn = 0, row = w->current_matrix->rows; y < yb && rn < nrows; @@ -924,10 +925,10 @@ draw_window_fringes (struct window *w, int no_fringe) continue; draw_row_fringe_bitmaps (w, row); row->redraw_fringe_bitmaps_p = 0; - updated++; + updated_p = 1; } - return updated; + return updated_p; } @@ -936,14 +937,14 @@ draw_window_fringes (struct window *w, int no_fringe) If KEEP_CURRENT_P is 0, update current_matrix too. */ -int -update_window_fringes (struct window *w, int keep_current_p) +bool +update_window_fringes (struct window *w, bool keep_current_p) { struct glyph_row *row, *cur = 0; int yb = window_text_bottom_y (w); int rn, nrows = w->current_matrix->nrows; int y; - int redraw_p = 0; + bool redraw_p = 0; Lisp_Object boundary_top = Qnil, boundary_bot = Qnil; Lisp_Object arrow_top = Qnil, arrow_bot = Qnil; Lisp_Object empty_pos; @@ -1169,7 +1170,7 @@ update_window_fringes (struct window *w, int keep_current_p) int left, right; unsigned left_face_id, right_face_id; int left_offset, right_offset; - int periodic_p; + bool periodic_p; row = w->desired_matrix->rows + rn; cur = w->current_matrix->rows + rn; @@ -1285,7 +1286,7 @@ update_window_fringes (struct window *w, int keep_current_p) || periodic_p != cur->fringe_bitmap_periodic_p || cur->redraw_fringe_bitmaps_p) { - redraw_p = row->redraw_fringe_bitmaps_p = 1; + redraw_p = 1, row->redraw_fringe_bitmaps_p = 1; if (!keep_current_p) { cur->redraw_fringe_bitmaps_p = 1; @@ -1304,7 +1305,7 @@ update_window_fringes (struct window *w, int keep_current_p) if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap) { - redraw_p = row->redraw_fringe_bitmaps_p = 1; + redraw_p = 1, row->redraw_fringe_bitmaps_p = 1; if (!keep_current_p) { cur->redraw_fringe_bitmaps_p = 1; @@ -1339,7 +1340,7 @@ update_window_fringes (struct window *w, int keep_current_p) */ void -compute_fringe_widths (struct frame *f, int redraw) +compute_fringe_widths (struct frame *f, bool redraw_p) { int o_left = FRAME_LEFT_FRINGE_WIDTH (f); int o_right = FRAME_RIGHT_FRINGE_WIDTH (f); @@ -1410,7 +1411,7 @@ compute_fringe_widths (struct frame *f, int redraw) FRAME_FRINGE_COLS (f) = 0; } - if (redraw && FRAME_VISIBLE_P (f)) + if (redraw_p && FRAME_VISIBLE_P (f)) if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) || o_right != FRAME_RIGHT_FRINGE_WIDTH (f) || o_cols != FRAME_FRINGE_COLS (f)) diff --git a/src/ftfont.c b/src/ftfont.c index 10090cb3bda..3636f86f5c4 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -493,12 +493,12 @@ ftfont_get_otf (struct ftfont_info *ftfont_info) } #endif /* HAVE_LIBOTF */ -static Lisp_Object ftfont_get_cache (FRAME_PTR); -static Lisp_Object ftfont_list (Lisp_Object, Lisp_Object); -static Lisp_Object ftfont_match (Lisp_Object, Lisp_Object); -static Lisp_Object ftfont_list_family (Lisp_Object); -static Lisp_Object ftfont_open (FRAME_PTR, Lisp_Object, int); -static void ftfont_close (FRAME_PTR, struct font *); +static Lisp_Object ftfont_get_cache (struct frame *); +static Lisp_Object ftfont_list (struct frame *, Lisp_Object); +static Lisp_Object ftfont_match (struct frame *, Lisp_Object); +static Lisp_Object ftfont_list_family (struct frame *); +static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); +static void ftfont_close (struct frame *, struct font *); static int ftfont_has_char (Lisp_Object, int); static unsigned ftfont_encode_char (struct font *, int); static int ftfont_text_extents (struct font *, unsigned *, int, @@ -568,7 +568,7 @@ struct font_driver ftfont_driver = }; static Lisp_Object -ftfont_get_cache (FRAME_PTR f) +ftfont_get_cache (struct frame *f) { return freetype_font_cache; } @@ -884,7 +884,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots } static Lisp_Object -ftfont_list (Lisp_Object frame, Lisp_Object spec) +ftfont_list (struct frame *f, Lisp_Object spec) { Lisp_Object val = Qnil, family, adstyle; int i; @@ -1080,7 +1080,7 @@ ftfont_list (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -ftfont_match (Lisp_Object frame, Lisp_Object spec) +ftfont_match (struct frame *f, Lisp_Object spec) { Lisp_Object entity = Qnil; FcPattern *pattern, *match = NULL; @@ -1130,7 +1130,7 @@ ftfont_match (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -ftfont_list_family (Lisp_Object frame) +ftfont_list_family (struct frame *f) { Lisp_Object list = Qnil; FcPattern *pattern = NULL; @@ -1173,7 +1173,7 @@ ftfont_list_family (Lisp_Object frame) static Lisp_Object -ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) +ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { struct ftfont_info *ftfont_info; struct font *font; @@ -1317,7 +1317,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) } static void -ftfont_close (FRAME_PTR f, struct font *font) +ftfont_close (struct frame *f, struct font *font) { struct ftfont_info *ftfont_info = (struct ftfont_info *) font; Lisp_Object val, cache; diff --git a/src/ftxfont.c b/src/ftxfont.c index 8c56ee05adc..63d03b0e244 100644 --- a/src/ftxfont.c +++ b/src/ftxfont.c @@ -57,7 +57,7 @@ struct ftxfont_frame_data /* Return an array of 6 GCs for antialiasing. */ static GC * -ftxfont_get_gcs (FRAME_PTR f, long unsigned int foreground, long unsigned int background) +ftxfont_get_gcs (struct frame *f, long unsigned int foreground, long unsigned int background) { XColor color; XGCValues xgcv; @@ -134,7 +134,7 @@ ftxfont_get_gcs (FRAME_PTR f, long unsigned int foreground, long unsigned int ba } static int -ftxfont_draw_bitmap (FRAME_PTR f, GC gc_fore, GC *gcs, struct font *font, +ftxfont_draw_bitmap (struct frame *f, GC gc_fore, GC *gcs, struct font *font, unsigned int code, int x, int y, XPoint *p, int size, int *n, bool flush) { @@ -212,7 +212,7 @@ ftxfont_draw_bitmap (FRAME_PTR f, GC gc_fore, GC *gcs, struct font *font, } static void -ftxfont_draw_background (FRAME_PTR f, struct font *font, GC gc, int x, int y, +ftxfont_draw_background (struct frame *f, struct font *font, GC gc, int x, int y, int width) { XGCValues xgcv; @@ -226,9 +226,9 @@ ftxfont_draw_background (FRAME_PTR f, struct font *font, GC gc, int x, int y, } static Lisp_Object -ftxfont_list (Lisp_Object frame, Lisp_Object spec) +ftxfont_list (struct frame *f, Lisp_Object spec) { - Lisp_Object list = ftfont_driver.list (frame, spec), tail; + Lisp_Object list = ftfont_driver.list (f, spec), tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx); @@ -236,9 +236,9 @@ ftxfont_list (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -ftxfont_match (Lisp_Object frame, Lisp_Object spec) +ftxfont_match (struct frame *f, Lisp_Object spec) { - Lisp_Object entity = ftfont_driver.match (frame, spec); + Lisp_Object entity = ftfont_driver.match (f, spec); if (VECTORP (entity)) ASET (entity, FONT_TYPE_INDEX, Qftx); @@ -246,7 +246,7 @@ ftxfont_match (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -ftxfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) +ftxfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { Lisp_Object font_object; struct font *font; @@ -260,7 +260,7 @@ ftxfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) } static void -ftxfont_close (FRAME_PTR f, struct font *font) +ftxfont_close (struct frame *f, struct font *font) { ftfont_driver.close (f, font); } @@ -269,7 +269,7 @@ static int ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y, bool with_background) { - FRAME_PTR f = s->f; + struct frame *f = s->f; struct face *face = s->face; struct font *font = s->font; XPoint p[0x700]; @@ -338,7 +338,7 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y, } static int -ftxfont_end_for_frame (FRAME_PTR f) +ftxfont_end_for_frame (struct frame *f) { struct ftxfont_frame_data *data = font_get_frame_data (f, &ftxfont_driver); diff --git a/src/gtkutil.c b/src/gtkutil.c index f8ddf6a90f6..7e304d417d8 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -136,7 +136,7 @@ static GdkDisplay *gdpy_def; W can be a GtkMenu or a GtkWindow widget. */ static void -xg_set_screen (GtkWidget *w, FRAME_PTR f) +xg_set_screen (GtkWidget *w, struct frame *f) { if (FRAME_X_DISPLAY (f) != DEFAULT_GDK_DISPLAY ()) { @@ -280,7 +280,7 @@ xg_create_default_cursor (Display *dpy) } static GdkPixbuf * -xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix) +xg_get_pixbuf_from_pixmap (struct frame *f, Pixmap pix) { int iunused; GdkPixbuf *tmp_buf; @@ -311,7 +311,7 @@ xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix) /* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */ static GdkPixbuf * -xg_get_pixbuf_from_pix_and_mask (FRAME_PTR f, +xg_get_pixbuf_from_pix_and_mask (struct frame *f, Pixmap pix, Pixmap mask) { @@ -387,7 +387,7 @@ file_for_image (Lisp_Object image) If OLD_WIDGET is not NULL, that widget is modified. */ static GtkWidget * -xg_get_image_for_pixmap (FRAME_PTR f, +xg_get_image_for_pixmap (struct frame *f, struct image *img, GtkWidget *widget, GtkImage *old_widget) @@ -641,7 +641,7 @@ hierarchy_ch_cb (GtkWidget *widget, GtkWidget *previous_toplevel, gpointer user_data) { - FRAME_PTR f = (FRAME_PTR) user_data; + struct frame *f = user_data; struct x_output *x = f->output_data.x; GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl); @@ -663,7 +663,7 @@ qttip_cb (GtkWidget *widget, GtkTooltip *tooltip, gpointer user_data) { - FRAME_PTR f = (FRAME_PTR) user_data; + struct frame *f = user_data; struct x_output *x = f->output_data.x; if (x->ttip_widget == NULL) { @@ -707,7 +707,7 @@ qttip_cb (GtkWidget *widget, Return true if a system tooltip is available. */ bool -xg_prepare_tooltip (FRAME_PTR f, +xg_prepare_tooltip (struct frame *f, Lisp_Object string, int *width, int *height) @@ -764,7 +764,7 @@ xg_prepare_tooltip (FRAME_PTR f, xg_prepare_tooltip must have been called before this function. */ void -xg_show_tooltip (FRAME_PTR f, int root_x, int root_y) +xg_show_tooltip (struct frame *f, int root_x, int root_y) { #ifdef USE_GTK_TOOLTIP struct x_output *x = f->output_data.x; @@ -783,7 +783,7 @@ xg_show_tooltip (FRAME_PTR f, int root_x, int root_y) system tooltips). */ bool -xg_hide_tooltip (FRAME_PTR f) +xg_hide_tooltip (struct frame *f) { bool ret = 0; #ifdef USE_GTK_TOOLTIP @@ -827,7 +827,7 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, F is the frame we shall set geometry for. */ static void -xg_set_geometry (FRAME_PTR f) +xg_set_geometry (struct frame *f) { if (f->size_hint_flags & (USPosition | PPosition)) { @@ -865,7 +865,7 @@ xg_set_geometry (FRAME_PTR f) and use a GtkFixed widget, this doesn't happen automatically. */ static void -xg_clear_under_internal_border (FRAME_PTR f) +xg_clear_under_internal_border (struct frame *f) { if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) { @@ -903,7 +903,7 @@ xg_clear_under_internal_border (FRAME_PTR f) PIXELWIDTH, PIXELHEIGHT is the new size in pixels. */ void -xg_frame_resized (FRAME_PTR f, int pixelwidth, int pixelheight) +xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight) { int rows, columns; @@ -939,7 +939,7 @@ xg_frame_resized (FRAME_PTR f, int pixelwidth, int pixelheight) COLUMNS/ROWS is the size the edit area shall have after the resize. */ void -xg_frame_set_char_size (FRAME_PTR f, int cols, int rows) +xg_frame_set_char_size (struct frame *f, int cols, int rows) { int pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); @@ -1002,7 +1002,7 @@ xg_frame_set_char_size (FRAME_PTR f, int cols, int rows) The policy is to keep the number of editable lines. */ static void -xg_height_or_width_changed (FRAME_PTR f) +xg_height_or_width_changed (struct frame *f) { gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), FRAME_TOTAL_PIXEL_WIDTH (f), @@ -1042,7 +1042,7 @@ xg_win_to_widget (Display *dpy, Window wdesc) /* Set the background of widget W to PIXEL. */ static void -xg_set_widget_bg (FRAME_PTR f, GtkWidget *w, long unsigned int pixel) +xg_set_widget_bg (struct frame *f, GtkWidget *w, long unsigned int pixel) { #ifdef HAVE_GTK3 GdkRGBA bg; @@ -1073,7 +1073,7 @@ style_changed_cb (GObject *go, gpointer user_data) { struct input_event event; - GdkDisplay *gdpy = (GdkDisplay *) user_data; + GdkDisplay *gdpy = user_data; const char *display_name = gdk_display_get_name (gdpy); Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy); @@ -1093,7 +1093,7 @@ style_changed_cb (GObject *go, Lisp_Object rest, frame; FOR_EACH_FRAME (rest, frame) { - FRAME_PTR f = XFRAME (frame); + struct frame *f = XFRAME (frame); if (FRAME_LIVE_P (f) && FRAME_X_P (f) && FRAME_X_DISPLAY (f) == dpy) @@ -1115,7 +1115,7 @@ delete_cb (GtkWidget *widget, #ifdef HAVE_GTK3 /* The event doesn't arrive in the normal event loop. Send event here. */ - FRAME_PTR f = (FRAME_PTR) user_data; + struct frame *f = user_data; struct input_event ie; EVENT_INIT (ie); @@ -1131,7 +1131,7 @@ delete_cb (GtkWidget *widget, Return true if creation succeeded. */ bool -xg_create_frame_widgets (FRAME_PTR f) +xg_create_frame_widgets (struct frame *f) { GtkWidget *wtop; GtkWidget *wvbox, *whbox; @@ -1300,7 +1300,7 @@ xg_create_frame_widgets (FRAME_PTR f) } void -xg_free_frame_widgets (FRAME_PTR f) +xg_free_frame_widgets (struct frame *f) { if (FRAME_GTK_OUTER_WIDGET (f)) { @@ -1332,7 +1332,7 @@ xg_free_frame_widgets (FRAME_PTR f) flag (this is useful when FLAGS is 0). */ void -x_wm_set_size_hint (FRAME_PTR f, long int flags, bool user_position) +x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) { /* Must use GTK routines here, otherwise GTK resets the size hints to its own defaults. */ @@ -1432,7 +1432,7 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, bool user_position) BG is the pixel value to change to. */ void -xg_set_background_color (FRAME_PTR f, long unsigned int bg) +xg_set_background_color (struct frame *f, long unsigned int bg) { if (FRAME_GTK_WIDGET (f)) { @@ -1447,7 +1447,7 @@ xg_set_background_color (FRAME_PTR f, long unsigned int bg) functions so GTK does not overwrite the icon. */ void -xg_set_frame_icon (FRAME_PTR f, Pixmap icon_pixmap, Pixmap icon_mask) +xg_set_frame_icon (struct frame *f, Pixmap icon_pixmap, Pixmap icon_mask) { GdkPixbuf *gp = xg_get_pixbuf_from_pix_and_mask (f, icon_pixmap, @@ -1642,7 +1642,7 @@ xg_dialog_response_cb (GtkDialog *w, gint response, gpointer user_data) { - struct xg_dialog_data *dd = (struct xg_dialog_data *)user_data; + struct xg_dialog_data *dd = user_data; dd->response = response; g_main_loop_quit (dd->loop); } @@ -1671,7 +1671,7 @@ pop_down_dialog (void *arg) static gboolean xg_maybe_add_timer (gpointer data) { - struct xg_dialog_data *dd = (struct xg_dialog_data *) data; + struct xg_dialog_data *dd = data; EMACS_TIME next_time = timer_check (); dd->timerid = 0; @@ -1693,7 +1693,7 @@ xg_maybe_add_timer (gpointer data) The dialog W is not destroyed when this function returns. */ static int -xg_dialog_run (FRAME_PTR f, GtkWidget *w) +xg_dialog_run (struct frame *f, GtkWidget *w) { ptrdiff_t count = SPECPDL_INDEX (); struct xg_dialog_data dd; @@ -1813,7 +1813,7 @@ xg_toggle_notify_cb (GObject *gobject, GParamSpec *arg1, gpointer user_data) Returns the created widget. */ static GtkWidget * -xg_get_file_with_chooser (FRAME_PTR f, +xg_get_file_with_chooser (struct frame *f, char *prompt, char *default_filename, bool mustmatch_p, bool only_dir_p, @@ -1921,7 +1921,7 @@ static char * xg_get_file_name_from_selector (GtkWidget *w) { GtkFileSelection *filesel = GTK_FILE_SELECTION (w); - return xstrdup ((char*) gtk_file_selection_get_filename (filesel)); + return xstrdup (gtk_file_selection_get_filename (filesel)); } /* Create a file selection dialog. @@ -1935,7 +1935,7 @@ xg_get_file_name_from_selector (GtkWidget *w) Returns the created widget. */ static GtkWidget * -xg_get_file_with_selection (FRAME_PTR f, +xg_get_file_with_selection (struct frame *f, char *prompt, char *default_filename, bool mustmatch_p, bool only_dir_p, @@ -1977,7 +1977,7 @@ xg_get_file_with_selection (FRAME_PTR f, The returned string must be freed by the caller. */ char * -xg_get_file_name (FRAME_PTR f, +xg_get_file_name (struct frame *f, char *prompt, char *default_filename, bool mustmatch_p, @@ -2051,7 +2051,7 @@ extern Lisp_Object Qxft; DEFAULT_NAME, if non-zero, is the default font name. */ Lisp_Object -xg_get_font (FRAME_PTR f, const char *default_name) +xg_get_font (struct frame *f, const char *default_name) { GtkWidget *w; int done = 0; @@ -2169,7 +2169,7 @@ static xg_list_node xg_menu_item_cb_list; allocated xg_menu_cb_data if CL_DATA is NULL. */ static xg_menu_cb_data * -make_cl_data (xg_menu_cb_data *cl_data, FRAME_PTR f, GCallback highlight_cb) +make_cl_data (xg_menu_cb_data *cl_data, struct frame *f, GCallback highlight_cb) { if (! cl_data) { @@ -2201,7 +2201,7 @@ make_cl_data (xg_menu_cb_data *cl_data, FRAME_PTR f, GCallback highlight_cb) static void update_cl_data (xg_menu_cb_data *cl_data, - FRAME_PTR f, + struct frame *f, GCallback highlight_cb) { if (cl_data) @@ -2251,7 +2251,7 @@ xg_mark_data (void) FOR_EACH_FRAME (rest, frame) { - FRAME_PTR f = XFRAME (frame); + struct frame *f = XFRAME (frame); if (FRAME_X_P (f) && FRAME_GTK_OUTER_WIDGET (f)) { @@ -2277,7 +2277,7 @@ menuitem_destroy_callback (GtkWidget *w, gpointer client_data) { if (client_data) { - xg_menu_item_cb_data *data = (xg_menu_item_cb_data*) client_data; + xg_menu_item_cb_data *data = client_data; xg_list_remove (&xg_menu_item_cb_list, &data->ptrs); xfree (data); } @@ -2301,8 +2301,7 @@ menuitem_highlight_callback (GtkWidget *w, ev.crossing = *event; subwidget = gtk_get_event_widget (&ev); - data = (xg_menu_item_cb_data *) g_object_get_data (G_OBJECT (subwidget), - XG_ITEM_DATA); + data = g_object_get_data (G_OBJECT (subwidget), XG_ITEM_DATA); if (data) { if (! NILP (data->help) && data->cl_data->highlight_cb) @@ -2323,7 +2322,7 @@ menuitem_highlight_callback (GtkWidget *w, static void menu_destroy_callback (GtkWidget *w, gpointer client_data) { - unref_cl_data ((xg_menu_cb_data*) client_data); + unref_cl_data (client_data); } /* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both @@ -2480,7 +2479,7 @@ xg_have_tear_offs (void) static GtkWidget * xg_create_one_menuitem (widget_value *item, - FRAME_PTR f, + struct frame *f, GCallback select_cb, GCallback highlight_cb, xg_menu_cb_data *cl_data, @@ -2551,7 +2550,7 @@ xg_create_one_menuitem (widget_value *item, static GtkWidget * create_menus (widget_value *data, - FRAME_PTR f, + struct frame *f, GCallback select_cb, GCallback deactivate_cb, GCallback highlight_cb, @@ -2694,9 +2693,9 @@ create_menus (widget_value *data, Returns the widget created. */ GtkWidget * -xg_create_widget (const char *type, const char *name, FRAME_PTR f, widget_value *val, - GCallback select_cb, GCallback deactivate_cb, - GCallback highlight_cb) +xg_create_widget (const char *type, const char *name, struct frame *f, + widget_value *val, GCallback select_cb, + GCallback deactivate_cb, GCallback highlight_cb) { GtkWidget *w = 0; bool menu_bar_p = strcmp (type, "menubar") == 0; @@ -2802,7 +2801,7 @@ xg_destroy_widgets (GList *list) static void xg_update_menubar (GtkWidget *menubar, - FRAME_PTR f, + struct frame *f, GList **list, GList *iter, int pos, @@ -3064,8 +3063,7 @@ xg_update_menu_item (widget_value *val, else if (val->enabled && ! gtk_widget_get_sensitive (w)) gtk_widget_set_sensitive (w, TRUE); - cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (w), - XG_ITEM_DATA); + cb_data = g_object_get_data (G_OBJECT (w), XG_ITEM_DATA); if (cb_data) { cb_data->call_data = val->call_data; @@ -3119,7 +3117,7 @@ xg_update_radio_item (widget_value *val, GtkWidget *w) static GtkWidget * xg_update_submenu (GtkWidget *submenu, - FRAME_PTR f, + struct frame *f, widget_value *val, GCallback select_cb, GCallback deactivate_cb, @@ -3261,8 +3259,8 @@ xg_update_submenu (GtkWidget *submenu, HIGHLIGHT_CB is the callback to call when entering/leaving menu items. */ void -xg_modify_menubar_widgets (GtkWidget *menubar, FRAME_PTR f, widget_value *val, - bool deep_p, +xg_modify_menubar_widgets (GtkWidget *menubar, struct frame *f, + widget_value *val, bool deep_p, GCallback select_cb, GCallback deactivate_cb, GCallback highlight_cb) { @@ -3271,8 +3269,7 @@ xg_modify_menubar_widgets (GtkWidget *menubar, FRAME_PTR f, widget_value *val, if (! list) return; - cl_data = (xg_menu_cb_data*) g_object_get_data (G_OBJECT (menubar), - XG_FRAME_DATA); + cl_data = g_object_get_data (G_OBJECT (menubar), XG_FRAME_DATA); xg_update_menubar (menubar, f, &list, list, 0, val->contents, select_cb, deactivate_cb, highlight_cb, cl_data); @@ -3336,7 +3333,7 @@ static void menubar_map_cb (GtkWidget *w, gpointer user_data) { GtkRequisition req; - FRAME_PTR f = (FRAME_PTR) user_data; + struct frame *f = user_data; gtk_widget_get_preferred_size (w, NULL, &req); if (FRAME_MENUBAR_HEIGHT (f) != req.height) { @@ -3349,7 +3346,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data) changed. */ void -xg_update_frame_menubar (FRAME_PTR f) +xg_update_frame_menubar (struct frame *f) { struct x_output *x = f->output_data.x; GtkRequisition req; @@ -3387,7 +3384,7 @@ xg_update_frame_menubar (FRAME_PTR f) This is used when deleting a frame, and when turning off the menu bar. */ void -free_frame_menubar (FRAME_PTR f) +free_frame_menubar (struct frame *f) { struct x_output *x = f->output_data.x; @@ -3406,7 +3403,7 @@ free_frame_menubar (FRAME_PTR f) } bool -xg_event_is_for_menubar (FRAME_PTR f, XEvent *event) +xg_event_is_for_menubar (struct frame *f, XEvent *event) { struct x_output *x = f->output_data.x; GList *iter; @@ -3619,7 +3616,7 @@ xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data) to set resources for the widget. */ void -xg_create_scroll_bar (FRAME_PTR f, +xg_create_scroll_bar (struct frame *f, struct scroll_bar *bar, GCallback scroll_callback, GCallback end_callback, @@ -3681,7 +3678,7 @@ xg_create_scroll_bar (FRAME_PTR f, /* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */ void -xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id) +xg_remove_scroll_bar (struct frame *f, ptrdiff_t scrollbar_id) { GtkWidget *w = xg_get_widget_from_map (scrollbar_id); if (w) @@ -3699,7 +3696,7 @@ xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id) WIDTH, HEIGHT is the size in pixels the bar shall have. */ void -xg_update_scrollbar_pos (FRAME_PTR f, +xg_update_scrollbar_pos (struct frame *f, ptrdiff_t scrollbar_id, int top, int left, @@ -3781,7 +3778,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, { GtkWidget *wscroll = xg_get_widget_from_map (bar->x_window); - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); if (wscroll && NILP (bar->dragging)) { @@ -3861,7 +3858,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, frame. This function does additional checks. */ bool -xg_event_is_for_scrollbar (FRAME_PTR f, XEvent *event) +xg_event_is_for_scrollbar (struct frame *f, XEvent *event) { bool retval = 0; @@ -3946,7 +3943,7 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data) gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); intptr_t mod = (intptr_t) gmod; - FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); + struct frame *f = g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object key, frame; struct input_event event; EVENT_INIT (event); @@ -4019,8 +4016,8 @@ static GtkWidget * xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage) { GList *clist = gtk_container_get_children (GTK_CONTAINER (vb)); - GtkWidget *c1 = (GtkWidget *) clist->data; - GtkWidget *c2 = clist->next ? (GtkWidget *) clist->next->data : NULL; + GtkWidget *c1 = clist->data; + GtkWidget *c2 = clist->next ? clist->next->data : NULL; *wimage = GTK_IS_IMAGE (c1) ? c1 : c2; g_list_free (clist); @@ -4149,7 +4146,7 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox, GtkWidget *w, gpointer client_data) { - FRAME_PTR f = (FRAME_PTR) client_data; + struct frame *f = client_data; g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar, NULL); @@ -4186,7 +4183,7 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox, GtkWidget *w, gpointer client_data) { - FRAME_PTR f = (FRAME_PTR) client_data; + struct frame *f = client_data; g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL); if (f) @@ -4224,7 +4221,7 @@ xg_tool_bar_help_callback (GtkWidget *w, gpointer client_data) { intptr_t idx = (intptr_t) client_data; - FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); + struct frame *f = g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object help, frame; if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items)) @@ -4297,7 +4294,7 @@ xg_tool_bar_item_expose_callback (GtkWidget *w, /* Attach a tool bar to frame F. */ static void -xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos) +xg_pack_tool_bar (struct frame *f, Lisp_Object pos) { struct x_output *x = f->output_data.x; bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright); @@ -4354,7 +4351,7 @@ xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos) x->toolbar_is_packed = true; } -static bool xg_update_tool_bar_sizes (FRAME_PTR f); +static bool xg_update_tool_bar_sizes (struct frame *f); static void tb_size_cb (GtkWidget *widget, @@ -4364,7 +4361,7 @@ tb_size_cb (GtkWidget *widget, /* When tool bar is created it has one preferred size. But when size is allocated between widgets, it may get another. So we must update size hints if tool bar size changes. Seen on Fedora 18 at least. */ - FRAME_PTR f = (FRAME_PTR) user_data; + struct frame *f = user_data; if (xg_update_tool_bar_sizes (f)) x_wm_set_size_hint (f, 0, 0); } @@ -4372,7 +4369,7 @@ tb_size_cb (GtkWidget *widget, /* Create a tool bar for frame F. */ static void -xg_create_tool_bar (FRAME_PTR f) +xg_create_tool_bar (struct frame *f) { struct x_output *x = f->output_data.x; #if GTK_CHECK_VERSION (3, 3, 6) @@ -4415,7 +4412,7 @@ xg_create_tool_bar (FRAME_PTR f) Returns IMAGE if RTL is not found. */ static Lisp_Object -find_rtl_image (FRAME_PTR f, Lisp_Object image, Lisp_Object rtl) +find_rtl_image (struct frame *f, Lisp_Object image, Lisp_Object rtl) { int i; Lisp_Object file, rtl_name; @@ -4443,7 +4440,7 @@ find_rtl_image (FRAME_PTR f, Lisp_Object image, Lisp_Object rtl) } static GtkToolItem * -xg_make_tool_item (FRAME_PTR f, +xg_make_tool_item (struct frame *f, GtkWidget *wimage, GtkWidget **wbutton, const char *label, @@ -4606,7 +4603,7 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name, } static bool -xg_update_tool_bar_sizes (FRAME_PTR f) +xg_update_tool_bar_sizes (struct frame *f) { struct x_output *x = f->output_data.x; GtkRequisition req; @@ -4654,7 +4651,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f) /* Update the tool bar for frame F. Add new buttons and remove old. */ void -update_frame_tool_bar (FRAME_PTR f) +update_frame_tool_bar (struct frame *f) { int i, j; struct x_output *x = f->output_data.x; @@ -4929,7 +4926,7 @@ update_frame_tool_bar (FRAME_PTR f) Remove the tool bar. */ void -free_frame_tool_bar (FRAME_PTR f) +free_frame_tool_bar (struct frame *f) { struct x_output *x = f->output_data.x; @@ -4976,7 +4973,7 @@ free_frame_tool_bar (FRAME_PTR f) } void -xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos) +xg_change_toolbar_position (struct frame *f, Lisp_Object pos) { struct x_output *x = f->output_data.x; GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); diff --git a/src/gtkutil.h b/src/gtkutil.h index 288b3e99299..482331a8934 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -55,7 +55,7 @@ typedef struct xg_menu_cb_data_ { xg_list_node ptrs; - FRAME_PTR f; + struct frame *f; Lisp_Object menu_bar_vector; int menu_bar_items_used; GCallback highlight_cb; @@ -81,46 +81,46 @@ extern void free_widget_value (struct _widget_value *); extern bool xg_uses_old_file_dialog (void) ATTRIBUTE_CONST; -extern char *xg_get_file_name (FRAME_PTR f, +extern char *xg_get_file_name (struct frame *f, char *prompt, char *default_filename, bool mustmatch_p, bool only_dir_p); -extern Lisp_Object xg_get_font (FRAME_PTR f, const char *); +extern Lisp_Object xg_get_font (struct frame *f, const char *); extern GtkWidget *xg_create_widget (const char *type, const char *name, - FRAME_PTR f, + struct frame *f, struct _widget_value *val, GCallback select_cb, GCallback deactivate_cb, GCallback highlight_cb); extern void xg_modify_menubar_widgets (GtkWidget *menubar, - FRAME_PTR f, + struct frame *f, struct _widget_value *val, bool deep_p, GCallback select_cb, GCallback deactivate_cb, GCallback highlight_cb); -extern void xg_update_frame_menubar (FRAME_PTR f); +extern void xg_update_frame_menubar (struct frame *f); -extern bool xg_event_is_for_menubar (FRAME_PTR f, XEvent *event); +extern bool xg_event_is_for_menubar (struct frame *f, XEvent *event); extern bool xg_have_tear_offs (void); extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid); -extern void xg_create_scroll_bar (FRAME_PTR f, +extern void xg_create_scroll_bar (struct frame *f, struct scroll_bar *bar, GCallback scroll_callback, GCallback end_callback, const char *scroll_bar_name); -extern void xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id); +extern void xg_remove_scroll_bar (struct frame *f, ptrdiff_t scrollbar_id); -extern void xg_update_scrollbar_pos (FRAME_PTR f, +extern void xg_update_scrollbar_pos (struct frame *f, ptrdiff_t scrollbar_id, int top, int left, @@ -131,40 +131,40 @@ extern void xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole); -extern bool xg_event_is_for_scrollbar (FRAME_PTR f, XEvent *event); +extern bool xg_event_is_for_scrollbar (struct frame *f, XEvent *event); extern int xg_get_default_scrollbar_width (void); -extern void update_frame_tool_bar (FRAME_PTR f); -extern void free_frame_tool_bar (FRAME_PTR f); -extern void xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos); +extern void update_frame_tool_bar (struct frame *f); +extern void free_frame_tool_bar (struct frame *f); +extern void xg_change_toolbar_position (struct frame *f, Lisp_Object pos); -extern void xg_frame_resized (FRAME_PTR f, +extern void xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight); -extern void xg_frame_set_char_size (FRAME_PTR f, int cols, int rows); +extern void xg_frame_set_char_size (struct frame *f, int cols, int rows); extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc); extern void xg_display_open (char *display_name, Display **dpy); extern void xg_display_close (Display *dpy); extern GdkCursor * xg_create_default_cursor (Display *dpy); -extern bool xg_create_frame_widgets (FRAME_PTR f); -extern void xg_free_frame_widgets (FRAME_PTR f); -extern void xg_set_background_color (FRAME_PTR f, unsigned long bg); +extern bool xg_create_frame_widgets (struct frame *f); +extern void xg_free_frame_widgets (struct frame *f); +extern void xg_set_background_color (struct frame *f, unsigned long bg); extern bool xg_check_special_colors (struct frame *f, const char *color_name, XColor *color); -extern void xg_set_frame_icon (FRAME_PTR f, +extern void xg_set_frame_icon (struct frame *f, Pixmap icon_pixmap, Pixmap icon_mask); -extern bool xg_prepare_tooltip (FRAME_PTR f, +extern bool xg_prepare_tooltip (struct frame *f, Lisp_Object string, int *width, int *height); -extern void xg_show_tooltip (FRAME_PTR f, int root_x, int root_y); -extern bool xg_hide_tooltip (FRAME_PTR f); +extern void xg_show_tooltip (struct frame *f, int root_x, int root_y); +extern bool xg_hide_tooltip (struct frame *f); /* Mark all callback data that are Lisp_object:s during GC. */ diff --git a/src/image.c b/src/image.c index 1f8cb520dca..2db44d07c81 100644 --- a/src/image.c +++ b/src/image.c @@ -164,20 +164,20 @@ XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) /* Functions to access the contents of a bitmap, given an id. */ int -x_bitmap_height (FRAME_PTR f, ptrdiff_t id) +x_bitmap_height (struct frame *f, ptrdiff_t id) { return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height; } int -x_bitmap_width (FRAME_PTR f, ptrdiff_t id) +x_bitmap_width (struct frame *f, ptrdiff_t id) { return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width; } #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) ptrdiff_t -x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) +x_bitmap_pixmap (struct frame *f, ptrdiff_t id) { /* HAVE_NTGUI needs the explicit cast here. */ return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; @@ -186,7 +186,7 @@ x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) #ifdef HAVE_X_WINDOWS int -x_bitmap_mask (FRAME_PTR f, ptrdiff_t id) +x_bitmap_mask (struct frame *f, ptrdiff_t id) { return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask; } @@ -195,7 +195,7 @@ x_bitmap_mask (FRAME_PTR f, ptrdiff_t id) /* Allocate a new bitmap record. Returns index of new record. */ static ptrdiff_t -x_allocate_bitmap_record (FRAME_PTR f) +x_allocate_bitmap_record (struct frame *f) { Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); ptrdiff_t i; @@ -216,7 +216,7 @@ x_allocate_bitmap_record (FRAME_PTR f) /* Add one reference to the reference count of the bitmap with id ID. */ void -x_reference_bitmap (FRAME_PTR f, ptrdiff_t id) +x_reference_bitmap (struct frame *f, ptrdiff_t id) { ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; } @@ -302,11 +302,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) id = x_allocate_bitmap_record (f); dpyinfo->bitmaps[id - 1].img = bitmap; dpyinfo->bitmaps[id - 1].refcount = 1; - dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); dpyinfo->bitmaps[id - 1].depth = 1; dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap); dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap); - strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file)); return id; #endif @@ -345,11 +344,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) dpyinfo->bitmaps[id - 1].pixmap = bitmap; dpyinfo->bitmaps[id - 1].have_mask = 0; dpyinfo->bitmaps[id - 1].refcount = 1; - dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); dpyinfo->bitmaps[id - 1].depth = 1; dpyinfo->bitmaps[id - 1].height = height; dpyinfo->bitmaps[id - 1].width = width; - strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file)); return id; #endif /* HAVE_X_WINDOWS */ @@ -384,7 +382,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) /* Remove reference to bitmap with id number ID. */ void -x_destroy_bitmap (FRAME_PTR f, ptrdiff_t id) +x_destroy_bitmap (struct frame *f, ptrdiff_t id) { Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); @@ -1362,14 +1360,12 @@ static void cache_image (struct frame *f, struct image *img); struct image_cache * make_image_cache (void) { - struct image_cache *c = xzalloc (sizeof *c); - int size; + struct image_cache *c = xmalloc (sizeof *c); - size = 50; - c->images = xmalloc (size * sizeof *c->images); - c->size = size; - size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; - c->buckets = xzalloc (size); + c->size = 50; + c->used = c->refcount = 0; + c->images = xmalloc (c->size * sizeof *c->images); + c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets); return c; } @@ -3332,7 +3328,7 @@ static int xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color, void *closure) { - return xpm_lookup_color ((struct frame *) closure, color_name, color); + return xpm_lookup_color (closure, color_name, color); } @@ -5652,8 +5648,7 @@ struct png_memory_storage static void png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) { - struct png_memory_storage *tbr - = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr); + struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr); if (length > tbr->len - tbr->index) fn_png_error (png_ptr, "Read error"); @@ -5670,7 +5665,7 @@ png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) static void png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) { - FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr); + FILE *fp = fn_png_get_io_ptr (png_ptr); if (fread (data, 1, length, fp) < length) fn_png_error (png_ptr, "Read error"); @@ -5814,9 +5809,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) /* Read image info. */ if (!NILP (specified_data)) - fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); + fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory); else - fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file); + fn_png_set_read_fn (png_ptr, fp, png_read_from_file); fn_png_set_sig_bytes (png_ptr, sizeof sig); fn_png_read_info (png_ptr, info_ptr); @@ -6306,7 +6301,7 @@ our_memory_fill_input_buffer (j_decompress_ptr cinfo) static void our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) { - struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src; + struct jpeg_source_mgr *src = cinfo->src; if (src) { @@ -6326,19 +6321,17 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) static void jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) { - struct jpeg_source_mgr *src; + struct jpeg_source_mgr *src = cinfo->src; - if (cinfo->src == NULL) + if (! src) { /* First time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof (struct jpeg_source_mgr)); - src = (struct jpeg_source_mgr *) cinfo->src; + src = cinfo->mem->alloc_small ((j_common_ptr) cinfo, + JPOOL_PERMANENT, sizeof *src); + cinfo->src = src; src->next_input_byte = data; } - src = (struct jpeg_source_mgr *) cinfo->src; src->init_source = our_common_init_source; src->fill_input_buffer = our_memory_fill_input_buffer; src->skip_input_data = our_memory_skip_input_data; @@ -6430,20 +6423,17 @@ our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) static void jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) { - struct jpeg_stdio_mgr *src; + struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src; - if (cinfo->src != NULL) - src = (struct jpeg_stdio_mgr *) cinfo->src; - else + if (! src) { /* First time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof (struct jpeg_stdio_mgr)); - src = (struct jpeg_stdio_mgr *) cinfo->src; - src->buffer = (JOCTET *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - JPEG_STDIO_BUFFER_SIZE); + src = cinfo->mem->alloc_small ((j_common_ptr) cinfo, + JPOOL_PERMANENT, sizeof *src); + cinfo->src = (struct jpeg_source_mgr *) src; + src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo, + JPOOL_PERMANENT, + JPEG_STDIO_BUFFER_SIZE); } src->file = fp; @@ -7746,6 +7736,7 @@ enum imagemagick_keyword_index IMAGEMAGICK_WIDTH, IMAGEMAGICK_MAX_HEIGHT, IMAGEMAGICK_MAX_WIDTH, + IMAGEMAGICK_FORMAT, IMAGEMAGICK_ROTATION, IMAGEMAGICK_CROP, IMAGEMAGICK_LAST @@ -7770,6 +7761,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = {":width", IMAGE_INTEGER_VALUE, 0}, {":max-height", IMAGE_INTEGER_VALUE, 0}, {":max-width", IMAGE_INTEGER_VALUE, 0}, + {":format", IMAGE_SYMBOL_VALUE, 0}, {":rotation", IMAGE_NUMBER_VALUE, 0}, {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; @@ -7848,6 +7840,233 @@ imagemagick_error (MagickWand *wand) description = (char *) MagickRelinquishMemory (description); } +/* Possibly give ImageMagick some extra help to determine the image + type by supplying a "dummy" filename based on the Content-Type. */ + +static char * +imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent]) +{ + Lisp_Object symbol = intern ("image-format-suffixes"); + Lisp_Object val = find_symbol_value (symbol); + Lisp_Object format; + + if (! CONSP (val)) + return NULL; + + format = image_spec_value (spec, intern (":format"), NULL); + val = Fcar_safe (Fcdr_safe (Fassq (format, val))); + if (! STRINGP (val)) + return NULL; + + /* It's OK to truncate the hint if it has MaxTextExtent or more bytes, + as ImageMagick would ignore the extra bytes anyway. */ + snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val)); + return hint_buffer; +} + +/* Animated images (e.g., GIF89a) are composed from one "master image" + (which is the first one, and then there's a number of images that + follow. If following images have non-transparent colors, these are + composed "on top" of the master image. So, in general, one has to + compute ann the preceding images to be able to display a particular + sub-image. + + Computing all the preceding images is too slow, so we maintain a + cache of previously computed images. We have to maintain a cache + separate from the image cache, because the images may be scaled + before display. */ + +struct animation_cache +{ + MagickWand *wand; + int index; + EMACS_TIME update_time; + struct animation_cache *next; + char signature[FLEXIBLE_ARRAY_MEMBER]; +}; + +static struct animation_cache *animation_cache = NULL; + +static struct animation_cache * +imagemagick_create_cache (char *signature) +{ + struct animation_cache *cache + = xmalloc (offsetof (struct animation_cache, signature) + + strlen (signature) + 1); + cache->wand = 0; + cache->index = 0; + cache->next = 0; + strcpy (cache->signature, signature); + return cache; +} + +/* Discard cached images that haven't been used for a minute. */ +static void +imagemagick_prune_animation_cache (void) +{ + struct animation_cache **pcache = &animation_cache; + EMACS_TIME old = sub_emacs_time (current_emacs_time (), + make_emacs_time (60, 0)); + + while (*pcache) + { + struct animation_cache *cache = *pcache; + if (EMACS_TIME_LE (old, cache->update_time)) + pcache = &cache->next; + else + { + if (cache->wand) + DestroyMagickWand (cache->wand); + *pcache = cache->next; + xfree (cache); + } + } +} + +static struct animation_cache * +imagemagick_get_animation_cache (MagickWand *wand) +{ + char *signature = MagickGetImageSignature (wand); + struct animation_cache *cache; + struct animation_cache **pcache = &animation_cache; + + imagemagick_prune_animation_cache (); + + while (1) + { + cache = *pcache; + if (! cache) + { + *pcache = cache = imagemagick_create_cache (signature); + break; + } + if (strcmp (signature, cache->signature) == 0) + break; + pcache = &cache->next; + } + + DestroyString (signature); + cache->update_time = current_emacs_time (); + return cache; +} + +static MagickWand * +imagemagick_compute_animated_image (MagickWand *super_wand, int ino) +{ + int i; + MagickWand *composite_wand; + size_t dest_width, dest_height; + struct animation_cache *cache = imagemagick_get_animation_cache (super_wand); + + MagickSetIteratorIndex (super_wand, 0); + + if (ino == 0 || cache->wand == NULL || cache->index > ino) + { + composite_wand = MagickGetImage (super_wand); + if (cache->wand) + DestroyMagickWand (cache->wand); + } + else + composite_wand = cache->wand; + + dest_width = MagickGetImageWidth (composite_wand); + dest_height = MagickGetImageHeight (composite_wand); + + for (i = max (1, cache->index + 1); i <= ino; i++) + { + MagickWand *sub_wand; + PixelIterator *source_iterator, *dest_iterator; + PixelWand **source, **dest; + size_t source_width, source_height; + ssize_t source_left, source_top; + MagickPixelPacket pixel; + DisposeType dispose; + ptrdiff_t lines = 0; + + MagickSetIteratorIndex (super_wand, i); + sub_wand = MagickGetImage (super_wand); + + MagickGetImagePage (sub_wand, &source_width, &source_height, + &source_left, &source_top); + + /* This flag says how to handle transparent pixels. */ + dispose = MagickGetImageDispose (sub_wand); + + source_iterator = NewPixelIterator (sub_wand); + if (! source_iterator) + { + DestroyMagickWand (composite_wand); + DestroyMagickWand (sub_wand); + cache->wand = NULL; + image_error ("Imagemagick pixel iterator creation failed", + Qnil, Qnil); + return NULL; + } + + dest_iterator = NewPixelIterator (composite_wand); + if (! dest_iterator) + { + DestroyMagickWand (composite_wand); + DestroyMagickWand (sub_wand); + DestroyPixelIterator (source_iterator); + cache->wand = NULL; + image_error ("Imagemagick pixel iterator creation failed", + Qnil, Qnil); + return NULL; + } + + /* The sub-image may not start at origin, so move the destination + iterator to where the sub-image should start. */ + if (source_top > 0) + { + PixelSetIteratorRow (dest_iterator, source_top); + lines = source_top; + } + + while ((source = PixelGetNextIteratorRow (source_iterator, &source_width)) + != NULL) + { + ptrdiff_t x; + + /* Sanity check. This shouldn't happen, but apparently + does in some pictures. */ + if (++lines >= dest_height) + break; + + dest = PixelGetNextIteratorRow (dest_iterator, &dest_width); + for (x = 0; x < source_width; x++) + { + /* Sanity check. This shouldn't happen, but apparently + also does in some pictures. */ + if (x + source_left > dest_width) + break; + /* Normally we only copy over non-transparent pixels, + but if the disposal method is "Background", then we + copy over all pixels. */ + if (dispose == BackgroundDispose || + PixelGetAlpha (source[x])) + { + PixelGetMagickColor (source[x], &pixel); + PixelSetMagickColor (dest[x + source_left], &pixel); + } + } + PixelSyncIterator (dest_iterator); + } + + DestroyPixelIterator (source_iterator); + DestroyPixelIterator (dest_iterator); + DestroyMagickWand (sub_wand); + } + + /* Cache a copy for the next iteration. The current wand will be + destroyed by the caller. */ + cache->wand = CloneMagickWand (composite_wand); + cache->index = ino; + + return composite_wand; +} + + /* Helper function for imagemagick_load, which does the actual loading given contents and size, apart from frame and image structures, passed from imagemagick_load. Uses librimagemagick to do most of @@ -7870,7 +8089,6 @@ imagemagick_load_image (struct frame *f, struct image *img, XImagePtr ximg; int x, y; MagickWand *image_wand; - MagickWand *ping_wand; PixelIterator *iterator; PixelWand **pixels, *bg_wand = NULL; MagickPixelPacket pixel; @@ -7881,6 +8099,8 @@ imagemagick_load_image (struct frame *f, struct image *img, int desired_width, desired_height; double rotation; int pixelwidth; + char hint_buffer[MaxTextExtent]; + char *filename_hint = NULL; /* Handle image index for image types who can contain more than one image. Interface :index is same as for GIF. First we "ping" the image to see how @@ -7891,48 +8111,48 @@ imagemagick_load_image (struct frame *f, struct image *img, MagickWandGenesis (); image = image_spec_value (img->spec, QCindex, NULL); ino = INTEGERP (image) ? XFASTINT (image) : 0; - ping_wand = NewMagickWand (); - /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */ + image_wand = NewMagickWand (); - status = filename - ? MagickPingImage (ping_wand, filename) - : MagickPingImageBlob (ping_wand, contents, size); + if (filename) + status = MagickReadImage (image_wand, filename); + else + { + filename_hint = imagemagick_filename_hint (img->spec, hint_buffer); + MagickSetFilename (image_wand, filename_hint); + status = MagickReadImageBlob (image_wand, contents, size); + } if (status == MagickFalse) { - imagemagick_error (ping_wand); - DestroyMagickWand (ping_wand); + imagemagick_error (image_wand); + DestroyMagickWand (image_wand); return 0; } - if (ino < 0 || ino >= MagickGetNumberImages (ping_wand)) + if (ino < 0 || ino >= MagickGetNumberImages (image_wand)) { image_error ("Invalid image number `%s' in image `%s'", image, img->spec); - DestroyMagickWand (ping_wand); + DestroyMagickWand (image_wand); return 0; } - if (MagickGetNumberImages (ping_wand) > 1) + if (MagickGetNumberImages (image_wand) > 1) img->lisp_data = Fcons (Qcount, - Fcons (make_number (MagickGetNumberImages (ping_wand)), + Fcons (make_number (MagickGetNumberImages (image_wand)), img->lisp_data)); - DestroyMagickWand (ping_wand); - - /* Now we know how many images are inside the file. If it's not a - bundle, the number is one. Load the image data. */ - - image_wand = NewMagickWand (); - - if ((filename - ? MagickReadImage (image_wand, filename) - : MagickReadImageBlob (image_wand, contents, size)) - == MagickFalse) + /* If we have an animated image, get the new wand based on the + "super-wand". */ + if (MagickGetNumberImages (image_wand) > 1) { - imagemagick_error (image_wand); - goto imagemagick_error; + MagickWand *super_wand = image_wand; + image_wand = imagemagick_compute_animated_image (super_wand, ino); + if (! image_wand) + image_wand = super_wand; + else + DestroyMagickWand (super_wand); } /* Retrieve the frame's background color, for use later. */ @@ -8120,7 +8340,7 @@ imagemagick_load_image (struct frame *f, struct image *img, /* Copy pixels from the imagemagick image structure to the x image map. */ iterator = NewPixelIterator (image_wand); - if (iterator == (PixelIterator *) NULL) + if (! iterator) { #ifdef COLOR_TABLE_SUPPORT free_color_table (); @@ -8135,7 +8355,7 @@ imagemagick_load_image (struct frame *f, struct image *img, for (y = 0; y < image_height; y++) { pixels = PixelGetNextIteratorRow (iterator, &width); - if (pixels == (PixelWand **) NULL) + if (! pixels) break; for (x = 0; x < (long) width; x++) { @@ -9200,7 +9420,7 @@ A cross is always drawn on black & white displays. */); DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path, doc: /* List of directories to search for window system bitmap files. */); - Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); + Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS); DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay, doc: /* Maximum time after which images are removed from the cache. diff --git a/src/indent.c b/src/indent.c index 47358e17db8..6aaf86579d7 100644 --- a/src/indent.c +++ b/src/indent.c @@ -141,13 +141,13 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); } -/* Allocate or free the width run cache, as requested by the current - state of current_buffer's cache_long_line_scans variable. */ +/* Allocate or free the width run cache, as requested by the + current state of current_buffer's cache_long_scans variable. */ static void width_run_cache_on_off (void) { - if (NILP (BVAR (current_buffer, cache_long_line_scans)) + if (NILP (BVAR (current_buffer, cache_long_scans)) /* And, for the moment, this feature doesn't work on multibyte characters. */ || !NILP (BVAR (current_buffer, enable_multibyte_characters))) diff --git a/src/insdel.c b/src/insdel.c index 15d585568a0..f746fd34330 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1211,12 +1211,9 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, adjust_markers_for_insert (from, from_byte, from + len, from_byte + len_byte, 0); - if (! EQ (BVAR (current_buffer, undo_list), Qt)) - { - if (nchars_del > 0) - record_delete (from, prev_text); - record_insert (from, len); - } + if (nchars_del > 0) + record_delete (from, prev_text); + record_insert (from, len); if (len > nchars_del) adjust_overlays_for_insert (from, len - nchars_del); @@ -1373,12 +1370,12 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, emacs_abort (); #endif - if (! EQ (BVAR (current_buffer, undo_list), Qt)) + /* Record the insertion first, so that when we undo, + the deletion will be undone first. Thus, undo + will insert before deleting, and thus will keep + the markers before and after this text separate. */ + if (!NILP (deletion)) { - /* Record the insertion first, so that when we undo, - the deletion will be undone first. Thus, undo - will insert before deleting, and thus will keep - the markers before and after this text separate. */ record_insert (from + SCHARS (deletion), inschars); record_delete (from, deletion); } @@ -1718,8 +1715,7 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, so that undo handles this after reinserting the text. */ adjust_markers_for_delete (from, from_byte, to, to_byte); - if (! EQ (BVAR (current_buffer, undo_list), Qt)) - record_delete (from, deletion); + record_delete (from, deletion); MODIFF++; CHARS_MODIFF = MODIFF; @@ -1760,27 +1756,22 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, return deletion; } -/* Call this if you're about to change the region of current buffer +/* Call this if you're about to change the text of current buffer from character positions START to END. This checks the read-only properties of the region, calls the necessary modification hooks, and warns the next redisplay that it should pay attention to that - area. - - If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF. - Otherwise set CHARS_MODIFF to the new value of MODIFF. */ + area. */ void -modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) +modify_text (ptrdiff_t start, ptrdiff_t end) { prepare_to_modify_buffer (start, end, NULL); BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); - if (MODIFF <= SAVE_MODIFF) record_first_change (); MODIFF++; - if (! preserve_chars_modiff) - CHARS_MODIFF = MODIFF; + CHARS_MODIFF = MODIFF; bset_point_before_scroll (current_buffer, Qnil); } @@ -1796,8 +1787,8 @@ modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) by holding its value temporarily in a marker. */ void -prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, - ptrdiff_t *preserve_ptr) +prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end, + ptrdiff_t *preserve_ptr) { struct buffer *base_buffer; @@ -1868,6 +1859,17 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, } signal_before_change (start, end, preserve_ptr); + Vdeactivate_mark = Qt; +} + +/* Like above, but called when we know that the buffer text + will be modified and region caches should be invalidated. */ + +void +prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, + ptrdiff_t *preserve_ptr) +{ + prepare_to_modify_buffer_1 (start, end, preserve_ptr); if (current_buffer->newline_cache) invalidate_region_cache (current_buffer, @@ -1877,10 +1879,12 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, invalidate_region_cache (current_buffer, current_buffer->width_run_cache, start - BEG, Z - end); - - Vdeactivate_mark = Qt; + if (current_buffer->bidi_paragraph_cache) + invalidate_region_cache (current_buffer, + current_buffer->bidi_paragraph_cache, + start - BEG, Z - end); } - + /* These macros work with an argument named `preserve_ptr' and a local variable named `preserve_marker'. */ diff --git a/src/keyboard.c b/src/keyboard.c index 830f70bc1f5..8a99d5a0766 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1281,7 +1281,7 @@ static #endif bool ignore_mouse_drag_p; -static FRAME_PTR +static struct frame * some_mouse_moved (void) { Lisp_Object tail, frame; @@ -2163,7 +2163,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, This causes trouble if we are trying to read a mouse motion event (i.e., if we are inside a `track-mouse' form), so we restore the mouse_moved flag. */ - FRAME_PTR f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved (); + struct frame *f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved (); help = call1 (Qmouse_fixup_help_message, help); if (f) f->mouse_moved = 1; @@ -4152,7 +4152,7 @@ kbd_buffer_get_event (KBOARD **kbp, /* Try generating a mouse motion event. */ else if (!NILP (do_mouse_tracking) && some_mouse_moved ()) { - FRAME_PTR f = some_mouse_moved (); + struct frame *f = some_mouse_moved (); Lisp_Object bar_window; enum scroll_bar_part part; Lisp_Object x, y; @@ -5898,7 +5898,7 @@ make_lispy_event (struct input_event *event) case DRAG_N_DROP_EVENT: { - FRAME_PTR f; + struct frame *f; Lisp_Object head, position; Lisp_Object files; @@ -5977,7 +5977,7 @@ make_lispy_event (struct input_event *event) #ifdef HAVE_GPM case GPM_CLICK_EVENT: { - FRAME_PTR f = XFRAME (event->frame_or_window); + struct frame *f = XFRAME (event->frame_or_window); Lisp_Object head, position; Lisp_Object *start_pos_ptr; Lisp_Object start_pos; @@ -6031,7 +6031,7 @@ make_lispy_event (struct input_event *event) } static Lisp_Object -make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part, +make_lispy_movement (struct frame *frame, Lisp_Object bar_window, enum scroll_bar_part part, Lisp_Object x, Lisp_Object y, Time t) { /* Is it a scroll bar movement? */ @@ -8431,7 +8431,7 @@ read_char_minibuf_menu_prompt (int commandflag, return Qnil; #define PUSH_C_STR(str, listvar) \ - listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar) + listvar = Fcons (build_unibyte_string (str), listvar) /* Prompt string always starts with map's prompt, and a space. */ prompt_strings = Fcons (name, prompt_strings); @@ -10124,8 +10124,6 @@ Also end any kbd macro being defined. */) end_kbd_macro (); } - update_mode_lines++; - Vunread_command_events = Qnil; discard_tty_input (); diff --git a/src/keymap.c b/src/keymap.c index d13a6274347..7a18cd5d983 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -3249,8 +3249,7 @@ describe_map (Lisp_Object map, Lisp_Object prefix, for (tail = map; CONSP (tail); tail = XCDR (tail)) length_needed++; - vect = ((struct describe_map_elt *) - alloca (sizeof (struct describe_map_elt) * length_needed)); + vect = alloca (length_needed * sizeof *vect); for (tail = map; CONSP (tail); tail = XCDR (tail)) { diff --git a/src/lisp.h b/src/lisp.h index 952991a32d9..60a553cc7d1 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -775,6 +775,7 @@ extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; extern Lisp_Object Qvector_or_char_table_p, Qwholenump; +extern Lisp_Object Qwindow; extern Lisp_Object Ffboundp (Lisp_Object); extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); @@ -3371,6 +3372,7 @@ extern struct hash_table_test hashtest_eql, hashtest_equal; extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); +extern Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object do_yes_or_no_p (Lisp_Object); extern Lisp_Object concat2 (Lisp_Object, Lisp_Object); extern Lisp_Object concat3 (Lisp_Object, Lisp_Object, Lisp_Object); @@ -3437,8 +3439,9 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool); extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); -extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); +extern void modify_text (ptrdiff_t, ptrdiff_t); extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); +extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); @@ -3816,11 +3819,12 @@ extern Lisp_Object internal_condition_case_n Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); extern void specbind (Lisp_Object, Lisp_Object); extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); -extern void record_unwind_protect_int (void (*) (int), int); extern void record_unwind_protect_ptr (void (*) (void *), void *); +extern void record_unwind_protect_int (void (*) (int), int); extern void record_unwind_protect_void (void (*) (void)); extern void record_unwind_protect_nothing (void); extern void clear_unwind_protect (ptrdiff_t); +extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object); extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *); extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); extern void rebind_for_thread_switch (void); @@ -3874,9 +3878,7 @@ extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t); extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, Lisp_Object, Lisp_Object, Lisp_Object); extern bool overlay_touches_p (ptrdiff_t); -extern Lisp_Object Vbuffer_alist; extern Lisp_Object other_buffer_safely (Lisp_Object); -extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; extern Lisp_Object get_truename_buffer (Lisp_Object); extern void init_buffer_once (void); extern void init_buffer (void); @@ -3907,6 +3909,9 @@ extern Lisp_Object Qfile_directory_p; extern Lisp_Object Qinsert_file_contents; extern Lisp_Object Qfile_name_history; extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); +extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object, int); EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ extern void close_file_unwind (int); extern void fclose_unwind (void *); @@ -4289,6 +4294,11 @@ extern void syms_of_xml (void); extern void xml_cleanup_parser (void); #endif +#ifdef HAVE_ZLIB +/* Defined in decompress.c. */ +extern void syms_of_decompress (void); +#endif + #ifdef HAVE_DBUS /* Defined in dbusbind.c. */ void syms_of_dbusbind (void); @@ -4322,10 +4332,17 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t); extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern char *xstrdup (const char *); +extern char *xlispstrdup (Lisp_Object); extern void xputenv (const char *); extern char *egetenv (const char *); +/* Copy Lisp string to temporary (allocated on stack) C string. */ + +#define xlispstrdupa(string) \ + memcpy (alloca (SBYTES (string) + 1), \ + SSDATA (string), SBYTES (string) + 1) + /* Set up the name of the machine we're running on. */ extern void init_system_name (void); @@ -4402,6 +4419,12 @@ extern void *record_xmalloc (size_t); memory_full (SIZE_MAX); \ } while (0) +/* Do a `for' loop over alist values. */ + +#define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \ + for (list_var = head_var; \ + (CONSP (list_var) && (value_var = XCDR (XCAR (list_var)), 1)); \ + list_var = XCDR (list_var)) /* Check whether it's time for GC, and run it if so. */ diff --git a/src/lisp.mk b/src/lisp.mk index edd81bcf493..a9a661ea3a8 100644 --- a/src/lisp.mk +++ b/src/lisp.mk @@ -71,6 +71,7 @@ lisp = \ $(lispsource)/faces.elc \ $(lispsource)/button.elc \ $(lispsource)/startup.elc \ + $(lispsource)/emacs-lisp/nadvice.elc \ $(lispsource)/minibuffer.elc \ $(lispsource)/abbrev.elc \ $(lispsource)/simple.elc \ diff --git a/src/marker.c b/src/marker.c index 6c50def51a3..2f91bdf9727 100644 --- a/src/marker.c +++ b/src/marker.c @@ -534,9 +534,9 @@ set_marker_internal (Lisp_Object marker, Lisp_Object position, } DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0, - doc: /* Position MARKER before character number POSITION in BUFFER, -which defaults to the current buffer. If POSITION is nil, -makes marker point nowhere so it no longer slows down + doc: /* Position MARKER before character number POSITION in BUFFER. +If BUFFER is omitted or nil, it defaults to the current buffer. If +POSITION is nil, makes marker point nowhere so it no longer slows down editing in any buffer. Returns MARKER. */) (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer) { diff --git a/src/menu.c b/src/menu.c index 6b4a22d3052..6fce5b91caf 100644 --- a/src/menu.c +++ b/src/menu.c @@ -867,7 +867,8 @@ update_submenu_strings (widget_value *first_wv) VECTOR is an array of menu events for the whole menu. */ void -find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object vector, void *client_data) +find_and_call_menu_selection (struct frame *f, int menu_bar_items_used, + Lisp_Object vector, void *client_data) { Lisp_Object prefix, entry; Lisp_Object *subprefix_stack; @@ -950,7 +951,7 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object /* As above, but return the menu selection instead of storing in kb buffer. If KEYMAPS, return full prefixes to selection. */ Lisp_Object -find_and_return_menu_selection (FRAME_PTR f, bool keymaps, void *client_data) +find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data) { Lisp_Object prefix, entry; int i; @@ -1060,7 +1061,7 @@ no quit occurs and `x-popup-menu' returns nil. */) Lisp_Object title; const char *error_name = NULL; Lisp_Object selection = Qnil; - FRAME_PTR f = NULL; + struct frame *f = NULL; Lisp_Object x, y, window; bool keymaps = 0; bool for_click = 0; @@ -1116,7 +1117,7 @@ no quit occurs and `x-popup-menu' returns nil. */) if (get_current_pos_p) { /* Use the mouse's current position. */ - FRAME_PTR new_f = SELECTED_FRAME (); + struct frame *new_f = SELECTED_FRAME (); #ifdef HAVE_X_WINDOWS /* Can't use mouse_position_hook for X since it returns coordinates relative to the window the mouse is in, diff --git a/src/menu.h b/src/menu.h index f60873eadb3..0f94ad8000b 100644 --- a/src/menu.h +++ b/src/menu.h @@ -35,20 +35,20 @@ extern void list_of_panes (Lisp_Object); || defined (HAVE_NS) extern void free_menubar_widget_value_tree (widget_value *); extern void update_submenu_strings (widget_value *); -extern void find_and_call_menu_selection (FRAME_PTR, int, +extern void find_and_call_menu_selection (struct frame *, int, Lisp_Object, void *); extern widget_value *xmalloc_widget_value (void); extern widget_value *digest_single_submenu (int, int, bool); #endif #ifdef HAVE_X_WINDOWS -extern void mouse_position_for_popup (FRAME_PTR f, int *x, int *y); +extern void mouse_position_for_popup (struct frame *f, int *x, int *y); #endif -extern Lisp_Object w32_menu_show (FRAME_PTR, int, int, int, int, +extern Lisp_Object w32_menu_show (struct frame *, int, int, int, int, Lisp_Object, const char **); -extern Lisp_Object ns_menu_show (FRAME_PTR, int, int, bool, bool, +extern Lisp_Object ns_menu_show (struct frame *, int, int, bool, bool, Lisp_Object, const char **); -extern Lisp_Object xmenu_show (FRAME_PTR, int, int, bool, bool, +extern Lisp_Object xmenu_show (struct frame *, int, int, bool, bool, Lisp_Object, const char **, Time); #endif /* MENU_H */ diff --git a/src/minibuf.c b/src/minibuf.c index 2c33b83c11b..7403fc6c32d 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -568,22 +568,15 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, bset_directory (current_buffer, ambient_dir); else { - Lisp_Object buf_list; + Lisp_Object tail, buf; - for (buf_list = Vbuffer_alist; - CONSP (buf_list); - buf_list = XCDR (buf_list)) - { - Lisp_Object other_buf; - - other_buf = XCDR (XCAR (buf_list)); - if (STRINGP (BVAR (XBUFFER (other_buf), directory))) - { - bset_directory (current_buffer, - BVAR (XBUFFER (other_buf), directory)); - break; - } - } + FOR_EACH_LIVE_BUFFER (tail, buf) + if (STRINGP (BVAR (XBUFFER (buf), directory))) + { + bset_directory (current_buffer, + BVAR (XBUFFER (buf), directory)); + break; + } } if (!EQ (mini_frame, selected_frame)) @@ -877,10 +870,8 @@ read_minibuf_unwind (void) if (minibuf_level == 0) resize_mini_window (XWINDOW (window), 0); - /* Make sure minibuffer window is erased, not ignored. */ + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; - XWINDOW (window)->last_modified = 0; - XWINDOW (window)->last_overlay_modified = 0; /* In case the previous minibuffer displayed in this miniwindow is dead, we may keep displaying this buffer (tho it's inactive), so reset it, diff --git a/src/msdos.c b/src/msdos.c index a2bcc06ac17..88a2eb60726 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -298,7 +298,7 @@ mouse_button_depressed (int b, int *xp, int *yp) } void -mouse_get_pos (FRAME_PTR *f, int insist, Lisp_Object *bar_window, +mouse_get_pos (struct frame **f, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, Time *time) { @@ -1158,7 +1158,7 @@ IT_display_cursor (int on) to put the cursor at the end of the text displayed there. */ static void -IT_cmgoto (FRAME_PTR f) +IT_cmgoto (struct frame *f) { /* Only set the cursor to where it should be if the display is already in sync with the window contents. */ @@ -1760,7 +1760,7 @@ IT_set_frame_parameters (struct frame *f, Lisp_Object alist) } } -extern void init_frame_faces (FRAME_PTR); +extern void init_frame_faces (struct frame *); #endif /* !HAVE_X_WINDOWS */ @@ -3320,18 +3320,6 @@ XMenuDestroy (Display *foo, XMenu *menu) xfree (menu); menu_help_message = prev_menu_help_message = NULL; } - -int -x_pixel_width (struct frame *f) -{ - return FRAME_COLS (f); -} - -int -x_pixel_height (struct frame *f) -{ - return FRAME_LINES (f); -} #endif /* !HAVE_X_WINDOWS */ /* ----------------------- DOS / UNIX conversion --------------------- */ diff --git a/src/msdos.h b/src/msdos.h index ee0d49464ae..6a6fe349131 100644 --- a/src/msdos.h +++ b/src/msdos.h @@ -74,8 +74,6 @@ struct window; /* Defined in xfns.c; emulated on msdos.c */ extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); -extern int x_pixel_width (struct frame *); -extern int x_pixel_height (struct frame *); #define XFreeGC (void) #define x_destroy_bitmap(p1,p2) diff --git a/src/nsfns.m b/src/nsfns.m index 121ac539646..fc276c2b12d 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -143,7 +143,7 @@ check_ns_display_info (Lisp_Object object) dpyinfo = ns_display_info_for_name (object); else { - FRAME_PTR f = decode_window_system_frame (object); + struct frame *f = decode_window_system_frame (object); dpyinfo = FRAME_NS_DISPLAY_INFO (f); } @@ -431,7 +431,7 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) } static void -ns_set_name_internal (FRAME_PTR f, Lisp_Object name) +ns_set_name_internal (struct frame *f, Lisp_Object name) { struct gcpro gcpro1; Lisp_Object encoded_name, encoded_icon_name; @@ -503,7 +503,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit) specified a name for the frame; the name will override any set by the redisplay code. */ static void -x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { NSTRACE (x_explicitly_set_name); ns_set_name (f, arg, 1); @@ -514,7 +514,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) name; names set this way will never override names set by the user's lisp code. */ void -x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { NSTRACE (x_implicitly_set_name); @@ -857,14 +857,10 @@ ns_cursor_type_to_lisp (int arg) /* This is the same as the xfns.c definition. */ static void -x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { set_frame_cursor_types (f, arg); - - /* Make sure the cursor gets redrawn. */ - cursor_type_changed = 1; } - /* called to set mouse pointer color, but all other terms use it to initialize pointer types (and don't set the color ;) */ @@ -1068,7 +1064,7 @@ This function is an internal primitive--use `make-frame' instead. */) Lisp_Object frame, tem; Lisp_Object name; int minibuffer_only = 0; - int window_prompting = 0; + long window_prompting = 0; int width, height; ptrdiff_t count = specpdl_ptr - specpdl; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; @@ -2035,13 +2031,17 @@ DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc, /* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping, remove this. */ NSString *utfStr; + Lisp_Object ret; CHECK_STRING (str); - utfStr = [NSString stringWithUTF8String: SSDATA (str)]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + utfStr = [NSString stringWithUTF8String: SSDATA (str)]; #ifdef NS_IMPL_COCOA - utfStr = [utfStr precomposedStringWithCanonicalMapping]; + utfStr = [utfStr precomposedStringWithCanonicalMapping]; #endif - return build_string ([utfStr UTF8String]); + ret = build_string ([utfStr UTF8String]); + [pool release]; + return ret; } @@ -2231,21 +2231,6 @@ x_get_focus_frame (struct frame *frame) return nsfocus; } - -int -x_pixel_width (struct frame *f) -{ - return FRAME_PIXEL_WIDTH (f); -} - - -int -x_pixel_height (struct frame *f) -{ - return FRAME_PIXEL_HEIGHT (f); -} - - void x_sync (struct frame *f) { @@ -2462,7 +2447,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) if (n_monitors == 0) return Qnil; - monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); + monitors = xzalloc (n_monitors * sizeof *monitors); for (i = 0; i < [screens count]; ++i) { diff --git a/src/nsfont.m b/src/nsfont.m index df7ef0bb0bc..235150e3aef 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -619,13 +619,13 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch) ========================================================================== */ -static Lisp_Object nsfont_get_cache (FRAME_PTR frame); -static Lisp_Object nsfont_list (Lisp_Object frame, Lisp_Object font_spec); -static Lisp_Object nsfont_match (Lisp_Object frame, Lisp_Object font_spec); -static Lisp_Object nsfont_list_family (Lisp_Object frame); -static Lisp_Object nsfont_open (FRAME_PTR f, Lisp_Object font_entity, +static Lisp_Object nsfont_get_cache (struct frame *frame); +static Lisp_Object nsfont_list (struct frame *, Lisp_Object); +static Lisp_Object nsfont_match (struct frame *, Lisp_Object); +static Lisp_Object nsfont_list_family (struct frame *); +static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size); -static void nsfont_close (FRAME_PTR f, struct font *font); +static void nsfont_close (struct frame *f, struct font *font); static int nsfont_has_char (Lisp_Object entity, int c); static unsigned int nsfont_encode_char (struct font *font, int c); static int nsfont_text_extents (struct font *font, unsigned int *code, @@ -659,7 +659,7 @@ struct font_driver nsfont_driver = /* Return a cache of font-entities on FRAME. The cache must be a cons whose cdr part is the actual cache area. */ static Lisp_Object -nsfont_get_cache (FRAME_PTR frame) +nsfont_get_cache (struct frame *frame) { Display_Info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame); return (dpyinfo->name_list_element); @@ -679,9 +679,9 @@ nsfont_get_cache (FRAME_PTR frame) weight, slant, width, size (0 if scalable), dpi, spacing, avgwidth (0 if scalable) */ static Lisp_Object -nsfont_list (Lisp_Object frame, Lisp_Object font_spec) +nsfont_list (struct frame *f, Lisp_Object font_spec) { - return ns_findfonts (font_spec, NO); + return ns_findfonts (font_spec, NO); } @@ -690,16 +690,16 @@ nsfont_list (Lisp_Object frame, Lisp_Object font_spec) `face-font-selection-order' is ignored here. Properties to be considered are same as for list(). */ static Lisp_Object -nsfont_match (Lisp_Object frame, Lisp_Object font_spec) +nsfont_match (struct frame *f, Lisp_Object font_spec) { - return ns_findfonts(font_spec, YES); + return ns_findfonts (font_spec, YES); } /* List available families. The value is a list of family names (symbols). */ static Lisp_Object -nsfont_list_family (Lisp_Object frame) +nsfont_list_family (struct frame *f) { Lisp_Object list = Qnil; NSEnumerator *families; @@ -724,7 +724,7 @@ nsfont_list_family (Lisp_Object frame) /* Open a font specified by FONT_ENTITY on frame F. If the font is scalable, open it with PIXEL_SIZE. */ static Lisp_Object -nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) +nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size) { BOOL synthItal; unsigned int traits = 0; @@ -920,8 +920,7 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) font->underline_thickness = lrint (font_info->underwidth); font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil); - font->props[FONT_FULLNAME_INDEX] = - make_unibyte_string (font_info->name, strlen (font_info->name)); + font->props[FONT_FULLNAME_INDEX] = build_unibyte_string (font_info->name); } unblock_input (); @@ -931,7 +930,7 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) /* Close FONT on frame F. */ static void -nsfont_close (FRAME_PTR f, struct font *font) +nsfont_close (struct frame *f, struct font *font) { struct nsfont_info *font_info = (struct nsfont_info *)font; int i; diff --git a/src/nsmenu.m b/src/nsmenu.m index 02fe0b04ca0..5af813ac758 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -366,7 +366,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) } else { - [menu fillWithWidgetValue: first_wv->contents]; + [menu fillWithWidgetValue: first_wv->contents frame: f]; } } @@ -504,23 +504,11 @@ void x_activate_menubar (struct frame *f) { #ifdef NS_IMPL_COCOA - NSArray *a = [[NSApp mainMenu] itemArray]; - /* Update each submenu separately so ns_update_menubar doesn't reset - the delegate. */ - int i = 0; - while (i < [a count]) - { - EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu]; - const char *title = [[menu title] UTF8String]; - if (strcmp (title, ns_get_pending_menu_title ()) == 0) - { - ns_update_menubar (f, true, menu); - break; - } - ++i; - } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + ns_update_menubar (f, true, nil); ns_check_pending_open_menu (); #endif +#endif } @@ -541,6 +529,7 @@ x_activate_menubar (struct frame *f) /* override designated initializer */ - initWithTitle: (NSString *)title { + frame = 0; if ((self = [super initWithTitle: title])) [self setAutoenablesItems: NO]; return self; @@ -576,17 +565,36 @@ extern NSString *NSMenuDidBeginTrackingNotification; /* Update menu in menuNeedsUpdate only while tracking menus. */ trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification ? 1 : 0); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (! trackingMenu) ns_check_menu_open (nil); +#endif } #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - (void)menuWillOpen:(NSMenu *)menu { - ns_check_menu_open (menu); -} -#endif + ++trackingMenu; +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + // On 10.6 we get repeated calls, only the one for NSSystemDefined is "real". + if ([[NSApp currentEvent] type] != NSSystemDefined) return; #endif + /* When dragging from one menu to another, we get willOpen followed by didClose, + i.e. trackingMenu == 3 in willOpen and then 2 after didClose. + We have updated all menus, so avoid doing it when trackingMenu == 3. */ + if (trackingMenu == 2) + ns_check_menu_open (menu); +} + +- (void)menuDidClose:(NSMenu *)menu +{ + --trackingMenu; +} +#endif /* OSX >= 10.5 */ + +#endif /* NS_IMPL_COCOA */ + /* delegate method called when a submenu is being opened: run a 'deep' call to set_frame_menubar */ - (void)menuNeedsUpdate: (NSMenu *)menu @@ -722,6 +730,11 @@ extern NSString *NSMenuDidBeginTrackingNotification; - (void)fillWithWidgetValue: (void *)wvptr { + [self fillWithWidgetValue: wvptr frame:nil]; +} + +- (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f +{ widget_value *wv = (widget_value *)wvptr; /* clear existing contents */ @@ -735,7 +748,12 @@ extern NSString *NSMenuDidBeginTrackingNotification; if (wv->contents) { - EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; + EmacsMenu *submenu; + + if (f) + submenu = [[EmacsMenu alloc] initWithTitle: [item title] frame:f]; + else + submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; [self setSubmenu: submenu forItem: item]; [submenu fillWithWidgetValue: wv->contents]; @@ -806,7 +824,7 @@ extern NSString *NSMenuDidBeginTrackingNotification; ========================================================================== */ Lisp_Object -ns_menu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, +ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, Lisp_Object title, const char **error) { EmacsMenu *pmenu; @@ -1028,7 +1046,7 @@ ns_menu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, ========================================================================== */ void -free_frame_tool_bar (FRAME_PTR f) +free_frame_tool_bar (struct frame *f) /* -------------------------------------------------------------------------- Under NS we just hide the toolbar until it might be needed again. -------------------------------------------------------------------------- */ @@ -1040,7 +1058,7 @@ free_frame_tool_bar (FRAME_PTR f) } void -update_frame_tool_bar (FRAME_PTR f) +update_frame_tool_bar (struct frame *f) /* -------------------------------------------------------------------------- Update toolbar contents -------------------------------------------------------------------------- */ @@ -1665,7 +1683,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) } if (buttons > 0) - button_values = (Lisp_Object *) xmalloc (buttons * sizeof (*button_values)); + button_values = xmalloc (buttons * sizeof *button_values); for (; XTYPE (list) == Lisp_Cons; list = XCDR (list)) { diff --git a/src/nsterm.h b/src/nsterm.h index 745b8a4145b..c34067991f6 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -53,9 +53,24 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ /* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some versions. - On Cocoa, functions expect CGFloat*. Make compatible type. */ -#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \ - GNUSTEP_GUI_MINOR_VERSION >= 22 + On Cocoa >= 10.5, functions expect CGFloat*. Make compatible type. */ +#ifdef NS_IMPL_COCOA + +#ifndef NS_HAVE_NSINTEGER +#if defined (__LP64__) && __LP64__ +typedef double CGFloat; +typedef long NSInteger; +typedef unsigned long NSUInteger; +#else +typedef float CGFloat; +typedef int NSInteger; +typedef unsigned int NSUInteger; +#endif /* not LP64 */ +#endif /* not NS_HAVE_NSINTEGER */ + +typedef CGFloat EmacsCGFloat; + +#elif GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 22 typedef CGFloat EmacsCGFloat; #else typedef float EmacsCGFloat; @@ -109,7 +124,10 @@ typedef float EmacsCGFloat; @interface EmacsView : NSView <NSTextInput> #endif { +#ifdef NS_IMPL_COCOA char *old_title; + BOOL maximizing_resize; +#endif BOOL windowClosing; NSString *workingText; BOOL processingCompose; @@ -193,6 +211,7 @@ typedef float EmacsCGFloat; - (NSString *)parseKeyEquiv: (const char *)key; - (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr; - (void)fillWithWidgetValue: (void *)wvptr; +- (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f; - (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f; - (void) clear; - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f @@ -420,18 +439,6 @@ extern EmacsMenu *mainMenu, *svcsMenu, *dockMenu; @end #endif -#ifndef NS_HAVE_NSINTEGER -#if defined (__LP64__) && __LP64__ -typedef double CGFloat; -typedef long NSInteger; -typedef unsigned long NSUInteger; -#else -typedef float CGFloat; -typedef int NSInteger; -typedef unsigned int NSUInteger; -#endif /* not LP64 */ -#endif /* not NS_HAVE_NSINTEGER */ - #endif /* __OBJC__ */ @@ -778,7 +785,7 @@ void ns_dump_glyphstring (struct glyph_string *s); /* Implemented in nsterm, published in or needed from nsfns. */ extern Lisp_Object Qfontsize; -extern Lisp_Object ns_list_fonts (FRAME_PTR f, Lisp_Object pattern, +extern Lisp_Object ns_list_fonts (struct frame *f, Lisp_Object pattern, int size, int maxnames); extern void ns_clear_frame (struct frame *f); @@ -824,11 +831,11 @@ extern void ns_release_autorelease_pool (void *); extern const char *ns_get_defaults_value (const char *key); /* in nsmenu */ -extern void update_frame_tool_bar (FRAME_PTR f); -extern void free_frame_tool_bar (FRAME_PTR f); -extern void find_and_call_menu_selection (FRAME_PTR f, +extern void update_frame_tool_bar (struct frame *f); +extern void free_frame_tool_bar (struct frame *f); +extern void find_and_call_menu_selection (struct frame *f, int menu_bar_items_used, Lisp_Object vector, void *client_data); -extern Lisp_Object find_and_return_menu_selection (FRAME_PTR f, +extern Lisp_Object find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data); extern Lisp_Object ns_popup_dialog (Lisp_Object position, Lisp_Object contents, diff --git a/src/nsterm.m b/src/nsterm.m index 61538798337..f374bfd90c6 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -250,9 +250,6 @@ static int menu_will_open_state = MENU_NONE; /* Saved position for menu click. */ static CGPoint menu_mouse_point; - -/* Title for the menu to open. */ -static char *menu_pending_title = 0; #endif /* Convert modifiers in a NeXTstep event to emacs style modifiers. */ @@ -344,8 +341,8 @@ hold_event (struct input_event *event) { if (hold_event_q.cap == 0) hold_event_q.cap = 10; else hold_event_q.cap *= 2; - hold_event_q.q = (struct input_event *) - xrealloc (hold_event_q.q, hold_event_q.cap * sizeof (*hold_event_q.q)); + hold_event_q.q = + xrealloc (hold_event_q.q, hold_event_q.cap * sizeof *hold_event_q.q); } hold_event_q.q[hold_event_q.nr++] = *event; @@ -691,9 +688,18 @@ ns_update_begin (struct frame *f) { NSBezierPath *bp; NSRect r = [view frame]; - bp = [[NSBezierPath bezierPathWithRect: r] retain]; - [bp setClip]; - [bp release]; + NSRect cr = [[view window] frame]; + /* If a large frame size is set, r may be larger than the window frame + before constrained. In that case don't change the clip path, as we + will clear in to the tool bar and title bar. */ + if (r.size.height + + FRAME_NS_TITLEBAR_HEIGHT (f) + + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) + { + bp = [[NSBezierPath bezierPathWithRect: r] retain]; + [bp setClip]; + [bp release]; + } } #endif @@ -711,9 +717,9 @@ ns_update_window_begin (struct window *w) -------------------------------------------------------------------------- */ { struct frame *f = XFRAME (WINDOW_FRAME (w)); - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + NSTRACE (ns_update_window_begin); - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -770,7 +776,6 @@ ns_update_window_end (struct window *w, int cursor_on_p, hlinfo->mouse_face_window = Qnil; } - updated_window = NULL; NSTRACE (update_window_end); } @@ -785,9 +790,9 @@ ns_update_end (struct frame *f) EmacsView *view = FRAME_NS_VIEW (f); /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ - MOUSE_HL_INFO (f)->mouse_face_defer = 0; + MOUSE_HL_INFO (f)->mouse_face_defer = 0; - block_input (); + block_input (); [view unlockFocus]; [[view window] flushWindow]; @@ -1353,7 +1358,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) static void -ns_fullscreen_hook (FRAME_PTR f) +ns_fullscreen_hook (struct frame *f) { EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); @@ -1883,10 +1888,9 @@ ns_frame_up_to_date (struct frame *f) { block_input (); ns_update_begin(f); - if (hlinfo->mouse_face_mouse_frame) - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, - hlinfo->mouse_face_mouse_x, - hlinfo->mouse_face_mouse_y); + note_mouse_highlight (hlinfo->mouse_face_mouse_frame, + hlinfo->mouse_face_mouse_x, + hlinfo->mouse_face_mouse_y); ns_update_end(f); unblock_input (); } @@ -2085,7 +2089,6 @@ ns_scroll_run (struct window *w, struct run *run) block_input (); - updated_window = w; x_clear_cursor (w); { @@ -2103,12 +2106,11 @@ ns_scroll_run (struct window *w, struct run *run) static void -ns_after_update_window_line (struct glyph_row *desired_row) +ns_after_update_window_line (struct window *w, struct glyph_row *desired_row) /* -------------------------------------------------------------------------- External (RIF): preparatory to fringe update after text was updated -------------------------------------------------------------------------- */ { - struct window *w = updated_window; struct frame *f; int width, height; @@ -3392,12 +3394,6 @@ check_native_fs () /* GNUStep and OSX <= 10.4 does not have cancelTracking. */ #if defined (NS_IMPL_COCOA) && \ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 -const char * -ns_get_pending_menu_title () -{ - return menu_pending_title; -} - /* Check if menu open should be cancelled or continued as normal. */ void ns_check_menu_open (NSMenu *menu) @@ -3406,6 +3402,14 @@ ns_check_menu_open (NSMenu *menu) NSArray *a = [[NSApp mainMenu] itemArray]; int i; BOOL found = NO; + + if (menu == nil) // Menu tracking ended. + { + if (menu_will_open_state == MENU_OPENING) + menu_will_open_state = MENU_NONE; + return; + } + for (i = 0; ! found && i < [a count]; i++) found = menu == [[a objectAtIndex:i] submenu]; if (found) @@ -3423,8 +3427,6 @@ ns_check_menu_open (NSMenu *menu) CGEventRef ourEvent = CGEventCreate (NULL); menu_mouse_point = CGEventGetLocation (ourEvent); CFRelease (ourEvent); - xfree (menu_pending_title); - menu_pending_title = xstrdup ([[menu title] UTF8String]); } else if (menu_will_open_state == MENU_OPENING) { @@ -3738,16 +3740,7 @@ ns_set_vertical_scroll_bar (struct window *window, v = [view frame]; r.origin.y = (v.size.height - r.size.height - r.origin.y); - if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (window)) - fringe_extended_p = (WINDOW_LEFTMOST_P (window) - && WINDOW_LEFT_FRINGE_WIDTH (window) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window) - || WINDOW_LEFT_MARGIN_COLS (window) == 0)); - else - fringe_extended_p = (WINDOW_RIGHTMOST_P (window) - && WINDOW_RIGHT_FRINGE_WIDTH (window) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window) - || WINDOW_RIGHT_MARGIN_COLS (window) == 0)); + fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (window); XSETWINDOW (win, window); block_input (); @@ -3863,15 +3856,6 @@ ns_judge_scroll_bars (struct frame *f) [eview updateFrameSize: NO]; } - -void -x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) -{ - /* XXX irrelevant under NS */ -} - - - /* ========================================================================== Initialization @@ -4473,9 +4457,9 @@ ns_term_shutdown (int sig) #ifdef NS_IMPL_COCOA /* If no dialog and none of our frames have focus and it is a move, skip it. - It is a mouse move in an auxillary menu, i.e. on the top right on OSX, + It is a mouse move in an auxiliary menu, i.e. on the top right on OSX, such as Wifi, sound, date or similar. - This prevents "spooky" highlightning in the frame under the menu. */ + This prevents "spooky" highlighting in the frame under the menu. */ if (type == NSMouseMoved && [NSApp modalWindow] == nil) { struct ns_display_info *di; @@ -5673,17 +5657,17 @@ not_in_argv (NSString *arg) old_title = 0; } } - else + else if (fs_state == FULLSCREEN_NONE && ! maximizing_resize) { char *size_title; NSWindow *window = [self window]; if (old_title == 0) { - const char *t = [[[self window] title] UTF8String]; + char *t = strdup ([[[self window] title] UTF8String]); char *pos = strstr (t, " — "); if (pos) *pos = '\0'; - old_title = xstrdup (t); + old_title = t; } size_title = xmalloc (strlen (old_title) + 40); esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); @@ -5722,21 +5706,27 @@ not_in_argv (NSString *arg) NSTRACE (windowDidResize); /*fprintf (stderr,"windowDidResize: %.0f\n",[theWindow frame].size.height); */ +if (cols > 0 && rows > 0) + { + [self updateFrameSize: YES]; + } + + ns_send_appdefined (-1); +} + #ifdef NS_IMPL_COCOA +- (void)viewDidEndLiveResize +{ + [super viewDidEndLiveResize]; if (old_title != 0) { + [[self window] setTitle: [NSString stringWithUTF8String: old_title]]; xfree (old_title); old_title = 0; } -#endif /* NS_IMPL_COCOA */ - - if (cols > 0 && rows > 0) - { - [self updateFrameSize: YES]; - } - - ns_send_appdefined (-1); + maximizing_resize = NO; } +#endif /* NS_IMPL_COCOA */ - (void)windowDidBecomeKey: (NSNotification *)notification @@ -5841,7 +5831,10 @@ not_in_argv (NSString *arg) FRAME_NS_VIEW (f) = self; emacsframe = f; +#ifdef NS_IMPL_COCOA old_title = 0; + maximizing_resize = NO; +#endif win = [[EmacsWindow alloc] initWithContentRect: r @@ -5984,6 +5977,9 @@ not_in_argv (NSString *arg) maximized_width = -1; result.origin.y = defaultFrame.origin.y; [self setFSValue: FULLSCREEN_HEIGHT]; +#ifdef NS_IMPL_COCOA + maximizing_resize = YES; +#endif } else if (next_maximized == FULLSCREEN_WIDTH) { @@ -6002,12 +5998,18 @@ not_in_argv (NSString *arg) maximized_width = result.size.width; maximized_height = result.size.height; [self setFSValue: FULLSCREEN_MAXIMIZED]; +#ifdef NS_IMPL_COCOA + maximizing_resize = YES; +#endif } else { /* restore */ result = ns_userRect.size.height ? ns_userRect : result; ns_userRect = NSMakeRect (0, 0, 0, 0); +#ifdef NS_IMPL_COCOA + maximizing_resize = fs_state != FULLSCREEN_NONE; +#endif [self setFSValue: FULLSCREEN_NONE]; maximized_width = maximized_height = -1; } diff --git a/src/process.c b/src/process.c index 33d8ccbbc35..91483e5839f 100644 --- a/src/process.c +++ b/src/process.c @@ -92,6 +92,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <c-ctype.h> #include <sig2str.h> +#include <verify.h> #endif /* subprocesses */ @@ -301,7 +302,7 @@ static void exec_sentinel (Lisp_Object proc, Lisp_Object reason); static int num_pending_connects; #endif /* NON_BLOCKING_CONNECT */ -/* The largest descriptor currently in use for input. */ +/* The largest descriptor currently in use; -1 if none. */ static int max_desc; /* Indexed by descriptor, gives the process (if any) for that descriptor */ @@ -335,6 +336,12 @@ static struct sockaddr_and_len { #define DATAGRAM_CONN_P(proc) (0) #endif +/* FOR_EACH_PROCESS (LIST_VAR, PROC_VAR) followed by a statement is + a `for' loop which iterates over processes from Vprocess_alist. */ + +#define FOR_EACH_PROCESS(list_var, proc_var) \ + FOR_EACH_ALIST_VALUE (Vprocess_alist, list_var, proc_var) + /* These setters are used only in this file, so they can be private. */ static void pset_buffer (struct Lisp_Process *p, Lisp_Object val) @@ -543,6 +550,22 @@ recompute_max_desc (void) } } +/* FD is no longer an input descriptor; update max_input_desc accordingly. */ + +static void +delete_input_desc (int fd) +{ + if (fd == max_input_desc) + { + do + fd--; + while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask) + || FD_ISSET (fd, &write_mask))); + + max_input_desc = fd; + } +} + /* Stop monitoring file descriptor FD for when write is possible. */ void @@ -862,6 +885,8 @@ make_process (Lisp_Object name) non-Lisp data, so do it only for slots which should not be zero. */ p->infd = -1; p->outfd = -1; + for (i = 0; i < PROCESS_OPEN_FDS; i++) + p->open_fd[i] = -1; #ifdef HAVE_GNUTLS p->gnutls_initstage = GNUTLS_STAGE_EMPTY; @@ -979,13 +1004,17 @@ get_process (register Lisp_Object name) treated by the SIGCHLD handler and waitpid has been invoked on them; otherwise they might fill up the kernel's process table. - Some processes created by call-process are also put onto this list. */ + Some processes created by call-process are also put onto this list. + + Members of this list are (process-ID . filename) pairs. The + process-ID is a number; the filename, if a string, is a file that + needs to be removed after the process exits. */ static Lisp_Object deleted_pid_list; void -record_deleted_pid (pid_t pid) +record_deleted_pid (pid_t pid, Lisp_Object filename) { - deleted_pid_list = Fcons (make_fixnum_or_float (pid), + deleted_pid_list = Fcons (Fcons (make_fixnum_or_float (pid), filename), /* GC treated elements set to nil. */ Fdelq (Qnil, deleted_pid_list)); @@ -1013,7 +1042,7 @@ nil, indicating the current buffer's process. */) else { if (p->alive) - record_kill_process (p); + record_kill_process (p, Qnil); if (p->infd >= 0) { @@ -1796,17 +1825,45 @@ start_process_unwind (Lisp_Object proc) remove_process (proc); } +/* If *FD_ADDR is nonnegative, close it, and mark it as closed. */ + +static void +close_process_fd (int *fd_addr) +{ + int fd = *fd_addr; + if (0 <= fd) + { + *fd_addr = -1; + emacs_close (fd); + } +} + +/* Indexes of file descriptors in open_fds. */ +enum + { + /* The pipe from Emacs to its subprocess. */ + SUBPROCESS_STDIN, + WRITE_TO_SUBPROCESS, + + /* The main pipe from the subprocess to Emacs. */ + READ_FROM_SUBPROCESS, + SUBPROCESS_STDOUT, + + /* The pipe from the subprocess to Emacs that is closed when the + subprocess execs. */ + READ_FROM_EXEC_MONITOR, + EXEC_MONITOR_OUTPUT + }; + +verify (PROCESS_OPEN_FDS == EXEC_MONITOR_OUTPUT + 1); static void create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) { + struct Lisp_Process *p = XPROCESS (process); int inchannel, outchannel; pid_t pid; int vfork_errno; - int sv[2]; -#ifndef WINDOWSNT - int wait_child_setup[2]; -#endif int forkin, forkout; bool pty_flag = 0; char pty_name[PTY_NAME_SIZE]; @@ -1820,6 +1877,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) if (inchannel >= 0) { + p->open_fd[READ_FROM_SUBPROCESS] = inchannel; #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ @@ -1828,6 +1886,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); if (forkin < 0) report_file_error ("Opening pty", Qnil); + p->open_fd[SUBPROCESS_STDIN] = forkin; #else forkin = forkout = -1; #endif /* not USG, or USG_SUBTTY_WORKS */ @@ -1836,23 +1895,17 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) } else { - if (emacs_pipe (sv) != 0) + if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 + || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) report_file_error ("Creating pipe", Qnil); - inchannel = sv[0]; - forkout = sv[1]; - if (emacs_pipe (sv) != 0) - { - int pipe_errno = errno; - emacs_close (inchannel); - emacs_close (forkout); - report_file_errno ("Creating pipe", Qnil, pipe_errno); - } - outchannel = sv[1]; - forkin = sv[0]; + forkin = p->open_fd[SUBPROCESS_STDIN]; + outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; + inchannel = p->open_fd[READ_FROM_SUBPROCESS]; + forkout = p->open_fd[SUBPROCESS_STDOUT]; } #ifndef WINDOWSNT - if (emacs_pipe (wait_child_setup) != 0) + if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0) report_file_error ("Creating pipe", Qnil); #endif @@ -1861,16 +1914,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* Record this as an active process, with its channels. */ chan_process[inchannel] = process; - XPROCESS (process)->infd = inchannel; - XPROCESS (process)->outfd = outchannel; + p->infd = inchannel; + p->outfd = outchannel; /* Previously we recorded the tty descriptor used in the subprocess. It was only used for getting the foreground tty process, so now we just reopen the device (see emacs_get_tty_pgrp) as this is more portable (see USG_SUBTTY_WORKS above). */ - XPROCESS (process)->pty_flag = pty_flag; - pset_status (XPROCESS (process), Qrun); + p->pty_flag = pty_flag; + pset_status (p, Qrun); add_process_read_fd (inchannel); @@ -1887,25 +1940,21 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) { Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; - Lisp_Object volatile process_volatile = process; char **volatile new_argv_volatile = new_argv; int volatile forkin_volatile = forkin; int volatile forkout_volatile = forkout; - int volatile wait_child_setup_0_volatile = wait_child_setup[0]; - int volatile wait_child_setup_1_volatile = wait_child_setup[1]; + struct Lisp_Process *p_volatile = p; pid = vfork (); encoded_current_dir = encoded_current_dir_volatile; lisp_pty_name = lisp_pty_name_volatile; - process = process_volatile; new_argv = new_argv_volatile; forkin = forkin_volatile; forkout = forkout_volatile; - wait_child_setup[0] = wait_child_setup_0_volatile; - wait_child_setup[1] = wait_child_setup_1_volatile; + p = p_volatile; - pty_flag = XPROCESS (process)->pty_flag; + pty_flag = p->pty_flag; } if (pid == 0) @@ -2021,42 +2070,42 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* Back in the parent process. */ vfork_errno = errno; - XPROCESS (process)->pid = pid; + p->pid = pid; if (pid >= 0) - XPROCESS (process)->alive = 1; + p->alive = 1; /* Stop blocking in the parent. */ unblock_child_signal (); unblock_input (); - if (forkin >= 0) - emacs_close (forkin); - if (forkin != forkout && forkout >= 0) - emacs_close (forkout); - if (pid < 0) report_file_errno ("Doing vfork", Qnil, vfork_errno); else { /* vfork succeeded. */ + /* Close the pipe ends that the child uses, or the child's pty. */ + close_process_fd (&p->open_fd[SUBPROCESS_STDIN]); + close_process_fd (&p->open_fd[SUBPROCESS_STDOUT]); + #ifdef WINDOWSNT register_child (pid, inchannel); #endif /* WINDOWSNT */ - pset_tty_name (XPROCESS (process), lisp_pty_name); + pset_tty_name (p, lisp_pty_name); #ifndef WINDOWSNT /* Wait for child_setup to complete in case that vfork is - actually defined as fork. The descriptor wait_child_setup[1] + actually defined as fork. The descriptor + XPROCESS (proc)->open_fd[EXEC_MONITOR_OUTPUT] of a pipe is closed at the child side either by close-on-exec on successful execve or the _exit call in child_setup. */ { char dummy; - emacs_close (wait_child_setup[1]); - emacs_read (wait_child_setup[0], &dummy, 1); - emacs_close (wait_child_setup[0]); + close_process_fd (&p->open_fd[EXEC_MONITOR_OUTPUT]); + emacs_read (p->open_fd[READ_FROM_EXEC_MONITOR], &dummy, 1); + close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); } #endif } @@ -2065,16 +2114,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) static void create_pty (Lisp_Object process) { + struct Lisp_Process *p = XPROCESS (process); char pty_name[PTY_NAME_SIZE]; - int inchannel, outchannel; - - inchannel = outchannel = -1; - - if (!NILP (Vprocess_connection_type)) - outchannel = inchannel = allocate_pty (pty_name); + int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name); - if (inchannel >= 0) + if (pty_fd >= 0) { + p->open_fd[SUBPROCESS_STDIN] = pty_fd; #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ @@ -2083,6 +2129,7 @@ create_pty (Lisp_Object process) int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); if (forkout < 0) report_file_error ("Opening pty", Qnil); + p->open_fd[WRITE_TO_SUBPROCESS] = forkout; #if defined (DONT_REOPEN_PTY) /* In the case that vfork is defined as fork, the parent process (Emacs) may send some data before the child process completes @@ -2091,28 +2138,29 @@ create_pty (Lisp_Object process) #endif /* DONT_REOPEN_PTY */ #endif /* not USG, or USG_SUBTTY_WORKS */ - fcntl (inchannel, F_SETFL, O_NONBLOCK); - fcntl (outchannel, F_SETFL, O_NONBLOCK); + fcntl (pty_fd, F_SETFL, O_NONBLOCK); /* Record this as an active process, with its channels. As a result, child_setup will close Emacs's side of the pipes. */ - chan_process[inchannel] = process; - XPROCESS (process)->infd = inchannel; - XPROCESS (process)->outfd = outchannel; + chan_process[pty_fd] = process; + p->infd = pty_fd; + p->outfd = pty_fd; /* Previously we recorded the tty descriptor used in the subprocess. It was only used for getting the foreground tty process, so now we just reopen the device (see emacs_get_tty_pgrp) as this is more portable (see USG_SUBTTY_WORKS above). */ - XPROCESS (process)->pty_flag = 1; - pset_status (XPROCESS (process), Qrun); + p->pty_flag = 1; + pset_status (p, Qrun); setup_process_coding_systems (process); - pset_tty_name (XPROCESS (process), build_string (pty_name)); + fixme; + + pset_tty_name (p, build_string (pty_name)); } - XPROCESS (process)->pid = -2; + p->pid = -2; } @@ -2718,6 +2766,7 @@ usage: (make-serial-process &rest ARGS) */) p = XPROCESS (proc); fd = serial_open (port); + p->open_fd[SUBPROCESS_STDIN] = fd; p->infd = fd; p->outfd = fd; if (fd > max_desc) @@ -3477,12 +3526,6 @@ usage: (make-network-process &rest ARGS) */) } #endif - /* Discard the unwind protect for closing S, if any. */ - specpdl_ptr = specpdl + count1; - - /* Unwind bind_polling_period and request_sigio. */ - unbind_to (count, Qnil); - if (s < 0) { /* If non-blocking got this far - and failed - assume non-blocking is @@ -3524,8 +3567,17 @@ usage: (make-network-process &rest ARGS) */) if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) pset_command (p, Qt); p->pid = 0; + + p->open_fd[SUBPROCESS_STDIN] = inch; p->infd = inch; p->outfd = outch; + + /* Discard the unwind protect for closing S, if any. */ + specpdl_ptr = specpdl + count1; + + /* Unwind bind_polling_period and request_sigio. */ + unbind_to (count, Qnil); + if (is_server && socktype != SOCK_DGRAM) pset_status (p, Qlisten); @@ -3957,17 +4009,15 @@ FLAGS is the current flags of the interface. */) static void deactivate_process (Lisp_Object proc) { - register int inchannel, outchannel; - register struct Lisp_Process *p = XPROCESS (proc); + int inchannel; + struct Lisp_Process *p = XPROCESS (proc); + int i; #ifdef HAVE_GNUTLS /* Delete GnuTLS structures in PROC, if any. */ emacs_gnutls_deinit (proc); #endif /* HAVE_GNUTLS */ - inchannel = p->infd; - outchannel = p->outfd; - #ifdef ADAPTIVE_READ_BUFFERING if (p->read_output_delay > 0) { @@ -3978,14 +4028,17 @@ deactivate_process (Lisp_Object proc) } #endif + inchannel = p->infd; + + /* Beware SIGCHLD hereabouts. */ if (inchannel >= 0) - { - /* Beware SIGCHLD hereabouts. */ - flush_pending_output (inchannel); - emacs_close (inchannel); - if (outchannel >= 0 && outchannel != inchannel) - emacs_close (outchannel); + flush_pending_output (inchannel); + for (i = 0; i < PROCESS_OPEN_FDS; i++) + close_process_fd (&p->open_fd[i]); + + if (inchannel >= 0) + { p->infd = -1; p->outfd = -1; #ifdef DATAGRAM_SOCKETS @@ -4263,6 +4316,7 @@ server_accept_connection (Lisp_Object server, int channel) /* Discard the unwind protect for closing S. */ specpdl_ptr = specpdl + count; + p->open_fd[SUBPROCESS_STDIN] = s; p->infd = s; p->outfd = s; pset_status (p, Qrun); @@ -4682,7 +4736,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, #endif , max_desc + 1, &Available, - (check_write ? &Writeok : (SELECT_TYPE *)0), + (check_write ? &Writeok : 0), NULL, &timeout, NULL); #ifdef HAVE_GNUTLS @@ -6160,7 +6214,8 @@ process has been transmitted to the serial port. */) } else { - int old_outfd, new_outfd; + int old_outfd = XPROCESS (proc)->outfd; + int new_outfd; #ifdef HAVE_SHUTDOWN /* If this is a network connection, or socketpair is used @@ -6168,18 +6223,15 @@ process has been transmitted to the serial port. */) (In some old system, shutdown to socketpair doesn't work. Then we just can't win.) */ if (EQ (XPROCESS (proc)->type, Qnetwork) - || XPROCESS (proc)->outfd == XPROCESS (proc)->infd) - shutdown (XPROCESS (proc)->outfd, 1); - /* In case of socketpair, outfd == infd, so don't close it. */ - if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd) - emacs_close (XPROCESS (proc)->outfd); -#else /* not HAVE_SHUTDOWN */ - emacs_close (XPROCESS (proc)->outfd); -#endif /* not HAVE_SHUTDOWN */ + || XPROCESS (proc)->infd == old_outfd) + shutdown (old_outfd, 1); +#endif + close_process_fd (&XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS]); new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); if (new_outfd < 0) - emacs_abort (); - old_outfd = XPROCESS (proc)->outfd; + report_file_error ("Opening null device", Qnil); + XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS] = new_outfd; + XPROCESS (proc)->outfd = new_outfd; if (!proc_encode_coding_system[new_outfd]) proc_encode_coding_system[new_outfd] @@ -6188,8 +6240,6 @@ process has been transmitted to the serial port. */) = *proc_encode_coding_system[old_outfd]; memset (proc_encode_coding_system[old_outfd], 0, sizeof (struct coding_system)); - - XPROCESS (proc)->outfd = new_outfd; } return process; } @@ -6255,7 +6305,7 @@ static signal_handler_t volatile lib_child_handler; static void handle_child_signal (int sig) { - Lisp_Object tail; + Lisp_Object tail, proc; /* Find the process that signaled us, and record its status. */ @@ -6266,7 +6316,11 @@ handle_child_signal (int sig) bool all_pids_are_fixnums = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); - Lisp_Object xpid = XCAR (tail); + Lisp_Object head = XCAR (tail); + Lisp_Object xpid; + if (! CONSP (head)) + continue; + xpid = XCAR (head); if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) { pid_t deleted_pid; @@ -6275,14 +6329,17 @@ handle_child_signal (int sig) else deleted_pid = XFLOAT_DATA (xpid); if (child_status_changed (deleted_pid, 0, 0)) - XSETCAR (tail, Qnil); + { + if (STRINGP (XCDR (head))) + unlink (SSDATA (XCDR (head))); + XSETCAR (tail, Qnil); + } } } /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_PROCESS (tail, proc) { - Lisp_Object proc = XCDR (XCAR (tail)); struct Lisp_Process *p = XPROCESS (proc); int status; @@ -6434,13 +6491,10 @@ status_notify (struct Lisp_Process *deleting_process) that we run, we get called again to handle their status changes. */ update_tick = process_tick; - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_PROCESS (tail, proc) { Lisp_Object symbol; - register struct Lisp_Process *p; - - proc = Fcdr (XCAR (tail)); - p = XPROCESS (proc); + register struct Lisp_Process *p = XPROCESS (proc); if (p->tick != p->update_tick) { @@ -6970,12 +7024,9 @@ BUFFER may be a buffer or the name of one. */) buf = Fget_buffer (buffer); if (NILP (buf)) return Qnil; - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) - { - proc = Fcdr (XCAR (tail)); - if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf)) - return proc; - } + FOR_EACH_PROCESS (tail, proc) + if (EQ (XPROCESS (proc)->buffer, buf)) + return proc; #endif /* subprocesses */ return Qnil; } @@ -7008,18 +7059,14 @@ kill_buffer_processes (Lisp_Object buffer) #ifdef subprocesses Lisp_Object tail, proc; - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) - { - proc = XCDR (XCAR (tail)); - if (PROCESSP (proc) - && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) - { - if (NETCONN_P (proc) || SERIALCONN_P (proc)) - Fdelete_process (proc); - else if (XPROCESS (proc)->infd >= 0) - process_send_signal (proc, SIGHUP, Qnil, 1); - } - } + FOR_EACH_PROCESS (tail, proc) + if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) + { + if (NETCONN_P (proc) || SERIALCONN_P (proc)) + Fdelete_process (proc); + else if (XPROCESS (proc)->infd >= 0) + process_send_signal (proc, SIGHUP, Qnil, 1); + } #else /* subprocesses */ /* Since we have no subprocesses, this does nothing. */ #endif /* subprocesses */ @@ -7183,7 +7230,7 @@ init_process_emacs (void) catch_child_signal (); } - max_desc = 0; + max_desc = -1; memset (fd_callback_info, 0, sizeof (fd_callback_info)); #ifdef NON_BLOCKING_CONNECT diff --git a/src/process.h b/src/process.h index 89c7e8b1259..95881d10f58 100644 --- a/src/process.h +++ b/src/process.h @@ -31,6 +31,11 @@ INLINE_HEADER_BEGIN # define PROCESS_INLINE INLINE #endif +/* Bound on number of file descriptors opened on behalf of a process, + that need to be closed. */ + +enum { PROCESS_OPEN_FDS = 6 }; + /* This structure records information about a subprocess or network connection. */ @@ -118,6 +123,9 @@ struct Lisp_Process int infd; /* Descriptor by which we write to this process */ int outfd; + /* Descriptors that were created for this process and that need + closing. Unused entries are negative. */ + int open_fd[PROCESS_OPEN_FDS]; /* Event-count of last event in which this process changed status. */ EMACS_INT tick; /* Event-count of last such event reported. */ @@ -213,13 +221,16 @@ enum extern void block_child_signal (void); extern void unblock_child_signal (void); -extern void record_kill_process (struct Lisp_Process *); +extern void record_kill_process (struct Lisp_Process *, Lisp_Object); -/* Defined in process.c. */ +/* Defined in sysdep.c. */ extern Lisp_Object list_system_processes (void); extern Lisp_Object system_process_attributes (Lisp_Object); +/* Defined in process.c. */ + +extern void record_deleted_pid (pid_t, Lisp_Object); extern void hold_keyboard_input (void); extern void unhold_keyboard_input (void); extern bool kbd_on_hold_p (void); diff --git a/src/regex.c b/src/regex.c index 5024f748884..75661a27892 100644 --- a/src/regex.c +++ b/src/regex.c @@ -468,7 +468,7 @@ init_syntax_once (void) /* Assumes a `char *destination' variable. */ # define REGEX_REALLOCATE(source, osize, nsize) \ - (destination = (char *) alloca (nsize), \ + (destination = alloca (nsize), \ memcpy (destination, source, osize)) /* No need to do anything to free, after alloca. */ @@ -4212,7 +4212,7 @@ re_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs, uns { bufp->regs_allocated = REGS_UNALLOCATED; regs->num_regs = 0; - regs->start = regs->end = (regoff_t *) 0; + regs->start = regs->end = 0; } } WEAK_ALIAS (__re_set_registers, re_set_registers) @@ -6393,8 +6393,7 @@ weak_function re_exec (const char *s) { const size_t len = strlen (s); - return (re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0) - >= 0); + return re_search (&re_comp_buf, s, len, 0, len, 0) >= 0; } #endif /* _REGEX_RE_COMP */ @@ -6558,7 +6557,7 @@ regexec (const regex_t *_Restrict_ preg, const char *_Restrict_ string, /* Perform the searching operation. */ ret = re_search (&private_preg, string, len, /* start: */ 0, /* range: */ len, - want_reg_info ? ®s : (struct re_registers *) 0); + want_reg_info ? ®s : 0); /* Copy the register information to the POSIX structure. */ if (want_reg_info) diff --git a/src/scroll.c b/src/scroll.c index 037e338c696..b9ed8c04ba8 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -86,7 +86,7 @@ static void do_scrolling (struct frame *, new contents appears. */ static void -calculate_scrolling (FRAME_PTR frame, +calculate_scrolling (struct frame *frame, /* matrix is of size window_size + 1 on each side. */ struct matrix_elt *matrix, int window_size, int lines_below, @@ -422,7 +422,7 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix, is the equivalent of draw_cost for the old line contents */ static void -calculate_direct_scrolling (FRAME_PTR frame, +calculate_direct_scrolling (struct frame *frame, /* matrix is of size window_size + 1 on each side. */ struct matrix_elt *matrix, int window_size, int lines_below, @@ -652,8 +652,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix, /* A queue of deletions and insertions to be performed. */ struct alt_queue { int count, pos, window; }; - struct alt_queue *queue_start = (struct alt_queue *) - alloca (window_size * sizeof *queue_start); + struct alt_queue *queue_start = alloca (window_size * sizeof *queue_start); struct alt_queue *queue = queue_start; /* True if a terminal window has been set with set_terminal_window. */ @@ -793,13 +792,12 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix, void -scrolling_1 (FRAME_PTR frame, int window_size, int unchanged_at_top, +scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top, int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, int *old_hash, int *new_hash, int free_at_end) { - struct matrix_elt *matrix; - matrix = ((struct matrix_elt *) - alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix)); + struct matrix_elt *matrix + = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix); if (FRAME_SCROLL_REGION_OK (frame)) { @@ -883,7 +881,7 @@ scrolling_max_lines_saved (int start, int end, overhead and multiply factor values */ static void -line_ins_del (FRAME_PTR frame, int ov1, int pf1, int ovn, int pfn, +line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn, register int *ov, register int *mf) { register int i; @@ -901,7 +899,7 @@ line_ins_del (FRAME_PTR frame, int ov1, int pf1, int ovn, int pfn, } static void -ins_del_costs (FRAME_PTR frame, +ins_del_costs (struct frame *frame, const char *one_line_string, const char *multi_string, const char *setup_string, const char *cleanup_string, int *costvec, int *ncostvec, @@ -957,7 +955,7 @@ ins_del_costs (FRAME_PTR frame, */ void -do_line_insertion_deletion_costs (FRAME_PTR frame, +do_line_insertion_deletion_costs (struct frame *frame, const char *ins_line_string, const char *multi_ins_string, const char *del_line_string, diff --git a/src/search.c b/src/search.c index e1147aca858..8916960cf62 100644 --- a/src/search.c +++ b/src/search.c @@ -598,14 +598,14 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, /* The newline cache: remembering which sections of text have no newlines. */ -/* If the user has requested newline caching, make sure it's on. +/* If the user has requested the long scans caching, make sure it's on. Otherwise, make sure it's off. This is our cheezy way of associating an action with the change of state of a buffer-local variable. */ static void newline_cache_on_off (struct buffer *buf) { - if (NILP (BVAR (buf, cache_long_line_scans))) + if (NILP (BVAR (buf, cache_long_scans))) { /* It should be off. */ if (buf->newline_cache) diff --git a/src/sheap.c b/src/sheap.c index 54eef60c27d..daff0c1d700 100644 --- a/src/sheap.c +++ b/src/sheap.c @@ -26,10 +26,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <unistd.h> #ifdef __x86_64__ +#ifdef ENABLE_CHECKING +#define STATIC_HEAP_SIZE (28 * 1024 * 1024) +#else +#define STATIC_HEAP_SIZE (19 * 1024 * 1024) +#endif +#else /* x86 */ +#ifdef ENABLE_CHECKING #define STATIC_HEAP_SIZE (18 * 1024 * 1024) #else #define STATIC_HEAP_SIZE (13 * 1024 * 1024) #endif +#endif /* x86 */ int debug_sheap = 0; @@ -37,6 +45,7 @@ int debug_sheap = 0; char bss_sbrk_buffer[STATIC_HEAP_SIZE]; char *bss_sbrk_ptr; +char *max_bss_sbrk_ptr; int bss_sbrk_did_unexec; void * @@ -44,7 +53,7 @@ bss_sbrk (ptrdiff_t request_size) { if (!bss_sbrk_ptr) { - bss_sbrk_ptr = bss_sbrk_buffer; + max_bss_sbrk_ptr = bss_sbrk_ptr = bss_sbrk_buffer; #ifdef CYGWIN sbrk (BLOCKSIZE); /* force space for fork to work */ #endif @@ -85,6 +94,8 @@ bss_sbrk (ptrdiff_t request_size) if (debug_sheap) printf ("allocated 0x%08x size %d\n", ret, request_size); bss_sbrk_ptr += (int) request_size; + if (bss_sbrk_ptr > max_bss_sbrk_ptr) + max_bss_sbrk_ptr = bss_sbrk_ptr; return ret; } } @@ -93,8 +104,8 @@ void report_sheap_usage (int die_if_pure_storage_exceeded) { char buf[200]; - sprintf (buf, "Static heap usage: %d of %d bytes", - bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); + sprintf (buf, "Maximum static heap usage: %d of %d bytes", + max_bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); /* Don't log messages, cause at this point, we're not allowed to create buffers. */ message1_nolog (buf); diff --git a/src/syntax.c b/src/syntax.c index 6d52d115889..f5b37303a4a 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -1464,6 +1464,7 @@ scan_words (register ptrdiff_t from, register EMACS_INT count) DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p", doc: /* Move point forward ARG words (backward if ARG is negative). +If ARG is omitted or nil, move point forward one word. Normally returns t. If an edge of the buffer or a field boundary is reached, point is left there and the function returns nil. Field boundaries are not noticed if diff --git a/src/sysdep.c b/src/sysdep.c index 11a6f4a76ce..201ba9d104d 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -3243,13 +3243,11 @@ system_process_attributes (Lisp_Object pid) attrs); decoded_cmd = (code_convert_string_norecord - (make_unibyte_string (pinfo.pr_fname, - strlen (pinfo.pr_fname)), + (build_unibyte_string (pinfo.pr_fname), Vlocale_coding_system, 0)); attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); decoded_cmd = (code_convert_string_norecord - (make_unibyte_string (pinfo.pr_psargs, - strlen (pinfo.pr_psargs)), + (build_unibyte_string (pinfo.pr_psargs), Vlocale_coding_system, 0)); attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); } @@ -3319,9 +3317,9 @@ system_process_attributes (Lisp_Object pid) if (gr) attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); - decoded_comm = code_convert_string_norecord - (make_unibyte_string (proc.ki_comm, strlen (proc.ki_comm)), - Vlocale_coding_system, 0); + decoded_comm = (code_convert_string_norecord + (build_unibyte_string (proc.ki_comm), + Vlocale_coding_system, 0)); attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); { diff --git a/src/syswait.h b/src/syswait.h index 03e5cb5fe2e..4ae9129d7ed 100644 --- a/src/syswait.h +++ b/src/syswait.h @@ -52,9 +52,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #define WTERMSIG(status) ((status) & 0x7f) #endif -/* Defined in process.c. */ -extern void record_deleted_pid (pid_t); - /* Defined in sysdep.c. */ extern void wait_for_termination (pid_t, int *, bool); extern pid_t child_status_changed (pid_t, int *, int); diff --git a/src/term.c b/src/term.c index 376d6e7831a..2966466aed2 100644 --- a/src/term.c +++ b/src/term.c @@ -2233,8 +2233,7 @@ get_named_tty (const char *name) { struct terminal *t; - if (!name) - emacs_abort (); + eassert (name); for (t = terminal_list; t; t = t->next_terminal) { @@ -2522,7 +2521,7 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, } static bool -term_mouse_movement (FRAME_PTR frame, Gpm_Event *event) +term_mouse_movement (struct frame *frame, Gpm_Event *event) { /* Has the mouse moved off the glyph it was on at the last sighting? */ if (event->x != last_mouse_x || event->y != last_mouse_y) @@ -2563,7 +2562,7 @@ timeval_to_Time (struct timeval const *t) This clears mouse_moved until the next motion event arrives. */ static void -term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, +term_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, Time *timeptr) { @@ -2786,8 +2785,7 @@ create_tty_output (struct frame *f) { struct tty_output *t = xzalloc (sizeof *t); - if (! FRAME_TERMCAP_P (f)) - emacs_abort (); + eassert (FRAME_TERMCAP_P (f)); t->display_info = FRAME_TERMINAL (f)->display_info.tty; @@ -2799,8 +2797,7 @@ create_tty_output (struct frame *f) static void tty_free_frame_resources (struct frame *f) { - if (! FRAME_TERMCAP_P (f)) - emacs_abort (); + eassert (FRAME_TERMCAP_P (f)); if (FRAME_FACE_CACHE (f)) free_frame_faces (f); @@ -2815,8 +2812,7 @@ tty_free_frame_resources (struct frame *f) static void tty_free_frame_resources (struct frame *f) { - if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f)) - emacs_abort (); + eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); if (FRAME_FACE_CACHE (f)) free_frame_faces (f); @@ -2933,7 +2929,7 @@ dissociate_if_controlling_tty (int fd) TERMINAL_TYPE is the termcap type of the device, e.g. "vt100". - If MUST_SUCCEED is true, then all errors are fatal. */ + If MUST_SUCCEED is true, then all errors are fatal. */ struct terminal * init_tty (const char *name, const char *terminal_type, bool must_succeed) @@ -2944,7 +2940,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) int status; struct tty_display_info *tty = NULL; struct terminal *terminal = NULL; - bool ctty = 0; /* True if asked to open controlling tty. */ + bool ctty = false; /* True if asked to open controlling tty. */ if (!terminal_type) maybe_fatal (must_succeed, 0, @@ -3031,7 +3027,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) tty->termcap_term_buffer = xmalloc (buffer_size); /* On some systems, tgetent tries to access the controlling - terminal. */ + terminal. */ block_tty_out_signal (); status = tgetent (tty->termcap_term_buffer, terminal_type); unblock_tty_out_signal (); @@ -3101,13 +3097,13 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ Right (tty) = tgetstr ("nd", address); Down (tty) = tgetstr ("do", address); if (!Down (tty)) - Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */ + Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do". */ if (tgetflag ("bs")) - Left (tty) = "\b"; /* can't possibly be longer! */ - else /* (Actually, "bs" is obsolete...) */ + Left (tty) = "\b"; /* Can't possibly be longer! */ + else /* (Actually, "bs" is obsolete...) */ Left (tty) = tgetstr ("le", address); if (!Left (tty)) - Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le" */ + Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le". */ tty->TS_pad_char = tgetstr ("pc", address); tty->TS_repeat = tgetstr ("rp", address); tty->TS_end_standout_mode = tgetstr ("se", address); @@ -3229,7 +3225,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ don't think we're losing anything by turning it off. */ terminal->line_ins_del_ok = 0; - tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ + tty->TN_max_colors = 16; /* Must be non-zero for tty-display-color-p. */ #endif /* DOS_NT */ #ifdef HAVE_GPM @@ -3325,16 +3321,16 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ tty->Wcm->cm_tab = 0; /* We can't support standout mode, because it uses magic cookies. */ tty->TS_standout_mode = 0; - /* But that means we cannot rely on ^M to go to column zero! */ + /* But that means we cannot rely on ^M to go to column zero! */ CR (tty) = 0; - /* LF can't be trusted either -- can alter hpos */ - /* if move at column 0 thru a line with TS_standout_mode */ + /* LF can't be trusted either -- can alter hpos. */ + /* If move at column 0 thru a line with TS_standout_mode. */ Down (tty) = 0; } tty->specified_window = FrameRows (tty); - if (Wcm_init (tty) == -1) /* can't do cursor motion */ + if (Wcm_init (tty) == -1) /* Can't do cursor motion. */ { maybe_fatal (must_succeed, terminal, "Terminal type \"%s\" is not powerful enough to run Emacs", @@ -3443,8 +3439,7 @@ delete_tty (struct terminal *terminal) if (!terminal->name) return; - if (terminal->type != output_termcap) - emacs_abort (); + eassert (terminal->type == output_termcap); tty = terminal->display_info.tty; diff --git a/src/termcap.c b/src/termcap.c index be05828eea6..aa225d9b3b1 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -406,7 +406,7 @@ tgetent (char *bp, const char *name) if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) { - indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); + indirect = tgetst1 (find_capability (termcap_name, "tc"), 0); if (!indirect) { if (!bp) @@ -490,7 +490,7 @@ tgetent (char *bp, const char *name) /* Does this entry refer to another terminal type's entry? If something is found, copy it into heap and null-terminate it. */ tc_search_point = find_capability (tc_search_point, "tc"); - term = tgetst1 (tc_search_point, (char **) 0); + term = tgetst1 (tc_search_point, 0); } emacs_close (fd); diff --git a/src/terminal.c b/src/terminal.c index c55fd4eb077..4b5532e3a44 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -39,6 +39,8 @@ static int next_terminal_id; /* The initial terminal device, created by initial_term_init. */ struct terminal *initial_terminal; +static Lisp_Object Qterminal_live_p; + static void delete_initial_terminal (struct terminal *); /* This setter is used only in this file, so it can be private. */ @@ -549,6 +551,8 @@ Each function is called with argument, the terminal. This may be called just before actually deleting the terminal, or some time later. */); Vdelete_terminal_functions = Qnil; + + DEFSYM (Qterminal_live_p, "terminal-live-p"); DEFSYM (Qdelete_terminal_functions, "delete-terminal-functions"); DEFSYM (Qrun_hook_with_args, "run-hook-with-args"); diff --git a/src/textprop.c b/src/textprop.c index 282ae11d4ac..b804f345047 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -93,15 +93,25 @@ text_read_only (Lisp_Object propval) xsignal0 (Qtext_read_only); } -/* Prepare to modify the region of BUFFER from START to END. */ +/* Prepare to modify the text properties of BUFFER from START to END. */ static void -modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) +modify_text_properties (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) { + ptrdiff_t b = XINT (start), e = XINT (end); struct buffer *buf = XBUFFER (buffer), *old = current_buffer; set_buffer_internal (buf); - modify_region_1 (XINT (start), XINT (end), true); + + prepare_to_modify_buffer_1 (b, e, NULL); + + BUF_COMPUTE_UNCHANGED (buf, b - 1, e); + if (MODIFF <= SAVE_MODIFF) + record_first_change (); + MODIFF++; + + bset_point_before_scroll (current_buffer, Qnil); + set_buffer_internal (old); } @@ -1213,9 +1223,9 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end, ptrdiff_t prev_total_length = TOTAL_LENGTH (i); ptrdiff_t prev_pos = i->position; - modify_region (object, start, end); + modify_text_properties (object, start, end); /* If someone called us recursively as a side effect of - modify_region, and changed the intervals behind our back + modify_text_properties, and changed the intervals behind our back (could happen if lock_file, called by prepare_to_modify_buffer, triggers redisplay, and that calls add-text-properties again in the same buffer), we cannot continue with I, because its @@ -1357,7 +1367,8 @@ into it. */) otherwise. */ Lisp_Object -set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, Lisp_Object coherent_change_p) +set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, + Lisp_Object object, Lisp_Object coherent_change_p) { register INTERVAL i; Lisp_Object ostart, oend; @@ -1403,7 +1414,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, } if (BUFFERP (object) && !NILP (coherent_change_p)) - modify_region (object, start, end); + modify_text_properties (object, start, end); set_text_properties_1 (start, end, properties, object, i); @@ -1558,9 +1569,9 @@ Use `set-text-properties' if you want to remove all text properties. */) ptrdiff_t prev_total_length = TOTAL_LENGTH (i); ptrdiff_t prev_pos = i->position; - modify_region (object, start, end); + modify_text_properties (object, start, end); /* If someone called us recursively as a side effect of - modify_region, and changed the intervals behind our back + modify_text_properties, and changed the intervals behind our back (could happen if lock_file, called by prepare_to_modify_buffer, triggers redisplay, and that calls add-text-properties again in the same buffer), we cannot continue with I, because its @@ -1667,9 +1678,9 @@ Return t if any property was actually removed, nil otherwise. */) /* We are at the beginning of an interval, with len to scan. The flag `modified' records if changes have been made. - When object is a buffer, we must call modify_region before changes are - made and signal_after_change when we are done. - We call modify_region before calling remove_properties if modified == 0, + When object is a buffer, we must call modify_text_properties + before changes are made and signal_after_change when we are done. + We call modify_text_properties before calling remove_properties if modified == 0, and we call signal_after_change before returning if modified != 0. */ for (;;) { @@ -1693,7 +1704,7 @@ Return t if any property was actually removed, nil otherwise. */) else if (LENGTH (i) == len) { if (!modified && BUFFERP (object)) - modify_region (object, start, end); + modify_text_properties (object, start, end); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1706,7 +1717,7 @@ Return t if any property was actually removed, nil otherwise. */) i = split_interval_left (i, len); copy_properties (unchanged, i); if (!modified && BUFFERP (object)) - modify_region (object, start, end); + modify_text_properties (object, start, end); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1717,7 +1728,7 @@ Return t if any property was actually removed, nil otherwise. */) if (interval_has_some_properties_list (properties, i)) { if (!modified && BUFFERP (object)) - modify_region (object, start, end); + modify_text_properties (object, start, end); remove_properties (Qnil, properties, i, object); modified = 1; } diff --git a/src/w16select.c b/src/w16select.c index 3bcc663e565..864757b3e61 100644 --- a/src/w16select.c +++ b/src/w16select.c @@ -452,11 +452,7 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat CHECK_STRING (string); - if (NILP (frame)) - frame = Fselected_frame (); - - CHECK_LIVE_FRAME (frame); - if ( !FRAME_MSDOS_P (XFRAME (frame))) + if (!FRAME_MSDOS_P (decode_live_frame (frame))) goto done; block_input (); @@ -558,11 +554,7 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat Lisp_Object ret = Qnil; int require_decoding = 0; - if (NILP (frame)) - frame = Fselected_frame (); - - CHECK_LIVE_FRAME (frame); - if ( !FRAME_MSDOS_P (XFRAME (frame))) + if (!FRAME_MSDOS_P (decode_live_frame (frame))) goto done; block_input (); diff --git a/src/w32.c b/src/w32.c index fb2d7c75972..21dbf49ed7c 100644 --- a/src/w32.c +++ b/src/w32.c @@ -47,7 +47,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #undef fopen #undef link #undef mkdir -#undef mktemp #undef open #undef rename #undef rmdir @@ -90,6 +89,21 @@ typedef struct _MEMORY_STATUS_EX { DWORDLONG ullAvailExtendedVirtual; } MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX; +/* These are here so that GDB would know about these data types. This + allows to attach GDB to Emacs when a fatal exception is triggered + and Windows pops up the "application needs to be closed" dialog. + At that point, _gnu_exception_handler, the top-level exception + handler installed by the MinGW startup code, is somewhere on the + call-stack of the main thread, so going to that call frame and + looking at the argument to _gnu_exception_handler, which is a + PEXCEPTION_POINTERS pointer, can reveal the exception code + (excptr->ExceptionRecord->ExceptionCode) and the address where the + exception happened (excptr->ExceptionRecord->ExceptionAddress), as + well as some additional information specific to the exception. */ +PEXCEPTION_POINTERS excptr; +PEXCEPTION_RECORD excprec; +PCONTEXT ctxrec; + #include <lmcons.h> #include <shlobj.h> @@ -3414,25 +3428,46 @@ sys_mkdir (const char * path) return _mkdir (map_w32_filename (path, NULL)); } -/* Because of long name mapping issues, we need to implement this - ourselves. Also, MSVC's _mktemp returns NULL when it can't generate - a unique name, instead of setting the input template to an empty - string. +int +sys_open (const char * path, int oflag, int mode) +{ + const char* mpath = map_w32_filename (path, NULL); + int res = -1; - Standard algorithm seems to be use pid or tid with a letter on the - front (in place of the 6 X's) and cycle through the letters to find a - unique name. We extend that to allow any reasonable character as the - first of the 6 X's. */ -char * -sys_mktemp (char * template) + /* If possible, try to open file without _O_CREAT, to be able to + write to existing hidden and system files. Force all file + handles to be non-inheritable. */ + if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL)) + res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); + if (res < 0) + res = _open (mpath, oflag | _O_NOINHERIT, mode); + + return res; +} + +/* Implementation of mkostemp for MS-Windows, to avoid race conditions + when using mktemp. + + Standard algorithm for generating a temporary file name seems to be + use pid or tid with a letter on the front (in place of the 6 X's) + and cycle through the letters to find a unique name. We extend + that to allow any reasonable character as the first of the 6 X's, + so that the number of simultaneously used temporary files will be + greater. */ + +int +mkostemp (char * template, int flags) { char * p; - int i; + int i, fd = -1; unsigned uid = GetCurrentThreadId (); + int save_errno = errno; static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; + errno = EINVAL; if (template == NULL) - return NULL; + return -1; + p = template + strlen (template); i = 5; /* replace up to the last 5 X's with uid in decimal */ @@ -3447,38 +3482,22 @@ sys_mktemp (char * template) i = 0; do { - int save_errno = errno; p[0] = first_char[i]; - if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0) + if ((fd = sys_open (template, + flags | _O_CREAT | _O_EXCL | _O_RDWR, + S_IRUSR | S_IWUSR)) >= 0 + || errno != EEXIST) { - errno = save_errno; - return template; + if (fd >= 0) + errno = save_errno; + return fd; } } while (++i < sizeof (first_char)); } - /* Template is badly formed or else we can't generate a unique name, - so return empty string */ - template[0] = 0; - return template; -} - -int -sys_open (const char * path, int oflag, int mode) -{ - const char* mpath = map_w32_filename (path, NULL); - int res = -1; - - /* If possible, try to open file without _O_CREAT, to be able to - write to existing hidden and system files. Force all file - handles to be non-inheritable. */ - if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL)) - res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); - if (res < 0) - res = _open (mpath, oflag | _O_NOINHERIT, mode); - - return res; + /* Template is badly formed or else we can't generate a unique name. */ + return -1; } int @@ -5750,8 +5769,8 @@ system_process_attributes (Lisp_Object pid) { /* Decode the command name from locale-specific encoding. */ - cmd_str = make_unibyte_string (pe.szExeFile, - strlen (pe.szExeFile)); + cmd_str = build_unibyte_string (pe.szExeFile); + decoded_cmd = code_convert_string_norecord (cmd_str, Vlocale_coding_system, 0); diff --git a/src/w32fns.c b/src/w32fns.c index 675b716f3b0..b8c445a3a36 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -285,7 +285,7 @@ check_x_display_info (Lisp_Object frame) return x_display_info_for_name (frame); else { - FRAME_PTR f; + struct frame *f; CHECK_LIVE_FRAME (frame); f = XFRAME (frame); @@ -344,7 +344,7 @@ void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object); not Emacs's own window. */ void -x_real_positions (FRAME_PTR f, int *xptr, int *yptr) +x_real_positions (struct frame *f, int *xptr, int *yptr) { POINT pt; RECT rect; @@ -1019,7 +1019,7 @@ x_to_w32_color (const char * colorname) } void -w32_regenerate_palette (FRAME_PTR f) +w32_regenerate_palette (struct frame *f) { struct w32_palette_entry * list; LOGPALETTE * log_palette; @@ -1069,7 +1069,7 @@ w32_regenerate_palette (FRAME_PTR f) #if 0 /* Keep these around in case we ever want to track color usage. */ void -w32_map_color (FRAME_PTR f, COLORREF color) +w32_map_color (struct frame *f, COLORREF color) { struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list; @@ -1100,7 +1100,7 @@ w32_map_color (FRAME_PTR f, COLORREF color) } void -w32_unmap_color (FRAME_PTR f, COLORREF color) +w32_unmap_color (struct frame *f, COLORREF color) { struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list; struct w32_palette_entry **prev = &FRAME_W32_DISPLAY_INFO (f)->color_list; @@ -1153,7 +1153,7 @@ gamma_correct (struct frame *f, COLORREF *color) If ALLOC is nonzero, allocate a new colormap cell. */ int -w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc) +w32_defined_color (struct frame *f, const char *color, XColor *color_def, int alloc) { register Lisp_Object tem; COLORREF w32_color_ref; @@ -1224,7 +1224,7 @@ w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc) ARG says. */ int -x_decode_color (FRAME_PTR f, Lisp_Object arg, int def) +x_decode_color (struct frame *f, Lisp_Object arg, int def) { XColor cdef; @@ -1525,14 +1525,11 @@ x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) void -x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { set_frame_cursor_types (f, arg); - - /* Make sure the cursor gets redrawn. */ - cursor_type_changed = 1; } - + void x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { @@ -1787,7 +1784,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit) specified a name for the frame; the name will override any set by the redisplay code. */ void -x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { x_set_name (f, arg, 1); } @@ -1796,7 +1793,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) name; names set this way will never override names set by the user's lisp code. */ void -x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { x_set_name (f, arg, 0); } @@ -3213,6 +3210,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) described by W was deleted, as indicated by its buffer field being reset to nil. */ f = x_window_to_frame (dpyinfo, hwnd); + if (!(f && FRAME_LIVE_P (f))) + break; w = XWINDOW (FRAME_SELECTED_WINDOW (f)); /* Punt if someone changed the frame's selected window behind our back. */ @@ -4122,12 +4121,7 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only) for the window manager, so GC relocation won't bother it. Elsewhere we specify the window name for the window manager. */ - - { - char *str = SSDATA (Vx_resource_name); - f->namebuf = xmalloc (strlen (str) + 1); - strcpy (f->namebuf, str); - } + f->namebuf = xstrdup (SSDATA (Vx_resource_name)); my_create_window (f); @@ -4180,9 +4174,6 @@ x_icon (struct frame *f, Lisp_Object parms) block_input (); - if (! EQ (icon_x, Qunbound)) - x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y)); - #if 0 /* TODO */ /* Start up iconic or window? */ x_wm_set_window_state @@ -4646,7 +4637,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0, (Lisp_Object color, Lisp_Object frame) { XColor foo; - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_STRING (color); @@ -4661,7 +4652,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, (Lisp_Object color, Lisp_Object frame) { XColor foo; - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_STRING (color); @@ -4993,8 +4984,8 @@ w32_display_monitor_attributes_list (void) attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), attributes); - name = DECODE_SYSTEM (make_unibyte_string (mi.szDevice, - strlen (mi.szDevice))); + name = DECODE_SYSTEM (build_unibyte_string (mi.szDevice)); + attributes = Fcons (Fcons (Qname, name), attributes); attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), @@ -5137,19 +5128,6 @@ SOUND is nil to use the normal beep. */) return sound; } - -int -x_pixel_width (register struct frame *f) -{ - return FRAME_PIXEL_WIDTH (f); -} - -int -x_pixel_height (register struct frame *f) -{ - return FRAME_PIXEL_HEIGHT (f); -} - int x_screen_planes (register struct frame *f) { @@ -6624,7 +6602,7 @@ screen saver if defined. If optional parameter FRAME is not specified, use selected frame. */) (Lisp_Object command, Lisp_Object frame) { - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_NUMBER (command); diff --git a/src/w32font.c b/src/w32font.c index 105daa06365..4a97fd90a4e 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -99,7 +99,7 @@ static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac; /* Font spacing symbols - defined in font.c. */ extern Lisp_Object Qc, Qp, Qm; -static void fill_in_logfont (FRAME_PTR, LOGFONT *, Lisp_Object); +static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object); static BYTE w32_antialias_type (Lisp_Object); static Lisp_Object lispy_antialias_type (BYTE); @@ -297,7 +297,7 @@ intern_font_name (char * string) Return a cache of font-entities on FRAME. The cache must be a cons whose cdr part is the actual cache area. */ Lisp_Object -w32font_get_cache (FRAME_PTR f) +w32font_get_cache (struct frame *f) { struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); @@ -309,9 +309,9 @@ w32font_get_cache (FRAME_PTR f) is a vector of font-entities. This is the sole API that allocates font-entities. */ static Lisp_Object -w32font_list (Lisp_Object frame, Lisp_Object font_spec) +w32font_list (struct frame *f, Lisp_Object font_spec) { - Lisp_Object fonts = w32font_list_internal (frame, font_spec, 0); + Lisp_Object fonts = w32font_list_internal (f, font_spec, 0); FONT_ADD_LOG ("w32font-list", font_spec, fonts); return fonts; } @@ -321,9 +321,9 @@ w32font_list (Lisp_Object frame, Lisp_Object font_spec) FRAME. The closeness is determined by the font backend, thus `face-font-selection-order' is ignored here. */ static Lisp_Object -w32font_match (Lisp_Object frame, Lisp_Object font_spec) +w32font_match (struct frame *f, Lisp_Object font_spec) { - Lisp_Object entity = w32font_match_internal (frame, font_spec, 0); + Lisp_Object entity = w32font_match_internal (f, font_spec, 0); FONT_ADD_LOG ("w32font-match", font_spec, entity); return entity; } @@ -332,12 +332,11 @@ w32font_match (Lisp_Object frame, Lisp_Object font_spec) List available families. The value is a list of family names (symbols). */ static Lisp_Object -w32font_list_family (Lisp_Object frame) +w32font_list_family (struct frame *f) { Lisp_Object list = Qnil; LOGFONT font_match_pattern; HDC dc; - FRAME_PTR f = XFRAME (frame); memset (&font_match_pattern, 0, sizeof (font_match_pattern)); font_match_pattern.lfCharSet = DEFAULT_CHARSET; @@ -356,7 +355,7 @@ w32font_list_family (Lisp_Object frame) Open a font specified by FONT_ENTITY on frame F. If the font is scalable, open it with PIXEL_SIZE. */ static Lisp_Object -w32font_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) +w32font_open (struct frame *f, Lisp_Object font_entity, int pixel_size) { Lisp_Object font_object = font_make_object (VECSIZE (struct w32font_info), @@ -380,7 +379,7 @@ w32font_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) /* w32 implementation of close for font_backend. Close FONT on frame F. */ void -w32font_close (FRAME_PTR f, struct font *font) +w32font_close (struct frame *f, struct font *font) { int i; struct w32font_info *w32_font = (struct w32font_info *) font; @@ -732,13 +731,13 @@ w32font_free_entity (Lisp_Object entity); storing some data in FACE->extra. If successful, return 0. Otherwise, return -1. static int -w32font_prepare_face (FRAME_PTR f, struct face *face); +w32font_prepare_face (struct frame *f, struct face *face); */ /* w32 implementation of done_face for font backend. Optional. Done FACE for displaying characters by FACE->font on frame F. static void -w32font_done_face (FRAME_PTR f, struct face *face); */ +w32font_done_face (struct frame *f, struct face *face); */ /* w32 implementation of get_bitmap for font backend. Optional. @@ -811,15 +810,14 @@ w32font_otf_drive (struct font *font, Lisp_Object features, Additional parameter opentype_only restricts the returned fonts to opentype fonts, which can be used with the Uniscribe backend. */ Lisp_Object -w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only) +w32font_list_internal (struct frame *f, Lisp_Object font_spec, int opentype_only) { struct font_callback_data match_data; HDC dc; - FRAME_PTR f = XFRAME (frame); match_data.orig_font_spec = font_spec; match_data.list = Qnil; - match_data.frame = frame; + XSETFRAME (match_data.frame, f); memset (&match_data.pattern, 0, sizeof (LOGFONT)); fill_in_logfont (f, &match_data.pattern, font_spec); @@ -864,14 +862,13 @@ w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_on Additional parameter opentype_only restricts the returned fonts to opentype fonts, which can be used with the Uniscribe backend. */ Lisp_Object -w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only) +w32font_match_internal (struct frame *f, Lisp_Object font_spec, int opentype_only) { struct font_callback_data match_data; HDC dc; - FRAME_PTR f = XFRAME (frame); match_data.orig_font_spec = font_spec; - match_data.frame = frame; + XSETFRAME (match_data.frame, f); match_data.list = Qnil; memset (&match_data.pattern, 0, sizeof (LOGFONT)); @@ -892,7 +889,7 @@ w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_o } int -w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, +w32font_open_internal (struct frame *f, Lisp_Object font_entity, int pixel_size, Lisp_Object font_object) { int len, size; @@ -1964,7 +1961,7 @@ w32_to_fc_weight (int n) /* Fill in all the available details of LOGFONT from FONT_SPEC. */ static void -fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec) +fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec) { Lisp_Object tmp, extra; int dpi = FRAME_RES_Y (f); @@ -2114,7 +2111,7 @@ static void list_all_matching_fonts (struct font_callback_data *match_data) { HDC dc; - Lisp_Object families = w32font_list_family (match_data->frame); + Lisp_Object families = w32font_list_family (XFRAME (match_data->frame)); struct frame *f = XFRAME (match_data->frame); dc = get_frame_dc (f); @@ -2467,7 +2464,7 @@ If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts in the font selection dialog. */) (Lisp_Object frame, Lisp_Object exclude_proportional) { - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHOOSEFONT cf; LOGFONT lf; TEXTMETRIC tm; diff --git a/src/w32font.h b/src/w32font.h index b4345478a22..56220860863 100644 --- a/src/w32font.h +++ b/src/w32font.h @@ -63,16 +63,16 @@ struct w32font_info #define CACHE_BLOCKSIZE 128 -Lisp_Object w32font_get_cache (FRAME_PTR fe); -Lisp_Object w32font_list_internal (Lisp_Object frame, +Lisp_Object w32font_get_cache (struct frame *fe); +Lisp_Object w32font_list_internal (struct frame *f, Lisp_Object font_spec, int opentype_only); -Lisp_Object w32font_match_internal (Lisp_Object frame, +Lisp_Object w32font_match_internal (struct frame *f, Lisp_Object font_spec, int opentype_only); -int w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, +int w32font_open_internal (struct frame *f, Lisp_Object font_entity, int pixel_size, Lisp_Object font_object); -void w32font_close (FRAME_PTR f, struct font *font); +void w32font_close (struct frame *f, struct font *font); int w32font_has_char (Lisp_Object entity, int c); int w32font_text_extents (struct font *font, unsigned *code, int nglyphs, struct font_metrics *metrics); diff --git a/src/w32inevt.c b/src/w32inevt.c index 88a3f9739cd..ce36f291b00 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -103,10 +103,10 @@ fill_queue (BOOL block) } /* In a generic, multi-frame world this should take a console handle - and return the frame for it + and return the frame for it. Right now, there's only one frame so return it. */ -static FRAME_PTR +static struct frame * get_frame (void) { return SELECTED_FRAME (); @@ -394,7 +394,7 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) /* Mouse position hook. */ void -w32_console_mouse_position (FRAME_PTR *f, +w32_console_mouse_position (struct frame **f, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, @@ -461,7 +461,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event, if (event->dwEventFlags == MOUSE_MOVED) { - FRAME_PTR f = SELECTED_FRAME (); + struct frame *f = SELECTED_FRAME (); Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y; @@ -555,7 +555,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event, static void resize_event (WINDOW_BUFFER_SIZE_RECORD *event) { - FRAME_PTR f = get_frame (); + struct frame *f = get_frame (); change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0); SET_FRAME_GARBAGED (f); @@ -565,7 +565,7 @@ static void maybe_generate_resize_event (void) { CONSOLE_SCREEN_BUFFER_INFO info; - FRAME_PTR f = get_frame (); + struct frame *f = get_frame (); GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info); diff --git a/src/w32inevt.h b/src/w32inevt.h index 8a7e4fed06a..070d1ad7b03 100644 --- a/src/w32inevt.h +++ b/src/w32inevt.h @@ -23,7 +23,7 @@ extern int w32_console_unicode_input; extern int w32_console_read_socket (struct terminal *term, struct input_event *hold_quit); -extern void w32_console_mouse_position (FRAME_PTR *f, int insist, +extern void w32_console_mouse_position (struct frame **f, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, diff --git a/src/w32menu.c b/src/w32menu.c index 346402b7c6b..34020fa61d2 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -100,13 +100,13 @@ MessageBoxW_Proc unicode_message_box = NULL; Lisp_Object Qdebug_on_next_call; -void set_frame_menubar (FRAME_PTR, bool, bool); +void set_frame_menubar (struct frame *, bool, bool); #ifdef HAVE_DIALOGS -static Lisp_Object w32_dialog_show (FRAME_PTR, int, Lisp_Object, char**); +static Lisp_Object w32_dialog_show (struct frame *, int, Lisp_Object, char**); #else static int is_simple_dialog (Lisp_Object); -static Lisp_Object simple_dialog_show (FRAME_PTR, Lisp_Object, Lisp_Object); +static Lisp_Object simple_dialog_show (struct frame *, Lisp_Object, Lisp_Object); #endif static void utf8to16 (unsigned char *, int, WCHAR *); @@ -137,7 +137,7 @@ If HEADER is non-nil, the frame title for the box is "Information", otherwise it is "Question". */) (Lisp_Object position, Lisp_Object contents, Lisp_Object header) { - FRAME_PTR f = NULL; + struct frame *f = NULL; Lisp_Object window; /* Decode the first argument: find the window or frame to use. */ @@ -147,7 +147,7 @@ otherwise it is "Question". */) { #if 0 /* Using the frame the mouse is on may not be right. */ /* Use the mouse's current position. */ - FRAME_PTR new_f = SELECTED_FRAME (); + struct frame *new_f = SELECTED_FRAME (); Lisp_Object bar_window; enum scroll_bar_part part; Time time; @@ -206,8 +206,8 @@ otherwise it is "Question". */) in the middle of frame F. */ Lisp_Object x, y, frame, newpos; XSETFRAME (frame, f); - XSETINT (x, x_pixel_width (f) / 2); - XSETINT (y, x_pixel_height (f) / 2); + XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2); + XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2); newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil)); return Fx_popup_menu (newpos, Fcons (Fcar (contents), Fcons (contents, Qnil))); @@ -252,7 +252,7 @@ otherwise it is "Question". */) This way we can safely execute Lisp code. */ void -x_activate_menubar (FRAME_PTR f) +x_activate_menubar (struct frame *f) { set_frame_menubar (f, 0, 1); @@ -269,7 +269,7 @@ x_activate_menubar (FRAME_PTR f) and put the appropriate events into the keyboard buffer. */ void -menubar_selection_callback (FRAME_PTR f, void * client_data) +menubar_selection_callback (struct frame *f, void * client_data) { Lisp_Object prefix, entry; Lisp_Object vector; @@ -361,7 +361,7 @@ menubar_selection_callback (FRAME_PTR f, void * client_data) it is set the first time this is called, from initialize_frame_menubar. */ void -set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool first_time, bool deep_p) { HMENU menubar_widget = f->output_data.w32->menubar_widget; Lisp_Object items; @@ -613,7 +613,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p) is visible. */ void -initialize_frame_menubar (FRAME_PTR f) +initialize_frame_menubar (struct frame *f) { /* This function is called before the first chance to redisplay the frame. It has to be, so the frame will have the right size. */ @@ -625,7 +625,7 @@ initialize_frame_menubar (FRAME_PTR f) This is used when deleting a frame, and when turning off the menu bar. */ void -free_frame_menubar (FRAME_PTR f) +free_frame_menubar (struct frame *f) { block_input (); @@ -656,7 +656,7 @@ free_frame_menubar (FRAME_PTR f) (We return nil on failure, but the value doesn't actually matter.) */ Lisp_Object -w32_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, +w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps, Lisp_Object title, const char **error) { int i; @@ -983,7 +983,7 @@ static char * button_names [] = { "button6", "button7", "button8", "button9", "button10" }; static Lisp_Object -w32_dialog_show (FRAME_PTR f, int keymaps, +w32_dialog_show (struct frame *f, int keymaps, Lisp_Object title, Lisp_Object header, char **error) { @@ -1219,7 +1219,7 @@ is_simple_dialog (Lisp_Object contents) } static Lisp_Object -simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header) +simple_dialog_show (struct frame *f, Lisp_Object contents, Lisp_Object header) { int answer; UINT type; @@ -1699,7 +1699,7 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ (void) { #ifdef HAVE_MENUS - FRAME_PTR f; + struct frame *f; f = SELECTED_FRAME (); return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil; #else diff --git a/src/w32notify.c b/src/w32notify.c index 95ab298f2d3..a48a83daf53 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -129,7 +129,7 @@ send_notifications (BYTE *info, DWORD info_size, void *desc, volatile int *terminate) { int done = 0; - FRAME_PTR f = SELECTED_FRAME (); + struct frame *f = SELECTED_FRAME (); /* A single buffer is used to communicate all notifications to the main thread. Since both the main thread and several watcher diff --git a/src/w32term.c b/src/w32term.c index 0b22fd178e4..7d51850559b 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -181,7 +181,7 @@ int w32_keyboard_codepage; /* Where the mouse was last time we reported a mouse event. */ static RECT last_mouse_glyph; -static FRAME_PTR last_mouse_glyph_frame; +static struct frame *last_mouse_glyph_frame; /* The scroll bar in which the last motion event occurred. @@ -249,7 +249,7 @@ static void my_set_focus (struct frame *, HWND); #endif static void my_set_foreground_window (HWND); static void my_destroy_window (struct frame *, HWND); -static void w32fullscreen_hook (FRAME_PTR); +static void w32fullscreen_hook (struct frame *); #ifdef GLYPH_DEBUG static void x_check_font (struct frame *, struct font *); @@ -450,7 +450,7 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y, /* Draw a filled rectangle at the specified position. */ void -w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect) +w32_fill_rect (struct frame *f, HDC hdc, COLORREF pix, RECT *lprect) { HBRUSH hb; @@ -460,7 +460,7 @@ w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect) } void -w32_clear_window (FRAME_PTR f) +w32_clear_window (struct frame *f) { RECT rect; HDC hdc = get_frame_dc (f); @@ -577,8 +577,7 @@ x_update_begin (struct frame *f) } -/* Start update of window W. Set the global variable updated_window - to the window being updated and set output_cursor to the cursor +/* Start update of window W. Set output_cursor to the cursor position of W. */ static void @@ -593,7 +592,6 @@ x_update_window_begin (struct window *w) SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0); } - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -664,7 +662,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) } -/* End update of window W (which is equal to updated_window). +/* End update of window W. Draw vertical borders between horizontally adjacent windows, and display W's cursor if CURSOR_ON_P is non-zero. @@ -714,8 +712,6 @@ x_update_window_end (struct window *w, int cursor_on_p, { SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0); } - - updated_window = NULL; } @@ -733,9 +729,8 @@ x_update_end (struct frame *f) } -/* This function is called from various places in xdisp.c whenever a - complete update has been performed. The global variable - updated_window is not available here. */ +/* This function is called from various places in xdisp.c + whenever a complete update has been performed. */ static void w32_frame_up_to_date (struct frame *f) @@ -747,15 +742,13 @@ w32_frame_up_to_date (struct frame *f) /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay arrow bitmaps, or clear the fringes if no bitmaps are required - before DESIRED_ROW is made current. The window being updated is - found in updated_window. This function is called from + before DESIRED_ROW is made current. This function is called from update_window_line only if it is known that there are differences between bitmaps to be drawn between current row and DESIRED_ROW. */ static void -x_after_update_window_line (struct glyph_row *desired_row) +x_after_update_window_line (struct window *w, struct glyph_row *desired_row) { - struct window *w = updated_window; struct frame *f; int width, height; @@ -766,7 +759,7 @@ x_after_update_window_line (struct glyph_row *desired_row) /* When a window has disappeared, make sure that no rest of full-width rows stays visible in the internal border. Could - check here if updated_window is the leftmost/rightmost window, + check here if updated window is the leftmost/rightmost window, but I guess it's not worth doing since vertically split windows are almost never used, internal border is rarely set, and the overhead is very small. */ @@ -2360,7 +2353,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s) static void x_draw_glyph_string (struct glyph_string *s) { - int relief_drawn_p = 0; + bool relief_drawn_p = 0; /* If S draws into the background of its successor, draw the background of the successor first so that S can draw into it. @@ -2806,7 +2799,6 @@ x_scroll_run (struct window *w, struct run *run) block_input (); /* Cursor off. Will be switched on again in x_update_window_end. */ - updated_window = w; x_clear_cursor (w); { @@ -3370,7 +3362,7 @@ static MSG last_mouse_motion_event; static Lisp_Object last_mouse_motion_frame; static int -note_mouse_movement (FRAME_PTR frame, MSG *msg) +note_mouse_movement (struct frame *frame, MSG *msg) { int mouse_x = LOWORD (msg->lParam); int mouse_y = HIWORD (msg->lParam); @@ -3419,7 +3411,7 @@ note_mouse_movement (FRAME_PTR frame, MSG *msg) ************************************************************************/ static struct scroll_bar *x_window_to_scroll_bar (Window); -static void x_scroll_bar_report_motion (FRAME_PTR *, Lisp_Object *, +static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, unsigned long *); @@ -3461,11 +3453,11 @@ w32_define_cursor (Window window, Cursor cursor) movement. */ static void -w32_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, +w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, unsigned long *time) { - FRAME_PTR f1; + struct frame *f1; block_input (); @@ -3696,7 +3688,7 @@ my_create_scrollbar (struct frame * f, struct scroll_bar * bar) /*#define ATTACH_THREADS*/ static BOOL -my_show_window (FRAME_PTR f, HWND hwnd, int how) +my_show_window (struct frame *f, HWND hwnd, int how) { #ifndef ATTACH_THREADS return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW, @@ -3765,7 +3757,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) HWND hwnd; SCROLLINFO si; struct scroll_bar *bar - = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil)); + = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, fringe_extended_p, PVEC_OTHER); Lisp_Object barobj; block_input (); @@ -3778,7 +3770,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) XSETINT (bar->start, 0); XSETINT (bar->end, 0); bar->dragging = Qnil; - bar->fringe_extended_p = Qnil; + bar->fringe_extended_p = 0; /* Requires geometry to be set before call to create the real window */ @@ -3816,7 +3808,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height) static void x_scroll_bar_remove (struct scroll_bar *bar) { - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); block_input (); @@ -3842,7 +3834,7 @@ w32_set_vertical_scroll_bar (struct window *w, struct scroll_bar *bar; int top, height, left, sb_left, width, sb_width; int window_y, window_height; - int fringe_extended_p; + bool fringe_extended_p; /* Get window dimensions. */ window_box (w, -1, 0, &window_y, 0, &window_height); @@ -3866,16 +3858,7 @@ w32_set_vertical_scroll_bar (struct window *w, else sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width); - if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) - fringe_extended_p = (WINDOW_LEFTMOST_P (w) - && WINDOW_LEFT_FRINGE_WIDTH (w) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - || WINDOW_LEFT_MARGIN_COLS (w) == 0)); - else - fringe_extended_p = (WINDOW_RIGHTMOST_P (w) - && WINDOW_RIGHT_FRINGE_WIDTH (w) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - || WINDOW_RIGHT_MARGIN_COLS (w) == 0)); + fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w); /* Does the scroll bar exist yet? */ if (NILP (w->vertical_scroll_bar)) @@ -3904,11 +3887,11 @@ w32_set_vertical_scroll_bar (struct window *w, hwnd = SCROLL_BAR_W32_WINDOW (bar); /* If already correctly positioned, do nothing. */ - if ( XINT (bar->left) == sb_left - && XINT (bar->top) == top - && XINT (bar->width) == sb_width - && XINT (bar->height) == height - && !NILP (bar->fringe_extended_p) == fringe_extended_p ) + if (XINT (bar->left) == sb_left + && XINT (bar->top) == top + && XINT (bar->width) == sb_width + && XINT (bar->height) == height + && bar->fringe_extended_p == fringe_extended_p) { /* Redraw after clear_frame. */ if (!my_show_window (f, hwnd, SW_NORMAL)) @@ -3958,7 +3941,7 @@ w32_set_vertical_scroll_bar (struct window *w, unblock_input (); } } - bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil; + bar->fringe_extended_p = fringe_extended_p; w32_set_scroll_bar_thumb (bar, portion, position, whole); XSETVECTOR (barobj, bar); @@ -3979,7 +3962,7 @@ w32_set_vertical_scroll_bar (struct window *w, `*redeem_scroll_bar_hook' is applied to its window before the judgment. */ static void -w32_condemn_scroll_bars (FRAME_PTR frame) +w32_condemn_scroll_bars (struct frame *frame) { /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ while (! NILP (FRAME_SCROLL_BARS (frame))) @@ -4047,7 +4030,7 @@ w32_redeem_scroll_bar (struct window *window) last call to `*condemn_scroll_bars_hook'. */ static void -w32_judge_scroll_bars (FRAME_PTR f) +w32_judge_scroll_bars (struct frame *f) { Lisp_Object bar, next; @@ -4185,14 +4168,14 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg, on the scroll bar. */ static void -x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, +x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, unsigned long *time) { struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar); Window w = SCROLL_BAR_W32_WINDOW (bar); - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); int pos; int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)); SCROLLINFO si; @@ -4244,7 +4227,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, redraw them. */ void -x_scroll_bar_clear (FRAME_PTR f) +x_scroll_bar_clear (struct frame *f) { Lisp_Object bar; @@ -4629,7 +4612,7 @@ w32_read_socket (struct terminal *terminal, { /* If we decide we want to generate an event to be seen by the rest of Emacs, we put it here. */ - int tool_bar_p = 0; + bool tool_bar_p = 0; int button; int up; @@ -4923,16 +4906,11 @@ w32_read_socket (struct terminal *terminal, break; case WM_KILLFOCUS: + w32_detect_focus_change (dpyinfo, &msg, &inev); f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd); if (f) { - if (f == dpyinfo->w32_focus_event_frame) - dpyinfo->w32_focus_event_frame = 0; - - if (f == dpyinfo->w32_focus_frame) - x_new_focus_frame (dpyinfo, 0); - if (f == hlinfo->mouse_face_mouse_frame) { /* If we move outside the frame, then we're @@ -4979,7 +4957,7 @@ w32_read_socket (struct terminal *terminal, if (f) { extern void menubar_selection_callback - (FRAME_PTR f, void * client_data); + (struct frame *f, void * client_data); menubar_selection_callback (f, (void *)msg.msg.wParam); } @@ -5076,7 +5054,7 @@ w32_read_socket (struct terminal *terminal, FOR_EACH_FRAME (tail, frame) { - FRAME_PTR f = XFRAME (frame); + struct frame *f = XFRAME (frame); /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED below. */ if (EQ (frame, tip_frame)) @@ -5697,7 +5675,7 @@ x_check_fullscreen (struct frame *f) } static void -w32fullscreen_hook (FRAME_PTR f) +w32fullscreen_hook (struct frame *f) { if (FRAME_VISIBLE_P (f)) { @@ -5722,7 +5700,9 @@ w32fullscreen_hook (FRAME_PTR f) w32_fullscreen_rect (hwnd, f->want_fullscreen, FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); FRAME_PREV_FSMODE (f) = f->want_fullscreen; - if (f->want_fullscreen == FULLSCREEN_BOTH) + if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) + PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0); + else if (f->want_fullscreen == FULLSCREEN_BOTH) { SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, @@ -5894,11 +5874,6 @@ x_focus_on_frame (struct frame *f) unblock_input (); } -void -x_unfocus_frame (struct frame *f) -{ -} - /* Raise frame F. */ void x_raise_frame (struct frame *f) @@ -5974,7 +5949,7 @@ x_lower_frame (struct frame *f) } static void -w32_frame_raise_lower (FRAME_PTR f, int raise_flag) +w32_frame_raise_lower (struct frame *f, int raise_flag) { if (! FRAME_W32_P (f)) return; @@ -6230,22 +6205,6 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) leave_crit (); } -/* Window manager things */ -void -x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) -{ -#if 0 - Window window = FRAME_W32_WINDOW (f); - - f->display.x->wm_hints.flags |= IconPositionHint; - f->display.x->wm_hints.icon_x = icon_x; - f->display.x->wm_hints.icon_y = icon_y; - - XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints); -#endif -} - - /*********************************************************************** Fonts ***********************************************************************/ @@ -6504,9 +6463,7 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) terminal = w32_create_terminal (dpyinfo); /* Set the name of the terminal. */ - terminal->name = xmalloc (SBYTES (display_name) + 1); - strncpy (terminal->name, SDATA (display_name), SBYTES (display_name)); - terminal->name[SBYTES (display_name)] = 0; + terminal->name = xlispstrdup (display_name); dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL; diff --git a/src/w32term.h b/src/w32term.h index ace58758302..41c5c71832a 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -205,7 +205,7 @@ extern void x_focus_on_frame (struct frame *f); extern struct w32_display_info *w32_term_init (Lisp_Object, char *, char *); -extern int w32_defined_color (FRAME_PTR f, const char *color, +extern int w32_defined_color (struct frame *f, const char *color, XColor *color_def, int alloc); extern void x_set_window_size (struct frame *f, int change_grav, int cols, int rows); @@ -218,8 +218,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); extern void x_make_frame_visible (struct frame *f); extern void x_make_frame_invisible (struct frame *f); extern void x_iconify_frame (struct frame *f); -extern int x_pixel_width (struct frame *f); -extern int x_pixel_height (struct frame *f); extern void x_set_frame_alpha (struct frame *f); extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); extern void x_set_tool_bar_lines (struct frame *f, @@ -453,9 +451,11 @@ struct scroll_bar { being dragged, this is Qnil. */ Lisp_Object dragging; - /* t if the background of the fringe that is adjacent to a scroll + /* 1 if the background of the fringe that is adjacent to a scroll bar is extended to the gap between the fringe and the bar. */ - Lisp_Object fringe_extended_p; + /* Note: this could be a bit field, but we need to take its address + in ALLOCATE_PSEUDOVECTOR (see x_scroll_bar_create). */ + bool fringe_extended_p; }; /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index c153c8f3565..b31baa0e65c 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c @@ -69,28 +69,27 @@ memq_no_quit (Lisp_Object elt, Lisp_Object list) /* Font backend interface implementation. */ static Lisp_Object -uniscribe_list (Lisp_Object frame, Lisp_Object font_spec) +uniscribe_list (struct frame *f, Lisp_Object font_spec) { - Lisp_Object fonts = w32font_list_internal (frame, font_spec, 1); + Lisp_Object fonts = w32font_list_internal (f, font_spec, 1); FONT_ADD_LOG ("uniscribe-list", font_spec, fonts); return fonts; } static Lisp_Object -uniscribe_match (Lisp_Object frame, Lisp_Object font_spec) +uniscribe_match (struct frame *f, Lisp_Object font_spec) { - Lisp_Object entity = w32font_match_internal (frame, font_spec, 1); + Lisp_Object entity = w32font_match_internal (f, font_spec, 1); FONT_ADD_LOG ("uniscribe-match", font_spec, entity); return entity; } static Lisp_Object -uniscribe_list_family (Lisp_Object frame) +uniscribe_list_family (struct frame *f) { Lisp_Object list = Qnil; LOGFONT font_match_pattern; HDC dc; - FRAME_PTR f = XFRAME (frame); memset (&font_match_pattern, 0, sizeof (font_match_pattern)); /* Limit enumerated fonts to outline fonts to save time. */ @@ -107,7 +106,7 @@ uniscribe_list_family (Lisp_Object frame) } static Lisp_Object -uniscribe_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) +uniscribe_open (struct frame *f, Lisp_Object font_entity, int pixel_size) { Lisp_Object font_object = font_make_object (VECSIZE (struct uniscribe_font_info), @@ -136,7 +135,7 @@ uniscribe_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) } static void -uniscribe_close (FRAME_PTR f, struct font *font) +uniscribe_close (struct frame *f, struct font *font) { struct uniscribe_font_info *uniscribe_font = (struct uniscribe_font_info *) font; @@ -600,8 +599,8 @@ uniscribe_encode_char (struct font *font, int c) int x, int y, int with_background); Unused: - int uniscribe_prepare_face (FRAME_PTR f, struct face *face); - void uniscribe_done_face (FRAME_PTR f, struct face *face); + int uniscribe_prepare_face (struct frame *f, struct face *face); + void uniscribe_done_face (struct frame *f, struct face *face); int uniscribe_get_bitmap (struct font *font, unsigned code, struct font_bitmap *bitmap, int bits_per_pixel); void uniscribe_free_bitmap (struct font *font, struct font_bitmap *bitmap); @@ -609,8 +608,8 @@ uniscribe_encode_char (struct font *font, int c) void uniscribe_free_outline (struct font *font, void *outline); int uniscribe_anchor_point (struct font *font, unsigned code, int index, int *x, int *y); - int uniscribe_start_for_frame (FRAME_PTR f); - int uniscribe_end_for_frame (FRAME_PTR f); + int uniscribe_start_for_frame (struct frame *f); + int uniscribe_end_for_frame (struct frame *f); */ diff --git a/src/w32xfns.c b/src/w32xfns.c index 03611e19768..19c6b72bf89 100644 --- a/src/w32xfns.c +++ b/src/w32xfns.c @@ -90,7 +90,7 @@ signal_quit (void) } void -select_palette (FRAME_PTR f, HDC hdc) +select_palette (struct frame *f, HDC hdc) { struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f); @@ -117,7 +117,7 @@ select_palette (FRAME_PTR f, HDC hdc) } void -deselect_palette (FRAME_PTR f, HDC hdc) +deselect_palette (struct frame *f, HDC hdc) { if (f->output_data.w32->old_palette) SelectPalette (hdc, f->output_data.w32->old_palette, FALSE); @@ -126,7 +126,7 @@ deselect_palette (FRAME_PTR f, HDC hdc) /* Get a DC for frame and select palette for drawing; force an update of all frames if palette's mapping changes. */ HDC -get_frame_dc (FRAME_PTR f) +get_frame_dc (struct frame *f) { HDC hdc; @@ -146,7 +146,7 @@ get_frame_dc (FRAME_PTR f) } int -release_frame_dc (FRAME_PTR f, HDC hdc) +release_frame_dc (struct frame *f, HDC hdc) { int ret; diff --git a/src/widget.c b/src/widget.c index e2c8e9fa23f..ec0b506046b 100644 --- a/src/widget.c +++ b/src/widget.c @@ -503,26 +503,6 @@ widget_update_wm_size_hints (Widget widget) update_wm_hints (ew); } - -#if 0 - -static void -create_frame_gcs (EmacsFrame ew) -{ - struct frame *s = ew->emacs_frame.frame; - - s->output_data.x->normal_gc - = XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0); - s->output_data.x->reverse_gc - = XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0); - s->output_data.x->cursor_gc - = XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0); - s->output_data.x->black_relief.gc = 0; - s->output_data.x->white_relief.gc = 0; -} - -#endif /* 0 */ - static char setup_frame_cursor_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -683,19 +663,7 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs static void EmacsFrameDestroy (Widget widget) { - EmacsFrame ew = (EmacsFrame) widget; - struct frame* s = ew->emacs_frame.frame; - - if (! s) emacs_abort (); - if (! s->output_data.x) emacs_abort (); - - block_input (); - x_free_gcs (s); - if (s->output_data.x->white_relief.gc) - XFreeGC (XtDisplay (widget), s->output_data.x->white_relief.gc); - if (s->output_data.x->black_relief.gc) - XFreeGC (XtDisplay (widget), s->output_data.x->black_relief.gc); - unblock_input (); + /* All GCs are now freed in x_free_frame_resources. */ } static void @@ -838,7 +806,7 @@ void widget_store_internal_border (Widget widget) { EmacsFrame ew = (EmacsFrame) widget; - FRAME_PTR f = ew->emacs_frame.frame; + struct frame *f = ew->emacs_frame.frame; ew->emacs_frame.internal_border_width = f->internal_border_width; } diff --git a/src/window.c b/src/window.c index bf4ce1dbe39..a1a069e0e7d 100644 --- a/src/window.c +++ b/src/window.c @@ -66,14 +66,11 @@ static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; static int displayed_window_lines (struct window *); static int count_windows (struct window *); static int get_leaf_windows (struct window *, struct window **, int); -static void window_scroll (Lisp_Object, EMACS_INT, int, int); -static void window_scroll_pixel_based (Lisp_Object, int, int, int); -static void window_scroll_line_based (Lisp_Object, int, int, int); -static int freeze_window_start (struct window *, void *); +static void window_scroll (Lisp_Object, EMACS_INT, bool, int); +static void window_scroll_pixel_based (Lisp_Object, int, bool, int); +static void window_scroll_line_based (Lisp_Object, int, bool, int); static Lisp_Object window_list (void); static int add_window_to_list (struct window *, void *); -static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, - Lisp_Object); static Lisp_Object next_window (Lisp_Object, Lisp_Object, Lisp_Object, int); static void decode_next_window_args (Lisp_Object *, Lisp_Object *, @@ -90,6 +87,14 @@ static void window_resize_apply (struct window *, bool); static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); static void select_window_1 (Lisp_Object, bool); +static struct window *set_window_fringes (struct window *, Lisp_Object, + Lisp_Object, Lisp_Object); +static struct window *set_window_margins (struct window *, Lisp_Object, + Lisp_Object); +static struct window *set_window_scroll_bars (struct window *, Lisp_Object, + Lisp_Object, Lisp_Object); +static void apply_window_adjustment (struct window *); + /* This is the window in which the terminal's cursor should be left when nothing is being done with it. This must always be a leaf window, and its buffer is selected by @@ -154,16 +159,6 @@ wset_display_table (struct window *w, Lisp_Object val) w->display_table = val; } static void -wset_left_fringe_width (struct window *w, Lisp_Object val) -{ - w->left_fringe_width = val; -} -static void -wset_left_margin_cols (struct window *w, Lisp_Object val) -{ - w->left_margin_cols = val; -} -static void wset_new_normal (struct window *w, Lisp_Object val) { w->new_normal = val; @@ -194,21 +189,6 @@ wset_pointm (struct window *w, Lisp_Object val) w->pointm = val; } static void -wset_right_fringe_width (struct window *w, Lisp_Object val) -{ - w->right_fringe_width = val; -} -static void -wset_right_margin_cols (struct window *w, Lisp_Object val) -{ - w->right_margin_cols = val; -} -static void -wset_scroll_bar_width (struct window *w, Lisp_Object val) -{ - w->scroll_bar_width = val; -} -static void wset_start (struct window *w, Lisp_Object val) { w->start = val; @@ -241,6 +221,17 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val) w->horizontal = horflag; } +/* Nonzero if leaf window W doesn't reflect the actual state + of displayed buffer due to its text or overlays change. */ + +bool +window_outdated (struct window *w) +{ + struct buffer *b = XBUFFER (w->contents); + return (w->last_modified < BUF_MODIFF (b) + || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)); +} + struct window * decode_live_window (register Lisp_Object window) { @@ -490,7 +481,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) CHECK_LIVE_WINDOW (window); w = XWINDOW (window); - w->frozen_window_start_p = 0; /* Make the selected window's buffer current. */ Fset_buffer (w->contents); @@ -1355,7 +1345,7 @@ struct check_window_data static int check_window_containing (struct window *w, void *user_data) { - struct check_window_data *cw = (struct check_window_data *) user_data; + struct check_window_data *cw = user_data; enum window_part found; int continue_p = 1; @@ -1508,8 +1498,7 @@ if it isn't already recorded. */) || !w->window_end_valid || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) && !noninteractive) { struct text_pos startp; @@ -1550,7 +1539,7 @@ if it isn't already recorded. */) set_buffer_internal (old_buffer); } else - XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); + XSETINT (value, BUF_Z (b) - w->window_end_pos); return value; } @@ -1606,9 +1595,8 @@ overriding motion of point in order to display at this exact start. */) if (NILP (noforce)) w->force_start = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; - if (!EQ (window, selected_window)) + if (w != XWINDOW (selected_window)) + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; return pos; @@ -1722,8 +1710,7 @@ Return nil if window display is not up-to-date. In that case, use || windows_or_buffers_changed || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) return Qnil; if (NILP (line)) @@ -2046,10 +2033,9 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag) n->phys_cursor_width = -1; n->must_be_updated_p = 0; n->pseudo_window_p = 0; - wset_window_end_vpos (n, make_number (0)); - wset_window_end_pos (n, make_number (0)); + n->window_end_vpos = 0; + n->window_end_pos = 0; n->window_end_valid = 0; - n->frozen_window_start_p = 0; } tem = o->next; @@ -2158,7 +2144,7 @@ delete_deletable_window (Lisp_Object window) static int add_window_to_list (struct window *w, void *user_data) { - Lisp_Object *list = (Lisp_Object *) user_data; + Lisp_Object *list = user_data; Lisp_Object window; XSETWINDOW (window, w); *list = Fcons (window, *list); @@ -2213,12 +2199,13 @@ window_list (void) a window means search the frame that window belongs to, a frame means consider windows on that frame, only. */ -static int -candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf, Lisp_Object all_frames) +static bool +candidate_window_p (Lisp_Object window, Lisp_Object owindow, + Lisp_Object minibuf, Lisp_Object all_frames) { struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); - int candidate_p = 1; + bool candidate_p = 1; if (!BUFFERP (w->contents)) candidate_p = 0; @@ -3020,7 +3007,7 @@ replace_buffer_in_windows_safely (Lisp_Object buffer) minimum allowable size. */ void -check_frame_size (FRAME_PTR frame, int *rows, int *cols) +check_frame_size (struct frame *frame, int *rows, int *cols) { /* For height, we have to see: how many windows the frame has at minimum (one or two), @@ -3064,15 +3051,12 @@ adjust_window_margins (struct window *w) if (WINDOW_RIGHT_MARGIN_COLS (w) > 0) { if (WINDOW_LEFT_MARGIN_COLS (w) > 0) - { - wset_left_margin_cols (w, make_number (margin_cols / 2)); - wset_right_margin_cols (w, make_number (margin_cols / 2)); - } + w->left_margin_cols = w->right_margin_cols = margin_cols / 2; else - wset_right_margin_cols (w, make_number (margin_cols)); + w->right_margin_cols = margin_cols; } else - wset_left_margin_cols (w, make_number (margin_cols)); + w->left_margin_cols = margin_cols; return 1; } @@ -3120,7 +3104,7 @@ run_window_configuration_change_hook (struct frame *f) if (SELECTED_FRAME () != f) { - record_unwind_protect (select_frame_norecord, Fselected_frame ()); + record_unwind_protect (select_frame_norecord, selected_frame); select_frame_norecord (frame); } @@ -3135,7 +3119,7 @@ run_window_configuration_change_hook (struct frame *f) buffer))) { ptrdiff_t inner_count = SPECPDL_INDEX (); - record_unwind_protect (select_window_norecord, Fselected_window ()); + record_unwind_protect (select_window_norecord, selected_window); select_window_norecord (window); run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, buffer)); @@ -3186,8 +3170,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1)); bset_display_time (b, Fcurrent_time ()); - wset_window_end_pos (w, make_number (0)); - wset_window_end_vpos (w, make_number (0)); + w->window_end_pos = 0; + w->window_end_vpos = 0; memset (&w->last_cursor, 0, sizeof w->last_cursor); if (!(keep_margins_p && samebuf)) @@ -3207,8 +3191,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, buffer); w->start_at_line_beg = 0; w->force_start = 0; - w->last_modified = 0; - w->last_overlay_modified = 0; } /* Maybe we could move this into the `if' but it's not obviously safe and I doubt it's worth the trouble. */ @@ -3228,28 +3210,14 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, if (!keep_margins_p) { /* Set left and right marginal area width etc. from buffer. */ - - /* This may call adjust_window_margins three times, so - temporarily disable window margins. */ - Lisp_Object save_left = w->left_margin_cols; - Lisp_Object save_right = w->right_margin_cols; - - wset_left_margin_cols (w, Qnil); - wset_right_margin_cols (w, Qnil); - - Fset_window_fringes (window, - BVAR (b, left_fringe_width), BVAR (b, right_fringe_width), - BVAR (b, fringes_outside_margins)); - - Fset_window_scroll_bars (window, - BVAR (b, scroll_bar_width), - BVAR (b, vertical_scroll_bar_type), Qnil); - - wset_left_margin_cols (w, save_left); - wset_right_margin_cols (w, save_right); - - Fset_window_margins (window, - BVAR (b, left_margin_cols), BVAR (b, right_margin_cols)); + set_window_fringes (w, BVAR (b, left_fringe_width), + BVAR (b, right_fringe_width), + BVAR (b, fringes_outside_margins)); + set_window_scroll_bars (w, BVAR (b, scroll_bar_width), + BVAR (b, vertical_scroll_bar_type), Qnil); + set_window_margins (w, BVAR (b, left_margin_cols), + BVAR (b, right_margin_cols)); + apply_window_adjustment (w); } if (run_hooks_p) @@ -3469,8 +3437,6 @@ make_window (void) wset_start (w, Fmake_marker ()); wset_pointm (w, Fmake_marker ()); wset_vertical_scroll_bar_type (w, Qt); - wset_window_end_pos (w, make_number (0)); - wset_window_end_vpos (w, make_number (0)); /* These Lisp fields are marked specially so they're not set to nil by allocate_window. */ wset_prev_buffers (w, Qnil); @@ -3479,8 +3445,10 @@ make_window (void) /* Initialize non-Lisp data. Note that allocate_window zeroes out all non-Lisp data, so do it only for slots which should not be zero. */ w->nrows_scale_factor = w->ncols_scale_factor = 1; + w->left_fringe_width = w->right_fringe_width = -1; w->phys_cursor_type = -1; w->phys_cursor_width = -1; + w->scroll_bar_width = -1; w->column_number_displayed = -1; /* Reset window_list. */ @@ -3669,10 +3637,6 @@ window_resize_apply (struct window *w, bool horflag) c = NILP (c->next) ? 0 : XWINDOW (c->next); } } - - /* Clear out some redisplay caches. */ - w->last_modified = 0; - w->last_overlay_modified = 0; } @@ -3950,12 +3914,12 @@ set correctly. See the code of `split-window' for how this is done. */) memset (&n->last_cursor, 0, sizeof n->last_cursor); /* Get special geometry settings from reference window. */ - wset_left_margin_cols (n, r->left_margin_cols); - wset_right_margin_cols (n, r->right_margin_cols); - wset_left_fringe_width (n, r->left_fringe_width); - wset_right_fringe_width (n, r->right_fringe_width); + n->left_margin_cols = r->left_margin_cols; + n->right_margin_cols = r->right_margin_cols; + n->left_fringe_width = r->left_fringe_width; + n->right_fringe_width = r->right_fringe_width; n->fringes_outside_margins = r->fringes_outside_margins; - wset_scroll_bar_width (n, r->scroll_bar_width); + n->scroll_bar_width = r->scroll_bar_width; wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); /* Directly assign orthogonal coordinates and sizes. */ @@ -4191,9 +4155,7 @@ grow_mini_window (struct window *w, int delta) /* Grow the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines -= XINT (value); - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; adjust_glyphs (f); unblock_input (); @@ -4227,10 +4189,7 @@ shrink_mini_window (struct window *w) /* Shrink the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines = 1; - - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; adjust_glyphs (f); unblock_input (); @@ -4337,7 +4296,7 @@ window_internal_height (struct window *w) respectively. */ static void -window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) +window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror) { immediate_quit = 1; n = clip_to_bounds (INT_MIN, n, INT_MAX); @@ -4358,7 +4317,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) descriptions. */ static void -window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) +window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) { struct it it; struct window *w = XWINDOW (window); @@ -4456,8 +4415,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) w->contents); w->start_at_line_beg = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4602,8 +4559,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) bytepos = marker_byte_position (w->start); w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4726,7 +4681,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) See the comment of window_scroll for parameter descriptions. */ static void -window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) +window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror) { register struct window *w = XWINDOW (window); /* Fvertical_motion enters redisplay, which can trigger @@ -4738,7 +4693,7 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) register ptrdiff_t pos, pos_byte; register int ht = window_internal_height (w); register Lisp_Object tem; - int lose; + bool lose; Lisp_Object bolp; ptrdiff_t startpos = marker_position (w->start); ptrdiff_t startbyte = marker_byte_position (w->start); @@ -4802,8 +4757,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) set_marker_restricted_both (w->start, w->contents, pos, pos_byte); w->start_at_line_beg = !NILP (bolp); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -5172,7 +5125,7 @@ and redisplay normally--don't erase and redraw the frame. */) struct window *w = XWINDOW (selected_window); struct buffer *buf = XBUFFER (w->contents); struct buffer *obuf = current_buffer; - int center_p = 0; + bool center_p = 0; ptrdiff_t charpos, bytepos; EMACS_INT iarg IF_LINT (= 0); int this_scroll_margin; @@ -5517,7 +5470,7 @@ the return value is nil. Otherwise the value is t. */) struct Lisp_Vector *saved_windows; Lisp_Object new_current_buffer; Lisp_Object frame; - FRAME_PTR f; + struct frame *f; ptrdiff_t old_point = -1; CHECK_WINDOW_CONFIGURATION (configuration); @@ -5704,12 +5657,12 @@ the return value is nil. Otherwise the value is t. */) w->hscroll = XFASTINT (p->hscroll); w->min_hscroll = XFASTINT (p->min_hscroll); wset_display_table (w, p->display_table); - wset_left_margin_cols (w, p->left_margin_cols); - wset_right_margin_cols (w, p->right_margin_cols); - wset_left_fringe_width (w, p->left_fringe_width); - wset_right_fringe_width (w, p->right_fringe_width); + w->left_margin_cols = XINT (p->left_margin_cols); + w->right_margin_cols = XINT (p->right_margin_cols); + w->left_fringe_width = XINT (p->left_fringe_width); + w->right_fringe_width = XINT (p->right_fringe_width); w->fringes_outside_margins = !NILP (p->fringes_outside_margins); - wset_scroll_bar_width (w, p->scroll_bar_width); + w->scroll_bar_width = XINT (p->scroll_bar_width); wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); wset_dedicated (w, p->dedicated); wset_combination_limit (w, p->combination_limit); @@ -5735,9 +5688,6 @@ the return value is nil. Otherwise the value is t. */) } } - w->last_modified = 0; - w->last_overlay_modified = 0; - if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) /* If saved buffer is alive, install it. */ { @@ -6008,12 +5958,12 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i) XSETFASTINT (p->hscroll, w->hscroll); XSETFASTINT (p->min_hscroll, w->min_hscroll); p->display_table = w->display_table; - p->left_margin_cols = w->left_margin_cols; - p->right_margin_cols = w->right_margin_cols; - p->left_fringe_width = w->left_fringe_width; - p->right_fringe_width = w->right_fringe_width; + p->left_margin_cols = make_number (w->left_margin_cols); + p->right_margin_cols = make_number (w->right_margin_cols); + p->left_fringe_width = make_number (w->left_fringe_width); + p->right_fringe_width = make_number (w->right_fringe_width); p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; - p->scroll_bar_width = w->scroll_bar_width; + p->scroll_bar_width = make_number (w->scroll_bar_width); p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; p->dedicated = w->dedicated; p->combination_limit = w->combination_limit; @@ -6154,11 +6104,46 @@ saved by this function. */) XSETWINDOW_CONFIGURATION (tem, data); return (tem); } + +/* Called after W's margins, fringes or scroll bars was adjusted. */ + +static void +apply_window_adjustment (struct window *w) +{ + eassert (w); + adjust_window_margins (w); + clear_glyph_matrix (w->current_matrix); + w->window_end_valid = 0; + windows_or_buffers_changed++; + adjust_glyphs (XFRAME (WINDOW_FRAME (w))); +} + /*********************************************************************** Marginal Areas ***********************************************************************/ +static struct window * +set_window_margins (struct window *w, Lisp_Object left_width, + Lisp_Object right_width) +{ + int left, right; + + /* FIXME: what about margins that are too wide? */ + left = (NILP (left_width) ? 0 + : (CHECK_NATNUM (left_width), XINT (left_width))); + right = (NILP (right_width) ? 0 + : (CHECK_NATNUM (right_width), XINT (right_width))); + + if (w->left_margin_cols != left || w->right_margin_cols != right) + { + w->left_margin_cols = left; + w->right_margin_cols = right; + return w; + } + return NULL; +} + DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 2, 3, 0, doc: /* Set width of marginal areas of window WINDOW. @@ -6167,41 +6152,14 @@ WINDOW must be a live window and defaults to the selected one. Second arg LEFT-WIDTH specifies the number of character cells to reserve for the left marginal area. Optional third arg RIGHT-WIDTH does the same for the right marginal area. A nil width parameter -means no margin. */) +means no margin. + +Return t if any margin was actually changed and nil otherwise. */) (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width) { - struct window *w = decode_live_window (window); - - /* Translate negative or zero widths to nil. - Margins that are too wide have to be checked elsewhere. */ - - if (!NILP (left_width)) - { - CHECK_NUMBER (left_width); - if (XINT (left_width) <= 0) - left_width = Qnil; - } - - if (!NILP (right_width)) - { - CHECK_NUMBER (right_width); - if (XINT (right_width) <= 0) - right_width = Qnil; - } - - if (!EQ (w->left_margin_cols, left_width) - || !EQ (w->right_margin_cols, right_width)) - { - wset_left_margin_cols (w, left_width); - wset_right_margin_cols (w, right_width); - - adjust_window_margins (w); - - ++windows_or_buffers_changed; - adjust_glyphs (XFRAME (WINDOW_FRAME (w))); - } - - return Qnil; + struct window *w = set_window_margins (decode_live_window (window), + left_width, right_width); + return w ? (apply_window_adjustment (w), Qt) : Qnil; } @@ -6216,7 +6174,8 @@ as nil. */) (Lisp_Object window) { struct window *w = decode_live_window (window); - return Fcons (w->left_margin_cols, w->right_margin_cols); + return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil, + w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil); } @@ -6225,6 +6184,31 @@ as nil. */) Fringes ***********************************************************************/ +static struct window * +set_window_fringes (struct window *w, Lisp_Object left_width, + Lisp_Object right_width, Lisp_Object outside_margins) +{ + int left, right, outside = !NILP (outside_margins); + + left = (NILP (left_width) ? -1 + : (CHECK_NATNUM (left_width), XINT (left_width))); + right = (NILP (right_width) ? -1 + : (CHECK_NATNUM (right_width), XINT (right_width))); + + /* Do nothing on a tty or if nothing to actually change. */ + if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) + && (w->left_fringe_width != left + || w->right_fringe_width != right + || w->fringes_outside_margins != outside)) + { + w->left_fringe_width = left; + w->right_fringe_width = right; + w->fringes_outside_margins = outside; + return w; + } + return NULL; +} + DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 2, 4, 0, doc: /* Set the fringe widths of window WINDOW. @@ -6237,37 +6221,16 @@ frame's default fringe width. Default fringe widths can be set with the command `set-fringe-style'. If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes outside of the display margins. By default, fringes are drawn between -display marginal areas and the text area. */) - (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins) -{ - struct window *w = decode_live_window (window); - int outside = !NILP (outside_margins); - - if (!NILP (left_width)) - CHECK_NATNUM (left_width); - if (!NILP (right_width)) - CHECK_NATNUM (right_width); - - /* Do nothing on a tty. */ - if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) - && (!EQ (w->left_fringe_width, left_width) - || !EQ (w->right_fringe_width, right_width) - || w->fringes_outside_margins != outside)) - { - wset_left_fringe_width (w, left_width); - wset_right_fringe_width (w, right_width); - w->fringes_outside_margins = outside; - - adjust_window_margins (w); - - clear_glyph_matrix (w->current_matrix); - w->window_end_valid = 0; +display marginal areas and the text area. - ++windows_or_buffers_changed; - adjust_glyphs (XFRAME (WINDOW_FRAME (w))); - } - - return Qnil; +Return t if any fringe was actually changed and nil otherwise. */) + (Lisp_Object window, Lisp_Object left_width, + Lisp_Object right_width, Lisp_Object outside_margins) +{ + struct window *w + = set_window_fringes (decode_live_window (window), + left_width, right_width, outside_margins); + return w ? (apply_window_adjustment (w), Qt) : Qnil; } @@ -6292,29 +6255,14 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */) Scroll bars ***********************************************************************/ -DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, - Sset_window_scroll_bars, 2, 4, 0, - doc: /* Set width and type of scroll bars of window WINDOW. -WINDOW must be a live window and defaults to the selected one. - -Second parameter WIDTH specifies the pixel width for the scroll bar; -this is automatically adjusted to a multiple of the frame column width. -Third parameter VERTICAL-TYPE specifies the type of the vertical scroll -bar: left, right, or nil. -If WIDTH is nil, use the frame's scroll-bar width. -If VERTICAL-TYPE is t, use the frame's scroll-bar type. -Fourth parameter HORIZONTAL-TYPE is currently unused. */) - (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, Lisp_Object horizontal_type) +static struct window * +set_window_scroll_bars (struct window *w, Lisp_Object width, + Lisp_Object vertical_type, Lisp_Object horizontal_type) { - struct window *w = decode_live_window (window); + int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); - if (!NILP (width)) - { - CHECK_RANGED_INTEGER (width, 0, INT_MAX); - - if (XINT (width) == 0) - vertical_type = Qnil; - } + if (iwidth == 0) + vertical_type = Qnil; if (!(NILP (vertical_type) || EQ (vertical_type, Qleft) @@ -6322,22 +6270,37 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */) || EQ (vertical_type, Qt))) error ("Invalid type of vertical scroll bar"); - if (!EQ (w->scroll_bar_width, width) + if (w->scroll_bar_width != iwidth || !EQ (w->vertical_scroll_bar_type, vertical_type)) { - wset_scroll_bar_width (w, width); + w->scroll_bar_width = iwidth; wset_vertical_scroll_bar_type (w, vertical_type); + return w; + } + return NULL; +} - adjust_window_margins (w); - - clear_glyph_matrix (w->current_matrix); - w->window_end_valid = 0; +DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, + Sset_window_scroll_bars, 2, 4, 0, + doc: /* Set width and type of scroll bars of window WINDOW. +WINDOW must be a live window and defaults to the selected one. - ++windows_or_buffers_changed; - adjust_glyphs (XFRAME (WINDOW_FRAME (w))); - } +Second parameter WIDTH specifies the pixel width for the scroll bar; +this is automatically adjusted to a multiple of the frame column width. +Third parameter VERTICAL-TYPE specifies the type of the vertical scroll +bar: left, right, or nil. +If WIDTH is nil, use the frame's scroll-bar width. +If VERTICAL-TYPE is t, use the frame's scroll-bar type. +Fourth parameter HORIZONTAL-TYPE is currently unused. - return Qnil; +Return t if scroll bars was actually changed and nil otherwise. */) + (Lisp_Object window, Lisp_Object width, + Lisp_Object vertical_type, Lisp_Object horizontal_type) +{ + struct window *w + = set_window_scroll_bars (decode_live_window (window), + width, vertical_type, horizontal_type); + return w ? (apply_window_adjustment (w), Qt) : Qnil; } @@ -6466,38 +6429,6 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u return cont; } - -/* Freeze or unfreeze the window start of W unless it is a - mini-window or the selected window. FREEZE_P non-null means freeze - the window start. */ - -static int -freeze_window_start (struct window *w, void *freeze_p) -{ - if (MINI_WINDOW_P (w) - || (WINDOWP (selected_window) /* Can be nil in corner cases. */ - && (w == XWINDOW (selected_window) - || (MINI_WINDOW_P (XWINDOW (selected_window)) - && ! NILP (Vminibuf_scroll_window) - && w == XWINDOW (Vminibuf_scroll_window))))) - freeze_p = NULL; - - w->frozen_window_start_p = freeze_p != NULL; - return 1; -} - - -/* Freeze or unfreeze the window starts of all leaf windows on frame - F, except the selected window and a mini-window. FREEZE_P non-zero - means freeze the window start. */ - -void -freeze_window_starts (struct frame *f, bool freeze_p) -{ - foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0)); -} - - /*********************************************************************** Initialization ***********************************************************************/ diff --git a/src/window.h b/src/window.h index 5da6165c48d..c64641825e3 100644 --- a/src/window.h +++ b/src/window.h @@ -141,32 +141,10 @@ struct window it yet, or if the frame doesn't have any scroll bars, this is nil. */ Lisp_Object vertical_scroll_bar; - /* Width of left and right marginal areas. A value of nil means - no margin. */ - Lisp_Object left_margin_cols; - Lisp_Object right_margin_cols; - - /* Width of left and right fringes. - A value of nil or t means use frame values. */ - Lisp_Object left_fringe_width; - Lisp_Object right_fringe_width; - - /* Pixel width of scroll bars. - A value of nil or t means use frame values. */ - Lisp_Object scroll_bar_width; - /* Type of vertical scroll bar. A value of nil means no scroll bar. A value of t means use frame value. */ Lisp_Object vertical_scroll_bar_type; - /* Z - the buffer position of the last glyph in the current - matrix of W. Only valid if window_end_valid is nonzero. */ - Lisp_Object window_end_pos; - - /* Glyph matrix row of the last glyph in the current matrix - of W. Only valid if window_end_valid is nonzero. */ - Lisp_Object window_end_vpos; - /* Display-table to use for displaying chars in this window. Nil means use the buffer's own display-table. */ Lisp_Object display_table; @@ -269,6 +247,28 @@ struct window /* This is handy for undrawing the cursor. */ int phys_cursor_ascent, phys_cursor_height; + /* Width of left and right fringes, in pixels. + A value of -1 means use frame values. */ + int left_fringe_width; + int right_fringe_width; + + /* Width of left and right marginal areas in columns. + A value of 0 means no margin. */ + int left_margin_cols; + int right_margin_cols; + + /* Pixel width of scroll bars. + A value of -1 means use frame values. */ + int scroll_bar_width; + + /* Z - the buffer position of the last glyph in the current + matrix of W. Only valid if window_end_valid is nonzero. */ + ptrdiff_t window_end_pos; + + /* Glyph matrix row of the last glyph in the current matrix + of W. Only valid if window_end_valid is nonzero. */ + int window_end_vpos; + /* Non-zero if this window is a minibuffer window. */ unsigned mini : 1; @@ -316,11 +316,6 @@ struct window Currently only used for menu bar windows of frames. */ unsigned pseudo_window_p : 1; - /* 1 means the window start of this window is frozen and may not - be changed during redisplay. If point is not in the window, - accept that. */ - unsigned frozen_window_start_p : 1; - /* Non-zero means fringes are drawn outside display margins. Otherwise draw them between margin areas and text. */ unsigned fringes_outside_margins : 1; @@ -371,16 +366,6 @@ wset_vertical_scroll_bar (struct window *w, Lisp_Object val) w->vertical_scroll_bar = val; } WINDOW_INLINE void -wset_window_end_pos (struct window *w, Lisp_Object val) -{ - w->window_end_pos = val; -} -WINDOW_INLINE void -wset_window_end_vpos (struct window *w, Lisp_Object val) -{ - w->window_end_vpos = val; -} -WINDOW_INLINE void wset_prev_buffers (struct window *w, Lisp_Object val) { w->prev_buffers = val; @@ -605,33 +590,21 @@ wset_next_buffers (struct window *w, Lisp_Object val) /* Width of left margin area in columns. */ -#define WINDOW_LEFT_MARGIN_COLS(W) \ - (NILP (W->left_margin_cols) \ - ? 0 \ - : XINT (W->left_margin_cols)) +#define WINDOW_LEFT_MARGIN_COLS(W) (W->left_margin_cols) /* Width of right marginal area in columns. */ -#define WINDOW_RIGHT_MARGIN_COLS(W) \ - (NILP (W->right_margin_cols) \ - ? 0 \ - : XINT (W->right_margin_cols)) +#define WINDOW_RIGHT_MARGIN_COLS(W) (W->right_margin_cols) /* Width of left margin area in pixels. */ -#define WINDOW_LEFT_MARGIN_WIDTH(W) \ - (NILP (W->left_margin_cols) \ - ? 0 \ - : (XINT (W->left_margin_cols) \ - * WINDOW_FRAME_COLUMN_WIDTH (W))) +#define WINDOW_LEFT_MARGIN_WIDTH(W) \ + (W->left_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W)) /* Width of right marginal area in pixels. */ -#define WINDOW_RIGHT_MARGIN_WIDTH(W) \ - (NILP (W->right_margin_cols) \ - ? 0 \ - : (XINT (W->right_margin_cols) \ - * WINDOW_FRAME_COLUMN_WIDTH (W))) +#define WINDOW_RIGHT_MARGIN_WIDTH(W) \ + (W->right_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W)) /* Total width of fringes reserved for drawing truncation bitmaps, continuation bitmaps and alike. The width is in canonical char @@ -640,10 +613,10 @@ wset_next_buffers (struct window *w, Lisp_Object val) able to split windows horizontally nicely. */ #define WINDOW_FRINGE_COLS(W) \ - ((INTEGERP (W->left_fringe_width) \ - || INTEGERP (W->right_fringe_width)) \ - ? ((WINDOW_LEFT_FRINGE_WIDTH (W) \ - + WINDOW_RIGHT_FRINGE_WIDTH (W) \ + ((W->left_fringe_width >= 0 \ + && W->right_fringe_width >= 0) \ + ? ((W->left_fringe_width \ + + W->right_fringe_width \ + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ / WINDOW_FRAME_COLUMN_WIDTH (W)) \ : FRAME_FRINGE_COLS (WINDOW_XFRAME (W))) @@ -663,13 +636,11 @@ wset_next_buffers (struct window *w, Lisp_Object val) /* Pixel-width of the left and right fringe. */ #define WINDOW_LEFT_FRINGE_WIDTH(W) \ - (INTEGERP (W->left_fringe_width) \ - ? XFASTINT (W->left_fringe_width) \ + (W->left_fringe_width >= 0 ? W->left_fringe_width \ : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W))) #define WINDOW_RIGHT_FRINGE_WIDTH(W) \ - (INTEGERP (W->right_fringe_width) \ - ? XFASTINT (W->right_fringe_width) \ + (W->right_fringe_width >= 0 ? W->right_fringe_width \ : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W))) /* Total width of fringes in pixels. */ @@ -714,8 +685,7 @@ wset_next_buffers (struct window *w, Lisp_Object val) nonzero. */ #define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \ - (INTEGERP (w->scroll_bar_width) \ - ? XFASTINT (w->scroll_bar_width) \ + (w->scroll_bar_width >= 0 ? w->scroll_bar_width \ : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w))) /* Width that a scroll bar in window W should have, if there is one. @@ -723,8 +693,8 @@ wset_next_buffers (struct window *w, Lisp_Object val) this is still nonzero. */ #define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \ - (INTEGERP (w->scroll_bar_width) \ - ? ((XFASTINT (w->scroll_bar_width) \ + (w->scroll_bar_width >= 0 \ + ? ((w->scroll_bar_width \ + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) \ / WINDOW_FRAME_COLUMN_WIDTH (w)) \ : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w))) @@ -847,13 +817,25 @@ wset_next_buffers (struct window *w, Lisp_Object val) #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ (window_box_left ((W), TEXT_AREA) + (X)) -/* This is the window in which the terminal's cursor should - be left when nothing is being done with it. This must - always be a leaf window, and its buffer is selected by - the top level editing loop at the end of each command. +/* Nonzero if the background of the window W's fringe that is adjacent to + a scroll bar is extended to the gap between the fringe and the bar. */ + +#define WINDOW_FRINGE_EXTENDED_P(w) \ + (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \ + ? (WINDOW_LEFTMOST_P (w) \ + && WINDOW_LEFT_FRINGE_WIDTH (w) \ + && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \ + || WINDOW_LEFT_MARGIN_COLS (w) == 0)) \ + : (WINDOW_RIGHTMOST_P (w) \ + && WINDOW_RIGHT_FRINGE_WIDTH (w) \ + && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \ + || WINDOW_RIGHT_MARGIN_COLS (w) == 0))) - This value is always the same as - FRAME_SELECTED_WINDOW (selected_frame). */ +/* This is the window in which the terminal's cursor should be left when + nothing is being done with it. This must always be a leaf window, and its + buffer is selected by the top level editing loop at the end of each command. + + This value is always the same as FRAME_SELECTED_WINDOW (selected_frame). */ extern Lisp_Object selected_window; @@ -888,7 +870,6 @@ extern Lisp_Object window_from_coordinates (struct frame *, int, int, extern void resize_frame_windows (struct frame *, int, bool); extern void restore_window_configuration (Lisp_Object); extern void delete_all_child_windows (Lisp_Object); -extern void freeze_window_starts (struct frame *, bool); extern void grow_mini_window (struct window *, int); extern void shrink_mini_window (struct window *); extern int window_relative_x_coord (struct window *, enum window_part, int); @@ -925,10 +906,6 @@ extern int update_mode_lines; extern int windows_or_buffers_changed; -/* Nonzero means a frame's cursor type has been changed. */ - -extern int cursor_type_changed; - /* If *ROWS or *COLS are too small a size for FRAME, set them to the minimum allowable size. */ @@ -973,6 +950,7 @@ extern void replace_buffer_in_windows (Lisp_Object); extern void replace_buffer_in_windows_safely (Lisp_Object); /* This looks like a setter, but it is a bit special. */ extern void wset_buffer (struct window *, Lisp_Object); +extern bool window_outdated (struct window *); extern void init_window_once (void); extern void init_window (void); extern void syms_of_window (void); diff --git a/src/xdisp.c b/src/xdisp.c index 1da7de5759c..ea1cd7dd2bc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -524,7 +524,7 @@ int windows_or_buffers_changed; /* Nonzero means a frame's cursor type has been changed. */ -int cursor_type_changed; +static int cursor_type_changed; /* Nonzero after display_mode_line if %l was used and it displayed a line number. */ @@ -804,7 +804,6 @@ static void pint2str (char *, int, ptrdiff_t); static void pint2hrstr (char *, int, ptrdiff_t); static struct text_pos run_window_scroll_functions (Lisp_Object, struct text_pos); -static void reconsider_clip_changes (struct window *, struct buffer *); static int text_outside_line_unchanged_p (struct window *, ptrdiff_t, ptrdiff_t); static void store_mode_line_noprop_char (char); @@ -983,22 +982,18 @@ window_box_width (struct window *w, int area) if (area == TEXT_AREA) { - if (INTEGERP (w->left_margin_cols)) - cols -= XFASTINT (w->left_margin_cols); - if (INTEGERP (w->right_margin_cols)) - cols -= XFASTINT (w->right_margin_cols); + cols -= max (0, w->left_margin_cols); + cols -= max (0, w->right_margin_cols); pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w); } else if (area == LEFT_MARGIN_AREA) { - cols = (INTEGERP (w->left_margin_cols) - ? XFASTINT (w->left_margin_cols) : 0); + cols = max (0, w->left_margin_cols); pixels = 0; } else if (area == RIGHT_MARGIN_AREA) { - cols = (INTEGERP (w->right_margin_cols) - ? XFASTINT (w->right_margin_cols) : 0); + cols = max (0, w->right_margin_cols); pixels = 0; } } @@ -1854,7 +1849,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id) not force the value into range. */ void -pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y, +pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y, int *x, int *y, NativeRectangle *bounds, int noclip) { @@ -2466,7 +2461,16 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect) #endif /* HAVE_WINDOW_SYSTEM */ - +static void +adjust_window_ends (struct window *w, struct glyph_row *row, bool current) +{ + eassert (w); + w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); + w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); + w->window_end_vpos + = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix); +} + /*********************************************************************** Lisp form evaluation ***********************************************************************/ @@ -2602,8 +2606,7 @@ check_window_end (struct window *w) if (!MINI_WINDOW_P (w) && w->window_end_valid) { struct glyph_row *row; - eassert ((row = MATRIX_ROW (w->current_matrix, - XFASTINT (w->window_end_vpos)), + eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos), !row->enabled_p || MATRIX_ROW_DISPLAYS_TEXT_P (row) || MATRIX_ROW_VPOS (row, w->current_matrix) == 0)); @@ -5346,7 +5349,7 @@ handle_composition_prop (struct it *it) composition (in the case that the composition is from the current buffer), draw a glyph composed from the composition components. */ if (find_composition (pos, -1, &start, &end, &prop, string) - && COMPOSITION_VALID_P (start, end, prop) + && composition_valid_p (start, end, prop) && (STRINGP (it->string) || (PT <= start || PT >= end))) { if (start < pos) @@ -5509,8 +5512,8 @@ next_overlay_string (struct it *it) static int compare_overlay_entries (const void *e1, const void *e2) { - struct overlay_entry *entry1 = (struct overlay_entry *) e1; - struct overlay_entry *entry2 = (struct overlay_entry *) e2; + struct overlay_entry const *entry1 = e1; + struct overlay_entry const *entry2 = e2; int result; if (entry1->after_string_p != entry2->after_string_p) @@ -7458,6 +7461,8 @@ static int next_element_from_display_vector (struct it *it) { Lisp_Object gc; + int prev_face_id = it->face_id; + int next_face_id; /* Precondition. */ eassert (it->dpvec && it->current.dpvec_index >= 0); @@ -7470,6 +7475,8 @@ next_element_from_display_vector (struct it *it) if (GLYPH_CODE_P (gc)) { + struct face *this_face, *prev_face, *next_face; + it->c = GLYPH_CODE_CHAR (gc); it->len = CHAR_BYTES (it->c); @@ -7485,6 +7492,41 @@ next_element_from_display_vector (struct it *it) it->face_id = merge_faces (it->f, Qt, lface_id, it->saved_face_id); } + + /* Glyphs in the display vector could have the box face, so we + need to set the related flags in the iterator, as + appropriate. */ + this_face = FACE_FROM_ID (it->f, it->face_id); + prev_face = FACE_FROM_ID (it->f, prev_face_id); + + /* Is this character the first character of a box-face run? */ + it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX + && (!prev_face + || prev_face->box == FACE_NO_BOX)); + + /* For the last character of the box-face run, we need to look + either at the next glyph from the display vector, or at the + face we saw before the display vector. */ + next_face_id = it->saved_face_id; + if (it->current.dpvec_index < it->dpend - it->dpvec - 1) + { + if (it->dpvec_face_id >= 0) + next_face_id = it->dpvec_face_id; + else + { + int lface_id = + GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]); + + if (lface_id > 0) + next_face_id = merge_faces (it->f, Qt, lface_id, + it->saved_face_id); + } + } + next_face = FACE_FROM_ID (it->f, next_face_id); + it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX + && (!next_face + || next_face->box == FACE_NO_BOX)); + it->face_box_p = this_face && this_face->box != FACE_NO_BOX; } else /* Display table entry is invalid. Return a space. */ @@ -9059,7 +9101,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos && it->current_x == it->last_visible_x - 1 && it->c != '\n' && it->c != '\t' - && it->vpos < XFASTINT (it->w->window_end_vpos)) + && it->vpos < it->w->window_end_vpos) { it->continuation_lines_width += it->current_x; it->current_x = it->hpos = it->max_ascent = it->max_descent = 0; @@ -9790,7 +9832,7 @@ message3_nolog (Lisp_Object m) void message1 (const char *m) { - message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil); + message3 (m ? build_unibyte_string (m) : Qnil); } @@ -9799,7 +9841,7 @@ message1 (const char *m) void message1_nolog (const char *m) { - message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil); + message3_nolog (m ? build_unibyte_string (m) : Qnil); } /* Display a message M which contains a single %s @@ -9909,7 +9951,7 @@ vmessage (const char *m, va_list ap) ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f); char *message_buf = alloca (maxsize + 1); - len = doprnt (message_buf, maxsize, m, (char *)0, ap); + len = doprnt (message_buf, maxsize, m, 0, ap); message3 (make_string (message_buf, len)); } @@ -10461,7 +10503,8 @@ resize_mini_window (struct window *w, int exact_p) if (height > WINDOW_TOTAL_LINES (w)) { int old_height = WINDOW_TOTAL_LINES (w); - freeze_window_starts (f, 1); + + FRAME_WINDOWS_FROZEN (f) = 1; grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; } @@ -10469,7 +10512,8 @@ resize_mini_window (struct window *w, int exact_p) && (exact_p || BEGV == ZV)) { int old_height = WINDOW_TOTAL_LINES (w); - freeze_window_starts (f, 0); + + FRAME_WINDOWS_FROZEN (f) = 0; shrink_mini_window (w); window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; } @@ -10480,19 +10524,21 @@ resize_mini_window (struct window *w, int exact_p) if (height > WINDOW_TOTAL_LINES (w)) { int old_height = WINDOW_TOTAL_LINES (w); - freeze_window_starts (f, 1); + + FRAME_WINDOWS_FROZEN (f) = 1; grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; } else if (height < WINDOW_TOTAL_LINES (w)) { int old_height = WINDOW_TOTAL_LINES (w); - freeze_window_starts (f, 0); + + FRAME_WINDOWS_FROZEN (f) = 0; shrink_mini_window (w); if (height) { - freeze_window_starts (f, 1); + FRAME_WINDOWS_FROZEN (f) = 1; grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); } @@ -10850,17 +10896,6 @@ buffer_shared_and_changed (void) && UNCHANGED_MODIFIED < MODIFF); } -/* Nonzero if W doesn't reflect the actual state of current buffer due - to its text or overlays change. FIXME: this may be called when - XBUFFER (w->contents) != current_buffer, which looks suspicious. */ - -static int -window_outdated (struct window *w) -{ - return (w->last_modified < MODIFF - || w->last_overlay_modified < OVERLAY_MODIFF); -} - /* Nonzero if W's buffer was changed but not saved or Transient Mark mode is enabled and mark of W's buffer was changed since last W's update. */ @@ -10886,6 +10921,31 @@ mode_line_update_needed (struct window *w) && (w->column_number_displayed != current_column ())); } +/* Nonzero if window start of W is frozen and may not be changed during + redisplay. */ + +static bool +window_frozen_p (struct window *w) +{ + if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w)))) + { + Lisp_Object window; + + XSETWINDOW (window, w); + if (MINI_WINDOW_P (w)) + return 0; + else if (EQ (window, selected_window)) + return 0; + else if (MINI_WINDOW_P (XWINDOW (selected_window)) + && EQ (window, Vminibuf_scroll_window)) + /* This special window can't be frozen too. */ + return 0; + else + return 1; + } + return 0; +} + /*********************************************************************** Mode Lines and Frame Titles ***********************************************************************/ @@ -11181,7 +11241,18 @@ prepare_menu_bars (void) { f = XFRAME (frame); if (!EQ (frame, tooltip_frame) - && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))) + && (FRAME_ICONIFIED_P (f) + || FRAME_VISIBLE_P (f) == 1 + /* Exclude TTY frames that are obscured because they + are not the top frame on their console. This is + because x_consider_frame_title actually switches + to the frame, which for TTY frames means it is + marked as garbaged, and will be completely + redrawn on the next redisplay cycle. This causes + TTY frames to be completely redrawn, when there + are more than one of them, even though nothing + should be changed on display. */ + || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f)))) x_consider_frame_title (frame); } } @@ -11386,7 +11457,7 @@ struct cursor_pos output_cursor; /* EXPORT: Set the global variable output_cursor to CURSOR. All cursor - positions are relative to updated_window. */ + positions are relative to currently updated window. */ void set_output_cursor (struct cursor_pos *cursor) @@ -11401,41 +11472,24 @@ set_output_cursor (struct cursor_pos *cursor) /* EXPORT for RIF: Set a nominal cursor position. - HPOS and VPOS are column/row positions in a window glyph matrix. X - and Y are window text area relative pixel positions. + HPOS and VPOS are column/row positions in a window glyph matrix. + X and Y are window text area relative pixel positions. - If this is done during an update, updated_window will contain the - window that is being updated and the position is the future output - cursor position for that window. If updated_window is null, use - selected_window and display the cursor at the given position. */ + This is always done during window update, so the position is the + future output cursor position for currently updated window W. + NOTE: W is used only to check whether this function is called + in a consistent manner via the redisplay interface. */ void -x_cursor_to (int vpos, int hpos, int y, int x) +x_cursor_to (struct window *w, int vpos, int hpos, int y, int x) { - struct window *w; - - /* If updated_window is not set, work on selected_window. */ - if (updated_window) - w = updated_window; - else - w = XWINDOW (selected_window); + eassert (w); /* Set the output cursor. */ output_cursor.hpos = hpos; output_cursor.vpos = vpos; output_cursor.x = x; output_cursor.y = y; - - /* If not called as part of an update, really display the cursor. - This will also set the cursor position of W. */ - if (updated_window == NULL) - { - block_input (); - display_and_set_cursor (w, 1, hpos, vpos, x, y); - if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional) - FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ()); - unblock_input (); - } } #endif /* HAVE_WINDOW_SYSTEM */ @@ -11449,7 +11503,7 @@ x_cursor_to (int vpos, int hpos, int y, int x) /* Where the mouse was last time we reported a mouse event. */ -FRAME_PTR last_mouse_frame; +struct frame *last_mouse_frame; /* Tool-bar item index of the item on which a mouse button was pressed or -1. */ @@ -12852,7 +12906,7 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt, if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf) && find_composition (prev_pt, -1, &start, &end, &prop, buffer) - && COMPOSITION_VALID_P (start, end, prop) + && composition_valid_p (start, end, prop) && start < prev_pt && end > prev_pt) /* The last point was within the composition. Return 1 iff point moved out of the composition. */ @@ -12862,17 +12916,17 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt, /* Check a composition at the current point. */ return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf) && find_composition (pt, -1, &start, &end, &prop, buffer) - && COMPOSITION_VALID_P (start, end, prop) + && composition_valid_p (start, end, prop) && start < pt && end > pt); } - -/* Reconsider the setting of B->clip_changed which is displayed - in window W. */ +/* Reconsider the clip changes of buffer which is displayed in W. */ static void -reconsider_clip_changes (struct window *w, struct buffer *b) +reconsider_clip_changes (struct window *w) { + struct buffer *b = XBUFFER (w->contents); + if (b->clip_changed && w->window_end_valid && w->current_matrix->buffer == b @@ -12885,24 +12939,17 @@ reconsider_clip_changes (struct window *w, struct buffer *b) we set b->clip_changed to 1 to force updating the screen. If b->clip_changed has already been set to 1, we can skip this check. */ - if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid) + if (!b->clip_changed && w->window_end_valid) { - ptrdiff_t pt; + ptrdiff_t pt = (w == XWINDOW (selected_window) + ? PT : marker_position (w->pointm)); - if (w == XWINDOW (selected_window)) - pt = PT; - else - pt = marker_position (w->pointm); - - if ((w->current_matrix->buffer != XBUFFER (w->contents) - || pt != w->last_point) + if ((w->current_matrix->buffer != b || pt != w->last_point) && check_point_in_composition (w->current_matrix->buffer, - w->last_point, - XBUFFER (w->contents), pt)) + w->last_point, b, pt)) b->clip_changed = 1; } } - #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ @@ -12923,10 +12970,10 @@ redisplay_internal (void) struct window *sw; struct frame *fr; int pending; - int must_finish = 0; + bool must_finish = 0, match_p; struct text_pos tlbufpos, tlendpos; int number_of_visible_frames; - ptrdiff_t count, count1; + ptrdiff_t count; struct frame *sf; int polling_stopped_here = 0; Lisp_Object tail, frame; @@ -12983,7 +13030,6 @@ redisplay_internal (void) sw = w; pending = 0; - reconsider_clip_changes (w, current_buffer); last_escape_glyph_frame = NULL; last_escape_glyph_face_id = (1 << FACE_ID_BITS); last_glyphless_glyph_frame = NULL; @@ -13038,10 +13084,7 @@ redisplay_internal (void) /* do_pending_window_change could change the selected_window due to frame resizing which makes the selected window too small. */ if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) - { - sw = w; - reconsider_clip_changes (w, current_buffer); - } + sw = w; /* Clear frames marked as garbaged. */ clear_garbaged_frames (); @@ -13053,22 +13096,31 @@ redisplay_internal (void) if (windows_or_buffers_changed) update_mode_lines++; - /* Detect case that we need to write or remove a star in the mode line. */ - if ((SAVE_MODIFF < MODIFF) != w->last_had_star) + reconsider_clip_changes (w); + + /* In most cases selected window displays current buffer. */ + match_p = XBUFFER (w->contents) == current_buffer; + if (match_p) { - w->update_mode_line = 1; - if (buffer_shared_and_changed ()) - update_mode_lines++; - } + ptrdiff_t count1; - /* Avoid invocation of point motion hooks by `current_column' below. */ - count1 = SPECPDL_INDEX (); - specbind (Qinhibit_point_motion_hooks, Qt); + /* Detect case that we need to write or remove a star in the mode line. */ + if ((SAVE_MODIFF < MODIFF) != w->last_had_star) + { + w->update_mode_line = 1; + if (buffer_shared_and_changed ()) + update_mode_lines++; + } - if (mode_line_update_needed (w)) - w->update_mode_line = 1; + /* Avoid invocation of point motion hooks by `current_column' below. */ + count1 = SPECPDL_INDEX (); + specbind (Qinhibit_point_motion_hooks, Qt); - unbind_to (count1, Qnil); + if (mode_line_update_needed (w)) + w->update_mode_line = 1; + + unbind_to (count1, Qnil); + } consider_all_windows_p = (update_mode_lines || buffer_shared_and_changed () @@ -13167,7 +13219,7 @@ redisplay_internal (void) && !FRAME_OBSCURED_P (XFRAME (w->frame)) /* Make sure recorded data applies to current buffer, etc. */ && this_line_buffer == current_buffer - && current_buffer == XBUFFER (w->contents) + && match_p && !w->force_start && !w->optional_new_start /* Point must be on the line that we have info recorded about. */ @@ -13263,12 +13315,12 @@ redisplay_internal (void) adjusted. */ if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1)) { - if (XFASTINT (w->window_end_vpos) < this_line_vpos) - wset_window_end_vpos (w, make_number (this_line_vpos)); + if (w->window_end_vpos < this_line_vpos) + w->window_end_vpos = this_line_vpos; } - else if (XFASTINT (w->window_end_vpos) == this_line_vpos + else if (w->window_end_vpos == this_line_vpos && this_line_vpos > 0) - wset_window_end_vpos (w, make_number (this_line_vpos - 1)); + w->window_end_vpos = this_line_vpos - 1; w->window_end_valid = 0; /* Update hint: No need to try to scroll in update_window. */ @@ -14458,8 +14510,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp) struct window *w = XWINDOW (window); SET_MARKER_FROM_TEXT_POS (w->start, startp); - if (current_buffer != XBUFFER (w->contents)) - emacs_abort (); + eassert (current_buffer == XBUFFER (w->contents)); if (!NILP (Vwindow_scroll_functions)) { @@ -14900,7 +14951,25 @@ compute_window_start_on_continuation_line (struct window *w) { min_distance = distance; pos = it.current.pos; - move_it_by_lines (&it, 1); + if (it.line_wrap == WORD_WRAP) + { + /* Under WORD_WRAP, move_it_by_lines is likely to + overshoot and stop not at the first, but the + second character from the left margin. So in + that case, we need a more tight control on the X + coordinate of the iterator than move_it_by_lines + promises in its contract. The method is to first + go to the last (rightmost) visible character of a + line, then move to the leftmost character on the + next line in a separate call. */ + move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1, + MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + move_it_to (&it, ZV, 0, + it.current_y + it.max_ascent + it.max_descent, -1, + MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + } + else + move_it_by_lines (&it, 1); } /* Set the window start there. */ @@ -14952,6 +15021,10 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste if-statement below. Now, this field is converted to ptrdiff_t, thus zero means invalid position in a buffer. */ eassert (w->last_point > 0); + /* Likewise there was a check whether window_end_vpos is nil or larger + than the window. Now window_end_vpos is int and so never nil, but + let's leave eassert to check whether it fits in the window. */ + eassert (w->window_end_vpos < w->current_matrix->nrows); /* Handle case where text has not changed, only point, and it has not moved off the frame. */ @@ -14979,13 +15052,6 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste since the handling of this_line_start_pos, etc., in redisplay handles the same cases. */ && !EQ (window, minibuf_window) - /* When splitting windows or for new windows, it happens that - redisplay is called with a nil window_end_vpos or one being - larger than the window. This should really be fixed in - window.c. I don't have this on my list, now, so we do - approximately the same as the old redisplay code. --gerd. */ - && INTEGERP (w->window_end_vpos) - && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows && (FRAME_WINDOW_P (f) || !overlay_arrow_in_current_buffer_p ())) { @@ -15299,7 +15365,7 @@ set_vertical_scroll_bar (struct window *w) start = marker_position (w->start) - BUF_BEGV (buf); /* I don't think this is guaranteed to be right. For the moment, we'll pretend it is. */ - end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf); + end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf); if (end < start) end = start; @@ -15360,7 +15426,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) eassert (XMARKER (w->pointm)->buffer == buffer); restart: - reconsider_clip_changes (w, buffer); + reconsider_clip_changes (w); frame_line_height = default_line_pixel_height (w); /* Has the mode line to be updated? */ @@ -15440,8 +15506,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p) && !current_buffer->clip_changed && !window_outdated (w)); - /* When windows_or_buffers_changed is non-zero, we can't rely on - the window end being valid, so set it to nil there. */ + /* When windows_or_buffers_changed is non-zero, we can't rely + on the window end being valid, so set it to zero there. */ if (windows_or_buffers_changed) { /* If window starts on a continuation line, maybe adjust the @@ -15450,6 +15516,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p) compute_window_start_on_continuation_line (w); w->window_end_valid = 0; + /* If so, we also can't rely on current matrix + and should not fool try_cursor_movement below. */ + current_matrix_up_to_date_p = 0; } /* Some sanity checks. */ @@ -15531,7 +15600,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) /* Handle case where place to start displaying has been specified, unless the specified location is outside the accessible range. */ - if (w->force_start || w->frozen_window_start_p) + if (w->force_start || window_frozen_p (w)) { /* We set this later on if we have to adjust point. */ int new_vpos = -1; @@ -15559,8 +15628,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) startp = run_window_scroll_functions (window, startp); } - w->last_modified = 0; - w->last_overlay_modified = 0; if (CHARPOS (startp) < BEGV) SET_TEXT_POS (startp, BEGV, BEGV_BYTE); else if (CHARPOS (startp) > ZV) @@ -15578,7 +15645,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) goto need_larger_matrices; } - if (w->cursor.vpos < 0 && !w->frozen_window_start_p) + if (w->cursor.vpos < 0 && !window_frozen_p (w)) { /* If point does not appear, try to move point so it does appear. The desired matrix has been built above, so we @@ -15806,9 +15873,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) try_to_scroll: - w->last_modified = 0; - w->last_overlay_modified = 0; - /* Redisplay the mode line. Select the buffer properly for that. */ if (!update_mode_line) { @@ -15994,7 +16058,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) line.) */ if (w->cursor.vpos < 0) { - if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos)) + if (w->window_end_valid && PT >= Z - w->window_end_pos) { clear_glyph_matrix (w->desired_matrix); move_it_by_lines (&it, 1); @@ -16287,8 +16351,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) } /* If bottom moved off end of frame, change mode line percentage. */ - if (XFASTINT (w->window_end_pos) <= 0 - && Z != IT_CHARPOS (it)) + if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it)) w->update_mode_line = 1; /* Set window_end_pos to the offset of the last character displayed @@ -16297,21 +16360,16 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) if (last_text_row) { eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row)); - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - wset_window_end_pos - (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix))); + adjust_window_ends (w, last_text_row, 0); eassert (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix, - XFASTINT (w->window_end_vpos)))); + w->window_end_vpos))); } else { w->window_end_bytepos = Z_BYTE - ZV_BYTE; - wset_window_end_pos (w, make_number (Z - ZV)); - wset_window_end_vpos (w, make_number (0)); + w->window_end_pos = Z - ZV; + w->window_end_vpos = 0; } /* But that is not valid info until redisplay finishes. */ @@ -16535,32 +16593,15 @@ try_window_reusing_current_matrix (struct window *w) The value of last_text_row is the last displayed line containing text. */ if (last_reused_text_row) - { - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row); - wset_window_end_pos - (w, make_number (Z - - MATRIX_ROW_END_CHARPOS (last_reused_text_row))); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row, - w->current_matrix))); - } + adjust_window_ends (w, last_reused_text_row, 1); else if (last_text_row) - { - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - wset_window_end_pos - (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (last_text_row, - w->desired_matrix))); - } + adjust_window_ends (w, last_text_row, 0); else { /* This window must be completely empty. */ w->window_end_bytepos = Z_BYTE - ZV_BYTE; - wset_window_end_pos (w, make_number (Z - ZV)); - wset_window_end_vpos (w, make_number (0)); + w->window_end_pos = Z - ZV; + w->window_end_vpos = 0; } w->window_end_valid = 0; @@ -16745,20 +16786,9 @@ try_window_reusing_current_matrix (struct window *w) the window end is in reused rows which in turn means that only its vpos can have changed. */ if (last_text_row) - { - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - wset_window_end_pos - (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (last_text_row, - w->desired_matrix))); - } + adjust_window_ends (w, last_text_row, 0); else - { - wset_window_end_vpos - (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled)); - } + w->window_end_vpos -= nrows_scrolled; w->window_end_valid = 0; w->desired_matrix->no_scrolling_p = 1; @@ -16898,11 +16928,11 @@ find_first_unchanged_at_end_row (struct window *w, /* A value of window_end_pos >= END_UNCHANGED means that the window end is in the range of changed text. If so, there is no unchanged row at the end of W's current matrix. */ - if (XFASTINT (w->window_end_pos) >= END_UNCHANGED) + if (w->window_end_pos >= END_UNCHANGED) return NULL; /* Set row to the last row in W's current matrix displaying text. */ - row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); + row = MATRIX_ROW (w->current_matrix, w->window_end_vpos); /* If matrix is entirely empty, no unchanged row exists. */ if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) @@ -16913,7 +16943,7 @@ find_first_unchanged_at_end_row (struct window *w, buffer positions in the current matrix to current buffer positions for characters not in changed text. */ ptrdiff_t Z_old = - MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); + MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos; ptrdiff_t Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; ptrdiff_t last_unchanged_pos, last_unchanged_pos_old; @@ -17247,7 +17277,7 @@ try_window_id (struct window *w) This case happens with stealth-fontification. Note that although the display is unchanged, glyph positions in the matrix have to be adjusted, of course. */ - row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); + row = MATRIX_ROW (w->current_matrix, w->window_end_vpos); if (MATRIX_ROW_DISPLAYS_TEXT_P (row) && ((last_changed_charpos < CHARPOS (start) && CHARPOS (start) == BEGV) @@ -17259,7 +17289,7 @@ try_window_id (struct window *w) /* Compute how many chars/bytes have been added to or removed from the buffer. */ - Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); + Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos; Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; Z_delta = Z - Z_old; Z_delta_bytes = Z_BYTE - Z_BYTE_old; @@ -17330,10 +17360,8 @@ try_window_id (struct window *w) { /* We have to compute the window end anew since text could have been added/removed after it. */ - wset_window_end_pos - (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); + w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); + w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); /* Set the cursor. */ row = row_containing_pos (w, PT, r0, NULL, 0); @@ -17366,7 +17394,7 @@ try_window_id (struct window *w) /* Give up if the window ends in strings. Overlay strings at the end are difficult to handle, so don't try. */ - row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos)); + row = MATRIX_ROW (current_matrix, w->window_end_vpos); if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row)) GIVE_UP (20); @@ -17712,7 +17740,7 @@ try_window_id (struct window *w) /* Set last_row to the glyph row in the current matrix where the window end line is found. It has been moved up or down in the matrix by dvpos. */ - int last_vpos = XFASTINT (w->window_end_vpos) + dvpos; + int last_vpos = w->window_end_vpos + dvpos; struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos); /* If last_row is the window end line, it should display text. */ @@ -17756,8 +17784,7 @@ try_window_id (struct window *w) } /* Update window_end_pos and window_end_vpos. */ - if (first_unchanged_at_end_row - && !last_text_row_at_end) + if (first_unchanged_at_end_row && !last_text_row_at_end) { /* Window end line if one of the preserved rows from the current matrix. Set row to the last row displaying text in current @@ -17767,23 +17794,13 @@ try_window_id (struct window *w) row = find_last_row_displaying_text (w->current_matrix, &it, first_unchanged_at_end_row); eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); - - wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); - w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix))); + adjust_window_ends (w, row, 1); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "A")); } else if (last_text_row_at_end) { - wset_window_end_pos - (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end))); - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end, - desired_matrix))); + adjust_window_ends (w, last_text_row_at_end, 0); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "B")); } @@ -17792,12 +17809,7 @@ try_window_id (struct window *w) /* We have displayed either to the end of the window or at the end of the window, i.e. the last row with text is to be found in the desired matrix. */ - wset_window_end_pos - (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row))); - w->window_end_bytepos - = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); - wset_window_end_vpos - (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix))); + adjust_window_ends (w, last_text_row, 0); eassert (w->window_end_bytepos >= 0); } else if (first_unchanged_at_end_row == NULL @@ -17807,7 +17819,7 @@ try_window_id (struct window *w) /* Displayed to end of window, but no line containing text was displayed. Lines were deleted at the end of the window. */ int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; - int vpos = XFASTINT (w->window_end_vpos); + int vpos = w->window_end_vpos; struct glyph_row *current_row = current_matrix->rows + vpos; struct glyph_row *desired_row = desired_matrix->rows + vpos; @@ -17825,8 +17837,8 @@ try_window_id (struct window *w) } eassert (row != NULL); - wset_window_end_vpos (w, make_number (vpos + 1)); - wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); + w->window_end_vpos = vpos + 1; + w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "C")); @@ -17834,8 +17846,8 @@ try_window_id (struct window *w) else emacs_abort (); - IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos); - debug_end_vpos = XFASTINT (w->window_end_vpos)); + IF_DEBUG (debug_end_pos = w->window_end_pos; + debug_end_vpos = w->window_end_vpos); /* Record that display has not been completed. */ w->window_end_valid = 0; @@ -20115,7 +20127,7 @@ Value is the new character position of point. */) (Lisp_Object direction) { struct window *w = XWINDOW (selected_window); - struct buffer *b = NULL; + struct buffer *b = XBUFFER (w->contents); struct glyph_row *row; int dir; Lisp_Object paragraph_dir; @@ -20135,9 +20147,6 @@ Value is the new character position of point. */) else dir = -1; - if (BUFFERP (w->contents)) - b = XBUFFER (w->contents); - /* If current matrix is up-to-date, we can use the information recorded in the glyphs, at least as long as the goal is on the screen. */ @@ -20146,8 +20155,7 @@ Value is the new character position of point. */) && b && !b->clip_changed && !b->prevent_redisplay_optimizations_p - && w->last_modified >= BUF_MODIFF (b) - && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b) + && !window_outdated (w) && w->cursor.vpos >= 0 && w->cursor.vpos < w->current_matrix->nrows && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) @@ -22007,7 +22015,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, ptrdiff_t pos = marker_position (w->start); ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); - if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b)) + if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b)) { if (pos <= BUF_BEGV (b)) return "All"; @@ -22036,7 +22044,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, case 'P': { ptrdiff_t toppos = marker_position (w->start); - ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos); + ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos; ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); if (botpos >= BUF_ZV (b)) @@ -23856,17 +23864,15 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, && hlinfo->mouse_face_beg_row >= 0 && hlinfo->mouse_face_end_row >= 0) { - struct glyph_row *mouse_beg_row, *mouse_end_row; - - mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row); - mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row); + ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix); - if (row >= mouse_beg_row && row <= mouse_end_row) + if (row_vpos >= hlinfo->mouse_face_beg_row + && row_vpos <= hlinfo->mouse_face_end_row) { check_mouse_face = 1; - mouse_beg_col = (row == mouse_beg_row) + mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row) ? hlinfo->mouse_face_beg_col : 0; - mouse_end_col = (row == mouse_end_row) + mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row) ? hlinfo->mouse_face_end_col : row->used[TEXT_AREA]; } @@ -25758,16 +25764,15 @@ x_produce_glyphs (struct it *it) /* EXPORT for RIF: Output LEN glyphs starting at START at the nominal cursor position. Advance the nominal cursor over the text. The global variable - updated_window contains the window being updated, updated_row is - the glyph row being updated, and updated_area is the area of that - row being updated. */ + updated_row is the glyph row being updated, and updated_area is the + area of that row being updated. */ void -x_write_glyphs (struct glyph *start, int len) +x_write_glyphs (struct window *w, struct glyph *start, int len) { - int x, hpos, chpos = updated_window->phys_cursor.hpos; + int x, hpos, chpos = w->phys_cursor.hpos; - eassert (updated_window && updated_row); + eassert (updated_row); /* When the window is hscrolled, cursor hpos can legitimately be out of bounds, but we draw the cursor at the corresponding window margin in that case. */ @@ -25781,18 +25786,18 @@ x_write_glyphs (struct glyph *start, int len) /* Write glyphs. */ hpos = start - updated_row->glyphs[updated_area]; - x = draw_glyphs (updated_window, output_cursor.x, + x = draw_glyphs (w, output_cursor.x, updated_row, updated_area, hpos, hpos + len, DRAW_NORMAL_TEXT, 0); /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ if (updated_area == TEXT_AREA - && updated_window->phys_cursor_on_p - && updated_window->phys_cursor.vpos == output_cursor.vpos + && w->phys_cursor_on_p + && w->phys_cursor.vpos == output_cursor.vpos && chpos >= hpos && chpos < hpos + len) - updated_window->phys_cursor_on_p = 0; + w->phys_cursor_on_p = 0; unblock_input (); @@ -25806,19 +25811,17 @@ x_write_glyphs (struct glyph *start, int len) Insert LEN glyphs from START at the nominal cursor position. */ void -x_insert_glyphs (struct glyph *start, int len) +x_insert_glyphs (struct window *w, struct glyph *start, int len) { struct frame *f; - struct window *w; int line_height, shift_by_width, shifted_region_width; struct glyph_row *row; struct glyph *glyph; int frame_x, frame_y; ptrdiff_t hpos; - eassert (updated_window && updated_row); + eassert (updated_row); block_input (); - w = updated_window; f = XFRAME (WINDOW_FRAME (w)); /* Get the height of the line we are in. */ @@ -25860,18 +25863,17 @@ x_insert_glyphs (struct glyph *start, int len) (inclusive) to pixel column TO_X (exclusive). The idea is that everything from TO_X onward is already erased. - TO_X is a pixel position relative to updated_area of - updated_window. TO_X == -1 means clear to the end of this area. */ + TO_X is a pixel position relative to updated_area of currently + updated window W. TO_X == -1 means clear to the end of this area. */ void -x_clear_end_of_line (int to_x) +x_clear_end_of_line (struct window *w, int to_x) { struct frame *f; - struct window *w = updated_window; int max_x, min_y, max_y; int from_x, from_y, to_y; - eassert (updated_window && updated_row); + eassert (updated_row); f = XFRAME (w->frame); if (updated_row->full_width_p) @@ -26010,6 +26012,9 @@ set_frame_cursor_types (struct frame *f, Lisp_Object arg) } else FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR; + + /* Make sure the cursor gets redrawn. */ + cursor_type_changed = 1; } @@ -27048,7 +27053,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */ rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2); if (r1 == NULL) - r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); + r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos); /* If the before-string or display-string contains newlines, rows_from_pos_range skips to its last row. Move back. */ if (!NILP (before_string) || !NILP (disp_string)) @@ -27070,7 +27075,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, } if (r2 == NULL) { - r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); + r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos); hlinfo->mouse_face_past_end = 1; } else if (!NILP (after_string)) @@ -27078,7 +27083,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, /* If the after-string has newlines, advance to its last row. */ struct glyph_row *next; struct glyph_row *last - = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); + = MATRIX_ROW (w->current_matrix, w->window_end_vpos); for (next = r2 + 1; next <= last @@ -28142,10 +28147,7 @@ note_mouse_highlight (struct frame *f, int x, int y) /* Are we in a window whose display is up to date? And verify the buffer's text has not changed. */ b = XBUFFER (w->contents); - if (part == ON_TEXT - && w->window_end_valid - && w->last_modified == BUF_MODIFF (b) - && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b)) + if (part == ON_TEXT && w->window_end_valid && !window_outdated (w)) { int hpos, vpos, dx, dy, area = LAST_AREA; ptrdiff_t pos; @@ -28387,8 +28389,7 @@ note_mouse_highlight (struct frame *f, int x, int y) : Qnil; Lisp_Object lim2 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering)) - ? make_number (BUF_Z (XBUFFER (buffer)) - - XFASTINT (w->window_end_pos)) + ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos) : Qnil; if (NILP (overlay)) @@ -28836,7 +28837,7 @@ expose_window (struct window *w, XRectangle *fr) /* When we're currently updating the window, display and current matrix usually don't agree. Arrange for a thorough display later. */ - if (w == updated_window) + if (w->must_be_updated_p) { SET_FRAME_GARBAGED (f); return 0; diff --git a/src/xfaces.c b/src/xfaces.c index f647ff2e209..b76f9d24180 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -448,8 +448,8 @@ static struct face *realize_non_ascii_face (struct frame *, Lisp_Object, struct face *); static struct face *realize_x_face (struct face_cache *, Lisp_Object *); static struct face *realize_tty_face (struct face_cache *, Lisp_Object *); -static int realize_basic_faces (struct frame *); -static int realize_default_face (struct frame *); +static bool realize_basic_faces (struct frame *); +static bool realize_default_face (struct frame *); static void realize_named_face (struct frame *, Lisp_Object, int); static struct face_cache *make_face_cache (struct frame *); static void clear_face_gcs (struct face_cache *); @@ -759,11 +759,6 @@ clear_face_cache (int clear_fonts_p) if (clear_fonts_p || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) { -#if 0 - /* Not yet implemented. */ - clear_font_cache (frame); -#endif - /* From time to time see if we can unload some fonts. This also frees all realized faces on all frames. Fonts needed by faces will be loaded again when faces are realized again. */ @@ -774,7 +769,10 @@ clear_face_cache (int clear_fonts_p) struct frame *f = XFRAME (frame); if (FRAME_WINDOW_P (f) && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS) - free_all_realized_faces (frame); + { + clear_font_cache (f); + free_all_realized_faces (frame); + } } } else @@ -819,7 +817,7 @@ the pixmap. Bits are stored row by row, each row occupies \(WIDTH + 7)/8 bytes. */) (Lisp_Object object) { - int pixmap_p = 0; + bool pixmap_p = 0; if (STRINGP (object)) /* If OBJECT is a string, it's a file name. */ @@ -869,7 +867,7 @@ the pixmap. Bits are stored row by row, each row occupies if these pointers are not null. */ static ptrdiff_t -load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr, +load_pixmap (struct frame *f, Lisp_Object name, unsigned int *w_ptr, unsigned int *h_ptr) { ptrdiff_t bitmap_id; @@ -1530,15 +1528,12 @@ the face font sort order. */) (Lisp_Object family, Lisp_Object frame) { Lisp_Object font_spec, list, *drivers, vec; + struct frame *f = decode_live_frame (frame); ptrdiff_t i, nfonts; EMACS_INT ndrivers; Lisp_Object result; USE_SAFE_ALLOCA; - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); - font_spec = Ffont_spec (0, NULL); if (!NILP (family)) { @@ -1546,7 +1541,7 @@ the face font sort order. */) font_parse_family_registry (family, Qnil, font_spec); } - list = font_list_entities (frame, font_spec); + list = font_list_entities (f, font_spec); if (NILP (list)) return Qnil; @@ -1589,7 +1584,7 @@ the face font sort order. */) ASET (v, 0, AREF (font, FONT_FAMILY_INDEX)); ASET (v, 1, FONT_WIDTH_SYMBOLIC (font)); point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10, - FRAME_RES_Y (XFRAME (frame))); + FRAME_RES_Y (f)); ASET (v, 2, make_number (point)); ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font)); ASET (v, 4, FONT_SLANT_SYMBOLIC (font)); @@ -2854,7 +2849,7 @@ FRAME 0 means change the face on all frames, and change the default } else if (EQ (attr, QCunderline)) { - int valid_p = 0; + bool valid_p = 0; if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value)) valid_p = 1; @@ -2941,7 +2936,7 @@ FRAME 0 means change the face on all frames, and change the default } else if (EQ (attr, QCbox)) { - int valid_p; + bool valid_p; /* Allow t meaning a simple box of width 1 in foreground color of the face. */ @@ -3078,7 +3073,7 @@ FRAME 0 means change the face on all frames, and change the default { if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) { - FRAME_PTR f; + struct frame *f; old_value = LFACE_FONT (lface); if (! FONTP (value)) @@ -3247,10 +3242,9 @@ FRAME 0 means change the face on all frames, and change the default #endif /* HAVE_WINDOW_SYSTEM */ else if (EQ (face, Qmenu)) { - /* Indicate that we have to update the menu bar when - realizing faces on FRAME. FRAME t change the - default for new frames. We do this by setting - setting the flag in new face caches */ + /* Indicate that we have to update the menu bar when realizing + faces on FRAME. FRAME t change the default for new frames. + We do this by setting the flag in new face caches. */ if (FRAMEP (frame)) { struct frame *f = XFRAME (frame); @@ -3510,7 +3504,7 @@ x_update_menu_appearance (struct frame *f) Lisp_Object lface = lface_from_face_name (f, Qmenu, 1); struct face *face = FACE_FROM_ID (f, MENU_FACE_ID); const char *myname = SSDATA (Vx_resource_name); - int changed_p = 0; + bool changed_p = 0; #ifdef USE_MOTIF const char *popup_path = "popup_menu"; #else @@ -3858,7 +3852,7 @@ return the font name used for CHARACTER. */) all attributes are `equal'. Tries to be fast because this function is called quite often. */ -static int +static bool face_attr_equal_p (Lisp_Object v1, Lisp_Object v2) { /* Type can differ, e.g. when one attribute is unspecified, i.e. nil, @@ -3891,10 +3885,11 @@ face_attr_equal_p (Lisp_Object v1, Lisp_Object v2) all attributes are `equal'. Tries to be fast because this function is called quite often. */ -static int +static bool lface_equal_p (Lisp_Object *v1, Lisp_Object *v2) { - int i, equal_p = 1; + int i; + bool equal_p = 1; for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i) equal_p = face_attr_equal_p (v1[i], v2[i]); @@ -4166,13 +4161,11 @@ If FRAME is unspecified or nil, the current frame is used. */) static struct face_cache * make_face_cache (struct frame *f) { - struct face_cache *c; - int size; + struct face_cache *c = xmalloc (sizeof *c); - c = xzalloc (sizeof *c); - size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; - c->buckets = xzalloc (size); + c->buckets = xzalloc (FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets); c->size = 50; + c->used = 0; c->faces_by_id = xmalloc (c->size * sizeof *c->faces_by_id); c->f = f; c->menu_face_changed_p = menu_face_changed_default; @@ -5201,10 +5194,10 @@ face_fontset (Lisp_Object attrs[LFACE_VECTOR_SIZE]) of F don't contain enough information needed to realize the default face. */ -static int +static bool realize_basic_faces (struct frame *f) { - int success_p = 0; + bool success_p = 0; ptrdiff_t count = SPECPDL_INDEX (); /* Block input here so that we won't be surprised by an X expose @@ -5249,7 +5242,7 @@ realize_basic_faces (struct frame *f) specified, make it fully-specified. Attributes of the default face that are not explicitly specified are taken from frame parameters. */ -static int +static bool realize_default_face (struct frame *f) { struct face_cache *c = FRAME_FACE_CACHE (f); diff --git a/src/xfns.c b/src/xfns.c index a3eff1a5cce..0c91e298ec8 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -176,7 +176,7 @@ check_x_display_info (Lisp_Object object) dpyinfo = x_display_info_for_name (object); else { - FRAME_PTR f = decode_window_system_frame (object); + struct frame *f = decode_window_system_frame (object); dpyinfo = FRAME_X_DISPLAY_INFO (f); } @@ -369,7 +369,7 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc) not Emacs's own window. */ void -x_real_positions (FRAME_PTR f, int *xptr, int *yptr) +x_real_positions (struct frame *f, int *xptr, int *yptr) { int win_x, win_y, outer_x IF_LINT (= 0), outer_y IF_LINT (= 0); int real_x = 0, real_y = 0; @@ -565,7 +565,7 @@ x_defined_color (struct frame *f, const char *color_name, Signal an error if color can't be allocated. */ static int -x_decode_color (FRAME_PTR f, Lisp_Object color_name, int mono_color) +x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color) { XColor cdef; @@ -626,7 +626,7 @@ x_set_tool_bar_position (struct frame *f, may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */ int -xg_set_icon (FRAME_PTR f, Lisp_Object file) +xg_set_icon (struct frame *f, Lisp_Object file) { int result = 0; Lisp_Object found; @@ -660,7 +660,7 @@ xg_set_icon (FRAME_PTR f, Lisp_Object file) } int -xg_set_icon_from_xpm_data (FRAME_PTR f, const char **data) +xg_set_icon_from_xpm_data (struct frame *f, const char **data) { GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data); @@ -942,7 +942,7 @@ static void x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { unsigned long fore_pixel, pixel; - int fore_pixel_allocated_p = 0, pixel_allocated_p = 0; + bool fore_pixel_allocated_p = 0, pixel_allocated_p = 0; struct x_output *x = f->output_data.x; if (!NILP (Vx_cursor_fore_pixel)) @@ -1050,14 +1050,11 @@ x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) static void -x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { set_frame_cursor_types (f, arg); - - /* Make sure the cursor gets redrawn. */ - cursor_type_changed = 1; } - + static void x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { @@ -1449,7 +1446,7 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, icon name to NAME. */ static void -x_set_name_internal (FRAME_PTR f, Lisp_Object name) +x_set_name_internal (struct frame *f, Lisp_Object name) { if (FRAME_X_WINDOW (f)) { @@ -1608,7 +1605,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit) specified a name for the frame; the name will override any set by the redisplay code. */ static void -x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { x_set_name (f, arg, 1); } @@ -1617,7 +1614,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) name; names set this way will never override names set by the user's lisp code. */ void -x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) +x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { x_set_name (f, arg, 0); } @@ -1730,7 +1727,7 @@ x_default_scroll_bar_color_parameter (struct frame *f, for example, but Xt doesn't). */ static void -hack_wm_protocols (FRAME_PTR f, Widget widget) +hack_wm_protocols (struct frame *f, Widget widget) { Display *dpy = XtDisplay (widget); Window w = XtWindow (widget); @@ -2066,7 +2063,7 @@ void xic_free_xfontset (struct frame *f) { Lisp_Object rest, frame; - int shared_p = 0; + bool shared_p = 0; if (!FRAME_XIC_FONTSET (f)) return; @@ -2088,9 +2085,6 @@ xic_free_xfontset (struct frame *f) /* The fontset is not used anymore. It is safe to free it. */ XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); - if (FRAME_XIC_BASE_FONTNAME (f)) - xfree (FRAME_XIC_BASE_FONTNAME (f)); - FRAME_XIC_BASE_FONTNAME (f) = NULL; FRAME_XIC_FONTSET (f) = NULL; } @@ -2316,12 +2310,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) for the window manager, so GC relocation won't bother it. Elsewhere we specify the window name for the window manager. */ - - { - char *str = SSDATA (Vx_resource_name); - f->namebuf = xmalloc (strlen (str) + 1); - strcpy (f->namebuf, str); - } + f->namebuf = xstrdup (SSDATA (Vx_resource_name)); ac = 0; XtSetArg (al[ac], XtNallowShellResize, 1); ac++; @@ -2339,12 +2328,8 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) /* maybe_set_screen_title_format (shell_widget); */ pane_widget = lw_create_widget ("main", "pane", widget_id_tick++, - (widget_value *) NULL, - shell_widget, False, - (lw_callback) NULL, - (lw_callback) NULL, - (lw_callback) NULL, - (lw_callback) NULL); + NULL, shell_widget, False, + NULL, NULL, NULL, NULL); ac = 0; XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++; @@ -2491,8 +2476,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) */ XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget), FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, - XA_ATOM, 32, PropModeAppend, - (unsigned char*) NULL, 0); + XA_ATOM, 32, PropModeAppend, NULL, 0); /* Make all the standard events reach the Emacs frame. */ attributes.event_mask = STANDARD_EVENT_SET; @@ -2541,7 +2525,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only) #else /* not USE_X_TOOLKIT */ #ifdef USE_GTK static void -x_window (FRAME_PTR f) +x_window (struct frame *f) { if (! xg_create_frame_widgets (f)) error ("Unable to create window"); @@ -2791,10 +2775,6 @@ x_make_gc (struct frame *f) | GCFillStyle | GCLineWidth), &gc_values); - /* Reliefs. */ - f->output_data.x->white_relief.gc = 0; - f->output_data.x->black_relief.gc = 0; - /* Create the gray border tile used when the pointer is not in the frame. Since this depends on the frame's pixel values, this must be done on a per-frame basis. */ @@ -3492,7 +3472,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0, (Lisp_Object color, Lisp_Object frame) { XColor foo; - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_STRING (color); @@ -3507,7 +3487,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, (Lisp_Object color, Lisp_Object frame) { XColor foo; - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHECK_STRING (color); @@ -4021,7 +4001,7 @@ x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo) / x_display_pixel_width (dpyinfo)); mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen) / x_display_pixel_height (dpyinfo)); - monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); + monitors = xzalloc (n_monitors * sizeof *monitors); for (i = 0; i < n_monitors; ++i) { struct MonitorInfo *mi = &monitors[i]; @@ -4081,7 +4061,7 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo) return Qnil; } n_monitors = resources->noutput; - monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); + monitors = xzalloc (n_monitors * sizeof *monitors); #ifdef HAVE_XRRGETOUTPUTPRIMARY pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window); @@ -4237,7 +4217,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) #endif n_monitors = gdk_screen_get_n_monitors (gscreen); monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); - monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); + monitors = xzalloc (n_monitors * sizeof *monitors); FOR_EACH_FRAME (rest, frame) { @@ -4325,19 +4305,6 @@ Internal use only, use `display-monitor-attributes-list' instead. */) return attributes_list; } - -int -x_pixel_width (register struct frame *f) -{ - return FRAME_PIXEL_WIDTH (f); -} - -int -x_pixel_height (register struct frame *f) -{ - return FRAME_PIXEL_HEIGHT (f); -} - /************************************************************************ X Displays ************************************************************************/ @@ -4488,8 +4455,7 @@ x_display_info_for_name (Lisp_Object name) validate_x_resource_name (); - dpyinfo = x_term_init (name, (char *)0, - SSDATA (Vx_resource_name)); + dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name)); if (dpyinfo == 0) error ("Cannot connect to X server %s", SDATA (name)); @@ -4522,10 +4488,7 @@ terminate Emacs if we can't open the connection. error ("Not using X Windows"); /* That doesn't stop us anymore. */ #endif - if (! NILP (xrm_string)) - xrm_option = SSDATA (xrm_string); - else - xrm_option = (char *) 0; + xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string); validate_x_resource_name (); @@ -4606,7 +4569,7 @@ If TERMINAL is omitted or nil, that stands for the selected frame's display. */ /* Wait for responses to all X commands issued so far for frame F. */ void -x_sync (FRAME_PTR f) +x_sync (struct frame *f) { block_input (); XSync (FRAME_X_DISPLAY (f), False); @@ -5749,8 +5712,8 @@ DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog, static void file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data) { - int *result = (int *) client_data; - XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data; + int *result = client_data; + XmAnyCallbackStruct *cb = call_data; *result = cb->reason; } @@ -5763,7 +5726,7 @@ file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data) static void file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data) { - int *result = (int *) client_data; + int *result = client_data; *result = XmCR_CANCEL; } @@ -5790,7 +5753,8 @@ or directory must exist. This function is only defined on NS, MS Windows, and X Windows with the Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) - (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) + (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, + Lisp_Object mustmatch, Lisp_Object only_dir_p) { int result; struct frame *f = SELECTED_FRAME (); @@ -5963,7 +5927,7 @@ Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) { - FRAME_PTR f = SELECTED_FRAME (); + struct frame *f = SELECTED_FRAME (); char *fn; Lisp_Object file = Qnil; Lisp_Object decoded_file; @@ -6026,7 +5990,7 @@ FRAME is the frame on which to pop up the font chooser. If omitted or nil, it defaults to the selected frame. */) (Lisp_Object frame, Lisp_Object ignored) { - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); Lisp_Object font; Lisp_Object font_param; char *default_name = NULL; diff --git a/src/xfont.c b/src/xfont.c index 9647a51ac6e..1aface6f972 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -114,19 +114,19 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b) ? NULL : pcm); } -static Lisp_Object xfont_get_cache (FRAME_PTR); -static Lisp_Object xfont_list (Lisp_Object, Lisp_Object); -static Lisp_Object xfont_match (Lisp_Object, Lisp_Object); -static Lisp_Object xfont_list_family (Lisp_Object); -static Lisp_Object xfont_open (FRAME_PTR, Lisp_Object, int); -static void xfont_close (FRAME_PTR, struct font *); -static int xfont_prepare_face (FRAME_PTR, struct face *); +static Lisp_Object xfont_get_cache (struct frame *); +static Lisp_Object xfont_list (struct frame *, Lisp_Object); +static Lisp_Object xfont_match (struct frame *, Lisp_Object); +static Lisp_Object xfont_list_family (struct frame *); +static Lisp_Object xfont_open (struct frame *, Lisp_Object, int); +static void xfont_close (struct frame *, struct font *); +static int xfont_prepare_face (struct frame *, struct face *); static int xfont_has_char (Lisp_Object, int); static unsigned xfont_encode_char (struct font *, int); static int xfont_text_extents (struct font *, unsigned *, int, struct font_metrics *); static int xfont_draw (struct glyph_string *, int, int, int, int, bool); -static int xfont_check (FRAME_PTR, struct font *); +static int xfont_check (struct frame *, struct font *); struct font_driver xfont_driver = { @@ -152,7 +152,7 @@ struct font_driver xfont_driver = }; static Lisp_Object -xfont_get_cache (FRAME_PTR f) +xfont_get_cache (struct frame *f) { Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); @@ -486,9 +486,8 @@ xfont_list_pattern (Display *display, const char *pattern, } static Lisp_Object -xfont_list (Lisp_Object frame, Lisp_Object spec) +xfont_list (struct frame *f, Lisp_Object spec) { - FRAME_PTR f = XFRAME (frame); Display *display = FRAME_X_DISPLAY_INFO (f)->display; Lisp_Object registry, list, val, extra, script; int len; @@ -565,9 +564,8 @@ xfont_list (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -xfont_match (Lisp_Object frame, Lisp_Object spec) +xfont_match (struct frame *f, Lisp_Object spec) { - FRAME_PTR f = XFRAME (frame); Display *display = FRAME_X_DISPLAY_INFO (f)->display; Lisp_Object extra, val, entity; char name[512]; @@ -595,9 +593,7 @@ xfont_match (Lisp_Object frame, Lisp_Object spec) { if (XGetFontProperty (xfont, XA_FONT, &value)) { - char *s; - - s = (char *) XGetAtomName (display, (Atom) value); + char *s = XGetAtomName (display, (Atom) value); /* If DXPC (a Differential X Protocol Compressor) Ver.3.7 is running, XGetAtomName will return null @@ -622,9 +618,8 @@ xfont_match (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -xfont_list_family (Lisp_Object frame) +xfont_list_family (struct frame *f) { - FRAME_PTR f = XFRAME (frame); Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); char **names; int num_fonts, i; @@ -679,7 +674,7 @@ xfont_list_family (Lisp_Object frame) } static Lisp_Object -xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) +xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); Display *display = dpyinfo->display; @@ -763,7 +758,7 @@ xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) char *p0, *p; int dashes = 0; - p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value); + p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value); /* Count the number of dashes in the "full name". If it is too few, this isn't really the font's full name, so don't use it. @@ -895,7 +890,7 @@ xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) } static void -xfont_close (FRAME_PTR f, struct font *font) +xfont_close (struct frame *f, struct font *font) { block_input (); XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont); @@ -903,7 +898,7 @@ xfont_close (FRAME_PTR f, struct font *font) } static int -xfont_prepare_face (FRAME_PTR f, struct face *face) +xfont_prepare_face (struct frame *f, struct face *face) { block_input (); XSetFont (FRAME_X_DISPLAY (f), face->gc, @@ -1092,7 +1087,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, } static int -xfont_check (FRAME_PTR f, struct font *font) +xfont_check (struct frame *f, struct font *font) { struct xfont_info *xfont = (struct xfont_info *) font; diff --git a/src/xftfont.c b/src/xftfont.c index 166a70acd85..f2b4c2abe2b 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -70,7 +70,7 @@ struct xftface_info XftColor xft_bg; /* color for face->background */ }; -static void xftfont_get_colors (FRAME_PTR, struct face *, GC gc, +static void xftfont_get_colors (struct frame *, struct face *, GC gc, struct xftface_info *, XftColor *fg, XftColor *bg); @@ -80,7 +80,9 @@ static void xftfont_get_colors (FRAME_PTR, struct face *, GC gc, may be NULL. */ static void -xftfont_get_colors (FRAME_PTR f, struct face *face, GC gc, struct xftface_info *xftface_info, XftColor *fg, XftColor *bg) +xftfont_get_colors (struct frame *f, struct face *face, GC gc, + struct xftface_info *xftface_info, + XftColor *fg, XftColor *bg) { if (xftface_info && face->gc == gc) { @@ -139,9 +141,9 @@ xftfont_get_colors (FRAME_PTR f, struct face *face, GC gc, struct xftface_info * struct font_driver xftfont_driver; static Lisp_Object -xftfont_list (Lisp_Object frame, Lisp_Object spec) +xftfont_list (struct frame *f, Lisp_Object spec) { - Lisp_Object list = ftfont_driver.list (frame, spec), tail; + Lisp_Object list = ftfont_driver.list (f, spec), tail; for (tail = list; CONSP (tail); tail = XCDR (tail)) ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft); @@ -149,9 +151,9 @@ xftfont_list (Lisp_Object frame, Lisp_Object spec) } static Lisp_Object -xftfont_match (Lisp_Object frame, Lisp_Object spec) +xftfont_match (struct frame *f, Lisp_Object spec) { - Lisp_Object entity = ftfont_driver.match (frame, spec); + Lisp_Object entity = ftfont_driver.match (f, spec); if (! NILP (entity)) ASET (entity, FONT_TYPE_INDEX, Qxft); @@ -262,7 +264,7 @@ xftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity) } static Lisp_Object -xftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) +xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { FcResult result; Display *display = FRAME_X_DISPLAY (f); @@ -484,7 +486,7 @@ xftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) } static void -xftfont_close (FRAME_PTR f, struct font *font) +xftfont_close (struct frame *f, struct font *font) { struct xftfont_info *xftfont_info = (struct xftfont_info *) font; @@ -499,7 +501,7 @@ xftfont_close (FRAME_PTR f, struct font *font) } static int -xftfont_prepare_face (FRAME_PTR f, struct face *face) +xftfont_prepare_face (struct frame *f, struct face *face) { struct xftface_info *xftface_info; @@ -522,7 +524,7 @@ xftfont_prepare_face (FRAME_PTR f, struct face *face) } static void -xftfont_done_face (FRAME_PTR f, struct face *face) +xftfont_done_face (struct frame *f, struct face *face) { struct xftface_info *xftface_info; @@ -595,7 +597,7 @@ xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct } static XftDraw * -xftfont_get_xft_draw (FRAME_PTR f) +xftfont_get_xft_draw (struct frame *f) { XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver); @@ -617,7 +619,7 @@ static int xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, bool with_background) { - FRAME_PTR f = s->f; + struct frame *f = s->f; struct face *face = s->face; struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font; struct xftface_info *xftface_info = NULL; @@ -677,7 +679,7 @@ xftfont_shape (Lisp_Object lgstring) #endif static int -xftfont_end_for_frame (FRAME_PTR f) +xftfont_end_for_frame (struct frame *f) { XftDraw *xft_draw; diff --git a/src/xmenu.c b/src/xmenu.c index 6c0e3dd78a6..95ae5393553 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -111,7 +111,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ static Lisp_Object Qdebug_on_next_call; #if defined (USE_X_TOOLKIT) || defined (USE_GTK) -static Lisp_Object xdialog_show (FRAME_PTR, bool, Lisp_Object, Lisp_Object, +static Lisp_Object xdialog_show (struct frame *, bool, Lisp_Object, Lisp_Object, const char **); #endif @@ -130,7 +130,7 @@ static struct frame * menubar_id_to_frame (LWLIB_ID id) { Lisp_Object tail, frame; - FRAME_PTR f; + struct frame *f; FOR_EACH_FRAME (tail, frame) { @@ -154,13 +154,12 @@ menubar_id_to_frame (LWLIB_ID id) the scroll bar or the edit window. Fx_popup_menu needs to be sure it is the edit window. */ void -mouse_position_for_popup (FRAME_PTR f, int *x, int *y) +mouse_position_for_popup (struct frame *f, int *x, int *y) { Window root, dummy_window; int dummy; - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); block_input (); @@ -220,7 +219,7 @@ for instance using the window manager, then this produces a quit and `x-popup-dialog' does not return. */) (Lisp_Object position, Lisp_Object contents, Lisp_Object header) { - FRAME_PTR f = NULL; + struct frame *f = NULL; Lisp_Object window; /* Decode the first argument: find the window or frame to use. */ @@ -230,7 +229,7 @@ for instance using the window manager, then this produces a quit and { #if 0 /* Using the frame the mouse is on may not be right. */ /* Use the mouse's current position. */ - FRAME_PTR new_f = SELECTED_FRAME (); + struct frame *new_f = SELECTED_FRAME (); Lisp_Object bar_window; enum scroll_bar_part part; Time time; @@ -294,8 +293,8 @@ for instance using the window manager, then this produces a quit and { Lisp_Object x, y, frame, newpos; XSETFRAME (frame, f); - XSETINT (x, x_pixel_width (f) / 2); - XSETINT (y, x_pixel_height (f) / 2); + XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2); + XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2); newpos = list2 (list2 (x, y), frame); return Fx_popup_menu (newpos, @@ -374,7 +373,7 @@ x_menu_wait_for_event (void *data) #elif defined USE_GTK ! gtk_events_pending () #else - ! XPending ((Display*) data) + ! XPending (data) #endif ) { @@ -482,7 +481,7 @@ If FRAME is nil or not given, use the selected frame. */) (Lisp_Object frame) { XEvent ev; - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); Widget menubar; block_input (); @@ -493,7 +492,7 @@ If FRAME is nil or not given, use the selected frame. */) if (menubar) { Window child; - int error_p = 0; + bool error_p = 0; x_catch_errors (FRAME_X_DISPLAY (f)); memset (&ev, 0, sizeof ev); @@ -560,10 +559,7 @@ If FRAME is nil or not given, use the selected frame. */) (Lisp_Object frame) { GtkWidget *menubar; - FRAME_PTR f; - - /* gcc 2.95 doesn't accept the FRAME_PTR declaration after - block_input (). */ + struct frame *f; block_input (); f = decode_window_system_frame (frame); @@ -621,10 +617,9 @@ popup_widget_loop (int do_timers, GtkWidget *widget) execute Lisp code. */ void -x_activate_menubar (FRAME_PTR f) +x_activate_menubar (struct frame *f) { - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); if (!f->output_data.x->saved_menu_event->type) return; @@ -684,7 +679,7 @@ popup_deactivate_callback ( for that widget. F is the frame if known, or NULL if not known. */ static void -show_help_event (FRAME_PTR f, xt_or_gtk_widget widget, Lisp_Object help) +show_help_event (struct frame *f, xt_or_gtk_widget widget, Lisp_Object help) { Lisp_Object frame; @@ -727,8 +722,7 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data) xg_menu_item_cb_data *cb_data; Lisp_Object help; - cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (widget), - XG_ITEM_DATA); + cb_data = g_object_get_data (G_OBJECT (widget), XG_ITEM_DATA); if (! cb_data) return; help = call_data ? cb_data->help : Qnil; @@ -746,15 +740,11 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data) static void menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data) { - struct frame *f; - Lisp_Object help; - - widget_value *wv = (widget_value *) call_data; - - help = wv ? wv->help : Qnil; + widget_value *wv = call_data; + Lisp_Object help = wv ? wv->help : Qnil; /* Determine the frame for the help event. */ - f = menubar_id_to_frame (id); + struct frame *f = menubar_id_to_frame (id); show_help_event (f, widget, help); } @@ -774,7 +764,7 @@ static int xg_crazy_callback_abort; static void menubar_selection_callback (GtkWidget *widget, gpointer client_data) { - xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data; + xg_menu_item_cb_data *cb_data = client_data; if (xg_crazy_callback_abort) return; @@ -817,7 +807,7 @@ menubar_selection_callback (GtkWidget *widget, gpointer client_data) static void menubar_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) { - FRAME_PTR f; + struct frame *f; f = menubar_id_to_frame (id); if (!f) @@ -831,7 +821,7 @@ menubar_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) changed. */ static void -update_frame_menubar (FRAME_PTR f) +update_frame_menubar (struct frame *f) { #ifdef USE_GTK xg_update_frame_menubar (f); @@ -839,8 +829,7 @@ update_frame_menubar (FRAME_PTR f) struct x_output *x; int columns, rows; - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); x = f->output_data.x; @@ -914,7 +903,7 @@ apply_systemfont_to_menu (struct frame *f, Widget w) it is set the first time this is called, from initialize_frame_menubar. */ void -set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool first_time, bool deep_p) { xt_or_gtk_widget menubar_widget; #ifdef USE_X_TOOLKIT @@ -927,8 +916,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p) bool *submenu_top_level_items; int *submenu_n_panes; - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); menubar_widget = f->output_data.x->menubar_widget; @@ -1267,7 +1255,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p) is visible. */ void -initialize_frame_menubar (FRAME_PTR f) +initialize_frame_menubar (struct frame *f) { /* This function is called before the first chance to redisplay the frame. It has to be, so the frame will have the right size. */ @@ -1282,12 +1270,11 @@ initialize_frame_menubar (FRAME_PTR f) #ifndef USE_GTK void -free_frame_menubar (FRAME_PTR f) +free_frame_menubar (struct frame *f) { Widget menubar_widget; - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); menubar_widget = f->output_data.x->menubar_widget; @@ -1360,7 +1347,7 @@ static Lisp_Object *volatile menu_item_selection; create_and_show_popup_menu below. */ struct next_popup_x_y { - FRAME_PTR f; + struct frame *f; int x; int y; }; @@ -1378,7 +1365,7 @@ struct next_popup_x_y static void menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) { - struct next_popup_x_y* data = (struct next_popup_x_y*)user_data; + struct next_popup_x_y *data = user_data; GtkRequisition req; struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (data->f); int disp_width = x_display_pixel_width (dpyinfo); @@ -1399,10 +1386,10 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer static void popup_selection_callback (GtkWidget *widget, gpointer client_data) { - xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data; + xg_menu_item_cb_data *cb_data = client_data; if (xg_crazy_callback_abort) return; - if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; + if (cb_data) menu_item_selection = cb_data->call_data; } static void @@ -1418,7 +1405,7 @@ pop_down_menu (void *arg) menu pops down. menu_item_selection will be set to the selection. */ static void -create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, +create_and_show_popup_menu (struct frame *f, widget_value *first_wv, int x, int y, bool for_click, Time timestamp) { int i; @@ -1434,8 +1421,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, use_pos_func = 1; #endif - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); xg_crazy_callback_abort = 1; menu = xg_create_widget ("popup", first_wv->name, f, first_wv, @@ -1506,7 +1492,7 @@ LWLIB_ID widget_id_tick; static void popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) { - menu_item_selection = (Lisp_Object *) client_data; + menu_item_selection = client_data; } /* ARG is the LWLIB ID of the dialog box, represented @@ -1528,7 +1514,7 @@ pop_down_menu (Lisp_Object arg) menu pops down. menu_item_selection will be set to the selection. */ static void -create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, +create_and_show_popup_menu (struct frame *f, widget_value *first_wv, int x, int y, bool for_click, Time timestamp) { int i; @@ -1539,8 +1525,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, LWLIB_ID menu_id; Widget menu; - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); #ifdef USE_LUCID apply_systemfont_to_menu (f, f->output_data.x->widget); @@ -1593,7 +1578,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, make_number (menu_id & ~(-1 << (fact))))); /* Process events that apply to the menu. */ - popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1); + popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), menu_id, 1); unbind_to (specpdl_count, Qnil); } @@ -1608,7 +1593,7 @@ cleanup_widget_value_tree (void *arg) } Lisp_Object -xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, +xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, Lisp_Object title, const char **error_name, Time timestamp) { int i; @@ -1623,8 +1608,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, ptrdiff_t specpdl_count = SPECPDL_INDEX (); - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); *error_name = NULL; @@ -1893,7 +1877,7 @@ dialog_selection_callback (GtkWidget *widget, gpointer client_data) /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ if ((intptr_t) client_data != -1) - menu_item_selection = (Lisp_Object *) client_data; + menu_item_selection = client_data; popup_activated_flag = 0; } @@ -1902,12 +1886,11 @@ dialog_selection_callback (GtkWidget *widget, gpointer client_data) dialog pops down. menu_item_selection will be set to the selection. */ static void -create_and_show_dialog (FRAME_PTR f, widget_value *first_wv) +create_and_show_dialog (struct frame *f, widget_value *first_wv) { GtkWidget *menu; - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); menu = xg_create_widget ("dialog", first_wv->name, f, first_wv, G_CALLBACK (dialog_selection_callback), @@ -1936,7 +1919,7 @@ dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ if ((intptr_t) client_data != -1) - menu_item_selection = (Lisp_Object *) client_data; + menu_item_selection = client_data; block_input (); lw_destroy_all_widgets (id); @@ -1949,12 +1932,11 @@ dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) dialog pops down. menu_item_selection will be set to the selection. */ static void -create_and_show_dialog (FRAME_PTR f, widget_value *first_wv) +create_and_show_dialog (struct frame *f, widget_value *first_wv) { LWLIB_ID dialog_id; - if (!FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); dialog_id = widget_id_tick++; #ifdef USE_LUCID @@ -1980,8 +1962,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv) Fcons (make_number (dialog_id >> (fact)), make_number (dialog_id & ~(-1 << (fact))))); - popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), - dialog_id, 1); + popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1); unbind_to (count, Qnil); } @@ -1994,7 +1975,7 @@ static const char * button_names [] = { "button6", "button7", "button8", "button9", "button10" }; static Lisp_Object -xdialog_show (FRAME_PTR f, +xdialog_show (struct frame *f, bool keymaps, Lisp_Object title, Lisp_Object header, @@ -2012,8 +1993,7 @@ xdialog_show (FRAME_PTR f, ptrdiff_t specpdl_count = SPECPDL_INDEX (); - if (! FRAME_X_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f)); *error_name = NULL; @@ -2225,7 +2205,7 @@ menu_help_callback (char const *help_string, int pane, int item) static void pop_down_menu (Lisp_Object arg) { - FRAME_PTR f = XSAVE_POINTER (arg, 0); + struct frame *f = XSAVE_POINTER (arg, 0); XMenu *menu = XSAVE_POINTER (arg, 1); block_input (); @@ -2253,7 +2233,7 @@ pop_down_menu (Lisp_Object arg) Lisp_Object -xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, +xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, Lisp_Object title, const char **error_name, Time timestamp) { Window root; @@ -2269,8 +2249,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps, unsigned int dummy_uint; ptrdiff_t specpdl_count = SPECPDL_INDEX (); - if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f)) - emacs_abort (); + eassert (FRAME_X_P (f) || FRAME_MSDOS_P (f)); *error_name = 0; if (menu_items_n_panes == 0) diff --git a/src/xrdb.c b/src/xrdb.c index 7c9cd53fa8c..60dcdae080d 100644 --- a/src/xrdb.c +++ b/src/xrdb.c @@ -75,18 +75,9 @@ x_get_customization_string (XrmDatabase db, const char *name, sprintf (full_class, "%s.%s", class, "Customization"); result = x_get_string_resource (db, full_name, full_class); - - if (result) - { - char *copy = xmalloc (strlen (result) + 1); - strcpy (copy, result); - return copy; - } - else - return 0; + return result ? xstrdup (result) : NULL; } - /* Expand all the Xt-style %-escapes in STRING, whose length is given by STRING_LEN. Here are the escapes we're supposed to recognize: @@ -605,7 +596,7 @@ x_get_string_resource (XrmDatabase rdb, const char *name, const char *class) if (x_get_resource (rdb, name, class, x_rm_string, &value)) return (char *) value.addr; - return (char *) 0; + return 0; } /* Stand-alone test facilities. */ @@ -655,10 +646,7 @@ main (int argc, char **argv) displayname = "localhost:0.0"; lp = member ("-xrm", arg_list); - if (! NIL (lp)) - resource_string = car (cdr (lp)); - else - resource_string = (char *) 0; + resource_string = NIL (lp) ? 0 : car (cdr (lp)); lp = member ("-c", arg_list); if (! NIL (lp)) diff --git a/src/xselect.c b/src/xselect.c index 6a80eddc82c..e5f2e214fba 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -654,7 +654,7 @@ x_reply_selection_request (struct input_event *event, if (cs->wait_object) { int format_bytes = cs->format / 8; - int had_errors = x_had_errors_p (display); + bool had_errors_p = x_had_errors_p (display); unblock_input (); bytes_remaining = cs->size; @@ -662,7 +662,7 @@ x_reply_selection_request (struct input_event *event, /* Wait for the requestor to ack by deleting the property. This can run Lisp code (process handlers) or signal. */ - if (! had_errors) + if (! had_errors_p) { TRACE1 ("Waiting for ACK (deletion of %s)", XGetAtomName (display, cs->property)); @@ -694,10 +694,10 @@ x_reply_selection_request (struct input_event *event, cs->data += i * ((cs->format == 32) ? sizeof (long) : format_bytes); XFlush (display); - had_errors = x_had_errors_p (display); + had_errors_p = x_had_errors_p (display); unblock_input (); - if (had_errors) break; + if (had_errors_p) break; /* Wait for the requestor to ack this chunk by deleting the property. This can run Lisp code or signal. */ @@ -993,7 +993,7 @@ x_handle_selection_event (struct input_event *event) We do this when about to delete a frame. */ void -x_clear_frame_selections (FRAME_PTR f) +x_clear_frame_selections (struct frame *f) { Lisp_Object frame; Lisp_Object rest; @@ -2377,7 +2377,7 @@ x_property_data_to_lisp (struct frame *f, const unsigned char *data, /* Get the mouse position in frame relative coordinates. */ static void -mouse_position_for_drop (FRAME_PTR f, int *x, int *y) +mouse_position_for_drop (struct frame *f, int *x, int *y) { Window root, dummy_window; int dummy; @@ -2427,17 +2427,17 @@ If the value is 0 or the atom is not known, return the empty string. */) Lisp_Object ret = Qnil; Display *dpy = FRAME_X_DISPLAY (f); Atom atom; - int had_errors; + bool had_errors_p; CONS_TO_INTEGER (value, Atom, atom); block_input (); x_catch_errors (dpy); name = atom ? XGetAtomName (dpy, atom) : empty; - had_errors = x_had_errors_p (dpy); + had_errors_p = x_had_errors_p (dpy); x_uncatch_errors (); - if (!had_errors) + if (!had_errors_p) ret = build_string (name); if (atom && name) XFree (name); @@ -2628,6 +2628,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, block_input (); + event.xclient.send_event = True; + event.xclient.serial = 0; event.xclient.message_type = message_type; event.xclient.display = dpyinfo->display; @@ -2635,19 +2637,19 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, when sending to the root window. */ event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; - - memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); + memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l)); x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, event.xclient.format); /* If event mask is 0 the event is sent to the client that created the destination window. But if we are sending to the root window, - there is no such client. Then we set the event mask to 0xffff. The + there is no such client. Then we set the event mask to 0xffffff. The event then goes to clients selecting for events on the root window. */ x_catch_errors (dpyinfo->display); { int propagate = to_root ? False : True; - unsigned mask = to_root ? 0xffff : 0; + long mask = to_root ? 0xffffff : 0; + XSendEvent (dpyinfo->display, wdest, propagate, mask, &event); XFlush (dpyinfo->display); } diff --git a/src/xsettings.c b/src/xsettings.c index 45f8435d9f4..b5d5f4db59b 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -756,8 +756,7 @@ read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p) void xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) { - int check_window_p = 0; - int apply_settings = 0; + bool check_window_p = 0, apply_settings_p = 0; switch (event->type) { @@ -777,7 +776,7 @@ xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) if (event->xproperty.window == dpyinfo->xsettings_window && event->xproperty.state == PropertyNewValue && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop) - apply_settings = 1; + apply_settings_p = 1; break; } @@ -787,10 +786,10 @@ xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) dpyinfo->xsettings_window = None; get_prop_window (dpyinfo); if (dpyinfo->xsettings_window != None) - apply_settings = 1; + apply_settings_p = 1; } - if (apply_settings) + if (apply_settings_p) read_and_apply_settings (dpyinfo, True); } diff --git a/src/xsmfns.c b/src/xsmfns.c index cb7122202df..526d4c3610b 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c @@ -107,8 +107,7 @@ x_session_check_input (int fd, void *data) will be called. */ emacs_event.kind = NO_EVENT; - ret = IceProcessMessages (SmcGetIceConnection (smc_conn), - (IceReplyWaitInfo *)0, (Bool *)0); + ret = IceProcessMessages (SmcGetIceConnection (smc_conn), 0, 0); if (ret != IceProcessMessagesSuccess) { /* Either IO error or Connection closed. */ diff --git a/src/xterm.c b/src/xterm.c index b3534871da9..b5c5a5cb584 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -145,7 +145,7 @@ int use_xim = 0; /* configure --without-xim */ /* Non-zero means that a HELP_EVENT has been generated since Emacs start. */ -static int any_help_event_p; +static bool any_help_event_p; /* Last window where we saw the mouse. Used by mouse-autoselect-window. */ static Lisp_Object last_window; @@ -212,8 +212,7 @@ static unsigned long ignore_next_mouse_click_timeout; /* Where the mouse was last time we reported a mouse event. */ static XRectangle last_mouse_glyph; -static FRAME_PTR last_mouse_glyph_frame; -static Lisp_Object last_mouse_press_frame; +static struct frame *last_mouse_glyph_frame; /* The scroll bar in which the last X motion event occurred. @@ -288,8 +287,6 @@ enum xembed_message XEMBED_ACTIVATE_ACCELERATOR = 14 }; -/* Used in x_flush. */ - static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); static void x_set_window_size_1 (struct frame *, int, int, int); static void x_raise_frame (struct frame *); @@ -323,7 +320,6 @@ static void x_clip_to_row (struct window *, struct glyph_row *, int, GC); static void x_flush (struct frame *f); static void x_update_begin (struct frame *); static void x_update_window_begin (struct window *); -static void x_after_update_window_line (struct glyph_row *); static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, @@ -357,15 +353,18 @@ x_flush (struct frame *f) return; block_input (); - if (f == NULL) + if (f) + { + eassert (FRAME_X_P (f)); + XFlush (FRAME_X_DISPLAY (f)); + } + else { - Lisp_Object rest, frame; - FOR_EACH_FRAME (rest, frame) - if (FRAME_X_P (XFRAME (frame))) - x_flush (XFRAME (frame)); + /* Flush all displays and so all frames on them. */ + struct x_display_info *xdi; + for (xdi = x_display_list; xdi; xdi = xdi->next) + XFlush (xdi->display); } - else if (FRAME_X_P (f)) - XFlush (FRAME_X_DISPLAY (f)); unblock_input (); } @@ -554,8 +553,7 @@ x_update_begin (struct frame *f) } -/* Start update of window W. Set the global variable updated_window - to the window being updated and set output_cursor to the cursor +/* Start update of window W. Set output_cursor to the cursor position of W. */ static void @@ -564,7 +562,6 @@ x_update_window_begin (struct window *w) struct frame *f = XFRAME (WINDOW_FRAME (w)); Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -601,7 +598,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) f->output_data.x->normal_gc, x, y0, x, y1); } -/* End update of window W (which is equal to updated_window). +/* End update of window W. Draw vertical borders between horizontally adjacent windows, and display W's cursor if CURSOR_ON_P is non-zero. @@ -642,8 +639,6 @@ x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritt hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_window = Qnil; } - - updated_window = NULL; } @@ -664,9 +659,8 @@ x_update_end (struct frame *f) } -/* This function is called from various places in xdisp.c whenever a - complete update has been performed. The global variable - updated_window is not available here. */ +/* This function is called from various places in xdisp.c + whenever a complete update has been performed. */ static void XTframe_up_to_date (struct frame *f) @@ -678,15 +672,13 @@ XTframe_up_to_date (struct frame *f) /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay arrow bitmaps, or clear the fringes if no bitmaps are required - before DESIRED_ROW is made current. The window being updated is - found in updated_window. This function It is called from + before DESIRED_ROW is made current. This function is called from update_window_line only if it is known that there are differences between bitmaps to be drawn between current row and DESIRED_ROW. */ static void -x_after_update_window_line (struct glyph_row *desired_row) +x_after_update_window_line (struct window *w, struct glyph_row *desired_row) { - struct window *w = updated_window; struct frame *f; int width, height; @@ -697,7 +689,7 @@ x_after_update_window_line (struct glyph_row *desired_row) /* When a window has disappeared, make sure that no rest of full-width rows stays visible in the internal border. Could - check here if updated_window is the leftmost/rightmost window, + check here if updated window is the leftmost/rightmost window, but I guess it's not worth doing since vertically split windows are almost never used, internal border is rarely set, and the overhead is very small. */ @@ -877,8 +869,6 @@ XTreset_terminal_modes (struct terminal *terminal) static void x_set_glyph_string_clipping (struct glyph_string *); static void x_set_glyph_string_gc (struct glyph_string *); -static void x_draw_glyph_string_background (struct glyph_string *, - int); static void x_draw_glyph_string_foreground (struct glyph_string *); static void x_draw_composite_glyph_string_foreground (struct glyph_string *); static void x_draw_glyph_string_box (struct glyph_string *); @@ -1163,7 +1153,7 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h) contains the first component of a composition. */ static void -x_draw_glyph_string_background (struct glyph_string *s, int force_p) +x_draw_glyph_string_background (struct glyph_string *s, bool force_p) { /* Nothing to do if background has already been drawn or if it shouldn't be drawn in the first place. */ @@ -1376,7 +1366,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) } else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE) { - sprintf ((char *) buf, "%0*X", + sprintf (buf, "%0*X", glyph->u.glyphless.ch < 0x10000 ? 4 : 6, glyph->u.glyphless.ch); str = buf; @@ -1413,11 +1403,6 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) #ifdef USE_X_TOOLKIT -static Boolean cvt_string_to_pixel (Display *, XrmValue *, Cardinal *, - XrmValue *, XrmValue *, XtPointer *); -static void cvt_pixel_dtor (XtAppContext, XrmValue *, XtPointer, - XrmValue *, Cardinal *); - #ifdef USE_LUCID /* Return the frame on which widget WIDGET is used.. Abort if frame @@ -2691,7 +2676,7 @@ x_draw_underwave (struct glyph_string *s) static void x_draw_glyph_string (struct glyph_string *s) { - int relief_drawn_p = 0; + bool relief_drawn_p = 0; /* If S draws into the background of its successors, draw the background of the successors first so that S can draw into it. @@ -3195,7 +3180,7 @@ XTflash (struct frame *f) static void -XTtoggle_invisible_pointer (FRAME_PTR f, int invisible) +XTtoggle_invisible_pointer (struct frame *f, int invisible) { block_input (); if (invisible) @@ -3330,7 +3315,6 @@ x_scroll_run (struct window *w, struct run *run) block_input (); /* Cursor off. Will be switched on again in x_update_window_end. */ - updated_window = w; x_clear_cursor (w); XCopyArea (FRAME_X_DISPLAY (f), @@ -3804,7 +3788,7 @@ static XMotionEvent last_mouse_motion_event; static Lisp_Object last_mouse_motion_frame; static int -note_mouse_movement (FRAME_PTR frame, XMotionEvent *event) +note_mouse_movement (struct frame *frame, XMotionEvent *event) { last_mouse_movement_time = event->time; last_mouse_motion_event = *event; @@ -3880,11 +3864,11 @@ redo_mouse_highlight (void) movement. */ static void -XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, +XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, Time *timestamp) { - FRAME_PTR f1; + struct frame *f1; block_input (); @@ -4344,8 +4328,8 @@ x_scroll_bar_to_input_event (XEvent *event, struct input_event *ievent) static void xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) { - struct scroll_bar *bar = (struct scroll_bar *) client_data; - XmScrollBarCallbackStruct *cs = (XmScrollBarCallbackStruct *) call_data; + struct scroll_bar *bar = client_data; + XmScrollBarCallbackStruct *cs = call_data; int part = -1, whole = 0, portion = 0; switch (cs->reason) @@ -4419,11 +4403,11 @@ xg_scroll_callback (GtkRange *range, gdouble value, gpointer user_data) { - struct scroll_bar *bar = (struct scroll_bar *) user_data; + struct scroll_bar *bar = user_data; gdouble position; int part = -1, whole = 0, portion = 0; GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); - FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (range), XG_FRAME_DATA); + struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA); if (xg_ignore_gtk_scrollbar) return FALSE; position = gtk_adjustment_get_value (adj); @@ -4478,7 +4462,7 @@ xg_end_scroll_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { - struct scroll_bar *bar = (struct scroll_bar *) user_data; + struct scroll_bar *bar = user_data; bar->dragging = Qnil; if (WINDOWP (window_being_scrolled)) { @@ -4501,8 +4485,9 @@ xg_end_scroll_callback (GtkWidget *widget, static void xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) { - struct scroll_bar *bar = (struct scroll_bar *) client_data; - float top = *(float *) call_data; + struct scroll_bar *bar = client_data; + float *top_addr = call_data; + float top = *top_addr; float shown; int whole, portion, height; int part; @@ -4543,9 +4528,9 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) static void xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) { - struct scroll_bar *bar = (struct scroll_bar *) client_data; + struct scroll_bar *bar = client_data; /* The position really is stored cast to a pointer. */ - int position = (long) call_data; + int position = (intptr_t) call_data; Dimension height; int part; @@ -5040,7 +5025,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild { int dragging = ! NILP (bar->dragging); Window w = bar->x_window; - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); GC gc = f->output_data.x->normal_gc; /* If the display is already accurate, do nothing. */ @@ -5170,7 +5155,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio int top, height, left, sb_left, width, sb_width; int window_y, window_height; #ifdef USE_TOOLKIT_SCROLL_BARS - int fringe_extended_p; + bool fringe_extended_p; #endif /* Get window dimensions. */ @@ -5203,16 +5188,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio #endif #ifdef USE_TOOLKIT_SCROLL_BARS - if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) - fringe_extended_p = (WINDOW_LEFTMOST_P (w) - && WINDOW_LEFT_FRINGE_WIDTH (w) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - || WINDOW_LEFT_MARGIN_COLS (w) == 0)); - else - fringe_extended_p = (WINDOW_RIGHTMOST_P (w) - && WINDOW_RIGHT_FRINGE_WIDTH (w) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - || WINDOW_RIGHT_MARGIN_COLS (w) == 0)); + fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w); #endif /* Does the scroll bar exist yet? */ @@ -5381,7 +5357,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio `*redeem_scroll_bar_hook' is applied to its window before the judgment. */ static void -XTcondemn_scroll_bars (FRAME_PTR frame) +XTcondemn_scroll_bars (struct frame *frame) { /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ while (! NILP (FRAME_SCROLL_BARS (frame))) @@ -5449,7 +5425,7 @@ XTredeem_scroll_bar (struct window *window) last call to `*condemn_scroll_bars_hook'. */ static void -XTjudge_scroll_bars (FRAME_PTR f) +XTjudge_scroll_bars (struct frame *f) { Lisp_Object bar, next; @@ -5485,7 +5461,7 @@ static void x_scroll_bar_expose (struct scroll_bar *bar, XEvent *event) { Window w = bar->x_window; - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); GC gc = f->output_data.x->normal_gc; int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM; @@ -5584,7 +5560,7 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e static void x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event) { - FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame); + struct frame *f = XFRAME (XWINDOW (bar->window)->frame); last_mouse_movement_time = event->xmotion.time; @@ -5612,13 +5588,13 @@ x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event) on the scroll bar. */ static void -x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, +x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, Time *timestamp) { struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar); Window w = bar->x_window; - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); + struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); int win_x, win_y; Window dummy_window; int dummy_coord; @@ -5686,7 +5662,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window, redraw them. */ static void -x_scroll_bar_clear (FRAME_PTR f) +x_scroll_bar_clear (struct frame *f) { #ifndef USE_TOOLKIT_SCROLL_BARS Lisp_Object bar; @@ -6854,7 +6830,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, { /* If we decide we want to generate an event to be seen by the rest of Emacs, we put it here. */ - int tool_bar_p = 0; + bool tool_bar_p = 0; memset (&compose_status, 0, sizeof (compose_status)); last_mouse_glyph_frame = 0; @@ -6975,14 +6951,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, && event.xbutton.same_screen) { SET_SAVED_BUTTON_EVENT; - XSETFRAME (last_mouse_press_frame, f); *finish = X_EVENT_DROP; } - else if (event.type == ButtonPress) - { - last_mouse_press_frame = Qnil; - goto OTHER; - } else goto OTHER; #endif /* USE_X_TOOLKIT || USE_GTK */ @@ -7663,7 +7633,7 @@ x_check_errors (Display *dpy, const char *format) /* Nonzero if we had any X protocol errors since we did x_catch_errors on DPY. */ -int +bool x_had_errors_p (Display *dpy) { /* Make sure to catch any errors incurred so far. */ @@ -7829,9 +7799,8 @@ static int x_error_handler (Display *display, XErrorEvent *event) { #if defined USE_GTK && defined HAVE_GTK3 - if (event->error_code == BadMatch - && event->request_code == X_SetInputFocus - && event->minor_code == 0) + if ((event->error_code == BadMatch || event->error_code == BadWindow) + && event->request_code == X_SetInputFocus) { return 0; } @@ -8102,13 +8071,10 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name) { #ifdef HAVE_X11R6_XIM struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst); - ptrdiff_t len; dpyinfo->xim_callback_data = xim_inst; xim_inst->dpyinfo = dpyinfo; - len = strlen (resource_name); - xim_inst->resource_name = xmalloc (len + 1); - memcpy (xim_inst->resource_name, resource_name, len + 1); + xim_inst->resource_name = xstrdup (resource_name); XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb, resource_name, emacs_class, xim_instantiate_callback, @@ -8537,7 +8503,7 @@ do_ewmh_fullscreen (struct frame *f) } static void -XTfullscreen_hook (FRAME_PTR f) +XTfullscreen_hook (struct frame *f) { if (FRAME_VISIBLE_P (f)) { @@ -8938,7 +8904,7 @@ x_lower_frame (struct frame *f) /* Request focus with XEmbed */ void -xembed_request_focus (FRAME_PTR f) +xembed_request_focus (struct frame *f) { /* See XEmbed Protocol Specification at http://freedesktop.org/wiki/Specifications/xembed-spec */ @@ -8950,7 +8916,7 @@ xembed_request_focus (FRAME_PTR f) /* Activate frame with Extended Window Manager Hints */ void -x_ewmh_activate_frame (FRAME_PTR f) +x_ewmh_activate_frame (struct frame *f) { /* See Window Manager Specification/Extended Window Manager Hints at http://freedesktop.org/wiki/Specifications/wm-spec */ @@ -8968,7 +8934,7 @@ x_ewmh_activate_frame (FRAME_PTR f) } static void -XTframe_raise_lower (FRAME_PTR f, int raise_flag) +XTframe_raise_lower (struct frame *f, int raise_flag) { if (raise_flag) x_raise_frame (f); @@ -9452,6 +9418,19 @@ x_free_frame_resources (struct frame *f) unload_color (f, f->output_data.x->black_relief.pixel); x_free_gcs (f); + + /* Free extra GCs allocated by x_setup_relief_colors. */ + if (f->output_data.x->white_relief.gc) + { + XFreeGC (dpyinfo->display, f->output_data.x->white_relief.gc); + f->output_data.x->white_relief.gc = 0; + } + if (f->output_data.x->black_relief.gc) + { + XFreeGC (dpyinfo->display, f->output_data.x->black_relief.gc); + f->output_data.x->black_relief.gc = 0; + } + XFlush (FRAME_X_DISPLAY (f)); } @@ -9817,18 +9796,11 @@ get_bits_and_offset (long unsigned int mask, int *bits, int *offset) /* Return 1 if display DISPLAY is available for use, 0 otherwise. But don't permanently open it, just test its availability. */ -int +bool x_display_ok (const char *display) { - int dpy_ok = 1; - Display *dpy; - - dpy = XOpenDisplay (display); - if (dpy) - XCloseDisplay (dpy); - else - dpy_ok = 0; - return dpy_ok; + Display *dpy = XOpenDisplay (display); + return dpy ? (XCloseDisplay (dpy), 1) : 0; } #ifdef USE_GTK @@ -10066,9 +10038,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) dpyinfo->display = dpy; /* Set the name of the terminal. */ - terminal->name = xmalloc (SBYTES (display_name) + 1); - memcpy (terminal->name, SSDATA (display_name), SBYTES (display_name)); - terminal->name[SBYTES (display_name)] = 0; + terminal->name = xlispstrdup (display_name); #if 0 XSetAfterFunction (x_current_display, x_trace_wire); @@ -10110,33 +10080,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) select_visual (dpyinfo); dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen); dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen); - dpyinfo->client_leader_window = 0; - dpyinfo->grabbed = 0; - dpyinfo->reference_count = 0; dpyinfo->icon_bitmap_id = -1; - dpyinfo->n_fonts = 0; - dpyinfo->bitmaps = 0; - dpyinfo->bitmaps_size = 0; - dpyinfo->bitmaps_last = 0; - dpyinfo->scratch_cursor_gc = 0; - hlinfo->mouse_face_mouse_frame = 0; hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; hlinfo->mouse_face_window = Qnil; hlinfo->mouse_face_overlay = Qnil; - hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; - hlinfo->mouse_face_defer = 0; - hlinfo->mouse_face_hidden = 0; - dpyinfo->x_focus_frame = 0; - dpyinfo->x_focus_event_frame = 0; - dpyinfo->x_highlight_frame = 0; dpyinfo->wm_type = X_WMTYPE_UNKNOWN; /* See if we can construct pixel values from RGB values. */ - dpyinfo->red_bits = dpyinfo->blue_bits = dpyinfo->green_bits = 0; - dpyinfo->red_offset = dpyinfo->blue_offset = dpyinfo->green_offset = 0; - if (dpyinfo->visual->class == TrueColor) { get_bits_and_offset (dpyinfo->visual->red_mask, @@ -10297,14 +10249,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) } dpyinfo->x_dnd_atoms_size = 8; - dpyinfo->x_dnd_atoms_length = 0; dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms * dpyinfo->x_dnd_atoms_size); - dpyinfo->net_supported_atoms = NULL; - dpyinfo->nr_net_supported_atoms = 0; - dpyinfo->net_supported_window = 0; - connection = ConnectionNumber (dpyinfo->display); dpyinfo->connection = connection; dpyinfo->gray @@ -10728,9 +10675,6 @@ syms_of_xterm (void) DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); DEFSYM (Qlatin_1, "latin-1"); - staticpro (&last_mouse_press_frame); - last_mouse_press_frame = Qnil; - #ifdef USE_GTK xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); staticpro (&xg_default_icon_file); diff --git a/src/xterm.h b/src/xterm.h index 5415a77cf58..fbc2f05a375 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -403,7 +403,7 @@ extern Lisp_Object x_display_name_list; extern struct x_display_info *x_display_info_for_display (Display *); extern struct x_display_info *x_term_init (Lisp_Object, char *, char *); -extern int x_display_ok (const char *); +extern bool x_display_ok (const char *); extern void select_visual (struct x_display_info *); @@ -590,7 +590,6 @@ struct x_output XIC xic; XIMStyle xic_style; XFontSet xic_xfs; - char *xic_base_fontname; #endif /* Relief GCs, colors etc. */ @@ -754,7 +753,6 @@ enum #define FRAME_X_XIM_STYLES(f) (FRAME_X_DISPLAY_INFO (f)->xim_styles) #define FRAME_XIC_STYLE(f) ((f)->output_data.x->xic_style) #define FRAME_XIC_FONTSET(f) ((f)->output_data.x->xic_xfs) -#define FRAME_XIC_BASE_FONTNAME(f) ((f)->output_data.x->xic_base_fontname) /* Value is the smallest width of any character in any font on frame F. */ @@ -817,7 +815,7 @@ struct scroll_bar /* 1 if the background of the fringe that is adjacent to a scroll bar is extended to the gap between the fringe and the bar. */ - unsigned int fringe_extended_p : 1; + unsigned fringe_extended_p : 1; }; /* Turning a lisp vector value into a pointer to a struct scroll_bar. */ @@ -947,7 +945,7 @@ extern int x_text_icon (struct frame *, const char *); extern void x_catch_errors (Display *); extern void x_check_errors (Display *, const char *) ATTRIBUTE_FORMAT_PRINTF (2, 0); -extern int x_had_errors_p (Display *); +extern bool x_had_errors_p (Display *); extern void x_uncatch_errors (void); extern void x_clear_errors (Display *); extern void x_set_window_size (struct frame *, int, int, int); @@ -1031,8 +1029,6 @@ extern void destroy_frame_xic (struct frame *); extern void xic_set_preeditarea (struct window *, int, int); extern void xic_set_statusarea (struct frame *); extern void xic_set_xfontset (struct frame *, const char *); -extern int x_pixel_width (struct frame *); -extern int x_pixel_height (struct frame *); extern bool x_defined_color (struct frame *, const char *, XColor *, bool); #ifdef HAVE_X_I18N extern void free_frame_xic (struct frame *); |
