/[emacs]/emacs/src/xdisp.c
ViewVC logotype

Diff of /emacs/src/xdisp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.754 by kfstorm, Tue Jun 11 22:27:11 2002 UTC revision 1.754.2.1 by miles, Fri Apr 4 06:21:05 2003 UTC
# Line 1  Line 1 
1  /* Display generation from window structure and buffer text.  /* Display generation from window structure and buffer text.
2     Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99, 2000, 2001, 2002     Copyright (C) 1985,86,87,88,93,94,95,97,98,99, 2000, 2001, 2002, 2003
3     Free Software Foundation, Inc.     Free Software Foundation, Inc.
4    
5  This file is part of GNU Emacs.  This file is part of GNU Emacs.
# Line 64  Boston, MA 02111-1307, USA.  */ Line 64  Boston, MA 02111-1307, USA.  */
64                                                           |                                                           |
65                                     X expose events  -----+                                     X expose events  -----+
66    
67     What does redisplay?  Obviously, it has to figure out somehow what     What does redisplay do?  Obviously, it has to figure out somehow what
68     has been changed since the last time the display has been updated,     has been changed since the last time the display has been updated,
69     and to make these changes visible.  Preferably it would do that in     and to make these changes visible.  Preferably it would do that in
70     a moderately intelligent way, i.e. fast.     a moderately intelligent way, i.e. fast.
# Line 120  Boston, MA 02111-1307, USA.  */ Line 120  Boston, MA 02111-1307, USA.  */
120     on various settings of buffers and windows, on overlays and text     on various settings of buffers and windows, on overlays and text
121     properties, on display tables, on selective display.  The good news     properties, on display tables, on selective display.  The good news
122     is that all this hairy stuff is hidden behind a small set of     is that all this hairy stuff is hidden behind a small set of
123     interface functions taking a iterator structure (struct it)     interface functions taking an iterator structure (struct it)
124     argument.     argument.
125    
126     Iteration over things to be displayed is then simple.  It is     Iteration over things to be displayed is then simple.  It is
# Line 179  Boston, MA 02111-1307, USA.  */ Line 179  Boston, MA 02111-1307, USA.  */
179  #include "charset.h"  #include "charset.h"
180  #include "indent.h"  #include "indent.h"
181  #include "commands.h"  #include "commands.h"
182    #include "keymap.h"
183  #include "macros.h"  #include "macros.h"
184  #include "disptab.h"  #include "disptab.h"
185  #include "termhooks.h"  #include "termhooks.h"
# Line 187  Boston, MA 02111-1307, USA.  */ Line 188  Boston, MA 02111-1307, USA.  */
188  #include "process.h"  #include "process.h"
189  #include "region-cache.h"  #include "region-cache.h"
190  #include "fontset.h"  #include "fontset.h"
191    #include "blockinput.h"
192    
193  #ifdef HAVE_X_WINDOWS  #ifdef HAVE_X_WINDOWS
194  #include "xterm.h"  #include "xterm.h"
# Line 196  Boston, MA 02111-1307, USA.  */ Line 198  Boston, MA 02111-1307, USA.  */
198  #endif  #endif
199  #ifdef MAC_OS  #ifdef MAC_OS
200  #include "macterm.h"  #include "macterm.h"
201    
202    Cursor No_Cursor;
203    #endif
204    
205    #ifndef FRAME_X_OUTPUT
206    #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207  #endif  #endif
208    
209  #define INFINITY 10000000  #define INFINITY 10000000
210    
211  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212        || defined (USE_GTK)
213  extern void set_frame_menubar P_ ((struct frame *f, int, int));  extern void set_frame_menubar P_ ((struct frame *f, int, int));
214  extern int pending_menu_activation;  extern int pending_menu_activation;
215  #endif  #endif
# Line 209  extern int interrupt_input; Line 218  extern int interrupt_input;
218  extern int command_loop_level;  extern int command_loop_level;
219    
220  extern int minibuffer_auto_raise;  extern int minibuffer_auto_raise;
221    extern Lisp_Object Vminibuffer_list;
222    
223  extern Lisp_Object Qface;  extern Lisp_Object Qface;
224    extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225    
226  extern Lisp_Object Voverriding_local_map;  extern Lisp_Object Voverriding_local_map;
227  extern Lisp_Object Voverriding_local_map_menu_flag;  extern Lisp_Object Voverriding_local_map_menu_flag;
228  extern Lisp_Object Qmenu_item;  extern Lisp_Object Qmenu_item;
229    extern Lisp_Object Qwhen;
230    extern Lisp_Object Qhelp_echo;
231    
232  Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;  Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233  Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;  Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234  Lisp_Object Qredisplay_end_trigger_functions;  Lisp_Object Qredisplay_end_trigger_functions;
235  Lisp_Object Qinhibit_point_motion_hooks;  Lisp_Object Qinhibit_point_motion_hooks;
236  Lisp_Object QCeval, Qwhen, QCfile, QCdata, QCpropertize;  Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237  Lisp_Object Qfontified;  Lisp_Object Qfontified;
238  Lisp_Object Qgrow_only;  Lisp_Object Qgrow_only;
239  Lisp_Object Qinhibit_eval_during_redisplay;  Lisp_Object Qinhibit_eval_during_redisplay;
240  Lisp_Object Qbuffer_position, Qposition, Qobject;  Lisp_Object Qbuffer_position, Qposition, Qobject;
241    
242    /* Cursor shapes */
243    Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244    
245  Lisp_Object Qrisky_local_variable;  Lisp_Object Qrisky_local_variable;
246    
247  /* Holds the list (error).  */  /* Holds the list (error).  */
# Line 236  Lisp_Object list_of_error; Line 252  Lisp_Object list_of_error;
252  Lisp_Object Vfontification_functions;  Lisp_Object Vfontification_functions;
253  Lisp_Object Qfontification_functions;  Lisp_Object Qfontification_functions;
254    
255    /* Non-zero means automatically select any window when the mouse
256       cursor moves into it.  */
257    int mouse_autoselect_window;
258    
259  /* Non-zero means draw tool bar buttons raised when the mouse moves  /* Non-zero means draw tool bar buttons raised when the mouse moves
260     over them.  */     over them.  */
261    
# Line 254  EMACS_INT tool_bar_button_relief; Line 274  EMACS_INT tool_bar_button_relief;
274    
275  int auto_resize_tool_bars_p;  int auto_resize_tool_bars_p;
276    
277    /* Non-zero means draw block and hollow cursor as wide as the glyph
278       under it.  For example, if a block cursor is over a tab, it will be
279       drawn as wide as that tab on the display.  */
280    
281    int x_stretch_cursor_p;
282    
283  /* Non-nil means don't actually do any redisplay.  */  /* Non-nil means don't actually do any redisplay.  */
284    
285  Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;  Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
# Line 273  Lisp_Object Qspace, QCalign_to, QCrelati Line 299  Lisp_Object Qspace, QCalign_to, QCrelati
299  Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;  Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
300  Lisp_Object Qmargin;  Lisp_Object Qmargin;
301  extern Lisp_Object Qheight;  extern Lisp_Object Qheight;
302    extern Lisp_Object QCwidth, QCheight, QCascent;
303    
304  /* Non-nil means highlight trailing whitespace.  */  /* Non-nil means highlight trailing whitespace.  */
305    
# Line 530  static int message_cleared_p; Line 557  static int message_cleared_p;
557  /* Non-zero means we want a hollow cursor in windows that are not  /* Non-zero means we want a hollow cursor in windows that are not
558     selected.  Zero means there's no cursor in such windows.  */     selected.  Zero means there's no cursor in such windows.  */
559    
560  int cursor_in_non_selected_windows;  Lisp_Object Vcursor_in_non_selected_windows;
561  Lisp_Object Qcursor_in_non_selected_windows;  Lisp_Object Qcursor_in_non_selected_windows;
562    
563    /* How to blink the default frame cursor off.  */
564    Lisp_Object Vblink_cursor_alist;
565    
566  /* A scratch glyph row with contents used for generating truncation  /* A scratch glyph row with contents used for generating truncation
567     glyphs.  Also used in direct_output_for_insert.  */     glyphs.  Also used in direct_output_for_insert.  */
568    
# Line 689  enum move_it_result Line 719  enum move_it_result
719    MOVE_NEWLINE_OR_CR    MOVE_NEWLINE_OR_CR
720  };  };
721    
722    /* This counter is used to clear the face cache every once in a while
723       in redisplay_internal.  It is incremented for each redisplay.
724       Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
725       cleared.  */
726    
727    #define CLEAR_FACE_CACHE_COUNT  500
728    static int clear_face_cache_count;
729    
730    /* Record the previous terminal frame we displayed.  */
731    
732    static struct frame *previous_terminal_frame;
733    
734    /* Non-zero while redisplay_internal is in progress.  */
735    
736    int redisplaying_p;
737    
738    /* Non-zero means don't free realized faces.  Bound while freeing
739       realized faces is dangerous because glyph matrices might still
740       reference them.  */
741    
742    int inhibit_free_realized_faces;
743    Lisp_Object Qinhibit_free_realized_faces;
744    
745    /* If a string, XTread_socket generates an event to display that string.
746       (The display is done in read_char.)  */
747    
748    Lisp_Object help_echo_string;
749    Lisp_Object help_echo_window;
750    Lisp_Object help_echo_object;
751    int help_echo_pos;
752    
753    /* Temporary variable for XTread_socket.  */
754    
755    Lisp_Object previous_help_echo_string;
756    
757    
758    
759  /* Function prototypes.  */  /* Function prototypes.  */
# Line 712  static struct text_pos run_window_scroll Line 777  static struct text_pos run_window_scroll
777  static void reconsider_clip_changes P_ ((struct window *, struct buffer *));  static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
778  static int text_outside_line_unchanged_p P_ ((struct window *, int, int));  static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
779  static void store_frame_title_char P_ ((char));  static void store_frame_title_char P_ ((char));
780  static int store_frame_title P_ ((unsigned char *, int, int));  static int store_frame_title P_ ((const unsigned char *, int, int));
781  static void x_consider_frame_title P_ ((Lisp_Object));  static void x_consider_frame_title P_ ((Lisp_Object));
782  static void handle_stop P_ ((struct it *));  static void handle_stop P_ ((struct it *));
783  static int tool_bar_lines_needed P_ ((struct frame *));  static int tool_bar_lines_needed P_ ((struct frame *));
# Line 731  static int display_echo_area P_ ((struct Line 796  static int display_echo_area P_ ((struct
796  static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));  static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
797  static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));  static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
798  static Lisp_Object unwind_redisplay P_ ((Lisp_Object));  static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
799  static int string_char_and_length P_ ((unsigned char *, int, int *));  static int string_char_and_length P_ ((const unsigned char *, int, int *));
800  static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,  static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
801                                               struct text_pos));                                               struct text_pos));
802  static int compute_window_start_on_continuation_line P_ ((struct window *));  static int compute_window_start_on_continuation_line P_ ((struct window *));
# Line 741  static struct glyph_row *get_overlay_arr Line 806  static struct glyph_row *get_overlay_arr
806  static void extend_face_to_end_of_line P_ ((struct it *));  static void extend_face_to_end_of_line P_ ((struct it *));
807  static int append_space P_ ((struct it *, int));  static int append_space P_ ((struct it *, int));
808  static int make_cursor_line_fully_visible P_ ((struct window *));  static int make_cursor_line_fully_visible P_ ((struct window *));
809  static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int));  static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
810  static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));  static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
811  static int trailing_whitespace_p P_ ((int));  static int trailing_whitespace_p P_ ((int));
812  static int message_log_check_duplicate P_ ((int, int, int, int));  static int message_log_check_duplicate P_ ((int, int, int, int));
# Line 762  static int display_line P_ ((struct it * Line 827  static int display_line P_ ((struct it *
827  static int display_mode_lines P_ ((struct window *));  static int display_mode_lines P_ ((struct window *));
828  static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));  static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
829  static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));  static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
830    static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
831  static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));  static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
832  static void display_menu_bar P_ ((struct window *));  static void display_menu_bar P_ ((struct window *));
833  static int display_count_lines P_ ((int, int, int, int, int *));  static int display_count_lines P_ ((int, int, int, int, int *));
# Line 823  static void update_tool_bar P_ ((struct Line 889  static void update_tool_bar P_ ((struct
889  static void build_desired_tool_bar_string P_ ((struct frame *f));  static void build_desired_tool_bar_string P_ ((struct frame *f));
890  static int redisplay_tool_bar P_ ((struct frame *));  static int redisplay_tool_bar P_ ((struct frame *));
891  static void display_tool_bar_line P_ ((struct it *));  static void display_tool_bar_line P_ ((struct it *));
892    static void notice_overwritten_cursor P_ ((struct window *,
893                                               enum glyph_row_area,
894                                               int, int, int, int));
895    
896    
897    
898  #endif /* HAVE_WINDOW_SYSTEM */  #endif /* HAVE_WINDOW_SYSTEM */
899    
# Line 831  static void display_tool_bar_line P_ ((s Line 902  static void display_tool_bar_line P_ ((s
902                        Window display dimensions                        Window display dimensions
903   ***********************************************************************/   ***********************************************************************/
904    
905  /* Return the window-relative maximum y + 1 for glyph rows displaying  /* Return the bottom boundary y-position for text lines in window W.
906     text in window W.  This is the height of W minus the height of a     This is the first y position at which a line cannot start.
907     mode line, if any.  */     It is relative to the top of the window.
908    
909       This is the height of W minus the height of a mode line, if any.  */
910    
911  INLINE int  INLINE int
912  window_text_bottom_y (w)  window_text_bottom_y (w)
# Line 1147  pos_visible_p (w, charpos, fully, exact_ Line 1220  pos_visible_p (w, charpos, fully, exact_
1220    
1221  static INLINE int  static INLINE int
1222  string_char_and_length (str, maxlen, len)  string_char_and_length (str, maxlen, len)
1223       unsigned char *str;       const unsigned char *str;
1224       int maxlen, *len;       int maxlen, *len;
1225  {  {
1226    int c;    int c;
# Line 1178  string_pos_nchars_ahead (pos, string, nc Line 1251  string_pos_nchars_ahead (pos, string, nc
1251    if (STRING_MULTIBYTE (string))    if (STRING_MULTIBYTE (string))
1252      {      {
1253        int rest = SBYTES (string) - BYTEPOS (pos);        int rest = SBYTES (string) - BYTEPOS (pos);
1254        unsigned char *p = SDATA (string) + BYTEPOS (pos);        const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1255        int len;        int len;
1256    
1257        while (nchars--)        while (nchars--)
# Line 1296  compute_string_pos (newpos, pos, string) Line 1369  compute_string_pos (newpos, pos, string)
1369      BYTEPOS (*newpos) = CHARPOS (*newpos);      BYTEPOS (*newpos) = CHARPOS (*newpos);
1370  }  }
1371    
1372    /* EXPORT:
1373       Return an estimation of the pixel height of mode or top lines on
1374       frame F.  FACE_ID specifies what line's height to estimate.  */
1375    
1376    int
1377    estimate_mode_line_height (f, face_id)
1378         struct frame *f;
1379         enum face_id face_id;
1380    {
1381    #ifdef HAVE_WINDOW_SYSTEM
1382      if (FRAME_WINDOW_P (f))
1383        {
1384          int height = FONT_HEIGHT (FRAME_FONT (f));
1385    
1386          /* This function is called so early when Emacs starts that the face
1387             cache and mode line face are not yet initialized.  */
1388          if (FRAME_FACE_CACHE (f))
1389            {
1390              struct face *face = FACE_FROM_ID (f, face_id);
1391              if (face)
1392                {
1393                  if (face->font)
1394                    height = FONT_HEIGHT (face->font);
1395                  if (face->box_line_width > 0)
1396                    height += 2 * face->box_line_width;
1397                }
1398            }
1399    
1400          return height;
1401        }
1402    #endif
1403    
1404      return 1;
1405    }
1406    
1407    /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1408       co-ordinates in (*X, *Y).  Set *BOUNDS to the rectangle that the
1409       glyph at X, Y occupies, if BOUNDS != 0.  If NOCLIP is non-zero, do
1410       not force the value into range.  */
1411    
1412    void
1413    pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1414         FRAME_PTR f;
1415         register int pix_x, pix_y;
1416         int *x, *y;
1417         NativeRectangle *bounds;
1418         int noclip;
1419    {
1420    
1421    #ifdef HAVE_WINDOW_SYSTEM
1422      if (FRAME_WINDOW_P (f))
1423        {
1424          /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
1425             even for negative values.  */
1426          if (pix_x < 0)
1427            pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
1428          if (pix_y < 0)
1429            pix_y -= FRAME_X_OUTPUT(f)->line_height - 1;
1430    
1431          pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
1432          pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
1433    
1434          if (bounds)
1435            STORE_NATIVE_RECT (*bounds,
1436                               CHAR_TO_PIXEL_COL (f, pix_x),
1437                               CHAR_TO_PIXEL_ROW (f, pix_y),
1438                               FONT_WIDTH  (FRAME_FONT (f)) - 1,
1439                               FRAME_X_OUTPUT (f)->line_height - 1);
1440    
1441          if (!noclip)
1442            {
1443              if (pix_x < 0)
1444                pix_x = 0;
1445              else if (pix_x > FRAME_WINDOW_WIDTH (f))
1446                pix_x = FRAME_WINDOW_WIDTH (f);
1447    
1448              if (pix_y < 0)
1449                pix_y = 0;
1450              else if (pix_y > f->height)
1451                pix_y = f->height;
1452            }
1453        }
1454    #endif
1455    
1456      *x = pix_x;
1457      *y = pix_y;
1458    }
1459    
1460    
1461    /* Given HPOS/VPOS in the current matrix of W, return corresponding
1462       frame-relative pixel positions in *FRAME_X and *FRAME_Y.  If we
1463       can't tell the positions because W's display is not up to date,
1464       return 0.  */
1465    
1466    int
1467    glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1468         struct window *w;
1469         int hpos, vpos;
1470         int *frame_x, *frame_y;
1471    {
1472    #ifdef HAVE_WINDOW_SYSTEM
1473      if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1474        {
1475          int success_p;
1476    
1477          xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1478          xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1479    
1480          if (display_completed)
1481            {
1482              struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1483              struct glyph *glyph = row->glyphs[TEXT_AREA];
1484              struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1485    
1486              hpos = row->x;
1487              vpos = row->y;
1488              while (glyph < end)
1489                {
1490                  hpos += glyph->pixel_width;
1491                  ++glyph;
1492                }
1493    
1494              success_p = 1;
1495            }
1496          else
1497            {
1498              hpos = vpos = 0;
1499              success_p = 0;
1500            }
1501    
1502          *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1503          *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1504          return success_p;
1505        }
1506    #endif
1507    
1508      *frame_x = hpos;
1509      *frame_y = vpos;
1510      return 1;
1511    }
1512    
1513    
1514    #ifdef HAVE_WINDOW_SYSTEM
1515    
1516    /* Find the glyph under window-relative coordinates X/Y in window W.
1517       Consider only glyphs from buffer text, i.e. no glyphs from overlay
1518       strings.  Return in *HPOS and *VPOS the row and column number of
1519       the glyph found.  Return in *AREA the glyph area containing X.
1520       Value is a pointer to the glyph found or null if X/Y is not on
1521       text, or we can't tell because W's current matrix is not up to
1522       date.  */
1523    
1524    static struct glyph *
1525    x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
1526         struct window *w;
1527         int x, y;
1528         int *hpos, *vpos, *area;
1529         int buffer_only_p;
1530    {
1531      struct glyph *glyph, *end;
1532      struct glyph_row *row = NULL;
1533      int x0, i, left_area_width;
1534    
1535      /* Find row containing Y.  Give up if some row is not enabled.  */
1536      for (i = 0; i < w->current_matrix->nrows; ++i)
1537        {
1538          row = MATRIX_ROW (w->current_matrix, i);
1539          if (!row->enabled_p)
1540            return NULL;
1541          if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1542            break;
1543        }
1544    
1545      *vpos = i;
1546      *hpos = 0;
1547    
1548      /* Give up if Y is not in the window.  */
1549      if (i == w->current_matrix->nrows)
1550        return NULL;
1551    
1552      /* Get the glyph area containing X.  */
1553      if (w->pseudo_window_p)
1554        {
1555          *area = TEXT_AREA;
1556          x0 = 0;
1557        }
1558      else
1559        {
1560          left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
1561          if (x < left_area_width)
1562            {
1563              *area = LEFT_MARGIN_AREA;
1564              x0 = 0;
1565            }
1566          else if (x < left_area_width + window_box_width (w, TEXT_AREA))
1567            {
1568              *area = TEXT_AREA;
1569              x0 = row->x + left_area_width;
1570            }
1571          else
1572            {
1573              *area = RIGHT_MARGIN_AREA;
1574              x0 = left_area_width + window_box_width (w, TEXT_AREA);
1575            }
1576        }
1577    
1578      /* Find glyph containing X.  */
1579      glyph = row->glyphs[*area];
1580      end = glyph + row->used[*area];
1581      while (glyph < end)
1582        {
1583          if (x < x0 + glyph->pixel_width)
1584            {
1585              if (w->pseudo_window_p)
1586                break;
1587              else if (!buffer_only_p || BUFFERP (glyph->object))
1588                break;
1589            }
1590    
1591          x0 += glyph->pixel_width;
1592          ++glyph;
1593        }
1594    
1595      if (glyph == end)
1596        return NULL;
1597    
1598      *hpos = glyph - row->glyphs[*area];
1599      return glyph;
1600    }
1601    
1602    
1603    /* EXPORT:
1604       Convert frame-relative x/y to coordinates relative to window W.
1605       Takes pseudo-windows into account.  */
1606    
1607    void
1608    frame_to_window_pixel_xy (w, x, y)
1609         struct window *w;
1610         int *x, *y;
1611    {
1612      if (w->pseudo_window_p)
1613        {
1614          /* A pseudo-window is always full-width, and starts at the
1615             left edge of the frame, plus a frame border.  */
1616          struct frame *f = XFRAME (w->frame);
1617          *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
1618          *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1619        }
1620      else
1621        {
1622          *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
1623          *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1624        }
1625    }
1626    
1627    /* EXPORT:
1628       Return in *R the clipping rectangle for glyph string S.  */
1629    
1630    void
1631    get_glyph_string_clip_rect (s, nr)
1632         struct glyph_string *s;
1633         NativeRectangle *nr;
1634    {
1635      XRectangle r;
1636    
1637      if (s->row->full_width_p)
1638        {
1639          /* Draw full-width.  X coordinates are relative to S->w->left.  */
1640          int canon_x = CANON_X_UNIT (s->f);
1641    
1642          r.x = WINDOW_LEFT_MARGIN (s->w) * canon_x;
1643          r.width = XFASTINT (s->w->width) * canon_x;
1644    
1645          if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
1646            {
1647              int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
1648              if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
1649                r.x -= width;
1650            }
1651    
1652          r.x += FRAME_INTERNAL_BORDER_WIDTH (s->f);
1653    
1654          /* Unless displaying a mode or menu bar line, which are always
1655             fully visible, clip to the visible part of the row.  */
1656          if (s->w->pseudo_window_p)
1657            r.height = s->row->visible_height;
1658          else
1659            r.height = s->height;
1660        }
1661      else
1662        {
1663          /* This is a text line that may be partially visible.  */
1664          r.x = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
1665          r.width = window_box_width (s->w, s->area);
1666          r.height = s->row->visible_height;
1667        }
1668    
1669      /* If S draws overlapping rows, it's sufficient to use the top and
1670         bottom of the window for clipping because this glyph string
1671         intentionally draws over other lines.  */
1672      if (s->for_overlaps_p)
1673        {
1674          r.y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1675          r.height = window_text_bottom_y (s->w) - r.y;
1676        }
1677      else
1678        {
1679          /* Don't use S->y for clipping because it doesn't take partially
1680             visible lines into account.  For example, it can be negative for
1681             partially visible lines at the top of a window.  */
1682          if (!s->row->full_width_p
1683              && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1684            r.y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1685          else
1686            r.y = max (0, s->row->y);
1687    
1688          /* If drawing a tool-bar window, draw it over the internal border
1689             at the top of the window.  */
1690          if (s->w == XWINDOW (s->f->tool_bar_window))
1691            r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1692        }
1693    
1694      r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1695    
1696    #ifdef HAVE_NTGUI
1697      /* ++KFS: From W32 port, but it looks ok for all platforms to me.  */
1698      /* If drawing the cursor, don't let glyph draw outside its
1699         advertised boundaries. Cleartype does this under some circumstances.  */
1700      if (s->hl == DRAW_CURSOR)
1701        {
1702          if (s->x > r.x)
1703            {
1704              r.width -= s->x - r.x;
1705              r.x = s->x;
1706            }
1707          r.width = min (r.width, s->first_glyph->pixel_width);
1708        }
1709    #endif
1710    
1711    #ifdef CONVERT_FROM_XRECT
1712      CONVERT_FROM_XRECT (r, *nr);
1713    #else
1714      *nr = r;
1715    #endif
1716    }
1717    
1718    #endif /* HAVE_WINDOW_SYSTEM */
1719    
1720    
1721  /***********************************************************************  /***********************************************************************
# Line 1326  safe_eval (sexpr) Line 1746  safe_eval (sexpr)
1746      val = Qnil;      val = Qnil;
1747    else    else
1748      {      {
1749        int count = BINDING_STACK_SIZE ();        int count = SPECPDL_INDEX ();
1750        struct gcpro gcpro1;        struct gcpro gcpro1;
1751    
1752        GCPRO1 (sexpr);        GCPRO1 (sexpr);
# Line 1358  safe_call (nargs, args) Line 1778  safe_call (nargs, args)
1778      val = Qnil;      val = Qnil;
1779    else    else
1780      {      {
1781        int count = BINDING_STACK_SIZE ();        int count = SPECPDL_INDEX ();
1782        struct gcpro gcpro1;        struct gcpro gcpro1;
1783    
1784        GCPRO1 (args[0]);        GCPRO1 (args[0]);
# Line 1501  init_iterator (it, w, charpos, bytepos, Line 1921  init_iterator (it, w, charpos, bytepos,
1921    
1922    /* If face attributes have been changed since the last redisplay,    /* If face attributes have been changed since the last redisplay,
1923       free realized faces now because they depend on face definitions       free realized faces now because they depend on face definitions
1924       that might have changed.  */       that might have changed.  Don't free faces while there might be
1925    if (face_change_count)       desired matrices pending which reference these faces.  */
1926      if (face_change_count && !inhibit_free_realized_faces)
1927      {      {
1928        face_change_count = 0;        face_change_count = 0;
1929        free_all_realized_faces (Qnil);        free_all_realized_faces (Qnil);
# Line 1760  start_display (it, w, pos) Line 2181  start_display (it, w, pos)
2181                               || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');                               || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2182        if (!start_at_line_beg_p)        if (!start_at_line_beg_p)
2183          {          {
2184              int new_x;
2185    
2186            reseat_at_previous_visible_line_start (it);            reseat_at_previous_visible_line_start (it);
2187            move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);            move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2188    
2189              new_x = it->current_x + it->pixel_width;
2190    
2191            /* If lines are continued, this line may end in the middle            /* If lines are continued, this line may end in the middle
2192               of a multi-glyph character (e.g. a control character               of a multi-glyph character (e.g. a control character
2193               displayed as \003, or in the middle of an overlay               displayed as \003, or in the middle of an overlay
2194               string).  In this case move_it_to above will not have               string).  In this case move_it_to above will not have
2195               taken us to the start of the continuation line but to the               taken us to the start of the continuation line but to the
2196               end of the continued line.  */               end of the continued line.  */
2197            if (it->current_x > 0)            if (it->current_x > 0
2198                  && !it->truncate_lines_p /* Lines are continued.  */
2199                  && (/* And glyph doesn't fit on the line.  */
2200                      new_x > it->last_visible_x
2201                      /* Or it fits exactly and we're on a window
2202                         system frame.  */
2203                      || (new_x == it->last_visible_x
2204                          && FRAME_WINDOW_P (it->f))))
2205              {              {
2206                if (it->current.dpvec_index >= 0                if (it->current.dpvec_index >= 0
2207                    || it->current.overlay_string_index >= 0)                    || it->current.overlay_string_index >= 0)
# Line 1876  init_from_display_pos (it, w, pos) Line 2308  init_from_display_pos (it, w, pos)
2308    
2309    for (i = 0; i < it->n_overlay_strings; ++i)    for (i = 0; i < it->n_overlay_strings; ++i)
2310      {      {
2311        char *s = SDATA (it->overlay_strings[i]);        const char *s = SDATA (it->overlay_strings[i]);
2312        char *e = s + SBYTES (it->overlay_strings[i]);        const char *e = s + SBYTES (it->overlay_strings[i]);
2313    
2314        while (s < e && *s != '\n')        while (s < e && *s != '\n')
2315          ++s;          ++s;
# Line 2239  handle_fontified_prop (it) Line 2671  handle_fontified_prop (it)
2671            prop = Fget_char_property (pos, Qfontified, Qnil),            prop = Fget_char_property (pos, Qfontified, Qnil),
2672            NILP (prop)))            NILP (prop)))
2673      {      {
2674        int count = BINDING_STACK_SIZE ();        int count = SPECPDL_INDEX ();
2675        Lisp_Object val;        Lisp_Object val;
2676    
2677        val = Vfontification_functions;        val = Vfontification_functions;
# Line 2483  face_before_or_after_it_pos (it, before_ Line 2915  face_before_or_after_it_pos (it, before_
2915           suitable for unibyte text if IT->string is unibyte.  */           suitable for unibyte text if IT->string is unibyte.  */
2916        if (STRING_MULTIBYTE (it->string))        if (STRING_MULTIBYTE (it->string))
2917          {          {
2918            unsigned char *p = SDATA (it->string) + BYTEPOS (pos);            const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2919            int rest = SBYTES (it->string) - BYTEPOS (pos);            int rest = SBYTES (it->string) - BYTEPOS (pos);
2920            int c, len;            int c, len;
2921            struct face *face = FACE_FROM_ID (it->f, face_id);            struct face *face = FACE_FROM_ID (it->f, face_id);
# Line 2526  face_before_or_after_it_pos (it, before_ Line 2958  face_before_or_after_it_pos (it, before_
2958           suitable for unibyte text if current_buffer is unibyte.  */           suitable for unibyte text if current_buffer is unibyte.  */
2959        if (it->multibyte_p)        if (it->multibyte_p)
2960          {          {
2961            int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));            int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
2962            struct face *face = FACE_FROM_ID (it->f, face_id);            struct face *face = FACE_FROM_ID (it->f, face_id);
2963            face_id = FACE_FOR_CHAR (it->f, face, c);            face_id = FACE_FOR_CHAR (it->f, face, c);
2964          }          }
# Line 2862  handle_single_display_prop (it, prop, ob Line 3294  handle_single_display_prop (it, prop, ob
3294    
3295    if (!NILP (form) && !EQ (form, Qt))    if (!NILP (form) && !EQ (form, Qt))
3296      {      {
3297        int count = BINDING_STACK_SIZE ();        int count = SPECPDL_INDEX ();
3298        struct gcpro gcpro1;        struct gcpro gcpro1;
3299    
3300        /* Bind `object' to the object having the `display' property, a        /* Bind `object' to the object having the `display' property, a
# Line 2933  handle_single_display_prop (it, prop, ob Line 3365  handle_single_display_prop (it, prop, ob
3365                /* Evaluate IT->font_height with `height' bound to the                /* Evaluate IT->font_height with `height' bound to the
3366                   current specified height to get the new height.  */                   current specified height to get the new height.  */
3367                Lisp_Object value;                Lisp_Object value;
3368                int count = BINDING_STACK_SIZE ();                int count = SPECPDL_INDEX ();
3369    
3370                specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);                specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3371                value = safe_eval (it->font_height);                value = safe_eval (it->font_height);
# Line 3113  single_display_prop_intangible_p (prop) Line 3545  single_display_prop_intangible_p (prop)
3545        prop = XCDR (prop);        prop = XCDR (prop);
3546      }      }
3547    
3548      if (STRINGP (prop))
3549        return 1;
3550    
3551    if (!CONSP (prop))    if (!CONSP (prop))
3552      return 0;      return 0;
3553    
# Line 3696  get_overlay_strings (it, charpos) Line 4131  get_overlay_strings (it, charpos)
4131        it->stop_charpos = 0;        it->stop_charpos = 0;
4132        xassert (STRINGP (it->string));        xassert (STRINGP (it->string));
4133        it->end_charpos = SCHARS (it->string);        it->end_charpos = SCHARS (it->string);
4134        it->multibyte_p = SMBP (it->string);        it->multibyte_p = STRING_MULTIBYTE (it->string);
4135        it->method = next_element_from_string;        it->method = next_element_from_string;
4136      }      }
4137    else    else
# Line 3847  forward_to_next_line_start (it, skipped_ Line 4282  forward_to_next_line_start (it, skipped_
4282         n += STRINGP (it->string) ? 0 : 1)         n += STRINGP (it->string) ? 0 : 1)
4283      {      {
4284        if (!get_next_display_element (it))        if (!get_next_display_element (it))
4285          break;          return 0;
4286        newline_found_p = it->what == IT_CHARACTER && it->c == '\n';        newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4287        set_iterator_to_next (it, 0);        set_iterator_to_next (it, 0);
4288      }      }
4289    
4290    /* If we didn't find a newline near enough, see if we can use a    /* If we didn't find a newline near enough, see if we can use a
4291       short-cut.  */       short-cut.  */
4292    if (n == MAX_NEWLINE_DISTANCE)    if (!newline_found_p)
4293      {      {
4294        int start = IT_CHARPOS (*it);        int start = IT_CHARPOS (*it);
4295        int limit = find_next_newline_no_quit (start, 1);        int limit = find_next_newline_no_quit (start, 1);
# Line 3918  back_to_previous_visible_line_start (it) Line 4353  back_to_previous_visible_line_start (it)
4353           are invisible.  */           are invisible.  */
4354        if (it->selective > 0        if (it->selective > 0
4355            && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),            && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4356                                  (float) it->selective)) /* iftc */                                  (double) it->selective)) /* iftc */
4357          visible_p = 0;          visible_p = 0;
4358        else        else
4359          {          {
# Line 3978  reseat_at_next_visible_line_start (it, o Line 4413  reseat_at_next_visible_line_start (it, o
4413    if (it->selective > 0)    if (it->selective > 0)
4414      while (IT_CHARPOS (*it) < ZV      while (IT_CHARPOS (*it) < ZV
4415             && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),             && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4416                                   (float) it->selective)) /* iftc */                                   (double) it->selective)) /* iftc */
4417        {        {
4418          xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');          xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4419          newline_found_p = forward_to_next_line_start (it, &skipped_p);          newline_found_p = forward_to_next_line_start (it, &skipped_p);
# Line 4184  int Line 4619  int
4619  get_next_display_element (it)  get_next_display_element (it)
4620       struct it *it;       struct it *it;
4621  {  {
4622    /* Non-zero means that we found an display element.  Zero means that    /* Non-zero means that we found a display element.  Zero means that
4623       we hit the end of what we iterate over.  Performance note: the       we hit the end of what we iterate over.  Performance note: the
4624       function pointer `method' used here turns out to be faster than       function pointer `method' used here turns out to be faster than
4625       using a sequence of if-statements.  */       using a sequence of if-statements.  */
# Line 4236  get_next_display_element (it) Line 4671  get_next_display_element (it)
4671               the translation.  This could easily be changed but I               the translation.  This could easily be changed but I
4672               don't believe that it is worth doing.               don't believe that it is worth doing.
4673    
4674               Non-printable multibyte characters are also translated               If it->multibyte_p is nonzero, eight-bit characters and
4675               octal form.  */               non-printable multibyte characters are also translated to
4676                 octal form.
4677    
4678                 If it->multibyte_p is zero, eight-bit characters that
4679                 don't have corresponding multibyte char code are also
4680                 translated to octal form.  */
4681            else if ((it->c < ' '            else if ((it->c < ' '
4682                      && (it->area != TEXT_AREA                      && (it->area != TEXT_AREA
4683                          || (it->c != '\n' && it->c != '\t')))                          || (it->c != '\n' && it->c != '\t')))
4684                     || (it->c >= 127                     || (it->multibyte_p
4685                         && it->len == 1)                         ? ((it->c >= 127
4686                     || !CHAR_PRINTABLE_P (it->c))                             && it->len == 1)
4687                              || !CHAR_PRINTABLE_P (it->c))
4688                           : (it->c >= 127
4689                              && it->c == unibyte_char_to_multibyte (it->c))))
4690              {              {
4691                /* IT->c is a control character which must be displayed                /* IT->c is a control character which must be displayed
4692                   either as '\003' or as `^C' where the '\\' and '^'                   either as '\003' or as `^C' where the '\\' and '^'
# Line 4610  next_element_from_string (it) Line 5053  next_element_from_string (it)
5053        else if (STRING_MULTIBYTE (it->string))        else if (STRING_MULTIBYTE (it->string))
5054          {          {
5055            int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);            int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5056            unsigned char *s = SDATA (it->string) + IT_STRING_BYTEPOS (*it);            const unsigned char *s = (SDATA (it->string)
5057                                        + IT_STRING_BYTEPOS (*it));
5058            it->c = string_char_and_length (s, remaining, &it->len);            it->c = string_char_and_length (s, remaining, &it->len);
5059          }          }
5060        else        else
# Line 4639  next_element_from_string (it) Line 5083  next_element_from_string (it)
5083        else if (STRING_MULTIBYTE (it->string))        else if (STRING_MULTIBYTE (it->string))
5084          {          {
5085            int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);            int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5086            unsigned char *s = SDATA (it->string) + IT_STRING_BYTEPOS (*it);            const unsigned char *s = (SDATA (it->string)
5087                                        + IT_STRING_BYTEPOS (*it));
5088            it->c = string_char_and_length (s, maxlen, &it->len);            it->c = string_char_and_length (s, maxlen, &it->len);
5089          }          }
5090        else        else
# Line 4871  next_element_from_buffer (it) Line 5316  next_element_from_buffer (it)
5316                    && IT_CHARPOS (*it) + 1 < ZV                    && IT_CHARPOS (*it) + 1 < ZV
5317                    && indented_beyond_p (IT_CHARPOS (*it) + 1,                    && indented_beyond_p (IT_CHARPOS (*it) + 1,
5318                                          IT_BYTEPOS (*it) + 1,                                          IT_BYTEPOS (*it) + 1,
5319                                          (float) it->selective)) /* iftc */                                          (double) it->selective)) /* iftc */
5320                  {                  {
5321                    success_p = next_element_from_ellipsis (it);                    success_p = next_element_from_ellipsis (it);
5322                    it->dpvec_char_len = -1;                    it->dpvec_char_len = -1;
# Line 5363  move_it_vertically_backward (it, dy) Line 5808  move_it_vertically_backward (it, dy)
5808    
5809    /* We are now surely at a line start.  */    /* We are now surely at a line start.  */
5810    it->current_x = it->hpos = 0;    it->current_x = it->hpos = 0;
5811      it->continuation_lines_width = 0;
5812    
5813    /* Move forward and see what y-distance we moved.  First move to the    /* Move forward and see what y-distance we moved.  First move to the
5814       start of the next line so that we get its height.  We need this       start of the next line so that we get its height.  We need this
# Line 5589  move_it_by_lines (it, dvpos, need_y_p) Line 6035  move_it_by_lines (it, dvpos, need_y_p)
6035      }      }
6036  }  }
6037    
6038    /* Return 1 if IT points into the middle of a display vector.  */
6039    
6040    int
6041    in_display_vector_p (it)
6042         struct it *it;
6043    {
6044      return (it->method == next_element_from_display_vector
6045              && it->current.dpvec_index > 0
6046              && it->dpvec + it->current.dpvec_index != it->dpend);
6047    }
6048    
6049    
6050  /***********************************************************************  /***********************************************************************
# Line 5651  message_log_maybe_newline () Line 6107  message_log_maybe_newline ()
6107    
6108  void  void
6109  message_dolog (m, nbytes, nlflag, multibyte)  message_dolog (m, nbytes, nlflag, multibyte)
6110       char *m;       const char *m;
6111       int nbytes, nlflag, multibyte;       int nbytes, nlflag, multibyte;
6112  {  {
6113      if (!NILP (Vmemory_full))
6114        return;
6115    
6116    if (!NILP (Vmessage_log_max))    if (!NILP (Vmessage_log_max))
6117      {      {
6118        struct buffer *oldbuf;        struct buffer *oldbuf;
# Line 5698  message_dolog (m, nbytes, nlflag, multib Line 6157  message_dolog (m, nbytes, nlflag, multib
6157    
6158            /* Convert a multibyte string to single-byte            /* Convert a multibyte string to single-byte
6159               for the *Message* buffer.  */               for the *Message* buffer.  */
6160            for (i = 0; i < nbytes; i += nbytes)            for (i = 0; i < nbytes; i += char_bytes)
6161              {              {
6162                c = string_char_and_length (m + i, nbytes - i, &char_bytes);                c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6163                work[0] = (SINGLE_BYTE_CHAR_P (c)                work[0] = (SINGLE_BYTE_CHAR_P (c)
# Line 5862  message_log_check_duplicate (prev_bol, p Line 6321  message_log_check_duplicate (prev_bol, p
6321    
6322  void  void
6323  message2 (m, nbytes, multibyte)  message2 (m, nbytes, multibyte)
6324       char *m;       const char *m;
6325       int nbytes;       int nbytes;
6326       int multibyte;       int multibyte;
6327  {  {
# Line 5878  message2 (m, nbytes, multibyte) Line 6337  message2 (m, nbytes, multibyte)
6337    
6338  void  void
6339  message2_nolog (m, nbytes, multibyte)  message2_nolog (m, nbytes, multibyte)
6340       char *m;       const char *m;
6341       int nbytes;       int nbytes, multibyte;
6342  {  {
6343    struct frame *sf = SELECTED_FRAME ();    struct frame *sf = SELECTED_FRAME ();
6344    message_enable_multibyte = multibyte;    message_enable_multibyte = multibyte;
# Line 6097  message_with_string (m, string, log) Line 6556  message_with_string (m, string, log)
6556            message = Fformat (2, args);            message = Fformat (2, args);
6557    
6558            if (log)            if (log)
6559              message3 (message, SBYTES (message), SMBP (message));              message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6560            else            else
6561              message3_nolog (message, SBYTES (message), SMBP (message));              message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6562    
6563            UNGCPRO;            UNGCPRO;
6564    
# Line 6214  update_echo_area () Line 6673  update_echo_area ()
6673  }  }
6674    
6675    
6676  /* Make sure echo area buffers in echo_buffers[] are life.  If they  /* Make sure echo area buffers in `echo_buffers' are live.
6677     aren't, make new ones.  */     If they aren't, make new ones.  */
6678    
6679  static void  static void
6680  ensure_echo_area_buffers ()  ensure_echo_area_buffers ()
# Line 6269  with_echo_area_buffer (w, which, fn, a1, Line 6728  with_echo_area_buffer (w, which, fn, a1,
6728  {  {
6729    Lisp_Object buffer;    Lisp_Object buffer;
6730    int this_one, the_other, clear_buffer_p, rc;    int this_one, the_other, clear_buffer_p, rc;
6731    int count = BINDING_STACK_SIZE ();    int count = SPECPDL_INDEX ();
6732    
6733    /* If buffers aren't live, make new ones.  */    /* If buffers aren't live, make new ones.  */
6734    ensure_echo_area_buffers ();    ensure_echo_area_buffers ();
# Line 6427  void Line 6886  void
6886  setup_echo_area_for_printing (multibyte_p)  setup_echo_area_for_printing (multibyte_p)
6887       int multibyte_p;       int multibyte_p;
6888  {  {
6889      /* If we can't find an echo area any more, exit.  */
6890      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
6891        Fkill_emacs (Qnil);
6892    
6893    ensure_echo_area_buffers ();    ensure_echo_area_buffers ();
6894    
6895    if (!message_buf_print)    if (!message_buf_print)
# Line 6444  setup_echo_area_for_printing (multibyte_ Line 6907  setup_echo_area_for_printing (multibyte_
6907    
6908        if (Z > BEG)        if (Z > BEG)
6909          {          {
6910            int count = BINDING_STACK_SIZE ();            int count = SPECPDL_INDEX ();
6911            specbind (Qinhibit_read_only, Qt);            specbind (Qinhibit_read_only, Qt);
6912              /* Note that undo recording is always disabled.  */
6913            del_range (BEG, Z);            del_range (BEG, Z);
6914            unbind_to (count, Qnil);            unbind_to (count, Qnil);
6915          }          }
# Line 6630  resize_mini_window (w, exact_p) Line 7094  resize_mini_window (w, exact_p)
7094    
7095    /* Nil means don't try to resize.  */    /* Nil means don't try to resize.  */
7096    if (NILP (Vresize_mini_windows)    if (NILP (Vresize_mini_windows)
7097        || (FRAME_X_P (f) && f->output_data.x == NULL))        || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7098      return 0;      return 0;
7099    
7100    if (!FRAME_MINIBUF_ONLY_P (f))    if (!FRAME_MINIBUF_ONLY_P (f))
# Line 6797  push_message () Line 7261  push_message ()
7261  }  }
7262    
7263    
 /* Handler for record_unwind_protect calling pop_message.  */  
   
 Lisp_Object  
 push_message_unwind (dummy)  
      Lisp_Object dummy;  
 {  
   pop_message ();  
   return Qnil;  
 }  
   
   
7264  /* Restore message display from the top of Vmessage_stack.  */  /* Restore message display from the top of Vmessage_stack.  */
7265    
7266  void  void
# Line 6818  restore_message () Line 7271  restore_message ()
7271    xassert (CONSP (Vmessage_stack));    xassert (CONSP (Vmessage_stack));
7272    msg = XCAR (Vmessage_stack);    msg = XCAR (Vmessage_stack);
7273    if (STRINGP (msg))    if (STRINGP (msg))
7274      message3_nolog (msg, SBYTES (msg), SMBP (msg));      message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7275    else    else
7276      message3_nolog (msg, 0, 0);      message3_nolog (msg, 0, 0);
7277  }  }
7278    
7279    
7280    /* Handler for record_unwind_protect calling pop_message.  */
7281    
7282    Lisp_Object
7283    pop_message_unwind (dummy)
7284         Lisp_Object dummy;
7285    {
7286      pop_message ();
7287      return Qnil;
7288    }
7289    
7290  /* Pop the top-most entry off Vmessage_stack.  */  /* Pop the top-most entry off Vmessage_stack.  */
7291    
7292  void  void
# Line 6898  truncate_message_1 (nchars, a2, a3, a4) Line 7361  truncate_message_1 (nchars, a2, a3, a4)
7361    
7362  void  void
7363  set_message (s, string, nbytes, multibyte_p)  set_message (s, string, nbytes, multibyte_p)
7364       char *s;       const char *s;
7365       Lisp_Object string;       Lisp_Object string;
7366       int nbytes;       int nbytes, multibyte_p;
7367  {  {
7368    message_enable_multibyte    message_enable_multibyte
7369      = ((s && multibyte_p)      = ((s && multibyte_p)
# Line 6924  set_message_1 (a1, a2, nbytes, multibyte Line 7387  set_message_1 (a1, a2, nbytes, multibyte
7387       Lisp_Object a2;       Lisp_Object a2;
7388       EMACS_INT nbytes, multibyte_p;       EMACS_INT nbytes, multibyte_p;
7389  {  {
7390    char *s = (char *) a1;    const char *s = (const char *) a1;
7391    Lisp_Object string = a2;    Lisp_Object string = a2;
7392    
7393    xassert (BEG == Z);    xassert (BEG == Z);
# Line 6978  set_message_1 (a1, a2, nbytes, multibyte Line 7441  set_message_1 (a1, a2, nbytes, multibyte
7441          {          {
7442            /* Convert from single-byte to multi-byte.  */            /* Convert from single-byte to multi-byte.  */
7443            int i, c, n;            int i, c, n;
7444            unsigned char *msg = (unsigned char *) s;            const unsigned char *msg = (const unsigned char *) s;
7445            unsigned char str[MAX_MULTIBYTE_LENGTH];            unsigned char str[MAX_MULTIBYTE_LENGTH];
7446    
7447            /* Convert a single-byte string to multibyte.  */            /* Convert a single-byte string to multibyte.  */
# Line 7124  echo_area_display (update_frame_p) Line 7587  echo_area_display (update_frame_p)
7587                /* Must update other windows.  Likewise as in other                /* Must update other windows.  Likewise as in other
7588                   cases, don't let this update be interrupted by                   cases, don't let this update be interrupted by
7589                   pending input.  */                   pending input.  */
7590                int count = BINDING_STACK_SIZE ();                int count = SPECPDL_INDEX ();
7591                specbind (Qredisplay_dont_pause, Qt);                specbind (Qredisplay_dont_pause, Qt);
7592                windows_or_buffers_changed = 1;                windows_or_buffers_changed = 1;
7593                redisplay_internal (0);                redisplay_internal (0);
# Line 7188  static char *frame_title_ptr; Line 7651  static char *frame_title_ptr;
7651     Re-allocate frame_title_buf if necessary.  */     Re-allocate frame_title_buf if necessary.  */
7652    
7653  static void  static void
7654    #ifdef PROTOTYPES
7655    store_frame_title_char (char c)
7656    #else
7657  store_frame_title_char (c)  store_frame_title_char (c)
7658      char c;      char c;
7659    #endif
7660  {  {
7661    /* If output position has reached the end of the allocated buffer,    /* If output position has reached the end of the allocated buffer,
7662       double the buffer's size.  */       double the buffer's size.  */
# Line 7216  store_frame_title_char (c) Line 7683  store_frame_title_char (c)
7683    
7684  static int  static int
7685  store_frame_title (str, field_width, precision)  store_frame_title (str, field_width, precision)
7686       unsigned char *str;       const unsigned char *str;
7687       int field_width, precision;       int field_width, precision;
7688  {  {
7689    int n = 0;    int n = 0;
# Line 7357  prepare_menu_bars () Line 7824  prepare_menu_bars ()
7824    if (all_windows)    if (all_windows)
7825      {      {
7826        Lisp_Object tail, frame;        Lisp_Object tail, frame;
7827        int count = BINDING_STACK_SIZE ();        int count = SPECPDL_INDEX ();
7828    
7829        record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));        record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7830    
# Line 7449  update_menu_bar (f, save_match_data) Line 7916  update_menu_bar (f, save_match_data)
7916    
7917    if (FRAME_WINDOW_P (f)    if (FRAME_WINDOW_P (f)
7918        ?        ?
7919  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7920        || defined (USE_GTK)
7921        FRAME_EXTERNAL_MENU_BAR (f)        FRAME_EXTERNAL_MENU_BAR (f)
7922  #else  #else
7923        FRAME_MENU_BAR_LINES (f) > 0        FRAME_MENU_BAR_LINES (f) > 0
# Line 7475  update_menu_bar (f, save_match_data) Line 7943  update_menu_bar (f, save_match_data)
7943                != !NILP (w->region_showing)))                != !NILP (w->region_showing)))
7944          {          {
7945            struct buffer *prev = current_buffer;            struct buffer *prev = current_buffer;
7946            int count = BINDING_STACK_SIZE ();            int count = SPECPDL_INDEX ();
7947    
7948            specbind (Qinhibit_menubar_update, Qt);            specbind (Qinhibit_menubar_update, Qt);
7949    
# Line 7500  update_menu_bar (f, save_match_data) Line 7968  update_menu_bar (f, save_match_data)
7968            FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));            FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
7969    
7970            /* Redisplay the menu bar in case we changed it.  */            /* Redisplay the menu bar in case we changed it.  */
7971  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7972        || defined (USE_GTK)
7973            if (FRAME_WINDOW_P (f)            if (FRAME_WINDOW_P (f)
7974  #if defined (MAC_OS)  #if defined (MAC_OS)
7975                /* All frames on Mac OS share the same menubar.  So only the                /* All frames on Mac OS share the same menubar.  So only the
# Line 7513  update_menu_bar (f, save_match_data) Line 7982  update_menu_bar (f, save_match_data)
7982              /* On a terminal screen, the menu bar is an ordinary screen              /* On a terminal screen, the menu bar is an ordinary screen
7983                 line, and this makes it get updated.  */                 line, and this makes it get updated.  */
7984              w->update_mode_line = Qt;              w->update_mode_line = Qt;
7985  #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */  #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
7986            /* In the non-toolkit version, the menu bar is an ordinary screen            /* In the non-toolkit version, the menu bar is an ordinary screen
7987               line, and this makes it get updated.  */               line, and this makes it get updated.  */
7988            w->update_mode_line = Qt;            w->update_mode_line = Qt;
7989  #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */  #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
7990    
7991            unbind_to (count, Qnil);            unbind_to (count, Qnil);
7992            set_buffer_internal_1 (prev);            set_buffer_internal_1 (prev);
# Line 7528  update_menu_bar (f, save_match_data) Line 7997  update_menu_bar (f, save_match_data)
7997    
7998    
7999  /***********************************************************************  /***********************************************************************
8000                                Output Cursor
8001     ***********************************************************************/
8002    
8003    #ifdef HAVE_WINDOW_SYSTEM
8004    
8005    /* EXPORT:
8006       Nominal cursor position -- where to draw output.
8007       HPOS and VPOS are window relative glyph matrix coordinates.
8008       X and Y are window relative pixel coordinates.  */
8009    
8010    struct cursor_pos output_cursor;
8011    
8012    
8013    /* EXPORT:
8014       Set the global variable output_cursor to CURSOR.  All cursor
8015       positions are relative to updated_window.  */
8016    
8017    void
8018    set_output_cursor (cursor)
8019        struct cursor_pos *cursor;
8020    {
8021      output_cursor.hpos = cursor->hpos;
8022      output_cursor.vpos = cursor->vpos;
8023      output_cursor.x = cursor->x;
8024      output_cursor.y = cursor->y;
8025    }
8026    
8027    
8028    /* EXPORT for RIF:
8029       Set a nominal cursor position.
8030    
8031       HPOS and VPOS are column/row positions in a window glyph matrix.  X
8032       and Y are window text area relative pixel positions.
8033    
8034       If this is done during an update, updated_window will contain the
8035       window that is being updated and the position is the future output
8036       cursor position for that window.  If updated_window is null, use
8037       selected_window and display the cursor at the given position.  */
8038    
8039    void
8040    x_cursor_to (vpos, hpos, y, x)
8041         int vpos, hpos, y, x;
8042    {
8043      struct window *w;
8044    
8045      /* If updated_window is not set, work on selected_window.  */
8046      if (updated_window)
8047        w = updated_window;
8048      else
8049        w = XWINDOW (selected_window);
8050    
8051      /* Set the output cursor.  */
8052      output_cursor.hpos = hpos;
8053      output_cursor.vpos = vpos;
8054      output_cursor.x = x;
8055      output_cursor.y = y;
8056    
8057      /* If not called as part of an update, really display the cursor.
8058         This will also set the cursor position of W.  */
8059      if (updated_window == NULL)
8060        {
8061          BLOCK_INPUT;
8062          display_and_set_cursor (w, 1, hpos, vpos, x, y);
8063          if (rif->flush_display_optional)
8064            rif->flush_display_optional (SELECTED_FRAME ());
8065          UNBLOCK_INPUT;
8066        }
8067    }
8068    
8069    #endif /* HAVE_WINDOW_SYSTEM */
8070    
8071    
8072    /***********************************************************************
8073                                 Tool-bars                                 Tool-bars
8074   ***********************************************************************/   ***********************************************************************/
8075    
8076  #ifdef HAVE_WINDOW_SYSTEM  #ifdef HAVE_WINDOW_SYSTEM
8077    
8078    /* Where the mouse was last time we reported a mouse event.  */
8079    
8080    FRAME_PTR last_mouse_frame;
8081    
8082    /* Tool-bar item index of the item on which a mouse button was pressed
8083       or -1.  */
8084    
8085    int last_tool_bar_item;
8086    
8087    
8088  /* Update the tool-bar item list for frame F.  This has to be done  /* Update the tool-bar item list for frame F.  This has to be done
8089     before we start to fill in any display lines.  Called from     before we start to fill in any display lines.  Called from
8090     prepare_menu_bars.  If SAVE_MATCH_DATA is non-zero, we must save     prepare_menu_bars.  If SAVE_MATCH_DATA is non-zero, we must save
# Line 7543  update_tool_bar (f, save_match_data) Line 8095  update_tool_bar (f, save_match_data)
8095       struct frame *f;       struct frame *f;
8096       int save_match_data;       int save_match_data;
8097  {  {
8098    if (WINDOWP (f->tool_bar_window)  #ifdef USE_GTK
8099        && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)    int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
8100    #else
8101      int do_update = WINDOWP (f->tool_bar_window)
8102        && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0;
8103    #endif
8104    
8105      if (do_update)
8106      {      {
8107        Lisp_Object window;        Lisp_Object window;
8108        struct window *w;        struct window *w;
# Line 7561  update_tool_bar (f, save_match_data) Line 8119  update_tool_bar (f, save_match_data)
8119           windows_or_buffers_changed anyway.  */           windows_or_buffers_changed anyway.  */
8120        if (windows_or_buffers_changed        if (windows_or_buffers_changed
8121            || !NILP (w->update_mode_line)            || !NILP (w->update_mode_line)
8122              || update_mode_lines
8123            || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))            || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8124                 < BUF_MODIFF (XBUFFER (w->buffer)))                 < BUF_MODIFF (XBUFFER (w->buffer)))
8125                != !NILP (w->last_had_star))                != !NILP (w->last_had_star))
# Line 7569  update_tool_bar (f, save_match_data) Line 8128  update_tool_bar (f, save_match_data)
8128                != !NILP (w->region_showing)))                != !NILP (w->region_showing)))
8129          {          {
8130            struct buffer *prev = current_buffer;            struct buffer *prev = current_buffer;
8131            int count = BINDING_STACK_SIZE ();            int count = SPECPDL_INDEX ();
8132              Lisp_Object old_tool_bar;
8133              struct gcpro gcpro1;
8134    
8135            /* Set current_buffer to the buffer of the selected            /* Set current_buffer to the buffer of the selected
8136               window of the frame, so that we get the right local               window of the frame, so that we get the right local
# Line 7587  update_tool_bar (f, save_match_data) Line 8148  update_tool_bar (f, save_match_data)
8148                specbind (Qoverriding_local_map, Qnil);                specbind (Qoverriding_local_map, Qnil);
8149              }              }
8150    
8151              old_tool_bar = f->tool_bar_items;
8152              GCPRO1 (old_tool_bar);
8153    
8154            /* Build desired tool-bar items from keymaps.  */            /* Build desired tool-bar items from keymaps.  */
8155            f->tool_bar_items            f->tool_bar_items
8156              = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);              = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8157    
8158            /* Redisplay the tool-bar in case we changed it.  */            /* Redisplay the tool-bar if we changed it.  */
8159            w->update_mode_line = Qt;            if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8160                w->update_mode_line = Qt;
8161    
8162            unbind_to (count, Qnil);            unbind_to (count, Qnil);
8163            set_buffer_internal_1 (prev);            set_buffer_internal_1 (prev);
# Line 7923  redisplay_tool_bar (f) Line 8488  redisplay_tool_bar (f)
8488    struct glyph_row *row;    struct glyph_row *row;
8489    int change_height_p = 0;    int change_height_p = 0;
8490    
8491    #ifdef USE_GTK
8492      if (FRAME_EXTERNAL_TOOL_BAR(f))
8493        update_frame_tool_bar (f);
8494      return 0;
8495    #endif
8496    
8497    /* If frame hasn't a tool-bar window or if it is zero-height, don't    /* If frame hasn't a tool-bar window or if it is zero-height, don't
8498       do anything.  This means you must start with tool-bar-lines       do anything.  This means you must start with tool-bar-lines
8499       non-zero to get the auto-sizing effect.  Or in other words, you       non-zero to get the auto-sizing effect.  Or in other words, you
8500       can turn off tool-bars by specifying tool-bar-lines zero.  */       can turn off tool-bars by specifying tool-bar-lines zero.  */
8501    if (!WINDOWP (f->tool_bar_window)    if (!WINDOWP (f->tool_bar_window)
8502        || (w = XWINDOW (f->tool_bar_window),        || (w = XWINDOW (f->tool_bar_window),
8503            XFASTINT (w->height) == 0))            XFASTINT (w->height) == 0))
8504      return 0;      return 0;
8505    
8506    /* Set up an iterator for the tool-bar window.  */    /* Set up an iterator for the tool-bar window.  */
# Line 8004  redisplay_tool_bar (f) Line 8575  redisplay_tool_bar (f)
8575     properties start in F->tool_bar_items.  Value is zero if     properties start in F->tool_bar_items.  Value is zero if
8576     GLYPH doesn't display a tool-bar item.  */     GLYPH doesn't display a tool-bar item.  */
8577    
8578  int  static int
8579  tool_bar_item_info (f, glyph, prop_idx)  tool_bar_item_info (f, glyph, prop_idx)
8580       struct frame *f;       struct frame *f;
8581       struct glyph *glyph;       struct glyph *glyph;
# Line 8036  tool_bar_item_info (f, glyph, prop_idx) Line 8607  tool_bar_item_info (f, glyph, prop_idx)
8607    return success_p;    return success_p;
8608  }  }
8609    
8610    
8611    /* Get information about the tool-bar item at position X/Y on frame F.
8612       Return in *GLYPH a pointer to the glyph of the tool-bar item in
8613       the current matrix of the tool-bar window of F, or NULL if not
8614       on a tool-bar item.  Return in *PROP_IDX the index of the tool-bar
8615       item in F->tool_bar_items.  Value is
8616    
8617       -1   if X/Y is not on a tool-bar item
8618       0    if X/Y is on the same item that was highlighted before.
8619       1    otherwise.  */
8620    
8621    static int
8622    get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8623         struct frame *f;
8624         int x, y;
8625         struct glyph **glyph;
8626         int *hpos, *vpos, *prop_idx;
8627    {
8628      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8629      struct window *w = XWINDOW (f->tool_bar_window);
8630      int area;
8631    
8632      /* Find the glyph under X/Y.  */
8633      *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
8634      if (*glyph == NULL)
8635        return -1;
8636    
8637      /* Get the start of this tool-bar item's properties in
8638         f->tool_bar_items.  */
8639      if (!tool_bar_item_info (f, *glyph, prop_idx))
8640        return -1;
8641    
8642      /* Is mouse on the highlighted item?  */
8643      if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8644          && *vpos >= dpyinfo->mouse_face_beg_row
8645          && *vpos <= dpyinfo->mouse_face_end_row
8646          && (*vpos > dpyinfo->mouse_face_beg_row
8647              || *hpos >= dpyinfo->mouse_face_beg_col)
8648          && (*vpos < dpyinfo->mouse_face_end_row
8649              || *hpos < dpyinfo->mouse_face_end_col
8650              || dpyinfo->mouse_face_past_end))
8651        return 0;
8652    
8653      return 1;
8654    }
8655    
8656    
8657    /* EXPORT:
8658       Handle mouse button event on the tool-bar of frame F, at
8659       frame-relative coordinates X/Y.  DOWN_P is 1 for a button press,
8660       0 for button release.  MODIFIERS is event modifiers for button
8661       release.  */
8662    
8663    void
8664    handle_tool_bar_click (f, x, y, down_p, modifiers)
8665         struct frame *f;
8666         int x, y, down_p;
8667         unsigned int modifiers;
8668    {
8669      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8670      struct window *w = XWINDOW (f->tool_bar_window);
8671      int hpos, vpos, prop_idx;
8672      struct glyph *glyph;
8673      Lisp_Object enabled_p;
8674    
8675      /* If not on the highlighted tool-bar item, return.  */
8676      frame_to_window_pixel_xy (w, &x, &y);
8677      if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8678        return;
8679    
8680      /* If item is disabled, do nothing.  */
8681      enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8682      if (NILP (enabled_p))
8683        return;
8684    
8685      if (down_p)
8686        {
8687          /* Show item in pressed state.  */
8688          show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8689          dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8690          last_tool_bar_item = prop_idx;
8691        }
8692      else
8693        {
8694          Lisp_Object key, frame;
8695          struct input_event event;
8696    
8697          /* Show item in released state.  */
8698          show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8699          dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8700    
8701          key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8702    
8703          XSETFRAME (frame, f);
8704          event.kind = TOOL_BAR_EVENT;
8705          event.frame_or_window = frame;
8706          event.arg = frame;
8707          kbd_buffer_store_event (&event);
8708    
8709          event.kind = TOOL_BAR_EVENT;
8710          event.frame_or_window = frame;
8711          event.arg = key;
8712          event.modifiers = modifiers;
8713          kbd_buffer_store_event (&event);
8714          last_tool_bar_item = -1;
8715        }
8716    }
8717    
8718    
8719    /* Possibly highlight a tool-bar item on frame F when mouse moves to
8720       tool-bar window-relative coordinates X/Y.  Called from
8721       note_mouse_highlight.  */
8722    
8723    static void
8724    note_tool_bar_highlight (f, x, y)
8725         struct frame *f;
8726         int x, y;
8727    {
8728      Lisp_Object window = f->tool_bar_window;
8729      struct window *w = XWINDOW (window);
8730      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8731      int hpos, vpos;
8732      struct glyph *glyph;
8733      struct glyph_row *row;
8734      int i;
8735      Lisp_Object enabled_p;
8736      int prop_idx;
8737      enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8738      int mouse_down_p, rc;
8739    
8740      /* Function note_mouse_highlight is called with negative x(y
8741         values when mouse moves outside of the frame.  */
8742      if (x <= 0 || y <= 0)
8743        {
8744          clear_mouse_face (dpyinfo);
8745          return;
8746        }
8747    
8748      rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8749      if (rc < 0)
8750        {
8751          /* Not on tool-bar item.  */
8752          clear_mouse_face (dpyinfo);
8753          return;
8754        }
8755      else if (rc == 0)
8756        /* On same tool-bar item as before.  */
8757        goto set_help_echo;
8758    
8759      clear_mouse_face (dpyinfo);
8760    
8761      /* Mouse is down, but on different tool-bar item?  */
8762      mouse_down_p = (dpyinfo->grabbed
8763                      && f == last_mouse_frame
8764                      && FRAME_LIVE_P (f));
8765      if (mouse_down_p
8766          && last_tool_bar_item != prop_idx)
8767        return;
8768    
8769      dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8770      draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8771    
8772      /* If tool-bar item is not enabled, don't highlight it.  */
8773      enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8774      if (!NILP (enabled_p))
8775        {
8776          /* Compute the x-position of the glyph.  In front and past the
8777             image is a space.  We include this is the highlighted area.  */
8778          row = MATRIX_ROW (w->current_matrix, vpos);
8779          for (i = x = 0; i < hpos; ++i)
8780            x += row->glyphs[TEXT_AREA][i].pixel_width;
8781    
8782          /* Record this as the current active region.  */
8783          dpyinfo->mouse_face_beg_col = hpos;
8784          dpyinfo->mouse_face_beg_row = vpos;
8785          dpyinfo->mouse_face_beg_x = x;
8786          dpyinfo->mouse_face_beg_y = row->y;
8787          dpyinfo->mouse_face_past_end = 0;
8788    
8789          dpyinfo->mouse_face_end_col = hpos + 1;
8790          dpyinfo->mouse_face_end_row = vpos;
8791          dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8792          dpyinfo->mouse_face_end_y = row->y;
8793          dpyinfo->mouse_face_window = window;
8794          dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8795    
8796          /* Display it as active.  */
8797          show_mouse_face (dpyinfo, draw);
8798          dpyinfo->mouse_face_image_state = draw;
8799        }
8800    
8801     set_help_echo:
8802    
8803      /* Set help_echo_string to a help string to display for this tool-bar item.
8804         XTread_socket does the rest.  */
8805      help_echo_object = help_echo_window = Qnil;
8806      help_echo_pos = -1;
8807      help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8808      if (NILP (help_echo_string))
8809        help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8810    }
8811    
8812    #endif /* HAVE_WINDOW_SYSTEM */
8813    
8814    
8815    
8816    /***********************************************************************
8817                                   Fringes
8818     ***********************************************************************/
8819    
8820    #ifdef HAVE_WINDOW_SYSTEM
8821    
8822    /* An arrow like this: `<-'.  */
8823    static unsigned char left_bits[] = {
8824       0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8825    
8826    /* Right truncation arrow bitmap `->'.  */
8827    static unsigned char right_bits[] = {
8828       0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8829    
8830    /* Marker for continued lines.  */
8831    static unsigned char continued_bits[] = {
8832       0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
8833    
8834    /* Marker for continuation lines.  */
8835    static unsigned char continuation_bits[] = {
8836       0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
8837    
8838    /* Overlay arrow bitmap.  A triangular arrow.  */
8839    static unsigned char ov_bits[] = {
8840       0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
8841    
8842    /* Bitmap drawn to indicate lines not displaying text if
8843       `indicate-empty-lines' is non-nil.  */
8844    static unsigned char zv_bits[] = {
8845      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8846      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8847      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8848      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8849      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8850      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8851      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8852      0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
8853    
8854    struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
8855    {
8856      { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
8857      { 8, sizeof (left_bits), 0, left_bits },
8858      { 8, sizeof (right_bits), 0, right_bits },
8859      { 8, sizeof (continued_bits), 0, continued_bits },
8860      { 8, sizeof (continuation_bits), 0, continuation_bits },
8861      { 8, sizeof (ov_bits), 0, ov_bits },
8862      { 8, sizeof (zv_bits), 3, zv_bits }
8863    };
8864    
8865    
8866    /* Draw the bitmap WHICH in one of the left or right fringes of
8867       window W.  ROW is the glyph row for which to display the bitmap; it
8868       determines the vertical position at which the bitmap has to be
8869       drawn.  */
8870    
8871    static void
8872    draw_fringe_bitmap (w, row, which, left_p)
8873         struct window *w;
8874         struct glyph_row *row;
8875         enum fringe_bitmap_type which;
8876         int left_p;
8877    {
8878      struct frame *f = XFRAME (WINDOW_FRAME (w));
8879      struct draw_fringe_bitmap_params p;
8880    
8881      /* Convert row to frame coordinates.  */
8882      p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8883    
8884      p.which = which;
8885      p.wd = fringe_bitmaps[which].width;
8886    
8887      p.h = fringe_bitmaps[which].height;
8888      p.dh = (fringe_bitmaps[which].period
8889              ? (p.y % fringe_bitmaps[which].period)
8890              : 0);
8891      p.h -= p.dh;
8892      /* Clip bitmap if too high.  */
8893      if (p.h > row->height)
8894        p.h = row->height;
8895    
8896      p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
8897      PREPARE_FACE_FOR_DISPLAY (f, p.face);
8898    
8899      /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
8900         the fringe.  */
8901      p.bx = -1;
8902      if (left_p)
8903        {
8904          if (p.wd > FRAME_X_LEFT_FRINGE_WIDTH (f))
8905            p.wd = FRAME_X_LEFT_FRINGE_WIDTH (f);
8906          p.x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
8907                 - p.wd
8908                 - (FRAME_X_LEFT_FRINGE_WIDTH (f) - p.wd) / 2);
8909          if (p.wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > p.h)
8910            {
8911              /* If W has a vertical border to its left, don't draw over it.  */
8912              int border = ((XFASTINT (w->left) > 0
8913                             && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
8914                            ? 1 : 0);
8915              p.bx = (window_box_left (w, -1)
8916                      - FRAME_X_LEFT_FRINGE_WIDTH (f)
8917                      + border);
8918              p.nx = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border);
8919            }
8920        }
8921      else
8922        {
8923          if (p.wd > FRAME_X_RIGHT_FRINGE_WIDTH (f))
8924            p.wd = FRAME_X_RIGHT_FRINGE_WIDTH (f);
8925          p.x = (window_box_right (w, -1)
8926                 + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - p.wd) / 2);
8927          /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
8928             the fringe.  */
8929          if (p.wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > p.h)
8930            {
8931              p.bx = window_box_right (w, -1);
8932              p.nx = FRAME_X_RIGHT_FRINGE_WIDTH (f);
8933            }
8934        }
8935    
8936      if (p.bx >= 0)
8937        {
8938          int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
8939    
8940          p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
8941          p.ny = row->visible_height;
8942        }
8943    
8944      /* Adjust y to the offset in the row to start drawing the bitmap.  */
8945      p.y += (row->height - p.h) / 2;
8946    
8947      rif->draw_fringe_bitmap (w, row, &p);
8948    }
8949    
8950    /* Draw fringe bitmaps for glyph row ROW on window W.  Call this
8951       function with input blocked.  */
8952    
8953    void
8954    draw_row_fringe_bitmaps (w, row)
8955         struct window *w;
8956         struct glyph_row *row;
8957    {
8958      struct frame *f = XFRAME (w->frame);
8959      enum fringe_bitmap_type bitmap;
8960    
8961      xassert (interrupt_input_blocked);
8962    
8963      /* If row is completely invisible, because of vscrolling, we
8964         don't have to draw anything.  */
8965      if (row->visible_height <= 0)
8966        return;
8967    
8968      if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0)
8969        {
8970          /* Decide which bitmap to draw in the left fringe.  */
8971          if (row->overlay_arrow_p)
8972            bitmap = OVERLAY_ARROW_BITMAP;
8973          else if (row->truncated_on_left_p)
8974            bitmap = LEFT_TRUNCATION_BITMAP;
8975          else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
8976            bitmap = CONTINUATION_LINE_BITMAP;
8977          else if (row->indicate_empty_line_p)
8978            bitmap = ZV_LINE_BITMAP;
8979          else
8980            bitmap = NO_FRINGE_BITMAP;
8981    
8982          draw_fringe_bitmap (w, row, bitmap, 1);
8983        }
8984    
8985      if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
8986        {
8987          /* Decide which bitmap to draw in the right fringe.  */
8988          if (row->truncated_on_right_p)
8989            bitmap = RIGHT_TRUNCATION_BITMAP;
8990          else if (row->continued_p)
8991            bitmap = CONTINUED_LINE_BITMAP;
8992          else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0)
8993            bitmap = ZV_LINE_BITMAP;
8994          else
8995            bitmap = NO_FRINGE_BITMAP;
8996    
8997          draw_fringe_bitmap (w, row, bitmap, 0);
8998        }
8999    }
9000    
9001    
9002    /* Compute actual fringe widths */
9003    
9004    void
9005    compute_fringe_widths (f, redraw)
9006         struct frame *f;
9007         int redraw;
9008    {
9009      int o_left = FRAME_X_LEFT_FRINGE_WIDTH (f);
9010      int o_right = FRAME_X_RIGHT_FRINGE_WIDTH (f);
9011      int o_cols = FRAME_X_FRINGE_COLS (f);
9012    
9013      Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9014      Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9015      int left_fringe_width, right_fringe_width;
9016    
9017      if (!NILP (left_fringe))
9018        left_fringe = Fcdr (left_fringe);
9019      if (!NILP (right_fringe))
9020        right_fringe = Fcdr (right_fringe);
9021    
9022      left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9023                           XINT (left_fringe));
9024      right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9025                            XINT (right_fringe));
9026    
9027      if (left_fringe_width || right_fringe_width)
9028        {
9029          int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9030          int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9031          int conf_wid = left_wid + right_wid;
9032          int font_wid = FONT_WIDTH (FRAME_FONT (f));
9033          int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9034          int real_wid = cols * font_wid;
9035          if (left_wid && right_wid)
9036            {
9037              if (left_fringe_width < 0)
9038                {
9039                  /* Left fringe width is fixed, adjust right fringe if necessary */
9040                  FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid;
9041                  FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9042                }
9043              else if (right_fringe_width < 0)
9044                {
9045                  /* Right fringe width is fixed, adjust left fringe if necessary */
9046                  FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9047                  FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid;
9048                }
9049              else
9050                {
9051                  /* Adjust both fringes with an equal amount.
9052                     Note that we are doing integer arithmetic here, so don't
9053                     lose a pixel if the total width is an odd number.  */
9054                  int fill = real_wid - conf_wid;
9055                  FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9056                  FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9057                }
9058            }
9059          else if (left_fringe_width)
9060            {
9061              FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid;
9062              FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0;
9063            }
9064          else
9065            {
9066              FRAME_X_LEFT_FRINGE_WIDTH (f) = 0;
9067              FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid;
9068            }
9069          FRAME_X_FRINGE_COLS (f) = cols;
9070          FRAME_X_FRINGE_WIDTH (f) = real_wid;
9071        }
9072      else
9073        {
9074          FRAME_X_LEFT_FRINGE_WIDTH (f) = 0;
9075          FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0;
9076          FRAME_X_FRINGE_COLS (f) = 0;
9077          FRAME_X_FRINGE_WIDTH (f) = 0;
9078        }
9079    
9080      if (redraw && FRAME_VISIBLE_P (f))
9081        if (o_left != FRAME_X_LEFT_FRINGE_WIDTH (f) ||
9082            o_right != FRAME_X_RIGHT_FRINGE_WIDTH (f) ||
9083            o_cols != FRAME_X_FRINGE_COLS (f))
9084          redraw_frame (f);
9085    }
9086    
9087  #endif /* HAVE_WINDOW_SYSTEM */  #endif /* HAVE_WINDOW_SYSTEM */
9088    
9089    
# Line 8280  debug_method_add (w, fmt, a1, a2, a3, a4 Line 9328  debug_method_add (w, fmt, a1, a2, a3, a4
9328  #endif /* GLYPH_DEBUG */  #endif /* GLYPH_DEBUG */
9329    
9330    
 /* This counter is used to clear the face cache every once in a while  
    in redisplay_internal.  It is incremented for each redisplay.  
    Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is  
    cleared.  */  
   
 #define CLEAR_FACE_CACHE_COUNT  500  
 static int clear_face_cache_count;  
   
 /* Record the previous terminal frame we displayed.  */  
   
 static struct frame *previous_terminal_frame;  
   
 /* Non-zero while redisplay_internal is in progress.  */  
   
 int redisplaying_p;  
   
   
9331  /* Value is non-zero if all changes in window W, which displays  /* Value is non-zero if all changes in window W, which displays
9332     current_buffer, are in the text between START and END.  START is a     current_buffer, are in the text between START and END.  START is a
9333     buffer position, END is given as a distance from Z.  Used in     buffer position, END is given as a distance from Z.  Used in
# Line 8414  reconsider_clip_changes (w, b) Line 9445  reconsider_clip_changes (w, b)
9445       struct window *w;       struct window *w;
9446       struct buffer *b;       struct buffer *b;
9447  {  {
9448    if (b->prevent_redisplay_optimizations_p)    if (b->clip_changed
     b->clip_changed = 1;  
   else if (b->clip_changed  
9449             && !NILP (w->window_end_valid)             && !NILP (w->window_end_valid)
9450             && w->current_matrix->buffer == b             && w->current_matrix->buffer == b
9451             && w->current_matrix->zv == BUF_ZV (b)             && w->current_matrix->zv == BUF_ZV (b)
# Line 8446  reconsider_clip_changes (w, b) Line 9475  reconsider_clip_changes (w, b)
9475          b->clip_changed = 1;          b->clip_changed = 1;
9476      }      }
9477  }  }
9478    
9479    #define STOP_POLLING                                    \
9480    do { if (! polling_stopped_here) stop_polling ();       \
9481           polling_stopped_here = 1; } while (0)
9482    
9483    #define RESUME_POLLING                                  \
9484    do { if (polling_stopped_here) start_polling ();        \
9485           polling_stopped_here = 0; } while (0)
9486    
9487    
9488  /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in  /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
# Line 8466  redisplay_internal (preserve_echo_area) Line 9503  redisplay_internal (preserve_echo_area)
9503    int number_of_visible_frames;    int number_of_visible_frames;
9504    int count;    int count;
9505    struct frame *sf = SELECTED_FRAME ();    struct frame *sf = SELECTED_FRAME ();
9506      int polling_stopped_here = 0;
9507    
9508    /* Non-zero means redisplay has to consider all windows on all    /* Non-zero means redisplay has to consider all windows on all
9509       frames.  Zero means, only selected_window is considered.  */       frames.  Zero means, only selected_window is considered.  */
# Line 8491  redisplay_internal (preserve_echo_area) Line 9529  redisplay_internal (preserve_echo_area)
9529          return;          return;
9530      }      }
9531    
9532  #ifdef USE_X_TOOLKIT  #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9533    if (popup_activated ())    if (popup_activated ())
9534      return;      return;
9535  #endif  #endif
# Line 8502  redisplay_internal (preserve_echo_area) Line 9540  redisplay_internal (preserve_echo_area)
9540    
9541    /* Record a function that resets redisplaying_p to its old value    /* Record a function that resets redisplaying_p to its old value
9542       when we leave this function.  */       when we leave this function.  */
9543    count = BINDING_STACK_SIZE ();    count = SPECPDL_INDEX ();
9544    record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));    record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
9545    ++redisplaying_p;    ++redisplaying_p;
9546      specbind (Qinhibit_free_realized_faces, Qnil);
9547    
9548   retry:   retry:
9549    pause = 0;    pause = 0;
# Line 8683  redisplay_internal (preserve_echo_area) Line 9722  redisplay_internal (preserve_echo_area)
9722        && CHARPOS (tlbufpos) > 0        && CHARPOS (tlbufpos) > 0
9723        && NILP (w->update_mode_line)        && NILP (w->update_mode_line)
9724        && !current_buffer->clip_changed        && !current_buffer->clip_changed
9725          && !current_buffer->prevent_redisplay_optimizations_p
9726        && FRAME_VISIBLE_P (XFRAME (w->frame))        && FRAME_VISIBLE_P (XFRAME (w->frame))
9727        && !FRAME_OBSCURED_P (XFRAME (w->frame))        && !FRAME_OBSCURED_P (XFRAME (w->frame))
9728        /* Make sure recorded data applies to current buffer, etc.  */        /* Make sure recorded data applies to current buffer, etc.  */
9729        && this_line_buffer == current_buffer        && this_line_buffer == current_buffer
9730        && current_buffer == XBUFFER (w->buffer)        && current_buffer == XBUFFER (w->buffer)
9731        && NILP (w->force_start)        && NILP (w->force_start)
9732          && NILP (w->optional_new_start)
9733        /* Point must be on the line that we have info recorded about.  */        /* Point must be on the line that we have info recorded about.  */
9734        && PT >= CHARPOS (tlbufpos)        && PT >= CHARPOS (tlbufpos)
9735        && PT <= Z - CHARPOS (tlendpos)        && PT <= Z - CHARPOS (tlendpos)
# Line 8934  redisplay_internal (preserve_echo_area) Line 9975  redisplay_internal (preserve_echo_area)
9975                  judge_scroll_bars_hook (f);                  judge_scroll_bars_hook (f);
9976    
9977                /* If fonts changed, display again.  */                /* If fonts changed, display again.  */
9978                  /* ??? rms: I suspect it is a mistake to jump all the way
9979                     back to retry here.  It should just retry this frame.  */
9980                if (fonts_changed_p)                if (fonts_changed_p)
9981                  goto retry;                  goto retry;
9982    
# Line 8949  redisplay_internal (preserve_echo_area) Line 9992  redisplay_internal (preserve_echo_area)
9992                       error.  */                       error.  */
9993                    if (interrupt_input)                    if (interrupt_input)
9994                      unrequest_sigio ();                      unrequest_sigio ();
9995                    stop_polling ();                    STOP_POLLING;
9996    
9997                    /* Update the display.  */                    /* Update the display.  */
9998                    set_window_update_flags (XWINDOW (f->root_window), 1);                    set_window_update_flags (XWINDOW (f->root_window), 1);
# Line 8994  redisplay_internal (preserve_echo_area) Line 10037  redisplay_internal (preserve_echo_area)
10037                                   redisplay_window_error);                                   redisplay_window_error);
10038    
10039        /* Compare desired and current matrices, perform output.  */        /* Compare desired and current matrices, perform output.  */
     update:  
10040    
10041        update:
10042        /* If fonts changed, display again.  */        /* If fonts changed, display again.  */
10043        if (fonts_changed_p)        if (fonts_changed_p)
10044          goto retry;          goto retry;
# Line 9005  redisplay_internal (preserve_echo_area) Line 10048  redisplay_internal (preserve_echo_area)
10048           which can cause an apparent I/O error.  */           which can cause an apparent I/O error.  */
10049        if (interrupt_input)        if (interrupt_input)
10050          unrequest_sigio ();          unrequest_sigio ();
10051        stop_polling ();        STOP_POLLING;
10052    
10053        if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))        if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10054          {          {
# Line 9081  redisplay_internal (preserve_echo_area) Line 10124  redisplay_internal (preserve_echo_area)
10124       But it is much hairier to try to do anything about that.  */       But it is much hairier to try to do anything about that.  */
10125    if (interrupt_input)    if (interrupt_input)
10126      request_sigio ();      request_sigio ();
10127    start_polling ();    RESUME_POLLING;
10128    
10129    /* If a frame has become visible which was not before, redisplay    /* If a frame has become visible which was not before, redisplay
10130       again, so that we display it.  Expose events for such a frame       again, so that we display it.  Expose events for such a frame
# Line 9120  redisplay_internal (preserve_echo_area) Line 10163  redisplay_internal (preserve_echo_area)
10163    if (windows_or_buffers_changed && !pause)    if (windows_or_buffers_changed && !pause)
10164      goto retry;      goto retry;
10165    
10166   end_of_redisplay:;   end_of_redisplay:
   
10167    unbind_to (count, Qnil);    unbind_to (count, Qnil);
10168      RESUME_POLLING;
10169  }  }
10170    
10171    
# Line 9157  redisplay_preserve_echo_area (from_where Line 10200  redisplay_preserve_echo_area (from_where
10200    
10201    
10202  /* Function registered with record_unwind_protect in  /* Function registered with record_unwind_protect in
10203     redisplay_internal.  Clears the flag indicating that a redisplay is     redisplay_internal.  Reset redisplaying_p to the value it had
10204     in progress.  */     before redisplay_internal was called, and clear
10205       prevent_freeing_realized_faces_p.  */
10206    
10207  static Lisp_Object  static Lisp_Object
10208  unwind_redisplay (old_redisplaying_p)  unwind_redisplay (old_redisplaying_p)
# Line 9366  redisplay_window_1 (window) Line 10410  redisplay_window_1 (window)
10410    return Qnil;    return Qnil;
10411  }  }
10412    
10413    
10414    /* Increment GLYPH until it reaches END or CONDITION fails while
10415       adding (GLYPH)->pixel_width to X. */
10416    
10417    #define SKIP_GLYPHS(glyph, end, x, condition)   \
10418      do                                            \
10419        {                                           \
10420          (x) += (glyph)->pixel_width;              \
10421          ++(glyph);                                \
10422        }                                           \
10423      while ((glyph) < (end) && (condition))
10424    
10425    
10426  /* Set cursor position of W.  PT is assumed to be displayed in ROW.  /* Set cursor position of W.  PT is assumed to be displayed in ROW.
10427     DELTA is the number of bytes by which positions recorded in ROW     DELTA is the number of bytes by which positions recorded in ROW
10428     differ from current buffer positions.  */     differ from current buffer positions.  */
# Line 9379  set_cursor_from_row (w, row, matrix, del Line 10436  set_cursor_from_row (w, row, matrix, del
10436  {  {
10437    struct glyph *glyph = row->glyphs[TEXT_AREA];    struct glyph *glyph = row->glyphs[TEXT_AREA];
10438    struct glyph *end = glyph + row->used[TEXT_AREA];    struct glyph *end = glyph + row->used[TEXT_AREA];
10439      /* The first glyph that starts a sequence of glyphs from string.  */
10440      struct glyph *string_start;
10441      /* The X coordinate of string_start.  */
10442      int string_start_x;
10443      /* The last known character position.  */
10444      int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10445      /* The last known character position before string_start.  */
10446      int string_before_pos;
10447    int x = row->x;    int x = row->x;
10448    int pt_old = PT - delta;    int pt_old = PT - delta;
10449    
# Line 9394  set_cursor_from_row (w, row, matrix, del Line 10459  set_cursor_from_row (w, row, matrix, del
10459          ++glyph;          ++glyph;
10460        }        }
10461    
10462      string_start = NULL;
10463    while (glyph < end    while (glyph < end
10464           && !INTEGERP (glyph->object)           && !INTEGERP (glyph->object)
10465           && (!BUFFERP (glyph->object)           && (!BUFFERP (glyph->object)
10466               || glyph->charpos < pt_old))               || (last_pos = glyph->charpos) < pt_old))
10467      {      {
10468        x += glyph->pixel_width;        if (! STRINGP (glyph->object))
10469        ++glyph;          {
10470              string_start = NULL;
10471              x += glyph->pixel_width;
10472              ++glyph;
10473            }
10474          else
10475            {
10476              string_before_pos = last_pos;
10477              string_start = glyph;
10478              string_start_x = x;
10479              /* Skip all glyphs from string.  */
10480              SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10481            }
10482        }
10483    
10484      if (string_start
10485          && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10486        {
10487          /* We may have skipped over point because the previous glyphs
10488             are from string.  As there's no easy way to know the
10489             character position of the current glyph, find the correct
10490             glyph on point by scanning from string_start again.  */
10491          Lisp_Object limit;
10492          Lisp_Object string;
10493          int pos;
10494    
10495          limit = make_number (pt_old + 1);
10496          end = glyph;
10497          glyph = string_start;
10498          x = string_start_x;
10499          string = glyph->object;
10500          pos = string_buffer_position (w, string, string_before_pos);
10501          /* If STRING is from overlay, LAST_POS == 0.  We skip such glyphs
10502             because we always put cursor after overlay strings.  */
10503          while (pos == 0 && glyph < end)
10504            {
10505              string = glyph->object;
10506              SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10507              if (glyph < end)
10508                pos = string_buffer_position (w, glyph->object, string_before_pos);
10509            }
10510    
10511          while (glyph < end)
10512            {
10513              pos = XINT (Fnext_single_char_property_change
10514                          (make_number (pos), Qdisplay, Qnil, limit));
10515              if (pos > pt_old)
10516                break;
10517              /* Skip glyphs from the same string.  */
10518              string = glyph->object;
10519              SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10520              /* Skip glyphs from an overlay.  */
10521              while (glyph < end
10522                     && ! string_buffer_position (w, glyph->object, pos))
10523                {
10524                  string = glyph->object;
10525                  SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10526                }
10527            }
10528      }      }
10529    
10530    w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];    w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
# Line 9467  run_window_scroll_functions (window, sta Line 10591  run_window_scroll_functions (window, sta
10591  }  }
10592    
10593    
10594  /* Modify the desired matrix of window W and W->vscroll so that the  /* Make sure the line containing the cursor is fully visible.
10595     line containing the cursor is fully visible.  If this requires     A value of 1 means there is nothing to be done.
10596     larger matrices than are allocated, set fonts_changed_p and return     (Either the line is fully visible, or it cannot be made so,
10597     0.  */     or we cannot tell.)
10598       A value of 0 means the caller should do scrolling
10599       as if point had gone off the screen.  */
10600    
10601  static int  static int
10602  make_cursor_line_fully_visible (w)  make_cursor_line_fully_visible (w)
# Line 9488  make_cursor_line_fully_visible (w) Line 10614  make_cursor_line_fully_visible (w)
10614    matrix = w->desired_matrix;    matrix = w->desired_matrix;
10615    row = MATRIX_ROW (matrix, w->cursor.vpos);    row = MATRIX_ROW (matrix, w->cursor.vpos);
10616    
10617    /* If the cursor row is not partially visible, there's nothing    /* If the cursor row is not partially visible, there's nothing to do.  */
      to do.  */  
10618    if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))    if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10619      return 1;      return 1;
10620    
# Line 9499  make_cursor_line_fully_visible (w) Line 10624  make_cursor_line_fully_visible (w)
10624    if (row->height >= window_height)    if (row->height >= window_height)
10625      return 1;      return 1;
10626    
10627      return 0;
10628    
10629    #if 0
10630      /* This code used to try to scroll the window just enough to make
10631         the line visible.  It returned 0 to say that the caller should
10632         allocate larger glyph matrices.  */
10633    
10634    if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))    if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10635      {      {
10636        int dy = row->height - row->visible_height;        int dy = row->height - row->visible_height;
# Line 9530  make_cursor_line_fully_visible (w) Line 10662  make_cursor_line_fully_visible (w)
10662      }      }
10663    
10664    return 1;    return 1;
10665    #endif /* 0 */
10666  }  }
10667    
10668    
# Line 9539  make_cursor_line_fully_visible (w) Line 10672  make_cursor_line_fully_visible (w)
10672     in redisplay_window to bring a partially visible line into view in     in redisplay_window to bring a partially visible line into view in
10673     the case that only the cursor has moved.     the case that only the cursor has moved.
10674    
10675       LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10676       last screen line's vertical height extends past the end of the screen.
10677    
10678     Value is     Value is
10679    
10680     1    if scrolling succeeded     1    if scrolling succeeded
# Line 9557  enum Line 10693  enum
10693    
10694  static int  static int
10695  try_scrolling (window, just_this_one_p, scroll_conservatively,  try_scrolling (window, just_this_one_p, scroll_conservatively,
10696                 scroll_step, temp_scroll_step)                 scroll_step, temp_scroll_step, last_line_misfit)
10697       Lisp_Object window;       Lisp_Object window;
10698       int just_this_one_p;       int just_this_one_p;
10699       EMACS_INT scroll_conservatively, scroll_step;       EMACS_INT scroll_conservatively, scroll_step;
10700       int temp_scroll_step;       int temp_scroll_step;
10701         int last_line_misfit;
10702  {  {
10703    struct window *w = XWINDOW (window);    struct window *w = XWINDOW (window);
10704    struct frame *f = XFRAME (w->frame);    struct frame *f = XFRAME (w->frame);
# Line 9577  try_scrolling (window, just_this_one_p, Line 10714  try_scrolling (window, just_this_one_p,
10714    int amount_to_scroll = 0;    int amount_to_scroll = 0;
10715    Lisp_Object aggressive;    Lisp_Object aggressive;
10716    int height;    int height;
10717      int end_scroll_margin;
10718    
10719  #if GLYPH_DEBUG  #if GLYPH_DEBUG
10720    debug_method_add (w, "try_scrolling");    debug_method_add (w, "try_scrolling");
# Line 9613  try_scrolling (window, just_this_one_p, Line 10751  try_scrolling (window, just_this_one_p,
10751       and move this_scroll_margin up to find the position of the scroll       and move this_scroll_margin up to find the position of the scroll
10752       margin.  */       margin.  */
10753    window_end = Fwindow_end (window, Qt);    window_end = Fwindow_end (window, Qt);
10754    
10755     too_near_end:
10756    
10757    CHARPOS (scroll_margin_pos) = XINT (window_end);    CHARPOS (scroll_margin_pos) = XINT (window_end);
10758    BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));    BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10759    if (this_scroll_margin)  
10760      end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10761      if (end_scroll_margin)
10762      {      {
10763        start_display (&it, w, scroll_margin_pos);        start_display (&it, w, scroll_margin_pos);
10764        move_it_vertically (&it, - this_scroll_margin);        move_it_vertically (&it, - end_scroll_margin);
10765        scroll_margin_pos = it.current.pos;        scroll_margin_pos = it.current.pos;
10766      }      }
10767    
# Line 9650  try_scrolling (window, just_this_one_p, Line 10793  try_scrolling (window, just_this_one_p,
10793        start_display (&it, w, startp);        start_display (&it, w, startp);
10794    
10795        if (scroll_conservatively)        if (scroll_conservatively)
10796            /* Set AMOUNT_TO_SCROLL to at least one line,
10797               and at most scroll_conservatively lines.  */
10798          amount_to_scroll          amount_to_scroll
10799            = max (max (dy, CANON_Y_UNIT (f)),            = min (max (dy, CANON_Y_UNIT (f)),
10800                   CANON_Y_UNIT (f) * max (scroll_step, temp_scroll_step));                   CANON_Y_UNIT (f) * scroll_conservatively);
10801        else if (scroll_step || temp_scroll_step)        else if (scroll_step || temp_scroll_step)
10802          amount_to_scroll = scroll_max;          amount_to_scroll = scroll_max;
10803        else        else
# Line 9667  try_scrolling (window, just_this_one_p, Line 10812  try_scrolling (window, just_this_one_p,
10812        if (amount_to_scroll <= 0)        if (amount_to_scroll <= 0)
10813          return SCROLLING_FAILED;          return SCROLLING_FAILED;
10814    
10815          /* If moving by amount_to_scroll leaves STARTP unchanged,
10816             move it down one screen line.  */
10817    
10818        move_it_vertically (&it, amount_to_scroll);        move_it_vertically (&it, amount_to_scroll);
10819          if (CHARPOS (it.current.pos) == CHARPOS (startp))
10820            move_it_by_lines (&it, 1, 1);
10821        startp = it.current.pos;        startp = it.current.pos;
10822      }      }
10823    else    else
# Line 9746  try_scrolling (window, just_this_one_p, Line 10896  try_scrolling (window, just_this_one_p,
10896            || BEG_UNCHANGED < CHARPOS (startp))            || BEG_UNCHANGED < CHARPOS (startp))
10897          w->base_line_number = Qnil;          w->base_line_number = Qnil;
10898    
10899        /* If cursor ends up on a partially visible line, shift display        /* If cursor ends up on a partially visible line,
10900           lines up or down.  If that fails because we need larger           treat that as being off the bottom of the screen.  */
10901           matrices, give up.  */        if (! make_cursor_line_fully_visible (w))
10902        if (!make_cursor_line_fully_visible (w))          {
10903          rc = SCROLLING_NEED_LARGER_MATRICES;            clear_glyph_matrix (w->desired_matrix);
10904        else            last_line_misfit = 1;
10905          rc = SCROLLING_SUCCESS;            goto too_near_end;
10906            }
10907          rc = SCROLLING_SUCCESS;
10908      }      }
10909    
10910    return rc;    return rc;
# Line 10039  try_cursor_movement (window, startp, scr Line 11191  try_cursor_movement (window, startp, scr
11191                else                else
11192                  {                  {
11193                    set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);                    set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
                   try_window (window, startp);  
11194                    if (!make_cursor_line_fully_visible (w))                    if (!make_cursor_line_fully_visible (w))
11195                      rc = CURSOR_MOVEMENT_NEED_LARGER_MATRICES;                      rc = CURSOR_MOVEMENT_MUST_SCROLL;
11196                    else                    else
11197                      rc = CURSOR_MOVEMENT_SUCCESS;                      rc = CURSOR_MOVEMENT_SUCCESS;
11198                  }                  }
# Line 10059  try_cursor_movement (window, startp, scr Line 11210  try_cursor_movement (window, startp, scr
11210    return rc;    return rc;
11211  }  }
11212    
11213    void
11214    set_vertical_scroll_bar (w)
11215         struct window *w;
11216    {
11217      int start, end, whole;
11218    
11219      /* Calculate the start and end positions for the current window.
11220         At some point, it would be nice to choose between scrollbars
11221         which reflect the whole buffer size, with special markers
11222         indicating narrowing, and scrollbars which reflect only the
11223         visible region.
11224        
11225         Note that mini-buffers sometimes aren't displaying any text.  */
11226      if (!MINI_WINDOW_P (w)
11227          || (w == XWINDOW (minibuf_window)
11228              && NILP (echo_area_buffer[0])))
11229        {
11230          struct buffer *buf = XBUFFER (w->buffer);
11231          whole = BUF_ZV (buf) - BUF_BEGV (buf);
11232          start = marker_position (w->start) - BUF_BEGV (buf);
11233          /* I don't think this is guaranteed to be right.  For the
11234             moment, we'll pretend it is.  */
11235          end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11236          
11237          if (end < start)
11238            end = start;
11239          if (whole < (end - start))
11240            whole = end - start;
11241        }
11242      else
11243        start = end = whole = 0;
11244    
11245      /* Indicate what this scroll bar ought to be displaying now.  */
11246      set_vertical_scroll_bar_hook (w, end - start, whole, start);
11247    }
11248    
11249  /* Redisplay leaf window WINDOW.  JUST_THIS_ONE_P non-zero means only  /* Redisplay leaf window WINDOW.  JUST_THIS_ONE_P non-zero means only
11250     selected_window is redisplayed.  */     selected_window is redisplayed.
11251    
11252       We can return without actually redisplaying the window if
11253       fonts_changed_p is nonzero.  In that case, redisplay_internal will
11254       retry.  */
11255    
11256  static void  static void
11257  redisplay_window (window, just_this_one_p)  redisplay_window (window, just_this_one_p)
# Line 10078  redisplay_window (window, just_this_one_ Line 11268  redisplay_window (window, just_this_one_
11268    struct it it;    struct it it;
11269    /* Record it now because it's overwritten.  */    /* Record it now because it's overwritten.  */
11270    int current_matrix_up_to_date_p = 0;    int current_matrix_up_to_date_p = 0;
11271      /* This is less strict than current_matrix_up_to_date_p.
11272         It indictes that the buffer contents and narrowing are unchanged.  */
11273      int buffer_unchanged_p = 0;
11274    int temp_scroll_step = 0;    int temp_scroll_step = 0;
11275    int count = BINDING_STACK_SIZE ();    int count = SPECPDL_INDEX ();
11276    int rc;    int rc;
11277      int centering_position;
11278      int last_line_misfit = 0;
11279    
11280    SET_TEXT_POS (lpoint, PT, PT_BYTE);    SET_TEXT_POS (lpoint, PT, PT_BYTE);
11281    opoint = lpoint;    opoint = lpoint;
# Line 10098  redisplay_window (window, just_this_one_ Line 11293  redisplay_window (window, just_this_one_
11293    /* Has the mode line to be updated?  */    /* Has the mode line to be updated?  */
11294    update_mode_line = (!NILP (w->update_mode_line)    update_mode_line = (!NILP (w->update_mode_line)
11295                        || update_mode_lines                        || update_mode_lines
11296                        || buffer->clip_changed);                        || buffer->clip_changed
11297                          || buffer->prevent_redisplay_optimizations_p);
11298    
11299    if (MINI_WINDOW_P (w))    if (MINI_WINDOW_P (w))
11300      {      {
# Line 10113  redisplay_window (window, just_this_one_ Line 11309  redisplay_window (window, just_this_one_
11309              /* We've already displayed the echo area glyphs in this window.  */              /* We've already displayed the echo area glyphs in this window.  */
11310              goto finish_scroll_bars;              goto finish_scroll_bars;
11311          }          }
11312        else if (w != XWINDOW (minibuf_window))        else if ((w != XWINDOW (minibuf_window)
11313                    || minibuf_level == 0)
11314                   /* When buffer is nonempty, redisplay window normally. */
11315                   && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11316                   /* Quail displays non-mini buffers in minibuffer window.
11317                      In that case, redisplay the window normally.  */
11318                   && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11319          {          {
11320            /* W is a mini-buffer window, but it's not the currently            /* W is a mini-buffer window, but it's not active, so clear
11321               active one, so clear it.  */               it.  */
11322            int yb = window_text_bottom_y (w);            int yb = window_text_bottom_y (w);
11323            struct glyph_row *row;            struct glyph_row *row;
11324            int y;            int y;
# Line 10141  redisplay_window (window, just_this_one_ Line 11343  redisplay_window (window, just_this_one_
11343    current_matrix_up_to_date_p    current_matrix_up_to_date_p
11344      = (!NILP (w->window_end_valid)      = (!NILP (w->window_end_valid)
11345         && !current_buffer->clip_changed         && !current_buffer->clip_changed
11346           && !current_buffer->prevent_redisplay_optimizations_p
11347           && XFASTINT (w->last_modified) >= MODIFF
11348           && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11349    
11350      buffer_unchanged_p
11351        = (!NILP (w->window_end_valid)
11352           && !current_buffer->clip_changed
11353         && XFASTINT (w->last_modified) >= MODIFF         && XFASTINT (w->last_modified) >= MODIFF
11354         && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);         && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11355    
# Line 10256  redisplay_window (window, just_this_one_ Line 11465  redisplay_window (window, just_this_one_
11465    if (!NILP (w->force_start)    if (!NILP (w->force_start)
11466        || w->frozen_window_start_p)        || w->frozen_window_start_p)
11467      {      {
11468          /* We set this later on if we have to adjust point.  */
11469          int new_vpos = -1;
11470    
11471        w->force_start = Qnil;        w->force_start = Qnil;
11472        w->vscroll = 0;        w->vscroll = 0;
11473        w->window_end_valid = Qnil;        w->window_end_valid = Qnil;
11474    
11475        /* Forget any recorded base line for line number display.  */        /* Forget any recorded base line for line number display.  */
11476        if (!current_matrix_up_to_date_p        if (!buffer_unchanged_p)
           || current_buffer->clip_changed)  
11477          w->base_line_number = Qnil;          w->base_line_number = Qnil;
11478    
11479        /* Redisplay the mode line.  Select the buffer properly for that.        /* Redisplay the mode line.  Select the buffer properly for that.
# Line 10293  redisplay_window (window, just_this_one_ Line 11504  redisplay_window (window, just_this_one_
11504          {          {
11505            w->force_start = Qt;            w->force_start = Qt;
11506            clear_glyph_matrix (w->desired_matrix);            clear_glyph_matrix (w->desired_matrix);
11507            goto finish_scroll_bars;            goto need_larger_matrices;
11508          }          }
11509    
11510        if (w->cursor.vpos < 0 && !w->frozen_window_start_p)        if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
# Line 10301  redisplay_window (window, just_this_one_ Line 11512  redisplay_window (window, just_this_one_
11512            /* If point does not appear, try to move point so it does            /* If point does not appear, try to move point so it does
11513               appear. The desired matrix has been built above, so we               appear. The desired matrix has been built above, so we
11514               can use it here.  */               can use it here.  */
11515            int window_height;            new_vpos = window_box_height (w) / 2;
11516            }
11517    
11518          if (!make_cursor_line_fully_visible (w))
11519            {
11520              /* Point does appear, but on a line partly visible at end of window.
11521                 Move it back to a fully-visible line.  */
11522              new_vpos = window_box_height (w);
11523            }
11524    
11525          /* If we need to move point for either of the above reasons,
11526             now actually do it.  */
11527          if (new_vpos >= 0)
11528            {
11529            struct glyph_row *row;            struct glyph_row *row;
11530    
           window_height = window_box_height (w) / 2;  
11531            row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);            row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11532            while (MATRIX_ROW_BOTTOM_Y (row) < window_height)            while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11533              ++row;              ++row;
11534    
11535            TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),            TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
# Line 10330  redisplay_window (window, just_this_one_ Line 11553  redisplay_window (window, just_this_one_
11553              }              }
11554          }          }
11555    
       if (!make_cursor_line_fully_visible (w))  
         goto need_larger_matrices;  
11556  #if GLYPH_DEBUG  #if GLYPH_DEBUG
11557        debug_method_add (w, "forced window start");        debug_method_add (w, "forced window start");
11558  #endif  #endif
# Line 10339  redisplay_window (window, just_this_one_ Line 11560  redisplay_window (window, just_this_one_
11560      }      }
11561    
11562    /* Handle case where text has not changed, only point, and it has    /* Handle case where text has not changed, only point, and it has
11563       not moved off the frame.  */       not moved off the frame, and we are not retrying after hscroll.
11564         (current_matrix_up_to_date_p is nonzero when retrying.)  */
11565    if (current_matrix_up_to_date_p    if (current_matrix_up_to_date_p
11566        && (rc = try_cursor_movement (window, startp, &temp_scroll_step),        && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11567            rc != CURSOR_MOVEMENT_CANNOT_BE_USED))            rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
# Line 10349  redisplay_window (window, just_this_one_ Line 11571  redisplay_window (window, just_this_one_
11571          case CURSOR_MOVEMENT_SUCCESS:          case CURSOR_MOVEMENT_SUCCESS:
11572            goto done;            goto done;
11573    
11574    #if 0  /* try_cursor_movement never returns this value.  */
11575          case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:          case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11576            goto need_larger_matrices;            goto need_larger_matrices;
11577    #endif
11578    
11579          case CURSOR_MOVEMENT_MUST_SCROLL:          case CURSOR_MOVEMENT_MUST_SCROLL:
11580            goto try_to_scroll;            goto try_to_scroll;
# Line 10427  redisplay_window (window, just_this_one_ Line 11651  redisplay_window (window, just_this_one_
11651              w->base_line_number = Qnil;              w->base_line_number = Qnil;
11652    
11653            if (!make_cursor_line_fully_visible (w))            if (!make_cursor_line_fully_visible (w))
11654              goto need_larger_matrices;              {
11655            goto done;                clear_glyph_matrix (w->desired_matrix);
11656                  last_line_misfit = 1;
11657                }
11658                /* Drop through and scroll.  */
11659              else
11660                goto done;
11661          }          }
11662        else        else
11663          clear_glyph_matrix (w->desired_matrix);          clear_glyph_matrix (w->desired_matrix);
# Line 10461  redisplay_window (window, just_this_one_ Line 11690  redisplay_window (window, just_this_one_
11690        int rc = try_scrolling (window, just_this_one_p,        int rc = try_scrolling (window, just_this_one_p,
11691                                scroll_conservatively,                                scroll_conservatively,
11692                                scroll_step,                                scroll_step,
11693                                temp_scroll_step);                                temp_scroll_step, last_line_misfit);
11694        switch (rc)        switch (rc)
11695          {          {
11696          case SCROLLING_SUCCESS:          case SCROLLING_SUCCESS:
# Line 10481  redisplay_window (window, just_this_one_ Line 11710  redisplay_window (window, just_this_one_
11710    /* Finally, just choose place to start which centers point */    /* Finally, just choose place to start which centers point */
11711    
11712   recenter:   recenter:
11713      centering_position = window_box_height (w) / 2;
11714    
11715     point_at_top:
11716      /* Jump here with centering_position already set to 0.  */
11717    
11718  #if GLYPH_DEBUG  #if GLYPH_DEBUG
11719    debug_method_add (w, "recenter");    debug_method_add (w, "recenter");
# Line 10489  redisplay_window (window, just_this_one_ Line 11722  redisplay_window (window, just_this_one_
11722    /* w->vscroll = 0; */    /* w->vscroll = 0; */
11723    
11724    /* Forget any previously recorded base line for line number display.  */    /* Forget any previously recorded base line for line number display.  */
11725    if (!current_matrix_up_to_date_p    if (!buffer_unchanged_p)
       || current_buffer->clip_changed)  
11726      w->base_line_number = Qnil;      w->base_line_number = Qnil;
11727    
11728    /* Move backward half the height of the window.  */    /* Move backward half the height of the window.  */
11729    init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);    init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11730    it.current_y = it.last_visible_y;    it.current_y = it.last_visible_y;
11731    move_it_vertically_backward (&it, window_box_height (w) / 2);    move_it_vertically_backward (&it, centering_position);
11732    xassert (IT_CHARPOS (it) >= BEGV);    xassert (IT_CHARPOS (it) >= BEGV);
11733    
11734    /* The function move_it_vertically_backward may move over more    /* The function move_it_vertically_backward may move over more
# Line 10578  redisplay_window (window, just_this_one_ Line 11810  redisplay_window (window, just_this_one_
11810      }      }
11811    
11812    if (!make_cursor_line_fully_visible (w))    if (!make_cursor_line_fully_visible (w))
11813      goto need_larger_matrices;      {
11814          /* If vscroll is enabled, disable it and try again.  */
11815          if (w->vscroll)
11816            {
11817              w->vscroll = 0;
11818              clear_glyph_matrix (w->desired_matrix);
11819              goto recenter;
11820            }
11821    
11822          /* If centering point failed to make the whole line visible,
11823             put point at the top instead.  That has to make the whole line
11824             visible, if it can be done.  */
11825          centering_position = 0;
11826          goto point_at_top;
11827        }
11828    
11829   done:   done:
11830    
# Line 10646  redisplay_window (window, just_this_one_ Line 11892  redisplay_window (window, just_this_one_
11892        && EQ (FRAME_SELECTED_WINDOW (f), window))        && EQ (FRAME_SELECTED_WINDOW (f), window))
11893      {      {
11894        int redisplay_menu_p = 0;        int redisplay_menu_p = 0;
11895          int redisplay_tool_bar_p = 0;
11896    
11897        if (FRAME_WINDOW_P (f))        if (FRAME_WINDOW_P (f))
11898          {          {
11899  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS)  #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11900        || defined (USE_GTK)
11901            redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);            redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
11902  #else  #else
11903            redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;            redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
# Line 10662  redisplay_window (window, just_this_one_ Line 11910  redisplay_window (window, just_this_one_
11910          display_menu_bar (w);          display_menu_bar (w);
11911    
11912  #ifdef HAVE_WINDOW_SYSTEM  #ifdef HAVE_WINDOW_SYSTEM
11913        if (WINDOWP (f->tool_bar_window)  #ifdef USE_GTK
11914            && (FRAME_TOOL_BAR_LINES (f) > 0        redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
11915                || auto_resize_tool_bars_p))  #else
11916          redisplay_tool_bar (f);        redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
11917            && (FRAME_TOOL_BAR_LINES (f) > 0
11918                || auto_resize_tool_bars_p);
11919    
11920    #endif
11921    
11922          if (redisplay_tool_bar_p)
11923            redisplay_tool_bar (f);
11924  #endif  #endif
11925      }      }
11926    
11927      /* We go to this label, with fonts_changed_p nonzero,
11928         if it is necessary to try again using larger glyph matrices.
11929         We have to redeem the scroll bar even in this case,
11930         because the loop in redisplay_internal expects that.  */
11931   need_larger_matrices:   need_larger_matrices:
11932    ;    ;
11933   finish_scroll_bars:   finish_scroll_bars:
11934    
11935    if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))    if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
11936      {      {
11937        int start, end, whole;        /* Set the thumb's position and size.  */
11938          set_vertical_scroll_bar (w);
       /* Calculate the start and end positions for the current window.  
          At some point, it would be nice to choose between scrollbars  
          which reflect the whole buffer size, with special markers  
          indicating narrowing, and scrollbars which reflect only the  
          visible region.  
   
          Note that mini-buffers sometimes aren't displaying any text.  */  
       if (!MINI_WINDOW_P (w)  
           || (w == XWINDOW (minibuf_window)  
               && NILP (echo_area_buffer[0])))  
         {  
           whole = ZV - BEGV;  
           start = marker_position (w->start) - BEGV;  
           /* I don't think this is guaranteed to be right.  For the  
              moment, we'll pretend it is.  */  
           end = (Z - XFASTINT (w->window_end_pos)) - BEGV;  
   
           if (end < start)  
             end = start;  
           if (whole < (end - start))  
             whole = end - start;  
         }  
       else  
         start = end = whole = 0;  
   
       /* Indicate what this scroll bar ought to be displaying now.  */  
       set_vertical_scroll_bar_hook (w, end - start, whole, start);  
11939    
11940        /* Note that we actually used the scroll bar attached to this        /* Note that we actually used the scroll bar attached to this
11941           window, so it shouldn't be deleted at the end of redisplay.  */           window, so it shouldn't be deleted at the end of redisplay.  */
# Line 10916  try_window_reusing_current_matrix (w) Line 12148  try_window_reusing_current_matrix (w)
12148              {              {
12149                update_begin (f);                update_begin (f);
12150                rif->update_window_begin_hook (w);                rif->update_window_begin_hook (w);
12151                rif->clear_mouse_face (w);                rif->clear_window_mouse_face (w);
12152                rif->scroll_run_hook (w, &run);                rif->scroll_run_hook (w, &run);
12153                rif->update_window_end_hook (w, 0, 0);                rif->update_window_end_hook (w, 0, 0);
12154                update_end (f);                update_end (f);
# Line 11088  try_window_reusing_current_matrix (w) Line 12320  try_window_reusing_current_matrix (w)
12320            struct frame *f = XFRAME (WINDOW_FRAME (w));            struct frame *f = XFRAME (WINDOW_FRAME (w));
12321            update_begin (f);            update_begin (f);
12322            rif->update_window_begin_hook (w);            rif->update_window_begin_hook (w);
12323            rif->clear_mouse_face (w);            rif->clear_window_mouse_face (w);
12324            rif->scroll_run_hook (w, &run);            rif->scroll_run_hook (w, &run);
12325            rif->update_window_end_hook (w, 0, 0);            rif->update_window_end_hook (w, 0, 0);
12326            update_end (f);            update_end (f);
# Line 11393  row_containing_pos (w, charpos, start, e Line 12625  row_containing_pos (w, charpos, start, e
12625    
12626    last_y = window_text_bottom_y (w) - dy;    last_y = window_text_bottom_y (w) - dy;
12627    
12628    while ((end == NULL || row < end)    while (1)
12629           && MATRIX_ROW_BOTTOM_Y (row) < last_y      {
12630           && (MATRIX_ROW_END_CHARPOS (row) < charpos        /* Give up if we have gone too far.  */
12631          if (end && row >= end)
12632            return NULL;
12633          /* This formerly returned if they were equal.
12634             I think that both quantities are of a "last plus one" type;
12635             if so, when they are equal, the row is within the screen. -- rms.  */
12636          if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12637            return NULL;
12638    
12639          /* If it is in this row, return this row.  */
12640          if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12641               || (MATRIX_ROW_END_CHARPOS (row) == charpos               || (MATRIX_ROW_END_CHARPOS (row) == charpos
12642                   /* The end position of a row equals the start                   /* The end position of a row equals the start
12643                      position of the next row.  If CHARPOS is there, we                      position of the next row.  If CHARPOS is there, we
12644                      would rather display it in the next line, except                      would rather display it in the next line, except
12645                      when this line ends in ZV.  */                      when this line ends in ZV.  */
12646                   && !row->ends_at_zv_p                   && !row->ends_at_zv_p
12647                   && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))                   && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12648      ++row;            && charpos >= MATRIX_ROW_START_CHARPOS (row))
12649            return row;
12650    /* Give up if CHARPOS not found.  */        ++row;
12651    if ((end && row >= end)      }
       || charpos < MATRIX_ROW_START_CHARPOS (row)  
       || charpos > MATRIX_ROW_END_CHARPOS (row))  
     row = NULL;  
   
   return row;  
12652  }  }
12653    
12654    
# Line 11498  try_window_id (w) Line 12735  try_window_id (w)
12735    if (windows_or_buffers_changed || cursor_type_changed)    if (windows_or_buffers_changed || cursor_type_changed)
12736      GIVE_UP (2);      GIVE_UP (2);
12737    
12738    /* Verify that narrowing has not changed.  This flag is also set to prevent    /* Verify that narrowing has not changed.
12739       redisplay optimizations.  It would be nice to further       Also verify that we were not told to prevent redisplay optimizations.
12740         It would be nice to further
12741       reduce the number of cases where this prevents try_window_id.  */       reduce the number of cases where this prevents try_window_id.  */
12742    if (current_buffer->clip_changed)    if (current_buffer->clip_changed
12743          || current_buffer->prevent_redisplay_optimizations_p)
12744      GIVE_UP (3);      GIVE_UP (3);
12745    
12746    /* Window must either use window-based redisplay or be full width.  */    /* Window must either use window-based redisplay or be full width.  */
# Line 11612  try_window_id (w) Line 12851  try_window_id (w)
12851    
12852            /* Set the cursor.  */            /* Set the cursor.  */
12853            row = row_containing_pos (w, PT, r0, NULL, 0);            row = row_containing_pos (w, PT, r0, NULL, 0);
12854            set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);            if (row)
12855                set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12856              else
12857                abort ();
12858            return 1;            return 1;
12859          }          }
12860      }      }
# Line 11650  try_window_id (w) Line 12892  try_window_id (w)
12892    
12893            /* Set the cursor.  */            /* Set the cursor.  */
12894            row = row_containing_pos (w, PT, r0, NULL, 0);            row = row_containing_pos (w, PT, r0, NULL, 0);
12895            set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);            if (row)
12896                set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12897              else
12898                abort ();
12899            return 2;            return 2;
12900          }          }
12901      }      }
# Line 11903  try_window_id (w) Line 13148  try_window_id (w)
13148        if (FRAME_WINDOW_P (f))        if (FRAME_WINDOW_P (f))
13149          {          {
13150            rif->update_window_begin_hook (w);            rif->update_window_begin_hook (w);
13151            rif->clear_mouse_face (w);            rif->clear_window_mouse_face (w);
13152            rif->scroll_run_hook (w, &run);            rif->scroll_run_hook (w, &run);
13153            rif->update_window_end_hook (w, 0, 0);            rif->update_window_end_hook (w, 0, 0);
13154          }          }
# Line 12444  With ARG, turn tracing on if and only if Line 13689  With ARG, turn tracing on if and only if
13689    
13690    
13691  DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",  DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13692         doc: /* Like `format', but print result to stderr.  */)         doc: /* Like `format', but print result to stderr.
13693    usage: (trace-to-stderr STRING &rest OBJECTS)  */)
13694       (nargs, args)       (nargs, args)
13695       int nargs;       int nargs;
13696       Lisp_Object *args;       Lisp_Object *args;
# Line 12472  get_overlay_arrow_glyph_row (w) Line 13718  get_overlay_arrow_glyph_row (w)
13718    struct frame *f = XFRAME (WINDOW_FRAME (w));    struct frame *f = XFRAME (WINDOW_FRAME (w));
13719    struct buffer *buffer = XBUFFER (w->buffer);    struct buffer *buffer = XBUFFER (w->buffer);
13720    struct buffer *old = current_buffer;    struct buffer *old = current_buffer;
13721    unsigned char *arrow_string = SDATA (Voverlay_arrow_string);    const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13722    int arrow_len = SCHARS (Voverlay_arrow_string);    int arrow_len = SCHARS (Voverlay_arrow_string);
13723    unsigned char *arrow_end = arrow_string + arrow_len;    const unsigned char *arrow_end = arrow_string + arrow_len;
13724    unsigned char *p;    const unsigned char *p;
13725    struct it it;    struct it it;
13726    int multibyte_p;    int multibyte_p;
13727    int n_glyphs_before;    int n_glyphs_before;
# Line 13188  display_line (it) Line 14434  display_line (it)
14434                  {                  {
14435                    /* Glyph is completely off the left margin of the                    /* Glyph is completely off the left margin of the
14436                       window.  This should not happen because of the                       window.  This should not happen because of the
14437                       move_it_in_display_line at the start of                       move_it_in_display_line at the start of this
14438                       this function.  */                       function, unless the text display area of the
14439                    abort ();                       window is empty.  */
14440                      xassert (it->first_visible_x <= it->last_visible_x);
14441                  }                  }
14442              }              }
14443    
# Line 13377  display_menu_bar (w) Line 14624  display_menu_bar (w)
14624    if (!NILP (Vwindow_system))    if (!NILP (Vwindow_system))
14625      return;      return;
14626  #endif  #endif
14627  #ifdef USE_X_TOOLKIT  #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14628    if (FRAME_X_P (f))    if (FRAME_X_P (f))
14629      return;      return;
14630  #endif  #endif
# Line 13625  display_mode_line (w, face_id, format) Line 14872  display_mode_line (w, face_id, format)
14872     Each element is (PROPERTIZED-STRING . PROPERTY-LIST).  */     Each element is (PROPERTIZED-STRING . PROPERTY-LIST).  */
14873  Lisp_Object mode_line_proptrans_alist;  Lisp_Object mode_line_proptrans_alist;
14874    
14875    /* List of strings making up the mode-line.  */
14876    Lisp_Object mode_line_string_list;
14877    
14878    /* Base face property when building propertized mode line string.  */
14879    static Lisp_Object mode_line_string_face;
14880    static Lisp_Object mode_line_string_face_prop;
14881    
14882    
14883  /* Contribute ELT to the mode line for window IT->w.  How it  /* Contribute ELT to the mode line for window IT->w.  How it
14884     translates into text depends on its data type.     translates into text depends on its data type.
14885    
# Line 13643  Lisp_Object mode_line_proptrans_alist; Line 14898  Lisp_Object mode_line_proptrans_alist;
14898     PROPS is a property list to add to any string we encounter.     PROPS is a property list to add to any string we encounter.
14899    
14900     If RISKY is nonzero, remove (disregard) any properties in any string     If RISKY is nonzero, remove (disregard) any properties in any string
14901     we encounter, and ignore :eval and :propertize.  */     we encounter, and ignore :eval and :propertize.
14902    
14903       If the global variable `frame_title_ptr' is non-NULL, then the output
14904       is passed to `store_frame_title' instead of `display_string'.  */
14905    
14906  static int  static int
14907  display_mode_element (it, depth, field_width, precision, elt, props, risky)  display_mode_element (it, depth, field_width, precision, elt, props, risky)
# Line 13668  display_mode_element (it, depth, field_w Line 14926  display_mode_element (it, depth, field_w
14926        {        {
14927          /* A string: output it and check for %-constructs within it.  */          /* A string: output it and check for %-constructs within it.  */
14928          unsigned char c;          unsigned char c;
14929          unsigned char *this, *lisp_string;          const unsigned char *this, *lisp_string;
14930    
14931          if (!NILP (props) || risky)          if (!NILP (props) || risky)
14932            {            {
# Line 13730  display_mode_element (it, depth, field_w Line 14988  display_mode_element (it, depth, field_w
14988              prec = precision - n;              prec = precision - n;
14989              if (frame_title_ptr)              if (frame_title_ptr)
14990                n += store_frame_title (SDATA (elt), -1, prec);                n += store_frame_title (SDATA (elt), -1, prec);
14991                else if (!NILP (mode_line_string_list))
14992                  n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
14993              else              else
14994                n += display_string (NULL, elt, Qnil, 0, 0, it,                n += display_string (NULL, elt, Qnil, 0, 0, it,
14995                                     0, prec, 0, STRING_MULTIBYTE (elt));                                     0, prec, 0, STRING_MULTIBYTE (elt));
# Line 13740  display_mode_element (it, depth, field_w Line 15000  display_mode_element (it, depth, field_w
15000          while ((precision <= 0 || n < precision)          while ((precision <= 0 || n < precision)
15001                 && *this                 && *this
15002                 && (frame_title_ptr                 && (frame_title_ptr
15003                       || !NILP (mode_line_string_list)
15004                     || it->current_x < it->last_visible_x))                     || it->current_x < it->last_visible_x))
15005            {            {
15006              unsigned char *last = this;              const unsigned char *last = this;
15007    
15008              /* Advance to end of string or next format specifier.  */              /* Advance to end of string or next format specifier.  */
15009              while ((c = *this++) != '\0' && c != '%')              while ((c = *this++) != '\0' && c != '%')
# Line 13761  display_mode_element (it, depth, field_w Line 15022  display_mode_element (it, depth, field_w
15022    
15023                  if (frame_title_ptr)                  if (frame_title_ptr)
15024                    n += store_frame_title (last, 0, prec);                    n += store_frame_title (last, 0, prec);
15025                    else if (!NILP (mode_line_string_list))
15026                      {
15027                        int bytepos = last - lisp_string;
15028                        int charpos = string_byte_to_char (elt, bytepos);
15029                        n += store_mode_line_string (NULL,
15030                                                     Fsubstring (elt, make_number (charpos),
15031                                                                 make_number (charpos + prec)),
15032                                                     0, 0, 0, Qnil);
15033                      }
15034                  else                  else
15035                    {                    {
15036                      int bytepos = last - lisp_string;                      int bytepos = last - lisp_string;
# Line 13772  display_mode_element (it, depth, field_w Line 15042  display_mode_element (it, depth, field_w
15042                }                }
15043              else /* c == '%' */              else /* c == '%' */
15044                {                {
15045                  unsigned char *percent_position = this;                  const unsigned char *percent_position = this;
15046    
15047                  /* Get the specified minimum width.  Zero means                  /* Get the specified minimum width.  Zero means
15048                     don't pad.  */                     don't pad.  */
# Line 13807  display_mode_element (it, depth, field_w Line 15077  display_mode_element (it, depth, field_w
15077    
15078                      if (frame_title_ptr)                      if (frame_title_ptr)
15079                        n += store_frame_title (spec, field, prec);                        n += store_frame_title (spec, field, prec);
15080                        else if (!NILP (mode_line_string_list))
15081                          {
15082                            int len = strlen (spec);
15083                            Lisp_Object tem = make_string (spec, len);
15084                            props = Ftext_properties_at (make_number (charpos), elt);
15085                            /* Should only keep face property in props */
15086                            n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15087                          }
15088                      else                      else
15089                        {                        {
15090                          int nglyphs_before, nwritten;                          int nglyphs_before, nwritten;
# Line 13995  display_mode_element (it, depth, field_w Line 15273  display_mode_element (it, depth, field_w
15273      invalid:      invalid:
15274        if (frame_title_ptr)        if (frame_title_ptr)
15275          n += store_frame_title ("*invalid*", 0, precision - n);          n += store_frame_title ("*invalid*", 0, precision - n);
15276          else if (!NILP (mode_line_string_list))
15277            n += store_mode_line_string ("*invalid*", Qnil, 0, 0, precision - n, Qnil);
15278        else        else
15279          n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,          n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
15280                               precision - n, 0, 0);                               precision - n, 0, 0);
# Line 14006  display_mode_element (it, depth, field_w Line 15286  display_mode_element (it, depth, field_w
15286      {      {
15287        if (frame_title_ptr)        if (frame_title_ptr)
15288          n += store_frame_title ("", field_width - n, 0);          n += store_frame_title ("", field_width - n, 0);
15289          else if (!NILP (mode_line_string_list))
15290            n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15291        else        else
15292          n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,          n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15293                               0, 0, 0);                               0, 0, 0);
# Line 14014  display_mode_element (it, depth, field_w Line 15296  display_mode_element (it, depth, field_w
15296    return n;    return n;
15297  }  }
15298    
15299    /* Store a mode-line string element in mode_line_string_list.
15300    
15301       If STRING is non-null, display that C string.  Otherwise, the Lisp
15302       string LISP_STRING is displayed.
15303    
15304       FIELD_WIDTH is the minimum number of output glyphs to produce.
15305       If STRING has fewer characters than FIELD_WIDTH, pad to the right
15306       with spaces.  FIELD_WIDTH <= 0 means don't pad.
15307    
15308       PRECISION is the maximum number of characters to output from
15309       STRING.  PRECISION <= 0  means don't truncate the string.
15310    
15311       If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15312       properties to the string.
15313    
15314       PROPS are the properties to add to the string.
15315       The mode_line_string_face face property is always added to the string.
15316     */
15317    
15318    static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15319         char *string;
15320         Lisp_Object lisp_string;
15321         int copy_string;
15322         int field_width;
15323         int precision;
15324         Lisp_Object props;
15325    {
15326      int len;
15327      int n = 0;
15328    
15329      if (string != NULL)
15330        {
15331          len = strlen (string);
15332          if (precision > 0 && len > precision)
15333            len = precision;
15334          lisp_string = make_string (string, len);
15335          if (NILP (props))
15336            props = mode_line_string_face_prop;
15337          else if (!NILP (mode_line_string_face))
15338            {
15339              Lisp_Object face = Fplist_get (props, Qface);
15340              props = Fcopy_sequence (props);
15341              if (NILP (face))
15342                face = mode_line_string_face;
15343              else
15344                face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15345              props = Fplist_put (props, Qface, face);
15346            }
15347          Fadd_text_properties (make_number (0), make_number (len),
15348                                props, lisp_string);
15349        }
15350      else
15351        {
15352          len = XFASTINT (Flength (lisp_string));
15353          if (precision > 0 && len > precision)
15354            {
15355              len = precision;
15356              lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15357              precision = -1;
15358            }
15359          if (!NILP (mode_line_string_face))
15360            {
15361              Lisp_Object face;
15362              if (NILP (props))
15363                props = Ftext_properties_at (make_number (0), lisp_string);
15364              face = Fplist_get (props, Qface);
15365              if (NILP (face))
15366                face = mode_line_string_face;
15367              else
15368                face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15369              props = Fcons (Qface, Fcons (face, Qnil));
15370              if (copy_string)
15371                lisp_string = Fcopy_sequence (lisp_string);
15372            }
15373          if (!NILP (props))
15374            Fadd_text_properties (make_number (0), make_number (len),
15375                                  props, lisp_string);
15376        }
15377    
15378      if (len > 0)
15379        {
15380          mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15381          n += len;
15382        }
15383    
15384      if (field_width > len)
15385        {
15386          field_width -= len;
15387          lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15388          if (!NILP (props))
15389            Fadd_text_properties (make_number (0), make_number (field_width),
15390                                  props, lisp_string);
15391          mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15392          n += field_width;
15393        }
15394    
15395      return n;
15396    }
15397    
15398    
15399  DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,  DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15400         0, 2, 0,         0, 3, 0,
15401         doc: /* Return the mode-line of selected window as a string.         doc: /* Return the mode-line of selected window as a string.
15402  First optional arg FORMAT specifies a different format string (see  First optional arg FORMAT specifies a different format string (see
15403  `mode-line-format' for for details) to use.  If FORMAT is t, return  `mode-line-format' for details) to use.  If FORMAT is t, return
15404  the buffer's header-line.  Second optional arg WINDOW specifies a  the buffer's header-line.  Second optional arg WINDOW specifies a
15405  different window to use as the context for the formatting.  */)  different window to use as the context for the formatting.
15406       (format, window)  If third optional arg NO-PROPS is non-nil, string is not propertized.  */)
15407       Lisp_Object format, window;       (format, window, no_props)
15408         Lisp_Object format, window, no_props;
15409  {  {
15410    struct it it;    struct it it;
   struct face *face;  
15411    int len;    int len;
15412    struct window *w;    struct window *w;
15413    struct buffer *old_buffer = NULL;    struct buffer *old_buffer = NULL;
15414      enum face_id face_id = DEFAULT_FACE_ID;
15415    
15416    if (NILP (window))    if (NILP (window))
15417      window = selected_window;      window = selected_window;
# Line 14044  different window to use as the context f Line 15426  different window to use as the context f
15426      }      }
15427    
15428    if (NILP (format) || EQ (format, Qt))    if (NILP (format) || EQ (format, Qt))
15429      format = NILP (format)      {
15430        ? current_buffer->mode_line_format        face_id = NILP (format)
15431        : current_buffer->header_line_format;          ? CURRENT_MODE_LINE_FACE_ID (w) :
15432            HEADER_LINE_FACE_ID;
15433          format = NILP (format)
15434            ? current_buffer->mode_line_format
15435            : current_buffer->header_line_format;
15436        }
15437    
15438    init_iterator (&it, w, -1, -1, NULL, DEFAULT_FACE_ID);    init_iterator (&it, w, -1, -1, NULL, face_id);
15439    
15440    frame_title_ptr = frame_title_buf;    if (NILP (no_props))
15441        {
15442          mode_line_string_face =
15443            (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15444             face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15445             face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15446    
15447          mode_line_string_face_prop =
15448            NILP (mode_line_string_face) ? Qnil :
15449            Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15450    
15451          /* We need a dummy last element in mode_line_string_list to
15452             indicate we are building the propertized mode-line string.
15453             Using mode_line_string_face_prop here GC protects it.  */
15454          mode_line_string_list =
15455            Fcons (mode_line_string_face_prop, Qnil);
15456          frame_title_ptr = NULL;
15457        }
15458      else
15459        {
15460          mode_line_string_face_prop = Qnil;
15461          mode_line_string_list = Qnil;
15462          frame_title_ptr = frame_title_buf;
15463        }
15464    
15465    push_frame_kboard (it.f);    push_frame_kboard (it.f);
15466    display_mode_element (&it, 0, 0, 0, format, Qnil, 0);    display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
# Line 14059  different window to use as the context f Line 15469  different window to use as the context f
15469    if (old_buffer)    if (old_buffer)
15470      set_buffer_internal_1 (old_buffer);      set_buffer_internal_1 (old_buffer);
15471    
15472      if (NILP (no_props))
15473        {
15474          Lisp_Object str;
15475          mode_line_string_list = Fnreverse (mode_line_string_list);
15476          str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15477                            make_string ("", 0));
15478          mode_line_string_face_prop = Qnil;
15479          mode_line_string_list = Qnil;
15480          return str;
15481        }
15482    
15483    len = frame_title_ptr - frame_title_buf;    len = frame_title_ptr - frame_title_buf;
15484    if (len > 0 && frame_title_ptr[-1] == '-')    if (len > 0 && frame_title_ptr[-1] == '-')
15485      {      {
# Line 14121  decode_mode_spec_coding (coding_system, Line 15542  decode_mode_spec_coding (coding_system,
15542  {  {
15543    Lisp_Object val;    Lisp_Object val;
15544    int multibyte = !NILP (current_buffer->enable_multibyte_characters);    int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15545    unsigned char *eol_str;    const unsigned char *eol_str;
15546    int eol_str_len;    int eol_str_len;
15547    /* The EOL conversion we are using.  */    /* The EOL conversion we are using.  */
15548    Lisp_Object eoltype;    Lisp_Object eoltype;
# Line 14173  decode_mode_spec_coding (coding_system, Line 15594  decode_mode_spec_coding (coding_system,
15594        else if (INTEGERP (eoltype)        else if (INTEGERP (eoltype)
15595                 && CHAR_VALID_P (XINT (eoltype), 0))                 && CHAR_VALID_P (XINT (eoltype), 0))
15596          {          {
15597            eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);            unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15598            eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);            eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15599              eol_str = tmp;
15600          }          }
15601        else        else
15602          {          {
# Line 14270  decode_mode_spec (w, c, field_width, pre Line 15692  decode_mode_spec (w, c, field_width, pre
15692          register int i;          register int i;
15693    
15694          /* Let lots_of_dashes be a string of infinite length.  */          /* Let lots_of_dashes be a string of infinite length.  */
15695            if (!NILP (mode_line_string_list))
15696              return "--";
15697          if (field_width <= 0          if (field_width <= 0
15698              || field_width > sizeof (lots_of_dashes))              || field_width > sizeof (lots_of_dashes))
15699            {            {
# Line 14923  invisible_p (propval, list) Line 16347  invisible_p (propval, list)
16347    
16348    
16349  /***********************************************************************  /***********************************************************************
16350                                 Glyph Display
16351     ***********************************************************************/
16352    
16353    #ifdef HAVE_WINDOW_SYSTEM
16354    
16355    #if GLYPH_DEBUG
16356    
16357    void
16358    dump_glyph_string (s)
16359         struct glyph_string *s;
16360    {
16361      fprintf (stderr, "glyph string\n");
16362      fprintf (stderr, "  x, y, w, h = %d, %d, %d, %d\n",
16363               s->x, s->y, s->width, s->height);
16364      fprintf (stderr, "  ybase = %d\n", s->ybase);
16365      fprintf (stderr, "  hl = %d\n", s->hl);
16366      fprintf (stderr, "  left overhang = %d, right = %d\n",
16367               s->left_overhang, s->right_overhang);
16368      fprintf (stderr, "  nchars = %d\n", s->nchars);
16369      fprintf (stderr, "  extends to end of line = %d\n",
16370               s->extends_to_end_of_line_p);
16371      fprintf (stderr, "  font height = %d\n", FONT_HEIGHT (s->font));
16372      fprintf (stderr, "  bg width = %d\n", s->background_width);
16373    }
16374    
16375    #endif /* GLYPH_DEBUG */
16376    
16377    /* Initialize glyph string S.  CHAR2B is a suitably allocated vector
16378       of XChar2b structures for S; it can't be allocated in
16379       init_glyph_string because it must be allocated via `alloca'.  W
16380       is the window on which S is drawn.  ROW and AREA are the glyph row
16381       and area within the row from which S is constructed.  START is the
16382       index of the first glyph structure covered by S.  HL is a
16383       face-override for drawing S.  */
16384    
16385    #ifdef HAVE_NTGUI
16386    #define OPTIONAL_HDC(hdc)  hdc,
16387    #define DECLARE_HDC(hdc)   HDC hdc;
16388    #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16389    #define RELEASE_HDC(hdc, f)  release_frame_dc ((f), (hdc))
16390    #endif
16391    
16392    #ifndef OPTIONAL_HDC
16393    #define OPTIONAL_HDC(hdc)
16394    #define DECLARE_HDC(hdc)
16395    #define ALLOCATE_HDC(hdc, f)
16396    #define RELEASE_HDC(hdc, f)
16397    #endif
16398    
16399    static void
16400    init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16401         struct glyph_string *s;
16402         DECLARE_HDC (hdc)
16403         XChar2b *char2b;
16404         struct window *w;
16405         struct glyph_row *row;
16406         enum glyph_row_area area;
16407         int start;
16408         enum draw_glyphs_face hl;
16409    {
16410      bzero (s, sizeof *s);
16411      s->w = w;
16412      s->f = XFRAME (w->frame);
16413    #ifdef HAVE_NTGUI
16414      s->hdc = hdc;
16415    #endif
16416      s->display = FRAME_X_DISPLAY (s->f);
16417      s->window = FRAME_X_WINDOW (s->f);
16418      s->char2b = char2b;
16419      s->hl = hl;
16420      s->row = row;
16421      s->area = area;
16422      s->first_glyph = row->glyphs[area] + start;
16423      s->height = row->height;
16424      s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16425    
16426      /* Display the internal border below the tool-bar window.  */
16427      if (s->w == XWINDOW (s->f->tool_bar_window))
16428        s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16429    
16430      s->ybase = s->y + row->ascent;
16431    }
16432    
16433    
16434    /* Append the list of glyph strings with head H and tail T to the list
16435       with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the result.  */
16436    
16437    static INLINE void
16438    append_glyph_string_lists (head, tail, h, t)
16439         struct glyph_string **head, **tail;
16440         struct glyph_string *h, *t;
16441    {
16442      if (h)
16443        {
16444          if (*head)
16445            (*tail)->next = h;
16446          else
16447            *head = h;
16448          h->prev = *tail;
16449          *tail = t;
16450        }
16451    }
16452    
16453    
16454    /* Prepend the list of glyph strings with head H and tail T to the
16455       list with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the
16456       result.  */
16457    
16458    static INLINE void
16459    prepend_glyph_string_lists (head, tail, h, t)
16460         struct glyph_string **head, **tail;
16461         struct glyph_string *h, *t;
16462    {
16463      if (h)
16464        {
16465          if (*head)
16466            (*head)->prev = t;
16467          else
16468            *tail = t;
16469          t->next = *head;
16470          *head = h;
16471        }
16472    }
16473    
16474    
16475    /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16476       Set *HEAD and *TAIL to the resulting list.  */
16477    
16478    static INLINE void
16479    append_glyph_string (head, tail, s)
16480         struct glyph_string **head, **tail;
16481         struct glyph_string *s;
16482    {
16483      s->next = s->prev = NULL;
16484      append_glyph_string_lists (head, tail, s, s);
16485    }
16486    
16487    
16488    /* Get face and two-byte form of character glyph GLYPH on frame F.
16489       The encoding of GLYPH->u.ch is returned in *CHAR2B.  Value is
16490       a pointer to a realized face that is ready for display.  */
16491    
16492    static INLINE struct face *
16493    get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16494         struct frame *f;
16495         struct glyph *glyph;
16496         XChar2b *char2b;
16497         int *two_byte_p;
16498    {
16499      struct face *face;
16500    
16501      xassert (glyph->type == CHAR_GLYPH);
16502      face = FACE_FROM_ID (f, glyph->face_id);
16503    
16504      if (two_byte_p)
16505        *two_byte_p = 0;
16506    
16507      if (!glyph->multibyte_p)
16508        {
16509          /* Unibyte case.  We don't have to encode, but we have to make
16510             sure to use a face suitable for unibyte.  */
16511          STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16512        }
16513      else if (glyph->u.ch < 128
16514               && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16515        {
16516          /* Case of ASCII in a face known to fit ASCII.  */
16517          STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16518        }
16519      else
16520        {
16521          int c1, c2, charset;
16522    
16523          /* Split characters into bytes.  If c2 is -1 afterwards, C is
16524             really a one-byte character so that byte1 is zero.  */
16525          SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16526          if (c2 > 0)
16527            STORE_XCHAR2B (char2b, c1, c2);
16528          else
16529            STORE_XCHAR2B (char2b, 0, c1);
16530    
16531          /* Maybe encode the character in *CHAR2B.  */
16532          if (charset != CHARSET_ASCII)
16533            {
16534              struct font_info *font_info
16535                = FONT_INFO_FROM_ID (f, face->font_info_id);
16536              if (font_info)
16537                glyph->font_type
16538                  = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16539            }
16540        }
16541    
16542      /* Make sure X resources of the face are allocated.  */
16543      xassert (face != NULL);
16544      PREPARE_FACE_FOR_DISPLAY (f, face);
16545      return face;
16546    }
16547    
16548    
16549    /* Fill glyph string S with composition components specified by S->cmp.
16550    
16551       FACES is an array of faces for all components of this composition.
16552       S->gidx is the index of the first component for S.
16553       OVERLAPS_P non-zero means S should draw the foreground only, and
16554       use its physical height for clipping.
16555    
16556       Value is the index of a component not in S.  */
16557    
16558    static int
16559    fill_composite_glyph_string (s, faces, overlaps_p)
16560         struct glyph_string *s;
16561         struct face **faces;
16562         int overlaps_p;
16563    {
16564      int i;
16565    
16566      xassert (s);
16567    
16568      s->for_overlaps_p = overlaps_p;
16569    
16570      s->face = faces[s->gidx];
16571      s->font = s->face->font;
16572      s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16573    
16574      /* For all glyphs of this composition, starting at the offset
16575         S->gidx, until we reach the end of the definition or encounter a
16576         glyph that requires the different face, add it to S.  */
16577      ++s->nchars;
16578      for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16579        ++s->nchars;
16580    
16581      /* All glyph strings for the same composition has the same width,
16582         i.e. the width set for the first component of the composition.  */
16583    
16584      s->width = s->first_glyph->pixel_width;
16585    
16586      /* If the specified font could not be loaded, use the frame's
16587         default font, but record the fact that we couldn't load it in
16588         the glyph string so that we can draw rectangles for the
16589         characters of the glyph string.  */
16590      if (s->font == NULL)
16591        {
16592          s->font_not_found_p = 1;
16593          s->font = FRAME_FONT (s->f);
16594        }
16595    
16596      /* Adjust base line for subscript/superscript text.  */
16597      s->ybase += s->first_glyph->voffset;
16598    
16599      xassert (s->face && s->face->gc);
16600    
16601      /* This glyph string must always be drawn with 16-bit functions.  */
16602      s->two_byte_p = 1;
16603    
16604      return s->gidx + s->nchars;
16605    }
16606    
16607    
16608    /* Fill glyph string S from a sequence of character glyphs.
16609    
16610       FACE_ID is the face id of the string.  START is the index of the
16611       first glyph to consider, END is the index of the last + 1.
16612       OVERLAPS_P non-zero means S should draw the foreground only, and
16613       use its physical height for clipping.
16614    
16615       Value is the index of the first glyph not in S.  */
16616    
16617    static int
16618    fill_glyph_string (s, face_id, start, end, overlaps_p)
16619         struct glyph_string *s;
16620         int face_id;
16621         int start, end, overlaps_p;
16622    {
16623      struct glyph *glyph, *last;
16624      int voffset;
16625      int glyph_not_available_p;
16626    
16627      xassert (s->f == XFRAME (s->w->frame));
16628      xassert (s->nchars == 0);
16629      xassert (start >= 0 && end > start);
16630    
16631      s->for_overlaps_p = overlaps_p,
16632      glyph = s->row->glyphs[s->area] + start;
16633      last = s->row->glyphs[s->area] + end;
16634      voffset = glyph->voffset;
16635    
16636      glyph_not_available_p = glyph->glyph_not_available_p;
16637    
16638      while (glyph < last
16639             && glyph->type == CHAR_GLYPH
16640             && glyph->voffset == voffset
16641             /* Same face id implies same font, nowadays.  */
16642             && glyph->face_id == face_id
16643             && glyph->glyph_not_available_p == glyph_not_available_p)
16644        {
16645          int two_byte_p;
16646    
16647          s->face = get_glyph_face_and_encoding (s->f, glyph,
16648                                                   s->char2b + s->nchars,
16649                                                   &two_byte_p);
16650          s->two_byte_p = two_byte_p;
16651          ++s->nchars;
16652          xassert (s->nchars <= end - start);
16653          s->width += glyph->pixel_width;
16654          ++glyph;
16655        }
16656    
16657      s->font = s->face->font;
16658      s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16659    
16660      /* If the specified font could not be loaded, use the frame's font,
16661         but record the fact that we couldn't load it in
16662         S->font_not_found_p so that we can draw rectangles for the
16663         characters of the glyph string.  */
16664      if (s->font == NULL || glyph_not_available_p)
16665        {
16666          s->font_not_found_p = 1;
16667          s->font = FRAME_FONT (s->f);
16668        }
16669    
16670      /* Adjust base line for subscript/superscript text.  */
16671      s->ybase += voffset;
16672    
16673      xassert (s->face && s->face->gc);
16674      return glyph - s->row->glyphs[s->area];
16675    }
16676    
16677    
16678    /* Fill glyph string S from image glyph S->first_glyph.  */
16679    
16680    static void
16681    fill_image_glyph_string (s)
16682         struct glyph_string *s;
16683    {
16684      xassert (s->first_glyph->type == IMAGE_GLYPH);
16685      s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16686      xassert (s->img);
16687      s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16688      s->font = s->face->font;
16689      s->width = s->first_glyph->pixel_width;
16690    
16691      /* Adjust base line for subscript/superscript text.  */
16692      s->ybase += s->first_glyph->voffset;
16693    }
16694    
16695    
16696    /* Fill glyph string S from a sequence of stretch glyphs.
16697    
16698       ROW is the glyph row in which the glyphs are found, AREA is the
16699       area within the row.  START is the index of the first glyph to
16700       consider, END is the index of the last + 1.
16701    
16702       Value is the index of the first glyph not in S.  */
16703    
16704    static int
16705    fill_stretch_glyph_string (s, row, area, start, end)
16706         struct glyph_string *s;
16707         struct glyph_row *row;
16708         enum glyph_row_area area;
16709         int start, end;
16710    {
16711      struct glyph *glyph, *last;
16712      int voffset, face_id;
16713    
16714      xassert (s->first_glyph->type == STRETCH_GLYPH);
16715    
16716      glyph = s->row->glyphs[s->area] + start;
16717      last = s->row->glyphs[s->area] + end;
16718      face_id = glyph->face_id;
16719      s->face = FACE_FROM_ID (s->f, face_id);
16720      s->font = s->face->font;
16721      s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16722      s->width = glyph->pixel_width;
16723      voffset = glyph->voffset;
16724    
16725      for (++glyph;
16726           (glyph < last
16727            && glyph->type == STRETCH_GLYPH
16728            && glyph->voffset == voffset
16729            && glyph->face_id == face_id);
16730           ++glyph)
16731        s->width += glyph->pixel_width;
16732    
16733      /* Adjust base line for subscript/superscript text.  */
16734      s->ybase += voffset;
16735    
16736      /* The case that face->gc == 0 is handled when drawing the glyph
16737         string by calling PREPARE_FACE_FOR_DISPLAY.  */
16738      xassert (s->face);
16739      return glyph - s->row->glyphs[s->area];
16740    }
16741    
16742    
16743    /* EXPORT for RIF:
16744       Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16745       frame F.  Overhangs of glyphs other than type CHAR_GLYPH are
16746       assumed to be zero.  */
16747    
16748    void
16749    x_get_glyph_overhangs (glyph, f, left, right)
16750         struct glyph *glyph;
16751         struct frame *f;
16752         int *left, *right;
16753    {
16754      *left = *right = 0;
16755    
16756      if (glyph->type == CHAR_GLYPH)
16757        {
16758          XFontStruct *font;
16759          struct face *face;
16760          struct font_info *font_info;
16761          XChar2b char2b;
16762          XCharStruct *pcm;
16763    
16764          face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
16765          font = face->font;
16766          font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
16767          if (font  /* ++KFS: Should this be font_info ?  */
16768              && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
16769            {
16770              if (pcm->rbearing > pcm->width)
16771                *right = pcm->rbearing - pcm->width;
16772              if (pcm->lbearing < 0)
16773                *left = -pcm->lbearing;
16774            }
16775        }
16776    }
16777    
16778    
16779    /* Return the index of the first glyph preceding glyph string S that
16780       is overwritten by S because of S's left overhang.  Value is -1
16781       if no glyphs are overwritten.  */
16782    
16783    static int
16784    left_overwritten (s)
16785         struct glyph_string *s;
16786    {
16787      int k;
16788    
16789      if (s->left_overhang)
16790        {
16791          int x = 0, i;
16792          struct glyph *glyphs = s->row->glyphs[s->area];
16793          int first = s->first_glyph - glyphs;
16794    
16795          for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
16796            x -= glyphs[i].pixel_width;
16797    
16798          k = i + 1;
16799        }
16800      else
16801        k = -1;
16802    
16803      return k;
16804    }
16805    
16806    
16807    /* Return the index of the first glyph preceding glyph string S that
16808       is overwriting S because of its right overhang.  Value is -1 if no
16809       glyph in front of S overwrites S.  */
16810    
16811    static int
16812    left_overwriting (s)
16813         struct glyph_string *s;
16814    {
16815      int i, k, x;
16816      struct glyph *glyphs = s->row->glyphs[s->area];
16817      int first = s->first_glyph - glyphs;
16818    
16819      k = -1;
16820      x = 0;
16821      for (i = first - 1; i >= 0; --i)
16822        {
16823          int left, right;
16824          x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16825          if (x + right > 0)
16826            k = i;
16827          x -= glyphs[i].pixel_width;
16828        }
16829    
16830      return k;
16831    }
16832    
16833    
16834    /* Return the index of the last glyph following glyph string S that is
16835       not overwritten by S because of S's right overhang.  Value is -1 if
16836       no such glyph is found.  */
16837    
16838    static int
16839    right_overwritten (s)
16840         struct glyph_string *s;
16841    {
16842      int k = -1;
16843    
16844      if (s->right_overhang)
16845        {
16846          int x = 0, i;
16847          struct glyph *glyphs = s->row->glyphs[s->area];
16848          int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
16849          int end = s->row->used[s->area];
16850    
16851          for (i = first; i < end && s->right_overhang > x; ++i)
16852            x += glyphs[i].pixel_width;
16853    
16854          k = i;
16855        }
16856    
16857      return k;
16858    }
16859    
16860    
16861    /* Return the index of the last glyph following glyph string S that
16862       overwrites S because of its left overhang.  Value is negative
16863       if no such glyph is found.  */
16864    
16865    static int
16866    right_overwriting (s)
16867         struct glyph_string *s;
16868    {
16869      int i, k, x;
16870      int end = s->row->used[s->area];
16871      struct glyph *glyphs = s->row->glyphs[s->area];
16872      int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
16873    
16874      k = -1;
16875      x = 0;
16876      for (i = first; i < end; ++i)
16877        {
16878          int left, right;
16879          x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16880          if (x - left < 0)
16881            k = i;
16882          x += glyphs[i].pixel_width;
16883        }
16884    
16885      return k;
16886    }
16887    
16888    
16889    /* Get face and two-byte form of character C in face FACE_ID on frame
16890       F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
16891       means we want to display multibyte text.  DISPLAY_P non-zero means
16892       make sure that X resources for the face returned are allocated.
16893       Value is a pointer to a realized face that is ready for display if
16894       DISPLAY_P is non-zero.  */
16895    
16896    static INLINE struct face *
16897    get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
16898         struct frame *f;
16899         int c, face_id;
16900         XChar2b *char2b;
16901         int multibyte_p, display_p;
16902    {
16903      struct face *face = FACE_FROM_ID (f, face_id);
16904    
16905      if (!multibyte_p)
16906        {
16907          /* Unibyte case.  We don't have to encode, but we have to make
16908             sure to use a face suitable for unibyte.  */
16909          STORE_XCHAR2B (char2b, 0, c);
16910          face_id = FACE_FOR_CHAR (f, face, c);
16911          face = FACE_FROM_ID (f, face_id);
16912        }
16913      else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
16914        {
16915          /* Case of ASCII in a face known to fit ASCII.  */
16916          STORE_XCHAR2B (char2b, 0, c);
16917        }
16918      else
16919        {
16920          int c1, c2, charset;
16921    
16922          /* Split characters into bytes.  If c2 is -1 afterwards, C is
16923             really a one-byte character so that byte1 is zero.  */
16924          SPLIT_CHAR (c, charset, c1, c2);
16925          if (c2 > 0)
16926            STORE_XCHAR2B (char2b, c1, c2);
16927          else
16928            STORE_XCHAR2B (char2b, 0, c1);
16929    
16930          /* Maybe encode the character in *CHAR2B.  */
16931          if (face->font != NULL)
16932            {
16933              struct font_info *font_info
16934                = FONT_INFO_FROM_ID (f, face->font_info_id);
16935              if (font_info)
16936                rif->encode_char (c, char2b, font_info, 0);
16937            }
16938        }
16939    
16940      /* Make sure X resources of the face are allocated.  */
16941    #ifdef HAVE_X_WINDOWS
16942      if (display_p)
16943    #endif
16944        {
16945          xassert (face != NULL);
16946          PREPARE_FACE_FOR_DISPLAY (f, face);
16947        }
16948    
16949      return face;
16950    }
16951    
16952    
16953    /* Set background width of glyph string S.  START is the index of the
16954       first glyph following S.  LAST_X is the right-most x-position + 1
16955       in the drawing area.  */
16956    
16957    static INLINE void
16958    set_glyph_string_background_width (s, start, last_x)
16959         struct glyph_string *s;
16960         int start;
16961         int last_x;
16962    {
16963      /* If the face of this glyph string has to be drawn to the end of
16964         the drawing area, set S->extends_to_end_of_line_p.  */
16965      struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
16966    
16967      if (start == s->row->used[s->area]
16968          && s->area == TEXT_AREA
16969          && ((s->hl == DRAW_NORMAL_TEXT
16970               && (s->row->fill_line_p
16971                   || s->face->background != default_face->background
16972                   || s->face->stipple != default_face->stipple
16973                   || s->row->mouse_face_p))
16974              || s->hl == DRAW_MOUSE_FACE
16975              || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
16976                  && s->row->fill_line_p)))
16977          s->extends_to_end_of_line_p = 1;
16978    
16979      /* If S extends its face to the end of the line, set its
16980         background_width to the distance to the right edge of the drawing
16981         area.  */
16982      if (s->extends_to_end_of_line_p)
16983        s->background_width = last_x - s->x + 1;
16984      else
16985        s->background_width = s->width;
16986    }
16987    
16988    
16989    /* Compute overhangs and x-positions for glyph string S and its
16990       predecessors, or successors.  X is the starting x-position for S.
16991       BACKWARD_P non-zero means process predecessors.  */
16992    
16993    static void
16994    compute_overhangs_and_x (s, x, backward_p)
16995         struct glyph_string *s;
16996         int x;
16997         int backward_p;
16998    {
16999      if (backward_p)
17000        {
17001          while (s)
17002            {
17003              if (rif->compute_glyph_string_overhangs)
17004                rif->compute_glyph_string_overhangs (s);
17005              x -= s->width;
17006              s->x = x;
17007              s = s->prev;
17008            }
17009        }
17010      else
17011        {
17012          while (s)
17013            {
17014              if (rif->compute_glyph_string_overhangs)
17015                rif->compute_glyph_string_overhangs (s);
17016              s->x = x;
17017              x += s->width;
17018              s = s->next;
17019            }
17020        }
17021    }
17022    
17023    
17024    
17025    /* The following macros are only called from draw_glyphs below.
17026       They reference the following parameters of that function directly:
17027         `w', `row', `area', and `overlap_p'
17028       as well as the following local variables:
17029         `s', `f', and `hdc' (in W32)  */
17030    
17031    #ifdef HAVE_NTGUI
17032    /* On W32, silently add local `hdc' variable to argument list of
17033       init_glyph_string.  */
17034    #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17035      init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17036    #else
17037    #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17038      init_glyph_string (s, char2b, w, row, area, start, hl)
17039    #endif
17040    
17041    /* Add a glyph string for a stretch glyph to the list of strings
17042       between HEAD and TAIL.  START is the index of the stretch glyph in
17043       row area AREA of glyph row ROW.  END is the index of the last glyph
17044       in that glyph row area.  X is the current output position assigned
17045       to the new glyph string constructed.  HL overrides that face of the
17046       glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn.  LAST_X
17047       is the right-most x-position of the drawing area.  */
17048    
17049    /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17050       and below -- keep them on one line.  */
17051    #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X)   \
17052         do                                                                     \
17053           {                                                                    \
17054             s = (struct glyph_string *) alloca (sizeof *s);                    \
17055             INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);              \
17056             START = fill_stretch_glyph_string (s, row, area, START, END);      \
17057             append_glyph_string (&HEAD, &TAIL, s);                             \
17058             s->x = (X);                                                        \
17059           }                                                                    \
17060         while (0)
17061    
17062    
17063    /* Add a glyph string for an image glyph to the list of strings
17064       between HEAD and TAIL.  START is the index of the image glyph in
17065       row area AREA of glyph row ROW.  END is the index of the last glyph
17066       in that glyph row area.  X is the current output position assigned
17067       to the new glyph string constructed.  HL overrides that face of the
17068       glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn.  LAST_X
17069       is the right-most x-position of the drawing area.  */
17070    
17071    #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17072         do                                                                 \
17073           {                                                                \
17074             s = (struct glyph_string *) alloca (sizeof *s);                \
17075             INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);          \
17076             fill_image_glyph_string (s);                                   \
17077             append_glyph_string (&HEAD, &TAIL, s);                         \
17078             ++START;                                                       \
17079             s->x = (X);                                                    \
17080           }                                                                \
17081         while (0)
17082    
17083    
17084    /* Add a glyph string for a sequence of character glyphs to the list
17085       of strings between HEAD and TAIL.  START is the index of the first
17086       glyph in row area AREA of glyph row ROW that is part of the new
17087       glyph string.  END is the index of the last glyph in that glyph row
17088       area.  X is the current output position assigned to the new glyph
17089       string constructed.  HL overrides that face of the glyph; e.g. it
17090       is DRAW_CURSOR if a cursor has to be drawn.  LAST_X is the
17091       right-most x-position of the drawing area.  */
17092    
17093    #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)    \
17094         do                                                                    \
17095           {                                                                   \
17096             int c, face_id;                                                   \
17097             XChar2b *char2b;                                                  \
17098                                                                               \
17099             c = (row)->glyphs[area][START].u.ch;                              \
17100             face_id = (row)->glyphs[area][START].face_id;                     \
17101                                                                               \
17102             s = (struct glyph_string *) alloca (sizeof *s);                   \
17103             char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b);     \
17104             INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);           \
17105             append_glyph_string (&HEAD, &TAIL, s);                            \
17106             s->x = (X);                                                       \
17107             START = fill_glyph_string (s, face_id, START, END, overlaps_p);   \
17108           }                                                                   \
17109         while (0)
17110    
17111    
17112    /* Add a glyph string for a composite sequence to the list of strings
17113       between HEAD and TAIL.  START is the index of the first glyph in
17114       row area AREA of glyph row ROW that is part of the new glyph
17115       string.  END is the index of the last glyph in that glyph row area.
17116       X is the current output position assigned to the new glyph string
17117       constructed.  HL overrides that face of the glyph; e.g. it is
17118       DRAW_CURSOR if a cursor has to be drawn.  LAST_X is the right-most
17119       x-position of the drawing area.  */
17120    
17121    #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17122      do {                                                                    \
17123        int cmp_id = (row)->glyphs[area][START].u.cmp_id;                     \
17124        int face_id = (row)->glyphs[area][START].face_id;                     \
17125        struct face *base_face = FACE_FROM_ID (f, face_id);                   \
17126        struct composition *cmp = composition_table[cmp_id];                  \
17127        int glyph_len = cmp->glyph_len;                                       \
17128        XChar2b *char2b;                                                      \
17129        struct face **faces;                                                  \
17130        struct glyph_string *first_s = NULL;                                  \
17131        int n;                                                                \
17132                                                                              \
17133        base_face = base_face->ascii_face;                                    \
17134        char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);           \
17135        faces = (struct face **) alloca ((sizeof *faces) * glyph_len);        \
17136        /* At first, fill in `char2b' and `faces'.  */                        \
17137        for (n = 0; n < glyph_len; n++)                                       \
17138          {                                                                   \
17139            int c = COMPOSITION_GLYPH (cmp, n);                               \
17140            int this_face_id = FACE_FOR_CHAR (f, base_face, c);               \
17141            faces[n] = FACE_FROM_ID (f, this_face_id);                        \
17142            get_char_face_and_encoding (f, c, this_face_id,                   \
17143                                        char2b + n, 1, 1);                    \
17144          }                                                                   \
17145                                                                              \
17146        /* Make glyph_strings for each glyph sequence that is drawable by     \
17147           the same face, and append them to HEAD/TAIL.  */                   \
17148        for (n = 0; n < cmp->glyph_len;)                                      \
17149          {                                                                   \
17150            s = (struct glyph_string *) alloca (sizeof *s);                   \
17151            INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL);       \
17152            append_glyph_string (&(HEAD), &(TAIL), s);                        \
17153            s->cmp = cmp;                                                     \
17154            s->gidx = n;                                                      \
17155            s->x = (X);                                                       \
17156                                                                              \
17157            if (n == 0)                                                       \
17158              first_s = s;                                                    \
17159                                                                              \
17160            n = fill_composite_glyph_string (s, faces, overlaps_p);           \
17161          }                                                                   \
17162                                                                              \
17163        ++START;                                                              \
17164        s = first_s;                                                          \
17165      } while (0)
17166    
17167    
17168    /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17169       of AREA of glyph row ROW on window W between indices START and END.
17170       HL overrides the face for drawing glyph strings, e.g. it is
17171       DRAW_CURSOR to draw a cursor.  X and LAST_X are start and end
17172       x-positions of the drawing area.
17173    
17174       This is an ugly monster macro construct because we must use alloca
17175       to allocate glyph strings (because draw_glyphs can be called
17176       asynchronously).  */
17177    
17178    #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)         \
17179         do                                                                    \
17180           {                                                                   \
17181             HEAD = TAIL = NULL;                                               \
17182             while (START < END)                                               \
17183               {                                                               \
17184                 struct glyph *first_glyph = (row)->glyphs[area] + START;      \
17185                 switch (first_glyph->type)                                    \
17186                   {                                                           \
17187                   case CHAR_GLYPH:                                            \
17188                     BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL,         \
17189                                               HL, X, LAST_X);                 \
17190                     break;                                                    \
17191                                                                               \
17192                   case COMPOSITE_GLYPH:                                       \
17193                     BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL,     \
17194                                                   HL, X, LAST_X);             \
17195                     break;                                                    \
17196                                                                               \
17197                   case STRETCH_GLYPH:                                         \
17198                     BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL,       \
17199                                                 HL, X, LAST_X);               \
17200                     break;                                                    \
17201                                                                               \
17202                   case IMAGE_GLYPH:                                           \
17203                     BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL,         \
17204                                               HL, X, LAST_X);                 \
17205                     break;                                                    \
17206                                                                               \
17207                   default:                                                    \
17208                     abort ();                                                 \
17209                   }                                                           \
17210                                                                               \
17211                 set_glyph_string_background_width (s, START, LAST_X);         \
17212                 (X) += s->width;                                              \
17213                }                                                              \
17214           }                                                                   \
17215         while (0)
17216    
17217    
17218    /* Draw glyphs between START and END in AREA of ROW on window W,
17219       starting at x-position X.  X is relative to AREA in W.  HL is a
17220       face-override with the following meaning:
17221    
17222       DRAW_NORMAL_TEXT     draw normally
17223       DRAW_CURSOR          draw in cursor face
17224       DRAW_MOUSE_FACE      draw in mouse face.
17225       DRAW_INVERSE_VIDEO   draw in mode line face
17226       DRAW_IMAGE_SUNKEN    draw an image with a sunken relief around it
17227       DRAW_IMAGE_RAISED    draw an image with a raised relief around it
17228    
17229       If OVERLAPS_P is non-zero, draw only the foreground of characters
17230       and clip to the physical height of ROW.
17231    
17232       Value is the x-position reached, relative to AREA of W.  */
17233    
17234    static int
17235    draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17236         struct window *w;
17237         int x;
17238         struct glyph_row *row;
17239         enum glyph_row_area area;
17240         int start, end;
17241         enum draw_glyphs_face hl;
17242         int overlaps_p;
17243    {
17244      struct glyph_string *head, *tail;
17245      struct glyph_string *s;
17246      int last_x, area_width;
17247      int x_reached;
17248      int i, j;
17249      struct frame *f = XFRAME (WINDOW_FRAME (w));
17250      DECLARE_HDC (hdc);
17251    
17252      ALLOCATE_HDC (hdc, f);
17253    
17254      /* Let's rather be paranoid than getting a SEGV.  */
17255      end = min (end, row->used[area]);
17256      start = max (0, start);
17257      start = min (end, start);
17258    
17259      /* Translate X to frame coordinates.  Set last_x to the right
17260         end of the drawing area.  */
17261      if (row->full_width_p)
17262        {
17263          /* X is relative to the left edge of W, without scroll bars
17264             or fringes.  */
17265          int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
17266    
17267          x += window_left_x;
17268          area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
17269          last_x = window_left_x + area_width;
17270    
17271          if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
17272            {
17273              int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
17274              if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
17275                last_x += width;
17276              else
17277                x -= width;
17278            }
17279    
17280          x += FRAME_INTERNAL_BORDER_WIDTH (f);
17281          /* ++KFS: W32 and MAC versions had -= in next line (bug??)  */
17282          last_x += FRAME_INTERNAL_BORDER_WIDTH (f);
17283        }
17284      else
17285        {
17286          x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
17287          area_width = window_box_width (w, area);
17288          last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
17289        }
17290    
17291      /* Build a doubly-linked list of glyph_string structures between
17292         head and tail from what we have to draw.  Note that the macro
17293         BUILD_GLYPH_STRINGS will modify its start parameter.  That's
17294         the reason we use a separate variable `i'.  */
17295      i = start;
17296      BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17297      if (tail)
17298        x_reached = tail->x + tail->background_width;
17299      else
17300        x_reached = x;
17301    
17302      /* If there are any glyphs with lbearing < 0 or rbearing > width in
17303         the row, redraw some glyphs in front or following the glyph
17304         strings built above.  */
17305      if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17306        {
17307          int dummy_x = 0;
17308          struct glyph_string *h, *t;
17309    
17310          /* Compute overhangs for all glyph strings.  */
17311          if (rif->compute_glyph_string_overhangs)
17312            for (s = head; s; s = s->next)
17313              rif->compute_glyph_string_overhangs (s);
17314    
17315          /* Prepend glyph strings for glyphs in front of the first glyph
17316             string that are overwritten because of the first glyph
17317             string's left overhang.  The background of all strings
17318             prepended must be drawn because the first glyph string
17319             draws over it.  */
17320          i = left_overwritten (head);
17321          if (i >= 0)
17322            {
17323              j = i;
17324              BUILD_GLYPH_STRINGS (j, start, h, t,
17325                                   DRAW_NORMAL_TEXT, dummy_x, last_x);
17326              start = i;
17327              compute_overhangs_and_x (t, head->x, 1);
17328              prepend_glyph_string_lists (&head, &tail, h, t);
17329            }
17330    
17331          /* Prepend glyph strings for glyphs in front of the first glyph
17332             string that overwrite that glyph string because of their
17333             right overhang.  For these strings, only the foreground must
17334             be drawn, because it draws over the glyph string at `head'.
17335             The background must not be drawn because this would overwrite
17336             right overhangs of preceding glyphs for which no glyph
17337             strings exist.  */
17338          i = left_overwriting (head);
17339          if (i >= 0)
17340            {
17341              BUILD_GLYPH_STRINGS (i, start, h, t,
17342                                   DRAW_NORMAL_TEXT, dummy_x, last_x);
17343              for (s = h; s; s = s->next)
17344                s->background_filled_p = 1;
17345              compute_overhangs_and_x (t, head->x, 1);
17346              prepend_glyph_string_lists (&head, &tail, h, t);
17347            }
17348    
17349          /* Append glyphs strings for glyphs following the last glyph
17350             string tail that are overwritten by tail.  The background of
17351             these strings has to be drawn because tail's foreground draws
17352             over it.  */
17353          i = right_overwritten (tail);
17354          if (i >= 0)
17355            {
17356              BUILD_GLYPH_STRINGS (end, i, h, t,
17357                                   DRAW_NORMAL_TEXT, x, last_x);
17358              compute_overhangs_and_x (h, tail->x + tail->width, 0);
17359              append_glyph_string_lists (&head, &tail, h, t);
17360            }
17361    
17362          /* Append glyph strings for glyphs following the last glyph
17363             string tail that overwrite tail.  The foreground of such
17364             glyphs has to be drawn because it writes into the background
17365             of tail.  The background must not be drawn because it could
17366             paint over the foreground of following glyphs.  */
17367          i = right_overwriting (tail);
17368          if (i >= 0)
17369            {
17370              BUILD_GLYPH_STRINGS (end, i, h, t,
17371                                   DRAW_NORMAL_TEXT, x, last_x);
17372              for (s = h; s; s = s->next)
17373                s->background_filled_p = 1;
17374              compute_overhangs_and_x (h, tail->x + tail->width, 0);
17375              append_glyph_string_lists (&head, &tail, h, t);
17376            }
17377        }
17378    
17379      /* Draw all strings.  */
17380      for (s = head; s; s = s->next)
17381        rif->draw_glyph_string (s);
17382    
17383      if (area == TEXT_AREA
17384          && !row->full_width_p
17385          /* When drawing overlapping rows, only the glyph strings'
17386             foreground is drawn, which doesn't erase a cursor
17387             completely. */
17388          && !overlaps_p)
17389        {
17390          int x0 = head ? head->x : x;
17391          int x1 = tail ? tail->x + tail->background_width : x;
17392    
17393          x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
17394          x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
17395    
17396          /* ++KFS: W32 and MAC versions had following test here:
17397             if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
17398          */
17399    
17400          if (XFASTINT (w->left_margin_width) != 0)
17401            {
17402              int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
17403              x0 -= left_area_width;
17404              x1 -= left_area_width;
17405            }
17406    
17407          notice_overwritten_cursor (w, area, x0, x1,
17408                                     row->y, MATRIX_ROW_BOTTOM_Y (row));
17409        }
17410    
17411      /* Value is the x-position up to which drawn, relative to AREA of W.
17412         This doesn't include parts drawn because of overhangs.  */
17413      x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17414      if (!row->full_width_p)
17415        {
17416          /* ++KFS: W32 and MAC versions only had this test here:
17417             if (area > LEFT_MARGIN_AREA)
17418          */
17419    
17420          if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0)
17421            x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
17422          if (area > TEXT_AREA)
17423            x_reached -= window_box_width (w, TEXT_AREA);
17424        }
17425    
17426      RELEASE_HDC (hdc, f);
17427    
17428      return x_reached;
17429    }
17430    
17431    
17432    /* Store one glyph for IT->char_to_display in IT->glyph_row.
17433       Called from x_produce_glyphs when IT->glyph_row is non-null.  */
17434    
17435    static INLINE void
17436    append_glyph (it)
17437         struct it *it;
17438    {
17439      struct glyph *glyph;
17440      enum glyph_row_area area = it->area;
17441    
17442      xassert (it->glyph_row);
17443      xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17444    
17445      glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17446      if (glyph < it->glyph_row->glyphs[area + 1])
17447        {
17448          glyph->charpos = CHARPOS (it->position);
17449          glyph->object = it->object;
17450          glyph->pixel_width = it->pixel_width;
17451          glyph->voffset = it->voffset;
17452          glyph->type = CHAR_GLYPH;
17453          glyph->multibyte_p = it->multibyte_p;
17454          glyph->left_box_line_p = it->start_of_box_run_p;
17455          glyph->right_box_line_p = it->end_of_box_run_p;
17456          glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17457                                          || it->phys_descent > it->descent);
17458          glyph->padding_p = 0;
17459          glyph->glyph_not_available_p = it->glyph_not_available_p;
17460          glyph->face_id = it->face_id;
17461          glyph->u.ch = it->char_to_display;
17462          glyph->font_type = FONT_TYPE_UNKNOWN;
17463          ++it->glyph_row->used[area];
17464        }
17465    }
17466    
17467    /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17468       Called from x_produce_glyphs when IT->glyph_row is non-null.  */
17469    
17470    static INLINE void
17471    append_composite_glyph (it)
17472         struct it *it;
17473    {
17474      struct glyph *glyph;
17475      enum glyph_row_area area = it->area;
17476    
17477      xassert (it->glyph_row);
17478    
17479      glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17480      if (glyph < it->glyph_row->glyphs[area + 1])
17481        {
17482          glyph->charpos = CHARPOS (it->position);
17483          glyph->object = it->object;
17484          glyph->pixel_width = it->pixel_width;
17485          glyph->voffset = it->voffset;
17486          glyph->type = COMPOSITE_GLYPH;
17487          glyph->multibyte_p = it->multibyte_p;
17488          glyph->left_box_line_p = it->start_of_box_run_p;
17489          glyph->right_box_line_p = it->end_of_box_run_p;
17490          glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17491                                          || it->phys_descent > it->descent);
17492          glyph->padding_p = 0;
17493          glyph->glyph_not_available_p = 0;
17494          glyph->face_id = it->face_id;
17495          glyph->u.cmp_id = it->cmp_id;
17496          glyph->font_type = FONT_TYPE_UNKNOWN;
17497          ++it->glyph_row->used[area];
17498        }
17499    }
17500    
17501    
17502    /* Change IT->ascent and IT->height according to the setting of
17503       IT->voffset.  */
17504    
17505    static INLINE void
17506    take_vertical_position_into_account (it)
17507         struct it *it;
17508    {
17509      if (it->voffset)
17510        {
17511          if (it->voffset < 0)
17512            /* Increase the ascent so that we can display the text higher
17513               in the line.  */
17514            it->ascent += abs (it->voffset);
17515          else
17516            /* Increase the descent so that we can display the text lower
17517               in the line.  */
17518            it->descent += it->voffset;
17519        }
17520    }
17521    
17522    
17523    /* Produce glyphs/get display metrics for the image IT is loaded with.
17524       See the description of struct display_iterator in dispextern.h for
17525       an overview of struct display_iterator.  */
17526    
17527    static void
17528    produce_image_glyph (it)
17529         struct it *it;
17530    {
17531      struct image *img;
17532      struct face *face;
17533    
17534      xassert (it->what == IT_IMAGE);
17535    
17536      face = FACE_FROM_ID (it->f, it->face_id);
17537      img = IMAGE_FROM_ID (it->f, it->image_id);
17538      xassert (img);
17539    
17540      /* Make sure X resources of the face and image are loaded.  */
17541      PREPARE_FACE_FOR_DISPLAY (it->f, face);
17542      prepare_image_for_display (it->f, img);
17543    
17544      it->ascent = it->phys_ascent = image_ascent (img, face);
17545      it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17546      it->pixel_width = img->width + 2 * img->hmargin;
17547    
17548      it->nglyphs = 1;
17549    
17550      if (face->box != FACE_NO_BOX)
17551        {
17552          if (face->box_line_width > 0)
17553            {
17554              it->ascent += face->box_line_width;
17555              it->descent += face->box_line_width;
17556            }
17557    
17558          if (it->start_of_box_run_p)
17559            it->pixel_width += abs (face->box_line_width);
17560          if (it->end_of_box_run_p)
17561            it->pixel_width += abs (face->box_line_width);
17562        }
17563    
17564      take_vertical_position_into_account (it);
17565    
17566      if (it->glyph_row)
17567        {
17568          struct glyph *glyph;
17569          enum glyph_row_area area = it->area;
17570    
17571          glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17572          if (glyph < it->glyph_row->glyphs[area + 1])
17573            {
17574              glyph->charpos = CHARPOS (it->position);
17575              glyph->object = it->object;
17576              glyph->pixel_width = it->pixel_width;
17577              glyph->voffset = it->voffset;
17578              glyph->type = IMAGE_GLYPH;
17579              glyph->multibyte_p = it->multibyte_p;
17580              glyph->left_box_line_p = it->start_of_box_run_p;
17581              glyph->right_box_line_p = it->end_of_box_run_p;
17582              glyph->overlaps_vertically_p = 0;
17583              glyph->padding_p = 0;
17584              glyph->glyph_not_available_p = 0;
17585              glyph->face_id = it->face_id;
17586              glyph->u.img_id = img->id;
17587              glyph->font_type = FONT_TYPE_UNKNOWN;
17588              ++it->glyph_row->used[area];
17589            }
17590        }
17591    }
17592    
17593    
17594    /* Append a stretch glyph to IT->glyph_row.  OBJECT is the source
17595       of the glyph, WIDTH and HEIGHT are the width and height of the
17596       stretch.  ASCENT is the percentage/100 of HEIGHT to use for the
17597       ascent of the glyph (0 <= ASCENT <= 1).  */
17598    
17599    static void
17600    append_stretch_glyph (it, object, width, height, ascent)
17601         struct it *it;
17602         Lisp_Object object;
17603         int width, height;
17604         double ascent;
17605    {
17606      struct glyph *glyph;
17607      enum glyph_row_area area = it->area;
17608    
17609      xassert (ascent >= 0 && ascent <= 1);
17610    
17611      glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17612      if (glyph < it->glyph_row->glyphs[area + 1])
17613        {
17614          glyph->charpos = CHARPOS (it->position);
17615          glyph->object = object;
17616          glyph->pixel_width = width;
17617          glyph->voffset = it->voffset;
17618          glyph->type = STRETCH_GLYPH;
17619          glyph->multibyte_p = it->multibyte_p;
17620          glyph->left_box_line_p = it->start_of_box_run_p;
17621          glyph->right_box_line_p = it->end_of_box_run_p;
17622          glyph->overlaps_vertically_p = 0;
17623          glyph->padding_p = 0;
17624          glyph->glyph_not_available_p = 0;
17625          glyph->face_id = it->face_id;
17626          glyph->u.stretch.ascent = height * ascent;
17627          glyph->u.stretch.height = height;
17628          glyph->font_type = FONT_TYPE_UNKNOWN;
17629          ++it->glyph_row->used[area];
17630        }
17631    }
17632    
17633    
17634    /* Produce a stretch glyph for iterator IT.  IT->object is the value
17635       of the glyph property displayed.  The value must be a list
17636       `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17637       being recognized:
17638    
17639       1. `:width WIDTH' specifies that the space should be WIDTH *
17640       canonical char width wide.  WIDTH may be an integer or floating
17641       point number.
17642    
17643       2. `:relative-width FACTOR' specifies that the width of the stretch
17644       should be computed from the width of the first character having the
17645       `glyph' property, and should be FACTOR times that width.
17646    
17647       3. `:align-to HPOS' specifies that the space should be wide enough
17648       to reach HPOS, a value in canonical character units.
17649    
17650       Exactly one of the above pairs must be present.
17651    
17652       4. `:height HEIGHT' specifies that the height of the stretch produced
17653       should be HEIGHT, measured in canonical character units.
17654    
17655       5. `:relative-height FACTOR' specifies that the height of the
17656       stretch should be FACTOR times the height of the characters having
17657       the glyph property.
17658    
17659       Either none or exactly one of 4 or 5 must be present.
17660    
17661       6. `:ascent ASCENT'  specifies that ASCENT percent of the height
17662       of the stretch should be used for the ascent of the stretch.
17663       ASCENT must be in the range 0 <= ASCENT <= 100.  */
17664    
17665    #define NUMVAL(X)                               \
17666         ((INTEGERP (X) || FLOATP (X))              \
17667          ? XFLOATINT (X)                           \
17668          : - 1)
17669    
17670    
17671    static void
17672    produce_stretch_glyph (it)
17673         struct it *it;
17674    {
17675      /* (space :width WIDTH :height HEIGHT.  */
17676      Lisp_Object prop, plist;
17677      int width = 0, height = 0;
17678      double ascent = 0;
17679      struct face *face = FACE_FROM_ID (it->f, it->face_id);
17680      XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
17681    
17682      PREPARE_FACE_FOR_DISPLAY (it->f, face);
17683    
17684      /* List should start with `space'.  */
17685      xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
17686      plist = XCDR (it->object);
17687    
17688      /* Compute the width of the stretch.  */
17689      if (prop = Fplist_get (plist, QCwidth),
17690          NUMVAL (prop) > 0)
17691        /* Absolute width `:width WIDTH' specified and valid.  */
17692        width = NUMVAL (prop) * CANON_X_UNIT (it->f);
17693      else if (prop = Fplist_get (plist, QCrelative_width),
17694               NUMVAL (prop) > 0)
17695        {
17696          /* Relative width `:relative-width FACTOR' specified and valid.
17697             Compute the width of the characters having the `glyph'
17698             property.  */
17699          struct it it2;
17700          unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
17701    
17702          it2 = *it;
17703          if (it->multibyte_p)
17704            {
17705              int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
17706                            - IT_BYTEPOS (*it));
17707              it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
17708            }
17709          else
17710            it2.c = *p, it2.len = 1;
17711    
17712          it2.glyph_row = NULL;
17713          it2.what = IT_CHARACTER;
17714          x_produce_glyphs (&it2);
17715          width = NUMVAL (prop) * it2.pixel_width;
17716        }
17717      else if (prop = Fplist_get (plist, QCalign_to),
17718               NUMVAL (prop) > 0)
17719        width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
17720      else
17721        /* Nothing specified -> width defaults to canonical char width.  */
17722        width = CANON_X_UNIT (it->f);
17723    
17724      /* Compute height.  */
17725      if (prop = Fplist_get (plist, QCheight),
17726          NUMVAL (prop) > 0)
17727        height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
17728      else if (prop = Fplist_get (plist, QCrelative_height),
17729               NUMVAL (prop) > 0)
17730        height = FONT_HEIGHT (font) * NUMVAL (prop);
17731      else
17732        height = FONT_HEIGHT (font);
17733    
17734      /* Compute percentage of height used for ascent.  If
17735         `:ascent ASCENT' is present and valid, use that.  Otherwise,
17736         derive the ascent from the font in use.  */
17737      if (prop = Fplist_get (plist, QCascent),
17738          NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
17739        ascent = NUMVAL (prop) / 100.0;
17740      else
17741        ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
17742    
17743      if (width <= 0)
17744        width = 1;
17745      if (height <= 0)
17746        height = 1;
17747    
17748      if (it->glyph_row)
17749        {
17750          Lisp_Object object = it->stack[it->sp - 1].string;
17751          if (!STRINGP (object))
17752            object = it->w->buffer;
17753          append_stretch_glyph (it, object, width, height, ascent);
17754        }
17755    
17756      it->pixel_width = width;
17757      it->ascent = it->phys_ascent = height * ascent;
17758      it->descent = it->phys_descent = height - it->ascent;
17759      it->nglyphs = 1;
17760    
17761      if (face->box != FACE_NO_BOX)
17762        {
17763          if (face->box_line_width > 0)
17764            {
17765              it->ascent += face->box_line_width;
17766              it->descent += face->box_line_width;
17767            }
17768    
17769          if (it->start_of_box_run_p)
17770            it->pixel_width += abs (face->box_line_width);
17771          if (it->end_of_box_run_p)
17772            it->pixel_width += abs (face->box_line_width);
17773        }
17774    
17775      take_vertical_position_into_account (it);
17776    }
17777    
17778    /* RIF:
17779       Produce glyphs/get display metrics for the display element IT is
17780       loaded with.  See the description of struct display_iterator in
17781       dispextern.h for an overview of struct display_iterator.  */
17782    
17783    void
17784    x_produce_glyphs (it)
17785         struct it *it;
17786    {
17787      it->glyph_not_available_p = 0;
17788    
17789      if (it->what == IT_CHARACTER)
17790        {
17791          XChar2b char2b;
17792          XFontStruct *font;
17793          struct face *face = FACE_FROM_ID (it->f, it->face_id);
17794          XCharStruct *pcm;
17795          int font_not_found_p;
17796          struct font_info *font_info;
17797          int boff;                 /* baseline offset */
17798          /* We may change it->multibyte_p upon unibyte<->multibyte
17799             conversion.  So, save the current value now and restore it
17800             later.
17801    
17802             Note: It seems that we don't have to record multibyte_p in
17803             struct glyph because the character code itself tells if or
17804             not the character is multibyte.  Thus, in the future, we must
17805             consider eliminating the field `multibyte_p' in the struct
17806             glyph.  */
17807          int saved_multibyte_p = it->multibyte_p;
17808    
17809          /* Maybe translate single-byte characters to multibyte, or the
17810             other way.  */
17811          it->char_to_display = it->c;
17812          if (!ASCII_BYTE_P (it->c))
17813            {
17814              if (unibyte_display_via_language_environment
17815                  && SINGLE_BYTE_CHAR_P (it->c)
17816                  && (it->c >= 0240
17817                      || !NILP (Vnonascii_translation_table)))
17818                {
17819                  it->char_to_display = unibyte_char_to_multibyte (it->c);
17820                  it->multibyte_p = 1;
17821                  it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
17822                  face = FACE_FROM_ID (it->f, it->face_id);
17823                }
17824              else if (!SINGLE_BYTE_CHAR_P (it->c)
17825                       && !it->multibyte_p)
17826                {
17827                  it->multibyte_p = 1;
17828                  it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
17829                  face = FACE_FROM_ID (it->f, it->face_id);
17830                }
17831            }
17832    
17833          /* Get font to use.  Encode IT->char_to_display.  */
17834          get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
17835                                      &char2b, it->multibyte_p, 0);
17836          font = face->font;
17837    
17838          /* When no suitable font found, use the default font.  */
17839          font_not_found_p = font == NULL;
17840          if (font_not_found_p)
17841            {
17842              font = FRAME_FONT (it->f);
17843              boff = FRAME_BASELINE_OFFSET (it->f);
17844              font_info = NULL;
17845            }
17846          else
17847            {
17848              font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
17849              boff = font_info->baseline_offset;
17850              if (font_info->vertical_centering)
17851                boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
17852            }
17853    
17854          if (it->char_to_display >= ' '
17855              && (!it->multibyte_p || it->char_to_display < 128))
17856            {
17857              /* Either unibyte or ASCII.  */
17858              int stretched_p;
17859    
17860              it->nglyphs = 1;
17861    
17862              pcm = rif->per_char_metric (font, &char2b,
17863                                          FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
17864              it->ascent = FONT_BASE (font) + boff;
17865              it->descent = FONT_DESCENT (font) - boff;
17866    
17867              if (pcm)
17868                {
17869                  it->phys_ascent = pcm->ascent + boff;
17870                  it->phys_descent = pcm->descent - boff;
17871                  it->pixel_width = pcm->width;
17872                }
17873              else
17874                {
17875                  it->glyph_not_available_p = 1;
17876                  it->phys_ascent = FONT_BASE (font) + boff;
17877                  it->phys_descent = FONT_DESCENT (font) - boff;
17878                  it->pixel_width = FONT_WIDTH (font);
17879                }
17880    
17881              /* If this is a space inside a region of text with
17882                 `space-width' property, change its width.  */
17883              stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
17884              if (stretched_p)
17885                it->pixel_width *= XFLOATINT (it->space_width);
17886    
17887              /* If face has a box, add the box thickness to the character
17888                 height.  If character has a box line to the left and/or
17889                 right, add the box line width to the character's width.  */
17890              if (face->box != FACE_NO_BOX)
17891                {
17892                  int thick = face->box_line_width;
17893    
17894                  if (thick > 0)
17895                    {
17896                      it->ascent += thick;
17897                      it->descent += thick;
17898                    }
17899                  else
17900                    thick = -thick;
17901    
17902                  if (it->start_of_box_run_p)
17903                    it->pixel_width += thick;
17904                  if (it->end_of_box_run_p)
17905                    it->pixel_width += thick;
17906                }
17907    
17908              /* If face has an overline, add the height of the overline
17909                 (1 pixel) and a 1 pixel margin to the character height.  */
17910              if (face->overline_p)
17911                it->ascent += 2;
17912    
17913              take_vertical_position_into_account (it);
17914    
17915              /* If we have to actually produce glyphs, do it.  */
17916              if (it->glyph_row)
17917                {
17918                  if (stretched_p)
17919                    {
17920                      /* Translate a space with a `space-width' property
17921                         into a stretch glyph.  */
17922                      double ascent = (double) FONT_BASE (font)
17923                                    / FONT_HEIGHT (font);
17924                      append_stretch_glyph (it, it->object, it->pixel_width,
17925                                            it->ascent + it->descent, ascent);
17926                    }
17927                  else
17928                    append_glyph (it);
17929    
17930                  /* If characters with lbearing or rbearing are displayed
17931                     in this line, record that fact in a flag of the
17932                     glyph row.  This is used to optimize X output code.  */
17933                  if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
17934                    it->glyph_row->contains_overlapping_glyphs_p = 1;
17935                }
17936            }
17937          else if (it->char_to_display == '\n')
17938            {
17939              /* A newline has no width but we need the height of the line.  */
17940              it->pixel_width = 0;
17941              it->nglyphs = 0;
17942              it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
17943              it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
17944    
17945              if (face->box != FACE_NO_BOX
17946                  && face->box_line_width > 0)
17947                {
17948                  it->ascent += face->box_line_width;
17949                  it->descent += face->box_line_width;
17950                }
17951            }
17952          else if (it->char_to_display == '\t')
17953            {
17954              int tab_width = it->tab_width * CANON_X_UNIT (it->f);
17955              int x = it->current_x + it->continuation_lines_width;
17956              int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
17957    
17958              /* If the distance from the current position to the next tab
17959                 stop is less than a canonical character width, use the
17960                 tab stop after that.  */
17961              if (next_tab_x - x < CANON_X_UNIT (it->f))
17962                next_tab_x += tab_width;
17963    
17964              it->pixel_width = next_tab_x - x;
17965              it->nglyphs = 1;
17966              it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
17967              it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
17968    
17969              if (it->glyph_row)
17970                {
17971                  double ascent = (double) it->ascent / (it->ascent + it->descent);
17972                  append_stretch_glyph (it, it->object, it->pixel_width,
17973                                        it->ascent + it->descent, ascent);
17974                }
17975            }
17976          else
17977            {
17978              /* A multi-byte character.  Assume that the display width of the
17979                 character is the width of the character multiplied by the
17980                 width of the font.  */
17981    
17982              /* If we found a font, this font should give us the right
17983                 metrics.  If we didn't find a font, use the frame's
17984                 default font and calculate the width of the character
17985                 from the charset width; this is what old redisplay code
17986                 did.  */
17987    
17988              pcm = rif->per_char_metric (font, &char2b,
17989                                          FONT_TYPE_FOR_MULTIBYTE (font, it->c));
17990    
17991              if (font_not_found_p || !pcm)
17992                {
17993                  int charset = CHAR_CHARSET (it->char_to_display);
17994    
17995                  it->glyph_not_available_p = 1;
17996                  it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
17997                                     * CHARSET_WIDTH (charset));
17998                  it->phys_ascent = FONT_BASE (font) + boff;
17999                  it->phys_descent = FONT_DESCENT (font) - boff;
18000                }
18001              else
18002                {
18003                  it->pixel_width = pcm->width;
18004                  it->phys_ascent = pcm->ascent + boff;
18005                  it->phys_descent = pcm->descent - boff;
18006                  if (it->glyph_row
18007                      && (pcm->lbearing < 0
18008                          || pcm->rbearing > pcm->width))
18009                    it->glyph_row->contains_overlapping_glyphs_p = 1;
18010                }
18011              it->nglyphs = 1;
18012              it->ascent = FONT_BASE (font) + boff;
18013              it->descent = FONT_DESCENT (font) - boff;
18014              if (face->box != FACE_NO_BOX)
18015                {
18016                  int thick = face->box_line_width;
18017    
18018                  if (thick > 0)
18019                    {
18020                      it->ascent += thick;
18021                      it->descent += thick;
18022                    }
18023                  else
18024                    thick = - thick;
18025    
18026                  if (it->start_of_box_run_p)
18027                    it->pixel_width += thick;
18028                  if (it->end_of_box_run_p)
18029                    it->pixel_width += thick;
18030                }
18031    
18032              /* If face has an overline, add the height of the overline
18033                 (1 pixel) and a 1 pixel margin to the character height.  */
18034              if (face->overline_p)
18035                it->ascent += 2;
18036    
18037              take_vertical_position_into_account (it);
18038    
18039              if (it->glyph_row)
18040                append_glyph (it);
18041            }
18042          it->multibyte_p = saved_multibyte_p;
18043        }
18044      else if (it->what == IT_COMPOSITION)
18045        {
18046          /* Note: A composition is represented as one glyph in the
18047             glyph matrix.  There are no padding glyphs.  */
18048          XChar2b char2b;
18049          XFontStruct *font;
18050          struct face *face = FACE_FROM_ID (it->f, it->face_id);
18051          XCharStruct *pcm;
18052          int font_not_found_p;
18053          struct font_info *font_info;
18054          int boff;                 /* baseline offset */
18055          struct composition *cmp = composition_table[it->cmp_id];
18056    
18057          /* Maybe translate single-byte characters to multibyte.  */
18058          it->char_to_display = it->c;
18059          if (unibyte_display_via_language_environment
18060              && SINGLE_BYTE_CHAR_P (it->c)
18061              && (it->c >= 0240
18062                  || (it->c >= 0200
18063                      && !NILP (Vnonascii_translation_table))))
18064            {
18065              it->char_to_display = unibyte_char_to_multibyte (it->c);
18066            }
18067    
18068          /* Get face and font to use.  Encode IT->char_to_display.  */
18069          it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18070          face = FACE_FROM_ID (it->f, it->face_id);
18071          get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18072                                      &char2b, it->multibyte_p, 0);
18073          font = face->font;
18074    
18075          /* When no suitable font found, use the default font.  */
18076          font_not_found_p = font == NULL;
18077          if (font_not_found_p)
18078            {
18079              font = FRAME_FONT (it->f);
18080              boff = FRAME_BASELINE_OFFSET (it->f);
18081              font_info = NULL;
18082            }
18083          else
18084            {
18085              font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18086              boff = font_info->baseline_offset;
18087              if (font_info->vertical_centering)
18088                boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18089            }
18090    
18091          /* There are no padding glyphs, so there is only one glyph to
18092             produce for the composition.  Important is that pixel_width,
18093             ascent and descent are the values of what is drawn by
18094             draw_glyphs (i.e. the values of the overall glyphs composed).  */
18095          it->nglyphs = 1;
18096    
18097          /* If we have not yet calculated pixel size data of glyphs of
18098             the composition for the current face font, calculate them
18099             now.  Theoretically, we have to check all fonts for the
18100             glyphs, but that requires much time and memory space.  So,
18101             here we check only the font of the first glyph.  This leads
18102             to incorrect display very rarely, and C-l (recenter) can
18103             correct the display anyway.  */
18104          if (cmp->font != (void *) font)
18105            {
18106              /* Ascent and descent of the font of the first character of
18107                 this composition (adjusted by baseline offset).  Ascent
18108                 and descent of overall glyphs should not be less than
18109                 them respectively.  */
18110              int font_ascent = FONT_BASE (font) + boff;
18111              int font_descent = FONT_DESCENT (font) - boff;
18112              /* Bounding box of the overall glyphs.  */
18113              int leftmost, rightmost, lowest, highest;
18114              int i, width, ascent, descent;
18115    
18116              cmp->font = (void *) font;
18117    
18118              /* Initialize the bounding box.  */
18119              if (font_info
18120                  && (pcm = rif->per_char_metric (font, &char2b,
18121                                                  FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18122                {
18123                  width = pcm->width;
18124                  ascent = pcm->ascent;
18125                  descent = pcm->descent;
18126                }
18127              else
18128                {
18129                  width = FONT_WIDTH (font);
18130                  ascent = FONT_BASE (font);
18131                  descent = FONT_DESCENT (font);
18132                }
18133    
18134              rightmost = width;
18135              lowest = - descent + boff;
18136              highest = ascent + boff;
18137              leftmost = 0;
18138    
18139              if (font_info
18140                  && font_info->default_ascent
18141                  && CHAR_TABLE_P (Vuse_default_ascent)
18142                  && !NILP (Faref (Vuse_default_ascent,
18143                                   make_number (it->char_to_display))))
18144                highest = font_info->default_ascent + boff;
18145    
18146              /* Draw the first glyph at the normal position.  It may be
18147                 shifted to right later if some other glyphs are drawn at
18148                 the left.  */
18149              cmp->offsets[0] = 0;
18150              cmp->offsets[1] = boff;
18151    
18152              /* Set cmp->offsets for the remaining glyphs.  */
18153              for (i = 1; i < cmp->glyph_len; i++)
18154                {
18155                  int left, right, btm, top;
18156                  int ch = COMPOSITION_GLYPH (cmp, i);
18157                  int face_id = FACE_FOR_CHAR (it->f, face, ch);
18158    
18159                  face = FACE_FROM_ID (it->f, face_id);
18160                  get_char_face_and_encoding (it->f, ch, face->id,
18161                                              &char2b, it->multibyte_p, 0);
18162                  font = face->font;
18163                  if (font == NULL)
18164                    {
18165                      font = FRAME_FONT (it->f);
18166                      boff = FRAME_BASELINE_OFFSET (it->f);
18167                      font_info = NULL;
18168                    }
18169                  else
18170                    {
18171                      font_info
18172                        = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18173                      boff = font_info->baseline_offset;
18174                      if (font_info->vertical_centering)
18175                        boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18176                    }
18177    
18178                  if (font_info
18179                      && (pcm = rif->per_char_metric (font, &char2b,
18180                                                      FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18181                    {
18182                      width = pcm->width;
18183                      ascent = pcm->ascent;
18184                      descent = pcm->descent;
18185                    }
18186                  else
18187                    {
18188                      width = FONT_WIDTH (font);
18189                      ascent = 1;
18190                      descent = 0;
18191                    }
18192    
18193                  if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18194                    {
18195                      /* Relative composition with or without
18196                         alternate chars.  */
18197                      left = (leftmost + rightmost - width) / 2;
18198                      btm = - descent + boff;
18199                      if (font_info && font_info->relative_compose
18200                          && (! CHAR_TABLE_P (Vignore_relative_composition)
18201                              || NILP (Faref (Vignore_relative_composition,
18202                                              make_number (ch)))))
18203                        {
18204    
18205                          if (- descent >= font_info->relative_compose)
18206                            /* One extra pixel between two glyphs.  */
18207                            btm = highest + 1;
18208                          else if (ascent <= 0)
18209                            /* One extra pixel between two glyphs.  */
18210                            btm = lowest - 1 - ascent - descent;
18211                        }
18212                    }
18213                  else
18214                    {
18215                      /* A composition rule is specified by an integer
18216                         value that encodes global and new reference
18217                         points (GREF and NREF).  GREF and NREF are
18218                         specified by numbers as below:
18219    
18220                            0---1---2 -- ascent
18221                            |       |
18222                            |       |
18223                            |       |
18224                            9--10--11 -- center
18225                            |       |
18226                         ---3---4---5--- baseline
18227                            |       |
18228                            6---7---8 -- descent
18229                      */
18230                      int rule = COMPOSITION_RULE (cmp, i);
18231                      int gref, nref, grefx, grefy, nrefx, nrefy;
18232    
18233                      COMPOSITION_DECODE_RULE (rule, gref, nref);
18234                      grefx = gref % 3, nrefx = nref % 3;
18235                      grefy = gref / 3, nrefy = nref / 3;
18236    
18237                      left = (leftmost
18238                              + grefx * (rightmost - leftmost) / 2
18239                              - nrefx * width / 2);
18240                      btm = ((grefy == 0 ? highest
18241                              : grefy == 1 ? 0
18242                              : grefy == 2 ? lowest
18243                              : (highest + lowest) / 2)
18244                             - (nrefy == 0 ? ascent + descent
18245                                : nrefy == 1 ? descent - boff
18246                                : nrefy == 2 ? 0
18247                                : (ascent + descent) / 2));
18248                    }
18249    
18250                  cmp->offsets[i * 2] = left;
18251                  cmp->offsets[i * 2 + 1] = btm + descent;
18252    
18253                  /* Update the bounding box of the overall glyphs. */
18254                  right = left + width;
18255                  top = btm + descent + ascent;
18256                  if (left < leftmost)
18257                    leftmost = left;
18258                  if (right > rightmost)
18259                    rightmost = right;
18260                  if (top > highest)
18261                    highest = top;
18262                  if (btm < lowest)
18263                    lowest = btm;
18264                }
18265    
18266              /* If there are glyphs whose x-offsets are negative,
18267                 shift all glyphs to the right and make all x-offsets
18268                 non-negative.  */
18269              if (leftmost < 0)
18270                {
18271                  for (i = 0; i < cmp->glyph_len; i++)
18272                    cmp->offsets[i * 2] -= leftmost;
18273                  rightmost -= leftmost;
18274                }
18275    
18276              cmp->pixel_width = rightmost;
18277              cmp->ascent = highest;
18278              cmp->descent = - lowest;
18279              if (cmp->ascent < font_ascent)
18280                cmp->ascent = font_ascent;
18281              if (cmp->descent < font_descent)
18282                cmp->descent = font_descent;
18283            }
18284    
18285          it->pixel_width = cmp->pixel_width;
18286          it->ascent = it->phys_ascent = cmp->ascent;
18287          it->descent = it->phys_descent = cmp->descent;
18288    
18289          if (face->box != FACE_NO_BOX)
18290            {
18291              int thick = face->box_line_width;
18292    
18293              if (thick > 0)
18294                {
18295                  it->ascent += thick;
18296                  it->descent += thick;
18297                }
18298              else
18299                thick = - thick;
18300    
18301              if (it->start_of_box_run_p)
18302                it->pixel_width += thick;
18303              if (it->end_of_box_run_p)
18304                it->pixel_width += thick;
18305            }
18306    
18307          /* If face has an overline, add the height of the overline
18308             (1 pixel) and a 1 pixel margin to the character height.  */
18309          if (face->overline_p)
18310            it->ascent += 2;
18311    
18312          take_vertical_position_into_account (it);
18313    
18314          if (it->glyph_row)
18315            append_composite_glyph (it);
18316        }
18317      else if (it->what == IT_IMAGE)
18318        produce_image_glyph (it);
18319      else if (it->what == IT_STRETCH)
18320        produce_stretch_glyph (it);
18321    
18322      /* Accumulate dimensions.  Note: can't assume that it->descent > 0
18323         because this isn't true for images with `:ascent 100'.  */
18324      xassert (it->ascent >= 0 && it->descent >= 0);
18325      if (it->area == TEXT_AREA)
18326        it->current_x += it->pixel_width;
18327    
18328      it->descent += it->extra_line_spacing;
18329    
18330      it->max_ascent = max (it->max_ascent, it->ascent);
18331      it->max_descent = max (it->max_descent, it->descent);
18332      it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18333      it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18334    }
18335    
18336    /* EXPORT for RIF:
18337       Output LEN glyphs starting at START at the nominal cursor position.
18338       Advance the nominal cursor over the text.  The global variable
18339       updated_window contains the window being updated, updated_row is
18340       the glyph row being updated, and updated_area is the area of that
18341       row being updated.  */
18342    
18343    void
18344    x_write_glyphs (start, len)
18345         struct glyph *start;
18346         int len;
18347    {
18348      int x, hpos;
18349    
18350      xassert (updated_window && updated_row);
18351      BLOCK_INPUT;
18352    
18353      /* Write glyphs.  */
18354    
18355      hpos = start - updated_row->glyphs[updated_area];
18356      x = draw_glyphs (updated_window, output_cursor.x,
18357                       updated_row, updated_area,
18358                       hpos, hpos + len,
18359                       DRAW_NORMAL_TEXT, 0);
18360    
18361      /* Invalidate old phys cursor if the glyph at its hpos is redrawn.  */
18362      if (updated_area == TEXT_AREA
18363          && updated_window->phys_cursor_on_p
18364          && updated_window->phys_cursor.vpos == output_cursor.vpos
18365          && updated_window->phys_cursor.hpos >= hpos
18366          && updated_window->phys_cursor.hpos < hpos + len)
18367        updated_window->phys_cursor_on_p = 0;
18368    
18369      UNBLOCK_INPUT;
18370    
18371      /* Advance the output cursor.  */
18372      output_cursor.hpos += len;
18373      output_cursor.x = x;
18374    }
18375    
18376    
18377    /* EXPORT for RIF:
18378       Insert LEN glyphs from START at the nominal cursor position.   */
18379    
18380    void
18381    x_insert_glyphs (start, len)
18382         struct glyph *start;
18383         int len;
18384    {
18385      struct frame *f;
18386      struct window *w;
18387      int line_height, shift_by_width, shifted_region_width;
18388      struct glyph_row *row;
18389      struct glyph *glyph;
18390      int frame_x, frame_y, hpos;
18391    
18392      xassert (updated_window && updated_row);
18393      BLOCK_INPUT;
18394      w = updated_window;
18395      f = XFRAME (WINDOW_FRAME (w));
18396    
18397      /* Get the height of the line we are in.  */
18398      row = updated_row;
18399      line_height = row->height;
18400    
18401      /* Get the width of the glyphs to insert.  */
18402      shift_by_width = 0;
18403      for (glyph = start; glyph < start + len; ++glyph)
18404        shift_by_width += glyph->pixel_width;
18405    
18406      /* Get the width of the region to shift right.  */
18407      shifted_region_width = (window_box_width (w, updated_area)
18408                              - output_cursor.x
18409                              - shift_by_width);
18410    
18411      /* Shift right.  */
18412      frame_x = window_box_left (w, updated_area) + output_cursor.x;
18413      frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18414    
18415      rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18416                                    line_height, shift_by_width);
18417    
18418      /* Write the glyphs.  */
18419      hpos = start - row->glyphs[updated_area];
18420      draw_glyphs (w, output_cursor.x, row, updated_area,
18421                   hpos, hpos + len,
18422                   DRAW_NORMAL_TEXT, 0);
18423    
18424      /* Advance the output cursor.  */
18425      output_cursor.hpos += len;
18426      output_cursor.x += shift_by_width;
18427      UNBLOCK_INPUT;
18428    }
18429    
18430    
18431    /* EXPORT for RIF:
18432       Erase the current text line from the nominal cursor position
18433       (inclusive) to pixel column TO_X (exclusive).  The idea is that
18434       everything from TO_X onward is already erased.
18435    
18436       TO_X is a pixel position relative to updated_area of
18437       updated_window.  TO_X == -1 means clear to the end of this area.  */
18438    
18439    void
18440    x_clear_end_of_line (to_x)
18441         int to_x;
18442    {
18443      struct frame *f;
18444      struct window *w = updated_window;
18445      int max_x, min_y, max_y;
18446      int from_x, from_y, to_y;
18447    
18448      xassert (updated_window && updated_row);
18449      f = XFRAME (w->frame);
18450    
18451      if (updated_row->full_width_p)
18452        {
18453          max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
18454          if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
18455              && !w->pseudo_window_p)
18456            max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
18457        }
18458      else
18459        max_x = window_box_width (w, updated_area);
18460      max_y = window_text_bottom_y (w);
18461    
18462      /* TO_X == 0 means don't do anything.  TO_X < 0 means clear to end
18463         of window.  For TO_X > 0, truncate to end of drawing area.  */
18464      if (to_x == 0)
18465        return;
18466      else if (to_x < 0)
18467        to_x = max_x;
18468      else
18469        to_x = min (to_x, max_x);
18470    
18471      to_y = min (max_y, output_cursor.y + updated_row->height);
18472    
18473      /* Notice if the cursor will be cleared by this operation.  */
18474      if (!updated_row->full_width_p)
18475        notice_overwritten_cursor (w, updated_area,
18476                                   output_cursor.x, -1,
18477                                   updated_row->y,
18478                                   MATRIX_ROW_BOTTOM_Y (updated_row));
18479    
18480      from_x = output_cursor.x;
18481    
18482      /* Translate to frame coordinates.  */
18483      if (updated_row->full_width_p)
18484        {
18485          from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18486          to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18487        }
18488      else
18489        {
18490          from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
18491          to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
18492        }
18493    
18494      min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
18495      from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18496      to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18497    
18498      /* Prevent inadvertently clearing to end of the X window.  */
18499      if (to_x > from_x && to_y > from_y)
18500        {
18501          BLOCK_INPUT;
18502          rif->clear_frame_area (f, from_x, from_y,
18503                                 to_x - from_x, to_y - from_y);
18504          UNBLOCK_INPUT;
18505        }
18506    }
18507    
18508    #endif /* HAVE_WINDOW_SYSTEM */
18509    
18510    
18511    
18512    /***********************************************************************
18513                                 Cursor types
18514     ***********************************************************************/
18515    
18516    /* Value is the internal representation of the specified cursor type
18517       ARG.  If type is BAR_CURSOR, return in *WIDTH the specified width
18518       of the bar cursor.  */
18519    
18520    enum text_cursor_kinds
18521    get_specified_cursor_type (arg, width)
18522         Lisp_Object arg;
18523         int *width;
18524    {
18525      enum text_cursor_kinds type;
18526    
18527      if (NILP (arg))
18528        return NO_CURSOR;
18529    
18530      if (EQ (arg, Qbox))
18531        return FILLED_BOX_CURSOR;
18532    
18533      if (EQ (arg, Qhollow))
18534        return HOLLOW_BOX_CURSOR;
18535    
18536      if (EQ (arg, Qbar))
18537        {
18538          *width = 2;
18539          return BAR_CURSOR;
18540        }
18541    
18542      if (CONSP (arg)
18543          && EQ (XCAR (arg), Qbar)
18544          && INTEGERP (XCDR (arg))
18545          && XINT (XCDR (arg)) >= 0)
18546        {
18547          *width = XINT (XCDR (arg));
18548          return BAR_CURSOR;
18549        }
18550    
18551      if (EQ (arg, Qhbar))
18552        {
18553          *width = 2;
18554          return HBAR_CURSOR;
18555        }
18556    
18557      if (CONSP (arg)
18558          && EQ (XCAR (arg), Qhbar)
18559          && INTEGERP (XCDR (arg))
18560          && XINT (XCDR (arg)) >= 0)
18561        {
18562          *width = XINT (XCDR (arg));
18563          return HBAR_CURSOR;
18564        }
18565    
18566      /* Treat anything unknown as "hollow box cursor".
18567         It was bad to signal an error; people have trouble fixing
18568         .Xdefaults with Emacs, when it has something bad in it.  */
18569      type = HOLLOW_BOX_CURSOR;
18570    
18571      return type;
18572    }
18573    
18574    /* Set the default cursor types for specified frame.  */
18575    void
18576    set_frame_cursor_types (f, arg)
18577         struct frame *f;
18578         Lisp_Object arg;
18579    {
18580      int width;
18581      Lisp_Object tem;
18582    
18583      FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
18584      FRAME_CURSOR_WIDTH (f) = width;
18585    
18586      /* By default, set up the blink-off state depending on the on-state.  */
18587    
18588      tem = Fassoc (arg, Vblink_cursor_alist);
18589      if (!NILP (tem))
18590        {
18591          FRAME_BLINK_OFF_CURSOR (f)
18592            = get_specified_cursor_type (XCDR (tem), &width);
18593          FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
18594        }
18595      else
18596        FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
18597    }
18598    
18599    
18600    /* Return the cursor we want to be displayed in window W.  Return
18601       width of bar/hbar cursor through WIDTH arg.  Return with
18602       ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18603       (i.e. if the `system caret' should track this cursor).
18604    
18605       In a mini-buffer window, we want the cursor only to appear if we
18606       are reading input from this window.  For the selected window, we
18607       want the cursor type given by the frame parameter or buffer local
18608       setting of cursor-type.  If explicitly marked off, draw no cursor.
18609       In all other cases, we want a hollow box cursor.  */
18610    
18611    enum text_cursor_kinds
18612    get_window_cursor_type (w, width, active_cursor)
18613         struct window *w;
18614         int *width;
18615         int *active_cursor;
18616    {
18617      struct frame *f = XFRAME (w->frame);
18618      struct buffer *b = XBUFFER (w->buffer);
18619      int cursor_type = DEFAULT_CURSOR;
18620      Lisp_Object alt_cursor;
18621      int non_selected = 0;
18622    
18623      *active_cursor = 1;
18624    
18625      /* Echo area */
18626      if (cursor_in_echo_area
18627          && FRAME_HAS_MINIBUF_P (f)
18628          && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
18629        {
18630          if (w == XWINDOW (echo_area_window))
18631            {
18632              *width = FRAME_CURSOR_WIDTH (f);
18633              return FRAME_DESIRED_CURSOR (f);
18634            }
18635    
18636          *active_cursor = 0;
18637          non_selected = 1;
18638        }
18639    
18640      /* Nonselected window or nonselected frame.  */
18641      else if (w != XWINDOW (f->selected_window)
18642    #ifdef HAVE_WINDOW_SYSTEM
18643               || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
18644    #endif
18645               )
18646        {
18647          *active_cursor = 0;
18648    
18649          if (MINI_WINDOW_P (w) && minibuf_level == 0)
18650            return NO_CURSOR;
18651    
18652          non_selected = 1;
18653        }
18654    
18655      /* Never display a cursor in a window in which cursor-type is nil.  */
18656      if (NILP (b->cursor_type))
18657        return NO_CURSOR;
18658    
18659      /* Use cursor-in-non-selected-windows for non-selected window or frame.  */
18660      if (non_selected)
18661        {
18662          alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
18663          return get_specified_cursor_type (alt_cursor, width);
18664        }
18665    
18666      /* Get the normal cursor type for this window.  */
18667      if (EQ (b->cursor_type, Qt))
18668        {
18669          cursor_type = FRAME_DESIRED_CURSOR (f);
18670          *width = FRAME_CURSOR_WIDTH (f);
18671        }
18672      else
18673        cursor_type = get_specified_cursor_type (b->cursor_type, width);
18674    
18675      /* Use normal cursor if not blinked off.  */
18676      if (!w->cursor_off_p)
18677        return cursor_type;
18678    
18679      /* Cursor is blinked off, so determine how to "toggle" it.  */
18680    
18681      /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist.  */
18682      if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
18683        return get_specified_cursor_type (XCDR (alt_cursor), width);
18684    
18685      /* Then see if frame has specified a specific blink off cursor type.  */
18686      if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
18687        {
18688          *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
18689          return FRAME_BLINK_OFF_CURSOR (f);
18690        }
18691    
18692      /* Finally perform built-in cursor blinking:
18693           filled box      <->   hollow box
18694           wide [h]bar     <->   narrow [h]bar
18695           narrow [h]bar   <->   no cursor
18696           other type      <->   no cursor  */
18697    
18698      if (cursor_type == FILLED_BOX_CURSOR)
18699        return HOLLOW_BOX_CURSOR;
18700    
18701      if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
18702        {
18703          *width = 1;
18704          return cursor_type;
18705        }
18706    
18707      return NO_CURSOR;
18708    }
18709    
18710    
18711    #ifdef HAVE_WINDOW_SYSTEM
18712    
18713    /* Notice when the text cursor of window W has been completely
18714       overwritten by a drawing operation that outputs glyphs in AREA
18715       starting at X0 and ending at X1 in the line starting at Y0 and
18716       ending at Y1.  X coordinates are area-relative.  X1 < 0 means all
18717       the rest of the line after X0 has been written.  Y coordinates
18718       are window-relative.  */
18719    
18720    static void
18721    notice_overwritten_cursor (w, area, x0, x1, y0, y1)
18722         struct window *w;
18723         enum glyph_row_area area;
18724         int x0, y0, x1, y1;
18725    {
18726      if (area == TEXT_AREA && w->phys_cursor_on_p)
18727        {
18728          int cx0 = w->phys_cursor.x;
18729          int cx1 = cx0 + w->phys_cursor_width;
18730          int cy0 = w->phys_cursor.y;
18731          int cy1 = cy0 + w->phys_cursor_height;
18732    
18733          if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
18734            {
18735              /* The cursor image will be completely removed from the
18736                 screen if the output area intersects the cursor area in
18737                 y-direction.  When we draw in [y0 y1[, and some part of
18738                 the cursor is at y < y0, that part must have been drawn
18739                 before.  When scrolling, the cursor is erased before
18740                 actually scrolling, so we don't come here.  When not
18741                 scrolling, the rows above the old cursor row must have
18742                 changed, and in this case these rows must have written
18743                 over the cursor image.
18744    
18745                 Likewise if part of the cursor is below y1, with the
18746                 exception of the cursor being in the first blank row at
18747                 the buffer and window end because update_text_area
18748                 doesn't draw that row.  (Except when it does, but
18749                 that's handled in update_text_area.)  */
18750    
18751              if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
18752                  && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
18753                w->phys_cursor_on_p = 0;
18754            }
18755        }
18756    }
18757    
18758    #endif /* HAVE_WINDOW_SYSTEM */
18759    
18760    
18761    /************************************************************************
18762                                  Mouse Face
18763     ************************************************************************/
18764    
18765    #ifdef HAVE_WINDOW_SYSTEM
18766    
18767    /* EXPORT for RIF:
18768       Fix the display of area AREA of overlapping row ROW in window W.  */
18769    
18770    void
18771    x_fix_overlapping_area (w, row, area)
18772         struct window *w;
18773         struct glyph_row *row;
18774         enum glyph_row_area area;
18775    {
18776      int i, x;
18777    
18778      BLOCK_INPUT;
18779    
18780      if (area == LEFT_MARGIN_AREA)
18781        x = 0;
18782      else if (area == TEXT_AREA)
18783        x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
18784      else
18785        x = (window_box_width (w, LEFT_MARGIN_AREA)
18786             + window_box_width (w, TEXT_AREA));
18787    
18788      for (i = 0; i < row->used[area];)
18789        {
18790          if (row->glyphs[area][i].overlaps_vertically_p)
18791            {
18792              int start = i, start_x = x;
18793    
18794              do
18795                {
18796                  x += row->glyphs[area][i].pixel_width;
18797                  ++i;
18798                }
18799              while (i < row->used[area]
18800                     && row->glyphs[area][i].overlaps_vertically_p);
18801    
18802              draw_glyphs (w, start_x, row, area,
18803                           start, i,
18804                           DRAW_NORMAL_TEXT, 1);
18805            }
18806          else
18807            {
18808              x += row->glyphs[area][i].pixel_width;
18809              ++i;
18810            }
18811        }
18812    
18813      UNBLOCK_INPUT;
18814    }
18815    
18816    
18817    /* EXPORT:
18818       Draw the cursor glyph of window W in glyph row ROW.  See the
18819       comment of draw_glyphs for the meaning of HL.  */
18820    
18821    void
18822    draw_phys_cursor_glyph (w, row, hl)
18823         struct window *w;
18824         struct glyph_row *row;
18825         enum draw_glyphs_face hl;
18826    {
18827      /* If cursor hpos is out of bounds, don't draw garbage.  This can
18828         happen in mini-buffer windows when switching between echo area
18829         glyphs and mini-buffer.  */
18830      if (w->phys_cursor.hpos < row->used[TEXT_AREA])
18831        {
18832          int on_p = w->phys_cursor_on_p;
18833          int x1;
18834          x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
18835                            w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
18836                            hl, 0);
18837          w->phys_cursor_on_p = on_p;
18838    
18839          if (hl == DRAW_CURSOR)
18840            w->phys_cursor_width = x1 - w->phys_cursor.x;
18841          /* When we erase the cursor, and ROW is overlapped by other
18842             rows, make sure that these overlapping parts of other rows
18843             are redrawn.  */
18844          else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
18845            {
18846              if (row > w->current_matrix->rows
18847                  && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
18848                x_fix_overlapping_area (w, row - 1, TEXT_AREA);
18849    
18850              if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
18851                  && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
18852                x_fix_overlapping_area (w, row + 1, TEXT_AREA);
18853            }
18854        }
18855    }
18856    
18857    
18858    /* EXPORT:
18859       Erase the image of a cursor of window W from the screen.  */
18860    
18861    void
18862    erase_phys_cursor (w)
18863         struct window *w;
18864    {
18865      struct frame *f = XFRAME (w->frame);
18866      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
18867      int hpos = w->phys_cursor.hpos;
18868      int vpos = w->phys_cursor.vpos;
18869      int mouse_face_here_p = 0;
18870      struct glyph_matrix *active_glyphs = w->current_matrix;
18871      struct glyph_row *cursor_row;
18872      struct glyph *cursor_glyph;
18873      enum draw_glyphs_face hl;
18874    
18875      /* No cursor displayed or row invalidated => nothing to do on the
18876         screen.  */
18877      if (w->phys_cursor_type == NO_CURSOR)
18878        goto mark_cursor_off;
18879    
18880      /* VPOS >= active_glyphs->nrows means that window has been resized.
18881         Don't bother to erase the cursor.  */
18882      if (vpos >= active_glyphs->nrows)
18883        goto mark_cursor_off;
18884    
18885      /* If row containing cursor is marked invalid, there is nothing we
18886         can do.  */
18887      cursor_row = MATRIX_ROW (active_glyphs, vpos);
18888      if (!cursor_row->enabled_p)
18889        goto mark_cursor_off;
18890    
18891      /* If row is completely invisible, don't attempt to delete a cursor which
18892         isn't there.  This can happen if cursor is at top of a window, and
18893         we switch to a buffer with a header line in that window.  */
18894      if (cursor_row->visible_height <= 0)
18895        goto mark_cursor_off;
18896    
18897      /* This can happen when the new row is shorter than the old one.
18898         In this case, either draw_glyphs or clear_end_of_line
18899         should have cleared the cursor.  Note that we wouldn't be
18900         able to erase the cursor in this case because we don't have a
18901         cursor glyph at hand.  */
18902      if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
18903        goto mark_cursor_off;
18904    
18905      /* If the cursor is in the mouse face area, redisplay that when
18906         we clear the cursor.  */
18907      if (! NILP (dpyinfo->mouse_face_window)
18908          && w == XWINDOW (dpyinfo->mouse_face_window)
18909          && (vpos > dpyinfo->mouse_face_beg_row
18910              || (vpos == dpyinfo->mouse_face_beg_row
18911                  && hpos >= dpyinfo->mouse_face_beg_col))
18912          && (vpos < dpyinfo->mouse_face_end_row
18913              || (vpos == dpyinfo->mouse_face_end_row
18914                  && hpos < dpyinfo->mouse_face_end_col))
18915          /* Don't redraw the cursor's spot in mouse face if it is at the
18916             end of a line (on a newline).  The cursor appears there, but
18917             mouse highlighting does not.  */
18918          && cursor_row->used[TEXT_AREA] > hpos)
18919        mouse_face_here_p = 1;
18920    
18921      /* Maybe clear the display under the cursor.  */
18922      if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
18923        {
18924          int x, y;
18925          int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
18926    
18927          cursor_glyph = get_phys_cursor_glyph (w);
18928          if (cursor_glyph == NULL)
18929            goto mark_cursor_off;
18930    
18931          x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
18932          y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
18933    
18934          rif->clear_frame_area (f, x, y,
18935                                 cursor_glyph->pixel_width, cursor_row->visible_height);
18936        }
18937    
18938      /* Erase the cursor by redrawing the character underneath it.  */
18939      if (mouse_face_here_p)
18940        hl = DRAW_MOUSE_FACE;
18941      else
18942        hl = DRAW_NORMAL_TEXT;
18943      draw_phys_cursor_glyph (w, cursor_row, hl);
18944    
18945     mark_cursor_off:
18946      w->phys_cursor_on_p = 0;
18947      w->phys_cursor_type = NO_CURSOR;
18948    }
18949    
18950    
18951    /* EXPORT:
18952       Display or clear cursor of window W.  If ON is zero, clear the
18953       cursor.  If it is non-zero, display the cursor.  If ON is nonzero,
18954       where to put the cursor is specified by HPOS, VPOS, X and Y.  */
18955    
18956    void
18957    display_and_set_cursor (w, on, hpos, vpos, x, y)
18958         struct window *w;
18959         int on, hpos, vpos, x, y;
18960    {
18961      struct frame *f = XFRAME (w->frame);
18962      int new_cursor_type;
18963      int new_cursor_width;
18964      int active_cursor;
18965      struct glyph_matrix *current_glyphs;
18966      struct glyph_row *glyph_row;
18967      struct glyph *glyph;
18968    
18969      /* This is pointless on invisible frames, and dangerous on garbaged
18970         windows and frames; in the latter case, the frame or window may
18971         be in the midst of changing its size, and x and y may be off the
18972         window.  */
18973      if (! FRAME_VISIBLE_P (f)
18974          || FRAME_GARBAGED_P (f)
18975          || vpos >= w->current_matrix->nrows
18976          || hpos >= w->current_matrix->matrix_w)
18977        return;
18978    
18979      /* If cursor is off and we want it off, return quickly.  */
18980      if (!on && !w->phys_cursor_on_p)
18981        return;
18982    
18983      current_glyphs = w->current_matrix;
18984      glyph_row = MATRIX_ROW (current_glyphs, vpos);
18985      glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
18986    
18987      /* If cursor row is not enabled, we don't really know where to
18988         display the cursor.  */
18989      if (!glyph_row->enabled_p)
18990        {
18991          w->phys_cursor_on_p = 0;
18992          return;
18993        }
18994    
18995      xassert (interrupt_input_blocked);
18996    
18997      /* Set new_cursor_type to the cursor we want to be displayed.  */
18998      new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
18999    
19000      /* If cursor is currently being shown and we don't want it to be or
19001         it is in the wrong place, or the cursor type is not what we want,
19002         erase it.  */
19003      if (w->phys_cursor_on_p
19004          && (!on
19005              || w->phys_cursor.x != x
19006              || w->phys_cursor.y != y
19007              || new_cursor_type != w->phys_cursor_type
19008              || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19009                  && new_cursor_width != w->phys_cursor_width)))
19010        erase_phys_cursor (w);
19011    
19012      /* Don't check phys_cursor_on_p here because that flag is only set
19013         to zero in some cases where we know that the cursor has been
19014         completely erased, to avoid the extra work of erasing the cursor
19015         twice.  In other words, phys_cursor_on_p can be 1 and the cursor
19016         still not be visible, or it has only been partly erased.  */
19017      if (on)
19018        {
19019          w->phys_cursor_ascent = glyph_row->ascent;
19020          w->phys_cursor_height = glyph_row->height;
19021    
19022          /* Set phys_cursor_.* before x_draw_.* is called because some
19023             of them may need the information.  */
19024          w->phys_cursor.x = x;
19025          w->phys_cursor.y = glyph_row->y;
19026          w->phys_cursor.hpos = hpos;
19027          w->phys_cursor.vpos = vpos;
19028        }
19029    
19030      rif->draw_window_cursor (w, glyph_row, x, y,
19031                               new_cursor_type, new_cursor_width,
19032                               on, active_cursor);
19033    }
19034    
19035    
19036    /* Switch the display of W's cursor on or off, according to the value
19037       of ON.  */
19038    
19039    static void
19040    update_window_cursor (w, on)
19041         struct window *w;
19042         int on;
19043    {
19044      /* Don't update cursor in windows whose frame is in the process
19045         of being deleted.  */
19046      if (w->current_matrix)
19047        {
19048          BLOCK_INPUT;
19049          display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19050                                  w->phys_cursor.x, w->phys_cursor.y);
19051          UNBLOCK_INPUT;
19052        }
19053    }
19054    
19055    
19056    /* Call update_window_cursor with parameter ON_P on all leaf windows
19057       in the window tree rooted at W.  */
19058    
19059    static void
19060    update_cursor_in_window_tree (w, on_p)
19061         struct window *w;
19062         int on_p;
19063    {
19064      while (w)
19065        {
19066          if (!NILP (w->hchild))
19067            update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19068          else if (!NILP (w->vchild))
19069            update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19070          else
19071            update_window_cursor (w, on_p);
19072    
19073          w = NILP (w->next) ? 0 : XWINDOW (w->next);
19074        }
19075    }
19076    
19077    
19078    /* EXPORT:
19079       Display the cursor on window W, or clear it, according to ON_P.
19080       Don't change the cursor's position.  */
19081    
19082    void
19083    x_update_cursor (f, on_p)
19084         struct frame *f;
19085         int on_p;
19086    {
19087      update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19088    }
19089    
19090    
19091    /* EXPORT:
19092       Clear the cursor of window W to background color, and mark the
19093       cursor as not shown.  This is used when the text where the cursor
19094       is is about to be rewritten.  */
19095    
19096    void
19097    x_clear_cursor (w)
19098         struct window *w;
19099    {
19100      if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19101        update_window_cursor (w, 0);
19102    }
19103    
19104    
19105    /* EXPORT:
19106       Display the active region described by mouse_face_* according to DRAW.  */
19107    
19108    void
19109    show_mouse_face (dpyinfo, draw)
19110         Display_Info *dpyinfo;
19111         enum draw_glyphs_face draw;
19112    {
19113      struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19114      struct frame *f = XFRAME (WINDOW_FRAME (w));
19115    
19116      if (/* If window is in the process of being destroyed, don't bother
19117             to do anything.  */
19118          w->current_matrix != NULL
19119          /* Don't update mouse highlight if hidden */
19120          && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19121          /* Recognize when we are called to operate on rows that don't exist
19122             anymore.  This can happen when a window is split.  */
19123          && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19124        {
19125          int phys_cursor_on_p = w->phys_cursor_on_p;
19126          struct glyph_row *row, *first, *last;
19127    
19128          first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19129          last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19130    
19131          for (row = first; row <= last && row->enabled_p; ++row)
19132            {
19133              int start_hpos, end_hpos, start_x;
19134    
19135              /* For all but the first row, the highlight starts at column 0.  */
19136              if (row == first)
19137                {
19138                  start_hpos = dpyinfo->mouse_face_beg_col;
19139                  start_x = dpyinfo->mouse_face_beg_x;
19140                }
19141              else
19142                {
19143                  start_hpos = 0;
19144                  start_x = 0;
19145                }
19146    
19147              if (row == last)
19148                end_hpos = dpyinfo->mouse_face_end_col;
19149              else
19150                end_hpos = row->used[TEXT_AREA];
19151    
19152              if (end_hpos > start_hpos)
19153                {
19154                  draw_glyphs (w, start_x, row, TEXT_AREA,
19155                               start_hpos, end_hpos,
19156                               draw, 0);
19157    
19158                  row->mouse_face_p
19159                    = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19160                }
19161            }
19162    
19163          /* When we've written over the cursor, arrange for it to
19164             be displayed again.  */
19165          if (phys_cursor_on_p && !w->phys_cursor_on_p)
19166            {
19167              BLOCK_INPUT;
19168              display_and_set_cursor (w, 1,
19169                                      w->phys_cursor.hpos, w->phys_cursor.vpos,
19170                                      w->phys_cursor.x, w->phys_cursor.y);
19171              UNBLOCK_INPUT;
19172            }
19173        }
19174    
19175      /* Change the mouse cursor.  */
19176      if (draw == DRAW_NORMAL_TEXT)
19177        rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19178      else if (draw == DRAW_MOUSE_FACE)
19179        rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19180      else
19181        rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19182    }
19183    
19184    /* EXPORT:
19185       Clear out the mouse-highlighted active region.
19186       Redraw it un-highlighted first.  Value is non-zero if mouse
19187       face was actually drawn unhighlighted.  */
19188    
19189    int
19190    clear_mouse_face (dpyinfo)
19191         Display_Info *dpyinfo;
19192    {
19193      int cleared = 0;
19194    
19195      if (!NILP (dpyinfo->mouse_face_window))
19196        {
19197          show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19198          cleared = 1;
19199        }
19200    
19201      dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19202      dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19203      dpyinfo->mouse_face_window = Qnil;
19204      dpyinfo->mouse_face_overlay = Qnil;
19205      return cleared;
19206    }
19207    
19208    
19209    /* EXPORT:
19210       Non-zero if physical cursor of window W is within mouse face.  */
19211    
19212    int
19213    cursor_in_mouse_face_p (w)
19214         struct window *w;
19215    {
19216      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19217      int in_mouse_face = 0;
19218    
19219      if (WINDOWP (dpyinfo->mouse_face_window)
19220          && XWINDOW (dpyinfo->mouse_face_window) == w)
19221        {
19222          int hpos = w->phys_cursor.hpos;
19223          int vpos = w->phys_cursor.vpos;
19224    
19225          if (vpos >= dpyinfo->mouse_face_beg_row
19226              && vpos <= dpyinfo->mouse_face_end_row
19227              && (vpos > dpyinfo->mouse_face_beg_row
19228                  || hpos >= dpyinfo->mouse_face_beg_col)
19229              && (vpos < dpyinfo->mouse_face_end_row
19230                  || hpos < dpyinfo->mouse_face_end_col
19231                  || dpyinfo->mouse_face_past_end))
19232            in_mouse_face = 1;
19233        }
19234    
19235      return in_mouse_face;
19236    }
19237    
19238    
19239    
19240    
19241    /* Find the glyph matrix position of buffer position CHARPOS in window
19242       *W.  HPOS, *VPOS, *X, and *Y are set to the positions found.  W's
19243       current glyphs must be up to date.  If CHARPOS is above window
19244       start return (0, 0, 0, 0).  If CHARPOS is after end of W, return end
19245       of last line in W.  In the row containing CHARPOS, stop before glyphs
19246       having STOP as object.  */
19247    
19248    #if 0 /* This is a version of fast_find_position that's more correct
19249             in the presence of hscrolling, for example.  I didn't install
19250             it right away because the problem fixed is minor, it failed
19251             in 20.x as well, and I think it's too risky to install
19252             so near the release of 21.1.  2001-09-25 gerd.  */
19253    
19254    static int
19255    fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19256         struct window *w;
19257         int charpos;
19258         int *hpos, *vpos, *x, *y;
19259         Lisp_Object stop;
19260    {
19261      struct glyph_row *row, *first;
19262      struct glyph *glyph, *end;
19263      int i, past_end = 0;
19264    
19265      first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19266      row = row_containing_pos (w, charpos, first, NULL, 0);
19267      if (row == NULL)
19268        {
19269          if (charpos < MATRIX_ROW_START_CHARPOS (first))
19270            {
19271              *x = *y = *hpos = *vpos = 0;
19272              return 0;
19273            }
19274          else
19275            {
19276              row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19277              past_end = 1;
19278            }
19279        }
19280    
19281      *x = row->x;
19282      *y = row->y;
19283      *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19284    
19285      glyph = row->glyphs[TEXT_AREA];
19286      end = glyph + row->used[TEXT_AREA];
19287    
19288      /* Skip over glyphs not having an object at the start of the row.
19289         These are special glyphs like truncation marks on terminal
19290         frames.  */
19291      if (row->displays_text_p)
19292        while (glyph < end
19293               && INTEGERP (glyph->object)
19294               && !EQ (stop, glyph->object)
19295               && glyph->charpos < 0)
19296          {
19297            *x += glyph->pixel_width;
19298            ++glyph;
19299          }
19300    
19301      while (glyph < end
19302             && !INTEGERP (glyph->object)
19303             && !EQ (stop, glyph->object)
19304             && (!BUFFERP (glyph->object)
19305                 || glyph->charpos < charpos))
19306        {
19307          *x += glyph->pixel_width;
19308          ++glyph;
19309        }
19310    
19311      *hpos = glyph - row->glyphs[TEXT_AREA];
19312      return past_end;
19313    }
19314    
19315    #else /* not 0 */
19316    
19317    static int
19318    fast_find_position (w, pos, hpos, vpos, x, y, stop)
19319         struct window *w;
19320         int pos;
19321         int *hpos, *vpos, *x, *y;
19322         Lisp_Object stop;
19323    {
19324      int i;
19325      int lastcol;
19326      int maybe_next_line_p = 0;
19327      int line_start_position;
19328      int yb = window_text_bottom_y (w);
19329      struct glyph_row *row, *best_row;
19330      int row_vpos, best_row_vpos;
19331      int current_x;
19332    
19333      row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19334      row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19335    
19336      while (row->y < yb)
19337        {
19338          if (row->used[TEXT_AREA])
19339            line_start_position = row->glyphs[TEXT_AREA]->charpos;
19340          else
19341            line_start_position = 0;
19342    
19343          if (line_start_position > pos)
19344            break;
19345          /* If the position sought is the end of the buffer,
19346             don't include the blank lines at the bottom of the window.  */
19347          else if (line_start_position == pos
19348                   && pos == BUF_ZV (XBUFFER (w->buffer)))
19349            {
19350              maybe_next_line_p = 1;
19351              break;
19352            }
19353          else if (line_start_position > 0)
19354            {
19355              best_row = row;
19356              best_row_vpos = row_vpos;
19357            }
19358    
19359          if (row->y + row->height >= yb)
19360            break;
19361    
19362          ++row;
19363          ++row_vpos;
19364        }
19365    
19366      /* Find the right column within BEST_ROW.  */
19367      lastcol = 0;
19368      current_x = best_row->x;
19369      for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19370        {
19371          struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19372          int charpos = glyph->charpos;
19373    
19374          if (BUFFERP (glyph->object))
19375            {
19376              if (charpos == pos)
19377                {
19378                  *hpos = i;
19379                  *vpos = best_row_vpos;
19380                  *x = current_x;
19381                  *y = best_row->y;
19382                  return 1;
19383                }
19384              else if (charpos > pos)
19385                break;
19386            }
19387          else if (EQ (glyph->object, stop))
19388            break;
19389    
19390          if (charpos > 0)
19391            lastcol = i;
19392          current_x += glyph->pixel_width;
19393        }
19394    
19395      /* If we're looking for the end of the buffer,
19396         and we didn't find it in the line we scanned,
19397         use the start of the following line.  */
19398      if (maybe_next_line_p)
19399        {
19400          ++best_row;
19401          ++best_row_vpos;
19402          lastcol = 0;
19403          current_x = best_row->x;
19404        }
19405    
19406      *vpos = best_row_vpos;
19407      *hpos = lastcol + 1;
19408      *x = current_x;
19409      *y = best_row->y;
19410      return 0;
19411    }
19412    
19413    #endif /* not 0 */
19414    
19415    
19416    /* Find the position of the glyph for position POS in OBJECT in
19417       window W's current matrix, and return in *X, *Y the pixel
19418       coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19419    
19420       RIGHT_P non-zero means return the position of the right edge of the
19421       glyph, RIGHT_P zero means return the left edge position.
19422    
19423       If no glyph for POS exists in the matrix, return the position of
19424       the glyph with the next smaller position that is in the matrix, if
19425       RIGHT_P is zero.  If RIGHT_P is non-zero, and no glyph for POS
19426       exists in the matrix, return the position of the glyph with the
19427       next larger position in OBJECT.
19428    
19429       Value is non-zero if a glyph was found.  */
19430    
19431    static int
19432    fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19433         struct window *w;
19434         int pos;
19435         Lisp_Object object;
19436         int *hpos, *vpos, *x, *y;
19437         int right_p;
19438    {
19439      int yb = window_text_bottom_y (w);
19440      struct glyph_row *r;
19441      struct glyph *best_glyph = NULL;
19442      struct glyph_row *best_row = NULL;
19443      int best_x = 0;
19444    
19445      for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19446           r->enabled_p && r->y < yb;
19447           ++r)
19448        {
19449          struct glyph *g = r->glyphs[TEXT_AREA];
19450          struct glyph *e = g + r->used[TEXT_AREA];
19451          int gx;
19452    
19453          for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19454            if (EQ (g->object, object))
19455              {
19456                if (g->charpos == pos)
19457                  {
19458                    best_glyph = g;
19459                    best_x = gx;
19460                    best_row = r;
19461                    goto found;
19462                  }
19463                else if (best_glyph == NULL
19464                         || ((abs (g->charpos - pos)
19465                             < abs (best_glyph->charpos - pos))
19466                             && (right_p
19467                                 ? g->charpos < pos
19468                                 : g->charpos > pos)))
19469                  {
19470                    best_glyph = g;
19471                    best_x = gx;
19472                    best_row = r;
19473                  }
19474              }
19475        }
19476    
19477     found:
19478    
19479      if (best_glyph)
19480        {
19481          *x = best_x;
19482          *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19483    
19484          if (right_p)
19485            {
19486              *x += best_glyph->pixel_width;
19487              ++*hpos;
19488            }
19489    
19490          *y = best_row->y;
19491          *vpos = best_row - w->current_matrix->rows;
19492        }
19493    
19494      return best_glyph != NULL;
19495    }
19496    
19497    
19498    /* Take proper action when mouse has moved to the mode or header line
19499       or marginal area AREA of window W, x-position X and y-position Y.
19500       X is relative to the start of the text display area of W, so the
19501       width of bitmap areas and scroll bars must be subtracted to get a
19502       position relative to the start of the mode line.  */
19503    
19504    static void
19505    note_mode_line_or_margin_highlight (w, x, y, area)
19506         struct window *w;
19507         int x, y;
19508         enum window_part area;
19509    {
19510      struct frame *f = XFRAME (w->frame);
19511      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19512      Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
19513      int charpos;
19514      Lisp_Object string, help, map, pos;
19515    
19516      if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
19517        string = mode_line_string (w, x, y, area, &charpos);
19518      else
19519        string = marginal_area_string (w, x, y, area, &charpos);
19520    
19521      if (STRINGP (string))
19522        {
19523          pos = make_number (charpos);
19524    
19525          /* If we're on a string with `help-echo' text property, arrange
19526             for the help to be displayed.  This is done by setting the
19527             global variable help_echo_string to the help string.  */
19528          help = Fget_text_property (pos, Qhelp_echo, string);
19529          if (!NILP (help))
19530            {
19531              help_echo_string = help;
19532              XSETWINDOW (help_echo_window, w);
19533              help_echo_object = string;
19534              help_echo_pos = charpos;
19535            }
19536    
19537         /* Change the mouse pointer according to what is under X/Y.  */
19538          map = Fget_text_property (pos, Qlocal_map, string);
19539          if (!KEYMAPP (map))
19540            map = Fget_text_property (pos, Qkeymap, string);
19541          if (KEYMAPP (map))
19542            cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19543        }
19544    
19545      rif->define_frame_cursor (f, cursor);
19546    }
19547    
19548    
19549    /* EXPORT:
19550       Take proper action when the mouse has moved to position X, Y on
19551       frame F as regards highlighting characters that have mouse-face
19552       properties.  Also de-highlighting chars where the mouse was before.
19553       X and Y can be negative or out of range.  */
19554    
19555    void
19556    note_mouse_highlight (f, x, y)
19557         struct frame *f;
19558         int x, y;
19559    {
19560      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19561      enum window_part part;
19562      Lisp_Object window;
19563      struct window *w;
19564      Cursor cursor = No_Cursor;
19565      struct buffer *b;
19566    
19567      /* When a menu is active, don't highlight because this looks odd.  */
19568    #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
19569      if (popup_activated ())
19570        return;
19571    #endif
19572    
19573      if (NILP (Vmouse_highlight)
19574          || !f->glyphs_initialized_p)
19575        return;
19576    
19577      dpyinfo->mouse_face_mouse_x = x;
19578      dpyinfo->mouse_face_mouse_y = y;
19579      dpyinfo->mouse_face_mouse_frame = f;
19580    
19581      if (dpyinfo->mouse_face_defer)
19582        return;
19583    
19584      if (gc_in_progress)
19585        {
19586          dpyinfo->mouse_face_deferred_gc = 1;
19587          return;
19588        }
19589    
19590      /* Which window is that in?  */
19591      window = window_from_coordinates (f, x, y, &part, 1);
19592    
19593      /* If we were displaying active text in another window, clear that.  */
19594      if (! EQ (window, dpyinfo->mouse_face_window))
19595        clear_mouse_face (dpyinfo);
19596    
19597      /* Not on a window -> return.  */
19598      if (!WINDOWP (window))
19599        return;
19600    
19601      /* Reset help_echo_string. It will get recomputed below.  */
19602      /* ++KFS: X version didn't do this, but it looks harmless.  */
19603      help_echo_string = Qnil;
19604    
19605      /* Convert to window-relative pixel coordinates.  */
19606      w = XWINDOW (window);
19607      frame_to_window_pixel_xy (w, &x, &y);
19608    
19609      /* Handle tool-bar window differently since it doesn't display a
19610         buffer.  */
19611      if (EQ (window, f->tool_bar_window))
19612        {
19613          note_tool_bar_highlight (f, x, y);
19614          return;
19615        }
19616    
19617      /* Mouse is on the mode, header line or margin?  */
19618      if (part == ON_MODE_LINE || part == ON_HEADER_LINE
19619          || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
19620        {
19621          note_mode_line_or_margin_highlight (w, x, y, part);
19622          return;
19623        }
19624    
19625      if (part == ON_VERTICAL_BORDER)
19626        cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
19627      else
19628        cursor = FRAME_X_OUTPUT (f)->text_cursor;
19629    
19630      /* Are we in a window whose display is up to date?
19631         And verify the buffer's text has not changed.  */
19632      b = XBUFFER (w->buffer);
19633      if (part == ON_TEXT
19634          && EQ (w->window_end_valid, w->buffer)
19635          && XFASTINT (w->last_modified) == BUF_MODIFF (b)
19636          && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
19637        {
19638          int hpos, vpos, pos, i, area;
19639          struct glyph *glyph;
19640          Lisp_Object object;
19641          Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
19642          Lisp_Object *overlay_vec = NULL;
19643          int len, noverlays;
19644          struct buffer *obuf;
19645          int obegv, ozv, same_region;
19646    
19647          /* Find the glyph under X/Y.  */
19648          glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
19649    
19650          /* Clear mouse face if X/Y not over text.  */
19651          if (glyph == NULL
19652              || area != TEXT_AREA
19653              || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
19654            {
19655    #if defined (HAVE_NTGUI)
19656              /* ++KFS: Why is this necessary on W32 ?  */
19657              clear_mouse_face (dpyinfo);
19658              cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19659    #else
19660              if (clear_mouse_face (dpyinfo))
19661                cursor = No_Cursor;
19662    #endif
19663              goto set_cursor;
19664            }
19665    
19666          pos = glyph->charpos;
19667          object = glyph->object;
19668          if (!STRINGP (object) && !BUFFERP (object))
19669            goto set_cursor;
19670    
19671          /* If we get an out-of-range value, return now; avoid an error.  */
19672          if (BUFFERP (object) && pos > BUF_Z (b))
19673            goto set_cursor;
19674    
19675          /* Make the window's buffer temporarily current for
19676             overlays_at and compute_char_face.  */
19677          obuf = current_buffer;
19678          current_buffer = b;
19679          obegv = BEGV;
19680          ozv = ZV;
19681          BEGV = BEG;
19682          ZV = Z;
19683    
19684          /* Is this char mouse-active or does it have help-echo?  */
19685          position = make_number (pos);
19686    
19687          if (BUFFERP (object))
19688            {
19689              /* Put all the overlays we want in a vector in overlay_vec.
19690                 Store the length in len.  If there are more than 10, make
19691                 enough space for all, and try again.  */
19692              len = 10;
19693              overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
19694              noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
19695              if (noverlays > len)
19696                {
19697                  len = noverlays;
19698                  overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
19699                  noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
19700                }
19701    
19702              /* Sort overlays into increasing priority order.  */
19703              noverlays = sort_overlays (overlay_vec, noverlays, w);
19704            }
19705          else
19706            noverlays = 0;
19707    
19708          same_region = (EQ (window, dpyinfo->mouse_face_window)
19709                         && vpos >= dpyinfo->mouse_face_beg_row
19710                         && vpos <= dpyinfo->mouse_face_end_row
19711                         && (vpos > dpyinfo->mouse_face_beg_row
19712                             || hpos >= dpyinfo->mouse_face_beg_col)
19713                         && (vpos < dpyinfo->mouse_face_end_row
19714                             || hpos < dpyinfo->mouse_face_end_col
19715                             || dpyinfo->mouse_face_past_end));
19716    
19717          if (same_region)
19718            cursor = No_Cursor;
19719    
19720          /* Check mouse-face highlighting.  */
19721          if (! same_region
19722              /* If there exists an overlay with mouse-face overlapping
19723                 the one we are currently highlighting, we have to
19724                 check if we enter the overlapping overlay, and then
19725                 highlight only that.  */
19726              || (OVERLAYP (dpyinfo->mouse_face_overlay)
19727                  && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
19728            {
19729              /* Find the highest priority overlay that has a mouse-face
19730                 property.  */
19731              overlay = Qnil;
19732              for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
19733                {
19734                  mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
19735                  if (!NILP (mouse_face))
19736                    overlay = overlay_vec[i];
19737                }
19738    
19739              /* If we're actually highlighting the same overlay as
19740                 before, there's no need to do that again.  */
19741              if (!NILP (overlay)
19742                  && EQ (overlay, dpyinfo->mouse_face_overlay))
19743                goto check_help_echo;
19744    
19745              dpyinfo->mouse_face_overlay = overlay;
19746    
19747              /* Clear the display of the old active region, if any.  */
19748              if (clear_mouse_face (dpyinfo))
19749                cursor = No_Cursor;
19750    
19751              /* If no overlay applies, get a text property.  */
19752              if (NILP (overlay))
19753                mouse_face = Fget_text_property (position, Qmouse_face, object);
19754    
19755              /* Handle the overlay case.  */
19756              if (!NILP (overlay))
19757                {
19758                  /* Find the range of text around this char that
19759                     should be active.  */
19760                  Lisp_Object before, after;
19761                  int ignore;
19762    
19763                  before = Foverlay_start (overlay);
19764                  after = Foverlay_end (overlay);
19765                  /* Record this as the current active region.  */
19766                  fast_find_position (w, XFASTINT (before),
19767                                      &dpyinfo->mouse_face_beg_col,
19768                                      &dpyinfo->mouse_face_beg_row,
19769                                      &dpyinfo->mouse_face_beg_x,
19770                                      &dpyinfo->mouse_face_beg_y, Qnil);
19771    
19772                  dpyinfo->mouse_face_past_end
19773                    = !fast_find_position (w, XFASTINT (after),
19774                                           &dpyinfo->mouse_face_end_col,
19775                                           &dpyinfo->mouse_face_end_row,
19776                                           &dpyinfo->mouse_face_end_x,
19777                                           &dpyinfo->mouse_face_end_y, Qnil);
19778                  dpyinfo->mouse_face_window = window;
19779    
19780                  dpyinfo->mouse_face_face_id
19781                    = face_at_buffer_position (w, pos, 0, 0,
19782                                               &ignore, pos + 1,
19783                                               !dpyinfo->mouse_face_hidden);
19784    
19785                  /* Display it as active.  */
19786                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19787                  cursor = No_Cursor;
19788                }
19789              /* Handle the text property case.  */
19790              else if (!NILP (mouse_face) && BUFFERP (object))
19791                {
19792                  /* Find the range of text around this char that
19793                     should be active.  */
19794                  Lisp_Object before, after, beginning, end;
19795                  int ignore;
19796    
19797                  beginning = Fmarker_position (w->start);
19798                  end = make_number (BUF_Z (XBUFFER (object))
19799                                     - XFASTINT (w->window_end_pos));
19800                  before
19801                    = Fprevious_single_property_change (make_number (pos + 1),
19802                                                        Qmouse_face,
19803                                                        object, beginning);
19804                  after
19805                    = Fnext_single_property_change (position, Qmouse_face,
19806                                                    object, end);
19807    
19808                  /* Record this as the current active region.  */
19809                  fast_find_position (w, XFASTINT (before),
19810                                      &dpyinfo->mouse_face_beg_col,
19811                                      &dpyinfo->mouse_face_beg_row,
19812                                      &dpyinfo->mouse_face_beg_x,
19813                                      &dpyinfo->mouse_face_beg_y, Qnil);
19814                  dpyinfo->mouse_face_past_end
19815                    = !fast_find_position (w, XFASTINT (after),
19816                                           &dpyinfo->mouse_face_end_col,
19817                                           &dpyinfo->mouse_face_end_row,
19818                                           &dpyinfo->mouse_face_end_x,
19819                                           &dpyinfo->mouse_face_end_y, Qnil);
19820                  dpyinfo->mouse_face_window = window;
19821    
19822                  if (BUFFERP (object))
19823                    dpyinfo->mouse_face_face_id
19824                      = face_at_buffer_position (w, pos, 0, 0,
19825                                                 &ignore, pos + 1,
19826                                                 !dpyinfo->mouse_face_hidden);
19827    
19828                  /* Display it as active.  */
19829                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19830                  cursor = No_Cursor;
19831                }
19832              else if (!NILP (mouse_face) && STRINGP (object))
19833                {
19834                  Lisp_Object b, e;
19835                  int ignore;
19836    
19837                  b = Fprevious_single_property_change (make_number (pos + 1),
19838                                                        Qmouse_face,
19839                                                        object, Qnil);
19840                  e = Fnext_single_property_change (position, Qmouse_face,
19841                                                    object, Qnil);
19842                  if (NILP (b))
19843                    b = make_number (0);
19844                  if (NILP (e))
19845                    e = make_number (SCHARS (object) - 1);
19846                  fast_find_string_pos (w, XINT (b), object,
19847                                        &dpyinfo->mouse_face_beg_col,
19848                                        &dpyinfo->mouse_face_beg_row,
19849                                        &dpyinfo->mouse_face_beg_x,
19850                                        &dpyinfo->mouse_face_beg_y, 0);
19851                  fast_find_string_pos (w, XINT (e), object,
19852                                        &dpyinfo->mouse_face_end_col,
19853                                        &dpyinfo->mouse_face_end_row,
19854                                        &dpyinfo->mouse_face_end_x,
19855                                        &dpyinfo->mouse_face_end_y, 1);
19856                  dpyinfo->mouse_face_past_end = 0;
19857                  dpyinfo->mouse_face_window = window;
19858                  dpyinfo->mouse_face_face_id
19859                    = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
19860                                               glyph->face_id, 1);
19861                  show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19862                  cursor = No_Cursor;
19863                }
19864              else if (STRINGP (object) && NILP (mouse_face))
19865                {
19866                  /* A string which doesn't have mouse-face, but
19867                     the text ``under'' it might have.  */
19868                  struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
19869                  int start = MATRIX_ROW_START_CHARPOS (r);
19870    
19871                  pos = string_buffer_position (w, object, start);
19872                  if (pos > 0)
19873                    mouse_face = get_char_property_and_overlay (make_number (pos),
19874                                                                Qmouse_face,
19875                                                                w->buffer,
19876                                                                &overlay);
19877                  if (!NILP (mouse_face) && !NILP (overlay))
19878                    {
19879                      Lisp_Object before = Foverlay_start (overlay);
19880                      Lisp_Object after = Foverlay_end (overlay);
19881                      int ignore;
19882    
19883                      /* Note that we might not be able to find position
19884                         BEFORE in the glyph matrix if the overlay is
19885                         entirely covered by a `display' property.  In
19886                         this case, we overshoot.  So let's stop in
19887                         the glyph matrix before glyphs for OBJECT.  */
19888                      fast_find_position (w, XFASTINT (before),
19889                                          &dpyinfo->mouse_face_beg_col,
19890                                          &dpyinfo->mouse_face_beg_row,
19891                                          &dpyinfo->mouse_face_beg_x,
19892                                          &dpyinfo->mouse_face_beg_y,
19893                                          object);
19894    
19895                      dpyinfo->mouse_face_past_end
19896                        = !fast_find_position (w, XFASTINT (after),
19897                                               &dpyinfo->mouse_face_end_col,
19898                                               &dpyinfo->mouse_face_end_row,
19899                                               &dpyinfo->mouse_face_end_x,
19900                                               &dpyinfo->mouse_face_end_y,
19901                                               Qnil);
19902                      dpyinfo->mouse_face_window = window;
19903                      dpyinfo->mouse_face_face_id
19904                        = face_at_buffer_position (w, pos, 0, 0,
19905                                                   &ignore, pos + 1,
19906                                                   !dpyinfo->mouse_face_hidden);
19907    
19908                      /* Display it as active.  */
19909                      show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19910                      cursor = No_Cursor;
19911                    }
19912                }
19913            }
19914    
19915        check_help_echo:
19916    
19917          /* Look for a `help-echo' property.  */
19918          {
19919            Lisp_Object help, overlay;
19920    
19921            /* Check overlays first.  */
19922            help = overlay = Qnil;
19923            for (i = noverlays - 1; i >= 0 && NILP (help); --i)
19924              {
19925                overlay = overlay_vec[i];
19926                help = Foverlay_get (overlay, Qhelp_echo);
19927              }
19928    
19929            if (!NILP (help))
19930              {
19931                help_echo_string = help;
19932                help_echo_window = window;
19933                help_echo_object = overlay;
19934                help_echo_pos = pos;
19935              }
19936            else
19937              {
19938                Lisp_Object object = glyph->object;
19939                int charpos = glyph->charpos;
19940    
19941                /* Try text properties.  */
19942                if (STRINGP (object)
19943                    && charpos >= 0
19944                    && charpos < SCHARS (object))
19945                  {
19946                    help = Fget_text_property (make_number (charpos),
19947                                               Qhelp_echo, object);
19948                    if (NILP (help))
19949                      {
19950                        /* If the string itself doesn't specify a help-echo,
19951                           see if the buffer text ``under'' it does.  */
19952                        struct glyph_row *r
19953                          = MATRIX_ROW (w->current_matrix, vpos);
19954                        int start = MATRIX_ROW_START_CHARPOS (r);
19955                        int pos = string_buffer_position (w, object, start);
19956                        if (pos > 0)
19957                          {
19958                            help = Fget_char_property (make_number (pos),
19959                                                       Qhelp_echo, w->buffer);
19960                            if (!NILP (help))
19961                              {
19962                                charpos = pos;
19963                                object = w->buffer;
19964                              }
19965                          }
19966                      }
19967                  }
19968                else if (BUFFERP (object)
19969                         && charpos >= BEGV
19970                         && charpos < ZV)
19971                  help = Fget_text_property (make_number (charpos), Qhelp_echo,
19972                                             object);
19973    
19974                if (!NILP (help))
19975                  {
19976                    help_echo_string = help;
19977                    help_echo_window = window;
19978                    help_echo_object = object;
19979                    help_echo_pos = charpos;
19980                  }
19981              }
19982          }
19983    
19984          BEGV = obegv;
19985          ZV = ozv;
19986          current_buffer = obuf;
19987        }
19988    
19989     set_cursor:
19990    
19991    #ifndef HAVE_CARBON
19992      if (cursor != No_Cursor)
19993    #else
19994      if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
19995    #endif
19996        rif->define_frame_cursor (f, cursor);
19997    }
19998    
19999    
20000    /* EXPORT for RIF:
20001       Clear any mouse-face on window W.  This function is part of the
20002       redisplay interface, and is called from try_window_id and similar
20003       functions to ensure the mouse-highlight is off.  */
20004    
20005    void
20006    x_clear_window_mouse_face (w)
20007         struct window *w;
20008    {
20009      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20010      Lisp_Object window;
20011    
20012      BLOCK_INPUT;
20013      XSETWINDOW (window, w);
20014      if (EQ (window, dpyinfo->mouse_face_window))
20015        clear_mouse_face (dpyinfo);
20016      UNBLOCK_INPUT;
20017    }
20018    
20019    
20020    /* EXPORT:
20021       Just discard the mouse face information for frame F, if any.
20022       This is used when the size of F is changed.  */
20023    
20024    void
20025    cancel_mouse_face (f)
20026         struct frame *f;
20027    {
20028      Lisp_Object window;
20029      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20030    
20031      window = dpyinfo->mouse_face_window;
20032      if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20033        {
20034          dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20035          dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20036          dpyinfo->mouse_face_window = Qnil;
20037        }
20038    }
20039    
20040    
20041    #endif /* HAVE_WINDOW_SYSTEM */
20042    
20043    
20044    /***********************************************************************
20045                               Exposure Events
20046     ***********************************************************************/
20047    
20048    #ifdef HAVE_WINDOW_SYSTEM
20049    
20050    /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20051       which intersects rectangle R.  R is in window-relative coordinates.  */
20052    
20053    static void
20054    expose_area (w, row, r, area)
20055         struct window *w;
20056         struct glyph_row *row;
20057         XRectangle *r;
20058         enum glyph_row_area area;
20059    {
20060      struct glyph *first = row->glyphs[area];
20061      struct glyph *end = row->glyphs[area] + row->used[area];
20062      struct glyph *last;
20063      int first_x, start_x, x;
20064    
20065      if (area == TEXT_AREA && row->fill_line_p)
20066        /* If row extends face to end of line write the whole line.  */
20067        draw_glyphs (w, 0, row, area,
20068                     0, row->used[area],
20069                     DRAW_NORMAL_TEXT, 0);
20070      else
20071        {
20072          /* Set START_X to the window-relative start position for drawing glyphs of
20073             AREA.  The first glyph of the text area can be partially visible.
20074             The first glyphs of other areas cannot.  */
20075          if (area == LEFT_MARGIN_AREA)
20076            start_x = 0;
20077          else if (area == TEXT_AREA)
20078            start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
20079          else
20080            start_x = (window_box_width (w, LEFT_MARGIN_AREA)
20081                       + window_box_width (w, TEXT_AREA));
20082          x = start_x;
20083    
20084          /* Find the first glyph that must be redrawn.  */
20085          while (first < end
20086                 && x + first->pixel_width < r->x)
20087            {
20088              x += first->pixel_width;
20089              ++first;
20090            }
20091    
20092          /* Find the last one.  */
20093          last = first;
20094          first_x = x;
20095          while (last < end
20096                 && x < r->x + r->width)
20097            {
20098              x += last->pixel_width;
20099              ++last;
20100            }
20101    
20102          /* Repaint.  */
20103          if (last > first)
20104            draw_glyphs (w, first_x - start_x, row, area,
20105                         first - row->glyphs[area], last - row->glyphs[area],
20106                         DRAW_NORMAL_TEXT, 0);
20107        }
20108    }
20109    
20110    
20111    /* Redraw the parts of the glyph row ROW on window W intersecting
20112       rectangle R.  R is in window-relative coordinates.  Value is
20113       non-zero if mouse-face was overwritten.  */
20114    
20115    static int
20116    expose_line (w, row, r)
20117         struct window *w;
20118         struct glyph_row *row;
20119         XRectangle *r;
20120    {
20121      xassert (row->enabled_p);
20122    
20123      if (row->mode_line_p || w->pseudo_window_p)
20124        draw_glyphs (w, 0, row, TEXT_AREA,
20125                     0, row->used[TEXT_AREA],
20126                     DRAW_NORMAL_TEXT, 0);
20127      else
20128        {
20129          if (row->used[LEFT_MARGIN_AREA])
20130            expose_area (w, row, r, LEFT_MARGIN_AREA);
20131          if (row->used[TEXT_AREA])
20132            expose_area (w, row, r, TEXT_AREA);
20133          if (row->used[RIGHT_MARGIN_AREA])
20134            expose_area (w, row, r, RIGHT_MARGIN_AREA);
20135          draw_row_fringe_bitmaps (w, row);
20136        }
20137    
20138      return row->mouse_face_p;
20139    }
20140    
20141    
20142    /* Redraw those parts of glyphs rows during expose event handling that
20143       overlap other rows.  Redrawing of an exposed line writes over parts
20144       of lines overlapping that exposed line; this function fixes that.
20145    
20146       W is the window being exposed.  FIRST_OVERLAPPING_ROW is the first
20147       row in W's current matrix that is exposed and overlaps other rows.
20148       LAST_OVERLAPPING_ROW is the last such row.  */
20149    
20150    static void
20151    expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20152         struct window *w;
20153         struct glyph_row *first_overlapping_row;
20154         struct glyph_row *last_overlapping_row;
20155    {
20156      struct glyph_row *row;
20157    
20158      for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20159        if (row->overlapping_p)
20160          {
20161            xassert (row->enabled_p && !row->mode_line_p);
20162    
20163            if (row->used[LEFT_MARGIN_AREA])
20164              x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20165    
20166            if (row->used[TEXT_AREA])
20167              x_fix_overlapping_area (w, row, TEXT_AREA);
20168    
20169            if (row->used[RIGHT_MARGIN_AREA])
20170              x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20171          }
20172    }
20173    
20174    
20175    /* Return non-zero if W's cursor intersects rectangle R.  */
20176    
20177    static int
20178    phys_cursor_in_rect_p (w, r)
20179         struct window *w;
20180         XRectangle *r;
20181    {
20182      XRectangle cr, result;
20183      struct glyph *cursor_glyph;
20184    
20185      cursor_glyph = get_phys_cursor_glyph (w);
20186      if (cursor_glyph)
20187        {
20188          cr.x = w->phys_cursor.x;
20189          cr.y = w->phys_cursor.y;
20190          cr.width = cursor_glyph->pixel_width;
20191          cr.height = w->phys_cursor_height;
20192          /* ++KFS: W32 version used W32-specific IntersectRect here, but
20193             I assume the effect is the same -- and this is portable.  */
20194          return x_intersect_rectangles (&cr, r, &result);
20195        }
20196      else
20197        return 0;
20198    }
20199    
20200    
20201    /* EXPORT:
20202       Draw a vertical window border to the right of window W if W doesn't
20203       have vertical scroll bars.  */
20204    
20205    void
20206    x_draw_vertical_border (w)
20207         struct window *w;
20208    {
20209      struct frame *f = XFRAME (WINDOW_FRAME (w));
20210    
20211      /* Redraw borders between horizontally adjacent windows.  Don't
20212         do it for frames with vertical scroll bars because either the
20213         right scroll bar of a window, or the left scroll bar of its
20214         neighbor will suffice as a border.  */
20215      if (!WINDOW_RIGHTMOST_P (w)
20216          && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
20217        {
20218          int x0, x1, y0, y1;
20219    
20220          window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20221          x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f);
20222          y1 -= 1;
20223    
20224          rif->draw_vertical_window_border (w, x1, y0, y1);
20225        }
20226    }
20227    
20228    
20229    /* Redraw the part of window W intersection rectangle FR.  Pixel
20230       coordinates in FR are frame-relative.  Call this function with
20231       input blocked.  Value is non-zero if the exposure overwrites
20232       mouse-face.  */
20233    
20234    static int
20235    expose_window (w, fr)
20236         struct window *w;
20237         XRectangle *fr;
20238    {
20239      struct frame *f = XFRAME (w->frame);
20240      XRectangle wr, r;
20241      int mouse_face_overwritten_p = 0;
20242    
20243      /* If window is not yet fully initialized, do nothing.  This can
20244         happen when toolkit scroll bars are used and a window is split.
20245         Reconfiguring the scroll bar will generate an expose for a newly
20246         created window.  */
20247      if (w->current_matrix == NULL)
20248        return 0;
20249    
20250      /* When we're currently updating the window, display and current
20251         matrix usually don't agree.  Arrange for a thorough display
20252         later.  */
20253      if (w == updated_window)
20254        {
20255          SET_FRAME_GARBAGED (f);
20256          return 0;
20257        }
20258    
20259      /* Frame-relative pixel rectangle of W.  */
20260      wr.x = XFASTINT (w->left) * CANON_X_UNIT (f);
20261      wr.y = XFASTINT (w->top) * CANON_Y_UNIT (f);
20262      wr.width = XFASTINT (w->width) * CANON_X_UNIT (f);
20263      wr.height = XFASTINT (w->height) * CANON_Y_UNIT (f);
20264    
20265      if (x_intersect_rectangles (fr, &wr, &r))
20266        {
20267          int yb = window_text_bottom_y (w);
20268          struct glyph_row *row;
20269          int cursor_cleared_p;
20270          struct glyph_row *first_overlapping_row, *last_overlapping_row;
20271    
20272          TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20273                  r.x, r.y, r.width, r.height));
20274    
20275          /* Convert to window coordinates.  */
20276          r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x);
20277          r.y = FRAME_TO_WINDOW_PIXEL_Y (w, r.y);
20278    
20279          /* Turn off the cursor.  */
20280          if (!w->pseudo_window_p
20281              && phys_cursor_in_rect_p (w, &r))
20282            {
20283              x_clear_cursor (w);
20284              cursor_cleared_p = 1;
20285            }
20286          else
20287            cursor_cleared_p = 0;
20288    
20289          /* Update lines intersecting rectangle R.  */
20290          first_overlapping_row = last_overlapping_row = NULL;
20291          for (row = w->current_matrix->rows;
20292               row->enabled_p;
20293               ++row)
20294            {
20295              int y0 = row->y;
20296              int y1 = MATRIX_ROW_BOTTOM_Y (row);
20297    
20298              if ((y0 >= r.y && y0 < r.y + r.height)
20299                  || (y1 > r.y && y1 < r.y + r.height)
20300                  || (r.y >= y0 && r.y < y1)
20301                  || (r.y + r.height > y0 && r.y + r.height < y1))
20302                {
20303                  if (row->overlapping_p)
20304                    {
20305                      if (first_overlapping_row == NULL)
20306                        first_overlapping_row = row;
20307                      last_overlapping_row = row;
20308                    }
20309    
20310                  if (expose_line (w, row, &r))
20311                    mouse_face_overwritten_p = 1;
20312                }
20313    
20314              if (y1 >= yb)
20315                break;
20316            }
20317    
20318          /* Display the mode line if there is one.  */
20319          if (WINDOW_WANTS_MODELINE_P (w)
20320              && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
20321                  row->enabled_p)
20322              && row->y < r.y + r.height)
20323            {
20324              if (expose_line (w, row, &r))
20325                mouse_face_overwritten_p = 1;
20326            }
20327    
20328          if (!w->pseudo_window_p)
20329            {
20330              /* Fix the display of overlapping rows.  */
20331              if (first_overlapping_row)
20332                expose_overlaps (w, first_overlapping_row, last_overlapping_row);
20333    
20334              /* Draw border between windows.  */
20335              x_draw_vertical_border (w);
20336    
20337              /* Turn the cursor on again.  */
20338              if (cursor_cleared_p)
20339                update_window_cursor (w, 1);
20340            }
20341        }
20342    
20343    #ifdef HAVE_CARBON
20344      /* Display scroll bar for this window.  */
20345      if (!NILP (w->vertical_scroll_bar))
20346        {
20347          /* ++KFS:
20348             If this doesn't work here (maybe some header files are missing),
20349             make a function in macterm.c and call it to do the job! */
20350          ControlHandle ch
20351            = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
20352    
20353          Draw1Control (ch);
20354        }
20355    #endif
20356    
20357      return mouse_face_overwritten_p;
20358    }
20359    
20360    
20361    
20362    /* Redraw (parts) of all windows in the window tree rooted at W that
20363       intersect R.  R contains frame pixel coordinates.  Value is
20364       non-zero if the exposure overwrites mouse-face.  */
20365    
20366    static int
20367    expose_window_tree (w, r)
20368         struct window *w;
20369         XRectangle *r;
20370    {
20371      struct frame *f = XFRAME (w->frame);
20372      int mouse_face_overwritten_p = 0;
20373    
20374      while (w && !FRAME_GARBAGED_P (f))
20375        {
20376          if (!NILP (w->hchild))
20377            mouse_face_overwritten_p
20378              |= expose_window_tree (XWINDOW (w->hchild), r);
20379          else if (!NILP (w->vchild))
20380            mouse_face_overwritten_p
20381              |= expose_window_tree (XWINDOW (w->vchild), r);
20382          else
20383            mouse_face_overwritten_p |= expose_window (w, r);
20384    
20385          w = NILP (w->next) ? NULL : XWINDOW (w->next);
20386        }
20387    
20388      return mouse_face_overwritten_p;
20389    }
20390    
20391    
20392    /* EXPORT:
20393       Redisplay an exposed area of frame F.  X and Y are the upper-left
20394       corner of the exposed rectangle.  W and H are width and height of
20395       the exposed area.  All are pixel values.  W or H zero means redraw
20396       the entire frame.  */
20397    
20398    void
20399    expose_frame (f, x, y, w, h)
20400         struct frame *f;
20401         int x, y, w, h;
20402    {
20403      XRectangle r;
20404      int mouse_face_overwritten_p = 0;
20405    
20406      TRACE ((stderr, "expose_frame "));
20407    
20408      /* No need to redraw if frame will be redrawn soon.  */
20409      if (FRAME_GARBAGED_P (f))
20410        {
20411          TRACE ((stderr, " garbaged\n"));
20412          return;
20413        }
20414    
20415    #ifdef HAVE_CARBON
20416      /* MAC_TODO: this is a kludge, but if scroll bars are not activated
20417         or deactivated here, for unknown reasons, activated scroll bars
20418         are shown in deactivated frames in some instances.  */
20419      if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
20420        activate_scroll_bars (f);
20421      else
20422        deactivate_scroll_bars (f);
20423    #endif
20424    
20425      /* If basic faces haven't been realized yet, there is no point in
20426         trying to redraw anything.  This can happen when we get an expose
20427         event while Emacs is starting, e.g. by moving another window.  */
20428      if (FRAME_FACE_CACHE (f) == NULL
20429          || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
20430        {
20431          TRACE ((stderr, " no faces\n"));
20432          return;
20433        }
20434    
20435      if (w == 0 || h == 0)
20436        {
20437          r.x = r.y = 0;
20438          r.width = CANON_X_UNIT (f) * f->width;
20439          r.height = CANON_Y_UNIT (f) * f->height;
20440        }
20441      else
20442        {
20443          r.x = x;
20444          r.y = y;
20445          r.width = w;
20446          r.height = h;
20447        }
20448    
20449      TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
20450      mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
20451    
20452      if (WINDOWP (f->tool_bar_window))
20453        mouse_face_overwritten_p
20454          |= expose_window (XWINDOW (f->tool_bar_window), &r);
20455    
20456    #ifdef HAVE_X_WINDOWS
20457    #ifndef MSDOS
20458    #ifndef USE_X_TOOLKIT
20459      if (WINDOWP (f->menu_bar_window))
20460        mouse_face_overwritten_p
20461          |= expose_window (XWINDOW (f->menu_bar_window), &r);
20462    #endif /* not USE_X_TOOLKIT */
20463    #endif
20464    #endif
20465    
20466      /* Some window managers support a focus-follows-mouse style with
20467         delayed raising of frames.  Imagine a partially obscured frame,
20468         and moving the mouse into partially obscured mouse-face on that
20469         frame.  The visible part of the mouse-face will be highlighted,
20470         then the WM raises the obscured frame.  With at least one WM, KDE
20471         2.1, Emacs is not getting any event for the raising of the frame
20472         (even tried with SubstructureRedirectMask), only Expose events.
20473         These expose events will draw text normally, i.e. not
20474         highlighted.  Which means we must redo the highlight here.
20475         Subsume it under ``we love X''.  --gerd 2001-08-15  */
20476      /* Included in Windows version because Windows most likely does not
20477         do the right thing if any third party tool offers
20478         focus-follows-mouse with delayed raise.  --jason 2001-10-12  */
20479      if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
20480        {
20481          Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20482          if (f == dpyinfo->mouse_face_mouse_frame)
20483            {
20484              int x = dpyinfo->mouse_face_mouse_x;
20485              int y = dpyinfo->mouse_face_mouse_y;
20486              clear_mouse_face (dpyinfo);
20487              note_mouse_highlight (f, x, y);
20488            }
20489        }
20490    }
20491    
20492    
20493    /* EXPORT:
20494       Determine the intersection of two rectangles R1 and R2.  Return
20495       the intersection in *RESULT.  Value is non-zero if RESULT is not
20496       empty.  */
20497    
20498    int
20499    x_intersect_rectangles (r1, r2, result)
20500         XRectangle *r1, *r2, *result;
20501    {
20502      XRectangle *left, *right;
20503      XRectangle *upper, *lower;
20504      int intersection_p = 0;
20505    
20506      /* Rearrange so that R1 is the left-most rectangle.  */
20507      if (r1->x < r2->x)
20508        left = r1, right = r2;
20509      else
20510        left = r2, right = r1;
20511    
20512      /* X0 of the intersection is right.x0, if this is inside R1,
20513         otherwise there is no intersection.  */
20514      if (right->x <= left->x + left->width)
20515        {
20516          result->x = right->x;
20517    
20518          /* The right end of the intersection is the minimum of the
20519             the right ends of left and right.  */
20520          result->width = (min (left->x + left->width, right->x + right->width)
20521                           - result->x);
20522    
20523          /* Same game for Y.  */
20524          if (r1->y < r2->y)
20525            upper = r1, lower = r2;
20526          else
20527            upper = r2, lower = r1;
20528    
20529          /* The upper end of the intersection is lower.y0, if this is inside
20530             of upper.  Otherwise, there is no intersection.  */
20531          if (lower->y <= upper->y + upper->height)
20532            {
20533              result->y = lower->y;
20534    
20535              /* The lower end of the intersection is the minimum of the lower
20536                 ends of upper and lower.  */
20537              result->height = (min (lower->y + lower->height,
20538                                     upper->y + upper->height)
20539                                - result->y);
20540              intersection_p = 1;
20541            }
20542        }
20543    
20544      return intersection_p;
20545    }
20546    
20547    #endif /* HAVE_WINDOW_SYSTEM */
20548    
20549    
20550    /***********************************************************************
20551                              Initialization                              Initialization
20552   ***********************************************************************/   ***********************************************************************/
20553    
# Line 15006  syms_of_xdisp () Line 20631  syms_of_xdisp ()
20631    staticpro (&QCeval);    staticpro (&QCeval);
20632    QCpropertize = intern (":propertize");    QCpropertize = intern (":propertize");
20633    staticpro (&QCpropertize);    staticpro (&QCpropertize);
   Qwhen = intern ("when");  
   staticpro (&Qwhen);  
20634    QCfile = intern (":file");    QCfile = intern (":file");
20635    staticpro (&QCfile);    staticpro (&QCfile);
20636    Qfontified = intern ("fontified");    Qfontified = intern ("fontified");
# Line 15034  syms_of_xdisp () Line 20657  syms_of_xdisp ()
20657    staticpro (&Qbuffer_position);    staticpro (&Qbuffer_position);
20658    Qobject = intern ("object");    Qobject = intern ("object");
20659    staticpro (&Qobject);    staticpro (&Qobject);
20660      Qbar = intern ("bar");
20661      staticpro (&Qbar);
20662      Qhbar = intern ("hbar");
20663      staticpro (&Qhbar);
20664      Qbox = intern ("box");
20665      staticpro (&Qbox);
20666      Qhollow = intern ("hollow");
20667      staticpro (&Qhollow);
20668    Qrisky_local_variable = intern ("risky-local-variable");    Qrisky_local_variable = intern ("risky-local-variable");
20669    staticpro (&Qrisky_local_variable);    staticpro (&Qrisky_local_variable);
20670      Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
20671      staticpro (&Qinhibit_free_realized_faces);
20672    
20673    list_of_error = Fcons (intern ("error"), Qnil);    list_of_error = Fcons (intern ("error"), Qnil);
20674    staticpro (&list_of_error);    staticpro (&list_of_error);
# Line 15059  syms_of_xdisp () Line 20692  syms_of_xdisp ()
20692    mode_line_proptrans_alist = Qnil;    mode_line_proptrans_alist = Qnil;
20693    staticpro (&mode_line_proptrans_alist);    staticpro (&mode_line_proptrans_alist);
20694    
20695      mode_line_string_list = Qnil;
20696      staticpro (&mode_line_string_list);
20697    
20698      help_echo_string = Qnil;
20699      staticpro (&help_echo_string);
20700      help_echo_object = Qnil;
20701      staticpro (&help_echo_object);
20702      help_echo_window = Qnil;
20703      staticpro (&help_echo_window);
20704      previous_help_echo_string = Qnil;
20705      staticpro (&previous_help_echo_string);
20706      help_echo_pos = -1;
20707    
20708    #ifdef HAVE_WINDOW_SYSTEM
20709      DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
20710        doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
20711    For example, if a block cursor is over a tab, it will be drawn as
20712    wide as that tab on the display.  */);
20713      x_stretch_cursor_p = 0;
20714    #endif
20715    
20716    DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,    DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
20717      doc: /* Non-nil means highlight trailing whitespace.      doc: /* Non-nil means highlight trailing whitespace.
20718  The face used for trailing whitespace is `trailing-whitespace'.  */);  The face used for trailing whitespace is `trailing-whitespace'.  */);
# Line 15114  of the top or bottom of the window.  */) Line 20768  of the top or bottom of the window.  */)
20768    DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,    DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
20769      doc: /* nil means display the mode-line/header-line/menu-bar in the default face.      doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
20770  Any other value means to use the appropriate face, `mode-line',  Any other value means to use the appropriate face, `mode-line',
20771  `header-line', or `menu' respectively.  `header-line', or `menu' respectively.  */);
   
 This variable is deprecated; please change the above faces instead.  */);  
20772    mode_line_inverse_video = 1;    mode_line_inverse_video = 1;
20773    
20774    DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,    DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
# Line 15186  and its new display-start position.  Not Line 20838  and its new display-start position.  Not
20838  is not valid when these functions are called.  */);  is not valid when these functions are called.  */);
20839    Vwindow_scroll_functions = Qnil;    Vwindow_scroll_functions = Qnil;
20840    
20841      DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
20842        doc: /* *Non-nil means autoselect window with mouse pointer.  */);
20843      mouse_autoselect_window = 0;
20844    
20845    DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,    DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
20846      doc: /* *Non-nil means automatically resize tool-bars.      doc: /* *Non-nil means automatically resize tool-bars.
20847  This increases a tool-bar's height if not all tool-bar items are visible.  This increases a tool-bar's height if not all tool-bar items are visible.
# Line 15241  only, until their display becomes empty, Line 20897  only, until their display becomes empty,
20897  go back to their normal size.  */);  go back to their normal size.  */);
20898    Vresize_mini_windows = Qgrow_only;    Vresize_mini_windows = Qgrow_only;
20899    
20900    DEFVAR_BOOL ("cursor-in-non-selected-windows",    DEFVAR_LISP ("cursor-in-non-selected-windows",
20901                 &cursor_in_non_selected_windows,                 &Vcursor_in_non_selected_windows,
20902      doc: /* *Non-nil means display a hollow cursor in non-selected windows.      doc: /* *Cursor type to display in non-selected windows.
20903  nil means don't display a cursor there.  */);  t means to use hollow box cursor.  See `cursor-type' for other values.  */);
20904    cursor_in_non_selected_windows = 1;    Vcursor_in_non_selected_windows = Qt;
20905    
20906      DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
20907        doc: /* Alist specifying how to blink the cursor off.
20908    Each element has the form (ON-STATE . OFF-STATE).  Whenever the
20909    `cursor-type' frame-parameter or variable equals ON-STATE,
20910    comparing using `equal', Emacs uses OFF-STATE to specify
20911    how to blink it off.  */);
20912      Vblink_cursor_alist = Qnil;
20913    
20914    DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,    DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
20915      doc: /* *Non-nil means scroll the display automatically to make point visible.  */);      doc: /* *Non-nil means scroll the display automatically to make point visible.  */);
# Line 15297  Can be used to update submenus whose con Line 20961  Can be used to update submenus whose con
20961      doc: /* Non-nil means don't eval Lisp during redisplay.  */);      doc: /* Non-nil means don't eval Lisp during redisplay.  */);
20962    inhibit_eval_during_redisplay = 0;    inhibit_eval_during_redisplay = 0;
20963    
20964      DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
20965        doc: /* Non-nil means don't free realized faces.  Internal use only.  */);
20966      inhibit_free_realized_faces = 0;
20967    
20968  #if GLYPH_DEBUG  #if GLYPH_DEBUG
20969    DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,    DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
20970                 doc: /* Inhibit try_window_id display optimization.  */);                 doc: /* Inhibit try_window_id display optimization.  */);
# Line 15353  init_xdisp () Line 21021  init_xdisp ()
21021      }      }
21022    
21023    {    {
21024      /* Allocate the buffer for frame titles.  */      /* Allocate the buffer for frame titles.
21025           Also used for `format-mode-line'.  */
21026      int size = 100;      int size = 100;
21027      frame_title_buf = (char *) xmalloc (size);      frame_title_buf = (char *) xmalloc (size);
21028      frame_title_buf_end = frame_title_buf + size;      frame_title_buf_end = frame_title_buf + size;

Legend:
Removed from v.1.754  
changed lines
  Added in v.1.754.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26