1/* Display generation from window structure and buffer text. 2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 3 1997, 1998, 1999, 2000, 2001, 2002, 2003, 4 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 5 6This file is part of GNU Emacs. 7 8GNU Emacs is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 2, or (at your option) 11any later version. 12 13GNU Emacs is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with GNU Emacs; see the file COPYING. If not, write to 20the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21Boston, MA 02110-1301, USA. */ 22 23/* New redisplay written by Gerd Moellmann <gerd@gnu.org>. 24 25 Redisplay. 26 27 Emacs separates the task of updating the display from code 28 modifying global state, e.g. buffer text. This way functions 29 operating on buffers don't also have to be concerned with updating 30 the display. 31 32 Updating the display is triggered by the Lisp interpreter when it 33 decides it's time to do it. This is done either automatically for 34 you as part of the interpreter's command loop or as the result of 35 calling Lisp functions like `sit-for'. The C function `redisplay' 36 in xdisp.c is the only entry into the inner redisplay code. (Or, 37 let's say almost---see the description of direct update 38 operations, below.) 39 40 The following diagram shows how redisplay code is invoked. As you 41 can see, Lisp calls redisplay and vice versa. Under window systems 42 like X, some portions of the redisplay code are also called 43 asynchronously during mouse movement or expose events. It is very 44 important that these code parts do NOT use the C library (malloc, 45 free) because many C libraries under Unix are not reentrant. They 46 may also NOT call functions of the Lisp interpreter which could 47 change the interpreter's state. If you don't follow these rules, 48 you will encounter bugs which are very hard to explain. 49 50 (Direct functions, see below) 51 direct_output_for_insert, 52 direct_forward_char (dispnew.c) 53 +---------------------------------+ 54 | | 55 | V 56 +--------------+ redisplay +----------------+ 57 | Lisp machine |---------------->| Redisplay code |<--+ 58 +--------------+ (xdisp.c) +----------------+ | 59 ^ | | 60 +----------------------------------+ | 61 Don't use this path when called | 62 asynchronously! | 63 | 64 expose_window (asynchronous) | 65 | 66 X expose events -----+ 67 68 What does redisplay do? Obviously, it has to figure out somehow what 69 has been changed since the last time the display has been updated, 70 and to make these changes visible. Preferably it would do that in 71 a moderately intelligent way, i.e. fast. 72 73 Changes in buffer text can be deduced from window and buffer 74 structures, and from some global variables like `beg_unchanged' and 75 `end_unchanged'. The contents of the display are additionally 76 recorded in a `glyph matrix', a two-dimensional matrix of glyph 77 structures. Each row in such a matrix corresponds to a line on the 78 display, and each glyph in a row corresponds to a column displaying 79 a character, an image, or what else. This matrix is called the 80 `current glyph matrix' or `current matrix' in redisplay 81 terminology. 82 83 For buffer parts that have been changed since the last update, a 84 second glyph matrix is constructed, the so called `desired glyph 85 matrix' or short `desired matrix'. Current and desired matrix are 86 then compared to find a cheap way to update the display, e.g. by 87 reusing part of the display by scrolling lines. 88 89 90 Direct operations. 91 92 You will find a lot of redisplay optimizations when you start 93 looking at the innards of redisplay. The overall goal of all these 94 optimizations is to make redisplay fast because it is done 95 frequently. 96 97 Two optimizations are not found in xdisp.c. These are the direct 98 operations mentioned above. As the name suggests they follow a 99 different principle than the rest of redisplay. Instead of 100 building a desired matrix and then comparing it with the current 101 display, they perform their actions directly on the display and on 102 the current matrix. 103 104 One direct operation updates the display after one character has 105 been entered. The other one moves the cursor by one position 106 forward or backward. You find these functions under the names 107 `direct_output_for_insert' and `direct_output_forward_char' in 108 dispnew.c. 109 110 111 Desired matrices. 112 113 Desired matrices are always built per Emacs window. The function 114 `display_line' is the central function to look at if you are 115 interested. It constructs one row in a desired matrix given an 116 iterator structure containing both a buffer position and a 117 description of the environment in which the text is to be 118 displayed. But this is too early, read on. 119 120 Characters and pixmaps displayed for a range of buffer text depend 121 on various settings of buffers and windows, on overlays and text 122 properties, on display tables, on selective display. The good news 123 is that all this hairy stuff is hidden behind a small set of 124 interface functions taking an iterator structure (struct it) 125 argument. 126 127 Iteration over things to be displayed is then simple. It is 128 started by initializing an iterator with a call to init_iterator. 129 Calls to get_next_display_element fill the iterator structure with 130 relevant information about the next thing to display. Calls to 131 set_iterator_to_next move the iterator to the next thing. 132 133 Besides this, an iterator also contains information about the 134 display environment in which glyphs for display elements are to be 135 produced. It has fields for the width and height of the display, 136 the information whether long lines are truncated or continued, a 137 current X and Y position, and lots of other stuff you can better 138 see in dispextern.h. 139 140 Glyphs in a desired matrix are normally constructed in a loop 141 calling get_next_display_element and then produce_glyphs. The call 142 to produce_glyphs will fill the iterator structure with pixel 143 information about the element being displayed and at the same time 144 produce glyphs for it. If the display element fits on the line 145 being displayed, set_iterator_to_next is called next, otherwise the 146 glyphs produced are discarded. 147 148 149 Frame matrices. 150 151 That just couldn't be all, could it? What about terminal types not 152 supporting operations on sub-windows of the screen? To update the 153 display on such a terminal, window-based glyph matrices are not 154 well suited. To be able to reuse part of the display (scrolling 155 lines up and down), we must instead have a view of the whole 156 screen. This is what `frame matrices' are for. They are a trick. 157 158 Frames on terminals like above have a glyph pool. Windows on such 159 a frame sub-allocate their glyph memory from their frame's glyph 160 pool. The frame itself is given its own glyph matrices. By 161 coincidence---or maybe something else---rows in window glyph 162 matrices are slices of corresponding rows in frame matrices. Thus 163 writing to window matrices implicitly updates a frame matrix which 164 provides us with the view of the whole screen that we originally 165 wanted to have without having to move many bytes around. To be 166 honest, there is a little bit more done, but not much more. If you 167 plan to extend that code, take a look at dispnew.c. The function 168 build_frame_matrix is a good starting point. */ 169 170#include <config.h> 171#include <stdio.h> 172 173#include "lisp.h" 174#include "keyboard.h" 175#include "frame.h" 176#include "window.h" 177#include "termchar.h" 178#include "dispextern.h" 179#include "buffer.h" 180#include "charset.h" 181#include "indent.h" 182#include "commands.h" 183#include "keymap.h" 184#include "macros.h" 185#include "disptab.h" 186#include "termhooks.h" 187#include "intervals.h" 188#include "coding.h" 189#include "process.h" 190#include "region-cache.h" 191#include "fontset.h" 192#include "blockinput.h" 193 194#ifdef HAVE_X_WINDOWS 195#include "xterm.h" 196#endif 197#ifdef WINDOWSNT 198#include "w32term.h" 199#endif 200#ifdef MAC_OS 201#include "macterm.h" 202#endif 203 204#ifndef FRAME_X_OUTPUT 205#define FRAME_X_OUTPUT(f) ((f)->output_data.x) 206#endif 207 208#define INFINITY 10000000 209 210#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \ 211 || defined (USE_GTK) 212extern void set_frame_menubar P_ ((struct frame *f, int, int)); 213extern int pending_menu_activation; 214#endif 215 216extern int interrupt_input; 217extern int command_loop_level; 218 219extern Lisp_Object do_mouse_tracking; 220 221extern int minibuffer_auto_raise; 222extern Lisp_Object Vminibuffer_list; 223 224extern Lisp_Object Qface; 225extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line; 226 227extern Lisp_Object Voverriding_local_map; 228extern Lisp_Object Voverriding_local_map_menu_flag; 229extern Lisp_Object Qmenu_item; 230extern Lisp_Object Qwhen; 231extern Lisp_Object Qhelp_echo; 232 233Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; 234Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions; 235Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions; 236Lisp_Object Qinhibit_point_motion_hooks; 237Lisp_Object QCeval, QCfile, QCdata, QCpropertize; 238Lisp_Object Qfontified; 239Lisp_Object Qgrow_only; 240Lisp_Object Qinhibit_eval_during_redisplay; 241Lisp_Object Qbuffer_position, Qposition, Qobject; 242 243/* Cursor shapes */ 244Lisp_Object Qbar, Qhbar, Qbox, Qhollow; 245 246/* Pointer shapes */ 247Lisp_Object Qarrow, Qhand, Qtext; 248 249Lisp_Object Qrisky_local_variable; 250 251/* Holds the list (error). */ 252Lisp_Object list_of_error; 253 254/* Functions called to fontify regions of text. */ 255 256Lisp_Object Vfontification_functions; 257Lisp_Object Qfontification_functions; 258 259/* Non-nil means automatically select any window when the mouse 260 cursor moves into it. */ 261Lisp_Object Vmouse_autoselect_window; 262 263/* Non-zero means draw tool bar buttons raised when the mouse moves 264 over them. */ 265 266int auto_raise_tool_bar_buttons_p; 267 268/* Non-zero means to reposition window if cursor line is only partially visible. */ 269 270int make_cursor_line_fully_visible_p; 271 272/* Margin below tool bar in pixels. 0 or nil means no margin. 273 If value is `internal-border-width' or `border-width', 274 the corresponding frame parameter is used. */ 275 276Lisp_Object Vtool_bar_border; 277 278/* Margin around tool bar buttons in pixels. */ 279 280Lisp_Object Vtool_bar_button_margin; 281 282/* Thickness of shadow to draw around tool bar buttons. */ 283 284EMACS_INT tool_bar_button_relief; 285 286/* Non-nil means automatically resize tool-bars so that all tool-bar 287 items are visible, and no blank lines remain. 288 289 If value is `grow-only', only make tool-bar bigger. */ 290 291Lisp_Object Vauto_resize_tool_bars; 292 293/* Non-zero means draw block and hollow cursor as wide as the glyph 294 under it. For example, if a block cursor is over a tab, it will be 295 drawn as wide as that tab on the display. */ 296 297int x_stretch_cursor_p; 298 299/* Non-nil means don't actually do any redisplay. */ 300 301Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay; 302 303/* Non-zero means Lisp evaluation during redisplay is inhibited. */ 304 305int inhibit_eval_during_redisplay; 306 307/* Names of text properties relevant for redisplay. */ 308 309Lisp_Object Qdisplay; 310extern Lisp_Object Qface, Qinvisible, Qwidth; 311 312/* Symbols used in text property values. */ 313 314Lisp_Object Vdisplay_pixels_per_inch; 315Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height; 316Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise; 317Lisp_Object Qslice; 318Lisp_Object Qcenter; 319Lisp_Object Qmargin, Qpointer; 320Lisp_Object Qline_height; 321extern Lisp_Object Qheight; 322extern Lisp_Object QCwidth, QCheight, QCascent; 323extern Lisp_Object Qscroll_bar; 324extern Lisp_Object Qcursor; 325 326/* Non-nil means highlight trailing whitespace. */ 327 328Lisp_Object Vshow_trailing_whitespace; 329 330/* Non-nil means escape non-break space and hyphens. */ 331 332Lisp_Object Vnobreak_char_display; 333 334#ifdef HAVE_WINDOW_SYSTEM 335extern Lisp_Object Voverflow_newline_into_fringe; 336 337/* Test if overflow newline into fringe. Called with iterator IT 338 at or past right window margin, and with IT->current_x set. */ 339 340#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \ 341 (!NILP (Voverflow_newline_into_fringe) \ 342 && FRAME_WINDOW_P (it->f) \ 343 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \ 344 && it->current_x == it->last_visible_x) 345 346#endif /* HAVE_WINDOW_SYSTEM */ 347 348/* Non-nil means show the text cursor in void text areas 349 i.e. in blank areas after eol and eob. This used to be 350 the default in 21.3. */ 351 352Lisp_Object Vvoid_text_area_pointer; 353 354/* Name of the face used to highlight trailing whitespace. */ 355 356Lisp_Object Qtrailing_whitespace; 357 358/* Name and number of the face used to highlight escape glyphs. */ 359 360Lisp_Object Qescape_glyph; 361 362/* Name and number of the face used to highlight non-breaking spaces. */ 363 364Lisp_Object Qnobreak_space; 365 366/* The symbol `image' which is the car of the lists used to represent 367 images in Lisp. */ 368 369Lisp_Object Qimage; 370 371/* The image map types. */ 372Lisp_Object QCmap, QCpointer; 373Lisp_Object Qrect, Qcircle, Qpoly; 374 375/* Non-zero means print newline to stdout before next mini-buffer 376 message. */ 377 378int noninteractive_need_newline; 379 380/* Non-zero means print newline to message log before next message. */ 381 382static int message_log_need_newline; 383 384/* Three markers that message_dolog uses. 385 It could allocate them itself, but that causes trouble 386 in handling memory-full errors. */ 387static Lisp_Object message_dolog_marker1; 388static Lisp_Object message_dolog_marker2; 389static Lisp_Object message_dolog_marker3; 390 391/* The buffer position of the first character appearing entirely or 392 partially on the line of the selected window which contains the 393 cursor; <= 0 if not known. Set by set_cursor_from_row, used for 394 redisplay optimization in redisplay_internal. */ 395 396static struct text_pos this_line_start_pos; 397 398/* Number of characters past the end of the line above, including the 399 terminating newline. */ 400 401static struct text_pos this_line_end_pos; 402 403/* The vertical positions and the height of this line. */ 404 405static int this_line_vpos; 406static int this_line_y; 407static int this_line_pixel_height; 408 409/* X position at which this display line starts. Usually zero; 410 negative if first character is partially visible. */ 411 412static int this_line_start_x; 413 414/* Buffer that this_line_.* variables are referring to. */ 415 416static struct buffer *this_line_buffer; 417 418/* Nonzero means truncate lines in all windows less wide than the 419 frame. */ 420 421int truncate_partial_width_windows; 422 423/* A flag to control how to display unibyte 8-bit character. */ 424 425int unibyte_display_via_language_environment; 426 427/* Nonzero means we have more than one non-mini-buffer-only frame. 428 Not guaranteed to be accurate except while parsing 429 frame-title-format. */ 430 431int multiple_frames; 432 433Lisp_Object Vglobal_mode_string; 434 435 436/* List of variables (symbols) which hold markers for overlay arrows. 437 The symbols on this list are examined during redisplay to determine 438 where to display overlay arrows. */ 439 440Lisp_Object Voverlay_arrow_variable_list; 441 442/* Marker for where to display an arrow on top of the buffer text. */ 443 444Lisp_Object Voverlay_arrow_position; 445 446/* String to display for the arrow. Only used on terminal frames. */ 447 448Lisp_Object Voverlay_arrow_string; 449 450/* Values of those variables at last redisplay are stored as 451 properties on `overlay-arrow-position' symbol. However, if 452 Voverlay_arrow_position is a marker, last-arrow-position is its 453 numerical position. */ 454 455Lisp_Object Qlast_arrow_position, Qlast_arrow_string; 456 457/* Alternative overlay-arrow-string and overlay-arrow-bitmap 458 properties on a symbol in overlay-arrow-variable-list. */ 459 460Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap; 461 462/* Like mode-line-format, but for the title bar on a visible frame. */ 463 464Lisp_Object Vframe_title_format; 465 466/* Like mode-line-format, but for the title bar on an iconified frame. */ 467 468Lisp_Object Vicon_title_format; 469 470/* List of functions to call when a window's size changes. These 471 functions get one arg, a frame on which one or more windows' sizes 472 have changed. */ 473 474static Lisp_Object Vwindow_size_change_functions; 475 476Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook; 477 478/* Nonzero if an overlay arrow has been displayed in this window. */ 479 480static int overlay_arrow_seen; 481 482/* Nonzero means highlight the region even in nonselected windows. */ 483 484int highlight_nonselected_windows; 485 486/* If cursor motion alone moves point off frame, try scrolling this 487 many lines up or down if that will bring it back. */ 488 489static EMACS_INT scroll_step; 490 491/* Nonzero means scroll just far enough to bring point back on the 492 screen, when appropriate. */ 493 494static EMACS_INT scroll_conservatively; 495 496/* Recenter the window whenever point gets within this many lines of 497 the top or bottom of the window. This value is translated into a 498 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means 499 that there is really a fixed pixel height scroll margin. */ 500 501EMACS_INT scroll_margin; 502 503/* Number of windows showing the buffer of the selected window (or 504 another buffer with the same base buffer). keyboard.c refers to 505 this. */ 506 507int buffer_shared; 508 509/* Vector containing glyphs for an ellipsis `...'. */ 510 511static Lisp_Object default_invis_vector[3]; 512 513/* Zero means display the mode-line/header-line/menu-bar in the default face 514 (this slightly odd definition is for compatibility with previous versions 515 of emacs), non-zero means display them using their respective faces. 516 517 This variable is deprecated. */ 518 519int mode_line_inverse_video; 520 521/* Prompt to display in front of the mini-buffer contents. */ 522 523Lisp_Object minibuf_prompt; 524 525/* Width of current mini-buffer prompt. Only set after display_line 526 of the line that contains the prompt. */ 527 528int minibuf_prompt_width; 529 530/* This is the window where the echo area message was displayed. It 531 is always a mini-buffer window, but it may not be the same window 532 currently active as a mini-buffer. */ 533 534Lisp_Object echo_area_window; 535 536/* List of pairs (MESSAGE . MULTIBYTE). The function save_message 537 pushes the current message and the value of 538 message_enable_multibyte on the stack, the function restore_message 539 pops the stack and displays MESSAGE again. */ 540 541Lisp_Object Vmessage_stack; 542 543/* Nonzero means multibyte characters were enabled when the echo area 544 message was specified. */ 545 546int message_enable_multibyte; 547 548/* Nonzero if we should redraw the mode lines on the next redisplay. */ 549 550int update_mode_lines; 551 552/* Nonzero if window sizes or contents have changed since last 553 redisplay that finished. */ 554 555int windows_or_buffers_changed; 556 557/* Nonzero means a frame's cursor type has been changed. */ 558 559int cursor_type_changed; 560 561/* Nonzero after display_mode_line if %l was used and it displayed a 562 line number. */ 563 564int line_number_displayed; 565 566/* Maximum buffer size for which to display line numbers. */ 567 568Lisp_Object Vline_number_display_limit; 569 570/* Line width to consider when repositioning for line number display. */ 571 572static EMACS_INT line_number_display_limit_width; 573 574/* Number of lines to keep in the message log buffer. t means 575 infinite. nil means don't log at all. */ 576 577Lisp_Object Vmessage_log_max; 578 579/* The name of the *Messages* buffer, a string. */ 580 581static Lisp_Object Vmessages_buffer_name; 582 583/* Index 0 is the buffer that holds the current (desired) echo area message, 584 or nil if none is desired right now. 585 586 Index 1 is the buffer that holds the previously displayed echo area message, 587 or nil to indicate no message. This is normally what's on the screen now. 588 589 These two can point to the same buffer. That happens when the last 590 message output by the user (or made by echoing) has been displayed. */ 591 592Lisp_Object echo_area_buffer[2]; 593 594/* Permanent pointers to the two buffers that are used for echo area 595 purposes. Once the two buffers are made, and their pointers are 596 placed here, these two slots remain unchanged unless those buffers 597 need to be created afresh. */ 598 599static Lisp_Object echo_buffer[2]; 600 601/* A vector saved used in with_area_buffer to reduce consing. */ 602 603static Lisp_Object Vwith_echo_area_save_vector; 604 605/* Non-zero means display_echo_area should display the last echo area 606 message again. Set by redisplay_preserve_echo_area. */ 607 608static int display_last_displayed_message_p; 609 610/* Nonzero if echo area is being used by print; zero if being used by 611 message. */ 612 613int message_buf_print; 614 615/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */ 616 617Lisp_Object Qinhibit_menubar_update; 618int inhibit_menubar_update; 619 620/* When evaluating expressions from menu bar items (enable conditions, 621 for instance), this is the frame they are being processed for. */ 622 623Lisp_Object Vmenu_updating_frame; 624 625/* Maximum height for resizing mini-windows. Either a float 626 specifying a fraction of the available height, or an integer 627 specifying a number of lines. */ 628 629Lisp_Object Vmax_mini_window_height; 630 631/* Non-zero means messages should be displayed with truncated 632 lines instead of being continued. */ 633 634int message_truncate_lines; 635Lisp_Object Qmessage_truncate_lines; 636 637/* Set to 1 in clear_message to make redisplay_internal aware 638 of an emptied echo area. */ 639 640static int message_cleared_p; 641 642/* How to blink the default frame cursor off. */ 643Lisp_Object Vblink_cursor_alist; 644 645/* A scratch glyph row with contents used for generating truncation 646 glyphs. Also used in direct_output_for_insert. */ 647 648#define MAX_SCRATCH_GLYPHS 100 649struct glyph_row scratch_glyph_row; 650static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS]; 651 652/* Ascent and height of the last line processed by move_it_to. */ 653 654static int last_max_ascent, last_height; 655 656/* Non-zero if there's a help-echo in the echo area. */ 657 658int help_echo_showing_p; 659 660/* If >= 0, computed, exact values of mode-line and header-line height 661 to use in the macros CURRENT_MODE_LINE_HEIGHT and 662 CURRENT_HEADER_LINE_HEIGHT. */ 663 664int current_mode_line_height, current_header_line_height; 665 666/* The maximum distance to look ahead for text properties. Values 667 that are too small let us call compute_char_face and similar 668 functions too often which is expensive. Values that are too large 669 let us call compute_char_face and alike too often because we 670 might not be interested in text properties that far away. */ 671 672#define TEXT_PROP_DISTANCE_LIMIT 100 673 674#if GLYPH_DEBUG 675 676/* Variables to turn off display optimizations from Lisp. */ 677 678int inhibit_try_window_id, inhibit_try_window_reusing; 679int inhibit_try_cursor_movement; 680 681/* Non-zero means print traces of redisplay if compiled with 682 GLYPH_DEBUG != 0. */ 683 684int trace_redisplay_p; 685 686#endif /* GLYPH_DEBUG */ 687 688#ifdef DEBUG_TRACE_MOVE 689/* Non-zero means trace with TRACE_MOVE to stderr. */ 690int trace_move; 691 692#define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0 693#else 694#define TRACE_MOVE(x) (void) 0 695#endif 696 697/* Non-zero means automatically scroll windows horizontally to make 698 point visible. */ 699 700int automatic_hscrolling_p; 701 702/* How close to the margin can point get before the window is scrolled 703 horizontally. */ 704EMACS_INT hscroll_margin; 705 706/* How much to scroll horizontally when point is inside the above margin. */ 707Lisp_Object Vhscroll_step; 708 709/* The variable `resize-mini-windows'. If nil, don't resize 710 mini-windows. If t, always resize them to fit the text they 711 display. If `grow-only', let mini-windows grow only until they 712 become empty. */ 713 714Lisp_Object Vresize_mini_windows; 715 716/* Buffer being redisplayed -- for redisplay_window_error. */ 717 718struct buffer *displayed_buffer; 719 720/* Space between overline and text. */ 721 722EMACS_INT overline_margin; 723 724/* Value returned from text property handlers (see below). */ 725 726enum prop_handled 727{ 728 HANDLED_NORMALLY, 729 HANDLED_RECOMPUTE_PROPS, 730 HANDLED_OVERLAY_STRING_CONSUMED, 731 HANDLED_RETURN 732}; 733 734/* A description of text properties that redisplay is interested 735 in. */ 736 737struct props 738{ 739 /* The name of the property. */ 740 Lisp_Object *name; 741 742 /* A unique index for the property. */ 743 enum prop_idx idx; 744 745 /* A handler function called to set up iterator IT from the property 746 at IT's current position. Value is used to steer handle_stop. */ 747 enum prop_handled (*handler) P_ ((struct it *it)); 748}; 749 750static enum prop_handled handle_face_prop P_ ((struct it *)); 751static enum prop_handled handle_invisible_prop P_ ((struct it *)); 752static enum prop_handled handle_display_prop P_ ((struct it *)); 753static enum prop_handled handle_composition_prop P_ ((struct it *)); 754static enum prop_handled handle_overlay_change P_ ((struct it *)); 755static enum prop_handled handle_fontified_prop P_ ((struct it *)); 756 757/* Properties handled by iterators. */ 758 759static struct props it_props[] = 760{ 761 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop}, 762 /* Handle `face' before `display' because some sub-properties of 763 `display' need to know the face. */ 764 {&Qface, FACE_PROP_IDX, handle_face_prop}, 765 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop}, 766 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop}, 767 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop}, 768 {NULL, 0, NULL} 769}; 770 771/* Value is the position described by X. If X is a marker, value is 772 the marker_position of X. Otherwise, value is X. */ 773 774#define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X)) 775 776/* Enumeration returned by some move_it_.* functions internally. */ 777 778enum move_it_result 779{ 780 /* Not used. Undefined value. */ 781 MOVE_UNDEFINED, 782 783 /* Move ended at the requested buffer position or ZV. */ 784 MOVE_POS_MATCH_OR_ZV, 785 786 /* Move ended at the requested X pixel position. */ 787 MOVE_X_REACHED, 788 789 /* Move within a line ended at the end of a line that must be 790 continued. */ 791 MOVE_LINE_CONTINUED, 792 793 /* Move within a line ended at the end of a line that would 794 be displayed truncated. */ 795 MOVE_LINE_TRUNCATED, 796 797 /* Move within a line ended at a line end. */ 798 MOVE_NEWLINE_OR_CR 799}; 800 801/* This counter is used to clear the face cache every once in a while 802 in redisplay_internal. It is incremented for each redisplay. 803 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is 804 cleared. */ 805 806#define CLEAR_FACE_CACHE_COUNT 500 807static int clear_face_cache_count; 808 809/* Similarly for the image cache. */ 810 811#ifdef HAVE_WINDOW_SYSTEM 812#define CLEAR_IMAGE_CACHE_COUNT 101 813static int clear_image_cache_count; 814#endif 815 816/* Record the previous terminal frame we displayed. */ 817 818static struct frame *previous_terminal_frame; 819 820/* Non-zero while redisplay_internal is in progress. */ 821 822int redisplaying_p; 823 824/* Non-zero means don't free realized faces. Bound while freeing 825 realized faces is dangerous because glyph matrices might still 826 reference them. */ 827 828int inhibit_free_realized_faces; 829Lisp_Object Qinhibit_free_realized_faces; 830 831/* If a string, XTread_socket generates an event to display that string. 832 (The display is done in read_char.) */ 833 834Lisp_Object help_echo_string; 835Lisp_Object help_echo_window; 836Lisp_Object help_echo_object; 837int help_echo_pos; 838 839/* Temporary variable for XTread_socket. */ 840 841Lisp_Object previous_help_echo_string; 842 843/* Null glyph slice */ 844 845static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 }; 846 847 848/* Function prototypes. */ 849 850static void setup_for_ellipsis P_ ((struct it *, int)); 851static void mark_window_display_accurate_1 P_ ((struct window *, int)); 852static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object)); 853static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); 854static int cursor_row_p P_ ((struct window *, struct glyph_row *)); 855static int redisplay_mode_lines P_ ((Lisp_Object, int)); 856static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int)); 857 858#if 0 859static int invisible_text_between_p P_ ((struct it *, int, int)); 860#endif 861 862static void pint2str P_ ((char *, int, int)); 863static void pint2hrstr P_ ((char *, int, int)); 864static struct text_pos run_window_scroll_functions P_ ((Lisp_Object, 865 struct text_pos)); 866static void reconsider_clip_changes P_ ((struct window *, struct buffer *)); 867static int text_outside_line_unchanged_p P_ ((struct window *, int, int)); 868static void store_mode_line_noprop_char P_ ((char)); 869static int store_mode_line_noprop P_ ((const unsigned char *, int, int)); 870static void x_consider_frame_title P_ ((Lisp_Object)); 871static void handle_stop P_ ((struct it *)); 872static int tool_bar_lines_needed P_ ((struct frame *, int *)); 873static int single_display_spec_intangible_p P_ ((Lisp_Object)); 874static void ensure_echo_area_buffers P_ ((void)); 875static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object)); 876static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *)); 877static int with_echo_area_buffer P_ ((struct window *, int, 878 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT), 879 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 880static void clear_garbaged_frames P_ ((void)); 881static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 882static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 883static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 884static int display_echo_area P_ ((struct window *)); 885static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 886static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 887static Lisp_Object unwind_redisplay P_ ((Lisp_Object)); 888static int string_char_and_length P_ ((const unsigned char *, int, int *)); 889static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object, 890 struct text_pos)); 891static int compute_window_start_on_continuation_line P_ ((struct window *)); 892static Lisp_Object safe_eval_handler P_ ((Lisp_Object)); 893static void insert_left_trunc_glyphs P_ ((struct it *)); 894static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *, 895 Lisp_Object)); 896static void extend_face_to_end_of_line P_ ((struct it *)); 897static int append_space_for_newline P_ ((struct it *, int)); 898static int cursor_row_fully_visible_p P_ ((struct window *, int, int)); 899static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); 900static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); 901static int trailing_whitespace_p P_ ((int)); 902static int message_log_check_duplicate P_ ((int, int, int, int)); 903static void push_it P_ ((struct it *)); 904static void pop_it P_ ((struct it *)); 905static void sync_frame_with_window_matrix_rows P_ ((struct window *)); 906static void select_frame_for_redisplay P_ ((Lisp_Object)); 907static void redisplay_internal P_ ((int)); 908static int echo_area_display P_ ((int)); 909static void redisplay_windows P_ ((Lisp_Object)); 910static void redisplay_window P_ ((Lisp_Object, int)); 911static Lisp_Object redisplay_window_error (); 912static Lisp_Object redisplay_window_0 P_ ((Lisp_Object)); 913static Lisp_Object redisplay_window_1 P_ ((Lisp_Object)); 914static int update_menu_bar P_ ((struct frame *, int, int)); 915static int try_window_reusing_current_matrix P_ ((struct window *)); 916static int try_window_id P_ ((struct window *)); 917static int display_line P_ ((struct it *)); 918static int display_mode_lines P_ ((struct window *)); 919static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object)); 920static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int)); 921static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object)); 922static char *decode_mode_spec P_ ((struct window *, int, int, int, int *)); 923static void display_menu_bar P_ ((struct window *)); 924static int display_count_lines P_ ((int, int, int, int, int *)); 925static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object, 926 int, int, struct it *, int, int, int, int)); 927static void compute_line_metrics P_ ((struct it *)); 928static void run_redisplay_end_trigger_hook P_ ((struct it *)); 929static int get_overlay_strings P_ ((struct it *, int)); 930static int get_overlay_strings_1 P_ ((struct it *, int, int)); 931static void next_overlay_string P_ ((struct it *)); 932static void reseat P_ ((struct it *, struct text_pos, int)); 933static void reseat_1 P_ ((struct it *, struct text_pos, int)); 934static void back_to_previous_visible_line_start P_ ((struct it *)); 935void reseat_at_previous_visible_line_start P_ ((struct it *)); 936static void reseat_at_next_visible_line_start P_ ((struct it *, int)); 937static int next_element_from_ellipsis P_ ((struct it *)); 938static int next_element_from_display_vector P_ ((struct it *)); 939static int next_element_from_string P_ ((struct it *)); 940static int next_element_from_c_string P_ ((struct it *)); 941static int next_element_from_buffer P_ ((struct it *)); 942static int next_element_from_composition P_ ((struct it *)); 943static int next_element_from_image P_ ((struct it *)); 944static int next_element_from_stretch P_ ((struct it *)); 945static void load_overlay_strings P_ ((struct it *, int)); 946static int init_from_display_pos P_ ((struct it *, struct window *, 947 struct display_pos *)); 948static void reseat_to_string P_ ((struct it *, unsigned char *, 949 Lisp_Object, int, int, int, int)); 950static enum move_it_result move_it_in_display_line_to P_ ((struct it *, 951 int, int, int)); 952void move_it_vertically_backward P_ ((struct it *, int)); 953static void init_to_row_start P_ ((struct it *, struct window *, 954 struct glyph_row *)); 955static int init_to_row_end P_ ((struct it *, struct window *, 956 struct glyph_row *)); 957static void back_to_previous_line_start P_ ((struct it *)); 958static int forward_to_next_line_start P_ ((struct it *, int *)); 959static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos, 960 Lisp_Object, int)); 961static struct text_pos string_pos P_ ((int, Lisp_Object)); 962static struct text_pos c_string_pos P_ ((int, unsigned char *, int)); 963static int number_of_chars P_ ((unsigned char *, int)); 964static void compute_stop_pos P_ ((struct it *)); 965static void compute_string_pos P_ ((struct text_pos *, struct text_pos, 966 Lisp_Object)); 967static int face_before_or_after_it_pos P_ ((struct it *, int)); 968static int next_overlay_change P_ ((int)); 969static int handle_single_display_spec P_ ((struct it *, Lisp_Object, 970 Lisp_Object, struct text_pos *, 971 int)); 972static int underlying_face_id P_ ((struct it *)); 973static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *, 974 struct window *)); 975 976#define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1) 977#define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0) 978 979#ifdef HAVE_WINDOW_SYSTEM 980 981static void update_tool_bar P_ ((struct frame *, int)); 982static void build_desired_tool_bar_string P_ ((struct frame *f)); 983static int redisplay_tool_bar P_ ((struct frame *)); 984static void display_tool_bar_line P_ ((struct it *, int)); 985static void notice_overwritten_cursor P_ ((struct window *, 986 enum glyph_row_area, 987 int, int, int, int)); 988 989 990 991#endif /* HAVE_WINDOW_SYSTEM */ 992 993 994/*********************************************************************** 995 Window display dimensions 996 ***********************************************************************/ 997 998/* Return the bottom boundary y-position for text lines in window W. 999 This is the first y position at which a line cannot start. 1000 It is relative to the top of the window. 1001 1002 This is the height of W minus the height of a mode line, if any. */ 1003 1004INLINE int 1005window_text_bottom_y (w) 1006 struct window *w; 1007{ 1008 int height = WINDOW_TOTAL_HEIGHT (w); 1009 1010 if (WINDOW_WANTS_MODELINE_P (w)) 1011 height -= CURRENT_MODE_LINE_HEIGHT (w); 1012 return height; 1013} 1014 1015/* Return the pixel width of display area AREA of window W. AREA < 0 1016 means return the total width of W, not including fringes to 1017 the left and right of the window. */ 1018 1019INLINE int 1020window_box_width (w, area) 1021 struct window *w; 1022 int area; 1023{ 1024 int cols = XFASTINT (w->total_cols); 1025 int pixels = 0; 1026 1027 if (!w->pseudo_window_p) 1028 { 1029 cols -= WINDOW_SCROLL_BAR_COLS (w); 1030 1031 if (area == TEXT_AREA) 1032 { 1033 if (INTEGERP (w->left_margin_cols)) 1034 cols -= XFASTINT (w->left_margin_cols); 1035 if (INTEGERP (w->right_margin_cols)) 1036 cols -= XFASTINT (w->right_margin_cols); 1037 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w); 1038 } 1039 else if (area == LEFT_MARGIN_AREA) 1040 { 1041 cols = (INTEGERP (w->left_margin_cols) 1042 ? XFASTINT (w->left_margin_cols) : 0); 1043 pixels = 0; 1044 } 1045 else if (area == RIGHT_MARGIN_AREA) 1046 { 1047 cols = (INTEGERP (w->right_margin_cols) 1048 ? XFASTINT (w->right_margin_cols) : 0); 1049 pixels = 0; 1050 } 1051 } 1052 1053 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels; 1054} 1055 1056 1057/* Return the pixel height of the display area of window W, not 1058 including mode lines of W, if any. */ 1059 1060INLINE int 1061window_box_height (w) 1062 struct window *w; 1063{ 1064 struct frame *f = XFRAME (w->frame); 1065 int height = WINDOW_TOTAL_HEIGHT (w); 1066 1067 xassert (height >= 0); 1068 1069 /* Note: the code below that determines the mode-line/header-line 1070 height is essentially the same as that contained in the macro 1071 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether 1072 the appropriate glyph row has its `mode_line_p' flag set, 1073 and if it doesn't, uses estimate_mode_line_height instead. */ 1074 1075 if (WINDOW_WANTS_MODELINE_P (w)) 1076 { 1077 struct glyph_row *ml_row 1078 = (w->current_matrix && w->current_matrix->rows 1079 ? MATRIX_MODE_LINE_ROW (w->current_matrix) 1080 : 0); 1081 if (ml_row && ml_row->mode_line_p) 1082 height -= ml_row->height; 1083 else 1084 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w)); 1085 } 1086 1087 if (WINDOW_WANTS_HEADER_LINE_P (w)) 1088 { 1089 struct glyph_row *hl_row 1090 = (w->current_matrix && w->current_matrix->rows 1091 ? MATRIX_HEADER_LINE_ROW (w->current_matrix) 1092 : 0); 1093 if (hl_row && hl_row->mode_line_p) 1094 height -= hl_row->height; 1095 else 1096 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID); 1097 } 1098 1099 /* With a very small font and a mode-line that's taller than 1100 default, we might end up with a negative height. */ 1101 return max (0, height); 1102} 1103 1104/* Return the window-relative coordinate of the left edge of display 1105 area AREA of window W. AREA < 0 means return the left edge of the 1106 whole window, to the right of the left fringe of W. */ 1107 1108INLINE int 1109window_box_left_offset (w, area) 1110 struct window *w; 1111 int area; 1112{ 1113 int x; 1114 1115 if (w->pseudo_window_p) 1116 return 0; 1117 1118 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w); 1119 1120 if (area == TEXT_AREA) 1121 x += (WINDOW_LEFT_FRINGE_WIDTH (w) 1122 + window_box_width (w, LEFT_MARGIN_AREA)); 1123 else if (area == RIGHT_MARGIN_AREA) 1124 x += (WINDOW_LEFT_FRINGE_WIDTH (w) 1125 + window_box_width (w, LEFT_MARGIN_AREA) 1126 + window_box_width (w, TEXT_AREA) 1127 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 1128 ? 0 1129 : WINDOW_RIGHT_FRINGE_WIDTH (w))); 1130 else if (area == LEFT_MARGIN_AREA 1131 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) 1132 x += WINDOW_LEFT_FRINGE_WIDTH (w); 1133 1134 return x; 1135} 1136 1137 1138/* Return the window-relative coordinate of the right edge of display 1139 area AREA of window W. AREA < 0 means return the left edge of the 1140 whole window, to the left of the right fringe of W. */ 1141 1142INLINE int 1143window_box_right_offset (w, area) 1144 struct window *w; 1145 int area; 1146{ 1147 return window_box_left_offset (w, area) + window_box_width (w, area); 1148} 1149 1150/* Return the frame-relative coordinate of the left edge of display 1151 area AREA of window W. AREA < 0 means return the left edge of the 1152 whole window, to the right of the left fringe of W. */ 1153 1154INLINE int 1155window_box_left (w, area) 1156 struct window *w; 1157 int area; 1158{ 1159 struct frame *f = XFRAME (w->frame); 1160 int x; 1161 1162 if (w->pseudo_window_p) 1163 return FRAME_INTERNAL_BORDER_WIDTH (f); 1164 1165 x = (WINDOW_LEFT_EDGE_X (w) 1166 + window_box_left_offset (w, area)); 1167 1168 return x; 1169} 1170 1171 1172/* Return the frame-relative coordinate of the right edge of display 1173 area AREA of window W. AREA < 0 means return the left edge of the 1174 whole window, to the left of the right fringe of W. */ 1175 1176INLINE int 1177window_box_right (w, area) 1178 struct window *w; 1179 int area; 1180{ 1181 return window_box_left (w, area) + window_box_width (w, area); 1182} 1183 1184/* Get the bounding box of the display area AREA of window W, without 1185 mode lines, in frame-relative coordinates. AREA < 0 means the 1186 whole window, not including the left and right fringes of 1187 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel 1188 coordinates of the upper-left corner of the box. Return in 1189 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */ 1190 1191INLINE void 1192window_box (w, area, box_x, box_y, box_width, box_height) 1193 struct window *w; 1194 int area; 1195 int *box_x, *box_y, *box_width, *box_height; 1196{ 1197 if (box_width) 1198 *box_width = window_box_width (w, area); 1199 if (box_height) 1200 *box_height = window_box_height (w); 1201 if (box_x) 1202 *box_x = window_box_left (w, area); 1203 if (box_y) 1204 { 1205 *box_y = WINDOW_TOP_EDGE_Y (w); 1206 if (WINDOW_WANTS_HEADER_LINE_P (w)) 1207 *box_y += CURRENT_HEADER_LINE_HEIGHT (w); 1208 } 1209} 1210 1211 1212/* Get the bounding box of the display area AREA of window W, without 1213 mode lines. AREA < 0 means the whole window, not including the 1214 left and right fringe of the window. Return in *TOP_LEFT_X 1215 and TOP_LEFT_Y the frame-relative pixel coordinates of the 1216 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and 1217 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the 1218 box. */ 1219 1220INLINE void 1221window_box_edges (w, area, top_left_x, top_left_y, 1222 bottom_right_x, bottom_right_y) 1223 struct window *w; 1224 int area; 1225 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y; 1226{ 1227 window_box (w, area, top_left_x, top_left_y, bottom_right_x, 1228 bottom_right_y); 1229 *bottom_right_x += *top_left_x; 1230 *bottom_right_y += *top_left_y; 1231} 1232 1233 1234 1235/*********************************************************************** 1236 Utilities 1237 ***********************************************************************/ 1238 1239/* Return the bottom y-position of the line the iterator IT is in. 1240 This can modify IT's settings. */ 1241 1242int 1243line_bottom_y (it) 1244 struct it *it; 1245{ 1246 int line_height = it->max_ascent + it->max_descent; 1247 int line_top_y = it->current_y; 1248 1249 if (line_height == 0) 1250 { 1251 if (last_height) 1252 line_height = last_height; 1253 else if (IT_CHARPOS (*it) < ZV) 1254 { 1255 move_it_by_lines (it, 1, 1); 1256 line_height = (it->max_ascent || it->max_descent 1257 ? it->max_ascent + it->max_descent 1258 : last_height); 1259 } 1260 else 1261 { 1262 struct glyph_row *row = it->glyph_row; 1263 1264 /* Use the default character height. */ 1265 it->glyph_row = NULL; 1266 it->what = IT_CHARACTER; 1267 it->c = ' '; 1268 it->len = 1; 1269 PRODUCE_GLYPHS (it); 1270 line_height = it->ascent + it->descent; 1271 it->glyph_row = row; 1272 } 1273 } 1274 1275 return line_top_y + line_height; 1276} 1277 1278 1279/* Return 1 if position CHARPOS is visible in window W. 1280 CHARPOS < 0 means return info about WINDOW_END position. 1281 If visible, set *X and *Y to pixel coordinates of top left corner. 1282 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS. 1283 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */ 1284 1285int 1286pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos) 1287 struct window *w; 1288 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos; 1289{ 1290 struct it it; 1291 struct text_pos top; 1292 int visible_p = 0; 1293 struct buffer *old_buffer = NULL; 1294 1295 if (noninteractive) 1296 return visible_p; 1297 1298 if (XBUFFER (w->buffer) != current_buffer) 1299 { 1300 old_buffer = current_buffer; 1301 set_buffer_internal_1 (XBUFFER (w->buffer)); 1302 } 1303 1304 SET_TEXT_POS_FROM_MARKER (top, w->start); 1305 1306 /* Compute exact mode line heights. */ 1307 if (WINDOW_WANTS_MODELINE_P (w)) 1308 current_mode_line_height 1309 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w), 1310 current_buffer->mode_line_format); 1311 1312 if (WINDOW_WANTS_HEADER_LINE_P (w)) 1313 current_header_line_height 1314 = display_mode_line (w, HEADER_LINE_FACE_ID, 1315 current_buffer->header_line_format); 1316 1317 start_display (&it, w, top); 1318 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, 1319 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); 1320 1321 /* Note that we may overshoot because of invisible text. */ 1322 if (charpos >= 0 && IT_CHARPOS (it) >= charpos) 1323 { 1324 int top_x = it.current_x; 1325 int top_y = it.current_y; 1326 int bottom_y = (last_height = 0, line_bottom_y (&it)); 1327 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); 1328 1329 if (top_y < window_top_y) 1330 visible_p = bottom_y > window_top_y; 1331 else if (top_y < it.last_visible_y) 1332 visible_p = 1; 1333 if (visible_p) 1334 { 1335 *x = top_x; 1336 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y); 1337 *rtop = max (0, window_top_y - top_y); 1338 *rbot = max (0, bottom_y - it.last_visible_y); 1339 *rowh = max (0, (min (bottom_y, it.last_visible_y) 1340 - max (top_y, window_top_y))); 1341 *vpos = it.vpos; 1342 } 1343 } 1344 else 1345 { 1346 struct it it2; 1347 1348 it2 = it; 1349 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n') 1350 move_it_by_lines (&it, 1, 0); 1351 if (charpos < IT_CHARPOS (it) 1352 || (it.what == IT_EOB && charpos == IT_CHARPOS (it))) 1353 { 1354 visible_p = 1; 1355 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS); 1356 *x = it2.current_x; 1357 *y = it2.current_y + it2.max_ascent - it2.ascent; 1358 *rtop = max (0, -it2.current_y); 1359 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent) 1360 - it.last_visible_y)); 1361 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent, 1362 it.last_visible_y) 1363 - max (it2.current_y, 1364 WINDOW_HEADER_LINE_HEIGHT (w)))); 1365 *vpos = it2.vpos; 1366 } 1367 } 1368 1369 if (old_buffer) 1370 set_buffer_internal_1 (old_buffer); 1371 1372 current_header_line_height = current_mode_line_height = -1; 1373 1374 if (visible_p && XFASTINT (w->hscroll) > 0) 1375 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w); 1376 1377#if 0 1378 /* Debugging code. */ 1379 if (visible_p) 1380 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n", 1381 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos); 1382 else 1383 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll); 1384#endif 1385 1386 return visible_p; 1387} 1388 1389 1390/* Return the next character from STR which is MAXLEN bytes long. 1391 Return in *LEN the length of the character. This is like 1392 STRING_CHAR_AND_LENGTH but never returns an invalid character. If 1393 we find one, we return a `?', but with the length of the invalid 1394 character. */ 1395 1396static INLINE int 1397string_char_and_length (str, maxlen, len) 1398 const unsigned char *str; 1399 int maxlen, *len; 1400{ 1401 int c; 1402 1403 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len); 1404 if (!CHAR_VALID_P (c, 1)) 1405 /* We may not change the length here because other places in Emacs 1406 don't use this function, i.e. they silently accept invalid 1407 characters. */ 1408 c = '?'; 1409 1410 return c; 1411} 1412 1413 1414 1415/* Given a position POS containing a valid character and byte position 1416 in STRING, return the position NCHARS ahead (NCHARS >= 0). */ 1417 1418static struct text_pos 1419string_pos_nchars_ahead (pos, string, nchars) 1420 struct text_pos pos; 1421 Lisp_Object string; 1422 int nchars; 1423{ 1424 xassert (STRINGP (string) && nchars >= 0); 1425 1426 if (STRING_MULTIBYTE (string)) 1427 { 1428 int rest = SBYTES (string) - BYTEPOS (pos); 1429 const unsigned char *p = SDATA (string) + BYTEPOS (pos); 1430 int len; 1431 1432 while (nchars--) 1433 { 1434 string_char_and_length (p, rest, &len); 1435 p += len, rest -= len; 1436 xassert (rest >= 0); 1437 CHARPOS (pos) += 1; 1438 BYTEPOS (pos) += len; 1439 } 1440 } 1441 else 1442 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars); 1443 1444 return pos; 1445} 1446 1447 1448/* Value is the text position, i.e. character and byte position, 1449 for character position CHARPOS in STRING. */ 1450 1451static INLINE struct text_pos 1452string_pos (charpos, string) 1453 int charpos; 1454 Lisp_Object string; 1455{ 1456 struct text_pos pos; 1457 xassert (STRINGP (string)); 1458 xassert (charpos >= 0); 1459 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos)); 1460 return pos; 1461} 1462 1463 1464/* Value is a text position, i.e. character and byte position, for 1465 character position CHARPOS in C string S. MULTIBYTE_P non-zero 1466 means recognize multibyte characters. */ 1467 1468static struct text_pos 1469c_string_pos (charpos, s, multibyte_p) 1470 int charpos; 1471 unsigned char *s; 1472 int multibyte_p; 1473{ 1474 struct text_pos pos; 1475 1476 xassert (s != NULL); 1477 xassert (charpos >= 0); 1478 1479 if (multibyte_p) 1480 { 1481 int rest = strlen (s), len; 1482 1483 SET_TEXT_POS (pos, 0, 0); 1484 while (charpos--) 1485 { 1486 string_char_and_length (s, rest, &len); 1487 s += len, rest -= len; 1488 xassert (rest >= 0); 1489 CHARPOS (pos) += 1; 1490 BYTEPOS (pos) += len; 1491 } 1492 } 1493 else 1494 SET_TEXT_POS (pos, charpos, charpos); 1495 1496 return pos; 1497} 1498 1499 1500/* Value is the number of characters in C string S. MULTIBYTE_P 1501 non-zero means recognize multibyte characters. */ 1502 1503static int 1504number_of_chars (s, multibyte_p) 1505 unsigned char *s; 1506 int multibyte_p; 1507{ 1508 int nchars; 1509 1510 if (multibyte_p) 1511 { 1512 int rest = strlen (s), len; 1513 unsigned char *p = (unsigned char *) s; 1514 1515 for (nchars = 0; rest > 0; ++nchars) 1516 { 1517 string_char_and_length (p, rest, &len); 1518 rest -= len, p += len; 1519 } 1520 } 1521 else 1522 nchars = strlen (s); 1523 1524 return nchars; 1525} 1526 1527 1528/* Compute byte position NEWPOS->bytepos corresponding to 1529 NEWPOS->charpos. POS is a known position in string STRING. 1530 NEWPOS->charpos must be >= POS.charpos. */ 1531 1532static void 1533compute_string_pos (newpos, pos, string) 1534 struct text_pos *newpos, pos; 1535 Lisp_Object string; 1536{ 1537 xassert (STRINGP (string)); 1538 xassert (CHARPOS (*newpos) >= CHARPOS (pos)); 1539 1540 if (STRING_MULTIBYTE (string)) 1541 *newpos = string_pos_nchars_ahead (pos, string, 1542 CHARPOS (*newpos) - CHARPOS (pos)); 1543 else 1544 BYTEPOS (*newpos) = CHARPOS (*newpos); 1545} 1546 1547/* EXPORT: 1548 Return an estimation of the pixel height of mode or top lines on 1549 frame F. FACE_ID specifies what line's height to estimate. */ 1550 1551int 1552estimate_mode_line_height (f, face_id) 1553 struct frame *f; 1554 enum face_id face_id; 1555{ 1556#ifdef HAVE_WINDOW_SYSTEM 1557 if (FRAME_WINDOW_P (f)) 1558 { 1559 int height = FONT_HEIGHT (FRAME_FONT (f)); 1560 1561 /* This function is called so early when Emacs starts that the face 1562 cache and mode line face are not yet initialized. */ 1563 if (FRAME_FACE_CACHE (f)) 1564 { 1565 struct face *face = FACE_FROM_ID (f, face_id); 1566 if (face) 1567 { 1568 if (face->font) 1569 height = FONT_HEIGHT (face->font); 1570 if (face->box_line_width > 0) 1571 height += 2 * face->box_line_width; 1572 } 1573 } 1574 1575 return height; 1576 } 1577#endif 1578 1579 return 1; 1580} 1581 1582/* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph 1583 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the 1584 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do 1585 not force the value into range. */ 1586 1587void 1588pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip) 1589 FRAME_PTR f; 1590 register int pix_x, pix_y; 1591 int *x, *y; 1592 NativeRectangle *bounds; 1593 int noclip; 1594{ 1595 1596#ifdef HAVE_WINDOW_SYSTEM 1597 if (FRAME_WINDOW_P (f)) 1598 { 1599 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down 1600 even for negative values. */ 1601 if (pix_x < 0) 1602 pix_x -= FRAME_COLUMN_WIDTH (f) - 1; 1603 if (pix_y < 0) 1604 pix_y -= FRAME_LINE_HEIGHT (f) - 1; 1605 1606 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x); 1607 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y); 1608 1609 if (bounds) 1610 STORE_NATIVE_RECT (*bounds, 1611 FRAME_COL_TO_PIXEL_X (f, pix_x), 1612 FRAME_LINE_TO_PIXEL_Y (f, pix_y), 1613 FRAME_COLUMN_WIDTH (f) - 1, 1614 FRAME_LINE_HEIGHT (f) - 1); 1615 1616 if (!noclip) 1617 { 1618 if (pix_x < 0) 1619 pix_x = 0; 1620 else if (pix_x > FRAME_TOTAL_COLS (f)) 1621 pix_x = FRAME_TOTAL_COLS (f); 1622 1623 if (pix_y < 0) 1624 pix_y = 0; 1625 else if (pix_y > FRAME_LINES (f)) 1626 pix_y = FRAME_LINES (f); 1627 } 1628 } 1629#endif 1630 1631 *x = pix_x; 1632 *y = pix_y; 1633} 1634 1635 1636/* Given HPOS/VPOS in the current matrix of W, return corresponding 1637 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we 1638 can't tell the positions because W's display is not up to date, 1639 return 0. */ 1640 1641int 1642glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y) 1643 struct window *w; 1644 int hpos, vpos; 1645 int *frame_x, *frame_y; 1646{ 1647#ifdef HAVE_WINDOW_SYSTEM 1648 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))) 1649 { 1650 int success_p; 1651 1652 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w); 1653 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h); 1654 1655 if (display_completed) 1656 { 1657 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos); 1658 struct glyph *glyph = row->glyphs[TEXT_AREA]; 1659 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]); 1660 1661 hpos = row->x; 1662 vpos = row->y; 1663 while (glyph < end) 1664 { 1665 hpos += glyph->pixel_width; 1666 ++glyph; 1667 } 1668 1669 /* If first glyph is partially visible, its first visible position is still 0. */ 1670 if (hpos < 0) 1671 hpos = 0; 1672 1673 success_p = 1; 1674 } 1675 else 1676 { 1677 hpos = vpos = 0; 1678 success_p = 0; 1679 } 1680 1681 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos); 1682 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos); 1683 return success_p; 1684 } 1685#endif 1686 1687 *frame_x = hpos; 1688 *frame_y = vpos; 1689 return 1; 1690} 1691 1692 1693#ifdef HAVE_WINDOW_SYSTEM 1694 1695/* Find the glyph under window-relative coordinates X/Y in window W. 1696 Consider only glyphs from buffer text, i.e. no glyphs from overlay 1697 strings. Return in *HPOS and *VPOS the row and column number of 1698 the glyph found. Return in *AREA the glyph area containing X. 1699 Value is a pointer to the glyph found or null if X/Y is not on 1700 text, or we can't tell because W's current matrix is not up to 1701 date. */ 1702 1703static struct glyph * 1704x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area) 1705 struct window *w; 1706 int x, y; 1707 int *hpos, *vpos, *dx, *dy, *area; 1708{ 1709 struct glyph *glyph, *end; 1710 struct glyph_row *row = NULL; 1711 int x0, i; 1712 1713 /* Find row containing Y. Give up if some row is not enabled. */ 1714 for (i = 0; i < w->current_matrix->nrows; ++i) 1715 { 1716 row = MATRIX_ROW (w->current_matrix, i); 1717 if (!row->enabled_p) 1718 return NULL; 1719 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row)) 1720 break; 1721 } 1722 1723 *vpos = i; 1724 *hpos = 0; 1725 1726 /* Give up if Y is not in the window. */ 1727 if (i == w->current_matrix->nrows) 1728 return NULL; 1729 1730 /* Get the glyph area containing X. */ 1731 if (w->pseudo_window_p) 1732 { 1733 *area = TEXT_AREA; 1734 x0 = 0; 1735 } 1736 else 1737 { 1738 if (x < window_box_left_offset (w, TEXT_AREA)) 1739 { 1740 *area = LEFT_MARGIN_AREA; 1741 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA); 1742 } 1743 else if (x < window_box_right_offset (w, TEXT_AREA)) 1744 { 1745 *area = TEXT_AREA; 1746 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0); 1747 } 1748 else 1749 { 1750 *area = RIGHT_MARGIN_AREA; 1751 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA); 1752 } 1753 } 1754 1755 /* Find glyph containing X. */ 1756 glyph = row->glyphs[*area]; 1757 end = glyph + row->used[*area]; 1758 x -= x0; 1759 while (glyph < end && x >= glyph->pixel_width) 1760 { 1761 x -= glyph->pixel_width; 1762 ++glyph; 1763 } 1764 1765 if (glyph == end) 1766 return NULL; 1767 1768 if (dx) 1769 { 1770 *dx = x; 1771 *dy = y - (row->y + row->ascent - glyph->ascent); 1772 } 1773 1774 *hpos = glyph - row->glyphs[*area]; 1775 return glyph; 1776} 1777 1778 1779/* EXPORT: 1780 Convert frame-relative x/y to coordinates relative to window W. 1781 Takes pseudo-windows into account. */ 1782 1783void 1784frame_to_window_pixel_xy (w, x, y) 1785 struct window *w; 1786 int *x, *y; 1787{ 1788 if (w->pseudo_window_p) 1789 { 1790 /* A pseudo-window is always full-width, and starts at the 1791 left edge of the frame, plus a frame border. */ 1792 struct frame *f = XFRAME (w->frame); 1793 *x -= FRAME_INTERNAL_BORDER_WIDTH (f); 1794 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y); 1795 } 1796 else 1797 { 1798 *x -= WINDOW_LEFT_EDGE_X (w); 1799 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y); 1800 } 1801} 1802 1803/* EXPORT: 1804 Return in RECTS[] at most N clipping rectangles for glyph string S. 1805 Return the number of stored rectangles. */ 1806 1807int 1808get_glyph_string_clip_rects (s, rects, n) 1809 struct glyph_string *s; 1810 NativeRectangle *rects; 1811 int n; 1812{ 1813 XRectangle r; 1814 1815 if (n <= 0) 1816 return 0; 1817 1818 if (s->row->full_width_p) 1819 { 1820 /* Draw full-width. X coordinates are relative to S->w->left_col. */ 1821 r.x = WINDOW_LEFT_EDGE_X (s->w); 1822 r.width = WINDOW_TOTAL_WIDTH (s->w); 1823 1824 /* Unless displaying a mode or menu bar line, which are always 1825 fully visible, clip to the visible part of the row. */ 1826 if (s->w->pseudo_window_p) 1827 r.height = s->row->visible_height; 1828 else 1829 r.height = s->height; 1830 } 1831 else 1832 { 1833 /* This is a text line that may be partially visible. */ 1834 r.x = window_box_left (s->w, s->area); 1835 r.width = window_box_width (s->w, s->area); 1836 r.height = s->row->visible_height; 1837 } 1838 1839 if (s->clip_head) 1840 if (r.x < s->clip_head->x) 1841 { 1842 if (r.width >= s->clip_head->x - r.x) 1843 r.width -= s->clip_head->x - r.x; 1844 else 1845 r.width = 0; 1846 r.x = s->clip_head->x; 1847 } 1848 if (s->clip_tail) 1849 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width) 1850 { 1851 if (s->clip_tail->x + s->clip_tail->background_width >= r.x) 1852 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x; 1853 else 1854 r.width = 0; 1855 } 1856 1857 /* If S draws overlapping rows, it's sufficient to use the top and 1858 bottom of the window for clipping because this glyph string 1859 intentionally draws over other lines. */ 1860 if (s->for_overlaps) 1861 { 1862 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w); 1863 r.height = window_text_bottom_y (s->w) - r.y; 1864 1865 /* Alas, the above simple strategy does not work for the 1866 environments with anti-aliased text: if the same text is 1867 drawn onto the same place multiple times, it gets thicker. 1868 If the overlap we are processing is for the erased cursor, we 1869 take the intersection with the rectagle of the cursor. */ 1870 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR) 1871 { 1872 XRectangle rc, r_save = r; 1873 1874 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x); 1875 rc.y = s->w->phys_cursor.y; 1876 rc.width = s->w->phys_cursor_width; 1877 rc.height = s->w->phys_cursor_height; 1878 1879 x_intersect_rectangles (&r_save, &rc, &r); 1880 } 1881 } 1882 else 1883 { 1884 /* Don't use S->y for clipping because it doesn't take partially 1885 visible lines into account. For example, it can be negative for 1886 partially visible lines at the top of a window. */ 1887 if (!s->row->full_width_p 1888 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row)) 1889 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w); 1890 else 1891 r.y = max (0, s->row->y); 1892 1893 /* If drawing a tool-bar window, draw it over the internal border 1894 at the top of the window. */ 1895 if (WINDOWP (s->f->tool_bar_window) 1896 && s->w == XWINDOW (s->f->tool_bar_window)) 1897 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f); 1898 } 1899 1900 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y); 1901 1902 /* If drawing the cursor, don't let glyph draw outside its 1903 advertised boundaries. Cleartype does this under some circumstances. */ 1904 if (s->hl == DRAW_CURSOR) 1905 { 1906 struct glyph *glyph = s->first_glyph; 1907 int height, max_y; 1908 1909 if (s->x > r.x) 1910 { 1911 r.width -= s->x - r.x; 1912 r.x = s->x; 1913 } 1914 r.width = min (r.width, glyph->pixel_width); 1915 1916 /* If r.y is below window bottom, ensure that we still see a cursor. */ 1917 height = min (glyph->ascent + glyph->descent, 1918 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height)); 1919 max_y = window_text_bottom_y (s->w) - height; 1920 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y); 1921 if (s->ybase - glyph->ascent > max_y) 1922 { 1923 r.y = max_y; 1924 r.height = height; 1925 } 1926 else 1927 { 1928 /* Don't draw cursor glyph taller than our actual glyph. */ 1929 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent); 1930 if (height < r.height) 1931 { 1932 max_y = r.y + r.height; 1933 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height)); 1934 r.height = min (max_y - r.y, height); 1935 } 1936 } 1937 } 1938 1939 if ((s->for_overlaps & OVERLAPS_BOTH) == 0 1940 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1)) 1941 { 1942#ifdef CONVERT_FROM_XRECT 1943 CONVERT_FROM_XRECT (r, *rects); 1944#else 1945 *rects = r; 1946#endif 1947 return 1; 1948 } 1949 else 1950 { 1951 /* If we are processing overlapping and allowed to return 1952 multiple clipping rectangles, we exclude the row of the glyph 1953 string from the clipping rectangle. This is to avoid drawing 1954 the same text on the environment with anti-aliasing. */ 1955#ifdef CONVERT_FROM_XRECT 1956 XRectangle rs[2]; 1957#else 1958 XRectangle *rs = rects; 1959#endif 1960 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y); 1961 1962 if (s->for_overlaps & OVERLAPS_PRED) 1963 { 1964 rs[i] = r; 1965 if (r.y + r.height > row_y) 1966 { 1967 if (r.y < row_y) 1968 rs[i].height = row_y - r.y; 1969 else 1970 rs[i].height = 0; 1971 } 1972 i++; 1973 } 1974 if (s->for_overlaps & OVERLAPS_SUCC) 1975 { 1976 rs[i] = r; 1977 if (r.y < row_y + s->row->visible_height) 1978 { 1979 if (r.y + r.height > row_y + s->row->visible_height) 1980 { 1981 rs[i].y = row_y + s->row->visible_height; 1982 rs[i].height = r.y + r.height - rs[i].y; 1983 } 1984 else 1985 rs[i].height = 0; 1986 } 1987 i++; 1988 } 1989 1990 n = i; 1991#ifdef CONVERT_FROM_XRECT 1992 for (i = 0; i < n; i++) 1993 CONVERT_FROM_XRECT (rs[i], rects[i]); 1994#endif 1995 return n; 1996 } 1997} 1998 1999/* EXPORT: 2000 Return in *NR the clipping rectangle for glyph string S. */ 2001 2002void 2003get_glyph_string_clip_rect (s, nr) 2004 struct glyph_string *s; 2005 NativeRectangle *nr; 2006{ 2007 get_glyph_string_clip_rects (s, nr, 1); 2008} 2009 2010 2011/* EXPORT: 2012 Return the position and height of the phys cursor in window W. 2013 Set w->phys_cursor_width to width of phys cursor. 2014*/ 2015 2016void 2017get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp) 2018 struct window *w; 2019 struct glyph_row *row; 2020 struct glyph *glyph; 2021 int *xp, *yp, *heightp; 2022{ 2023 struct frame *f = XFRAME (WINDOW_FRAME (w)); 2024 int x, y, wd, h, h0, y0; 2025 2026 /* Compute the width of the rectangle to draw. If on a stretch 2027 glyph, and `x-stretch-block-cursor' is nil, don't draw a 2028 rectangle as wide as the glyph, but use a canonical character 2029 width instead. */ 2030 wd = glyph->pixel_width - 1; 2031#ifdef HAVE_NTGUI 2032 wd++; /* Why? */ 2033#endif 2034 2035 x = w->phys_cursor.x; 2036 if (x < 0) 2037 { 2038 wd += x; 2039 x = 0; 2040 } 2041 2042 if (glyph->type == STRETCH_GLYPH 2043 && !x_stretch_cursor_p) 2044 wd = min (FRAME_COLUMN_WIDTH (f), wd); 2045 w->phys_cursor_width = wd; 2046 2047 y = w->phys_cursor.y + row->ascent - glyph->ascent; 2048 2049 /* If y is below window bottom, ensure that we still see a cursor. */ 2050 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height); 2051 2052 h = max (h0, glyph->ascent + glyph->descent); 2053 h0 = min (h0, glyph->ascent + glyph->descent); 2054 2055 y0 = WINDOW_HEADER_LINE_HEIGHT (w); 2056 if (y < y0) 2057 { 2058 h = max (h - (y0 - y) + 1, h0); 2059 y = y0 - 1; 2060 } 2061 else 2062 { 2063 y0 = window_text_bottom_y (w) - h0; 2064 if (y > y0) 2065 { 2066 h += y - y0; 2067 y = y0; 2068 } 2069 } 2070 2071 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x); 2072 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y); 2073 *heightp = h; 2074} 2075 2076/* 2077 * Remember which glyph the mouse is over. 2078 */ 2079 2080void 2081remember_mouse_glyph (f, gx, gy, rect) 2082 struct frame *f; 2083 int gx, gy; 2084 NativeRectangle *rect; 2085{ 2086 Lisp_Object window; 2087 struct window *w; 2088 struct glyph_row *r, *gr, *end_row; 2089 enum window_part part; 2090 enum glyph_row_area area; 2091 int x, y, width, height; 2092 2093 /* Try to determine frame pixel position and size of the glyph under 2094 frame pixel coordinates X/Y on frame F. */ 2095 2096 if (!f->glyphs_initialized_p 2097 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0), 2098 NILP (window))) 2099 { 2100 width = FRAME_SMALLEST_CHAR_WIDTH (f); 2101 height = FRAME_SMALLEST_FONT_HEIGHT (f); 2102 goto virtual_glyph; 2103 } 2104 2105 w = XWINDOW (window); 2106 width = WINDOW_FRAME_COLUMN_WIDTH (w); 2107 height = WINDOW_FRAME_LINE_HEIGHT (w); 2108 2109 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 2110 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); 2111 2112 if (w->pseudo_window_p) 2113 { 2114 area = TEXT_AREA; 2115 part = ON_MODE_LINE; /* Don't adjust margin. */ 2116 goto text_glyph; 2117 } 2118 2119 switch (part) 2120 { 2121 case ON_LEFT_MARGIN: 2122 area = LEFT_MARGIN_AREA; 2123 goto text_glyph; 2124 2125 case ON_RIGHT_MARGIN: 2126 area = RIGHT_MARGIN_AREA; 2127 goto text_glyph; 2128 2129 case ON_HEADER_LINE: 2130 case ON_MODE_LINE: 2131 gr = (part == ON_HEADER_LINE 2132 ? MATRIX_HEADER_LINE_ROW (w->current_matrix) 2133 : MATRIX_MODE_LINE_ROW (w->current_matrix)); 2134 gy = gr->y; 2135 area = TEXT_AREA; 2136 goto text_glyph_row_found; 2137 2138 case ON_TEXT: 2139 area = TEXT_AREA; 2140 2141 text_glyph: 2142 gr = 0; gy = 0; 2143 for (; r <= end_row && r->enabled_p; ++r) 2144 if (r->y + r->height > y) 2145 { 2146 gr = r; gy = r->y; 2147 break; 2148 } 2149 2150 text_glyph_row_found: 2151 if (gr && gy <= y) 2152 { 2153 struct glyph *g = gr->glyphs[area]; 2154 struct glyph *end = g + gr->used[area]; 2155 2156 height = gr->height; 2157 for (gx = gr->x; g < end; gx += g->pixel_width, ++g) 2158 if (gx + g->pixel_width > x) 2159 break; 2160 2161 if (g < end) 2162 { 2163 if (g->type == IMAGE_GLYPH) 2164 { 2165 /* Don't remember when mouse is over image, as 2166 image may have hot-spots. */ 2167 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0); 2168 return; 2169 } 2170 width = g->pixel_width; 2171 } 2172 else 2173 { 2174 /* Use nominal char spacing at end of line. */ 2175 x -= gx; 2176 gx += (x / width) * width; 2177 } 2178 2179 if (part != ON_MODE_LINE && part != ON_HEADER_LINE) 2180 gx += window_box_left_offset (w, area); 2181 } 2182 else 2183 { 2184 /* Use nominal line height at end of window. */ 2185 gx = (x / width) * width; 2186 y -= gy; 2187 gy += (y / height) * height; 2188 } 2189 break; 2190 2191 case ON_LEFT_FRINGE: 2192 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 2193 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w) 2194 : window_box_right_offset (w, LEFT_MARGIN_AREA)); 2195 width = WINDOW_LEFT_FRINGE_WIDTH (w); 2196 goto row_glyph; 2197 2198 case ON_RIGHT_FRINGE: 2199 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 2200 ? window_box_right_offset (w, RIGHT_MARGIN_AREA) 2201 : window_box_right_offset (w, TEXT_AREA)); 2202 width = WINDOW_RIGHT_FRINGE_WIDTH (w); 2203 goto row_glyph; 2204 2205 case ON_SCROLL_BAR: 2206 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) 2207 ? 0 2208 : (window_box_right_offset (w, RIGHT_MARGIN_AREA) 2209 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 2210 ? WINDOW_RIGHT_FRINGE_WIDTH (w) 2211 : 0))); 2212 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w); 2213 2214 row_glyph: 2215 gr = 0, gy = 0; 2216 for (; r <= end_row && r->enabled_p; ++r) 2217 if (r->y + r->height > y) 2218 { 2219 gr = r; gy = r->y; 2220 break; 2221 } 2222 2223 if (gr && gy <= y) 2224 height = gr->height; 2225 else 2226 { 2227 /* Use nominal line height at end of window. */ 2228 y -= gy; 2229 gy += (y / height) * height; 2230 } 2231 break; 2232 2233 default: 2234 ; 2235 virtual_glyph: 2236 /* If there is no glyph under the mouse, then we divide the screen 2237 into a grid of the smallest glyph in the frame, and use that 2238 as our "glyph". */ 2239 2240 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to 2241 round down even for negative values. */ 2242 if (gx < 0) 2243 gx -= width - 1; 2244 if (gy < 0) 2245 gy -= height - 1; 2246 2247 gx = (gx / width) * width; 2248 gy = (gy / height) * height; 2249 2250 goto store_rect; 2251 } 2252 2253 gx += WINDOW_LEFT_EDGE_X (w); 2254 gy += WINDOW_TOP_EDGE_Y (w); 2255 2256 store_rect: 2257 STORE_NATIVE_RECT (*rect, gx, gy, width, height); 2258 2259 /* Visible feedback for debugging. */ 2260#if 0 2261#if HAVE_X_WINDOWS 2262 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 2263 f->output_data.x->normal_gc, 2264 gx, gy, width, height); 2265#endif 2266#endif 2267} 2268 2269 2270#endif /* HAVE_WINDOW_SYSTEM */ 2271 2272 2273/*********************************************************************** 2274 Lisp form evaluation 2275 ***********************************************************************/ 2276 2277/* Error handler for safe_eval and safe_call. */ 2278 2279static Lisp_Object 2280safe_eval_handler (arg) 2281 Lisp_Object arg; 2282{ 2283 add_to_log ("Error during redisplay: %s", arg, Qnil); 2284 return Qnil; 2285} 2286 2287 2288/* Evaluate SEXPR and return the result, or nil if something went 2289 wrong. Prevent redisplay during the evaluation. */ 2290 2291Lisp_Object 2292safe_eval (sexpr) 2293 Lisp_Object sexpr; 2294{ 2295 Lisp_Object val; 2296 2297 if (inhibit_eval_during_redisplay) 2298 val = Qnil; 2299 else 2300 { 2301 int count = SPECPDL_INDEX (); 2302 struct gcpro gcpro1; 2303 2304 GCPRO1 (sexpr); 2305 specbind (Qinhibit_redisplay, Qt); 2306 /* Use Qt to ensure debugger does not run, 2307 so there is no possibility of wanting to redisplay. */ 2308 val = internal_condition_case_1 (Feval, sexpr, Qt, 2309 safe_eval_handler); 2310 UNGCPRO; 2311 val = unbind_to (count, val); 2312 } 2313 2314 return val; 2315} 2316 2317 2318/* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1]. 2319 Return the result, or nil if something went wrong. Prevent 2320 redisplay during the evaluation. */ 2321 2322Lisp_Object 2323safe_call (nargs, args) 2324 int nargs; 2325 Lisp_Object *args; 2326{ 2327 Lisp_Object val; 2328 2329 if (inhibit_eval_during_redisplay) 2330 val = Qnil; 2331 else 2332 { 2333 int count = SPECPDL_INDEX (); 2334 struct gcpro gcpro1; 2335 2336 GCPRO1 (args[0]); 2337 gcpro1.nvars = nargs; 2338 specbind (Qinhibit_redisplay, Qt); 2339 /* Use Qt to ensure debugger does not run, 2340 so there is no possibility of wanting to redisplay. */ 2341 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt, 2342 safe_eval_handler); 2343 UNGCPRO; 2344 val = unbind_to (count, val); 2345 } 2346 2347 return val; 2348} 2349 2350 2351/* Call function FN with one argument ARG. 2352 Return the result, or nil if something went wrong. */ 2353 2354Lisp_Object 2355safe_call1 (fn, arg) 2356 Lisp_Object fn, arg; 2357{ 2358 Lisp_Object args[2]; 2359 args[0] = fn; 2360 args[1] = arg; 2361 return safe_call (2, args); 2362} 2363 2364 2365 2366/*********************************************************************** 2367 Debugging 2368 ***********************************************************************/ 2369 2370#if 0 2371 2372/* Define CHECK_IT to perform sanity checks on iterators. 2373 This is for debugging. It is too slow to do unconditionally. */ 2374 2375static void 2376check_it (it) 2377 struct it *it; 2378{ 2379 if (it->method == GET_FROM_STRING) 2380 { 2381 xassert (STRINGP (it->string)); 2382 xassert (IT_STRING_CHARPOS (*it) >= 0); 2383 } 2384 else 2385 { 2386 xassert (IT_STRING_CHARPOS (*it) < 0); 2387 if (it->method == GET_FROM_BUFFER) 2388 { 2389 /* Check that character and byte positions agree. */ 2390 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it))); 2391 } 2392 } 2393 2394 if (it->dpvec) 2395 xassert (it->current.dpvec_index >= 0); 2396 else 2397 xassert (it->current.dpvec_index < 0); 2398} 2399 2400#define CHECK_IT(IT) check_it ((IT)) 2401 2402#else /* not 0 */ 2403 2404#define CHECK_IT(IT) (void) 0 2405 2406#endif /* not 0 */ 2407 2408 2409#if GLYPH_DEBUG 2410 2411/* Check that the window end of window W is what we expect it 2412 to be---the last row in the current matrix displaying text. */ 2413 2414static void 2415check_window_end (w) 2416 struct window *w; 2417{ 2418 if (!MINI_WINDOW_P (w) 2419 && !NILP (w->window_end_valid)) 2420 { 2421 struct glyph_row *row; 2422 xassert ((row = MATRIX_ROW (w->current_matrix, 2423 XFASTINT (w->window_end_vpos)), 2424 !row->enabled_p 2425 || MATRIX_ROW_DISPLAYS_TEXT_P (row) 2426 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0)); 2427 } 2428} 2429 2430#define CHECK_WINDOW_END(W) check_window_end ((W)) 2431 2432#else /* not GLYPH_DEBUG */ 2433 2434#define CHECK_WINDOW_END(W) (void) 0 2435 2436#endif /* not GLYPH_DEBUG */ 2437 2438 2439 2440/*********************************************************************** 2441 Iterator initialization 2442 ***********************************************************************/ 2443 2444/* Initialize IT for displaying current_buffer in window W, starting 2445 at character position CHARPOS. CHARPOS < 0 means that no buffer 2446 position is specified which is useful when the iterator is assigned 2447 a position later. BYTEPOS is the byte position corresponding to 2448 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS. 2449 2450 If ROW is not null, calls to produce_glyphs with IT as parameter 2451 will produce glyphs in that row. 2452 2453 BASE_FACE_ID is the id of a base face to use. It must be one of 2454 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID, 2455 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying 2456 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar. 2457 2458 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID, 2459 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator 2460 will be initialized to use the corresponding mode line glyph row of 2461 the desired matrix of W. */ 2462 2463void 2464init_iterator (it, w, charpos, bytepos, row, base_face_id) 2465 struct it *it; 2466 struct window *w; 2467 int charpos, bytepos; 2468 struct glyph_row *row; 2469 enum face_id base_face_id; 2470{ 2471 int highlight_region_p; 2472 2473 /* Some precondition checks. */ 2474 xassert (w != NULL && it != NULL); 2475 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer) 2476 && charpos <= ZV)); 2477 2478 /* If face attributes have been changed since the last redisplay, 2479 free realized faces now because they depend on face definitions 2480 that might have changed. Don't free faces while there might be 2481 desired matrices pending which reference these faces. */ 2482 if (face_change_count && !inhibit_free_realized_faces) 2483 { 2484 face_change_count = 0; 2485 free_all_realized_faces (Qnil); 2486 } 2487 2488 /* Use one of the mode line rows of W's desired matrix if 2489 appropriate. */ 2490 if (row == NULL) 2491 { 2492 if (base_face_id == MODE_LINE_FACE_ID 2493 || base_face_id == MODE_LINE_INACTIVE_FACE_ID) 2494 row = MATRIX_MODE_LINE_ROW (w->desired_matrix); 2495 else if (base_face_id == HEADER_LINE_FACE_ID) 2496 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix); 2497 } 2498 2499 /* Clear IT. */ 2500 bzero (it, sizeof *it); 2501 it->current.overlay_string_index = -1; 2502 it->current.dpvec_index = -1; 2503 it->base_face_id = base_face_id; 2504 it->string = Qnil; 2505 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; 2506 2507 /* The window in which we iterate over current_buffer: */ 2508 XSETWINDOW (it->window, w); 2509 it->w = w; 2510 it->f = XFRAME (w->frame); 2511 2512 /* Extra space between lines (on window systems only). */ 2513 if (base_face_id == DEFAULT_FACE_ID 2514 && FRAME_WINDOW_P (it->f)) 2515 { 2516 if (NATNUMP (current_buffer->extra_line_spacing)) 2517 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing); 2518 else if (FLOATP (current_buffer->extra_line_spacing)) 2519 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing) 2520 * FRAME_LINE_HEIGHT (it->f)); 2521 else if (it->f->extra_line_spacing > 0) 2522 it->extra_line_spacing = it->f->extra_line_spacing; 2523 it->max_extra_line_spacing = 0; 2524 } 2525 2526 /* If realized faces have been removed, e.g. because of face 2527 attribute changes of named faces, recompute them. When running 2528 in batch mode, the face cache of Vterminal_frame is null. If 2529 we happen to get called, make a dummy face cache. */ 2530 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL) 2531 init_frame_faces (it->f); 2532 if (FRAME_FACE_CACHE (it->f)->used == 0) 2533 recompute_basic_faces (it->f); 2534 2535 /* Current value of the `slice', `space-width', and 'height' properties. */ 2536 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil; 2537 it->space_width = Qnil; 2538 it->font_height = Qnil; 2539 it->override_ascent = -1; 2540 2541 /* Are control characters displayed as `^C'? */ 2542 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow); 2543 2544 /* -1 means everything between a CR and the following line end 2545 is invisible. >0 means lines indented more than this value are 2546 invisible. */ 2547 it->selective = (INTEGERP (current_buffer->selective_display) 2548 ? XFASTINT (current_buffer->selective_display) 2549 : (!NILP (current_buffer->selective_display) 2550 ? -1 : 0)); 2551 it->selective_display_ellipsis_p 2552 = !NILP (current_buffer->selective_display_ellipses); 2553 2554 /* Display table to use. */ 2555 it->dp = window_display_table (w); 2556 2557 /* Are multibyte characters enabled in current_buffer? */ 2558 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); 2559 2560 /* Non-zero if we should highlight the region. */ 2561 highlight_region_p 2562 = (!NILP (Vtransient_mark_mode) 2563 && !NILP (current_buffer->mark_active) 2564 && XMARKER (current_buffer->mark)->buffer != 0); 2565 2566 /* Set IT->region_beg_charpos and IT->region_end_charpos to the 2567 start and end of a visible region in window IT->w. Set both to 2568 -1 to indicate no region. */ 2569 if (highlight_region_p 2570 /* Maybe highlight only in selected window. */ 2571 && (/* Either show region everywhere. */ 2572 highlight_nonselected_windows 2573 /* Or show region in the selected window. */ 2574 || w == XWINDOW (selected_window) 2575 /* Or show the region if we are in the mini-buffer and W is 2576 the window the mini-buffer refers to. */ 2577 || (MINI_WINDOW_P (XWINDOW (selected_window)) 2578 && WINDOWP (minibuf_selected_window) 2579 && w == XWINDOW (minibuf_selected_window)))) 2580 { 2581 int charpos = marker_position (current_buffer->mark); 2582 it->region_beg_charpos = min (PT, charpos); 2583 it->region_end_charpos = max (PT, charpos); 2584 } 2585 else 2586 it->region_beg_charpos = it->region_end_charpos = -1; 2587 2588 /* Get the position at which the redisplay_end_trigger hook should 2589 be run, if it is to be run at all. */ 2590 if (MARKERP (w->redisplay_end_trigger) 2591 && XMARKER (w->redisplay_end_trigger)->buffer != 0) 2592 it->redisplay_end_trigger_charpos 2593 = marker_position (w->redisplay_end_trigger); 2594 else if (INTEGERP (w->redisplay_end_trigger)) 2595 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger); 2596 2597 /* Correct bogus values of tab_width. */ 2598 it->tab_width = XINT (current_buffer->tab_width); 2599 if (it->tab_width <= 0 || it->tab_width > 1000) 2600 it->tab_width = 8; 2601 2602 /* Are lines in the display truncated? */ 2603 it->truncate_lines_p 2604 = (base_face_id != DEFAULT_FACE_ID 2605 || XINT (it->w->hscroll) 2606 || (truncate_partial_width_windows 2607 && !WINDOW_FULL_WIDTH_P (it->w)) 2608 || !NILP (current_buffer->truncate_lines)); 2609 2610 /* Get dimensions of truncation and continuation glyphs. These are 2611 displayed as fringe bitmaps under X, so we don't need them for such 2612 frames. */ 2613 if (!FRAME_WINDOW_P (it->f)) 2614 { 2615 if (it->truncate_lines_p) 2616 { 2617 /* We will need the truncation glyph. */ 2618 xassert (it->glyph_row == NULL); 2619 produce_special_glyphs (it, IT_TRUNCATION); 2620 it->truncation_pixel_width = it->pixel_width; 2621 } 2622 else 2623 { 2624 /* We will need the continuation glyph. */ 2625 xassert (it->glyph_row == NULL); 2626 produce_special_glyphs (it, IT_CONTINUATION); 2627 it->continuation_pixel_width = it->pixel_width; 2628 } 2629 2630 /* Reset these values to zero because the produce_special_glyphs 2631 above has changed them. */ 2632 it->pixel_width = it->ascent = it->descent = 0; 2633 it->phys_ascent = it->phys_descent = 0; 2634 } 2635 2636 /* Set this after getting the dimensions of truncation and 2637 continuation glyphs, so that we don't produce glyphs when calling 2638 produce_special_glyphs, above. */ 2639 it->glyph_row = row; 2640 it->area = TEXT_AREA; 2641 2642 /* Get the dimensions of the display area. The display area 2643 consists of the visible window area plus a horizontally scrolled 2644 part to the left of the window. All x-values are relative to the 2645 start of this total display area. */ 2646 if (base_face_id != DEFAULT_FACE_ID) 2647 { 2648 /* Mode lines, menu bar in terminal frames. */ 2649 it->first_visible_x = 0; 2650 it->last_visible_x = WINDOW_TOTAL_WIDTH (w); 2651 } 2652 else 2653 { 2654 it->first_visible_x 2655 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f); 2656 it->last_visible_x = (it->first_visible_x 2657 + window_box_width (w, TEXT_AREA)); 2658 2659 /* If we truncate lines, leave room for the truncator glyph(s) at 2660 the right margin. Otherwise, leave room for the continuation 2661 glyph(s). Truncation and continuation glyphs are not inserted 2662 for window-based redisplay. */ 2663 if (!FRAME_WINDOW_P (it->f)) 2664 { 2665 if (it->truncate_lines_p) 2666 it->last_visible_x -= it->truncation_pixel_width; 2667 else 2668 it->last_visible_x -= it->continuation_pixel_width; 2669 } 2670 2671 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w); 2672 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll; 2673 } 2674 2675 /* Leave room for a border glyph. */ 2676 if (!FRAME_WINDOW_P (it->f) 2677 && !WINDOW_RIGHTMOST_P (it->w)) 2678 it->last_visible_x -= 1; 2679 2680 it->last_visible_y = window_text_bottom_y (w); 2681 2682 /* For mode lines and alike, arrange for the first glyph having a 2683 left box line if the face specifies a box. */ 2684 if (base_face_id != DEFAULT_FACE_ID) 2685 { 2686 struct face *face; 2687 2688 it->face_id = base_face_id; 2689 2690 /* If we have a boxed mode line, make the first character appear 2691 with a left box line. */ 2692 face = FACE_FROM_ID (it->f, base_face_id); 2693 if (face->box != FACE_NO_BOX) 2694 it->start_of_box_run_p = 1; 2695 } 2696 2697 /* If a buffer position was specified, set the iterator there, 2698 getting overlays and face properties from that position. */ 2699 if (charpos >= BUF_BEG (current_buffer)) 2700 { 2701 it->end_charpos = ZV; 2702 it->face_id = -1; 2703 IT_CHARPOS (*it) = charpos; 2704 2705 /* Compute byte position if not specified. */ 2706 if (bytepos < charpos) 2707 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos); 2708 else 2709 IT_BYTEPOS (*it) = bytepos; 2710 2711 it->start = it->current; 2712 2713 /* Compute faces etc. */ 2714 reseat (it, it->current.pos, 1); 2715 } 2716 2717 CHECK_IT (it); 2718} 2719 2720 2721/* Initialize IT for the display of window W with window start POS. */ 2722 2723void 2724start_display (it, w, pos) 2725 struct it *it; 2726 struct window *w; 2727 struct text_pos pos; 2728{ 2729 struct glyph_row *row; 2730 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; 2731 2732 row = w->desired_matrix->rows + first_vpos; 2733 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID); 2734 it->first_vpos = first_vpos; 2735 2736 /* Don't reseat to previous visible line start if current start 2737 position is in a string or image. */ 2738 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p) 2739 { 2740 int start_at_line_beg_p; 2741 int first_y = it->current_y; 2742 2743 /* If window start is not at a line start, skip forward to POS to 2744 get the correct continuation lines width. */ 2745 start_at_line_beg_p = (CHARPOS (pos) == BEGV 2746 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n'); 2747 if (!start_at_line_beg_p) 2748 { 2749 int new_x; 2750 2751 reseat_at_previous_visible_line_start (it); 2752 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS); 2753 2754 new_x = it->current_x + it->pixel_width; 2755 2756 /* If lines are continued, this line may end in the middle 2757 of a multi-glyph character (e.g. a control character 2758 displayed as \003, or in the middle of an overlay 2759 string). In this case move_it_to above will not have 2760 taken us to the start of the continuation line but to the 2761 end of the continued line. */ 2762 if (it->current_x > 0 2763 && !it->truncate_lines_p /* Lines are continued. */ 2764 && (/* And glyph doesn't fit on the line. */ 2765 new_x > it->last_visible_x 2766 /* Or it fits exactly and we're on a window 2767 system frame. */ 2768 || (new_x == it->last_visible_x 2769 && FRAME_WINDOW_P (it->f)))) 2770 { 2771 if (it->current.dpvec_index >= 0 2772 || it->current.overlay_string_index >= 0) 2773 { 2774 set_iterator_to_next (it, 1); 2775 move_it_in_display_line_to (it, -1, -1, 0); 2776 } 2777 2778 it->continuation_lines_width += it->current_x; 2779 } 2780 2781 /* We're starting a new display line, not affected by the 2782 height of the continued line, so clear the appropriate 2783 fields in the iterator structure. */ 2784 it->max_ascent = it->max_descent = 0; 2785 it->max_phys_ascent = it->max_phys_descent = 0; 2786 2787 it->current_y = first_y; 2788 it->vpos = 0; 2789 it->current_x = it->hpos = 0; 2790 } 2791 } 2792 2793#if 0 /* Don't assert the following because start_display is sometimes 2794 called intentionally with a window start that is not at a 2795 line start. Please leave this code in as a comment. */ 2796 2797 /* Window start should be on a line start, now. */ 2798 xassert (it->continuation_lines_width 2799 || IT_CHARPOS (it) == BEGV 2800 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n'); 2801#endif /* 0 */ 2802} 2803 2804 2805/* Return 1 if POS is a position in ellipses displayed for invisible 2806 text. W is the window we display, for text property lookup. */ 2807 2808static int 2809in_ellipses_for_invisible_text_p (pos, w) 2810 struct display_pos *pos; 2811 struct window *w; 2812{ 2813 Lisp_Object prop, window; 2814 int ellipses_p = 0; 2815 int charpos = CHARPOS (pos->pos); 2816 2817 /* If POS specifies a position in a display vector, this might 2818 be for an ellipsis displayed for invisible text. We won't 2819 get the iterator set up for delivering that ellipsis unless 2820 we make sure that it gets aware of the invisible text. */ 2821 if (pos->dpvec_index >= 0 2822 && pos->overlay_string_index < 0 2823 && CHARPOS (pos->string_pos) < 0 2824 && charpos > BEGV 2825 && (XSETWINDOW (window, w), 2826 prop = Fget_char_property (make_number (charpos), 2827 Qinvisible, window), 2828 !TEXT_PROP_MEANS_INVISIBLE (prop))) 2829 { 2830 prop = Fget_char_property (make_number (charpos - 1), Qinvisible, 2831 window); 2832 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop); 2833 } 2834 2835 return ellipses_p; 2836} 2837 2838 2839/* Initialize IT for stepping through current_buffer in window W, 2840 starting at position POS that includes overlay string and display 2841 vector/ control character translation position information. Value 2842 is zero if there are overlay strings with newlines at POS. */ 2843 2844static int 2845init_from_display_pos (it, w, pos) 2846 struct it *it; 2847 struct window *w; 2848 struct display_pos *pos; 2849{ 2850 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos); 2851 int i, overlay_strings_with_newlines = 0; 2852 2853 /* If POS specifies a position in a display vector, this might 2854 be for an ellipsis displayed for invisible text. We won't 2855 get the iterator set up for delivering that ellipsis unless 2856 we make sure that it gets aware of the invisible text. */ 2857 if (in_ellipses_for_invisible_text_p (pos, w)) 2858 { 2859 --charpos; 2860 bytepos = 0; 2861 } 2862 2863 /* Keep in mind: the call to reseat in init_iterator skips invisible 2864 text, so we might end up at a position different from POS. This 2865 is only a problem when POS is a row start after a newline and an 2866 overlay starts there with an after-string, and the overlay has an 2867 invisible property. Since we don't skip invisible text in 2868 display_line and elsewhere immediately after consuming the 2869 newline before the row start, such a POS will not be in a string, 2870 but the call to init_iterator below will move us to the 2871 after-string. */ 2872 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID); 2873 2874 /* This only scans the current chunk -- it should scan all chunks. 2875 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1 2876 to 16 in 22.1 to make this a lesser problem. */ 2877 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i) 2878 { 2879 const char *s = SDATA (it->overlay_strings[i]); 2880 const char *e = s + SBYTES (it->overlay_strings[i]); 2881 2882 while (s < e && *s != '\n') 2883 ++s; 2884 2885 if (s < e) 2886 { 2887 overlay_strings_with_newlines = 1; 2888 break; 2889 } 2890 } 2891 2892 /* If position is within an overlay string, set up IT to the right 2893 overlay string. */ 2894 if (pos->overlay_string_index >= 0) 2895 { 2896 int relative_index; 2897 2898 /* If the first overlay string happens to have a `display' 2899 property for an image, the iterator will be set up for that 2900 image, and we have to undo that setup first before we can 2901 correct the overlay string index. */ 2902 if (it->method == GET_FROM_IMAGE) 2903 pop_it (it); 2904 2905 /* We already have the first chunk of overlay strings in 2906 IT->overlay_strings. Load more until the one for 2907 pos->overlay_string_index is in IT->overlay_strings. */ 2908 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE) 2909 { 2910 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE; 2911 it->current.overlay_string_index = 0; 2912 while (n--) 2913 { 2914 load_overlay_strings (it, 0); 2915 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE; 2916 } 2917 } 2918 2919 it->current.overlay_string_index = pos->overlay_string_index; 2920 relative_index = (it->current.overlay_string_index 2921 % OVERLAY_STRING_CHUNK_SIZE); 2922 it->string = it->overlay_strings[relative_index]; 2923 xassert (STRINGP (it->string)); 2924 it->current.string_pos = pos->string_pos; 2925 it->method = GET_FROM_STRING; 2926 } 2927 2928#if 0 /* This is bogus because POS not having an overlay string 2929 position does not mean it's after the string. Example: A 2930 line starting with a before-string and initialization of IT 2931 to the previous row's end position. */ 2932 else if (it->current.overlay_string_index >= 0) 2933 { 2934 /* If POS says we're already after an overlay string ending at 2935 POS, make sure to pop the iterator because it will be in 2936 front of that overlay string. When POS is ZV, we've thereby 2937 also ``processed'' overlay strings at ZV. */ 2938 while (it->sp) 2939 pop_it (it); 2940 xassert (it->current.overlay_string_index == -1); 2941 xassert (it->method == GET_FROM_BUFFER); 2942 if (CHARPOS (pos->pos) == ZV) 2943 it->overlay_strings_at_end_processed_p = 1; 2944 } 2945#endif /* 0 */ 2946 2947 if (CHARPOS (pos->string_pos) >= 0) 2948 { 2949 /* Recorded position is not in an overlay string, but in another 2950 string. This can only be a string from a `display' property. 2951 IT should already be filled with that string. */ 2952 it->current.string_pos = pos->string_pos; 2953 xassert (STRINGP (it->string)); 2954 } 2955 2956 /* Restore position in display vector translations, control 2957 character translations or ellipses. */ 2958 if (pos->dpvec_index >= 0) 2959 { 2960 if (it->dpvec == NULL) 2961 get_next_display_element (it); 2962 xassert (it->dpvec && it->current.dpvec_index == 0); 2963 it->current.dpvec_index = pos->dpvec_index; 2964 } 2965 2966 CHECK_IT (it); 2967 return !overlay_strings_with_newlines; 2968} 2969 2970 2971/* Initialize IT for stepping through current_buffer in window W 2972 starting at ROW->start. */ 2973 2974static void 2975init_to_row_start (it, w, row) 2976 struct it *it; 2977 struct window *w; 2978 struct glyph_row *row; 2979{ 2980 init_from_display_pos (it, w, &row->start); 2981 it->start = row->start; 2982 it->continuation_lines_width = row->continuation_lines_width; 2983 CHECK_IT (it); 2984} 2985 2986 2987/* Initialize IT for stepping through current_buffer in window W 2988 starting in the line following ROW, i.e. starting at ROW->end. 2989 Value is zero if there are overlay strings with newlines at ROW's 2990 end position. */ 2991 2992static int 2993init_to_row_end (it, w, row) 2994 struct it *it; 2995 struct window *w; 2996 struct glyph_row *row; 2997{ 2998 int success = 0; 2999 3000 if (init_from_display_pos (it, w, &row->end)) 3001 { 3002 if (row->continued_p) 3003 it->continuation_lines_width 3004 = row->continuation_lines_width + row->pixel_width; 3005 CHECK_IT (it); 3006 success = 1; 3007 } 3008 3009 return success; 3010} 3011 3012 3013 3014 3015/*********************************************************************** 3016 Text properties 3017 ***********************************************************************/ 3018 3019/* Called when IT reaches IT->stop_charpos. Handle text property and 3020 overlay changes. Set IT->stop_charpos to the next position where 3021 to stop. */ 3022 3023static void 3024handle_stop (it) 3025 struct it *it; 3026{ 3027 enum prop_handled handled; 3028 int handle_overlay_change_p; 3029 struct props *p; 3030 3031 it->dpvec = NULL; 3032 it->current.dpvec_index = -1; 3033 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p; 3034 it->ignore_overlay_strings_at_pos_p = 0; 3035 3036 /* Use face of preceding text for ellipsis (if invisible) */ 3037 if (it->selective_display_ellipsis_p) 3038 it->saved_face_id = it->face_id; 3039 3040 do 3041 { 3042 handled = HANDLED_NORMALLY; 3043 3044 /* Call text property handlers. */ 3045 for (p = it_props; p->handler; ++p) 3046 { 3047 handled = p->handler (it); 3048 3049 if (handled == HANDLED_RECOMPUTE_PROPS) 3050 break; 3051 else if (handled == HANDLED_RETURN) 3052 { 3053 /* We still want to show before and after strings from 3054 overlays even if the actual buffer text is replaced. */ 3055 if (!handle_overlay_change_p || it->sp > 1) 3056 return; 3057 if (!get_overlay_strings_1 (it, 0, 0)) 3058 return; 3059 it->ignore_overlay_strings_at_pos_p = 1; 3060 it->string_from_display_prop_p = 0; 3061 handle_overlay_change_p = 0; 3062 handled = HANDLED_RECOMPUTE_PROPS; 3063 break; 3064 } 3065 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED) 3066 handle_overlay_change_p = 0; 3067 } 3068 3069 if (handled != HANDLED_RECOMPUTE_PROPS) 3070 { 3071 /* Don't check for overlay strings below when set to deliver 3072 characters from a display vector. */ 3073 if (it->method == GET_FROM_DISPLAY_VECTOR) 3074 handle_overlay_change_p = 0; 3075 3076 /* Handle overlay changes. */ 3077 if (handle_overlay_change_p) 3078 handled = handle_overlay_change (it); 3079 3080 /* Determine where to stop next. */ 3081 if (handled == HANDLED_NORMALLY) 3082 compute_stop_pos (it); 3083 } 3084 } 3085 while (handled == HANDLED_RECOMPUTE_PROPS); 3086} 3087 3088 3089/* Compute IT->stop_charpos from text property and overlay change 3090 information for IT's current position. */ 3091 3092static void 3093compute_stop_pos (it) 3094 struct it *it; 3095{ 3096 register INTERVAL iv, next_iv; 3097 Lisp_Object object, limit, position; 3098 3099 /* If nowhere else, stop at the end. */ 3100 it->stop_charpos = it->end_charpos; 3101 3102 if (STRINGP (it->string)) 3103 { 3104 /* Strings are usually short, so don't limit the search for 3105 properties. */ 3106 object = it->string; 3107 limit = Qnil; 3108 position = make_number (IT_STRING_CHARPOS (*it)); 3109 } 3110 else 3111 { 3112 int charpos; 3113 3114 /* If next overlay change is in front of the current stop pos 3115 (which is IT->end_charpos), stop there. Note: value of 3116 next_overlay_change is point-max if no overlay change 3117 follows. */ 3118 charpos = next_overlay_change (IT_CHARPOS (*it)); 3119 if (charpos < it->stop_charpos) 3120 it->stop_charpos = charpos; 3121 3122 /* If showing the region, we have to stop at the region 3123 start or end because the face might change there. */ 3124 if (it->region_beg_charpos > 0) 3125 { 3126 if (IT_CHARPOS (*it) < it->region_beg_charpos) 3127 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos); 3128 else if (IT_CHARPOS (*it) < it->region_end_charpos) 3129 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos); 3130 } 3131 3132 /* Set up variables for computing the stop position from text 3133 property changes. */ 3134 XSETBUFFER (object, current_buffer); 3135 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT); 3136 position = make_number (IT_CHARPOS (*it)); 3137 3138 } 3139 3140 /* Get the interval containing IT's position. Value is a null 3141 interval if there isn't such an interval. */ 3142 iv = validate_interval_range (object, &position, &position, 0); 3143 if (!NULL_INTERVAL_P (iv)) 3144 { 3145 Lisp_Object values_here[LAST_PROP_IDX]; 3146 struct props *p; 3147 3148 /* Get properties here. */ 3149 for (p = it_props; p->handler; ++p) 3150 values_here[p->idx] = textget (iv->plist, *p->name); 3151 3152 /* Look for an interval following iv that has different 3153 properties. */ 3154 for (next_iv = next_interval (iv); 3155 (!NULL_INTERVAL_P (next_iv) 3156 && (NILP (limit) 3157 || XFASTINT (limit) > next_iv->position)); 3158 next_iv = next_interval (next_iv)) 3159 { 3160 for (p = it_props; p->handler; ++p) 3161 { 3162 Lisp_Object new_value; 3163 3164 new_value = textget (next_iv->plist, *p->name); 3165 if (!EQ (values_here[p->idx], new_value)) 3166 break; 3167 } 3168 3169 if (p->handler) 3170 break; 3171 } 3172 3173 if (!NULL_INTERVAL_P (next_iv)) 3174 { 3175 if (INTEGERP (limit) 3176 && next_iv->position >= XFASTINT (limit)) 3177 /* No text property change up to limit. */ 3178 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos); 3179 else 3180 /* Text properties change in next_iv. */ 3181 it->stop_charpos = min (it->stop_charpos, next_iv->position); 3182 } 3183 } 3184 3185 xassert (STRINGP (it->string) 3186 || (it->stop_charpos >= BEGV 3187 && it->stop_charpos >= IT_CHARPOS (*it))); 3188} 3189 3190 3191/* Return the position of the next overlay change after POS in 3192 current_buffer. Value is point-max if no overlay change 3193 follows. This is like `next-overlay-change' but doesn't use 3194 xmalloc. */ 3195 3196static int 3197next_overlay_change (pos) 3198 int pos; 3199{ 3200 int noverlays; 3201 int endpos; 3202 Lisp_Object *overlays; 3203 int i; 3204 3205 /* Get all overlays at the given position. */ 3206 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1); 3207 3208 /* If any of these overlays ends before endpos, 3209 use its ending point instead. */ 3210 for (i = 0; i < noverlays; ++i) 3211 { 3212 Lisp_Object oend; 3213 int oendpos; 3214 3215 oend = OVERLAY_END (overlays[i]); 3216 oendpos = OVERLAY_POSITION (oend); 3217 endpos = min (endpos, oendpos); 3218 } 3219 3220 return endpos; 3221} 3222 3223 3224 3225/*********************************************************************** 3226 Fontification 3227 ***********************************************************************/ 3228 3229/* Handle changes in the `fontified' property of the current buffer by 3230 calling hook functions from Qfontification_functions to fontify 3231 regions of text. */ 3232 3233static enum prop_handled 3234handle_fontified_prop (it) 3235 struct it *it; 3236{ 3237 Lisp_Object prop, pos; 3238 enum prop_handled handled = HANDLED_NORMALLY; 3239 3240 if (!NILP (Vmemory_full)) 3241 return handled; 3242 3243 /* Get the value of the `fontified' property at IT's current buffer 3244 position. (The `fontified' property doesn't have a special 3245 meaning in strings.) If the value is nil, call functions from 3246 Qfontification_functions. */ 3247 if (!STRINGP (it->string) 3248 && it->s == NULL 3249 && !NILP (Vfontification_functions) 3250 && !NILP (Vrun_hooks) 3251 && (pos = make_number (IT_CHARPOS (*it)), 3252 prop = Fget_char_property (pos, Qfontified, Qnil), 3253 /* Ignore the special cased nil value always present at EOB since 3254 no amount of fontifying will be able to change it. */ 3255 NILP (prop) && IT_CHARPOS (*it) < Z)) 3256 { 3257 int count = SPECPDL_INDEX (); 3258 Lisp_Object val; 3259 3260 val = Vfontification_functions; 3261 specbind (Qfontification_functions, Qnil); 3262 3263 if (!CONSP (val) || EQ (XCAR (val), Qlambda)) 3264 safe_call1 (val, pos); 3265 else 3266 { 3267 Lisp_Object globals, fn; 3268 struct gcpro gcpro1, gcpro2; 3269 3270 globals = Qnil; 3271 GCPRO2 (val, globals); 3272 3273 for (; CONSP (val); val = XCDR (val)) 3274 { 3275 fn = XCAR (val); 3276 3277 if (EQ (fn, Qt)) 3278 { 3279 /* A value of t indicates this hook has a local 3280 binding; it means to run the global binding too. 3281 In a global value, t should not occur. If it 3282 does, we must ignore it to avoid an endless 3283 loop. */ 3284 for (globals = Fdefault_value (Qfontification_functions); 3285 CONSP (globals); 3286 globals = XCDR (globals)) 3287 { 3288 fn = XCAR (globals); 3289 if (!EQ (fn, Qt)) 3290 safe_call1 (fn, pos); 3291 } 3292 } 3293 else 3294 safe_call1 (fn, pos); 3295 } 3296 3297 UNGCPRO; 3298 } 3299 3300 unbind_to (count, Qnil); 3301 3302 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified 3303 something. This avoids an endless loop if they failed to 3304 fontify the text for which reason ever. */ 3305 if (!NILP (Fget_char_property (pos, Qfontified, Qnil))) 3306 handled = HANDLED_RECOMPUTE_PROPS; 3307 } 3308 3309 return handled; 3310} 3311 3312 3313 3314/*********************************************************************** 3315 Faces 3316 ***********************************************************************/ 3317 3318/* Set up iterator IT from face properties at its current position. 3319 Called from handle_stop. */ 3320 3321static enum prop_handled 3322handle_face_prop (it) 3323 struct it *it; 3324{ 3325 int new_face_id, next_stop; 3326 3327 if (!STRINGP (it->string)) 3328 { 3329 new_face_id 3330 = face_at_buffer_position (it->w, 3331 IT_CHARPOS (*it), 3332 it->region_beg_charpos, 3333 it->region_end_charpos, 3334 &next_stop, 3335 (IT_CHARPOS (*it) 3336 + TEXT_PROP_DISTANCE_LIMIT), 3337 0); 3338 3339 /* Is this a start of a run of characters with box face? 3340 Caveat: this can be called for a freshly initialized 3341 iterator; face_id is -1 in this case. We know that the new 3342 face will not change until limit, i.e. if the new face has a 3343 box, all characters up to limit will have one. But, as 3344 usual, we don't know whether limit is really the end. */ 3345 if (new_face_id != it->face_id) 3346 { 3347 struct face *new_face = FACE_FROM_ID (it->f, new_face_id); 3348 3349 /* If new face has a box but old face has not, this is 3350 the start of a run of characters with box, i.e. it has 3351 a shadow on the left side. The value of face_id of the 3352 iterator will be -1 if this is the initial call that gets 3353 the face. In this case, we have to look in front of IT's 3354 position and see whether there is a face != new_face_id. */ 3355 it->start_of_box_run_p 3356 = (new_face->box != FACE_NO_BOX 3357 && (it->face_id >= 0 3358 || IT_CHARPOS (*it) == BEG 3359 || new_face_id != face_before_it_pos (it))); 3360 it->face_box_p = new_face->box != FACE_NO_BOX; 3361 } 3362 } 3363 else 3364 { 3365 int base_face_id, bufpos; 3366 3367 if (it->current.overlay_string_index >= 0) 3368 bufpos = IT_CHARPOS (*it); 3369 else 3370 bufpos = 0; 3371 3372 /* For strings from a buffer, i.e. overlay strings or strings 3373 from a `display' property, use the face at IT's current 3374 buffer position as the base face to merge with, so that 3375 overlay strings appear in the same face as surrounding 3376 text, unless they specify their own faces. */ 3377 base_face_id = underlying_face_id (it); 3378 3379 new_face_id = face_at_string_position (it->w, 3380 it->string, 3381 IT_STRING_CHARPOS (*it), 3382 bufpos, 3383 it->region_beg_charpos, 3384 it->region_end_charpos, 3385 &next_stop, 3386 base_face_id, 0); 3387 3388#if 0 /* This shouldn't be neccessary. Let's check it. */ 3389 /* If IT is used to display a mode line we would really like to 3390 use the mode line face instead of the frame's default face. */ 3391 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix) 3392 && new_face_id == DEFAULT_FACE_ID) 3393 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w); 3394#endif 3395 3396 /* Is this a start of a run of characters with box? Caveat: 3397 this can be called for a freshly allocated iterator; face_id 3398 is -1 is this case. We know that the new face will not 3399 change until the next check pos, i.e. if the new face has a 3400 box, all characters up to that position will have a 3401 box. But, as usual, we don't know whether that position 3402 is really the end. */ 3403 if (new_face_id != it->face_id) 3404 { 3405 struct face *new_face = FACE_FROM_ID (it->f, new_face_id); 3406 struct face *old_face = FACE_FROM_ID (it->f, it->face_id); 3407 3408 /* If new face has a box but old face hasn't, this is the 3409 start of a run of characters with box, i.e. it has a 3410 shadow on the left side. */ 3411 it->start_of_box_run_p 3412 = new_face->box && (old_face == NULL || !old_face->box); 3413 it->face_box_p = new_face->box != FACE_NO_BOX; 3414 } 3415 } 3416 3417 it->face_id = new_face_id; 3418 return HANDLED_NORMALLY; 3419} 3420 3421 3422/* Return the ID of the face ``underlying'' IT's current position, 3423 which is in a string. If the iterator is associated with a 3424 buffer, return the face at IT's current buffer position. 3425 Otherwise, use the iterator's base_face_id. */ 3426 3427static int 3428underlying_face_id (it) 3429 struct it *it; 3430{ 3431 int face_id = it->base_face_id, i; 3432 3433 xassert (STRINGP (it->string)); 3434 3435 for (i = it->sp - 1; i >= 0; --i) 3436 if (NILP (it->stack[i].string)) 3437 face_id = it->stack[i].face_id; 3438 3439 return face_id; 3440} 3441 3442 3443/* Compute the face one character before or after the current position 3444 of IT. BEFORE_P non-zero means get the face in front of IT's 3445 position. Value is the id of the face. */ 3446 3447static int 3448face_before_or_after_it_pos (it, before_p) 3449 struct it *it; 3450 int before_p; 3451{ 3452 int face_id, limit; 3453 int next_check_charpos; 3454 struct text_pos pos; 3455 3456 xassert (it->s == NULL); 3457 3458 if (STRINGP (it->string)) 3459 { 3460 int bufpos, base_face_id; 3461 3462 /* No face change past the end of the string (for the case 3463 we are padding with spaces). No face change before the 3464 string start. */ 3465 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string) 3466 || (IT_STRING_CHARPOS (*it) == 0 && before_p)) 3467 return it->face_id; 3468 3469 /* Set pos to the position before or after IT's current position. */ 3470 if (before_p) 3471 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); 3472 else 3473 /* For composition, we must check the character after the 3474 composition. */ 3475 pos = (it->what == IT_COMPOSITION 3476 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string) 3477 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); 3478 3479 if (it->current.overlay_string_index >= 0) 3480 bufpos = IT_CHARPOS (*it); 3481 else 3482 bufpos = 0; 3483 3484 base_face_id = underlying_face_id (it); 3485 3486 /* Get the face for ASCII, or unibyte. */ 3487 face_id = face_at_string_position (it->w, 3488 it->string, 3489 CHARPOS (pos), 3490 bufpos, 3491 it->region_beg_charpos, 3492 it->region_end_charpos, 3493 &next_check_charpos, 3494 base_face_id, 0); 3495 3496 /* Correct the face for charsets different from ASCII. Do it 3497 for the multibyte case only. The face returned above is 3498 suitable for unibyte text if IT->string is unibyte. */ 3499 if (STRING_MULTIBYTE (it->string)) 3500 { 3501 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos); 3502 int rest = SBYTES (it->string) - BYTEPOS (pos); 3503 int c, len; 3504 struct face *face = FACE_FROM_ID (it->f, face_id); 3505 3506 c = string_char_and_length (p, rest, &len); 3507 face_id = FACE_FOR_CHAR (it->f, face, c); 3508 } 3509 } 3510 else 3511 { 3512 if ((IT_CHARPOS (*it) >= ZV && !before_p) 3513 || (IT_CHARPOS (*it) <= BEGV && before_p)) 3514 return it->face_id; 3515 3516 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT; 3517 pos = it->current.pos; 3518 3519 if (before_p) 3520 DEC_TEXT_POS (pos, it->multibyte_p); 3521 else 3522 { 3523 if (it->what == IT_COMPOSITION) 3524 /* For composition, we must check the position after the 3525 composition. */ 3526 pos.charpos += it->cmp_len, pos.bytepos += it->len; 3527 else 3528 INC_TEXT_POS (pos, it->multibyte_p); 3529 } 3530 3531 /* Determine face for CHARSET_ASCII, or unibyte. */ 3532 face_id = face_at_buffer_position (it->w, 3533 CHARPOS (pos), 3534 it->region_beg_charpos, 3535 it->region_end_charpos, 3536 &next_check_charpos, 3537 limit, 0); 3538 3539 /* Correct the face for charsets different from ASCII. Do it 3540 for the multibyte case only. The face returned above is 3541 suitable for unibyte text if current_buffer is unibyte. */ 3542 if (it->multibyte_p) 3543 { 3544 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos)); 3545 struct face *face = FACE_FROM_ID (it->f, face_id); 3546 face_id = FACE_FOR_CHAR (it->f, face, c); 3547 } 3548 } 3549 3550 return face_id; 3551} 3552 3553 3554 3555/*********************************************************************** 3556 Invisible text 3557 ***********************************************************************/ 3558 3559/* Set up iterator IT from invisible properties at its current 3560 position. Called from handle_stop. */ 3561 3562static enum prop_handled 3563handle_invisible_prop (it) 3564 struct it *it; 3565{ 3566 enum prop_handled handled = HANDLED_NORMALLY; 3567 3568 if (STRINGP (it->string)) 3569 { 3570 extern Lisp_Object Qinvisible; 3571 Lisp_Object prop, end_charpos, limit, charpos; 3572 3573 /* Get the value of the invisible text property at the 3574 current position. Value will be nil if there is no such 3575 property. */ 3576 charpos = make_number (IT_STRING_CHARPOS (*it)); 3577 prop = Fget_text_property (charpos, Qinvisible, it->string); 3578 3579 if (!NILP (prop) 3580 && IT_STRING_CHARPOS (*it) < it->end_charpos) 3581 { 3582 handled = HANDLED_RECOMPUTE_PROPS; 3583 3584 /* Get the position at which the next change of the 3585 invisible text property can be found in IT->string. 3586 Value will be nil if the property value is the same for 3587 all the rest of IT->string. */ 3588 XSETINT (limit, SCHARS (it->string)); 3589 end_charpos = Fnext_single_property_change (charpos, Qinvisible, 3590 it->string, limit); 3591 3592 /* Text at current position is invisible. The next 3593 change in the property is at position end_charpos. 3594 Move IT's current position to that position. */ 3595 if (INTEGERP (end_charpos) 3596 && XFASTINT (end_charpos) < XFASTINT (limit)) 3597 { 3598 struct text_pos old; 3599 old = it->current.string_pos; 3600 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos); 3601 compute_string_pos (&it->current.string_pos, old, it->string); 3602 } 3603 else 3604 { 3605 /* The rest of the string is invisible. If this is an 3606 overlay string, proceed with the next overlay string 3607 or whatever comes and return a character from there. */ 3608 if (it->current.overlay_string_index >= 0) 3609 { 3610 next_overlay_string (it); 3611 /* Don't check for overlay strings when we just 3612 finished processing them. */ 3613 handled = HANDLED_OVERLAY_STRING_CONSUMED; 3614 } 3615 else 3616 { 3617 IT_STRING_CHARPOS (*it) = SCHARS (it->string); 3618 IT_STRING_BYTEPOS (*it) = SBYTES (it->string); 3619 } 3620 } 3621 } 3622 } 3623 else 3624 { 3625 int invis_p, newpos, next_stop, start_charpos; 3626 Lisp_Object pos, prop, overlay; 3627 3628 /* First of all, is there invisible text at this position? */ 3629 start_charpos = IT_CHARPOS (*it); 3630 pos = make_number (IT_CHARPOS (*it)); 3631 prop = get_char_property_and_overlay (pos, Qinvisible, it->window, 3632 &overlay); 3633 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); 3634 3635 /* If we are on invisible text, skip over it. */ 3636 if (invis_p && IT_CHARPOS (*it) < it->end_charpos) 3637 { 3638 /* Record whether we have to display an ellipsis for the 3639 invisible text. */ 3640 int display_ellipsis_p = invis_p == 2; 3641 3642 handled = HANDLED_RECOMPUTE_PROPS; 3643 3644 /* Loop skipping over invisible text. The loop is left at 3645 ZV or with IT on the first char being visible again. */ 3646 do 3647 { 3648 /* Try to skip some invisible text. Return value is the 3649 position reached which can be equal to IT's position 3650 if there is nothing invisible here. This skips both 3651 over invisible text properties and overlays with 3652 invisible property. */ 3653 newpos = skip_invisible (IT_CHARPOS (*it), 3654 &next_stop, ZV, it->window); 3655 3656 /* If we skipped nothing at all we weren't at invisible 3657 text in the first place. If everything to the end of 3658 the buffer was skipped, end the loop. */ 3659 if (newpos == IT_CHARPOS (*it) || newpos >= ZV) 3660 invis_p = 0; 3661 else 3662 { 3663 /* We skipped some characters but not necessarily 3664 all there are. Check if we ended up on visible 3665 text. Fget_char_property returns the property of 3666 the char before the given position, i.e. if we 3667 get invis_p = 0, this means that the char at 3668 newpos is visible. */ 3669 pos = make_number (newpos); 3670 prop = Fget_char_property (pos, Qinvisible, it->window); 3671 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); 3672 } 3673 3674 /* If we ended up on invisible text, proceed to 3675 skip starting with next_stop. */ 3676 if (invis_p) 3677 IT_CHARPOS (*it) = next_stop; 3678 3679 /* If there are adjacent invisible texts, don't lose the 3680 second one's ellipsis. */ 3681 if (invis_p == 2) 3682 display_ellipsis_p = 1; 3683 } 3684 while (invis_p); 3685 3686 /* The position newpos is now either ZV or on visible text. */ 3687 IT_CHARPOS (*it) = newpos; 3688 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos); 3689 3690 /* If there are before-strings at the start of invisible 3691 text, and the text is invisible because of a text 3692 property, arrange to show before-strings because 20.x did 3693 it that way. (If the text is invisible because of an 3694 overlay property instead of a text property, this is 3695 already handled in the overlay code.) */ 3696 if (NILP (overlay) 3697 && get_overlay_strings (it, start_charpos)) 3698 { 3699 handled = HANDLED_RECOMPUTE_PROPS; 3700 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p; 3701 } 3702 else if (display_ellipsis_p) 3703 { 3704 /* Make sure that the glyphs of the ellipsis will get 3705 correct `charpos' values. If we would not update 3706 it->position here, the glyphs would belong to the 3707 last visible character _before_ the invisible 3708 text, which confuses `set_cursor_from_row'. 3709 3710 We use the last invisible position instead of the 3711 first because this way the cursor is always drawn on 3712 the first "." of the ellipsis, whenever PT is inside 3713 the invisible text. Otherwise the cursor would be 3714 placed _after_ the ellipsis when the point is after the 3715 first invisible character. */ 3716 if (!STRINGP (it->object)) 3717 { 3718 it->position.charpos = IT_CHARPOS (*it) - 1; 3719 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos); 3720 } 3721 setup_for_ellipsis (it, 0); 3722 } 3723 } 3724 } 3725 3726 return handled; 3727} 3728 3729 3730/* Make iterator IT return `...' next. 3731 Replaces LEN characters from buffer. */ 3732 3733static void 3734setup_for_ellipsis (it, len) 3735 struct it *it; 3736 int len; 3737{ 3738 /* Use the display table definition for `...'. Invalid glyphs 3739 will be handled by the method returning elements from dpvec. */ 3740 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp))) 3741 { 3742 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp)); 3743 it->dpvec = v->contents; 3744 it->dpend = v->contents + v->size; 3745 } 3746 else 3747 { 3748 /* Default `...'. */ 3749 it->dpvec = default_invis_vector; 3750 it->dpend = default_invis_vector + 3; 3751 } 3752 3753 it->dpvec_char_len = len; 3754 it->current.dpvec_index = 0; 3755 it->dpvec_face_id = -1; 3756 3757 /* Remember the current face id in case glyphs specify faces. 3758 IT's face is restored in set_iterator_to_next. 3759 saved_face_id was set to preceding char's face in handle_stop. */ 3760 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id) 3761 it->saved_face_id = it->face_id = DEFAULT_FACE_ID; 3762 3763 it->method = GET_FROM_DISPLAY_VECTOR; 3764 it->ellipsis_p = 1; 3765} 3766 3767 3768 3769/*********************************************************************** 3770 'display' property 3771 ***********************************************************************/ 3772 3773/* Set up iterator IT from `display' property at its current position. 3774 Called from handle_stop. 3775 We return HANDLED_RETURN if some part of the display property 3776 overrides the display of the buffer text itself. 3777 Otherwise we return HANDLED_NORMALLY. */ 3778 3779static enum prop_handled 3780handle_display_prop (it) 3781 struct it *it; 3782{ 3783 Lisp_Object prop, object; 3784 struct text_pos *position; 3785 /* Nonzero if some property replaces the display of the text itself. */ 3786 int display_replaced_p = 0; 3787 3788 if (STRINGP (it->string)) 3789 { 3790 object = it->string; 3791 position = &it->current.string_pos; 3792 } 3793 else 3794 { 3795 XSETWINDOW (object, it->w); 3796 position = &it->current.pos; 3797 } 3798 3799 /* Reset those iterator values set from display property values. */ 3800 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil; 3801 it->space_width = Qnil; 3802 it->font_height = Qnil; 3803 it->voffset = 0; 3804 3805 /* We don't support recursive `display' properties, i.e. string 3806 values that have a string `display' property, that have a string 3807 `display' property etc. */ 3808 if (!it->string_from_display_prop_p) 3809 it->area = TEXT_AREA; 3810 3811 prop = Fget_char_property (make_number (position->charpos), 3812 Qdisplay, object); 3813 if (NILP (prop)) 3814 return HANDLED_NORMALLY; 3815 3816 if (!STRINGP (it->string)) 3817 object = it->w->buffer; 3818 3819 if (CONSP (prop) 3820 /* Simple properties. */ 3821 && !EQ (XCAR (prop), Qimage) 3822 && !EQ (XCAR (prop), Qspace) 3823 && !EQ (XCAR (prop), Qwhen) 3824 && !EQ (XCAR (prop), Qslice) 3825 && !EQ (XCAR (prop), Qspace_width) 3826 && !EQ (XCAR (prop), Qheight) 3827 && !EQ (XCAR (prop), Qraise) 3828 /* Marginal area specifications. */ 3829 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin)) 3830 && !EQ (XCAR (prop), Qleft_fringe) 3831 && !EQ (XCAR (prop), Qright_fringe) 3832 && !NILP (XCAR (prop))) 3833 { 3834 for (; CONSP (prop); prop = XCDR (prop)) 3835 { 3836 if (handle_single_display_spec (it, XCAR (prop), object, 3837 position, display_replaced_p)) 3838 display_replaced_p = 1; 3839 } 3840 } 3841 else if (VECTORP (prop)) 3842 { 3843 int i; 3844 for (i = 0; i < ASIZE (prop); ++i) 3845 if (handle_single_display_spec (it, AREF (prop, i), object, 3846 position, display_replaced_p)) 3847 display_replaced_p = 1; 3848 } 3849 else 3850 { 3851 int ret = handle_single_display_spec (it, prop, object, position, 0); 3852 if (ret < 0) /* Replaced by "", i.e. nothing. */ 3853 return HANDLED_RECOMPUTE_PROPS; 3854 if (ret) 3855 display_replaced_p = 1; 3856 } 3857 3858 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY; 3859} 3860 3861 3862/* Value is the position of the end of the `display' property starting 3863 at START_POS in OBJECT. */ 3864 3865static struct text_pos 3866display_prop_end (it, object, start_pos) 3867 struct it *it; 3868 Lisp_Object object; 3869 struct text_pos start_pos; 3870{ 3871 Lisp_Object end; 3872 struct text_pos end_pos; 3873 3874 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)), 3875 Qdisplay, object, Qnil); 3876 CHARPOS (end_pos) = XFASTINT (end); 3877 if (STRINGP (object)) 3878 compute_string_pos (&end_pos, start_pos, it->string); 3879 else 3880 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end)); 3881 3882 return end_pos; 3883} 3884 3885 3886/* Set up IT from a single `display' specification PROP. OBJECT 3887 is the object in which the `display' property was found. *POSITION 3888 is the position at which it was found. DISPLAY_REPLACED_P non-zero 3889 means that we previously saw a display specification which already 3890 replaced text display with something else, for example an image; 3891 we ignore such properties after the first one has been processed. 3892 3893 If PROP is a `space' or `image' specification, and in some other 3894 cases too, set *POSITION to the position where the `display' 3895 property ends. 3896 3897 Value is non-zero if something was found which replaces the display 3898 of buffer or string text. Specifically, the value is -1 if that 3899 "something" is "nothing". */ 3900 3901static int 3902handle_single_display_spec (it, spec, object, position, 3903 display_replaced_before_p) 3904 struct it *it; 3905 Lisp_Object spec; 3906 Lisp_Object object; 3907 struct text_pos *position; 3908 int display_replaced_before_p; 3909{ 3910 Lisp_Object form; 3911 Lisp_Object location, value; 3912 struct text_pos start_pos, save_pos; 3913 int valid_p; 3914 3915 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. 3916 If the result is non-nil, use VALUE instead of SPEC. */ 3917 form = Qt; 3918 if (CONSP (spec) && EQ (XCAR (spec), Qwhen)) 3919 { 3920 spec = XCDR (spec); 3921 if (!CONSP (spec)) 3922 return 0; 3923 form = XCAR (spec); 3924 spec = XCDR (spec); 3925 } 3926 3927 if (!NILP (form) && !EQ (form, Qt)) 3928 { 3929 int count = SPECPDL_INDEX (); 3930 struct gcpro gcpro1; 3931 3932 /* Bind `object' to the object having the `display' property, a 3933 buffer or string. Bind `position' to the position in the 3934 object where the property was found, and `buffer-position' 3935 to the current position in the buffer. */ 3936 specbind (Qobject, object); 3937 specbind (Qposition, make_number (CHARPOS (*position))); 3938 specbind (Qbuffer_position, 3939 make_number (STRINGP (object) 3940 ? IT_CHARPOS (*it) : CHARPOS (*position))); 3941 GCPRO1 (form); 3942 form = safe_eval (form); 3943 UNGCPRO; 3944 unbind_to (count, Qnil); 3945 } 3946 3947 if (NILP (form)) 3948 return 0; 3949 3950 /* Handle `(height HEIGHT)' specifications. */ 3951 if (CONSP (spec) 3952 && EQ (XCAR (spec), Qheight) 3953 && CONSP (XCDR (spec))) 3954 { 3955 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) 3956 return 0; 3957 3958 it->font_height = XCAR (XCDR (spec)); 3959 if (!NILP (it->font_height)) 3960 { 3961 struct face *face = FACE_FROM_ID (it->f, it->face_id); 3962 int new_height = -1; 3963 3964 if (CONSP (it->font_height) 3965 && (EQ (XCAR (it->font_height), Qplus) 3966 || EQ (XCAR (it->font_height), Qminus)) 3967 && CONSP (XCDR (it->font_height)) 3968 && INTEGERP (XCAR (XCDR (it->font_height)))) 3969 { 3970 /* `(+ N)' or `(- N)' where N is an integer. */ 3971 int steps = XINT (XCAR (XCDR (it->font_height))); 3972 if (EQ (XCAR (it->font_height), Qplus)) 3973 steps = - steps; 3974 it->face_id = smaller_face (it->f, it->face_id, steps); 3975 } 3976 else if (FUNCTIONP (it->font_height)) 3977 { 3978 /* Call function with current height as argument. 3979 Value is the new height. */ 3980 Lisp_Object height; 3981 height = safe_call1 (it->font_height, 3982 face->lface[LFACE_HEIGHT_INDEX]); 3983 if (NUMBERP (height)) 3984 new_height = XFLOATINT (height); 3985 } 3986 else if (NUMBERP (it->font_height)) 3987 { 3988 /* Value is a multiple of the canonical char height. */ 3989 struct face *face; 3990 3991 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID); 3992 new_height = (XFLOATINT (it->font_height) 3993 * XINT (face->lface[LFACE_HEIGHT_INDEX])); 3994 } 3995 else 3996 { 3997 /* Evaluate IT->font_height with `height' bound to the 3998 current specified height to get the new height. */ 3999 int count = SPECPDL_INDEX (); 4000 4001 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); 4002 value = safe_eval (it->font_height); 4003 unbind_to (count, Qnil); 4004 4005 if (NUMBERP (value)) 4006 new_height = XFLOATINT (value); 4007 } 4008 4009 if (new_height > 0) 4010 it->face_id = face_with_height (it->f, it->face_id, new_height); 4011 } 4012 4013 return 0; 4014 } 4015 4016 /* Handle `(space_width WIDTH)'. */ 4017 if (CONSP (spec) 4018 && EQ (XCAR (spec), Qspace_width) 4019 && CONSP (XCDR (spec))) 4020 { 4021 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) 4022 return 0; 4023 4024 value = XCAR (XCDR (spec)); 4025 if (NUMBERP (value) && XFLOATINT (value) > 0) 4026 it->space_width = value; 4027 4028 return 0; 4029 } 4030 4031 /* Handle `(slice X Y WIDTH HEIGHT)'. */ 4032 if (CONSP (spec) 4033 && EQ (XCAR (spec), Qslice)) 4034 { 4035 Lisp_Object tem; 4036 4037 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) 4038 return 0; 4039 4040 if (tem = XCDR (spec), CONSP (tem)) 4041 { 4042 it->slice.x = XCAR (tem); 4043 if (tem = XCDR (tem), CONSP (tem)) 4044 { 4045 it->slice.y = XCAR (tem); 4046 if (tem = XCDR (tem), CONSP (tem)) 4047 { 4048 it->slice.width = XCAR (tem); 4049 if (tem = XCDR (tem), CONSP (tem)) 4050 it->slice.height = XCAR (tem); 4051 } 4052 } 4053 } 4054 4055 return 0; 4056 } 4057 4058 /* Handle `(raise FACTOR)'. */ 4059 if (CONSP (spec) 4060 && EQ (XCAR (spec), Qraise) 4061 && CONSP (XCDR (spec))) 4062 { 4063 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) 4064 return 0; 4065 4066#ifdef HAVE_WINDOW_SYSTEM 4067 value = XCAR (XCDR (spec)); 4068 if (NUMBERP (value)) 4069 { 4070 struct face *face = FACE_FROM_ID (it->f, it->face_id); 4071 it->voffset = - (XFLOATINT (value) 4072 * (FONT_HEIGHT (face->font))); 4073 } 4074#endif /* HAVE_WINDOW_SYSTEM */ 4075 4076 return 0; 4077 } 4078 4079 /* Don't handle the other kinds of display specifications 4080 inside a string that we got from a `display' property. */ 4081 if (it->string_from_display_prop_p) 4082 return 0; 4083 4084 /* Characters having this form of property are not displayed, so 4085 we have to find the end of the property. */ 4086 start_pos = *position; 4087 *position = display_prop_end (it, object, start_pos); 4088 value = Qnil; 4089 4090 /* Stop the scan at that end position--we assume that all 4091 text properties change there. */ 4092 it->stop_charpos = position->charpos; 4093 4094 /* Handle `(left-fringe BITMAP [FACE])' 4095 and `(right-fringe BITMAP [FACE])'. */ 4096 if (CONSP (spec) 4097 && (EQ (XCAR (spec), Qleft_fringe) 4098 || EQ (XCAR (spec), Qright_fringe)) 4099 && CONSP (XCDR (spec))) 4100 { 4101 int face_id = DEFAULT_FACE_ID; 4102 int fringe_bitmap; 4103 4104 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f)) 4105 /* If we return here, POSITION has been advanced 4106 across the text with this property. */ 4107 return 0; 4108 4109#ifdef HAVE_WINDOW_SYSTEM 4110 value = XCAR (XCDR (spec)); 4111 if (!SYMBOLP (value) 4112 || !(fringe_bitmap = lookup_fringe_bitmap (value))) 4113 /* If we return here, POSITION has been advanced 4114 across the text with this property. */ 4115 return 0; 4116 4117 if (CONSP (XCDR (XCDR (spec)))) 4118 { 4119 Lisp_Object face_name = XCAR (XCDR (XCDR (spec))); 4120 int face_id2 = lookup_derived_face (it->f, face_name, 4121 'A', FRINGE_FACE_ID, 0); 4122 if (face_id2 >= 0) 4123 face_id = face_id2; 4124 } 4125 4126 /* Save current settings of IT so that we can restore them 4127 when we are finished with the glyph property value. */ 4128 4129 save_pos = it->position; 4130 it->position = *position; 4131 push_it (it); 4132 it->position = save_pos; 4133 4134 it->area = TEXT_AREA; 4135 it->what = IT_IMAGE; 4136 it->image_id = -1; /* no image */ 4137 it->position = start_pos; 4138 it->object = NILP (object) ? it->w->buffer : object; 4139 it->method = GET_FROM_IMAGE; 4140 it->face_id = face_id; 4141 4142 /* Say that we haven't consumed the characters with 4143 `display' property yet. The call to pop_it in 4144 set_iterator_to_next will clean this up. */ 4145 *position = start_pos; 4146 4147 if (EQ (XCAR (spec), Qleft_fringe)) 4148 { 4149 it->left_user_fringe_bitmap = fringe_bitmap; 4150 it->left_user_fringe_face_id = face_id; 4151 } 4152 else 4153 { 4154 it->right_user_fringe_bitmap = fringe_bitmap; 4155 it->right_user_fringe_face_id = face_id; 4156 } 4157#endif /* HAVE_WINDOW_SYSTEM */ 4158 return 1; 4159 } 4160 4161 /* Prepare to handle `((margin left-margin) ...)', 4162 `((margin right-margin) ...)' and `((margin nil) ...)' 4163 prefixes for display specifications. */ 4164 location = Qunbound; 4165 if (CONSP (spec) && CONSP (XCAR (spec))) 4166 { 4167 Lisp_Object tem; 4168 4169 value = XCDR (spec); 4170 if (CONSP (value)) 4171 value = XCAR (value); 4172 4173 tem = XCAR (spec); 4174 if (EQ (XCAR (tem), Qmargin) 4175 && (tem = XCDR (tem), 4176 tem = CONSP (tem) ? XCAR (tem) : Qnil, 4177 (NILP (tem) 4178 || EQ (tem, Qleft_margin) 4179 || EQ (tem, Qright_margin)))) 4180 location = tem; 4181 } 4182 4183 if (EQ (location, Qunbound)) 4184 { 4185 location = Qnil; 4186 value = spec; 4187 } 4188 4189 /* After this point, VALUE is the property after any 4190 margin prefix has been stripped. It must be a string, 4191 an image specification, or `(space ...)'. 4192 4193 LOCATION specifies where to display: `left-margin', 4194 `right-margin' or nil. */ 4195 4196 valid_p = (STRINGP (value) 4197#ifdef HAVE_WINDOW_SYSTEM 4198 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value)) 4199#endif /* not HAVE_WINDOW_SYSTEM */ 4200 || (CONSP (value) && EQ (XCAR (value), Qspace))); 4201 4202 if (valid_p && !display_replaced_before_p) 4203 { 4204 /* Save current settings of IT so that we can restore them 4205 when we are finished with the glyph property value. */ 4206 save_pos = it->position; 4207 it->position = *position; 4208 push_it (it); 4209 it->position = save_pos; 4210 4211 if (NILP (location)) 4212 it->area = TEXT_AREA; 4213 else if (EQ (location, Qleft_margin)) 4214 it->area = LEFT_MARGIN_AREA; 4215 else 4216 it->area = RIGHT_MARGIN_AREA; 4217 4218 if (STRINGP (value)) 4219 { 4220 if (SCHARS (value) == 0) 4221 { 4222 pop_it (it); 4223 return -1; /* Replaced by "", i.e. nothing. */ 4224 } 4225 it->string = value; 4226 it->multibyte_p = STRING_MULTIBYTE (it->string); 4227 it->current.overlay_string_index = -1; 4228 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; 4229 it->end_charpos = it->string_nchars = SCHARS (it->string); 4230 it->method = GET_FROM_STRING; 4231 it->stop_charpos = 0; 4232 it->string_from_display_prop_p = 1; 4233 /* Say that we haven't consumed the characters with 4234 `display' property yet. The call to pop_it in 4235 set_iterator_to_next will clean this up. */ 4236 *position = start_pos; 4237 } 4238 else if (CONSP (value) && EQ (XCAR (value), Qspace)) 4239 { 4240 it->method = GET_FROM_STRETCH; 4241 it->object = value; 4242 *position = it->position = start_pos; 4243 } 4244#ifdef HAVE_WINDOW_SYSTEM 4245 else 4246 { 4247 it->what = IT_IMAGE; 4248 it->image_id = lookup_image (it->f, value); 4249 it->position = start_pos; 4250 it->object = NILP (object) ? it->w->buffer : object; 4251 it->method = GET_FROM_IMAGE; 4252 4253 /* Say that we haven't consumed the characters with 4254 `display' property yet. The call to pop_it in 4255 set_iterator_to_next will clean this up. */ 4256 *position = start_pos; 4257 } 4258#endif /* HAVE_WINDOW_SYSTEM */ 4259 4260 return 1; 4261 } 4262 4263 /* Invalid property or property not supported. Restore 4264 POSITION to what it was before. */ 4265 *position = start_pos; 4266 return 0; 4267} 4268 4269 4270/* Check if SPEC is a display specification value whose text should be 4271 treated as intangible. */ 4272 4273static int 4274single_display_spec_intangible_p (prop) 4275 Lisp_Object prop; 4276{ 4277 /* Skip over `when FORM'. */ 4278 if (CONSP (prop) && EQ (XCAR (prop), Qwhen)) 4279 { 4280 prop = XCDR (prop); 4281 if (!CONSP (prop)) 4282 return 0; 4283 prop = XCDR (prop); 4284 } 4285 4286 if (STRINGP (prop)) 4287 return 1; 4288 4289 if (!CONSP (prop)) 4290 return 0; 4291 4292 /* Skip over `margin LOCATION'. If LOCATION is in the margins, 4293 we don't need to treat text as intangible. */ 4294 if (EQ (XCAR (prop), Qmargin)) 4295 { 4296 prop = XCDR (prop); 4297 if (!CONSP (prop)) 4298 return 0; 4299 4300 prop = XCDR (prop); 4301 if (!CONSP (prop) 4302 || EQ (XCAR (prop), Qleft_margin) 4303 || EQ (XCAR (prop), Qright_margin)) 4304 return 0; 4305 } 4306 4307 return (CONSP (prop) 4308 && (EQ (XCAR (prop), Qimage) 4309 || EQ (XCAR (prop), Qspace))); 4310} 4311 4312 4313/* Check if PROP is a display property value whose text should be 4314 treated as intangible. */ 4315 4316int 4317display_prop_intangible_p (prop) 4318 Lisp_Object prop; 4319{ 4320 if (CONSP (prop) 4321 && CONSP (XCAR (prop)) 4322 && !EQ (Qmargin, XCAR (XCAR (prop)))) 4323 { 4324 /* A list of sub-properties. */ 4325 while (CONSP (prop)) 4326 { 4327 if (single_display_spec_intangible_p (XCAR (prop))) 4328 return 1; 4329 prop = XCDR (prop); 4330 } 4331 } 4332 else if (VECTORP (prop)) 4333 { 4334 /* A vector of sub-properties. */ 4335 int i; 4336 for (i = 0; i < ASIZE (prop); ++i) 4337 if (single_display_spec_intangible_p (AREF (prop, i))) 4338 return 1; 4339 } 4340 else 4341 return single_display_spec_intangible_p (prop); 4342 4343 return 0; 4344} 4345 4346 4347/* Return 1 if PROP is a display sub-property value containing STRING. */ 4348 4349static int 4350single_display_spec_string_p (prop, string) 4351 Lisp_Object prop, string; 4352{ 4353 if (EQ (string, prop)) 4354 return 1; 4355 4356 /* Skip over `when FORM'. */ 4357 if (CONSP (prop) && EQ (XCAR (prop), Qwhen)) 4358 { 4359 prop = XCDR (prop); 4360 if (!CONSP (prop)) 4361 return 0; 4362 prop = XCDR (prop); 4363 } 4364 4365 if (CONSP (prop)) 4366 /* Skip over `margin LOCATION'. */ 4367 if (EQ (XCAR (prop), Qmargin)) 4368 { 4369 prop = XCDR (prop); 4370 if (!CONSP (prop)) 4371 return 0; 4372 4373 prop = XCDR (prop); 4374 if (!CONSP (prop)) 4375 return 0; 4376 } 4377 4378 return CONSP (prop) && EQ (XCAR (prop), string); 4379} 4380 4381 4382/* Return 1 if STRING appears in the `display' property PROP. */ 4383 4384static int 4385display_prop_string_p (prop, string) 4386 Lisp_Object prop, string; 4387{ 4388 if (CONSP (prop) 4389 && CONSP (XCAR (prop)) 4390 && !EQ (Qmargin, XCAR (XCAR (prop)))) 4391 { 4392 /* A list of sub-properties. */ 4393 while (CONSP (prop)) 4394 { 4395 if (single_display_spec_string_p (XCAR (prop), string)) 4396 return 1; 4397 prop = XCDR (prop); 4398 } 4399 } 4400 else if (VECTORP (prop)) 4401 { 4402 /* A vector of sub-properties. */ 4403 int i; 4404 for (i = 0; i < ASIZE (prop); ++i) 4405 if (single_display_spec_string_p (AREF (prop, i), string)) 4406 return 1; 4407 } 4408 else 4409 return single_display_spec_string_p (prop, string); 4410 4411 return 0; 4412} 4413 4414 4415/* Determine from which buffer position in W's buffer STRING comes 4416 from. AROUND_CHARPOS is an approximate position where it could 4417 be from. Value is the buffer position or 0 if it couldn't be 4418 determined. 4419 4420 W's buffer must be current. 4421 4422 This function is necessary because we don't record buffer positions 4423 in glyphs generated from strings (to keep struct glyph small). 4424 This function may only use code that doesn't eval because it is 4425 called asynchronously from note_mouse_highlight. */ 4426 4427int 4428string_buffer_position (w, string, around_charpos) 4429 struct window *w; 4430 Lisp_Object string; 4431 int around_charpos; 4432{ 4433 Lisp_Object limit, prop, pos; 4434 const int MAX_DISTANCE = 1000; 4435 int found = 0; 4436 4437 pos = make_number (around_charpos); 4438 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV)); 4439 while (!found && !EQ (pos, limit)) 4440 { 4441 prop = Fget_char_property (pos, Qdisplay, Qnil); 4442 if (!NILP (prop) && display_prop_string_p (prop, string)) 4443 found = 1; 4444 else 4445 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit); 4446 } 4447 4448 if (!found) 4449 { 4450 pos = make_number (around_charpos); 4451 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV)); 4452 while (!found && !EQ (pos, limit)) 4453 { 4454 prop = Fget_char_property (pos, Qdisplay, Qnil); 4455 if (!NILP (prop) && display_prop_string_p (prop, string)) 4456 found = 1; 4457 else 4458 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil, 4459 limit); 4460 } 4461 } 4462 4463 return found ? XINT (pos) : 0; 4464} 4465 4466 4467 4468/*********************************************************************** 4469 `composition' property 4470 ***********************************************************************/ 4471 4472/* Set up iterator IT from `composition' property at its current 4473 position. Called from handle_stop. */ 4474 4475static enum prop_handled 4476handle_composition_prop (it) 4477 struct it *it; 4478{ 4479 Lisp_Object prop, string; 4480 int pos, pos_byte, end; 4481 enum prop_handled handled = HANDLED_NORMALLY; 4482 4483 if (STRINGP (it->string)) 4484 { 4485 pos = IT_STRING_CHARPOS (*it); 4486 pos_byte = IT_STRING_BYTEPOS (*it); 4487 string = it->string; 4488 } 4489 else 4490 { 4491 pos = IT_CHARPOS (*it); 4492 pos_byte = IT_BYTEPOS (*it); 4493 string = Qnil; 4494 } 4495 4496 /* If there's a valid composition and point is not inside of the 4497 composition (in the case that the composition is from the current 4498 buffer), draw a glyph composed from the composition components. */ 4499 if (find_composition (pos, -1, &pos, &end, &prop, string) 4500 && COMPOSITION_VALID_P (pos, end, prop) 4501 && (STRINGP (it->string) || (PT <= pos || PT >= end))) 4502 { 4503 int id = get_composition_id (pos, pos_byte, end - pos, prop, string); 4504 4505 if (id >= 0) 4506 { 4507 struct composition *cmp = composition_table[id]; 4508 4509 if (cmp->glyph_len == 0) 4510 { 4511 /* No glyph. */ 4512 if (STRINGP (it->string)) 4513 { 4514 IT_STRING_CHARPOS (*it) = end; 4515 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string, 4516 end); 4517 } 4518 else 4519 { 4520 IT_CHARPOS (*it) = end; 4521 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end); 4522 } 4523 return HANDLED_RECOMPUTE_PROPS; 4524 } 4525 4526 it->stop_charpos = end; 4527 push_it (it); 4528 4529 it->method = GET_FROM_COMPOSITION; 4530 it->cmp_id = id; 4531 it->cmp_len = COMPOSITION_LENGTH (prop); 4532 /* For a terminal, draw only the first character of the 4533 components. */ 4534 it->c = COMPOSITION_GLYPH (composition_table[id], 0); 4535 it->len = (STRINGP (it->string) 4536 ? string_char_to_byte (it->string, end) 4537 : CHAR_TO_BYTE (end)) - pos_byte; 4538 handled = HANDLED_RETURN; 4539 } 4540 } 4541 4542 return handled; 4543} 4544 4545 4546 4547/*********************************************************************** 4548 Overlay strings 4549 ***********************************************************************/ 4550 4551/* The following structure is used to record overlay strings for 4552 later sorting in load_overlay_strings. */ 4553 4554struct overlay_entry 4555{ 4556 Lisp_Object overlay; 4557 Lisp_Object string; 4558 int priority; 4559 int after_string_p; 4560}; 4561 4562 4563/* Set up iterator IT from overlay strings at its current position. 4564 Called from handle_stop. */ 4565 4566static enum prop_handled 4567handle_overlay_change (it) 4568 struct it *it; 4569{ 4570 if (!STRINGP (it->string) && get_overlay_strings (it, 0)) 4571 return HANDLED_RECOMPUTE_PROPS; 4572 else 4573 return HANDLED_NORMALLY; 4574} 4575 4576 4577/* Set up the next overlay string for delivery by IT, if there is an 4578 overlay string to deliver. Called by set_iterator_to_next when the 4579 end of the current overlay string is reached. If there are more 4580 overlay strings to display, IT->string and 4581 IT->current.overlay_string_index are set appropriately here. 4582 Otherwise IT->string is set to nil. */ 4583 4584static void 4585next_overlay_string (it) 4586 struct it *it; 4587{ 4588 ++it->current.overlay_string_index; 4589 if (it->current.overlay_string_index == it->n_overlay_strings) 4590 { 4591 /* No more overlay strings. Restore IT's settings to what 4592 they were before overlay strings were processed, and 4593 continue to deliver from current_buffer. */ 4594 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p; 4595 4596 pop_it (it); 4597 xassert (it->sp > 0 4598 || it->method == GET_FROM_COMPOSITION 4599 || (NILP (it->string) 4600 && it->method == GET_FROM_BUFFER 4601 && it->stop_charpos >= BEGV 4602 && it->stop_charpos <= it->end_charpos)); 4603 it->current.overlay_string_index = -1; 4604 it->n_overlay_strings = 0; 4605 4606 /* If we're at the end of the buffer, record that we have 4607 processed the overlay strings there already, so that 4608 next_element_from_buffer doesn't try it again. */ 4609 if (IT_CHARPOS (*it) >= it->end_charpos) 4610 it->overlay_strings_at_end_processed_p = 1; 4611 4612 /* If we have to display `...' for invisible text, set 4613 the iterator up for that. */ 4614 if (display_ellipsis_p) 4615 setup_for_ellipsis (it, 0); 4616 } 4617 else 4618 { 4619 /* There are more overlay strings to process. If 4620 IT->current.overlay_string_index has advanced to a position 4621 where we must load IT->overlay_strings with more strings, do 4622 it. */ 4623 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE; 4624 4625 if (it->current.overlay_string_index && i == 0) 4626 load_overlay_strings (it, 0); 4627 4628 /* Initialize IT to deliver display elements from the overlay 4629 string. */ 4630 it->string = it->overlay_strings[i]; 4631 it->multibyte_p = STRING_MULTIBYTE (it->string); 4632 SET_TEXT_POS (it->current.string_pos, 0, 0); 4633 it->method = GET_FROM_STRING; 4634 it->stop_charpos = 0; 4635 } 4636 4637 CHECK_IT (it); 4638} 4639 4640 4641/* Compare two overlay_entry structures E1 and E2. Used as a 4642 comparison function for qsort in load_overlay_strings. Overlay 4643 strings for the same position are sorted so that 4644 4645 1. All after-strings come in front of before-strings, except 4646 when they come from the same overlay. 4647 4648 2. Within after-strings, strings are sorted so that overlay strings 4649 from overlays with higher priorities come first. 4650 4651 2. Within before-strings, strings are sorted so that overlay 4652 strings from overlays with higher priorities come last. 4653 4654 Value is analogous to strcmp. */ 4655 4656 4657static int 4658compare_overlay_entries (e1, e2) 4659 void *e1, *e2; 4660{ 4661 struct overlay_entry *entry1 = (struct overlay_entry *) e1; 4662 struct overlay_entry *entry2 = (struct overlay_entry *) e2; 4663 int result; 4664 4665 if (entry1->after_string_p != entry2->after_string_p) 4666 { 4667 /* Let after-strings appear in front of before-strings if 4668 they come from different overlays. */ 4669 if (EQ (entry1->overlay, entry2->overlay)) 4670 result = entry1->after_string_p ? 1 : -1; 4671 else 4672 result = entry1->after_string_p ? -1 : 1; 4673 } 4674 else if (entry1->after_string_p) 4675 /* After-strings sorted in order of decreasing priority. */ 4676 result = entry2->priority - entry1->priority; 4677 else 4678 /* Before-strings sorted in order of increasing priority. */ 4679 result = entry1->priority - entry2->priority; 4680 4681 return result; 4682} 4683 4684 4685/* Load the vector IT->overlay_strings with overlay strings from IT's 4686 current buffer position, or from CHARPOS if that is > 0. Set 4687 IT->n_overlays to the total number of overlay strings found. 4688 4689 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at 4690 a time. On entry into load_overlay_strings, 4691 IT->current.overlay_string_index gives the number of overlay 4692 strings that have already been loaded by previous calls to this 4693 function. 4694 4695 IT->add_overlay_start contains an additional overlay start 4696 position to consider for taking overlay strings from, if non-zero. 4697 This position comes into play when the overlay has an `invisible' 4698 property, and both before and after-strings. When we've skipped to 4699 the end of the overlay, because of its `invisible' property, we 4700 nevertheless want its before-string to appear. 4701 IT->add_overlay_start will contain the overlay start position 4702 in this case. 4703 4704 Overlay strings are sorted so that after-string strings come in 4705 front of before-string strings. Within before and after-strings, 4706 strings are sorted by overlay priority. See also function 4707 compare_overlay_entries. */ 4708 4709static void 4710load_overlay_strings (it, charpos) 4711 struct it *it; 4712 int charpos; 4713{ 4714 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority; 4715 Lisp_Object overlay, window, str, invisible; 4716 struct Lisp_Overlay *ov; 4717 int start, end; 4718 int size = 20; 4719 int n = 0, i, j, invis_p; 4720 struct overlay_entry *entries 4721 = (struct overlay_entry *) alloca (size * sizeof *entries); 4722 4723 if (charpos <= 0) 4724 charpos = IT_CHARPOS (*it); 4725 4726 /* Append the overlay string STRING of overlay OVERLAY to vector 4727 `entries' which has size `size' and currently contains `n' 4728 elements. AFTER_P non-zero means STRING is an after-string of 4729 OVERLAY. */ 4730#define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \ 4731 do \ 4732 { \ 4733 Lisp_Object priority; \ 4734 \ 4735 if (n == size) \ 4736 { \ 4737 int new_size = 2 * size; \ 4738 struct overlay_entry *old = entries; \ 4739 entries = \ 4740 (struct overlay_entry *) alloca (new_size \ 4741 * sizeof *entries); \ 4742 bcopy (old, entries, size * sizeof *entries); \ 4743 size = new_size; \ 4744 } \ 4745 \ 4746 entries[n].string = (STRING); \ 4747 entries[n].overlay = (OVERLAY); \ 4748 priority = Foverlay_get ((OVERLAY), Qpriority); \ 4749 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \ 4750 entries[n].after_string_p = (AFTER_P); \ 4751 ++n; \ 4752 } \ 4753 while (0) 4754 4755 /* Process overlay before the overlay center. */ 4756 for (ov = current_buffer->overlays_before; ov; ov = ov->next) 4757 { 4758 XSETMISC (overlay, ov); 4759 xassert (OVERLAYP (overlay)); 4760 start = OVERLAY_POSITION (OVERLAY_START (overlay)); 4761 end = OVERLAY_POSITION (OVERLAY_END (overlay)); 4762 4763 if (end < charpos) 4764 break; 4765 4766 /* Skip this overlay if it doesn't start or end at IT's current 4767 position. */ 4768 if (end != charpos && start != charpos) 4769 continue; 4770 4771 /* Skip this overlay if it doesn't apply to IT->w. */ 4772 window = Foverlay_get (overlay, Qwindow); 4773 if (WINDOWP (window) && XWINDOW (window) != it->w) 4774 continue; 4775 4776 /* If the text ``under'' the overlay is invisible, both before- 4777 and after-strings from this overlay are visible; start and 4778 end position are indistinguishable. */ 4779 invisible = Foverlay_get (overlay, Qinvisible); 4780 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible); 4781 4782 /* If overlay has a non-empty before-string, record it. */ 4783 if ((start == charpos || (end == charpos && invis_p)) 4784 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) 4785 && SCHARS (str)) 4786 RECORD_OVERLAY_STRING (overlay, str, 0); 4787 4788 /* If overlay has a non-empty after-string, record it. */ 4789 if ((end == charpos || (start == charpos && invis_p)) 4790 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)) 4791 && SCHARS (str)) 4792 RECORD_OVERLAY_STRING (overlay, str, 1); 4793 } 4794 4795 /* Process overlays after the overlay center. */ 4796 for (ov = current_buffer->overlays_after; ov; ov = ov->next) 4797 { 4798 XSETMISC (overlay, ov); 4799 xassert (OVERLAYP (overlay)); 4800 start = OVERLAY_POSITION (OVERLAY_START (overlay)); 4801 end = OVERLAY_POSITION (OVERLAY_END (overlay)); 4802 4803 if (start > charpos) 4804 break; 4805 4806 /* Skip this overlay if it doesn't start or end at IT's current 4807 position. */ 4808 if (end != charpos && start != charpos) 4809 continue; 4810 4811 /* Skip this overlay if it doesn't apply to IT->w. */ 4812 window = Foverlay_get (overlay, Qwindow); 4813 if (WINDOWP (window) && XWINDOW (window) != it->w) 4814 continue; 4815 4816 /* If the text ``under'' the overlay is invisible, it has a zero 4817 dimension, and both before- and after-strings apply. */ 4818 invisible = Foverlay_get (overlay, Qinvisible); 4819 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible); 4820 4821 /* If overlay has a non-empty before-string, record it. */ 4822 if ((start == charpos || (end == charpos && invis_p)) 4823 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) 4824 && SCHARS (str)) 4825 RECORD_OVERLAY_STRING (overlay, str, 0); 4826 4827 /* If overlay has a non-empty after-string, record it. */ 4828 if ((end == charpos || (start == charpos && invis_p)) 4829 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)) 4830 && SCHARS (str)) 4831 RECORD_OVERLAY_STRING (overlay, str, 1); 4832 } 4833 4834#undef RECORD_OVERLAY_STRING 4835 4836 /* Sort entries. */ 4837 if (n > 1) 4838 qsort (entries, n, sizeof *entries, compare_overlay_entries); 4839 4840 /* Record the total number of strings to process. */ 4841 it->n_overlay_strings = n; 4842 4843 /* IT->current.overlay_string_index is the number of overlay strings 4844 that have already been consumed by IT. Copy some of the 4845 remaining overlay strings to IT->overlay_strings. */ 4846 i = 0; 4847 j = it->current.overlay_string_index; 4848 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n) 4849 it->overlay_strings[i++] = entries[j++].string; 4850 4851 CHECK_IT (it); 4852} 4853 4854 4855/* Get the first chunk of overlay strings at IT's current buffer 4856 position, or at CHARPOS if that is > 0. Value is non-zero if at 4857 least one overlay string was found. */ 4858 4859static int 4860get_overlay_strings_1 (it, charpos, compute_stop_p) 4861 struct it *it; 4862 int charpos; 4863{ 4864 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to 4865 process. This fills IT->overlay_strings with strings, and sets 4866 IT->n_overlay_strings to the total number of strings to process. 4867 IT->pos.overlay_string_index has to be set temporarily to zero 4868 because load_overlay_strings needs this; it must be set to -1 4869 when no overlay strings are found because a zero value would 4870 indicate a position in the first overlay string. */ 4871 it->current.overlay_string_index = 0; 4872 load_overlay_strings (it, charpos); 4873 4874 /* If we found overlay strings, set up IT to deliver display 4875 elements from the first one. Otherwise set up IT to deliver 4876 from current_buffer. */ 4877 if (it->n_overlay_strings) 4878 { 4879 /* Make sure we know settings in current_buffer, so that we can 4880 restore meaningful values when we're done with the overlay 4881 strings. */ 4882 if (compute_stop_p) 4883 compute_stop_pos (it); 4884 xassert (it->face_id >= 0); 4885 4886 /* Save IT's settings. They are restored after all overlay 4887 strings have been processed. */ 4888 xassert (!compute_stop_p || it->sp == 0); 4889 push_it (it); 4890 4891 /* Set up IT to deliver display elements from the first overlay 4892 string. */ 4893 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; 4894 it->string = it->overlay_strings[0]; 4895 it->stop_charpos = 0; 4896 xassert (STRINGP (it->string)); 4897 it->end_charpos = SCHARS (it->string); 4898 it->multibyte_p = STRING_MULTIBYTE (it->string); 4899 it->method = GET_FROM_STRING; 4900 return 1; 4901 } 4902 4903 it->current.overlay_string_index = -1; 4904 return 0; 4905} 4906 4907static int 4908get_overlay_strings (it, charpos) 4909 struct it *it; 4910 int charpos; 4911{ 4912 it->string = Qnil; 4913 it->method = GET_FROM_BUFFER; 4914 4915 (void) get_overlay_strings_1 (it, charpos, 1); 4916 4917 CHECK_IT (it); 4918 4919 /* Value is non-zero if we found at least one overlay string. */ 4920 return STRINGP (it->string); 4921} 4922 4923 4924 4925/*********************************************************************** 4926 Saving and restoring state 4927 ***********************************************************************/ 4928 4929/* Save current settings of IT on IT->stack. Called, for example, 4930 before setting up IT for an overlay string, to be able to restore 4931 IT's settings to what they were after the overlay string has been 4932 processed. */ 4933 4934static void 4935push_it (it) 4936 struct it *it; 4937{ 4938 struct iterator_stack_entry *p; 4939 4940 xassert (it->sp < IT_STACK_SIZE); 4941 p = it->stack + it->sp; 4942 4943 p->stop_charpos = it->stop_charpos; 4944 xassert (it->face_id >= 0); 4945 p->face_id = it->face_id; 4946 p->string = it->string; 4947 p->method = it->method; 4948 switch (p->method) 4949 { 4950 case GET_FROM_IMAGE: 4951 p->u.image.object = it->object; 4952 p->u.image.image_id = it->image_id; 4953 p->u.image.slice = it->slice; 4954 break; 4955 case GET_FROM_COMPOSITION: 4956 p->u.comp.object = it->object; 4957 p->u.comp.c = it->c; 4958 p->u.comp.len = it->len; 4959 p->u.comp.cmp_id = it->cmp_id; 4960 p->u.comp.cmp_len = it->cmp_len; 4961 break; 4962 case GET_FROM_STRETCH: 4963 p->u.stretch.object = it->object; 4964 break; 4965 } 4966 p->position = it->position; 4967 p->current = it->current; 4968 p->end_charpos = it->end_charpos; 4969 p->string_nchars = it->string_nchars; 4970 p->area = it->area; 4971 p->multibyte_p = it->multibyte_p; 4972 p->space_width = it->space_width; 4973 p->font_height = it->font_height; 4974 p->voffset = it->voffset; 4975 p->string_from_display_prop_p = it->string_from_display_prop_p; 4976 p->display_ellipsis_p = 0; 4977 ++it->sp; 4978} 4979 4980 4981/* Restore IT's settings from IT->stack. Called, for example, when no 4982 more overlay strings must be processed, and we return to delivering 4983 display elements from a buffer, or when the end of a string from a 4984 `display' property is reached and we return to delivering display 4985 elements from an overlay string, or from a buffer. */ 4986 4987static void 4988pop_it (it) 4989 struct it *it; 4990{ 4991 struct iterator_stack_entry *p; 4992 4993 xassert (it->sp > 0); 4994 --it->sp; 4995 p = it->stack + it->sp; 4996 it->stop_charpos = p->stop_charpos; 4997 it->face_id = p->face_id; 4998 it->current = p->current; 4999 it->position = p->position; 5000 it->string = p->string; 5001 if (NILP (it->string)) 5002 SET_TEXT_POS (it->current.string_pos, -1, -1); 5003 it->method = p->method; 5004 switch (it->method) 5005 { 5006 case GET_FROM_IMAGE: 5007 it->image_id = p->u.image.image_id; 5008 it->object = p->u.image.object; 5009 it->slice = p->u.image.slice; 5010 break; 5011 case GET_FROM_COMPOSITION: 5012 it->object = p->u.comp.object; 5013 it->c = p->u.comp.c; 5014 it->len = p->u.comp.len; 5015 it->cmp_id = p->u.comp.cmp_id; 5016 it->cmp_len = p->u.comp.cmp_len; 5017 break; 5018 case GET_FROM_STRETCH: 5019 it->object = p->u.comp.object; 5020 break; 5021 case GET_FROM_BUFFER: 5022 it->object = it->w->buffer; 5023 break; 5024 case GET_FROM_STRING: 5025 it->object = it->string; 5026 break; 5027 } 5028 it->end_charpos = p->end_charpos; 5029 it->string_nchars = p->string_nchars; 5030 it->area = p->area; 5031 it->multibyte_p = p->multibyte_p; 5032 it->space_width = p->space_width; 5033 it->font_height = p->font_height; 5034 it->voffset = p->voffset; 5035 it->string_from_display_prop_p = p->string_from_display_prop_p; 5036} 5037 5038 5039 5040/*********************************************************************** 5041 Moving over lines 5042 ***********************************************************************/ 5043 5044/* Set IT's current position to the previous line start. */ 5045 5046static void 5047back_to_previous_line_start (it) 5048 struct it *it; 5049{ 5050 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1); 5051 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); 5052} 5053 5054 5055/* Move IT to the next line start. 5056 5057 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if 5058 we skipped over part of the text (as opposed to moving the iterator 5059 continuously over the text). Otherwise, don't change the value 5060 of *SKIPPED_P. 5061 5062 Newlines may come from buffer text, overlay strings, or strings 5063 displayed via the `display' property. That's the reason we can't 5064 simply use find_next_newline_no_quit. 5065 5066 Note that this function may not skip over invisible text that is so 5067 because of text properties and immediately follows a newline. If 5068 it would, function reseat_at_next_visible_line_start, when called 5069 from set_iterator_to_next, would effectively make invisible 5070 characters following a newline part of the wrong glyph row, which 5071 leads to wrong cursor motion. */ 5072 5073static int 5074forward_to_next_line_start (it, skipped_p) 5075 struct it *it; 5076 int *skipped_p; 5077{ 5078 int old_selective, newline_found_p, n; 5079 const int MAX_NEWLINE_DISTANCE = 500; 5080 5081 /* If already on a newline, just consume it to avoid unintended 5082 skipping over invisible text below. */ 5083 if (it->what == IT_CHARACTER 5084 && it->c == '\n' 5085 && CHARPOS (it->position) == IT_CHARPOS (*it)) 5086 { 5087 set_iterator_to_next (it, 0); 5088 it->c = 0; 5089 return 1; 5090 } 5091 5092 /* Don't handle selective display in the following. It's (a) 5093 unnecessary because it's done by the caller, and (b) leads to an 5094 infinite recursion because next_element_from_ellipsis indirectly 5095 calls this function. */ 5096 old_selective = it->selective; 5097 it->selective = 0; 5098 5099 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements 5100 from buffer text. */ 5101 for (n = newline_found_p = 0; 5102 !newline_found_p && n < MAX_NEWLINE_DISTANCE; 5103 n += STRINGP (it->string) ? 0 : 1) 5104 { 5105 if (!get_next_display_element (it)) 5106 return 0; 5107 newline_found_p = it->what == IT_CHARACTER && it->c == '\n'; 5108 set_iterator_to_next (it, 0); 5109 } 5110 5111 /* If we didn't find a newline near enough, see if we can use a 5112 short-cut. */ 5113 if (!newline_found_p) 5114 { 5115 int start = IT_CHARPOS (*it); 5116 int limit = find_next_newline_no_quit (start, 1); 5117 Lisp_Object pos; 5118 5119 xassert (!STRINGP (it->string)); 5120 5121 /* If there isn't any `display' property in sight, and no 5122 overlays, we can just use the position of the newline in 5123 buffer text. */ 5124 if (it->stop_charpos >= limit 5125 || ((pos = Fnext_single_property_change (make_number (start), 5126 Qdisplay, 5127 Qnil, make_number (limit)), 5128 NILP (pos)) 5129 && next_overlay_change (start) == ZV)) 5130 { 5131 IT_CHARPOS (*it) = limit; 5132 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); 5133 *skipped_p = newline_found_p = 1; 5134 } 5135 else 5136 { 5137 while (get_next_display_element (it) 5138 && !newline_found_p) 5139 { 5140 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it); 5141 set_iterator_to_next (it, 0); 5142 } 5143 } 5144 } 5145 5146 it->selective = old_selective; 5147 return newline_found_p; 5148} 5149 5150 5151/* Set IT's current position to the previous visible line start. Skip 5152 invisible text that is so either due to text properties or due to 5153 selective display. Caution: this does not change IT->current_x and 5154 IT->hpos. */ 5155 5156static void 5157back_to_previous_visible_line_start (it) 5158 struct it *it; 5159{ 5160 while (IT_CHARPOS (*it) > BEGV) 5161 { 5162 back_to_previous_line_start (it); 5163 5164 if (IT_CHARPOS (*it) <= BEGV) 5165 break; 5166 5167 /* If selective > 0, then lines indented more than that values 5168 are invisible. */ 5169 if (it->selective > 0 5170 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it), 5171 (double) it->selective)) /* iftc */ 5172 continue; 5173 5174 /* Check the newline before point for invisibility. */ 5175 { 5176 Lisp_Object prop; 5177 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1), 5178 Qinvisible, it->window); 5179 if (TEXT_PROP_MEANS_INVISIBLE (prop)) 5180 continue; 5181 } 5182 5183 if (IT_CHARPOS (*it) <= BEGV) 5184 break; 5185 5186 { 5187 struct it it2; 5188 int pos; 5189 int beg, end; 5190 Lisp_Object val, overlay; 5191 5192 /* If newline is part of a composition, continue from start of composition */ 5193 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil) 5194 && beg < IT_CHARPOS (*it)) 5195 goto replaced; 5196 5197 /* If newline is replaced by a display property, find start of overlay 5198 or interval and continue search from that point. */ 5199 it2 = *it; 5200 pos = --IT_CHARPOS (it2); 5201 --IT_BYTEPOS (it2); 5202 it2.sp = 0; 5203 if (handle_display_prop (&it2) == HANDLED_RETURN 5204 && !NILP (val = get_char_property_and_overlay 5205 (make_number (pos), Qdisplay, Qnil, &overlay)) 5206 && (OVERLAYP (overlay) 5207 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) 5208 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) 5209 goto replaced; 5210 5211 /* Newline is not replaced by anything -- so we are done. */ 5212 break; 5213 5214 replaced: 5215 if (beg < BEGV) 5216 beg = BEGV; 5217 IT_CHARPOS (*it) = beg; 5218 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg); 5219 } 5220 } 5221 5222 it->continuation_lines_width = 0; 5223 5224 xassert (IT_CHARPOS (*it) >= BEGV); 5225 xassert (IT_CHARPOS (*it) == BEGV 5226 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n'); 5227 CHECK_IT (it); 5228} 5229 5230 5231/* Reseat iterator IT at the previous visible line start. Skip 5232 invisible text that is so either due to text properties or due to 5233 selective display. At the end, update IT's overlay information, 5234 face information etc. */ 5235 5236void 5237reseat_at_previous_visible_line_start (it) 5238 struct it *it; 5239{ 5240 back_to_previous_visible_line_start (it); 5241 reseat (it, it->current.pos, 1); 5242 CHECK_IT (it); 5243} 5244 5245 5246/* Reseat iterator IT on the next visible line start in the current 5247 buffer. ON_NEWLINE_P non-zero means position IT on the newline 5248 preceding the line start. Skip over invisible text that is so 5249 because of selective display. Compute faces, overlays etc at the 5250 new position. Note that this function does not skip over text that 5251 is invisible because of text properties. */ 5252 5253static void 5254reseat_at_next_visible_line_start (it, on_newline_p) 5255 struct it *it; 5256 int on_newline_p; 5257{ 5258 int newline_found_p, skipped_p = 0; 5259 5260 newline_found_p = forward_to_next_line_start (it, &skipped_p); 5261 5262 /* Skip over lines that are invisible because they are indented 5263 more than the value of IT->selective. */ 5264 if (it->selective > 0) 5265 while (IT_CHARPOS (*it) < ZV 5266 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it), 5267 (double) it->selective)) /* iftc */ 5268 { 5269 xassert (IT_BYTEPOS (*it) == BEGV 5270 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n'); 5271 newline_found_p = forward_to_next_line_start (it, &skipped_p); 5272 } 5273 5274 /* Position on the newline if that's what's requested. */ 5275 if (on_newline_p && newline_found_p) 5276 { 5277 if (STRINGP (it->string)) 5278 { 5279 if (IT_STRING_CHARPOS (*it) > 0) 5280 { 5281 --IT_STRING_CHARPOS (*it); 5282 --IT_STRING_BYTEPOS (*it); 5283 } 5284 } 5285 else if (IT_CHARPOS (*it) > BEGV) 5286 { 5287 --IT_CHARPOS (*it); 5288 --IT_BYTEPOS (*it); 5289 reseat (it, it->current.pos, 0); 5290 } 5291 } 5292 else if (skipped_p) 5293 reseat (it, it->current.pos, 0); 5294 5295 CHECK_IT (it); 5296} 5297 5298 5299 5300/*********************************************************************** 5301 Changing an iterator's position 5302***********************************************************************/ 5303 5304/* Change IT's current position to POS in current_buffer. If FORCE_P 5305 is non-zero, always check for text properties at the new position. 5306 Otherwise, text properties are only looked up if POS >= 5307 IT->check_charpos of a property. */ 5308 5309static void 5310reseat (it, pos, force_p) 5311 struct it *it; 5312 struct text_pos pos; 5313 int force_p; 5314{ 5315 int original_pos = IT_CHARPOS (*it); 5316 5317 reseat_1 (it, pos, 0); 5318 5319 /* Determine where to check text properties. Avoid doing it 5320 where possible because text property lookup is very expensive. */ 5321 if (force_p 5322 || CHARPOS (pos) > it->stop_charpos 5323 || CHARPOS (pos) < original_pos) 5324 handle_stop (it); 5325 5326 CHECK_IT (it); 5327} 5328 5329 5330/* Change IT's buffer position to POS. SET_STOP_P non-zero means set 5331 IT->stop_pos to POS, also. */ 5332 5333static void 5334reseat_1 (it, pos, set_stop_p) 5335 struct it *it; 5336 struct text_pos pos; 5337 int set_stop_p; 5338{ 5339 /* Don't call this function when scanning a C string. */ 5340 xassert (it->s == NULL); 5341 5342 /* POS must be a reasonable value. */ 5343 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV); 5344 5345 it->current.pos = it->position = pos; 5346 it->end_charpos = ZV; 5347 it->dpvec = NULL; 5348 it->current.dpvec_index = -1; 5349 it->current.overlay_string_index = -1; 5350 IT_STRING_CHARPOS (*it) = -1; 5351 IT_STRING_BYTEPOS (*it) = -1; 5352 it->string = Qnil; 5353 it->method = GET_FROM_BUFFER; 5354 it->object = it->w->buffer; 5355 it->area = TEXT_AREA; 5356 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); 5357 it->sp = 0; 5358 it->string_from_display_prop_p = 0; 5359 it->face_before_selective_p = 0; 5360 5361 if (set_stop_p) 5362 it->stop_charpos = CHARPOS (pos); 5363} 5364 5365 5366/* Set up IT for displaying a string, starting at CHARPOS in window W. 5367 If S is non-null, it is a C string to iterate over. Otherwise, 5368 STRING gives a Lisp string to iterate over. 5369 5370 If PRECISION > 0, don't return more then PRECISION number of 5371 characters from the string. 5372 5373 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH 5374 characters have been returned. FIELD_WIDTH < 0 means an infinite 5375 field width. 5376 5377 MULTIBYTE = 0 means disable processing of multibyte characters, 5378 MULTIBYTE > 0 means enable it, 5379 MULTIBYTE < 0 means use IT->multibyte_p. 5380 5381 IT must be initialized via a prior call to init_iterator before 5382 calling this function. */ 5383 5384static void 5385reseat_to_string (it, s, string, charpos, precision, field_width, multibyte) 5386 struct it *it; 5387 unsigned char *s; 5388 Lisp_Object string; 5389 int charpos; 5390 int precision, field_width, multibyte; 5391{ 5392 /* No region in strings. */ 5393 it->region_beg_charpos = it->region_end_charpos = -1; 5394 5395 /* No text property checks performed by default, but see below. */ 5396 it->stop_charpos = -1; 5397 5398 /* Set iterator position and end position. */ 5399 bzero (&it->current, sizeof it->current); 5400 it->current.overlay_string_index = -1; 5401 it->current.dpvec_index = -1; 5402 xassert (charpos >= 0); 5403 5404 /* If STRING is specified, use its multibyteness, otherwise use the 5405 setting of MULTIBYTE, if specified. */ 5406 if (multibyte >= 0) 5407 it->multibyte_p = multibyte > 0; 5408 5409 if (s == NULL) 5410 { 5411 xassert (STRINGP (string)); 5412 it->string = string; 5413 it->s = NULL; 5414 it->end_charpos = it->string_nchars = SCHARS (string); 5415 it->method = GET_FROM_STRING; 5416 it->current.string_pos = string_pos (charpos, string); 5417 } 5418 else 5419 { 5420 it->s = s; 5421 it->string = Qnil; 5422 5423 /* Note that we use IT->current.pos, not it->current.string_pos, 5424 for displaying C strings. */ 5425 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; 5426 if (it->multibyte_p) 5427 { 5428 it->current.pos = c_string_pos (charpos, s, 1); 5429 it->end_charpos = it->string_nchars = number_of_chars (s, 1); 5430 } 5431 else 5432 { 5433 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos; 5434 it->end_charpos = it->string_nchars = strlen (s); 5435 } 5436 5437 it->method = GET_FROM_C_STRING; 5438 } 5439 5440 /* PRECISION > 0 means don't return more than PRECISION characters 5441 from the string. */ 5442 if (precision > 0 && it->end_charpos - charpos > precision) 5443 it->end_charpos = it->string_nchars = charpos + precision; 5444 5445 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH 5446 characters have been returned. FIELD_WIDTH == 0 means don't pad, 5447 FIELD_WIDTH < 0 means infinite field width. This is useful for 5448 padding with `-' at the end of a mode line. */ 5449 if (field_width < 0) 5450 field_width = INFINITY; 5451 if (field_width > it->end_charpos - charpos) 5452 it->end_charpos = charpos + field_width; 5453 5454 /* Use the standard display table for displaying strings. */ 5455 if (DISP_TABLE_P (Vstandard_display_table)) 5456 it->dp = XCHAR_TABLE (Vstandard_display_table); 5457 5458 it->stop_charpos = charpos; 5459 CHECK_IT (it); 5460} 5461 5462 5463 5464/*********************************************************************** 5465 Iteration 5466 ***********************************************************************/ 5467 5468/* Map enum it_method value to corresponding next_element_from_* function. */ 5469 5470static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) = 5471{ 5472 next_element_from_buffer, 5473 next_element_from_display_vector, 5474 next_element_from_composition, 5475 next_element_from_string, 5476 next_element_from_c_string, 5477 next_element_from_image, 5478 next_element_from_stretch 5479}; 5480 5481 5482/* Load IT's display element fields with information about the next 5483 display element from the current position of IT. Value is zero if 5484 end of buffer (or C string) is reached. */ 5485 5486static struct frame *last_escape_glyph_frame = NULL; 5487static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS); 5488static int last_escape_glyph_merged_face_id = 0; 5489 5490int 5491get_next_display_element (it) 5492 struct it *it; 5493{ 5494 /* Non-zero means that we found a display element. Zero means that 5495 we hit the end of what we iterate over. Performance note: the 5496 function pointer `method' used here turns out to be faster than 5497 using a sequence of if-statements. */ 5498 int success_p; 5499 5500 get_next: 5501 success_p = (*get_next_element[it->method]) (it); 5502 5503 if (it->what == IT_CHARACTER) 5504 { 5505 /* Map via display table or translate control characters. 5506 IT->c, IT->len etc. have been set to the next character by 5507 the function call above. If we have a display table, and it 5508 contains an entry for IT->c, translate it. Don't do this if 5509 IT->c itself comes from a display table, otherwise we could 5510 end up in an infinite recursion. (An alternative could be to 5511 count the recursion depth of this function and signal an 5512 error when a certain maximum depth is reached.) Is it worth 5513 it? */ 5514 if (success_p && it->dpvec == NULL) 5515 { 5516 Lisp_Object dv; 5517 5518 if (it->dp 5519 && (dv = DISP_CHAR_VECTOR (it->dp, it->c), 5520 VECTORP (dv))) 5521 { 5522 struct Lisp_Vector *v = XVECTOR (dv); 5523 5524 /* Return the first character from the display table 5525 entry, if not empty. If empty, don't display the 5526 current character. */ 5527 if (v->size) 5528 { 5529 it->dpvec_char_len = it->len; 5530 it->dpvec = v->contents; 5531 it->dpend = v->contents + v->size; 5532 it->current.dpvec_index = 0; 5533 it->dpvec_face_id = -1; 5534 it->saved_face_id = it->face_id; 5535 it->method = GET_FROM_DISPLAY_VECTOR; 5536 it->ellipsis_p = 0; 5537 } 5538 else 5539 { 5540 set_iterator_to_next (it, 0); 5541 } 5542 goto get_next; 5543 } 5544 5545 /* Translate control characters into `\003' or `^C' form. 5546 Control characters coming from a display table entry are 5547 currently not translated because we use IT->dpvec to hold 5548 the translation. This could easily be changed but I 5549 don't believe that it is worth doing. 5550 5551 If it->multibyte_p is nonzero, eight-bit characters and 5552 non-printable multibyte characters are also translated to 5553 octal form. 5554 5555 If it->multibyte_p is zero, eight-bit characters that 5556 don't have corresponding multibyte char code are also 5557 translated to octal form. */ 5558 else if ((it->c < ' ' 5559 && (it->area != TEXT_AREA 5560 /* In mode line, treat \n like other crl chars. */ 5561 || (it->c != '\t' 5562 && it->glyph_row && it->glyph_row->mode_line_p) 5563 || (it->c != '\n' && it->c != '\t'))) 5564 || (it->multibyte_p 5565 ? ((it->c >= 127 5566 && it->len == 1) 5567 || !CHAR_PRINTABLE_P (it->c) 5568 || (!NILP (Vnobreak_char_display) 5569 && (it->c == 0x8a0 || it->c == 0x8ad 5570 || it->c == 0x920 || it->c == 0x92d 5571 || it->c == 0xe20 || it->c == 0xe2d 5572 || it->c == 0xf20 || it->c == 0xf2d))) 5573 : (it->c >= 127 5574 && (!unibyte_display_via_language_environment 5575 || it->c == unibyte_char_to_multibyte (it->c))))) 5576 { 5577 /* IT->c is a control character which must be displayed 5578 either as '\003' or as `^C' where the '\\' and '^' 5579 can be defined in the display table. Fill 5580 IT->ctl_chars with glyphs for what we have to 5581 display. Then, set IT->dpvec to these glyphs. */ 5582 GLYPH g; 5583 int ctl_len; 5584 int face_id, lface_id = 0 ; 5585 GLYPH escape_glyph; 5586 5587 /* Handle control characters with ^. */ 5588 5589 if (it->c < 128 && it->ctl_arrow_p) 5590 { 5591 g = '^'; /* default glyph for Control */ 5592 /* Set IT->ctl_chars[0] to the glyph for `^'. */ 5593 if (it->dp 5594 && INTEGERP (DISP_CTRL_GLYPH (it->dp)) 5595 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp)))) 5596 { 5597 g = XINT (DISP_CTRL_GLYPH (it->dp)); 5598 lface_id = FAST_GLYPH_FACE (g); 5599 } 5600 if (lface_id) 5601 { 5602 g = FAST_GLYPH_CHAR (g); 5603 face_id = merge_faces (it->f, Qt, lface_id, 5604 it->face_id); 5605 } 5606 else if (it->f == last_escape_glyph_frame 5607 && it->face_id == last_escape_glyph_face_id) 5608 { 5609 face_id = last_escape_glyph_merged_face_id; 5610 } 5611 else 5612 { 5613 /* Merge the escape-glyph face into the current face. */ 5614 face_id = merge_faces (it->f, Qescape_glyph, 0, 5615 it->face_id); 5616 last_escape_glyph_frame = it->f; 5617 last_escape_glyph_face_id = it->face_id; 5618 last_escape_glyph_merged_face_id = face_id; 5619 } 5620 5621 XSETINT (it->ctl_chars[0], g); 5622 g = it->c ^ 0100; 5623 XSETINT (it->ctl_chars[1], g); 5624 ctl_len = 2; 5625 goto display_control; 5626 } 5627 5628 /* Handle non-break space in the mode where it only gets 5629 highlighting. */ 5630 5631 if (EQ (Vnobreak_char_display, Qt) 5632 && (it->c == 0x8a0 || it->c == 0x920 5633 || it->c == 0xe20 || it->c == 0xf20)) 5634 { 5635 /* Merge the no-break-space face into the current face. */ 5636 face_id = merge_faces (it->f, Qnobreak_space, 0, 5637 it->face_id); 5638 5639 g = it->c = ' '; 5640 XSETINT (it->ctl_chars[0], g); 5641 ctl_len = 1; 5642 goto display_control; 5643 } 5644 5645 /* Handle sequences that start with the "escape glyph". */ 5646 5647 /* the default escape glyph is \. */ 5648 escape_glyph = '\\'; 5649 5650 if (it->dp 5651 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp)) 5652 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp)))) 5653 { 5654 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp)); 5655 lface_id = FAST_GLYPH_FACE (escape_glyph); 5656 } 5657 if (lface_id) 5658 { 5659 /* The display table specified a face. 5660 Merge it into face_id and also into escape_glyph. */ 5661 escape_glyph = FAST_GLYPH_CHAR (escape_glyph); 5662 face_id = merge_faces (it->f, Qt, lface_id, 5663 it->face_id); 5664 } 5665 else if (it->f == last_escape_glyph_frame 5666 && it->face_id == last_escape_glyph_face_id) 5667 { 5668 face_id = last_escape_glyph_merged_face_id; 5669 } 5670 else 5671 { 5672 /* Merge the escape-glyph face into the current face. */ 5673 face_id = merge_faces (it->f, Qescape_glyph, 0, 5674 it->face_id); 5675 last_escape_glyph_frame = it->f; 5676 last_escape_glyph_face_id = it->face_id; 5677 last_escape_glyph_merged_face_id = face_id; 5678 } 5679 5680 /* Handle soft hyphens in the mode where they only get 5681 highlighting. */ 5682 5683 if (EQ (Vnobreak_char_display, Qt) 5684 && (it->c == 0x8ad || it->c == 0x92d 5685 || it->c == 0xe2d || it->c == 0xf2d)) 5686 { 5687 g = it->c = '-'; 5688 XSETINT (it->ctl_chars[0], g); 5689 ctl_len = 1; 5690 goto display_control; 5691 } 5692 5693 /* Handle non-break space and soft hyphen 5694 with the escape glyph. */ 5695 5696 if (it->c == 0x8a0 || it->c == 0x8ad 5697 || it->c == 0x920 || it->c == 0x92d 5698 || it->c == 0xe20 || it->c == 0xe2d 5699 || it->c == 0xf20 || it->c == 0xf2d) 5700 { 5701 XSETINT (it->ctl_chars[0], escape_glyph); 5702 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-'); 5703 XSETINT (it->ctl_chars[1], g); 5704 ctl_len = 2; 5705 goto display_control; 5706 } 5707 5708 { 5709 unsigned char str[MAX_MULTIBYTE_LENGTH]; 5710 int len; 5711 int i; 5712 5713 /* Set IT->ctl_chars[0] to the glyph for `\\'. */ 5714 if (SINGLE_BYTE_CHAR_P (it->c)) 5715 str[0] = it->c, len = 1; 5716 else 5717 { 5718 len = CHAR_STRING_NO_SIGNAL (it->c, str); 5719 if (len < 0) 5720 { 5721 /* It's an invalid character, which shouldn't 5722 happen actually, but due to bugs it may 5723 happen. Let's print the char as is, there's 5724 not much meaningful we can do with it. */ 5725 str[0] = it->c; 5726 str[1] = it->c >> 8; 5727 str[2] = it->c >> 16; 5728 str[3] = it->c >> 24; 5729 len = 4; 5730 } 5731 } 5732 5733 for (i = 0; i < len; i++) 5734 { 5735 XSETINT (it->ctl_chars[i * 4], escape_glyph); 5736 /* Insert three more glyphs into IT->ctl_chars for 5737 the octal display of the character. */ 5738 g = ((str[i] >> 6) & 7) + '0'; 5739 XSETINT (it->ctl_chars[i * 4 + 1], g); 5740 g = ((str[i] >> 3) & 7) + '0'; 5741 XSETINT (it->ctl_chars[i * 4 + 2], g); 5742 g = (str[i] & 7) + '0'; 5743 XSETINT (it->ctl_chars[i * 4 + 3], g); 5744 } 5745 ctl_len = len * 4; 5746 } 5747 5748 display_control: 5749 /* Set up IT->dpvec and return first character from it. */ 5750 it->dpvec_char_len = it->len; 5751 it->dpvec = it->ctl_chars; 5752 it->dpend = it->dpvec + ctl_len; 5753 it->current.dpvec_index = 0; 5754 it->dpvec_face_id = face_id; 5755 it->saved_face_id = it->face_id; 5756 it->method = GET_FROM_DISPLAY_VECTOR; 5757 it->ellipsis_p = 0; 5758 goto get_next; 5759 } 5760 } 5761 5762 /* Adjust face id for a multibyte character. There are no 5763 multibyte character in unibyte text. */ 5764 if (it->multibyte_p 5765 && success_p 5766 && FRAME_WINDOW_P (it->f)) 5767 { 5768 struct face *face = FACE_FROM_ID (it->f, it->face_id); 5769 it->face_id = FACE_FOR_CHAR (it->f, face, it->c); 5770 } 5771 } 5772 5773 /* Is this character the last one of a run of characters with 5774 box? If yes, set IT->end_of_box_run_p to 1. */ 5775 if (it->face_box_p 5776 && it->s == NULL) 5777 { 5778 int face_id; 5779 struct face *face; 5780 5781 it->end_of_box_run_p 5782 = ((face_id = face_after_it_pos (it), 5783 face_id != it->face_id) 5784 && (face = FACE_FROM_ID (it->f, face_id), 5785 face->box == FACE_NO_BOX)); 5786 } 5787 5788 /* Value is 0 if end of buffer or string reached. */ 5789 return success_p; 5790} 5791 5792 5793/* Move IT to the next display element. 5794 5795 RESEAT_P non-zero means if called on a newline in buffer text, 5796 skip to the next visible line start. 5797 5798 Functions get_next_display_element and set_iterator_to_next are 5799 separate because I find this arrangement easier to handle than a 5800 get_next_display_element function that also increments IT's 5801 position. The way it is we can first look at an iterator's current 5802 display element, decide whether it fits on a line, and if it does, 5803 increment the iterator position. The other way around we probably 5804 would either need a flag indicating whether the iterator has to be 5805 incremented the next time, or we would have to implement a 5806 decrement position function which would not be easy to write. */ 5807 5808void 5809set_iterator_to_next (it, reseat_p) 5810 struct it *it; 5811 int reseat_p; 5812{ 5813 /* Reset flags indicating start and end of a sequence of characters 5814 with box. Reset them at the start of this function because 5815 moving the iterator to a new position might set them. */ 5816 it->start_of_box_run_p = it->end_of_box_run_p = 0; 5817 5818 switch (it->method) 5819 { 5820 case GET_FROM_BUFFER: 5821 /* The current display element of IT is a character from 5822 current_buffer. Advance in the buffer, and maybe skip over 5823 invisible lines that are so because of selective display. */ 5824 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p) 5825 reseat_at_next_visible_line_start (it, 0); 5826 else 5827 { 5828 xassert (it->len != 0); 5829 IT_BYTEPOS (*it) += it->len; 5830 IT_CHARPOS (*it) += 1; 5831 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); 5832 } 5833 break; 5834 5835 case GET_FROM_COMPOSITION: 5836 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions); 5837 xassert (it->sp > 0); 5838 pop_it (it); 5839 if (it->method == GET_FROM_STRING) 5840 { 5841 IT_STRING_BYTEPOS (*it) += it->len; 5842 IT_STRING_CHARPOS (*it) += it->cmp_len; 5843 goto consider_string_end; 5844 } 5845 else if (it->method == GET_FROM_BUFFER) 5846 { 5847 IT_BYTEPOS (*it) += it->len; 5848 IT_CHARPOS (*it) += it->cmp_len; 5849 } 5850 break; 5851 5852 case GET_FROM_C_STRING: 5853 /* Current display element of IT is from a C string. */ 5854 IT_BYTEPOS (*it) += it->len; 5855 IT_CHARPOS (*it) += 1; 5856 break; 5857 5858 case GET_FROM_DISPLAY_VECTOR: 5859 /* Current display element of IT is from a display table entry. 5860 Advance in the display table definition. Reset it to null if 5861 end reached, and continue with characters from buffers/ 5862 strings. */ 5863 ++it->current.dpvec_index; 5864 5865 /* Restore face of the iterator to what they were before the 5866 display vector entry (these entries may contain faces). */ 5867 it->face_id = it->saved_face_id; 5868 5869 if (it->dpvec + it->current.dpvec_index == it->dpend) 5870 { 5871 int recheck_faces = it->ellipsis_p; 5872 5873 if (it->s) 5874 it->method = GET_FROM_C_STRING; 5875 else if (STRINGP (it->string)) 5876 it->method = GET_FROM_STRING; 5877 else 5878 { 5879 it->method = GET_FROM_BUFFER; 5880 it->object = it->w->buffer; 5881 } 5882 5883 it->dpvec = NULL; 5884 it->current.dpvec_index = -1; 5885 5886 /* Skip over characters which were displayed via IT->dpvec. */ 5887 if (it->dpvec_char_len < 0) 5888 reseat_at_next_visible_line_start (it, 1); 5889 else if (it->dpvec_char_len > 0) 5890 { 5891 if (it->method == GET_FROM_STRING 5892 && it->n_overlay_strings > 0) 5893 it->ignore_overlay_strings_at_pos_p = 1; 5894 it->len = it->dpvec_char_len; 5895 set_iterator_to_next (it, reseat_p); 5896 } 5897 5898 /* Maybe recheck faces after display vector */ 5899 if (recheck_faces) 5900 it->stop_charpos = IT_CHARPOS (*it); 5901 } 5902 break; 5903 5904 case GET_FROM_STRING: 5905 /* Current display element is a character from a Lisp string. */ 5906 xassert (it->s == NULL && STRINGP (it->string)); 5907 IT_STRING_BYTEPOS (*it) += it->len; 5908 IT_STRING_CHARPOS (*it) += 1; 5909 5910 consider_string_end: 5911 5912 if (it->current.overlay_string_index >= 0) 5913 { 5914 /* IT->string is an overlay string. Advance to the 5915 next, if there is one. */ 5916 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)) 5917 next_overlay_string (it); 5918 } 5919 else 5920 { 5921 /* IT->string is not an overlay string. If we reached 5922 its end, and there is something on IT->stack, proceed 5923 with what is on the stack. This can be either another 5924 string, this time an overlay string, or a buffer. */ 5925 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string) 5926 && it->sp > 0) 5927 { 5928 pop_it (it); 5929 if (it->method == GET_FROM_STRING) 5930 goto consider_string_end; 5931 } 5932 } 5933 break; 5934 5935 case GET_FROM_IMAGE: 5936 case GET_FROM_STRETCH: 5937 /* The position etc with which we have to proceed are on 5938 the stack. The position may be at the end of a string, 5939 if the `display' property takes up the whole string. */ 5940 xassert (it->sp > 0); 5941 pop_it (it); 5942 if (it->method == GET_FROM_STRING) 5943 goto consider_string_end; 5944 break; 5945 5946 default: 5947 /* There are no other methods defined, so this should be a bug. */ 5948 abort (); 5949 } 5950 5951 xassert (it->method != GET_FROM_STRING 5952 || (STRINGP (it->string) 5953 && IT_STRING_CHARPOS (*it) >= 0)); 5954} 5955 5956/* Load IT's display element fields with information about the next 5957 display element which comes from a display table entry or from the 5958 result of translating a control character to one of the forms `^C' 5959 or `\003'. 5960 5961 IT->dpvec holds the glyphs to return as characters. 5962 IT->saved_face_id holds the face id before the display vector-- 5963 it is restored into IT->face_idin set_iterator_to_next. */ 5964 5965static int 5966next_element_from_display_vector (it) 5967 struct it *it; 5968{ 5969 /* Precondition. */ 5970 xassert (it->dpvec && it->current.dpvec_index >= 0); 5971 5972 it->face_id = it->saved_face_id; 5973 5974 if (INTEGERP (*it->dpvec) 5975 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec))) 5976 { 5977 GLYPH g; 5978 5979 g = XFASTINT (it->dpvec[it->current.dpvec_index]); 5980 it->c = FAST_GLYPH_CHAR (g); 5981 it->len = CHAR_BYTES (it->c); 5982 5983 /* The entry may contain a face id to use. Such a face id is 5984 the id of a Lisp face, not a realized face. A face id of 5985 zero means no face is specified. */ 5986 if (it->dpvec_face_id >= 0) 5987 it->face_id = it->dpvec_face_id; 5988 else 5989 { 5990 int lface_id = FAST_GLYPH_FACE (g); 5991 if (lface_id > 0) 5992 it->face_id = merge_faces (it->f, Qt, lface_id, 5993 it->saved_face_id); 5994 } 5995 } 5996 else 5997 /* Display table entry is invalid. Return a space. */ 5998 it->c = ' ', it->len = 1; 5999 6000 /* Don't change position and object of the iterator here. They are 6001 still the values of the character that had this display table 6002 entry or was translated, and that's what we want. */ 6003 it->what = IT_CHARACTER; 6004 return 1; 6005} 6006 6007 6008/* Load IT with the next display element from Lisp string IT->string. 6009 IT->current.string_pos is the current position within the string. 6010 If IT->current.overlay_string_index >= 0, the Lisp string is an 6011 overlay string. */ 6012 6013static int 6014next_element_from_string (it) 6015 struct it *it; 6016{ 6017 struct text_pos position; 6018 6019 xassert (STRINGP (it->string)); 6020 xassert (IT_STRING_CHARPOS (*it) >= 0); 6021 position = it->current.string_pos; 6022 6023 /* Time to check for invisible text? */ 6024 if (IT_STRING_CHARPOS (*it) < it->end_charpos 6025 && IT_STRING_CHARPOS (*it) == it->stop_charpos) 6026 { 6027 handle_stop (it); 6028 6029 /* Since a handler may have changed IT->method, we must 6030 recurse here. */ 6031 return get_next_display_element (it); 6032 } 6033 6034 if (it->current.overlay_string_index >= 0) 6035 { 6036 /* Get the next character from an overlay string. In overlay 6037 strings, There is no field width or padding with spaces to 6038 do. */ 6039 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)) 6040 { 6041 it->what = IT_EOB; 6042 return 0; 6043 } 6044 else if (STRING_MULTIBYTE (it->string)) 6045 { 6046 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it); 6047 const unsigned char *s = (SDATA (it->string) 6048 + IT_STRING_BYTEPOS (*it)); 6049 it->c = string_char_and_length (s, remaining, &it->len); 6050 } 6051 else 6052 { 6053 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it)); 6054 it->len = 1; 6055 } 6056 } 6057 else 6058 { 6059 /* Get the next character from a Lisp string that is not an 6060 overlay string. Such strings come from the mode line, for 6061 example. We may have to pad with spaces, or truncate the 6062 string. See also next_element_from_c_string. */ 6063 if (IT_STRING_CHARPOS (*it) >= it->end_charpos) 6064 { 6065 it->what = IT_EOB; 6066 return 0; 6067 } 6068 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars) 6069 { 6070 /* Pad with spaces. */ 6071 it->c = ' ', it->len = 1; 6072 CHARPOS (position) = BYTEPOS (position) = -1; 6073 } 6074 else if (STRING_MULTIBYTE (it->string)) 6075 { 6076 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it); 6077 const unsigned char *s = (SDATA (it->string) 6078 + IT_STRING_BYTEPOS (*it)); 6079 it->c = string_char_and_length (s, maxlen, &it->len); 6080 } 6081 else 6082 { 6083 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it)); 6084 it->len = 1; 6085 } 6086 } 6087 6088 /* Record what we have and where it came from. */ 6089 it->what = IT_CHARACTER; 6090 it->object = it->string; 6091 it->position = position; 6092 return 1; 6093} 6094 6095 6096/* Load IT with next display element from C string IT->s. 6097 IT->string_nchars is the maximum number of characters to return 6098 from the string. IT->end_charpos may be greater than 6099 IT->string_nchars when this function is called, in which case we 6100 may have to return padding spaces. Value is zero if end of string 6101 reached, including padding spaces. */ 6102 6103static int 6104next_element_from_c_string (it) 6105 struct it *it; 6106{ 6107 int success_p = 1; 6108 6109 xassert (it->s); 6110 it->what = IT_CHARACTER; 6111 BYTEPOS (it->position) = CHARPOS (it->position) = 0; 6112 it->object = Qnil; 6113 6114 /* IT's position can be greater IT->string_nchars in case a field 6115 width or precision has been specified when the iterator was 6116 initialized. */ 6117 if (IT_CHARPOS (*it) >= it->end_charpos) 6118 { 6119 /* End of the game. */ 6120 it->what = IT_EOB; 6121 success_p = 0; 6122 } 6123 else if (IT_CHARPOS (*it) >= it->string_nchars) 6124 { 6125 /* Pad with spaces. */ 6126 it->c = ' ', it->len = 1; 6127 BYTEPOS (it->position) = CHARPOS (it->position) = -1; 6128 } 6129 else if (it->multibyte_p) 6130 { 6131 /* Implementation note: The calls to strlen apparently aren't a 6132 performance problem because there is no noticeable performance 6133 difference between Emacs running in unibyte or multibyte mode. */ 6134 int maxlen = strlen (it->s) - IT_BYTEPOS (*it); 6135 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), 6136 maxlen, &it->len); 6137 } 6138 else 6139 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1; 6140 6141 return success_p; 6142} 6143 6144 6145/* Set up IT to return characters from an ellipsis, if appropriate. 6146 The definition of the ellipsis glyphs may come from a display table 6147 entry. This function Fills IT with the first glyph from the 6148 ellipsis if an ellipsis is to be displayed. */ 6149 6150static int 6151next_element_from_ellipsis (it) 6152 struct it *it; 6153{ 6154 if (it->selective_display_ellipsis_p) 6155 setup_for_ellipsis (it, it->len); 6156 else 6157 { 6158 /* The face at the current position may be different from the 6159 face we find after the invisible text. Remember what it 6160 was in IT->saved_face_id, and signal that it's there by 6161 setting face_before_selective_p. */ 6162 it->saved_face_id = it->face_id; 6163 it->method = GET_FROM_BUFFER; 6164 it->object = it->w->buffer; 6165 reseat_at_next_visible_line_start (it, 1); 6166 it->face_before_selective_p = 1; 6167 } 6168 6169 return get_next_display_element (it); 6170} 6171 6172 6173/* Deliver an image display element. The iterator IT is already 6174 filled with image information (done in handle_display_prop). Value 6175 is always 1. */ 6176 6177 6178static int 6179next_element_from_image (it) 6180 struct it *it; 6181{ 6182 it->what = IT_IMAGE; 6183 return 1; 6184} 6185 6186 6187/* Fill iterator IT with next display element from a stretch glyph 6188 property. IT->object is the value of the text property. Value is 6189 always 1. */ 6190 6191static int 6192next_element_from_stretch (it) 6193 struct it *it; 6194{ 6195 it->what = IT_STRETCH; 6196 return 1; 6197} 6198 6199 6200/* Load IT with the next display element from current_buffer. Value 6201 is zero if end of buffer reached. IT->stop_charpos is the next 6202 position at which to stop and check for text properties or buffer 6203 end. */ 6204 6205static int 6206next_element_from_buffer (it) 6207 struct it *it; 6208{ 6209 int success_p = 1; 6210 6211 /* Check this assumption, otherwise, we would never enter the 6212 if-statement, below. */ 6213 xassert (IT_CHARPOS (*it) >= BEGV 6214 && IT_CHARPOS (*it) <= it->stop_charpos); 6215 6216 if (IT_CHARPOS (*it) >= it->stop_charpos) 6217 { 6218 if (IT_CHARPOS (*it) >= it->end_charpos) 6219 { 6220 int overlay_strings_follow_p; 6221 6222 /* End of the game, except when overlay strings follow that 6223 haven't been returned yet. */ 6224 if (it->overlay_strings_at_end_processed_p) 6225 overlay_strings_follow_p = 0; 6226 else 6227 { 6228 it->overlay_strings_at_end_processed_p = 1; 6229 overlay_strings_follow_p = get_overlay_strings (it, 0); 6230 } 6231 6232 if (overlay_strings_follow_p) 6233 success_p = get_next_display_element (it); 6234 else 6235 { 6236 it->what = IT_EOB; 6237 it->position = it->current.pos; 6238 success_p = 0; 6239 } 6240 } 6241 else 6242 { 6243 handle_stop (it); 6244 return get_next_display_element (it); 6245 } 6246 } 6247 else 6248 { 6249 /* No face changes, overlays etc. in sight, so just return a 6250 character from current_buffer. */ 6251 unsigned char *p; 6252 6253 /* Maybe run the redisplay end trigger hook. Performance note: 6254 This doesn't seem to cost measurable time. */ 6255 if (it->redisplay_end_trigger_charpos 6256 && it->glyph_row 6257 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos) 6258 run_redisplay_end_trigger_hook (it); 6259 6260 /* Get the next character, maybe multibyte. */ 6261 p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); 6262 if (it->multibyte_p && !ASCII_BYTE_P (*p)) 6263 { 6264 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE) 6265 - IT_BYTEPOS (*it)); 6266 it->c = string_char_and_length (p, maxlen, &it->len); 6267 } 6268 else 6269 it->c = *p, it->len = 1; 6270 6271 /* Record what we have and where it came from. */ 6272 it->what = IT_CHARACTER;; 6273 it->object = it->w->buffer; 6274 it->position = it->current.pos; 6275 6276 /* Normally we return the character found above, except when we 6277 really want to return an ellipsis for selective display. */ 6278 if (it->selective) 6279 { 6280 if (it->c == '\n') 6281 { 6282 /* A value of selective > 0 means hide lines indented more 6283 than that number of columns. */ 6284 if (it->selective > 0 6285 && IT_CHARPOS (*it) + 1 < ZV 6286 && indented_beyond_p (IT_CHARPOS (*it) + 1, 6287 IT_BYTEPOS (*it) + 1, 6288 (double) it->selective)) /* iftc */ 6289 { 6290 success_p = next_element_from_ellipsis (it); 6291 it->dpvec_char_len = -1; 6292 } 6293 } 6294 else if (it->c == '\r' && it->selective == -1) 6295 { 6296 /* A value of selective == -1 means that everything from the 6297 CR to the end of the line is invisible, with maybe an 6298 ellipsis displayed for it. */ 6299 success_p = next_element_from_ellipsis (it); 6300 it->dpvec_char_len = -1; 6301 } 6302 } 6303 } 6304 6305 /* Value is zero if end of buffer reached. */ 6306 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0); 6307 return success_p; 6308} 6309 6310 6311/* Run the redisplay end trigger hook for IT. */ 6312 6313static void 6314run_redisplay_end_trigger_hook (it) 6315 struct it *it; 6316{ 6317 Lisp_Object args[3]; 6318 6319 /* IT->glyph_row should be non-null, i.e. we should be actually 6320 displaying something, or otherwise we should not run the hook. */ 6321 xassert (it->glyph_row); 6322 6323 /* Set up hook arguments. */ 6324 args[0] = Qredisplay_end_trigger_functions; 6325 args[1] = it->window; 6326 XSETINT (args[2], it->redisplay_end_trigger_charpos); 6327 it->redisplay_end_trigger_charpos = 0; 6328 6329 /* Since we are *trying* to run these functions, don't try to run 6330 them again, even if they get an error. */ 6331 it->w->redisplay_end_trigger = Qnil; 6332 Frun_hook_with_args (3, args); 6333 6334 /* Notice if it changed the face of the character we are on. */ 6335 handle_face_prop (it); 6336} 6337 6338 6339/* Deliver a composition display element. The iterator IT is already 6340 filled with composition information (done in 6341 handle_composition_prop). Value is always 1. */ 6342 6343static int 6344next_element_from_composition (it) 6345 struct it *it; 6346{ 6347 it->what = IT_COMPOSITION; 6348 it->position = (STRINGP (it->string) 6349 ? it->current.string_pos 6350 : it->current.pos); 6351 if (STRINGP (it->string)) 6352 it->object = it->string; 6353 else 6354 it->object = it->w->buffer; 6355 return 1; 6356} 6357 6358 6359 6360/*********************************************************************** 6361 Moving an iterator without producing glyphs 6362 ***********************************************************************/ 6363 6364/* Check if iterator is at a position corresponding to a valid buffer 6365 position after some move_it_ call. */ 6366 6367#define IT_POS_VALID_AFTER_MOVE_P(it) \ 6368 ((it)->method == GET_FROM_STRING \ 6369 ? IT_STRING_CHARPOS (*it) == 0 \ 6370 : 1) 6371 6372 6373/* Move iterator IT to a specified buffer or X position within one 6374 line on the display without producing glyphs. 6375 6376 OP should be a bit mask including some or all of these bits: 6377 MOVE_TO_X: Stop on reaching x-position TO_X. 6378 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS. 6379 Regardless of OP's value, stop in reaching the end of the display line. 6380 6381 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x. 6382 This means, in particular, that TO_X includes window's horizontal 6383 scroll amount. 6384 6385 The return value has several possible values that 6386 say what condition caused the scan to stop: 6387 6388 MOVE_POS_MATCH_OR_ZV 6389 - when TO_POS or ZV was reached. 6390 6391 MOVE_X_REACHED 6392 -when TO_X was reached before TO_POS or ZV were reached. 6393 6394 MOVE_LINE_CONTINUED 6395 - when we reached the end of the display area and the line must 6396 be continued. 6397 6398 MOVE_LINE_TRUNCATED 6399 - when we reached the end of the display area and the line is 6400 truncated. 6401 6402 MOVE_NEWLINE_OR_CR 6403 - when we stopped at a line end, i.e. a newline or a CR and selective 6404 display is on. */ 6405 6406static enum move_it_result 6407move_it_in_display_line_to (it, to_charpos, to_x, op) 6408 struct it *it; 6409 int to_charpos, to_x, op; 6410{ 6411 enum move_it_result result = MOVE_UNDEFINED; 6412 struct glyph_row *saved_glyph_row; 6413 6414 /* Don't produce glyphs in produce_glyphs. */ 6415 saved_glyph_row = it->glyph_row; 6416 it->glyph_row = NULL; 6417 6418#define BUFFER_POS_REACHED_P() \ 6419 ((op & MOVE_TO_POS) != 0 \ 6420 && BUFFERP (it->object) \ 6421 && IT_CHARPOS (*it) >= to_charpos \ 6422 && (it->method == GET_FROM_BUFFER \ 6423 || (it->method == GET_FROM_DISPLAY_VECTOR \ 6424 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) 6425 6426 6427 while (1) 6428 { 6429 int x, i, ascent = 0, descent = 0; 6430 6431 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */ 6432 if ((op & MOVE_TO_POS) != 0 6433 && BUFFERP (it->object) 6434 && it->method == GET_FROM_BUFFER 6435 && IT_CHARPOS (*it) > to_charpos) 6436 { 6437 result = MOVE_POS_MATCH_OR_ZV; 6438 break; 6439 } 6440 6441 /* Stop when ZV reached. 6442 We used to stop here when TO_CHARPOS reached as well, but that is 6443 too soon if this glyph does not fit on this line. So we handle it 6444 explicitly below. */ 6445 if (!get_next_display_element (it) 6446 || (it->truncate_lines_p 6447 && BUFFER_POS_REACHED_P ())) 6448 { 6449 result = MOVE_POS_MATCH_OR_ZV; 6450 break; 6451 } 6452 6453 /* The call to produce_glyphs will get the metrics of the 6454 display element IT is loaded with. We record in x the 6455 x-position before this display element in case it does not 6456 fit on the line. */ 6457 x = it->current_x; 6458 6459 /* Remember the line height so far in case the next element doesn't 6460 fit on the line. */ 6461 if (!it->truncate_lines_p) 6462 { 6463 ascent = it->max_ascent; 6464 descent = it->max_descent; 6465 } 6466 6467 PRODUCE_GLYPHS (it); 6468 6469 if (it->area != TEXT_AREA) 6470 { 6471 set_iterator_to_next (it, 1); 6472 continue; 6473 } 6474 6475 /* The number of glyphs we get back in IT->nglyphs will normally 6476 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph 6477 character on a terminal frame, or (iii) a line end. For the 6478 second case, IT->nglyphs - 1 padding glyphs will be present 6479 (on X frames, there is only one glyph produced for a 6480 composite character. 6481 6482 The behavior implemented below means, for continuation lines, 6483 that as many spaces of a TAB as fit on the current line are 6484 displayed there. For terminal frames, as many glyphs of a 6485 multi-glyph character are displayed in the current line, too. 6486 This is what the old redisplay code did, and we keep it that 6487 way. Under X, the whole shape of a complex character must 6488 fit on the line or it will be completely displayed in the 6489 next line. 6490 6491 Note that both for tabs and padding glyphs, all glyphs have 6492 the same width. */ 6493 if (it->nglyphs) 6494 { 6495 /* More than one glyph or glyph doesn't fit on line. All 6496 glyphs have the same width. */ 6497 int single_glyph_width = it->pixel_width / it->nglyphs; 6498 int new_x; 6499 int x_before_this_char = x; 6500 int hpos_before_this_char = it->hpos; 6501 6502 for (i = 0; i < it->nglyphs; ++i, x = new_x) 6503 { 6504 new_x = x + single_glyph_width; 6505 6506 /* We want to leave anything reaching TO_X to the caller. */ 6507 if ((op & MOVE_TO_X) && new_x > to_x) 6508 { 6509 if (BUFFER_POS_REACHED_P ()) 6510 goto buffer_pos_reached; 6511 it->current_x = x; 6512 result = MOVE_X_REACHED; 6513 break; 6514 } 6515 else if (/* Lines are continued. */ 6516 !it->truncate_lines_p 6517 && (/* And glyph doesn't fit on the line. */ 6518 new_x > it->last_visible_x 6519 /* Or it fits exactly and we're on a window 6520 system frame. */ 6521 || (new_x == it->last_visible_x 6522 && FRAME_WINDOW_P (it->f)))) 6523 { 6524 if (/* IT->hpos == 0 means the very first glyph 6525 doesn't fit on the line, e.g. a wide image. */ 6526 it->hpos == 0 6527 || (new_x == it->last_visible_x 6528 && FRAME_WINDOW_P (it->f))) 6529 { 6530 ++it->hpos; 6531 it->current_x = new_x; 6532 6533 /* The character's last glyph just barely fits 6534 in this row. */ 6535 if (i == it->nglyphs - 1) 6536 { 6537 /* If this is the destination position, 6538 return a position *before* it in this row, 6539 now that we know it fits in this row. */ 6540 if (BUFFER_POS_REACHED_P ()) 6541 { 6542 it->hpos = hpos_before_this_char; 6543 it->current_x = x_before_this_char; 6544 result = MOVE_POS_MATCH_OR_ZV; 6545 break; 6546 } 6547 6548 set_iterator_to_next (it, 1); 6549#ifdef HAVE_WINDOW_SYSTEM 6550 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 6551 { 6552 if (!get_next_display_element (it)) 6553 { 6554 result = MOVE_POS_MATCH_OR_ZV; 6555 break; 6556 } 6557 if (BUFFER_POS_REACHED_P ()) 6558 { 6559 if (ITERATOR_AT_END_OF_LINE_P (it)) 6560 result = MOVE_POS_MATCH_OR_ZV; 6561 else 6562 result = MOVE_LINE_CONTINUED; 6563 break; 6564 } 6565 if (ITERATOR_AT_END_OF_LINE_P (it)) 6566 { 6567 result = MOVE_NEWLINE_OR_CR; 6568 break; 6569 } 6570 } 6571#endif /* HAVE_WINDOW_SYSTEM */ 6572 } 6573 } 6574 else 6575 { 6576 it->current_x = x; 6577 it->max_ascent = ascent; 6578 it->max_descent = descent; 6579 } 6580 6581 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n", 6582 IT_CHARPOS (*it))); 6583 result = MOVE_LINE_CONTINUED; 6584 break; 6585 } 6586 else if (BUFFER_POS_REACHED_P ()) 6587 goto buffer_pos_reached; 6588 else if (new_x > it->first_visible_x) 6589 { 6590 /* Glyph is visible. Increment number of glyphs that 6591 would be displayed. */ 6592 ++it->hpos; 6593 } 6594 else 6595 { 6596 /* Glyph is completely off the left margin of the display 6597 area. Nothing to do. */ 6598 } 6599 } 6600 6601 if (result != MOVE_UNDEFINED) 6602 break; 6603 } 6604 else if (BUFFER_POS_REACHED_P ()) 6605 { 6606 buffer_pos_reached: 6607 it->current_x = x; 6608 it->max_ascent = ascent; 6609 it->max_descent = descent; 6610 result = MOVE_POS_MATCH_OR_ZV; 6611 break; 6612 } 6613 else if ((op & MOVE_TO_X) && it->current_x >= to_x) 6614 { 6615 /* Stop when TO_X specified and reached. This check is 6616 necessary here because of lines consisting of a line end, 6617 only. The line end will not produce any glyphs and we 6618 would never get MOVE_X_REACHED. */ 6619 xassert (it->nglyphs == 0); 6620 result = MOVE_X_REACHED; 6621 break; 6622 } 6623 6624 /* Is this a line end? If yes, we're done. */ 6625 if (ITERATOR_AT_END_OF_LINE_P (it)) 6626 { 6627 result = MOVE_NEWLINE_OR_CR; 6628 break; 6629 } 6630 6631 /* The current display element has been consumed. Advance 6632 to the next. */ 6633 set_iterator_to_next (it, 1); 6634 6635 /* Stop if lines are truncated and IT's current x-position is 6636 past the right edge of the window now. */ 6637 if (it->truncate_lines_p 6638 && it->current_x >= it->last_visible_x) 6639 { 6640#ifdef HAVE_WINDOW_SYSTEM 6641 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 6642 { 6643 if (!get_next_display_element (it) 6644 || BUFFER_POS_REACHED_P ()) 6645 { 6646 result = MOVE_POS_MATCH_OR_ZV; 6647 break; 6648 } 6649 if (ITERATOR_AT_END_OF_LINE_P (it)) 6650 { 6651 result = MOVE_NEWLINE_OR_CR; 6652 break; 6653 } 6654 } 6655#endif /* HAVE_WINDOW_SYSTEM */ 6656 result = MOVE_LINE_TRUNCATED; 6657 break; 6658 } 6659 } 6660 6661#undef BUFFER_POS_REACHED_P 6662 6663 /* Restore the iterator settings altered at the beginning of this 6664 function. */ 6665 it->glyph_row = saved_glyph_row; 6666 return result; 6667} 6668 6669 6670/* Move IT forward until it satisfies one or more of the criteria in 6671 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS. 6672 6673 OP is a bit-mask that specifies where to stop, and in particular, 6674 which of those four position arguments makes a difference. See the 6675 description of enum move_operation_enum. 6676 6677 If TO_CHARPOS is in invisible text, e.g. a truncated part of a 6678 screen line, this function will set IT to the next position > 6679 TO_CHARPOS. */ 6680 6681void 6682move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) 6683 struct it *it; 6684 int to_charpos, to_x, to_y, to_vpos; 6685 int op; 6686{ 6687 enum move_it_result skip, skip2 = MOVE_X_REACHED; 6688 int line_height; 6689 int reached = 0; 6690 6691 for (;;) 6692 { 6693 if (op & MOVE_TO_VPOS) 6694 { 6695 /* If no TO_CHARPOS and no TO_X specified, stop at the 6696 start of the line TO_VPOS. */ 6697 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0) 6698 { 6699 if (it->vpos == to_vpos) 6700 { 6701 reached = 1; 6702 break; 6703 } 6704 else 6705 skip = move_it_in_display_line_to (it, -1, -1, 0); 6706 } 6707 else 6708 { 6709 /* TO_VPOS >= 0 means stop at TO_X in the line at 6710 TO_VPOS, or at TO_POS, whichever comes first. */ 6711 if (it->vpos == to_vpos) 6712 { 6713 reached = 2; 6714 break; 6715 } 6716 6717 skip = move_it_in_display_line_to (it, to_charpos, to_x, op); 6718 6719 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos) 6720 { 6721 reached = 3; 6722 break; 6723 } 6724 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos) 6725 { 6726 /* We have reached TO_X but not in the line we want. */ 6727 skip = move_it_in_display_line_to (it, to_charpos, 6728 -1, MOVE_TO_POS); 6729 if (skip == MOVE_POS_MATCH_OR_ZV) 6730 { 6731 reached = 4; 6732 break; 6733 } 6734 } 6735 } 6736 } 6737 else if (op & MOVE_TO_Y) 6738 { 6739 struct it it_backup; 6740 6741 /* TO_Y specified means stop at TO_X in the line containing 6742 TO_Y---or at TO_CHARPOS if this is reached first. The 6743 problem is that we can't really tell whether the line 6744 contains TO_Y before we have completely scanned it, and 6745 this may skip past TO_X. What we do is to first scan to 6746 TO_X. 6747 6748 If TO_X is not specified, use a TO_X of zero. The reason 6749 is to make the outcome of this function more predictable. 6750 If we didn't use TO_X == 0, we would stop at the end of 6751 the line which is probably not what a caller would expect 6752 to happen. */ 6753 skip = move_it_in_display_line_to (it, to_charpos, 6754 ((op & MOVE_TO_X) 6755 ? to_x : 0), 6756 (MOVE_TO_X 6757 | (op & MOVE_TO_POS))); 6758 6759 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */ 6760 if (skip == MOVE_POS_MATCH_OR_ZV) 6761 { 6762 reached = 5; 6763 break; 6764 } 6765 6766 /* If TO_X was reached, we would like to know whether TO_Y 6767 is in the line. This can only be said if we know the 6768 total line height which requires us to scan the rest of 6769 the line. */ 6770 if (skip == MOVE_X_REACHED) 6771 { 6772 it_backup = *it; 6773 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it))); 6774 skip2 = move_it_in_display_line_to (it, to_charpos, -1, 6775 op & MOVE_TO_POS); 6776 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it))); 6777 } 6778 6779 /* Now, decide whether TO_Y is in this line. */ 6780 line_height = it->max_ascent + it->max_descent; 6781 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height)); 6782 6783 if (to_y >= it->current_y 6784 && to_y < it->current_y + line_height) 6785 { 6786 if (skip == MOVE_X_REACHED) 6787 /* If TO_Y is in this line and TO_X was reached above, 6788 we scanned too far. We have to restore IT's settings 6789 to the ones before skipping. */ 6790 *it = it_backup; 6791 reached = 6; 6792 } 6793 else if (skip == MOVE_X_REACHED) 6794 { 6795 skip = skip2; 6796 if (skip == MOVE_POS_MATCH_OR_ZV) 6797 reached = 7; 6798 } 6799 6800 if (reached) 6801 break; 6802 } 6803 else if (BUFFERP (it->object) 6804 && it->method == GET_FROM_BUFFER 6805 && IT_CHARPOS (*it) >= to_charpos) 6806 skip = MOVE_POS_MATCH_OR_ZV; 6807 else 6808 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS); 6809 6810 switch (skip) 6811 { 6812 case MOVE_POS_MATCH_OR_ZV: 6813 reached = 8; 6814 goto out; 6815 6816 case MOVE_NEWLINE_OR_CR: 6817 set_iterator_to_next (it, 1); 6818 it->continuation_lines_width = 0; 6819 break; 6820 6821 case MOVE_LINE_TRUNCATED: 6822 it->continuation_lines_width = 0; 6823 reseat_at_next_visible_line_start (it, 0); 6824 if ((op & MOVE_TO_POS) != 0 6825 && IT_CHARPOS (*it) > to_charpos) 6826 { 6827 reached = 9; 6828 goto out; 6829 } 6830 break; 6831 6832 case MOVE_LINE_CONTINUED: 6833 /* For continued lines ending in a tab, some of the glyphs 6834 associated with the tab are displayed on the current 6835 line. Since it->current_x does not include these glyphs, 6836 we use it->last_visible_x instead. */ 6837 it->continuation_lines_width += 6838 (it->c == '\t') ? it->last_visible_x : it->current_x; 6839 break; 6840 6841 default: 6842 abort (); 6843 } 6844 6845 /* Reset/increment for the next run. */ 6846 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); 6847 it->current_x = it->hpos = 0; 6848 it->current_y += it->max_ascent + it->max_descent; 6849 ++it->vpos; 6850 last_height = it->max_ascent + it->max_descent; 6851 last_max_ascent = it->max_ascent; 6852 it->max_ascent = it->max_descent = 0; 6853 } 6854 6855 out: 6856 6857 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); 6858} 6859 6860 6861/* Move iterator IT backward by a specified y-distance DY, DY >= 0. 6862 6863 If DY > 0, move IT backward at least that many pixels. DY = 0 6864 means move IT backward to the preceding line start or BEGV. This 6865 function may move over more than DY pixels if IT->current_y - DY 6866 ends up in the middle of a line; in this case IT->current_y will be 6867 set to the top of the line moved to. */ 6868 6869void 6870move_it_vertically_backward (it, dy) 6871 struct it *it; 6872 int dy; 6873{ 6874 int nlines, h; 6875 struct it it2, it3; 6876 int start_pos; 6877 6878 move_further_back: 6879 xassert (dy >= 0); 6880 6881 start_pos = IT_CHARPOS (*it); 6882 6883 /* Estimate how many newlines we must move back. */ 6884 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f)); 6885 6886 /* Set the iterator's position that many lines back. */ 6887 while (nlines-- && IT_CHARPOS (*it) > BEGV) 6888 back_to_previous_visible_line_start (it); 6889 6890 /* Reseat the iterator here. When moving backward, we don't want 6891 reseat to skip forward over invisible text, set up the iterator 6892 to deliver from overlay strings at the new position etc. So, 6893 use reseat_1 here. */ 6894 reseat_1 (it, it->current.pos, 1); 6895 6896 /* We are now surely at a line start. */ 6897 it->current_x = it->hpos = 0; 6898 it->continuation_lines_width = 0; 6899 6900 /* Move forward and see what y-distance we moved. First move to the 6901 start of the next line so that we get its height. We need this 6902 height to be able to tell whether we reached the specified 6903 y-distance. */ 6904 it2 = *it; 6905 it2.max_ascent = it2.max_descent = 0; 6906 do 6907 { 6908 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1, 6909 MOVE_TO_POS | MOVE_TO_VPOS); 6910 } 6911 while (!IT_POS_VALID_AFTER_MOVE_P (&it2)); 6912 xassert (IT_CHARPOS (*it) >= BEGV); 6913 it3 = it2; 6914 6915 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS); 6916 xassert (IT_CHARPOS (*it) >= BEGV); 6917 /* H is the actual vertical distance from the position in *IT 6918 and the starting position. */ 6919 h = it2.current_y - it->current_y; 6920 /* NLINES is the distance in number of lines. */ 6921 nlines = it2.vpos - it->vpos; 6922 6923 /* Correct IT's y and vpos position 6924 so that they are relative to the starting point. */ 6925 it->vpos -= nlines; 6926 it->current_y -= h; 6927 6928 if (dy == 0) 6929 { 6930 /* DY == 0 means move to the start of the screen line. The 6931 value of nlines is > 0 if continuation lines were involved. */ 6932 if (nlines > 0) 6933 move_it_by_lines (it, nlines, 1); 6934#if 0 6935 /* I think this assert is bogus if buffer contains 6936 invisible text or images. KFS. */ 6937 xassert (IT_CHARPOS (*it) <= start_pos); 6938#endif 6939 } 6940 else 6941 { 6942 /* The y-position we try to reach, relative to *IT. 6943 Note that H has been subtracted in front of the if-statement. */ 6944 int target_y = it->current_y + h - dy; 6945 int y0 = it3.current_y; 6946 int y1 = line_bottom_y (&it3); 6947 int line_height = y1 - y0; 6948 6949 /* If we did not reach target_y, try to move further backward if 6950 we can. If we moved too far backward, try to move forward. */ 6951 if (target_y < it->current_y 6952 /* This is heuristic. In a window that's 3 lines high, with 6953 a line height of 13 pixels each, recentering with point 6954 on the bottom line will try to move -39/2 = 19 pixels 6955 backward. Try to avoid moving into the first line. */ 6956 && (it->current_y - target_y 6957 > min (window_box_height (it->w), line_height * 2 / 3)) 6958 && IT_CHARPOS (*it) > BEGV) 6959 { 6960 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n", 6961 target_y - it->current_y)); 6962 dy = it->current_y - target_y; 6963 goto move_further_back; 6964 } 6965 else if (target_y >= it->current_y + line_height 6966 && IT_CHARPOS (*it) < ZV) 6967 { 6968 /* Should move forward by at least one line, maybe more. 6969 6970 Note: Calling move_it_by_lines can be expensive on 6971 terminal frames, where compute_motion is used (via 6972 vmotion) to do the job, when there are very long lines 6973 and truncate-lines is nil. That's the reason for 6974 treating terminal frames specially here. */ 6975 6976 if (!FRAME_WINDOW_P (it->f)) 6977 move_it_vertically (it, target_y - (it->current_y + line_height)); 6978 else 6979 { 6980 do 6981 { 6982 move_it_by_lines (it, 1, 1); 6983 } 6984 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV); 6985 } 6986 6987#if 0 6988 /* I think this assert is bogus if buffer contains 6989 invisible text or images. KFS. */ 6990 xassert (IT_CHARPOS (*it) >= BEGV); 6991#endif 6992 } 6993 } 6994} 6995 6996 6997/* Move IT by a specified amount of pixel lines DY. DY negative means 6998 move backwards. DY = 0 means move to start of screen line. At the 6999 end, IT will be on the start of a screen line. */ 7000 7001void 7002move_it_vertically (it, dy) 7003 struct it *it; 7004 int dy; 7005{ 7006 if (dy <= 0) 7007 move_it_vertically_backward (it, -dy); 7008 else 7009 { 7010 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy)); 7011 move_it_to (it, ZV, -1, it->current_y + dy, -1, 7012 MOVE_TO_POS | MOVE_TO_Y); 7013 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it))); 7014 7015 /* If buffer ends in ZV without a newline, move to the start of 7016 the line to satisfy the post-condition. */ 7017 if (IT_CHARPOS (*it) == ZV 7018 && ZV > BEGV 7019 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n') 7020 move_it_by_lines (it, 0, 0); 7021 } 7022} 7023 7024 7025/* Move iterator IT past the end of the text line it is in. */ 7026 7027void 7028move_it_past_eol (it) 7029 struct it *it; 7030{ 7031 enum move_it_result rc; 7032 7033 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS); 7034 if (rc == MOVE_NEWLINE_OR_CR) 7035 set_iterator_to_next (it, 0); 7036} 7037 7038 7039#if 0 /* Currently not used. */ 7040 7041/* Return non-zero if some text between buffer positions START_CHARPOS 7042 and END_CHARPOS is invisible. IT->window is the window for text 7043 property lookup. */ 7044 7045static int 7046invisible_text_between_p (it, start_charpos, end_charpos) 7047 struct it *it; 7048 int start_charpos, end_charpos; 7049{ 7050 Lisp_Object prop, limit; 7051 int invisible_found_p; 7052 7053 xassert (it != NULL && start_charpos <= end_charpos); 7054 7055 /* Is text at START invisible? */ 7056 prop = Fget_char_property (make_number (start_charpos), Qinvisible, 7057 it->window); 7058 if (TEXT_PROP_MEANS_INVISIBLE (prop)) 7059 invisible_found_p = 1; 7060 else 7061 { 7062 limit = Fnext_single_char_property_change (make_number (start_charpos), 7063 Qinvisible, Qnil, 7064 make_number (end_charpos)); 7065 invisible_found_p = XFASTINT (limit) < end_charpos; 7066 } 7067 7068 return invisible_found_p; 7069} 7070 7071#endif /* 0 */ 7072 7073 7074/* Move IT by a specified number DVPOS of screen lines down. DVPOS 7075 negative means move up. DVPOS == 0 means move to the start of the 7076 screen line. NEED_Y_P non-zero means calculate IT->current_y. If 7077 NEED_Y_P is zero, IT->current_y will be left unchanged. 7078 7079 Further optimization ideas: If we would know that IT->f doesn't use 7080 a face with proportional font, we could be faster for 7081 truncate-lines nil. */ 7082 7083void 7084move_it_by_lines (it, dvpos, need_y_p) 7085 struct it *it; 7086 int dvpos, need_y_p; 7087{ 7088 struct position pos; 7089 7090 if (!FRAME_WINDOW_P (it->f)) 7091 { 7092 struct text_pos textpos; 7093 7094 /* We can use vmotion on frames without proportional fonts. */ 7095 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w); 7096 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos); 7097 reseat (it, textpos, 1); 7098 it->vpos += pos.vpos; 7099 it->current_y += pos.vpos; 7100 } 7101 else if (dvpos == 0) 7102 { 7103 /* DVPOS == 0 means move to the start of the screen line. */ 7104 move_it_vertically_backward (it, 0); 7105 xassert (it->current_x == 0 && it->hpos == 0); 7106 /* Let next call to line_bottom_y calculate real line height */ 7107 last_height = 0; 7108 } 7109 else if (dvpos > 0) 7110 { 7111 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS); 7112 if (!IT_POS_VALID_AFTER_MOVE_P (it)) 7113 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS); 7114 } 7115 else 7116 { 7117 struct it it2; 7118 int start_charpos, i; 7119 7120 /* Start at the beginning of the screen line containing IT's 7121 position. This may actually move vertically backwards, 7122 in case of overlays, so adjust dvpos accordingly. */ 7123 dvpos += it->vpos; 7124 move_it_vertically_backward (it, 0); 7125 dvpos -= it->vpos; 7126 7127 /* Go back -DVPOS visible lines and reseat the iterator there. */ 7128 start_charpos = IT_CHARPOS (*it); 7129 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i) 7130 back_to_previous_visible_line_start (it); 7131 reseat (it, it->current.pos, 1); 7132 7133 /* Move further back if we end up in a string or an image. */ 7134 while (!IT_POS_VALID_AFTER_MOVE_P (it)) 7135 { 7136 /* First try to move to start of display line. */ 7137 dvpos += it->vpos; 7138 move_it_vertically_backward (it, 0); 7139 dvpos -= it->vpos; 7140 if (IT_POS_VALID_AFTER_MOVE_P (it)) 7141 break; 7142 /* If start of line is still in string or image, 7143 move further back. */ 7144 back_to_previous_visible_line_start (it); 7145 reseat (it, it->current.pos, 1); 7146 dvpos--; 7147 } 7148 7149 it->current_x = it->hpos = 0; 7150 7151 /* Above call may have moved too far if continuation lines 7152 are involved. Scan forward and see if it did. */ 7153 it2 = *it; 7154 it2.vpos = it2.current_y = 0; 7155 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS); 7156 it->vpos -= it2.vpos; 7157 it->current_y -= it2.current_y; 7158 it->current_x = it->hpos = 0; 7159 7160 /* If we moved too far back, move IT some lines forward. */ 7161 if (it2.vpos > -dvpos) 7162 { 7163 int delta = it2.vpos + dvpos; 7164 it2 = *it; 7165 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS); 7166 /* Move back again if we got too far ahead. */ 7167 if (IT_CHARPOS (*it) >= start_charpos) 7168 *it = it2; 7169 } 7170 } 7171} 7172 7173/* Return 1 if IT points into the middle of a display vector. */ 7174 7175int 7176in_display_vector_p (it) 7177 struct it *it; 7178{ 7179 return (it->method == GET_FROM_DISPLAY_VECTOR 7180 && it->current.dpvec_index > 0 7181 && it->dpvec + it->current.dpvec_index != it->dpend); 7182} 7183 7184 7185/*********************************************************************** 7186 Messages 7187 ***********************************************************************/ 7188 7189 7190/* Add a message with format string FORMAT and arguments ARG1 and ARG2 7191 to *Messages*. */ 7192 7193void 7194add_to_log (format, arg1, arg2) 7195 char *format; 7196 Lisp_Object arg1, arg2; 7197{ 7198 Lisp_Object args[3]; 7199 Lisp_Object msg, fmt; 7200 char *buffer; 7201 int len; 7202 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 7203 USE_SAFE_ALLOCA; 7204 7205 /* Do nothing if called asynchronously. Inserting text into 7206 a buffer may call after-change-functions and alike and 7207 that would means running Lisp asynchronously. */ 7208 if (handling_signal) 7209 return; 7210 7211 fmt = msg = Qnil; 7212 GCPRO4 (fmt, msg, arg1, arg2); 7213 7214 args[0] = fmt = build_string (format); 7215 args[1] = arg1; 7216 args[2] = arg2; 7217 msg = Fformat (3, args); 7218 7219 len = SBYTES (msg) + 1; 7220 SAFE_ALLOCA (buffer, char *, len); 7221 bcopy (SDATA (msg), buffer, len); 7222 7223 message_dolog (buffer, len - 1, 1, 0); 7224 SAFE_FREE (); 7225 7226 UNGCPRO; 7227} 7228 7229 7230/* Output a newline in the *Messages* buffer if "needs" one. */ 7231 7232void 7233message_log_maybe_newline () 7234{ 7235 if (message_log_need_newline) 7236 message_dolog ("", 0, 1, 0); 7237} 7238 7239 7240/* Add a string M of length NBYTES to the message log, optionally 7241 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if 7242 nonzero, means interpret the contents of M as multibyte. This 7243 function calls low-level routines in order to bypass text property 7244 hooks, etc. which might not be safe to run. 7245 7246 This may GC (insert may run before/after change hooks), 7247 so the buffer M must NOT point to a Lisp string. */ 7248 7249void 7250message_dolog (m, nbytes, nlflag, multibyte) 7251 const char *m; 7252 int nbytes, nlflag, multibyte; 7253{ 7254 if (!NILP (Vmemory_full)) 7255 return; 7256 7257 if (!NILP (Vmessage_log_max)) 7258 { 7259 struct buffer *oldbuf; 7260 Lisp_Object oldpoint, oldbegv, oldzv; 7261 int old_windows_or_buffers_changed = windows_or_buffers_changed; 7262 int point_at_end = 0; 7263 int zv_at_end = 0; 7264 Lisp_Object old_deactivate_mark, tem; 7265 struct gcpro gcpro1; 7266 7267 old_deactivate_mark = Vdeactivate_mark; 7268 oldbuf = current_buffer; 7269 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name)); 7270 current_buffer->undo_list = Qt; 7271 7272 oldpoint = message_dolog_marker1; 7273 set_marker_restricted (oldpoint, make_number (PT), Qnil); 7274 oldbegv = message_dolog_marker2; 7275 set_marker_restricted (oldbegv, make_number (BEGV), Qnil); 7276 oldzv = message_dolog_marker3; 7277 set_marker_restricted (oldzv, make_number (ZV), Qnil); 7278 GCPRO1 (old_deactivate_mark); 7279 7280 if (PT == Z) 7281 point_at_end = 1; 7282 if (ZV == Z) 7283 zv_at_end = 1; 7284 7285 BEGV = BEG; 7286 BEGV_BYTE = BEG_BYTE; 7287 ZV = Z; 7288 ZV_BYTE = Z_BYTE; 7289 TEMP_SET_PT_BOTH (Z, Z_BYTE); 7290 7291 /* Insert the string--maybe converting multibyte to single byte 7292 or vice versa, so that all the text fits the buffer. */ 7293 if (multibyte 7294 && NILP (current_buffer->enable_multibyte_characters)) 7295 { 7296 int i, c, char_bytes; 7297 unsigned char work[1]; 7298 7299 /* Convert a multibyte string to single-byte 7300 for the *Message* buffer. */ 7301 for (i = 0; i < nbytes; i += char_bytes) 7302 { 7303 c = string_char_and_length (m + i, nbytes - i, &char_bytes); 7304 work[0] = (SINGLE_BYTE_CHAR_P (c) 7305 ? c 7306 : multibyte_char_to_unibyte (c, Qnil)); 7307 insert_1_both (work, 1, 1, 1, 0, 0); 7308 } 7309 } 7310 else if (! multibyte 7311 && ! NILP (current_buffer->enable_multibyte_characters)) 7312 { 7313 int i, c, char_bytes; 7314 unsigned char *msg = (unsigned char *) m; 7315 unsigned char str[MAX_MULTIBYTE_LENGTH]; 7316 /* Convert a single-byte string to multibyte 7317 for the *Message* buffer. */ 7318 for (i = 0; i < nbytes; i++) 7319 { 7320 c = unibyte_char_to_multibyte (msg[i]); 7321 char_bytes = CHAR_STRING (c, str); 7322 insert_1_both (str, 1, char_bytes, 1, 0, 0); 7323 } 7324 } 7325 else if (nbytes) 7326 insert_1 (m, nbytes, 1, 0, 0); 7327 7328 if (nlflag) 7329 { 7330 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup; 7331 insert_1 ("\n", 1, 1, 0, 0); 7332 7333 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0); 7334 this_bol = PT; 7335 this_bol_byte = PT_BYTE; 7336 7337 /* See if this line duplicates the previous one. 7338 If so, combine duplicates. */ 7339 if (this_bol > BEG) 7340 { 7341 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0); 7342 prev_bol = PT; 7343 prev_bol_byte = PT_BYTE; 7344 7345 dup = message_log_check_duplicate (prev_bol, prev_bol_byte, 7346 this_bol, this_bol_byte); 7347 if (dup) 7348 { 7349 del_range_both (prev_bol, prev_bol_byte, 7350 this_bol, this_bol_byte, 0); 7351 if (dup > 1) 7352 { 7353 char dupstr[40]; 7354 int duplen; 7355 7356 /* If you change this format, don't forget to also 7357 change message_log_check_duplicate. */ 7358 sprintf (dupstr, " [%d times]", dup); 7359 duplen = strlen (dupstr); 7360 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1); 7361 insert_1 (dupstr, duplen, 1, 0, 1); 7362 } 7363 } 7364 } 7365 7366 /* If we have more than the desired maximum number of lines 7367 in the *Messages* buffer now, delete the oldest ones. 7368 This is safe because we don't have undo in this buffer. */ 7369 7370 if (NATNUMP (Vmessage_log_max)) 7371 { 7372 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, 7373 -XFASTINT (Vmessage_log_max) - 1, 0); 7374 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0); 7375 } 7376 } 7377 BEGV = XMARKER (oldbegv)->charpos; 7378 BEGV_BYTE = marker_byte_position (oldbegv); 7379 7380 if (zv_at_end) 7381 { 7382 ZV = Z; 7383 ZV_BYTE = Z_BYTE; 7384 } 7385 else 7386 { 7387 ZV = XMARKER (oldzv)->charpos; 7388 ZV_BYTE = marker_byte_position (oldzv); 7389 } 7390 7391 if (point_at_end) 7392 TEMP_SET_PT_BOTH (Z, Z_BYTE); 7393 else 7394 /* We can't do Fgoto_char (oldpoint) because it will run some 7395 Lisp code. */ 7396 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos, 7397 XMARKER (oldpoint)->bytepos); 7398 7399 UNGCPRO; 7400 unchain_marker (XMARKER (oldpoint)); 7401 unchain_marker (XMARKER (oldbegv)); 7402 unchain_marker (XMARKER (oldzv)); 7403 7404 tem = Fget_buffer_window (Fcurrent_buffer (), Qt); 7405 set_buffer_internal (oldbuf); 7406 if (NILP (tem)) 7407 windows_or_buffers_changed = old_windows_or_buffers_changed; 7408 message_log_need_newline = !nlflag; 7409 Vdeactivate_mark = old_deactivate_mark; 7410 } 7411} 7412 7413 7414/* We are at the end of the buffer after just having inserted a newline. 7415 (Note: We depend on the fact we won't be crossing the gap.) 7416 Check to see if the most recent message looks a lot like the previous one. 7417 Return 0 if different, 1 if the new one should just replace it, or a 7418 value N > 1 if we should also append " [N times]". */ 7419 7420static int 7421message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte) 7422 int prev_bol, this_bol; 7423 int prev_bol_byte, this_bol_byte; 7424{ 7425 int i; 7426 int len = Z_BYTE - 1 - this_bol_byte; 7427 int seen_dots = 0; 7428 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte); 7429 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte); 7430 7431 for (i = 0; i < len; i++) 7432 { 7433 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.') 7434 seen_dots = 1; 7435 if (p1[i] != p2[i]) 7436 return seen_dots; 7437 } 7438 p1 += len; 7439 if (*p1 == '\n') 7440 return 2; 7441 if (*p1++ == ' ' && *p1++ == '[') 7442 { 7443 int n = 0; 7444 while (*p1 >= '0' && *p1 <= '9') 7445 n = n * 10 + *p1++ - '0'; 7446 if (strncmp (p1, " times]\n", 8) == 0) 7447 return n+1; 7448 } 7449 return 0; 7450} 7451 7452 7453/* Display an echo area message M with a specified length of NBYTES 7454 bytes. The string may include null characters. If M is 0, clear 7455 out any existing message, and let the mini-buffer text show 7456 through. 7457 7458 This may GC, so the buffer M must NOT point to a Lisp string. */ 7459 7460void 7461message2 (m, nbytes, multibyte) 7462 const char *m; 7463 int nbytes; 7464 int multibyte; 7465{ 7466 /* First flush out any partial line written with print. */ 7467 message_log_maybe_newline (); 7468 if (m) 7469 message_dolog (m, nbytes, 1, multibyte); 7470 message2_nolog (m, nbytes, multibyte); 7471} 7472 7473 7474/* The non-logging counterpart of message2. */ 7475 7476void 7477message2_nolog (m, nbytes, multibyte) 7478 const char *m; 7479 int nbytes, multibyte; 7480{ 7481 struct frame *sf = SELECTED_FRAME (); 7482 message_enable_multibyte = multibyte; 7483 7484 if (noninteractive) 7485 { 7486 if (noninteractive_need_newline) 7487 putc ('\n', stderr); 7488 noninteractive_need_newline = 0; 7489 if (m) 7490 fwrite (m, nbytes, 1, stderr); 7491 if (cursor_in_echo_area == 0) 7492 fprintf (stderr, "\n"); 7493 fflush (stderr); 7494 } 7495 /* A null message buffer means that the frame hasn't really been 7496 initialized yet. Error messages get reported properly by 7497 cmd_error, so this must be just an informative message; toss it. */ 7498 else if (INTERACTIVE 7499 && sf->glyphs_initialized_p 7500 && FRAME_MESSAGE_BUF (sf)) 7501 { 7502 Lisp_Object mini_window; 7503 struct frame *f; 7504 7505 /* Get the frame containing the mini-buffer 7506 that the selected frame is using. */ 7507 mini_window = FRAME_MINIBUF_WINDOW (sf); 7508 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); 7509 7510 FRAME_SAMPLE_VISIBILITY (f); 7511 if (FRAME_VISIBLE_P (sf) 7512 && ! FRAME_VISIBLE_P (f)) 7513 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window))); 7514 7515 if (m) 7516 { 7517 set_message (m, Qnil, nbytes, multibyte); 7518 if (minibuffer_auto_raise) 7519 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); 7520 } 7521 else 7522 clear_message (1, 1); 7523 7524 do_pending_window_change (0); 7525 echo_area_display (1); 7526 do_pending_window_change (0); 7527 if (frame_up_to_date_hook != 0 && ! gc_in_progress) 7528 (*frame_up_to_date_hook) (f); 7529 } 7530} 7531 7532 7533/* Display an echo area message M with a specified length of NBYTES 7534 bytes. The string may include null characters. If M is not a 7535 string, clear out any existing message, and let the mini-buffer 7536 text show through. 7537 7538 This function cancels echoing. */ 7539 7540void 7541message3 (m, nbytes, multibyte) 7542 Lisp_Object m; 7543 int nbytes; 7544 int multibyte; 7545{ 7546 struct gcpro gcpro1; 7547 7548 GCPRO1 (m); 7549 clear_message (1,1); 7550 cancel_echoing (); 7551 7552 /* First flush out any partial line written with print. */ 7553 message_log_maybe_newline (); 7554 if (STRINGP (m)) 7555 { 7556 char *buffer; 7557 USE_SAFE_ALLOCA; 7558 7559 SAFE_ALLOCA (buffer, char *, nbytes); 7560 bcopy (SDATA (m), buffer, nbytes); 7561 message_dolog (buffer, nbytes, 1, multibyte); 7562 SAFE_FREE (); 7563 } 7564 message3_nolog (m, nbytes, multibyte); 7565 7566 UNGCPRO; 7567} 7568 7569 7570/* The non-logging version of message3. 7571 This does not cancel echoing, because it is used for echoing. 7572 Perhaps we need to make a separate function for echoing 7573 and make this cancel echoing. */ 7574 7575void 7576message3_nolog (m, nbytes, multibyte) 7577 Lisp_Object m; 7578 int nbytes, multibyte; 7579{ 7580 struct frame *sf = SELECTED_FRAME (); 7581 message_enable_multibyte = multibyte; 7582 7583 if (noninteractive) 7584 { 7585 if (noninteractive_need_newline) 7586 putc ('\n', stderr); 7587 noninteractive_need_newline = 0; 7588 if (STRINGP (m)) 7589 fwrite (SDATA (m), nbytes, 1, stderr); 7590 if (cursor_in_echo_area == 0) 7591 fprintf (stderr, "\n"); 7592 fflush (stderr); 7593 } 7594 /* A null message buffer means that the frame hasn't really been 7595 initialized yet. Error messages get reported properly by 7596 cmd_error, so this must be just an informative message; toss it. */ 7597 else if (INTERACTIVE 7598 && sf->glyphs_initialized_p 7599 && FRAME_MESSAGE_BUF (sf)) 7600 { 7601 Lisp_Object mini_window; 7602 Lisp_Object frame; 7603 struct frame *f; 7604 7605 /* Get the frame containing the mini-buffer 7606 that the selected frame is using. */ 7607 mini_window = FRAME_MINIBUF_WINDOW (sf); 7608 frame = XWINDOW (mini_window)->frame; 7609 f = XFRAME (frame); 7610 7611 FRAME_SAMPLE_VISIBILITY (f); 7612 if (FRAME_VISIBLE_P (sf) 7613 && !FRAME_VISIBLE_P (f)) 7614 Fmake_frame_visible (frame); 7615 7616 if (STRINGP (m) && SCHARS (m) > 0) 7617 { 7618 set_message (NULL, m, nbytes, multibyte); 7619 if (minibuffer_auto_raise) 7620 Fraise_frame (frame); 7621 /* Assume we are not echoing. 7622 (If we are, echo_now will override this.) */ 7623 echo_message_buffer = Qnil; 7624 } 7625 else 7626 clear_message (1, 1); 7627 7628 do_pending_window_change (0); 7629 echo_area_display (1); 7630 do_pending_window_change (0); 7631 if (frame_up_to_date_hook != 0 && ! gc_in_progress) 7632 (*frame_up_to_date_hook) (f); 7633 } 7634} 7635 7636 7637/* Display a null-terminated echo area message M. If M is 0, clear 7638 out any existing message, and let the mini-buffer text show through. 7639 7640 The buffer M must continue to exist until after the echo area gets 7641 cleared or some other message gets displayed there. Do not pass 7642 text that is stored in a Lisp string. Do not pass text in a buffer 7643 that was alloca'd. */ 7644 7645void 7646message1 (m) 7647 char *m; 7648{ 7649 message2 (m, (m ? strlen (m) : 0), 0); 7650} 7651 7652 7653/* The non-logging counterpart of message1. */ 7654 7655void 7656message1_nolog (m) 7657 char *m; 7658{ 7659 message2_nolog (m, (m ? strlen (m) : 0), 0); 7660} 7661 7662/* Display a message M which contains a single %s 7663 which gets replaced with STRING. */ 7664 7665void 7666message_with_string (m, string, log) 7667 char *m; 7668 Lisp_Object string; 7669 int log; 7670{ 7671 CHECK_STRING (string); 7672 7673 if (noninteractive) 7674 { 7675 if (m) 7676 { 7677 if (noninteractive_need_newline) 7678 putc ('\n', stderr); 7679 noninteractive_need_newline = 0; 7680 fprintf (stderr, m, SDATA (string)); 7681 if (cursor_in_echo_area == 0) 7682 fprintf (stderr, "\n"); 7683 fflush (stderr); 7684 } 7685 } 7686 else if (INTERACTIVE) 7687 { 7688 /* The frame whose minibuffer we're going to display the message on. 7689 It may be larger than the selected frame, so we need 7690 to use its buffer, not the selected frame's buffer. */ 7691 Lisp_Object mini_window; 7692 struct frame *f, *sf = SELECTED_FRAME (); 7693 7694 /* Get the frame containing the minibuffer 7695 that the selected frame is using. */ 7696 mini_window = FRAME_MINIBUF_WINDOW (sf); 7697 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); 7698 7699 /* A null message buffer means that the frame hasn't really been 7700 initialized yet. Error messages get reported properly by 7701 cmd_error, so this must be just an informative message; toss it. */ 7702 if (FRAME_MESSAGE_BUF (f)) 7703 { 7704 Lisp_Object args[2], message; 7705 struct gcpro gcpro1, gcpro2; 7706 7707 args[0] = build_string (m); 7708 args[1] = message = string; 7709 GCPRO2 (args[0], message); 7710 gcpro1.nvars = 2; 7711 7712 message = Fformat (2, args); 7713 7714 if (log) 7715 message3 (message, SBYTES (message), STRING_MULTIBYTE (message)); 7716 else 7717 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message)); 7718 7719 UNGCPRO; 7720 7721 /* Print should start at the beginning of the message 7722 buffer next time. */ 7723 message_buf_print = 0; 7724 } 7725 } 7726} 7727 7728 7729/* Dump an informative message to the minibuf. If M is 0, clear out 7730 any existing message, and let the mini-buffer text show through. */ 7731 7732/* VARARGS 1 */ 7733void 7734message (m, a1, a2, a3) 7735 char *m; 7736 EMACS_INT a1, a2, a3; 7737{ 7738 if (noninteractive) 7739 { 7740 if (m) 7741 { 7742 if (noninteractive_need_newline) 7743 putc ('\n', stderr); 7744 noninteractive_need_newline = 0; 7745 fprintf (stderr, m, a1, a2, a3); 7746 if (cursor_in_echo_area == 0) 7747 fprintf (stderr, "\n"); 7748 fflush (stderr); 7749 } 7750 } 7751 else if (INTERACTIVE) 7752 { 7753 /* The frame whose mini-buffer we're going to display the message 7754 on. It may be larger than the selected frame, so we need to 7755 use its buffer, not the selected frame's buffer. */ 7756 Lisp_Object mini_window; 7757 struct frame *f, *sf = SELECTED_FRAME (); 7758 7759 /* Get the frame containing the mini-buffer 7760 that the selected frame is using. */ 7761 mini_window = FRAME_MINIBUF_WINDOW (sf); 7762 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); 7763 7764 /* A null message buffer means that the frame hasn't really been 7765 initialized yet. Error messages get reported properly by 7766 cmd_error, so this must be just an informative message; toss 7767 it. */ 7768 if (FRAME_MESSAGE_BUF (f)) 7769 { 7770 if (m) 7771 { 7772 int len; 7773#ifdef NO_ARG_ARRAY 7774 char *a[3]; 7775 a[0] = (char *) a1; 7776 a[1] = (char *) a2; 7777 a[2] = (char *) a3; 7778 7779 len = doprnt (FRAME_MESSAGE_BUF (f), 7780 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a); 7781#else 7782 len = doprnt (FRAME_MESSAGE_BUF (f), 7783 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, 7784 (char **) &a1); 7785#endif /* NO_ARG_ARRAY */ 7786 7787 message2 (FRAME_MESSAGE_BUF (f), len, 0); 7788 } 7789 else 7790 message1 (0); 7791 7792 /* Print should start at the beginning of the message 7793 buffer next time. */ 7794 message_buf_print = 0; 7795 } 7796 } 7797} 7798 7799 7800/* The non-logging version of message. */ 7801 7802void 7803message_nolog (m, a1, a2, a3) 7804 char *m; 7805 EMACS_INT a1, a2, a3; 7806{ 7807 Lisp_Object old_log_max; 7808 old_log_max = Vmessage_log_max; 7809 Vmessage_log_max = Qnil; 7810 message (m, a1, a2, a3); 7811 Vmessage_log_max = old_log_max; 7812} 7813 7814 7815/* Display the current message in the current mini-buffer. This is 7816 only called from error handlers in process.c, and is not time 7817 critical. */ 7818 7819void 7820update_echo_area () 7821{ 7822 if (!NILP (echo_area_buffer[0])) 7823 { 7824 Lisp_Object string; 7825 string = Fcurrent_message (); 7826 message3 (string, SBYTES (string), 7827 !NILP (current_buffer->enable_multibyte_characters)); 7828 } 7829} 7830 7831 7832/* Make sure echo area buffers in `echo_buffers' are live. 7833 If they aren't, make new ones. */ 7834 7835static void 7836ensure_echo_area_buffers () 7837{ 7838 int i; 7839 7840 for (i = 0; i < 2; ++i) 7841 if (!BUFFERP (echo_buffer[i]) 7842 || NILP (XBUFFER (echo_buffer[i])->name)) 7843 { 7844 char name[30]; 7845 Lisp_Object old_buffer; 7846 int j; 7847 7848 old_buffer = echo_buffer[i]; 7849 sprintf (name, " *Echo Area %d*", i); 7850 echo_buffer[i] = Fget_buffer_create (build_string (name)); 7851 XBUFFER (echo_buffer[i])->truncate_lines = Qnil; 7852 7853 for (j = 0; j < 2; ++j) 7854 if (EQ (old_buffer, echo_area_buffer[j])) 7855 echo_area_buffer[j] = echo_buffer[i]; 7856 } 7857} 7858 7859 7860/* Call FN with args A1..A4 with either the current or last displayed 7861 echo_area_buffer as current buffer. 7862 7863 WHICH zero means use the current message buffer 7864 echo_area_buffer[0]. If that is nil, choose a suitable buffer 7865 from echo_buffer[] and clear it. 7866 7867 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a 7868 suitable buffer from echo_buffer[] and clear it. 7869 7870 Value is what FN returns. */ 7871 7872static int 7873with_echo_area_buffer (w, which, fn, a1, a2, a3, a4) 7874 struct window *w; 7875 int which; 7876 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT)); 7877 EMACS_INT a1; 7878 Lisp_Object a2; 7879 EMACS_INT a3, a4; 7880{ 7881 Lisp_Object buffer; 7882 int this_one, the_other, clear_buffer_p, rc; 7883 int count = SPECPDL_INDEX (); 7884 7885 /* If buffers aren't live, make new ones. */ 7886 ensure_echo_area_buffers (); 7887 7888 clear_buffer_p = 0; 7889 7890 if (which == 0) 7891 this_one = 0, the_other = 1; 7892 else if (which > 0) 7893 this_one = 1, the_other = 0; 7894 7895 /* Choose a suitable buffer from echo_buffer[] is we don't 7896 have one. */ 7897 if (NILP (echo_area_buffer[this_one])) 7898 { 7899 echo_area_buffer[this_one] 7900 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one]) 7901 ? echo_buffer[the_other] 7902 : echo_buffer[this_one]); 7903 clear_buffer_p = 1; 7904 } 7905 7906 buffer = echo_area_buffer[this_one]; 7907 7908 /* Don't get confused by reusing the buffer used for echoing 7909 for a different purpose. */ 7910 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer)) 7911 cancel_echoing (); 7912 7913 record_unwind_protect (unwind_with_echo_area_buffer, 7914 with_echo_area_buffer_unwind_data (w)); 7915 7916 /* Make the echo area buffer current. Note that for display 7917 purposes, it is not necessary that the displayed window's buffer 7918 == current_buffer, except for text property lookup. So, let's 7919 only set that buffer temporarily here without doing a full 7920 Fset_window_buffer. We must also change w->pointm, though, 7921 because otherwise an assertions in unshow_buffer fails, and Emacs 7922 aborts. */ 7923 set_buffer_internal_1 (XBUFFER (buffer)); 7924 if (w) 7925 { 7926 w->buffer = buffer; 7927 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE); 7928 } 7929 7930 current_buffer->undo_list = Qt; 7931 current_buffer->read_only = Qnil; 7932 specbind (Qinhibit_read_only, Qt); 7933 specbind (Qinhibit_modification_hooks, Qt); 7934 7935 if (clear_buffer_p && Z > BEG) 7936 del_range (BEG, Z); 7937 7938 xassert (BEGV >= BEG); 7939 xassert (ZV <= Z && ZV >= BEGV); 7940 7941 rc = fn (a1, a2, a3, a4); 7942 7943 xassert (BEGV >= BEG); 7944 xassert (ZV <= Z && ZV >= BEGV); 7945 7946 unbind_to (count, Qnil); 7947 return rc; 7948} 7949 7950 7951/* Save state that should be preserved around the call to the function 7952 FN called in with_echo_area_buffer. */ 7953 7954static Lisp_Object 7955with_echo_area_buffer_unwind_data (w) 7956 struct window *w; 7957{ 7958 int i = 0; 7959 Lisp_Object vector; 7960 7961 /* Reduce consing by keeping one vector in 7962 Vwith_echo_area_save_vector. */ 7963 vector = Vwith_echo_area_save_vector; 7964 Vwith_echo_area_save_vector = Qnil; 7965 7966 if (NILP (vector)) 7967 vector = Fmake_vector (make_number (7), Qnil); 7968 7969 XSETBUFFER (AREF (vector, i), current_buffer); ++i; 7970 AREF (vector, i) = Vdeactivate_mark, ++i; 7971 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i; 7972 7973 if (w) 7974 { 7975 XSETWINDOW (AREF (vector, i), w); ++i; 7976 AREF (vector, i) = w->buffer; ++i; 7977 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i; 7978 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i; 7979 } 7980 else 7981 { 7982 int end = i + 4; 7983 for (; i < end; ++i) 7984 AREF (vector, i) = Qnil; 7985 } 7986 7987 xassert (i == ASIZE (vector)); 7988 return vector; 7989} 7990 7991 7992/* Restore global state from VECTOR which was created by 7993 with_echo_area_buffer_unwind_data. */ 7994 7995static Lisp_Object 7996unwind_with_echo_area_buffer (vector) 7997 Lisp_Object vector; 7998{ 7999 set_buffer_internal_1 (XBUFFER (AREF (vector, 0))); 8000 Vdeactivate_mark = AREF (vector, 1); 8001 windows_or_buffers_changed = XFASTINT (AREF (vector, 2)); 8002 8003 if (WINDOWP (AREF (vector, 3))) 8004 { 8005 struct window *w; 8006 Lisp_Object buffer, charpos, bytepos; 8007 8008 w = XWINDOW (AREF (vector, 3)); 8009 buffer = AREF (vector, 4); 8010 charpos = AREF (vector, 5); 8011 bytepos = AREF (vector, 6); 8012 8013 w->buffer = buffer; 8014 set_marker_both (w->pointm, buffer, 8015 XFASTINT (charpos), XFASTINT (bytepos)); 8016 } 8017 8018 Vwith_echo_area_save_vector = vector; 8019 return Qnil; 8020} 8021 8022 8023/* Set up the echo area for use by print functions. MULTIBYTE_P 8024 non-zero means we will print multibyte. */ 8025 8026void 8027setup_echo_area_for_printing (multibyte_p) 8028 int multibyte_p; 8029{ 8030 /* If we can't find an echo area any more, exit. */ 8031 if (! FRAME_LIVE_P (XFRAME (selected_frame))) 8032 Fkill_emacs (Qnil); 8033 8034 ensure_echo_area_buffers (); 8035 8036 if (!message_buf_print) 8037 { 8038 /* A message has been output since the last time we printed. 8039 Choose a fresh echo area buffer. */ 8040 if (EQ (echo_area_buffer[1], echo_buffer[0])) 8041 echo_area_buffer[0] = echo_buffer[1]; 8042 else 8043 echo_area_buffer[0] = echo_buffer[0]; 8044 8045 /* Switch to that buffer and clear it. */ 8046 set_buffer_internal (XBUFFER (echo_area_buffer[0])); 8047 current_buffer->truncate_lines = Qnil; 8048 8049 if (Z > BEG) 8050 { 8051 int count = SPECPDL_INDEX (); 8052 specbind (Qinhibit_read_only, Qt); 8053 /* Note that undo recording is always disabled. */ 8054 del_range (BEG, Z); 8055 unbind_to (count, Qnil); 8056 } 8057 TEMP_SET_PT_BOTH (BEG, BEG_BYTE); 8058 8059 /* Set up the buffer for the multibyteness we need. */ 8060 if (multibyte_p 8061 != !NILP (current_buffer->enable_multibyte_characters)) 8062 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil); 8063 8064 /* Raise the frame containing the echo area. */ 8065 if (minibuffer_auto_raise) 8066 { 8067 struct frame *sf = SELECTED_FRAME (); 8068 Lisp_Object mini_window; 8069 mini_window = FRAME_MINIBUF_WINDOW (sf); 8070 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window))); 8071 } 8072 8073 message_log_maybe_newline (); 8074 message_buf_print = 1; 8075 } 8076 else 8077 { 8078 if (NILP (echo_area_buffer[0])) 8079 { 8080 if (EQ (echo_area_buffer[1], echo_buffer[0])) 8081 echo_area_buffer[0] = echo_buffer[1]; 8082 else 8083 echo_area_buffer[0] = echo_buffer[0]; 8084 } 8085 8086 if (current_buffer != XBUFFER (echo_area_buffer[0])) 8087 { 8088 /* Someone switched buffers between print requests. */ 8089 set_buffer_internal (XBUFFER (echo_area_buffer[0])); 8090 current_buffer->truncate_lines = Qnil; 8091 } 8092 } 8093} 8094 8095 8096/* Display an echo area message in window W. Value is non-zero if W's 8097 height is changed. If display_last_displayed_message_p is 8098 non-zero, display the message that was last displayed, otherwise 8099 display the current message. */ 8100 8101static int 8102display_echo_area (w) 8103 struct window *w; 8104{ 8105 int i, no_message_p, window_height_changed_p, count; 8106 8107 /* Temporarily disable garbage collections while displaying the echo 8108 area. This is done because a GC can print a message itself. 8109 That message would modify the echo area buffer's contents while a 8110 redisplay of the buffer is going on, and seriously confuse 8111 redisplay. */ 8112 count = inhibit_garbage_collection (); 8113 8114 /* If there is no message, we must call display_echo_area_1 8115 nevertheless because it resizes the window. But we will have to 8116 reset the echo_area_buffer in question to nil at the end because 8117 with_echo_area_buffer will sets it to an empty buffer. */ 8118 i = display_last_displayed_message_p ? 1 : 0; 8119 no_message_p = NILP (echo_area_buffer[i]); 8120 8121 window_height_changed_p 8122 = with_echo_area_buffer (w, display_last_displayed_message_p, 8123 display_echo_area_1, 8124 (EMACS_INT) w, Qnil, 0, 0); 8125 8126 if (no_message_p) 8127 echo_area_buffer[i] = Qnil; 8128 8129 unbind_to (count, Qnil); 8130 return window_height_changed_p; 8131} 8132 8133 8134/* Helper for display_echo_area. Display the current buffer which 8135 contains the current echo area message in window W, a mini-window, 8136 a pointer to which is passed in A1. A2..A4 are currently not used. 8137 Change the height of W so that all of the message is displayed. 8138 Value is non-zero if height of W was changed. */ 8139 8140static int 8141display_echo_area_1 (a1, a2, a3, a4) 8142 EMACS_INT a1; 8143 Lisp_Object a2; 8144 EMACS_INT a3, a4; 8145{ 8146 struct window *w = (struct window *) a1; 8147 Lisp_Object window; 8148 struct text_pos start; 8149 int window_height_changed_p = 0; 8150 8151 /* Do this before displaying, so that we have a large enough glyph 8152 matrix for the display. If we can't get enough space for the 8153 whole text, display the last N lines. That works by setting w->start. */ 8154 window_height_changed_p = resize_mini_window (w, 0); 8155 8156 /* Use the starting position chosen by resize_mini_window. */ 8157 SET_TEXT_POS_FROM_MARKER (start, w->start); 8158 8159 /* Display. */ 8160 clear_glyph_matrix (w->desired_matrix); 8161 XSETWINDOW (window, w); 8162 try_window (window, start, 0); 8163 8164 return window_height_changed_p; 8165} 8166 8167 8168/* Resize the echo area window to exactly the size needed for the 8169 currently displayed message, if there is one. If a mini-buffer 8170 is active, don't shrink it. */ 8171 8172void 8173resize_echo_area_exactly () 8174{ 8175 if (BUFFERP (echo_area_buffer[0]) 8176 && WINDOWP (echo_area_window)) 8177 { 8178 struct window *w = XWINDOW (echo_area_window); 8179 int resized_p; 8180 Lisp_Object resize_exactly; 8181 8182 if (minibuf_level == 0) 8183 resize_exactly = Qt; 8184 else 8185 resize_exactly = Qnil; 8186 8187 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1, 8188 (EMACS_INT) w, resize_exactly, 0, 0); 8189 if (resized_p) 8190 { 8191 ++windows_or_buffers_changed; 8192 ++update_mode_lines; 8193 redisplay_internal (0); 8194 } 8195 } 8196} 8197 8198 8199/* Callback function for with_echo_area_buffer, when used from 8200 resize_echo_area_exactly. A1 contains a pointer to the window to 8201 resize, EXACTLY non-nil means resize the mini-window exactly to the 8202 size of the text displayed. A3 and A4 are not used. Value is what 8203 resize_mini_window returns. */ 8204 8205static int 8206resize_mini_window_1 (a1, exactly, a3, a4) 8207 EMACS_INT a1; 8208 Lisp_Object exactly; 8209 EMACS_INT a3, a4; 8210{ 8211 return resize_mini_window ((struct window *) a1, !NILP (exactly)); 8212} 8213 8214 8215/* Resize mini-window W to fit the size of its contents. EXACT:P 8216 means size the window exactly to the size needed. Otherwise, it's 8217 only enlarged until W's buffer is empty. 8218 8219 Set W->start to the right place to begin display. If the whole 8220 contents fit, start at the beginning. Otherwise, start so as 8221 to make the end of the contents appear. This is particularly 8222 important for y-or-n-p, but seems desirable generally. 8223 8224 Value is non-zero if the window height has been changed. */ 8225 8226int 8227resize_mini_window (w, exact_p) 8228 struct window *w; 8229 int exact_p; 8230{ 8231 struct frame *f = XFRAME (w->frame); 8232 int window_height_changed_p = 0; 8233 8234 xassert (MINI_WINDOW_P (w)); 8235 8236 /* By default, start display at the beginning. */ 8237 set_marker_both (w->start, w->buffer, 8238 BUF_BEGV (XBUFFER (w->buffer)), 8239 BUF_BEGV_BYTE (XBUFFER (w->buffer))); 8240 8241 /* Don't resize windows while redisplaying a window; it would 8242 confuse redisplay functions when the size of the window they are 8243 displaying changes from under them. Such a resizing can happen, 8244 for instance, when which-func prints a long message while 8245 we are running fontification-functions. We're running these 8246 functions with safe_call which binds inhibit-redisplay to t. */ 8247 if (!NILP (Vinhibit_redisplay)) 8248 return 0; 8249 8250 /* Nil means don't try to resize. */ 8251 if (NILP (Vresize_mini_windows) 8252 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL)) 8253 return 0; 8254 8255 if (!FRAME_MINIBUF_ONLY_P (f)) 8256 { 8257 struct it it; 8258 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); 8259 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w); 8260 int height, max_height; 8261 int unit = FRAME_LINE_HEIGHT (f); 8262 struct text_pos start; 8263 struct buffer *old_current_buffer = NULL; 8264 8265 if (current_buffer != XBUFFER (w->buffer)) 8266 { 8267 old_current_buffer = current_buffer; 8268 set_buffer_internal (XBUFFER (w->buffer)); 8269 } 8270 8271 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID); 8272 8273 /* Compute the max. number of lines specified by the user. */ 8274 if (FLOATP (Vmax_mini_window_height)) 8275 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f); 8276 else if (INTEGERP (Vmax_mini_window_height)) 8277 max_height = XINT (Vmax_mini_window_height); 8278 else 8279 max_height = total_height / 4; 8280 8281 /* Correct that max. height if it's bogus. */ 8282 max_height = max (1, max_height); 8283 max_height = min (total_height, max_height); 8284 8285 /* Find out the height of the text in the window. */ 8286 if (it.truncate_lines_p) 8287 height = 1; 8288 else 8289 { 8290 last_height = 0; 8291 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS); 8292 if (it.max_ascent == 0 && it.max_descent == 0) 8293 height = it.current_y + last_height; 8294 else 8295 height = it.current_y + it.max_ascent + it.max_descent; 8296 height -= min (it.extra_line_spacing, it.max_extra_line_spacing); 8297 height = (height + unit - 1) / unit; 8298 } 8299 8300 /* Compute a suitable window start. */ 8301 if (height > max_height) 8302 { 8303 height = max_height; 8304 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID); 8305 move_it_vertically_backward (&it, (height - 1) * unit); 8306 start = it.current.pos; 8307 } 8308 else 8309 SET_TEXT_POS (start, BEGV, BEGV_BYTE); 8310 SET_MARKER_FROM_TEXT_POS (w->start, start); 8311 8312 if (EQ (Vresize_mini_windows, Qgrow_only)) 8313 { 8314 /* Let it grow only, until we display an empty message, in which 8315 case the window shrinks again. */ 8316 if (height > WINDOW_TOTAL_LINES (w)) 8317 { 8318 int old_height = WINDOW_TOTAL_LINES (w); 8319 freeze_window_starts (f, 1); 8320 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 8321 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 8322 } 8323 else if (height < WINDOW_TOTAL_LINES (w) 8324 && (exact_p || BEGV == ZV)) 8325 { 8326 int old_height = WINDOW_TOTAL_LINES (w); 8327 freeze_window_starts (f, 0); 8328 shrink_mini_window (w); 8329 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 8330 } 8331 } 8332 else 8333 { 8334 /* Always resize to exact size needed. */ 8335 if (height > WINDOW_TOTAL_LINES (w)) 8336 { 8337 int old_height = WINDOW_TOTAL_LINES (w); 8338 freeze_window_starts (f, 1); 8339 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 8340 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 8341 } 8342 else if (height < WINDOW_TOTAL_LINES (w)) 8343 { 8344 int old_height = WINDOW_TOTAL_LINES (w); 8345 freeze_window_starts (f, 0); 8346 shrink_mini_window (w); 8347 8348 if (height) 8349 { 8350 freeze_window_starts (f, 1); 8351 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 8352 } 8353 8354 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 8355 } 8356 } 8357 8358 if (old_current_buffer) 8359 set_buffer_internal (old_current_buffer); 8360 } 8361 8362 return window_height_changed_p; 8363} 8364 8365 8366/* Value is the current message, a string, or nil if there is no 8367 current message. */ 8368 8369Lisp_Object 8370current_message () 8371{ 8372 Lisp_Object msg; 8373 8374 if (NILP (echo_area_buffer[0])) 8375 msg = Qnil; 8376 else 8377 { 8378 with_echo_area_buffer (0, 0, current_message_1, 8379 (EMACS_INT) &msg, Qnil, 0, 0); 8380 if (NILP (msg)) 8381 echo_area_buffer[0] = Qnil; 8382 } 8383 8384 return msg; 8385} 8386 8387 8388static int 8389current_message_1 (a1, a2, a3, a4) 8390 EMACS_INT a1; 8391 Lisp_Object a2; 8392 EMACS_INT a3, a4; 8393{ 8394 Lisp_Object *msg = (Lisp_Object *) a1; 8395 8396 if (Z > BEG) 8397 *msg = make_buffer_string (BEG, Z, 1); 8398 else 8399 *msg = Qnil; 8400 return 0; 8401} 8402 8403 8404/* Push the current message on Vmessage_stack for later restauration 8405 by restore_message. Value is non-zero if the current message isn't 8406 empty. This is a relatively infrequent operation, so it's not 8407 worth optimizing. */ 8408 8409int 8410push_message () 8411{ 8412 Lisp_Object msg; 8413 msg = current_message (); 8414 Vmessage_stack = Fcons (msg, Vmessage_stack); 8415 return STRINGP (msg); 8416} 8417 8418 8419/* Restore message display from the top of Vmessage_stack. */ 8420 8421void 8422restore_message () 8423{ 8424 Lisp_Object msg; 8425 8426 xassert (CONSP (Vmessage_stack)); 8427 msg = XCAR (Vmessage_stack); 8428 if (STRINGP (msg)) 8429 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg)); 8430 else 8431 message3_nolog (msg, 0, 0); 8432} 8433 8434 8435/* Handler for record_unwind_protect calling pop_message. */ 8436 8437Lisp_Object 8438pop_message_unwind (dummy) 8439 Lisp_Object dummy; 8440{ 8441 pop_message (); 8442 return Qnil; 8443} 8444 8445/* Pop the top-most entry off Vmessage_stack. */ 8446 8447void 8448pop_message () 8449{ 8450 xassert (CONSP (Vmessage_stack)); 8451 Vmessage_stack = XCDR (Vmessage_stack); 8452} 8453 8454 8455/* Check that Vmessage_stack is nil. Called from emacs.c when Emacs 8456 exits. If the stack is not empty, we have a missing pop_message 8457 somewhere. */ 8458 8459void 8460check_message_stack () 8461{ 8462 if (!NILP (Vmessage_stack)) 8463 abort (); 8464} 8465 8466 8467/* Truncate to NCHARS what will be displayed in the echo area the next 8468 time we display it---but don't redisplay it now. */ 8469 8470void 8471truncate_echo_area (nchars) 8472 int nchars; 8473{ 8474 if (nchars == 0) 8475 echo_area_buffer[0] = Qnil; 8476 /* A null message buffer means that the frame hasn't really been 8477 initialized yet. Error messages get reported properly by 8478 cmd_error, so this must be just an informative message; toss it. */ 8479 else if (!noninteractive 8480 && INTERACTIVE 8481 && !NILP (echo_area_buffer[0])) 8482 { 8483 struct frame *sf = SELECTED_FRAME (); 8484 if (FRAME_MESSAGE_BUF (sf)) 8485 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0); 8486 } 8487} 8488 8489 8490/* Helper function for truncate_echo_area. Truncate the current 8491 message to at most NCHARS characters. */ 8492 8493static int 8494truncate_message_1 (nchars, a2, a3, a4) 8495 EMACS_INT nchars; 8496 Lisp_Object a2; 8497 EMACS_INT a3, a4; 8498{ 8499 if (BEG + nchars < Z) 8500 del_range (BEG + nchars, Z); 8501 if (Z == BEG) 8502 echo_area_buffer[0] = Qnil; 8503 return 0; 8504} 8505 8506 8507/* Set the current message to a substring of S or STRING. 8508 8509 If STRING is a Lisp string, set the message to the first NBYTES 8510 bytes from STRING. NBYTES zero means use the whole string. If 8511 STRING is multibyte, the message will be displayed multibyte. 8512 8513 If S is not null, set the message to the first LEN bytes of S. LEN 8514 zero means use the whole string. MULTIBYTE_P non-zero means S is 8515 multibyte. Display the message multibyte in that case. 8516 8517 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks 8518 to t before calling set_message_1 (which calls insert). 8519 */ 8520 8521void 8522set_message (s, string, nbytes, multibyte_p) 8523 const char *s; 8524 Lisp_Object string; 8525 int nbytes, multibyte_p; 8526{ 8527 message_enable_multibyte 8528 = ((s && multibyte_p) 8529 || (STRINGP (string) && STRING_MULTIBYTE (string))); 8530 8531 with_echo_area_buffer (0, 0, set_message_1, 8532 (EMACS_INT) s, string, nbytes, multibyte_p); 8533 message_buf_print = 0; 8534 help_echo_showing_p = 0; 8535} 8536 8537 8538/* Helper function for set_message. Arguments have the same meaning 8539 as there, with A1 corresponding to S and A2 corresponding to STRING 8540 This function is called with the echo area buffer being 8541 current. */ 8542 8543static int 8544set_message_1 (a1, a2, nbytes, multibyte_p) 8545 EMACS_INT a1; 8546 Lisp_Object a2; 8547 EMACS_INT nbytes, multibyte_p; 8548{ 8549 const char *s = (const char *) a1; 8550 Lisp_Object string = a2; 8551 8552 /* Change multibyteness of the echo buffer appropriately. */ 8553 if (message_enable_multibyte 8554 != !NILP (current_buffer->enable_multibyte_characters)) 8555 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil); 8556 8557 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil; 8558 8559 /* Insert new message at BEG. */ 8560 TEMP_SET_PT_BOTH (BEG, BEG_BYTE); 8561 Ferase_buffer (); 8562 8563 if (STRINGP (string)) 8564 { 8565 int nchars; 8566 8567 if (nbytes == 0) 8568 nbytes = SBYTES (string); 8569 nchars = string_byte_to_char (string, nbytes); 8570 8571 /* This function takes care of single/multibyte conversion. We 8572 just have to ensure that the echo area buffer has the right 8573 setting of enable_multibyte_characters. */ 8574 insert_from_string (string, 0, 0, nchars, nbytes, 1); 8575 } 8576 else if (s) 8577 { 8578 if (nbytes == 0) 8579 nbytes = strlen (s); 8580 8581 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters)) 8582 { 8583 /* Convert from multi-byte to single-byte. */ 8584 int i, c, n; 8585 unsigned char work[1]; 8586 8587 /* Convert a multibyte string to single-byte. */ 8588 for (i = 0; i < nbytes; i += n) 8589 { 8590 c = string_char_and_length (s + i, nbytes - i, &n); 8591 work[0] = (SINGLE_BYTE_CHAR_P (c) 8592 ? c 8593 : multibyte_char_to_unibyte (c, Qnil)); 8594 insert_1_both (work, 1, 1, 1, 0, 0); 8595 } 8596 } 8597 else if (!multibyte_p 8598 && !NILP (current_buffer->enable_multibyte_characters)) 8599 { 8600 /* Convert from single-byte to multi-byte. */ 8601 int i, c, n; 8602 const unsigned char *msg = (const unsigned char *) s; 8603 unsigned char str[MAX_MULTIBYTE_LENGTH]; 8604 8605 /* Convert a single-byte string to multibyte. */ 8606 for (i = 0; i < nbytes; i++) 8607 { 8608 c = unibyte_char_to_multibyte (msg[i]); 8609 n = CHAR_STRING (c, str); 8610 insert_1_both (str, 1, n, 1, 0, 0); 8611 } 8612 } 8613 else 8614 insert_1 (s, nbytes, 1, 0, 0); 8615 } 8616 8617 return 0; 8618} 8619 8620 8621/* Clear messages. CURRENT_P non-zero means clear the current 8622 message. LAST_DISPLAYED_P non-zero means clear the message 8623 last displayed. */ 8624 8625void 8626clear_message (current_p, last_displayed_p) 8627 int current_p, last_displayed_p; 8628{ 8629 if (current_p) 8630 { 8631 echo_area_buffer[0] = Qnil; 8632 message_cleared_p = 1; 8633 } 8634 8635 if (last_displayed_p) 8636 echo_area_buffer[1] = Qnil; 8637 8638 message_buf_print = 0; 8639} 8640 8641/* Clear garbaged frames. 8642 8643 This function is used where the old redisplay called 8644 redraw_garbaged_frames which in turn called redraw_frame which in 8645 turn called clear_frame. The call to clear_frame was a source of 8646 flickering. I believe a clear_frame is not necessary. It should 8647 suffice in the new redisplay to invalidate all current matrices, 8648 and ensure a complete redisplay of all windows. */ 8649 8650static void 8651clear_garbaged_frames () 8652{ 8653 if (frame_garbaged) 8654 { 8655 Lisp_Object tail, frame; 8656 int changed_count = 0; 8657 8658 FOR_EACH_FRAME (tail, frame) 8659 { 8660 struct frame *f = XFRAME (frame); 8661 8662 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f)) 8663 { 8664 if (f->resized_p) 8665 { 8666 Fredraw_frame (frame); 8667 f->force_flush_display_p = 1; 8668 } 8669 clear_current_matrices (f); 8670 changed_count++; 8671 f->garbaged = 0; 8672 f->resized_p = 0; 8673 } 8674 } 8675 8676 frame_garbaged = 0; 8677 if (changed_count) 8678 ++windows_or_buffers_changed; 8679 } 8680} 8681 8682 8683/* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P 8684 is non-zero update selected_frame. Value is non-zero if the 8685 mini-windows height has been changed. */ 8686 8687static int 8688echo_area_display (update_frame_p) 8689 int update_frame_p; 8690{ 8691 Lisp_Object mini_window; 8692 struct window *w; 8693 struct frame *f; 8694 int window_height_changed_p = 0; 8695 struct frame *sf = SELECTED_FRAME (); 8696 8697 mini_window = FRAME_MINIBUF_WINDOW (sf); 8698 w = XWINDOW (mini_window); 8699 f = XFRAME (WINDOW_FRAME (w)); 8700 8701 /* Don't display if frame is invisible or not yet initialized. */ 8702 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p) 8703 return 0; 8704 8705/* The terminal frame is used as the first Emacs frame on the Mac OS. */ 8706#ifndef MAC_OS8 8707#ifdef HAVE_WINDOW_SYSTEM 8708 /* When Emacs starts, selected_frame may be a visible terminal 8709 frame, even if we run under a window system. If we let this 8710 through, a message would be displayed on the terminal. */ 8711 if (EQ (selected_frame, Vterminal_frame) 8712 && !NILP (Vwindow_system)) 8713 return 0; 8714#endif /* HAVE_WINDOW_SYSTEM */ 8715#endif 8716 8717 /* Redraw garbaged frames. */ 8718 if (frame_garbaged) 8719 clear_garbaged_frames (); 8720 8721 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0) 8722 { 8723 echo_area_window = mini_window; 8724 window_height_changed_p = display_echo_area (w); 8725 w->must_be_updated_p = 1; 8726 8727 /* Update the display, unless called from redisplay_internal. 8728 Also don't update the screen during redisplay itself. The 8729 update will happen at the end of redisplay, and an update 8730 here could cause confusion. */ 8731 if (update_frame_p && !redisplaying_p) 8732 { 8733 int n = 0; 8734 8735 /* If the display update has been interrupted by pending 8736 input, update mode lines in the frame. Due to the 8737 pending input, it might have been that redisplay hasn't 8738 been called, so that mode lines above the echo area are 8739 garbaged. This looks odd, so we prevent it here. */ 8740 if (!display_completed) 8741 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0); 8742 8743 if (window_height_changed_p 8744 /* Don't do this if Emacs is shutting down. Redisplay 8745 needs to run hooks. */ 8746 && !NILP (Vrun_hooks)) 8747 { 8748 /* Must update other windows. Likewise as in other 8749 cases, don't let this update be interrupted by 8750 pending input. */ 8751 int count = SPECPDL_INDEX (); 8752 specbind (Qredisplay_dont_pause, Qt); 8753 windows_or_buffers_changed = 1; 8754 redisplay_internal (0); 8755 unbind_to (count, Qnil); 8756 } 8757 else if (FRAME_WINDOW_P (f) && n == 0) 8758 { 8759 /* Window configuration is the same as before. 8760 Can do with a display update of the echo area, 8761 unless we displayed some mode lines. */ 8762 update_single_window (w, 1); 8763 rif->flush_display (f); 8764 } 8765 else 8766 update_frame (f, 1, 1); 8767 8768 /* If cursor is in the echo area, make sure that the next 8769 redisplay displays the minibuffer, so that the cursor will 8770 be replaced with what the minibuffer wants. */ 8771 if (cursor_in_echo_area) 8772 ++windows_or_buffers_changed; 8773 } 8774 } 8775 else if (!EQ (mini_window, selected_window)) 8776 windows_or_buffers_changed++; 8777 8778 /* The current message is now also the last one displayed. */ 8779 echo_area_buffer[1] = echo_area_buffer[0]; 8780 8781 /* Prevent redisplay optimization in redisplay_internal by resetting 8782 this_line_start_pos. This is done because the mini-buffer now 8783 displays the message instead of its buffer text. */ 8784 if (EQ (mini_window, selected_window)) 8785 CHARPOS (this_line_start_pos) = 0; 8786 8787 return window_height_changed_p; 8788} 8789 8790 8791 8792/*********************************************************************** 8793 Mode Lines and Frame Titles 8794 ***********************************************************************/ 8795 8796/* A buffer for constructing non-propertized mode-line strings and 8797 frame titles in it; allocated from the heap in init_xdisp and 8798 resized as needed in store_mode_line_noprop_char. */ 8799 8800static char *mode_line_noprop_buf; 8801 8802/* The buffer's end, and a current output position in it. */ 8803 8804static char *mode_line_noprop_buf_end; 8805static char *mode_line_noprop_ptr; 8806 8807#define MODE_LINE_NOPROP_LEN(start) \ 8808 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start) 8809 8810static enum { 8811 MODE_LINE_DISPLAY = 0, 8812 MODE_LINE_TITLE, 8813 MODE_LINE_NOPROP, 8814 MODE_LINE_STRING 8815} mode_line_target; 8816 8817/* Alist that caches the results of :propertize. 8818 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */ 8819static Lisp_Object mode_line_proptrans_alist; 8820 8821/* List of strings making up the mode-line. */ 8822static Lisp_Object mode_line_string_list; 8823 8824/* Base face property when building propertized mode line string. */ 8825static Lisp_Object mode_line_string_face; 8826static Lisp_Object mode_line_string_face_prop; 8827 8828 8829/* Unwind data for mode line strings */ 8830 8831static Lisp_Object Vmode_line_unwind_vector; 8832 8833static Lisp_Object 8834format_mode_line_unwind_data (obuf, save_proptrans) 8835 struct buffer *obuf; 8836{ 8837 Lisp_Object vector; 8838 8839 /* Reduce consing by keeping one vector in 8840 Vwith_echo_area_save_vector. */ 8841 vector = Vmode_line_unwind_vector; 8842 Vmode_line_unwind_vector = Qnil; 8843 8844 if (NILP (vector)) 8845 vector = Fmake_vector (make_number (7), Qnil); 8846 8847 AREF (vector, 0) = make_number (mode_line_target); 8848 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0)); 8849 AREF (vector, 2) = mode_line_string_list; 8850 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt); 8851 AREF (vector, 4) = mode_line_string_face; 8852 AREF (vector, 5) = mode_line_string_face_prop; 8853 8854 if (obuf) 8855 XSETBUFFER (AREF (vector, 6), obuf); 8856 else 8857 AREF (vector, 6) = Qnil; 8858 8859 return vector; 8860} 8861 8862static Lisp_Object 8863unwind_format_mode_line (vector) 8864 Lisp_Object vector; 8865{ 8866 mode_line_target = XINT (AREF (vector, 0)); 8867 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1)); 8868 mode_line_string_list = AREF (vector, 2); 8869 if (! EQ (AREF (vector, 3), Qt)) 8870 mode_line_proptrans_alist = AREF (vector, 3); 8871 mode_line_string_face = AREF (vector, 4); 8872 mode_line_string_face_prop = AREF (vector, 5); 8873 8874 if (!NILP (AREF (vector, 6))) 8875 { 8876 set_buffer_internal_1 (XBUFFER (AREF (vector, 6))); 8877 AREF (vector, 6) = Qnil; 8878 } 8879 8880 Vmode_line_unwind_vector = vector; 8881 return Qnil; 8882} 8883 8884 8885/* Store a single character C for the frame title in mode_line_noprop_buf. 8886 Re-allocate mode_line_noprop_buf if necessary. */ 8887 8888static void 8889#ifdef PROTOTYPES 8890store_mode_line_noprop_char (char c) 8891#else 8892store_mode_line_noprop_char (c) 8893 char c; 8894#endif 8895{ 8896 /* If output position has reached the end of the allocated buffer, 8897 double the buffer's size. */ 8898 if (mode_line_noprop_ptr == mode_line_noprop_buf_end) 8899 { 8900 int len = MODE_LINE_NOPROP_LEN (0); 8901 int new_size = 2 * len * sizeof *mode_line_noprop_buf; 8902 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size); 8903 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size; 8904 mode_line_noprop_ptr = mode_line_noprop_buf + len; 8905 } 8906 8907 *mode_line_noprop_ptr++ = c; 8908} 8909 8910 8911/* Store part of a frame title in mode_line_noprop_buf, beginning at 8912 mode_line_noprop_ptr. STR is the string to store. Do not copy 8913 characters that yield more columns than PRECISION; PRECISION <= 0 8914 means copy the whole string. Pad with spaces until FIELD_WIDTH 8915 number of characters have been copied; FIELD_WIDTH <= 0 means don't 8916 pad. Called from display_mode_element when it is used to build a 8917 frame title. */ 8918 8919static int 8920store_mode_line_noprop (str, field_width, precision) 8921 const unsigned char *str; 8922 int field_width, precision; 8923{ 8924 int n = 0; 8925 int dummy, nbytes; 8926 8927 /* Copy at most PRECISION chars from STR. */ 8928 nbytes = strlen (str); 8929 n += c_string_width (str, nbytes, precision, &dummy, &nbytes); 8930 while (nbytes--) 8931 store_mode_line_noprop_char (*str++); 8932 8933 /* Fill up with spaces until FIELD_WIDTH reached. */ 8934 while (field_width > 0 8935 && n < field_width) 8936 { 8937 store_mode_line_noprop_char (' '); 8938 ++n; 8939 } 8940 8941 return n; 8942} 8943 8944/*********************************************************************** 8945 Frame Titles 8946 ***********************************************************************/ 8947 8948#ifdef HAVE_WINDOW_SYSTEM 8949 8950/* Set the title of FRAME, if it has changed. The title format is 8951 Vicon_title_format if FRAME is iconified, otherwise it is 8952 frame_title_format. */ 8953 8954static void 8955x_consider_frame_title (frame) 8956 Lisp_Object frame; 8957{ 8958 struct frame *f = XFRAME (frame); 8959 8960 if (FRAME_WINDOW_P (f) 8961 || FRAME_MINIBUF_ONLY_P (f) 8962 || f->explicit_name) 8963 { 8964 /* Do we have more than one visible frame on this X display? */ 8965 Lisp_Object tail; 8966 Lisp_Object fmt; 8967 int title_start; 8968 char *title; 8969 int len; 8970 struct it it; 8971 int count = SPECPDL_INDEX (); 8972 8973 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 8974 { 8975 Lisp_Object other_frame = XCAR (tail); 8976 struct frame *tf = XFRAME (other_frame); 8977 8978 if (tf != f 8979 && FRAME_KBOARD (tf) == FRAME_KBOARD (f) 8980 && !FRAME_MINIBUF_ONLY_P (tf) 8981 && !EQ (other_frame, tip_frame) 8982 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf))) 8983 break; 8984 } 8985 8986 /* Set global variable indicating that multiple frames exist. */ 8987 multiple_frames = CONSP (tail); 8988 8989 /* Switch to the buffer of selected window of the frame. Set up 8990 mode_line_target so that display_mode_element will output into 8991 mode_line_noprop_buf; then display the title. */ 8992 record_unwind_protect (unwind_format_mode_line, 8993 format_mode_line_unwind_data (current_buffer, 0)); 8994 8995 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer)); 8996 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; 8997 8998 mode_line_target = MODE_LINE_TITLE; 8999 title_start = MODE_LINE_NOPROP_LEN (0); 9000 init_iterator (&it, XWINDOW (f->selected_window), -1, -1, 9001 NULL, DEFAULT_FACE_ID); 9002 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0); 9003 len = MODE_LINE_NOPROP_LEN (title_start); 9004 title = mode_line_noprop_buf + title_start; 9005 unbind_to (count, Qnil); 9006 9007 /* Set the title only if it's changed. This avoids consing in 9008 the common case where it hasn't. (If it turns out that we've 9009 already wasted too much time by walking through the list with 9010 display_mode_element, then we might need to optimize at a 9011 higher level than this.) */ 9012 if (! STRINGP (f->name) 9013 || SBYTES (f->name) != len 9014 || bcmp (title, SDATA (f->name), len) != 0) 9015 x_implicitly_set_name (f, make_string (title, len), Qnil); 9016 } 9017} 9018 9019#endif /* not HAVE_WINDOW_SYSTEM */ 9020 9021 9022 9023 9024/*********************************************************************** 9025 Menu Bars 9026 ***********************************************************************/ 9027 9028 9029/* Prepare for redisplay by updating menu-bar item lists when 9030 appropriate. This can call eval. */ 9031 9032void 9033prepare_menu_bars () 9034{ 9035 int all_windows; 9036 struct gcpro gcpro1, gcpro2; 9037 struct frame *f; 9038 Lisp_Object tooltip_frame; 9039 9040#ifdef HAVE_WINDOW_SYSTEM 9041 tooltip_frame = tip_frame; 9042#else 9043 tooltip_frame = Qnil; 9044#endif 9045 9046 /* Update all frame titles based on their buffer names, etc. We do 9047 this before the menu bars so that the buffer-menu will show the 9048 up-to-date frame titles. */ 9049#ifdef HAVE_WINDOW_SYSTEM 9050 if (windows_or_buffers_changed || update_mode_lines) 9051 { 9052 Lisp_Object tail, frame; 9053 9054 FOR_EACH_FRAME (tail, frame) 9055 { 9056 f = XFRAME (frame); 9057 if (!EQ (frame, tooltip_frame) 9058 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))) 9059 x_consider_frame_title (frame); 9060 } 9061 } 9062#endif /* HAVE_WINDOW_SYSTEM */ 9063 9064 /* Update the menu bar item lists, if appropriate. This has to be 9065 done before any actual redisplay or generation of display lines. */ 9066 all_windows = (update_mode_lines 9067 || buffer_shared > 1 9068 || windows_or_buffers_changed); 9069 if (all_windows) 9070 { 9071 Lisp_Object tail, frame; 9072 int count = SPECPDL_INDEX (); 9073 /* 1 means that update_menu_bar has run its hooks 9074 so any further calls to update_menu_bar shouldn't do so again. */ 9075 int menu_bar_hooks_run = 0; 9076 9077 record_unwind_save_match_data (); 9078 9079 FOR_EACH_FRAME (tail, frame) 9080 { 9081 f = XFRAME (frame); 9082 9083 /* Ignore tooltip frame. */ 9084 if (EQ (frame, tooltip_frame)) 9085 continue; 9086 9087 /* If a window on this frame changed size, report that to 9088 the user and clear the size-change flag. */ 9089 if (FRAME_WINDOW_SIZES_CHANGED (f)) 9090 { 9091 Lisp_Object functions; 9092 9093 /* Clear flag first in case we get an error below. */ 9094 FRAME_WINDOW_SIZES_CHANGED (f) = 0; 9095 functions = Vwindow_size_change_functions; 9096 GCPRO2 (tail, functions); 9097 9098 while (CONSP (functions)) 9099 { 9100 call1 (XCAR (functions), frame); 9101 functions = XCDR (functions); 9102 } 9103 UNGCPRO; 9104 } 9105 9106 GCPRO1 (tail); 9107 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run); 9108#ifdef HAVE_WINDOW_SYSTEM 9109 update_tool_bar (f, 0); 9110#ifdef MAC_OS 9111 mac_update_title_bar (f, 0); 9112#endif 9113#endif 9114 UNGCPRO; 9115 } 9116 9117 unbind_to (count, Qnil); 9118 } 9119 else 9120 { 9121 struct frame *sf = SELECTED_FRAME (); 9122 update_menu_bar (sf, 1, 0); 9123#ifdef HAVE_WINDOW_SYSTEM 9124 update_tool_bar (sf, 1); 9125#ifdef MAC_OS 9126 mac_update_title_bar (sf, 1); 9127#endif 9128#endif 9129 } 9130 9131 /* Motif needs this. See comment in xmenu.c. Turn it off when 9132 pending_menu_activation is not defined. */ 9133#ifdef USE_X_TOOLKIT 9134 pending_menu_activation = 0; 9135#endif 9136} 9137 9138 9139/* Update the menu bar item list for frame F. This has to be done 9140 before we start to fill in any display lines, because it can call 9141 eval. 9142 9143 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. 9144 9145 If HOOKS_RUN is 1, that means a previous call to update_menu_bar 9146 already ran the menu bar hooks for this redisplay, so there 9147 is no need to run them again. The return value is the 9148 updated value of this flag, to pass to the next call. */ 9149 9150static int 9151update_menu_bar (f, save_match_data, hooks_run) 9152 struct frame *f; 9153 int save_match_data; 9154 int hooks_run; 9155{ 9156 Lisp_Object window; 9157 register struct window *w; 9158 9159 /* If called recursively during a menu update, do nothing. This can 9160 happen when, for instance, an activate-menubar-hook causes a 9161 redisplay. */ 9162 if (inhibit_menubar_update) 9163 return hooks_run; 9164 9165 window = FRAME_SELECTED_WINDOW (f); 9166 w = XWINDOW (window); 9167 9168#if 0 /* The if statement below this if statement used to include the 9169 condition !NILP (w->update_mode_line), rather than using 9170 update_mode_lines directly, and this if statement may have 9171 been added to make that condition work. Now the if 9172 statement below matches its comment, this isn't needed. */ 9173 if (update_mode_lines) 9174 w->update_mode_line = Qt; 9175#endif 9176 9177 if (FRAME_WINDOW_P (f) 9178 ? 9179#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \ 9180 || defined (USE_GTK) 9181 FRAME_EXTERNAL_MENU_BAR (f) 9182#else 9183 FRAME_MENU_BAR_LINES (f) > 0 9184#endif 9185 : FRAME_MENU_BAR_LINES (f) > 0) 9186 { 9187 /* If the user has switched buffers or windows, we need to 9188 recompute to reflect the new bindings. But we'll 9189 recompute when update_mode_lines is set too; that means 9190 that people can use force-mode-line-update to request 9191 that the menu bar be recomputed. The adverse effect on 9192 the rest of the redisplay algorithm is about the same as 9193 windows_or_buffers_changed anyway. */ 9194 if (windows_or_buffers_changed 9195 /* This used to test w->update_mode_line, but we believe 9196 there is no need to recompute the menu in that case. */ 9197 || update_mode_lines 9198 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer)) 9199 < BUF_MODIFF (XBUFFER (w->buffer))) 9200 != !NILP (w->last_had_star)) 9201 || ((!NILP (Vtransient_mark_mode) 9202 && !NILP (XBUFFER (w->buffer)->mark_active)) 9203 != !NILP (w->region_showing))) 9204 { 9205 struct buffer *prev = current_buffer; 9206 int count = SPECPDL_INDEX (); 9207 9208 specbind (Qinhibit_menubar_update, Qt); 9209 9210 set_buffer_internal_1 (XBUFFER (w->buffer)); 9211 if (save_match_data) 9212 record_unwind_save_match_data (); 9213 if (NILP (Voverriding_local_map_menu_flag)) 9214 { 9215 specbind (Qoverriding_terminal_local_map, Qnil); 9216 specbind (Qoverriding_local_map, Qnil); 9217 } 9218 9219 if (!hooks_run) 9220 { 9221 /* Run the Lucid hook. */ 9222 safe_run_hooks (Qactivate_menubar_hook); 9223 9224 /* If it has changed current-menubar from previous value, 9225 really recompute the menu-bar from the value. */ 9226 if (! NILP (Vlucid_menu_bar_dirty_flag)) 9227 call0 (Qrecompute_lucid_menubar); 9228 9229 safe_run_hooks (Qmenu_bar_update_hook); 9230 9231 hooks_run = 1; 9232 } 9233 9234 XSETFRAME (Vmenu_updating_frame, f); 9235 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); 9236 9237 /* Redisplay the menu bar in case we changed it. */ 9238#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \ 9239 || defined (USE_GTK) 9240 if (FRAME_WINDOW_P (f)) 9241 { 9242#ifdef MAC_OS 9243 /* All frames on Mac OS share the same menubar. So only 9244 the selected frame should be allowed to set it. */ 9245 if (f == SELECTED_FRAME ()) 9246#endif 9247 set_frame_menubar (f, 0, 0); 9248 } 9249 else 9250 /* On a terminal screen, the menu bar is an ordinary screen 9251 line, and this makes it get updated. */ 9252 w->update_mode_line = Qt; 9253#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */ 9254 /* In the non-toolkit version, the menu bar is an ordinary screen 9255 line, and this makes it get updated. */ 9256 w->update_mode_line = Qt; 9257#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */ 9258 9259 unbind_to (count, Qnil); 9260 set_buffer_internal_1 (prev); 9261 } 9262 } 9263 9264 return hooks_run; 9265} 9266 9267 9268 9269/*********************************************************************** 9270 Output Cursor 9271 ***********************************************************************/ 9272 9273#ifdef HAVE_WINDOW_SYSTEM 9274 9275/* EXPORT: 9276 Nominal cursor position -- where to draw output. 9277 HPOS and VPOS are window relative glyph matrix coordinates. 9278 X and Y are window relative pixel coordinates. */ 9279 9280struct cursor_pos output_cursor; 9281 9282 9283/* EXPORT: 9284 Set the global variable output_cursor to CURSOR. All cursor 9285 positions are relative to updated_window. */ 9286 9287void 9288set_output_cursor (cursor) 9289 struct cursor_pos *cursor; 9290{ 9291 output_cursor.hpos = cursor->hpos; 9292 output_cursor.vpos = cursor->vpos; 9293 output_cursor.x = cursor->x; 9294 output_cursor.y = cursor->y; 9295} 9296 9297 9298/* EXPORT for RIF: 9299 Set a nominal cursor position. 9300 9301 HPOS and VPOS are column/row positions in a window glyph matrix. X 9302 and Y are window text area relative pixel positions. 9303 9304 If this is done during an update, updated_window will contain the 9305 window that is being updated and the position is the future output 9306 cursor position for that window. If updated_window is null, use 9307 selected_window and display the cursor at the given position. */ 9308 9309void 9310x_cursor_to (vpos, hpos, y, x) 9311 int vpos, hpos, y, x; 9312{ 9313 struct window *w; 9314 9315 /* If updated_window is not set, work on selected_window. */ 9316 if (updated_window) 9317 w = updated_window; 9318 else 9319 w = XWINDOW (selected_window); 9320 9321 /* Set the output cursor. */ 9322 output_cursor.hpos = hpos; 9323 output_cursor.vpos = vpos; 9324 output_cursor.x = x; 9325 output_cursor.y = y; 9326 9327 /* If not called as part of an update, really display the cursor. 9328 This will also set the cursor position of W. */ 9329 if (updated_window == NULL) 9330 { 9331 BLOCK_INPUT; 9332 display_and_set_cursor (w, 1, hpos, vpos, x, y); 9333 if (rif->flush_display_optional) 9334 rif->flush_display_optional (SELECTED_FRAME ()); 9335 UNBLOCK_INPUT; 9336 } 9337} 9338 9339#endif /* HAVE_WINDOW_SYSTEM */ 9340 9341 9342/*********************************************************************** 9343 Tool-bars 9344 ***********************************************************************/ 9345 9346#ifdef HAVE_WINDOW_SYSTEM 9347 9348/* Where the mouse was last time we reported a mouse event. */ 9349 9350FRAME_PTR last_mouse_frame; 9351 9352/* Tool-bar item index of the item on which a mouse button was pressed 9353 or -1. */ 9354 9355int last_tool_bar_item; 9356 9357 9358/* Update the tool-bar item list for frame F. This has to be done 9359 before we start to fill in any display lines. Called from 9360 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save 9361 and restore it here. */ 9362 9363static void 9364update_tool_bar (f, save_match_data) 9365 struct frame *f; 9366 int save_match_data; 9367{ 9368#ifdef USE_GTK 9369 int do_update = FRAME_EXTERNAL_TOOL_BAR (f); 9370#else 9371 int do_update = WINDOWP (f->tool_bar_window) 9372 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0; 9373#endif 9374 9375 if (do_update) 9376 { 9377 Lisp_Object window; 9378 struct window *w; 9379 9380 window = FRAME_SELECTED_WINDOW (f); 9381 w = XWINDOW (window); 9382 9383 /* If the user has switched buffers or windows, we need to 9384 recompute to reflect the new bindings. But we'll 9385 recompute when update_mode_lines is set too; that means 9386 that people can use force-mode-line-update to request 9387 that the menu bar be recomputed. The adverse effect on 9388 the rest of the redisplay algorithm is about the same as 9389 windows_or_buffers_changed anyway. */ 9390 if (windows_or_buffers_changed 9391 || !NILP (w->update_mode_line) 9392 || update_mode_lines 9393 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer)) 9394 < BUF_MODIFF (XBUFFER (w->buffer))) 9395 != !NILP (w->last_had_star)) 9396 || ((!NILP (Vtransient_mark_mode) 9397 && !NILP (XBUFFER (w->buffer)->mark_active)) 9398 != !NILP (w->region_showing))) 9399 { 9400 struct buffer *prev = current_buffer; 9401 int count = SPECPDL_INDEX (); 9402 Lisp_Object new_tool_bar; 9403 int new_n_tool_bar; 9404 struct gcpro gcpro1; 9405 9406 /* Set current_buffer to the buffer of the selected 9407 window of the frame, so that we get the right local 9408 keymaps. */ 9409 set_buffer_internal_1 (XBUFFER (w->buffer)); 9410 9411 /* Save match data, if we must. */ 9412 if (save_match_data) 9413 record_unwind_save_match_data (); 9414 9415 /* Make sure that we don't accidentally use bogus keymaps. */ 9416 if (NILP (Voverriding_local_map_menu_flag)) 9417 { 9418 specbind (Qoverriding_terminal_local_map, Qnil); 9419 specbind (Qoverriding_local_map, Qnil); 9420 } 9421 9422 GCPRO1 (new_tool_bar); 9423 9424 /* Build desired tool-bar items from keymaps. */ 9425 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items), 9426 &new_n_tool_bar); 9427 9428 /* Redisplay the tool-bar if we changed it. */ 9429 if (new_n_tool_bar != f->n_tool_bar_items 9430 || NILP (Fequal (new_tool_bar, f->tool_bar_items))) 9431 { 9432 /* Redisplay that happens asynchronously due to an expose event 9433 may access f->tool_bar_items. Make sure we update both 9434 variables within BLOCK_INPUT so no such event interrupts. */ 9435 BLOCK_INPUT; 9436 f->tool_bar_items = new_tool_bar; 9437 f->n_tool_bar_items = new_n_tool_bar; 9438 w->update_mode_line = Qt; 9439 UNBLOCK_INPUT; 9440 } 9441 9442 UNGCPRO; 9443 9444 unbind_to (count, Qnil); 9445 set_buffer_internal_1 (prev); 9446 } 9447 } 9448} 9449 9450 9451/* Set F->desired_tool_bar_string to a Lisp string representing frame 9452 F's desired tool-bar contents. F->tool_bar_items must have 9453 been set up previously by calling prepare_menu_bars. */ 9454 9455static void 9456build_desired_tool_bar_string (f) 9457 struct frame *f; 9458{ 9459 int i, size, size_needed; 9460 struct gcpro gcpro1, gcpro2, gcpro3; 9461 Lisp_Object image, plist, props; 9462 9463 image = plist = props = Qnil; 9464 GCPRO3 (image, plist, props); 9465 9466 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so. 9467 Otherwise, make a new string. */ 9468 9469 /* The size of the string we might be able to reuse. */ 9470 size = (STRINGP (f->desired_tool_bar_string) 9471 ? SCHARS (f->desired_tool_bar_string) 9472 : 0); 9473 9474 /* We need one space in the string for each image. */ 9475 size_needed = f->n_tool_bar_items; 9476 9477 /* Reuse f->desired_tool_bar_string, if possible. */ 9478 if (size < size_needed || NILP (f->desired_tool_bar_string)) 9479 f->desired_tool_bar_string = Fmake_string (make_number (size_needed), 9480 make_number (' ')); 9481 else 9482 { 9483 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil); 9484 Fremove_text_properties (make_number (0), make_number (size), 9485 props, f->desired_tool_bar_string); 9486 } 9487 9488 /* Put a `display' property on the string for the images to display, 9489 put a `menu_item' property on tool-bar items with a value that 9490 is the index of the item in F's tool-bar item vector. */ 9491 for (i = 0; i < f->n_tool_bar_items; ++i) 9492 { 9493#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX)) 9494 9495 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); 9496 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); 9497 int hmargin, vmargin, relief, idx, end; 9498 extern Lisp_Object QCrelief, QCmargin, QCconversion; 9499 9500 /* If image is a vector, choose the image according to the 9501 button state. */ 9502 image = PROP (TOOL_BAR_ITEM_IMAGES); 9503 if (VECTORP (image)) 9504 { 9505 if (enabled_p) 9506 idx = (selected_p 9507 ? TOOL_BAR_IMAGE_ENABLED_SELECTED 9508 : TOOL_BAR_IMAGE_ENABLED_DESELECTED); 9509 else 9510 idx = (selected_p 9511 ? TOOL_BAR_IMAGE_DISABLED_SELECTED 9512 : TOOL_BAR_IMAGE_DISABLED_DESELECTED); 9513 9514 xassert (ASIZE (image) >= idx); 9515 image = AREF (image, idx); 9516 } 9517 else 9518 idx = -1; 9519 9520 /* Ignore invalid image specifications. */ 9521 if (!valid_image_p (image)) 9522 continue; 9523 9524 /* Display the tool-bar button pressed, or depressed. */ 9525 plist = Fcopy_sequence (XCDR (image)); 9526 9527 /* Compute margin and relief to draw. */ 9528 relief = (tool_bar_button_relief >= 0 9529 ? tool_bar_button_relief 9530 : DEFAULT_TOOL_BAR_BUTTON_RELIEF); 9531 hmargin = vmargin = relief; 9532 9533 if (INTEGERP (Vtool_bar_button_margin) 9534 && XINT (Vtool_bar_button_margin) > 0) 9535 { 9536 hmargin += XFASTINT (Vtool_bar_button_margin); 9537 vmargin += XFASTINT (Vtool_bar_button_margin); 9538 } 9539 else if (CONSP (Vtool_bar_button_margin)) 9540 { 9541 if (INTEGERP (XCAR (Vtool_bar_button_margin)) 9542 && XINT (XCAR (Vtool_bar_button_margin)) > 0) 9543 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin)); 9544 9545 if (INTEGERP (XCDR (Vtool_bar_button_margin)) 9546 && XINT (XCDR (Vtool_bar_button_margin)) > 0) 9547 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin)); 9548 } 9549 9550 if (auto_raise_tool_bar_buttons_p) 9551 { 9552 /* Add a `:relief' property to the image spec if the item is 9553 selected. */ 9554 if (selected_p) 9555 { 9556 plist = Fplist_put (plist, QCrelief, make_number (-relief)); 9557 hmargin -= relief; 9558 vmargin -= relief; 9559 } 9560 } 9561 else 9562 { 9563 /* If image is selected, display it pressed, i.e. with a 9564 negative relief. If it's not selected, display it with a 9565 raised relief. */ 9566 plist = Fplist_put (plist, QCrelief, 9567 (selected_p 9568 ? make_number (-relief) 9569 : make_number (relief))); 9570 hmargin -= relief; 9571 vmargin -= relief; 9572 } 9573 9574 /* Put a margin around the image. */ 9575 if (hmargin || vmargin) 9576 { 9577 if (hmargin == vmargin) 9578 plist = Fplist_put (plist, QCmargin, make_number (hmargin)); 9579 else 9580 plist = Fplist_put (plist, QCmargin, 9581 Fcons (make_number (hmargin), 9582 make_number (vmargin))); 9583 } 9584 9585 /* If button is not enabled, and we don't have special images 9586 for the disabled state, make the image appear disabled by 9587 applying an appropriate algorithm to it. */ 9588 if (!enabled_p && idx < 0) 9589 plist = Fplist_put (plist, QCconversion, Qdisabled); 9590 9591 /* Put a `display' text property on the string for the image to 9592 display. Put a `menu-item' property on the string that gives 9593 the start of this item's properties in the tool-bar items 9594 vector. */ 9595 image = Fcons (Qimage, plist); 9596 props = list4 (Qdisplay, image, 9597 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)); 9598 9599 /* Let the last image hide all remaining spaces in the tool bar 9600 string. The string can be longer than needed when we reuse a 9601 previous string. */ 9602 if (i + 1 == f->n_tool_bar_items) 9603 end = SCHARS (f->desired_tool_bar_string); 9604 else 9605 end = i + 1; 9606 Fadd_text_properties (make_number (i), make_number (end), 9607 props, f->desired_tool_bar_string); 9608#undef PROP 9609 } 9610 9611 UNGCPRO; 9612} 9613 9614 9615/* Display one line of the tool-bar of frame IT->f. 9616 9617 HEIGHT specifies the desired height of the tool-bar line. 9618 If the actual height of the glyph row is less than HEIGHT, the 9619 row's height is increased to HEIGHT, and the icons are centered 9620 vertically in the new height. 9621 9622 If HEIGHT is -1, we are counting needed tool-bar lines, so don't 9623 count a final empty row in case the tool-bar width exactly matches 9624 the window width. 9625*/ 9626 9627static void 9628display_tool_bar_line (it, height) 9629 struct it *it; 9630 int height; 9631{ 9632 struct glyph_row *row = it->glyph_row; 9633 int max_x = it->last_visible_x; 9634 struct glyph *last; 9635 9636 prepare_desired_row (row); 9637 row->y = it->current_y; 9638 9639 /* Note that this isn't made use of if the face hasn't a box, 9640 so there's no need to check the face here. */ 9641 it->start_of_box_run_p = 1; 9642 9643 while (it->current_x < max_x) 9644 { 9645 int x, n_glyphs_before, i, nglyphs; 9646 struct it it_before; 9647 9648 /* Get the next display element. */ 9649 if (!get_next_display_element (it)) 9650 { 9651 /* Don't count empty row if we are counting needed tool-bar lines. */ 9652 if (height < 0 && !it->hpos) 9653 return; 9654 break; 9655 } 9656 9657 /* Produce glyphs. */ 9658 n_glyphs_before = row->used[TEXT_AREA]; 9659 it_before = *it; 9660 9661 PRODUCE_GLYPHS (it); 9662 9663 nglyphs = row->used[TEXT_AREA] - n_glyphs_before; 9664 i = 0; 9665 x = it_before.current_x; 9666 while (i < nglyphs) 9667 { 9668 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i; 9669 9670 if (x + glyph->pixel_width > max_x) 9671 { 9672 /* Glyph doesn't fit on line. Backtrack. */ 9673 row->used[TEXT_AREA] = n_glyphs_before; 9674 *it = it_before; 9675 /* If this is the only glyph on this line, it will never fit on the 9676 toolbar, so skip it. But ensure there is at least one glyph, 9677 so we don't accidentally disable the tool-bar. */ 9678 if (n_glyphs_before == 0 9679 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1)) 9680 break; 9681 goto out; 9682 } 9683 9684 ++it->hpos; 9685 x += glyph->pixel_width; 9686 ++i; 9687 } 9688 9689 /* Stop at line ends. */ 9690 if (ITERATOR_AT_END_OF_LINE_P (it)) 9691 break; 9692 9693 set_iterator_to_next (it, 1); 9694 } 9695 9696 out:; 9697 9698 row->displays_text_p = row->used[TEXT_AREA] != 0; 9699 9700 /* Use default face for the border below the tool bar. 9701 9702 FIXME: When auto-resize-tool-bars is grow-only, there is 9703 no additional border below the possibly empty tool-bar lines. 9704 So to make the extra empty lines look "normal", we have to 9705 use the tool-bar face for the border too. */ 9706 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only)) 9707 it->face_id = DEFAULT_FACE_ID; 9708 9709 extend_face_to_end_of_line (it); 9710 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1; 9711 last->right_box_line_p = 1; 9712 if (last == row->glyphs[TEXT_AREA]) 9713 last->left_box_line_p = 1; 9714 9715 /* Make line the desired height and center it vertically. */ 9716 if ((height -= it->max_ascent + it->max_descent) > 0) 9717 { 9718 /* Don't add more than one line height. */ 9719 height %= FRAME_LINE_HEIGHT (it->f); 9720 it->max_ascent += height / 2; 9721 it->max_descent += (height + 1) / 2; 9722 } 9723 9724 compute_line_metrics (it); 9725 9726 /* If line is empty, make it occupy the rest of the tool-bar. */ 9727 if (!row->displays_text_p) 9728 { 9729 row->height = row->phys_height = it->last_visible_y - row->y; 9730 row->visible_height = row->height; 9731 row->ascent = row->phys_ascent = 0; 9732 row->extra_line_spacing = 0; 9733 } 9734 9735 row->full_width_p = 1; 9736 row->continued_p = 0; 9737 row->truncated_on_left_p = 0; 9738 row->truncated_on_right_p = 0; 9739 9740 it->current_x = it->hpos = 0; 9741 it->current_y += row->height; 9742 ++it->vpos; 9743 ++it->glyph_row; 9744} 9745 9746 9747/* Max tool-bar height. */ 9748 9749#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \ 9750 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f))) 9751 9752/* Value is the number of screen lines needed to make all tool-bar 9753 items of frame F visible. The number of actual rows needed is 9754 returned in *N_ROWS if non-NULL. */ 9755 9756static int 9757tool_bar_lines_needed (f, n_rows) 9758 struct frame *f; 9759 int *n_rows; 9760{ 9761 struct window *w = XWINDOW (f->tool_bar_window); 9762 struct it it; 9763 /* tool_bar_lines_needed is called from redisplay_tool_bar after building 9764 the desired matrix, so use (unused) mode-line row as temporary row to 9765 avoid destroying the first tool-bar row. */ 9766 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix); 9767 9768 /* Initialize an iterator for iteration over 9769 F->desired_tool_bar_string in the tool-bar window of frame F. */ 9770 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID); 9771 it.first_visible_x = 0; 9772 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 9773 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); 9774 9775 while (!ITERATOR_AT_END_P (&it)) 9776 { 9777 clear_glyph_row (temp_row); 9778 it.glyph_row = temp_row; 9779 display_tool_bar_line (&it, -1); 9780 } 9781 clear_glyph_row (temp_row); 9782 9783 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */ 9784 if (n_rows) 9785 *n_rows = it.vpos > 0 ? it.vpos : -1; 9786 9787 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); 9788} 9789 9790 9791DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed, 9792 0, 1, 0, 9793 doc: /* Return the number of lines occupied by the tool bar of FRAME. */) 9794 (frame) 9795 Lisp_Object frame; 9796{ 9797 struct frame *f; 9798 struct window *w; 9799 int nlines = 0; 9800 9801 if (NILP (frame)) 9802 frame = selected_frame; 9803 else 9804 CHECK_FRAME (frame); 9805 f = XFRAME (frame); 9806 9807 if (WINDOWP (f->tool_bar_window) 9808 || (w = XWINDOW (f->tool_bar_window), 9809 WINDOW_TOTAL_LINES (w) > 0)) 9810 { 9811 update_tool_bar (f, 1); 9812 if (f->n_tool_bar_items) 9813 { 9814 build_desired_tool_bar_string (f); 9815 nlines = tool_bar_lines_needed (f, NULL); 9816 } 9817 } 9818 9819 return make_number (nlines); 9820} 9821 9822 9823/* Display the tool-bar of frame F. Value is non-zero if tool-bar's 9824 height should be changed. */ 9825 9826static int 9827redisplay_tool_bar (f) 9828 struct frame *f; 9829{ 9830 struct window *w; 9831 struct it it; 9832 struct glyph_row *row; 9833 9834#ifdef USE_GTK 9835 if (FRAME_EXTERNAL_TOOL_BAR (f)) 9836 update_frame_tool_bar (f); 9837 return 0; 9838#endif 9839 9840 /* If frame hasn't a tool-bar window or if it is zero-height, don't 9841 do anything. This means you must start with tool-bar-lines 9842 non-zero to get the auto-sizing effect. Or in other words, you 9843 can turn off tool-bars by specifying tool-bar-lines zero. */ 9844 if (!WINDOWP (f->tool_bar_window) 9845 || (w = XWINDOW (f->tool_bar_window), 9846 WINDOW_TOTAL_LINES (w) == 0)) 9847 return 0; 9848 9849 /* Set up an iterator for the tool-bar window. */ 9850 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID); 9851 it.first_visible_x = 0; 9852 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 9853 row = it.glyph_row; 9854 9855 /* Build a string that represents the contents of the tool-bar. */ 9856 build_desired_tool_bar_string (f); 9857 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); 9858 9859 if (f->n_tool_bar_rows == 0) 9860 { 9861 int nlines; 9862 9863 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows), 9864 nlines != WINDOW_TOTAL_LINES (w))) 9865 { 9866 extern Lisp_Object Qtool_bar_lines; 9867 Lisp_Object frame; 9868 int old_height = WINDOW_TOTAL_LINES (w); 9869 9870 XSETFRAME (frame, f); 9871 Fmodify_frame_parameters (frame, 9872 Fcons (Fcons (Qtool_bar_lines, 9873 make_number (nlines)), 9874 Qnil)); 9875 if (WINDOW_TOTAL_LINES (w) != old_height) 9876 { 9877 clear_glyph_matrix (w->desired_matrix); 9878 fonts_changed_p = 1; 9879 return 1; 9880 } 9881 } 9882 } 9883 9884 /* Display as many lines as needed to display all tool-bar items. */ 9885 9886 if (f->n_tool_bar_rows > 0) 9887 { 9888 int border, rows, height, extra; 9889 9890 if (INTEGERP (Vtool_bar_border)) 9891 border = XINT (Vtool_bar_border); 9892 else if (EQ (Vtool_bar_border, Qinternal_border_width)) 9893 border = FRAME_INTERNAL_BORDER_WIDTH (f); 9894 else if (EQ (Vtool_bar_border, Qborder_width)) 9895 border = f->border_width; 9896 else 9897 border = 0; 9898 if (border < 0) 9899 border = 0; 9900 9901 rows = f->n_tool_bar_rows; 9902 height = max (1, (it.last_visible_y - border) / rows); 9903 extra = it.last_visible_y - border - height * rows; 9904 9905 while (it.current_y < it.last_visible_y) 9906 { 9907 int h = 0; 9908 if (extra > 0 && rows-- > 0) 9909 { 9910 h = (extra + rows - 1) / rows; 9911 extra -= h; 9912 } 9913 display_tool_bar_line (&it, height + h); 9914 } 9915 } 9916 else 9917 { 9918 while (it.current_y < it.last_visible_y) 9919 display_tool_bar_line (&it, 0); 9920 } 9921 9922 /* It doesn't make much sense to try scrolling in the tool-bar 9923 window, so don't do it. */ 9924 w->desired_matrix->no_scrolling_p = 1; 9925 w->must_be_updated_p = 1; 9926 9927 if (!NILP (Vauto_resize_tool_bars)) 9928 { 9929 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f); 9930 int change_height_p = 0; 9931 9932 /* If we couldn't display everything, change the tool-bar's 9933 height if there is room for more. */ 9934 if (IT_STRING_CHARPOS (it) < it.end_charpos 9935 && it.current_y < max_tool_bar_height) 9936 change_height_p = 1; 9937 9938 row = it.glyph_row - 1; 9939 9940 /* If there are blank lines at the end, except for a partially 9941 visible blank line at the end that is smaller than 9942 FRAME_LINE_HEIGHT, change the tool-bar's height. */ 9943 if (!row->displays_text_p 9944 && row->height >= FRAME_LINE_HEIGHT (f)) 9945 change_height_p = 1; 9946 9947 /* If row displays tool-bar items, but is partially visible, 9948 change the tool-bar's height. */ 9949 if (row->displays_text_p 9950 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y 9951 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height) 9952 change_height_p = 1; 9953 9954 /* Resize windows as needed by changing the `tool-bar-lines' 9955 frame parameter. */ 9956 if (change_height_p) 9957 { 9958 extern Lisp_Object Qtool_bar_lines; 9959 Lisp_Object frame; 9960 int old_height = WINDOW_TOTAL_LINES (w); 9961 int nrows; 9962 int nlines = tool_bar_lines_needed (f, &nrows); 9963 9964 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only) 9965 && !f->minimize_tool_bar_window_p) 9966 ? (nlines > old_height) 9967 : (nlines != old_height)); 9968 f->minimize_tool_bar_window_p = 0; 9969 9970 if (change_height_p) 9971 { 9972 XSETFRAME (frame, f); 9973 Fmodify_frame_parameters (frame, 9974 Fcons (Fcons (Qtool_bar_lines, 9975 make_number (nlines)), 9976 Qnil)); 9977 if (WINDOW_TOTAL_LINES (w) != old_height) 9978 { 9979 clear_glyph_matrix (w->desired_matrix); 9980 f->n_tool_bar_rows = nrows; 9981 fonts_changed_p = 1; 9982 return 1; 9983 } 9984 } 9985 } 9986 } 9987 9988 f->minimize_tool_bar_window_p = 0; 9989 return 0; 9990} 9991 9992 9993/* Get information about the tool-bar item which is displayed in GLYPH 9994 on frame F. Return in *PROP_IDX the index where tool-bar item 9995 properties start in F->tool_bar_items. Value is zero if 9996 GLYPH doesn't display a tool-bar item. */ 9997 9998static int 9999tool_bar_item_info (f, glyph, prop_idx) 10000 struct frame *f; 10001 struct glyph *glyph; 10002 int *prop_idx; 10003{ 10004 Lisp_Object prop; 10005 int success_p; 10006 int charpos; 10007 10008 /* This function can be called asynchronously, which means we must 10009 exclude any possibility that Fget_text_property signals an 10010 error. */ 10011 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos); 10012 charpos = max (0, charpos); 10013 10014 /* Get the text property `menu-item' at pos. The value of that 10015 property is the start index of this item's properties in 10016 F->tool_bar_items. */ 10017 prop = Fget_text_property (make_number (charpos), 10018 Qmenu_item, f->current_tool_bar_string); 10019 if (INTEGERP (prop)) 10020 { 10021 *prop_idx = XINT (prop); 10022 success_p = 1; 10023 } 10024 else 10025 success_p = 0; 10026 10027 return success_p; 10028} 10029 10030 10031/* Get information about the tool-bar item at position X/Y on frame F. 10032 Return in *GLYPH a pointer to the glyph of the tool-bar item in 10033 the current matrix of the tool-bar window of F, or NULL if not 10034 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar 10035 item in F->tool_bar_items. Value is 10036 10037 -1 if X/Y is not on a tool-bar item 10038 0 if X/Y is on the same item that was highlighted before. 10039 1 otherwise. */ 10040 10041static int 10042get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx) 10043 struct frame *f; 10044 int x, y; 10045 struct glyph **glyph; 10046 int *hpos, *vpos, *prop_idx; 10047{ 10048 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 10049 struct window *w = XWINDOW (f->tool_bar_window); 10050 int area; 10051 10052 /* Find the glyph under X/Y. */ 10053 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area); 10054 if (*glyph == NULL) 10055 return -1; 10056 10057 /* Get the start of this tool-bar item's properties in 10058 f->tool_bar_items. */ 10059 if (!tool_bar_item_info (f, *glyph, prop_idx)) 10060 return -1; 10061 10062 /* Is mouse on the highlighted item? */ 10063 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window) 10064 && *vpos >= dpyinfo->mouse_face_beg_row 10065 && *vpos <= dpyinfo->mouse_face_end_row 10066 && (*vpos > dpyinfo->mouse_face_beg_row 10067 || *hpos >= dpyinfo->mouse_face_beg_col) 10068 && (*vpos < dpyinfo->mouse_face_end_row 10069 || *hpos < dpyinfo->mouse_face_end_col 10070 || dpyinfo->mouse_face_past_end)) 10071 return 0; 10072 10073 return 1; 10074} 10075 10076 10077/* EXPORT: 10078 Handle mouse button event on the tool-bar of frame F, at 10079 frame-relative coordinates X/Y. DOWN_P is 1 for a button press, 10080 0 for button release. MODIFIERS is event modifiers for button 10081 release. */ 10082 10083void 10084handle_tool_bar_click (f, x, y, down_p, modifiers) 10085 struct frame *f; 10086 int x, y, down_p; 10087 unsigned int modifiers; 10088{ 10089 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 10090 struct window *w = XWINDOW (f->tool_bar_window); 10091 int hpos, vpos, prop_idx; 10092 struct glyph *glyph; 10093 Lisp_Object enabled_p; 10094 10095 /* If not on the highlighted tool-bar item, return. */ 10096 frame_to_window_pixel_xy (w, &x, &y); 10097 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0) 10098 return; 10099 10100 /* If item is disabled, do nothing. */ 10101 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); 10102 if (NILP (enabled_p)) 10103 return; 10104 10105 if (down_p) 10106 { 10107 /* Show item in pressed state. */ 10108 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN); 10109 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; 10110 last_tool_bar_item = prop_idx; 10111 } 10112 else 10113 { 10114 Lisp_Object key, frame; 10115 struct input_event event; 10116 EVENT_INIT (event); 10117 10118 /* Show item in released state. */ 10119 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED); 10120 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED; 10121 10122 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY); 10123 10124 XSETFRAME (frame, f); 10125 event.kind = TOOL_BAR_EVENT; 10126 event.frame_or_window = frame; 10127 event.arg = frame; 10128 kbd_buffer_store_event (&event); 10129 10130 event.kind = TOOL_BAR_EVENT; 10131 event.frame_or_window = frame; 10132 event.arg = key; 10133 event.modifiers = modifiers; 10134 kbd_buffer_store_event (&event); 10135 last_tool_bar_item = -1; 10136 } 10137} 10138 10139 10140/* Possibly highlight a tool-bar item on frame F when mouse moves to 10141 tool-bar window-relative coordinates X/Y. Called from 10142 note_mouse_highlight. */ 10143 10144static void 10145note_tool_bar_highlight (f, x, y) 10146 struct frame *f; 10147 int x, y; 10148{ 10149 Lisp_Object window = f->tool_bar_window; 10150 struct window *w = XWINDOW (window); 10151 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 10152 int hpos, vpos; 10153 struct glyph *glyph; 10154 struct glyph_row *row; 10155 int i; 10156 Lisp_Object enabled_p; 10157 int prop_idx; 10158 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED; 10159 int mouse_down_p, rc; 10160 10161 /* Function note_mouse_highlight is called with negative x(y 10162 values when mouse moves outside of the frame. */ 10163 if (x <= 0 || y <= 0) 10164 { 10165 clear_mouse_face (dpyinfo); 10166 return; 10167 } 10168 10169 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx); 10170 if (rc < 0) 10171 { 10172 /* Not on tool-bar item. */ 10173 clear_mouse_face (dpyinfo); 10174 return; 10175 } 10176 else if (rc == 0) 10177 /* On same tool-bar item as before. */ 10178 goto set_help_echo; 10179 10180 clear_mouse_face (dpyinfo); 10181 10182 /* Mouse is down, but on different tool-bar item? */ 10183 mouse_down_p = (dpyinfo->grabbed 10184 && f == last_mouse_frame 10185 && FRAME_LIVE_P (f)); 10186 if (mouse_down_p 10187 && last_tool_bar_item != prop_idx) 10188 return; 10189 10190 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; 10191 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; 10192 10193 /* If tool-bar item is not enabled, don't highlight it. */ 10194 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); 10195 if (!NILP (enabled_p)) 10196 { 10197 /* Compute the x-position of the glyph. In front and past the 10198 image is a space. We include this in the highlighted area. */ 10199 row = MATRIX_ROW (w->current_matrix, vpos); 10200 for (i = x = 0; i < hpos; ++i) 10201 x += row->glyphs[TEXT_AREA][i].pixel_width; 10202 10203 /* Record this as the current active region. */ 10204 dpyinfo->mouse_face_beg_col = hpos; 10205 dpyinfo->mouse_face_beg_row = vpos; 10206 dpyinfo->mouse_face_beg_x = x; 10207 dpyinfo->mouse_face_beg_y = row->y; 10208 dpyinfo->mouse_face_past_end = 0; 10209 10210 dpyinfo->mouse_face_end_col = hpos + 1; 10211 dpyinfo->mouse_face_end_row = vpos; 10212 dpyinfo->mouse_face_end_x = x + glyph->pixel_width; 10213 dpyinfo->mouse_face_end_y = row->y; 10214 dpyinfo->mouse_face_window = window; 10215 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; 10216 10217 /* Display it as active. */ 10218 show_mouse_face (dpyinfo, draw); 10219 dpyinfo->mouse_face_image_state = draw; 10220 } 10221 10222 set_help_echo: 10223 10224 /* Set help_echo_string to a help string to display for this tool-bar item. 10225 XTread_socket does the rest. */ 10226 help_echo_object = help_echo_window = Qnil; 10227 help_echo_pos = -1; 10228 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP); 10229 if (NILP (help_echo_string)) 10230 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION); 10231} 10232 10233#endif /* HAVE_WINDOW_SYSTEM */ 10234 10235 10236 10237/************************************************************************ 10238 Horizontal scrolling 10239 ************************************************************************/ 10240 10241static int hscroll_window_tree P_ ((Lisp_Object)); 10242static int hscroll_windows P_ ((Lisp_Object)); 10243 10244/* For all leaf windows in the window tree rooted at WINDOW, set their 10245 hscroll value so that PT is (i) visible in the window, and (ii) so 10246 that it is not within a certain margin at the window's left and 10247 right border. Value is non-zero if any window's hscroll has been 10248 changed. */ 10249 10250static int 10251hscroll_window_tree (window) 10252 Lisp_Object window; 10253{ 10254 int hscrolled_p = 0; 10255 int hscroll_relative_p = FLOATP (Vhscroll_step); 10256 int hscroll_step_abs = 0; 10257 double hscroll_step_rel = 0; 10258 10259 if (hscroll_relative_p) 10260 { 10261 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step); 10262 if (hscroll_step_rel < 0) 10263 { 10264 hscroll_relative_p = 0; 10265 hscroll_step_abs = 0; 10266 } 10267 } 10268 else if (INTEGERP (Vhscroll_step)) 10269 { 10270 hscroll_step_abs = XINT (Vhscroll_step); 10271 if (hscroll_step_abs < 0) 10272 hscroll_step_abs = 0; 10273 } 10274 else 10275 hscroll_step_abs = 0; 10276 10277 while (WINDOWP (window)) 10278 { 10279 struct window *w = XWINDOW (window); 10280 10281 if (WINDOWP (w->hchild)) 10282 hscrolled_p |= hscroll_window_tree (w->hchild); 10283 else if (WINDOWP (w->vchild)) 10284 hscrolled_p |= hscroll_window_tree (w->vchild); 10285 else if (w->cursor.vpos >= 0) 10286 { 10287 int h_margin; 10288 int text_area_width; 10289 struct glyph_row *current_cursor_row 10290 = MATRIX_ROW (w->current_matrix, w->cursor.vpos); 10291 struct glyph_row *desired_cursor_row 10292 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos); 10293 struct glyph_row *cursor_row 10294 = (desired_cursor_row->enabled_p 10295 ? desired_cursor_row 10296 : current_cursor_row); 10297 10298 text_area_width = window_box_width (w, TEXT_AREA); 10299 10300 /* Scroll when cursor is inside this scroll margin. */ 10301 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w); 10302 10303 if ((XFASTINT (w->hscroll) 10304 && w->cursor.x <= h_margin) 10305 || (cursor_row->enabled_p 10306 && cursor_row->truncated_on_right_p 10307 && (w->cursor.x >= text_area_width - h_margin))) 10308 { 10309 struct it it; 10310 int hscroll; 10311 struct buffer *saved_current_buffer; 10312 int pt; 10313 int wanted_x; 10314 10315 /* Find point in a display of infinite width. */ 10316 saved_current_buffer = current_buffer; 10317 current_buffer = XBUFFER (w->buffer); 10318 10319 if (w == XWINDOW (selected_window)) 10320 pt = BUF_PT (current_buffer); 10321 else 10322 { 10323 pt = marker_position (w->pointm); 10324 pt = max (BEGV, pt); 10325 pt = min (ZV, pt); 10326 } 10327 10328 /* Move iterator to pt starting at cursor_row->start in 10329 a line with infinite width. */ 10330 init_to_row_start (&it, w, cursor_row); 10331 it.last_visible_x = INFINITY; 10332 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS); 10333 current_buffer = saved_current_buffer; 10334 10335 /* Position cursor in window. */ 10336 if (!hscroll_relative_p && hscroll_step_abs == 0) 10337 hscroll = max (0, (it.current_x 10338 - (ITERATOR_AT_END_OF_LINE_P (&it) 10339 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f)) 10340 : (text_area_width / 2)))) 10341 / FRAME_COLUMN_WIDTH (it.f); 10342 else if (w->cursor.x >= text_area_width - h_margin) 10343 { 10344 if (hscroll_relative_p) 10345 wanted_x = text_area_width * (1 - hscroll_step_rel) 10346 - h_margin; 10347 else 10348 wanted_x = text_area_width 10349 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f) 10350 - h_margin; 10351 hscroll 10352 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f); 10353 } 10354 else 10355 { 10356 if (hscroll_relative_p) 10357 wanted_x = text_area_width * hscroll_step_rel 10358 + h_margin; 10359 else 10360 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f) 10361 + h_margin; 10362 hscroll 10363 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f); 10364 } 10365 hscroll = max (hscroll, XFASTINT (w->min_hscroll)); 10366 10367 /* Don't call Fset_window_hscroll if value hasn't 10368 changed because it will prevent redisplay 10369 optimizations. */ 10370 if (XFASTINT (w->hscroll) != hscroll) 10371 { 10372 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 10373 w->hscroll = make_number (hscroll); 10374 hscrolled_p = 1; 10375 } 10376 } 10377 } 10378 10379 window = w->next; 10380 } 10381 10382 /* Value is non-zero if hscroll of any leaf window has been changed. */ 10383 return hscrolled_p; 10384} 10385 10386 10387/* Set hscroll so that cursor is visible and not inside horizontal 10388 scroll margins for all windows in the tree rooted at WINDOW. See 10389 also hscroll_window_tree above. Value is non-zero if any window's 10390 hscroll has been changed. If it has, desired matrices on the frame 10391 of WINDOW are cleared. */ 10392 10393static int 10394hscroll_windows (window) 10395 Lisp_Object window; 10396{ 10397 int hscrolled_p; 10398 10399 if (automatic_hscrolling_p) 10400 { 10401 hscrolled_p = hscroll_window_tree (window); 10402 if (hscrolled_p) 10403 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 10404 } 10405 else 10406 hscrolled_p = 0; 10407 return hscrolled_p; 10408} 10409 10410 10411 10412/************************************************************************ 10413 Redisplay 10414 ************************************************************************/ 10415 10416/* Variables holding some state of redisplay if GLYPH_DEBUG is defined 10417 to a non-zero value. This is sometimes handy to have in a debugger 10418 session. */ 10419 10420#if GLYPH_DEBUG 10421 10422/* First and last unchanged row for try_window_id. */ 10423 10424int debug_first_unchanged_at_end_vpos; 10425int debug_last_unchanged_at_beg_vpos; 10426 10427/* Delta vpos and y. */ 10428 10429int debug_dvpos, debug_dy; 10430 10431/* Delta in characters and bytes for try_window_id. */ 10432 10433int debug_delta, debug_delta_bytes; 10434 10435/* Values of window_end_pos and window_end_vpos at the end of 10436 try_window_id. */ 10437 10438EMACS_INT debug_end_pos, debug_end_vpos; 10439 10440/* Append a string to W->desired_matrix->method. FMT is a printf 10441 format string. A1...A9 are a supplement for a variable-length 10442 argument list. If trace_redisplay_p is non-zero also printf the 10443 resulting string to stderr. */ 10444 10445static void 10446debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) 10447 struct window *w; 10448 char *fmt; 10449 int a1, a2, a3, a4, a5, a6, a7, a8, a9; 10450{ 10451 char buffer[512]; 10452 char *method = w->desired_matrix->method; 10453 int len = strlen (method); 10454 int size = sizeof w->desired_matrix->method; 10455 int remaining = size - len - 1; 10456 10457 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); 10458 if (len && remaining) 10459 { 10460 method[len] = '|'; 10461 --remaining, ++len; 10462 } 10463 10464 strncpy (method + len, buffer, remaining); 10465 10466 if (trace_redisplay_p) 10467 fprintf (stderr, "%p (%s): %s\n", 10468 w, 10469 ((BUFFERP (w->buffer) 10470 && STRINGP (XBUFFER (w->buffer)->name)) 10471 ? (char *) SDATA (XBUFFER (w->buffer)->name) 10472 : "no buffer"), 10473 buffer); 10474} 10475 10476#endif /* GLYPH_DEBUG */ 10477 10478 10479/* Value is non-zero if all changes in window W, which displays 10480 current_buffer, are in the text between START and END. START is a 10481 buffer position, END is given as a distance from Z. Used in 10482 redisplay_internal for display optimization. */ 10483 10484static INLINE int 10485text_outside_line_unchanged_p (w, start, end) 10486 struct window *w; 10487 int start, end; 10488{ 10489 int unchanged_p = 1; 10490 10491 /* If text or overlays have changed, see where. */ 10492 if (XFASTINT (w->last_modified) < MODIFF 10493 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF) 10494 { 10495 /* Gap in the line? */ 10496 if (GPT < start || Z - GPT < end) 10497 unchanged_p = 0; 10498 10499 /* Changes start in front of the line, or end after it? */ 10500 if (unchanged_p 10501 && (BEG_UNCHANGED < start - 1 10502 || END_UNCHANGED < end)) 10503 unchanged_p = 0; 10504 10505 /* If selective display, can't optimize if changes start at the 10506 beginning of the line. */ 10507 if (unchanged_p 10508 && INTEGERP (current_buffer->selective_display) 10509 && XINT (current_buffer->selective_display) > 0 10510 && (BEG_UNCHANGED < start || GPT <= start)) 10511 unchanged_p = 0; 10512 10513 /* If there are overlays at the start or end of the line, these 10514 may have overlay strings with newlines in them. A change at 10515 START, for instance, may actually concern the display of such 10516 overlay strings as well, and they are displayed on different 10517 lines. So, quickly rule out this case. (For the future, it 10518 might be desirable to implement something more telling than 10519 just BEG/END_UNCHANGED.) */ 10520 if (unchanged_p) 10521 { 10522 if (BEG + BEG_UNCHANGED == start 10523 && overlay_touches_p (start)) 10524 unchanged_p = 0; 10525 if (END_UNCHANGED == end 10526 && overlay_touches_p (Z - end)) 10527 unchanged_p = 0; 10528 } 10529 } 10530 10531 return unchanged_p; 10532} 10533 10534 10535/* Do a frame update, taking possible shortcuts into account. This is 10536 the main external entry point for redisplay. 10537 10538 If the last redisplay displayed an echo area message and that message 10539 is no longer requested, we clear the echo area or bring back the 10540 mini-buffer if that is in use. */ 10541 10542void 10543redisplay () 10544{ 10545 redisplay_internal (0); 10546} 10547 10548 10549static Lisp_Object 10550overlay_arrow_string_or_property (var) 10551 Lisp_Object var; 10552{ 10553 Lisp_Object val; 10554 10555 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val)) 10556 return val; 10557 10558 return Voverlay_arrow_string; 10559} 10560 10561/* Return 1 if there are any overlay-arrows in current_buffer. */ 10562static int 10563overlay_arrow_in_current_buffer_p () 10564{ 10565 Lisp_Object vlist; 10566 10567 for (vlist = Voverlay_arrow_variable_list; 10568 CONSP (vlist); 10569 vlist = XCDR (vlist)) 10570 { 10571 Lisp_Object var = XCAR (vlist); 10572 Lisp_Object val; 10573 10574 if (!SYMBOLP (var)) 10575 continue; 10576 val = find_symbol_value (var); 10577 if (MARKERP (val) 10578 && current_buffer == XMARKER (val)->buffer) 10579 return 1; 10580 } 10581 return 0; 10582} 10583 10584 10585/* Return 1 if any overlay_arrows have moved or overlay-arrow-string 10586 has changed. */ 10587 10588static int 10589overlay_arrows_changed_p () 10590{ 10591 Lisp_Object vlist; 10592 10593 for (vlist = Voverlay_arrow_variable_list; 10594 CONSP (vlist); 10595 vlist = XCDR (vlist)) 10596 { 10597 Lisp_Object var = XCAR (vlist); 10598 Lisp_Object val, pstr; 10599 10600 if (!SYMBOLP (var)) 10601 continue; 10602 val = find_symbol_value (var); 10603 if (!MARKERP (val)) 10604 continue; 10605 if (! EQ (COERCE_MARKER (val), 10606 Fget (var, Qlast_arrow_position)) 10607 || ! (pstr = overlay_arrow_string_or_property (var), 10608 EQ (pstr, Fget (var, Qlast_arrow_string)))) 10609 return 1; 10610 } 10611 return 0; 10612} 10613 10614/* Mark overlay arrows to be updated on next redisplay. */ 10615 10616static void 10617update_overlay_arrows (up_to_date) 10618 int up_to_date; 10619{ 10620 Lisp_Object vlist; 10621 10622 for (vlist = Voverlay_arrow_variable_list; 10623 CONSP (vlist); 10624 vlist = XCDR (vlist)) 10625 { 10626 Lisp_Object var = XCAR (vlist); 10627 10628 if (!SYMBOLP (var)) 10629 continue; 10630 10631 if (up_to_date > 0) 10632 { 10633 Lisp_Object val = find_symbol_value (var); 10634 Fput (var, Qlast_arrow_position, 10635 COERCE_MARKER (val)); 10636 Fput (var, Qlast_arrow_string, 10637 overlay_arrow_string_or_property (var)); 10638 } 10639 else if (up_to_date < 0 10640 || !NILP (Fget (var, Qlast_arrow_position))) 10641 { 10642 Fput (var, Qlast_arrow_position, Qt); 10643 Fput (var, Qlast_arrow_string, Qt); 10644 } 10645 } 10646} 10647 10648 10649/* Return overlay arrow string to display at row. 10650 Return integer (bitmap number) for arrow bitmap in left fringe. 10651 Return nil if no overlay arrow. */ 10652 10653static Lisp_Object 10654overlay_arrow_at_row (it, row) 10655 struct it *it; 10656 struct glyph_row *row; 10657{ 10658 Lisp_Object vlist; 10659 10660 for (vlist = Voverlay_arrow_variable_list; 10661 CONSP (vlist); 10662 vlist = XCDR (vlist)) 10663 { 10664 Lisp_Object var = XCAR (vlist); 10665 Lisp_Object val; 10666 10667 if (!SYMBOLP (var)) 10668 continue; 10669 10670 val = find_symbol_value (var); 10671 10672 if (MARKERP (val) 10673 && current_buffer == XMARKER (val)->buffer 10674 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val))) 10675 { 10676 if (FRAME_WINDOW_P (it->f) 10677 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0) 10678 { 10679#ifdef HAVE_WINDOW_SYSTEM 10680 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val)) 10681 { 10682 int fringe_bitmap; 10683 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0) 10684 return make_number (fringe_bitmap); 10685 } 10686#endif 10687 return make_number (-1); /* Use default arrow bitmap */ 10688 } 10689 return overlay_arrow_string_or_property (var); 10690 } 10691 } 10692 10693 return Qnil; 10694} 10695 10696/* Return 1 if point moved out of or into a composition. Otherwise 10697 return 0. PREV_BUF and PREV_PT are the last point buffer and 10698 position. BUF and PT are the current point buffer and position. */ 10699 10700int 10701check_point_in_composition (prev_buf, prev_pt, buf, pt) 10702 struct buffer *prev_buf, *buf; 10703 int prev_pt, pt; 10704{ 10705 int start, end; 10706 Lisp_Object prop; 10707 Lisp_Object buffer; 10708 10709 XSETBUFFER (buffer, buf); 10710 /* Check a composition at the last point if point moved within the 10711 same buffer. */ 10712 if (prev_buf == buf) 10713 { 10714 if (prev_pt == pt) 10715 /* Point didn't move. */ 10716 return 0; 10717 10718 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf) 10719 && find_composition (prev_pt, -1, &start, &end, &prop, buffer) 10720 && COMPOSITION_VALID_P (start, end, prop) 10721 && start < prev_pt && end > prev_pt) 10722 /* The last point was within the composition. Return 1 iff 10723 point moved out of the composition. */ 10724 return (pt <= start || pt >= end); 10725 } 10726 10727 /* Check a composition at the current point. */ 10728 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf) 10729 && find_composition (pt, -1, &start, &end, &prop, buffer) 10730 && COMPOSITION_VALID_P (start, end, prop) 10731 && start < pt && end > pt); 10732} 10733 10734 10735/* Reconsider the setting of B->clip_changed which is displayed 10736 in window W. */ 10737 10738static INLINE void 10739reconsider_clip_changes (w, b) 10740 struct window *w; 10741 struct buffer *b; 10742{ 10743 if (b->clip_changed 10744 && !NILP (w->window_end_valid) 10745 && w->current_matrix->buffer == b 10746 && w->current_matrix->zv == BUF_ZV (b) 10747 && w->current_matrix->begv == BUF_BEGV (b)) 10748 b->clip_changed = 0; 10749 10750 /* If display wasn't paused, and W is not a tool bar window, see if 10751 point has been moved into or out of a composition. In that case, 10752 we set b->clip_changed to 1 to force updating the screen. If 10753 b->clip_changed has already been set to 1, we can skip this 10754 check. */ 10755 if (!b->clip_changed 10756 && BUFFERP (w->buffer) && !NILP (w->window_end_valid)) 10757 { 10758 int pt; 10759 10760 if (w == XWINDOW (selected_window)) 10761 pt = BUF_PT (current_buffer); 10762 else 10763 pt = marker_position (w->pointm); 10764 10765 if ((w->current_matrix->buffer != XBUFFER (w->buffer) 10766 || pt != XINT (w->last_point)) 10767 && check_point_in_composition (w->current_matrix->buffer, 10768 XINT (w->last_point), 10769 XBUFFER (w->buffer), pt)) 10770 b->clip_changed = 1; 10771 } 10772} 10773 10774 10775/* Select FRAME to forward the values of frame-local variables into C 10776 variables so that the redisplay routines can access those values 10777 directly. */ 10778 10779static void 10780select_frame_for_redisplay (frame) 10781 Lisp_Object frame; 10782{ 10783 Lisp_Object tail, sym, val; 10784 Lisp_Object old = selected_frame; 10785 10786 selected_frame = frame; 10787 10788 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) 10789 if (CONSP (XCAR (tail)) 10790 && (sym = XCAR (XCAR (tail)), 10791 SYMBOLP (sym)) 10792 && (sym = indirect_variable (sym), 10793 val = SYMBOL_VALUE (sym), 10794 (BUFFER_LOCAL_VALUEP (val) 10795 || SOME_BUFFER_LOCAL_VALUEP (val))) 10796 && XBUFFER_LOCAL_VALUE (val)->check_frame) 10797 /* Use find_symbol_value rather than Fsymbol_value 10798 to avoid an error if it is void. */ 10799 find_symbol_value (sym); 10800 10801 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail)) 10802 if (CONSP (XCAR (tail)) 10803 && (sym = XCAR (XCAR (tail)), 10804 SYMBOLP (sym)) 10805 && (sym = indirect_variable (sym), 10806 val = SYMBOL_VALUE (sym), 10807 (BUFFER_LOCAL_VALUEP (val) 10808 || SOME_BUFFER_LOCAL_VALUEP (val))) 10809 && XBUFFER_LOCAL_VALUE (val)->check_frame) 10810 find_symbol_value (sym); 10811} 10812 10813 10814#define STOP_POLLING \ 10815do { if (! polling_stopped_here) stop_polling (); \ 10816 polling_stopped_here = 1; } while (0) 10817 10818#define RESUME_POLLING \ 10819do { if (polling_stopped_here) start_polling (); \ 10820 polling_stopped_here = 0; } while (0) 10821 10822 10823/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in 10824 response to any user action; therefore, we should preserve the echo 10825 area. (Actually, our caller does that job.) Perhaps in the future 10826 avoid recentering windows if it is not necessary; currently that 10827 causes some problems. */ 10828 10829static void 10830redisplay_internal (preserve_echo_area) 10831 int preserve_echo_area; 10832{ 10833 struct window *w = XWINDOW (selected_window); 10834 struct frame *f; 10835 int pause; 10836 int must_finish = 0; 10837 struct text_pos tlbufpos, tlendpos; 10838 int number_of_visible_frames; 10839 int count, count1; 10840 struct frame *sf; 10841 int polling_stopped_here = 0; 10842 10843 /* Non-zero means redisplay has to consider all windows on all 10844 frames. Zero means, only selected_window is considered. */ 10845 int consider_all_windows_p; 10846 10847 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); 10848 10849 /* No redisplay if running in batch mode or frame is not yet fully 10850 initialized, or redisplay is explicitly turned off by setting 10851 Vinhibit_redisplay. */ 10852 if (noninteractive 10853 || !NILP (Vinhibit_redisplay)) 10854 return; 10855 10856 /* Don't examine these until after testing Vinhibit_redisplay. 10857 When Emacs is shutting down, perhaps because its connection to 10858 X has dropped, we should not look at them at all. */ 10859 f = XFRAME (w->frame); 10860 sf = SELECTED_FRAME (); 10861 10862 if (!f->glyphs_initialized_p) 10863 return; 10864 10865 /* The flag redisplay_performed_directly_p is set by 10866 direct_output_for_insert when it already did the whole screen 10867 update necessary. */ 10868 if (redisplay_performed_directly_p) 10869 { 10870 redisplay_performed_directly_p = 0; 10871 if (!hscroll_windows (selected_window)) 10872 return; 10873 } 10874 10875#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS) 10876 if (popup_activated ()) 10877 return; 10878#endif 10879 10880 /* I don't think this happens but let's be paranoid. */ 10881 if (redisplaying_p) 10882 return; 10883 10884 /* Record a function that resets redisplaying_p to its old value 10885 when we leave this function. */ 10886 count = SPECPDL_INDEX (); 10887 record_unwind_protect (unwind_redisplay, 10888 Fcons (make_number (redisplaying_p), selected_frame)); 10889 ++redisplaying_p; 10890 specbind (Qinhibit_free_realized_faces, Qnil); 10891 10892 { 10893 Lisp_Object tail, frame; 10894 10895 FOR_EACH_FRAME (tail, frame) 10896 { 10897 struct frame *f = XFRAME (frame); 10898 f->already_hscrolled_p = 0; 10899 } 10900 } 10901 10902 retry: 10903 pause = 0; 10904 reconsider_clip_changes (w, current_buffer); 10905 last_escape_glyph_frame = NULL; 10906 last_escape_glyph_face_id = (1 << FACE_ID_BITS); 10907 10908 /* If new fonts have been loaded that make a glyph matrix adjustment 10909 necessary, do it. */ 10910 if (fonts_changed_p) 10911 { 10912 adjust_glyphs (NULL); 10913 ++windows_or_buffers_changed; 10914 fonts_changed_p = 0; 10915 } 10916 10917 /* If face_change_count is non-zero, init_iterator will free all 10918 realized faces, which includes the faces referenced from current 10919 matrices. So, we can't reuse current matrices in this case. */ 10920 if (face_change_count) 10921 ++windows_or_buffers_changed; 10922 10923 if (! FRAME_WINDOW_P (sf) 10924 && previous_terminal_frame != sf) 10925 { 10926 /* Since frames on an ASCII terminal share the same display 10927 area, displaying a different frame means redisplay the whole 10928 thing. */ 10929 windows_or_buffers_changed++; 10930 SET_FRAME_GARBAGED (sf); 10931 XSETFRAME (Vterminal_frame, sf); 10932 } 10933 previous_terminal_frame = sf; 10934 10935 /* Set the visible flags for all frames. Do this before checking 10936 for resized or garbaged frames; they want to know if their frames 10937 are visible. See the comment in frame.h for 10938 FRAME_SAMPLE_VISIBILITY. */ 10939 { 10940 Lisp_Object tail, frame; 10941 10942 number_of_visible_frames = 0; 10943 10944 FOR_EACH_FRAME (tail, frame) 10945 { 10946 struct frame *f = XFRAME (frame); 10947 10948 FRAME_SAMPLE_VISIBILITY (f); 10949 if (FRAME_VISIBLE_P (f)) 10950 ++number_of_visible_frames; 10951 clear_desired_matrices (f); 10952 } 10953 } 10954 10955 /* Notice any pending interrupt request to change frame size. */ 10956 do_pending_window_change (1); 10957 10958 /* Clear frames marked as garbaged. */ 10959 if (frame_garbaged) 10960 clear_garbaged_frames (); 10961 10962 /* Build menubar and tool-bar items. */ 10963 if (NILP (Vmemory_full)) 10964 prepare_menu_bars (); 10965 10966 if (windows_or_buffers_changed) 10967 update_mode_lines++; 10968 10969 /* Detect case that we need to write or remove a star in the mode line. */ 10970 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star)) 10971 { 10972 w->update_mode_line = Qt; 10973 if (buffer_shared > 1) 10974 update_mode_lines++; 10975 } 10976 10977 /* Avoid invocation of point motion hooks by `current_column' below. */ 10978 count1 = SPECPDL_INDEX (); 10979 specbind (Qinhibit_point_motion_hooks, Qt); 10980 10981 /* If %c is in the mode line, update it if needed. */ 10982 if (!NILP (w->column_number_displayed) 10983 /* This alternative quickly identifies a common case 10984 where no change is needed. */ 10985 && !(PT == XFASTINT (w->last_point) 10986 && XFASTINT (w->last_modified) >= MODIFF 10987 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF) 10988 && (XFASTINT (w->column_number_displayed) 10989 != (int) current_column ())) /* iftc */ 10990 w->update_mode_line = Qt; 10991 10992 unbind_to (count1, Qnil); 10993 10994 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1; 10995 10996 /* The variable buffer_shared is set in redisplay_window and 10997 indicates that we redisplay a buffer in different windows. See 10998 there. */ 10999 consider_all_windows_p = (update_mode_lines || buffer_shared > 1 11000 || cursor_type_changed); 11001 11002 /* If specs for an arrow have changed, do thorough redisplay 11003 to ensure we remove any arrow that should no longer exist. */ 11004 if (overlay_arrows_changed_p ()) 11005 consider_all_windows_p = windows_or_buffers_changed = 1; 11006 11007 /* Normally the message* functions will have already displayed and 11008 updated the echo area, but the frame may have been trashed, or 11009 the update may have been preempted, so display the echo area 11010 again here. Checking message_cleared_p captures the case that 11011 the echo area should be cleared. */ 11012 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p) 11013 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p) 11014 || (message_cleared_p 11015 && minibuf_level == 0 11016 /* If the mini-window is currently selected, this means the 11017 echo-area doesn't show through. */ 11018 && !MINI_WINDOW_P (XWINDOW (selected_window)))) 11019 { 11020 int window_height_changed_p = echo_area_display (0); 11021 must_finish = 1; 11022 11023 /* If we don't display the current message, don't clear the 11024 message_cleared_p flag, because, if we did, we wouldn't clear 11025 the echo area in the next redisplay which doesn't preserve 11026 the echo area. */ 11027 if (!display_last_displayed_message_p) 11028 message_cleared_p = 0; 11029 11030 if (fonts_changed_p) 11031 goto retry; 11032 else if (window_height_changed_p) 11033 { 11034 consider_all_windows_p = 1; 11035 ++update_mode_lines; 11036 ++windows_or_buffers_changed; 11037 11038 /* If window configuration was changed, frames may have been 11039 marked garbaged. Clear them or we will experience 11040 surprises wrt scrolling. */ 11041 if (frame_garbaged) 11042 clear_garbaged_frames (); 11043 } 11044 } 11045 else if (EQ (selected_window, minibuf_window) 11046 && (current_buffer->clip_changed 11047 || XFASTINT (w->last_modified) < MODIFF 11048 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF) 11049 && resize_mini_window (w, 0)) 11050 { 11051 /* Resized active mini-window to fit the size of what it is 11052 showing if its contents might have changed. */ 11053 must_finish = 1; 11054 consider_all_windows_p = 1; 11055 ++windows_or_buffers_changed; 11056 ++update_mode_lines; 11057 11058 /* If window configuration was changed, frames may have been 11059 marked garbaged. Clear them or we will experience 11060 surprises wrt scrolling. */ 11061 if (frame_garbaged) 11062 clear_garbaged_frames (); 11063 } 11064 11065 11066 /* If showing the region, and mark has changed, we must redisplay 11067 the whole window. The assignment to this_line_start_pos prevents 11068 the optimization directly below this if-statement. */ 11069 if (((!NILP (Vtransient_mark_mode) 11070 && !NILP (XBUFFER (w->buffer)->mark_active)) 11071 != !NILP (w->region_showing)) 11072 || (!NILP (w->region_showing) 11073 && !EQ (w->region_showing, 11074 Fmarker_position (XBUFFER (w->buffer)->mark)))) 11075 CHARPOS (this_line_start_pos) = 0; 11076 11077 /* Optimize the case that only the line containing the cursor in the 11078 selected window has changed. Variables starting with this_ are 11079 set in display_line and record information about the line 11080 containing the cursor. */ 11081 tlbufpos = this_line_start_pos; 11082 tlendpos = this_line_end_pos; 11083 if (!consider_all_windows_p 11084 && CHARPOS (tlbufpos) > 0 11085 && NILP (w->update_mode_line) 11086 && !current_buffer->clip_changed 11087 && !current_buffer->prevent_redisplay_optimizations_p 11088 && FRAME_VISIBLE_P (XFRAME (w->frame)) 11089 && !FRAME_OBSCURED_P (XFRAME (w->frame)) 11090 /* Make sure recorded data applies to current buffer, etc. */ 11091 && this_line_buffer == current_buffer 11092 && current_buffer == XBUFFER (w->buffer) 11093 && NILP (w->force_start) 11094 && NILP (w->optional_new_start) 11095 /* Point must be on the line that we have info recorded about. */ 11096 && PT >= CHARPOS (tlbufpos) 11097 && PT <= Z - CHARPOS (tlendpos) 11098 /* All text outside that line, including its final newline, 11099 must be unchanged */ 11100 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos), 11101 CHARPOS (tlendpos))) 11102 { 11103 if (CHARPOS (tlbufpos) > BEGV 11104 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n' 11105 && (CHARPOS (tlbufpos) == ZV 11106 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n')) 11107 /* Former continuation line has disappeared by becoming empty */ 11108 goto cancel; 11109 else if (XFASTINT (w->last_modified) < MODIFF 11110 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF 11111 || MINI_WINDOW_P (w)) 11112 { 11113 /* We have to handle the case of continuation around a 11114 wide-column character (See the comment in indent.c around 11115 line 885). 11116 11117 For instance, in the following case: 11118 11119 -------- Insert -------- 11120 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars. 11121 J_I_ ==> J_I_ `^^' are cursors. 11122 ^^ ^^ 11123 -------- -------- 11124 11125 As we have to redraw the line above, we should goto cancel. */ 11126 11127 struct it it; 11128 int line_height_before = this_line_pixel_height; 11129 11130 /* Note that start_display will handle the case that the 11131 line starting at tlbufpos is a continuation lines. */ 11132 start_display (&it, w, tlbufpos); 11133 11134 /* Implementation note: It this still necessary? */ 11135 if (it.current_x != this_line_start_x) 11136 goto cancel; 11137 11138 TRACE ((stderr, "trying display optimization 1\n")); 11139 w->cursor.vpos = -1; 11140 overlay_arrow_seen = 0; 11141 it.vpos = this_line_vpos; 11142 it.current_y = this_line_y; 11143 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos); 11144 display_line (&it); 11145 11146 /* If line contains point, is not continued, 11147 and ends at same distance from eob as before, we win */ 11148 if (w->cursor.vpos >= 0 11149 /* Line is not continued, otherwise this_line_start_pos 11150 would have been set to 0 in display_line. */ 11151 && CHARPOS (this_line_start_pos) 11152 /* Line ends as before. */ 11153 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos) 11154 /* Line has same height as before. Otherwise other lines 11155 would have to be shifted up or down. */ 11156 && this_line_pixel_height == line_height_before) 11157 { 11158 /* If this is not the window's last line, we must adjust 11159 the charstarts of the lines below. */ 11160 if (it.current_y < it.last_visible_y) 11161 { 11162 struct glyph_row *row 11163 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1); 11164 int delta, delta_bytes; 11165 11166 if (Z - CHARPOS (tlendpos) == ZV) 11167 { 11168 /* This line ends at end of (accessible part of) 11169 buffer. There is no newline to count. */ 11170 delta = (Z 11171 - CHARPOS (tlendpos) 11172 - MATRIX_ROW_START_CHARPOS (row)); 11173 delta_bytes = (Z_BYTE 11174 - BYTEPOS (tlendpos) 11175 - MATRIX_ROW_START_BYTEPOS (row)); 11176 } 11177 else 11178 { 11179 /* This line ends in a newline. Must take 11180 account of the newline and the rest of the 11181 text that follows. */ 11182 delta = (Z 11183 - CHARPOS (tlendpos) 11184 - MATRIX_ROW_START_CHARPOS (row)); 11185 delta_bytes = (Z_BYTE 11186 - BYTEPOS (tlendpos) 11187 - MATRIX_ROW_START_BYTEPOS (row)); 11188 } 11189 11190 increment_matrix_positions (w->current_matrix, 11191 this_line_vpos + 1, 11192 w->current_matrix->nrows, 11193 delta, delta_bytes); 11194 } 11195 11196 /* If this row displays text now but previously didn't, 11197 or vice versa, w->window_end_vpos may have to be 11198 adjusted. */ 11199 if ((it.glyph_row - 1)->displays_text_p) 11200 { 11201 if (XFASTINT (w->window_end_vpos) < this_line_vpos) 11202 XSETINT (w->window_end_vpos, this_line_vpos); 11203 } 11204 else if (XFASTINT (w->window_end_vpos) == this_line_vpos 11205 && this_line_vpos > 0) 11206 XSETINT (w->window_end_vpos, this_line_vpos - 1); 11207 w->window_end_valid = Qnil; 11208 11209 /* Update hint: No need to try to scroll in update_window. */ 11210 w->desired_matrix->no_scrolling_p = 1; 11211 11212#if GLYPH_DEBUG 11213 *w->desired_matrix->method = 0; 11214 debug_method_add (w, "optimization 1"); 11215#endif 11216#ifdef HAVE_WINDOW_SYSTEM 11217 update_window_fringes (w, 0); 11218#endif 11219 goto update; 11220 } 11221 else 11222 goto cancel; 11223 } 11224 else if (/* Cursor position hasn't changed. */ 11225 PT == XFASTINT (w->last_point) 11226 /* Make sure the cursor was last displayed 11227 in this window. Otherwise we have to reposition it. */ 11228 && 0 <= w->cursor.vpos 11229 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos) 11230 { 11231 if (!must_finish) 11232 { 11233 do_pending_window_change (1); 11234 11235 /* We used to always goto end_of_redisplay here, but this 11236 isn't enough if we have a blinking cursor. */ 11237 if (w->cursor_off_p == w->last_cursor_off_p) 11238 goto end_of_redisplay; 11239 } 11240 goto update; 11241 } 11242 /* If highlighting the region, or if the cursor is in the echo area, 11243 then we can't just move the cursor. */ 11244 else if (! (!NILP (Vtransient_mark_mode) 11245 && !NILP (current_buffer->mark_active)) 11246 && (EQ (selected_window, current_buffer->last_selected_window) 11247 || highlight_nonselected_windows) 11248 && NILP (w->region_showing) 11249 && NILP (Vshow_trailing_whitespace) 11250 && !cursor_in_echo_area) 11251 { 11252 struct it it; 11253 struct glyph_row *row; 11254 11255 /* Skip from tlbufpos to PT and see where it is. Note that 11256 PT may be in invisible text. If so, we will end at the 11257 next visible position. */ 11258 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos), 11259 NULL, DEFAULT_FACE_ID); 11260 it.current_x = this_line_start_x; 11261 it.current_y = this_line_y; 11262 it.vpos = this_line_vpos; 11263 11264 /* The call to move_it_to stops in front of PT, but 11265 moves over before-strings. */ 11266 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 11267 11268 if (it.vpos == this_line_vpos 11269 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos), 11270 row->enabled_p)) 11271 { 11272 xassert (this_line_vpos == it.vpos); 11273 xassert (this_line_y == it.current_y); 11274 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 11275#if GLYPH_DEBUG 11276 *w->desired_matrix->method = 0; 11277 debug_method_add (w, "optimization 3"); 11278#endif 11279 goto update; 11280 } 11281 else 11282 goto cancel; 11283 } 11284 11285 cancel: 11286 /* Text changed drastically or point moved off of line. */ 11287 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0); 11288 } 11289 11290 CHARPOS (this_line_start_pos) = 0; 11291 consider_all_windows_p |= buffer_shared > 1; 11292 ++clear_face_cache_count; 11293#ifdef HAVE_WINDOW_SYSTEM 11294 ++clear_image_cache_count; 11295#endif 11296 11297 /* Build desired matrices, and update the display. If 11298 consider_all_windows_p is non-zero, do it for all windows on all 11299 frames. Otherwise do it for selected_window, only. */ 11300 11301 if (consider_all_windows_p) 11302 { 11303 Lisp_Object tail, frame; 11304 11305 FOR_EACH_FRAME (tail, frame) 11306 XFRAME (frame)->updated_p = 0; 11307 11308 /* Recompute # windows showing selected buffer. This will be 11309 incremented each time such a window is displayed. */ 11310 buffer_shared = 0; 11311 11312 FOR_EACH_FRAME (tail, frame) 11313 { 11314 struct frame *f = XFRAME (frame); 11315 11316 if (FRAME_WINDOW_P (f) || f == sf) 11317 { 11318 if (! EQ (frame, selected_frame)) 11319 /* Select the frame, for the sake of frame-local 11320 variables. */ 11321 select_frame_for_redisplay (frame); 11322 11323 /* Mark all the scroll bars to be removed; we'll redeem 11324 the ones we want when we redisplay their windows. */ 11325 if (condemn_scroll_bars_hook) 11326 condemn_scroll_bars_hook (f); 11327 11328 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) 11329 redisplay_windows (FRAME_ROOT_WINDOW (f)); 11330 11331 /* Any scroll bars which redisplay_windows should have 11332 nuked should now go away. */ 11333 if (judge_scroll_bars_hook) 11334 judge_scroll_bars_hook (f); 11335 11336 /* If fonts changed, display again. */ 11337 /* ??? rms: I suspect it is a mistake to jump all the way 11338 back to retry here. It should just retry this frame. */ 11339 if (fonts_changed_p) 11340 goto retry; 11341 11342 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) 11343 { 11344 /* See if we have to hscroll. */ 11345 if (!f->already_hscrolled_p) 11346 { 11347 f->already_hscrolled_p = 1; 11348 if (hscroll_windows (f->root_window)) 11349 goto retry; 11350 } 11351 11352 /* Prevent various kinds of signals during display 11353 update. stdio is not robust about handling 11354 signals, which can cause an apparent I/O 11355 error. */ 11356 if (interrupt_input) 11357 unrequest_sigio (); 11358 STOP_POLLING; 11359 11360 /* Update the display. */ 11361 set_window_update_flags (XWINDOW (f->root_window), 1); 11362 pause |= update_frame (f, 0, 0); 11363#if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */ 11364 if (pause) 11365 break; 11366#endif 11367 11368 f->updated_p = 1; 11369 } 11370 } 11371 } 11372 11373 if (!pause) 11374 { 11375 /* Do the mark_window_display_accurate after all windows have 11376 been redisplayed because this call resets flags in buffers 11377 which are needed for proper redisplay. */ 11378 FOR_EACH_FRAME (tail, frame) 11379 { 11380 struct frame *f = XFRAME (frame); 11381 if (f->updated_p) 11382 { 11383 mark_window_display_accurate (f->root_window, 1); 11384 if (frame_up_to_date_hook) 11385 frame_up_to_date_hook (f); 11386 } 11387 } 11388 } 11389 } 11390 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) 11391 { 11392 Lisp_Object mini_window; 11393 struct frame *mini_frame; 11394 11395 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer); 11396 /* Use list_of_error, not Qerror, so that 11397 we catch only errors and don't run the debugger. */ 11398 internal_condition_case_1 (redisplay_window_1, selected_window, 11399 list_of_error, 11400 redisplay_window_error); 11401 11402 /* Compare desired and current matrices, perform output. */ 11403 11404 update: 11405 /* If fonts changed, display again. */ 11406 if (fonts_changed_p) 11407 goto retry; 11408 11409 /* Prevent various kinds of signals during display update. 11410 stdio is not robust about handling signals, 11411 which can cause an apparent I/O error. */ 11412 if (interrupt_input) 11413 unrequest_sigio (); 11414 STOP_POLLING; 11415 11416 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) 11417 { 11418 if (hscroll_windows (selected_window)) 11419 goto retry; 11420 11421 XWINDOW (selected_window)->must_be_updated_p = 1; 11422 pause = update_frame (sf, 0, 0); 11423 } 11424 11425 /* We may have called echo_area_display at the top of this 11426 function. If the echo area is on another frame, that may 11427 have put text on a frame other than the selected one, so the 11428 above call to update_frame would not have caught it. Catch 11429 it here. */ 11430 mini_window = FRAME_MINIBUF_WINDOW (sf); 11431 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); 11432 11433 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame)) 11434 { 11435 XWINDOW (mini_window)->must_be_updated_p = 1; 11436 pause |= update_frame (mini_frame, 0, 0); 11437 if (!pause && hscroll_windows (mini_window)) 11438 goto retry; 11439 } 11440 } 11441 11442 /* If display was paused because of pending input, make sure we do a 11443 thorough update the next time. */ 11444 if (pause) 11445 { 11446 /* Prevent the optimization at the beginning of 11447 redisplay_internal that tries a single-line update of the 11448 line containing the cursor in the selected window. */ 11449 CHARPOS (this_line_start_pos) = 0; 11450 11451 /* Let the overlay arrow be updated the next time. */ 11452 update_overlay_arrows (0); 11453 11454 /* If we pause after scrolling, some rows in the current 11455 matrices of some windows are not valid. */ 11456 if (!WINDOW_FULL_WIDTH_P (w) 11457 && !FRAME_WINDOW_P (XFRAME (w->frame))) 11458 update_mode_lines = 1; 11459 } 11460 else 11461 { 11462 if (!consider_all_windows_p) 11463 { 11464 /* This has already been done above if 11465 consider_all_windows_p is set. */ 11466 mark_window_display_accurate_1 (w, 1); 11467 11468 /* Say overlay arrows are up to date. */ 11469 update_overlay_arrows (1); 11470 11471 if (frame_up_to_date_hook != 0) 11472 frame_up_to_date_hook (sf); 11473 } 11474 11475 update_mode_lines = 0; 11476 windows_or_buffers_changed = 0; 11477 cursor_type_changed = 0; 11478 } 11479 11480 /* Start SIGIO interrupts coming again. Having them off during the 11481 code above makes it less likely one will discard output, but not 11482 impossible, since there might be stuff in the system buffer here. 11483 But it is much hairier to try to do anything about that. */ 11484 if (interrupt_input) 11485 request_sigio (); 11486 RESUME_POLLING; 11487 11488 /* If a frame has become visible which was not before, redisplay 11489 again, so that we display it. Expose events for such a frame 11490 (which it gets when becoming visible) don't call the parts of 11491 redisplay constructing glyphs, so simply exposing a frame won't 11492 display anything in this case. So, we have to display these 11493 frames here explicitly. */ 11494 if (!pause) 11495 { 11496 Lisp_Object tail, frame; 11497 int new_count = 0; 11498 11499 FOR_EACH_FRAME (tail, frame) 11500 { 11501 int this_is_visible = 0; 11502 11503 if (XFRAME (frame)->visible) 11504 this_is_visible = 1; 11505 FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); 11506 if (XFRAME (frame)->visible) 11507 this_is_visible = 1; 11508 11509 if (this_is_visible) 11510 new_count++; 11511 } 11512 11513 if (new_count != number_of_visible_frames) 11514 windows_or_buffers_changed++; 11515 } 11516 11517 /* Change frame size now if a change is pending. */ 11518 do_pending_window_change (1); 11519 11520 /* If we just did a pending size change, or have additional 11521 visible frames, redisplay again. */ 11522 if (windows_or_buffers_changed && !pause) 11523 goto retry; 11524 11525 /* Clear the face cache eventually. */ 11526 if (consider_all_windows_p) 11527 { 11528 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT) 11529 { 11530 clear_face_cache (0); 11531 clear_face_cache_count = 0; 11532 } 11533#ifdef HAVE_WINDOW_SYSTEM 11534 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) 11535 { 11536 Lisp_Object tail, frame; 11537 FOR_EACH_FRAME (tail, frame) 11538 { 11539 struct frame *f = XFRAME (frame); 11540 if (FRAME_WINDOW_P (f)) 11541 clear_image_cache (f, 0); 11542 } 11543 clear_image_cache_count = 0; 11544 } 11545#endif /* HAVE_WINDOW_SYSTEM */ 11546 } 11547 11548 end_of_redisplay: 11549 unbind_to (count, Qnil); 11550 RESUME_POLLING; 11551} 11552 11553 11554/* Redisplay, but leave alone any recent echo area message unless 11555 another message has been requested in its place. 11556 11557 This is useful in situations where you need to redisplay but no 11558 user action has occurred, making it inappropriate for the message 11559 area to be cleared. See tracking_off and 11560 wait_reading_process_output for examples of these situations. 11561 11562 FROM_WHERE is an integer saying from where this function was 11563 called. This is useful for debugging. */ 11564 11565void 11566redisplay_preserve_echo_area (from_where) 11567 int from_where; 11568{ 11569 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where)); 11570 11571 if (!NILP (echo_area_buffer[1])) 11572 { 11573 /* We have a previously displayed message, but no current 11574 message. Redisplay the previous message. */ 11575 display_last_displayed_message_p = 1; 11576 redisplay_internal (1); 11577 display_last_displayed_message_p = 0; 11578 } 11579 else 11580 redisplay_internal (1); 11581 11582 if (rif != NULL && rif->flush_display_optional) 11583 rif->flush_display_optional (NULL); 11584} 11585 11586 11587/* Function registered with record_unwind_protect in 11588 redisplay_internal. Reset redisplaying_p to the value it had 11589 before redisplay_internal was called, and clear 11590 prevent_freeing_realized_faces_p. It also selects the previously 11591 selected frame. */ 11592 11593static Lisp_Object 11594unwind_redisplay (val) 11595 Lisp_Object val; 11596{ 11597 Lisp_Object old_redisplaying_p, old_frame; 11598 11599 old_redisplaying_p = XCAR (val); 11600 redisplaying_p = XFASTINT (old_redisplaying_p); 11601 old_frame = XCDR (val); 11602 if (! EQ (old_frame, selected_frame)) 11603 select_frame_for_redisplay (old_frame); 11604 return Qnil; 11605} 11606 11607 11608/* Mark the display of window W as accurate or inaccurate. If 11609 ACCURATE_P is non-zero mark display of W as accurate. If 11610 ACCURATE_P is zero, arrange for W to be redisplayed the next time 11611 redisplay_internal is called. */ 11612 11613static void 11614mark_window_display_accurate_1 (w, accurate_p) 11615 struct window *w; 11616 int accurate_p; 11617{ 11618 if (BUFFERP (w->buffer)) 11619 { 11620 struct buffer *b = XBUFFER (w->buffer); 11621 11622 w->last_modified 11623 = make_number (accurate_p ? BUF_MODIFF (b) : 0); 11624 w->last_overlay_modified 11625 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0); 11626 w->last_had_star 11627 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil; 11628 11629 if (accurate_p) 11630 { 11631 b->clip_changed = 0; 11632 b->prevent_redisplay_optimizations_p = 0; 11633 11634 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b); 11635 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b); 11636 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b); 11637 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b); 11638 11639 w->current_matrix->buffer = b; 11640 w->current_matrix->begv = BUF_BEGV (b); 11641 w->current_matrix->zv = BUF_ZV (b); 11642 11643 w->last_cursor = w->cursor; 11644 w->last_cursor_off_p = w->cursor_off_p; 11645 11646 if (w == XWINDOW (selected_window)) 11647 w->last_point = make_number (BUF_PT (b)); 11648 else 11649 w->last_point = make_number (XMARKER (w->pointm)->charpos); 11650 } 11651 } 11652 11653 if (accurate_p) 11654 { 11655 w->window_end_valid = w->buffer; 11656#if 0 /* This is incorrect with variable-height lines. */ 11657 xassert (XINT (w->window_end_vpos) 11658 < (WINDOW_TOTAL_LINES (w) 11659 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0))); 11660#endif 11661 w->update_mode_line = Qnil; 11662 } 11663} 11664 11665 11666/* Mark the display of windows in the window tree rooted at WINDOW as 11667 accurate or inaccurate. If ACCURATE_P is non-zero mark display of 11668 windows as accurate. If ACCURATE_P is zero, arrange for windows to 11669 be redisplayed the next time redisplay_internal is called. */ 11670 11671void 11672mark_window_display_accurate (window, accurate_p) 11673 Lisp_Object window; 11674 int accurate_p; 11675{ 11676 struct window *w; 11677 11678 for (; !NILP (window); window = w->next) 11679 { 11680 w = XWINDOW (window); 11681 mark_window_display_accurate_1 (w, accurate_p); 11682 11683 if (!NILP (w->vchild)) 11684 mark_window_display_accurate (w->vchild, accurate_p); 11685 if (!NILP (w->hchild)) 11686 mark_window_display_accurate (w->hchild, accurate_p); 11687 } 11688 11689 if (accurate_p) 11690 { 11691 update_overlay_arrows (1); 11692 } 11693 else 11694 { 11695 /* Force a thorough redisplay the next time by setting 11696 last_arrow_position and last_arrow_string to t, which is 11697 unequal to any useful value of Voverlay_arrow_... */ 11698 update_overlay_arrows (-1); 11699 } 11700} 11701 11702 11703/* Return value in display table DP (Lisp_Char_Table *) for character 11704 C. Since a display table doesn't have any parent, we don't have to 11705 follow parent. Do not call this function directly but use the 11706 macro DISP_CHAR_VECTOR. */ 11707 11708Lisp_Object 11709disp_char_vector (dp, c) 11710 struct Lisp_Char_Table *dp; 11711 int c; 11712{ 11713 int code[4], i; 11714 Lisp_Object val; 11715 11716 if (SINGLE_BYTE_CHAR_P (c)) 11717 return (dp->contents[c]); 11718 11719 SPLIT_CHAR (c, code[0], code[1], code[2]); 11720 if (code[1] < 32) 11721 code[1] = -1; 11722 else if (code[2] < 32) 11723 code[2] = -1; 11724 11725 /* Here, the possible range of code[0] (== charset ID) is 11726 128..max_charset. Since the top level char table contains data 11727 for multibyte characters after 256th element, we must increment 11728 code[0] by 128 to get a correct index. */ 11729 code[0] += 128; 11730 code[3] = -1; /* anchor */ 11731 11732 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val)) 11733 { 11734 val = dp->contents[code[i]]; 11735 if (!SUB_CHAR_TABLE_P (val)) 11736 return (NILP (val) ? dp->defalt : val); 11737 } 11738 11739 /* Here, val is a sub char table. We return the default value of 11740 it. */ 11741 return (dp->defalt); 11742} 11743 11744 11745 11746/*********************************************************************** 11747 Window Redisplay 11748 ***********************************************************************/ 11749 11750/* Redisplay all leaf windows in the window tree rooted at WINDOW. */ 11751 11752static void 11753redisplay_windows (window) 11754 Lisp_Object window; 11755{ 11756 while (!NILP (window)) 11757 { 11758 struct window *w = XWINDOW (window); 11759 11760 if (!NILP (w->hchild)) 11761 redisplay_windows (w->hchild); 11762 else if (!NILP (w->vchild)) 11763 redisplay_windows (w->vchild); 11764 else 11765 { 11766 displayed_buffer = XBUFFER (w->buffer); 11767 /* Use list_of_error, not Qerror, so that 11768 we catch only errors and don't run the debugger. */ 11769 internal_condition_case_1 (redisplay_window_0, window, 11770 list_of_error, 11771 redisplay_window_error); 11772 } 11773 11774 window = w->next; 11775 } 11776} 11777 11778static Lisp_Object 11779redisplay_window_error () 11780{ 11781 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer); 11782 return Qnil; 11783} 11784 11785static Lisp_Object 11786redisplay_window_0 (window) 11787 Lisp_Object window; 11788{ 11789 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer)) 11790 redisplay_window (window, 0); 11791 return Qnil; 11792} 11793 11794static Lisp_Object 11795redisplay_window_1 (window) 11796 Lisp_Object window; 11797{ 11798 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer)) 11799 redisplay_window (window, 1); 11800 return Qnil; 11801} 11802 11803 11804/* Increment GLYPH until it reaches END or CONDITION fails while 11805 adding (GLYPH)->pixel_width to X. */ 11806 11807#define SKIP_GLYPHS(glyph, end, x, condition) \ 11808 do \ 11809 { \ 11810 (x) += (glyph)->pixel_width; \ 11811 ++(glyph); \ 11812 } \ 11813 while ((glyph) < (end) && (condition)) 11814 11815 11816/* Set cursor position of W. PT is assumed to be displayed in ROW. 11817 DELTA is the number of bytes by which positions recorded in ROW 11818 differ from current buffer positions. 11819 11820 Return 0 if cursor is not on this row. 1 otherwise. */ 11821 11822int 11823set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) 11824 struct window *w; 11825 struct glyph_row *row; 11826 struct glyph_matrix *matrix; 11827 int delta, delta_bytes, dy, dvpos; 11828{ 11829 struct glyph *glyph = row->glyphs[TEXT_AREA]; 11830 struct glyph *end = glyph + row->used[TEXT_AREA]; 11831 struct glyph *cursor = NULL; 11832 /* The first glyph that starts a sequence of glyphs from string. */ 11833 struct glyph *string_start; 11834 /* The X coordinate of string_start. */ 11835 int string_start_x; 11836 /* The last known character position. */ 11837 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta; 11838 /* The last known character position before string_start. */ 11839 int string_before_pos; 11840 int x = row->x; 11841 int cursor_x = x; 11842 int cursor_from_overlay_pos = 0; 11843 int pt_old = PT - delta; 11844 11845 /* Skip over glyphs not having an object at the start of the row. 11846 These are special glyphs like truncation marks on terminal 11847 frames. */ 11848 if (row->displays_text_p) 11849 while (glyph < end 11850 && INTEGERP (glyph->object) 11851 && glyph->charpos < 0) 11852 { 11853 x += glyph->pixel_width; 11854 ++glyph; 11855 } 11856 11857 string_start = NULL; 11858 while (glyph < end 11859 && !INTEGERP (glyph->object) 11860 && (!BUFFERP (glyph->object) 11861 || (last_pos = glyph->charpos) < pt_old)) 11862 { 11863 if (! STRINGP (glyph->object)) 11864 { 11865 string_start = NULL; 11866 x += glyph->pixel_width; 11867 ++glyph; 11868 if (cursor_from_overlay_pos 11869 && last_pos >= cursor_from_overlay_pos) 11870 { 11871 cursor_from_overlay_pos = 0; 11872 cursor = 0; 11873 } 11874 } 11875 else 11876 { 11877 if (string_start == NULL) 11878 { 11879 string_before_pos = last_pos; 11880 string_start = glyph; 11881 string_start_x = x; 11882 } 11883 /* Skip all glyphs from string. */ 11884 do 11885 { 11886 Lisp_Object cprop; 11887 int pos; 11888 if ((cursor == NULL || glyph > cursor) 11889 && (cprop = Fget_char_property (make_number ((glyph)->charpos), 11890 Qcursor, (glyph)->object), 11891 !NILP (cprop)) 11892 && (pos = string_buffer_position (w, glyph->object, 11893 string_before_pos), 11894 (pos == 0 /* From overlay */ 11895 || pos == pt_old))) 11896 { 11897 /* Estimate overlay buffer position from the buffer 11898 positions of the glyphs before and after the overlay. 11899 Add 1 to last_pos so that if point corresponds to the 11900 glyph right after the overlay, we still use a 'cursor' 11901 property found in that overlay. */ 11902 cursor_from_overlay_pos = (pos ? 0 : last_pos 11903 + (INTEGERP (cprop) ? XINT (cprop) : 0)); 11904 cursor = glyph; 11905 cursor_x = x; 11906 } 11907 x += glyph->pixel_width; 11908 ++glyph; 11909 } 11910 while (glyph < end && EQ (glyph->object, string_start->object)); 11911 } 11912 } 11913 11914 if (cursor != NULL) 11915 { 11916 glyph = cursor; 11917 x = cursor_x; 11918 } 11919 else if (row->ends_in_ellipsis_p && glyph == end) 11920 { 11921 /* Scan back over the ellipsis glyphs, decrementing positions. */ 11922 while (glyph > row->glyphs[TEXT_AREA] 11923 && (glyph - 1)->charpos == last_pos) 11924 glyph--, x -= glyph->pixel_width; 11925 /* That loop always goes one position too far, 11926 including the glyph before the ellipsis. 11927 So scan forward over that one. */ 11928 x += glyph->pixel_width; 11929 glyph++; 11930 } 11931 else if (string_start 11932 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old)) 11933 { 11934 /* We may have skipped over point because the previous glyphs 11935 are from string. As there's no easy way to know the 11936 character position of the current glyph, find the correct 11937 glyph on point by scanning from string_start again. */ 11938 Lisp_Object limit; 11939 Lisp_Object string; 11940 struct glyph *stop = glyph; 11941 int pos; 11942 11943 limit = make_number (pt_old + 1); 11944 glyph = string_start; 11945 x = string_start_x; 11946 string = glyph->object; 11947 pos = string_buffer_position (w, string, string_before_pos); 11948 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs 11949 because we always put cursor after overlay strings. */ 11950 while (pos == 0 && glyph < stop) 11951 { 11952 string = glyph->object; 11953 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string)); 11954 if (glyph < stop) 11955 pos = string_buffer_position (w, glyph->object, string_before_pos); 11956 } 11957 11958 while (glyph < stop) 11959 { 11960 pos = XINT (Fnext_single_char_property_change 11961 (make_number (pos), Qdisplay, Qnil, limit)); 11962 if (pos > pt_old) 11963 break; 11964 /* Skip glyphs from the same string. */ 11965 string = glyph->object; 11966 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string)); 11967 /* Skip glyphs from an overlay. */ 11968 while (glyph < stop 11969 && ! string_buffer_position (w, glyph->object, pos)) 11970 { 11971 string = glyph->object; 11972 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string)); 11973 } 11974 } 11975 11976 /* If we reached the end of the line, and end was from a string, 11977 cursor is not on this line. */ 11978 if (glyph == end && row->continued_p) 11979 return 0; 11980 } 11981 11982 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA]; 11983 w->cursor.x = x; 11984 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos; 11985 w->cursor.y = row->y + dy; 11986 11987 if (w == XWINDOW (selected_window)) 11988 { 11989 if (!row->continued_p 11990 && !MATRIX_ROW_CONTINUATION_LINE_P (row) 11991 && row->x == 0) 11992 { 11993 this_line_buffer = XBUFFER (w->buffer); 11994 11995 CHARPOS (this_line_start_pos) 11996 = MATRIX_ROW_START_CHARPOS (row) + delta; 11997 BYTEPOS (this_line_start_pos) 11998 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes; 11999 12000 CHARPOS (this_line_end_pos) 12001 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta); 12002 BYTEPOS (this_line_end_pos) 12003 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes); 12004 12005 this_line_y = w->cursor.y; 12006 this_line_pixel_height = row->height; 12007 this_line_vpos = w->cursor.vpos; 12008 this_line_start_x = row->x; 12009 } 12010 else 12011 CHARPOS (this_line_start_pos) = 0; 12012 } 12013 12014 return 1; 12015} 12016 12017 12018/* Run window scroll functions, if any, for WINDOW with new window 12019 start STARTP. Sets the window start of WINDOW to that position. 12020 12021 We assume that the window's buffer is really current. */ 12022 12023static INLINE struct text_pos 12024run_window_scroll_functions (window, startp) 12025 Lisp_Object window; 12026 struct text_pos startp; 12027{ 12028 struct window *w = XWINDOW (window); 12029 SET_MARKER_FROM_TEXT_POS (w->start, startp); 12030 12031 if (current_buffer != XBUFFER (w->buffer)) 12032 abort (); 12033 12034 if (!NILP (Vwindow_scroll_functions)) 12035 { 12036 run_hook_with_args_2 (Qwindow_scroll_functions, window, 12037 make_number (CHARPOS (startp))); 12038 SET_TEXT_POS_FROM_MARKER (startp, w->start); 12039 /* In case the hook functions switch buffers. */ 12040 if (current_buffer != XBUFFER (w->buffer)) 12041 set_buffer_internal_1 (XBUFFER (w->buffer)); 12042 } 12043 12044 return startp; 12045} 12046 12047 12048/* Make sure the line containing the cursor is fully visible. 12049 A value of 1 means there is nothing to be done. 12050 (Either the line is fully visible, or it cannot be made so, 12051 or we cannot tell.) 12052 12053 If FORCE_P is non-zero, return 0 even if partial visible cursor row 12054 is higher than window. 12055 12056 A value of 0 means the caller should do scrolling 12057 as if point had gone off the screen. */ 12058 12059static int 12060cursor_row_fully_visible_p (w, force_p, current_matrix_p) 12061 struct window *w; 12062 int force_p; 12063 int current_matrix_p; 12064{ 12065 struct glyph_matrix *matrix; 12066 struct glyph_row *row; 12067 int window_height; 12068 12069 if (!make_cursor_line_fully_visible_p) 12070 return 1; 12071 12072 /* It's not always possible to find the cursor, e.g, when a window 12073 is full of overlay strings. Don't do anything in that case. */ 12074 if (w->cursor.vpos < 0) 12075 return 1; 12076 12077 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix; 12078 row = MATRIX_ROW (matrix, w->cursor.vpos); 12079 12080 /* If the cursor row is not partially visible, there's nothing to do. */ 12081 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)) 12082 return 1; 12083 12084 /* If the row the cursor is in is taller than the window's height, 12085 it's not clear what to do, so do nothing. */ 12086 window_height = window_box_height (w); 12087 if (row->height >= window_height) 12088 { 12089 if (!force_p || MINI_WINDOW_P (w) 12090 || w->vscroll || w->cursor.vpos == 0) 12091 return 1; 12092 } 12093 return 0; 12094 12095#if 0 12096 /* This code used to try to scroll the window just enough to make 12097 the line visible. It returned 0 to say that the caller should 12098 allocate larger glyph matrices. */ 12099 12100 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row)) 12101 { 12102 int dy = row->height - row->visible_height; 12103 w->vscroll = 0; 12104 w->cursor.y += dy; 12105 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy); 12106 } 12107 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */ 12108 { 12109 int dy = - (row->height - row->visible_height); 12110 w->vscroll = dy; 12111 w->cursor.y += dy; 12112 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy); 12113 } 12114 12115 /* When we change the cursor y-position of the selected window, 12116 change this_line_y as well so that the display optimization for 12117 the cursor line of the selected window in redisplay_internal uses 12118 the correct y-position. */ 12119 if (w == XWINDOW (selected_window)) 12120 this_line_y = w->cursor.y; 12121 12122 /* If vscrolling requires a larger glyph matrix, arrange for a fresh 12123 redisplay with larger matrices. */ 12124 if (matrix->nrows < required_matrix_height (w)) 12125 { 12126 fonts_changed_p = 1; 12127 return 0; 12128 } 12129 12130 return 1; 12131#endif /* 0 */ 12132} 12133 12134 12135/* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P 12136 non-zero means only WINDOW is redisplayed in redisplay_internal. 12137 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used 12138 in redisplay_window to bring a partially visible line into view in 12139 the case that only the cursor has moved. 12140 12141 LAST_LINE_MISFIT should be nonzero if we're scrolling because the 12142 last screen line's vertical height extends past the end of the screen. 12143 12144 Value is 12145 12146 1 if scrolling succeeded 12147 12148 0 if scrolling didn't find point. 12149 12150 -1 if new fonts have been loaded so that we must interrupt 12151 redisplay, adjust glyph matrices, and try again. */ 12152 12153enum 12154{ 12155 SCROLLING_SUCCESS, 12156 SCROLLING_FAILED, 12157 SCROLLING_NEED_LARGER_MATRICES 12158}; 12159 12160static int 12161try_scrolling (window, just_this_one_p, scroll_conservatively, 12162 scroll_step, temp_scroll_step, last_line_misfit) 12163 Lisp_Object window; 12164 int just_this_one_p; 12165 EMACS_INT scroll_conservatively, scroll_step; 12166 int temp_scroll_step; 12167 int last_line_misfit; 12168{ 12169 struct window *w = XWINDOW (window); 12170 struct frame *f = XFRAME (w->frame); 12171 struct text_pos scroll_margin_pos; 12172 struct text_pos pos; 12173 struct text_pos startp; 12174 struct it it; 12175 Lisp_Object window_end; 12176 int this_scroll_margin; 12177 int dy = 0; 12178 int scroll_max; 12179 int rc; 12180 int amount_to_scroll = 0; 12181 Lisp_Object aggressive; 12182 int height; 12183 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0; 12184 12185#if GLYPH_DEBUG 12186 debug_method_add (w, "try_scrolling"); 12187#endif 12188 12189 SET_TEXT_POS_FROM_MARKER (startp, w->start); 12190 12191 /* Compute scroll margin height in pixels. We scroll when point is 12192 within this distance from the top or bottom of the window. */ 12193 if (scroll_margin > 0) 12194 { 12195 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); 12196 this_scroll_margin *= FRAME_LINE_HEIGHT (f); 12197 } 12198 else 12199 this_scroll_margin = 0; 12200 12201 /* Force scroll_conservatively to have a reasonable value so it doesn't 12202 cause an overflow while computing how much to scroll. */ 12203 if (scroll_conservatively) 12204 scroll_conservatively = min (scroll_conservatively, 12205 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f)); 12206 12207 /* Compute how much we should try to scroll maximally to bring point 12208 into view. */ 12209 if (scroll_step || scroll_conservatively || temp_scroll_step) 12210 scroll_max = max (scroll_step, 12211 max (scroll_conservatively, temp_scroll_step)); 12212 else if (NUMBERP (current_buffer->scroll_down_aggressively) 12213 || NUMBERP (current_buffer->scroll_up_aggressively)) 12214 /* We're trying to scroll because of aggressive scrolling 12215 but no scroll_step is set. Choose an arbitrary one. Maybe 12216 there should be a variable for this. */ 12217 scroll_max = 10; 12218 else 12219 scroll_max = 0; 12220 scroll_max *= FRAME_LINE_HEIGHT (f); 12221 12222 /* Decide whether we have to scroll down. Start at the window end 12223 and move this_scroll_margin up to find the position of the scroll 12224 margin. */ 12225 window_end = Fwindow_end (window, Qt); 12226 12227 too_near_end: 12228 12229 CHARPOS (scroll_margin_pos) = XINT (window_end); 12230 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos)); 12231 12232 if (this_scroll_margin || extra_scroll_margin_lines) 12233 { 12234 start_display (&it, w, scroll_margin_pos); 12235 if (this_scroll_margin) 12236 move_it_vertically_backward (&it, this_scroll_margin); 12237 if (extra_scroll_margin_lines) 12238 move_it_by_lines (&it, - extra_scroll_margin_lines, 0); 12239 scroll_margin_pos = it.current.pos; 12240 } 12241 12242 if (PT >= CHARPOS (scroll_margin_pos)) 12243 { 12244 int y0; 12245 12246 /* Point is in the scroll margin at the bottom of the window, or 12247 below. Compute a new window start that makes point visible. */ 12248 12249 /* Compute the distance from the scroll margin to PT. 12250 Give up if the distance is greater than scroll_max. */ 12251 start_display (&it, w, scroll_margin_pos); 12252 y0 = it.current_y; 12253 move_it_to (&it, PT, 0, it.last_visible_y, -1, 12254 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 12255 12256 /* To make point visible, we have to move the window start 12257 down so that the line the cursor is in is visible, which 12258 means we have to add in the height of the cursor line. */ 12259 dy = line_bottom_y (&it) - y0; 12260 12261 if (dy > scroll_max) 12262 return SCROLLING_FAILED; 12263 12264 /* Move the window start down. If scrolling conservatively, 12265 move it just enough down to make point visible. If 12266 scroll_step is set, move it down by scroll_step. */ 12267 start_display (&it, w, startp); 12268 12269 if (scroll_conservatively) 12270 /* Set AMOUNT_TO_SCROLL to at least one line, 12271 and at most scroll_conservatively lines. */ 12272 amount_to_scroll 12273 = min (max (dy, FRAME_LINE_HEIGHT (f)), 12274 FRAME_LINE_HEIGHT (f) * scroll_conservatively); 12275 else if (scroll_step || temp_scroll_step) 12276 amount_to_scroll = scroll_max; 12277 else 12278 { 12279 aggressive = current_buffer->scroll_up_aggressively; 12280 height = WINDOW_BOX_TEXT_HEIGHT (w); 12281 if (NUMBERP (aggressive)) 12282 { 12283 double float_amount = XFLOATINT (aggressive) * height; 12284 amount_to_scroll = float_amount; 12285 if (amount_to_scroll == 0 && float_amount > 0) 12286 amount_to_scroll = 1; 12287 } 12288 } 12289 12290 if (amount_to_scroll <= 0) 12291 return SCROLLING_FAILED; 12292 12293 /* If moving by amount_to_scroll leaves STARTP unchanged, 12294 move it down one screen line. */ 12295 12296 move_it_vertically (&it, amount_to_scroll); 12297 if (CHARPOS (it.current.pos) == CHARPOS (startp)) 12298 move_it_by_lines (&it, 1, 1); 12299 startp = it.current.pos; 12300 } 12301 else 12302 { 12303 /* See if point is inside the scroll margin at the top of the 12304 window. */ 12305 scroll_margin_pos = startp; 12306 if (this_scroll_margin) 12307 { 12308 start_display (&it, w, startp); 12309 move_it_vertically (&it, this_scroll_margin); 12310 scroll_margin_pos = it.current.pos; 12311 } 12312 12313 if (PT < CHARPOS (scroll_margin_pos)) 12314 { 12315 /* Point is in the scroll margin at the top of the window or 12316 above what is displayed in the window. */ 12317 int y0; 12318 12319 /* Compute the vertical distance from PT to the scroll 12320 margin position. Give up if distance is greater than 12321 scroll_max. */ 12322 SET_TEXT_POS (pos, PT, PT_BYTE); 12323 start_display (&it, w, pos); 12324 y0 = it.current_y; 12325 move_it_to (&it, CHARPOS (scroll_margin_pos), 0, 12326 it.last_visible_y, -1, 12327 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 12328 dy = it.current_y - y0; 12329 if (dy > scroll_max) 12330 return SCROLLING_FAILED; 12331 12332 /* Compute new window start. */ 12333 start_display (&it, w, startp); 12334 12335 if (scroll_conservatively) 12336 amount_to_scroll 12337 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step)); 12338 else if (scroll_step || temp_scroll_step) 12339 amount_to_scroll = scroll_max; 12340 else 12341 { 12342 aggressive = current_buffer->scroll_down_aggressively; 12343 height = WINDOW_BOX_TEXT_HEIGHT (w); 12344 if (NUMBERP (aggressive)) 12345 { 12346 double float_amount = XFLOATINT (aggressive) * height; 12347 amount_to_scroll = float_amount; 12348 if (amount_to_scroll == 0 && float_amount > 0) 12349 amount_to_scroll = 1; 12350 } 12351 } 12352 12353 if (amount_to_scroll <= 0) 12354 return SCROLLING_FAILED; 12355 12356 move_it_vertically_backward (&it, amount_to_scroll); 12357 startp = it.current.pos; 12358 } 12359 } 12360 12361 /* Run window scroll functions. */ 12362 startp = run_window_scroll_functions (window, startp); 12363 12364 /* Display the window. Give up if new fonts are loaded, or if point 12365 doesn't appear. */ 12366 if (!try_window (window, startp, 0)) 12367 rc = SCROLLING_NEED_LARGER_MATRICES; 12368 else if (w->cursor.vpos < 0) 12369 { 12370 clear_glyph_matrix (w->desired_matrix); 12371 rc = SCROLLING_FAILED; 12372 } 12373 else 12374 { 12375 /* Maybe forget recorded base line for line number display. */ 12376 if (!just_this_one_p 12377 || current_buffer->clip_changed 12378 || BEG_UNCHANGED < CHARPOS (startp)) 12379 w->base_line_number = Qnil; 12380 12381 /* If cursor ends up on a partially visible line, 12382 treat that as being off the bottom of the screen. */ 12383 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)) 12384 { 12385 clear_glyph_matrix (w->desired_matrix); 12386 ++extra_scroll_margin_lines; 12387 goto too_near_end; 12388 } 12389 rc = SCROLLING_SUCCESS; 12390 } 12391 12392 return rc; 12393} 12394 12395 12396/* Compute a suitable window start for window W if display of W starts 12397 on a continuation line. Value is non-zero if a new window start 12398 was computed. 12399 12400 The new window start will be computed, based on W's width, starting 12401 from the start of the continued line. It is the start of the 12402 screen line with the minimum distance from the old start W->start. */ 12403 12404static int 12405compute_window_start_on_continuation_line (w) 12406 struct window *w; 12407{ 12408 struct text_pos pos, start_pos; 12409 int window_start_changed_p = 0; 12410 12411 SET_TEXT_POS_FROM_MARKER (start_pos, w->start); 12412 12413 /* If window start is on a continuation line... Window start may be 12414 < BEGV in case there's invisible text at the start of the 12415 buffer (M-x rmail, for example). */ 12416 if (CHARPOS (start_pos) > BEGV 12417 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n') 12418 { 12419 struct it it; 12420 struct glyph_row *row; 12421 12422 /* Handle the case that the window start is out of range. */ 12423 if (CHARPOS (start_pos) < BEGV) 12424 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE); 12425 else if (CHARPOS (start_pos) > ZV) 12426 SET_TEXT_POS (start_pos, ZV, ZV_BYTE); 12427 12428 /* Find the start of the continued line. This should be fast 12429 because scan_buffer is fast (newline cache). */ 12430 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); 12431 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), 12432 row, DEFAULT_FACE_ID); 12433 reseat_at_previous_visible_line_start (&it); 12434 12435 /* If the line start is "too far" away from the window start, 12436 say it takes too much time to compute a new window start. */ 12437 if (CHARPOS (start_pos) - IT_CHARPOS (it) 12438 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)) 12439 { 12440 int min_distance, distance; 12441 12442 /* Move forward by display lines to find the new window 12443 start. If window width was enlarged, the new start can 12444 be expected to be > the old start. If window width was 12445 decreased, the new window start will be < the old start. 12446 So, we're looking for the display line start with the 12447 minimum distance from the old window start. */ 12448 pos = it.current.pos; 12449 min_distance = INFINITY; 12450 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))), 12451 distance < min_distance) 12452 { 12453 min_distance = distance; 12454 pos = it.current.pos; 12455 move_it_by_lines (&it, 1, 0); 12456 } 12457 12458 /* Set the window start there. */ 12459 SET_MARKER_FROM_TEXT_POS (w->start, pos); 12460 window_start_changed_p = 1; 12461 } 12462 } 12463 12464 return window_start_changed_p; 12465} 12466 12467 12468/* Try cursor movement in case text has not changed in window WINDOW, 12469 with window start STARTP. Value is 12470 12471 CURSOR_MOVEMENT_SUCCESS if successful 12472 12473 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used 12474 12475 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the 12476 display. *SCROLL_STEP is set to 1, under certain circumstances, if 12477 we want to scroll as if scroll-step were set to 1. See the code. 12478 12479 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in 12480 which case we have to abort this redisplay, and adjust matrices 12481 first. */ 12482 12483enum 12484{ 12485 CURSOR_MOVEMENT_SUCCESS, 12486 CURSOR_MOVEMENT_CANNOT_BE_USED, 12487 CURSOR_MOVEMENT_MUST_SCROLL, 12488 CURSOR_MOVEMENT_NEED_LARGER_MATRICES 12489}; 12490 12491static int 12492try_cursor_movement (window, startp, scroll_step) 12493 Lisp_Object window; 12494 struct text_pos startp; 12495 int *scroll_step; 12496{ 12497 struct window *w = XWINDOW (window); 12498 struct frame *f = XFRAME (w->frame); 12499 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED; 12500 12501#if GLYPH_DEBUG 12502 if (inhibit_try_cursor_movement) 12503 return rc; 12504#endif 12505 12506 /* Handle case where text has not changed, only point, and it has 12507 not moved off the frame. */ 12508 if (/* Point may be in this window. */ 12509 PT >= CHARPOS (startp) 12510 /* Selective display hasn't changed. */ 12511 && !current_buffer->clip_changed 12512 /* Function force-mode-line-update is used to force a thorough 12513 redisplay. It sets either windows_or_buffers_changed or 12514 update_mode_lines. So don't take a shortcut here for these 12515 cases. */ 12516 && !update_mode_lines 12517 && !windows_or_buffers_changed 12518 && !cursor_type_changed 12519 /* Can't use this case if highlighting a region. When a 12520 region exists, cursor movement has to do more than just 12521 set the cursor. */ 12522 && !(!NILP (Vtransient_mark_mode) 12523 && !NILP (current_buffer->mark_active)) 12524 && NILP (w->region_showing) 12525 && NILP (Vshow_trailing_whitespace) 12526 /* Right after splitting windows, last_point may be nil. */ 12527 && INTEGERP (w->last_point) 12528 /* This code is not used for mini-buffer for the sake of the case 12529 of redisplaying to replace an echo area message; since in 12530 that case the mini-buffer contents per se are usually 12531 unchanged. This code is of no real use in the mini-buffer 12532 since the handling of this_line_start_pos, etc., in redisplay 12533 handles the same cases. */ 12534 && !EQ (window, minibuf_window) 12535 /* When splitting windows or for new windows, it happens that 12536 redisplay is called with a nil window_end_vpos or one being 12537 larger than the window. This should really be fixed in 12538 window.c. I don't have this on my list, now, so we do 12539 approximately the same as the old redisplay code. --gerd. */ 12540 && INTEGERP (w->window_end_vpos) 12541 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows 12542 && (FRAME_WINDOW_P (f) 12543 || !overlay_arrow_in_current_buffer_p ())) 12544 { 12545 int this_scroll_margin, top_scroll_margin; 12546 struct glyph_row *row = NULL; 12547 12548#if GLYPH_DEBUG 12549 debug_method_add (w, "cursor movement"); 12550#endif 12551 12552 /* Scroll if point within this distance from the top or bottom 12553 of the window. This is a pixel value. */ 12554 this_scroll_margin = max (0, scroll_margin); 12555 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); 12556 this_scroll_margin *= FRAME_LINE_HEIGHT (f); 12557 12558 top_scroll_margin = this_scroll_margin; 12559 if (WINDOW_WANTS_HEADER_LINE_P (w)) 12560 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w); 12561 12562 /* Start with the row the cursor was displayed during the last 12563 not paused redisplay. Give up if that row is not valid. */ 12564 if (w->last_cursor.vpos < 0 12565 || w->last_cursor.vpos >= w->current_matrix->nrows) 12566 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12567 else 12568 { 12569 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos); 12570 if (row->mode_line_p) 12571 ++row; 12572 if (!row->enabled_p) 12573 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12574 } 12575 12576 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED) 12577 { 12578 int scroll_p = 0; 12579 int last_y = window_text_bottom_y (w) - this_scroll_margin; 12580 12581 if (PT > XFASTINT (w->last_point)) 12582 { 12583 /* Point has moved forward. */ 12584 while (MATRIX_ROW_END_CHARPOS (row) < PT 12585 && MATRIX_ROW_BOTTOM_Y (row) < last_y) 12586 { 12587 xassert (row->enabled_p); 12588 ++row; 12589 } 12590 12591 /* The end position of a row equals the start position 12592 of the next row. If PT is there, we would rather 12593 display it in the next line. */ 12594 while (MATRIX_ROW_BOTTOM_Y (row) < last_y 12595 && MATRIX_ROW_END_CHARPOS (row) == PT 12596 && !cursor_row_p (w, row)) 12597 ++row; 12598 12599 /* If within the scroll margin, scroll. Note that 12600 MATRIX_ROW_BOTTOM_Y gives the pixel position at which 12601 the next line would be drawn, and that 12602 this_scroll_margin can be zero. */ 12603 if (MATRIX_ROW_BOTTOM_Y (row) > last_y 12604 || PT > MATRIX_ROW_END_CHARPOS (row) 12605 /* Line is completely visible last line in window 12606 and PT is to be set in the next line. */ 12607 || (MATRIX_ROW_BOTTOM_Y (row) == last_y 12608 && PT == MATRIX_ROW_END_CHARPOS (row) 12609 && !row->ends_at_zv_p 12610 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))) 12611 scroll_p = 1; 12612 } 12613 else if (PT < XFASTINT (w->last_point)) 12614 { 12615 /* Cursor has to be moved backward. Note that PT >= 12616 CHARPOS (startp) because of the outer if-statement. */ 12617 while (!row->mode_line_p 12618 && (MATRIX_ROW_START_CHARPOS (row) > PT 12619 || (MATRIX_ROW_START_CHARPOS (row) == PT 12620 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row) 12621 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */ 12622 row > w->current_matrix->rows 12623 && (row-1)->ends_in_newline_from_string_p)))) 12624 && (row->y > top_scroll_margin 12625 || CHARPOS (startp) == BEGV)) 12626 { 12627 xassert (row->enabled_p); 12628 --row; 12629 } 12630 12631 /* Consider the following case: Window starts at BEGV, 12632 there is invisible, intangible text at BEGV, so that 12633 display starts at some point START > BEGV. It can 12634 happen that we are called with PT somewhere between 12635 BEGV and START. Try to handle that case. */ 12636 if (row < w->current_matrix->rows 12637 || row->mode_line_p) 12638 { 12639 row = w->current_matrix->rows; 12640 if (row->mode_line_p) 12641 ++row; 12642 } 12643 12644 /* Due to newlines in overlay strings, we may have to 12645 skip forward over overlay strings. */ 12646 while (MATRIX_ROW_BOTTOM_Y (row) < last_y 12647 && MATRIX_ROW_END_CHARPOS (row) == PT 12648 && !cursor_row_p (w, row)) 12649 ++row; 12650 12651 /* If within the scroll margin, scroll. */ 12652 if (row->y < top_scroll_margin 12653 && CHARPOS (startp) != BEGV) 12654 scroll_p = 1; 12655 } 12656 else 12657 { 12658 /* Cursor did not move. So don't scroll even if cursor line 12659 is partially visible, as it was so before. */ 12660 rc = CURSOR_MOVEMENT_SUCCESS; 12661 } 12662 12663 if (PT < MATRIX_ROW_START_CHARPOS (row) 12664 || PT > MATRIX_ROW_END_CHARPOS (row)) 12665 { 12666 /* if PT is not in the glyph row, give up. */ 12667 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12668 } 12669 else if (rc != CURSOR_MOVEMENT_SUCCESS 12670 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) 12671 && make_cursor_line_fully_visible_p) 12672 { 12673 if (PT == MATRIX_ROW_END_CHARPOS (row) 12674 && !row->ends_at_zv_p 12675 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) 12676 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12677 else if (row->height > window_box_height (w)) 12678 { 12679 /* If we end up in a partially visible line, let's 12680 make it fully visible, except when it's taller 12681 than the window, in which case we can't do much 12682 about it. */ 12683 *scroll_step = 1; 12684 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12685 } 12686 else 12687 { 12688 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 12689 if (!cursor_row_fully_visible_p (w, 0, 1)) 12690 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12691 else 12692 rc = CURSOR_MOVEMENT_SUCCESS; 12693 } 12694 } 12695 else if (scroll_p) 12696 rc = CURSOR_MOVEMENT_MUST_SCROLL; 12697 else 12698 { 12699 do 12700 { 12701 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0)) 12702 { 12703 rc = CURSOR_MOVEMENT_SUCCESS; 12704 break; 12705 } 12706 ++row; 12707 } 12708 while (MATRIX_ROW_BOTTOM_Y (row) < last_y 12709 && MATRIX_ROW_START_CHARPOS (row) == PT 12710 && cursor_row_p (w, row)); 12711 } 12712 } 12713 } 12714 12715 return rc; 12716} 12717 12718void 12719set_vertical_scroll_bar (w) 12720 struct window *w; 12721{ 12722 int start, end, whole; 12723 12724 /* Calculate the start and end positions for the current window. 12725 At some point, it would be nice to choose between scrollbars 12726 which reflect the whole buffer size, with special markers 12727 indicating narrowing, and scrollbars which reflect only the 12728 visible region. 12729 12730 Note that mini-buffers sometimes aren't displaying any text. */ 12731 if (!MINI_WINDOW_P (w) 12732 || (w == XWINDOW (minibuf_window) 12733 && NILP (echo_area_buffer[0]))) 12734 { 12735 struct buffer *buf = XBUFFER (w->buffer); 12736 whole = BUF_ZV (buf) - BUF_BEGV (buf); 12737 start = marker_position (w->start) - BUF_BEGV (buf); 12738 /* I don't think this is guaranteed to be right. For the 12739 moment, we'll pretend it is. */ 12740 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf); 12741 12742 if (end < start) 12743 end = start; 12744 if (whole < (end - start)) 12745 whole = end - start; 12746 } 12747 else 12748 start = end = whole = 0; 12749 12750 /* Indicate what this scroll bar ought to be displaying now. */ 12751 set_vertical_scroll_bar_hook (w, end - start, whole, start); 12752} 12753 12754 12755/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only 12756 selected_window is redisplayed. 12757 12758 We can return without actually redisplaying the window if 12759 fonts_changed_p is nonzero. In that case, redisplay_internal will 12760 retry. */ 12761 12762static void 12763redisplay_window (window, just_this_one_p) 12764 Lisp_Object window; 12765 int just_this_one_p; 12766{ 12767 struct window *w = XWINDOW (window); 12768 struct frame *f = XFRAME (w->frame); 12769 struct buffer *buffer = XBUFFER (w->buffer); 12770 struct buffer *old = current_buffer; 12771 struct text_pos lpoint, opoint, startp; 12772 int update_mode_line; 12773 int tem; 12774 struct it it; 12775 /* Record it now because it's overwritten. */ 12776 int current_matrix_up_to_date_p = 0; 12777 int used_current_matrix_p = 0; 12778 /* This is less strict than current_matrix_up_to_date_p. 12779 It indictes that the buffer contents and narrowing are unchanged. */ 12780 int buffer_unchanged_p = 0; 12781 int temp_scroll_step = 0; 12782 int count = SPECPDL_INDEX (); 12783 int rc; 12784 int centering_position = -1; 12785 int last_line_misfit = 0; 12786 int save_beg_unchanged, save_end_unchanged; 12787 12788 SET_TEXT_POS (lpoint, PT, PT_BYTE); 12789 opoint = lpoint; 12790 12791 /* W must be a leaf window here. */ 12792 xassert (!NILP (w->buffer)); 12793#if GLYPH_DEBUG 12794 *w->desired_matrix->method = 0; 12795#endif 12796 12797 specbind (Qinhibit_point_motion_hooks, Qt); 12798 12799 reconsider_clip_changes (w, buffer); 12800 12801 /* Has the mode line to be updated? */ 12802 update_mode_line = (!NILP (w->update_mode_line) 12803 || update_mode_lines 12804 || buffer->clip_changed 12805 || buffer->prevent_redisplay_optimizations_p); 12806 12807 if (MINI_WINDOW_P (w)) 12808 { 12809 if (w == XWINDOW (echo_area_window) 12810 && !NILP (echo_area_buffer[0])) 12811 { 12812 if (update_mode_line) 12813 /* We may have to update a tty frame's menu bar or a 12814 tool-bar. Example `M-x C-h C-h C-g'. */ 12815 goto finish_menu_bars; 12816 else 12817 /* We've already displayed the echo area glyphs in this window. */ 12818 goto finish_scroll_bars; 12819 } 12820 else if ((w != XWINDOW (minibuf_window) 12821 || minibuf_level == 0) 12822 /* When buffer is nonempty, redisplay window normally. */ 12823 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer)) 12824 /* Quail displays non-mini buffers in minibuffer window. 12825 In that case, redisplay the window normally. */ 12826 && !NILP (Fmemq (w->buffer, Vminibuffer_list))) 12827 { 12828 /* W is a mini-buffer window, but it's not active, so clear 12829 it. */ 12830 int yb = window_text_bottom_y (w); 12831 struct glyph_row *row; 12832 int y; 12833 12834 for (y = 0, row = w->desired_matrix->rows; 12835 y < yb; 12836 y += row->height, ++row) 12837 blank_row (w, row, y); 12838 goto finish_scroll_bars; 12839 } 12840 12841 clear_glyph_matrix (w->desired_matrix); 12842 } 12843 12844 /* Otherwise set up data on this window; select its buffer and point 12845 value. */ 12846 /* Really select the buffer, for the sake of buffer-local 12847 variables. */ 12848 set_buffer_internal_1 (XBUFFER (w->buffer)); 12849 SET_TEXT_POS (opoint, PT, PT_BYTE); 12850 12851 save_beg_unchanged = BEG_UNCHANGED; 12852 save_end_unchanged = END_UNCHANGED; 12853 12854 current_matrix_up_to_date_p 12855 = (!NILP (w->window_end_valid) 12856 && !current_buffer->clip_changed 12857 && !current_buffer->prevent_redisplay_optimizations_p 12858 && XFASTINT (w->last_modified) >= MODIFF 12859 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF); 12860 12861 buffer_unchanged_p 12862 = (!NILP (w->window_end_valid) 12863 && !current_buffer->clip_changed 12864 && XFASTINT (w->last_modified) >= MODIFF 12865 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF); 12866 12867 /* When windows_or_buffers_changed is non-zero, we can't rely on 12868 the window end being valid, so set it to nil there. */ 12869 if (windows_or_buffers_changed) 12870 { 12871 /* If window starts on a continuation line, maybe adjust the 12872 window start in case the window's width changed. */ 12873 if (XMARKER (w->start)->buffer == current_buffer) 12874 compute_window_start_on_continuation_line (w); 12875 12876 w->window_end_valid = Qnil; 12877 } 12878 12879 /* Some sanity checks. */ 12880 CHECK_WINDOW_END (w); 12881 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint)) 12882 abort (); 12883 if (BYTEPOS (opoint) < CHARPOS (opoint)) 12884 abort (); 12885 12886 /* If %c is in mode line, update it if needed. */ 12887 if (!NILP (w->column_number_displayed) 12888 /* This alternative quickly identifies a common case 12889 where no change is needed. */ 12890 && !(PT == XFASTINT (w->last_point) 12891 && XFASTINT (w->last_modified) >= MODIFF 12892 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF) 12893 && (XFASTINT (w->column_number_displayed) 12894 != (int) current_column ())) /* iftc */ 12895 update_mode_line = 1; 12896 12897 /* Count number of windows showing the selected buffer. An indirect 12898 buffer counts as its base buffer. */ 12899 if (!just_this_one_p) 12900 { 12901 struct buffer *current_base, *window_base; 12902 current_base = current_buffer; 12903 window_base = XBUFFER (XWINDOW (selected_window)->buffer); 12904 if (current_base->base_buffer) 12905 current_base = current_base->base_buffer; 12906 if (window_base->base_buffer) 12907 window_base = window_base->base_buffer; 12908 if (current_base == window_base) 12909 buffer_shared++; 12910 } 12911 12912 /* Point refers normally to the selected window. For any other 12913 window, set up appropriate value. */ 12914 if (!EQ (window, selected_window)) 12915 { 12916 int new_pt = XMARKER (w->pointm)->charpos; 12917 int new_pt_byte = marker_byte_position (w->pointm); 12918 if (new_pt < BEGV) 12919 { 12920 new_pt = BEGV; 12921 new_pt_byte = BEGV_BYTE; 12922 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE); 12923 } 12924 else if (new_pt > (ZV - 1)) 12925 { 12926 new_pt = ZV; 12927 new_pt_byte = ZV_BYTE; 12928 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE); 12929 } 12930 12931 /* We don't use SET_PT so that the point-motion hooks don't run. */ 12932 TEMP_SET_PT_BOTH (new_pt, new_pt_byte); 12933 } 12934 12935 /* If any of the character widths specified in the display table 12936 have changed, invalidate the width run cache. It's true that 12937 this may be a bit late to catch such changes, but the rest of 12938 redisplay goes (non-fatally) haywire when the display table is 12939 changed, so why should we worry about doing any better? */ 12940 if (current_buffer->width_run_cache) 12941 { 12942 struct Lisp_Char_Table *disptab = buffer_display_table (); 12943 12944 if (! disptab_matches_widthtab (disptab, 12945 XVECTOR (current_buffer->width_table))) 12946 { 12947 invalidate_region_cache (current_buffer, 12948 current_buffer->width_run_cache, 12949 BEG, Z); 12950 recompute_width_table (current_buffer, disptab); 12951 } 12952 } 12953 12954 /* If window-start is screwed up, choose a new one. */ 12955 if (XMARKER (w->start)->buffer != current_buffer) 12956 goto recenter; 12957 12958 SET_TEXT_POS_FROM_MARKER (startp, w->start); 12959 12960 /* If someone specified a new starting point but did not insist, 12961 check whether it can be used. */ 12962 if (!NILP (w->optional_new_start) 12963 && CHARPOS (startp) >= BEGV 12964 && CHARPOS (startp) <= ZV) 12965 { 12966 w->optional_new_start = Qnil; 12967 start_display (&it, w, startp); 12968 move_it_to (&it, PT, 0, it.last_visible_y, -1, 12969 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 12970 if (IT_CHARPOS (it) == PT) 12971 w->force_start = Qt; 12972 /* IT may overshoot PT if text at PT is invisible. */ 12973 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT) 12974 w->force_start = Qt; 12975 } 12976 12977 force_start: 12978 12979 /* Handle case where place to start displaying has been specified, 12980 unless the specified location is outside the accessible range. */ 12981 if (!NILP (w->force_start) 12982 || w->frozen_window_start_p) 12983 { 12984 /* We set this later on if we have to adjust point. */ 12985 int new_vpos = -1; 12986 int val; 12987 12988 w->force_start = Qnil; 12989 w->vscroll = 0; 12990 w->window_end_valid = Qnil; 12991 12992 /* Forget any recorded base line for line number display. */ 12993 if (!buffer_unchanged_p) 12994 w->base_line_number = Qnil; 12995 12996 /* Redisplay the mode line. Select the buffer properly for that. 12997 Also, run the hook window-scroll-functions 12998 because we have scrolled. */ 12999 /* Note, we do this after clearing force_start because 13000 if there's an error, it is better to forget about force_start 13001 than to get into an infinite loop calling the hook functions 13002 and having them get more errors. */ 13003 if (!update_mode_line 13004 || ! NILP (Vwindow_scroll_functions)) 13005 { 13006 update_mode_line = 1; 13007 w->update_mode_line = Qt; 13008 startp = run_window_scroll_functions (window, startp); 13009 } 13010 13011 w->last_modified = make_number (0); 13012 w->last_overlay_modified = make_number (0); 13013 if (CHARPOS (startp) < BEGV) 13014 SET_TEXT_POS (startp, BEGV, BEGV_BYTE); 13015 else if (CHARPOS (startp) > ZV) 13016 SET_TEXT_POS (startp, ZV, ZV_BYTE); 13017 13018 /* Redisplay, then check if cursor has been set during the 13019 redisplay. Give up if new fonts were loaded. */ 13020 val = try_window (window, startp, 1); 13021 if (!val) 13022 { 13023 w->force_start = Qt; 13024 clear_glyph_matrix (w->desired_matrix); 13025 goto need_larger_matrices; 13026 } 13027 /* Point was outside the scroll margins. */ 13028 if (val < 0) 13029 new_vpos = window_box_height (w) / 2; 13030 13031 if (w->cursor.vpos < 0 && !w->frozen_window_start_p) 13032 { 13033 /* If point does not appear, try to move point so it does 13034 appear. The desired matrix has been built above, so we 13035 can use it here. */ 13036 new_vpos = window_box_height (w) / 2; 13037 } 13038 13039 if (!cursor_row_fully_visible_p (w, 0, 0)) 13040 { 13041 /* Point does appear, but on a line partly visible at end of window. 13042 Move it back to a fully-visible line. */ 13043 new_vpos = window_box_height (w); 13044 } 13045 13046 /* If we need to move point for either of the above reasons, 13047 now actually do it. */ 13048 if (new_vpos >= 0) 13049 { 13050 struct glyph_row *row; 13051 13052 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix); 13053 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos) 13054 ++row; 13055 13056 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row), 13057 MATRIX_ROW_START_BYTEPOS (row)); 13058 13059 if (w != XWINDOW (selected_window)) 13060 set_marker_both (w->pointm, Qnil, PT, PT_BYTE); 13061 else if (current_buffer == old) 13062 SET_TEXT_POS (lpoint, PT, PT_BYTE); 13063 13064 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0); 13065 13066 /* If we are highlighting the region, then we just changed 13067 the region, so redisplay to show it. */ 13068 if (!NILP (Vtransient_mark_mode) 13069 && !NILP (current_buffer->mark_active)) 13070 { 13071 clear_glyph_matrix (w->desired_matrix); 13072 if (!try_window (window, startp, 0)) 13073 goto need_larger_matrices; 13074 } 13075 } 13076 13077#if GLYPH_DEBUG 13078 debug_method_add (w, "forced window start"); 13079#endif 13080 goto done; 13081 } 13082 13083 /* Handle case where text has not changed, only point, and it has 13084 not moved off the frame, and we are not retrying after hscroll. 13085 (current_matrix_up_to_date_p is nonzero when retrying.) */ 13086 if (current_matrix_up_to_date_p 13087 && (rc = try_cursor_movement (window, startp, &temp_scroll_step), 13088 rc != CURSOR_MOVEMENT_CANNOT_BE_USED)) 13089 { 13090 switch (rc) 13091 { 13092 case CURSOR_MOVEMENT_SUCCESS: 13093 used_current_matrix_p = 1; 13094 goto done; 13095 13096#if 0 /* try_cursor_movement never returns this value. */ 13097 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES: 13098 goto need_larger_matrices; 13099#endif 13100 13101 case CURSOR_MOVEMENT_MUST_SCROLL: 13102 goto try_to_scroll; 13103 13104 default: 13105 abort (); 13106 } 13107 } 13108 /* If current starting point was originally the beginning of a line 13109 but no longer is, find a new starting point. */ 13110 else if (!NILP (w->start_at_line_beg) 13111 && !(CHARPOS (startp) <= BEGV 13112 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')) 13113 { 13114#if GLYPH_DEBUG 13115 debug_method_add (w, "recenter 1"); 13116#endif 13117 goto recenter; 13118 } 13119 13120 /* Try scrolling with try_window_id. Value is > 0 if update has 13121 been done, it is -1 if we know that the same window start will 13122 not work. It is 0 if unsuccessful for some other reason. */ 13123 else if ((tem = try_window_id (w)) != 0) 13124 { 13125#if GLYPH_DEBUG 13126 debug_method_add (w, "try_window_id %d", tem); 13127#endif 13128 13129 if (fonts_changed_p) 13130 goto need_larger_matrices; 13131 if (tem > 0) 13132 goto done; 13133 13134 /* Otherwise try_window_id has returned -1 which means that we 13135 don't want the alternative below this comment to execute. */ 13136 } 13137 else if (CHARPOS (startp) >= BEGV 13138 && CHARPOS (startp) <= ZV 13139 && PT >= CHARPOS (startp) 13140 && (CHARPOS (startp) < ZV 13141 /* Avoid starting at end of buffer. */ 13142 || CHARPOS (startp) == BEGV 13143 || (XFASTINT (w->last_modified) >= MODIFF 13144 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF))) 13145 { 13146 13147 /* If first window line is a continuation line, and window start 13148 is inside the modified region, but the first change is before 13149 current window start, we must select a new window start. 13150 13151 However, if this is the result of a down-mouse event (e.g. by 13152 extending the mouse-drag-overlay), we don't want to select a 13153 new window start, since that would change the position under 13154 the mouse, resulting in an unwanted mouse-movement rather 13155 than a simple mouse-click. */ 13156 if (NILP (w->start_at_line_beg) 13157 && NILP (do_mouse_tracking) 13158 && CHARPOS (startp) > BEGV 13159 && CHARPOS (startp) > BEG + save_beg_unchanged 13160 && CHARPOS (startp) <= Z - save_end_unchanged) 13161 { 13162 w->force_start = Qt; 13163 if (XMARKER (w->start)->buffer == current_buffer) 13164 compute_window_start_on_continuation_line (w); 13165 SET_TEXT_POS_FROM_MARKER (startp, w->start); 13166 goto force_start; 13167 } 13168 13169#if GLYPH_DEBUG 13170 debug_method_add (w, "same window start"); 13171#endif 13172 13173 /* Try to redisplay starting at same place as before. 13174 If point has not moved off frame, accept the results. */ 13175 if (!current_matrix_up_to_date_p 13176 /* Don't use try_window_reusing_current_matrix in this case 13177 because a window scroll function can have changed the 13178 buffer. */ 13179 || !NILP (Vwindow_scroll_functions) 13180 || MINI_WINDOW_P (w) 13181 || !(used_current_matrix_p 13182 = try_window_reusing_current_matrix (w))) 13183 { 13184 IF_DEBUG (debug_method_add (w, "1")); 13185 if (try_window (window, startp, 1) < 0) 13186 /* -1 means we need to scroll. 13187 0 means we need new matrices, but fonts_changed_p 13188 is set in that case, so we will detect it below. */ 13189 goto try_to_scroll; 13190 } 13191 13192 if (fonts_changed_p) 13193 goto need_larger_matrices; 13194 13195 if (w->cursor.vpos >= 0) 13196 { 13197 if (!just_this_one_p 13198 || current_buffer->clip_changed 13199 || BEG_UNCHANGED < CHARPOS (startp)) 13200 /* Forget any recorded base line for line number display. */ 13201 w->base_line_number = Qnil; 13202 13203 if (!cursor_row_fully_visible_p (w, 1, 0)) 13204 { 13205 clear_glyph_matrix (w->desired_matrix); 13206 last_line_misfit = 1; 13207 } 13208 /* Drop through and scroll. */ 13209 else 13210 goto done; 13211 } 13212 else 13213 clear_glyph_matrix (w->desired_matrix); 13214 } 13215 13216 try_to_scroll: 13217 13218 w->last_modified = make_number (0); 13219 w->last_overlay_modified = make_number (0); 13220 13221 /* Redisplay the mode line. Select the buffer properly for that. */ 13222 if (!update_mode_line) 13223 { 13224 update_mode_line = 1; 13225 w->update_mode_line = Qt; 13226 } 13227 13228 /* Try to scroll by specified few lines. */ 13229 if ((scroll_conservatively 13230 || scroll_step 13231 || temp_scroll_step 13232 || NUMBERP (current_buffer->scroll_up_aggressively) 13233 || NUMBERP (current_buffer->scroll_down_aggressively)) 13234 && !current_buffer->clip_changed 13235 && CHARPOS (startp) >= BEGV 13236 && CHARPOS (startp) <= ZV) 13237 { 13238 /* The function returns -1 if new fonts were loaded, 1 if 13239 successful, 0 if not successful. */ 13240 int rc = try_scrolling (window, just_this_one_p, 13241 scroll_conservatively, 13242 scroll_step, 13243 temp_scroll_step, last_line_misfit); 13244 switch (rc) 13245 { 13246 case SCROLLING_SUCCESS: 13247 goto done; 13248 13249 case SCROLLING_NEED_LARGER_MATRICES: 13250 goto need_larger_matrices; 13251 13252 case SCROLLING_FAILED: 13253 break; 13254 13255 default: 13256 abort (); 13257 } 13258 } 13259 13260 /* Finally, just choose place to start which centers point */ 13261 13262 recenter: 13263 if (centering_position < 0) 13264 centering_position = window_box_height (w) / 2; 13265 13266#if GLYPH_DEBUG 13267 debug_method_add (w, "recenter"); 13268#endif 13269 13270 /* w->vscroll = 0; */ 13271 13272 /* Forget any previously recorded base line for line number display. */ 13273 if (!buffer_unchanged_p) 13274 w->base_line_number = Qnil; 13275 13276 /* Move backward half the height of the window. */ 13277 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); 13278 it.current_y = it.last_visible_y; 13279 move_it_vertically_backward (&it, centering_position); 13280 xassert (IT_CHARPOS (it) >= BEGV); 13281 13282 /* The function move_it_vertically_backward may move over more 13283 than the specified y-distance. If it->w is small, e.g. a 13284 mini-buffer window, we may end up in front of the window's 13285 display area. Start displaying at the start of the line 13286 containing PT in this case. */ 13287 if (it.current_y <= 0) 13288 { 13289 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); 13290 move_it_vertically_backward (&it, 0); 13291#if 0 13292 /* I think this assert is bogus if buffer contains 13293 invisible text or images. KFS. */ 13294 xassert (IT_CHARPOS (it) <= PT); 13295#endif 13296 it.current_y = 0; 13297 } 13298 13299 it.current_x = it.hpos = 0; 13300 13301 /* Set startp here explicitly in case that helps avoid an infinite loop 13302 in case the window-scroll-functions functions get errors. */ 13303 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it)); 13304 13305 /* Run scroll hooks. */ 13306 startp = run_window_scroll_functions (window, it.current.pos); 13307 13308 /* Redisplay the window. */ 13309 if (!current_matrix_up_to_date_p 13310 || windows_or_buffers_changed 13311 || cursor_type_changed 13312 /* Don't use try_window_reusing_current_matrix in this case 13313 because it can have changed the buffer. */ 13314 || !NILP (Vwindow_scroll_functions) 13315 || !just_this_one_p 13316 || MINI_WINDOW_P (w) 13317 || !(used_current_matrix_p 13318 = try_window_reusing_current_matrix (w))) 13319 try_window (window, startp, 0); 13320 13321 /* If new fonts have been loaded (due to fontsets), give up. We 13322 have to start a new redisplay since we need to re-adjust glyph 13323 matrices. */ 13324 if (fonts_changed_p) 13325 goto need_larger_matrices; 13326 13327 /* If cursor did not appear assume that the middle of the window is 13328 in the first line of the window. Do it again with the next line. 13329 (Imagine a window of height 100, displaying two lines of height 13330 60. Moving back 50 from it->last_visible_y will end in the first 13331 line.) */ 13332 if (w->cursor.vpos < 0) 13333 { 13334 if (!NILP (w->window_end_valid) 13335 && PT >= Z - XFASTINT (w->window_end_pos)) 13336 { 13337 clear_glyph_matrix (w->desired_matrix); 13338 move_it_by_lines (&it, 1, 0); 13339 try_window (window, it.current.pos, 0); 13340 } 13341 else if (PT < IT_CHARPOS (it)) 13342 { 13343 clear_glyph_matrix (w->desired_matrix); 13344 move_it_by_lines (&it, -1, 0); 13345 try_window (window, it.current.pos, 0); 13346 } 13347 else 13348 { 13349 /* Not much we can do about it. */ 13350 } 13351 } 13352 13353 /* Consider the following case: Window starts at BEGV, there is 13354 invisible, intangible text at BEGV, so that display starts at 13355 some point START > BEGV. It can happen that we are called with 13356 PT somewhere between BEGV and START. Try to handle that case. */ 13357 if (w->cursor.vpos < 0) 13358 { 13359 struct glyph_row *row = w->current_matrix->rows; 13360 if (row->mode_line_p) 13361 ++row; 13362 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 13363 } 13364 13365 if (!cursor_row_fully_visible_p (w, 0, 0)) 13366 { 13367 /* If vscroll is enabled, disable it and try again. */ 13368 if (w->vscroll) 13369 { 13370 w->vscroll = 0; 13371 clear_glyph_matrix (w->desired_matrix); 13372 goto recenter; 13373 } 13374 13375 /* If centering point failed to make the whole line visible, 13376 put point at the top instead. That has to make the whole line 13377 visible, if it can be done. */ 13378 if (centering_position == 0) 13379 goto done; 13380 13381 clear_glyph_matrix (w->desired_matrix); 13382 centering_position = 0; 13383 goto recenter; 13384 } 13385 13386 done: 13387 13388 SET_TEXT_POS_FROM_MARKER (startp, w->start); 13389 w->start_at_line_beg = ((CHARPOS (startp) == BEGV 13390 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n') 13391 ? Qt : Qnil); 13392 13393 /* Display the mode line, if we must. */ 13394 if ((update_mode_line 13395 /* If window not full width, must redo its mode line 13396 if (a) the window to its side is being redone and 13397 (b) we do a frame-based redisplay. This is a consequence 13398 of how inverted lines are drawn in frame-based redisplay. */ 13399 || (!just_this_one_p 13400 && !FRAME_WINDOW_P (f) 13401 && !WINDOW_FULL_WIDTH_P (w)) 13402 /* Line number to display. */ 13403 || INTEGERP (w->base_line_pos) 13404 /* Column number is displayed and different from the one displayed. */ 13405 || (!NILP (w->column_number_displayed) 13406 && (XFASTINT (w->column_number_displayed) 13407 != (int) current_column ()))) /* iftc */ 13408 /* This means that the window has a mode line. */ 13409 && (WINDOW_WANTS_MODELINE_P (w) 13410 || WINDOW_WANTS_HEADER_LINE_P (w))) 13411 { 13412 display_mode_lines (w); 13413 13414 /* If mode line height has changed, arrange for a thorough 13415 immediate redisplay using the correct mode line height. */ 13416 if (WINDOW_WANTS_MODELINE_P (w) 13417 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w)) 13418 { 13419 fonts_changed_p = 1; 13420 MATRIX_MODE_LINE_ROW (w->current_matrix)->height 13421 = DESIRED_MODE_LINE_HEIGHT (w); 13422 } 13423 13424 /* If top line height has changed, arrange for a thorough 13425 immediate redisplay using the correct mode line height. */ 13426 if (WINDOW_WANTS_HEADER_LINE_P (w) 13427 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w)) 13428 { 13429 fonts_changed_p = 1; 13430 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height 13431 = DESIRED_HEADER_LINE_HEIGHT (w); 13432 } 13433 13434 if (fonts_changed_p) 13435 goto need_larger_matrices; 13436 } 13437 13438 if (!line_number_displayed 13439 && !BUFFERP (w->base_line_pos)) 13440 { 13441 w->base_line_pos = Qnil; 13442 w->base_line_number = Qnil; 13443 } 13444 13445 finish_menu_bars: 13446 13447 /* When we reach a frame's selected window, redo the frame's menu bar. */ 13448 if (update_mode_line 13449 && EQ (FRAME_SELECTED_WINDOW (f), window)) 13450 { 13451 int redisplay_menu_p = 0; 13452 int redisplay_tool_bar_p = 0; 13453 13454 if (FRAME_WINDOW_P (f)) 13455 { 13456#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \ 13457 || defined (USE_GTK) 13458 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f); 13459#else 13460 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0; 13461#endif 13462 } 13463 else 13464 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0; 13465 13466 if (redisplay_menu_p) 13467 display_menu_bar (w); 13468 13469#ifdef HAVE_WINDOW_SYSTEM 13470#ifdef USE_GTK 13471 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f); 13472#else 13473 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window) 13474 && (FRAME_TOOL_BAR_LINES (f) > 0 13475 || !NILP (Vauto_resize_tool_bars)); 13476 13477#endif 13478 13479 if (redisplay_tool_bar_p && redisplay_tool_bar (f)) 13480 { 13481 extern int ignore_mouse_drag_p; 13482 ignore_mouse_drag_p = 1; 13483 } 13484#endif 13485 } 13486 13487#ifdef HAVE_WINDOW_SYSTEM 13488 if (FRAME_WINDOW_P (f) 13489 && update_window_fringes (w, (just_this_one_p 13490 || (!used_current_matrix_p && !overlay_arrow_seen) 13491 || w->pseudo_window_p))) 13492 { 13493 update_begin (f); 13494 BLOCK_INPUT; 13495 if (draw_window_fringes (w, 1)) 13496 x_draw_vertical_border (w); 13497 UNBLOCK_INPUT; 13498 update_end (f); 13499 } 13500#endif /* HAVE_WINDOW_SYSTEM */ 13501 13502 /* We go to this label, with fonts_changed_p nonzero, 13503 if it is necessary to try again using larger glyph matrices. 13504 We have to redeem the scroll bar even in this case, 13505 because the loop in redisplay_internal expects that. */ 13506 need_larger_matrices: 13507 ; 13508 finish_scroll_bars: 13509 13510 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) 13511 { 13512 /* Set the thumb's position and size. */ 13513 set_vertical_scroll_bar (w); 13514 13515 /* Note that we actually used the scroll bar attached to this 13516 window, so it shouldn't be deleted at the end of redisplay. */ 13517 redeem_scroll_bar_hook (w); 13518 } 13519 13520 /* Restore current_buffer and value of point in it. */ 13521 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint)); 13522 set_buffer_internal_1 (old); 13523 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become 13524 shorter. This can be caused by log truncation in *Messages*. */ 13525 if (CHARPOS (lpoint) <= ZV) 13526 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); 13527 13528 unbind_to (count, Qnil); 13529} 13530 13531 13532/* Build the complete desired matrix of WINDOW with a window start 13533 buffer position POS. 13534 13535 Value is 1 if successful. It is zero if fonts were loaded during 13536 redisplay which makes re-adjusting glyph matrices necessary, and -1 13537 if point would appear in the scroll margins. 13538 (We check that only if CHECK_MARGINS is nonzero. */ 13539 13540int 13541try_window (window, pos, check_margins) 13542 Lisp_Object window; 13543 struct text_pos pos; 13544 int check_margins; 13545{ 13546 struct window *w = XWINDOW (window); 13547 struct it it; 13548 struct glyph_row *last_text_row = NULL; 13549 struct frame *f = XFRAME (w->frame); 13550 13551 /* Make POS the new window start. */ 13552 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos)); 13553 13554 /* Mark cursor position as unknown. No overlay arrow seen. */ 13555 w->cursor.vpos = -1; 13556 overlay_arrow_seen = 0; 13557 13558 /* Initialize iterator and info to start at POS. */ 13559 start_display (&it, w, pos); 13560 13561 /* Display all lines of W. */ 13562 while (it.current_y < it.last_visible_y) 13563 { 13564 if (display_line (&it)) 13565 last_text_row = it.glyph_row - 1; 13566 if (fonts_changed_p) 13567 return 0; 13568 } 13569 13570 /* Don't let the cursor end in the scroll margins. */ 13571 if (check_margins 13572 && !MINI_WINDOW_P (w)) 13573 { 13574 int this_scroll_margin; 13575 13576 this_scroll_margin = max (0, scroll_margin); 13577 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); 13578 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 13579 13580 if ((w->cursor.y >= 0 /* not vscrolled */ 13581 && w->cursor.y < this_scroll_margin 13582 && CHARPOS (pos) > BEGV 13583 && IT_CHARPOS (it) < ZV) 13584 /* rms: considering make_cursor_line_fully_visible_p here 13585 seems to give wrong results. We don't want to recenter 13586 when the last line is partly visible, we want to allow 13587 that case to be handled in the usual way. */ 13588 || (w->cursor.y + 1) > it.last_visible_y) 13589 { 13590 w->cursor.vpos = -1; 13591 clear_glyph_matrix (w->desired_matrix); 13592 return -1; 13593 } 13594 } 13595 13596 /* If bottom moved off end of frame, change mode line percentage. */ 13597 if (XFASTINT (w->window_end_pos) <= 0 13598 && Z != IT_CHARPOS (it)) 13599 w->update_mode_line = Qt; 13600 13601 /* Set window_end_pos to the offset of the last character displayed 13602 on the window from the end of current_buffer. Set 13603 window_end_vpos to its row number. */ 13604 if (last_text_row) 13605 { 13606 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row)); 13607 w->window_end_bytepos 13608 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); 13609 w->window_end_pos 13610 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); 13611 w->window_end_vpos 13612 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)); 13613 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos)) 13614 ->displays_text_p); 13615 } 13616 else 13617 { 13618 w->window_end_bytepos = Z_BYTE - ZV_BYTE; 13619 w->window_end_pos = make_number (Z - ZV); 13620 w->window_end_vpos = make_number (0); 13621 } 13622 13623 /* But that is not valid info until redisplay finishes. */ 13624 w->window_end_valid = Qnil; 13625 return 1; 13626} 13627 13628 13629 13630/************************************************************************ 13631 Window redisplay reusing current matrix when buffer has not changed 13632 ************************************************************************/ 13633 13634/* Try redisplay of window W showing an unchanged buffer with a 13635 different window start than the last time it was displayed by 13636 reusing its current matrix. Value is non-zero if successful. 13637 W->start is the new window start. */ 13638 13639static int 13640try_window_reusing_current_matrix (w) 13641 struct window *w; 13642{ 13643 struct frame *f = XFRAME (w->frame); 13644 struct glyph_row *row, *bottom_row; 13645 struct it it; 13646 struct run run; 13647 struct text_pos start, new_start; 13648 int nrows_scrolled, i; 13649 struct glyph_row *last_text_row; 13650 struct glyph_row *last_reused_text_row; 13651 struct glyph_row *start_row; 13652 int start_vpos, min_y, max_y; 13653 13654#if GLYPH_DEBUG 13655 if (inhibit_try_window_reusing) 13656 return 0; 13657#endif 13658 13659 if (/* This function doesn't handle terminal frames. */ 13660 !FRAME_WINDOW_P (f) 13661 /* Don't try to reuse the display if windows have been split 13662 or such. */ 13663 || windows_or_buffers_changed 13664 || cursor_type_changed) 13665 return 0; 13666 13667 /* Can't do this if region may have changed. */ 13668 if ((!NILP (Vtransient_mark_mode) 13669 && !NILP (current_buffer->mark_active)) 13670 || !NILP (w->region_showing) 13671 || !NILP (Vshow_trailing_whitespace)) 13672 return 0; 13673 13674 /* If top-line visibility has changed, give up. */ 13675 if (WINDOW_WANTS_HEADER_LINE_P (w) 13676 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p) 13677 return 0; 13678 13679 /* Give up if old or new display is scrolled vertically. We could 13680 make this function handle this, but right now it doesn't. */ 13681 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 13682 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)) 13683 return 0; 13684 13685 /* The variable new_start now holds the new window start. The old 13686 start `start' can be determined from the current matrix. */ 13687 SET_TEXT_POS_FROM_MARKER (new_start, w->start); 13688 start = start_row->start.pos; 13689 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); 13690 13691 /* Clear the desired matrix for the display below. */ 13692 clear_glyph_matrix (w->desired_matrix); 13693 13694 if (CHARPOS (new_start) <= CHARPOS (start)) 13695 { 13696 int first_row_y; 13697 13698 /* Don't use this method if the display starts with an ellipsis 13699 displayed for invisible text. It's not easy to handle that case 13700 below, and it's certainly not worth the effort since this is 13701 not a frequent case. */ 13702 if (in_ellipses_for_invisible_text_p (&start_row->start, w)) 13703 return 0; 13704 13705 IF_DEBUG (debug_method_add (w, "twu1")); 13706 13707 /* Display up to a row that can be reused. The variable 13708 last_text_row is set to the last row displayed that displays 13709 text. Note that it.vpos == 0 if or if not there is a 13710 header-line; it's not the same as the MATRIX_ROW_VPOS! */ 13711 start_display (&it, w, new_start); 13712 first_row_y = it.current_y; 13713 w->cursor.vpos = -1; 13714 last_text_row = last_reused_text_row = NULL; 13715 13716 while (it.current_y < it.last_visible_y 13717 && !fonts_changed_p) 13718 { 13719 /* If we have reached into the characters in the START row, 13720 that means the line boundaries have changed. So we 13721 can't start copying with the row START. Maybe it will 13722 work to start copying with the following row. */ 13723 while (IT_CHARPOS (it) > CHARPOS (start)) 13724 { 13725 /* Advance to the next row as the "start". */ 13726 start_row++; 13727 start = start_row->start.pos; 13728 /* If there are no more rows to try, or just one, give up. */ 13729 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 13730 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row) 13731 || CHARPOS (start) == ZV) 13732 { 13733 clear_glyph_matrix (w->desired_matrix); 13734 return 0; 13735 } 13736 13737 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); 13738 } 13739 /* If we have reached alignment, 13740 we can copy the rest of the rows. */ 13741 if (IT_CHARPOS (it) == CHARPOS (start)) 13742 break; 13743 13744 if (display_line (&it)) 13745 last_text_row = it.glyph_row - 1; 13746 } 13747 13748 /* A value of current_y < last_visible_y means that we stopped 13749 at the previous window start, which in turn means that we 13750 have at least one reusable row. */ 13751 if (it.current_y < it.last_visible_y) 13752 { 13753 /* IT.vpos always starts from 0; it counts text lines. */ 13754 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix)); 13755 13756 /* Find PT if not already found in the lines displayed. */ 13757 if (w->cursor.vpos < 0) 13758 { 13759 int dy = it.current_y - start_row->y; 13760 13761 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 13762 row = row_containing_pos (w, PT, row, NULL, dy); 13763 if (row) 13764 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 13765 dy, nrows_scrolled); 13766 else 13767 { 13768 clear_glyph_matrix (w->desired_matrix); 13769 return 0; 13770 } 13771 } 13772 13773 /* Scroll the display. Do it before the current matrix is 13774 changed. The problem here is that update has not yet 13775 run, i.e. part of the current matrix is not up to date. 13776 scroll_run_hook will clear the cursor, and use the 13777 current matrix to get the height of the row the cursor is 13778 in. */ 13779 run.current_y = start_row->y; 13780 run.desired_y = it.current_y; 13781 run.height = it.last_visible_y - it.current_y; 13782 13783 if (run.height > 0 && run.current_y != run.desired_y) 13784 { 13785 update_begin (f); 13786 rif->update_window_begin_hook (w); 13787 rif->clear_window_mouse_face (w); 13788 rif->scroll_run_hook (w, &run); 13789 rif->update_window_end_hook (w, 0, 0); 13790 update_end (f); 13791 } 13792 13793 /* Shift current matrix down by nrows_scrolled lines. */ 13794 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); 13795 rotate_matrix (w->current_matrix, 13796 start_vpos, 13797 MATRIX_ROW_VPOS (bottom_row, w->current_matrix), 13798 nrows_scrolled); 13799 13800 /* Disable lines that must be updated. */ 13801 for (i = 0; i < nrows_scrolled; ++i) 13802 (start_row + i)->enabled_p = 0; 13803 13804 /* Re-compute Y positions. */ 13805 min_y = WINDOW_HEADER_LINE_HEIGHT (w); 13806 max_y = it.last_visible_y; 13807 for (row = start_row + nrows_scrolled; 13808 row < bottom_row; 13809 ++row) 13810 { 13811 row->y = it.current_y; 13812 row->visible_height = row->height; 13813 13814 if (row->y < min_y) 13815 row->visible_height -= min_y - row->y; 13816 if (row->y + row->height > max_y) 13817 row->visible_height -= row->y + row->height - max_y; 13818 row->redraw_fringe_bitmaps_p = 1; 13819 13820 it.current_y += row->height; 13821 13822 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) 13823 last_reused_text_row = row; 13824 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y) 13825 break; 13826 } 13827 13828 /* Disable lines in the current matrix which are now 13829 below the window. */ 13830 for (++row; row < bottom_row; ++row) 13831 row->enabled_p = row->mode_line_p = 0; 13832 } 13833 13834 /* Update window_end_pos etc.; last_reused_text_row is the last 13835 reused row from the current matrix containing text, if any. 13836 The value of last_text_row is the last displayed line 13837 containing text. */ 13838 if (last_reused_text_row) 13839 { 13840 w->window_end_bytepos 13841 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row); 13842 w->window_end_pos 13843 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row)); 13844 w->window_end_vpos 13845 = make_number (MATRIX_ROW_VPOS (last_reused_text_row, 13846 w->current_matrix)); 13847 } 13848 else if (last_text_row) 13849 { 13850 w->window_end_bytepos 13851 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); 13852 w->window_end_pos 13853 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); 13854 w->window_end_vpos 13855 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)); 13856 } 13857 else 13858 { 13859 /* This window must be completely empty. */ 13860 w->window_end_bytepos = Z_BYTE - ZV_BYTE; 13861 w->window_end_pos = make_number (Z - ZV); 13862 w->window_end_vpos = make_number (0); 13863 } 13864 w->window_end_valid = Qnil; 13865 13866 /* Update hint: don't try scrolling again in update_window. */ 13867 w->desired_matrix->no_scrolling_p = 1; 13868 13869#if GLYPH_DEBUG 13870 debug_method_add (w, "try_window_reusing_current_matrix 1"); 13871#endif 13872 return 1; 13873 } 13874 else if (CHARPOS (new_start) > CHARPOS (start)) 13875 { 13876 struct glyph_row *pt_row, *row; 13877 struct glyph_row *first_reusable_row; 13878 struct glyph_row *first_row_to_display; 13879 int dy; 13880 int yb = window_text_bottom_y (w); 13881 13882 /* Find the row starting at new_start, if there is one. Don't 13883 reuse a partially visible line at the end. */ 13884 first_reusable_row = start_row; 13885 while (first_reusable_row->enabled_p 13886 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb 13887 && (MATRIX_ROW_START_CHARPOS (first_reusable_row) 13888 < CHARPOS (new_start))) 13889 ++first_reusable_row; 13890 13891 /* Give up if there is no row to reuse. */ 13892 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb 13893 || !first_reusable_row->enabled_p 13894 || (MATRIX_ROW_START_CHARPOS (first_reusable_row) 13895 != CHARPOS (new_start))) 13896 return 0; 13897 13898 /* We can reuse fully visible rows beginning with 13899 first_reusable_row to the end of the window. Set 13900 first_row_to_display to the first row that cannot be reused. 13901 Set pt_row to the row containing point, if there is any. */ 13902 pt_row = NULL; 13903 for (first_row_to_display = first_reusable_row; 13904 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb; 13905 ++first_row_to_display) 13906 { 13907 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display) 13908 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)) 13909 pt_row = first_row_to_display; 13910 } 13911 13912 /* Start displaying at the start of first_row_to_display. */ 13913 xassert (first_row_to_display->y < yb); 13914 init_to_row_start (&it, w, first_row_to_display); 13915 13916 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix) 13917 - start_vpos); 13918 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix) 13919 - nrows_scrolled); 13920 it.current_y = (first_row_to_display->y - first_reusable_row->y 13921 + WINDOW_HEADER_LINE_HEIGHT (w)); 13922 13923 /* Display lines beginning with first_row_to_display in the 13924 desired matrix. Set last_text_row to the last row displayed 13925 that displays text. */ 13926 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos); 13927 if (pt_row == NULL) 13928 w->cursor.vpos = -1; 13929 last_text_row = NULL; 13930 while (it.current_y < it.last_visible_y && !fonts_changed_p) 13931 if (display_line (&it)) 13932 last_text_row = it.glyph_row - 1; 13933 13934 /* Give up If point isn't in a row displayed or reused. */ 13935 if (w->cursor.vpos < 0) 13936 { 13937 clear_glyph_matrix (w->desired_matrix); 13938 return 0; 13939 } 13940 13941 /* If point is in a reused row, adjust y and vpos of the cursor 13942 position. */ 13943 if (pt_row) 13944 { 13945 w->cursor.vpos -= nrows_scrolled; 13946 w->cursor.y -= first_reusable_row->y - start_row->y; 13947 } 13948 13949 /* Scroll the display. */ 13950 run.current_y = first_reusable_row->y; 13951 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w); 13952 run.height = it.last_visible_y - run.current_y; 13953 dy = run.current_y - run.desired_y; 13954 13955 if (run.height) 13956 { 13957 update_begin (f); 13958 rif->update_window_begin_hook (w); 13959 rif->clear_window_mouse_face (w); 13960 rif->scroll_run_hook (w, &run); 13961 rif->update_window_end_hook (w, 0, 0); 13962 update_end (f); 13963 } 13964 13965 /* Adjust Y positions of reused rows. */ 13966 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); 13967 min_y = WINDOW_HEADER_LINE_HEIGHT (w); 13968 max_y = it.last_visible_y; 13969 for (row = first_reusable_row; row < first_row_to_display; ++row) 13970 { 13971 row->y -= dy; 13972 row->visible_height = row->height; 13973 if (row->y < min_y) 13974 row->visible_height -= min_y - row->y; 13975 if (row->y + row->height > max_y) 13976 row->visible_height -= row->y + row->height - max_y; 13977 row->redraw_fringe_bitmaps_p = 1; 13978 } 13979 13980 /* Scroll the current matrix. */ 13981 xassert (nrows_scrolled > 0); 13982 rotate_matrix (w->current_matrix, 13983 start_vpos, 13984 MATRIX_ROW_VPOS (bottom_row, w->current_matrix), 13985 -nrows_scrolled); 13986 13987 /* Disable rows not reused. */ 13988 for (row -= nrows_scrolled; row < bottom_row; ++row) 13989 row->enabled_p = 0; 13990 13991 /* Point may have moved to a different line, so we cannot assume that 13992 the previous cursor position is valid; locate the correct row. */ 13993 if (pt_row) 13994 { 13995 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos); 13996 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row); 13997 row++) 13998 { 13999 w->cursor.vpos++; 14000 w->cursor.y = row->y; 14001 } 14002 if (row < bottom_row) 14003 { 14004 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; 14005 while (glyph->charpos < PT) 14006 { 14007 w->cursor.hpos++; 14008 w->cursor.x += glyph->pixel_width; 14009 glyph++; 14010 } 14011 } 14012 } 14013 14014 /* Adjust window end. A null value of last_text_row means that 14015 the window end is in reused rows which in turn means that 14016 only its vpos can have changed. */ 14017 if (last_text_row) 14018 { 14019 w->window_end_bytepos 14020 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); 14021 w->window_end_pos 14022 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); 14023 w->window_end_vpos 14024 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)); 14025 } 14026 else 14027 { 14028 w->window_end_vpos 14029 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled); 14030 } 14031 14032 w->window_end_valid = Qnil; 14033 w->desired_matrix->no_scrolling_p = 1; 14034 14035#if GLYPH_DEBUG 14036 debug_method_add (w, "try_window_reusing_current_matrix 2"); 14037#endif 14038 return 1; 14039 } 14040 14041 return 0; 14042} 14043 14044 14045 14046/************************************************************************ 14047 Window redisplay reusing current matrix when buffer has changed 14048 ************************************************************************/ 14049 14050static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *)); 14051static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *, 14052 int *, int *)); 14053static struct glyph_row * 14054find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *, 14055 struct glyph_row *)); 14056 14057 14058/* Return the last row in MATRIX displaying text. If row START is 14059 non-null, start searching with that row. IT gives the dimensions 14060 of the display. Value is null if matrix is empty; otherwise it is 14061 a pointer to the row found. */ 14062 14063static struct glyph_row * 14064find_last_row_displaying_text (matrix, it, start) 14065 struct glyph_matrix *matrix; 14066 struct it *it; 14067 struct glyph_row *start; 14068{ 14069 struct glyph_row *row, *row_found; 14070 14071 /* Set row_found to the last row in IT->w's current matrix 14072 displaying text. The loop looks funny but think of partially 14073 visible lines. */ 14074 row_found = NULL; 14075 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix); 14076 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)) 14077 { 14078 xassert (row->enabled_p); 14079 row_found = row; 14080 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y) 14081 break; 14082 ++row; 14083 } 14084 14085 return row_found; 14086} 14087 14088 14089/* Return the last row in the current matrix of W that is not affected 14090 by changes at the start of current_buffer that occurred since W's 14091 current matrix was built. Value is null if no such row exists. 14092 14093 BEG_UNCHANGED us the number of characters unchanged at the start of 14094 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the 14095 first changed character in current_buffer. Characters at positions < 14096 BEG + BEG_UNCHANGED are at the same buffer positions as they were 14097 when the current matrix was built. */ 14098 14099static struct glyph_row * 14100find_last_unchanged_at_beg_row (w) 14101 struct window *w; 14102{ 14103 int first_changed_pos = BEG + BEG_UNCHANGED; 14104 struct glyph_row *row; 14105 struct glyph_row *row_found = NULL; 14106 int yb = window_text_bottom_y (w); 14107 14108 /* Find the last row displaying unchanged text. */ 14109 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 14110 while (MATRIX_ROW_DISPLAYS_TEXT_P (row) 14111 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos) 14112 { 14113 if (/* If row ends before first_changed_pos, it is unchanged, 14114 except in some case. */ 14115 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos 14116 /* When row ends in ZV and we write at ZV it is not 14117 unchanged. */ 14118 && !row->ends_at_zv_p 14119 /* When first_changed_pos is the end of a continued line, 14120 row is not unchanged because it may be no longer 14121 continued. */ 14122 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos 14123 && (row->continued_p 14124 || row->exact_window_width_line_p))) 14125 row_found = row; 14126 14127 /* Stop if last visible row. */ 14128 if (MATRIX_ROW_BOTTOM_Y (row) >= yb) 14129 break; 14130 14131 ++row; 14132 } 14133 14134 return row_found; 14135} 14136 14137 14138/* Find the first glyph row in the current matrix of W that is not 14139 affected by changes at the end of current_buffer since the 14140 time W's current matrix was built. 14141 14142 Return in *DELTA the number of chars by which buffer positions in 14143 unchanged text at the end of current_buffer must be adjusted. 14144 14145 Return in *DELTA_BYTES the corresponding number of bytes. 14146 14147 Value is null if no such row exists, i.e. all rows are affected by 14148 changes. */ 14149 14150static struct glyph_row * 14151find_first_unchanged_at_end_row (w, delta, delta_bytes) 14152 struct window *w; 14153 int *delta, *delta_bytes; 14154{ 14155 struct glyph_row *row; 14156 struct glyph_row *row_found = NULL; 14157 14158 *delta = *delta_bytes = 0; 14159 14160 /* Display must not have been paused, otherwise the current matrix 14161 is not up to date. */ 14162 if (NILP (w->window_end_valid)) 14163 abort (); 14164 14165 /* A value of window_end_pos >= END_UNCHANGED means that the window 14166 end is in the range of changed text. If so, there is no 14167 unchanged row at the end of W's current matrix. */ 14168 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED) 14169 return NULL; 14170 14171 /* Set row to the last row in W's current matrix displaying text. */ 14172 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 14173 14174 /* If matrix is entirely empty, no unchanged row exists. */ 14175 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) 14176 { 14177 /* The value of row is the last glyph row in the matrix having a 14178 meaningful buffer position in it. The end position of row 14179 corresponds to window_end_pos. This allows us to translate 14180 buffer positions in the current matrix to current buffer 14181 positions for characters not in changed text. */ 14182 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); 14183 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; 14184 int last_unchanged_pos, last_unchanged_pos_old; 14185 struct glyph_row *first_text_row 14186 = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 14187 14188 *delta = Z - Z_old; 14189 *delta_bytes = Z_BYTE - Z_BYTE_old; 14190 14191 /* Set last_unchanged_pos to the buffer position of the last 14192 character in the buffer that has not been changed. Z is the 14193 index + 1 of the last character in current_buffer, i.e. by 14194 subtracting END_UNCHANGED we get the index of the last 14195 unchanged character, and we have to add BEG to get its buffer 14196 position. */ 14197 last_unchanged_pos = Z - END_UNCHANGED + BEG; 14198 last_unchanged_pos_old = last_unchanged_pos - *delta; 14199 14200 /* Search backward from ROW for a row displaying a line that 14201 starts at a minimum position >= last_unchanged_pos_old. */ 14202 for (; row > first_text_row; --row) 14203 { 14204 /* This used to abort, but it can happen. 14205 It is ok to just stop the search instead here. KFS. */ 14206 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row)) 14207 break; 14208 14209 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old) 14210 row_found = row; 14211 } 14212 } 14213 14214 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found)) 14215 abort (); 14216 14217 return row_found; 14218} 14219 14220 14221/* Make sure that glyph rows in the current matrix of window W 14222 reference the same glyph memory as corresponding rows in the 14223 frame's frame matrix. This function is called after scrolling W's 14224 current matrix on a terminal frame in try_window_id and 14225 try_window_reusing_current_matrix. */ 14226 14227static void 14228sync_frame_with_window_matrix_rows (w) 14229 struct window *w; 14230{ 14231 struct frame *f = XFRAME (w->frame); 14232 struct glyph_row *window_row, *window_row_end, *frame_row; 14233 14234 /* Preconditions: W must be a leaf window and full-width. Its frame 14235 must have a frame matrix. */ 14236 xassert (NILP (w->hchild) && NILP (w->vchild)); 14237 xassert (WINDOW_FULL_WIDTH_P (w)); 14238 xassert (!FRAME_WINDOW_P (f)); 14239 14240 /* If W is a full-width window, glyph pointers in W's current matrix 14241 have, by definition, to be the same as glyph pointers in the 14242 corresponding frame matrix. Note that frame matrices have no 14243 marginal areas (see build_frame_matrix). */ 14244 window_row = w->current_matrix->rows; 14245 window_row_end = window_row + w->current_matrix->nrows; 14246 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w); 14247 while (window_row < window_row_end) 14248 { 14249 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA]; 14250 struct glyph *end = window_row->glyphs[LAST_AREA]; 14251 14252 frame_row->glyphs[LEFT_MARGIN_AREA] = start; 14253 frame_row->glyphs[TEXT_AREA] = start; 14254 frame_row->glyphs[RIGHT_MARGIN_AREA] = end; 14255 frame_row->glyphs[LAST_AREA] = end; 14256 14257 /* Disable frame rows whose corresponding window rows have 14258 been disabled in try_window_id. */ 14259 if (!window_row->enabled_p) 14260 frame_row->enabled_p = 0; 14261 14262 ++window_row, ++frame_row; 14263 } 14264} 14265 14266 14267/* Find the glyph row in window W containing CHARPOS. Consider all 14268 rows between START and END (not inclusive). END null means search 14269 all rows to the end of the display area of W. Value is the row 14270 containing CHARPOS or null. */ 14271 14272struct glyph_row * 14273row_containing_pos (w, charpos, start, end, dy) 14274 struct window *w; 14275 int charpos; 14276 struct glyph_row *start, *end; 14277 int dy; 14278{ 14279 struct glyph_row *row = start; 14280 int last_y; 14281 14282 /* If we happen to start on a header-line, skip that. */ 14283 if (row->mode_line_p) 14284 ++row; 14285 14286 if ((end && row >= end) || !row->enabled_p) 14287 return NULL; 14288 14289 last_y = window_text_bottom_y (w) - dy; 14290 14291 while (1) 14292 { 14293 /* Give up if we have gone too far. */ 14294 if (end && row >= end) 14295 return NULL; 14296 /* This formerly returned if they were equal. 14297 I think that both quantities are of a "last plus one" type; 14298 if so, when they are equal, the row is within the screen. -- rms. */ 14299 if (MATRIX_ROW_BOTTOM_Y (row) > last_y) 14300 return NULL; 14301 14302 /* If it is in this row, return this row. */ 14303 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos 14304 || (MATRIX_ROW_END_CHARPOS (row) == charpos 14305 /* The end position of a row equals the start 14306 position of the next row. If CHARPOS is there, we 14307 would rather display it in the next line, except 14308 when this line ends in ZV. */ 14309 && !row->ends_at_zv_p 14310 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))) 14311 && charpos >= MATRIX_ROW_START_CHARPOS (row)) 14312 return row; 14313 ++row; 14314 } 14315} 14316 14317 14318/* Try to redisplay window W by reusing its existing display. W's 14319 current matrix must be up to date when this function is called, 14320 i.e. window_end_valid must not be nil. 14321 14322 Value is 14323 14324 1 if display has been updated 14325 0 if otherwise unsuccessful 14326 -1 if redisplay with same window start is known not to succeed 14327 14328 The following steps are performed: 14329 14330 1. Find the last row in the current matrix of W that is not 14331 affected by changes at the start of current_buffer. If no such row 14332 is found, give up. 14333 14334 2. Find the first row in W's current matrix that is not affected by 14335 changes at the end of current_buffer. Maybe there is no such row. 14336 14337 3. Display lines beginning with the row + 1 found in step 1 to the 14338 row found in step 2 or, if step 2 didn't find a row, to the end of 14339 the window. 14340 14341 4. If cursor is not known to appear on the window, give up. 14342 14343 5. If display stopped at the row found in step 2, scroll the 14344 display and current matrix as needed. 14345 14346 6. Maybe display some lines at the end of W, if we must. This can 14347 happen under various circumstances, like a partially visible line 14348 becoming fully visible, or because newly displayed lines are displayed 14349 in smaller font sizes. 14350 14351 7. Update W's window end information. */ 14352 14353static int 14354try_window_id (w) 14355 struct window *w; 14356{ 14357 struct frame *f = XFRAME (w->frame); 14358 struct glyph_matrix *current_matrix = w->current_matrix; 14359 struct glyph_matrix *desired_matrix = w->desired_matrix; 14360 struct glyph_row *last_unchanged_at_beg_row; 14361 struct glyph_row *first_unchanged_at_end_row; 14362 struct glyph_row *row; 14363 struct glyph_row *bottom_row; 14364 int bottom_vpos; 14365 struct it it; 14366 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy; 14367 struct text_pos start_pos; 14368 struct run run; 14369 int first_unchanged_at_end_vpos = 0; 14370 struct glyph_row *last_text_row, *last_text_row_at_end; 14371 struct text_pos start; 14372 int first_changed_charpos, last_changed_charpos; 14373 14374#if GLYPH_DEBUG 14375 if (inhibit_try_window_id) 14376 return 0; 14377#endif 14378 14379 /* This is handy for debugging. */ 14380#if 0 14381#define GIVE_UP(X) \ 14382 do { \ 14383 fprintf (stderr, "try_window_id give up %d\n", (X)); \ 14384 return 0; \ 14385 } while (0) 14386#else 14387#define GIVE_UP(X) return 0 14388#endif 14389 14390 SET_TEXT_POS_FROM_MARKER (start, w->start); 14391 14392 /* Don't use this for mini-windows because these can show 14393 messages and mini-buffers, and we don't handle that here. */ 14394 if (MINI_WINDOW_P (w)) 14395 GIVE_UP (1); 14396 14397 /* This flag is used to prevent redisplay optimizations. */ 14398 if (windows_or_buffers_changed || cursor_type_changed) 14399 GIVE_UP (2); 14400 14401 /* Verify that narrowing has not changed. 14402 Also verify that we were not told to prevent redisplay optimizations. 14403 It would be nice to further 14404 reduce the number of cases where this prevents try_window_id. */ 14405 if (current_buffer->clip_changed 14406 || current_buffer->prevent_redisplay_optimizations_p) 14407 GIVE_UP (3); 14408 14409 /* Window must either use window-based redisplay or be full width. */ 14410 if (!FRAME_WINDOW_P (f) 14411 && (!line_ins_del_ok 14412 || !WINDOW_FULL_WIDTH_P (w))) 14413 GIVE_UP (4); 14414 14415 /* Give up if point is not known NOT to appear in W. */ 14416 if (PT < CHARPOS (start)) 14417 GIVE_UP (5); 14418 14419 /* Another way to prevent redisplay optimizations. */ 14420 if (XFASTINT (w->last_modified) == 0) 14421 GIVE_UP (6); 14422 14423 /* Verify that window is not hscrolled. */ 14424 if (XFASTINT (w->hscroll) != 0) 14425 GIVE_UP (7); 14426 14427 /* Verify that display wasn't paused. */ 14428 if (NILP (w->window_end_valid)) 14429 GIVE_UP (8); 14430 14431 /* Can't use this if highlighting a region because a cursor movement 14432 will do more than just set the cursor. */ 14433 if (!NILP (Vtransient_mark_mode) 14434 && !NILP (current_buffer->mark_active)) 14435 GIVE_UP (9); 14436 14437 /* Likewise if highlighting trailing whitespace. */ 14438 if (!NILP (Vshow_trailing_whitespace)) 14439 GIVE_UP (11); 14440 14441 /* Likewise if showing a region. */ 14442 if (!NILP (w->region_showing)) 14443 GIVE_UP (10); 14444 14445 /* Can use this if overlay arrow position and or string have changed. */ 14446 if (overlay_arrows_changed_p ()) 14447 GIVE_UP (12); 14448 14449 14450 /* Make sure beg_unchanged and end_unchanged are up to date. Do it 14451 only if buffer has really changed. The reason is that the gap is 14452 initially at Z for freshly visited files. The code below would 14453 set end_unchanged to 0 in that case. */ 14454 if (MODIFF > SAVE_MODIFF 14455 /* This seems to happen sometimes after saving a buffer. */ 14456 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE) 14457 { 14458 if (GPT - BEG < BEG_UNCHANGED) 14459 BEG_UNCHANGED = GPT - BEG; 14460 if (Z - GPT < END_UNCHANGED) 14461 END_UNCHANGED = Z - GPT; 14462 } 14463 14464 /* The position of the first and last character that has been changed. */ 14465 first_changed_charpos = BEG + BEG_UNCHANGED; 14466 last_changed_charpos = Z - END_UNCHANGED; 14467 14468 /* If window starts after a line end, and the last change is in 14469 front of that newline, then changes don't affect the display. 14470 This case happens with stealth-fontification. Note that although 14471 the display is unchanged, glyph positions in the matrix have to 14472 be adjusted, of course. */ 14473 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 14474 if (MATRIX_ROW_DISPLAYS_TEXT_P (row) 14475 && ((last_changed_charpos < CHARPOS (start) 14476 && CHARPOS (start) == BEGV) 14477 || (last_changed_charpos < CHARPOS (start) - 1 14478 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'))) 14479 { 14480 int Z_old, delta, Z_BYTE_old, delta_bytes; 14481 struct glyph_row *r0; 14482 14483 /* Compute how many chars/bytes have been added to or removed 14484 from the buffer. */ 14485 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); 14486 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; 14487 delta = Z - Z_old; 14488 delta_bytes = Z_BYTE - Z_BYTE_old; 14489 14490 /* Give up if PT is not in the window. Note that it already has 14491 been checked at the start of try_window_id that PT is not in 14492 front of the window start. */ 14493 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta) 14494 GIVE_UP (13); 14495 14496 /* If window start is unchanged, we can reuse the whole matrix 14497 as is, after adjusting glyph positions. No need to compute 14498 the window end again, since its offset from Z hasn't changed. */ 14499 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); 14500 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta 14501 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes 14502 /* PT must not be in a partially visible line. */ 14503 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta 14504 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) 14505 { 14506 /* Adjust positions in the glyph matrix. */ 14507 if (delta || delta_bytes) 14508 { 14509 struct glyph_row *r1 14510 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w); 14511 increment_matrix_positions (w->current_matrix, 14512 MATRIX_ROW_VPOS (r0, current_matrix), 14513 MATRIX_ROW_VPOS (r1, current_matrix), 14514 delta, delta_bytes); 14515 } 14516 14517 /* Set the cursor. */ 14518 row = row_containing_pos (w, PT, r0, NULL, 0); 14519 if (row) 14520 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0); 14521 else 14522 abort (); 14523 return 1; 14524 } 14525 } 14526 14527 /* Handle the case that changes are all below what is displayed in 14528 the window, and that PT is in the window. This shortcut cannot 14529 be taken if ZV is visible in the window, and text has been added 14530 there that is visible in the window. */ 14531 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row) 14532 /* ZV is not visible in the window, or there are no 14533 changes at ZV, actually. */ 14534 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row) 14535 || first_changed_charpos == last_changed_charpos)) 14536 { 14537 struct glyph_row *r0; 14538 14539 /* Give up if PT is not in the window. Note that it already has 14540 been checked at the start of try_window_id that PT is not in 14541 front of the window start. */ 14542 if (PT >= MATRIX_ROW_END_CHARPOS (row)) 14543 GIVE_UP (14); 14544 14545 /* If window start is unchanged, we can reuse the whole matrix 14546 as is, without changing glyph positions since no text has 14547 been added/removed in front of the window end. */ 14548 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); 14549 if (TEXT_POS_EQUAL_P (start, r0->start.pos) 14550 /* PT must not be in a partially visible line. */ 14551 && !(PT >= MATRIX_ROW_START_CHARPOS (row) 14552 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) 14553 { 14554 /* We have to compute the window end anew since text 14555 can have been added/removed after it. */ 14556 w->window_end_pos 14557 = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); 14558 w->window_end_bytepos 14559 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); 14560 14561 /* Set the cursor. */ 14562 row = row_containing_pos (w, PT, r0, NULL, 0); 14563 if (row) 14564 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0); 14565 else 14566 abort (); 14567 return 2; 14568 } 14569 } 14570 14571 /* Give up if window start is in the changed area. 14572 14573 The condition used to read 14574 14575 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...) 14576 14577 but why that was tested escapes me at the moment. */ 14578 if (CHARPOS (start) >= first_changed_charpos 14579 && CHARPOS (start) <= last_changed_charpos) 14580 GIVE_UP (15); 14581 14582 /* Check that window start agrees with the start of the first glyph 14583 row in its current matrix. Check this after we know the window 14584 start is not in changed text, otherwise positions would not be 14585 comparable. */ 14586 row = MATRIX_FIRST_TEXT_ROW (current_matrix); 14587 if (!TEXT_POS_EQUAL_P (start, row->start.pos)) 14588 GIVE_UP (16); 14589 14590 /* Give up if the window ends in strings. Overlay strings 14591 at the end are difficult to handle, so don't try. */ 14592 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos)); 14593 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row)) 14594 GIVE_UP (20); 14595 14596 /* Compute the position at which we have to start displaying new 14597 lines. Some of the lines at the top of the window might be 14598 reusable because they are not displaying changed text. Find the 14599 last row in W's current matrix not affected by changes at the 14600 start of current_buffer. Value is null if changes start in the 14601 first line of window. */ 14602 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w); 14603 if (last_unchanged_at_beg_row) 14604 { 14605 /* Avoid starting to display in the moddle of a character, a TAB 14606 for instance. This is easier than to set up the iterator 14607 exactly, and it's not a frequent case, so the additional 14608 effort wouldn't really pay off. */ 14609 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row) 14610 || last_unchanged_at_beg_row->ends_in_newline_from_string_p) 14611 && last_unchanged_at_beg_row > w->current_matrix->rows) 14612 --last_unchanged_at_beg_row; 14613 14614 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)) 14615 GIVE_UP (17); 14616 14617 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0) 14618 GIVE_UP (18); 14619 start_pos = it.current.pos; 14620 14621 /* Start displaying new lines in the desired matrix at the same 14622 vpos we would use in the current matrix, i.e. below 14623 last_unchanged_at_beg_row. */ 14624 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row, 14625 current_matrix); 14626 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos); 14627 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row); 14628 14629 xassert (it.hpos == 0 && it.current_x == 0); 14630 } 14631 else 14632 { 14633 /* There are no reusable lines at the start of the window. 14634 Start displaying in the first text line. */ 14635 start_display (&it, w, start); 14636 it.vpos = it.first_vpos; 14637 start_pos = it.current.pos; 14638 } 14639 14640 /* Find the first row that is not affected by changes at the end of 14641 the buffer. Value will be null if there is no unchanged row, in 14642 which case we must redisplay to the end of the window. delta 14643 will be set to the value by which buffer positions beginning with 14644 first_unchanged_at_end_row have to be adjusted due to text 14645 changes. */ 14646 first_unchanged_at_end_row 14647 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes); 14648 IF_DEBUG (debug_delta = delta); 14649 IF_DEBUG (debug_delta_bytes = delta_bytes); 14650 14651 /* Set stop_pos to the buffer position up to which we will have to 14652 display new lines. If first_unchanged_at_end_row != NULL, this 14653 is the buffer position of the start of the line displayed in that 14654 row. For first_unchanged_at_end_row == NULL, use 0 to indicate 14655 that we don't stop at a buffer position. */ 14656 stop_pos = 0; 14657 if (first_unchanged_at_end_row) 14658 { 14659 xassert (last_unchanged_at_beg_row == NULL 14660 || first_unchanged_at_end_row >= last_unchanged_at_beg_row); 14661 14662 /* If this is a continuation line, move forward to the next one 14663 that isn't. Changes in lines above affect this line. 14664 Caution: this may move first_unchanged_at_end_row to a row 14665 not displaying text. */ 14666 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row) 14667 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row) 14668 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row) 14669 < it.last_visible_y)) 14670 ++first_unchanged_at_end_row; 14671 14672 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row) 14673 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row) 14674 >= it.last_visible_y)) 14675 first_unchanged_at_end_row = NULL; 14676 else 14677 { 14678 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row) 14679 + delta); 14680 first_unchanged_at_end_vpos 14681 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix); 14682 xassert (stop_pos >= Z - END_UNCHANGED); 14683 } 14684 } 14685 else if (last_unchanged_at_beg_row == NULL) 14686 GIVE_UP (19); 14687 14688 14689#if GLYPH_DEBUG 14690 14691 /* Either there is no unchanged row at the end, or the one we have 14692 now displays text. This is a necessary condition for the window 14693 end pos calculation at the end of this function. */ 14694 xassert (first_unchanged_at_end_row == NULL 14695 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)); 14696 14697 debug_last_unchanged_at_beg_vpos 14698 = (last_unchanged_at_beg_row 14699 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix) 14700 : -1); 14701 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos; 14702 14703#endif /* GLYPH_DEBUG != 0 */ 14704 14705 14706 /* Display new lines. Set last_text_row to the last new line 14707 displayed which has text on it, i.e. might end up as being the 14708 line where the window_end_vpos is. */ 14709 w->cursor.vpos = -1; 14710 last_text_row = NULL; 14711 overlay_arrow_seen = 0; 14712 while (it.current_y < it.last_visible_y 14713 && !fonts_changed_p 14714 && (first_unchanged_at_end_row == NULL 14715 || IT_CHARPOS (it) < stop_pos)) 14716 { 14717 if (display_line (&it)) 14718 last_text_row = it.glyph_row - 1; 14719 } 14720 14721 if (fonts_changed_p) 14722 return -1; 14723 14724 14725 /* Compute differences in buffer positions, y-positions etc. for 14726 lines reused at the bottom of the window. Compute what we can 14727 scroll. */ 14728 if (first_unchanged_at_end_row 14729 /* No lines reused because we displayed everything up to the 14730 bottom of the window. */ 14731 && it.current_y < it.last_visible_y) 14732 { 14733 dvpos = (it.vpos 14734 - MATRIX_ROW_VPOS (first_unchanged_at_end_row, 14735 current_matrix)); 14736 dy = it.current_y - first_unchanged_at_end_row->y; 14737 run.current_y = first_unchanged_at_end_row->y; 14738 run.desired_y = run.current_y + dy; 14739 run.height = it.last_visible_y - max (run.current_y, run.desired_y); 14740 } 14741 else 14742 { 14743 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0; 14744 first_unchanged_at_end_row = NULL; 14745 } 14746 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy); 14747 14748 14749 /* Find the cursor if not already found. We have to decide whether 14750 PT will appear on this window (it sometimes doesn't, but this is 14751 not a very frequent case.) This decision has to be made before 14752 the current matrix is altered. A value of cursor.vpos < 0 means 14753 that PT is either in one of the lines beginning at 14754 first_unchanged_at_end_row or below the window. Don't care for 14755 lines that might be displayed later at the window end; as 14756 mentioned, this is not a frequent case. */ 14757 if (w->cursor.vpos < 0) 14758 { 14759 /* Cursor in unchanged rows at the top? */ 14760 if (PT < CHARPOS (start_pos) 14761 && last_unchanged_at_beg_row) 14762 { 14763 row = row_containing_pos (w, PT, 14764 MATRIX_FIRST_TEXT_ROW (w->current_matrix), 14765 last_unchanged_at_beg_row + 1, 0); 14766 if (row) 14767 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 14768 } 14769 14770 /* Start from first_unchanged_at_end_row looking for PT. */ 14771 else if (first_unchanged_at_end_row) 14772 { 14773 row = row_containing_pos (w, PT - delta, 14774 first_unchanged_at_end_row, NULL, 0); 14775 if (row) 14776 set_cursor_from_row (w, row, w->current_matrix, delta, 14777 delta_bytes, dy, dvpos); 14778 } 14779 14780 /* Give up if cursor was not found. */ 14781 if (w->cursor.vpos < 0) 14782 { 14783 clear_glyph_matrix (w->desired_matrix); 14784 return -1; 14785 } 14786 } 14787 14788 /* Don't let the cursor end in the scroll margins. */ 14789 { 14790 int this_scroll_margin, cursor_height; 14791 14792 this_scroll_margin = max (0, scroll_margin); 14793 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); 14794 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 14795 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height; 14796 14797 if ((w->cursor.y < this_scroll_margin 14798 && CHARPOS (start) > BEGV) 14799 /* Old redisplay didn't take scroll margin into account at the bottom, 14800 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */ 14801 || (w->cursor.y + (make_cursor_line_fully_visible_p 14802 ? cursor_height + this_scroll_margin 14803 : 1)) > it.last_visible_y) 14804 { 14805 w->cursor.vpos = -1; 14806 clear_glyph_matrix (w->desired_matrix); 14807 return -1; 14808 } 14809 } 14810 14811 /* Scroll the display. Do it before changing the current matrix so 14812 that xterm.c doesn't get confused about where the cursor glyph is 14813 found. */ 14814 if (dy && run.height) 14815 { 14816 update_begin (f); 14817 14818 if (FRAME_WINDOW_P (f)) 14819 { 14820 rif->update_window_begin_hook (w); 14821 rif->clear_window_mouse_face (w); 14822 rif->scroll_run_hook (w, &run); 14823 rif->update_window_end_hook (w, 0, 0); 14824 } 14825 else 14826 { 14827 /* Terminal frame. In this case, dvpos gives the number of 14828 lines to scroll by; dvpos < 0 means scroll up. */ 14829 int first_unchanged_at_end_vpos 14830 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix); 14831 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos; 14832 int end = (WINDOW_TOP_EDGE_LINE (w) 14833 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) 14834 + window_internal_height (w)); 14835 14836 /* Perform the operation on the screen. */ 14837 if (dvpos > 0) 14838 { 14839 /* Scroll last_unchanged_at_beg_row to the end of the 14840 window down dvpos lines. */ 14841 set_terminal_window (end); 14842 14843 /* On dumb terminals delete dvpos lines at the end 14844 before inserting dvpos empty lines. */ 14845 if (!scroll_region_ok) 14846 ins_del_lines (end - dvpos, -dvpos); 14847 14848 /* Insert dvpos empty lines in front of 14849 last_unchanged_at_beg_row. */ 14850 ins_del_lines (from, dvpos); 14851 } 14852 else if (dvpos < 0) 14853 { 14854 /* Scroll up last_unchanged_at_beg_vpos to the end of 14855 the window to last_unchanged_at_beg_vpos - |dvpos|. */ 14856 set_terminal_window (end); 14857 14858 /* Delete dvpos lines in front of 14859 last_unchanged_at_beg_vpos. ins_del_lines will set 14860 the cursor to the given vpos and emit |dvpos| delete 14861 line sequences. */ 14862 ins_del_lines (from + dvpos, dvpos); 14863 14864 /* On a dumb terminal insert dvpos empty lines at the 14865 end. */ 14866 if (!scroll_region_ok) 14867 ins_del_lines (end + dvpos, -dvpos); 14868 } 14869 14870 set_terminal_window (0); 14871 } 14872 14873 update_end (f); 14874 } 14875 14876 /* Shift reused rows of the current matrix to the right position. 14877 BOTTOM_ROW is the last + 1 row in the current matrix reserved for 14878 text. */ 14879 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w); 14880 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix); 14881 if (dvpos < 0) 14882 { 14883 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos, 14884 bottom_vpos, dvpos); 14885 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos, 14886 bottom_vpos, 0); 14887 } 14888 else if (dvpos > 0) 14889 { 14890 rotate_matrix (current_matrix, first_unchanged_at_end_vpos, 14891 bottom_vpos, dvpos); 14892 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos, 14893 first_unchanged_at_end_vpos + dvpos, 0); 14894 } 14895 14896 /* For frame-based redisplay, make sure that current frame and window 14897 matrix are in sync with respect to glyph memory. */ 14898 if (!FRAME_WINDOW_P (f)) 14899 sync_frame_with_window_matrix_rows (w); 14900 14901 /* Adjust buffer positions in reused rows. */ 14902 if (delta || delta_bytes) 14903 increment_matrix_positions (current_matrix, 14904 first_unchanged_at_end_vpos + dvpos, 14905 bottom_vpos, delta, delta_bytes); 14906 14907 /* Adjust Y positions. */ 14908 if (dy) 14909 shift_glyph_matrix (w, current_matrix, 14910 first_unchanged_at_end_vpos + dvpos, 14911 bottom_vpos, dy); 14912 14913 if (first_unchanged_at_end_row) 14914 { 14915 first_unchanged_at_end_row += dvpos; 14916 if (first_unchanged_at_end_row->y >= it.last_visible_y 14917 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)) 14918 first_unchanged_at_end_row = NULL; 14919 } 14920 14921 /* If scrolling up, there may be some lines to display at the end of 14922 the window. */ 14923 last_text_row_at_end = NULL; 14924 if (dy < 0) 14925 { 14926 /* Scrolling up can leave for example a partially visible line 14927 at the end of the window to be redisplayed. */ 14928 /* Set last_row to the glyph row in the current matrix where the 14929 window end line is found. It has been moved up or down in 14930 the matrix by dvpos. */ 14931 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos; 14932 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos); 14933 14934 /* If last_row is the window end line, it should display text. */ 14935 xassert (last_row->displays_text_p); 14936 14937 /* If window end line was partially visible before, begin 14938 displaying at that line. Otherwise begin displaying with the 14939 line following it. */ 14940 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y) 14941 { 14942 init_to_row_start (&it, w, last_row); 14943 it.vpos = last_vpos; 14944 it.current_y = last_row->y; 14945 } 14946 else 14947 { 14948 init_to_row_end (&it, w, last_row); 14949 it.vpos = 1 + last_vpos; 14950 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row); 14951 ++last_row; 14952 } 14953 14954 /* We may start in a continuation line. If so, we have to 14955 get the right continuation_lines_width and current_x. */ 14956 it.continuation_lines_width = last_row->continuation_lines_width; 14957 it.hpos = it.current_x = 0; 14958 14959 /* Display the rest of the lines at the window end. */ 14960 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos); 14961 while (it.current_y < it.last_visible_y 14962 && !fonts_changed_p) 14963 { 14964 /* Is it always sure that the display agrees with lines in 14965 the current matrix? I don't think so, so we mark rows 14966 displayed invalid in the current matrix by setting their 14967 enabled_p flag to zero. */ 14968 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0; 14969 if (display_line (&it)) 14970 last_text_row_at_end = it.glyph_row - 1; 14971 } 14972 } 14973 14974 /* Update window_end_pos and window_end_vpos. */ 14975 if (first_unchanged_at_end_row 14976 && !last_text_row_at_end) 14977 { 14978 /* Window end line if one of the preserved rows from the current 14979 matrix. Set row to the last row displaying text in current 14980 matrix starting at first_unchanged_at_end_row, after 14981 scrolling. */ 14982 xassert (first_unchanged_at_end_row->displays_text_p); 14983 row = find_last_row_displaying_text (w->current_matrix, &it, 14984 first_unchanged_at_end_row); 14985 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); 14986 14987 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); 14988 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); 14989 w->window_end_vpos 14990 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix)); 14991 xassert (w->window_end_bytepos >= 0); 14992 IF_DEBUG (debug_method_add (w, "A")); 14993 } 14994 else if (last_text_row_at_end) 14995 { 14996 w->window_end_pos 14997 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)); 14998 w->window_end_bytepos 14999 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end); 15000 w->window_end_vpos 15001 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix)); 15002 xassert (w->window_end_bytepos >= 0); 15003 IF_DEBUG (debug_method_add (w, "B")); 15004 } 15005 else if (last_text_row) 15006 { 15007 /* We have displayed either to the end of the window or at the 15008 end of the window, i.e. the last row with text is to be found 15009 in the desired matrix. */ 15010 w->window_end_pos 15011 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)); 15012 w->window_end_bytepos 15013 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row); 15014 w->window_end_vpos 15015 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)); 15016 xassert (w->window_end_bytepos >= 0); 15017 } 15018 else if (first_unchanged_at_end_row == NULL 15019 && last_text_row == NULL 15020 && last_text_row_at_end == NULL) 15021 { 15022 /* Displayed to end of window, but no line containing text was 15023 displayed. Lines were deleted at the end of the window. */ 15024 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; 15025 int vpos = XFASTINT (w->window_end_vpos); 15026 struct glyph_row *current_row = current_matrix->rows + vpos; 15027 struct glyph_row *desired_row = desired_matrix->rows + vpos; 15028 15029 for (row = NULL; 15030 row == NULL && vpos >= first_vpos; 15031 --vpos, --current_row, --desired_row) 15032 { 15033 if (desired_row->enabled_p) 15034 { 15035 if (desired_row->displays_text_p) 15036 row = desired_row; 15037 } 15038 else if (current_row->displays_text_p) 15039 row = current_row; 15040 } 15041 15042 xassert (row != NULL); 15043 w->window_end_vpos = make_number (vpos + 1); 15044 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); 15045 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); 15046 xassert (w->window_end_bytepos >= 0); 15047 IF_DEBUG (debug_method_add (w, "C")); 15048 } 15049 else 15050 abort (); 15051 15052#if 0 /* This leads to problems, for instance when the cursor is 15053 at ZV, and the cursor line displays no text. */ 15054 /* Disable rows below what's displayed in the window. This makes 15055 debugging easier. */ 15056 enable_glyph_matrix_rows (current_matrix, 15057 XFASTINT (w->window_end_vpos) + 1, 15058 bottom_vpos, 0); 15059#endif 15060 15061 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos); 15062 debug_end_vpos = XFASTINT (w->window_end_vpos)); 15063 15064 /* Record that display has not been completed. */ 15065 w->window_end_valid = Qnil; 15066 w->desired_matrix->no_scrolling_p = 1; 15067 return 3; 15068 15069#undef GIVE_UP 15070} 15071 15072 15073 15074/*********************************************************************** 15075 More debugging support 15076 ***********************************************************************/ 15077 15078#if GLYPH_DEBUG 15079 15080void dump_glyph_row P_ ((struct glyph_row *, int, int)); 15081void dump_glyph_matrix P_ ((struct glyph_matrix *, int)); 15082void dump_glyph P_ ((struct glyph_row *, struct glyph *, int)); 15083 15084 15085/* Dump the contents of glyph matrix MATRIX on stderr. 15086 15087 GLYPHS 0 means don't show glyph contents. 15088 GLYPHS 1 means show glyphs in short form 15089 GLYPHS > 1 means show glyphs in long form. */ 15090 15091void 15092dump_glyph_matrix (matrix, glyphs) 15093 struct glyph_matrix *matrix; 15094 int glyphs; 15095{ 15096 int i; 15097 for (i = 0; i < matrix->nrows; ++i) 15098 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs); 15099} 15100 15101 15102/* Dump contents of glyph GLYPH to stderr. ROW and AREA are 15103 the glyph row and area where the glyph comes from. */ 15104 15105void 15106dump_glyph (row, glyph, area) 15107 struct glyph_row *row; 15108 struct glyph *glyph; 15109 int area; 15110{ 15111 if (glyph->type == CHAR_GLYPH) 15112 { 15113 fprintf (stderr, 15114 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", 15115 glyph - row->glyphs[TEXT_AREA], 15116 'C', 15117 glyph->charpos, 15118 (BUFFERP (glyph->object) 15119 ? 'B' 15120 : (STRINGP (glyph->object) 15121 ? 'S' 15122 : '-')), 15123 glyph->pixel_width, 15124 glyph->u.ch, 15125 (glyph->u.ch < 0x80 && glyph->u.ch >= ' ' 15126 ? glyph->u.ch 15127 : '.'), 15128 glyph->face_id, 15129 glyph->left_box_line_p, 15130 glyph->right_box_line_p); 15131 } 15132 else if (glyph->type == STRETCH_GLYPH) 15133 { 15134 fprintf (stderr, 15135 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", 15136 glyph - row->glyphs[TEXT_AREA], 15137 'S', 15138 glyph->charpos, 15139 (BUFFERP (glyph->object) 15140 ? 'B' 15141 : (STRINGP (glyph->object) 15142 ? 'S' 15143 : '-')), 15144 glyph->pixel_width, 15145 0, 15146 '.', 15147 glyph->face_id, 15148 glyph->left_box_line_p, 15149 glyph->right_box_line_p); 15150 } 15151 else if (glyph->type == IMAGE_GLYPH) 15152 { 15153 fprintf (stderr, 15154 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", 15155 glyph - row->glyphs[TEXT_AREA], 15156 'I', 15157 glyph->charpos, 15158 (BUFFERP (glyph->object) 15159 ? 'B' 15160 : (STRINGP (glyph->object) 15161 ? 'S' 15162 : '-')), 15163 glyph->pixel_width, 15164 glyph->u.img_id, 15165 '.', 15166 glyph->face_id, 15167 glyph->left_box_line_p, 15168 glyph->right_box_line_p); 15169 } 15170 else if (glyph->type == COMPOSITE_GLYPH) 15171 { 15172 fprintf (stderr, 15173 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", 15174 glyph - row->glyphs[TEXT_AREA], 15175 '+', 15176 glyph->charpos, 15177 (BUFFERP (glyph->object) 15178 ? 'B' 15179 : (STRINGP (glyph->object) 15180 ? 'S' 15181 : '-')), 15182 glyph->pixel_width, 15183 glyph->u.cmp_id, 15184 '.', 15185 glyph->face_id, 15186 glyph->left_box_line_p, 15187 glyph->right_box_line_p); 15188 } 15189} 15190 15191 15192/* Dump the contents of glyph row at VPOS in MATRIX to stderr. 15193 GLYPHS 0 means don't show glyph contents. 15194 GLYPHS 1 means show glyphs in short form 15195 GLYPHS > 1 means show glyphs in long form. */ 15196 15197void 15198dump_glyph_row (row, vpos, glyphs) 15199 struct glyph_row *row; 15200 int vpos, glyphs; 15201{ 15202 if (glyphs != 1) 15203 { 15204 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n"); 15205 fprintf (stderr, "======================================================================\n"); 15206 15207 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\ 15208%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n", 15209 vpos, 15210 MATRIX_ROW_START_CHARPOS (row), 15211 MATRIX_ROW_END_CHARPOS (row), 15212 row->used[TEXT_AREA], 15213 row->contains_overlapping_glyphs_p, 15214 row->enabled_p, 15215 row->truncated_on_left_p, 15216 row->truncated_on_right_p, 15217 row->continued_p, 15218 MATRIX_ROW_CONTINUATION_LINE_P (row), 15219 row->displays_text_p, 15220 row->ends_at_zv_p, 15221 row->fill_line_p, 15222 row->ends_in_middle_of_char_p, 15223 row->starts_in_middle_of_char_p, 15224 row->mouse_face_p, 15225 row->x, 15226 row->y, 15227 row->pixel_width, 15228 row->height, 15229 row->visible_height, 15230 row->ascent, 15231 row->phys_ascent); 15232 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index, 15233 row->end.overlay_string_index, 15234 row->continuation_lines_width); 15235 fprintf (stderr, "%9d %5d\n", 15236 CHARPOS (row->start.string_pos), 15237 CHARPOS (row->end.string_pos)); 15238 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index, 15239 row->end.dpvec_index); 15240 } 15241 15242 if (glyphs > 1) 15243 { 15244 int area; 15245 15246 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) 15247 { 15248 struct glyph *glyph = row->glyphs[area]; 15249 struct glyph *glyph_end = glyph + row->used[area]; 15250 15251 /* Glyph for a line end in text. */ 15252 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0) 15253 ++glyph_end; 15254 15255 if (glyph < glyph_end) 15256 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n"); 15257 15258 for (; glyph < glyph_end; ++glyph) 15259 dump_glyph (row, glyph, area); 15260 } 15261 } 15262 else if (glyphs == 1) 15263 { 15264 int area; 15265 15266 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) 15267 { 15268 char *s = (char *) alloca (row->used[area] + 1); 15269 int i; 15270 15271 for (i = 0; i < row->used[area]; ++i) 15272 { 15273 struct glyph *glyph = row->glyphs[area] + i; 15274 if (glyph->type == CHAR_GLYPH 15275 && glyph->u.ch < 0x80 15276 && glyph->u.ch >= ' ') 15277 s[i] = glyph->u.ch; 15278 else 15279 s[i] = '.'; 15280 } 15281 15282 s[i] = '\0'; 15283 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s); 15284 } 15285 } 15286} 15287 15288 15289DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix, 15290 Sdump_glyph_matrix, 0, 1, "p", 15291 doc: /* Dump the current matrix of the selected window to stderr. 15292Shows contents of glyph row structures. With non-nil 15293parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show 15294glyphs in short form, otherwise show glyphs in long form. */) 15295 (glyphs) 15296 Lisp_Object glyphs; 15297{ 15298 struct window *w = XWINDOW (selected_window); 15299 struct buffer *buffer = XBUFFER (w->buffer); 15300 15301 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n", 15302 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer)); 15303 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n", 15304 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos); 15305 fprintf (stderr, "=============================================\n"); 15306 dump_glyph_matrix (w->current_matrix, 15307 NILP (glyphs) ? 0 : XINT (glyphs)); 15308 return Qnil; 15309} 15310 15311 15312DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix, 15313 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */) 15314 () 15315{ 15316 struct frame *f = XFRAME (selected_frame); 15317 dump_glyph_matrix (f->current_matrix, 1); 15318 return Qnil; 15319} 15320 15321 15322DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "", 15323 doc: /* Dump glyph row ROW to stderr. 15324GLYPH 0 means don't dump glyphs. 15325GLYPH 1 means dump glyphs in short form. 15326GLYPH > 1 or omitted means dump glyphs in long form. */) 15327 (row, glyphs) 15328 Lisp_Object row, glyphs; 15329{ 15330 struct glyph_matrix *matrix; 15331 int vpos; 15332 15333 CHECK_NUMBER (row); 15334 matrix = XWINDOW (selected_window)->current_matrix; 15335 vpos = XINT (row); 15336 if (vpos >= 0 && vpos < matrix->nrows) 15337 dump_glyph_row (MATRIX_ROW (matrix, vpos), 15338 vpos, 15339 INTEGERP (glyphs) ? XINT (glyphs) : 2); 15340 return Qnil; 15341} 15342 15343 15344DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "", 15345 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr. 15346GLYPH 0 means don't dump glyphs. 15347GLYPH 1 means dump glyphs in short form. 15348GLYPH > 1 or omitted means dump glyphs in long form. */) 15349 (row, glyphs) 15350 Lisp_Object row, glyphs; 15351{ 15352 struct frame *sf = SELECTED_FRAME (); 15353 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix; 15354 int vpos; 15355 15356 CHECK_NUMBER (row); 15357 vpos = XINT (row); 15358 if (vpos >= 0 && vpos < m->nrows) 15359 dump_glyph_row (MATRIX_ROW (m, vpos), vpos, 15360 INTEGERP (glyphs) ? XINT (glyphs) : 2); 15361 return Qnil; 15362} 15363 15364 15365DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P", 15366 doc: /* Toggle tracing of redisplay. 15367With ARG, turn tracing on if and only if ARG is positive. */) 15368 (arg) 15369 Lisp_Object arg; 15370{ 15371 if (NILP (arg)) 15372 trace_redisplay_p = !trace_redisplay_p; 15373 else 15374 { 15375 arg = Fprefix_numeric_value (arg); 15376 trace_redisplay_p = XINT (arg) > 0; 15377 } 15378 15379 return Qnil; 15380} 15381 15382 15383DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "", 15384 doc: /* Like `format', but print result to stderr. 15385usage: (trace-to-stderr STRING &rest OBJECTS) */) 15386 (nargs, args) 15387 int nargs; 15388 Lisp_Object *args; 15389{ 15390 Lisp_Object s = Fformat (nargs, args); 15391 fprintf (stderr, "%s", SDATA (s)); 15392 return Qnil; 15393} 15394 15395#endif /* GLYPH_DEBUG */ 15396 15397 15398 15399/*********************************************************************** 15400 Building Desired Matrix Rows 15401 ***********************************************************************/ 15402 15403/* Return a temporary glyph row holding the glyphs of an overlay arrow. 15404 Used for non-window-redisplay windows, and for windows w/o left fringe. */ 15405 15406static struct glyph_row * 15407get_overlay_arrow_glyph_row (w, overlay_arrow_string) 15408 struct window *w; 15409 Lisp_Object overlay_arrow_string; 15410{ 15411 struct frame *f = XFRAME (WINDOW_FRAME (w)); 15412 struct buffer *buffer = XBUFFER (w->buffer); 15413 struct buffer *old = current_buffer; 15414 const unsigned char *arrow_string = SDATA (overlay_arrow_string); 15415 int arrow_len = SCHARS (overlay_arrow_string); 15416 const unsigned char *arrow_end = arrow_string + arrow_len; 15417 const unsigned char *p; 15418 struct it it; 15419 int multibyte_p; 15420 int n_glyphs_before; 15421 15422 set_buffer_temp (buffer); 15423 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID); 15424 it.glyph_row->used[TEXT_AREA] = 0; 15425 SET_TEXT_POS (it.position, 0, 0); 15426 15427 multibyte_p = !NILP (buffer->enable_multibyte_characters); 15428 p = arrow_string; 15429 while (p < arrow_end) 15430 { 15431 Lisp_Object face, ilisp; 15432 15433 /* Get the next character. */ 15434 if (multibyte_p) 15435 it.c = string_char_and_length (p, arrow_len, &it.len); 15436 else 15437 it.c = *p, it.len = 1; 15438 p += it.len; 15439 15440 /* Get its face. */ 15441 ilisp = make_number (p - arrow_string); 15442 face = Fget_text_property (ilisp, Qface, overlay_arrow_string); 15443 it.face_id = compute_char_face (f, it.c, face); 15444 15445 /* Compute its width, get its glyphs. */ 15446 n_glyphs_before = it.glyph_row->used[TEXT_AREA]; 15447 SET_TEXT_POS (it.position, -1, -1); 15448 PRODUCE_GLYPHS (&it); 15449 15450 /* If this character doesn't fit any more in the line, we have 15451 to remove some glyphs. */ 15452 if (it.current_x > it.last_visible_x) 15453 { 15454 it.glyph_row->used[TEXT_AREA] = n_glyphs_before; 15455 break; 15456 } 15457 } 15458 15459 set_buffer_temp (old); 15460 return it.glyph_row; 15461} 15462 15463 15464/* Insert truncation glyphs at the start of IT->glyph_row. Truncation 15465 glyphs are only inserted for terminal frames since we can't really 15466 win with truncation glyphs when partially visible glyphs are 15467 involved. Which glyphs to insert is determined by 15468 produce_special_glyphs. */ 15469 15470static void 15471insert_left_trunc_glyphs (it) 15472 struct it *it; 15473{ 15474 struct it truncate_it; 15475 struct glyph *from, *end, *to, *toend; 15476 15477 xassert (!FRAME_WINDOW_P (it->f)); 15478 15479 /* Get the truncation glyphs. */ 15480 truncate_it = *it; 15481 truncate_it.current_x = 0; 15482 truncate_it.face_id = DEFAULT_FACE_ID; 15483 truncate_it.glyph_row = &scratch_glyph_row; 15484 truncate_it.glyph_row->used[TEXT_AREA] = 0; 15485 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1; 15486 truncate_it.object = make_number (0); 15487 produce_special_glyphs (&truncate_it, IT_TRUNCATION); 15488 15489 /* Overwrite glyphs from IT with truncation glyphs. */ 15490 from = truncate_it.glyph_row->glyphs[TEXT_AREA]; 15491 end = from + truncate_it.glyph_row->used[TEXT_AREA]; 15492 to = it->glyph_row->glyphs[TEXT_AREA]; 15493 toend = to + it->glyph_row->used[TEXT_AREA]; 15494 15495 while (from < end) 15496 *to++ = *from++; 15497 15498 /* There may be padding glyphs left over. Overwrite them too. */ 15499 while (to < toend && CHAR_GLYPH_PADDING_P (*to)) 15500 { 15501 from = truncate_it.glyph_row->glyphs[TEXT_AREA]; 15502 while (from < end) 15503 *to++ = *from++; 15504 } 15505 15506 if (to > toend) 15507 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA]; 15508} 15509 15510 15511/* Compute the pixel height and width of IT->glyph_row. 15512 15513 Most of the time, ascent and height of a display line will be equal 15514 to the max_ascent and max_height values of the display iterator 15515 structure. This is not the case if 15516 15517 1. We hit ZV without displaying anything. In this case, max_ascent 15518 and max_height will be zero. 15519 15520 2. We have some glyphs that don't contribute to the line height. 15521 (The glyph row flag contributes_to_line_height_p is for future 15522 pixmap extensions). 15523 15524 The first case is easily covered by using default values because in 15525 these cases, the line height does not really matter, except that it 15526 must not be zero. */ 15527 15528static void 15529compute_line_metrics (it) 15530 struct it *it; 15531{ 15532 struct glyph_row *row = it->glyph_row; 15533 int area, i; 15534 15535 if (FRAME_WINDOW_P (it->f)) 15536 { 15537 int i, min_y, max_y; 15538 15539 /* The line may consist of one space only, that was added to 15540 place the cursor on it. If so, the row's height hasn't been 15541 computed yet. */ 15542 if (row->height == 0) 15543 { 15544 if (it->max_ascent + it->max_descent == 0) 15545 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f); 15546 row->ascent = it->max_ascent; 15547 row->height = it->max_ascent + it->max_descent; 15548 row->phys_ascent = it->max_phys_ascent; 15549 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 15550 row->extra_line_spacing = it->max_extra_line_spacing; 15551 } 15552 15553 /* Compute the width of this line. */ 15554 row->pixel_width = row->x; 15555 for (i = 0; i < row->used[TEXT_AREA]; ++i) 15556 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width; 15557 15558 xassert (row->pixel_width >= 0); 15559 xassert (row->ascent >= 0 && row->height > 0); 15560 15561 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row) 15562 || MATRIX_ROW_OVERLAPS_PRED_P (row)); 15563 15564 /* If first line's physical ascent is larger than its logical 15565 ascent, use the physical ascent, and make the row taller. 15566 This makes accented characters fully visible. */ 15567 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix) 15568 && row->phys_ascent > row->ascent) 15569 { 15570 row->height += row->phys_ascent - row->ascent; 15571 row->ascent = row->phys_ascent; 15572 } 15573 15574 /* Compute how much of the line is visible. */ 15575 row->visible_height = row->height; 15576 15577 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w); 15578 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w); 15579 15580 if (row->y < min_y) 15581 row->visible_height -= min_y - row->y; 15582 if (row->y + row->height > max_y) 15583 row->visible_height -= row->y + row->height - max_y; 15584 } 15585 else 15586 { 15587 row->pixel_width = row->used[TEXT_AREA]; 15588 if (row->continued_p) 15589 row->pixel_width -= it->continuation_pixel_width; 15590 else if (row->truncated_on_right_p) 15591 row->pixel_width -= it->truncation_pixel_width; 15592 row->ascent = row->phys_ascent = 0; 15593 row->height = row->phys_height = row->visible_height = 1; 15594 row->extra_line_spacing = 0; 15595 } 15596 15597 /* Compute a hash code for this row. */ 15598 row->hash = 0; 15599 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) 15600 for (i = 0; i < row->used[area]; ++i) 15601 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff) 15602 + row->glyphs[area][i].u.val 15603 + row->glyphs[area][i].face_id 15604 + row->glyphs[area][i].padding_p 15605 + (row->glyphs[area][i].type << 2)); 15606 15607 it->max_ascent = it->max_descent = 0; 15608 it->max_phys_ascent = it->max_phys_descent = 0; 15609} 15610 15611 15612/* Append one space to the glyph row of iterator IT if doing a 15613 window-based redisplay. The space has the same face as 15614 IT->face_id. Value is non-zero if a space was added. 15615 15616 This function is called to make sure that there is always one glyph 15617 at the end of a glyph row that the cursor can be set on under 15618 window-systems. (If there weren't such a glyph we would not know 15619 how wide and tall a box cursor should be displayed). 15620 15621 At the same time this space let's a nicely handle clearing to the 15622 end of the line if the row ends in italic text. */ 15623 15624static int 15625append_space_for_newline (it, default_face_p) 15626 struct it *it; 15627 int default_face_p; 15628{ 15629 if (FRAME_WINDOW_P (it->f)) 15630 { 15631 int n = it->glyph_row->used[TEXT_AREA]; 15632 15633 if (it->glyph_row->glyphs[TEXT_AREA] + n 15634 < it->glyph_row->glyphs[1 + TEXT_AREA]) 15635 { 15636 /* Save some values that must not be changed. 15637 Must save IT->c and IT->len because otherwise 15638 ITERATOR_AT_END_P wouldn't work anymore after 15639 append_space_for_newline has been called. */ 15640 enum display_element_type saved_what = it->what; 15641 int saved_c = it->c, saved_len = it->len; 15642 int saved_x = it->current_x; 15643 int saved_face_id = it->face_id; 15644 struct text_pos saved_pos; 15645 Lisp_Object saved_object; 15646 struct face *face; 15647 15648 saved_object = it->object; 15649 saved_pos = it->position; 15650 15651 it->what = IT_CHARACTER; 15652 bzero (&it->position, sizeof it->position); 15653 it->object = make_number (0); 15654 it->c = ' '; 15655 it->len = 1; 15656 15657 if (default_face_p) 15658 it->face_id = DEFAULT_FACE_ID; 15659 else if (it->face_before_selective_p) 15660 it->face_id = it->saved_face_id; 15661 face = FACE_FROM_ID (it->f, it->face_id); 15662 it->face_id = FACE_FOR_CHAR (it->f, face, 0); 15663 15664 PRODUCE_GLYPHS (it); 15665 15666 it->override_ascent = -1; 15667 it->constrain_row_ascent_descent_p = 0; 15668 it->current_x = saved_x; 15669 it->object = saved_object; 15670 it->position = saved_pos; 15671 it->what = saved_what; 15672 it->face_id = saved_face_id; 15673 it->len = saved_len; 15674 it->c = saved_c; 15675 return 1; 15676 } 15677 } 15678 15679 return 0; 15680} 15681 15682 15683/* Extend the face of the last glyph in the text area of IT->glyph_row 15684 to the end of the display line. Called from display_line. 15685 If the glyph row is empty, add a space glyph to it so that we 15686 know the face to draw. Set the glyph row flag fill_line_p. */ 15687 15688static void 15689extend_face_to_end_of_line (it) 15690 struct it *it; 15691{ 15692 struct face *face; 15693 struct frame *f = it->f; 15694 15695 /* If line is already filled, do nothing. */ 15696 if (it->current_x >= it->last_visible_x) 15697 return; 15698 15699 /* Face extension extends the background and box of IT->face_id 15700 to the end of the line. If the background equals the background 15701 of the frame, we don't have to do anything. */ 15702 if (it->face_before_selective_p) 15703 face = FACE_FROM_ID (it->f, it->saved_face_id); 15704 else 15705 face = FACE_FROM_ID (f, it->face_id); 15706 15707 if (FRAME_WINDOW_P (f) 15708 && it->glyph_row->displays_text_p 15709 && face->box == FACE_NO_BOX 15710 && face->background == FRAME_BACKGROUND_PIXEL (f) 15711 && !face->stipple) 15712 return; 15713 15714 /* Set the glyph row flag indicating that the face of the last glyph 15715 in the text area has to be drawn to the end of the text area. */ 15716 it->glyph_row->fill_line_p = 1; 15717 15718 /* If current character of IT is not ASCII, make sure we have the 15719 ASCII face. This will be automatically undone the next time 15720 get_next_display_element returns a multibyte character. Note 15721 that the character will always be single byte in unibyte text. */ 15722 if (!SINGLE_BYTE_CHAR_P (it->c)) 15723 { 15724 it->face_id = FACE_FOR_CHAR (f, face, 0); 15725 } 15726 15727 if (FRAME_WINDOW_P (f)) 15728 { 15729 /* If the row is empty, add a space with the current face of IT, 15730 so that we know which face to draw. */ 15731 if (it->glyph_row->used[TEXT_AREA] == 0) 15732 { 15733 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph; 15734 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id; 15735 it->glyph_row->used[TEXT_AREA] = 1; 15736 } 15737 } 15738 else 15739 { 15740 /* Save some values that must not be changed. */ 15741 int saved_x = it->current_x; 15742 struct text_pos saved_pos; 15743 Lisp_Object saved_object; 15744 enum display_element_type saved_what = it->what; 15745 int saved_face_id = it->face_id; 15746 15747 saved_object = it->object; 15748 saved_pos = it->position; 15749 15750 it->what = IT_CHARACTER; 15751 bzero (&it->position, sizeof it->position); 15752 it->object = make_number (0); 15753 it->c = ' '; 15754 it->len = 1; 15755 it->face_id = face->id; 15756 15757 PRODUCE_GLYPHS (it); 15758 15759 while (it->current_x <= it->last_visible_x) 15760 PRODUCE_GLYPHS (it); 15761 15762 /* Don't count these blanks really. It would let us insert a left 15763 truncation glyph below and make us set the cursor on them, maybe. */ 15764 it->current_x = saved_x; 15765 it->object = saved_object; 15766 it->position = saved_pos; 15767 it->what = saved_what; 15768 it->face_id = saved_face_id; 15769 } 15770} 15771 15772 15773/* Value is non-zero if text starting at CHARPOS in current_buffer is 15774 trailing whitespace. */ 15775 15776static int 15777trailing_whitespace_p (charpos) 15778 int charpos; 15779{ 15780 int bytepos = CHAR_TO_BYTE (charpos); 15781 int c = 0; 15782 15783 while (bytepos < ZV_BYTE 15784 && (c = FETCH_CHAR (bytepos), 15785 c == ' ' || c == '\t')) 15786 ++bytepos; 15787 15788 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r') 15789 { 15790 if (bytepos != PT_BYTE) 15791 return 1; 15792 } 15793 return 0; 15794} 15795 15796 15797/* Highlight trailing whitespace, if any, in ROW. */ 15798 15799void 15800highlight_trailing_whitespace (f, row) 15801 struct frame *f; 15802 struct glyph_row *row; 15803{ 15804 int used = row->used[TEXT_AREA]; 15805 15806 if (used) 15807 { 15808 struct glyph *start = row->glyphs[TEXT_AREA]; 15809 struct glyph *glyph = start + used - 1; 15810 15811 /* Skip over glyphs inserted to display the cursor at the 15812 end of a line, for extending the face of the last glyph 15813 to the end of the line on terminals, and for truncation 15814 and continuation glyphs. */ 15815 while (glyph >= start 15816 && glyph->type == CHAR_GLYPH 15817 && INTEGERP (glyph->object)) 15818 --glyph; 15819 15820 /* If last glyph is a space or stretch, and it's trailing 15821 whitespace, set the face of all trailing whitespace glyphs in 15822 IT->glyph_row to `trailing-whitespace'. */ 15823 if (glyph >= start 15824 && BUFFERP (glyph->object) 15825 && (glyph->type == STRETCH_GLYPH 15826 || (glyph->type == CHAR_GLYPH 15827 && glyph->u.ch == ' ')) 15828 && trailing_whitespace_p (glyph->charpos)) 15829 { 15830 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0); 15831 if (face_id < 0) 15832 return; 15833 15834 while (glyph >= start 15835 && BUFFERP (glyph->object) 15836 && (glyph->type == STRETCH_GLYPH 15837 || (glyph->type == CHAR_GLYPH 15838 && glyph->u.ch == ' '))) 15839 (glyph--)->face_id = face_id; 15840 } 15841 } 15842} 15843 15844 15845/* Value is non-zero if glyph row ROW in window W should be 15846 used to hold the cursor. */ 15847 15848static int 15849cursor_row_p (w, row) 15850 struct window *w; 15851 struct glyph_row *row; 15852{ 15853 int cursor_row_p = 1; 15854 15855 if (PT == MATRIX_ROW_END_CHARPOS (row)) 15856 { 15857 /* Suppose the row ends on a string. 15858 Unless the row is continued, that means it ends on a newline 15859 in the string. If it's anything other than a display string 15860 (e.g. a before-string from an overlay), we don't want the 15861 cursor there. (This heuristic seems to give the optimal 15862 behavior for the various types of multi-line strings.) */ 15863 if (CHARPOS (row->end.string_pos) >= 0) 15864 { 15865 if (row->continued_p) 15866 cursor_row_p = 1; 15867 else 15868 { 15869 /* Check for `display' property. */ 15870 struct glyph *beg = row->glyphs[TEXT_AREA]; 15871 struct glyph *end = beg + row->used[TEXT_AREA] - 1; 15872 struct glyph *glyph; 15873 15874 cursor_row_p = 0; 15875 for (glyph = end; glyph >= beg; --glyph) 15876 if (STRINGP (glyph->object)) 15877 { 15878 Lisp_Object prop 15879 = Fget_char_property (make_number (PT), 15880 Qdisplay, Qnil); 15881 cursor_row_p = 15882 (!NILP (prop) 15883 && display_prop_string_p (prop, glyph->object)); 15884 break; 15885 } 15886 } 15887 } 15888 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) 15889 { 15890 /* If the row ends in middle of a real character, 15891 and the line is continued, we want the cursor here. 15892 That's because MATRIX_ROW_END_CHARPOS would equal 15893 PT if PT is before the character. */ 15894 if (!row->ends_in_ellipsis_p) 15895 cursor_row_p = row->continued_p; 15896 else 15897 /* If the row ends in an ellipsis, then 15898 MATRIX_ROW_END_CHARPOS will equal point after the invisible text. 15899 We want that position to be displayed after the ellipsis. */ 15900 cursor_row_p = 0; 15901 } 15902 /* If the row ends at ZV, display the cursor at the end of that 15903 row instead of at the start of the row below. */ 15904 else if (row->ends_at_zv_p) 15905 cursor_row_p = 1; 15906 else 15907 cursor_row_p = 0; 15908 } 15909 15910 return cursor_row_p; 15911} 15912 15913 15914/* Construct the glyph row IT->glyph_row in the desired matrix of 15915 IT->w from text at the current position of IT. See dispextern.h 15916 for an overview of struct it. Value is non-zero if 15917 IT->glyph_row displays text, as opposed to a line displaying ZV 15918 only. */ 15919 15920static int 15921display_line (it) 15922 struct it *it; 15923{ 15924 struct glyph_row *row = it->glyph_row; 15925 Lisp_Object overlay_arrow_string; 15926 15927 /* We always start displaying at hpos zero even if hscrolled. */ 15928 xassert (it->hpos == 0 && it->current_x == 0); 15929 15930 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix) 15931 >= it->w->desired_matrix->nrows) 15932 { 15933 it->w->nrows_scale_factor++; 15934 fonts_changed_p = 1; 15935 return 0; 15936 } 15937 15938 /* Is IT->w showing the region? */ 15939 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil; 15940 15941 /* Clear the result glyph row and enable it. */ 15942 prepare_desired_row (row); 15943 15944 row->y = it->current_y; 15945 row->start = it->start; 15946 row->continuation_lines_width = it->continuation_lines_width; 15947 row->displays_text_p = 1; 15948 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; 15949 it->starts_in_middle_of_char_p = 0; 15950 15951 /* Arrange the overlays nicely for our purposes. Usually, we call 15952 display_line on only one line at a time, in which case this 15953 can't really hurt too much, or we call it on lines which appear 15954 one after another in the buffer, in which case all calls to 15955 recenter_overlay_lists but the first will be pretty cheap. */ 15956 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); 15957 15958 /* Move over display elements that are not visible because we are 15959 hscrolled. This may stop at an x-position < IT->first_visible_x 15960 if the first glyph is partially visible or if we hit a line end. */ 15961 if (it->current_x < it->first_visible_x) 15962 { 15963 move_it_in_display_line_to (it, ZV, it->first_visible_x, 15964 MOVE_TO_POS | MOVE_TO_X); 15965 } 15966 15967 /* Get the initial row height. This is either the height of the 15968 text hscrolled, if there is any, or zero. */ 15969 row->ascent = it->max_ascent; 15970 row->height = it->max_ascent + it->max_descent; 15971 row->phys_ascent = it->max_phys_ascent; 15972 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 15973 row->extra_line_spacing = it->max_extra_line_spacing; 15974 15975 /* Loop generating characters. The loop is left with IT on the next 15976 character to display. */ 15977 while (1) 15978 { 15979 int n_glyphs_before, hpos_before, x_before; 15980 int x, i, nglyphs; 15981 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0; 15982 15983 /* Retrieve the next thing to display. Value is zero if end of 15984 buffer reached. */ 15985 if (!get_next_display_element (it)) 15986 { 15987 /* Maybe add a space at the end of this line that is used to 15988 display the cursor there under X. Set the charpos of the 15989 first glyph of blank lines not corresponding to any text 15990 to -1. */ 15991#ifdef HAVE_WINDOW_SYSTEM 15992 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 15993 row->exact_window_width_line_p = 1; 15994 else 15995#endif /* HAVE_WINDOW_SYSTEM */ 15996 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1) 15997 || row->used[TEXT_AREA] == 0) 15998 { 15999 row->glyphs[TEXT_AREA]->charpos = -1; 16000 row->displays_text_p = 0; 16001 16002 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines) 16003 && (!MINI_WINDOW_P (it->w) 16004 || (minibuf_level && EQ (it->window, minibuf_window)))) 16005 row->indicate_empty_line_p = 1; 16006 } 16007 16008 it->continuation_lines_width = 0; 16009 row->ends_at_zv_p = 1; 16010 break; 16011 } 16012 16013 /* Now, get the metrics of what we want to display. This also 16014 generates glyphs in `row' (which is IT->glyph_row). */ 16015 n_glyphs_before = row->used[TEXT_AREA]; 16016 x = it->current_x; 16017 16018 /* Remember the line height so far in case the next element doesn't 16019 fit on the line. */ 16020 if (!it->truncate_lines_p) 16021 { 16022 ascent = it->max_ascent; 16023 descent = it->max_descent; 16024 phys_ascent = it->max_phys_ascent; 16025 phys_descent = it->max_phys_descent; 16026 } 16027 16028 PRODUCE_GLYPHS (it); 16029 16030 /* If this display element was in marginal areas, continue with 16031 the next one. */ 16032 if (it->area != TEXT_AREA) 16033 { 16034 row->ascent = max (row->ascent, it->max_ascent); 16035 row->height = max (row->height, it->max_ascent + it->max_descent); 16036 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 16037 row->phys_height = max (row->phys_height, 16038 it->max_phys_ascent + it->max_phys_descent); 16039 row->extra_line_spacing = max (row->extra_line_spacing, 16040 it->max_extra_line_spacing); 16041 set_iterator_to_next (it, 1); 16042 continue; 16043 } 16044 16045 /* Does the display element fit on the line? If we truncate 16046 lines, we should draw past the right edge of the window. If 16047 we don't truncate, we want to stop so that we can display the 16048 continuation glyph before the right margin. If lines are 16049 continued, there are two possible strategies for characters 16050 resulting in more than 1 glyph (e.g. tabs): Display as many 16051 glyphs as possible in this line and leave the rest for the 16052 continuation line, or display the whole element in the next 16053 line. Original redisplay did the former, so we do it also. */ 16054 nglyphs = row->used[TEXT_AREA] - n_glyphs_before; 16055 hpos_before = it->hpos; 16056 x_before = x; 16057 16058 if (/* Not a newline. */ 16059 nglyphs > 0 16060 /* Glyphs produced fit entirely in the line. */ 16061 && it->current_x < it->last_visible_x) 16062 { 16063 it->hpos += nglyphs; 16064 row->ascent = max (row->ascent, it->max_ascent); 16065 row->height = max (row->height, it->max_ascent + it->max_descent); 16066 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 16067 row->phys_height = max (row->phys_height, 16068 it->max_phys_ascent + it->max_phys_descent); 16069 row->extra_line_spacing = max (row->extra_line_spacing, 16070 it->max_extra_line_spacing); 16071 if (it->current_x - it->pixel_width < it->first_visible_x) 16072 row->x = x - it->first_visible_x; 16073 } 16074 else 16075 { 16076 int new_x; 16077 struct glyph *glyph; 16078 16079 for (i = 0; i < nglyphs; ++i, x = new_x) 16080 { 16081 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i; 16082 new_x = x + glyph->pixel_width; 16083 16084 if (/* Lines are continued. */ 16085 !it->truncate_lines_p 16086 && (/* Glyph doesn't fit on the line. */ 16087 new_x > it->last_visible_x 16088 /* Or it fits exactly on a window system frame. */ 16089 || (new_x == it->last_visible_x 16090 && FRAME_WINDOW_P (it->f)))) 16091 { 16092 /* End of a continued line. */ 16093 16094 if (it->hpos == 0 16095 || (new_x == it->last_visible_x 16096 && FRAME_WINDOW_P (it->f))) 16097 { 16098 /* Current glyph is the only one on the line or 16099 fits exactly on the line. We must continue 16100 the line because we can't draw the cursor 16101 after the glyph. */ 16102 row->continued_p = 1; 16103 it->current_x = new_x; 16104 it->continuation_lines_width += new_x; 16105 ++it->hpos; 16106 if (i == nglyphs - 1) 16107 { 16108 set_iterator_to_next (it, 1); 16109#ifdef HAVE_WINDOW_SYSTEM 16110 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 16111 { 16112 if (!get_next_display_element (it)) 16113 { 16114 row->exact_window_width_line_p = 1; 16115 it->continuation_lines_width = 0; 16116 row->continued_p = 0; 16117 row->ends_at_zv_p = 1; 16118 } 16119 else if (ITERATOR_AT_END_OF_LINE_P (it)) 16120 { 16121 row->continued_p = 0; 16122 row->exact_window_width_line_p = 1; 16123 } 16124 } 16125#endif /* HAVE_WINDOW_SYSTEM */ 16126 } 16127 } 16128 else if (CHAR_GLYPH_PADDING_P (*glyph) 16129 && !FRAME_WINDOW_P (it->f)) 16130 { 16131 /* A padding glyph that doesn't fit on this line. 16132 This means the whole character doesn't fit 16133 on the line. */ 16134 row->used[TEXT_AREA] = n_glyphs_before; 16135 16136 /* Fill the rest of the row with continuation 16137 glyphs like in 20.x. */ 16138 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] 16139 < row->glyphs[1 + TEXT_AREA]) 16140 produce_special_glyphs (it, IT_CONTINUATION); 16141 16142 row->continued_p = 1; 16143 it->current_x = x_before; 16144 it->continuation_lines_width += x_before; 16145 16146 /* Restore the height to what it was before the 16147 element not fitting on the line. */ 16148 it->max_ascent = ascent; 16149 it->max_descent = descent; 16150 it->max_phys_ascent = phys_ascent; 16151 it->max_phys_descent = phys_descent; 16152 } 16153 else if (it->c == '\t' && FRAME_WINDOW_P (it->f)) 16154 { 16155 /* A TAB that extends past the right edge of the 16156 window. This produces a single glyph on 16157 window system frames. We leave the glyph in 16158 this row and let it fill the row, but don't 16159 consume the TAB. */ 16160 it->continuation_lines_width += it->last_visible_x; 16161 row->ends_in_middle_of_char_p = 1; 16162 row->continued_p = 1; 16163 glyph->pixel_width = it->last_visible_x - x; 16164 it->starts_in_middle_of_char_p = 1; 16165 } 16166 else 16167 { 16168 /* Something other than a TAB that draws past 16169 the right edge of the window. Restore 16170 positions to values before the element. */ 16171 row->used[TEXT_AREA] = n_glyphs_before + i; 16172 16173 /* Display continuation glyphs. */ 16174 if (!FRAME_WINDOW_P (it->f)) 16175 produce_special_glyphs (it, IT_CONTINUATION); 16176 row->continued_p = 1; 16177 16178 it->current_x = x_before; 16179 it->continuation_lines_width += x; 16180 extend_face_to_end_of_line (it); 16181 16182 if (nglyphs > 1 && i > 0) 16183 { 16184 row->ends_in_middle_of_char_p = 1; 16185 it->starts_in_middle_of_char_p = 1; 16186 } 16187 16188 /* Restore the height to what it was before the 16189 element not fitting on the line. */ 16190 it->max_ascent = ascent; 16191 it->max_descent = descent; 16192 it->max_phys_ascent = phys_ascent; 16193 it->max_phys_descent = phys_descent; 16194 } 16195 16196 break; 16197 } 16198 else if (new_x > it->first_visible_x) 16199 { 16200 /* Increment number of glyphs actually displayed. */ 16201 ++it->hpos; 16202 16203 if (x < it->first_visible_x) 16204 /* Glyph is partially visible, i.e. row starts at 16205 negative X position. */ 16206 row->x = x - it->first_visible_x; 16207 } 16208 else 16209 { 16210 /* Glyph is completely off the left margin of the 16211 window. This should not happen because of the 16212 move_it_in_display_line at the start of this 16213 function, unless the text display area of the 16214 window is empty. */ 16215 xassert (it->first_visible_x <= it->last_visible_x); 16216 } 16217 } 16218 16219 row->ascent = max (row->ascent, it->max_ascent); 16220 row->height = max (row->height, it->max_ascent + it->max_descent); 16221 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 16222 row->phys_height = max (row->phys_height, 16223 it->max_phys_ascent + it->max_phys_descent); 16224 row->extra_line_spacing = max (row->extra_line_spacing, 16225 it->max_extra_line_spacing); 16226 16227 /* End of this display line if row is continued. */ 16228 if (row->continued_p || row->ends_at_zv_p) 16229 break; 16230 } 16231 16232 at_end_of_line: 16233 /* Is this a line end? If yes, we're also done, after making 16234 sure that a non-default face is extended up to the right 16235 margin of the window. */ 16236 if (ITERATOR_AT_END_OF_LINE_P (it)) 16237 { 16238 int used_before = row->used[TEXT_AREA]; 16239 16240 row->ends_in_newline_from_string_p = STRINGP (it->object); 16241 16242#ifdef HAVE_WINDOW_SYSTEM 16243 /* Add a space at the end of the line that is used to 16244 display the cursor there. */ 16245 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 16246 append_space_for_newline (it, 0); 16247#endif /* HAVE_WINDOW_SYSTEM */ 16248 16249 /* Extend the face to the end of the line. */ 16250 extend_face_to_end_of_line (it); 16251 16252 /* Make sure we have the position. */ 16253 if (used_before == 0) 16254 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); 16255 16256 /* Consume the line end. This skips over invisible lines. */ 16257 set_iterator_to_next (it, 1); 16258 it->continuation_lines_width = 0; 16259 break; 16260 } 16261 16262 /* Proceed with next display element. Note that this skips 16263 over lines invisible because of selective display. */ 16264 set_iterator_to_next (it, 1); 16265 16266 /* If we truncate lines, we are done when the last displayed 16267 glyphs reach past the right margin of the window. */ 16268 if (it->truncate_lines_p 16269 && (FRAME_WINDOW_P (it->f) 16270 ? (it->current_x >= it->last_visible_x) 16271 : (it->current_x > it->last_visible_x))) 16272 { 16273 /* Maybe add truncation glyphs. */ 16274 if (!FRAME_WINDOW_P (it->f)) 16275 { 16276 int i, n; 16277 16278 for (i = row->used[TEXT_AREA] - 1; i > 0; --i) 16279 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i])) 16280 break; 16281 16282 for (n = row->used[TEXT_AREA]; i < n; ++i) 16283 { 16284 row->used[TEXT_AREA] = i; 16285 produce_special_glyphs (it, IT_TRUNCATION); 16286 } 16287 } 16288#ifdef HAVE_WINDOW_SYSTEM 16289 else 16290 { 16291 /* Don't truncate if we can overflow newline into fringe. */ 16292 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 16293 { 16294 if (!get_next_display_element (it)) 16295 { 16296 it->continuation_lines_width = 0; 16297 row->ends_at_zv_p = 1; 16298 row->exact_window_width_line_p = 1; 16299 break; 16300 } 16301 if (ITERATOR_AT_END_OF_LINE_P (it)) 16302 { 16303 row->exact_window_width_line_p = 1; 16304 goto at_end_of_line; 16305 } 16306 } 16307 } 16308#endif /* HAVE_WINDOW_SYSTEM */ 16309 16310 row->truncated_on_right_p = 1; 16311 it->continuation_lines_width = 0; 16312 reseat_at_next_visible_line_start (it, 0); 16313 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; 16314 it->hpos = hpos_before; 16315 it->current_x = x_before; 16316 break; 16317 } 16318 } 16319 16320 /* If line is not empty and hscrolled, maybe insert truncation glyphs 16321 at the left window margin. */ 16322 if (it->first_visible_x 16323 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row)) 16324 { 16325 if (!FRAME_WINDOW_P (it->f)) 16326 insert_left_trunc_glyphs (it); 16327 row->truncated_on_left_p = 1; 16328 } 16329 16330 /* If the start of this line is the overlay arrow-position, then 16331 mark this glyph row as the one containing the overlay arrow. 16332 This is clearly a mess with variable size fonts. It would be 16333 better to let it be displayed like cursors under X. */ 16334 if ((row->displays_text_p || !overlay_arrow_seen) 16335 && (overlay_arrow_string = overlay_arrow_at_row (it, row), 16336 !NILP (overlay_arrow_string))) 16337 { 16338 /* Overlay arrow in window redisplay is a fringe bitmap. */ 16339 if (STRINGP (overlay_arrow_string)) 16340 { 16341 struct glyph_row *arrow_row 16342 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string); 16343 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA]; 16344 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA]; 16345 struct glyph *p = row->glyphs[TEXT_AREA]; 16346 struct glyph *p2, *end; 16347 16348 /* Copy the arrow glyphs. */ 16349 while (glyph < arrow_end) 16350 *p++ = *glyph++; 16351 16352 /* Throw away padding glyphs. */ 16353 p2 = p; 16354 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; 16355 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2)) 16356 ++p2; 16357 if (p2 > p) 16358 { 16359 while (p2 < end) 16360 *p++ = *p2++; 16361 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA]; 16362 } 16363 } 16364 else 16365 { 16366 xassert (INTEGERP (overlay_arrow_string)); 16367 row->overlay_arrow_bitmap = XINT (overlay_arrow_string); 16368 } 16369 overlay_arrow_seen = 1; 16370 } 16371 16372 /* Compute pixel dimensions of this line. */ 16373 compute_line_metrics (it); 16374 16375 /* Remember the position at which this line ends. */ 16376 row->end = it->current; 16377 16378 /* Record whether this row ends inside an ellipsis. */ 16379 row->ends_in_ellipsis_p 16380 = (it->method == GET_FROM_DISPLAY_VECTOR 16381 && it->ellipsis_p); 16382 16383 /* Save fringe bitmaps in this row. */ 16384 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap; 16385 row->left_user_fringe_face_id = it->left_user_fringe_face_id; 16386 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap; 16387 row->right_user_fringe_face_id = it->right_user_fringe_face_id; 16388 16389 it->left_user_fringe_bitmap = 0; 16390 it->left_user_fringe_face_id = 0; 16391 it->right_user_fringe_bitmap = 0; 16392 it->right_user_fringe_face_id = 0; 16393 16394 /* Maybe set the cursor. */ 16395 if (it->w->cursor.vpos < 0 16396 && PT >= MATRIX_ROW_START_CHARPOS (row) 16397 && PT <= MATRIX_ROW_END_CHARPOS (row) 16398 && cursor_row_p (it->w, row)) 16399 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0); 16400 16401 /* Highlight trailing whitespace. */ 16402 if (!NILP (Vshow_trailing_whitespace)) 16403 highlight_trailing_whitespace (it->f, it->glyph_row); 16404 16405 /* Prepare for the next line. This line starts horizontally at (X 16406 HPOS) = (0 0). Vertical positions are incremented. As a 16407 convenience for the caller, IT->glyph_row is set to the next 16408 row to be used. */ 16409 it->current_x = it->hpos = 0; 16410 it->current_y += row->height; 16411 ++it->vpos; 16412 ++it->glyph_row; 16413 it->start = it->current; 16414 return row->displays_text_p; 16415} 16416 16417 16418 16419/*********************************************************************** 16420 Menu Bar 16421 ***********************************************************************/ 16422 16423/* Redisplay the menu bar in the frame for window W. 16424 16425 The menu bar of X frames that don't have X toolkit support is 16426 displayed in a special window W->frame->menu_bar_window. 16427 16428 The menu bar of terminal frames is treated specially as far as 16429 glyph matrices are concerned. Menu bar lines are not part of 16430 windows, so the update is done directly on the frame matrix rows 16431 for the menu bar. */ 16432 16433static void 16434display_menu_bar (w) 16435 struct window *w; 16436{ 16437 struct frame *f = XFRAME (WINDOW_FRAME (w)); 16438 struct it it; 16439 Lisp_Object items; 16440 int i; 16441 16442 /* Don't do all this for graphical frames. */ 16443#ifdef HAVE_NTGUI 16444 if (!NILP (Vwindow_system)) 16445 return; 16446#endif 16447#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 16448 if (FRAME_X_P (f)) 16449 return; 16450#endif 16451#ifdef MAC_OS 16452 if (FRAME_MAC_P (f)) 16453 return; 16454#endif 16455 16456#ifdef USE_X_TOOLKIT 16457 xassert (!FRAME_WINDOW_P (f)); 16458 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID); 16459 it.first_visible_x = 0; 16460 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 16461#else /* not USE_X_TOOLKIT */ 16462 if (FRAME_WINDOW_P (f)) 16463 { 16464 /* Menu bar lines are displayed in the desired matrix of the 16465 dummy window menu_bar_window. */ 16466 struct window *menu_w; 16467 xassert (WINDOWP (f->menu_bar_window)); 16468 menu_w = XWINDOW (f->menu_bar_window); 16469 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows, 16470 MENU_FACE_ID); 16471 it.first_visible_x = 0; 16472 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 16473 } 16474 else 16475 { 16476 /* This is a TTY frame, i.e. character hpos/vpos are used as 16477 pixel x/y. */ 16478 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, 16479 MENU_FACE_ID); 16480 it.first_visible_x = 0; 16481 it.last_visible_x = FRAME_COLS (f); 16482 } 16483#endif /* not USE_X_TOOLKIT */ 16484 16485 if (! mode_line_inverse_video) 16486 /* Force the menu-bar to be displayed in the default face. */ 16487 it.base_face_id = it.face_id = DEFAULT_FACE_ID; 16488 16489 /* Clear all rows of the menu bar. */ 16490 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i) 16491 { 16492 struct glyph_row *row = it.glyph_row + i; 16493 clear_glyph_row (row); 16494 row->enabled_p = 1; 16495 row->full_width_p = 1; 16496 } 16497 16498 /* Display all items of the menu bar. */ 16499 items = FRAME_MENU_BAR_ITEMS (it.f); 16500 for (i = 0; i < XVECTOR (items)->size; i += 4) 16501 { 16502 Lisp_Object string; 16503 16504 /* Stop at nil string. */ 16505 string = AREF (items, i + 1); 16506 if (NILP (string)) 16507 break; 16508 16509 /* Remember where item was displayed. */ 16510 AREF (items, i + 3) = make_number (it.hpos); 16511 16512 /* Display the item, pad with one space. */ 16513 if (it.current_x < it.last_visible_x) 16514 display_string (NULL, string, Qnil, 0, 0, &it, 16515 SCHARS (string) + 1, 0, 0, -1); 16516 } 16517 16518 /* Fill out the line with spaces. */ 16519 if (it.current_x < it.last_visible_x) 16520 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1); 16521 16522 /* Compute the total height of the lines. */ 16523 compute_line_metrics (&it); 16524} 16525 16526 16527 16528/*********************************************************************** 16529 Mode Line 16530 ***********************************************************************/ 16531 16532/* Redisplay mode lines in the window tree whose root is WINDOW. If 16533 FORCE is non-zero, redisplay mode lines unconditionally. 16534 Otherwise, redisplay only mode lines that are garbaged. Value is 16535 the number of windows whose mode lines were redisplayed. */ 16536 16537static int 16538redisplay_mode_lines (window, force) 16539 Lisp_Object window; 16540 int force; 16541{ 16542 int nwindows = 0; 16543 16544 while (!NILP (window)) 16545 { 16546 struct window *w = XWINDOW (window); 16547 16548 if (WINDOWP (w->hchild)) 16549 nwindows += redisplay_mode_lines (w->hchild, force); 16550 else if (WINDOWP (w->vchild)) 16551 nwindows += redisplay_mode_lines (w->vchild, force); 16552 else if (force 16553 || FRAME_GARBAGED_P (XFRAME (w->frame)) 16554 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p) 16555 { 16556 struct text_pos lpoint; 16557 struct buffer *old = current_buffer; 16558 16559 /* Set the window's buffer for the mode line display. */ 16560 SET_TEXT_POS (lpoint, PT, PT_BYTE); 16561 set_buffer_internal_1 (XBUFFER (w->buffer)); 16562 16563 /* Point refers normally to the selected window. For any 16564 other window, set up appropriate value. */ 16565 if (!EQ (window, selected_window)) 16566 { 16567 struct text_pos pt; 16568 16569 SET_TEXT_POS_FROM_MARKER (pt, w->pointm); 16570 if (CHARPOS (pt) < BEGV) 16571 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE); 16572 else if (CHARPOS (pt) > (ZV - 1)) 16573 TEMP_SET_PT_BOTH (ZV, ZV_BYTE); 16574 else 16575 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt)); 16576 } 16577 16578 /* Display mode lines. */ 16579 clear_glyph_matrix (w->desired_matrix); 16580 if (display_mode_lines (w)) 16581 { 16582 ++nwindows; 16583 w->must_be_updated_p = 1; 16584 } 16585 16586 /* Restore old settings. */ 16587 set_buffer_internal_1 (old); 16588 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); 16589 } 16590 16591 window = w->next; 16592 } 16593 16594 return nwindows; 16595} 16596 16597 16598/* Display the mode and/or top line of window W. Value is the number 16599 of mode lines displayed. */ 16600 16601static int 16602display_mode_lines (w) 16603 struct window *w; 16604{ 16605 Lisp_Object old_selected_window, old_selected_frame; 16606 int n = 0; 16607 16608 old_selected_frame = selected_frame; 16609 selected_frame = w->frame; 16610 old_selected_window = selected_window; 16611 XSETWINDOW (selected_window, w); 16612 16613 /* These will be set while the mode line specs are processed. */ 16614 line_number_displayed = 0; 16615 w->column_number_displayed = Qnil; 16616 16617 if (WINDOW_WANTS_MODELINE_P (w)) 16618 { 16619 struct window *sel_w = XWINDOW (old_selected_window); 16620 16621 /* Select mode line face based on the real selected window. */ 16622 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w), 16623 current_buffer->mode_line_format); 16624 ++n; 16625 } 16626 16627 if (WINDOW_WANTS_HEADER_LINE_P (w)) 16628 { 16629 display_mode_line (w, HEADER_LINE_FACE_ID, 16630 current_buffer->header_line_format); 16631 ++n; 16632 } 16633 16634 selected_frame = old_selected_frame; 16635 selected_window = old_selected_window; 16636 return n; 16637} 16638 16639 16640/* Display mode or top line of window W. FACE_ID specifies which line 16641 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID. 16642 FORMAT is the mode line format to display. Value is the pixel 16643 height of the mode line displayed. */ 16644 16645static int 16646display_mode_line (w, face_id, format) 16647 struct window *w; 16648 enum face_id face_id; 16649 Lisp_Object format; 16650{ 16651 struct it it; 16652 struct face *face; 16653 int count = SPECPDL_INDEX (); 16654 16655 init_iterator (&it, w, -1, -1, NULL, face_id); 16656 /* Don't extend on a previously drawn mode-line. 16657 This may happen if called from pos_visible_p. */ 16658 it.glyph_row->enabled_p = 0; 16659 prepare_desired_row (it.glyph_row); 16660 16661 it.glyph_row->mode_line_p = 1; 16662 16663 if (! mode_line_inverse_video) 16664 /* Force the mode-line to be displayed in the default face. */ 16665 it.base_face_id = it.face_id = DEFAULT_FACE_ID; 16666 16667 record_unwind_protect (unwind_format_mode_line, 16668 format_mode_line_unwind_data (NULL, 0)); 16669 16670 mode_line_target = MODE_LINE_DISPLAY; 16671 16672 /* Temporarily make frame's keyboard the current kboard so that 16673 kboard-local variables in the mode_line_format will get the right 16674 values. */ 16675 push_frame_kboard (it.f); 16676 record_unwind_save_match_data (); 16677 display_mode_element (&it, 0, 0, 0, format, Qnil, 0); 16678 pop_frame_kboard (); 16679 16680 unbind_to (count, Qnil); 16681 16682 /* Fill up with spaces. */ 16683 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0); 16684 16685 compute_line_metrics (&it); 16686 it.glyph_row->full_width_p = 1; 16687 it.glyph_row->continued_p = 0; 16688 it.glyph_row->truncated_on_left_p = 0; 16689 it.glyph_row->truncated_on_right_p = 0; 16690 16691 /* Make a 3D mode-line have a shadow at its right end. */ 16692 face = FACE_FROM_ID (it.f, face_id); 16693 extend_face_to_end_of_line (&it); 16694 if (face->box != FACE_NO_BOX) 16695 { 16696 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA] 16697 + it.glyph_row->used[TEXT_AREA] - 1); 16698 last->right_box_line_p = 1; 16699 } 16700 16701 return it.glyph_row->height; 16702} 16703 16704/* Move element ELT in LIST to the front of LIST. 16705 Return the updated list. */ 16706 16707static Lisp_Object 16708move_elt_to_front (elt, list) 16709 Lisp_Object elt, list; 16710{ 16711 register Lisp_Object tail, prev; 16712 register Lisp_Object tem; 16713 16714 tail = list; 16715 prev = Qnil; 16716 while (CONSP (tail)) 16717 { 16718 tem = XCAR (tail); 16719 16720 if (EQ (elt, tem)) 16721 { 16722 /* Splice out the link TAIL. */ 16723 if (NILP (prev)) 16724 list = XCDR (tail); 16725 else 16726 Fsetcdr (prev, XCDR (tail)); 16727 16728 /* Now make it the first. */ 16729 Fsetcdr (tail, list); 16730 return tail; 16731 } 16732 else 16733 prev = tail; 16734 tail = XCDR (tail); 16735 QUIT; 16736 } 16737 16738 /* Not found--return unchanged LIST. */ 16739 return list; 16740} 16741 16742/* Contribute ELT to the mode line for window IT->w. How it 16743 translates into text depends on its data type. 16744 16745 IT describes the display environment in which we display, as usual. 16746 16747 DEPTH is the depth in recursion. It is used to prevent 16748 infinite recursion here. 16749 16750 FIELD_WIDTH is the number of characters the display of ELT should 16751 occupy in the mode line, and PRECISION is the maximum number of 16752 characters to display from ELT's representation. See 16753 display_string for details. 16754 16755 Returns the hpos of the end of the text generated by ELT. 16756 16757 PROPS is a property list to add to any string we encounter. 16758 16759 If RISKY is nonzero, remove (disregard) any properties in any string 16760 we encounter, and ignore :eval and :propertize. 16761 16762 The global variable `mode_line_target' determines whether the 16763 output is passed to `store_mode_line_noprop', 16764 `store_mode_line_string', or `display_string'. */ 16765 16766static int 16767display_mode_element (it, depth, field_width, precision, elt, props, risky) 16768 struct it *it; 16769 int depth; 16770 int field_width, precision; 16771 Lisp_Object elt, props; 16772 int risky; 16773{ 16774 int n = 0, field, prec; 16775 int literal = 0; 16776 16777 tail_recurse: 16778 if (depth > 100) 16779 elt = build_string ("*too-deep*"); 16780 16781 depth++; 16782 16783 switch (SWITCH_ENUM_CAST (XTYPE (elt))) 16784 { 16785 case Lisp_String: 16786 { 16787 /* A string: output it and check for %-constructs within it. */ 16788 unsigned char c; 16789 int offset = 0; 16790 16791 if (SCHARS (elt) > 0 16792 && (!NILP (props) || risky)) 16793 { 16794 Lisp_Object oprops, aelt; 16795 oprops = Ftext_properties_at (make_number (0), elt); 16796 16797 /* If the starting string's properties are not what 16798 we want, translate the string. Also, if the string 16799 is risky, do that anyway. */ 16800 16801 if (NILP (Fequal (props, oprops)) || risky) 16802 { 16803 /* If the starting string has properties, 16804 merge the specified ones onto the existing ones. */ 16805 if (! NILP (oprops) && !risky) 16806 { 16807 Lisp_Object tem; 16808 16809 oprops = Fcopy_sequence (oprops); 16810 tem = props; 16811 while (CONSP (tem)) 16812 { 16813 oprops = Fplist_put (oprops, XCAR (tem), 16814 XCAR (XCDR (tem))); 16815 tem = XCDR (XCDR (tem)); 16816 } 16817 props = oprops; 16818 } 16819 16820 aelt = Fassoc (elt, mode_line_proptrans_alist); 16821 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt)))) 16822 { 16823 /* AELT is what we want. Move it to the front 16824 without consing. */ 16825 elt = XCAR (aelt); 16826 mode_line_proptrans_alist 16827 = move_elt_to_front (aelt, mode_line_proptrans_alist); 16828 } 16829 else 16830 { 16831 Lisp_Object tem; 16832 16833 /* If AELT has the wrong props, it is useless. 16834 so get rid of it. */ 16835 if (! NILP (aelt)) 16836 mode_line_proptrans_alist 16837 = Fdelq (aelt, mode_line_proptrans_alist); 16838 16839 elt = Fcopy_sequence (elt); 16840 Fset_text_properties (make_number (0), Flength (elt), 16841 props, elt); 16842 /* Add this item to mode_line_proptrans_alist. */ 16843 mode_line_proptrans_alist 16844 = Fcons (Fcons (elt, props), 16845 mode_line_proptrans_alist); 16846 /* Truncate mode_line_proptrans_alist 16847 to at most 50 elements. */ 16848 tem = Fnthcdr (make_number (50), 16849 mode_line_proptrans_alist); 16850 if (! NILP (tem)) 16851 XSETCDR (tem, Qnil); 16852 } 16853 } 16854 } 16855 16856 offset = 0; 16857 16858 if (literal) 16859 { 16860 prec = precision - n; 16861 switch (mode_line_target) 16862 { 16863 case MODE_LINE_NOPROP: 16864 case MODE_LINE_TITLE: 16865 n += store_mode_line_noprop (SDATA (elt), -1, prec); 16866 break; 16867 case MODE_LINE_STRING: 16868 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil); 16869 break; 16870 case MODE_LINE_DISPLAY: 16871 n += display_string (NULL, elt, Qnil, 0, 0, it, 16872 0, prec, 0, STRING_MULTIBYTE (elt)); 16873 break; 16874 } 16875 16876 break; 16877 } 16878 16879 /* Handle the non-literal case. */ 16880 16881 while ((precision <= 0 || n < precision) 16882 && SREF (elt, offset) != 0 16883 && (mode_line_target != MODE_LINE_DISPLAY 16884 || it->current_x < it->last_visible_x)) 16885 { 16886 int last_offset = offset; 16887 16888 /* Advance to end of string or next format specifier. */ 16889 while ((c = SREF (elt, offset++)) != '\0' && c != '%') 16890 ; 16891 16892 if (offset - 1 != last_offset) 16893 { 16894 int nchars, nbytes; 16895 16896 /* Output to end of string or up to '%'. Field width 16897 is length of string. Don't output more than 16898 PRECISION allows us. */ 16899 offset--; 16900 16901 prec = c_string_width (SDATA (elt) + last_offset, 16902 offset - last_offset, precision - n, 16903 &nchars, &nbytes); 16904 16905 switch (mode_line_target) 16906 { 16907 case MODE_LINE_NOPROP: 16908 case MODE_LINE_TITLE: 16909 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec); 16910 break; 16911 case MODE_LINE_STRING: 16912 { 16913 int bytepos = last_offset; 16914 int charpos = string_byte_to_char (elt, bytepos); 16915 int endpos = (precision <= 0 16916 ? string_byte_to_char (elt, offset) 16917 : charpos + nchars); 16918 16919 n += store_mode_line_string (NULL, 16920 Fsubstring (elt, make_number (charpos), 16921 make_number (endpos)), 16922 0, 0, 0, Qnil); 16923 } 16924 break; 16925 case MODE_LINE_DISPLAY: 16926 { 16927 int bytepos = last_offset; 16928 int charpos = string_byte_to_char (elt, bytepos); 16929 16930 if (precision <= 0) 16931 nchars = string_byte_to_char (elt, offset) - charpos; 16932 n += display_string (NULL, elt, Qnil, 0, charpos, 16933 it, 0, nchars, 0, 16934 STRING_MULTIBYTE (elt)); 16935 } 16936 break; 16937 } 16938 } 16939 else /* c == '%' */ 16940 { 16941 int percent_position = offset; 16942 16943 /* Get the specified minimum width. Zero means 16944 don't pad. */ 16945 field = 0; 16946 while ((c = SREF (elt, offset++)) >= '0' && c <= '9') 16947 field = field * 10 + c - '0'; 16948 16949 /* Don't pad beyond the total padding allowed. */ 16950 if (field_width - n > 0 && field > field_width - n) 16951 field = field_width - n; 16952 16953 /* Note that either PRECISION <= 0 or N < PRECISION. */ 16954 prec = precision - n; 16955 16956 if (c == 'M') 16957 n += display_mode_element (it, depth, field, prec, 16958 Vglobal_mode_string, props, 16959 risky); 16960 else if (c != 0) 16961 { 16962 int multibyte; 16963 int bytepos, charpos; 16964 unsigned char *spec; 16965 16966 bytepos = percent_position; 16967 charpos = (STRING_MULTIBYTE (elt) 16968 ? string_byte_to_char (elt, bytepos) 16969 : bytepos); 16970 16971 spec 16972 = decode_mode_spec (it->w, c, field, prec, &multibyte); 16973 16974 switch (mode_line_target) 16975 { 16976 case MODE_LINE_NOPROP: 16977 case MODE_LINE_TITLE: 16978 n += store_mode_line_noprop (spec, field, prec); 16979 break; 16980 case MODE_LINE_STRING: 16981 { 16982 int len = strlen (spec); 16983 Lisp_Object tem = make_string (spec, len); 16984 props = Ftext_properties_at (make_number (charpos), elt); 16985 /* Should only keep face property in props */ 16986 n += store_mode_line_string (NULL, tem, 0, field, prec, props); 16987 } 16988 break; 16989 case MODE_LINE_DISPLAY: 16990 { 16991 int nglyphs_before, nwritten; 16992 16993 nglyphs_before = it->glyph_row->used[TEXT_AREA]; 16994 nwritten = display_string (spec, Qnil, elt, 16995 charpos, 0, it, 16996 field, prec, 0, 16997 multibyte); 16998 16999 /* Assign to the glyphs written above the 17000 string where the `%x' came from, position 17001 of the `%'. */ 17002 if (nwritten > 0) 17003 { 17004 struct glyph *glyph 17005 = (it->glyph_row->glyphs[TEXT_AREA] 17006 + nglyphs_before); 17007 int i; 17008 17009 for (i = 0; i < nwritten; ++i) 17010 { 17011 glyph[i].object = elt; 17012 glyph[i].charpos = charpos; 17013 } 17014 17015 n += nwritten; 17016 } 17017 } 17018 break; 17019 } 17020 } 17021 else /* c == 0 */ 17022 break; 17023 } 17024 } 17025 } 17026 break; 17027 17028 case Lisp_Symbol: 17029 /* A symbol: process the value of the symbol recursively 17030 as if it appeared here directly. Avoid error if symbol void. 17031 Special case: if value of symbol is a string, output the string 17032 literally. */ 17033 { 17034 register Lisp_Object tem; 17035 17036 /* If the variable is not marked as risky to set 17037 then its contents are risky to use. */ 17038 if (NILP (Fget (elt, Qrisky_local_variable))) 17039 risky = 1; 17040 17041 tem = Fboundp (elt); 17042 if (!NILP (tem)) 17043 { 17044 tem = Fsymbol_value (elt); 17045 /* If value is a string, output that string literally: 17046 don't check for % within it. */ 17047 if (STRINGP (tem)) 17048 literal = 1; 17049 17050 if (!EQ (tem, elt)) 17051 { 17052 /* Give up right away for nil or t. */ 17053 elt = tem; 17054 goto tail_recurse; 17055 } 17056 } 17057 } 17058 break; 17059 17060 case Lisp_Cons: 17061 { 17062 register Lisp_Object car, tem; 17063 17064 /* A cons cell: five distinct cases. 17065 If first element is :eval or :propertize, do something special. 17066 If first element is a string or a cons, process all the elements 17067 and effectively concatenate them. 17068 If first element is a negative number, truncate displaying cdr to 17069 at most that many characters. If positive, pad (with spaces) 17070 to at least that many characters. 17071 If first element is a symbol, process the cadr or caddr recursively 17072 according to whether the symbol's value is non-nil or nil. */ 17073 car = XCAR (elt); 17074 if (EQ (car, QCeval)) 17075 { 17076 /* An element of the form (:eval FORM) means evaluate FORM 17077 and use the result as mode line elements. */ 17078 17079 if (risky) 17080 break; 17081 17082 if (CONSP (XCDR (elt))) 17083 { 17084 Lisp_Object spec; 17085 spec = safe_eval (XCAR (XCDR (elt))); 17086 n += display_mode_element (it, depth, field_width - n, 17087 precision - n, spec, props, 17088 risky); 17089 } 17090 } 17091 else if (EQ (car, QCpropertize)) 17092 { 17093 /* An element of the form (:propertize ELT PROPS...) 17094 means display ELT but applying properties PROPS. */ 17095 17096 if (risky) 17097 break; 17098 17099 if (CONSP (XCDR (elt))) 17100 n += display_mode_element (it, depth, field_width - n, 17101 precision - n, XCAR (XCDR (elt)), 17102 XCDR (XCDR (elt)), risky); 17103 } 17104 else if (SYMBOLP (car)) 17105 { 17106 tem = Fboundp (car); 17107 elt = XCDR (elt); 17108 if (!CONSP (elt)) 17109 goto invalid; 17110 /* elt is now the cdr, and we know it is a cons cell. 17111 Use its car if CAR has a non-nil value. */ 17112 if (!NILP (tem)) 17113 { 17114 tem = Fsymbol_value (car); 17115 if (!NILP (tem)) 17116 { 17117 elt = XCAR (elt); 17118 goto tail_recurse; 17119 } 17120 } 17121 /* Symbol's value is nil (or symbol is unbound) 17122 Get the cddr of the original list 17123 and if possible find the caddr and use that. */ 17124 elt = XCDR (elt); 17125 if (NILP (elt)) 17126 break; 17127 else if (!CONSP (elt)) 17128 goto invalid; 17129 elt = XCAR (elt); 17130 goto tail_recurse; 17131 } 17132 else if (INTEGERP (car)) 17133 { 17134 register int lim = XINT (car); 17135 elt = XCDR (elt); 17136 if (lim < 0) 17137 { 17138 /* Negative int means reduce maximum width. */ 17139 if (precision <= 0) 17140 precision = -lim; 17141 else 17142 precision = min (precision, -lim); 17143 } 17144 else if (lim > 0) 17145 { 17146 /* Padding specified. Don't let it be more than 17147 current maximum. */ 17148 if (precision > 0) 17149 lim = min (precision, lim); 17150 17151 /* If that's more padding than already wanted, queue it. 17152 But don't reduce padding already specified even if 17153 that is beyond the current truncation point. */ 17154 field_width = max (lim, field_width); 17155 } 17156 goto tail_recurse; 17157 } 17158 else if (STRINGP (car) || CONSP (car)) 17159 { 17160 register int limit = 50; 17161 /* Limit is to protect against circular lists. */ 17162 while (CONSP (elt) 17163 && --limit > 0 17164 && (precision <= 0 || n < precision)) 17165 { 17166 n += display_mode_element (it, depth, 17167 /* Do padding only after the last 17168 element in the list. */ 17169 (! CONSP (XCDR (elt)) 17170 ? field_width - n 17171 : 0), 17172 precision - n, XCAR (elt), 17173 props, risky); 17174 elt = XCDR (elt); 17175 } 17176 } 17177 } 17178 break; 17179 17180 default: 17181 invalid: 17182 elt = build_string ("*invalid*"); 17183 goto tail_recurse; 17184 } 17185 17186 /* Pad to FIELD_WIDTH. */ 17187 if (field_width > 0 && n < field_width) 17188 { 17189 switch (mode_line_target) 17190 { 17191 case MODE_LINE_NOPROP: 17192 case MODE_LINE_TITLE: 17193 n += store_mode_line_noprop ("", field_width - n, 0); 17194 break; 17195 case MODE_LINE_STRING: 17196 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil); 17197 break; 17198 case MODE_LINE_DISPLAY: 17199 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n, 17200 0, 0, 0); 17201 break; 17202 } 17203 } 17204 17205 return n; 17206} 17207 17208/* Store a mode-line string element in mode_line_string_list. 17209 17210 If STRING is non-null, display that C string. Otherwise, the Lisp 17211 string LISP_STRING is displayed. 17212 17213 FIELD_WIDTH is the minimum number of output glyphs to produce. 17214 If STRING has fewer characters than FIELD_WIDTH, pad to the right 17215 with spaces. FIELD_WIDTH <= 0 means don't pad. 17216 17217 PRECISION is the maximum number of characters to output from 17218 STRING. PRECISION <= 0 means don't truncate the string. 17219 17220 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding 17221 properties to the string. 17222 17223 PROPS are the properties to add to the string. 17224 The mode_line_string_face face property is always added to the string. 17225 */ 17226 17227static int 17228store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props) 17229 char *string; 17230 Lisp_Object lisp_string; 17231 int copy_string; 17232 int field_width; 17233 int precision; 17234 Lisp_Object props; 17235{ 17236 int len; 17237 int n = 0; 17238 17239 if (string != NULL) 17240 { 17241 len = strlen (string); 17242 if (precision > 0 && len > precision) 17243 len = precision; 17244 lisp_string = make_string (string, len); 17245 if (NILP (props)) 17246 props = mode_line_string_face_prop; 17247 else if (!NILP (mode_line_string_face)) 17248 { 17249 Lisp_Object face = Fplist_get (props, Qface); 17250 props = Fcopy_sequence (props); 17251 if (NILP (face)) 17252 face = mode_line_string_face; 17253 else 17254 face = Fcons (face, Fcons (mode_line_string_face, Qnil)); 17255 props = Fplist_put (props, Qface, face); 17256 } 17257 Fadd_text_properties (make_number (0), make_number (len), 17258 props, lisp_string); 17259 } 17260 else 17261 { 17262 len = XFASTINT (Flength (lisp_string)); 17263 if (precision > 0 && len > precision) 17264 { 17265 len = precision; 17266 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len)); 17267 precision = -1; 17268 } 17269 if (!NILP (mode_line_string_face)) 17270 { 17271 Lisp_Object face; 17272 if (NILP (props)) 17273 props = Ftext_properties_at (make_number (0), lisp_string); 17274 face = Fplist_get (props, Qface); 17275 if (NILP (face)) 17276 face = mode_line_string_face; 17277 else 17278 face = Fcons (face, Fcons (mode_line_string_face, Qnil)); 17279 props = Fcons (Qface, Fcons (face, Qnil)); 17280 if (copy_string) 17281 lisp_string = Fcopy_sequence (lisp_string); 17282 } 17283 if (!NILP (props)) 17284 Fadd_text_properties (make_number (0), make_number (len), 17285 props, lisp_string); 17286 } 17287 17288 if (len > 0) 17289 { 17290 mode_line_string_list = Fcons (lisp_string, mode_line_string_list); 17291 n += len; 17292 } 17293 17294 if (field_width > len) 17295 { 17296 field_width -= len; 17297 lisp_string = Fmake_string (make_number (field_width), make_number (' ')); 17298 if (!NILP (props)) 17299 Fadd_text_properties (make_number (0), make_number (field_width), 17300 props, lisp_string); 17301 mode_line_string_list = Fcons (lisp_string, mode_line_string_list); 17302 n += field_width; 17303 } 17304 17305 return n; 17306} 17307 17308 17309DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line, 17310 1, 4, 0, 17311 doc: /* Format a string out of a mode line format specification. 17312First arg FORMAT specifies the mode line format (see `mode-line-format' 17313for details) to use. 17314 17315Optional second arg FACE specifies the face property to put 17316on all characters for which no face is specified. 17317The value t means whatever face the window's mode line currently uses 17318\(either `mode-line' or `mode-line-inactive', depending). 17319A value of nil means the default is no face property. 17320If FACE is an integer, the value string has no text properties. 17321 17322Optional third and fourth args WINDOW and BUFFER specify the window 17323and buffer to use as the context for the formatting (defaults 17324are the selected window and the window's buffer). */) 17325 (format, face, window, buffer) 17326 Lisp_Object format, face, window, buffer; 17327{ 17328 struct it it; 17329 int len; 17330 struct window *w; 17331 struct buffer *old_buffer = NULL; 17332 int face_id = -1; 17333 int no_props = INTEGERP (face); 17334 int count = SPECPDL_INDEX (); 17335 Lisp_Object str; 17336 int string_start = 0; 17337 17338 if (NILP (window)) 17339 window = selected_window; 17340 CHECK_WINDOW (window); 17341 w = XWINDOW (window); 17342 17343 if (NILP (buffer)) 17344 buffer = w->buffer; 17345 CHECK_BUFFER (buffer); 17346 17347 if (NILP (format)) 17348 return build_string (""); 17349 17350 if (no_props) 17351 face = Qnil; 17352 17353 if (!NILP (face)) 17354 { 17355 if (EQ (face, Qt)) 17356 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive); 17357 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0); 17358 } 17359 17360 if (face_id < 0) 17361 face_id = DEFAULT_FACE_ID; 17362 17363 if (XBUFFER (buffer) != current_buffer) 17364 old_buffer = current_buffer; 17365 17366 /* Save things including mode_line_proptrans_alist, 17367 and set that to nil so that we don't alter the outer value. */ 17368 record_unwind_protect (unwind_format_mode_line, 17369 format_mode_line_unwind_data (old_buffer, 1)); 17370 mode_line_proptrans_alist = Qnil; 17371 17372 if (old_buffer) 17373 set_buffer_internal_1 (XBUFFER (buffer)); 17374 17375 init_iterator (&it, w, -1, -1, NULL, face_id); 17376 17377 if (no_props) 17378 { 17379 mode_line_target = MODE_LINE_NOPROP; 17380 mode_line_string_face_prop = Qnil; 17381 mode_line_string_list = Qnil; 17382 string_start = MODE_LINE_NOPROP_LEN (0); 17383 } 17384 else 17385 { 17386 mode_line_target = MODE_LINE_STRING; 17387 mode_line_string_list = Qnil; 17388 mode_line_string_face = face; 17389 mode_line_string_face_prop 17390 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil))); 17391 } 17392 17393 push_frame_kboard (it.f); 17394 display_mode_element (&it, 0, 0, 0, format, Qnil, 0); 17395 pop_frame_kboard (); 17396 17397 if (no_props) 17398 { 17399 len = MODE_LINE_NOPROP_LEN (string_start); 17400 str = make_string (mode_line_noprop_buf + string_start, len); 17401 } 17402 else 17403 { 17404 mode_line_string_list = Fnreverse (mode_line_string_list); 17405 str = Fmapconcat (intern ("identity"), mode_line_string_list, 17406 make_string ("", 0)); 17407 } 17408 17409 unbind_to (count, Qnil); 17410 return str; 17411} 17412 17413/* Write a null-terminated, right justified decimal representation of 17414 the positive integer D to BUF using a minimal field width WIDTH. */ 17415 17416static void 17417pint2str (buf, width, d) 17418 register char *buf; 17419 register int width; 17420 register int d; 17421{ 17422 register char *p = buf; 17423 17424 if (d <= 0) 17425 *p++ = '0'; 17426 else 17427 { 17428 while (d > 0) 17429 { 17430 *p++ = d % 10 + '0'; 17431 d /= 10; 17432 } 17433 } 17434 17435 for (width -= (int) (p - buf); width > 0; --width) 17436 *p++ = ' '; 17437 *p-- = '\0'; 17438 while (p > buf) 17439 { 17440 d = *buf; 17441 *buf++ = *p; 17442 *p-- = d; 17443 } 17444} 17445 17446/* Write a null-terminated, right justified decimal and "human 17447 readable" representation of the nonnegative integer D to BUF using 17448 a minimal field width WIDTH. D should be smaller than 999.5e24. */ 17449 17450static const char power_letter[] = 17451 { 17452 0, /* not used */ 17453 'k', /* kilo */ 17454 'M', /* mega */ 17455 'G', /* giga */ 17456 'T', /* tera */ 17457 'P', /* peta */ 17458 'E', /* exa */ 17459 'Z', /* zetta */ 17460 'Y' /* yotta */ 17461 }; 17462 17463static void 17464pint2hrstr (buf, width, d) 17465 char *buf; 17466 int width; 17467 int d; 17468{ 17469 /* We aim to represent the nonnegative integer D as 17470 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */ 17471 int quotient = d; 17472 int remainder = 0; 17473 /* -1 means: do not use TENTHS. */ 17474 int tenths = -1; 17475 int exponent = 0; 17476 17477 /* Length of QUOTIENT.TENTHS as a string. */ 17478 int length; 17479 17480 char * psuffix; 17481 char * p; 17482 17483 if (1000 <= quotient) 17484 { 17485 /* Scale to the appropriate EXPONENT. */ 17486 do 17487 { 17488 remainder = quotient % 1000; 17489 quotient /= 1000; 17490 exponent++; 17491 } 17492 while (1000 <= quotient); 17493 17494 /* Round to nearest and decide whether to use TENTHS or not. */ 17495 if (quotient <= 9) 17496 { 17497 tenths = remainder / 100; 17498 if (50 <= remainder % 100) 17499 { 17500 if (tenths < 9) 17501 tenths++; 17502 else 17503 { 17504 quotient++; 17505 if (quotient == 10) 17506 tenths = -1; 17507 else 17508 tenths = 0; 17509 } 17510 } 17511 } 17512 else 17513 if (500 <= remainder) 17514 { 17515 if (quotient < 999) 17516 quotient++; 17517 else 17518 { 17519 quotient = 1; 17520 exponent++; 17521 tenths = 0; 17522 } 17523 } 17524 } 17525 17526 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */ 17527 if (tenths == -1 && quotient <= 99) 17528 if (quotient <= 9) 17529 length = 1; 17530 else 17531 length = 2; 17532 else 17533 length = 3; 17534 p = psuffix = buf + max (width, length); 17535 17536 /* Print EXPONENT. */ 17537 if (exponent) 17538 *psuffix++ = power_letter[exponent]; 17539 *psuffix = '\0'; 17540 17541 /* Print TENTHS. */ 17542 if (tenths >= 0) 17543 { 17544 *--p = '0' + tenths; 17545 *--p = '.'; 17546 } 17547 17548 /* Print QUOTIENT. */ 17549 do 17550 { 17551 int digit = quotient % 10; 17552 *--p = '0' + digit; 17553 } 17554 while ((quotient /= 10) != 0); 17555 17556 /* Print leading spaces. */ 17557 while (buf < p) 17558 *--p = ' '; 17559} 17560 17561/* Set a mnemonic character for coding_system (Lisp symbol) in BUF. 17562 If EOL_FLAG is 1, set also a mnemonic character for end-of-line 17563 type of CODING_SYSTEM. Return updated pointer into BUF. */ 17564 17565static unsigned char invalid_eol_type[] = "(*invalid*)"; 17566 17567static char * 17568decode_mode_spec_coding (coding_system, buf, eol_flag) 17569 Lisp_Object coding_system; 17570 register char *buf; 17571 int eol_flag; 17572{ 17573 Lisp_Object val; 17574 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 17575 const unsigned char *eol_str; 17576 int eol_str_len; 17577 /* The EOL conversion we are using. */ 17578 Lisp_Object eoltype; 17579 17580 val = Fget (coding_system, Qcoding_system); 17581 eoltype = Qnil; 17582 17583 if (!VECTORP (val)) /* Not yet decided. */ 17584 { 17585 if (multibyte) 17586 *buf++ = '-'; 17587 if (eol_flag) 17588 eoltype = eol_mnemonic_undecided; 17589 /* Don't mention EOL conversion if it isn't decided. */ 17590 } 17591 else 17592 { 17593 Lisp_Object eolvalue; 17594 17595 eolvalue = Fget (coding_system, Qeol_type); 17596 17597 if (multibyte) 17598 *buf++ = XFASTINT (AREF (val, 1)); 17599 17600 if (eol_flag) 17601 { 17602 /* The EOL conversion that is normal on this system. */ 17603 17604 if (NILP (eolvalue)) /* Not yet decided. */ 17605 eoltype = eol_mnemonic_undecided; 17606 else if (VECTORP (eolvalue)) /* Not yet decided. */ 17607 eoltype = eol_mnemonic_undecided; 17608 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */ 17609 eoltype = (XFASTINT (eolvalue) == 0 17610 ? eol_mnemonic_unix 17611 : (XFASTINT (eolvalue) == 1 17612 ? eol_mnemonic_dos : eol_mnemonic_mac)); 17613 } 17614 } 17615 17616 if (eol_flag) 17617 { 17618 /* Mention the EOL conversion if it is not the usual one. */ 17619 if (STRINGP (eoltype)) 17620 { 17621 eol_str = SDATA (eoltype); 17622 eol_str_len = SBYTES (eoltype); 17623 } 17624 else if (INTEGERP (eoltype) 17625 && CHAR_VALID_P (XINT (eoltype), 0)) 17626 { 17627 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH); 17628 eol_str_len = CHAR_STRING (XINT (eoltype), tmp); 17629 eol_str = tmp; 17630 } 17631 else 17632 { 17633 eol_str = invalid_eol_type; 17634 eol_str_len = sizeof (invalid_eol_type) - 1; 17635 } 17636 bcopy (eol_str, buf, eol_str_len); 17637 buf += eol_str_len; 17638 } 17639 17640 return buf; 17641} 17642 17643/* Return a string for the output of a mode line %-spec for window W, 17644 generated by character C. PRECISION >= 0 means don't return a 17645 string longer than that value. FIELD_WIDTH > 0 means pad the 17646 string returned with spaces to that value. Return 1 in *MULTIBYTE 17647 if the result is multibyte text. 17648 17649 Note we operate on the current buffer for most purposes, 17650 the exception being w->base_line_pos. */ 17651 17652static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------"; 17653 17654static char * 17655decode_mode_spec (w, c, field_width, precision, multibyte) 17656 struct window *w; 17657 register int c; 17658 int field_width, precision; 17659 int *multibyte; 17660{ 17661 Lisp_Object obj; 17662 struct frame *f = XFRAME (WINDOW_FRAME (w)); 17663 char *decode_mode_spec_buf = f->decode_mode_spec_buffer; 17664 struct buffer *b = current_buffer; 17665 17666 obj = Qnil; 17667 *multibyte = 0; 17668 17669 switch (c) 17670 { 17671 case '*': 17672 if (!NILP (b->read_only)) 17673 return "%"; 17674 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) 17675 return "*"; 17676 return "-"; 17677 17678 case '+': 17679 /* This differs from %* only for a modified read-only buffer. */ 17680 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) 17681 return "*"; 17682 if (!NILP (b->read_only)) 17683 return "%"; 17684 return "-"; 17685 17686 case '&': 17687 /* This differs from %* in ignoring read-only-ness. */ 17688 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) 17689 return "*"; 17690 return "-"; 17691 17692 case '%': 17693 return "%"; 17694 17695 case '[': 17696 { 17697 int i; 17698 char *p; 17699 17700 if (command_loop_level > 5) 17701 return "[[[... "; 17702 p = decode_mode_spec_buf; 17703 for (i = 0; i < command_loop_level; i++) 17704 *p++ = '['; 17705 *p = 0; 17706 return decode_mode_spec_buf; 17707 } 17708 17709 case ']': 17710 { 17711 int i; 17712 char *p; 17713 17714 if (command_loop_level > 5) 17715 return " ...]]]"; 17716 p = decode_mode_spec_buf; 17717 for (i = 0; i < command_loop_level; i++) 17718 *p++ = ']'; 17719 *p = 0; 17720 return decode_mode_spec_buf; 17721 } 17722 17723 case '-': 17724 { 17725 register int i; 17726 17727 /* Let lots_of_dashes be a string of infinite length. */ 17728 if (mode_line_target == MODE_LINE_NOPROP || 17729 mode_line_target == MODE_LINE_STRING) 17730 return "--"; 17731 if (field_width <= 0 17732 || field_width > sizeof (lots_of_dashes)) 17733 { 17734 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i) 17735 decode_mode_spec_buf[i] = '-'; 17736 decode_mode_spec_buf[i] = '\0'; 17737 return decode_mode_spec_buf; 17738 } 17739 else 17740 return lots_of_dashes; 17741 } 17742 17743 case 'b': 17744 obj = b->name; 17745 break; 17746 17747 case 'c': 17748 /* %c and %l are ignored in `frame-title-format'. 17749 (In redisplay_internal, the frame title is drawn _before_ the 17750 windows are updated, so the stuff which depends on actual 17751 window contents (such as %l) may fail to render properly, or 17752 even crash emacs.) */ 17753 if (mode_line_target == MODE_LINE_TITLE) 17754 return ""; 17755 else 17756 { 17757 int col = (int) current_column (); /* iftc */ 17758 w->column_number_displayed = make_number (col); 17759 pint2str (decode_mode_spec_buf, field_width, col); 17760 return decode_mode_spec_buf; 17761 } 17762 17763 case 'e': 17764#ifndef SYSTEM_MALLOC 17765 { 17766 if (NILP (Vmemory_full)) 17767 return ""; 17768 else 17769 return "!MEM FULL! "; 17770 } 17771#else 17772 return ""; 17773#endif 17774 17775 case 'F': 17776 /* %F displays the frame name. */ 17777 if (!NILP (f->title)) 17778 return (char *) SDATA (f->title); 17779 if (f->explicit_name || ! FRAME_WINDOW_P (f)) 17780 return (char *) SDATA (f->name); 17781 return "Emacs"; 17782 17783 case 'f': 17784 obj = b->filename; 17785 break; 17786 17787 case 'i': 17788 { 17789 int size = ZV - BEGV; 17790 pint2str (decode_mode_spec_buf, field_width, size); 17791 return decode_mode_spec_buf; 17792 } 17793 17794 case 'I': 17795 { 17796 int size = ZV - BEGV; 17797 pint2hrstr (decode_mode_spec_buf, field_width, size); 17798 return decode_mode_spec_buf; 17799 } 17800 17801 case 'l': 17802 { 17803 int startpos, startpos_byte, line, linepos, linepos_byte; 17804 int topline, nlines, junk, height; 17805 17806 /* %c and %l are ignored in `frame-title-format'. */ 17807 if (mode_line_target == MODE_LINE_TITLE) 17808 return ""; 17809 17810 startpos = XMARKER (w->start)->charpos; 17811 startpos_byte = marker_byte_position (w->start); 17812 height = WINDOW_TOTAL_LINES (w); 17813 17814 /* If we decided that this buffer isn't suitable for line numbers, 17815 don't forget that too fast. */ 17816 if (EQ (w->base_line_pos, w->buffer)) 17817 goto no_value; 17818 /* But do forget it, if the window shows a different buffer now. */ 17819 else if (BUFFERP (w->base_line_pos)) 17820 w->base_line_pos = Qnil; 17821 17822 /* If the buffer is very big, don't waste time. */ 17823 if (INTEGERP (Vline_number_display_limit) 17824 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit)) 17825 { 17826 w->base_line_pos = Qnil; 17827 w->base_line_number = Qnil; 17828 goto no_value; 17829 } 17830 17831 if (!NILP (w->base_line_number) 17832 && !NILP (w->base_line_pos) 17833 && XFASTINT (w->base_line_pos) <= startpos) 17834 { 17835 line = XFASTINT (w->base_line_number); 17836 linepos = XFASTINT (w->base_line_pos); 17837 linepos_byte = buf_charpos_to_bytepos (b, linepos); 17838 } 17839 else 17840 { 17841 line = 1; 17842 linepos = BUF_BEGV (b); 17843 linepos_byte = BUF_BEGV_BYTE (b); 17844 } 17845 17846 /* Count lines from base line to window start position. */ 17847 nlines = display_count_lines (linepos, linepos_byte, 17848 startpos_byte, 17849 startpos, &junk); 17850 17851 topline = nlines + line; 17852 17853 /* Determine a new base line, if the old one is too close 17854 or too far away, or if we did not have one. 17855 "Too close" means it's plausible a scroll-down would 17856 go back past it. */ 17857 if (startpos == BUF_BEGV (b)) 17858 { 17859 w->base_line_number = make_number (topline); 17860 w->base_line_pos = make_number (BUF_BEGV (b)); 17861 } 17862 else if (nlines < height + 25 || nlines > height * 3 + 50 17863 || linepos == BUF_BEGV (b)) 17864 { 17865 int limit = BUF_BEGV (b); 17866 int limit_byte = BUF_BEGV_BYTE (b); 17867 int position; 17868 int distance = (height * 2 + 30) * line_number_display_limit_width; 17869 17870 if (startpos - distance > limit) 17871 { 17872 limit = startpos - distance; 17873 limit_byte = CHAR_TO_BYTE (limit); 17874 } 17875 17876 nlines = display_count_lines (startpos, startpos_byte, 17877 limit_byte, 17878 - (height * 2 + 30), 17879 &position); 17880 /* If we couldn't find the lines we wanted within 17881 line_number_display_limit_width chars per line, 17882 give up on line numbers for this window. */ 17883 if (position == limit_byte && limit == startpos - distance) 17884 { 17885 w->base_line_pos = w->buffer; 17886 w->base_line_number = Qnil; 17887 goto no_value; 17888 } 17889 17890 w->base_line_number = make_number (topline - nlines); 17891 w->base_line_pos = make_number (BYTE_TO_CHAR (position)); 17892 } 17893 17894 /* Now count lines from the start pos to point. */ 17895 nlines = display_count_lines (startpos, startpos_byte, 17896 PT_BYTE, PT, &junk); 17897 17898 /* Record that we did display the line number. */ 17899 line_number_displayed = 1; 17900 17901 /* Make the string to show. */ 17902 pint2str (decode_mode_spec_buf, field_width, topline + nlines); 17903 return decode_mode_spec_buf; 17904 no_value: 17905 { 17906 char* p = decode_mode_spec_buf; 17907 int pad = field_width - 2; 17908 while (pad-- > 0) 17909 *p++ = ' '; 17910 *p++ = '?'; 17911 *p++ = '?'; 17912 *p = '\0'; 17913 return decode_mode_spec_buf; 17914 } 17915 } 17916 break; 17917 17918 case 'm': 17919 obj = b->mode_name; 17920 break; 17921 17922 case 'n': 17923 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b)) 17924 return " Narrow"; 17925 break; 17926 17927 case 'p': 17928 { 17929 int pos = marker_position (w->start); 17930 int total = BUF_ZV (b) - BUF_BEGV (b); 17931 17932 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b)) 17933 { 17934 if (pos <= BUF_BEGV (b)) 17935 return "All"; 17936 else 17937 return "Bottom"; 17938 } 17939 else if (pos <= BUF_BEGV (b)) 17940 return "Top"; 17941 else 17942 { 17943 if (total > 1000000) 17944 /* Do it differently for a large value, to avoid overflow. */ 17945 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100); 17946 else 17947 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total; 17948 /* We can't normally display a 3-digit number, 17949 so get us a 2-digit number that is close. */ 17950 if (total == 100) 17951 total = 99; 17952 sprintf (decode_mode_spec_buf, "%2d%%", total); 17953 return decode_mode_spec_buf; 17954 } 17955 } 17956 17957 /* Display percentage of size above the bottom of the screen. */ 17958 case 'P': 17959 { 17960 int toppos = marker_position (w->start); 17961 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos); 17962 int total = BUF_ZV (b) - BUF_BEGV (b); 17963 17964 if (botpos >= BUF_ZV (b)) 17965 { 17966 if (toppos <= BUF_BEGV (b)) 17967 return "All"; 17968 else 17969 return "Bottom"; 17970 } 17971 else 17972 { 17973 if (total > 1000000) 17974 /* Do it differently for a large value, to avoid overflow. */ 17975 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100); 17976 else 17977 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total; 17978 /* We can't normally display a 3-digit number, 17979 so get us a 2-digit number that is close. */ 17980 if (total == 100) 17981 total = 99; 17982 if (toppos <= BUF_BEGV (b)) 17983 sprintf (decode_mode_spec_buf, "Top%2d%%", total); 17984 else 17985 sprintf (decode_mode_spec_buf, "%2d%%", total); 17986 return decode_mode_spec_buf; 17987 } 17988 } 17989 17990 case 's': 17991 /* status of process */ 17992 obj = Fget_buffer_process (Fcurrent_buffer ()); 17993 if (NILP (obj)) 17994 return "no process"; 17995#ifdef subprocesses 17996 obj = Fsymbol_name (Fprocess_status (obj)); 17997#endif 17998 break; 17999 18000 case 't': /* indicate TEXT or BINARY */ 18001#ifdef MODE_LINE_BINARY_TEXT 18002 return MODE_LINE_BINARY_TEXT (b); 18003#else 18004 return "T"; 18005#endif 18006 18007 case 'z': 18008 /* coding-system (not including end-of-line format) */ 18009 case 'Z': 18010 /* coding-system (including end-of-line type) */ 18011 { 18012 int eol_flag = (c == 'Z'); 18013 char *p = decode_mode_spec_buf; 18014 18015 if (! FRAME_WINDOW_P (f)) 18016 { 18017 /* No need to mention EOL here--the terminal never needs 18018 to do EOL conversion. */ 18019 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0); 18020 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0); 18021 } 18022 p = decode_mode_spec_coding (b->buffer_file_coding_system, 18023 p, eol_flag); 18024 18025#if 0 /* This proves to be annoying; I think we can do without. -- rms. */ 18026#ifdef subprocesses 18027 obj = Fget_buffer_process (Fcurrent_buffer ()); 18028 if (PROCESSP (obj)) 18029 { 18030 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system, 18031 p, eol_flag); 18032 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system, 18033 p, eol_flag); 18034 } 18035#endif /* subprocesses */ 18036#endif /* 0 */ 18037 *p = 0; 18038 return decode_mode_spec_buf; 18039 } 18040 } 18041 18042 if (STRINGP (obj)) 18043 { 18044 *multibyte = STRING_MULTIBYTE (obj); 18045 return (char *) SDATA (obj); 18046 } 18047 else 18048 return ""; 18049} 18050 18051 18052/* Count up to COUNT lines starting from START / START_BYTE. 18053 But don't go beyond LIMIT_BYTE. 18054 Return the number of lines thus found (always nonnegative). 18055 18056 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */ 18057 18058static int 18059display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr) 18060 int start, start_byte, limit_byte, count; 18061 int *byte_pos_ptr; 18062{ 18063 register unsigned char *cursor; 18064 unsigned char *base; 18065 18066 register int ceiling; 18067 register unsigned char *ceiling_addr; 18068 int orig_count = count; 18069 18070 /* If we are not in selective display mode, 18071 check only for newlines. */ 18072 int selective_display = (!NILP (current_buffer->selective_display) 18073 && !INTEGERP (current_buffer->selective_display)); 18074 18075 if (count > 0) 18076 { 18077 while (start_byte < limit_byte) 18078 { 18079 ceiling = BUFFER_CEILING_OF (start_byte); 18080 ceiling = min (limit_byte - 1, ceiling); 18081 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; 18082 base = (cursor = BYTE_POS_ADDR (start_byte)); 18083 while (1) 18084 { 18085 if (selective_display) 18086 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) 18087 ; 18088 else 18089 while (*cursor != '\n' && ++cursor != ceiling_addr) 18090 ; 18091 18092 if (cursor != ceiling_addr) 18093 { 18094 if (--count == 0) 18095 { 18096 start_byte += cursor - base + 1; 18097 *byte_pos_ptr = start_byte; 18098 return orig_count; 18099 } 18100 else 18101 if (++cursor == ceiling_addr) 18102 break; 18103 } 18104 else 18105 break; 18106 } 18107 start_byte += cursor - base; 18108 } 18109 } 18110 else 18111 { 18112 while (start_byte > limit_byte) 18113 { 18114 ceiling = BUFFER_FLOOR_OF (start_byte - 1); 18115 ceiling = max (limit_byte, ceiling); 18116 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; 18117 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); 18118 while (1) 18119 { 18120 if (selective_display) 18121 while (--cursor != ceiling_addr 18122 && *cursor != '\n' && *cursor != 015) 18123 ; 18124 else 18125 while (--cursor != ceiling_addr && *cursor != '\n') 18126 ; 18127 18128 if (cursor != ceiling_addr) 18129 { 18130 if (++count == 0) 18131 { 18132 start_byte += cursor - base + 1; 18133 *byte_pos_ptr = start_byte; 18134 /* When scanning backwards, we should 18135 not count the newline posterior to which we stop. */ 18136 return - orig_count - 1; 18137 } 18138 } 18139 else 18140 break; 18141 } 18142 /* Here we add 1 to compensate for the last decrement 18143 of CURSOR, which took it past the valid range. */ 18144 start_byte += cursor - base + 1; 18145 } 18146 } 18147 18148 *byte_pos_ptr = limit_byte; 18149 18150 if (count < 0) 18151 return - orig_count + count; 18152 return orig_count - count; 18153 18154} 18155 18156 18157 18158/*********************************************************************** 18159 Displaying strings 18160 ***********************************************************************/ 18161 18162/* Display a NUL-terminated string, starting with index START. 18163 18164 If STRING is non-null, display that C string. Otherwise, the Lisp 18165 string LISP_STRING is displayed. 18166 18167 If FACE_STRING is not nil, FACE_STRING_POS is a position in 18168 FACE_STRING. Display STRING or LISP_STRING with the face at 18169 FACE_STRING_POS in FACE_STRING: 18170 18171 Display the string in the environment given by IT, but use the 18172 standard display table, temporarily. 18173 18174 FIELD_WIDTH is the minimum number of output glyphs to produce. 18175 If STRING has fewer characters than FIELD_WIDTH, pad to the right 18176 with spaces. If STRING has more characters, more than FIELD_WIDTH 18177 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad. 18178 18179 PRECISION is the maximum number of characters to output from 18180 STRING. PRECISION < 0 means don't truncate the string. 18181 18182 This is roughly equivalent to printf format specifiers: 18183 18184 FIELD_WIDTH PRECISION PRINTF 18185 ---------------------------------------- 18186 -1 -1 %s 18187 -1 10 %.10s 18188 10 -1 %10s 18189 20 10 %20.10s 18190 18191 MULTIBYTE zero means do not display multibyte chars, > 0 means do 18192 display them, and < 0 means obey the current buffer's value of 18193 enable_multibyte_characters. 18194 18195 Value is the number of columns displayed. */ 18196 18197static int 18198display_string (string, lisp_string, face_string, face_string_pos, 18199 start, it, field_width, precision, max_x, multibyte) 18200 unsigned char *string; 18201 Lisp_Object lisp_string; 18202 Lisp_Object face_string; 18203 int face_string_pos; 18204 int start; 18205 struct it *it; 18206 int field_width, precision, max_x; 18207 int multibyte; 18208{ 18209 int hpos_at_start = it->hpos; 18210 int saved_face_id = it->face_id; 18211 struct glyph_row *row = it->glyph_row; 18212 18213 /* Initialize the iterator IT for iteration over STRING beginning 18214 with index START. */ 18215 reseat_to_string (it, string, lisp_string, start, 18216 precision, field_width, multibyte); 18217 18218 /* If displaying STRING, set up the face of the iterator 18219 from LISP_STRING, if that's given. */ 18220 if (STRINGP (face_string)) 18221 { 18222 int endptr; 18223 struct face *face; 18224 18225 it->face_id 18226 = face_at_string_position (it->w, face_string, face_string_pos, 18227 0, it->region_beg_charpos, 18228 it->region_end_charpos, 18229 &endptr, it->base_face_id, 0); 18230 face = FACE_FROM_ID (it->f, it->face_id); 18231 it->face_box_p = face->box != FACE_NO_BOX; 18232 } 18233 18234 /* Set max_x to the maximum allowed X position. Don't let it go 18235 beyond the right edge of the window. */ 18236 if (max_x <= 0) 18237 max_x = it->last_visible_x; 18238 else 18239 max_x = min (max_x, it->last_visible_x); 18240 18241 /* Skip over display elements that are not visible. because IT->w is 18242 hscrolled. */ 18243 if (it->current_x < it->first_visible_x) 18244 move_it_in_display_line_to (it, 100000, it->first_visible_x, 18245 MOVE_TO_POS | MOVE_TO_X); 18246 18247 row->ascent = it->max_ascent; 18248 row->height = it->max_ascent + it->max_descent; 18249 row->phys_ascent = it->max_phys_ascent; 18250 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 18251 row->extra_line_spacing = it->max_extra_line_spacing; 18252 18253 /* This condition is for the case that we are called with current_x 18254 past last_visible_x. */ 18255 while (it->current_x < max_x) 18256 { 18257 int x_before, x, n_glyphs_before, i, nglyphs; 18258 18259 /* Get the next display element. */ 18260 if (!get_next_display_element (it)) 18261 break; 18262 18263 /* Produce glyphs. */ 18264 x_before = it->current_x; 18265 n_glyphs_before = it->glyph_row->used[TEXT_AREA]; 18266 PRODUCE_GLYPHS (it); 18267 18268 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before; 18269 i = 0; 18270 x = x_before; 18271 while (i < nglyphs) 18272 { 18273 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i; 18274 18275 if (!it->truncate_lines_p 18276 && x + glyph->pixel_width > max_x) 18277 { 18278 /* End of continued line or max_x reached. */ 18279 if (CHAR_GLYPH_PADDING_P (*glyph)) 18280 { 18281 /* A wide character is unbreakable. */ 18282 it->glyph_row->used[TEXT_AREA] = n_glyphs_before; 18283 it->current_x = x_before; 18284 } 18285 else 18286 { 18287 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i; 18288 it->current_x = x; 18289 } 18290 break; 18291 } 18292 else if (x + glyph->pixel_width > it->first_visible_x) 18293 { 18294 /* Glyph is at least partially visible. */ 18295 ++it->hpos; 18296 if (x < it->first_visible_x) 18297 it->glyph_row->x = x - it->first_visible_x; 18298 } 18299 else 18300 { 18301 /* Glyph is off the left margin of the display area. 18302 Should not happen. */ 18303 abort (); 18304 } 18305 18306 row->ascent = max (row->ascent, it->max_ascent); 18307 row->height = max (row->height, it->max_ascent + it->max_descent); 18308 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent); 18309 row->phys_height = max (row->phys_height, 18310 it->max_phys_ascent + it->max_phys_descent); 18311 row->extra_line_spacing = max (row->extra_line_spacing, 18312 it->max_extra_line_spacing); 18313 x += glyph->pixel_width; 18314 ++i; 18315 } 18316 18317 /* Stop if max_x reached. */ 18318 if (i < nglyphs) 18319 break; 18320 18321 /* Stop at line ends. */ 18322 if (ITERATOR_AT_END_OF_LINE_P (it)) 18323 { 18324 it->continuation_lines_width = 0; 18325 break; 18326 } 18327 18328 set_iterator_to_next (it, 1); 18329 18330 /* Stop if truncating at the right edge. */ 18331 if (it->truncate_lines_p 18332 && it->current_x >= it->last_visible_x) 18333 { 18334 /* Add truncation mark, but don't do it if the line is 18335 truncated at a padding space. */ 18336 if (IT_CHARPOS (*it) < it->string_nchars) 18337 { 18338 if (!FRAME_WINDOW_P (it->f)) 18339 { 18340 int i, n; 18341 18342 if (it->current_x > it->last_visible_x) 18343 { 18344 for (i = row->used[TEXT_AREA] - 1; i > 0; --i) 18345 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i])) 18346 break; 18347 for (n = row->used[TEXT_AREA]; i < n; ++i) 18348 { 18349 row->used[TEXT_AREA] = i; 18350 produce_special_glyphs (it, IT_TRUNCATION); 18351 } 18352 } 18353 produce_special_glyphs (it, IT_TRUNCATION); 18354 } 18355 it->glyph_row->truncated_on_right_p = 1; 18356 } 18357 break; 18358 } 18359 } 18360 18361 /* Maybe insert a truncation at the left. */ 18362 if (it->first_visible_x 18363 && IT_CHARPOS (*it) > 0) 18364 { 18365 if (!FRAME_WINDOW_P (it->f)) 18366 insert_left_trunc_glyphs (it); 18367 it->glyph_row->truncated_on_left_p = 1; 18368 } 18369 18370 it->face_id = saved_face_id; 18371 18372 /* Value is number of columns displayed. */ 18373 return it->hpos - hpos_at_start; 18374} 18375 18376 18377 18378/* This is like a combination of memq and assq. Return 1/2 if PROPVAL 18379 appears as an element of LIST or as the car of an element of LIST. 18380 If PROPVAL is a list, compare each element against LIST in that 18381 way, and return 1/2 if any element of PROPVAL is found in LIST. 18382 Otherwise return 0. This function cannot quit. 18383 The return value is 2 if the text is invisible but with an ellipsis 18384 and 1 if it's invisible and without an ellipsis. */ 18385 18386int 18387invisible_p (propval, list) 18388 register Lisp_Object propval; 18389 Lisp_Object list; 18390{ 18391 register Lisp_Object tail, proptail; 18392 18393 for (tail = list; CONSP (tail); tail = XCDR (tail)) 18394 { 18395 register Lisp_Object tem; 18396 tem = XCAR (tail); 18397 if (EQ (propval, tem)) 18398 return 1; 18399 if (CONSP (tem) && EQ (propval, XCAR (tem))) 18400 return NILP (XCDR (tem)) ? 1 : 2; 18401 } 18402 18403 if (CONSP (propval)) 18404 { 18405 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail)) 18406 { 18407 Lisp_Object propelt; 18408 propelt = XCAR (proptail); 18409 for (tail = list; CONSP (tail); tail = XCDR (tail)) 18410 { 18411 register Lisp_Object tem; 18412 tem = XCAR (tail); 18413 if (EQ (propelt, tem)) 18414 return 1; 18415 if (CONSP (tem) && EQ (propelt, XCAR (tem))) 18416 return NILP (XCDR (tem)) ? 1 : 2; 18417 } 18418 } 18419 } 18420 18421 return 0; 18422} 18423 18424/* Calculate a width or height in pixels from a specification using 18425 the following elements: 18426 18427 SPEC ::= 18428 NUM - a (fractional) multiple of the default font width/height 18429 (NUM) - specifies exactly NUM pixels 18430 UNIT - a fixed number of pixels, see below. 18431 ELEMENT - size of a display element in pixels, see below. 18432 (NUM . SPEC) - equals NUM * SPEC 18433 (+ SPEC SPEC ...) - add pixel values 18434 (- SPEC SPEC ...) - subtract pixel values 18435 (- SPEC) - negate pixel value 18436 18437 NUM ::= 18438 INT or FLOAT - a number constant 18439 SYMBOL - use symbol's (buffer local) variable binding. 18440 18441 UNIT ::= 18442 in - pixels per inch *) 18443 mm - pixels per 1/1000 meter *) 18444 cm - pixels per 1/100 meter *) 18445 width - width of current font in pixels. 18446 height - height of current font in pixels. 18447 18448 *) using the ratio(s) defined in display-pixels-per-inch. 18449 18450 ELEMENT ::= 18451 18452 left-fringe - left fringe width in pixels 18453 right-fringe - right fringe width in pixels 18454 18455 left-margin - left margin width in pixels 18456 right-margin - right margin width in pixels 18457 18458 scroll-bar - scroll-bar area width in pixels 18459 18460 Examples: 18461 18462 Pixels corresponding to 5 inches: 18463 (5 . in) 18464 18465 Total width of non-text areas on left side of window (if scroll-bar is on left): 18466 '(space :width (+ left-fringe left-margin scroll-bar)) 18467 18468 Align to first text column (in header line): 18469 '(space :align-to 0) 18470 18471 Align to middle of text area minus half the width of variable `my-image' 18472 containing a loaded image: 18473 '(space :align-to (0.5 . (- text my-image))) 18474 18475 Width of left margin minus width of 1 character in the default font: 18476 '(space :width (- left-margin 1)) 18477 18478 Width of left margin minus width of 2 characters in the current font: 18479 '(space :width (- left-margin (2 . width))) 18480 18481 Center 1 character over left-margin (in header line): 18482 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5)) 18483 18484 Different ways to express width of left fringe plus left margin minus one pixel: 18485 '(space :width (- (+ left-fringe left-margin) (1))) 18486 '(space :width (+ left-fringe left-margin (- (1)))) 18487 '(space :width (+ left-fringe left-margin (-1))) 18488 18489*/ 18490 18491#define NUMVAL(X) \ 18492 ((INTEGERP (X) || FLOATP (X)) \ 18493 ? XFLOATINT (X) \ 18494 : - 1) 18495 18496int 18497calc_pixel_width_or_height (res, it, prop, font, width_p, align_to) 18498 double *res; 18499 struct it *it; 18500 Lisp_Object prop; 18501 void *font; 18502 int width_p, *align_to; 18503{ 18504 double pixels; 18505 18506#define OK_PIXELS(val) ((*res = (double)(val)), 1) 18507#define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1) 18508 18509 if (NILP (prop)) 18510 return OK_PIXELS (0); 18511 18512 if (SYMBOLP (prop)) 18513 { 18514 if (SCHARS (SYMBOL_NAME (prop)) == 2) 18515 { 18516 char *unit = SDATA (SYMBOL_NAME (prop)); 18517 18518 if (unit[0] == 'i' && unit[1] == 'n') 18519 pixels = 1.0; 18520 else if (unit[0] == 'm' && unit[1] == 'm') 18521 pixels = 25.4; 18522 else if (unit[0] == 'c' && unit[1] == 'm') 18523 pixels = 2.54; 18524 else 18525 pixels = 0; 18526 if (pixels > 0) 18527 { 18528 double ppi; 18529#ifdef HAVE_WINDOW_SYSTEM 18530 if (FRAME_WINDOW_P (it->f) 18531 && (ppi = (width_p 18532 ? FRAME_X_DISPLAY_INFO (it->f)->resx 18533 : FRAME_X_DISPLAY_INFO (it->f)->resy), 18534 ppi > 0)) 18535 return OK_PIXELS (ppi / pixels); 18536#endif 18537 18538 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0) 18539 || (CONSP (Vdisplay_pixels_per_inch) 18540 && (ppi = (width_p 18541 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch)) 18542 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))), 18543 ppi > 0))) 18544 return OK_PIXELS (ppi / pixels); 18545 18546 return 0; 18547 } 18548 } 18549 18550#ifdef HAVE_WINDOW_SYSTEM 18551 if (EQ (prop, Qheight)) 18552 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f)); 18553 if (EQ (prop, Qwidth)) 18554 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f)); 18555#else 18556 if (EQ (prop, Qheight) || EQ (prop, Qwidth)) 18557 return OK_PIXELS (1); 18558#endif 18559 18560 if (EQ (prop, Qtext)) 18561 return OK_PIXELS (width_p 18562 ? window_box_width (it->w, TEXT_AREA) 18563 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w)); 18564 18565 if (align_to && *align_to < 0) 18566 { 18567 *res = 0; 18568 if (EQ (prop, Qleft)) 18569 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)); 18570 if (EQ (prop, Qright)) 18571 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA)); 18572 if (EQ (prop, Qcenter)) 18573 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA) 18574 + window_box_width (it->w, TEXT_AREA) / 2); 18575 if (EQ (prop, Qleft_fringe)) 18576 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w) 18577 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w) 18578 : window_box_right_offset (it->w, LEFT_MARGIN_AREA)); 18579 if (EQ (prop, Qright_fringe)) 18580 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w) 18581 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA) 18582 : window_box_right_offset (it->w, TEXT_AREA)); 18583 if (EQ (prop, Qleft_margin)) 18584 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA)); 18585 if (EQ (prop, Qright_margin)) 18586 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA)); 18587 if (EQ (prop, Qscroll_bar)) 18588 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w) 18589 ? 0 18590 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA) 18591 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w) 18592 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w) 18593 : 0))); 18594 } 18595 else 18596 { 18597 if (EQ (prop, Qleft_fringe)) 18598 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w)); 18599 if (EQ (prop, Qright_fringe)) 18600 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w)); 18601 if (EQ (prop, Qleft_margin)) 18602 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w)); 18603 if (EQ (prop, Qright_margin)) 18604 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w)); 18605 if (EQ (prop, Qscroll_bar)) 18606 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)); 18607 } 18608 18609 prop = Fbuffer_local_value (prop, it->w->buffer); 18610 } 18611 18612 if (INTEGERP (prop) || FLOATP (prop)) 18613 { 18614 int base_unit = (width_p 18615 ? FRAME_COLUMN_WIDTH (it->f) 18616 : FRAME_LINE_HEIGHT (it->f)); 18617 return OK_PIXELS (XFLOATINT (prop) * base_unit); 18618 } 18619 18620 if (CONSP (prop)) 18621 { 18622 Lisp_Object car = XCAR (prop); 18623 Lisp_Object cdr = XCDR (prop); 18624 18625 if (SYMBOLP (car)) 18626 { 18627#ifdef HAVE_WINDOW_SYSTEM 18628 if (valid_image_p (prop)) 18629 { 18630 int id = lookup_image (it->f, prop); 18631 struct image *img = IMAGE_FROM_ID (it->f, id); 18632 18633 return OK_PIXELS (width_p ? img->width : img->height); 18634 } 18635#endif 18636 if (EQ (car, Qplus) || EQ (car, Qminus)) 18637 { 18638 int first = 1; 18639 double px; 18640 18641 pixels = 0; 18642 while (CONSP (cdr)) 18643 { 18644 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), 18645 font, width_p, align_to)) 18646 return 0; 18647 if (first) 18648 pixels = (EQ (car, Qplus) ? px : -px), first = 0; 18649 else 18650 pixels += px; 18651 cdr = XCDR (cdr); 18652 } 18653 if (EQ (car, Qminus)) 18654 pixels = -pixels; 18655 return OK_PIXELS (pixels); 18656 } 18657 18658 car = Fbuffer_local_value (car, it->w->buffer); 18659 } 18660 18661 if (INTEGERP (car) || FLOATP (car)) 18662 { 18663 double fact; 18664 pixels = XFLOATINT (car); 18665 if (NILP (cdr)) 18666 return OK_PIXELS (pixels); 18667 if (calc_pixel_width_or_height (&fact, it, cdr, 18668 font, width_p, align_to)) 18669 return OK_PIXELS (pixels * fact); 18670 return 0; 18671 } 18672 18673 return 0; 18674 } 18675 18676 return 0; 18677} 18678 18679 18680/*********************************************************************** 18681 Glyph Display 18682 ***********************************************************************/ 18683 18684#ifdef HAVE_WINDOW_SYSTEM 18685 18686#if GLYPH_DEBUG 18687 18688void 18689dump_glyph_string (s) 18690 struct glyph_string *s; 18691{ 18692 fprintf (stderr, "glyph string\n"); 18693 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n", 18694 s->x, s->y, s->width, s->height); 18695 fprintf (stderr, " ybase = %d\n", s->ybase); 18696 fprintf (stderr, " hl = %d\n", s->hl); 18697 fprintf (stderr, " left overhang = %d, right = %d\n", 18698 s->left_overhang, s->right_overhang); 18699 fprintf (stderr, " nchars = %d\n", s->nchars); 18700 fprintf (stderr, " extends to end of line = %d\n", 18701 s->extends_to_end_of_line_p); 18702 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font)); 18703 fprintf (stderr, " bg width = %d\n", s->background_width); 18704} 18705 18706#endif /* GLYPH_DEBUG */ 18707 18708/* Initialize glyph string S. CHAR2B is a suitably allocated vector 18709 of XChar2b structures for S; it can't be allocated in 18710 init_glyph_string because it must be allocated via `alloca'. W 18711 is the window on which S is drawn. ROW and AREA are the glyph row 18712 and area within the row from which S is constructed. START is the 18713 index of the first glyph structure covered by S. HL is a 18714 face-override for drawing S. */ 18715 18716#ifdef HAVE_NTGUI 18717#define OPTIONAL_HDC(hdc) hdc, 18718#define DECLARE_HDC(hdc) HDC hdc; 18719#define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f)) 18720#define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc)) 18721#endif 18722 18723#ifndef OPTIONAL_HDC 18724#define OPTIONAL_HDC(hdc) 18725#define DECLARE_HDC(hdc) 18726#define ALLOCATE_HDC(hdc, f) 18727#define RELEASE_HDC(hdc, f) 18728#endif 18729 18730static void 18731init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl) 18732 struct glyph_string *s; 18733 DECLARE_HDC (hdc) 18734 XChar2b *char2b; 18735 struct window *w; 18736 struct glyph_row *row; 18737 enum glyph_row_area area; 18738 int start; 18739 enum draw_glyphs_face hl; 18740{ 18741 bzero (s, sizeof *s); 18742 s->w = w; 18743 s->f = XFRAME (w->frame); 18744#ifdef HAVE_NTGUI 18745 s->hdc = hdc; 18746#endif 18747 s->display = FRAME_X_DISPLAY (s->f); 18748 s->window = FRAME_X_WINDOW (s->f); 18749 s->char2b = char2b; 18750 s->hl = hl; 18751 s->row = row; 18752 s->area = area; 18753 s->first_glyph = row->glyphs[area] + start; 18754 s->height = row->height; 18755 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); 18756 18757 /* Display the internal border below the tool-bar window. */ 18758 if (WINDOWP (s->f->tool_bar_window) 18759 && s->w == XWINDOW (s->f->tool_bar_window)) 18760 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f); 18761 18762 s->ybase = s->y + row->ascent; 18763} 18764 18765 18766/* Append the list of glyph strings with head H and tail T to the list 18767 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ 18768 18769static INLINE void 18770append_glyph_string_lists (head, tail, h, t) 18771 struct glyph_string **head, **tail; 18772 struct glyph_string *h, *t; 18773{ 18774 if (h) 18775 { 18776 if (*head) 18777 (*tail)->next = h; 18778 else 18779 *head = h; 18780 h->prev = *tail; 18781 *tail = t; 18782 } 18783} 18784 18785 18786/* Prepend the list of glyph strings with head H and tail T to the 18787 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the 18788 result. */ 18789 18790static INLINE void 18791prepend_glyph_string_lists (head, tail, h, t) 18792 struct glyph_string **head, **tail; 18793 struct glyph_string *h, *t; 18794{ 18795 if (h) 18796 { 18797 if (*head) 18798 (*head)->prev = t; 18799 else 18800 *tail = t; 18801 t->next = *head; 18802 *head = h; 18803 } 18804} 18805 18806 18807/* Append glyph string S to the list with head *HEAD and tail *TAIL. 18808 Set *HEAD and *TAIL to the resulting list. */ 18809 18810static INLINE void 18811append_glyph_string (head, tail, s) 18812 struct glyph_string **head, **tail; 18813 struct glyph_string *s; 18814{ 18815 s->next = s->prev = NULL; 18816 append_glyph_string_lists (head, tail, s, s); 18817} 18818 18819 18820/* Get face and two-byte form of character glyph GLYPH on frame F. 18821 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is 18822 a pointer to a realized face that is ready for display. */ 18823 18824static INLINE struct face * 18825get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p) 18826 struct frame *f; 18827 struct glyph *glyph; 18828 XChar2b *char2b; 18829 int *two_byte_p; 18830{ 18831 struct face *face; 18832 18833 xassert (glyph->type == CHAR_GLYPH); 18834 face = FACE_FROM_ID (f, glyph->face_id); 18835 18836 if (two_byte_p) 18837 *two_byte_p = 0; 18838 18839 if (!glyph->multibyte_p) 18840 { 18841 /* Unibyte case. We don't have to encode, but we have to make 18842 sure to use a face suitable for unibyte. */ 18843 STORE_XCHAR2B (char2b, 0, glyph->u.ch); 18844 } 18845 else if (glyph->u.ch < 128) 18846 { 18847 /* Case of ASCII in a face known to fit ASCII. */ 18848 STORE_XCHAR2B (char2b, 0, glyph->u.ch); 18849 } 18850 else 18851 { 18852 int c1, c2, charset; 18853 18854 /* Split characters into bytes. If c2 is -1 afterwards, C is 18855 really a one-byte character so that byte1 is zero. */ 18856 SPLIT_CHAR (glyph->u.ch, charset, c1, c2); 18857 if (c2 > 0) 18858 STORE_XCHAR2B (char2b, c1, c2); 18859 else 18860 STORE_XCHAR2B (char2b, 0, c1); 18861 18862 /* Maybe encode the character in *CHAR2B. */ 18863 if (charset != CHARSET_ASCII) 18864 { 18865 struct font_info *font_info 18866 = FONT_INFO_FROM_ID (f, face->font_info_id); 18867 if (font_info) 18868 glyph->font_type 18869 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p); 18870 } 18871 } 18872 18873 /* Make sure X resources of the face are allocated. */ 18874 xassert (face != NULL); 18875 PREPARE_FACE_FOR_DISPLAY (f, face); 18876 return face; 18877} 18878 18879 18880/* Fill glyph string S with composition components specified by S->cmp. 18881 18882 FACES is an array of faces for all components of this composition. 18883 S->gidx is the index of the first component for S. 18884 18885 OVERLAPS non-zero means S should draw the foreground only, and use 18886 its physical height for clipping. See also draw_glyphs. 18887 18888 Value is the index of a component not in S. */ 18889 18890static int 18891fill_composite_glyph_string (s, faces, overlaps) 18892 struct glyph_string *s; 18893 struct face **faces; 18894 int overlaps; 18895{ 18896 int i; 18897 18898 xassert (s); 18899 18900 s->for_overlaps = overlaps; 18901 18902 s->face = faces[s->gidx]; 18903 s->font = s->face->font; 18904 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); 18905 18906 /* For all glyphs of this composition, starting at the offset 18907 S->gidx, until we reach the end of the definition or encounter a 18908 glyph that requires the different face, add it to S. */ 18909 ++s->nchars; 18910 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i) 18911 ++s->nchars; 18912 18913 /* All glyph strings for the same composition has the same width, 18914 i.e. the width set for the first component of the composition. */ 18915 18916 s->width = s->first_glyph->pixel_width; 18917 18918 /* If the specified font could not be loaded, use the frame's 18919 default font, but record the fact that we couldn't load it in 18920 the glyph string so that we can draw rectangles for the 18921 characters of the glyph string. */ 18922 if (s->font == NULL) 18923 { 18924 s->font_not_found_p = 1; 18925 s->font = FRAME_FONT (s->f); 18926 } 18927 18928 /* Adjust base line for subscript/superscript text. */ 18929 s->ybase += s->first_glyph->voffset; 18930 18931 xassert (s->face && s->face->gc); 18932 18933 /* This glyph string must always be drawn with 16-bit functions. */ 18934 s->two_byte_p = 1; 18935 18936 return s->gidx + s->nchars; 18937} 18938 18939 18940/* Fill glyph string S from a sequence of character glyphs. 18941 18942 FACE_ID is the face id of the string. START is the index of the 18943 first glyph to consider, END is the index of the last + 1. 18944 OVERLAPS non-zero means S should draw the foreground only, and use 18945 its physical height for clipping. See also draw_glyphs. 18946 18947 Value is the index of the first glyph not in S. */ 18948 18949static int 18950fill_glyph_string (s, face_id, start, end, overlaps) 18951 struct glyph_string *s; 18952 int face_id; 18953 int start, end, overlaps; 18954{ 18955 struct glyph *glyph, *last; 18956 int voffset; 18957 int glyph_not_available_p; 18958 18959 xassert (s->f == XFRAME (s->w->frame)); 18960 xassert (s->nchars == 0); 18961 xassert (start >= 0 && end > start); 18962 18963 s->for_overlaps = overlaps, 18964 glyph = s->row->glyphs[s->area] + start; 18965 last = s->row->glyphs[s->area] + end; 18966 voffset = glyph->voffset; 18967 18968 glyph_not_available_p = glyph->glyph_not_available_p; 18969 18970 while (glyph < last 18971 && glyph->type == CHAR_GLYPH 18972 && glyph->voffset == voffset 18973 /* Same face id implies same font, nowadays. */ 18974 && glyph->face_id == face_id 18975 && glyph->glyph_not_available_p == glyph_not_available_p) 18976 { 18977 int two_byte_p; 18978 18979 s->face = get_glyph_face_and_encoding (s->f, glyph, 18980 s->char2b + s->nchars, 18981 &two_byte_p); 18982 s->two_byte_p = two_byte_p; 18983 ++s->nchars; 18984 xassert (s->nchars <= end - start); 18985 s->width += glyph->pixel_width; 18986 ++glyph; 18987 } 18988 18989 s->font = s->face->font; 18990 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); 18991 18992 /* If the specified font could not be loaded, use the frame's font, 18993 but record the fact that we couldn't load it in 18994 S->font_not_found_p so that we can draw rectangles for the 18995 characters of the glyph string. */ 18996 if (s->font == NULL || glyph_not_available_p) 18997 { 18998 s->font_not_found_p = 1; 18999 s->font = FRAME_FONT (s->f); 19000 } 19001 19002 /* Adjust base line for subscript/superscript text. */ 19003 s->ybase += voffset; 19004 19005 xassert (s->face && s->face->gc); 19006 return glyph - s->row->glyphs[s->area]; 19007} 19008 19009 19010/* Fill glyph string S from image glyph S->first_glyph. */ 19011 19012static void 19013fill_image_glyph_string (s) 19014 struct glyph_string *s; 19015{ 19016 xassert (s->first_glyph->type == IMAGE_GLYPH); 19017 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); 19018 xassert (s->img); 19019 s->slice = s->first_glyph->slice; 19020 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); 19021 s->font = s->face->font; 19022 s->width = s->first_glyph->pixel_width; 19023 19024 /* Adjust base line for subscript/superscript text. */ 19025 s->ybase += s->first_glyph->voffset; 19026} 19027 19028 19029/* Fill glyph string S from a sequence of stretch glyphs. 19030 19031 ROW is the glyph row in which the glyphs are found, AREA is the 19032 area within the row. START is the index of the first glyph to 19033 consider, END is the index of the last + 1. 19034 19035 Value is the index of the first glyph not in S. */ 19036 19037static int 19038fill_stretch_glyph_string (s, row, area, start, end) 19039 struct glyph_string *s; 19040 struct glyph_row *row; 19041 enum glyph_row_area area; 19042 int start, end; 19043{ 19044 struct glyph *glyph, *last; 19045 int voffset, face_id; 19046 19047 xassert (s->first_glyph->type == STRETCH_GLYPH); 19048 19049 glyph = s->row->glyphs[s->area] + start; 19050 last = s->row->glyphs[s->area] + end; 19051 face_id = glyph->face_id; 19052 s->face = FACE_FROM_ID (s->f, face_id); 19053 s->font = s->face->font; 19054 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); 19055 s->width = glyph->pixel_width; 19056 s->nchars = 1; 19057 voffset = glyph->voffset; 19058 19059 for (++glyph; 19060 (glyph < last 19061 && glyph->type == STRETCH_GLYPH 19062 && glyph->voffset == voffset 19063 && glyph->face_id == face_id); 19064 ++glyph) 19065 s->width += glyph->pixel_width; 19066 19067 /* Adjust base line for subscript/superscript text. */ 19068 s->ybase += voffset; 19069 19070 /* The case that face->gc == 0 is handled when drawing the glyph 19071 string by calling PREPARE_FACE_FOR_DISPLAY. */ 19072 xassert (s->face); 19073 return glyph - s->row->glyphs[s->area]; 19074} 19075 19076 19077/* EXPORT for RIF: 19078 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on 19079 frame F. Overhangs of glyphs other than type CHAR_GLYPH are 19080 assumed to be zero. */ 19081 19082void 19083x_get_glyph_overhangs (glyph, f, left, right) 19084 struct glyph *glyph; 19085 struct frame *f; 19086 int *left, *right; 19087{ 19088 *left = *right = 0; 19089 19090 if (glyph->type == CHAR_GLYPH) 19091 { 19092 XFontStruct *font; 19093 struct face *face; 19094 struct font_info *font_info; 19095 XChar2b char2b; 19096 XCharStruct *pcm; 19097 19098 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL); 19099 font = face->font; 19100 font_info = FONT_INFO_FROM_ID (f, face->font_info_id); 19101 if (font /* ++KFS: Should this be font_info ? */ 19102 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type))) 19103 { 19104 if (pcm->rbearing > pcm->width) 19105 *right = pcm->rbearing - pcm->width; 19106 if (pcm->lbearing < 0) 19107 *left = -pcm->lbearing; 19108 } 19109 } 19110} 19111 19112 19113/* Return the index of the first glyph preceding glyph string S that 19114 is overwritten by S because of S's left overhang. Value is -1 19115 if no glyphs are overwritten. */ 19116 19117static int 19118left_overwritten (s) 19119 struct glyph_string *s; 19120{ 19121 int k; 19122 19123 if (s->left_overhang) 19124 { 19125 int x = 0, i; 19126 struct glyph *glyphs = s->row->glyphs[s->area]; 19127 int first = s->first_glyph - glyphs; 19128 19129 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i) 19130 x -= glyphs[i].pixel_width; 19131 19132 k = i + 1; 19133 } 19134 else 19135 k = -1; 19136 19137 return k; 19138} 19139 19140 19141/* Return the index of the first glyph preceding glyph string S that 19142 is overwriting S because of its right overhang. Value is -1 if no 19143 glyph in front of S overwrites S. */ 19144 19145static int 19146left_overwriting (s) 19147 struct glyph_string *s; 19148{ 19149 int i, k, x; 19150 struct glyph *glyphs = s->row->glyphs[s->area]; 19151 int first = s->first_glyph - glyphs; 19152 19153 k = -1; 19154 x = 0; 19155 for (i = first - 1; i >= 0; --i) 19156 { 19157 int left, right; 19158 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); 19159 if (x + right > 0) 19160 k = i; 19161 x -= glyphs[i].pixel_width; 19162 } 19163 19164 return k; 19165} 19166 19167 19168/* Return the index of the last glyph following glyph string S that is 19169 not overwritten by S because of S's right overhang. Value is -1 if 19170 no such glyph is found. */ 19171 19172static int 19173right_overwritten (s) 19174 struct glyph_string *s; 19175{ 19176 int k = -1; 19177 19178 if (s->right_overhang) 19179 { 19180 int x = 0, i; 19181 struct glyph *glyphs = s->row->glyphs[s->area]; 19182 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); 19183 int end = s->row->used[s->area]; 19184 19185 for (i = first; i < end && s->right_overhang > x; ++i) 19186 x += glyphs[i].pixel_width; 19187 19188 k = i; 19189 } 19190 19191 return k; 19192} 19193 19194 19195/* Return the index of the last glyph following glyph string S that 19196 overwrites S because of its left overhang. Value is negative 19197 if no such glyph is found. */ 19198 19199static int 19200right_overwriting (s) 19201 struct glyph_string *s; 19202{ 19203 int i, k, x; 19204 int end = s->row->used[s->area]; 19205 struct glyph *glyphs = s->row->glyphs[s->area]; 19206 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); 19207 19208 k = -1; 19209 x = 0; 19210 for (i = first; i < end; ++i) 19211 { 19212 int left, right; 19213 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); 19214 if (x - left < 0) 19215 k = i; 19216 x += glyphs[i].pixel_width; 19217 } 19218 19219 return k; 19220} 19221 19222 19223/* Get face and two-byte form of character C in face FACE_ID on frame 19224 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero 19225 means we want to display multibyte text. DISPLAY_P non-zero means 19226 make sure that X resources for the face returned are allocated. 19227 Value is a pointer to a realized face that is ready for display if 19228 DISPLAY_P is non-zero. */ 19229 19230static INLINE struct face * 19231get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p) 19232 struct frame *f; 19233 int c, face_id; 19234 XChar2b *char2b; 19235 int multibyte_p, display_p; 19236{ 19237 struct face *face = FACE_FROM_ID (f, face_id); 19238 19239 if (!multibyte_p) 19240 { 19241 /* Unibyte case. We don't have to encode, but we have to make 19242 sure to use a face suitable for unibyte. */ 19243 STORE_XCHAR2B (char2b, 0, c); 19244 face_id = FACE_FOR_CHAR (f, face, c); 19245 face = FACE_FROM_ID (f, face_id); 19246 } 19247 else if (c < 128) 19248 { 19249 /* Case of ASCII in a face known to fit ASCII. */ 19250 STORE_XCHAR2B (char2b, 0, c); 19251 } 19252 else 19253 { 19254 int c1, c2, charset; 19255 19256 /* Split characters into bytes. If c2 is -1 afterwards, C is 19257 really a one-byte character so that byte1 is zero. */ 19258 SPLIT_CHAR (c, charset, c1, c2); 19259 if (c2 > 0) 19260 STORE_XCHAR2B (char2b, c1, c2); 19261 else 19262 STORE_XCHAR2B (char2b, 0, c1); 19263 19264 /* Maybe encode the character in *CHAR2B. */ 19265 if (face->font != NULL) 19266 { 19267 struct font_info *font_info 19268 = FONT_INFO_FROM_ID (f, face->font_info_id); 19269 if (font_info) 19270 rif->encode_char (c, char2b, font_info, 0); 19271 } 19272 } 19273 19274 /* Make sure X resources of the face are allocated. */ 19275#ifdef HAVE_X_WINDOWS 19276 if (display_p) 19277#endif 19278 { 19279 xassert (face != NULL); 19280 PREPARE_FACE_FOR_DISPLAY (f, face); 19281 } 19282 19283 return face; 19284} 19285 19286 19287/* Set background width of glyph string S. START is the index of the 19288 first glyph following S. LAST_X is the right-most x-position + 1 19289 in the drawing area. */ 19290 19291static INLINE void 19292set_glyph_string_background_width (s, start, last_x) 19293 struct glyph_string *s; 19294 int start; 19295 int last_x; 19296{ 19297 /* If the face of this glyph string has to be drawn to the end of 19298 the drawing area, set S->extends_to_end_of_line_p. */ 19299 19300 if (start == s->row->used[s->area] 19301 && s->area == TEXT_AREA 19302 && ((s->row->fill_line_p 19303 && (s->hl == DRAW_NORMAL_TEXT 19304 || s->hl == DRAW_IMAGE_RAISED 19305 || s->hl == DRAW_IMAGE_SUNKEN)) 19306 || s->hl == DRAW_MOUSE_FACE)) 19307 s->extends_to_end_of_line_p = 1; 19308 19309 /* If S extends its face to the end of the line, set its 19310 background_width to the distance to the right edge of the drawing 19311 area. */ 19312 if (s->extends_to_end_of_line_p) 19313 s->background_width = last_x - s->x + 1; 19314 else 19315 s->background_width = s->width; 19316} 19317 19318 19319/* Compute overhangs and x-positions for glyph string S and its 19320 predecessors, or successors. X is the starting x-position for S. 19321 BACKWARD_P non-zero means process predecessors. */ 19322 19323static void 19324compute_overhangs_and_x (s, x, backward_p) 19325 struct glyph_string *s; 19326 int x; 19327 int backward_p; 19328{ 19329 if (backward_p) 19330 { 19331 while (s) 19332 { 19333 if (rif->compute_glyph_string_overhangs) 19334 rif->compute_glyph_string_overhangs (s); 19335 x -= s->width; 19336 s->x = x; 19337 s = s->prev; 19338 } 19339 } 19340 else 19341 { 19342 while (s) 19343 { 19344 if (rif->compute_glyph_string_overhangs) 19345 rif->compute_glyph_string_overhangs (s); 19346 s->x = x; 19347 x += s->width; 19348 s = s->next; 19349 } 19350 } 19351} 19352 19353 19354 19355/* The following macros are only called from draw_glyphs below. 19356 They reference the following parameters of that function directly: 19357 `w', `row', `area', and `overlap_p' 19358 as well as the following local variables: 19359 `s', `f', and `hdc' (in W32) */ 19360 19361#ifdef HAVE_NTGUI 19362/* On W32, silently add local `hdc' variable to argument list of 19363 init_glyph_string. */ 19364#define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \ 19365 init_glyph_string (s, hdc, char2b, w, row, area, start, hl) 19366#else 19367#define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \ 19368 init_glyph_string (s, char2b, w, row, area, start, hl) 19369#endif 19370 19371/* Add a glyph string for a stretch glyph to the list of strings 19372 between HEAD and TAIL. START is the index of the stretch glyph in 19373 row area AREA of glyph row ROW. END is the index of the last glyph 19374 in that glyph row area. X is the current output position assigned 19375 to the new glyph string constructed. HL overrides that face of the 19376 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X 19377 is the right-most x-position of the drawing area. */ 19378 19379/* SunOS 4 bundled cc, barfed on continuations in the arg lists here 19380 and below -- keep them on one line. */ 19381#define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ 19382 do \ 19383 { \ 19384 s = (struct glyph_string *) alloca (sizeof *s); \ 19385 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \ 19386 START = fill_stretch_glyph_string (s, row, area, START, END); \ 19387 append_glyph_string (&HEAD, &TAIL, s); \ 19388 s->x = (X); \ 19389 } \ 19390 while (0) 19391 19392 19393/* Add a glyph string for an image glyph to the list of strings 19394 between HEAD and TAIL. START is the index of the image glyph in 19395 row area AREA of glyph row ROW. END is the index of the last glyph 19396 in that glyph row area. X is the current output position assigned 19397 to the new glyph string constructed. HL overrides that face of the 19398 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X 19399 is the right-most x-position of the drawing area. */ 19400 19401#define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ 19402 do \ 19403 { \ 19404 s = (struct glyph_string *) alloca (sizeof *s); \ 19405 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \ 19406 fill_image_glyph_string (s); \ 19407 append_glyph_string (&HEAD, &TAIL, s); \ 19408 ++START; \ 19409 s->x = (X); \ 19410 } \ 19411 while (0) 19412 19413 19414/* Add a glyph string for a sequence of character glyphs to the list 19415 of strings between HEAD and TAIL. START is the index of the first 19416 glyph in row area AREA of glyph row ROW that is part of the new 19417 glyph string. END is the index of the last glyph in that glyph row 19418 area. X is the current output position assigned to the new glyph 19419 string constructed. HL overrides that face of the glyph; e.g. it 19420 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the 19421 right-most x-position of the drawing area. */ 19422 19423#define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \ 19424 do \ 19425 { \ 19426 int c, face_id; \ 19427 XChar2b *char2b; \ 19428 \ 19429 c = (row)->glyphs[area][START].u.ch; \ 19430 face_id = (row)->glyphs[area][START].face_id; \ 19431 \ 19432 s = (struct glyph_string *) alloca (sizeof *s); \ 19433 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \ 19434 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \ 19435 append_glyph_string (&HEAD, &TAIL, s); \ 19436 s->x = (X); \ 19437 START = fill_glyph_string (s, face_id, START, END, overlaps); \ 19438 } \ 19439 while (0) 19440 19441 19442/* Add a glyph string for a composite sequence to the list of strings 19443 between HEAD and TAIL. START is the index of the first glyph in 19444 row area AREA of glyph row ROW that is part of the new glyph 19445 string. END is the index of the last glyph in that glyph row area. 19446 X is the current output position assigned to the new glyph string 19447 constructed. HL overrides that face of the glyph; e.g. it is 19448 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most 19449 x-position of the drawing area. */ 19450 19451#define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ 19452 do { \ 19453 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \ 19454 int face_id = (row)->glyphs[area][START].face_id; \ 19455 struct face *base_face = FACE_FROM_ID (f, face_id); \ 19456 struct composition *cmp = composition_table[cmp_id]; \ 19457 int glyph_len = cmp->glyph_len; \ 19458 XChar2b *char2b; \ 19459 struct face **faces; \ 19460 struct glyph_string *first_s = NULL; \ 19461 int n; \ 19462 \ 19463 base_face = base_face->ascii_face; \ 19464 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \ 19465 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \ 19466 /* At first, fill in `char2b' and `faces'. */ \ 19467 for (n = 0; n < glyph_len; n++) \ 19468 { \ 19469 int c = COMPOSITION_GLYPH (cmp, n); \ 19470 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \ 19471 faces[n] = FACE_FROM_ID (f, this_face_id); \ 19472 get_char_face_and_encoding (f, c, this_face_id, \ 19473 char2b + n, 1, 1); \ 19474 } \ 19475 \ 19476 /* Make glyph_strings for each glyph sequence that is drawable by \ 19477 the same face, and append them to HEAD/TAIL. */ \ 19478 for (n = 0; n < cmp->glyph_len;) \ 19479 { \ 19480 s = (struct glyph_string *) alloca (sizeof *s); \ 19481 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \ 19482 append_glyph_string (&(HEAD), &(TAIL), s); \ 19483 s->cmp = cmp; \ 19484 s->gidx = n; \ 19485 s->x = (X); \ 19486 \ 19487 if (n == 0) \ 19488 first_s = s; \ 19489 \ 19490 n = fill_composite_glyph_string (s, faces, overlaps); \ 19491 } \ 19492 \ 19493 ++START; \ 19494 s = first_s; \ 19495 } while (0) 19496 19497 19498/* Build a list of glyph strings between HEAD and TAIL for the glyphs 19499 of AREA of glyph row ROW on window W between indices START and END. 19500 HL overrides the face for drawing glyph strings, e.g. it is 19501 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end 19502 x-positions of the drawing area. 19503 19504 This is an ugly monster macro construct because we must use alloca 19505 to allocate glyph strings (because draw_glyphs can be called 19506 asynchronously). */ 19507 19508#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \ 19509 do \ 19510 { \ 19511 HEAD = TAIL = NULL; \ 19512 while (START < END) \ 19513 { \ 19514 struct glyph *first_glyph = (row)->glyphs[area] + START; \ 19515 switch (first_glyph->type) \ 19516 { \ 19517 case CHAR_GLYPH: \ 19518 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \ 19519 HL, X, LAST_X); \ 19520 break; \ 19521 \ 19522 case COMPOSITE_GLYPH: \ 19523 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \ 19524 HL, X, LAST_X); \ 19525 break; \ 19526 \ 19527 case STRETCH_GLYPH: \ 19528 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ 19529 HL, X, LAST_X); \ 19530 break; \ 19531 \ 19532 case IMAGE_GLYPH: \ 19533 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ 19534 HL, X, LAST_X); \ 19535 break; \ 19536 \ 19537 default: \ 19538 abort (); \ 19539 } \ 19540 \ 19541 set_glyph_string_background_width (s, START, LAST_X); \ 19542 (X) += s->width; \ 19543 } \ 19544 } \ 19545 while (0) 19546 19547 19548/* Draw glyphs between START and END in AREA of ROW on window W, 19549 starting at x-position X. X is relative to AREA in W. HL is a 19550 face-override with the following meaning: 19551 19552 DRAW_NORMAL_TEXT draw normally 19553 DRAW_CURSOR draw in cursor face 19554 DRAW_MOUSE_FACE draw in mouse face. 19555 DRAW_INVERSE_VIDEO draw in mode line face 19556 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it 19557 DRAW_IMAGE_RAISED draw an image with a raised relief around it 19558 19559 If OVERLAPS is non-zero, draw only the foreground of characters and 19560 clip to the physical height of ROW. Non-zero value also defines 19561 the overlapping part to be drawn: 19562 19563 OVERLAPS_PRED overlap with preceding rows 19564 OVERLAPS_SUCC overlap with succeeding rows 19565 OVERLAPS_BOTH overlap with both preceding/succeeding rows 19566 OVERLAPS_ERASED_CURSOR overlap with erased cursor area 19567 19568 Value is the x-position reached, relative to AREA of W. */ 19569 19570static int 19571draw_glyphs (w, x, row, area, start, end, hl, overlaps) 19572 struct window *w; 19573 int x; 19574 struct glyph_row *row; 19575 enum glyph_row_area area; 19576 int start, end; 19577 enum draw_glyphs_face hl; 19578 int overlaps; 19579{ 19580 struct glyph_string *head, *tail; 19581 struct glyph_string *s; 19582 struct glyph_string *clip_head = NULL, *clip_tail = NULL; 19583 int last_x, area_width; 19584 int x_reached; 19585 int i, j; 19586 struct frame *f = XFRAME (WINDOW_FRAME (w)); 19587 DECLARE_HDC (hdc); 19588 19589 ALLOCATE_HDC (hdc, f); 19590 19591 /* Let's rather be paranoid than getting a SEGV. */ 19592 end = min (end, row->used[area]); 19593 start = max (0, start); 19594 start = min (end, start); 19595 19596 /* Translate X to frame coordinates. Set last_x to the right 19597 end of the drawing area. */ 19598 if (row->full_width_p) 19599 { 19600 /* X is relative to the left edge of W, without scroll bars 19601 or fringes. */ 19602 x += WINDOW_LEFT_EDGE_X (w); 19603 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w); 19604 } 19605 else 19606 { 19607 int area_left = window_box_left (w, area); 19608 x += area_left; 19609 area_width = window_box_width (w, area); 19610 last_x = area_left + area_width; 19611 } 19612 19613 /* Build a doubly-linked list of glyph_string structures between 19614 head and tail from what we have to draw. Note that the macro 19615 BUILD_GLYPH_STRINGS will modify its start parameter. That's 19616 the reason we use a separate variable `i'. */ 19617 i = start; 19618 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x); 19619 if (tail) 19620 x_reached = tail->x + tail->background_width; 19621 else 19622 x_reached = x; 19623 19624 /* If there are any glyphs with lbearing < 0 or rbearing > width in 19625 the row, redraw some glyphs in front or following the glyph 19626 strings built above. */ 19627 if (head && !overlaps && row->contains_overlapping_glyphs_p) 19628 { 19629 int dummy_x = 0; 19630 struct glyph_string *h, *t; 19631 19632 /* Compute overhangs for all glyph strings. */ 19633 if (rif->compute_glyph_string_overhangs) 19634 for (s = head; s; s = s->next) 19635 rif->compute_glyph_string_overhangs (s); 19636 19637 /* Prepend glyph strings for glyphs in front of the first glyph 19638 string that are overwritten because of the first glyph 19639 string's left overhang. The background of all strings 19640 prepended must be drawn because the first glyph string 19641 draws over it. */ 19642 i = left_overwritten (head); 19643 if (i >= 0) 19644 { 19645 j = i; 19646 BUILD_GLYPH_STRINGS (j, start, h, t, 19647 DRAW_NORMAL_TEXT, dummy_x, last_x); 19648 start = i; 19649 compute_overhangs_and_x (t, head->x, 1); 19650 prepend_glyph_string_lists (&head, &tail, h, t); 19651 clip_head = head; 19652 } 19653 19654 /* Prepend glyph strings for glyphs in front of the first glyph 19655 string that overwrite that glyph string because of their 19656 right overhang. For these strings, only the foreground must 19657 be drawn, because it draws over the glyph string at `head'. 19658 The background must not be drawn because this would overwrite 19659 right overhangs of preceding glyphs for which no glyph 19660 strings exist. */ 19661 i = left_overwriting (head); 19662 if (i >= 0) 19663 { 19664 clip_head = head; 19665 BUILD_GLYPH_STRINGS (i, start, h, t, 19666 DRAW_NORMAL_TEXT, dummy_x, last_x); 19667 for (s = h; s; s = s->next) 19668 s->background_filled_p = 1; 19669 compute_overhangs_and_x (t, head->x, 1); 19670 prepend_glyph_string_lists (&head, &tail, h, t); 19671 } 19672 19673 /* Append glyphs strings for glyphs following the last glyph 19674 string tail that are overwritten by tail. The background of 19675 these strings has to be drawn because tail's foreground draws 19676 over it. */ 19677 i = right_overwritten (tail); 19678 if (i >= 0) 19679 { 19680 BUILD_GLYPH_STRINGS (end, i, h, t, 19681 DRAW_NORMAL_TEXT, x, last_x); 19682 compute_overhangs_and_x (h, tail->x + tail->width, 0); 19683 append_glyph_string_lists (&head, &tail, h, t); 19684 clip_tail = tail; 19685 } 19686 19687 /* Append glyph strings for glyphs following the last glyph 19688 string tail that overwrite tail. The foreground of such 19689 glyphs has to be drawn because it writes into the background 19690 of tail. The background must not be drawn because it could 19691 paint over the foreground of following glyphs. */ 19692 i = right_overwriting (tail); 19693 if (i >= 0) 19694 { 19695 clip_tail = tail; 19696 BUILD_GLYPH_STRINGS (end, i, h, t, 19697 DRAW_NORMAL_TEXT, x, last_x); 19698 for (s = h; s; s = s->next) 19699 s->background_filled_p = 1; 19700 compute_overhangs_and_x (h, tail->x + tail->width, 0); 19701 append_glyph_string_lists (&head, &tail, h, t); 19702 } 19703 if (clip_head || clip_tail) 19704 for (s = head; s; s = s->next) 19705 { 19706 s->clip_head = clip_head; 19707 s->clip_tail = clip_tail; 19708 } 19709 } 19710 19711 /* Draw all strings. */ 19712 for (s = head; s; s = s->next) 19713 rif->draw_glyph_string (s); 19714 19715 if (area == TEXT_AREA 19716 && !row->full_width_p 19717 /* When drawing overlapping rows, only the glyph strings' 19718 foreground is drawn, which doesn't erase a cursor 19719 completely. */ 19720 && !overlaps) 19721 { 19722 int x0 = clip_head ? clip_head->x : (head ? head->x : x); 19723 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width 19724 : (tail ? tail->x + tail->background_width : x)); 19725 19726 int text_left = window_box_left (w, TEXT_AREA); 19727 x0 -= text_left; 19728 x1 -= text_left; 19729 19730 notice_overwritten_cursor (w, TEXT_AREA, x0, x1, 19731 row->y, MATRIX_ROW_BOTTOM_Y (row)); 19732 } 19733 19734 /* Value is the x-position up to which drawn, relative to AREA of W. 19735 This doesn't include parts drawn because of overhangs. */ 19736 if (row->full_width_p) 19737 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached); 19738 else 19739 x_reached -= window_box_left (w, area); 19740 19741 RELEASE_HDC (hdc, f); 19742 19743 return x_reached; 19744} 19745 19746/* Expand row matrix if too narrow. Don't expand if area 19747 is not present. */ 19748 19749#define IT_EXPAND_MATRIX_WIDTH(it, area) \ 19750 { \ 19751 if (!fonts_changed_p \ 19752 && (it->glyph_row->glyphs[area] \ 19753 < it->glyph_row->glyphs[area + 1])) \ 19754 { \ 19755 it->w->ncols_scale_factor++; \ 19756 fonts_changed_p = 1; \ 19757 } \ 19758 } 19759 19760/* Store one glyph for IT->char_to_display in IT->glyph_row. 19761 Called from x_produce_glyphs when IT->glyph_row is non-null. */ 19762 19763static INLINE void 19764append_glyph (it) 19765 struct it *it; 19766{ 19767 struct glyph *glyph; 19768 enum glyph_row_area area = it->area; 19769 19770 xassert (it->glyph_row); 19771 xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); 19772 19773 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; 19774 if (glyph < it->glyph_row->glyphs[area + 1]) 19775 { 19776 glyph->charpos = CHARPOS (it->position); 19777 glyph->object = it->object; 19778 glyph->pixel_width = it->pixel_width; 19779 glyph->ascent = it->ascent; 19780 glyph->descent = it->descent; 19781 glyph->voffset = it->voffset; 19782 glyph->type = CHAR_GLYPH; 19783 glyph->multibyte_p = it->multibyte_p; 19784 glyph->left_box_line_p = it->start_of_box_run_p; 19785 glyph->right_box_line_p = it->end_of_box_run_p; 19786 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent 19787 || it->phys_descent > it->descent); 19788 glyph->padding_p = 0; 19789 glyph->glyph_not_available_p = it->glyph_not_available_p; 19790 glyph->face_id = it->face_id; 19791 glyph->u.ch = it->char_to_display; 19792 glyph->slice = null_glyph_slice; 19793 glyph->font_type = FONT_TYPE_UNKNOWN; 19794 ++it->glyph_row->used[area]; 19795 } 19796 else 19797 IT_EXPAND_MATRIX_WIDTH (it, area); 19798} 19799 19800/* Store one glyph for the composition IT->cmp_id in IT->glyph_row. 19801 Called from x_produce_glyphs when IT->glyph_row is non-null. */ 19802 19803static INLINE void 19804append_composite_glyph (it) 19805 struct it *it; 19806{ 19807 struct glyph *glyph; 19808 enum glyph_row_area area = it->area; 19809 19810 xassert (it->glyph_row); 19811 19812 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; 19813 if (glyph < it->glyph_row->glyphs[area + 1]) 19814 { 19815 glyph->charpos = CHARPOS (it->position); 19816 glyph->object = it->object; 19817 glyph->pixel_width = it->pixel_width; 19818 glyph->ascent = it->ascent; 19819 glyph->descent = it->descent; 19820 glyph->voffset = it->voffset; 19821 glyph->type = COMPOSITE_GLYPH; 19822 glyph->multibyte_p = it->multibyte_p; 19823 glyph->left_box_line_p = it->start_of_box_run_p; 19824 glyph->right_box_line_p = it->end_of_box_run_p; 19825 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent 19826 || it->phys_descent > it->descent); 19827 glyph->padding_p = 0; 19828 glyph->glyph_not_available_p = 0; 19829 glyph->face_id = it->face_id; 19830 glyph->u.cmp_id = it->cmp_id; 19831 glyph->slice = null_glyph_slice; 19832 glyph->font_type = FONT_TYPE_UNKNOWN; 19833 ++it->glyph_row->used[area]; 19834 } 19835 else 19836 IT_EXPAND_MATRIX_WIDTH (it, area); 19837} 19838 19839 19840/* Change IT->ascent and IT->height according to the setting of 19841 IT->voffset. */ 19842 19843static INLINE void 19844take_vertical_position_into_account (it) 19845 struct it *it; 19846{ 19847 if (it->voffset) 19848 { 19849 if (it->voffset < 0) 19850 /* Increase the ascent so that we can display the text higher 19851 in the line. */ 19852 it->ascent -= it->voffset; 19853 else 19854 /* Increase the descent so that we can display the text lower 19855 in the line. */ 19856 it->descent += it->voffset; 19857 } 19858} 19859 19860 19861/* Produce glyphs/get display metrics for the image IT is loaded with. 19862 See the description of struct display_iterator in dispextern.h for 19863 an overview of struct display_iterator. */ 19864 19865static void 19866produce_image_glyph (it) 19867 struct it *it; 19868{ 19869 struct image *img; 19870 struct face *face; 19871 int glyph_ascent, crop; 19872 struct glyph_slice slice; 19873 19874 xassert (it->what == IT_IMAGE); 19875 19876 face = FACE_FROM_ID (it->f, it->face_id); 19877 xassert (face); 19878 /* Make sure X resources of the face is loaded. */ 19879 PREPARE_FACE_FOR_DISPLAY (it->f, face); 19880 19881 if (it->image_id < 0) 19882 { 19883 /* Fringe bitmap. */ 19884 it->ascent = it->phys_ascent = 0; 19885 it->descent = it->phys_descent = 0; 19886 it->pixel_width = 0; 19887 it->nglyphs = 0; 19888 return; 19889 } 19890 19891 img = IMAGE_FROM_ID (it->f, it->image_id); 19892 xassert (img); 19893 /* Make sure X resources of the image is loaded. */ 19894 prepare_image_for_display (it->f, img); 19895 19896 slice.x = slice.y = 0; 19897 slice.width = img->width; 19898 slice.height = img->height; 19899 19900 if (INTEGERP (it->slice.x)) 19901 slice.x = XINT (it->slice.x); 19902 else if (FLOATP (it->slice.x)) 19903 slice.x = XFLOAT_DATA (it->slice.x) * img->width; 19904 19905 if (INTEGERP (it->slice.y)) 19906 slice.y = XINT (it->slice.y); 19907 else if (FLOATP (it->slice.y)) 19908 slice.y = XFLOAT_DATA (it->slice.y) * img->height; 19909 19910 if (INTEGERP (it->slice.width)) 19911 slice.width = XINT (it->slice.width); 19912 else if (FLOATP (it->slice.width)) 19913 slice.width = XFLOAT_DATA (it->slice.width) * img->width; 19914 19915 if (INTEGERP (it->slice.height)) 19916 slice.height = XINT (it->slice.height); 19917 else if (FLOATP (it->slice.height)) 19918 slice.height = XFLOAT_DATA (it->slice.height) * img->height; 19919 19920 if (slice.x >= img->width) 19921 slice.x = img->width; 19922 if (slice.y >= img->height) 19923 slice.y = img->height; 19924 if (slice.x + slice.width >= img->width) 19925 slice.width = img->width - slice.x; 19926 if (slice.y + slice.height > img->height) 19927 slice.height = img->height - slice.y; 19928 19929 if (slice.width == 0 || slice.height == 0) 19930 return; 19931 19932 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice); 19933 19934 it->descent = slice.height - glyph_ascent; 19935 if (slice.y == 0) 19936 it->descent += img->vmargin; 19937 if (slice.y + slice.height == img->height) 19938 it->descent += img->vmargin; 19939 it->phys_descent = it->descent; 19940 19941 it->pixel_width = slice.width; 19942 if (slice.x == 0) 19943 it->pixel_width += img->hmargin; 19944 if (slice.x + slice.width == img->width) 19945 it->pixel_width += img->hmargin; 19946 19947 /* It's quite possible for images to have an ascent greater than 19948 their height, so don't get confused in that case. */ 19949 if (it->descent < 0) 19950 it->descent = 0; 19951 19952#if 0 /* this breaks image tiling */ 19953 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */ 19954 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f); 19955 if (face_ascent > it->ascent) 19956 it->ascent = it->phys_ascent = face_ascent; 19957#endif 19958 19959 it->nglyphs = 1; 19960 19961 if (face->box != FACE_NO_BOX) 19962 { 19963 if (face->box_line_width > 0) 19964 { 19965 if (slice.y == 0) 19966 it->ascent += face->box_line_width; 19967 if (slice.y + slice.height == img->height) 19968 it->descent += face->box_line_width; 19969 } 19970 19971 if (it->start_of_box_run_p && slice.x == 0) 19972 it->pixel_width += abs (face->box_line_width); 19973 if (it->end_of_box_run_p && slice.x + slice.width == img->width) 19974 it->pixel_width += abs (face->box_line_width); 19975 } 19976 19977 take_vertical_position_into_account (it); 19978 19979 /* Automatically crop wide image glyphs at right edge so we can 19980 draw the cursor on same display row. */ 19981 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0) 19982 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4)) 19983 { 19984 it->pixel_width -= crop; 19985 slice.width -= crop; 19986 } 19987 19988 if (it->glyph_row) 19989 { 19990 struct glyph *glyph; 19991 enum glyph_row_area area = it->area; 19992 19993 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; 19994 if (glyph < it->glyph_row->glyphs[area + 1]) 19995 { 19996 glyph->charpos = CHARPOS (it->position); 19997 glyph->object = it->object; 19998 glyph->pixel_width = it->pixel_width; 19999 glyph->ascent = glyph_ascent; 20000 glyph->descent = it->descent; 20001 glyph->voffset = it->voffset; 20002 glyph->type = IMAGE_GLYPH; 20003 glyph->multibyte_p = it->multibyte_p; 20004 glyph->left_box_line_p = it->start_of_box_run_p; 20005 glyph->right_box_line_p = it->end_of_box_run_p; 20006 glyph->overlaps_vertically_p = 0; 20007 glyph->padding_p = 0; 20008 glyph->glyph_not_available_p = 0; 20009 glyph->face_id = it->face_id; 20010 glyph->u.img_id = img->id; 20011 glyph->slice = slice; 20012 glyph->font_type = FONT_TYPE_UNKNOWN; 20013 ++it->glyph_row->used[area]; 20014 } 20015 else 20016 IT_EXPAND_MATRIX_WIDTH (it, area); 20017 } 20018} 20019 20020 20021/* Append a stretch glyph to IT->glyph_row. OBJECT is the source 20022 of the glyph, WIDTH and HEIGHT are the width and height of the 20023 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */ 20024 20025static void 20026append_stretch_glyph (it, object, width, height, ascent) 20027 struct it *it; 20028 Lisp_Object object; 20029 int width, height; 20030 int ascent; 20031{ 20032 struct glyph *glyph; 20033 enum glyph_row_area area = it->area; 20034 20035 xassert (ascent >= 0 && ascent <= height); 20036 20037 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; 20038 if (glyph < it->glyph_row->glyphs[area + 1]) 20039 { 20040 glyph->charpos = CHARPOS (it->position); 20041 glyph->object = object; 20042 glyph->pixel_width = width; 20043 glyph->ascent = ascent; 20044 glyph->descent = height - ascent; 20045 glyph->voffset = it->voffset; 20046 glyph->type = STRETCH_GLYPH; 20047 glyph->multibyte_p = it->multibyte_p; 20048 glyph->left_box_line_p = it->start_of_box_run_p; 20049 glyph->right_box_line_p = it->end_of_box_run_p; 20050 glyph->overlaps_vertically_p = 0; 20051 glyph->padding_p = 0; 20052 glyph->glyph_not_available_p = 0; 20053 glyph->face_id = it->face_id; 20054 glyph->u.stretch.ascent = ascent; 20055 glyph->u.stretch.height = height; 20056 glyph->slice = null_glyph_slice; 20057 glyph->font_type = FONT_TYPE_UNKNOWN; 20058 ++it->glyph_row->used[area]; 20059 } 20060 else 20061 IT_EXPAND_MATRIX_WIDTH (it, area); 20062} 20063 20064 20065/* Produce a stretch glyph for iterator IT. IT->object is the value 20066 of the glyph property displayed. The value must be a list 20067 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs 20068 being recognized: 20069 20070 1. `:width WIDTH' specifies that the space should be WIDTH * 20071 canonical char width wide. WIDTH may be an integer or floating 20072 point number. 20073 20074 2. `:relative-width FACTOR' specifies that the width of the stretch 20075 should be computed from the width of the first character having the 20076 `glyph' property, and should be FACTOR times that width. 20077 20078 3. `:align-to HPOS' specifies that the space should be wide enough 20079 to reach HPOS, a value in canonical character units. 20080 20081 Exactly one of the above pairs must be present. 20082 20083 4. `:height HEIGHT' specifies that the height of the stretch produced 20084 should be HEIGHT, measured in canonical character units. 20085 20086 5. `:relative-height FACTOR' specifies that the height of the 20087 stretch should be FACTOR times the height of the characters having 20088 the glyph property. 20089 20090 Either none or exactly one of 4 or 5 must be present. 20091 20092 6. `:ascent ASCENT' specifies that ASCENT percent of the height 20093 of the stretch should be used for the ascent of the stretch. 20094 ASCENT must be in the range 0 <= ASCENT <= 100. */ 20095 20096static void 20097produce_stretch_glyph (it) 20098 struct it *it; 20099{ 20100 /* (space :width WIDTH :height HEIGHT ...) */ 20101 Lisp_Object prop, plist; 20102 int width = 0, height = 0, align_to = -1; 20103 int zero_width_ok_p = 0, zero_height_ok_p = 0; 20104 int ascent = 0; 20105 double tem; 20106 struct face *face = FACE_FROM_ID (it->f, it->face_id); 20107 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); 20108 20109 PREPARE_FACE_FOR_DISPLAY (it->f, face); 20110 20111 /* List should start with `space'. */ 20112 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); 20113 plist = XCDR (it->object); 20114 20115 /* Compute the width of the stretch. */ 20116 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop)) 20117 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0)) 20118 { 20119 /* Absolute width `:width WIDTH' specified and valid. */ 20120 zero_width_ok_p = 1; 20121 width = (int)tem; 20122 } 20123 else if (prop = Fplist_get (plist, QCrelative_width), 20124 NUMVAL (prop) > 0) 20125 { 20126 /* Relative width `:relative-width FACTOR' specified and valid. 20127 Compute the width of the characters having the `glyph' 20128 property. */ 20129 struct it it2; 20130 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); 20131 20132 it2 = *it; 20133 if (it->multibyte_p) 20134 { 20135 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) 20136 - IT_BYTEPOS (*it)); 20137 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len); 20138 } 20139 else 20140 it2.c = *p, it2.len = 1; 20141 20142 it2.glyph_row = NULL; 20143 it2.what = IT_CHARACTER; 20144 x_produce_glyphs (&it2); 20145 width = NUMVAL (prop) * it2.pixel_width; 20146 } 20147 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop)) 20148 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to)) 20149 { 20150 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p) 20151 align_to = (align_to < 0 20152 ? 0 20153 : align_to - window_box_left_offset (it->w, TEXT_AREA)); 20154 else if (align_to < 0) 20155 align_to = window_box_left_offset (it->w, TEXT_AREA); 20156 width = max (0, (int)tem + align_to - it->current_x); 20157 zero_width_ok_p = 1; 20158 } 20159 else 20160 /* Nothing specified -> width defaults to canonical char width. */ 20161 width = FRAME_COLUMN_WIDTH (it->f); 20162 20163 if (width <= 0 && (width < 0 || !zero_width_ok_p)) 20164 width = 1; 20165 20166 /* Compute height. */ 20167 if ((prop = Fplist_get (plist, QCheight), !NILP (prop)) 20168 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0)) 20169 { 20170 height = (int)tem; 20171 zero_height_ok_p = 1; 20172 } 20173 else if (prop = Fplist_get (plist, QCrelative_height), 20174 NUMVAL (prop) > 0) 20175 height = FONT_HEIGHT (font) * NUMVAL (prop); 20176 else 20177 height = FONT_HEIGHT (font); 20178 20179 if (height <= 0 && (height < 0 || !zero_height_ok_p)) 20180 height = 1; 20181 20182 /* Compute percentage of height used for ascent. If 20183 `:ascent ASCENT' is present and valid, use that. Otherwise, 20184 derive the ascent from the font in use. */ 20185 if (prop = Fplist_get (plist, QCascent), 20186 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) 20187 ascent = height * NUMVAL (prop) / 100.0; 20188 else if (!NILP (prop) 20189 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0)) 20190 ascent = min (max (0, (int)tem), height); 20191 else 20192 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font); 20193 20194 if (width > 0 && !it->truncate_lines_p 20195 && it->current_x + width > it->last_visible_x) 20196 width = it->last_visible_x - it->current_x - 1; 20197 20198 if (width > 0 && height > 0 && it->glyph_row) 20199 { 20200 Lisp_Object object = it->stack[it->sp - 1].string; 20201 if (!STRINGP (object)) 20202 object = it->w->buffer; 20203 append_stretch_glyph (it, object, width, height, ascent); 20204 } 20205 20206 it->pixel_width = width; 20207 it->ascent = it->phys_ascent = ascent; 20208 it->descent = it->phys_descent = height - it->ascent; 20209 it->nglyphs = width > 0 && height > 0 ? 1 : 0; 20210 20211 take_vertical_position_into_account (it); 20212} 20213 20214/* Get line-height and line-spacing property at point. 20215 If line-height has format (HEIGHT TOTAL), return TOTAL 20216 in TOTAL_HEIGHT. */ 20217 20218static Lisp_Object 20219get_line_height_property (it, prop) 20220 struct it *it; 20221 Lisp_Object prop; 20222{ 20223 Lisp_Object position; 20224 20225 if (STRINGP (it->object)) 20226 position = make_number (IT_STRING_CHARPOS (*it)); 20227 else if (BUFFERP (it->object)) 20228 position = make_number (IT_CHARPOS (*it)); 20229 else 20230 return Qnil; 20231 20232 return Fget_char_property (position, prop, it->object); 20233} 20234 20235/* Calculate line-height and line-spacing properties. 20236 An integer value specifies explicit pixel value. 20237 A float value specifies relative value to current face height. 20238 A cons (float . face-name) specifies relative value to 20239 height of specified face font. 20240 20241 Returns height in pixels, or nil. */ 20242 20243 20244static Lisp_Object 20245calc_line_height_property (it, val, font, boff, override) 20246 struct it *it; 20247 Lisp_Object val; 20248 XFontStruct *font; 20249 int boff, override; 20250{ 20251 Lisp_Object face_name = Qnil; 20252 int ascent, descent, height; 20253 20254 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt))) 20255 return val; 20256 20257 if (CONSP (val)) 20258 { 20259 face_name = XCAR (val); 20260 val = XCDR (val); 20261 if (!NUMBERP (val)) 20262 val = make_number (1); 20263 if (NILP (face_name)) 20264 { 20265 height = it->ascent + it->descent; 20266 goto scale; 20267 } 20268 } 20269 20270 if (NILP (face_name)) 20271 { 20272 font = FRAME_FONT (it->f); 20273 boff = FRAME_BASELINE_OFFSET (it->f); 20274 } 20275 else if (EQ (face_name, Qt)) 20276 { 20277 override = 0; 20278 } 20279 else 20280 { 20281 int face_id; 20282 struct face *face; 20283 struct font_info *font_info; 20284 20285 face_id = lookup_named_face (it->f, face_name, ' ', 0); 20286 if (face_id < 0) 20287 return make_number (-1); 20288 20289 face = FACE_FROM_ID (it->f, face_id); 20290 font = face->font; 20291 if (font == NULL) 20292 return make_number (-1); 20293 20294 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); 20295 boff = font_info->baseline_offset; 20296 if (font_info->vertical_centering) 20297 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 20298 } 20299 20300 ascent = FONT_BASE (font) + boff; 20301 descent = FONT_DESCENT (font) - boff; 20302 20303 if (override) 20304 { 20305 it->override_ascent = ascent; 20306 it->override_descent = descent; 20307 it->override_boff = boff; 20308 } 20309 20310 height = ascent + descent; 20311 20312 scale: 20313 if (FLOATP (val)) 20314 height = (int)(XFLOAT_DATA (val) * height); 20315 else if (INTEGERP (val)) 20316 height *= XINT (val); 20317 20318 return make_number (height); 20319} 20320 20321 20322/* RIF: 20323 Produce glyphs/get display metrics for the display element IT is 20324 loaded with. See the description of struct it in dispextern.h 20325 for an overview of struct it. */ 20326 20327void 20328x_produce_glyphs (it) 20329 struct it *it; 20330{ 20331 int extra_line_spacing = it->extra_line_spacing; 20332 20333 it->glyph_not_available_p = 0; 20334 20335 if (it->what == IT_CHARACTER) 20336 { 20337 XChar2b char2b; 20338 XFontStruct *font; 20339 struct face *face = FACE_FROM_ID (it->f, it->face_id); 20340 XCharStruct *pcm; 20341 int font_not_found_p; 20342 struct font_info *font_info; 20343 int boff; /* baseline offset */ 20344 /* We may change it->multibyte_p upon unibyte<->multibyte 20345 conversion. So, save the current value now and restore it 20346 later. 20347 20348 Note: It seems that we don't have to record multibyte_p in 20349 struct glyph because the character code itself tells if or 20350 not the character is multibyte. Thus, in the future, we must 20351 consider eliminating the field `multibyte_p' in the struct 20352 glyph. */ 20353 int saved_multibyte_p = it->multibyte_p; 20354 20355 /* Maybe translate single-byte characters to multibyte, or the 20356 other way. */ 20357 it->char_to_display = it->c; 20358 if (!ASCII_BYTE_P (it->c)) 20359 { 20360 if (unibyte_display_via_language_environment 20361 && SINGLE_BYTE_CHAR_P (it->c) 20362 && (it->c >= 0240 20363 || !NILP (Vnonascii_translation_table))) 20364 { 20365 it->char_to_display = unibyte_char_to_multibyte (it->c); 20366 it->multibyte_p = 1; 20367 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); 20368 face = FACE_FROM_ID (it->f, it->face_id); 20369 } 20370 else if (!SINGLE_BYTE_CHAR_P (it->c) 20371 && !it->multibyte_p) 20372 { 20373 it->multibyte_p = 1; 20374 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); 20375 face = FACE_FROM_ID (it->f, it->face_id); 20376 } 20377 } 20378 20379 /* Get font to use. Encode IT->char_to_display. */ 20380 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, 20381 &char2b, it->multibyte_p, 0); 20382 font = face->font; 20383 20384 /* When no suitable font found, use the default font. */ 20385 font_not_found_p = font == NULL; 20386 if (font_not_found_p) 20387 { 20388 font = FRAME_FONT (it->f); 20389 boff = FRAME_BASELINE_OFFSET (it->f); 20390 font_info = NULL; 20391 } 20392 else 20393 { 20394 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); 20395 boff = font_info->baseline_offset; 20396 if (font_info->vertical_centering) 20397 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 20398 } 20399 20400 if (it->char_to_display >= ' ' 20401 && (!it->multibyte_p || it->char_to_display < 128)) 20402 { 20403 /* Either unibyte or ASCII. */ 20404 int stretched_p; 20405 20406 it->nglyphs = 1; 20407 20408 pcm = rif->per_char_metric (font, &char2b, 20409 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display)); 20410 20411 if (it->override_ascent >= 0) 20412 { 20413 it->ascent = it->override_ascent; 20414 it->descent = it->override_descent; 20415 boff = it->override_boff; 20416 } 20417 else 20418 { 20419 it->ascent = FONT_BASE (font) + boff; 20420 it->descent = FONT_DESCENT (font) - boff; 20421 } 20422 20423 if (pcm) 20424 { 20425 it->phys_ascent = pcm->ascent + boff; 20426 it->phys_descent = pcm->descent - boff; 20427 it->pixel_width = pcm->width; 20428 } 20429 else 20430 { 20431 it->glyph_not_available_p = 1; 20432 it->phys_ascent = it->ascent; 20433 it->phys_descent = it->descent; 20434 it->pixel_width = FONT_WIDTH (font); 20435 } 20436 20437 if (it->constrain_row_ascent_descent_p) 20438 { 20439 if (it->descent > it->max_descent) 20440 { 20441 it->ascent += it->descent - it->max_descent; 20442 it->descent = it->max_descent; 20443 } 20444 if (it->ascent > it->max_ascent) 20445 { 20446 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent); 20447 it->ascent = it->max_ascent; 20448 } 20449 it->phys_ascent = min (it->phys_ascent, it->ascent); 20450 it->phys_descent = min (it->phys_descent, it->descent); 20451 extra_line_spacing = 0; 20452 } 20453 20454 /* If this is a space inside a region of text with 20455 `space-width' property, change its width. */ 20456 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); 20457 if (stretched_p) 20458 it->pixel_width *= XFLOATINT (it->space_width); 20459 20460 /* If face has a box, add the box thickness to the character 20461 height. If character has a box line to the left and/or 20462 right, add the box line width to the character's width. */ 20463 if (face->box != FACE_NO_BOX) 20464 { 20465 int thick = face->box_line_width; 20466 20467 if (thick > 0) 20468 { 20469 it->ascent += thick; 20470 it->descent += thick; 20471 } 20472 else 20473 thick = -thick; 20474 20475 if (it->start_of_box_run_p) 20476 it->pixel_width += thick; 20477 if (it->end_of_box_run_p) 20478 it->pixel_width += thick; 20479 } 20480 20481 /* If face has an overline, add the height of the overline 20482 (1 pixel) and a 1 pixel margin to the character height. */ 20483 if (face->overline_p) 20484 it->ascent += overline_margin; 20485 20486 if (it->constrain_row_ascent_descent_p) 20487 { 20488 if (it->ascent > it->max_ascent) 20489 it->ascent = it->max_ascent; 20490 if (it->descent > it->max_descent) 20491 it->descent = it->max_descent; 20492 } 20493 20494 take_vertical_position_into_account (it); 20495 20496 /* If we have to actually produce glyphs, do it. */ 20497 if (it->glyph_row) 20498 { 20499 if (stretched_p) 20500 { 20501 /* Translate a space with a `space-width' property 20502 into a stretch glyph. */ 20503 int ascent = (((it->ascent + it->descent) * FONT_BASE (font)) 20504 / FONT_HEIGHT (font)); 20505 append_stretch_glyph (it, it->object, it->pixel_width, 20506 it->ascent + it->descent, ascent); 20507 } 20508 else 20509 append_glyph (it); 20510 20511 /* If characters with lbearing or rbearing are displayed 20512 in this line, record that fact in a flag of the 20513 glyph row. This is used to optimize X output code. */ 20514 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) 20515 it->glyph_row->contains_overlapping_glyphs_p = 1; 20516 } 20517 } 20518 else if (it->char_to_display == '\n') 20519 { 20520 /* A newline has no width but we need the height of the line. 20521 But if previous part of the line set a height, don't 20522 increase that height */ 20523 20524 Lisp_Object height; 20525 Lisp_Object total_height = Qnil; 20526 20527 it->override_ascent = -1; 20528 it->pixel_width = 0; 20529 it->nglyphs = 0; 20530 20531 height = get_line_height_property(it, Qline_height); 20532 /* Split (line-height total-height) list */ 20533 if (CONSP (height) 20534 && CONSP (XCDR (height)) 20535 && NILP (XCDR (XCDR (height)))) 20536 { 20537 total_height = XCAR (XCDR (height)); 20538 height = XCAR (height); 20539 } 20540 height = calc_line_height_property(it, height, font, boff, 1); 20541 20542 if (it->override_ascent >= 0) 20543 { 20544 it->ascent = it->override_ascent; 20545 it->descent = it->override_descent; 20546 boff = it->override_boff; 20547 } 20548 else 20549 { 20550 it->ascent = FONT_BASE (font) + boff; 20551 it->descent = FONT_DESCENT (font) - boff; 20552 } 20553 20554 if (EQ (height, Qt)) 20555 { 20556 if (it->descent > it->max_descent) 20557 { 20558 it->ascent += it->descent - it->max_descent; 20559 it->descent = it->max_descent; 20560 } 20561 if (it->ascent > it->max_ascent) 20562 { 20563 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent); 20564 it->ascent = it->max_ascent; 20565 } 20566 it->phys_ascent = min (it->phys_ascent, it->ascent); 20567 it->phys_descent = min (it->phys_descent, it->descent); 20568 it->constrain_row_ascent_descent_p = 1; 20569 extra_line_spacing = 0; 20570 } 20571 else 20572 { 20573 Lisp_Object spacing; 20574 20575 it->phys_ascent = it->ascent; 20576 it->phys_descent = it->descent; 20577 20578 if ((it->max_ascent > 0 || it->max_descent > 0) 20579 && face->box != FACE_NO_BOX 20580 && face->box_line_width > 0) 20581 { 20582 it->ascent += face->box_line_width; 20583 it->descent += face->box_line_width; 20584 } 20585 if (!NILP (height) 20586 && XINT (height) > it->ascent + it->descent) 20587 it->ascent = XINT (height) - it->descent; 20588 20589 if (!NILP (total_height)) 20590 spacing = calc_line_height_property(it, total_height, font, boff, 0); 20591 else 20592 { 20593 spacing = get_line_height_property(it, Qline_spacing); 20594 spacing = calc_line_height_property(it, spacing, font, boff, 0); 20595 } 20596 if (INTEGERP (spacing)) 20597 { 20598 extra_line_spacing = XINT (spacing); 20599 if (!NILP (total_height)) 20600 extra_line_spacing -= (it->phys_ascent + it->phys_descent); 20601 } 20602 } 20603 } 20604 else if (it->char_to_display == '\t') 20605 { 20606 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f); 20607 int x = it->current_x + it->continuation_lines_width; 20608 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; 20609 20610 /* If the distance from the current position to the next tab 20611 stop is less than a space character width, use the 20612 tab stop after that. */ 20613 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f)) 20614 next_tab_x += tab_width; 20615 20616 it->pixel_width = next_tab_x - x; 20617 it->nglyphs = 1; 20618 it->ascent = it->phys_ascent = FONT_BASE (font) + boff; 20619 it->descent = it->phys_descent = FONT_DESCENT (font) - boff; 20620 20621 if (it->glyph_row) 20622 { 20623 append_stretch_glyph (it, it->object, it->pixel_width, 20624 it->ascent + it->descent, it->ascent); 20625 } 20626 } 20627 else 20628 { 20629 /* A multi-byte character. Assume that the display width of the 20630 character is the width of the character multiplied by the 20631 width of the font. */ 20632 20633 /* If we found a font, this font should give us the right 20634 metrics. If we didn't find a font, use the frame's 20635 default font and calculate the width of the character 20636 from the charset width; this is what old redisplay code 20637 did. */ 20638 20639 pcm = rif->per_char_metric (font, &char2b, 20640 FONT_TYPE_FOR_MULTIBYTE (font, it->c)); 20641 20642 if (font_not_found_p || !pcm) 20643 { 20644 int charset = CHAR_CHARSET (it->char_to_display); 20645 20646 it->glyph_not_available_p = 1; 20647 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f) 20648 * CHARSET_WIDTH (charset)); 20649 it->phys_ascent = FONT_BASE (font) + boff; 20650 it->phys_descent = FONT_DESCENT (font) - boff; 20651 } 20652 else 20653 { 20654 it->pixel_width = pcm->width; 20655 it->phys_ascent = pcm->ascent + boff; 20656 it->phys_descent = pcm->descent - boff; 20657 if (it->glyph_row 20658 && (pcm->lbearing < 0 20659 || pcm->rbearing > pcm->width)) 20660 it->glyph_row->contains_overlapping_glyphs_p = 1; 20661 } 20662 it->nglyphs = 1; 20663 it->ascent = FONT_BASE (font) + boff; 20664 it->descent = FONT_DESCENT (font) - boff; 20665 if (face->box != FACE_NO_BOX) 20666 { 20667 int thick = face->box_line_width; 20668 20669 if (thick > 0) 20670 { 20671 it->ascent += thick; 20672 it->descent += thick; 20673 } 20674 else 20675 thick = - thick; 20676 20677 if (it->start_of_box_run_p) 20678 it->pixel_width += thick; 20679 if (it->end_of_box_run_p) 20680 it->pixel_width += thick; 20681 } 20682 20683 /* If face has an overline, add the height of the overline 20684 (1 pixel) and a 1 pixel margin to the character height. */ 20685 if (face->overline_p) 20686 it->ascent += overline_margin; 20687 20688 take_vertical_position_into_account (it); 20689 20690 if (it->glyph_row) 20691 append_glyph (it); 20692 } 20693 it->multibyte_p = saved_multibyte_p; 20694 } 20695 else if (it->what == IT_COMPOSITION) 20696 { 20697 /* Note: A composition is represented as one glyph in the 20698 glyph matrix. There are no padding glyphs. */ 20699 XChar2b char2b; 20700 XFontStruct *font; 20701 struct face *face = FACE_FROM_ID (it->f, it->face_id); 20702 XCharStruct *pcm; 20703 int font_not_found_p; 20704 struct font_info *font_info; 20705 int boff; /* baseline offset */ 20706 struct composition *cmp = composition_table[it->cmp_id]; 20707 20708 /* Maybe translate single-byte characters to multibyte. */ 20709 it->char_to_display = it->c; 20710 if (unibyte_display_via_language_environment 20711 && SINGLE_BYTE_CHAR_P (it->c) 20712 && (it->c >= 0240 20713 || (it->c >= 0200 20714 && !NILP (Vnonascii_translation_table)))) 20715 { 20716 it->char_to_display = unibyte_char_to_multibyte (it->c); 20717 } 20718 20719 /* Get face and font to use. Encode IT->char_to_display. */ 20720 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); 20721 face = FACE_FROM_ID (it->f, it->face_id); 20722 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, 20723 &char2b, it->multibyte_p, 0); 20724 font = face->font; 20725 20726 /* When no suitable font found, use the default font. */ 20727 font_not_found_p = font == NULL; 20728 if (font_not_found_p) 20729 { 20730 font = FRAME_FONT (it->f); 20731 boff = FRAME_BASELINE_OFFSET (it->f); 20732 font_info = NULL; 20733 } 20734 else 20735 { 20736 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); 20737 boff = font_info->baseline_offset; 20738 if (font_info->vertical_centering) 20739 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 20740 } 20741 20742 /* There are no padding glyphs, so there is only one glyph to 20743 produce for the composition. Important is that pixel_width, 20744 ascent and descent are the values of what is drawn by 20745 draw_glyphs (i.e. the values of the overall glyphs composed). */ 20746 it->nglyphs = 1; 20747 20748 /* If we have not yet calculated pixel size data of glyphs of 20749 the composition for the current face font, calculate them 20750 now. Theoretically, we have to check all fonts for the 20751 glyphs, but that requires much time and memory space. So, 20752 here we check only the font of the first glyph. This leads 20753 to incorrect display very rarely, and C-l (recenter) can 20754 correct the display anyway. */ 20755 if (cmp->font != (void *) font) 20756 { 20757 /* Ascent and descent of the font of the first character of 20758 this composition (adjusted by baseline offset). Ascent 20759 and descent of overall glyphs should not be less than 20760 them respectively. */ 20761 int font_ascent = FONT_BASE (font) + boff; 20762 int font_descent = FONT_DESCENT (font) - boff; 20763 /* Bounding box of the overall glyphs. */ 20764 int leftmost, rightmost, lowest, highest; 20765 int i, width, ascent, descent; 20766 20767 cmp->font = (void *) font; 20768 20769 /* Initialize the bounding box. */ 20770 if (font_info 20771 && (pcm = rif->per_char_metric (font, &char2b, 20772 FONT_TYPE_FOR_MULTIBYTE (font, it->c)))) 20773 { 20774 width = pcm->width; 20775 ascent = pcm->ascent; 20776 descent = pcm->descent; 20777 } 20778 else 20779 { 20780 width = FONT_WIDTH (font); 20781 ascent = FONT_BASE (font); 20782 descent = FONT_DESCENT (font); 20783 } 20784 20785 rightmost = width; 20786 lowest = - descent + boff; 20787 highest = ascent + boff; 20788 leftmost = 0; 20789 20790 if (font_info 20791 && font_info->default_ascent 20792 && CHAR_TABLE_P (Vuse_default_ascent) 20793 && !NILP (Faref (Vuse_default_ascent, 20794 make_number (it->char_to_display)))) 20795 highest = font_info->default_ascent + boff; 20796 20797 /* Draw the first glyph at the normal position. It may be 20798 shifted to right later if some other glyphs are drawn at 20799 the left. */ 20800 cmp->offsets[0] = 0; 20801 cmp->offsets[1] = boff; 20802 20803 /* Set cmp->offsets for the remaining glyphs. */ 20804 for (i = 1; i < cmp->glyph_len; i++) 20805 { 20806 int left, right, btm, top; 20807 int ch = COMPOSITION_GLYPH (cmp, i); 20808 int face_id = FACE_FOR_CHAR (it->f, face, ch); 20809 20810 face = FACE_FROM_ID (it->f, face_id); 20811 get_char_face_and_encoding (it->f, ch, face->id, 20812 &char2b, it->multibyte_p, 0); 20813 font = face->font; 20814 if (font == NULL) 20815 { 20816 font = FRAME_FONT (it->f); 20817 boff = FRAME_BASELINE_OFFSET (it->f); 20818 font_info = NULL; 20819 } 20820 else 20821 { 20822 font_info 20823 = FONT_INFO_FROM_ID (it->f, face->font_info_id); 20824 boff = font_info->baseline_offset; 20825 if (font_info->vertical_centering) 20826 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 20827 } 20828 20829 if (font_info 20830 && (pcm = rif->per_char_metric (font, &char2b, 20831 FONT_TYPE_FOR_MULTIBYTE (font, ch)))) 20832 { 20833 width = pcm->width; 20834 ascent = pcm->ascent; 20835 descent = pcm->descent; 20836 } 20837 else 20838 { 20839 width = FONT_WIDTH (font); 20840 ascent = 1; 20841 descent = 0; 20842 } 20843 20844 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) 20845 { 20846 /* Relative composition with or without 20847 alternate chars. */ 20848 left = (leftmost + rightmost - width) / 2; 20849 btm = - descent + boff; 20850 if (font_info && font_info->relative_compose 20851 && (! CHAR_TABLE_P (Vignore_relative_composition) 20852 || NILP (Faref (Vignore_relative_composition, 20853 make_number (ch))))) 20854 { 20855 20856 if (- descent >= font_info->relative_compose) 20857 /* One extra pixel between two glyphs. */ 20858 btm = highest + 1; 20859 else if (ascent <= 0) 20860 /* One extra pixel between two glyphs. */ 20861 btm = lowest - 1 - ascent - descent; 20862 } 20863 } 20864 else 20865 { 20866 /* A composition rule is specified by an integer 20867 value that encodes global and new reference 20868 points (GREF and NREF). GREF and NREF are 20869 specified by numbers as below: 20870 20871 0---1---2 -- ascent 20872 | | 20873 | | 20874 | | 20875 9--10--11 -- center 20876 | | 20877 ---3---4---5--- baseline 20878 | | 20879 6---7---8 -- descent 20880 */ 20881 int rule = COMPOSITION_RULE (cmp, i); 20882 int gref, nref, grefx, grefy, nrefx, nrefy; 20883 20884 COMPOSITION_DECODE_RULE (rule, gref, nref); 20885 grefx = gref % 3, nrefx = nref % 3; 20886 grefy = gref / 3, nrefy = nref / 3; 20887 20888 left = (leftmost 20889 + grefx * (rightmost - leftmost) / 2 20890 - nrefx * width / 2); 20891 btm = ((grefy == 0 ? highest 20892 : grefy == 1 ? 0 20893 : grefy == 2 ? lowest 20894 : (highest + lowest) / 2) 20895 - (nrefy == 0 ? ascent + descent 20896 : nrefy == 1 ? descent - boff 20897 : nrefy == 2 ? 0 20898 : (ascent + descent) / 2)); 20899 } 20900 20901 cmp->offsets[i * 2] = left; 20902 cmp->offsets[i * 2 + 1] = btm + descent; 20903 20904 /* Update the bounding box of the overall glyphs. */ 20905 right = left + width; 20906 top = btm + descent + ascent; 20907 if (left < leftmost) 20908 leftmost = left; 20909 if (right > rightmost) 20910 rightmost = right; 20911 if (top > highest) 20912 highest = top; 20913 if (btm < lowest) 20914 lowest = btm; 20915 } 20916 20917 /* If there are glyphs whose x-offsets are negative, 20918 shift all glyphs to the right and make all x-offsets 20919 non-negative. */ 20920 if (leftmost < 0) 20921 { 20922 for (i = 0; i < cmp->glyph_len; i++) 20923 cmp->offsets[i * 2] -= leftmost; 20924 rightmost -= leftmost; 20925 } 20926 20927 cmp->pixel_width = rightmost; 20928 cmp->ascent = highest; 20929 cmp->descent = - lowest; 20930 if (cmp->ascent < font_ascent) 20931 cmp->ascent = font_ascent; 20932 if (cmp->descent < font_descent) 20933 cmp->descent = font_descent; 20934 } 20935 20936 it->pixel_width = cmp->pixel_width; 20937 it->ascent = it->phys_ascent = cmp->ascent; 20938 it->descent = it->phys_descent = cmp->descent; 20939 20940 if (face->box != FACE_NO_BOX) 20941 { 20942 int thick = face->box_line_width; 20943 20944 if (thick > 0) 20945 { 20946 it->ascent += thick; 20947 it->descent += thick; 20948 } 20949 else 20950 thick = - thick; 20951 20952 if (it->start_of_box_run_p) 20953 it->pixel_width += thick; 20954 if (it->end_of_box_run_p) 20955 it->pixel_width += thick; 20956 } 20957 20958 /* If face has an overline, add the height of the overline 20959 (1 pixel) and a 1 pixel margin to the character height. */ 20960 if (face->overline_p) 20961 it->ascent += overline_margin; 20962 20963 take_vertical_position_into_account (it); 20964 20965 if (it->glyph_row) 20966 append_composite_glyph (it); 20967 } 20968 else if (it->what == IT_IMAGE) 20969 produce_image_glyph (it); 20970 else if (it->what == IT_STRETCH) 20971 produce_stretch_glyph (it); 20972 20973 /* Accumulate dimensions. Note: can't assume that it->descent > 0 20974 because this isn't true for images with `:ascent 100'. */ 20975 xassert (it->ascent >= 0 && it->descent >= 0); 20976 if (it->area == TEXT_AREA) 20977 it->current_x += it->pixel_width; 20978 20979 if (extra_line_spacing > 0) 20980 { 20981 it->descent += extra_line_spacing; 20982 if (extra_line_spacing > it->max_extra_line_spacing) 20983 it->max_extra_line_spacing = extra_line_spacing; 20984 } 20985 20986 it->max_ascent = max (it->max_ascent, it->ascent); 20987 it->max_descent = max (it->max_descent, it->descent); 20988 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); 20989 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); 20990} 20991 20992/* EXPORT for RIF: 20993 Output LEN glyphs starting at START at the nominal cursor position. 20994 Advance the nominal cursor over the text. The global variable 20995 updated_window contains the window being updated, updated_row is 20996 the glyph row being updated, and updated_area is the area of that 20997 row being updated. */ 20998 20999void 21000x_write_glyphs (start, len) 21001 struct glyph *start; 21002 int len; 21003{ 21004 int x, hpos; 21005 21006 xassert (updated_window && updated_row); 21007 BLOCK_INPUT; 21008 21009 /* Write glyphs. */ 21010 21011 hpos = start - updated_row->glyphs[updated_area]; 21012 x = draw_glyphs (updated_window, output_cursor.x, 21013 updated_row, updated_area, 21014 hpos, hpos + len, 21015 DRAW_NORMAL_TEXT, 0); 21016 21017 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ 21018 if (updated_area == TEXT_AREA 21019 && updated_window->phys_cursor_on_p 21020 && updated_window->phys_cursor.vpos == output_cursor.vpos 21021 && updated_window->phys_cursor.hpos >= hpos 21022 && updated_window->phys_cursor.hpos < hpos + len) 21023 updated_window->phys_cursor_on_p = 0; 21024 21025 UNBLOCK_INPUT; 21026 21027 /* Advance the output cursor. */ 21028 output_cursor.hpos += len; 21029 output_cursor.x = x; 21030} 21031 21032 21033/* EXPORT for RIF: 21034 Insert LEN glyphs from START at the nominal cursor position. */ 21035 21036void 21037x_insert_glyphs (start, len) 21038 struct glyph *start; 21039 int len; 21040{ 21041 struct frame *f; 21042 struct window *w; 21043 int line_height, shift_by_width, shifted_region_width; 21044 struct glyph_row *row; 21045 struct glyph *glyph; 21046 int frame_x, frame_y, hpos; 21047 21048 xassert (updated_window && updated_row); 21049 BLOCK_INPUT; 21050 w = updated_window; 21051 f = XFRAME (WINDOW_FRAME (w)); 21052 21053 /* Get the height of the line we are in. */ 21054 row = updated_row; 21055 line_height = row->height; 21056 21057 /* Get the width of the glyphs to insert. */ 21058 shift_by_width = 0; 21059 for (glyph = start; glyph < start + len; ++glyph) 21060 shift_by_width += glyph->pixel_width; 21061 21062 /* Get the width of the region to shift right. */ 21063 shifted_region_width = (window_box_width (w, updated_area) 21064 - output_cursor.x 21065 - shift_by_width); 21066 21067 /* Shift right. */ 21068 frame_x = window_box_left (w, updated_area) + output_cursor.x; 21069 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y); 21070 21071 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width, 21072 line_height, shift_by_width); 21073 21074 /* Write the glyphs. */ 21075 hpos = start - row->glyphs[updated_area]; 21076 draw_glyphs (w, output_cursor.x, row, updated_area, 21077 hpos, hpos + len, 21078 DRAW_NORMAL_TEXT, 0); 21079 21080 /* Advance the output cursor. */ 21081 output_cursor.hpos += len; 21082 output_cursor.x += shift_by_width; 21083 UNBLOCK_INPUT; 21084} 21085 21086 21087/* EXPORT for RIF: 21088 Erase the current text line from the nominal cursor position 21089 (inclusive) to pixel column TO_X (exclusive). The idea is that 21090 everything from TO_X onward is already erased. 21091 21092 TO_X is a pixel position relative to updated_area of 21093 updated_window. TO_X == -1 means clear to the end of this area. */ 21094 21095void 21096x_clear_end_of_line (to_x) 21097 int to_x; 21098{ 21099 struct frame *f; 21100 struct window *w = updated_window; 21101 int max_x, min_y, max_y; 21102 int from_x, from_y, to_y; 21103 21104 xassert (updated_window && updated_row); 21105 f = XFRAME (w->frame); 21106 21107 if (updated_row->full_width_p) 21108 max_x = WINDOW_TOTAL_WIDTH (w); 21109 else 21110 max_x = window_box_width (w, updated_area); 21111 max_y = window_text_bottom_y (w); 21112 21113 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end 21114 of window. For TO_X > 0, truncate to end of drawing area. */ 21115 if (to_x == 0) 21116 return; 21117 else if (to_x < 0) 21118 to_x = max_x; 21119 else 21120 to_x = min (to_x, max_x); 21121 21122 to_y = min (max_y, output_cursor.y + updated_row->height); 21123 21124 /* Notice if the cursor will be cleared by this operation. */ 21125 if (!updated_row->full_width_p) 21126 notice_overwritten_cursor (w, updated_area, 21127 output_cursor.x, -1, 21128 updated_row->y, 21129 MATRIX_ROW_BOTTOM_Y (updated_row)); 21130 21131 from_x = output_cursor.x; 21132 21133 /* Translate to frame coordinates. */ 21134 if (updated_row->full_width_p) 21135 { 21136 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x); 21137 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x); 21138 } 21139 else 21140 { 21141 int area_left = window_box_left (w, updated_area); 21142 from_x += area_left; 21143 to_x += area_left; 21144 } 21145 21146 min_y = WINDOW_HEADER_LINE_HEIGHT (w); 21147 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y)); 21148 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); 21149 21150 /* Prevent inadvertently clearing to end of the X window. */ 21151 if (to_x > from_x && to_y > from_y) 21152 { 21153 BLOCK_INPUT; 21154 rif->clear_frame_area (f, from_x, from_y, 21155 to_x - from_x, to_y - from_y); 21156 UNBLOCK_INPUT; 21157 } 21158} 21159 21160#endif /* HAVE_WINDOW_SYSTEM */ 21161 21162 21163 21164/*********************************************************************** 21165 Cursor types 21166 ***********************************************************************/ 21167 21168/* Value is the internal representation of the specified cursor type 21169 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width 21170 of the bar cursor. */ 21171 21172static enum text_cursor_kinds 21173get_specified_cursor_type (arg, width) 21174 Lisp_Object arg; 21175 int *width; 21176{ 21177 enum text_cursor_kinds type; 21178 21179 if (NILP (arg)) 21180 return NO_CURSOR; 21181 21182 if (EQ (arg, Qbox)) 21183 return FILLED_BOX_CURSOR; 21184 21185 if (EQ (arg, Qhollow)) 21186 return HOLLOW_BOX_CURSOR; 21187 21188 if (EQ (arg, Qbar)) 21189 { 21190 *width = 2; 21191 return BAR_CURSOR; 21192 } 21193 21194 if (CONSP (arg) 21195 && EQ (XCAR (arg), Qbar) 21196 && INTEGERP (XCDR (arg)) 21197 && XINT (XCDR (arg)) >= 0) 21198 { 21199 *width = XINT (XCDR (arg)); 21200 return BAR_CURSOR; 21201 } 21202 21203 if (EQ (arg, Qhbar)) 21204 { 21205 *width = 2; 21206 return HBAR_CURSOR; 21207 } 21208 21209 if (CONSP (arg) 21210 && EQ (XCAR (arg), Qhbar) 21211 && INTEGERP (XCDR (arg)) 21212 && XINT (XCDR (arg)) >= 0) 21213 { 21214 *width = XINT (XCDR (arg)); 21215 return HBAR_CURSOR; 21216 } 21217 21218 /* Treat anything unknown as "hollow box cursor". 21219 It was bad to signal an error; people have trouble fixing 21220 .Xdefaults with Emacs, when it has something bad in it. */ 21221 type = HOLLOW_BOX_CURSOR; 21222 21223 return type; 21224} 21225 21226/* Set the default cursor types for specified frame. */ 21227void 21228set_frame_cursor_types (f, arg) 21229 struct frame *f; 21230 Lisp_Object arg; 21231{ 21232 int width; 21233 Lisp_Object tem; 21234 21235 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width); 21236 FRAME_CURSOR_WIDTH (f) = width; 21237 21238 /* By default, set up the blink-off state depending on the on-state. */ 21239 21240 tem = Fassoc (arg, Vblink_cursor_alist); 21241 if (!NILP (tem)) 21242 { 21243 FRAME_BLINK_OFF_CURSOR (f) 21244 = get_specified_cursor_type (XCDR (tem), &width); 21245 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width; 21246 } 21247 else 21248 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR; 21249} 21250 21251 21252/* Return the cursor we want to be displayed in window W. Return 21253 width of bar/hbar cursor through WIDTH arg. Return with 21254 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active' 21255 (i.e. if the `system caret' should track this cursor). 21256 21257 In a mini-buffer window, we want the cursor only to appear if we 21258 are reading input from this window. For the selected window, we 21259 want the cursor type given by the frame parameter or buffer local 21260 setting of cursor-type. If explicitly marked off, draw no cursor. 21261 In all other cases, we want a hollow box cursor. */ 21262 21263static enum text_cursor_kinds 21264get_window_cursor_type (w, glyph, width, active_cursor) 21265 struct window *w; 21266 struct glyph *glyph; 21267 int *width; 21268 int *active_cursor; 21269{ 21270 struct frame *f = XFRAME (w->frame); 21271 struct buffer *b = XBUFFER (w->buffer); 21272 int cursor_type = DEFAULT_CURSOR; 21273 Lisp_Object alt_cursor; 21274 int non_selected = 0; 21275 21276 *active_cursor = 1; 21277 21278 /* Echo area */ 21279 if (cursor_in_echo_area 21280 && FRAME_HAS_MINIBUF_P (f) 21281 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) 21282 { 21283 if (w == XWINDOW (echo_area_window)) 21284 { 21285 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type)) 21286 { 21287 *width = FRAME_CURSOR_WIDTH (f); 21288 return FRAME_DESIRED_CURSOR (f); 21289 } 21290 else 21291 return get_specified_cursor_type (b->cursor_type, width); 21292 } 21293 21294 *active_cursor = 0; 21295 non_selected = 1; 21296 } 21297 21298 /* Nonselected window or nonselected frame. */ 21299 else if (w != XWINDOW (f->selected_window) 21300#ifdef HAVE_WINDOW_SYSTEM 21301 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame 21302#endif 21303 ) 21304 { 21305 *active_cursor = 0; 21306 21307 if (MINI_WINDOW_P (w) && minibuf_level == 0) 21308 return NO_CURSOR; 21309 21310 non_selected = 1; 21311 } 21312 21313 /* Never display a cursor in a window in which cursor-type is nil. */ 21314 if (NILP (b->cursor_type)) 21315 return NO_CURSOR; 21316 21317 /* Use cursor-in-non-selected-windows for non-selected window or frame. */ 21318 if (non_selected) 21319 { 21320 alt_cursor = b->cursor_in_non_selected_windows; 21321 return get_specified_cursor_type (alt_cursor, width); 21322 } 21323 21324 /* Get the normal cursor type for this window. */ 21325 if (EQ (b->cursor_type, Qt)) 21326 { 21327 cursor_type = FRAME_DESIRED_CURSOR (f); 21328 *width = FRAME_CURSOR_WIDTH (f); 21329 } 21330 else 21331 cursor_type = get_specified_cursor_type (b->cursor_type, width); 21332 21333 /* Use normal cursor if not blinked off. */ 21334 if (!w->cursor_off_p) 21335 { 21336#ifdef HAVE_WINDOW_SYSTEM 21337 if (glyph != NULL && glyph->type == IMAGE_GLYPH) 21338 { 21339 if (cursor_type == FILLED_BOX_CURSOR) 21340 { 21341 /* Using a block cursor on large images can be very annoying. 21342 So use a hollow cursor for "large" images. 21343 If image is not transparent (no mask), also use hollow cursor. */ 21344 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id); 21345 if (img != NULL && IMAGEP (img->spec)) 21346 { 21347 /* Arbitrarily, interpret "Large" as >32x32 and >NxN 21348 where N = size of default frame font size. 21349 This should cover most of the "tiny" icons people may use. */ 21350 if (!img->mask 21351 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w)) 21352 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w))) 21353 cursor_type = HOLLOW_BOX_CURSOR; 21354 } 21355 } 21356 else if (cursor_type != NO_CURSOR) 21357 { 21358 /* Display current only supports BOX and HOLLOW cursors for images. 21359 So for now, unconditionally use a HOLLOW cursor when cursor is 21360 not a solid box cursor. */ 21361 cursor_type = HOLLOW_BOX_CURSOR; 21362 } 21363 } 21364#endif 21365 return cursor_type; 21366 } 21367 21368 /* Cursor is blinked off, so determine how to "toggle" it. */ 21369 21370 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */ 21371 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor))) 21372 return get_specified_cursor_type (XCDR (alt_cursor), width); 21373 21374 /* Then see if frame has specified a specific blink off cursor type. */ 21375 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR) 21376 { 21377 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f); 21378 return FRAME_BLINK_OFF_CURSOR (f); 21379 } 21380 21381#if 0 21382 /* Some people liked having a permanently visible blinking cursor, 21383 while others had very strong opinions against it. So it was 21384 decided to remove it. KFS 2003-09-03 */ 21385 21386 /* Finally perform built-in cursor blinking: 21387 filled box <-> hollow box 21388 wide [h]bar <-> narrow [h]bar 21389 narrow [h]bar <-> no cursor 21390 other type <-> no cursor */ 21391 21392 if (cursor_type == FILLED_BOX_CURSOR) 21393 return HOLLOW_BOX_CURSOR; 21394 21395 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1) 21396 { 21397 *width = 1; 21398 return cursor_type; 21399 } 21400#endif 21401 21402 return NO_CURSOR; 21403} 21404 21405 21406#ifdef HAVE_WINDOW_SYSTEM 21407 21408/* Notice when the text cursor of window W has been completely 21409 overwritten by a drawing operation that outputs glyphs in AREA 21410 starting at X0 and ending at X1 in the line starting at Y0 and 21411 ending at Y1. X coordinates are area-relative. X1 < 0 means all 21412 the rest of the line after X0 has been written. Y coordinates 21413 are window-relative. */ 21414 21415static void 21416notice_overwritten_cursor (w, area, x0, x1, y0, y1) 21417 struct window *w; 21418 enum glyph_row_area area; 21419 int x0, y0, x1, y1; 21420{ 21421 int cx0, cx1, cy0, cy1; 21422 struct glyph_row *row; 21423 21424 if (!w->phys_cursor_on_p) 21425 return; 21426 if (area != TEXT_AREA) 21427 return; 21428 21429 if (w->phys_cursor.vpos < 0 21430 || w->phys_cursor.vpos >= w->current_matrix->nrows 21431 || (row = w->current_matrix->rows + w->phys_cursor.vpos, 21432 !(row->enabled_p && row->displays_text_p))) 21433 return; 21434 21435 if (row->cursor_in_fringe_p) 21436 { 21437 row->cursor_in_fringe_p = 0; 21438 draw_fringe_bitmap (w, row, 0); 21439 w->phys_cursor_on_p = 0; 21440 return; 21441 } 21442 21443 cx0 = w->phys_cursor.x; 21444 cx1 = cx0 + w->phys_cursor_width; 21445 if (x0 > cx0 || (x1 >= 0 && x1 < cx1)) 21446 return; 21447 21448 /* The cursor image will be completely removed from the 21449 screen if the output area intersects the cursor area in 21450 y-direction. When we draw in [y0 y1[, and some part of 21451 the cursor is at y < y0, that part must have been drawn 21452 before. When scrolling, the cursor is erased before 21453 actually scrolling, so we don't come here. When not 21454 scrolling, the rows above the old cursor row must have 21455 changed, and in this case these rows must have written 21456 over the cursor image. 21457 21458 Likewise if part of the cursor is below y1, with the 21459 exception of the cursor being in the first blank row at 21460 the buffer and window end because update_text_area 21461 doesn't draw that row. (Except when it does, but 21462 that's handled in update_text_area.) */ 21463 21464 cy0 = w->phys_cursor.y; 21465 cy1 = cy0 + w->phys_cursor_height; 21466 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1)) 21467 return; 21468 21469 w->phys_cursor_on_p = 0; 21470} 21471 21472#endif /* HAVE_WINDOW_SYSTEM */ 21473 21474 21475/************************************************************************ 21476 Mouse Face 21477 ************************************************************************/ 21478 21479#ifdef HAVE_WINDOW_SYSTEM 21480 21481/* EXPORT for RIF: 21482 Fix the display of area AREA of overlapping row ROW in window W 21483 with respect to the overlapping part OVERLAPS. */ 21484 21485void 21486x_fix_overlapping_area (w, row, area, overlaps) 21487 struct window *w; 21488 struct glyph_row *row; 21489 enum glyph_row_area area; 21490 int overlaps; 21491{ 21492 int i, x; 21493 21494 BLOCK_INPUT; 21495 21496 x = 0; 21497 for (i = 0; i < row->used[area];) 21498 { 21499 if (row->glyphs[area][i].overlaps_vertically_p) 21500 { 21501 int start = i, start_x = x; 21502 21503 do 21504 { 21505 x += row->glyphs[area][i].pixel_width; 21506 ++i; 21507 } 21508 while (i < row->used[area] 21509 && row->glyphs[area][i].overlaps_vertically_p); 21510 21511 draw_glyphs (w, start_x, row, area, 21512 start, i, 21513 DRAW_NORMAL_TEXT, overlaps); 21514 } 21515 else 21516 { 21517 x += row->glyphs[area][i].pixel_width; 21518 ++i; 21519 } 21520 } 21521 21522 UNBLOCK_INPUT; 21523} 21524 21525 21526/* EXPORT: 21527 Draw the cursor glyph of window W in glyph row ROW. See the 21528 comment of draw_glyphs for the meaning of HL. */ 21529 21530void 21531draw_phys_cursor_glyph (w, row, hl) 21532 struct window *w; 21533 struct glyph_row *row; 21534 enum draw_glyphs_face hl; 21535{ 21536 /* If cursor hpos is out of bounds, don't draw garbage. This can 21537 happen in mini-buffer windows when switching between echo area 21538 glyphs and mini-buffer. */ 21539 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) 21540 { 21541 int on_p = w->phys_cursor_on_p; 21542 int x1; 21543 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, 21544 w->phys_cursor.hpos, w->phys_cursor.hpos + 1, 21545 hl, 0); 21546 w->phys_cursor_on_p = on_p; 21547 21548 if (hl == DRAW_CURSOR) 21549 w->phys_cursor_width = x1 - w->phys_cursor.x; 21550 /* When we erase the cursor, and ROW is overlapped by other 21551 rows, make sure that these overlapping parts of other rows 21552 are redrawn. */ 21553 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p) 21554 { 21555 w->phys_cursor_width = x1 - w->phys_cursor.x; 21556 21557 if (row > w->current_matrix->rows 21558 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1)) 21559 x_fix_overlapping_area (w, row - 1, TEXT_AREA, 21560 OVERLAPS_ERASED_CURSOR); 21561 21562 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w) 21563 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1)) 21564 x_fix_overlapping_area (w, row + 1, TEXT_AREA, 21565 OVERLAPS_ERASED_CURSOR); 21566 } 21567 } 21568} 21569 21570 21571/* EXPORT: 21572 Erase the image of a cursor of window W from the screen. */ 21573 21574void 21575erase_phys_cursor (w) 21576 struct window *w; 21577{ 21578 struct frame *f = XFRAME (w->frame); 21579 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 21580 int hpos = w->phys_cursor.hpos; 21581 int vpos = w->phys_cursor.vpos; 21582 int mouse_face_here_p = 0; 21583 struct glyph_matrix *active_glyphs = w->current_matrix; 21584 struct glyph_row *cursor_row; 21585 struct glyph *cursor_glyph; 21586 enum draw_glyphs_face hl; 21587 21588 /* No cursor displayed or row invalidated => nothing to do on the 21589 screen. */ 21590 if (w->phys_cursor_type == NO_CURSOR) 21591 goto mark_cursor_off; 21592 21593 /* VPOS >= active_glyphs->nrows means that window has been resized. 21594 Don't bother to erase the cursor. */ 21595 if (vpos >= active_glyphs->nrows) 21596 goto mark_cursor_off; 21597 21598 /* If row containing cursor is marked invalid, there is nothing we 21599 can do. */ 21600 cursor_row = MATRIX_ROW (active_glyphs, vpos); 21601 if (!cursor_row->enabled_p) 21602 goto mark_cursor_off; 21603 21604 /* If line spacing is > 0, old cursor may only be partially visible in 21605 window after split-window. So adjust visible height. */ 21606 cursor_row->visible_height = min (cursor_row->visible_height, 21607 window_text_bottom_y (w) - cursor_row->y); 21608 21609 /* If row is completely invisible, don't attempt to delete a cursor which 21610 isn't there. This can happen if cursor is at top of a window, and 21611 we switch to a buffer with a header line in that window. */ 21612 if (cursor_row->visible_height <= 0) 21613 goto mark_cursor_off; 21614 21615 /* If cursor is in the fringe, erase by drawing actual bitmap there. */ 21616 if (cursor_row->cursor_in_fringe_p) 21617 { 21618 cursor_row->cursor_in_fringe_p = 0; 21619 draw_fringe_bitmap (w, cursor_row, 0); 21620 goto mark_cursor_off; 21621 } 21622 21623 /* This can happen when the new row is shorter than the old one. 21624 In this case, either draw_glyphs or clear_end_of_line 21625 should have cleared the cursor. Note that we wouldn't be 21626 able to erase the cursor in this case because we don't have a 21627 cursor glyph at hand. */ 21628 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]) 21629 goto mark_cursor_off; 21630 21631 /* If the cursor is in the mouse face area, redisplay that when 21632 we clear the cursor. */ 21633 if (! NILP (dpyinfo->mouse_face_window) 21634 && w == XWINDOW (dpyinfo->mouse_face_window) 21635 && (vpos > dpyinfo->mouse_face_beg_row 21636 || (vpos == dpyinfo->mouse_face_beg_row 21637 && hpos >= dpyinfo->mouse_face_beg_col)) 21638 && (vpos < dpyinfo->mouse_face_end_row 21639 || (vpos == dpyinfo->mouse_face_end_row 21640 && hpos < dpyinfo->mouse_face_end_col)) 21641 /* Don't redraw the cursor's spot in mouse face if it is at the 21642 end of a line (on a newline). The cursor appears there, but 21643 mouse highlighting does not. */ 21644 && cursor_row->used[TEXT_AREA] > hpos) 21645 mouse_face_here_p = 1; 21646 21647 /* Maybe clear the display under the cursor. */ 21648 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR) 21649 { 21650 int x, y, left_x; 21651 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w); 21652 int width; 21653 21654 cursor_glyph = get_phys_cursor_glyph (w); 21655 if (cursor_glyph == NULL) 21656 goto mark_cursor_off; 21657 21658 width = cursor_glyph->pixel_width; 21659 left_x = window_box_left_offset (w, TEXT_AREA); 21660 x = w->phys_cursor.x; 21661 if (x < left_x) 21662 width -= left_x - x; 21663 width = min (width, window_box_width (w, TEXT_AREA) - x); 21664 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y)); 21665 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x)); 21666 21667 if (width > 0) 21668 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height); 21669 } 21670 21671 /* Erase the cursor by redrawing the character underneath it. */ 21672 if (mouse_face_here_p) 21673 hl = DRAW_MOUSE_FACE; 21674 else 21675 hl = DRAW_NORMAL_TEXT; 21676 draw_phys_cursor_glyph (w, cursor_row, hl); 21677 21678 mark_cursor_off: 21679 w->phys_cursor_on_p = 0; 21680 w->phys_cursor_type = NO_CURSOR; 21681} 21682 21683 21684/* EXPORT: 21685 Display or clear cursor of window W. If ON is zero, clear the 21686 cursor. If it is non-zero, display the cursor. If ON is nonzero, 21687 where to put the cursor is specified by HPOS, VPOS, X and Y. */ 21688 21689void 21690display_and_set_cursor (w, on, hpos, vpos, x, y) 21691 struct window *w; 21692 int on, hpos, vpos, x, y; 21693{ 21694 struct frame *f = XFRAME (w->frame); 21695 int new_cursor_type; 21696 int new_cursor_width; 21697 int active_cursor; 21698 struct glyph_row *glyph_row; 21699 struct glyph *glyph; 21700 21701 /* This is pointless on invisible frames, and dangerous on garbaged 21702 windows and frames; in the latter case, the frame or window may 21703 be in the midst of changing its size, and x and y may be off the 21704 window. */ 21705 if (! FRAME_VISIBLE_P (f) 21706 || FRAME_GARBAGED_P (f) 21707 || vpos >= w->current_matrix->nrows 21708 || hpos >= w->current_matrix->matrix_w) 21709 return; 21710 21711 /* If cursor is off and we want it off, return quickly. */ 21712 if (!on && !w->phys_cursor_on_p) 21713 return; 21714 21715 glyph_row = MATRIX_ROW (w->current_matrix, vpos); 21716 /* If cursor row is not enabled, we don't really know where to 21717 display the cursor. */ 21718 if (!glyph_row->enabled_p) 21719 { 21720 w->phys_cursor_on_p = 0; 21721 return; 21722 } 21723 21724 glyph = NULL; 21725 if (!glyph_row->exact_window_width_line_p 21726 || hpos < glyph_row->used[TEXT_AREA]) 21727 glyph = glyph_row->glyphs[TEXT_AREA] + hpos; 21728 21729 xassert (interrupt_input_blocked); 21730 21731 /* Set new_cursor_type to the cursor we want to be displayed. */ 21732 new_cursor_type = get_window_cursor_type (w, glyph, 21733 &new_cursor_width, &active_cursor); 21734 21735 /* If cursor is currently being shown and we don't want it to be or 21736 it is in the wrong place, or the cursor type is not what we want, 21737 erase it. */ 21738 if (w->phys_cursor_on_p 21739 && (!on 21740 || w->phys_cursor.x != x 21741 || w->phys_cursor.y != y 21742 || new_cursor_type != w->phys_cursor_type 21743 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR) 21744 && new_cursor_width != w->phys_cursor_width))) 21745 erase_phys_cursor (w); 21746 21747 /* Don't check phys_cursor_on_p here because that flag is only set 21748 to zero in some cases where we know that the cursor has been 21749 completely erased, to avoid the extra work of erasing the cursor 21750 twice. In other words, phys_cursor_on_p can be 1 and the cursor 21751 still not be visible, or it has only been partly erased. */ 21752 if (on) 21753 { 21754 w->phys_cursor_ascent = glyph_row->ascent; 21755 w->phys_cursor_height = glyph_row->height; 21756 21757 /* Set phys_cursor_.* before x_draw_.* is called because some 21758 of them may need the information. */ 21759 w->phys_cursor.x = x; 21760 w->phys_cursor.y = glyph_row->y; 21761 w->phys_cursor.hpos = hpos; 21762 w->phys_cursor.vpos = vpos; 21763 } 21764 21765 rif->draw_window_cursor (w, glyph_row, x, y, 21766 new_cursor_type, new_cursor_width, 21767 on, active_cursor); 21768} 21769 21770 21771/* Switch the display of W's cursor on or off, according to the value 21772 of ON. */ 21773 21774static void 21775update_window_cursor (w, on) 21776 struct window *w; 21777 int on; 21778{ 21779 /* Don't update cursor in windows whose frame is in the process 21780 of being deleted. */ 21781 if (w->current_matrix) 21782 { 21783 BLOCK_INPUT; 21784 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos, 21785 w->phys_cursor.x, w->phys_cursor.y); 21786 UNBLOCK_INPUT; 21787 } 21788} 21789 21790 21791/* Call update_window_cursor with parameter ON_P on all leaf windows 21792 in the window tree rooted at W. */ 21793 21794static void 21795update_cursor_in_window_tree (w, on_p) 21796 struct window *w; 21797 int on_p; 21798{ 21799 while (w) 21800 { 21801 if (!NILP (w->hchild)) 21802 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p); 21803 else if (!NILP (w->vchild)) 21804 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p); 21805 else 21806 update_window_cursor (w, on_p); 21807 21808 w = NILP (w->next) ? 0 : XWINDOW (w->next); 21809 } 21810} 21811 21812 21813/* EXPORT: 21814 Display the cursor on window W, or clear it, according to ON_P. 21815 Don't change the cursor's position. */ 21816 21817void 21818x_update_cursor (f, on_p) 21819 struct frame *f; 21820 int on_p; 21821{ 21822 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); 21823} 21824 21825 21826/* EXPORT: 21827 Clear the cursor of window W to background color, and mark the 21828 cursor as not shown. This is used when the text where the cursor 21829 is is about to be rewritten. */ 21830 21831void 21832x_clear_cursor (w) 21833 struct window *w; 21834{ 21835 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) 21836 update_window_cursor (w, 0); 21837} 21838 21839 21840/* EXPORT: 21841 Display the active region described by mouse_face_* according to DRAW. */ 21842 21843void 21844show_mouse_face (dpyinfo, draw) 21845 Display_Info *dpyinfo; 21846 enum draw_glyphs_face draw; 21847{ 21848 struct window *w = XWINDOW (dpyinfo->mouse_face_window); 21849 struct frame *f = XFRAME (WINDOW_FRAME (w)); 21850 21851 if (/* If window is in the process of being destroyed, don't bother 21852 to do anything. */ 21853 w->current_matrix != NULL 21854 /* Don't update mouse highlight if hidden */ 21855 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden) 21856 /* Recognize when we are called to operate on rows that don't exist 21857 anymore. This can happen when a window is split. */ 21858 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows) 21859 { 21860 int phys_cursor_on_p = w->phys_cursor_on_p; 21861 struct glyph_row *row, *first, *last; 21862 21863 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row); 21864 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row); 21865 21866 for (row = first; row <= last && row->enabled_p; ++row) 21867 { 21868 int start_hpos, end_hpos, start_x; 21869 21870 /* For all but the first row, the highlight starts at column 0. */ 21871 if (row == first) 21872 { 21873 start_hpos = dpyinfo->mouse_face_beg_col; 21874 start_x = dpyinfo->mouse_face_beg_x; 21875 } 21876 else 21877 { 21878 start_hpos = 0; 21879 start_x = 0; 21880 } 21881 21882 if (row == last) 21883 end_hpos = dpyinfo->mouse_face_end_col; 21884 else 21885 { 21886 end_hpos = row->used[TEXT_AREA]; 21887 if (draw == DRAW_NORMAL_TEXT) 21888 row->fill_line_p = 1; /* Clear to end of line */ 21889 } 21890 21891 if (end_hpos > start_hpos) 21892 { 21893 draw_glyphs (w, start_x, row, TEXT_AREA, 21894 start_hpos, end_hpos, 21895 draw, 0); 21896 21897 row->mouse_face_p 21898 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED; 21899 } 21900 } 21901 21902 /* When we've written over the cursor, arrange for it to 21903 be displayed again. */ 21904 if (phys_cursor_on_p && !w->phys_cursor_on_p) 21905 { 21906 BLOCK_INPUT; 21907 display_and_set_cursor (w, 1, 21908 w->phys_cursor.hpos, w->phys_cursor.vpos, 21909 w->phys_cursor.x, w->phys_cursor.y); 21910 UNBLOCK_INPUT; 21911 } 21912 } 21913 21914 /* Change the mouse cursor. */ 21915 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window)) 21916 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor); 21917 else if (draw == DRAW_MOUSE_FACE) 21918 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor); 21919 else 21920 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor); 21921} 21922 21923/* EXPORT: 21924 Clear out the mouse-highlighted active region. 21925 Redraw it un-highlighted first. Value is non-zero if mouse 21926 face was actually drawn unhighlighted. */ 21927 21928int 21929clear_mouse_face (dpyinfo) 21930 Display_Info *dpyinfo; 21931{ 21932 int cleared = 0; 21933 21934 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window)) 21935 { 21936 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); 21937 cleared = 1; 21938 } 21939 21940 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 21941 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 21942 dpyinfo->mouse_face_window = Qnil; 21943 dpyinfo->mouse_face_overlay = Qnil; 21944 return cleared; 21945} 21946 21947 21948/* EXPORT: 21949 Non-zero if physical cursor of window W is within mouse face. */ 21950 21951int 21952cursor_in_mouse_face_p (w) 21953 struct window *w; 21954{ 21955 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); 21956 int in_mouse_face = 0; 21957 21958 if (WINDOWP (dpyinfo->mouse_face_window) 21959 && XWINDOW (dpyinfo->mouse_face_window) == w) 21960 { 21961 int hpos = w->phys_cursor.hpos; 21962 int vpos = w->phys_cursor.vpos; 21963 21964 if (vpos >= dpyinfo->mouse_face_beg_row 21965 && vpos <= dpyinfo->mouse_face_end_row 21966 && (vpos > dpyinfo->mouse_face_beg_row 21967 || hpos >= dpyinfo->mouse_face_beg_col) 21968 && (vpos < dpyinfo->mouse_face_end_row 21969 || hpos < dpyinfo->mouse_face_end_col 21970 || dpyinfo->mouse_face_past_end)) 21971 in_mouse_face = 1; 21972 } 21973 21974 return in_mouse_face; 21975} 21976 21977 21978 21979 21980/* Find the glyph matrix position of buffer position CHARPOS in window 21981 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's 21982 current glyphs must be up to date. If CHARPOS is above window 21983 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end 21984 of last line in W. In the row containing CHARPOS, stop before glyphs 21985 having STOP as object. */ 21986 21987#if 1 /* This is a version of fast_find_position that's more correct 21988 in the presence of hscrolling, for example. I didn't install 21989 it right away because the problem fixed is minor, it failed 21990 in 20.x as well, and I think it's too risky to install 21991 so near the release of 21.1. 2001-09-25 gerd. */ 21992 21993static int 21994fast_find_position (w, charpos, hpos, vpos, x, y, stop) 21995 struct window *w; 21996 int charpos; 21997 int *hpos, *vpos, *x, *y; 21998 Lisp_Object stop; 21999{ 22000 struct glyph_row *row, *first; 22001 struct glyph *glyph, *end; 22002 int past_end = 0; 22003 22004 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 22005 if (charpos < MATRIX_ROW_START_CHARPOS (first)) 22006 { 22007 *x = first->x; 22008 *y = first->y; 22009 *hpos = 0; 22010 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix); 22011 return 1; 22012 } 22013 22014 row = row_containing_pos (w, charpos, first, NULL, 0); 22015 if (row == NULL) 22016 { 22017 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 22018 past_end = 1; 22019 } 22020 22021 /* If whole rows or last part of a row came from a display overlay, 22022 row_containing_pos will skip over such rows because their end pos 22023 equals the start pos of the overlay or interval. 22024 22025 Move back if we have a STOP object and previous row's 22026 end glyph came from STOP. */ 22027 if (!NILP (stop)) 22028 { 22029 struct glyph_row *prev; 22030 while ((prev = row - 1, prev >= first) 22031 && MATRIX_ROW_END_CHARPOS (prev) == charpos 22032 && prev->used[TEXT_AREA] > 0) 22033 { 22034 struct glyph *beg = prev->glyphs[TEXT_AREA]; 22035 glyph = beg + prev->used[TEXT_AREA]; 22036 while (--glyph >= beg 22037 && INTEGERP (glyph->object)); 22038 if (glyph < beg 22039 || !EQ (stop, glyph->object)) 22040 break; 22041 row = prev; 22042 } 22043 } 22044 22045 *x = row->x; 22046 *y = row->y; 22047 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix); 22048 22049 glyph = row->glyphs[TEXT_AREA]; 22050 end = glyph + row->used[TEXT_AREA]; 22051 22052 /* Skip over glyphs not having an object at the start of the row. 22053 These are special glyphs like truncation marks on terminal 22054 frames. */ 22055 if (row->displays_text_p) 22056 while (glyph < end 22057 && INTEGERP (glyph->object) 22058 && !EQ (stop, glyph->object) 22059 && glyph->charpos < 0) 22060 { 22061 *x += glyph->pixel_width; 22062 ++glyph; 22063 } 22064 22065 while (glyph < end 22066 && !INTEGERP (glyph->object) 22067 && !EQ (stop, glyph->object) 22068 && (!BUFFERP (glyph->object) 22069 || glyph->charpos < charpos)) 22070 { 22071 *x += glyph->pixel_width; 22072 ++glyph; 22073 } 22074 22075 *hpos = glyph - row->glyphs[TEXT_AREA]; 22076 return !past_end; 22077} 22078 22079#else /* not 1 */ 22080 22081static int 22082fast_find_position (w, pos, hpos, vpos, x, y, stop) 22083 struct window *w; 22084 int pos; 22085 int *hpos, *vpos, *x, *y; 22086 Lisp_Object stop; 22087{ 22088 int i; 22089 int lastcol; 22090 int maybe_next_line_p = 0; 22091 int line_start_position; 22092 int yb = window_text_bottom_y (w); 22093 struct glyph_row *row, *best_row; 22094 int row_vpos, best_row_vpos; 22095 int current_x; 22096 22097 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 22098 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix); 22099 22100 while (row->y < yb) 22101 { 22102 if (row->used[TEXT_AREA]) 22103 line_start_position = row->glyphs[TEXT_AREA]->charpos; 22104 else 22105 line_start_position = 0; 22106 22107 if (line_start_position > pos) 22108 break; 22109 /* If the position sought is the end of the buffer, 22110 don't include the blank lines at the bottom of the window. */ 22111 else if (line_start_position == pos 22112 && pos == BUF_ZV (XBUFFER (w->buffer))) 22113 { 22114 maybe_next_line_p = 1; 22115 break; 22116 } 22117 else if (line_start_position > 0) 22118 { 22119 best_row = row; 22120 best_row_vpos = row_vpos; 22121 } 22122 22123 if (row->y + row->height >= yb) 22124 break; 22125 22126 ++row; 22127 ++row_vpos; 22128 } 22129 22130 /* Find the right column within BEST_ROW. */ 22131 lastcol = 0; 22132 current_x = best_row->x; 22133 for (i = 0; i < best_row->used[TEXT_AREA]; i++) 22134 { 22135 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i; 22136 int charpos = glyph->charpos; 22137 22138 if (BUFFERP (glyph->object)) 22139 { 22140 if (charpos == pos) 22141 { 22142 *hpos = i; 22143 *vpos = best_row_vpos; 22144 *x = current_x; 22145 *y = best_row->y; 22146 return 1; 22147 } 22148 else if (charpos > pos) 22149 break; 22150 } 22151 else if (EQ (glyph->object, stop)) 22152 break; 22153 22154 if (charpos > 0) 22155 lastcol = i; 22156 current_x += glyph->pixel_width; 22157 } 22158 22159 /* If we're looking for the end of the buffer, 22160 and we didn't find it in the line we scanned, 22161 use the start of the following line. */ 22162 if (maybe_next_line_p) 22163 { 22164 ++best_row; 22165 ++best_row_vpos; 22166 lastcol = 0; 22167 current_x = best_row->x; 22168 } 22169 22170 *vpos = best_row_vpos; 22171 *hpos = lastcol + 1; 22172 *x = current_x; 22173 *y = best_row->y; 22174 return 0; 22175} 22176 22177#endif /* not 1 */ 22178 22179 22180/* Find the position of the glyph for position POS in OBJECT in 22181 window W's current matrix, and return in *X, *Y the pixel 22182 coordinates, and return in *HPOS, *VPOS the column/row of the glyph. 22183 22184 RIGHT_P non-zero means return the position of the right edge of the 22185 glyph, RIGHT_P zero means return the left edge position. 22186 22187 If no glyph for POS exists in the matrix, return the position of 22188 the glyph with the next smaller position that is in the matrix, if 22189 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS 22190 exists in the matrix, return the position of the glyph with the 22191 next larger position in OBJECT. 22192 22193 Value is non-zero if a glyph was found. */ 22194 22195static int 22196fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p) 22197 struct window *w; 22198 int pos; 22199 Lisp_Object object; 22200 int *hpos, *vpos, *x, *y; 22201 int right_p; 22202{ 22203 int yb = window_text_bottom_y (w); 22204 struct glyph_row *r; 22205 struct glyph *best_glyph = NULL; 22206 struct glyph_row *best_row = NULL; 22207 int best_x = 0; 22208 22209 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 22210 r->enabled_p && r->y < yb; 22211 ++r) 22212 { 22213 struct glyph *g = r->glyphs[TEXT_AREA]; 22214 struct glyph *e = g + r->used[TEXT_AREA]; 22215 int gx; 22216 22217 for (gx = r->x; g < e; gx += g->pixel_width, ++g) 22218 if (EQ (g->object, object)) 22219 { 22220 if (g->charpos == pos) 22221 { 22222 best_glyph = g; 22223 best_x = gx; 22224 best_row = r; 22225 goto found; 22226 } 22227 else if (best_glyph == NULL 22228 || ((abs (g->charpos - pos) 22229 < abs (best_glyph->charpos - pos)) 22230 && (right_p 22231 ? g->charpos < pos 22232 : g->charpos > pos))) 22233 { 22234 best_glyph = g; 22235 best_x = gx; 22236 best_row = r; 22237 } 22238 } 22239 } 22240 22241 found: 22242 22243 if (best_glyph) 22244 { 22245 *x = best_x; 22246 *hpos = best_glyph - best_row->glyphs[TEXT_AREA]; 22247 22248 if (right_p) 22249 { 22250 *x += best_glyph->pixel_width; 22251 ++*hpos; 22252 } 22253 22254 *y = best_row->y; 22255 *vpos = best_row - w->current_matrix->rows; 22256 } 22257 22258 return best_glyph != NULL; 22259} 22260 22261 22262/* See if position X, Y is within a hot-spot of an image. */ 22263 22264static int 22265on_hot_spot_p (hot_spot, x, y) 22266 Lisp_Object hot_spot; 22267 int x, y; 22268{ 22269 if (!CONSP (hot_spot)) 22270 return 0; 22271 22272 if (EQ (XCAR (hot_spot), Qrect)) 22273 { 22274 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */ 22275 Lisp_Object rect = XCDR (hot_spot); 22276 Lisp_Object tem; 22277 if (!CONSP (rect)) 22278 return 0; 22279 if (!CONSP (XCAR (rect))) 22280 return 0; 22281 if (!CONSP (XCDR (rect))) 22282 return 0; 22283 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem))) 22284 return 0; 22285 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem))) 22286 return 0; 22287 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem))) 22288 return 0; 22289 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem))) 22290 return 0; 22291 return 1; 22292 } 22293 else if (EQ (XCAR (hot_spot), Qcircle)) 22294 { 22295 /* CDR is (Center . Radius) = ((x0 . y0) . r) */ 22296 Lisp_Object circ = XCDR (hot_spot); 22297 Lisp_Object lr, lx0, ly0; 22298 if (CONSP (circ) 22299 && CONSP (XCAR (circ)) 22300 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr)) 22301 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0)) 22302 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0))) 22303 { 22304 double r = XFLOATINT (lr); 22305 double dx = XINT (lx0) - x; 22306 double dy = XINT (ly0) - y; 22307 return (dx * dx + dy * dy <= r * r); 22308 } 22309 } 22310 else if (EQ (XCAR (hot_spot), Qpoly)) 22311 { 22312 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */ 22313 if (VECTORP (XCDR (hot_spot))) 22314 { 22315 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot)); 22316 Lisp_Object *poly = v->contents; 22317 int n = v->size; 22318 int i; 22319 int inside = 0; 22320 Lisp_Object lx, ly; 22321 int x0, y0; 22322 22323 /* Need an even number of coordinates, and at least 3 edges. */ 22324 if (n < 6 || n & 1) 22325 return 0; 22326 22327 /* Count edge segments intersecting line from (X,Y) to (X,infinity). 22328 If count is odd, we are inside polygon. Pixels on edges 22329 may or may not be included depending on actual geometry of the 22330 polygon. */ 22331 if ((lx = poly[n-2], !INTEGERP (lx)) 22332 || (ly = poly[n-1], !INTEGERP (lx))) 22333 return 0; 22334 x0 = XINT (lx), y0 = XINT (ly); 22335 for (i = 0; i < n; i += 2) 22336 { 22337 int x1 = x0, y1 = y0; 22338 if ((lx = poly[i], !INTEGERP (lx)) 22339 || (ly = poly[i+1], !INTEGERP (ly))) 22340 return 0; 22341 x0 = XINT (lx), y0 = XINT (ly); 22342 22343 /* Does this segment cross the X line? */ 22344 if (x0 >= x) 22345 { 22346 if (x1 >= x) 22347 continue; 22348 } 22349 else if (x1 < x) 22350 continue; 22351 if (y > y0 && y > y1) 22352 continue; 22353 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0)) 22354 inside = !inside; 22355 } 22356 return inside; 22357 } 22358 } 22359 /* If we don't understand the format, pretend we're not in the hot-spot. */ 22360 return 0; 22361} 22362 22363Lisp_Object 22364find_hot_spot (map, x, y) 22365 Lisp_Object map; 22366 int x, y; 22367{ 22368 while (CONSP (map)) 22369 { 22370 if (CONSP (XCAR (map)) 22371 && on_hot_spot_p (XCAR (XCAR (map)), x, y)) 22372 return XCAR (map); 22373 map = XCDR (map); 22374 } 22375 22376 return Qnil; 22377} 22378 22379DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map, 22380 3, 3, 0, 22381 doc: /* Lookup in image map MAP coordinates X and Y. 22382An image map is an alist where each element has the format (AREA ID PLIST). 22383An AREA is specified as either a rectangle, a circle, or a polygon: 22384A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the 22385pixel coordinates of the upper left and bottom right corners. 22386A circle is a cons (circle . ((x0 . y0) . r)) specifying the center 22387and the radius of the circle; r may be a float or integer. 22388A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the 22389vector describes one corner in the polygon. 22390Returns the alist element for the first matching AREA in MAP. */) 22391 (map, x, y) 22392 Lisp_Object map; 22393 Lisp_Object x, y; 22394{ 22395 if (NILP (map)) 22396 return Qnil; 22397 22398 CHECK_NUMBER (x); 22399 CHECK_NUMBER (y); 22400 22401 return find_hot_spot (map, XINT (x), XINT (y)); 22402} 22403 22404 22405/* Display frame CURSOR, optionally using shape defined by POINTER. */ 22406static void 22407define_frame_cursor1 (f, cursor, pointer) 22408 struct frame *f; 22409 Cursor cursor; 22410 Lisp_Object pointer; 22411{ 22412 /* Do not change cursor shape while dragging mouse. */ 22413 if (!NILP (do_mouse_tracking)) 22414 return; 22415 22416 if (!NILP (pointer)) 22417 { 22418 if (EQ (pointer, Qarrow)) 22419 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 22420 else if (EQ (pointer, Qhand)) 22421 cursor = FRAME_X_OUTPUT (f)->hand_cursor; 22422 else if (EQ (pointer, Qtext)) 22423 cursor = FRAME_X_OUTPUT (f)->text_cursor; 22424 else if (EQ (pointer, intern ("hdrag"))) 22425 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; 22426#ifdef HAVE_X_WINDOWS 22427 else if (EQ (pointer, intern ("vdrag"))) 22428 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; 22429#endif 22430 else if (EQ (pointer, intern ("hourglass"))) 22431 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor; 22432 else if (EQ (pointer, Qmodeline)) 22433 cursor = FRAME_X_OUTPUT (f)->modeline_cursor; 22434 else 22435 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 22436 } 22437 22438 if (cursor != No_Cursor) 22439 rif->define_frame_cursor (f, cursor); 22440} 22441 22442/* Take proper action when mouse has moved to the mode or header line 22443 or marginal area AREA of window W, x-position X and y-position Y. 22444 X is relative to the start of the text display area of W, so the 22445 width of bitmap areas and scroll bars must be subtracted to get a 22446 position relative to the start of the mode line. */ 22447 22448static void 22449note_mode_line_or_margin_highlight (window, x, y, area) 22450 Lisp_Object window; 22451 int x, y; 22452 enum window_part area; 22453{ 22454 struct window *w = XWINDOW (window); 22455 struct frame *f = XFRAME (w->frame); 22456 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 22457 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 22458 Lisp_Object pointer = Qnil; 22459 int charpos, dx, dy, width, height; 22460 Lisp_Object string, object = Qnil; 22461 Lisp_Object pos, help; 22462 22463 Lisp_Object mouse_face; 22464 int original_x_pixel = x; 22465 struct glyph * glyph = NULL, * row_start_glyph = NULL; 22466 struct glyph_row *row; 22467 22468 if (area == ON_MODE_LINE || area == ON_HEADER_LINE) 22469 { 22470 int x0; 22471 struct glyph *end; 22472 22473 string = mode_line_string (w, area, &x, &y, &charpos, 22474 &object, &dx, &dy, &width, &height); 22475 22476 row = (area == ON_MODE_LINE 22477 ? MATRIX_MODE_LINE_ROW (w->current_matrix) 22478 : MATRIX_HEADER_LINE_ROW (w->current_matrix)); 22479 22480 /* Find glyph */ 22481 if (row->mode_line_p && row->enabled_p) 22482 { 22483 glyph = row_start_glyph = row->glyphs[TEXT_AREA]; 22484 end = glyph + row->used[TEXT_AREA]; 22485 22486 for (x0 = original_x_pixel; 22487 glyph < end && x0 >= glyph->pixel_width; 22488 ++glyph) 22489 x0 -= glyph->pixel_width; 22490 22491 if (glyph >= end) 22492 glyph = NULL; 22493 } 22494 } 22495 else 22496 { 22497 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w); 22498 string = marginal_area_string (w, area, &x, &y, &charpos, 22499 &object, &dx, &dy, &width, &height); 22500 } 22501 22502 help = Qnil; 22503 22504 if (IMAGEP (object)) 22505 { 22506 Lisp_Object image_map, hotspot; 22507 if ((image_map = Fplist_get (XCDR (object), QCmap), 22508 !NILP (image_map)) 22509 && (hotspot = find_hot_spot (image_map, dx, dy), 22510 CONSP (hotspot)) 22511 && (hotspot = XCDR (hotspot), CONSP (hotspot))) 22512 { 22513 Lisp_Object area_id, plist; 22514 22515 area_id = XCAR (hotspot); 22516 /* Could check AREA_ID to see if we enter/leave this hot-spot. 22517 If so, we could look for mouse-enter, mouse-leave 22518 properties in PLIST (and do something...). */ 22519 hotspot = XCDR (hotspot); 22520 if (CONSP (hotspot) 22521 && (plist = XCAR (hotspot), CONSP (plist))) 22522 { 22523 pointer = Fplist_get (plist, Qpointer); 22524 if (NILP (pointer)) 22525 pointer = Qhand; 22526 help = Fplist_get (plist, Qhelp_echo); 22527 if (!NILP (help)) 22528 { 22529 help_echo_string = help; 22530 /* Is this correct? ++kfs */ 22531 XSETWINDOW (help_echo_window, w); 22532 help_echo_object = w->buffer; 22533 help_echo_pos = charpos; 22534 } 22535 } 22536 } 22537 if (NILP (pointer)) 22538 pointer = Fplist_get (XCDR (object), QCpointer); 22539 } 22540 22541 if (STRINGP (string)) 22542 { 22543 pos = make_number (charpos); 22544 /* If we're on a string with `help-echo' text property, arrange 22545 for the help to be displayed. This is done by setting the 22546 global variable help_echo_string to the help string. */ 22547 if (NILP (help)) 22548 { 22549 help = Fget_text_property (pos, Qhelp_echo, string); 22550 if (!NILP (help)) 22551 { 22552 help_echo_string = help; 22553 XSETWINDOW (help_echo_window, w); 22554 help_echo_object = string; 22555 help_echo_pos = charpos; 22556 } 22557 } 22558 22559 if (NILP (pointer)) 22560 pointer = Fget_text_property (pos, Qpointer, string); 22561 22562 /* Change the mouse pointer according to what is under X/Y. */ 22563 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))) 22564 { 22565 Lisp_Object map; 22566 map = Fget_text_property (pos, Qlocal_map, string); 22567 if (!KEYMAPP (map)) 22568 map = Fget_text_property (pos, Qkeymap, string); 22569 if (!KEYMAPP (map)) 22570 cursor = dpyinfo->vertical_scroll_bar_cursor; 22571 } 22572 22573 /* Change the mouse face according to what is under X/Y. */ 22574 mouse_face = Fget_text_property (pos, Qmouse_face, string); 22575 if (!NILP (mouse_face) 22576 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)) 22577 && glyph) 22578 { 22579 Lisp_Object b, e; 22580 22581 struct glyph * tmp_glyph; 22582 22583 int gpos; 22584 int gseq_length; 22585 int total_pixel_width; 22586 int ignore; 22587 22588 int vpos, hpos; 22589 22590 b = Fprevious_single_property_change (make_number (charpos + 1), 22591 Qmouse_face, string, Qnil); 22592 if (NILP (b)) 22593 b = make_number (0); 22594 22595 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil); 22596 if (NILP (e)) 22597 e = make_number (SCHARS (string)); 22598 22599 /* Calculate the position(glyph position: GPOS) of GLYPH in 22600 displayed string. GPOS is different from CHARPOS. 22601 22602 CHARPOS is the position of glyph in internal string 22603 object. A mode line string format has structures which 22604 is converted to a flatten by emacs lisp interpreter. 22605 The internal string is an element of the structures. 22606 The displayed string is the flatten string. */ 22607 gpos = 0; 22608 if (glyph > row_start_glyph) 22609 { 22610 tmp_glyph = glyph - 1; 22611 while (tmp_glyph >= row_start_glyph 22612 && tmp_glyph->charpos >= XINT (b) 22613 && EQ (tmp_glyph->object, glyph->object)) 22614 { 22615 tmp_glyph--; 22616 gpos++; 22617 } 22618 } 22619 22620 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of 22621 displayed string holding GLYPH. 22622 22623 GSEQ_LENGTH is different from SCHARS (STRING). 22624 SCHARS (STRING) returns the length of the internal string. */ 22625 for (tmp_glyph = glyph, gseq_length = gpos; 22626 tmp_glyph->charpos < XINT (e); 22627 tmp_glyph++, gseq_length++) 22628 { 22629 if (!EQ (tmp_glyph->object, glyph->object)) 22630 break; 22631 } 22632 22633 total_pixel_width = 0; 22634 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++) 22635 total_pixel_width += tmp_glyph->pixel_width; 22636 22637 /* Pre calculation of re-rendering position */ 22638 vpos = (x - gpos); 22639 hpos = (area == ON_MODE_LINE 22640 ? (w->current_matrix)->nrows - 1 22641 : 0); 22642 22643 /* If the re-rendering position is included in the last 22644 re-rendering area, we should do nothing. */ 22645 if ( EQ (window, dpyinfo->mouse_face_window) 22646 && dpyinfo->mouse_face_beg_col <= vpos 22647 && vpos < dpyinfo->mouse_face_end_col 22648 && dpyinfo->mouse_face_beg_row == hpos ) 22649 return; 22650 22651 if (clear_mouse_face (dpyinfo)) 22652 cursor = No_Cursor; 22653 22654 dpyinfo->mouse_face_beg_col = vpos; 22655 dpyinfo->mouse_face_beg_row = hpos; 22656 22657 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx); 22658 dpyinfo->mouse_face_beg_y = 0; 22659 22660 dpyinfo->mouse_face_end_col = vpos + gseq_length; 22661 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row; 22662 22663 dpyinfo->mouse_face_end_x = 0; 22664 dpyinfo->mouse_face_end_y = 0; 22665 22666 dpyinfo->mouse_face_past_end = 0; 22667 dpyinfo->mouse_face_window = window; 22668 22669 dpyinfo->mouse_face_face_id = face_at_string_position (w, string, 22670 charpos, 22671 0, 0, 0, &ignore, 22672 glyph->face_id, 1); 22673 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 22674 22675 if (NILP (pointer)) 22676 pointer = Qhand; 22677 } 22678 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)) 22679 clear_mouse_face (dpyinfo); 22680 } 22681 define_frame_cursor1 (f, cursor, pointer); 22682} 22683 22684 22685/* EXPORT: 22686 Take proper action when the mouse has moved to position X, Y on 22687 frame F as regards highlighting characters that have mouse-face 22688 properties. Also de-highlighting chars where the mouse was before. 22689 X and Y can be negative or out of range. */ 22690 22691void 22692note_mouse_highlight (f, x, y) 22693 struct frame *f; 22694 int x, y; 22695{ 22696 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 22697 enum window_part part; 22698 Lisp_Object window; 22699 struct window *w; 22700 Cursor cursor = No_Cursor; 22701 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */ 22702 struct buffer *b; 22703 22704 /* When a menu is active, don't highlight because this looks odd. */ 22705#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS) 22706 if (popup_activated ()) 22707 return; 22708#endif 22709 22710 if (NILP (Vmouse_highlight) 22711 || !f->glyphs_initialized_p) 22712 return; 22713 22714 dpyinfo->mouse_face_mouse_x = x; 22715 dpyinfo->mouse_face_mouse_y = y; 22716 dpyinfo->mouse_face_mouse_frame = f; 22717 22718 if (dpyinfo->mouse_face_defer) 22719 return; 22720 22721 if (gc_in_progress) 22722 { 22723 dpyinfo->mouse_face_deferred_gc = 1; 22724 return; 22725 } 22726 22727 /* Which window is that in? */ 22728 window = window_from_coordinates (f, x, y, &part, 0, 0, 1); 22729 22730 /* If we were displaying active text in another window, clear that. 22731 Also clear if we move out of text area in same window. */ 22732 if (! EQ (window, dpyinfo->mouse_face_window) 22733 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE 22734 && !NILP (dpyinfo->mouse_face_window))) 22735 clear_mouse_face (dpyinfo); 22736 22737 /* Not on a window -> return. */ 22738 if (!WINDOWP (window)) 22739 return; 22740 22741 /* Reset help_echo_string. It will get recomputed below. */ 22742 help_echo_string = Qnil; 22743 22744 /* Convert to window-relative pixel coordinates. */ 22745 w = XWINDOW (window); 22746 frame_to_window_pixel_xy (w, &x, &y); 22747 22748 /* Handle tool-bar window differently since it doesn't display a 22749 buffer. */ 22750 if (EQ (window, f->tool_bar_window)) 22751 { 22752 note_tool_bar_highlight (f, x, y); 22753 return; 22754 } 22755 22756 /* Mouse is on the mode, header line or margin? */ 22757 if (part == ON_MODE_LINE || part == ON_HEADER_LINE 22758 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN) 22759 { 22760 note_mode_line_or_margin_highlight (window, x, y, part); 22761 return; 22762 } 22763 22764 if (part == ON_VERTICAL_BORDER) 22765 { 22766 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; 22767 help_echo_string = build_string ("drag-mouse-1: resize"); 22768 } 22769 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE 22770 || part == ON_SCROLL_BAR) 22771 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 22772 else 22773 cursor = FRAME_X_OUTPUT (f)->text_cursor; 22774 22775 /* Are we in a window whose display is up to date? 22776 And verify the buffer's text has not changed. */ 22777 b = XBUFFER (w->buffer); 22778 if (part == ON_TEXT 22779 && EQ (w->window_end_valid, w->buffer) 22780 && XFASTINT (w->last_modified) == BUF_MODIFF (b) 22781 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) 22782 { 22783 int hpos, vpos, pos, i, dx, dy, area; 22784 struct glyph *glyph; 22785 Lisp_Object object; 22786 Lisp_Object mouse_face = Qnil, overlay = Qnil, position; 22787 Lisp_Object *overlay_vec = NULL; 22788 int noverlays; 22789 struct buffer *obuf; 22790 int obegv, ozv, same_region; 22791 22792 /* Find the glyph under X/Y. */ 22793 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area); 22794 22795 /* Look for :pointer property on image. */ 22796 if (glyph != NULL && glyph->type == IMAGE_GLYPH) 22797 { 22798 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id); 22799 if (img != NULL && IMAGEP (img->spec)) 22800 { 22801 Lisp_Object image_map, hotspot; 22802 if ((image_map = Fplist_get (XCDR (img->spec), QCmap), 22803 !NILP (image_map)) 22804 && (hotspot = find_hot_spot (image_map, 22805 glyph->slice.x + dx, 22806 glyph->slice.y + dy), 22807 CONSP (hotspot)) 22808 && (hotspot = XCDR (hotspot), CONSP (hotspot))) 22809 { 22810 Lisp_Object area_id, plist; 22811 22812 area_id = XCAR (hotspot); 22813 /* Could check AREA_ID to see if we enter/leave this hot-spot. 22814 If so, we could look for mouse-enter, mouse-leave 22815 properties in PLIST (and do something...). */ 22816 hotspot = XCDR (hotspot); 22817 if (CONSP (hotspot) 22818 && (plist = XCAR (hotspot), CONSP (plist))) 22819 { 22820 pointer = Fplist_get (plist, Qpointer); 22821 if (NILP (pointer)) 22822 pointer = Qhand; 22823 help_echo_string = Fplist_get (plist, Qhelp_echo); 22824 if (!NILP (help_echo_string)) 22825 { 22826 help_echo_window = window; 22827 help_echo_object = glyph->object; 22828 help_echo_pos = glyph->charpos; 22829 } 22830 } 22831 } 22832 if (NILP (pointer)) 22833 pointer = Fplist_get (XCDR (img->spec), QCpointer); 22834 } 22835 } 22836 22837 /* Clear mouse face if X/Y not over text. */ 22838 if (glyph == NULL 22839 || area != TEXT_AREA 22840 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p) 22841 { 22842 if (clear_mouse_face (dpyinfo)) 22843 cursor = No_Cursor; 22844 if (NILP (pointer)) 22845 { 22846 if (area != TEXT_AREA) 22847 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 22848 else 22849 pointer = Vvoid_text_area_pointer; 22850 } 22851 goto set_cursor; 22852 } 22853 22854 pos = glyph->charpos; 22855 object = glyph->object; 22856 if (!STRINGP (object) && !BUFFERP (object)) 22857 goto set_cursor; 22858 22859 /* If we get an out-of-range value, return now; avoid an error. */ 22860 if (BUFFERP (object) && pos > BUF_Z (b)) 22861 goto set_cursor; 22862 22863 /* Make the window's buffer temporarily current for 22864 overlays_at and compute_char_face. */ 22865 obuf = current_buffer; 22866 current_buffer = b; 22867 obegv = BEGV; 22868 ozv = ZV; 22869 BEGV = BEG; 22870 ZV = Z; 22871 22872 /* Is this char mouse-active or does it have help-echo? */ 22873 position = make_number (pos); 22874 22875 if (BUFFERP (object)) 22876 { 22877 /* Put all the overlays we want in a vector in overlay_vec. */ 22878 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0); 22879 /* Sort overlays into increasing priority order. */ 22880 noverlays = sort_overlays (overlay_vec, noverlays, w); 22881 } 22882 else 22883 noverlays = 0; 22884 22885 same_region = (EQ (window, dpyinfo->mouse_face_window) 22886 && vpos >= dpyinfo->mouse_face_beg_row 22887 && vpos <= dpyinfo->mouse_face_end_row 22888 && (vpos > dpyinfo->mouse_face_beg_row 22889 || hpos >= dpyinfo->mouse_face_beg_col) 22890 && (vpos < dpyinfo->mouse_face_end_row 22891 || hpos < dpyinfo->mouse_face_end_col 22892 || dpyinfo->mouse_face_past_end)); 22893 22894 if (same_region) 22895 cursor = No_Cursor; 22896 22897 /* Check mouse-face highlighting. */ 22898 if (! same_region 22899 /* If there exists an overlay with mouse-face overlapping 22900 the one we are currently highlighting, we have to 22901 check if we enter the overlapping overlay, and then 22902 highlight only that. */ 22903 || (OVERLAYP (dpyinfo->mouse_face_overlay) 22904 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay))) 22905 { 22906 /* Find the highest priority overlay that has a mouse-face 22907 property. */ 22908 overlay = Qnil; 22909 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i) 22910 { 22911 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); 22912 if (!NILP (mouse_face)) 22913 overlay = overlay_vec[i]; 22914 } 22915 22916 /* If we're actually highlighting the same overlay as 22917 before, there's no need to do that again. */ 22918 if (!NILP (overlay) 22919 && EQ (overlay, dpyinfo->mouse_face_overlay)) 22920 goto check_help_echo; 22921 22922 dpyinfo->mouse_face_overlay = overlay; 22923 22924 /* Clear the display of the old active region, if any. */ 22925 if (clear_mouse_face (dpyinfo)) 22926 cursor = No_Cursor; 22927 22928 /* If no overlay applies, get a text property. */ 22929 if (NILP (overlay)) 22930 mouse_face = Fget_text_property (position, Qmouse_face, object); 22931 22932 /* Handle the overlay case. */ 22933 if (!NILP (overlay)) 22934 { 22935 /* Find the range of text around this char that 22936 should be active. */ 22937 Lisp_Object before, after; 22938 int ignore; 22939 22940 before = Foverlay_start (overlay); 22941 after = Foverlay_end (overlay); 22942 /* Record this as the current active region. */ 22943 fast_find_position (w, XFASTINT (before), 22944 &dpyinfo->mouse_face_beg_col, 22945 &dpyinfo->mouse_face_beg_row, 22946 &dpyinfo->mouse_face_beg_x, 22947 &dpyinfo->mouse_face_beg_y, Qnil); 22948 22949 dpyinfo->mouse_face_past_end 22950 = !fast_find_position (w, XFASTINT (after), 22951 &dpyinfo->mouse_face_end_col, 22952 &dpyinfo->mouse_face_end_row, 22953 &dpyinfo->mouse_face_end_x, 22954 &dpyinfo->mouse_face_end_y, Qnil); 22955 dpyinfo->mouse_face_window = window; 22956 22957 dpyinfo->mouse_face_face_id 22958 = face_at_buffer_position (w, pos, 0, 0, 22959 &ignore, pos + 1, 22960 !dpyinfo->mouse_face_hidden); 22961 22962 /* Display it as active. */ 22963 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 22964 cursor = No_Cursor; 22965 } 22966 /* Handle the text property case. */ 22967 else if (!NILP (mouse_face) && BUFFERP (object)) 22968 { 22969 /* Find the range of text around this char that 22970 should be active. */ 22971 Lisp_Object before, after, beginning, end; 22972 int ignore; 22973 22974 beginning = Fmarker_position (w->start); 22975 end = make_number (BUF_Z (XBUFFER (object)) 22976 - XFASTINT (w->window_end_pos)); 22977 before 22978 = Fprevious_single_property_change (make_number (pos + 1), 22979 Qmouse_face, 22980 object, beginning); 22981 after 22982 = Fnext_single_property_change (position, Qmouse_face, 22983 object, end); 22984 22985 /* Record this as the current active region. */ 22986 fast_find_position (w, XFASTINT (before), 22987 &dpyinfo->mouse_face_beg_col, 22988 &dpyinfo->mouse_face_beg_row, 22989 &dpyinfo->mouse_face_beg_x, 22990 &dpyinfo->mouse_face_beg_y, Qnil); 22991 dpyinfo->mouse_face_past_end 22992 = !fast_find_position (w, XFASTINT (after), 22993 &dpyinfo->mouse_face_end_col, 22994 &dpyinfo->mouse_face_end_row, 22995 &dpyinfo->mouse_face_end_x, 22996 &dpyinfo->mouse_face_end_y, Qnil); 22997 dpyinfo->mouse_face_window = window; 22998 22999 if (BUFFERP (object)) 23000 dpyinfo->mouse_face_face_id 23001 = face_at_buffer_position (w, pos, 0, 0, 23002 &ignore, pos + 1, 23003 !dpyinfo->mouse_face_hidden); 23004 23005 /* Display it as active. */ 23006 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 23007 cursor = No_Cursor; 23008 } 23009 else if (!NILP (mouse_face) && STRINGP (object)) 23010 { 23011 Lisp_Object b, e; 23012 int ignore; 23013 23014 b = Fprevious_single_property_change (make_number (pos + 1), 23015 Qmouse_face, 23016 object, Qnil); 23017 e = Fnext_single_property_change (position, Qmouse_face, 23018 object, Qnil); 23019 if (NILP (b)) 23020 b = make_number (0); 23021 if (NILP (e)) 23022 e = make_number (SCHARS (object) - 1); 23023 23024 fast_find_string_pos (w, XINT (b), object, 23025 &dpyinfo->mouse_face_beg_col, 23026 &dpyinfo->mouse_face_beg_row, 23027 &dpyinfo->mouse_face_beg_x, 23028 &dpyinfo->mouse_face_beg_y, 0); 23029 fast_find_string_pos (w, XINT (e), object, 23030 &dpyinfo->mouse_face_end_col, 23031 &dpyinfo->mouse_face_end_row, 23032 &dpyinfo->mouse_face_end_x, 23033 &dpyinfo->mouse_face_end_y, 1); 23034 dpyinfo->mouse_face_past_end = 0; 23035 dpyinfo->mouse_face_window = window; 23036 dpyinfo->mouse_face_face_id 23037 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore, 23038 glyph->face_id, 1); 23039 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 23040 cursor = No_Cursor; 23041 } 23042 else if (STRINGP (object) && NILP (mouse_face)) 23043 { 23044 /* A string which doesn't have mouse-face, but 23045 the text ``under'' it might have. */ 23046 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos); 23047 int start = MATRIX_ROW_START_CHARPOS (r); 23048 23049 pos = string_buffer_position (w, object, start); 23050 if (pos > 0) 23051 mouse_face = get_char_property_and_overlay (make_number (pos), 23052 Qmouse_face, 23053 w->buffer, 23054 &overlay); 23055 if (!NILP (mouse_face) && !NILP (overlay)) 23056 { 23057 Lisp_Object before = Foverlay_start (overlay); 23058 Lisp_Object after = Foverlay_end (overlay); 23059 int ignore; 23060 23061 /* Note that we might not be able to find position 23062 BEFORE in the glyph matrix if the overlay is 23063 entirely covered by a `display' property. In 23064 this case, we overshoot. So let's stop in 23065 the glyph matrix before glyphs for OBJECT. */ 23066 fast_find_position (w, XFASTINT (before), 23067 &dpyinfo->mouse_face_beg_col, 23068 &dpyinfo->mouse_face_beg_row, 23069 &dpyinfo->mouse_face_beg_x, 23070 &dpyinfo->mouse_face_beg_y, 23071 object); 23072 23073 dpyinfo->mouse_face_past_end 23074 = !fast_find_position (w, XFASTINT (after), 23075 &dpyinfo->mouse_face_end_col, 23076 &dpyinfo->mouse_face_end_row, 23077 &dpyinfo->mouse_face_end_x, 23078 &dpyinfo->mouse_face_end_y, 23079 Qnil); 23080 dpyinfo->mouse_face_window = window; 23081 dpyinfo->mouse_face_face_id 23082 = face_at_buffer_position (w, pos, 0, 0, 23083 &ignore, pos + 1, 23084 !dpyinfo->mouse_face_hidden); 23085 23086 /* Display it as active. */ 23087 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 23088 cursor = No_Cursor; 23089 } 23090 } 23091 } 23092 23093 check_help_echo: 23094 23095 /* Look for a `help-echo' property. */ 23096 if (NILP (help_echo_string)) { 23097 Lisp_Object help, overlay; 23098 23099 /* Check overlays first. */ 23100 help = overlay = Qnil; 23101 for (i = noverlays - 1; i >= 0 && NILP (help); --i) 23102 { 23103 overlay = overlay_vec[i]; 23104 help = Foverlay_get (overlay, Qhelp_echo); 23105 } 23106 23107 if (!NILP (help)) 23108 { 23109 help_echo_string = help; 23110 help_echo_window = window; 23111 help_echo_object = overlay; 23112 help_echo_pos = pos; 23113 } 23114 else 23115 { 23116 Lisp_Object object = glyph->object; 23117 int charpos = glyph->charpos; 23118 23119 /* Try text properties. */ 23120 if (STRINGP (object) 23121 && charpos >= 0 23122 && charpos < SCHARS (object)) 23123 { 23124 help = Fget_text_property (make_number (charpos), 23125 Qhelp_echo, object); 23126 if (NILP (help)) 23127 { 23128 /* If the string itself doesn't specify a help-echo, 23129 see if the buffer text ``under'' it does. */ 23130 struct glyph_row *r 23131 = MATRIX_ROW (w->current_matrix, vpos); 23132 int start = MATRIX_ROW_START_CHARPOS (r); 23133 int pos = string_buffer_position (w, object, start); 23134 if (pos > 0) 23135 { 23136 help = Fget_char_property (make_number (pos), 23137 Qhelp_echo, w->buffer); 23138 if (!NILP (help)) 23139 { 23140 charpos = pos; 23141 object = w->buffer; 23142 } 23143 } 23144 } 23145 } 23146 else if (BUFFERP (object) 23147 && charpos >= BEGV 23148 && charpos < ZV) 23149 help = Fget_text_property (make_number (charpos), Qhelp_echo, 23150 object); 23151 23152 if (!NILP (help)) 23153 { 23154 help_echo_string = help; 23155 help_echo_window = window; 23156 help_echo_object = object; 23157 help_echo_pos = charpos; 23158 } 23159 } 23160 } 23161 23162 /* Look for a `pointer' property. */ 23163 if (NILP (pointer)) 23164 { 23165 /* Check overlays first. */ 23166 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i) 23167 pointer = Foverlay_get (overlay_vec[i], Qpointer); 23168 23169 if (NILP (pointer)) 23170 { 23171 Lisp_Object object = glyph->object; 23172 int charpos = glyph->charpos; 23173 23174 /* Try text properties. */ 23175 if (STRINGP (object) 23176 && charpos >= 0 23177 && charpos < SCHARS (object)) 23178 { 23179 pointer = Fget_text_property (make_number (charpos), 23180 Qpointer, object); 23181 if (NILP (pointer)) 23182 { 23183 /* If the string itself doesn't specify a pointer, 23184 see if the buffer text ``under'' it does. */ 23185 struct glyph_row *r 23186 = MATRIX_ROW (w->current_matrix, vpos); 23187 int start = MATRIX_ROW_START_CHARPOS (r); 23188 int pos = string_buffer_position (w, object, start); 23189 if (pos > 0) 23190 pointer = Fget_char_property (make_number (pos), 23191 Qpointer, w->buffer); 23192 } 23193 } 23194 else if (BUFFERP (object) 23195 && charpos >= BEGV 23196 && charpos < ZV) 23197 pointer = Fget_text_property (make_number (charpos), 23198 Qpointer, object); 23199 } 23200 } 23201 23202 BEGV = obegv; 23203 ZV = ozv; 23204 current_buffer = obuf; 23205 } 23206 23207 set_cursor: 23208 23209 define_frame_cursor1 (f, cursor, pointer); 23210} 23211 23212 23213/* EXPORT for RIF: 23214 Clear any mouse-face on window W. This function is part of the 23215 redisplay interface, and is called from try_window_id and similar 23216 functions to ensure the mouse-highlight is off. */ 23217 23218void 23219x_clear_window_mouse_face (w) 23220 struct window *w; 23221{ 23222 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); 23223 Lisp_Object window; 23224 23225 BLOCK_INPUT; 23226 XSETWINDOW (window, w); 23227 if (EQ (window, dpyinfo->mouse_face_window)) 23228 clear_mouse_face (dpyinfo); 23229 UNBLOCK_INPUT; 23230} 23231 23232 23233/* EXPORT: 23234 Just discard the mouse face information for frame F, if any. 23235 This is used when the size of F is changed. */ 23236 23237void 23238cancel_mouse_face (f) 23239 struct frame *f; 23240{ 23241 Lisp_Object window; 23242 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 23243 23244 window = dpyinfo->mouse_face_window; 23245 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) 23246 { 23247 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 23248 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 23249 dpyinfo->mouse_face_window = Qnil; 23250 } 23251} 23252 23253 23254#endif /* HAVE_WINDOW_SYSTEM */ 23255 23256 23257/*********************************************************************** 23258 Exposure Events 23259 ***********************************************************************/ 23260 23261#ifdef HAVE_WINDOW_SYSTEM 23262 23263/* Redraw the part of glyph row area AREA of glyph row ROW on window W 23264 which intersects rectangle R. R is in window-relative coordinates. */ 23265 23266static void 23267expose_area (w, row, r, area) 23268 struct window *w; 23269 struct glyph_row *row; 23270 XRectangle *r; 23271 enum glyph_row_area area; 23272{ 23273 struct glyph *first = row->glyphs[area]; 23274 struct glyph *end = row->glyphs[area] + row->used[area]; 23275 struct glyph *last; 23276 int first_x, start_x, x; 23277 23278 if (area == TEXT_AREA && row->fill_line_p) 23279 /* If row extends face to end of line write the whole line. */ 23280 draw_glyphs (w, 0, row, area, 23281 0, row->used[area], 23282 DRAW_NORMAL_TEXT, 0); 23283 else 23284 { 23285 /* Set START_X to the window-relative start position for drawing glyphs of 23286 AREA. The first glyph of the text area can be partially visible. 23287 The first glyphs of other areas cannot. */ 23288 start_x = window_box_left_offset (w, area); 23289 x = start_x; 23290 if (area == TEXT_AREA) 23291 x += row->x; 23292 23293 /* Find the first glyph that must be redrawn. */ 23294 while (first < end 23295 && x + first->pixel_width < r->x) 23296 { 23297 x += first->pixel_width; 23298 ++first; 23299 } 23300 23301 /* Find the last one. */ 23302 last = first; 23303 first_x = x; 23304 while (last < end 23305 && x < r->x + r->width) 23306 { 23307 x += last->pixel_width; 23308 ++last; 23309 } 23310 23311 /* Repaint. */ 23312 if (last > first) 23313 draw_glyphs (w, first_x - start_x, row, area, 23314 first - row->glyphs[area], last - row->glyphs[area], 23315 DRAW_NORMAL_TEXT, 0); 23316 } 23317} 23318 23319 23320/* Redraw the parts of the glyph row ROW on window W intersecting 23321 rectangle R. R is in window-relative coordinates. Value is 23322 non-zero if mouse-face was overwritten. */ 23323 23324static int 23325expose_line (w, row, r) 23326 struct window *w; 23327 struct glyph_row *row; 23328 XRectangle *r; 23329{ 23330 xassert (row->enabled_p); 23331 23332 if (row->mode_line_p || w->pseudo_window_p) 23333 draw_glyphs (w, 0, row, TEXT_AREA, 23334 0, row->used[TEXT_AREA], 23335 DRAW_NORMAL_TEXT, 0); 23336 else 23337 { 23338 if (row->used[LEFT_MARGIN_AREA]) 23339 expose_area (w, row, r, LEFT_MARGIN_AREA); 23340 if (row->used[TEXT_AREA]) 23341 expose_area (w, row, r, TEXT_AREA); 23342 if (row->used[RIGHT_MARGIN_AREA]) 23343 expose_area (w, row, r, RIGHT_MARGIN_AREA); 23344 draw_row_fringe_bitmaps (w, row); 23345 } 23346 23347 return row->mouse_face_p; 23348} 23349 23350 23351/* Redraw those parts of glyphs rows during expose event handling that 23352 overlap other rows. Redrawing of an exposed line writes over parts 23353 of lines overlapping that exposed line; this function fixes that. 23354 23355 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first 23356 row in W's current matrix that is exposed and overlaps other rows. 23357 LAST_OVERLAPPING_ROW is the last such row. */ 23358 23359static void 23360expose_overlaps (w, first_overlapping_row, last_overlapping_row) 23361 struct window *w; 23362 struct glyph_row *first_overlapping_row; 23363 struct glyph_row *last_overlapping_row; 23364{ 23365 struct glyph_row *row; 23366 23367 for (row = first_overlapping_row; row <= last_overlapping_row; ++row) 23368 if (row->overlapping_p) 23369 { 23370 xassert (row->enabled_p && !row->mode_line_p); 23371 23372 if (row->used[LEFT_MARGIN_AREA]) 23373 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH); 23374 23375 if (row->used[TEXT_AREA]) 23376 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH); 23377 23378 if (row->used[RIGHT_MARGIN_AREA]) 23379 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH); 23380 } 23381} 23382 23383 23384/* Return non-zero if W's cursor intersects rectangle R. */ 23385 23386static int 23387phys_cursor_in_rect_p (w, r) 23388 struct window *w; 23389 XRectangle *r; 23390{ 23391 XRectangle cr, result; 23392 struct glyph *cursor_glyph; 23393 23394 cursor_glyph = get_phys_cursor_glyph (w); 23395 if (cursor_glyph) 23396 { 23397 /* r is relative to W's box, but w->phys_cursor.x is relative 23398 to left edge of W's TEXT area. Adjust it. */ 23399 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x; 23400 cr.y = w->phys_cursor.y; 23401 cr.width = cursor_glyph->pixel_width; 23402 cr.height = w->phys_cursor_height; 23403 /* ++KFS: W32 version used W32-specific IntersectRect here, but 23404 I assume the effect is the same -- and this is portable. */ 23405 return x_intersect_rectangles (&cr, r, &result); 23406 } 23407 else 23408 return 0; 23409} 23410 23411 23412/* EXPORT: 23413 Draw a vertical window border to the right of window W if W doesn't 23414 have vertical scroll bars. */ 23415 23416void 23417x_draw_vertical_border (w) 23418 struct window *w; 23419{ 23420 /* We could do better, if we knew what type of scroll-bar the adjacent 23421 windows (on either side) have... But we don't :-( 23422 However, I think this works ok. ++KFS 2003-04-25 */ 23423 23424 /* Redraw borders between horizontally adjacent windows. Don't 23425 do it for frames with vertical scroll bars because either the 23426 right scroll bar of a window, or the left scroll bar of its 23427 neighbor will suffice as a border. */ 23428 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame))) 23429 return; 23430 23431 if (!WINDOW_RIGHTMOST_P (w) 23432 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)) 23433 { 23434 int x0, x1, y0, y1; 23435 23436 window_box_edges (w, -1, &x0, &y0, &x1, &y1); 23437 y1 -= 1; 23438 23439 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) 23440 x1 -= 1; 23441 23442 rif->draw_vertical_window_border (w, x1, y0, y1); 23443 } 23444 else if (!WINDOW_LEFTMOST_P (w) 23445 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) 23446 { 23447 int x0, x1, y0, y1; 23448 23449 window_box_edges (w, -1, &x0, &y0, &x1, &y1); 23450 y1 -= 1; 23451 23452 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) 23453 x0 -= 1; 23454 23455 rif->draw_vertical_window_border (w, x0, y0, y1); 23456 } 23457} 23458 23459 23460/* Redraw the part of window W intersection rectangle FR. Pixel 23461 coordinates in FR are frame-relative. Call this function with 23462 input blocked. Value is non-zero if the exposure overwrites 23463 mouse-face. */ 23464 23465static int 23466expose_window (w, fr) 23467 struct window *w; 23468 XRectangle *fr; 23469{ 23470 struct frame *f = XFRAME (w->frame); 23471 XRectangle wr, r; 23472 int mouse_face_overwritten_p = 0; 23473 23474 /* If window is not yet fully initialized, do nothing. This can 23475 happen when toolkit scroll bars are used and a window is split. 23476 Reconfiguring the scroll bar will generate an expose for a newly 23477 created window. */ 23478 if (w->current_matrix == NULL) 23479 return 0; 23480 23481 /* When we're currently updating the window, display and current 23482 matrix usually don't agree. Arrange for a thorough display 23483 later. */ 23484 if (w == updated_window) 23485 { 23486 SET_FRAME_GARBAGED (f); 23487 return 0; 23488 } 23489 23490 /* Frame-relative pixel rectangle of W. */ 23491 wr.x = WINDOW_LEFT_EDGE_X (w); 23492 wr.y = WINDOW_TOP_EDGE_Y (w); 23493 wr.width = WINDOW_TOTAL_WIDTH (w); 23494 wr.height = WINDOW_TOTAL_HEIGHT (w); 23495 23496 if (x_intersect_rectangles (fr, &wr, &r)) 23497 { 23498 int yb = window_text_bottom_y (w); 23499 struct glyph_row *row; 23500 int cursor_cleared_p; 23501 struct glyph_row *first_overlapping_row, *last_overlapping_row; 23502 23503 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", 23504 r.x, r.y, r.width, r.height)); 23505 23506 /* Convert to window coordinates. */ 23507 r.x -= WINDOW_LEFT_EDGE_X (w); 23508 r.y -= WINDOW_TOP_EDGE_Y (w); 23509 23510 /* Turn off the cursor. */ 23511 if (!w->pseudo_window_p 23512 && phys_cursor_in_rect_p (w, &r)) 23513 { 23514 x_clear_cursor (w); 23515 cursor_cleared_p = 1; 23516 } 23517 else 23518 cursor_cleared_p = 0; 23519 23520 /* Update lines intersecting rectangle R. */ 23521 first_overlapping_row = last_overlapping_row = NULL; 23522 for (row = w->current_matrix->rows; 23523 row->enabled_p; 23524 ++row) 23525 { 23526 int y0 = row->y; 23527 int y1 = MATRIX_ROW_BOTTOM_Y (row); 23528 23529 if ((y0 >= r.y && y0 < r.y + r.height) 23530 || (y1 > r.y && y1 < r.y + r.height) 23531 || (r.y >= y0 && r.y < y1) 23532 || (r.y + r.height > y0 && r.y + r.height < y1)) 23533 { 23534 /* A header line may be overlapping, but there is no need 23535 to fix overlapping areas for them. KFS 2005-02-12 */ 23536 if (row->overlapping_p && !row->mode_line_p) 23537 { 23538 if (first_overlapping_row == NULL) 23539 first_overlapping_row = row; 23540 last_overlapping_row = row; 23541 } 23542 23543 if (expose_line (w, row, &r)) 23544 mouse_face_overwritten_p = 1; 23545 } 23546 23547 if (y1 >= yb) 23548 break; 23549 } 23550 23551 /* Display the mode line if there is one. */ 23552 if (WINDOW_WANTS_MODELINE_P (w) 23553 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix), 23554 row->enabled_p) 23555 && row->y < r.y + r.height) 23556 { 23557 if (expose_line (w, row, &r)) 23558 mouse_face_overwritten_p = 1; 23559 } 23560 23561 if (!w->pseudo_window_p) 23562 { 23563 /* Fix the display of overlapping rows. */ 23564 if (first_overlapping_row) 23565 expose_overlaps (w, first_overlapping_row, last_overlapping_row); 23566 23567 /* Draw border between windows. */ 23568 x_draw_vertical_border (w); 23569 23570 /* Turn the cursor on again. */ 23571 if (cursor_cleared_p) 23572 update_window_cursor (w, 1); 23573 } 23574 } 23575 23576 return mouse_face_overwritten_p; 23577} 23578 23579 23580 23581/* Redraw (parts) of all windows in the window tree rooted at W that 23582 intersect R. R contains frame pixel coordinates. Value is 23583 non-zero if the exposure overwrites mouse-face. */ 23584 23585static int 23586expose_window_tree (w, r) 23587 struct window *w; 23588 XRectangle *r; 23589{ 23590 struct frame *f = XFRAME (w->frame); 23591 int mouse_face_overwritten_p = 0; 23592 23593 while (w && !FRAME_GARBAGED_P (f)) 23594 { 23595 if (!NILP (w->hchild)) 23596 mouse_face_overwritten_p 23597 |= expose_window_tree (XWINDOW (w->hchild), r); 23598 else if (!NILP (w->vchild)) 23599 mouse_face_overwritten_p 23600 |= expose_window_tree (XWINDOW (w->vchild), r); 23601 else 23602 mouse_face_overwritten_p |= expose_window (w, r); 23603 23604 w = NILP (w->next) ? NULL : XWINDOW (w->next); 23605 } 23606 23607 return mouse_face_overwritten_p; 23608} 23609 23610 23611/* EXPORT: 23612 Redisplay an exposed area of frame F. X and Y are the upper-left 23613 corner of the exposed rectangle. W and H are width and height of 23614 the exposed area. All are pixel values. W or H zero means redraw 23615 the entire frame. */ 23616 23617void 23618expose_frame (f, x, y, w, h) 23619 struct frame *f; 23620 int x, y, w, h; 23621{ 23622 XRectangle r; 23623 int mouse_face_overwritten_p = 0; 23624 23625 TRACE ((stderr, "expose_frame ")); 23626 23627 /* No need to redraw if frame will be redrawn soon. */ 23628 if (FRAME_GARBAGED_P (f)) 23629 { 23630 TRACE ((stderr, " garbaged\n")); 23631 return; 23632 } 23633 23634 /* If basic faces haven't been realized yet, there is no point in 23635 trying to redraw anything. This can happen when we get an expose 23636 event while Emacs is starting, e.g. by moving another window. */ 23637 if (FRAME_FACE_CACHE (f) == NULL 23638 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL) 23639 { 23640 TRACE ((stderr, " no faces\n")); 23641 return; 23642 } 23643 23644 if (w == 0 || h == 0) 23645 { 23646 r.x = r.y = 0; 23647 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); 23648 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); 23649 } 23650 else 23651 { 23652 r.x = x; 23653 r.y = y; 23654 r.width = w; 23655 r.height = h; 23656 } 23657 23658 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height)); 23659 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r); 23660 23661 if (WINDOWP (f->tool_bar_window)) 23662 mouse_face_overwritten_p 23663 |= expose_window (XWINDOW (f->tool_bar_window), &r); 23664 23665#ifdef HAVE_X_WINDOWS 23666#ifndef MSDOS 23667#ifndef USE_X_TOOLKIT 23668 if (WINDOWP (f->menu_bar_window)) 23669 mouse_face_overwritten_p 23670 |= expose_window (XWINDOW (f->menu_bar_window), &r); 23671#endif /* not USE_X_TOOLKIT */ 23672#endif 23673#endif 23674 23675 /* Some window managers support a focus-follows-mouse style with 23676 delayed raising of frames. Imagine a partially obscured frame, 23677 and moving the mouse into partially obscured mouse-face on that 23678 frame. The visible part of the mouse-face will be highlighted, 23679 then the WM raises the obscured frame. With at least one WM, KDE 23680 2.1, Emacs is not getting any event for the raising of the frame 23681 (even tried with SubstructureRedirectMask), only Expose events. 23682 These expose events will draw text normally, i.e. not 23683 highlighted. Which means we must redo the highlight here. 23684 Subsume it under ``we love X''. --gerd 2001-08-15 */ 23685 /* Included in Windows version because Windows most likely does not 23686 do the right thing if any third party tool offers 23687 focus-follows-mouse with delayed raise. --jason 2001-10-12 */ 23688 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f)) 23689 { 23690 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 23691 if (f == dpyinfo->mouse_face_mouse_frame) 23692 { 23693 int x = dpyinfo->mouse_face_mouse_x; 23694 int y = dpyinfo->mouse_face_mouse_y; 23695 clear_mouse_face (dpyinfo); 23696 note_mouse_highlight (f, x, y); 23697 } 23698 } 23699} 23700 23701 23702/* EXPORT: 23703 Determine the intersection of two rectangles R1 and R2. Return 23704 the intersection in *RESULT. Value is non-zero if RESULT is not 23705 empty. */ 23706 23707int 23708x_intersect_rectangles (r1, r2, result) 23709 XRectangle *r1, *r2, *result; 23710{ 23711 XRectangle *left, *right; 23712 XRectangle *upper, *lower; 23713 int intersection_p = 0; 23714 23715 /* Rearrange so that R1 is the left-most rectangle. */ 23716 if (r1->x < r2->x) 23717 left = r1, right = r2; 23718 else 23719 left = r2, right = r1; 23720 23721 /* X0 of the intersection is right.x0, if this is inside R1, 23722 otherwise there is no intersection. */ 23723 if (right->x <= left->x + left->width) 23724 { 23725 result->x = right->x; 23726 23727 /* The right end of the intersection is the minimum of the 23728 the right ends of left and right. */ 23729 result->width = (min (left->x + left->width, right->x + right->width) 23730 - result->x); 23731 23732 /* Same game for Y. */ 23733 if (r1->y < r2->y) 23734 upper = r1, lower = r2; 23735 else 23736 upper = r2, lower = r1; 23737 23738 /* The upper end of the intersection is lower.y0, if this is inside 23739 of upper. Otherwise, there is no intersection. */ 23740 if (lower->y <= upper->y + upper->height) 23741 { 23742 result->y = lower->y; 23743 23744 /* The lower end of the intersection is the minimum of the lower 23745 ends of upper and lower. */ 23746 result->height = (min (lower->y + lower->height, 23747 upper->y + upper->height) 23748 - result->y); 23749 intersection_p = 1; 23750 } 23751 } 23752 23753 return intersection_p; 23754} 23755 23756#endif /* HAVE_WINDOW_SYSTEM */ 23757 23758 23759/*********************************************************************** 23760 Initialization 23761 ***********************************************************************/ 23762 23763void 23764syms_of_xdisp () 23765{ 23766 Vwith_echo_area_save_vector = Qnil; 23767 staticpro (&Vwith_echo_area_save_vector); 23768 23769 Vmessage_stack = Qnil; 23770 staticpro (&Vmessage_stack); 23771 23772 Qinhibit_redisplay = intern ("inhibit-redisplay"); 23773 staticpro (&Qinhibit_redisplay); 23774 23775 message_dolog_marker1 = Fmake_marker (); 23776 staticpro (&message_dolog_marker1); 23777 message_dolog_marker2 = Fmake_marker (); 23778 staticpro (&message_dolog_marker2); 23779 message_dolog_marker3 = Fmake_marker (); 23780 staticpro (&message_dolog_marker3); 23781 23782#if GLYPH_DEBUG 23783 defsubr (&Sdump_frame_glyph_matrix); 23784 defsubr (&Sdump_glyph_matrix); 23785 defsubr (&Sdump_glyph_row); 23786 defsubr (&Sdump_tool_bar_row); 23787 defsubr (&Strace_redisplay); 23788 defsubr (&Strace_to_stderr); 23789#endif 23790#ifdef HAVE_WINDOW_SYSTEM 23791 defsubr (&Stool_bar_lines_needed); 23792 defsubr (&Slookup_image_map); 23793#endif 23794 defsubr (&Sformat_mode_line); 23795 23796 staticpro (&Qmenu_bar_update_hook); 23797 Qmenu_bar_update_hook = intern ("menu-bar-update-hook"); 23798 23799 staticpro (&Qoverriding_terminal_local_map); 23800 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map"); 23801 23802 staticpro (&Qoverriding_local_map); 23803 Qoverriding_local_map = intern ("overriding-local-map"); 23804 23805 staticpro (&Qwindow_scroll_functions); 23806 Qwindow_scroll_functions = intern ("window-scroll-functions"); 23807 23808 staticpro (&Qredisplay_end_trigger_functions); 23809 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions"); 23810 23811 staticpro (&Qinhibit_point_motion_hooks); 23812 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks"); 23813 23814 QCdata = intern (":data"); 23815 staticpro (&QCdata); 23816 Qdisplay = intern ("display"); 23817 staticpro (&Qdisplay); 23818 Qspace_width = intern ("space-width"); 23819 staticpro (&Qspace_width); 23820 Qraise = intern ("raise"); 23821 staticpro (&Qraise); 23822 Qslice = intern ("slice"); 23823 staticpro (&Qslice); 23824 Qspace = intern ("space"); 23825 staticpro (&Qspace); 23826 Qmargin = intern ("margin"); 23827 staticpro (&Qmargin); 23828 Qpointer = intern ("pointer"); 23829 staticpro (&Qpointer); 23830 Qleft_margin = intern ("left-margin"); 23831 staticpro (&Qleft_margin); 23832 Qright_margin = intern ("right-margin"); 23833 staticpro (&Qright_margin); 23834 Qcenter = intern ("center"); 23835 staticpro (&Qcenter); 23836 Qline_height = intern ("line-height"); 23837 staticpro (&Qline_height); 23838 QCalign_to = intern (":align-to"); 23839 staticpro (&QCalign_to); 23840 QCrelative_width = intern (":relative-width"); 23841 staticpro (&QCrelative_width); 23842 QCrelative_height = intern (":relative-height"); 23843 staticpro (&QCrelative_height); 23844 QCeval = intern (":eval"); 23845 staticpro (&QCeval); 23846 QCpropertize = intern (":propertize"); 23847 staticpro (&QCpropertize); 23848 QCfile = intern (":file"); 23849 staticpro (&QCfile); 23850 Qfontified = intern ("fontified"); 23851 staticpro (&Qfontified); 23852 Qfontification_functions = intern ("fontification-functions"); 23853 staticpro (&Qfontification_functions); 23854 Qtrailing_whitespace = intern ("trailing-whitespace"); 23855 staticpro (&Qtrailing_whitespace); 23856 Qescape_glyph = intern ("escape-glyph"); 23857 staticpro (&Qescape_glyph); 23858 Qnobreak_space = intern ("nobreak-space"); 23859 staticpro (&Qnobreak_space); 23860 Qimage = intern ("image"); 23861 staticpro (&Qimage); 23862 QCmap = intern (":map"); 23863 staticpro (&QCmap); 23864 QCpointer = intern (":pointer"); 23865 staticpro (&QCpointer); 23866 Qrect = intern ("rect"); 23867 staticpro (&Qrect); 23868 Qcircle = intern ("circle"); 23869 staticpro (&Qcircle); 23870 Qpoly = intern ("poly"); 23871 staticpro (&Qpoly); 23872 Qmessage_truncate_lines = intern ("message-truncate-lines"); 23873 staticpro (&Qmessage_truncate_lines); 23874 Qgrow_only = intern ("grow-only"); 23875 staticpro (&Qgrow_only); 23876 Qinhibit_menubar_update = intern ("inhibit-menubar-update"); 23877 staticpro (&Qinhibit_menubar_update); 23878 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay"); 23879 staticpro (&Qinhibit_eval_during_redisplay); 23880 Qposition = intern ("position"); 23881 staticpro (&Qposition); 23882 Qbuffer_position = intern ("buffer-position"); 23883 staticpro (&Qbuffer_position); 23884 Qobject = intern ("object"); 23885 staticpro (&Qobject); 23886 Qbar = intern ("bar"); 23887 staticpro (&Qbar); 23888 Qhbar = intern ("hbar"); 23889 staticpro (&Qhbar); 23890 Qbox = intern ("box"); 23891 staticpro (&Qbox); 23892 Qhollow = intern ("hollow"); 23893 staticpro (&Qhollow); 23894 Qhand = intern ("hand"); 23895 staticpro (&Qhand); 23896 Qarrow = intern ("arrow"); 23897 staticpro (&Qarrow); 23898 Qtext = intern ("text"); 23899 staticpro (&Qtext); 23900 Qrisky_local_variable = intern ("risky-local-variable"); 23901 staticpro (&Qrisky_local_variable); 23902 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces"); 23903 staticpro (&Qinhibit_free_realized_faces); 23904 23905 list_of_error = Fcons (Fcons (intern ("error"), 23906 Fcons (intern ("void-variable"), Qnil)), 23907 Qnil); 23908 staticpro (&list_of_error); 23909 23910 Qlast_arrow_position = intern ("last-arrow-position"); 23911 staticpro (&Qlast_arrow_position); 23912 Qlast_arrow_string = intern ("last-arrow-string"); 23913 staticpro (&Qlast_arrow_string); 23914 23915 Qoverlay_arrow_string = intern ("overlay-arrow-string"); 23916 staticpro (&Qoverlay_arrow_string); 23917 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap"); 23918 staticpro (&Qoverlay_arrow_bitmap); 23919 23920 echo_buffer[0] = echo_buffer[1] = Qnil; 23921 staticpro (&echo_buffer[0]); 23922 staticpro (&echo_buffer[1]); 23923 23924 echo_area_buffer[0] = echo_area_buffer[1] = Qnil; 23925 staticpro (&echo_area_buffer[0]); 23926 staticpro (&echo_area_buffer[1]); 23927 23928 Vmessages_buffer_name = build_string ("*Messages*"); 23929 staticpro (&Vmessages_buffer_name); 23930 23931 mode_line_proptrans_alist = Qnil; 23932 staticpro (&mode_line_proptrans_alist); 23933 mode_line_string_list = Qnil; 23934 staticpro (&mode_line_string_list); 23935 mode_line_string_face = Qnil; 23936 staticpro (&mode_line_string_face); 23937 mode_line_string_face_prop = Qnil; 23938 staticpro (&mode_line_string_face_prop); 23939 Vmode_line_unwind_vector = Qnil; 23940 staticpro (&Vmode_line_unwind_vector); 23941 23942 help_echo_string = Qnil; 23943 staticpro (&help_echo_string); 23944 help_echo_object = Qnil; 23945 staticpro (&help_echo_object); 23946 help_echo_window = Qnil; 23947 staticpro (&help_echo_window); 23948 previous_help_echo_string = Qnil; 23949 staticpro (&previous_help_echo_string); 23950 help_echo_pos = -1; 23951 23952#ifdef HAVE_WINDOW_SYSTEM 23953 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p, 23954 doc: /* *Non-nil means draw block cursor as wide as the glyph under it. 23955For example, if a block cursor is over a tab, it will be drawn as 23956wide as that tab on the display. */); 23957 x_stretch_cursor_p = 0; 23958#endif 23959 23960 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace, 23961 doc: /* *Non-nil means highlight trailing whitespace. 23962The face used for trailing whitespace is `trailing-whitespace'. */); 23963 Vshow_trailing_whitespace = Qnil; 23964 23965 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display, 23966 doc: /* *Control highlighting of nobreak space and soft hyphen. 23967A value of t means highlight the character itself (for nobreak space, 23968use face `nobreak-space'). 23969A value of nil means no highlighting. 23970Other values mean display the escape glyph followed by an ordinary 23971space or ordinary hyphen. */); 23972 Vnobreak_char_display = Qt; 23973 23974 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer, 23975 doc: /* *The pointer shape to show in void text areas. 23976A value of nil means to show the text pointer. Other options are `arrow', 23977`text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */); 23978 Vvoid_text_area_pointer = Qarrow; 23979 23980 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay, 23981 doc: /* Non-nil means don't actually do any redisplay. 23982This is used for internal purposes. */); 23983 Vinhibit_redisplay = Qnil; 23984 23985 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string, 23986 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */); 23987 Vglobal_mode_string = Qnil; 23988 23989 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position, 23990 doc: /* Marker for where to display an arrow on top of the buffer text. 23991This must be the beginning of a line in order to work. 23992See also `overlay-arrow-string'. */); 23993 Voverlay_arrow_position = Qnil; 23994 23995 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string, 23996 doc: /* String to display as an arrow in non-window frames. 23997See also `overlay-arrow-position'. */); 23998 Voverlay_arrow_string = build_string ("=>"); 23999 24000 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list, 24001 doc: /* List of variables (symbols) which hold markers for overlay arrows. 24002The symbols on this list are examined during redisplay to determine 24003where to display overlay arrows. */); 24004 Voverlay_arrow_variable_list 24005 = Fcons (intern ("overlay-arrow-position"), Qnil); 24006 24007 DEFVAR_INT ("scroll-step", &scroll_step, 24008 doc: /* *The number of lines to try scrolling a window by when point moves out. 24009If that fails to bring point back on frame, point is centered instead. 24010If this is zero, point is always centered after it moves off frame. 24011If you want scrolling to always be a line at a time, you should set 24012`scroll-conservatively' to a large value rather than set this to 1. */); 24013 24014 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively, 24015 doc: /* *Scroll up to this many lines, to bring point back on screen. 24016A value of zero means to scroll the text to center point vertically 24017in the window. */); 24018 scroll_conservatively = 0; 24019 24020 DEFVAR_INT ("scroll-margin", &scroll_margin, 24021 doc: /* *Number of lines of margin at the top and bottom of a window. 24022Recenter the window whenever point gets within this many lines 24023of the top or bottom of the window. */); 24024 scroll_margin = 0; 24025 24026 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch, 24027 doc: /* Pixels per inch value for non-window system displays. 24028Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */); 24029 Vdisplay_pixels_per_inch = make_float (72.0); 24030 24031#if GLYPH_DEBUG 24032 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */); 24033#endif 24034 24035 DEFVAR_BOOL ("truncate-partial-width-windows", 24036 &truncate_partial_width_windows, 24037 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */); 24038 truncate_partial_width_windows = 1; 24039 24040 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video, 24041 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face. 24042Any other value means to use the appropriate face, `mode-line', 24043`header-line', or `menu' respectively. */); 24044 mode_line_inverse_video = 1; 24045 24046 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit, 24047 doc: /* *Maximum buffer size for which line number should be displayed. 24048If the buffer is bigger than this, the line number does not appear 24049in the mode line. A value of nil means no limit. */); 24050 Vline_number_display_limit = Qnil; 24051 24052 DEFVAR_INT ("line-number-display-limit-width", 24053 &line_number_display_limit_width, 24054 doc: /* *Maximum line width (in characters) for line number display. 24055If the average length of the lines near point is bigger than this, then the 24056line number may be omitted from the mode line. */); 24057 line_number_display_limit_width = 200; 24058 24059 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows, 24060 doc: /* *Non-nil means highlight region even in nonselected windows. */); 24061 highlight_nonselected_windows = 0; 24062 24063 DEFVAR_BOOL ("multiple-frames", &multiple_frames, 24064 doc: /* Non-nil if more than one frame is visible on this display. 24065Minibuffer-only frames don't count, but iconified frames do. 24066This variable is not guaranteed to be accurate except while processing 24067`frame-title-format' and `icon-title-format'. */); 24068 24069 DEFVAR_LISP ("frame-title-format", &Vframe_title_format, 24070 doc: /* Template for displaying the title bar of visible frames. 24071\(Assuming the window manager supports this feature.) 24072 24073This variable has the same structure as `mode-line-format', except that 24074the %c and %l constructs are ignored. It is used only on frames for 24075which no explicit name has been set \(see `modify-frame-parameters'). */); 24076 24077 DEFVAR_LISP ("icon-title-format", &Vicon_title_format, 24078 doc: /* Template for displaying the title bar of an iconified frame. 24079\(Assuming the window manager supports this feature.) 24080This variable has the same structure as `mode-line-format' (which see), 24081and is used only on frames for which no explicit name has been set 24082\(see `modify-frame-parameters'). */); 24083 Vicon_title_format 24084 = Vframe_title_format 24085 = Fcons (intern ("multiple-frames"), 24086 Fcons (build_string ("%b"), 24087 Fcons (Fcons (empty_string, 24088 Fcons (intern ("invocation-name"), 24089 Fcons (build_string ("@"), 24090 Fcons (intern ("system-name"), 24091 Qnil)))), 24092 Qnil))); 24093 24094 DEFVAR_LISP ("message-log-max", &Vmessage_log_max, 24095 doc: /* Maximum number of lines to keep in the message log buffer. 24096If nil, disable message logging. If t, log messages but don't truncate 24097the buffer when it becomes large. */); 24098 Vmessage_log_max = make_number (100); 24099 24100 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions, 24101 doc: /* Functions called before redisplay, if window sizes have changed. 24102The value should be a list of functions that take one argument. 24103Just before redisplay, for each frame, if any of its windows have changed 24104size since the last redisplay, or have been split or deleted, 24105all the functions in the list are called, with the frame as argument. */); 24106 Vwindow_size_change_functions = Qnil; 24107 24108 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions, 24109 doc: /* List of functions to call before redisplaying a window with scrolling. 24110Each function is called with two arguments, the window 24111and its new display-start position. Note that the value of `window-end' 24112is not valid when these functions are called. */); 24113 Vwindow_scroll_functions = Qnil; 24114 24115 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions, 24116 doc: /* Functions called when redisplay of a window reaches the end trigger. 24117Each function is called with two arguments, the window and the end trigger value. 24118See `set-window-redisplay-end-trigger'. */); 24119 Vredisplay_end_trigger_functions = Qnil; 24120 24121 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window, 24122 doc: /* *Non-nil means autoselect window with mouse pointer. 24123If nil, do not autoselect windows. 24124A positive number means delay autoselection by that many seconds: a 24125window is autoselected only after the mouse has remained in that 24126window for the duration of the delay. 24127A negative number has a similar effect, but causes windows to be 24128autoselected only after the mouse has stopped moving. \(Because of 24129the way Emacs compares mouse events, you will occasionally wait twice 24130that time before the window gets selected.\) 24131Any other value means to autoselect window instantaneously when the 24132mouse pointer enters it. 24133 24134Autoselection selects the minibuffer only if it is active, and never 24135unselects the minibuffer if it is active. */); 24136 Vmouse_autoselect_window = Qnil; 24137 24138 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars, 24139 doc: /* *Non-nil means automatically resize tool-bars. 24140This dynamically changes the tool-bar's height to the minimum height 24141that is needed to make all tool-bar items visible. 24142If value is `grow-only', the tool-bar's height is only increased 24143automatically; to decreace the tool-bar height, use \\[recenter]. */); 24144 Vauto_resize_tool_bars = Qt; 24145 24146 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p, 24147 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */); 24148 auto_raise_tool_bar_buttons_p = 1; 24149 24150 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p, 24151 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */); 24152 make_cursor_line_fully_visible_p = 1; 24153 24154 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border, 24155 doc: /* *Border below tool-bar in pixels. 24156If an integer, use it as the height of the border. 24157If it is one of `internal-border-width' or `border-width', use the 24158value of the corresponding frame parameter. 24159Otherwise, no border is added below the tool-bar. */); 24160 Vtool_bar_border = Qinternal_border_width; 24161 24162 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin, 24163 doc: /* *Margin around tool-bar buttons in pixels. 24164If an integer, use that for both horizontal and vertical margins. 24165Otherwise, value should be a pair of integers `(HORZ . VERT)' with 24166HORZ specifying the horizontal margin, and VERT specifying the 24167vertical margin. */); 24168 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN); 24169 24170 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief, 24171 doc: /* *Relief thickness of tool-bar buttons. */); 24172 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF; 24173 24174 DEFVAR_LISP ("fontification-functions", &Vfontification_functions, 24175 doc: /* List of functions to call to fontify regions of text. 24176Each function is called with one argument POS. Functions must 24177fontify a region starting at POS in the current buffer, and give 24178fontified regions the property `fontified'. */); 24179 Vfontification_functions = Qnil; 24180 Fmake_variable_buffer_local (Qfontification_functions); 24181 24182 DEFVAR_BOOL ("unibyte-display-via-language-environment", 24183 &unibyte_display_via_language_environment, 24184 doc: /* *Non-nil means display unibyte text according to language environment. 24185Specifically this means that unibyte non-ASCII characters 24186are displayed by converting them to the equivalent multibyte characters 24187according to the current language environment. As a result, they are 24188displayed according to the current fontset. */); 24189 unibyte_display_via_language_environment = 0; 24190 24191 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height, 24192 doc: /* *Maximum height for resizing mini-windows. 24193If a float, it specifies a fraction of the mini-window frame's height. 24194If an integer, it specifies a number of lines. */); 24195 Vmax_mini_window_height = make_float (0.25); 24196 24197 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows, 24198 doc: /* *How to resize mini-windows. 24199A value of nil means don't automatically resize mini-windows. 24200A value of t means resize them to fit the text displayed in them. 24201A value of `grow-only', the default, means let mini-windows grow 24202only, until their display becomes empty, at which point the windows 24203go back to their normal size. */); 24204 Vresize_mini_windows = Qgrow_only; 24205 24206 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist, 24207 doc: /* Alist specifying how to blink the cursor off. 24208Each element has the form (ON-STATE . OFF-STATE). Whenever the 24209`cursor-type' frame-parameter or variable equals ON-STATE, 24210comparing using `equal', Emacs uses OFF-STATE to specify 24211how to blink it off. ON-STATE and OFF-STATE are values for 24212the `cursor-type' frame parameter. 24213 24214If a frame's ON-STATE has no entry in this list, 24215the frame's other specifications determine how to blink the cursor off. */); 24216 Vblink_cursor_alist = Qnil; 24217 24218 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p, 24219 doc: /* *Non-nil means scroll the display automatically to make point visible. */); 24220 automatic_hscrolling_p = 1; 24221 24222 DEFVAR_INT ("hscroll-margin", &hscroll_margin, 24223 doc: /* *How many columns away from the window edge point is allowed to get 24224before automatic hscrolling will horizontally scroll the window. */); 24225 hscroll_margin = 5; 24226 24227 DEFVAR_LISP ("hscroll-step", &Vhscroll_step, 24228 doc: /* *How many columns to scroll the window when point gets too close to the edge. 24229When point is less than `hscroll-margin' columns from the window 24230edge, automatic hscrolling will scroll the window by the amount of columns 24231determined by this variable. If its value is a positive integer, scroll that 24232many columns. If it's a positive floating-point number, it specifies the 24233fraction of the window's width to scroll. If it's nil or zero, point will be 24234centered horizontally after the scroll. Any other value, including negative 24235numbers, are treated as if the value were zero. 24236 24237Automatic hscrolling always moves point outside the scroll margin, so if 24238point was more than scroll step columns inside the margin, the window will 24239scroll more than the value given by the scroll step. 24240 24241Note that the lower bound for automatic hscrolling specified by `scroll-left' 24242and `scroll-right' overrides this variable's effect. */); 24243 Vhscroll_step = make_number (0); 24244 24245 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines, 24246 doc: /* If non-nil, messages are truncated instead of resizing the echo area. 24247Bind this around calls to `message' to let it take effect. */); 24248 message_truncate_lines = 0; 24249 24250 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook, 24251 doc: /* Normal hook run to update the menu bar definitions. 24252Redisplay runs this hook before it redisplays the menu bar. 24253This is used to update submenus such as Buffers, 24254whose contents depend on various data. */); 24255 Vmenu_bar_update_hook = Qnil; 24256 24257 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame, 24258 doc: /* Frame for which we are updating a menu. 24259The enable predicate for a menu binding should check this variable. */); 24260 Vmenu_updating_frame = Qnil; 24261 24262 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update, 24263 doc: /* Non-nil means don't update menu bars. Internal use only. */); 24264 inhibit_menubar_update = 0; 24265 24266 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay, 24267 doc: /* Non-nil means don't eval Lisp during redisplay. */); 24268 inhibit_eval_during_redisplay = 0; 24269 24270 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces, 24271 doc: /* Non-nil means don't free realized faces. Internal use only. */); 24272 inhibit_free_realized_faces = 0; 24273 24274#if GLYPH_DEBUG 24275 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id, 24276 doc: /* Inhibit try_window_id display optimization. */); 24277 inhibit_try_window_id = 0; 24278 24279 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing, 24280 doc: /* Inhibit try_window_reusing display optimization. */); 24281 inhibit_try_window_reusing = 0; 24282 24283 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement, 24284 doc: /* Inhibit try_cursor_movement display optimization. */); 24285 inhibit_try_cursor_movement = 0; 24286#endif /* GLYPH_DEBUG */ 24287 24288 DEFVAR_INT ("overline-margin", &overline_margin, 24289 doc: /* *Space between overline and text, in pixels. 24290The default value is 2: the height of the overline (1 pixel) plus 1 pixel 24291margin to the caracter height. */); 24292 overline_margin = 2; 24293} 24294 24295 24296/* Initialize this module when Emacs starts. */ 24297 24298void 24299init_xdisp () 24300{ 24301 Lisp_Object root_window; 24302 struct window *mini_w; 24303 24304 current_header_line_height = current_mode_line_height = -1; 24305 24306 CHARPOS (this_line_start_pos) = 0; 24307 24308 mini_w = XWINDOW (minibuf_window); 24309 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w))); 24310 24311 if (!noninteractive) 24312 { 24313 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); 24314 int i; 24315 24316 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f)); 24317 set_window_height (root_window, 24318 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f), 24319 0); 24320 mini_w->top_line = make_number (FRAME_LINES (f) - 1); 24321 set_window_height (minibuf_window, 1, 0); 24322 24323 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f)); 24324 mini_w->total_cols = make_number (FRAME_COLS (f)); 24325 24326 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; 24327 scratch_glyph_row.glyphs[TEXT_AREA + 1] 24328 = scratch_glyphs + MAX_SCRATCH_GLYPHS; 24329 24330 /* The default ellipsis glyphs `...'. */ 24331 for (i = 0; i < 3; ++i) 24332 default_invis_vector[i] = make_number ('.'); 24333 } 24334 24335 { 24336 /* Allocate the buffer for frame titles. 24337 Also used for `format-mode-line'. */ 24338 int size = 100; 24339 mode_line_noprop_buf = (char *) xmalloc (size); 24340 mode_line_noprop_buf_end = mode_line_noprop_buf + size; 24341 mode_line_noprop_ptr = mode_line_noprop_buf; 24342 mode_line_target = MODE_LINE_DISPLAY; 24343 } 24344 24345 help_echo_showing_p = 0; 24346} 24347 24348 24349/* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b 24350 (do not change this comment) */ 24351