glyph with suitably computed width. Both the blanks and the
stretch glyph are given the face of the background of the line.
This way, the terminal-specific back-end can still draw the glyphs
- left to right, even for R2L lines. */
+ left to right, even for R2L lines.
+
+ Note one important detail mentioned above: that the bidi reordering
+ engine, driven by the iterator, produces characters in R2L rows
+ starting at the character that will be the rightmost on display.
+ As far as the iterator is concerned, the geometry of such rows is
+ still left to right, i.e. the iterator "thinks" the first character
+ is at the leftmost pixel position. The iterator does not know that
+ PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
+ delivers. This is important when functions from the the move_it_*
+ family are used to get to certain screen position or to match
+ screen coordinates with buffer coordinates: these functions use the
+ iterator geometry, which is left to right even in R2L paragraphs.
+ This works well with most callers of move_it_*, because they need
+ to get to a specific column, and columns are still numbered in the
+ reading order, i.e. the rightmost character in a R2L paragraph is
+ still column zero. But some callers do not get well with this; a
+ notable example is mouse clicks that need to find the character
+ that corresponds to certain pixel coordinates. See
+ buffer_posn_from_coords in dispnew.c for how this is handled. */
#include <config.h>
#include <stdio.h>
#include "macros.h"
#include "disptab.h"
#include "termhooks.h"
+#include "termopts.h"
#include "intervals.h"
#include "coding.h"
#include "process.h"
#include "font.h"
+#include "xwidget.h"
+
#ifndef FRAME_X_OUTPUT
#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
#endif
#define INFINITY 10000000
-#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
-extern void set_frame_menubar P_ ((struct frame *f, int, int));
-extern int pending_menu_activation;
-#endif
-
-extern int interrupt_input;
-extern int command_loop_level;
-
-extern Lisp_Object do_mouse_tracking;
-
-extern int minibuffer_auto_raise;
-extern Lisp_Object Vminibuffer_list;
-
-extern Lisp_Object Qface;
-extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
-
-extern Lisp_Object Voverriding_local_map;
-extern Lisp_Object Voverriding_local_map_menu_flag;
-extern Lisp_Object Qmenu_item;
-extern Lisp_Object Qwhen;
-extern Lisp_Object Qhelp_echo;
-extern Lisp_Object Qbefore_string, Qafter_string;
-
Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
/* Names of text properties relevant for redisplay. */
Lisp_Object Qdisplay;
-extern Lisp_Object Qface, Qinvisible, Qwidth;
/* Symbols used in text property values. */
Lisp_Object Qcenter;
Lisp_Object Qmargin, Qpointer;
Lisp_Object Qline_height;
-extern Lisp_Object Qheight;
-extern Lisp_Object QCwidth, QCheight, QCascent;
-extern Lisp_Object Qscroll_bar;
-extern Lisp_Object Qcursor;
/* Non-nil means highlight trailing whitespace. */
Lisp_Object Vnobreak_char_display;
#ifdef HAVE_WINDOW_SYSTEM
-extern Lisp_Object Voverflow_newline_into_fringe;
/* Test if overflow newline into fringe. Called with iterator IT
at or past right window margin, and with IT->current_x set. */
Lisp_Object Qrect, Qcircle, Qpoly;
/* Tool bar styles */
-Lisp_Object Qtext, Qboth, Qboth_horiz;
+Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
/* Non-zero means print newline to stdout before next mini-buffer
message. */
/* A handler function called to set up iterator IT from the property
at IT's current position. Value is used to steer handle_stop. */
- enum prop_handled (*handler) P_ ((struct it *it));
+ enum prop_handled (*handler) (struct it *it);
};
-static enum prop_handled handle_face_prop P_ ((struct it *));
-static enum prop_handled handle_invisible_prop P_ ((struct it *));
-static enum prop_handled handle_display_prop P_ ((struct it *));
-static enum prop_handled handle_composition_prop P_ ((struct it *));
-static enum prop_handled handle_overlay_change P_ ((struct it *));
-static enum prop_handled handle_fontified_prop P_ ((struct it *));
+static enum prop_handled handle_face_prop (struct it *);
+static enum prop_handled handle_invisible_prop (struct it *);
+static enum prop_handled handle_display_prop (struct it *);
+static enum prop_handled handle_composition_prop (struct it *);
+static enum prop_handled handle_overlay_change (struct it *);
+static enum prop_handled handle_fontified_prop (struct it *);
/* Properties handled by iterators. */
\f
/* Function prototypes. */
-static void setup_for_ellipsis P_ ((struct it *, int));
-static void mark_window_display_accurate_1 P_ ((struct window *, int));
-static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
-static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
-static int cursor_row_p P_ ((struct window *, struct glyph_row *));
-static int redisplay_mode_lines P_ ((Lisp_Object, int));
-static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
-
-static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
-
-static void handle_line_prefix P_ ((struct it *));
-
-static void pint2str P_ ((char *, int, int));
-static void pint2hrstr P_ ((char *, int, int));
-static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
- struct text_pos));
-static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
-static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
-static void store_mode_line_noprop_char P_ ((char));
-static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
-static void x_consider_frame_title P_ ((Lisp_Object));
-static void handle_stop P_ ((struct it *));
-static void handle_stop_backwards P_ ((struct it *, EMACS_INT));
-static int tool_bar_lines_needed P_ ((struct frame *, int *));
-static int single_display_spec_intangible_p P_ ((Lisp_Object));
-static void ensure_echo_area_buffers P_ ((void));
-static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
-static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
-static int with_echo_area_buffer P_ ((struct window *, int,
- int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
- EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static void clear_garbaged_frames P_ ((void));
-static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
-static int display_echo_area P_ ((struct window *));
-static int display_echo_area_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));
-static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
-static int string_char_and_length P_ ((const unsigned char *, int *));
-static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
- struct text_pos));
-static int compute_window_start_on_continuation_line P_ ((struct window *));
-static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
-static void insert_left_trunc_glyphs P_ ((struct it *));
-static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
- Lisp_Object));
-static void extend_face_to_end_of_line P_ ((struct it *));
-static int append_space_for_newline P_ ((struct it *, int));
-static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
-static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
-static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
-static int trailing_whitespace_p P_ ((int));
-static int message_log_check_duplicate P_ ((int, int, int, int));
-static void push_it P_ ((struct it *));
-static void pop_it P_ ((struct it *));
-static void sync_frame_with_window_matrix_rows P_ ((struct window *));
-static void select_frame_for_redisplay P_ ((Lisp_Object));
-static void redisplay_internal P_ ((int));
-static int echo_area_display P_ ((int));
-static void redisplay_windows P_ ((Lisp_Object));
-static void redisplay_window P_ ((Lisp_Object, int));
-static Lisp_Object redisplay_window_error ();
-static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
-static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
-static int update_menu_bar P_ ((struct frame *, int, int));
-static int try_window_reusing_current_matrix P_ ((struct window *));
-static int try_window_id P_ ((struct window *));
-static int display_line P_ ((struct it *));
-static int display_mode_lines P_ ((struct window *));
-static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
-static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
-static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
-static char *decode_mode_spec P_ ((struct window *, int, int, int,
- Lisp_Object *));
-static void display_menu_bar P_ ((struct window *));
-static int display_count_lines P_ ((int, int, int, int, int *));
-static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
- EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
-static void compute_line_metrics P_ ((struct it *));
-static void run_redisplay_end_trigger_hook P_ ((struct it *));
-static int get_overlay_strings P_ ((struct it *, int));
-static int get_overlay_strings_1 P_ ((struct it *, int, int));
-static void next_overlay_string P_ ((struct it *));
-static void reseat P_ ((struct it *, struct text_pos, int));
-static void reseat_1 P_ ((struct it *, struct text_pos, int));
-static void back_to_previous_visible_line_start P_ ((struct it *));
-void reseat_at_previous_visible_line_start P_ ((struct it *));
-static void reseat_at_next_visible_line_start P_ ((struct it *, int));
-static int next_element_from_ellipsis P_ ((struct it *));
-static int next_element_from_display_vector P_ ((struct it *));
-static int next_element_from_string P_ ((struct it *));
-static int next_element_from_c_string P_ ((struct it *));
-static int next_element_from_buffer P_ ((struct it *));
-static int next_element_from_composition P_ ((struct it *));
-static int next_element_from_image P_ ((struct it *));
-static int next_element_from_stretch P_ ((struct it *));
-static void load_overlay_strings P_ ((struct it *, int));
-static int init_from_display_pos P_ ((struct it *, struct window *,
- struct display_pos *));
-static void reseat_to_string P_ ((struct it *, unsigned char *,
- Lisp_Object, int, int, int, int));
+static void setup_for_ellipsis (struct it *, int);
+static void mark_window_display_accurate_1 (struct window *, int);
+static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
+static int display_prop_string_p (Lisp_Object, Lisp_Object);
+static int cursor_row_p (struct window *, struct glyph_row *);
+static int redisplay_mode_lines (Lisp_Object, int);
+static char *decode_mode_spec_coding (Lisp_Object, char *, int);
+
+static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
+
+static void handle_line_prefix (struct it *);
+
+static void pint2str (char *, int, int);
+static void pint2hrstr (char *, int, int);
+static struct text_pos run_window_scroll_functions (Lisp_Object,
+ struct text_pos);
+static void reconsider_clip_changes (struct window *, struct buffer *);
+static int text_outside_line_unchanged_p (struct window *, int, int);
+static void store_mode_line_noprop_char (char);
+static int store_mode_line_noprop (const unsigned char *, int, int);
+static void x_consider_frame_title (Lisp_Object);
+static void handle_stop (struct it *);
+static void handle_stop_backwards (struct it *, EMACS_INT);
+static int tool_bar_lines_needed (struct frame *, int *);
+static int single_display_spec_intangible_p (Lisp_Object);
+static void ensure_echo_area_buffers (void);
+static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
+static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
+static int with_echo_area_buffer (struct window *, int,
+ int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
+ EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static void clear_garbaged_frames (void);
+static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int display_echo_area (struct window *);
+static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static Lisp_Object unwind_redisplay (Lisp_Object);
+static int string_char_and_length (const unsigned char *, int *);
+static struct text_pos display_prop_end (struct it *, Lisp_Object,
+ struct text_pos);
+static int compute_window_start_on_continuation_line (struct window *);
+static Lisp_Object safe_eval_handler (Lisp_Object);
+static void insert_left_trunc_glyphs (struct it *);
+static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
+ Lisp_Object);
+static void extend_face_to_end_of_line (struct it *);
+static int append_space_for_newline (struct it *, int);
+static int cursor_row_fully_visible_p (struct window *, int, int);
+static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
+static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
+static int trailing_whitespace_p (int);
+static int message_log_check_duplicate (int, int, int, int);
+static void push_it (struct it *);
+static void pop_it (struct it *);
+static void sync_frame_with_window_matrix_rows (struct window *);
+static void select_frame_for_redisplay (Lisp_Object);
+static void redisplay_internal (int);
+static int echo_area_display (int);
+static void redisplay_windows (Lisp_Object);
+static void redisplay_window (Lisp_Object, int);
+static Lisp_Object redisplay_window_error (Lisp_Object);
+static Lisp_Object redisplay_window_0 (Lisp_Object);
+static Lisp_Object redisplay_window_1 (Lisp_Object);
+static int update_menu_bar (struct frame *, int, int);
+static int try_window_reusing_current_matrix (struct window *);
+static int try_window_id (struct window *);
+static int display_line (struct it *);
+static int display_mode_lines (struct window *);
+static int display_mode_line (struct window *, enum face_id, Lisp_Object);
+static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
+static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
+static const char *decode_mode_spec (struct window *, int, int, int,
+ Lisp_Object *);
+static void display_menu_bar (struct window *);
+static int display_count_lines (int, int, int, int, int *);
+static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
+ EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
+static void compute_line_metrics (struct it *);
+static void run_redisplay_end_trigger_hook (struct it *);
+static int get_overlay_strings (struct it *, int);
+static int get_overlay_strings_1 (struct it *, int, int);
+static void next_overlay_string (struct it *);
+static void reseat (struct it *, struct text_pos, int);
+static void reseat_1 (struct it *, struct text_pos, int);
+static void back_to_previous_visible_line_start (struct it *);
+void reseat_at_previous_visible_line_start (struct it *);
+static void reseat_at_next_visible_line_start (struct it *, int);
+static int next_element_from_ellipsis (struct it *);
+static int next_element_from_display_vector (struct it *);
+static int next_element_from_string (struct it *);
+static int next_element_from_c_string (struct it *);
+static int next_element_from_buffer (struct it *);
+static int next_element_from_composition (struct it *);
+static int next_element_from_image (struct it *);
+static int next_element_from_xwidget(struct it *);
+static int next_element_from_stretch (struct it *);
+static void load_overlay_strings (struct it *, int);
+static int init_from_display_pos (struct it *, struct window *,
+ struct display_pos *);
+static void reseat_to_string (struct it *, const unsigned char *,
+ Lisp_Object, int, int, int, int);
static enum move_it_result
move_it_in_display_line_to (struct it *, EMACS_INT, int,
enum move_operation_enum);
-void move_it_vertically_backward P_ ((struct it *, int));
-static void init_to_row_start P_ ((struct it *, struct window *,
- struct glyph_row *));
-static int init_to_row_end P_ ((struct it *, struct window *,
- struct glyph_row *));
-static void back_to_previous_line_start P_ ((struct it *));
-static int forward_to_next_line_start P_ ((struct it *, int *));
-static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
- Lisp_Object, int));
-static struct text_pos string_pos P_ ((int, Lisp_Object));
-static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
-static int number_of_chars P_ ((unsigned char *, int));
-static void compute_stop_pos P_ ((struct it *));
-static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
- Lisp_Object));
-static int face_before_or_after_it_pos P_ ((struct it *, int));
-static EMACS_INT next_overlay_change P_ ((EMACS_INT));
-static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
- Lisp_Object, Lisp_Object,
- struct text_pos *, int));
-static int underlying_face_id P_ ((struct it *));
-static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
- struct window *));
+void move_it_vertically_backward (struct it *, int);
+static void init_to_row_start (struct it *, struct window *,
+ struct glyph_row *);
+static int init_to_row_end (struct it *, struct window *,
+ struct glyph_row *);
+static void back_to_previous_line_start (struct it *);
+static int forward_to_next_line_start (struct it *, int *);
+static struct text_pos string_pos_nchars_ahead (struct text_pos,
+ Lisp_Object, int);
+static struct text_pos string_pos (int, Lisp_Object);
+static struct text_pos c_string_pos (int, const unsigned char *, int);
+static int number_of_chars (const unsigned char *, int);
+static void compute_stop_pos (struct it *);
+static void compute_string_pos (struct text_pos *, struct text_pos,
+ Lisp_Object);
+static int face_before_or_after_it_pos (struct it *, int);
+static EMACS_INT next_overlay_change (EMACS_INT);
+static int handle_single_display_spec (struct it *, Lisp_Object,
+ Lisp_Object, Lisp_Object,
+ struct text_pos *, int);
+static int underlying_face_id (struct it *);
+static int in_ellipses_for_invisible_text_p (struct display_pos *,
+ struct window *);
#define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
#define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
#ifdef HAVE_WINDOW_SYSTEM
-static void update_tool_bar P_ ((struct frame *, int));
-static void build_desired_tool_bar_string P_ ((struct frame *f));
-static int redisplay_tool_bar P_ ((struct frame *));
-static void display_tool_bar_line P_ ((struct it *, int));
-static void notice_overwritten_cursor P_ ((struct window *,
- enum glyph_row_area,
- int, int, int, int));
-static void append_stretch_glyph P_ ((struct it *, Lisp_Object,
- int, int, int));
+static void update_tool_bar (struct frame *, int);
+static void build_desired_tool_bar_string (struct frame *f);
+static int redisplay_tool_bar (struct frame *);
+static void display_tool_bar_line (struct it *, int);
+static void notice_overwritten_cursor (struct window *,
+ enum glyph_row_area,
+ int, int, int, int);
+static void append_stretch_glyph (struct it *, Lisp_Object,
+ int, int, int);
This is the height of W minus the height of a mode line, if any. */
INLINE int
-window_text_bottom_y (w)
- struct window *w;
+window_text_bottom_y (struct window *w)
{
int height = WINDOW_TOTAL_HEIGHT (w);
the left and right of the window. */
INLINE int
-window_box_width (w, area)
- struct window *w;
- int area;
+window_box_width (struct window *w, int area)
{
int cols = XFASTINT (w->total_cols);
int pixels = 0;
including mode lines of W, if any. */
INLINE int
-window_box_height (w)
- struct window *w;
+window_box_height (struct window *w)
{
struct frame *f = XFRAME (w->frame);
int height = WINDOW_TOTAL_HEIGHT (w);
whole window, to the right of the left fringe of W. */
INLINE int
-window_box_left_offset (w, area)
- struct window *w;
- int area;
+window_box_left_offset (struct window *w, int area)
{
int x;
/* Return the window-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
INLINE int
-window_box_right_offset (w, area)
- struct window *w;
- int area;
+window_box_right_offset (struct window *w, int area)
{
return window_box_left_offset (w, area) + window_box_width (w, area);
}
whole window, to the right of the left fringe of W. */
INLINE int
-window_box_left (w, area)
- struct window *w;
- int area;
+window_box_left (struct window *w, int area)
{
struct frame *f = XFRAME (w->frame);
int x;
/* Return the frame-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
INLINE int
-window_box_right (w, area)
- struct window *w;
- int area;
+window_box_right (struct window *w, int area)
{
return window_box_left (w, area) + window_box_width (w, area);
}
*BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
INLINE void
-window_box (w, area, box_x, box_y, box_width, box_height)
- struct window *w;
- int area;
- int *box_x, *box_y, *box_width, *box_height;
+window_box (struct window *w, int area, int *box_x, int *box_y,
+ int *box_width, int *box_height)
{
if (box_width)
*box_width = window_box_width (w, area);
box. */
INLINE void
-window_box_edges (w, area, top_left_x, top_left_y,
- bottom_right_x, bottom_right_y)
- struct window *w;
- int area;
- int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
+window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
+ int *bottom_right_x, int *bottom_right_y)
{
window_box (w, area, top_left_x, top_left_y, bottom_right_x,
bottom_right_y);
This can modify IT's settings. */
int
-line_bottom_y (it)
- struct it *it;
+line_bottom_y (struct it *it)
{
int line_height = it->max_ascent + it->max_descent;
int line_top_y = it->current_y;
Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
int
-pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
- struct window *w;
- int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
+pos_visible_p (struct window *w, int charpos, int *x, int *y,
+ int *rtop, int *rbot, int *rowh, int *vpos)
{
struct it it;
struct text_pos top;
character. */
static INLINE int
-string_char_and_length (str, len)
- const unsigned char *str;
- int *len;
+string_char_and_length (const unsigned char *str, int *len)
{
int c;
in STRING, return the position NCHARS ahead (NCHARS >= 0). */
static struct text_pos
-string_pos_nchars_ahead (pos, string, nchars)
- struct text_pos pos;
- Lisp_Object string;
- int nchars;
+string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
{
xassert (STRINGP (string) && nchars >= 0);
for character position CHARPOS in STRING. */
static INLINE struct text_pos
-string_pos (charpos, string)
- int charpos;
- Lisp_Object string;
+string_pos (int charpos, Lisp_Object string)
{
struct text_pos pos;
xassert (STRINGP (string));
means recognize multibyte characters. */
static struct text_pos
-c_string_pos (charpos, s, multibyte_p)
- int charpos;
- unsigned char *s;
- int multibyte_p;
+c_string_pos (int charpos, const unsigned char *s, int multibyte_p)
{
struct text_pos pos;
non-zero means recognize multibyte characters. */
static int
-number_of_chars (s, multibyte_p)
- unsigned char *s;
- int multibyte_p;
+number_of_chars (const unsigned char *s, int multibyte_p)
{
int nchars;
NEWPOS->charpos must be >= POS.charpos. */
static void
-compute_string_pos (newpos, pos, string)
- struct text_pos *newpos, pos;
- Lisp_Object string;
+compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
{
xassert (STRINGP (string));
xassert (CHARPOS (*newpos) >= CHARPOS (pos));
frame F. FACE_ID specifies what line's height to estimate. */
int
-estimate_mode_line_height (f, face_id)
- struct frame *f;
- enum face_id face_id;
+estimate_mode_line_height (struct frame *f, enum face_id face_id)
{
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
not force the value into range. */
void
-pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
- FRAME_PTR f;
- register int pix_x, pix_y;
- int *x, *y;
- NativeRectangle *bounds;
- int noclip;
+pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
+ int *x, int *y, NativeRectangle *bounds, int noclip)
{
#ifdef HAVE_WINDOW_SYSTEM
return 0. */
int
-glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
- struct window *w;
- int hpos, vpos;
- int *frame_x, *frame_y;
+glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
+ int *frame_x, int *frame_y)
{
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
static
struct glyph *
-x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
- struct window *w;
- int x, y;
- int *hpos, *vpos, *dx, *dy, *area;
+x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
+ int *dx, int *dy, int *area)
{
struct glyph *glyph, *end;
struct glyph_row *row = NULL;
Takes pseudo-windows into account. */
void
-frame_to_window_pixel_xy (w, x, y)
- struct window *w;
- int *x, *y;
+frame_to_window_pixel_xy (struct window *w, int *x, int *y)
{
if (w->pseudo_window_p)
{
Return the number of stored rectangles. */
int
-get_glyph_string_clip_rects (s, rects, n)
- struct glyph_string *s;
- NativeRectangle *rects;
- int n;
+get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
{
XRectangle r;
Return in *NR the clipping rectangle for glyph string S. */
void
-get_glyph_string_clip_rect (s, nr)
- struct glyph_string *s;
- NativeRectangle *nr;
+get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
{
get_glyph_string_clip_rects (s, nr, 1);
}
*/
void
-get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
- struct window *w;
- struct glyph_row *row;
- struct glyph *glyph;
- int *xp, *yp, *heightp;
+get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
+ struct glyph *glyph, int *xp, int *yp, int *heightp)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
int x, y, wd, h, h0, y0;
*/
void
-remember_mouse_glyph (f, gx, gy, rect)
- struct frame *f;
- int gx, gy;
- NativeRectangle *rect;
+remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
{
Lisp_Object window;
struct window *w;
/* Error handler for safe_eval and safe_call. */
static Lisp_Object
-safe_eval_handler (arg)
- Lisp_Object arg;
+safe_eval_handler (Lisp_Object arg)
{
add_to_log ("Error during redisplay: %s", arg, Qnil);
return Qnil;
redisplay during the evaluation. */
Lisp_Object
-safe_call (nargs, args)
- int nargs;
- Lisp_Object *args;
+safe_call (int nargs, Lisp_Object *args)
{
Lisp_Object val;
Return the result, or nil if something went wrong. */
Lisp_Object
-safe_call1 (fn, arg)
- Lisp_Object fn, arg;
+safe_call1 (Lisp_Object fn, Lisp_Object arg)
{
Lisp_Object args[2];
args[0] = fn;
the desired matrix of W. */
void
-init_iterator (it, w, charpos, bytepos, row, base_face_id)
- struct it *it;
- struct window *w;
- int charpos, bytepos;
- struct glyph_row *row;
- enum face_id base_face_id;
+init_iterator (struct it *it, struct window *w,
+ EMACS_INT charpos, EMACS_INT bytepos,
+ struct glyph_row *row, enum face_id base_face_id)
{
int highlight_region_p;
enum face_id remapped_base_face_id = base_face_id;
}
/* Clear IT. */
- bzero (it, sizeof *it);
+ memset (it, 0, sizeof *it);
it->current.overlay_string_index = -1;
it->current.dpvec_index = -1;
it->base_face_id = remapped_base_face_id;
/* Initialize IT for the display of window W with window start POS. */
void
-start_display (it, w, pos)
- struct it *it;
- struct window *w;
- struct text_pos pos;
+start_display (struct it *it, struct window *w, struct text_pos pos)
{
struct glyph_row *row;
int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
text. W is the window we display, for text property lookup. */
static int
-in_ellipses_for_invisible_text_p (pos, w)
- struct display_pos *pos;
- struct window *w;
+in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
{
Lisp_Object prop, window;
int ellipses_p = 0;
is zero if there are overlay strings with newlines at POS. */
static int
-init_from_display_pos (it, w, pos)
- struct it *it;
- struct window *w;
- struct display_pos *pos;
+init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
{
- int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
+ EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
int i, overlay_strings_with_newlines = 0;
/* If POS specifies a position in a display vector, this might
starting at ROW->start. */
static void
-init_to_row_start (it, w, row)
- struct it *it;
- struct window *w;
- struct glyph_row *row;
+init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
{
init_from_display_pos (it, w, &row->start);
it->start = row->start;
end position. */
static int
-init_to_row_end (it, w, row)
- struct it *it;
- struct window *w;
- struct glyph_row *row;
+init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
{
int success = 0;
to stop. */
static void
-handle_stop (it)
- struct it *it;
+handle_stop (struct it *it)
{
enum prop_handled handled;
int handle_overlay_change_p;
information for IT's current position. */
static void
-compute_stop_pos (it)
- struct it *it;
+compute_stop_pos (struct it *it)
{
register INTERVAL iv, next_iv;
Lisp_Object object, limit, position;
- EMACS_INT charpos, bytepos;
+ EMACS_INT charpos, bytepos, stoppos;
/* If nowhere else, stop at the end. */
it->stop_charpos = it->end_charpos;
}
}
+ if (it->bidi_p && it->bidi_it.scan_dir < 0)
+ stoppos = -1;
+ else
+ stoppos = it->stop_charpos;
composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
- it->stop_charpos, it->string);
+ stoppos, it->string);
xassert (STRINGP (it->string)
|| (it->stop_charpos >= BEGV
xmalloc. */
static EMACS_INT
-next_overlay_change (pos)
- EMACS_INT pos;
+next_overlay_change (EMACS_INT pos)
{
int noverlays;
EMACS_INT endpos;
regions of text. */
static enum prop_handled
-handle_fontified_prop (it)
- struct it *it;
+handle_fontified_prop (struct it *it)
{
Lisp_Object prop, pos;
enum prop_handled handled = HANDLED_NORMALLY;
Called from handle_stop. */
static enum prop_handled
-handle_face_prop (it)
- struct it *it;
+handle_face_prop (struct it *it)
{
int new_face_id;
EMACS_INT next_stop;
Otherwise, use the iterator's base_face_id. */
static int
-underlying_face_id (it)
- struct it *it;
+underlying_face_id (struct it *it)
{
int face_id = it->base_face_id, i;
position. Value is the id of the face. */
static int
-face_before_or_after_it_pos (it, before_p)
- struct it *it;
- int before_p;
+face_before_or_after_it_pos (struct it *it, int before_p)
{
int face_id, limit;
EMACS_INT next_check_charpos;
position. Called from handle_stop. */
static enum prop_handled
-handle_invisible_prop (it)
- struct it *it;
+handle_invisible_prop (struct it *it)
{
enum prop_handled handled = HANDLED_NORMALLY;
if (STRINGP (it->string))
{
- extern Lisp_Object Qinvisible;
Lisp_Object prop, end_charpos, limit, charpos;
/* Get the value of the invisible text property at the
Replaces LEN characters from buffer. */
static void
-setup_for_ellipsis (it, len)
- struct it *it;
- int len;
+setup_for_ellipsis (struct it *it, int len)
{
/* Use the display table definition for `...'. Invalid glyphs
will be handled by the method returning elements from dpvec. */
Otherwise we return HANDLED_NORMALLY. */
static enum prop_handled
-handle_display_prop (it)
- struct it *it;
+handle_display_prop (struct it *it)
{
Lisp_Object prop, object, overlay;
struct text_pos *position;
if (CONSP (prop)
/* Simple properties. */
&& !EQ (XCAR (prop), Qimage)
+ && !EQ (XCAR (prop), Qxwidget)
&& !EQ (XCAR (prop), Qspace)
&& !EQ (XCAR (prop), Qwhen)
&& !EQ (XCAR (prop), Qslice)
at START_POS in OBJECT. */
static struct text_pos
-display_prop_end (it, object, start_pos)
- struct it *it;
- Lisp_Object object;
- struct text_pos start_pos;
+display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
{
Lisp_Object end;
struct text_pos end_pos;
of buffer or string text. */
static int
-handle_single_display_spec (it, spec, object, overlay, position,
- display_replaced_before_p)
- struct it *it;
- Lisp_Object spec;
- Lisp_Object object;
- Lisp_Object overlay;
- struct text_pos *position;
- int display_replaced_before_p;
+handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
+ Lisp_Object overlay, struct text_pos *position,
+ int display_replaced_before_p)
{
Lisp_Object form;
Lisp_Object location, value;
struct text_pos start_pos, save_pos;
int valid_p;
+ printf("handle_single_display_spec:\n");
/* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
If the result is non-nil, use VALUE instead of SPEC. */
LOCATION specifies where to display: `left-margin',
`right-margin' or nil. */
+
+ printf("handle_single_display_spec xwidgetp:%d imagep:%d spacep:%d display_replaced_before_p:%d stringp:%d\n",
+ XWIDGETP(value),
+ valid_image_p (value),
+ (CONSP (value) && EQ (XCAR (value), Qspace)),
+ display_replaced_before_p,
+ STRINGP (value));
+
valid_p = (STRINGP (value)
#ifdef HAVE_WINDOW_SYSTEM
|| (FRAME_WINDOW_P (it->f) && valid_image_p (value))
#endif /* not HAVE_WINDOW_SYSTEM */
- || (CONSP (value) && EQ (XCAR (value), Qspace)));
+ || (CONSP (value) && EQ (XCAR (value), Qspace))
+ || XWIDGETP(value)
+ );
if (valid_p && !display_replaced_before_p)
{
it->object = value;
*position = it->position = start_pos;
}
+ else if (XWIDGETP(value))
+ {
+ printf("handle_single_display_spec: im an xwidget!!\n");
+ it->what = IT_XWIDGET;
+ it->method = GET_FROM_XWIDGET;
+ it->position = start_pos;
+ it->object = NILP (object) ? it->w->buffer : object;
+ *position = start_pos;
+
+ it->xwidget_id=lookup_xwidget(value);
+ assert_valid_xwidget_id(it->xwidget_id,"handle_single_display_spec");
+ }
#ifdef HAVE_WINDOW_SYSTEM
- else
+ else //if nothing else, its an image
{
it->what = IT_IMAGE;
it->image_id = lookup_image (it->f, value);
treated as intangible. */
static int
-single_display_spec_intangible_p (prop)
- Lisp_Object prop;
+single_display_spec_intangible_p (Lisp_Object prop)
{
/* Skip over `when FORM'. */
if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
return (CONSP (prop)
&& (EQ (XCAR (prop), Qimage)
- || EQ (XCAR (prop), Qspace)));
+ || EQ (XCAR (prop), Qspace)
+ || XWIDGETP(prop)));
}
treated as intangible. */
int
-display_prop_intangible_p (prop)
- Lisp_Object prop;
+display_prop_intangible_p (Lisp_Object prop)
{
if (CONSP (prop)
&& CONSP (XCAR (prop))
/* Return 1 if PROP is a display sub-property value containing STRING. */
static int
-single_display_spec_string_p (prop, string)
- Lisp_Object prop, string;
+single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
{
if (EQ (string, prop))
return 1;
/* Return 1 if STRING appears in the `display' property PROP. */
static int
-display_prop_string_p (prop, string)
- Lisp_Object prop, string;
+display_prop_string_p (Lisp_Object prop, Lisp_Object string)
{
if (CONSP (prop)
&& CONSP (XCAR (prop))
called asynchronously from note_mouse_highlight. */
static EMACS_INT
-string_buffer_position_lim (w, string, from, to, back_p)
- struct window *w;
- Lisp_Object string;
- EMACS_INT from, to;
- int back_p;
+string_buffer_position_lim (struct window *w, Lisp_Object string,
+ EMACS_INT from, EMACS_INT to, int back_p)
{
Lisp_Object limit, prop, pos;
int found = 0;
called asynchronously from note_mouse_highlight. */
EMACS_INT
-string_buffer_position (w, string, around_charpos)
- struct window *w;
- Lisp_Object string;
- EMACS_INT around_charpos;
+string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
{
Lisp_Object limit, prop, pos;
const int MAX_DISTANCE = 1000;
position. Called from handle_stop. */
static enum prop_handled
-handle_composition_prop (it)
- struct it *it;
+handle_composition_prop (struct it *it)
{
Lisp_Object prop, string;
EMACS_INT pos, pos_byte, start, end;
Called from handle_stop. */
static enum prop_handled
-handle_overlay_change (it)
- struct it *it;
+handle_overlay_change (struct it *it)
{
if (!STRINGP (it->string) && get_overlay_strings (it, 0))
return HANDLED_RECOMPUTE_PROPS;
Otherwise IT->string is set to nil. */
static void
-next_overlay_string (it)
- struct it *it;
+next_overlay_string (struct it *it)
{
++it->current.overlay_string_index;
if (it->current.overlay_string_index == it->n_overlay_strings)
static int
-compare_overlay_entries (e1, e2)
- void *e1, *e2;
+compare_overlay_entries (const void *e1, const void *e2)
{
struct overlay_entry *entry1 = (struct overlay_entry *) e1;
struct overlay_entry *entry2 = (struct overlay_entry *) e2;
compare_overlay_entries. */
static void
-load_overlay_strings (it, charpos)
- struct it *it;
- int charpos;
+load_overlay_strings (struct it *it, int charpos)
{
- extern Lisp_Object Qwindow, Qpriority;
Lisp_Object overlay, window, str, invisible;
struct Lisp_Overlay *ov;
int start, end;
entries = \
(struct overlay_entry *) alloca (new_size \
* sizeof *entries); \
- bcopy (old, entries, size * sizeof *entries); \
+ memcpy (entries, old, size * sizeof *entries); \
size = new_size; \
} \
\
least one overlay string was found. */
static int
-get_overlay_strings_1 (it, charpos, compute_stop_p)
- struct it *it;
- int charpos;
- int compute_stop_p;
+get_overlay_strings_1 (struct it *it, int charpos, int compute_stop_p)
{
/* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
process. This fills IT->overlay_strings with strings, and sets
}
static int
-get_overlay_strings (it, charpos)
- struct it *it;
- int charpos;
+get_overlay_strings (struct it *it, int charpos)
{
it->string = Qnil;
it->method = GET_FROM_BUFFER;
processed. */
static void
-push_it (it)
- struct it *it;
+push_it (struct it *it)
{
struct iterator_stack_entry *p;
case GET_FROM_STRETCH:
p->u.stretch.object = it->object;
break;
+ case GET_FROM_XWIDGET:
+ p->u.xwidget.object = it->object;
+ break;
+
}
p->position = it->position;
p->current = it->current;
}
static void
-iterate_out_of_display_property (it)
- struct it *it;
+iterate_out_of_display_property (struct it *it)
{
/* Maybe initialize paragraph direction. If we are at the beginning
of a new paragraph, next_element_from_buffer may not have a
elements from an overlay string, or from a buffer. */
static void
-pop_it (it)
- struct it *it;
+pop_it (struct it *it)
{
struct iterator_stack_entry *p;
it->object = p->u.image.object;
it->slice = p->u.image.slice;
break;
+ case GET_FROM_XWIDGET:
+ it->object = p->u.xwidget.object;
+ break;
case GET_FROM_STRETCH:
it->object = p->u.comp.object;
break;
/* Set IT's current position to the previous line start. */
static void
-back_to_previous_line_start (it)
- struct it *it;
+back_to_previous_line_start (struct it *it)
{
IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
leads to wrong cursor motion. */
static int
-forward_to_next_line_start (it, skipped_p)
- struct it *it;
- int *skipped_p;
+forward_to_next_line_start (struct it *it, int *skipped_p)
{
int old_selective, newline_found_p, n;
const int MAX_NEWLINE_DISTANCE = 500;
IT->hpos. */
static void
-back_to_previous_visible_line_start (it)
- struct it *it;
+back_to_previous_visible_line_start (struct it *it)
{
while (IT_CHARPOS (*it) > BEGV)
{
face information etc. */
void
-reseat_at_previous_visible_line_start (it)
- struct it *it;
+reseat_at_previous_visible_line_start (struct it *it)
{
back_to_previous_visible_line_start (it);
reseat (it, it->current.pos, 1);
is invisible because of text properties. */
static void
-reseat_at_next_visible_line_start (it, on_newline_p)
- struct it *it;
- int on_newline_p;
+reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
{
int newline_found_p, skipped_p = 0;
IT->check_charpos of a property. */
static void
-reseat (it, pos, force_p)
- struct it *it;
- struct text_pos pos;
- int force_p;
+reseat (struct it *it, struct text_pos pos, int force_p)
{
int original_pos = IT_CHARPOS (*it);
IT->stop_pos to POS, also. */
static void
-reseat_1 (it, pos, set_stop_p)
- struct it *it;
- struct text_pos pos;
- int set_stop_p;
+reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
{
/* Don't call this function when scanning a C string. */
xassert (it->s == NULL);
calling this function. */
static void
-reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
- struct it *it;
- unsigned char *s;
- Lisp_Object string;
- int charpos;
- int precision, field_width, multibyte;
+reseat_to_string (struct it *it, const unsigned char *s, Lisp_Object string,
+ int charpos, int precision, int field_width, int multibyte)
{
/* No region in strings. */
it->region_beg_charpos = it->region_end_charpos = -1;
it->stop_charpos = -1;
/* Set iterator position and end position. */
- bzero (&it->current, sizeof it->current);
+ memset (&it->current, 0, sizeof it->current);
it->current.overlay_string_index = -1;
it->current.dpvec_index = -1;
xassert (charpos >= 0);
/* Map enum it_method value to corresponding next_element_from_* function. */
-static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
+static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
{
next_element_from_buffer,
next_element_from_display_vector,
next_element_from_string,
next_element_from_c_string,
next_element_from_image,
- next_element_from_stretch
+ next_element_from_stretch,
+ next_element_from_xwidget
};
#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
static int last_escape_glyph_merged_face_id = 0;
int
-get_next_display_element (it)
- struct it *it;
+get_next_display_element (struct it *it)
{
/* Non-zero means that we found a display element. Zero means that
we hit the end of what we iterate over. Performance note: the
struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
nbsp_or_shy = char_is_other;
- int decoded = it->c;
+ int c = it->c; /* This is the character to display. */
+
+ if (! it->multibyte_p && ! ASCII_CHAR_P (c))
+ {
+ xassert (SINGLE_BYTE_CHAR_P (c));
+ if (unibyte_display_via_language_environment)
+ {
+ c = DECODE_CHAR (unibyte, c);
+ if (c < 0)
+ c = BYTE8_TO_CHAR (it->c);
+ }
+ else
+ c = BYTE8_TO_CHAR (it->c);
+ }
if (it->dp
- && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
+ && (dv = DISP_CHAR_VECTOR (it->dp, c),
VECTORP (dv)))
{
struct Lisp_Vector *v = XVECTOR (dv);
goto get_next;
}
- if (unibyte_display_via_language_environment
- && !ASCII_CHAR_P (it->c))
- decoded = DECODE_CHAR (unibyte, it->c);
-
- if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
- {
- if (it->multibyte_p)
- nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
- : it->c == 0xAD ? char_is_soft_hyphen
- : char_is_other);
- else if (unibyte_display_via_language_environment)
- nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
- : decoded == 0xAD ? char_is_soft_hyphen
- : char_is_other);
- }
+ if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
+ nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
+ : c == 0xAD ? char_is_soft_hyphen
+ : char_is_other);
/* Translate control characters into `\003' or `^C' form.
Control characters coming from a display table entry are
the translation. This could easily be changed but I
don't believe that it is worth doing.
- If it->multibyte_p is nonzero, non-printable non-ASCII
- characters are also translated to octal form.
+ NBSP and SOFT-HYPEN are property translated too.
- If it->multibyte_p is zero, eight-bit characters that
- don't have corresponding multibyte char code are also
+ Non-printable characters and raw-byte characters are also
translated to octal form. */
- if ((it->c < ' '
+ if (((c < ' ' || c == 127) /* ASCII control chars */
? (it->area != TEXT_AREA
/* In mode line, treat \n, \t like other crl chars. */
- || (it->c != '\t'
+ || (c != '\t'
&& it->glyph_row
&& (it->glyph_row->mode_line_p || it->avoid_cursor_p))
- || (it->c != '\n' && it->c != '\t'))
+ || (c != '\n' && c != '\t'))
: (nbsp_or_shy
- || (it->multibyte_p
- ? ! CHAR_PRINTABLE_P (it->c)
- : (! unibyte_display_via_language_environment
- ? it->c >= 0x80
- : (decoded >= 0x80 && decoded < 0xA0))))))
+ || CHAR_BYTE8_P (c)
+ || ! CHAR_PRINTABLE_P (c))))
{
- /* IT->c is a control character which must be displayed
+ /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
+ or a non-printable character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
can be defined in the display table. Fill
IT->ctl_chars with glyphs for what we have to
/* Handle control characters with ^. */
- if (it->c < 128 && it->ctl_arrow_p)
+ if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
{
int g;
}
XSETINT (it->ctl_chars[0], g);
- XSETINT (it->ctl_chars[1], it->c ^ 0100);
+ XSETINT (it->ctl_chars[1], c ^ 0100);
ctl_len = 2;
goto display_control;
}
face_id = merge_faces (it->f, Qnobreak_space, 0,
it->face_id);
- it->c = ' ';
+ c = ' ';
XSETINT (it->ctl_chars[0], ' ');
ctl_len = 1;
goto display_control;
if (EQ (Vnobreak_char_display, Qt)
&& nbsp_or_shy == char_is_soft_hyphen)
{
- it->c = '-';
XSETINT (it->ctl_chars[0], '-');
ctl_len = 1;
goto display_control;
if (nbsp_or_shy)
{
XSETINT (it->ctl_chars[0], escape_glyph);
- it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
- XSETINT (it->ctl_chars[1], it->c);
+ c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
+ XSETINT (it->ctl_chars[1], c);
ctl_len = 2;
goto display_control;
}
{
- unsigned char str[MAX_MULTIBYTE_LENGTH];
- int len;
- int i;
+ char str[10];
+ int len, i;
- /* Set IT->ctl_chars[0] to the glyph for `\\'. */
- if (CHAR_BYTE8_P (it->c))
- {
- str[0] = CHAR_TO_BYTE8 (it->c);
- len = 1;
- }
- else if (it->c < 256)
- {
- str[0] = it->c;
- len = 1;
- }
- else
- {
- /* It's an invalid character, which shouldn't
- happen actually, but due to bugs it may
- happen. Let's print the char as is, there's
- not much meaningful we can do with it. */
- str[0] = it->c;
- str[1] = it->c >> 8;
- str[2] = it->c >> 16;
- str[3] = it->c >> 24;
- len = 4;
- }
+ if (CHAR_BYTE8_P (c))
+ /* Display \200 instead of \17777600. */
+ c = CHAR_TO_BYTE8 (c);
+ len = sprintf (str, "%03o", c);
+ XSETINT (it->ctl_chars[0], escape_glyph);
for (i = 0; i < len; i++)
- {
- int g;
- XSETINT (it->ctl_chars[i * 4], escape_glyph);
- /* Insert three more glyphs into IT->ctl_chars for
- the octal display of the character. */
- g = ((str[i] >> 6) & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 1], g);
- g = ((str[i] >> 3) & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 2], g);
- g = (str[i] & 7) + '0';
- XSETINT (it->ctl_chars[i * 4 + 3], g);
- }
- ctl_len = len * 4;
+ XSETINT (it->ctl_chars[i + 1], str[i]);
+ ctl_len = len + 1;
}
display_control:
it->ellipsis_p = 0;
goto get_next;
}
+ it->char_to_display = c;
+ }
+ else if (success_p)
+ {
+ it->char_to_display = it->c;
}
}
: STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
: IT_CHARPOS (*it));
- it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
+ it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
+ it->string);
}
}
#endif
decrement position function which would not be easy to write. */
void
-set_iterator_to_next (it, reseat_p)
- struct it *it;
- int reseat_p;
+set_iterator_to_next (struct it *it, int reseat_p)
{
/* Reset flags indicating start and end of a sequence of characters
with box. Reset them at the start of this function because
case GET_FROM_IMAGE:
case GET_FROM_STRETCH:
+ case GET_FROM_XWIDGET:
/* The position etc with which we have to proceed are on
the stack. The position may be at the end of a string,
if the `display' property takes up the whole string. */
is restored into IT->face_id in set_iterator_to_next. */
static int
-next_element_from_display_vector (it)
- struct it *it;
+next_element_from_display_vector (struct it *it)
{
Lisp_Object gc;
overlay string. */
static int
-next_element_from_string (it)
- struct it *it;
+next_element_from_string (struct it *it)
{
struct text_pos position;
reached, including padding spaces. */
static int
-next_element_from_c_string (it)
- struct it *it;
+next_element_from_c_string (struct it *it)
{
int success_p = 1;
ellipsis if an ellipsis is to be displayed. */
static int
-next_element_from_ellipsis (it)
- struct it *it;
+next_element_from_ellipsis (struct it *it)
{
if (it->selective_display_ellipsis_p)
setup_for_ellipsis (it, it->len);
static int
-next_element_from_image (it)
- struct it *it;
+next_element_from_image (struct it *it)
{
it->what = IT_IMAGE;
+ it->ignore_overlay_strings_at_pos_p = 0;
+ return 1;
+}
+
+/* im not sure about this FIXME JAVE*/
+static int
+next_element_from_xwidget (it)
+ struct it *it;
+{
+ it->what = IT_XWIDGET;
+ assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget");
+ //this is shaky because why do we set "what" if we dont set the other parts??
+ printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id);
return 1;
}
+
/* Fill iterator IT with next display element from a stretch glyph
property. IT->object is the value of the text property. Value is
always 1. */
static int
-next_element_from_stretch (it)
- struct it *it;
+next_element_from_stretch (struct it *it)
{
it->what = IT_STRETCH;
return 1;
position. */
static void
-handle_stop_backwards (it, charpos)
- struct it *it;
- EMACS_INT charpos;
+handle_stop_backwards (struct it *it, EMACS_INT charpos)
{
EMACS_INT where_we_are = IT_CHARPOS (*it);
struct display_pos save_current = it->current;
end. */
static int
-next_element_from_buffer (it)
- struct it *it;
+next_element_from_buffer (struct it *it)
{
int success_p = 1;
/* Run the redisplay end trigger hook for IT. */
static void
-run_redisplay_end_trigger_hook (it)
- struct it *it;
+run_redisplay_end_trigger_hook (struct it *it)
{
Lisp_Object args[3];
next_element_from_string when necessary. */
static int
-next_element_from_composition (it)
- struct it *it;
+next_element_from_composition (struct it *it)
{
it->what = IT_COMPOSITION;
it->len = it->cmp_it.nbytes;
TO_CHARPOS. */
void
-move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
- struct it *it;
- int to_charpos, to_x, to_y, to_vpos;
- int op;
+move_it_to (struct it *it, int to_charpos, int to_x, int to_y, int to_vpos, int op)
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
int line_height, line_start_x = 0, reached = 0;
set to the top of the line moved to. */
void
-move_it_vertically_backward (it, dy)
- struct it *it;
- int dy;
+move_it_vertically_backward (struct it *it, int dy)
{
int nlines, h;
struct it it2, it3;
end, IT will be on the start of a screen line. */
void
-move_it_vertically (it, dy)
- struct it *it;
- int dy;
+move_it_vertically (struct it *it, int dy)
{
if (dy <= 0)
move_it_vertically_backward (it, -dy);
/* Move iterator IT past the end of the text line it is in. */
void
-move_it_past_eol (it)
- struct it *it;
+move_it_past_eol (struct it *it)
{
enum move_it_result rc;
truncate-lines nil. */
void
-move_it_by_lines (it, dvpos, need_y_p)
- struct it *it;
- int dvpos, need_y_p;
+move_it_by_lines (struct it *it, int dvpos, int need_y_p)
{
struct position pos;
/* Return 1 if IT points into the middle of a display vector. */
int
-in_display_vector_p (it)
- struct it *it;
+in_display_vector_p (struct it *it)
{
return (it->method == GET_FROM_DISPLAY_VECTOR
&& it->current.dpvec_index > 0
to *Messages*. */
void
-add_to_log (format, arg1, arg2)
- char *format;
- Lisp_Object arg1, arg2;
+add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
{
Lisp_Object args[3];
Lisp_Object msg, fmt;
len = SBYTES (msg) + 1;
SAFE_ALLOCA (buffer, char *, len);
- bcopy (SDATA (msg), buffer, len);
+ memcpy (buffer, SDATA (msg), len);
message_dolog (buffer, len - 1, 1, 0);
SAFE_FREE ();
/* Output a newline in the *Messages* buffer if "needs" one. */
void
-message_log_maybe_newline ()
+message_log_maybe_newline (void)
{
if (message_log_need_newline)
message_dolog ("", 0, 1, 0);
so the buffer M must NOT point to a Lisp string. */
void
-message_dolog (m, nbytes, nlflag, multibyte)
- const char *m;
- int nbytes, nlflag, multibyte;
+message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
{
if (!NILP (Vmemory_full))
return;
value N > 1 if we should also append " [N times]". */
static int
-message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
- int prev_bol, this_bol;
- int prev_bol_byte, this_bol_byte;
+message_log_check_duplicate (int prev_bol, int prev_bol_byte,
+ int this_bol, int this_bol_byte)
{
int i;
int len = Z_BYTE - 1 - this_bol_byte;
This may GC, so the buffer M must NOT point to a Lisp string. */
void
-message2 (m, nbytes, multibyte)
- const char *m;
- int nbytes;
- int multibyte;
+message2 (const char *m, int nbytes, int multibyte)
{
/* First flush out any partial line written with print. */
message_log_maybe_newline ();
/* The non-logging counterpart of message2. */
void
-message2_nolog (m, nbytes, multibyte)
- const char *m;
- int nbytes, multibyte;
+message2_nolog (const char *m, int nbytes, int multibyte)
{
struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
This function cancels echoing. */
void
-message3 (m, nbytes, multibyte)
- Lisp_Object m;
- int nbytes;
- int multibyte;
+message3 (Lisp_Object m, int nbytes, int multibyte)
{
struct gcpro gcpro1;
USE_SAFE_ALLOCA;
SAFE_ALLOCA (buffer, char *, nbytes);
- bcopy (SDATA (m), buffer, nbytes);
+ memcpy (buffer, SDATA (m), nbytes);
message_dolog (buffer, nbytes, 1, multibyte);
SAFE_FREE ();
}
and make this cancel echoing. */
void
-message3_nolog (m, nbytes, multibyte)
- Lisp_Object m;
- int nbytes, multibyte;
+message3_nolog (Lisp_Object m, int nbytes, int multibyte)
{
struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
that was alloca'd. */
void
-message1 (m)
- char *m;
+message1 (const char *m)
{
message2 (m, (m ? strlen (m) : 0), 0);
}
/* The non-logging counterpart of message1. */
void
-message1_nolog (m)
- char *m;
+message1_nolog (const char *m)
{
message2_nolog (m, (m ? strlen (m) : 0), 0);
}
which gets replaced with STRING. */
void
-message_with_string (m, string, log)
- char *m;
- Lisp_Object string;
- int log;
+message_with_string (const char *m, Lisp_Object string, int log)
{
CHECK_STRING (string);
/* Dump an informative message to the minibuf. If M is 0, clear out
any existing message, and let the mini-buffer text show through. */
-/* VARARGS 1 */
-void
-message (m, a1, a2, a3)
- char *m;
- EMACS_INT a1, a2, a3;
+static void
+vmessage (const char *m, va_list ap)
{
if (noninteractive)
{
if (noninteractive_need_newline)
putc ('\n', stderr);
noninteractive_need_newline = 0;
- fprintf (stderr, m, a1, a2, a3);
+ vfprintf (stderr, m, ap);
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
if (m)
{
int len;
- char *a[3];
- a[0] = (char *) a1;
- a[1] = (char *) a2;
- a[2] = (char *) a3;
len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
+ FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
message2 (FRAME_MESSAGE_BUF (f), len, 0);
}
}
}
+void
+message (const char *m, ...)
+{
+ va_list ap;
+ va_start (ap, m);
+ vmessage (m, ap);
+ va_end (ap);
+}
+
/* The non-logging version of message. */
void
-message_nolog (m, a1, a2, a3)
- char *m;
- EMACS_INT a1, a2, a3;
+message_nolog (const char *m, ...)
{
Lisp_Object old_log_max;
+ va_list ap;
+ va_start (ap, m);
old_log_max = Vmessage_log_max;
Vmessage_log_max = Qnil;
- message (m, a1, a2, a3);
+ vmessage (m, ap);
Vmessage_log_max = old_log_max;
+ va_end (ap);
}
critical. */
void
-update_echo_area ()
+update_echo_area (void)
{
if (!NILP (echo_area_buffer[0]))
{
If they aren't, make new ones. */
static void
-ensure_echo_area_buffers ()
+ensure_echo_area_buffers (void)
{
int i;
Value is what FN returns. */
static int
-with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
- struct window *w;
- int which;
- int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
- EMACS_INT a1;
- Lisp_Object a2;
- EMACS_INT a3, a4;
+with_echo_area_buffer (struct window *w, int which,
+ int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
+ EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
Lisp_Object buffer;
int this_one, the_other, clear_buffer_p, rc;
FN called in with_echo_area_buffer. */
static Lisp_Object
-with_echo_area_buffer_unwind_data (w)
- struct window *w;
+with_echo_area_buffer_unwind_data (struct window *w)
{
int i = 0;
Lisp_Object vector, tmp;
with_echo_area_buffer_unwind_data. */
static Lisp_Object
-unwind_with_echo_area_buffer (vector)
- Lisp_Object vector;
+unwind_with_echo_area_buffer (Lisp_Object vector)
{
set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
Vdeactivate_mark = AREF (vector, 1);
non-zero means we will print multibyte. */
void
-setup_echo_area_for_printing (multibyte_p)
- int multibyte_p;
+setup_echo_area_for_printing (int multibyte_p)
{
/* If we can't find an echo area any more, exit. */
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
display the current message. */
static int
-display_echo_area (w)
- struct window *w;
+display_echo_area (struct window *w)
{
int i, no_message_p, window_height_changed_p, count;
Value is non-zero if height of W was changed. */
static int
-display_echo_area_1 (a1, a2, a3, a4)
- EMACS_INT a1;
- Lisp_Object a2;
- EMACS_INT a3, a4;
+display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
struct window *w = (struct window *) a1;
Lisp_Object window;
is active, don't shrink it. */
void
-resize_echo_area_exactly ()
+resize_echo_area_exactly (void)
{
if (BUFFERP (echo_area_buffer[0])
&& WINDOWP (echo_area_window))
resize_mini_window returns. */
static int
-resize_mini_window_1 (a1, exactly, a3, a4)
- EMACS_INT a1;
- Lisp_Object exactly;
- EMACS_INT a3, a4;
+resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
{
return resize_mini_window ((struct window *) a1, !NILP (exactly));
}
Value is non-zero if the window height has been changed. */
int
-resize_mini_window (w, exact_p)
- struct window *w;
- int exact_p;
+resize_mini_window (struct window *w, int exact_p)
{
struct frame *f = XFRAME (w->frame);
int window_height_changed_p = 0;
current message. */
Lisp_Object
-current_message ()
+current_message (void)
{
Lisp_Object msg;
static int
-current_message_1 (a1, a2, a3, a4)
- EMACS_INT a1;
- Lisp_Object a2;
- EMACS_INT a3, a4;
+current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
Lisp_Object *msg = (Lisp_Object *) a1;
worth optimizing. */
int
-push_message ()
+push_message (void)
{
Lisp_Object msg;
msg = current_message ();
/* Restore message display from the top of Vmessage_stack. */
void
-restore_message ()
+restore_message (void)
{
Lisp_Object msg;
/* Handler for record_unwind_protect calling pop_message. */
Lisp_Object
-pop_message_unwind (dummy)
- Lisp_Object dummy;
+pop_message_unwind (Lisp_Object dummy)
{
pop_message ();
return Qnil;
/* Pop the top-most entry off Vmessage_stack. */
void
-pop_message ()
+pop_message (void)
{
xassert (CONSP (Vmessage_stack));
Vmessage_stack = XCDR (Vmessage_stack);
somewhere. */
void
-check_message_stack ()
+check_message_stack (void)
{
if (!NILP (Vmessage_stack))
abort ();
time we display it---but don't redisplay it now. */
void
-truncate_echo_area (nchars)
- int nchars;
+truncate_echo_area (int nchars)
{
if (nchars == 0)
echo_area_buffer[0] = Qnil;
message to at most NCHARS characters. */
static int
-truncate_message_1 (nchars, a2, a3, a4)
- EMACS_INT nchars;
- Lisp_Object a2;
- EMACS_INT a3, a4;
+truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
if (BEG + nchars < Z)
del_range (BEG + nchars, Z);
*/
void
-set_message (s, string, nbytes, multibyte_p)
- const char *s;
- Lisp_Object string;
- int nbytes, multibyte_p;
+set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
{
message_enable_multibyte
= ((s && multibyte_p)
current. */
static int
-set_message_1 (a1, a2, nbytes, multibyte_p)
- EMACS_INT a1;
- Lisp_Object a2;
- EMACS_INT nbytes, multibyte_p;
+set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
{
const char *s = (const char *) a1;
Lisp_Object string = a2;
last displayed. */
void
-clear_message (current_p, last_displayed_p)
- int current_p, last_displayed_p;
+clear_message (int current_p, int last_displayed_p)
{
if (current_p)
{
and ensure a complete redisplay of all windows. */
static void
-clear_garbaged_frames ()
+clear_garbaged_frames (void)
{
if (frame_garbaged)
{
mini-windows height has been changed. */
static int
-echo_area_display (update_frame_p)
- int update_frame_p;
+echo_area_display (int update_frame_p)
{
Lisp_Object mini_window;
struct window *w;
}
static Lisp_Object
-unwind_format_mode_line (vector)
- Lisp_Object vector;
+unwind_format_mode_line (Lisp_Object vector)
{
mode_line_target = XINT (AREF (vector, 0));
mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
Re-allocate mode_line_noprop_buf if necessary. */
static void
-#ifdef PROTOTYPES
store_mode_line_noprop_char (char c)
-#else
-store_mode_line_noprop_char (c)
- char c;
-#endif
{
/* If output position has reached the end of the allocated buffer,
double the buffer's size. */
frame title. */
static int
-store_mode_line_noprop (str, field_width, precision)
- const unsigned char *str;
- int field_width, precision;
+store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
{
int n = 0;
int dummy, nbytes;
frame_title_format. */
static void
-x_consider_frame_title (frame)
- Lisp_Object frame;
+x_consider_frame_title (Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
higher level than this.) */
if (! STRINGP (f->name)
|| SBYTES (f->name) != len
- || bcmp (title, SDATA (f->name), len) != 0)
+ || memcmp (title, SDATA (f->name), len) != 0)
x_implicitly_set_name (f, make_string (title, len), Qnil);
}
}
appropriate. This can call eval. */
void
-prepare_menu_bars ()
+prepare_menu_bars (void)
{
int all_windows;
struct gcpro gcpro1, gcpro2;
update_tool_bar (sf, 1);
#endif
}
-
- /* Motif needs this. See comment in xmenu.c. Turn it off when
- pending_menu_activation is not defined. */
-#ifdef USE_X_TOOLKIT
- pending_menu_activation = 0;
-#endif
}
updated value of this flag, to pass to the next call. */
static int
-update_menu_bar (f, save_match_data, hooks_run)
- struct frame *f;
- int save_match_data;
- int hooks_run;
+update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
{
Lisp_Object window;
register struct window *w;
positions are relative to updated_window. */
void
-set_output_cursor (cursor)
- struct cursor_pos *cursor;
+set_output_cursor (struct cursor_pos *cursor)
{
output_cursor.hpos = cursor->hpos;
output_cursor.vpos = cursor->vpos;
selected_window and display the cursor at the given position. */
void
-x_cursor_to (vpos, hpos, y, x)
- int vpos, hpos, y, x;
+x_cursor_to (int vpos, int hpos, int y, int x)
{
struct window *w;
static Lisp_Object
-update_tool_bar_unwind (frame)
- Lisp_Object frame;
+update_tool_bar_unwind (Lisp_Object frame)
{
selected_frame = frame;
return Qnil;
and restore it here. */
static void
-update_tool_bar (f, save_match_data)
- struct frame *f;
- int save_match_data;
+update_tool_bar (struct frame *f, int save_match_data)
{
#if defined (USE_GTK) || defined (HAVE_NS)
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
been set up previously by calling prepare_menu_bars. */
static void
-build_desired_tool_bar_string (f)
- struct frame *f;
+build_desired_tool_bar_string (struct frame *f)
{
int i, size, size_needed;
struct gcpro gcpro1, gcpro2, gcpro3;
int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
int hmargin, vmargin, relief, idx, end;
- extern Lisp_Object QCrelief, QCmargin, QCconversion;
/* If image is a vector, choose the image according to the
button state. */
*/
static void
-display_tool_bar_line (it, height)
- struct it *it;
- int height;
+display_tool_bar_line (struct it *it, int height)
{
struct glyph_row *row = it->glyph_row;
int max_x = it->last_visible_x;
returned in *N_ROWS if non-NULL. */
static int
-tool_bar_lines_needed (f, n_rows)
- struct frame *f;
- int *n_rows;
+tool_bar_lines_needed (struct frame *f, int *n_rows)
{
struct window *w = XWINDOW (f->tool_bar_window);
struct it it;
DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
0, 1, 0,
doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
- (frame)
- Lisp_Object frame;
+ (Lisp_Object frame)
{
struct frame *f;
struct window *w;
height should be changed. */
static int
-redisplay_tool_bar (f)
- struct frame *f;
+redisplay_tool_bar (struct frame *f)
{
struct window *w;
struct it it;
if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
nlines != WINDOW_TOTAL_LINES (w)))
{
- extern Lisp_Object Qtool_bar_lines;
Lisp_Object frame;
int old_height = WINDOW_TOTAL_LINES (w);
frame parameter. */
if (change_height_p)
{
- extern Lisp_Object Qtool_bar_lines;
Lisp_Object frame;
int old_height = WINDOW_TOTAL_LINES (w);
int nrows;
GLYPH doesn't display a tool-bar item. */
static int
-tool_bar_item_info (f, glyph, prop_idx)
- struct frame *f;
- struct glyph *glyph;
- int *prop_idx;
+tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
{
Lisp_Object prop;
int success_p;
1 otherwise. */
static int
-get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
- struct frame *f;
- int x, y;
- struct glyph **glyph;
- int *hpos, *vpos, *prop_idx;
+get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
+ int *hpos, int *vpos, int *prop_idx)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
struct window *w = XWINDOW (f->tool_bar_window);
release. */
void
-handle_tool_bar_click (f, x, y, down_p, modifiers)
- struct frame *f;
- int x, y, down_p;
- unsigned int modifiers;
+handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
+ unsigned int modifiers)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
struct window *w = XWINDOW (f->tool_bar_window);
note_mouse_highlight. */
static void
-note_tool_bar_highlight (f, x, y)
- struct frame *f;
- int x, y;
+note_tool_bar_highlight (struct frame *f, int x, int y)
{
Lisp_Object window = f->tool_bar_window;
struct window *w = XWINDOW (window);
enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
int mouse_down_p, rc;
- /* Function note_mouse_highlight is called with negative x(y
+ /* Function note_mouse_highlight is called with negative X/Y
values when mouse moves outside of the frame. */
if (x <= 0 || y <= 0)
{
Horizontal scrolling
************************************************************************/
-static int hscroll_window_tree P_ ((Lisp_Object));
-static int hscroll_windows P_ ((Lisp_Object));
+static int hscroll_window_tree (Lisp_Object);
+static int hscroll_windows (Lisp_Object);
/* For all leaf windows in the window tree rooted at WINDOW, set their
hscroll value so that PT is (i) visible in the window, and (ii) so
changed. */
static int
-hscroll_window_tree (window)
- Lisp_Object window;
+hscroll_window_tree (Lisp_Object window)
{
int hscrolled_p = 0;
int hscroll_relative_p = FLOATP (Vhscroll_step);
of WINDOW are cleared. */
static int
-hscroll_windows (window)
- Lisp_Object window;
+hscroll_windows (Lisp_Object window)
{
int hscrolled_p = hscroll_window_tree (window);
if (hscrolled_p)
redisplay_internal for display optimization. */
static INLINE int
-text_outside_line_unchanged_p (w, start, end)
- struct window *w;
- int start, end;
+text_outside_line_unchanged_p (struct window *w, int start, int end)
{
int unchanged_p = 1;
mini-buffer if that is in use. */
void
-redisplay ()
+redisplay (void)
{
redisplay_internal (0);
}
static Lisp_Object
-overlay_arrow_string_or_property (var)
- Lisp_Object var;
+overlay_arrow_string_or_property (Lisp_Object var)
{
Lisp_Object val;
/* Return 1 if there are any overlay-arrows in current_buffer. */
static int
-overlay_arrow_in_current_buffer_p ()
+overlay_arrow_in_current_buffer_p (void)
{
Lisp_Object vlist;
has changed. */
static int
-overlay_arrows_changed_p ()
+overlay_arrows_changed_p (void)
{
Lisp_Object vlist;
/* Mark overlay arrows to be updated on next redisplay. */
static void
-update_overlay_arrows (up_to_date)
- int up_to_date;
+update_overlay_arrows (int up_to_date)
{
Lisp_Object vlist;
Return nil if no overlay arrow. */
static Lisp_Object
-overlay_arrow_at_row (it, row)
- struct it *it;
- struct glyph_row *row;
+overlay_arrow_at_row (struct it *it, struct glyph_row *row)
{
Lisp_Object vlist;
&& (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
{
if (FRAME_WINDOW_P (it->f)
+ /* FIXME: if ROW->reversed_p is set, this should test
+ the right fringe, not the left one. */
&& WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
{
#ifdef HAVE_WINDOW_SYSTEM
position. BUF and PT are the current point buffer and position. */
int
-check_point_in_composition (prev_buf, prev_pt, buf, pt)
- struct buffer *prev_buf, *buf;
- int prev_pt, pt;
+check_point_in_composition (struct buffer *prev_buf, int prev_pt,
+ struct buffer *buf, int pt)
{
EMACS_INT start, end;
Lisp_Object prop;
in window W. */
static INLINE void
-reconsider_clip_changes (w, b)
- struct window *w;
- struct buffer *b;
+reconsider_clip_changes (struct window *w, struct buffer *b)
{
if (b->clip_changed
&& !NILP (w->window_end_valid)
directly. */
static void
-select_frame_for_redisplay (frame)
- Lisp_Object frame;
+select_frame_for_redisplay (Lisp_Object frame)
{
Lisp_Object tail, tem;
Lisp_Object old = selected_frame;
causes some problems. */
static void
-redisplay_internal (preserve_echo_area)
- int preserve_echo_area;
+redisplay_internal (int preserve_echo_area)
{
struct window *w = XWINDOW (selected_window);
struct frame *f;
frames. Zero means, only selected_window is considered. */
int consider_all_windows_p;
+ printf(">>>>redisplay\n");
+ // xwidget_start_redisplay();
+
TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
/* No redisplay if running in batch mode or frame is not yet fully
if (windows_or_buffers_changed && !pause)
goto retry;
- /* Clear the face cache eventually. */
- if (consider_all_windows_p)
+ /* Clear the face and image caches.
+
+ We used to do this only if consider_all_windows_p. But the cache
+ needs to be cleared if a timer creates images in the current
+ buffer (e.g. the test case in Bug#6230). */
+
+ if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
{
- if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
- {
- clear_face_cache (0);
- clear_face_cache_count = 0;
- }
+ clear_face_cache (0);
+ clear_face_cache_count = 0;
+ }
+
#ifdef HAVE_WINDOW_SYSTEM
- if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
- {
- clear_image_caches (Qnil);
- clear_image_cache_count = 0;
- }
-#endif /* HAVE_WINDOW_SYSTEM */
+ if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
+ {
+ clear_image_caches (Qnil);
+ clear_image_cache_count = 0;
}
+#endif /* HAVE_WINDOW_SYSTEM */
end_of_redisplay:
unbind_to (count, Qnil);
RESUME_POLLING;
+ //xwidget_end_redisplay();
+
+ printf("<<<<redisplay\n");
}
called. This is useful for debugging. */
void
-redisplay_preserve_echo_area (from_where)
- int from_where;
+redisplay_preserve_echo_area (int from_where)
{
TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
failure during redisplay, for example). */
static Lisp_Object
-unwind_redisplay (val)
- Lisp_Object val;
+unwind_redisplay (Lisp_Object val)
{
Lisp_Object old_redisplaying_p, old_frame;
redisplay_internal is called. */
static void
-mark_window_display_accurate_1 (w, accurate_p)
- struct window *w;
- int accurate_p;
+mark_window_display_accurate_1 (struct window *w, int accurate_p)
{
if (BUFFERP (w->buffer))
{
be redisplayed the next time redisplay_internal is called. */
void
-mark_window_display_accurate (window, accurate_p)
- Lisp_Object window;
- int accurate_p;
+mark_window_display_accurate (Lisp_Object window, int accurate_p)
{
struct window *w;
macro DISP_CHAR_VECTOR. */
Lisp_Object
-disp_char_vector (dp, c)
- struct Lisp_Char_Table *dp;
- int c;
+disp_char_vector (struct Lisp_Char_Table *dp, int c)
{
Lisp_Object val;
/* Redisplay all leaf windows in the window tree rooted at WINDOW. */
static void
-redisplay_windows (window)
- Lisp_Object window;
+redisplay_windows (Lisp_Object window)
{
while (!NILP (window))
{
}
static Lisp_Object
-redisplay_window_error ()
+redisplay_window_error (Lisp_Object ignore)
{
displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
return Qnil;
}
static Lisp_Object
-redisplay_window_0 (window)
- Lisp_Object window;
+redisplay_window_0 (Lisp_Object window)
{
if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
redisplay_window (window, 0);
}
static Lisp_Object
-redisplay_window_1 (window)
- Lisp_Object window;
+redisplay_window_1 (Lisp_Object window)
{
if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
redisplay_window (window, 1);
Return 0 if cursor is not on this row, 1 otherwise. */
int
-set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
- struct window *w;
- struct glyph_row *row;
- struct glyph_matrix *matrix;
- int delta, delta_bytes, dy, dvpos;
+set_cursor_from_row (struct window *w, struct glyph_row *row,
+ struct glyph_matrix *matrix, int delta, int delta_bytes,
+ int dy, int dvpos)
{
struct glyph *glyph = row->glyphs[TEXT_AREA];
struct glyph *end = glyph + row->used[TEXT_AREA];
point. */
if (/* previous candidate is a glyph in TEXT_AREA of that row */
w->cursor.hpos >= 0
- && w->cursor.hpos < MATRIX_ROW_USED(matrix, w->cursor.vpos)
+ && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
&& BUFFERP (g1->object)
&& (g1->charpos == pt_old /* an exact match always wins */
|| (BUFFERP (glyph->object)
We assume that the window's buffer is really current. */
static INLINE struct text_pos
-run_window_scroll_functions (window, startp)
- Lisp_Object window;
- struct text_pos startp;
+run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
{
struct window *w = XWINDOW (window);
SET_MARKER_FROM_TEXT_POS (w->start, startp);
as if point had gone off the screen. */
static int
-cursor_row_fully_visible_p (w, force_p, current_matrix_p)
- struct window *w;
- int force_p;
- int current_matrix_p;
+cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
{
struct glyph_matrix *matrix;
struct glyph_row *row;
};
static int
-try_scrolling (window, just_this_one_p, scroll_conservatively,
- scroll_step, temp_scroll_step, last_line_misfit)
- Lisp_Object window;
- int just_this_one_p;
- EMACS_INT scroll_conservatively, scroll_step;
- int temp_scroll_step;
- int last_line_misfit;
+try_scrolling (Lisp_Object window, int just_this_one_p,
+ EMACS_INT scroll_conservatively, EMACS_INT scroll_step,
+ int temp_scroll_step, int last_line_misfit)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
if (PT > CHARPOS (it.current.pos))
{
int y0 = line_bottom_y (&it);
-
- /* Compute the distance from the scroll margin to PT
- (including the height of the cursor line). Moving the
- iterator unconditionally to PT can be slow if PT is far
- away, so stop 10 lines past the window bottom (is there a
- way to do the right thing quickly?). */
- move_it_to (&it, PT, -1,
- it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
+ /* Compute how many pixels below window bottom to stop searching
+ for PT. This avoids costly search for PT that is far away if
+ the user limited scrolling by a small number of lines, but
+ always finds PT if scroll_conservatively is set to a large
+ number, such as most-positive-fixnum. */
+ int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
+ int y_to_move =
+ slack >= INT_MAX - it.last_visible_y
+ ? INT_MAX
+ : it.last_visible_y + slack;
+
+ /* Compute the distance from the scroll margin to PT or to
+ the scroll limit, whichever comes first. This should
+ include the height of the cursor line, to make that line
+ fully visible. */
+ move_it_to (&it, PT, -1, y_to_move,
-1, MOVE_TO_POS | MOVE_TO_Y);
dy = line_bottom_y (&it) - y0;
return SCROLLING_FAILED;
start_display (&it, w, startp);
- move_it_vertically (&it, amount_to_scroll);
+ if (scroll_max < INT_MAX)
+ move_it_vertically (&it, amount_to_scroll);
+ else
+ {
+ /* Extra precision for users who set scroll-conservatively
+ to most-positive-fixnum: make sure the amount we scroll
+ the window start is never less than amount_to_scroll,
+ which was computed as distance from window bottom to
+ point. This matters when lines at window top and lines
+ below window bottom have different height. */
+ struct it it1 = it;
+ /* We use a temporary it1 because line_bottom_y can modify
+ its argument, if it moves one line down; see there. */
+ int start_y = line_bottom_y (&it1);
+
+ do {
+ move_it_by_lines (&it, 1, 1);
+ it1 = it;
+ } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
+ }
/* If STARTP is unchanged, move it down another screen line. */
if (CHARPOS (it.current.pos) == CHARPOS (startp))
screen line with the minimum distance from the old start W->start. */
static int
-compute_window_start_on_continuation_line (w)
- struct window *w;
+compute_window_start_on_continuation_line (struct window *w)
{
struct text_pos pos, start_pos;
int window_start_changed_p = 0;
};
static int
-try_cursor_movement (window, startp, scroll_step)
- Lisp_Object window;
- struct text_pos startp;
- int *scroll_step;
+try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
++row;
if (!row->enabled_p)
rc = CURSOR_MOVEMENT_MUST_SCROLL;
- /* If rows are bidi-reordered, back up until we find a row
- that does not belong to a continuation line. This is
- because we must consider all rows of a continued line as
- candidates for cursor positioning, since row start and
- end positions change non-linearly with vertical position
- in such rows. */
- /* FIXME: Revisit this when glyph ``spilling'' in
- continuation lines' rows is implemented for
- bidi-reordered rows. */
- if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
- {
- while (MATRIX_ROW_CONTINUATION_LINE_P (row))
- {
- xassert (row->enabled_p);
- --row;
- /* If we hit the beginning of the displayed portion
- without finding the first row of a continued
- line, give up. */
- if (row <= w->current_matrix->rows)
- {
- rc = CURSOR_MOVEMENT_MUST_SCROLL;
- break;
- }
-
- }
- }
}
if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
{
- int scroll_p = 0;
+ int scroll_p = 0, must_scroll = 0;
int last_y = window_text_bottom_y (w) - this_scroll_margin;
if (PT > XFASTINT (w->last_point))
{
/* if PT is not in the glyph row, give up. */
rc = CURSOR_MOVEMENT_MUST_SCROLL;
+ must_scroll = 1;
+ }
+ else if (rc != CURSOR_MOVEMENT_SUCCESS
+ && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+ {
+ /* If rows are bidi-reordered and point moved, back up
+ until we find a row that does not belong to a
+ continuation line. This is because we must consider
+ all rows of a continued line as candidates for the
+ new cursor positioning, since row start and end
+ positions change non-linearly with vertical position
+ in such rows. */
+ /* FIXME: Revisit this when glyph ``spilling'' in
+ continuation lines' rows is implemented for
+ bidi-reordered rows. */
+ while (MATRIX_ROW_CONTINUATION_LINE_P (row))
+ {
+ xassert (row->enabled_p);
+ --row;
+ /* If we hit the beginning of the displayed portion
+ without finding the first row of a continued
+ line, give up. */
+ if (row <= w->current_matrix->rows)
+ {
+ rc = CURSOR_MOVEMENT_MUST_SCROLL;
+ break;
+ }
+
+ }
}
+ if (must_scroll)
+ ;
else if (rc != CURSOR_MOVEMENT_SUCCESS
- && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
- && make_cursor_line_fully_visible_p)
+ && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
+ && make_cursor_line_fully_visible_p)
{
if (PT == MATRIX_ROW_END_CHARPOS (row)
&& !row->ends_at_zv_p
}
else if (scroll_p)
rc = CURSOR_MOVEMENT_MUST_SCROLL;
- else if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+ else if (rc != CURSOR_MOVEMENT_SUCCESS
+ && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
{
/* With bidi-reordered rows, there could be more than
one candidate row whose start and end positions
do
{
- rv |= set_cursor_from_row (w, row, w->current_matrix,
- 0, 0, 0, 0);
+ if (MATRIX_ROW_START_CHARPOS (row) <= PT
+ && PT <= MATRIX_ROW_END_CHARPOS (row)
+ && cursor_row_p (w, row))
+ rv |= set_cursor_from_row (w, row, w->current_matrix,
+ 0, 0, 0, 0);
/* As soon as we've found the first suitable row
whose ends_at_zv_p flag is set, we are done. */
if (rv
}
++row;
}
- while (MATRIX_ROW_BOTTOM_Y (row) < last_y
- && MATRIX_ROW_START_CHARPOS (row) <= PT
- && PT <= MATRIX_ROW_END_CHARPOS (row)
- && cursor_row_p (w, row));
+ while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
+ && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
+ || (MATRIX_ROW_START_CHARPOS (row) == PT
+ && MATRIX_ROW_BOTTOM_Y (row) < last_y));
/* If we didn't find any candidate rows, or exited the
loop before all the candidates were examined, signal
to the caller that this method failed. */
if (rc != CURSOR_MOVEMENT_SUCCESS
- && (!rv
- || (MATRIX_ROW_START_CHARPOS (row) <= PT
- && PT <= MATRIX_ROW_END_CHARPOS (row))))
- rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
- else
+ && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
+ rc = CURSOR_MOVEMENT_MUST_SCROLL;
+ else if (rv)
rc = CURSOR_MOVEMENT_SUCCESS;
}
else
}
void
-set_vertical_scroll_bar (w)
- struct window *w;
+set_vertical_scroll_bar (struct window *w)
{
int start, end, whole;
retry. */
static void
-redisplay_window (window, just_this_one_p)
- Lisp_Object window;
- int just_this_one_p;
+redisplay_window (Lisp_Object window, int just_this_one_p)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
if (redisplay_tool_bar_p && redisplay_tool_bar (f))
{
- extern int ignore_mouse_drag_p;
ignore_mouse_drag_p = 1;
}
}
(*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
}
- /* Restore current_buffer and value of point in it. */
- TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+ /* Restore current_buffer and value of point in it. The window
+ update may have changed the buffer, so first make sure `opoint'
+ is still valid (Bug#6177). */
+ if (CHARPOS (opoint) < BEGV)
+ TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
+ else if (CHARPOS (opoint) > ZV)
+ TEMP_SET_PT_BOTH (Z, Z_BYTE);
+ else
+ TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
+
set_buffer_internal_1 (old);
/* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
shorter. This can be caused by log truncation in *Messages*. */
set in FLAGS.) */
int
-try_window (window, pos, flags)
- Lisp_Object window;
- struct text_pos pos;
- int flags;
+try_window (Lisp_Object window, struct text_pos pos, int flags)
{
struct window *w = XWINDOW (window);
struct it it;
W->start is the new window start. */
static int
-try_window_reusing_current_matrix (w)
- struct window *w;
+try_window_reusing_current_matrix (struct window *w)
{
struct frame *f = XFRAME (w->frame);
struct glyph_row *row, *bottom_row;
/* The variable new_start now holds the new window start. The old
start `start' can be determined from the current matrix. */
SET_TEXT_POS_FROM_MARKER (new_start, w->start);
- start = start_row->start.pos;
+ start = start_row->minpos;
start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
/* Clear the desired matrix for the display below. */
{
/* Advance to the next row as the "start". */
start_row++;
- start = start_row->start.pos;
+ start = start_row->minpos;
/* If there are no more rows to try, or just one, give up. */
if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
|| w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
{
struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
struct glyph *end = glyph + row->used[TEXT_AREA];
- struct glyph *orig_glyph = glyph;
- struct cursor_pos orig_cursor = w->cursor;
- for (; glyph < end
- && (!BUFFERP (glyph->object)
- || glyph->charpos != PT);
- glyph++)
+ /* Can't use this optimization with bidi-reordered glyph
+ rows, unless cursor is already at point. */
+ if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
{
- w->cursor.hpos++;
- w->cursor.x += glyph->pixel_width;
- }
- /* With bidi reordering, charpos changes non-linearly
- with hpos, so the right glyph could be to the
- left. */
- if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
- && (!BUFFERP (glyph->object) || glyph->charpos != PT))
- {
- struct glyph *start_glyph = row->glyphs[TEXT_AREA];
-
- glyph = orig_glyph - 1;
- orig_cursor.hpos--;
- orig_cursor.x -= glyph->pixel_width;
- for (; glyph >= start_glyph
- && (!BUFFERP (glyph->object)
- || glyph->charpos != PT);
- glyph--)
- {
- w->cursor.hpos--;
- w->cursor.x -= glyph->pixel_width;
- }
- if (BUFFERP (glyph->object) && glyph->charpos == PT)
- w->cursor = orig_cursor;
+ if (!(w->cursor.hpos >= 0
+ && w->cursor.hpos < row->used[TEXT_AREA]
+ && BUFFERP (glyph->object)
+ && glyph->charpos == PT))
+ return 0;
}
+ else
+ for (; glyph < end
+ && (!BUFFERP (glyph->object)
+ || glyph->charpos < PT);
+ glyph++)
+ {
+ w->cursor.hpos++;
+ w->cursor.x += glyph->pixel_width;
+ }
}
}
Window redisplay reusing current matrix when buffer has changed
************************************************************************/
-static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
-static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
- int *, int *));
+static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
+static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
+ int *, int *);
static struct glyph_row *
-find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
- struct glyph_row *));
+find_last_row_displaying_text (struct glyph_matrix *, struct it *,
+ struct glyph_row *);
/* Return the last row in MATRIX displaying text. If row START is
a pointer to the row found. */
static struct glyph_row *
-find_last_row_displaying_text (matrix, it, start)
- struct glyph_matrix *matrix;
- struct it *it;
- struct glyph_row *start;
+find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
+ struct glyph_row *start)
{
struct glyph_row *row, *row_found;
when the current matrix was built. */
static struct glyph_row *
-find_last_unchanged_at_beg_row (w)
- struct window *w;
+find_last_unchanged_at_beg_row (struct window *w)
{
int first_changed_pos = BEG + BEG_UNCHANGED;
struct glyph_row *row;
changes. */
static struct glyph_row *
-find_first_unchanged_at_end_row (w, delta, delta_bytes)
- struct window *w;
- int *delta, *delta_bytes;
+find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
{
struct glyph_row *row;
struct glyph_row *row_found = NULL;
try_window_reusing_current_matrix. */
static void
-sync_frame_with_window_matrix_rows (w)
- struct window *w;
+sync_frame_with_window_matrix_rows (struct window *w)
{
struct frame *f = XFRAME (w->frame);
struct glyph_row *window_row, *window_row_end, *frame_row;
containing CHARPOS or null. */
struct glyph_row *
-row_containing_pos (w, charpos, start, end, dy)
- struct window *w;
- int charpos;
- struct glyph_row *start, *end;
- int dy;
+row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
+ struct glyph_row *end, int dy)
{
struct glyph_row *row = start;
struct glyph_row *best_row = NULL;
7. Update W's window end information. */
static int
-try_window_id (w)
- struct window *w;
+try_window_id (struct window *w)
{
struct frame *f = XFRAME (w->frame);
struct glyph_matrix *current_matrix = w->current_matrix;
as is, without changing glyph positions since no text has
been added/removed in front of the window end. */
r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
- if (TEXT_POS_EQUAL_P (start, r0->start.pos)
+ if (TEXT_POS_EQUAL_P (start, r0->minpos)
/* PT must not be in a partially visible line. */
&& !(PT >= MATRIX_ROW_START_CHARPOS (row)
&& MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
{
/* We have to compute the window end anew since text
- can have been added/removed after it. */
+ could have been added/removed after it. */
w->window_end_pos
= make_number (Z - MATRIX_ROW_END_CHARPOS (row));
w->window_end_bytepos
start is not in changed text, otherwise positions would not be
comparable. */
row = MATRIX_FIRST_TEXT_ROW (current_matrix);
- if (!TEXT_POS_EQUAL_P (start, row->start.pos))
+ if (!TEXT_POS_EQUAL_P (start, row->minpos))
GIVE_UP (16);
/* Give up if the window ends in strings. Overlay strings
#if GLYPH_DEBUG
-void dump_glyph_row P_ ((struct glyph_row *, int, int));
-void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
-void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
+void dump_glyph_row (struct glyph_row *, int, int);
+void dump_glyph_matrix (struct glyph_matrix *, int);
+void dump_glyph (struct glyph_row *, struct glyph *, int);
/* Dump the contents of glyph matrix MATRIX on stderr.
glyph->left_box_line_p,
glyph->right_box_line_p);
}
+ else if (glyph->type == XWIDGET_GLYPH)
+ {
+ fprintf (stderr,
+ " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ glyph - row->glyphs[TEXT_AREA],
+ 'X',
+ glyph->charpos,
+ (BUFFERP (glyph->object)
+ ? 'B'
+ : (STRINGP (glyph->object)
+ ? 'S'
+ : '-')),
+ glyph->pixel_width,
+ glyph->u.xwidget_id,
+ '.',
+ glyph->face_id,
+ glyph->left_box_line_p,
+ glyph->right_box_line_p);
+
+ // printf("dump xwidget glyph\n");
+ }
}
Shows contents of glyph row structures. With non-nil
parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
glyphs in short form, otherwise show glyphs in long form. */)
- (glyphs)
- Lisp_Object glyphs;
+ (Lisp_Object glyphs)
{
struct window *w = XWINDOW (selected_window);
struct buffer *buffer = XBUFFER (w->buffer);
DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
- ()
+ (void)
{
struct frame *f = XFRAME (selected_frame);
dump_glyph_matrix (f->current_matrix, 1);
GLYPH 0 means don't dump glyphs.
GLYPH 1 means dump glyphs in short form.
GLYPH > 1 or omitted means dump glyphs in long form. */)
- (row, glyphs)
- Lisp_Object row, glyphs;
+ (Lisp_Object row, Lisp_Object glyphs)
{
struct glyph_matrix *matrix;
int vpos;
GLYPH 0 means don't dump glyphs.
GLYPH 1 means dump glyphs in short form.
GLYPH > 1 or omitted means dump glyphs in long form. */)
- (row, glyphs)
- Lisp_Object row, glyphs;
+ (Lisp_Object row, Lisp_Object glyphs)
{
struct frame *sf = SELECTED_FRAME ();
struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
doc: /* Toggle tracing of redisplay.
With ARG, turn tracing on if and only if ARG is positive. */)
- (arg)
- Lisp_Object arg;
+ (Lisp_Object arg)
{
if (NILP (arg))
trace_redisplay_p = !trace_redisplay_p;
DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
doc: /* Like `format', but print result to stderr.
usage: (trace-to-stderr STRING &rest OBJECTS) */)
- (nargs, args)
- int nargs;
- Lisp_Object *args;
+ (int nargs, Lisp_Object *args)
{
Lisp_Object s = Fformat (nargs, args);
fprintf (stderr, "%s", SDATA (s));
Used for non-window-redisplay windows, and for windows w/o left fringe. */
static struct glyph_row *
-get_overlay_arrow_glyph_row (w, overlay_arrow_string)
- struct window *w;
- Lisp_Object overlay_arrow_string;
+get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct buffer *buffer = XBUFFER (w->buffer);
/* Get the next character. */
if (multibyte_p)
- it.c = string_char_and_length (p, &it.len);
+ it.c = it.char_to_display = string_char_and_length (p, &it.len);
else
- it.c = *p, it.len = 1;
+ {
+ it.c = it.char_to_display = *p, it.len = 1;
+ if (! ASCII_CHAR_P (it.c))
+ it.char_to_display = BYTE8_TO_CHAR (it.c);
+ }
p += it.len;
/* Get its face. */
ilisp = make_number (p - arrow_string);
face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
- it.face_id = compute_char_face (f, it.c, face);
+ it.face_id = compute_char_face (f, it.char_to_display, face);
/* Compute its width, get its glyphs. */
n_glyphs_before = it.glyph_row->used[TEXT_AREA];
produce_special_glyphs. */
static void
-insert_left_trunc_glyphs (it)
- struct it *it;
+insert_left_trunc_glyphs (struct it *it)
{
struct it truncate_it;
struct glyph *from, *end, *to, *toend;
must not be zero. */
static void
-compute_line_metrics (it)
- struct it *it;
+compute_line_metrics (struct it *it)
{
struct glyph_row *row = it->glyph_row;
int area, i;
end of the line if the row ends in italic text. */
static int
-append_space_for_newline (it, default_face_p)
- struct it *it;
- int default_face_p;
+append_space_for_newline (struct it *it, int default_face_p)
{
if (FRAME_WINDOW_P (it->f))
{
append_space_for_newline has been called. */
enum display_element_type saved_what = it->what;
int saved_c = it->c, saved_len = it->len;
+ int saved_char_to_display = it->char_to_display;
int saved_x = it->current_x;
int saved_face_id = it->face_id;
struct text_pos saved_pos;
saved_pos = it->position;
it->what = IT_CHARACTER;
- bzero (&it->position, sizeof it->position);
+ memset (&it->position, 0, sizeof it->position);
it->object = make_number (0);
- it->c = ' ';
+ it->c = it->char_to_display = ' ';
it->len = 1;
if (default_face_p)
it->face_id = saved_face_id;
it->len = saved_len;
it->c = saved_c;
+ it->char_to_display = saved_char_to_display;
return 1;
}
}
left of the leftmost glyph. */
static void
-extend_face_to_end_of_line (it)
- struct it *it;
+extend_face_to_end_of_line (struct it *it)
{
struct face *face;
struct frame *f = it->f;
(((it->ascent + it->descent)
* FONT_BASE (font)) / FONT_HEIGHT (font));
saved_pos = it->position;
- bzero (&it->position, sizeof it->position);
+ memset (&it->position, 0, sizeof it->position);
saved_avoid_cursor = it->avoid_cursor_p;
it->avoid_cursor_p = 1;
saved_face_id = it->face_id;
saved_pos = it->position;
it->what = IT_CHARACTER;
- bzero (&it->position, sizeof it->position);
+ memset (&it->position, 0, sizeof it->position);
it->object = make_number (0);
- it->c = ' ';
+ it->c = it->char_to_display = ' ';
it->len = 1;
/* The last row's blank glyphs should get the default face, to
avoid painting the rest of the window with the region face,
trailing whitespace. */
static int
-trailing_whitespace_p (charpos)
- int charpos;
+trailing_whitespace_p (int charpos)
{
int bytepos = CHAR_TO_BYTE (charpos);
int c = 0;
/* Highlight trailing whitespace, if any, in ROW. */
void
-highlight_trailing_whitespace (f, row)
- struct frame *f;
- struct glyph_row *row;
+highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
{
int used = row->used[TEXT_AREA];
used to hold the cursor. */
static int
-cursor_row_p (w, row)
- struct window *w;
- struct glyph_row *row;
+cursor_row_p (struct window *w, struct glyph_row *row)
{
int cursor_row_p = 1;
- if (PT == MATRIX_ROW_END_CHARPOS (row))
+ if (PT == CHARPOS (row->end.pos))
{
/* Suppose the row ends on a string.
Unless the row is continued, that means it ends on a newline
{
/* If the row ends in middle of a real character,
and the line is continued, we want the cursor here.
- That's because MATRIX_ROW_END_CHARPOS would equal
+ That's because CHARPOS (ROW->end.pos) would equal
PT if PT is before the character. */
if (!row->ends_in_ellipsis_p)
cursor_row_p = row->continued_p;
else
/* If the row ends in an ellipsis, then
- MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
- We want that position to be displayed after the ellipsis. */
+ CHARPOS (ROW->end.pos) will equal point after the
+ invisible text. We want that position to be displayed
+ after the ellipsis. */
cursor_row_p = 0;
}
/* If the row ends at ZV, display the cursor at the end of that
/* Return the character-property PROP at the current position in IT. */
static Lisp_Object
-get_it_property (it, prop)
- struct it *it;
- Lisp_Object prop;
+get_it_property (struct it *it, Lisp_Object prop)
{
Lisp_Object position;
glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
continued. */
static void
-unproduce_glyphs (it, n)
- struct it *it;
- int n;
+unproduce_glyphs (struct it *it, int n)
{
struct glyph *glyph, *end;
glyph[-n] = *glyph;
}
-/* Find the positions in a bidi-reordered ROW to serve as ROW->start
- and ROW->end. */
-static struct display_pos
-find_row_end (it, row)
- struct it *it;
- struct glyph_row *row;
+/* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
+ and ROW->maxpos. */
+static void
+find_row_edges (struct it *it, struct glyph_row *row,
+ EMACS_INT min_pos, EMACS_INT min_bpos,
+ EMACS_INT max_pos, EMACS_INT max_bpos)
{
/* FIXME: Revisit this when glyph ``spilling'' in continuation
lines' rows is implemented for bidi-reordered rows. */
- EMACS_INT min_pos = ZV + 1, max_pos = 0;
- struct glyph *g;
- struct it save_it;
- struct text_pos tpos;
- struct display_pos row_end = it->current;
-
- for (g = row->glyphs[TEXT_AREA];
- g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
- g++)
- {
- if (BUFFERP (g->object))
- {
- if (g->charpos > 0 && g->charpos < min_pos)
- min_pos = g->charpos;
- if (g->charpos > max_pos)
- max_pos = g->charpos;
- }
- }
- /* Empty lines have a valid buffer position at their first
- glyph, but that glyph's OBJECT is zero, as if it didn't come
- from a buffer. If we didn't find any valid buffer positions
- in this row, maybe we have such an empty line. */
- if (max_pos == 0 && row->used[TEXT_AREA])
- {
- for (g = row->glyphs[TEXT_AREA];
- g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
- g++)
- {
- if (INTEGERP (g->object))
- {
- if (g->charpos > 0 && g->charpos < min_pos)
- min_pos = g->charpos;
- if (g->charpos > max_pos)
- max_pos = g->charpos;
- }
- }
- }
- /* ROW->start is the value of min_pos, the minimal buffer position
+ /* ROW->minpos is the value of min_pos, the minimal buffer position
we have in ROW. */
if (min_pos <= ZV)
+ SET_TEXT_POS (row->minpos, min_pos, min_bpos);
+ else
{
- /* Avoid calling the costly CHAR_TO_BYTE if possible. */
- if (min_pos != row->start.pos.charpos)
- SET_TEXT_POS (row->start.pos, min_pos, CHAR_TO_BYTE (min_pos));
- if (max_pos == 0)
- max_pos = min_pos;
+ /* We didn't find _any_ valid buffer positions in any of the
+ glyphs, so we must trust the iterator's computed
+ positions. */
+ row->minpos = row->start.pos;
+ max_pos = CHARPOS (it->current.pos);
+ max_bpos = BYTEPOS (it->current.pos);
}
- /* For ROW->end, we need the position that is _after_ max_pos, in
- the logical order, unless we are at ZV. */
- if (row->ends_at_zv_p)
- {
- if (!row->used[TEXT_AREA])
- row->start.pos = row_end.pos;
- }
- else if (row->used[TEXT_AREA] && max_pos)
- {
- int at_eol_p;
+ if (!max_pos)
+ abort ();
- SET_TEXT_POS (tpos, max_pos, CHAR_TO_BYTE (max_pos));
- save_it = *it;
- it->bidi_p = 0;
- reseat (it, tpos, 0);
- if (!get_next_display_element (it))
- abort (); /* this row cannot be at ZV, see above */
- at_eol_p = ITERATOR_AT_END_OF_LINE_P (it);
- set_iterator_to_next (it, 1);
- row_end = it->current;
- /* If the character at max_pos is not a newline and the
- characters at max_pos+1 is a newline, skip that newline as
- well. Note that this may skip some invisible text. */
- if (!at_eol_p
- && get_next_display_element (it)
- && ITERATOR_AT_END_OF_LINE_P (it))
- {
- set_iterator_to_next (it, 1);
- /* Record the position after the newline of a continued row.
- We will need that to set ROW->end of the last row
- produced for a continued line. */
- if (row->continued_p)
- save_it.eol_pos = it->current.pos;
+ /* Here are the various use-cases for ending the row, and the
+ corresponding values for ROW->maxpos:
+
+ Line ends in a newline from buffer eol_pos + 1
+ Line is continued from buffer max_pos + 1
+ Line is truncated on right it->current.pos
+ Line ends in a newline from string max_pos
+ Line is continued from string max_pos
+ Line is continued from display vector max_pos
+ Line is entirely from a string min_pos == max_pos
+ Line is entirely from a display vector min_pos == max_pos
+ Line that ends at ZV ZV
+
+ If you discover other use-cases, please add them here as
+ appropriate. */
+ if (row->ends_at_zv_p)
+ row->maxpos = it->current.pos;
+ else if (row->used[TEXT_AREA])
+ {
+ if (row->ends_in_newline_from_string_p)
+ SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+ else if (CHARPOS (it->eol_pos) > 0)
+ SET_TEXT_POS (row->maxpos,
+ CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
+ else if (row->continued_p)
+ {
+ /* If max_pos is different from IT's current position, it
+ means IT->method does not belong to the display element
+ at max_pos. However, it also means that the display
+ element at max_pos was displayed in its entirety on this
+ line, which is equivalent to saying that the next line
+ starts at the next buffer position. */
+ if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
+ SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
else
{
- row_end = it->current;
- save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0;
+ INC_BOTH (max_pos, max_bpos);
+ SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
}
}
- else if (!row->continued_p
- && MATRIX_ROW_CONTINUATION_LINE_P (row)
- && it->eol_pos.charpos > 0)
- {
- /* Last row of a continued line. Use the position recorded
- in IT->eol_pos, to the effect that the newline belongs to
- this row, not to the row which displays the character
- with the largest buffer position before the newline. */
- row_end.pos = it->eol_pos;
- it->eol_pos.charpos = it->eol_pos.bytepos = 0;
- }
- *it = save_it;
- /* The members of ROW->end that are not taken from buffer
- positions are copied from IT->current. */
- row_end.string_pos = it->current.string_pos;
- row_end.overlay_string_index = it->current.overlay_string_index;
- row_end.dpvec_index = it->current.dpvec_index;
+ else if (row->truncated_on_right_p)
+ /* display_line already called reseat_at_next_visible_line_start,
+ which puts the iterator at the beginning of the next line, in
+ the logical order. */
+ row->maxpos = it->current.pos;
+ else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
+ /* A line that is entirely from a string/image/stretch... */
+ row->maxpos = row->minpos;
+ else
+ abort ();
}
- return row_end;
+ else
+ row->maxpos = it->current.pos;
}
/* Construct the glyph row IT->glyph_row in the desired matrix of
only. */
static int
-display_line (it)
- struct it *it;
+display_line (struct it *it)
{
struct glyph_row *row = it->glyph_row;
Lisp_Object overlay_arrow_string;
int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
int wrap_row_phys_ascent, wrap_row_phys_height;
int wrap_row_extra_line_spacing;
+ EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
+ EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
int cvpos;
+ EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
/* We always start displaying at hpos zero even if hscrolled. */
xassert (it->hpos == 0 && it->current_x == 0);
row->phys_height = it->max_phys_ascent + it->max_phys_descent;
row->extra_line_spacing = it->max_extra_line_spacing;
+/* Utility macro to record max and min buffer positions seen until now. */
+#define RECORD_MAX_MIN_POS(IT) \
+ do \
+ { \
+ if (IT_CHARPOS (*(IT)) < min_pos) \
+ { \
+ min_pos = IT_CHARPOS (*(IT)); \
+ min_bpos = IT_BYTEPOS (*(IT)); \
+ } \
+ if (IT_CHARPOS (*(IT)) > max_pos) \
+ { \
+ max_pos = IT_CHARPOS (*(IT)); \
+ max_bpos = IT_BYTEPOS (*(IT)); \
+ } \
+ } \
+ while (0)
+
/* Loop generating characters. The loop is left with IT on the next
character to display. */
while (1)
row->ends_at_zv_p = 1;
/* A row that displays right-to-left text must always have
its last face extended all the way to the end of line,
- even if this row ends in ZV. */
+ even if this row ends in ZV, because we still write to
+ the screen left to right. */
if (row->reversed_p)
extend_face_to_end_of_line (it);
break;
wrap_row_phys_ascent = row->phys_ascent;
wrap_row_phys_height = row->phys_height;
wrap_row_extra_line_spacing = row->extra_line_spacing;
+ wrap_row_min_pos = min_pos;
+ wrap_row_min_bpos = min_bpos;
+ wrap_row_max_pos = max_pos;
+ wrap_row_max_bpos = max_bpos;
may_wrap = 0;
}
}
it->max_extra_line_spacing);
if (it->current_x - it->pixel_width < it->first_visible_x)
row->x = x - it->first_visible_x;
+ /* Record the maximum and minimum buffer positions seen so
+ far in glyphs that will be displayed by this row. */
+ if (it->bidi_p)
+ RECORD_MAX_MIN_POS (it);
}
else
{
it->current_x = new_x;
it->continuation_lines_width += new_x;
++it->hpos;
+ /* Record the maximum and minimum buffer
+ positions seen so far in glyphs that will be
+ displayed by this row. */
+ if (it->bidi_p)
+ RECORD_MAX_MIN_POS (it);
if (i == nglyphs - 1)
{
/* If line-wrap is on, check if a previous
row->phys_ascent = wrap_row_phys_ascent;
row->phys_height = wrap_row_phys_height;
row->extra_line_spacing = wrap_row_extra_line_spacing;
+ min_pos = wrap_row_min_pos;
+ min_bpos = wrap_row_min_bpos;
+ max_pos = wrap_row_max_pos;
+ max_bpos = wrap_row_max_bpos;
row->continued_p = 1;
row->ends_at_zv_p = 0;
row->exact_window_width_line_p = 0;
/* Increment number of glyphs actually displayed. */
++it->hpos;
+ /* Record the maximum and minimum buffer positions
+ seen so far in glyphs that will be displayed by
+ this row. */
+ if (it->bidi_p)
+ RECORD_MAX_MIN_POS (it);
+
if (x < it->first_visible_x)
/* Glyph is partially visible, i.e. row starts at
negative X position. */
if (used_before == 0)
row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
+ /* Record the position of the newline, for use in
+ find_row_edges. */
+ it->eol_pos = it->current.pos;
+
/* Consume the line end. This skips over invisible lines. */
set_iterator_to_next (it, 1);
it->continuation_lines_width = 0;
/* If line is not empty and hscrolled, maybe insert truncation glyphs
at the left window margin. */
if (it->first_visible_x
- && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
+ && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
{
if (!FRAME_WINDOW_P (it->f))
insert_left_trunc_glyphs (it);
row->truncated_on_left_p = 1;
}
+ /* Remember the position at which this line ends.
+
+ BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
+ cannot be before the call to find_row_edges below, since that is
+ where these positions are determined. */
+ row->end = it->current;
+ if (!it->bidi_p)
+ {
+ row->minpos = row->start.pos;
+ row->maxpos = row->end.pos;
+ }
+ else
+ {
+ /* ROW->minpos and ROW->maxpos must be the smallest and
+ `1 + the largest' buffer positions in ROW. But if ROW was
+ bidi-reordered, these two positions can be anywhere in the
+ row, so we must determine them now. */
+ find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
+ }
+
/* If the start of this line is the overlay arrow-position, then
mark this glyph row as the one containing the overlay arrow.
This is clearly a mess with variable size fonts. It would be
/* Compute pixel dimensions of this line. */
compute_line_metrics (it);
- /* Remember the position at which this line ends. */
- row->end = it->current;
- /* ROW->start and ROW->end must be the smallest and the largest
- buffer positions in ROW. But if ROW was bidi-reordered, these
- two positions can be anywhere in the row, so we must rescan all
- of the ROW's glyphs to find them. */
- if (it->bidi_p)
- row->end = find_row_end (it, row);
-
/* Record whether this row ends inside an ellipsis. */
row->ends_in_ellipsis_p
= (it->method == GET_FROM_DISPLAY_VECTOR
row to be used. */
it->current_x = it->hpos = 0;
it->current_y += row->height;
+ SET_TEXT_POS (it->eol_pos, 0, 0);
++it->vpos;
++it->glyph_row;
/* The next row should by default use the same value of the
it->glyph_row->reversed_p = row->reversed_p;
it->start = row->end;
return row->displays_text_p;
+
+#undef RECORD_MAX_MIN_POS
}
DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
paragraphs, text begins at the right margin and is read from right to left.
See also `bidi-paragraph-direction'. */)
- (buffer)
- Lisp_Object buffer;
+ (Lisp_Object buffer)
{
struct buffer *buf;
struct buffer *old;
struct bidi_it itb;
EMACS_INT pos = BUF_PT (buf);
EMACS_INT bytepos = BUF_PT_BYTE (buf);
+ int c;
if (buf != current_buffer)
set_buffer_temp (buf);
- /* Find previous non-empty line. */
+ /* bidi_paragraph_init finds the base direction of the paragraph
+ by searching forward from paragraph start. We need the base
+ direction of the current or _previous_ paragraph, so we need
+ to make sure we are within that paragraph. To that end, find
+ the previous non-empty line. */
if (pos >= ZV && pos > BEGV)
{
pos--;
bytepos = CHAR_TO_BYTE (pos);
}
- while (FETCH_BYTE (bytepos) == '\n')
+ while ((c = FETCH_BYTE (bytepos)) == '\n'
+ || c == ' ' || c == '\t' || c == '\f')
{
if (bytepos <= BEGV_BYTE)
break;
itb.charpos = pos;
itb.bytepos = bytepos;
itb.first_elt = 1;
+ itb.separator_limit = -1;
bidi_paragraph_init (NEUTRAL_DIR, &itb);
if (buf != current_buffer)
for the menu bar. */
static void
-display_menu_bar (w)
- struct window *w;
+display_menu_bar (struct window *w)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct it it;
the number of windows whose mode lines were redisplayed. */
static int
-redisplay_mode_lines (window, force)
- Lisp_Object window;
- int force;
+redisplay_mode_lines (Lisp_Object window, int force)
{
int nwindows = 0;
sum number of mode lines and header lines displayed. */
static int
-display_mode_lines (w)
- struct window *w;
+display_mode_lines (struct window *w)
{
Lisp_Object old_selected_window, old_selected_frame;
int n = 0;
displayed. */
static int
-display_mode_line (w, face_id, format)
- struct window *w;
- enum face_id face_id;
- Lisp_Object format;
+display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
{
struct it it;
struct face *face;
Return the updated list. */
static Lisp_Object
-move_elt_to_front (elt, list)
- Lisp_Object elt, list;
+move_elt_to_front (Lisp_Object elt, Lisp_Object list)
{
register Lisp_Object tail, prev;
register Lisp_Object tem;
`store_mode_line_string', or `display_string'. */
static int
-display_mode_element (it, depth, field_width, precision, elt, props, risky)
- struct it *it;
- int depth;
- int field_width, precision;
- Lisp_Object elt, props;
- int risky;
+display_mode_element (struct it *it, int depth, int field_width, int precision,
+ Lisp_Object elt, Lisp_Object props, int risky)
{
int n = 0, field, prec;
int literal = 0;
{
int multibyte;
int bytepos, charpos;
- unsigned char *spec;
+ const unsigned char *spec;
Lisp_Object string;
bytepos = percent_position;
*/
static int
-store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
- char *string;
- Lisp_Object lisp_string;
- int copy_string;
- int field_width;
- int precision;
- Lisp_Object props;
+store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
+ int field_width, int precision, Lisp_Object props)
{
int len;
int n = 0;
Optional third and fourth args WINDOW and BUFFER specify the window
and buffer to use as the context for the formatting (defaults
are the selected window and the window's buffer). */)
- (format, face, window, buffer)
- Lisp_Object format, face, window, buffer;
+ (Lisp_Object format, Lisp_Object face, Lisp_Object window, Lisp_Object buffer)
{
struct it it;
int len;
the positive integer D to BUF using a minimal field width WIDTH. */
static void
-pint2str (buf, width, d)
- register char *buf;
- register int width;
- register int d;
+pint2str (register char *buf, register int width, register int d)
{
register char *p = buf;
};
static void
-pint2hrstr (buf, width, d)
- char *buf;
- int width;
- int d;
+pint2hrstr (char *buf, int width, int d)
{
/* We aim to represent the nonnegative integer D as
QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
static unsigned char invalid_eol_type[] = "(*invalid*)";
static char *
-decode_mode_spec_coding (coding_system, buf, eol_flag)
- Lisp_Object coding_system;
- register char *buf;
- int eol_flag;
+decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
{
Lisp_Object val;
int multibyte = !NILP (current_buffer->enable_multibyte_characters);
eol_str = invalid_eol_type;
eol_str_len = sizeof (invalid_eol_type) - 1;
}
- bcopy (eol_str, buf, eol_str_len);
+ memcpy (buf, eol_str, eol_str_len);
buf += eol_str_len;
}
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
-static char *
-decode_mode_spec (w, c, field_width, precision, string)
- struct window *w;
- register int c;
- int field_width, precision;
- Lisp_Object *string;
+static const char *
+decode_mode_spec (struct window *w, register int c, int field_width,
+ int precision, Lisp_Object *string)
{
Lisp_Object obj;
struct frame *f = XFRAME (WINDOW_FRAME (w));
obj = Fget_buffer_process (Fcurrent_buffer ());
if (NILP (obj))
return "no process";
-#ifdef subprocesses
+#ifndef MSDOS
obj = Fsymbol_name (Fprocess_status (obj));
#endif
break;
Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
static int
-display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
- int start, start_byte, limit_byte, count;
- int *byte_pos_ptr;
+display_count_lines (int start, int start_byte, int limit_byte, int count,
+ int *byte_pos_ptr)
{
register unsigned char *cursor;
unsigned char *base;
Value is the number of columns displayed. */
static int
-display_string (string, lisp_string, face_string, face_string_pos,
- start, it, field_width, precision, max_x, multibyte)
- unsigned char *string;
- Lisp_Object lisp_string;
- Lisp_Object face_string;
- EMACS_INT face_string_pos;
- EMACS_INT start;
- struct it *it;
- int field_width, precision, max_x;
- int multibyte;
+display_string (const unsigned char *string, Lisp_Object lisp_string, Lisp_Object face_string,
+ EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
+ int field_width, int precision, int max_x, int multibyte)
{
int hpos_at_start = it->hpos;
int saved_face_id = it->face_id;
with index START. */
reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
precision, field_width, multibyte);
- if (string && STRINGP (lisp_string))
+ if (string && STRINGP (lisp_string))
/* LISP_STRING is the one returned by decode_mode_spec. We should
ignore its text properties. */
it->stop_charpos = -1;
and 1 if it's invisible and without an ellipsis. */
int
-invisible_p (propval, list)
- register Lisp_Object propval;
- Lisp_Object list;
+invisible_p (register Lisp_Object propval, Lisp_Object list)
{
register Lisp_Object tail, proptail;
value of the `invisible' property of the text of interest.
The non-nil value returned can be t for truly invisible text or something
else if the text is replaced by an ellipsis. */)
- (pos_or_prop)
- Lisp_Object pos_or_prop;
+ (Lisp_Object pos_or_prop)
{
Lisp_Object prop
= (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
: - 1)
int
-calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
- double *res;
- struct it *it;
- Lisp_Object prop;
- struct font *font;
- int width_p, *align_to;
+calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
+ struct font *font, int width_p, int *align_to)
{
double pixels;
return OK_PIXELS (width_p ? img->width : img->height);
}
+
+ if (FRAME_WINDOW_P (it->f)
+ && valid_xwidget_p (prop))
+ {
+ printf("calc_pixel_width_or_height: return dummy size FIXME\n");
+ return OK_PIXELS (width_p ? 100 : 100);
+ }
#endif
if (EQ (car, Qplus) || EQ (car, Qminus))
{
face-override for drawing S. */
#ifdef HAVE_NTGUI
-#define OPTIONAL_HDC(hdc) hdc,
+#define OPTIONAL_HDC(hdc) HDC hdc,
#define DECLARE_HDC(hdc) HDC hdc;
#define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
#define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
#endif
static void
-init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
- struct glyph_string *s;
- DECLARE_HDC (hdc)
- XChar2b *char2b;
- struct window *w;
- struct glyph_row *row;
- enum glyph_row_area area;
- int start;
- enum draw_glyphs_face hl;
+init_glyph_string (struct glyph_string *s,
+ OPTIONAL_HDC (hdc)
+ XChar2b *char2b, struct window *w, struct glyph_row *row,
+ enum glyph_row_area area, int start, enum draw_glyphs_face hl)
{
- bzero (s, sizeof *s);
+ memset (s, 0, sizeof *s);
s->w = w;
s->f = XFRAME (w->frame);
#ifdef HAVE_NTGUI
with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
static INLINE void
-append_glyph_string_lists (head, tail, h, t)
- struct glyph_string **head, **tail;
- struct glyph_string *h, *t;
+append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
+ struct glyph_string *h, struct glyph_string *t)
{
if (h)
{
result. */
static INLINE void
-prepend_glyph_string_lists (head, tail, h, t)
- struct glyph_string **head, **tail;
- struct glyph_string *h, *t;
+prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
+ struct glyph_string *h, struct glyph_string *t)
{
if (h)
{
Set *HEAD and *TAIL to the resulting list. */
static INLINE void
-append_glyph_string (head, tail, s)
- struct glyph_string **head, **tail;
- struct glyph_string *s;
+append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
+ struct glyph_string *s)
{
s->next = s->prev = NULL;
append_glyph_string_lists (head, tail, s, s);
DISPLAY_P is non-zero. */
static INLINE struct face *
-get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
- struct frame *f;
- int c, face_id;
- XChar2b *char2b;
- int multibyte_p, display_p;
+get_char_face_and_encoding (struct frame *f, int c, int face_id,
+ XChar2b *char2b, int multibyte_p, int display_p)
{
struct face *face = FACE_FROM_ID (f, face_id);
a pointer to a realized face that is ready for display. */
static INLINE struct face *
-get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
- struct frame *f;
- struct glyph *glyph;
- XChar2b *char2b;
- int *two_byte_p;
+get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
+ XChar2b *char2b, int *two_byte_p)
{
struct face *face;
if (face->font)
{
- unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
+ unsigned code;
+
+ if (CHAR_BYTE8_P (glyph->u.ch))
+ code = CHAR_TO_BYTE8 (glyph->u.ch);
+ else
+ code = face->font->driver->encode_char (face->font, glyph->u.ch);
if (code != FONT_INVALID_CODE)
STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
}
+/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
+ Retunr 1 if FONT has a glyph for C, otherwise return 0. */
+
+static INLINE int
+get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
+{
+ unsigned code;
+
+ if (CHAR_BYTE8_P (c))
+ code = CHAR_TO_BYTE8 (c);
+ else
+ code = font->driver->encode_char (font, c);
+
+ if (code == FONT_INVALID_CODE)
+ return 0;
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ return 1;
+}
+
+
/* Fill glyph string S with composition components specified by S->cmp.
BASE_FACE is the base face of the composition.
Value is the index of a component not in S. */
static int
-fill_composite_glyph_string (s, base_face, overlaps)
- struct glyph_string *s;
- struct face *base_face;
- int overlaps;
+fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
+ int overlaps)
{
int i;
/* For all glyphs of this composition, starting at the offset
}
static int
-fill_gstring_glyph_string (s, face_id, start, end, overlaps)
- struct glyph_string *s;
- int face_id;
- int start, end, overlaps;
+fill_gstring_glyph_string (struct glyph_string *s, int face_id,
+ int start, int end, int overlaps)
{
struct glyph *glyph, *last;
Lisp_Object lgstring;
Value is the index of the first glyph not in S. */
static int
-fill_glyph_string (s, face_id, start, end, overlaps)
- struct glyph_string *s;
- int face_id;
- int start, end, overlaps;
+fill_glyph_string (struct glyph_string *s, int face_id,
+ int start, int end, int overlaps)
{
struct glyph *glyph, *last;
int voffset;
/* Fill glyph string S from image glyph S->first_glyph. */
static void
-fill_image_glyph_string (s)
- struct glyph_string *s;
+fill_image_glyph_string (struct glyph_string *s)
{
xassert (s->first_glyph->type == IMAGE_GLYPH);
s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
s->ybase += s->first_glyph->voffset;
}
+static void
+fill_xwidget_glyph_string (s)
+ struct glyph_string *s;
+{
+ xassert (s->first_glyph->type == XWIDGET_GLYPH);
+ printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width);
+ s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+ s->font = s->face->font;
+ s->width = s->first_glyph->pixel_width;
+ s->ybase += s->first_glyph->voffset;
+ s->xwidget_id=s->first_glyph->u.xwidget_id;
+ assert_valid_xwidget_id(s->xwidget_id,"fill_xwidget_glyph_string");
+}
+
/* Fill glyph string S from a sequence of stretch glyphs.
Value is the index of the first glyph not in S. */
static int
-fill_stretch_glyph_string (s, row, area, start, end)
- struct glyph_string *s;
- struct glyph_row *row;
- enum glyph_row_area area;
- int start, end;
+fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
+ enum glyph_row_area area, int start, int end)
{
struct glyph *glyph, *last;
int voffset, face_id;
}
static struct font_metrics *
-get_per_char_metric (f, font, char2b)
- struct frame *f;
- struct font *font;
- XChar2b *char2b;
+get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
{
static struct font_metrics metrics;
unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
assumed to be zero. */
void
-x_get_glyph_overhangs (glyph, f, left, right)
- struct glyph *glyph;
- struct frame *f;
- int *left, *right;
+x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
{
*left = *right = 0;
if no glyphs are overwritten. */
static int
-left_overwritten (s)
- struct glyph_string *s;
+left_overwritten (struct glyph_string *s)
{
int k;
glyph in front of S overwrites S. */
static int
-left_overwriting (s)
- struct glyph_string *s;
+left_overwriting (struct glyph_string *s)
{
int i, k, x;
struct glyph *glyphs = s->row->glyphs[s->area];
no such glyph is found. */
static int
-right_overwritten (s)
- struct glyph_string *s;
+right_overwritten (struct glyph_string *s)
{
int k = -1;
if no such glyph is found. */
static int
-right_overwriting (s)
- struct glyph_string *s;
+right_overwriting (struct glyph_string *s)
{
int i, k, x;
int end = s->row->used[s->area];
in the drawing area. */
static INLINE void
-set_glyph_string_background_width (s, start, last_x)
- struct glyph_string *s;
- int start;
- int last_x;
+set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
{
/* If the face of this glyph string has to be drawn to the end of
the drawing area, set S->extends_to_end_of_line_p. */
BACKWARD_P non-zero means process predecessors. */
static void
-compute_overhangs_and_x (s, x, backward_p)
- struct glyph_string *s;
- int x;
- int backward_p;
+compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
{
if (backward_p)
{
} \
while (0)
+#define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+ do \
+ { \
+ printf("BUILD_XWIDGET_GLYPH_STRING\n"); \
+ s = (struct glyph_string *) alloca (sizeof *s); \
+ INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
+ fill_xwidget_glyph_string (s); \
+ append_glyph_string (&HEAD, &TAIL, s); \
+ ++START; \
+ s->x = (X); \
+ } \
+ while (0)
+
+
/* Add a glyph string for a sequence of character glyphs to the list
of strings between HEAD and TAIL. START is the index of the first
BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
HL, X, LAST_X); \
break; \
+ case XWIDGET_GLYPH: \
+ BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
+ HL, X, LAST_X); \
+ break; \
\
default: \
abort (); \
Value is the x-position reached, relative to AREA of W. */
static int
-draw_glyphs (w, x, row, area, start, end, hl, overlaps)
- struct window *w;
- int x;
- struct glyph_row *row;
- enum glyph_row_area area;
- EMACS_INT start, end;
- enum draw_glyphs_face hl;
- int overlaps;
+draw_glyphs (struct window *w, int x, struct glyph_row *row,
+ enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
+ enum draw_glyphs_face hl, int overlaps)
{
struct glyph_string *head, *tail;
struct glyph_string *s;
Called from x_produce_glyphs when IT->glyph_row is non-null. */
static INLINE void
-append_glyph (it)
- struct it *it;
+append_glyph (struct it *it)
{
struct glyph *glyph;
enum glyph_row_area area = it->area;
non-null. */
static INLINE void
-append_composite_glyph (it)
- struct it *it;
+append_composite_glyph (struct it *it)
{
struct glyph *glyph;
enum glyph_row_area area = it->area;
IT->voffset. */
static INLINE void
-take_vertical_position_into_account (it)
- struct it *it;
+take_vertical_position_into_account (struct it *it)
{
if (it->voffset)
{
an overview of struct display_iterator. */
static void
-produce_image_glyph (it)
- struct it *it;
+produce_image_glyph (struct it *it)
{
struct image *img;
struct face *face;
}
}
+static void
+produce_xwidget_glyph (it)
+ struct it *it;
+{
+ // struct image *img;
+ struct face *face;
+ int glyph_ascent, crop;
+ // struct glyph_slice slice;
+
+ printf("produce_xwidget_glyph:\n");
+ xassert (it->what == IT_XWIDGET);
+
+ face = FACE_FROM_ID (it->f, it->face_id);
+ xassert (face);
+ /* Make sure X resources of the face is loaded. */
+ PREPARE_FACE_FOR_DISPLAY (it->f, face);
+
+ /////////////////////////////////////////////
+
+ // img = IMAGE_FROM_ID (it->f, it->image_id);
+ //xassert (img);
+ /* Make sure X resources of the image is loaded. */
+ //prepare_image_for_display (it->f, img);
+
+ struct xwidget* xw=xwidget_from_id(it->xwidget_id);
+ //xwidget_touch(xw);
+
+ it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;//image_ascent (img, face, &slice);
+ it->descent = xw->height/2;//slice.height - glyph_ascent;
+
+ //it->descent += img->vmargin;
+ //it->descent += img->vmargin;
+ it->phys_descent = it->descent;
+
+ it->pixel_width = xw->width;
+
+ //it->pixel_width += img->hmargin;
+ //it->pixel_width += img->hmargin;
+
+ /////////////////////////////////////////
+
+ /* It's quite possible for images to have an ascent greater than
+ their height, so don't get confused in that case. */
+ if (it->descent < 0)
+ it->descent = 0;
+
+ it->nglyphs = 1;
+
+ if (face->box != FACE_NO_BOX)
+ {
+ if (face->box_line_width > 0)
+ {
+ it->ascent += face->box_line_width;
+ it->descent += face->box_line_width;
+ }
+
+ if (it->start_of_box_run_p)
+ it->pixel_width += eabs (face->box_line_width);
+ it->pixel_width += eabs (face->box_line_width);
+ }
+
+ take_vertical_position_into_account (it);
+
+ /* Automatically crop wide image glyphs at right edge so we can
+ draw the cursor on same display row. */
+ if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
+ && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
+ {
+ it->pixel_width -= crop;
+ }
+
+ if (it->glyph_row)
+ {
+ struct glyph *glyph;
+ enum glyph_row_area area = it->area;
+
+ glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+ if (glyph < it->glyph_row->glyphs[area + 1])
+ {
+ glyph->charpos = CHARPOS (it->position);
+ glyph->object = it->object;
+ glyph->pixel_width = it->pixel_width;
+ glyph->ascent = glyph_ascent;
+ glyph->descent = it->descent;
+ glyph->voffset = it->voffset;
+ // glyph->type = IMAGE_GLYPH;
+ glyph->type = XWIDGET_GLYPH;
+
+ glyph->multibyte_p = it->multibyte_p;
+ glyph->left_box_line_p = it->start_of_box_run_p;
+ glyph->right_box_line_p = it->end_of_box_run_p;
+ glyph->overlaps_vertically_p = 0;
+ glyph->padding_p = 0;
+ glyph->glyph_not_available_p = 0;
+ glyph->face_id = it->face_id;
+ glyph->u.xwidget_id = it->xwidget_id;
+ assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph");
+ // glyph->slice = slice;
+ glyph->font_type = FONT_TYPE_UNKNOWN;
+ ++it->glyph_row->used[area];
+ }
+ else
+ IT_EXPAND_MATRIX_WIDTH (it, area);
+ }
+}
+
/* Append a stretch glyph to IT->glyph_row. OBJECT is the source
of the glyph, WIDTH and HEIGHT are the width and height of the
stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
static void
-append_stretch_glyph (it, object, width, height, ascent)
- struct it *it;
- Lisp_Object object;
- int width, height;
- int ascent;
+append_stretch_glyph (struct it *it, Lisp_Object object,
+ int width, int height, int ascent)
{
struct glyph *glyph;
enum glyph_row_area area = it->area;
ASCENT must be in the range 0 <= ASCENT <= 100. */
static void
-produce_stretch_glyph (it)
- struct it *it;
+produce_stretch_glyph (struct it *it)
{
/* (space :width WIDTH :height HEIGHT ...) */
Lisp_Object prop, plist;
{
int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
- IT_BYTEPOS (*it));
- it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
+ it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
}
else
- it2.c = *p, it2.len = 1;
+ {
+ it2.c = it2.char_to_display = *p, it2.len = 1;
+ if (! ASCII_CHAR_P (it2.c))
+ it2.char_to_display = BYTE8_TO_CHAR (it2.c);
+ }
it2.glyph_row = NULL;
it2.what = IT_CHARACTER;
static Lisp_Object
-calc_line_height_property (it, val, font, boff, override)
- struct it *it;
- Lisp_Object val;
- struct font *font;
- int boff, override;
+calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
+ int boff, int override)
{
Lisp_Object face_name = Qnil;
int ascent, descent, height;
for an overview of struct it. */
void
-x_produce_glyphs (it)
- struct it *it;
+x_produce_glyphs (struct it *it)
{
int extra_line_spacing = it->extra_line_spacing;
if (it->what == IT_CHARACTER)
{
XChar2b char2b;
- struct font *font;
struct face *face = FACE_FROM_ID (it->f, it->face_id);
- struct font_metrics *pcm;
- int font_not_found_p;
+ struct font *font = face->font;
+ int font_not_found_p = font == NULL;
+ struct font_metrics *pcm = NULL;
int boff; /* baseline offset */
- /* We may change it->multibyte_p upon unibyte<->multibyte
- conversion. So, save the current value now and restore it
- later.
-
- Note: It seems that we don't have to record multibyte_p in
- struct glyph because the character code itself tells whether
- or not the character is multibyte. Thus, in the future, we
- must consider eliminating the field `multibyte_p' in the
- struct glyph. */
- int saved_multibyte_p = it->multibyte_p;
-
- /* Maybe translate single-byte characters to multibyte, or the
- other way. */
- it->char_to_display = it->c;
- if (!ASCII_BYTE_P (it->c)
- && ! it->multibyte_p)
- {
- if (SINGLE_BYTE_CHAR_P (it->c)
- && unibyte_display_via_language_environment)
- {
- struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
-
- /* get_next_display_element assures that this decoding
- never fails. */
- it->char_to_display = DECODE_CHAR (unibyte, it->c);
- it->multibyte_p = 1;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
- -1, Qnil);
- face = FACE_FROM_ID (it->f, it->face_id);
- }
- }
- /* Get font to use. Encode IT->char_to_display. */
- get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
- &char2b, it->multibyte_p, 0);
- font = face->font;
-
- font_not_found_p = font == NULL;
if (font_not_found_p)
{
/* When no suitable font found, display an empty box based
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
}
- if (it->char_to_display >= ' '
- && (!it->multibyte_p || it->char_to_display < 128))
+ if (it->char_to_display != '\n' && it->char_to_display != '\t')
{
- /* Either unibyte or ASCII. */
int stretched_p;
it->nglyphs = 1;
- pcm = get_per_char_metric (it->f, font, &char2b);
-
if (it->override_ascent >= 0)
{
it->ascent = it->override_ascent;
it->descent = FONT_DESCENT (font) - boff;
}
+ if (! font_not_found_p
+ && get_char_glyph_code (it->char_to_display, font, &char2b))
+ {
+ pcm = get_per_char_metric (it->f, font, &char2b);
+ if (pcm->width == 0
+ && pcm->rbearing == 0 && pcm->lbearing == 0)
+ pcm = NULL;
+ }
+
if (pcm)
{
it->phys_ascent = pcm->ascent + boff;
it->glyph_not_available_p = 1;
it->phys_ascent = it->ascent;
it->phys_descent = it->descent;
- it->pixel_width = FONT_WIDTH (font);
+ it->pixel_width = font->space_width;
}
if (it->constrain_row_ascent_descent_p)
it->pixel_width = 0;
it->nglyphs = 0;
- height = get_it_property(it, Qline_height);
+ height = get_it_property (it, Qline_height);
/* Split (line-height total-height) list */
if (CONSP (height)
&& CONSP (XCDR (height))
total_height = XCAR (XCDR (height));
height = XCAR (height);
}
- height = calc_line_height_property(it, height, font, boff, 1);
+ height = calc_line_height_property (it, height, font, boff, 1);
if (it->override_ascent >= 0)
{
it->ascent = XINT (height) - it->descent;
if (!NILP (total_height))
- spacing = calc_line_height_property(it, total_height, font, boff, 0);
+ spacing = calc_line_height_property (it, total_height, font, boff, 0);
else
{
- spacing = get_it_property(it, Qline_spacing);
- spacing = calc_line_height_property(it, spacing, font, boff, 0);
+ spacing = get_it_property (it, Qline_spacing);
+ spacing = calc_line_height_property (it, spacing, font, boff, 0);
}
if (INTEGERP (spacing))
{
}
}
}
- else if (it->char_to_display == '\t')
+ else /* i.e. (it->char_to_display == '\t') */
{
if (font->space_width > 0)
{
it->nglyphs = 1;
}
}
- else
- {
- /* A multi-byte character. Assume that the display width of the
- character is the width of the character multiplied by the
- width of the font. */
-
- /* If we found a font, this font should give us the right
- metrics. If we didn't find a font, use the frame's
- default font and calculate the width of the character by
- multiplying the width of font by the width of the
- character. */
-
- pcm = get_per_char_metric (it->f, font, &char2b);
-
- if (font_not_found_p || !pcm)
- {
- int char_width = CHAR_WIDTH (it->char_to_display);
-
- if (char_width == 0)
- /* This is a non spacing character. But, as we are
- going to display an empty box, the box must occupy
- at least one column. */
- char_width = 1;
- it->glyph_not_available_p = 1;
- it->pixel_width = font->space_width * char_width;
- it->phys_ascent = FONT_BASE (font) + boff;
- it->phys_descent = FONT_DESCENT (font) - boff;
- }
- else
- {
- it->pixel_width = pcm->width;
- it->phys_ascent = pcm->ascent + boff;
- it->phys_descent = pcm->descent - boff;
- if (it->glyph_row
- && (pcm->lbearing < 0
- || pcm->rbearing > pcm->width))
- it->glyph_row->contains_overlapping_glyphs_p = 1;
- }
- it->nglyphs = 1;
- it->ascent = FONT_BASE (font) + boff;
- it->descent = FONT_DESCENT (font) - boff;
- if (face->box != FACE_NO_BOX)
- {
- int thick = face->box_line_width;
-
- if (thick > 0)
- {
- it->ascent += thick;
- it->descent += thick;
- }
- else
- thick = - thick;
-
- if (it->start_of_box_run_p)
- it->pixel_width += thick;
- if (it->end_of_box_run_p)
- it->pixel_width += thick;
- }
-
- /* If face has an overline, add the height of the overline
- (1 pixel) and a 1 pixel margin to the character height. */
- if (face->overline_p)
- it->ascent += overline_margin;
-
- take_vertical_position_into_account (it);
-
- if (it->ascent < 0)
- it->ascent = 0;
- if (it->descent < 0)
- it->descent = 0;
-
- if (it->glyph_row)
- append_glyph (it);
- if (it->pixel_width == 0)
- /* We assure that all visible glyphs have at least 1-pixel
- width. */
- it->pixel_width = 1;
- }
- it->multibyte_p = saved_multibyte_p;
}
else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
{
}
else
{
- width = FONT_WIDTH (font);
+ width = font->space_width;
ascent = FONT_BASE (font);
descent = FONT_DESCENT (font);
lbearing = 0;
produce_image_glyph (it);
else if (it->what == IT_STRETCH)
produce_stretch_glyph (it);
+ else if (it->what == IT_XWIDGET)
+ produce_xwidget_glyph (it);
/* Accumulate dimensions. Note: can't assume that it->descent > 0
because this isn't true for images with `:ascent 100'. */
row being updated. */
void
-x_write_glyphs (start, len)
- struct glyph *start;
- int len;
+x_write_glyphs (struct glyph *start, int len)
{
int x, hpos;
Insert LEN glyphs from START at the nominal cursor position. */
void
-x_insert_glyphs (start, len)
- struct glyph *start;
- int len;
+x_insert_glyphs (struct glyph *start, int len)
{
struct frame *f;
struct window *w;
updated_window. TO_X == -1 means clear to the end of this area. */
void
-x_clear_end_of_line (to_x)
- int to_x;
+x_clear_end_of_line (int to_x)
{
struct frame *f;
struct window *w = updated_window;
of the bar cursor. */
static enum text_cursor_kinds
-get_specified_cursor_type (arg, width)
- Lisp_Object arg;
- int *width;
+get_specified_cursor_type (Lisp_Object arg, int *width)
{
enum text_cursor_kinds type;
/* Set the default cursor types for specified frame. */
void
-set_frame_cursor_types (f, arg)
- struct frame *f;
- Lisp_Object arg;
+set_frame_cursor_types (struct frame *f, Lisp_Object arg)
{
int width;
Lisp_Object tem;
In all other cases, we want a hollow box cursor. */
static enum text_cursor_kinds
-get_window_cursor_type (w, glyph, width, active_cursor)
- struct window *w;
- struct glyph *glyph;
- int *width;
- int *active_cursor;
+get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
+ int *active_cursor)
{
struct frame *f = XFRAME (w->frame);
struct buffer *b = XBUFFER (w->buffer);
are window-relative. */
static void
-notice_overwritten_cursor (w, area, x0, x1, y0, y1)
- struct window *w;
- enum glyph_row_area area;
- int x0, y0, x1, y1;
+notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
+ int x0, int x1, int y0, int y1)
{
int cx0, cx1, cy0, cy1;
struct glyph_row *row;
with respect to the overlapping part OVERLAPS. */
void
-x_fix_overlapping_area (w, row, area, overlaps)
- struct window *w;
- struct glyph_row *row;
- enum glyph_row_area area;
- int overlaps;
+x_fix_overlapping_area (struct window *w, struct glyph_row *row,
+ enum glyph_row_area area, int overlaps)
{
int i, x;
comment of draw_glyphs for the meaning of HL. */
void
-draw_phys_cursor_glyph (w, row, hl)
- struct window *w;
- struct glyph_row *row;
- enum draw_glyphs_face hl;
+draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
+ enum draw_glyphs_face hl)
{
/* If cursor hpos is out of bounds, don't draw garbage. This can
happen in mini-buffer windows when switching between echo area
Erase the image of a cursor of window W from the screen. */
void
-erase_phys_cursor (w)
- struct window *w;
+erase_phys_cursor (struct window *w)
{
struct frame *f = XFRAME (w->frame);
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
where to put the cursor is specified by HPOS, VPOS, X and Y. */
void
-display_and_set_cursor (w, on, hpos, vpos, x, y)
- struct window *w;
- int on, hpos, vpos, x, y;
+display_and_set_cursor (struct window *w, int on,
+ int hpos, int vpos, int x, int y)
{
struct frame *f = XFRAME (w->frame);
int new_cursor_type;
of ON. */
void
-update_window_cursor (w, on)
- struct window *w;
- int on;
+update_window_cursor (struct window *w, int on)
{
/* Don't update cursor in windows whose frame is in the process
of being deleted. */
in the window tree rooted at W. */
static void
-update_cursor_in_window_tree (w, on_p)
- struct window *w;
- int on_p;
+update_cursor_in_window_tree (struct window *w, int on_p)
{
while (w)
{
Don't change the cursor's position. */
void
-x_update_cursor (f, on_p)
- struct frame *f;
- int on_p;
+x_update_cursor (struct frame *f, int on_p)
{
update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
}
is about to be rewritten. */
void
-x_clear_cursor (w)
- struct window *w;
+x_clear_cursor (struct window *w)
{
if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
update_window_cursor (w, 0);
Display the active region described by mouse_face_* according to DRAW. */
void
-show_mouse_face (dpyinfo, draw)
- Display_Info *dpyinfo;
- enum draw_glyphs_face draw;
+show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
{
struct window *w = XWINDOW (dpyinfo->mouse_face_window);
struct frame *f = XFRAME (WINDOW_FRAME (w));
face was actually drawn unhighlighted. */
int
-clear_mouse_face (dpyinfo)
- Display_Info *dpyinfo;
+clear_mouse_face (Display_Info *dpyinfo)
{
int cleared = 0;
Non-zero if physical cursor of window W is within mouse face. */
int
-cursor_in_mouse_face_p (w)
- struct window *w;
+cursor_in_mouse_face_p (struct window *w)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
int in_mouse_face = 0;
Value is non-zero if a glyph was found. */
static int
-fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
- struct window *w;
- EMACS_INT pos;
- Lisp_Object object;
- int *hpos, *vpos, *x, *y;
- int right_p;
+fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
+ int *hpos, int *vpos, int *x, int *y, int right_p)
{
int yb = window_text_bottom_y (w);
struct glyph_row *r;
/* See if position X, Y is within a hot-spot of an image. */
static int
-on_hot_spot_p (hot_spot, x, y)
- Lisp_Object hot_spot;
- int x, y;
+on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
{
if (!CONSP (hot_spot))
return 0;
}
Lisp_Object
-find_hot_spot (map, x, y)
- Lisp_Object map;
- int x, y;
+find_hot_spot (Lisp_Object map, int x, int y)
{
while (CONSP (map))
{
A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
vector describes one corner in the polygon.
Returns the alist element for the first matching AREA in MAP. */)
- (map, x, y)
- Lisp_Object map;
- Lisp_Object x, y;
+ (Lisp_Object map, Lisp_Object x, Lisp_Object y)
{
if (NILP (map))
return Qnil;
/* Display frame CURSOR, optionally using shape defined by POINTER. */
static void
-define_frame_cursor1 (f, cursor, pointer)
- struct frame *f;
- Cursor cursor;
- Lisp_Object pointer;
+define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
{
/* Do not change cursor shape while dragging mouse. */
if (!NILP (do_mouse_tracking))
position relative to the start of the mode line. */
static void
-note_mode_line_or_margin_highlight (window, x, y, area)
- Lisp_Object window;
- int x, y;
- enum window_part area;
+note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
+ enum window_part area)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
X and Y can be negative or out of range. */
void
-note_mouse_highlight (f, x, y)
- struct frame *f;
- int x, y;
+note_mouse_highlight (struct frame *f, int x, int y)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
enum window_part part;
functions to ensure the mouse-highlight is off. */
void
-x_clear_window_mouse_face (w)
- struct window *w;
+x_clear_window_mouse_face (struct window *w)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
Lisp_Object window;
This is used when the size of F is changed. */
void
-cancel_mouse_face (f)
- struct frame *f;
+cancel_mouse_face (struct frame *f)
{
Lisp_Object window;
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
which intersects rectangle R. R is in window-relative coordinates. */
static void
-expose_area (w, row, r, area)
- struct window *w;
- struct glyph_row *row;
- XRectangle *r;
- enum glyph_row_area area;
+expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
+ enum glyph_row_area area)
{
struct glyph *first = row->glyphs[area];
struct glyph *end = row->glyphs[area] + row->used[area];
non-zero if mouse-face was overwritten. */
static int
-expose_line (w, row, r)
- struct window *w;
- struct glyph_row *row;
- XRectangle *r;
+expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
{
xassert (row->enabled_p);
LAST_OVERLAPPING_ROW is the last such row. */
static void
-expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
- struct window *w;
- struct glyph_row *first_overlapping_row;
- struct glyph_row *last_overlapping_row;
- XRectangle *r;
+expose_overlaps (struct window *w,
+ struct glyph_row *first_overlapping_row,
+ struct glyph_row *last_overlapping_row,
+ XRectangle *r)
{
struct glyph_row *row;
/* Return non-zero if W's cursor intersects rectangle R. */
static int
-phys_cursor_in_rect_p (w, r)
- struct window *w;
- XRectangle *r;
+phys_cursor_in_rect_p (struct window *w, XRectangle *r)
{
XRectangle cr, result;
struct glyph *cursor_glyph;
have vertical scroll bars. */
void
-x_draw_vertical_border (w)
- struct window *w;
+x_draw_vertical_border (struct window *w)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
mouse-face. */
static int
-expose_window (w, fr)
- struct window *w;
- XRectangle *fr;
+expose_window (struct window *w, XRectangle *fr)
{
struct frame *f = XFRAME (w->frame);
XRectangle wr, r;
non-zero if the exposure overwrites mouse-face. */
static int
-expose_window_tree (w, r)
- struct window *w;
- XRectangle *r;
+expose_window_tree (struct window *w, XRectangle *r)
{
struct frame *f = XFRAME (w->frame);
int mouse_face_overwritten_p = 0;
the entire frame. */
void
-expose_frame (f, x, y, w, h)
- struct frame *f;
- int x, y, w, h;
+expose_frame (struct frame *f, int x, int y, int w, int h)
{
XRectangle r;
int mouse_face_overwritten_p = 0;
empty. */
int
-x_intersect_rectangles (r1, r2, result)
- XRectangle *r1, *r2, *result;
+x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
{
XRectangle *left, *right;
XRectangle *upper, *lower;
***********************************************************************/
void
-syms_of_xdisp ()
+syms_of_xdisp (void)
{
Vwith_echo_area_save_vector = Qnil;
staticpro (&Vwith_echo_area_save_vector);
staticpro (&Qboth);
Qboth_horiz = intern_c_string ("both-horiz");
staticpro (&Qboth_horiz);
+ Qtext_image_horiz = intern_c_string ("text-image-horiz");
+ staticpro (&Qtext_image_horiz);
QCmap = intern_c_string (":map");
staticpro (&QCmap);
QCpointer = intern_c_string (":pointer");
DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
doc: /* *Tool bar style to use.
It can be one of
- image - show images only
- text - show text only
- both - show both, text under image
- both-horiz - show text to the right of the image
- any other - use system default or image if no system default. */);
+ image - show images only
+ text - show text only
+ both - show both, text below image
+ both-horiz - show text to the right of the image
+ text-image-horiz - show text to the left of the image
+ any other - use system default or image if no system default. */);
Vtool_bar_style = Qnil;
DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
/* Initialize this module when Emacs starts. */
void
-init_xdisp ()
+init_xdisp (void)
{
Lisp_Object root_window;
struct window *mini_w;
/* Return non-zero if houglass timer has been started or hourglass is shown. */
int
-hourglass_started ()
+hourglass_started (void)
{
return hourglass_shown_p || hourglass_atimer != NULL;
}
/* Cancel a currently active hourglass timer, and start a new one. */
void
-start_hourglass ()
+start_hourglass (void)
{
#if defined (HAVE_WINDOW_SYSTEM)
EMACS_TIME delay;
/* Cancel the hourglass cursor timer if active, hide a busy cursor if
shown. */
void
-cancel_hourglass ()
+cancel_hourglass (void)
{
#if defined (HAVE_WINDOW_SYSTEM)
if (hourglass_atimer)