Mercurial > hg > xemacs-beta
comparison src/redisplay.c @ 665:fdefd0186b75
[xemacs-hg @ 2001-09-20 06:28:42 by ben]
The great integral types renaming.
The purpose of this is to rationalize the names used for various
integral types, so that they match their intended uses and follow
consist conventions, and eliminate types that were not semantically
different from each other.
The conventions are:
-- All integral types that measure quantities of anything are
signed. Some people disagree vociferously with this, but their
arguments are mostly theoretical, and are vastly outweighed by
the practical headaches of mixing signed and unsigned values,
and more importantly by the far increased likelihood of
inadvertent bugs: Because of the broken "viral" nature of
unsigned quantities in C (operations involving mixed
signed/unsigned are done unsigned, when exactly the opposite is
nearly always wanted), even a single error in declaring a
quantity unsigned that should be signed, or even the even more
subtle error of comparing signed and unsigned values and
forgetting the necessary cast, can be catastrophic, as
comparisons will yield wrong results. -Wsign-compare is turned
on specifically to catch this, but this tends to result in a
great number of warnings when mixing signed and unsigned, and
the casts are annoying. More has been written on this
elsewhere.
-- All such quantity types just mentioned boil down to EMACS_INT,
which is 32 bits on 32-bit machines and 64 bits on 64-bit
machines. This is guaranteed to be the same size as Lisp
objects of type `int', and (as far as I can tell) of size_t
(unsigned!) and ssize_t. The only type below that is not an
EMACS_INT is Hashcode, which is an unsigned value of the same
size as EMACS_INT.
-- Type names should be relatively short (no more than 10
characters or so), with the first letter capitalized and no
underscores if they can at all be avoided.
-- "count" == a zero-based measurement of some quantity. Includes
sizes, offsets, and indexes.
-- "bpos" == a one-based measurement of a position in a buffer.
"Charbpos" and "Bytebpos" count text in the buffer, rather than
bytes in memory; thus Bytebpos does not directly correspond to
the memory representation. Use "Membpos" for this.
-- "Char" refers to internal-format characters, not to the C type
"char", which is really a byte.
-- For the actual name changes, see the script below.
I ran the following script to do the conversion. (NOTE: This script
is idempotent. You can safely run it multiple times and it will
not screw up previous results -- in fact, it will do nothing if
nothing has changed. Thus, it can be run repeatedly as necessary
to handle patches coming in from old workspaces, or old branches.)
There are two tags, just before and just after the change:
`pre-integral-type-rename' and `post-integral-type-rename'. When
merging code from the main trunk into a branch, the best thing to
do is first merge up to `pre-integral-type-rename', then apply the
script and associated changes, then merge from
`post-integral-type-change' to the present. (Alternatively, just do
the merging in one operation; but you may then have a lot of
conflicts needing to be resolved by hand.)
Script `fixtypes.sh' follows:
----------------------------------- cut ------------------------------------
files="*.[ch] s/*.h m/*.h config.h.in ../configure.in Makefile.in.in ../lib-src/*.[ch] ../lwlib/*.[ch]"
gr Memory_Count Bytecount $files
gr Lstream_Data_Count Bytecount $files
gr Element_Count Elemcount $files
gr Hash_Code Hashcode $files
gr extcount bytecount $files
gr bufpos charbpos $files
gr bytind bytebpos $files
gr memind membpos $files
gr bufbyte intbyte $files
gr Extcount Bytecount $files
gr Bufpos Charbpos $files
gr Bytind Bytebpos $files
gr Memind Membpos $files
gr Bufbyte Intbyte $files
gr EXTCOUNT BYTECOUNT $files
gr BUFPOS CHARBPOS $files
gr BYTIND BYTEBPOS $files
gr MEMIND MEMBPOS $files
gr BUFBYTE INTBYTE $files
gr MEMORY_COUNT BYTECOUNT $files
gr LSTREAM_DATA_COUNT BYTECOUNT $files
gr ELEMENT_COUNT ELEMCOUNT $files
gr HASH_CODE HASHCODE $files
----------------------------------- cut ------------------------------------
`fixtypes.sh' is a Bourne-shell script; it uses 'gr':
----------------------------------- cut ------------------------------------
#!/bin/sh
# Usage is like this:
# gr FROM TO FILES ...
# globally replace FROM with TO in FILES. FROM and TO are regular expressions.
# backup files are stored in the `backup' directory.
from="$1"
to="$2"
shift 2
echo ${1+"$@"} | xargs global-replace "s/$from/$to/g"
----------------------------------- cut ------------------------------------
`gr' in turn uses a Perl script to do its real work,
`global-replace', which follows:
----------------------------------- cut ------------------------------------
: #-*- Perl -*-
### global-modify --- modify the contents of a file by a Perl expression
## Copyright (C) 1999 Martin Buchholz.
## Copyright (C) 2001 Ben Wing.
## Authors: Martin Buchholz <martin@xemacs.org>, Ben Wing <ben@xemacs.org>
## Maintainer: Ben Wing <ben@xemacs.org>
## Current Version: 1.0, May 5, 2001
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with XEmacs; see the file COPYING. If not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
eval 'exec perl -w -S $0 ${1+"$@"}'
if 0;
use strict;
use FileHandle;
use Carp;
use Getopt::Long;
use File::Basename;
(my $myName = $0) =~ s@.*/@@; my $usage="
Usage: $myName [--help] [--backup-dir=DIR] [--line-mode] [--hunk-mode]
PERLEXPR FILE ...
Globally modify a file, either line by line or in one big hunk.
Typical usage is like this:
[with GNU print, GNU xargs: guaranteed to handle spaces, quotes, etc.
in file names]
find . -name '*.[ch]' -print0 | xargs -0 $0 's/\bCONST\b/const/g'\n
[with non-GNU print, xargs]
find . -name '*.[ch]' -print | xargs $0 's/\bCONST\b/const/g'\n
The file is read in, either line by line (with --line-mode specified)
or in one big hunk (with --hunk-mode specified; it's the default), and
the Perl expression is then evalled with \$_ set to the line or hunk of
text, including the terminating newline if there is one. It should
destructively modify the value there, storing the changed result in \$_.
Files in which any modifications are made are backed up to the directory
specified using --backup-dir, or to `backup' by default. To disable this,
use --backup-dir= with no argument.
Hunk mode is the default because it is MUCH MUCH faster than line-by-line.
Use line-by-line only when it matters, e.g. you want to do a replacement
only once per line (the default without the `g' argument). Conversely,
when using hunk mode, *ALWAYS* use `g'; otherwise, you will only make one
replacement in the entire file!
";
my %options = ();
$Getopt::Long::ignorecase = 0;
&GetOptions (
\%options,
'help', 'backup-dir=s', 'line-mode', 'hunk-mode',
);
die $usage if $options{"help"} or @ARGV <= 1;
my $code = shift;
die $usage if grep (-d || ! -w, @ARGV);
sub SafeOpen {
open ((my $fh = new FileHandle), $_[0]);
confess "Can't open $_[0]: $!" if ! defined $fh;
return $fh;
}
sub SafeClose {
close $_[0] or confess "Can't close $_[0]: $!";
}
sub FileContents {
my $fh = SafeOpen ("< $_[0]");
my $olddollarslash = $/;
local $/ = undef;
my $contents = <$fh>;
$/ = $olddollarslash;
return $contents;
}
sub WriteStringToFile {
my $fh = SafeOpen ("> $_[0]");
binmode $fh;
print $fh $_[1] or confess "$_[0]: $!\n";
SafeClose $fh;
}
foreach my $file (@ARGV) {
my $changed_p = 0;
my $new_contents = "";
if ($options{"line-mode"}) {
my $fh = SafeOpen $file;
while (<$fh>) {
my $save_line = $_;
eval $code;
$changed_p = 1 if $save_line ne $_;
$new_contents .= $_;
}
} else {
my $orig_contents = $_ = FileContents $file;
eval $code;
if ($_ ne $orig_contents) {
$changed_p = 1;
$new_contents = $_;
}
}
if ($changed_p) {
my $backdir = $options{"backup-dir"};
$backdir = "backup" if !defined ($backdir);
if ($backdir) {
my ($name, $path, $suffix) = fileparse ($file, "");
my $backfulldir = $path . $backdir;
my $backfile = "$backfulldir/$name";
mkdir $backfulldir, 0755 unless -d $backfulldir;
print "modifying $file (original saved in $backfile)\n";
rename $file, $backfile;
}
WriteStringToFile ($file, $new_contents);
}
}
----------------------------------- cut ------------------------------------
In addition to those programs, I needed to fix up a few other
things, particularly relating to the duplicate definitions of
types, now that some types merged with others. Specifically:
1. in lisp.h, removed duplicate declarations of Bytecount. The
changed code should now look like this: (In each code snippet
below, the first and last lines are the same as the original, as
are all lines outside of those lines. That allows you to locate
the section to be replaced, and replace the stuff in that
section, verifying that there isn't anything new added that
would need to be kept.)
--------------------------------- snip -------------------------------------
/* Counts of bytes or chars */
typedef EMACS_INT Bytecount;
typedef EMACS_INT Charcount;
/* Counts of elements */
typedef EMACS_INT Elemcount;
/* Hash codes */
typedef unsigned long Hashcode;
/* ------------------------ dynamic arrays ------------------- */
--------------------------------- snip -------------------------------------
2. in lstream.h, removed duplicate declaration of Bytecount.
Rewrote the comment about this type. The changed code should
now look like this:
--------------------------------- snip -------------------------------------
#endif
/* The have been some arguments over the what the type should be that
specifies a count of bytes in a data block to be written out or read in,
using Lstream_read(), Lstream_write(), and related functions.
Originally it was long, which worked fine; Martin "corrected" these to
size_t and ssize_t on the grounds that this is theoretically cleaner and
is in keeping with the C standards. Unfortunately, this practice is
horribly error-prone due to design flaws in the way that mixed
signed/unsigned arithmetic happens. In fact, by doing this change,
Martin introduced a subtle but fatal error that caused the operation of
sending large mail messages to the SMTP server under Windows to fail.
By putting all values back to be signed, avoiding any signed/unsigned
mixing, the bug immediately went away. The type then in use was
Lstream_Data_Count, so that it be reverted cleanly if a vote came to
that. Now it is Bytecount.
Some earlier comments about why the type must be signed: This MUST BE
SIGNED, since it also is used in functions that return the number of
bytes actually read to or written from in an operation, and these
functions can return -1 to signal error.
Note that the standard Unix read() and write() functions define the
count going in as a size_t, which is UNSIGNED, and the count going
out as an ssize_t, which is SIGNED. This is a horrible design
flaw. Not only is it highly likely to lead to logic errors when a
-1 gets interpreted as a large positive number, but operations are
bound to fail in all sorts of horrible ways when a number in the
upper-half of the size_t range is passed in -- this number is
unrepresentable as an ssize_t, so code that checks to see how many
bytes are actually written (which is mandatory if you are dealing
with certain types of devices) will get completely screwed up.
--ben
*/
typedef enum lstream_buffering
--------------------------------- snip -------------------------------------
3. in dumper.c, there are four places, all inside of switch()
statements, where XD_BYTECOUNT appears twice as a case tag. In
each case, the two case blocks contain identical code, and you
should *REMOVE THE SECOND* and leave the first.
author | ben |
---|---|
date | Thu, 20 Sep 2001 06:31:11 +0000 |
parents | b39c14581166 |
children | 943eaba38521 |
comparison
equal
deleted
inserted
replaced
664:6e99cc8c6ca5 | 665:fdefd0186b75 |
---|---|
68 #ifdef HAVE_TTY | 68 #ifdef HAVE_TTY |
69 #include "console-tty.h" | 69 #include "console-tty.h" |
70 #endif /* HAVE_TTY */ | 70 #endif /* HAVE_TTY */ |
71 | 71 |
72 /* Note: We have to be careful throughout this code to properly handle | 72 /* Note: We have to be careful throughout this code to properly handle |
73 and differentiate between Bufbytes and Emchars. | 73 and differentiate between Intbytes and Emchars. |
74 | 74 |
75 Since strings are generally composed of Bufbytes, I've taken the tack | 75 Since strings are generally composed of Intbytes, I've taken the tack |
76 that any contiguous set of Bufbytes is called a "string", while | 76 that any contiguous set of Intbytes is called a "string", while |
77 any contiguous set of Emchars is called an "array". */ | 77 any contiguous set of Emchars is called an "array". */ |
78 | 78 |
79 /* Return value to indicate a failure by an add_*_rune routine to add | 79 /* Return value to indicate a failure by an add_*_rune routine to add |
80 a rune, but no propagation information needs to be returned. */ | 80 a rune, but no propagation information needs to be returned. */ |
81 #define ADD_FAILED (prop_block_dynarr *) 1 | 81 #define ADD_FAILED (prop_block_dynarr *) 1 |
91 : vertical_clip) | 91 : vertical_clip) |
92 | 92 |
93 /* The following structures are completely private to redisplay.c so | 93 /* The following structures are completely private to redisplay.c so |
94 we put them here instead of in a header file, for modularity. */ | 94 we put them here instead of in a header file, for modularity. */ |
95 | 95 |
96 /* NOTE: Bytinds not Bufpos's in this structure. */ | 96 /* NOTE: Bytebposs not Charbpos's in this structure. */ |
97 | 97 |
98 typedef struct position_redisplay_data_type | 98 typedef struct position_redisplay_data_type |
99 { | 99 { |
100 /* This information is normally filled in by the create_*_block | 100 /* This information is normally filled in by the create_*_block |
101 routines and is used by the add_*_rune routines. */ | 101 routines and is used by the add_*_rune routines. */ |
119 | 119 |
120 int last_char_width; /* The width of the previous character. */ | 120 int last_char_width; /* The width of the previous character. */ |
121 int font_is_bogus; /* If true, it means we couldn't instantiate | 121 int font_is_bogus; /* If true, it means we couldn't instantiate |
122 the font for this charset, so we substitute | 122 the font for this charset, so we substitute |
123 ~'s from the ASCII charset. */ | 123 ~'s from the ASCII charset. */ |
124 Bytind bi_bufpos; | 124 Bytebpos bi_charbpos; |
125 Bytind bi_endpos; | 125 Bytebpos bi_endpos; |
126 int pixpos; | 126 int pixpos; |
127 int max_pixpos; | 127 int max_pixpos; |
128 int blank_width; /* Width of the blank that is to be added. | 128 int blank_width; /* Width of the blank that is to be added. |
129 This is used to communicate this information | 129 This is used to communicate this information |
130 to add_blank_rune(). | 130 to add_blank_rune(). |
134 blank that exists at the end of the line. | 134 blank that exists at the end of the line. |
135 add_emchar_rune() is called cheesily with | 135 add_emchar_rune() is called cheesily with |
136 the non-printing char '\n', which is stuck | 136 the non-printing char '\n', which is stuck |
137 in the output routines with its width being | 137 in the output routines with its width being |
138 BLANK_WIDTH. */ | 138 BLANK_WIDTH. */ |
139 Bytind bi_cursor_bufpos;/* This stores the buffer position of the cursor. */ | 139 Bytebpos bi_cursor_charbpos;/* This stores the buffer position of the cursor. */ |
140 unsigned int cursor_type :3; | 140 unsigned int cursor_type :3; |
141 int cursor_x; /* rune block cursor is at */ | 141 int cursor_x; /* rune block cursor is at */ |
142 int start_col; /* Number of character columns (each column has | 142 int start_col; /* Number of character columns (each column has |
143 a width of the default char width) that still | 143 a width of the default char width) that still |
144 need to be skipped. This is used for horizontal | 144 need to be skipped. This is used for horizontal |
145 scrolling, where a certain number of columns | 145 scrolling, where a certain number of columns |
146 (those off the left side of the screen) need | 146 (those off the left side of the screen) need |
147 to be skipped before anything is displayed. */ | 147 to be skipped before anything is displayed. */ |
148 Bytind bi_start_col_enabled; | 148 Bytebpos bi_start_col_enabled; |
149 int start_col_xoffset; /* Number of pixels that still need to | 149 int start_col_xoffset; /* Number of pixels that still need to |
150 be skipped. This is used for | 150 be skipped. This is used for |
151 horizontal scrolling of glyphs, where we want | 151 horizontal scrolling of glyphs, where we want |
152 to be able to scroll over part of the glyph. */ | 152 to be able to scroll over part of the glyph. */ |
153 | 153 |
194 PROP_MINIBUF_PROMPT, | 194 PROP_MINIBUF_PROMPT, |
195 PROP_BLANK | 195 PROP_BLANK |
196 }; | 196 }; |
197 | 197 |
198 /* Data that should be propagated to the next line. Either a single | 198 /* Data that should be propagated to the next line. Either a single |
199 Emchar or a string of Bufbyte's. | 199 Emchar or a string of Intbyte's. |
200 | 200 |
201 The actual data that is propagated ends up as a Dynarr of these | 201 The actual data that is propagated ends up as a Dynarr of these |
202 blocks. | 202 blocks. |
203 | 203 |
204 #### It's unclean that both Emchars and Bufbytes are here. | 204 #### It's unclean that both Emchars and Intbytes are here. |
205 */ | 205 */ |
206 | 206 |
207 typedef struct prop_block prop_block; | 207 typedef struct prop_block prop_block; |
208 struct prop_block | 208 struct prop_block |
209 { | 209 { |
211 | 211 |
212 union data | 212 union data |
213 { | 213 { |
214 struct | 214 struct |
215 { | 215 { |
216 Bufbyte *str; | 216 Intbyte *str; |
217 Bytecount len; /* length of the string. */ | 217 Bytecount len; /* length of the string. */ |
218 } p_string; | 218 } p_string; |
219 | 219 |
220 struct | 220 struct |
221 { | 221 { |
222 Emchar ch; | 222 Emchar ch; |
223 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */ | 223 Bytebpos bi_cursor_charbpos; /* NOTE: is in Bytebposs */ |
224 unsigned int cursor_type :3; | 224 unsigned int cursor_type :3; |
225 } p_char; | 225 } p_char; |
226 | 226 |
227 struct | 227 struct |
228 { | 228 { |
247 Lisp_Object cur_ext); | 247 Lisp_Object cur_ext); |
248 static prop_block_dynarr *add_glyph_rune (pos_data *data, | 248 static prop_block_dynarr *add_glyph_rune (pos_data *data, |
249 struct glyph_block *gb, | 249 struct glyph_block *gb, |
250 int pos_type, int allow_cursor, | 250 int pos_type, int allow_cursor, |
251 struct glyph_cachel *cachel); | 251 struct glyph_cachel *cachel); |
252 static Bytind create_text_block (struct window *w, struct display_line *dl, | 252 static Bytebpos create_text_block (struct window *w, struct display_line *dl, |
253 Bytind bi_start_pos, prop_block_dynarr **prop, | 253 Bytebpos bi_start_pos, prop_block_dynarr **prop, |
254 int type); | 254 int type); |
255 static int create_overlay_glyph_block (struct window *w, | 255 static int create_overlay_glyph_block (struct window *w, |
256 struct display_line *dl); | 256 struct display_line *dl); |
257 static void create_left_glyph_block (struct window *w, | 257 static void create_left_glyph_block (struct window *w, |
258 struct display_line *dl, | 258 struct display_line *dl, |
260 static void create_right_glyph_block (struct window *w, | 260 static void create_right_glyph_block (struct window *w, |
261 struct display_line *dl); | 261 struct display_line *dl); |
262 static void redisplay_windows (Lisp_Object window, int skip_selected); | 262 static void redisplay_windows (Lisp_Object window, int skip_selected); |
263 static void decode_mode_spec (struct window *w, Emchar spec, int type); | 263 static void decode_mode_spec (struct window *w, Emchar spec, int type); |
264 static void free_display_line (struct display_line *dl); | 264 static void free_display_line (struct display_line *dl); |
265 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, | 265 static void update_line_start_cache (struct window *w, Charbpos from, Charbpos to, |
266 Bufpos point, int no_regen); | 266 Charbpos point, int no_regen); |
267 static int point_visible (struct window *w, Bufpos point, int type); | 267 static int point_visible (struct window *w, Charbpos point, int type); |
268 | 268 |
269 /* This used to be 10 but 30 seems to give much better performance. */ | 269 /* This used to be 10 but 30 seems to give much better performance. */ |
270 #define INIT_MAX_PREEMPTS 30 | 270 #define INIT_MAX_PREEMPTS 30 |
271 static int max_preempts; | 271 static int max_preempts; |
272 | 272 |
302 /* #### probably temporary */ | 302 /* #### probably temporary */ |
303 Fixnum cache_adjustment; | 303 Fixnum cache_adjustment; |
304 | 304 |
305 /* This holds a string representing the text corresponding to a single | 305 /* This holds a string representing the text corresponding to a single |
306 modeline % spec. */ | 306 modeline % spec. */ |
307 static Bufbyte_dynarr *mode_spec_bufbyte_string; | 307 static Intbyte_dynarr *mode_spec_intbyte_string; |
308 | 308 |
309 int in_display; /* 1 if in redisplay. */ | 309 int in_display; /* 1 if in redisplay. */ |
310 | 310 |
311 int disable_preemption; /* Used for debugging redisplay and for | 311 int disable_preemption; /* Used for debugging redisplay and for |
312 force-redisplay. */ | 312 force-redisplay. */ |
492 | 492 |
493 static Emchar_dynarr *rtw_emchar_dynarr; | 493 static Emchar_dynarr *rtw_emchar_dynarr; |
494 | 494 |
495 int | 495 int |
496 redisplay_text_width_string (struct window *w, int findex, | 496 redisplay_text_width_string (struct window *w, int findex, |
497 Bufbyte *nonreloc, Lisp_Object reloc, | 497 Intbyte *nonreloc, Lisp_Object reloc, |
498 Bytecount offset, Bytecount len) | 498 Bytecount offset, Bytecount len) |
499 { | 499 { |
500 if (!rtw_emchar_dynarr) | 500 if (!rtw_emchar_dynarr) |
501 rtw_emchar_dynarr = Dynarr_new (Emchar); | 501 rtw_emchar_dynarr = Dynarr_new (Emchar); |
502 Dynarr_reset (rtw_emchar_dynarr); | 502 Dynarr_reset (rtw_emchar_dynarr); |
503 | 503 |
504 fixup_internal_substring (nonreloc, reloc, offset, &len); | 504 fixup_internal_substring (nonreloc, reloc, offset, &len); |
505 if (STRINGP (reloc)) | 505 if (STRINGP (reloc)) |
506 nonreloc = XSTRING_DATA (reloc); | 506 nonreloc = XSTRING_DATA (reloc); |
507 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr); | 507 convert_intbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr); |
508 return redisplay_text_width_emchar_string | 508 return redisplay_text_width_emchar_string |
509 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0), | 509 (w, findex, Dynarr_atp (rtw_emchar_dynarr, 0), |
510 Dynarr_length (rtw_emchar_dynarr)); | 510 Dynarr_length (rtw_emchar_dynarr)); |
511 } | 511 } |
512 | 512 |
513 int | 513 int |
514 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face, | 514 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face, |
515 Bufbyte *nonreloc, Lisp_Object reloc, | 515 Intbyte *nonreloc, Lisp_Object reloc, |
516 Bytecount offset, Bytecount len) | 516 Bytecount offset, Bytecount len) |
517 { | 517 { |
518 unsigned char charsets[NUM_LEADING_BYTES]; | 518 unsigned char charsets[NUM_LEADING_BYTES]; |
519 Lisp_Object frame; | 519 Lisp_Object frame; |
520 struct face_cachel cachel; | 520 struct face_cachel cachel; |
524 Dynarr_reset (rtw_emchar_dynarr); | 524 Dynarr_reset (rtw_emchar_dynarr); |
525 | 525 |
526 fixup_internal_substring (nonreloc, reloc, offset, &len); | 526 fixup_internal_substring (nonreloc, reloc, offset, &len); |
527 if (STRINGP (reloc)) | 527 if (STRINGP (reloc)) |
528 nonreloc = XSTRING_DATA (reloc); | 528 nonreloc = XSTRING_DATA (reloc); |
529 convert_bufbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr); | 529 convert_intbyte_string_into_emchar_dynarr (nonreloc, len, rtw_emchar_dynarr); |
530 find_charsets_in_bufbyte_string (charsets, nonreloc, len); | 530 find_charsets_in_intbyte_string (charsets, nonreloc, len); |
531 reset_face_cachel (&cachel); | 531 reset_face_cachel (&cachel); |
532 cachel.face = face; | 532 cachel.face = face; |
533 XSETFRAME (frame, f); | 533 XSETFRAME (frame, f); |
534 ensure_face_cachel_complete (&cachel, frame, charsets); | 534 ensure_face_cachel_complete (&cachel, frame, charsets); |
535 return DEVMETH (XDEVICE (FRAME_DEVICE (f)), | 535 return DEVMETH (XDEVICE (FRAME_DEVICE (f)), |
685 representation of the buffer contents starting from the given | 685 representation of the buffer contents starting from the given |
686 position when displayed in the given window. The display line ends | 686 position when displayed in the given window. The display line ends |
687 when the contents of the line reach the right boundary of the given | 687 when the contents of the line reach the right boundary of the given |
688 window. */ | 688 window. */ |
689 | 689 |
690 static Bufpos | 690 static Charbpos |
691 generate_display_line (struct window *w, struct display_line *dl, int bounds, | 691 generate_display_line (struct window *w, struct display_line *dl, int bounds, |
692 Bufpos start_pos, prop_block_dynarr **prop, | 692 Charbpos start_pos, prop_block_dynarr **prop, |
693 int type) | 693 int type) |
694 { | 694 { |
695 Bufpos ret_bufpos; | 695 Charbpos ret_charbpos; |
696 int overlay_width; | 696 int overlay_width; |
697 struct buffer *b = XBUFFER (WINDOW_BUFFER (w)); | 697 struct buffer *b = XBUFFER (WINDOW_BUFFER (w)); |
698 | 698 |
699 /* If our caller hasn't already set the boundaries, then do so now. */ | 699 /* If our caller hasn't already set the boundaries, then do so now. */ |
700 if (!bounds) | 700 if (!bounds) |
718 dl->modeline = 0; | 718 dl->modeline = 0; |
719 | 719 |
720 /* Create a display block for the text region of the line. */ | 720 /* Create a display block for the text region of the line. */ |
721 { | 721 { |
722 /* #### urk urk urk!!! Chuck fix this shit! */ | 722 /* #### urk urk urk!!! Chuck fix this shit! */ |
723 Bytind hacked_up_bytind = | 723 Bytebpos hacked_up_bytebpos = |
724 create_text_block (w, dl, bufpos_to_bytind (b, start_pos), | 724 create_text_block (w, dl, charbpos_to_bytebpos (b, start_pos), |
725 prop, type); | 725 prop, type); |
726 if (hacked_up_bytind > BI_BUF_ZV (b)) | 726 if (hacked_up_bytebpos > BI_BUF_ZV (b)) |
727 ret_bufpos = BUF_ZV (b) + 1; | 727 ret_charbpos = BUF_ZV (b) + 1; |
728 else | 728 else |
729 ret_bufpos = bytind_to_bufpos (b, hacked_up_bytind); | 729 ret_charbpos = bytebpos_to_charbpos (b, hacked_up_bytebpos); |
730 } | 730 } |
731 dl->bufpos = start_pos; | 731 dl->charbpos = start_pos; |
732 if (dl->end_bufpos < dl->bufpos) | 732 if (dl->end_charbpos < dl->charbpos) |
733 dl->end_bufpos = dl->bufpos; | 733 dl->end_charbpos = dl->charbpos; |
734 | 734 |
735 if (MARKERP (Voverlay_arrow_position) | 735 if (MARKERP (Voverlay_arrow_position) |
736 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position)) | 736 && EQ (w->buffer, Fmarker_buffer (Voverlay_arrow_position)) |
737 && start_pos == marker_position (Voverlay_arrow_position) | 737 && start_pos == marker_position (Voverlay_arrow_position) |
738 && (STRINGP (Voverlay_arrow_string) | 738 && (STRINGP (Voverlay_arrow_string) |
754 create_right_glyph_block (w, dl); | 754 create_right_glyph_block (w, dl); |
755 | 755 |
756 /* In the future additional types of display blocks may be generated | 756 /* In the future additional types of display blocks may be generated |
757 here. */ | 757 here. */ |
758 | 758 |
759 w->last_redisplay_pos = ret_bufpos; | 759 w->last_redisplay_pos = ret_charbpos; |
760 | 760 |
761 return ret_bufpos; | 761 return ret_charbpos; |
762 } | 762 } |
763 | 763 |
764 /* Adds an hscroll glyph to a display block. If this is called, then | 764 /* Adds an hscroll glyph to a display block. If this is called, then |
765 the block had better be empty. | 765 the block had better be empty. |
766 | 766 |
772 static prop_block_dynarr * | 772 static prop_block_dynarr * |
773 add_hscroll_rune (pos_data *data) | 773 add_hscroll_rune (pos_data *data) |
774 { | 774 { |
775 struct glyph_block gb; | 775 struct glyph_block gb; |
776 prop_block_dynarr *retval; | 776 prop_block_dynarr *retval; |
777 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos; | 777 Bytebpos bi_old_cursor_charbpos = data->bi_cursor_charbpos; |
778 int old_cursor_type = data->cursor_type; | 778 int old_cursor_type = data->cursor_type; |
779 Bytind bi_old_bufpos = data->bi_bufpos; | 779 Bytebpos bi_old_charbpos = data->bi_charbpos; |
780 | 780 |
781 if (data->cursor_type == CURSOR_ON | 781 if (data->cursor_type == CURSOR_ON |
782 && data->bi_cursor_bufpos >= data->bi_start_col_enabled | 782 && data->bi_cursor_charbpos >= data->bi_start_col_enabled |
783 && data->bi_cursor_bufpos <= data->bi_bufpos) | 783 && data->bi_cursor_charbpos <= data->bi_charbpos) |
784 { | 784 { |
785 data->bi_cursor_bufpos = data->bi_start_col_enabled; | 785 data->bi_cursor_charbpos = data->bi_start_col_enabled; |
786 } | 786 } |
787 else | 787 else |
788 { | 788 { |
789 data->cursor_type = NO_CURSOR; | 789 data->cursor_type = NO_CURSOR; |
790 } | 790 } |
791 | 791 |
792 data->bi_endpos = data->bi_bufpos; | 792 data->bi_endpos = data->bi_charbpos; |
793 data->bi_bufpos = data->bi_start_col_enabled; | 793 data->bi_charbpos = data->bi_start_col_enabled; |
794 | 794 |
795 gb.extent = Qnil; | 795 gb.extent = Qnil; |
796 gb.glyph = Vhscroll_glyph; | 796 gb.glyph = Vhscroll_glyph; |
797 { | 797 { |
798 int oldpixpos = data->pixpos; | 798 int oldpixpos = data->pixpos; |
801 HSCROLL_GLYPH_INDEX)); | 801 HSCROLL_GLYPH_INDEX)); |
802 data->hscroll_glyph_width_adjust = | 802 data->hscroll_glyph_width_adjust = |
803 data->pixpos - oldpixpos - space_width (XWINDOW (data->window)); | 803 data->pixpos - oldpixpos - space_width (XWINDOW (data->window)); |
804 } | 804 } |
805 data->bi_endpos = 0; | 805 data->bi_endpos = 0; |
806 data->bi_cursor_bufpos = bi_old_cursor_bufpos; | 806 data->bi_cursor_charbpos = bi_old_cursor_charbpos; |
807 data->cursor_type = old_cursor_type; | 807 data->cursor_type = old_cursor_type; |
808 data->bi_bufpos = bi_old_bufpos; | 808 data->bi_charbpos = bi_old_charbpos; |
809 | 809 |
810 data->bi_start_col_enabled = 0; | 810 data->bi_start_col_enabled = 0; |
811 return retval; | 811 return retval; |
812 } | 812 } |
813 | 813 |
901 } | 901 } |
902 | 902 |
903 crb->findex = data->findex; | 903 crb->findex = data->findex; |
904 crb->xpos = data->pixpos; | 904 crb->xpos = data->pixpos; |
905 crb->width = width; | 905 crb->width = width; |
906 if (data->bi_bufpos) | 906 if (data->bi_charbpos) |
907 { | 907 { |
908 if (NILP (data->string)) | 908 if (NILP (data->string)) |
909 crb->bufpos = | 909 crb->charbpos = |
910 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))), | 910 bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))), |
911 data->bi_bufpos); | 911 data->bi_charbpos); |
912 else | 912 else |
913 crb->bufpos = | 913 crb->charbpos = |
914 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos); | 914 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_charbpos); |
915 } | 915 } |
916 else if (data->is_modeline) | 916 else if (data->is_modeline) |
917 crb->bufpos = data->modeline_charpos; | 917 crb->charbpos = data->modeline_charpos; |
918 else | 918 else |
919 /* Text but not in buffer */ | 919 /* Text but not in buffer */ |
920 crb->bufpos = 0; | 920 crb->charbpos = 0; |
921 crb->type = RUNE_CHAR; | 921 crb->type = RUNE_CHAR; |
922 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch; | 922 crb->object.chr.ch = data->font_is_bogus ? '~' : data->ch; |
923 crb->endpos = 0; | 923 crb->endpos = 0; |
924 | 924 |
925 if (data->cursor_type == CURSOR_ON) | 925 if (data->cursor_type == CURSOR_ON) |
926 { | 926 { |
927 if (data->bi_bufpos == data->bi_cursor_bufpos) | 927 if (data->bi_charbpos == data->bi_cursor_charbpos) |
928 { | 928 { |
929 crb->cursor_type = CURSOR_ON; | 929 crb->cursor_type = CURSOR_ON; |
930 data->cursor_x = Dynarr_length (data->db->runes); | 930 data->cursor_x = Dynarr_length (data->db->runes); |
931 } | 931 } |
932 else | 932 else |
956 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune | 956 /* Given a string C_STRING of length C_LENGTH, call add_emchar_rune |
957 for each character in the string. Propagate any left-over data | 957 for each character in the string. Propagate any left-over data |
958 unless NO_PROP is non-zero. */ | 958 unless NO_PROP is non-zero. */ |
959 | 959 |
960 static prop_block_dynarr * | 960 static prop_block_dynarr * |
961 add_bufbyte_string_runes (pos_data *data, Bufbyte *c_string, | 961 add_intbyte_string_runes (pos_data *data, Intbyte *c_string, |
962 Bytecount c_length, int no_prop) | 962 Bytecount c_length, int no_prop) |
963 { | 963 { |
964 Bufbyte *pos, *end = c_string + c_length; | 964 Intbyte *pos, *end = c_string + c_length; |
965 prop_block_dynarr *prop; | 965 prop_block_dynarr *prop; |
966 | 966 |
967 /* #### This function is too simplistic. It needs to do the same | 967 /* #### This function is too simplistic. It needs to do the same |
968 sort of character interpretation (display-table lookup, | 968 sort of character interpretation (display-table lookup, |
969 ctl-arrow checking), etc. that create_text_block() does. | 969 ctl-arrow checking), etc. that create_text_block() does. |
970 The functionality to do this in that routine needs to be | 970 The functionality to do this in that routine needs to be |
971 modularized. */ | 971 modularized. */ |
972 | 972 |
973 for (pos = c_string; pos < end;) | 973 for (pos = c_string; pos < end;) |
974 { | 974 { |
975 Bufbyte *old_pos = pos; | 975 Intbyte *old_pos = pos; |
976 | 976 |
977 data->ch = charptr_emchar (pos); | 977 data->ch = charptr_emchar (pos); |
978 | 978 |
979 prop = add_emchar_rune (data); | 979 prop = add_emchar_rune (data); |
980 | 980 |
987 struct prop_block pb; | 987 struct prop_block pb; |
988 Bytecount len = end - pos; | 988 Bytecount len = end - pos; |
989 prop = Dynarr_new (prop_block); | 989 prop = Dynarr_new (prop_block); |
990 | 990 |
991 pb.type = PROP_STRING; | 991 pb.type = PROP_STRING; |
992 pb.data.p_string.str = xnew_array (Bufbyte, len); | 992 pb.data.p_string.str = xnew_array (Intbyte, len); |
993 strncpy ((char *) pb.data.p_string.str, (char *) pos, len); | 993 strncpy ((char *) pb.data.p_string.str, (char *) pos, len); |
994 pb.data.p_string.len = len; | 994 pb.data.p_string.len = len; |
995 | 995 |
996 Dynarr_add (prop, pb); | 996 Dynarr_add (prop, pb); |
997 return prop; | 997 return prop; |
1054 assert (data->pixpos + data->blank_width <= data->max_pixpos); | 1054 assert (data->pixpos + data->blank_width <= data->max_pixpos); |
1055 | 1055 |
1056 rb.findex = data->findex; | 1056 rb.findex = data->findex; |
1057 rb.xpos = data->pixpos; | 1057 rb.xpos = data->pixpos; |
1058 rb.width = data->blank_width; | 1058 rb.width = data->blank_width; |
1059 if (data->bi_bufpos) | 1059 if (data->bi_charbpos) |
1060 rb.bufpos = | 1060 rb.charbpos = |
1061 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))), | 1061 bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))), |
1062 data->bi_bufpos); | 1062 data->bi_charbpos); |
1063 else | 1063 else |
1064 /* #### and this is really correct too? */ | 1064 /* #### and this is really correct too? */ |
1065 rb.bufpos = 0; | 1065 rb.charbpos = 0; |
1066 rb.endpos = 0; | 1066 rb.endpos = 0; |
1067 rb.type = RUNE_BLANK; | 1067 rb.type = RUNE_BLANK; |
1068 | 1068 |
1069 if (data->cursor_type == CURSOR_ON) | 1069 if (data->cursor_type == CURSOR_ON) |
1070 { | 1070 { |
1071 if (data->bi_bufpos == data->bi_cursor_bufpos) | 1071 if (data->bi_charbpos == data->bi_cursor_charbpos) |
1072 { | 1072 { |
1073 rb.cursor_type = CURSOR_ON; | 1073 rb.cursor_type = CURSOR_ON; |
1074 data->cursor_x = Dynarr_length (data->db->runes); | 1074 data->cursor_x = Dynarr_length (data->db->runes); |
1075 } | 1075 } |
1076 else | 1076 else |
1256 { | 1256 { |
1257 prop_block_dynarr *prop = NULL; | 1257 prop_block_dynarr *prop = NULL; |
1258 | 1258 |
1259 if (STRINGP (entry)) | 1259 if (STRINGP (entry)) |
1260 { | 1260 { |
1261 prop = add_bufbyte_string_runes (data, | 1261 prop = add_intbyte_string_runes (data, |
1262 XSTRING_DATA (entry), | 1262 XSTRING_DATA (entry), |
1263 XSTRING_LENGTH (entry), | 1263 XSTRING_LENGTH (entry), |
1264 0); | 1264 0); |
1265 } | 1265 } |
1266 else if (GLYPHP (entry)) | 1266 else if (GLYPHP (entry)) |
1291 if (EQ (XCAR (entry), Qformat) | 1291 if (EQ (XCAR (entry), Qformat) |
1292 && CONSP (XCDR (entry)) | 1292 && CONSP (XCDR (entry)) |
1293 && STRINGP (XCAR (XCDR (entry)))) | 1293 && STRINGP (XCAR (XCDR (entry)))) |
1294 { | 1294 { |
1295 Lisp_Object format = XCAR (XCDR (entry)); | 1295 Lisp_Object format = XCAR (XCDR (entry)); |
1296 Bytind len = XSTRING_LENGTH (format); | 1296 Bytebpos len = XSTRING_LENGTH (format); |
1297 Bufbyte *src = XSTRING_DATA (format), *end = src + len; | 1297 Intbyte *src = XSTRING_DATA (format), *end = src + len; |
1298 Bufbyte *result = alloca_array (Bufbyte, len); | 1298 Intbyte *result = alloca_array (Intbyte, len); |
1299 Bufbyte *dst = result; | 1299 Intbyte *dst = result; |
1300 | 1300 |
1301 while (src < end) | 1301 while (src < end) |
1302 { | 1302 { |
1303 Emchar c = charptr_emchar (src); | 1303 Emchar c = charptr_emchar (src); |
1304 INC_CHARPTR (src); | 1304 INC_CHARPTR (src); |
1318 break; | 1318 break; |
1319 /* #### unimplemented */ | 1319 /* #### unimplemented */ |
1320 } | 1320 } |
1321 } | 1321 } |
1322 } | 1322 } |
1323 prop = add_bufbyte_string_runes (data, result, dst - result, 0); | 1323 prop = add_intbyte_string_runes (data, result, dst - result, 0); |
1324 } | 1324 } |
1325 } | 1325 } |
1326 | 1326 |
1327 /* Else blow it off because someone added a bad entry and we don't | 1327 /* Else blow it off because someone added a bad entry and we don't |
1328 have any safe way of signaling an error. */ | 1328 have any safe way of signaling an error. */ |
1379 /* #### This function also doesn't even pay attention to ADD_FAILED! | 1379 /* #### This function also doesn't even pay attention to ADD_FAILED! |
1380 This is seriously fucked! Seven ####'s in 130 lines -- is that a | 1380 This is seriously fucked! Seven ####'s in 130 lines -- is that a |
1381 record? */ | 1381 record? */ |
1382 int elt; | 1382 int elt; |
1383 prop_block_dynarr *add_failed; | 1383 prop_block_dynarr *add_failed; |
1384 Bytind bi_old_cursor_bufpos = data->bi_cursor_bufpos; | 1384 Bytebpos bi_old_cursor_charbpos = data->bi_cursor_charbpos; |
1385 int old_cursor_type = data->cursor_type; | 1385 int old_cursor_type = data->cursor_type; |
1386 | 1386 |
1387 for (elt = 0; elt < Dynarr_length (*prop); elt++) | 1387 for (elt = 0; elt < Dynarr_length (*prop); elt++) |
1388 { | 1388 { |
1389 struct prop_block *pb = Dynarr_atp (*prop, elt); | 1389 struct prop_block *pb = Dynarr_atp (*prop, elt); |
1390 | 1390 |
1391 switch (pb->type) | 1391 switch (pb->type) |
1392 { | 1392 { |
1393 case PROP_CHAR: | 1393 case PROP_CHAR: |
1394 data->ch = pb->data.p_char.ch; | 1394 data->ch = pb->data.p_char.ch; |
1395 data->bi_cursor_bufpos = pb->data.p_char.bi_cursor_bufpos; | 1395 data->bi_cursor_charbpos = pb->data.p_char.bi_cursor_charbpos; |
1396 data->cursor_type = pb->data.p_char.cursor_type; | 1396 data->cursor_type = pb->data.p_char.cursor_type; |
1397 add_failed = add_emchar_rune (data); | 1397 add_failed = add_emchar_rune (data); |
1398 | 1398 |
1399 if (add_failed) | 1399 if (add_failed) |
1400 goto oops_no_more_space; | 1400 goto oops_no_more_space; |
1401 break; | 1401 break; |
1402 case PROP_STRING: | 1402 case PROP_STRING: |
1403 if (pb->data.p_string.str) | 1403 if (pb->data.p_string.str) |
1404 xfree (pb->data.p_string.str); | 1404 xfree (pb->data.p_string.str); |
1405 /* #### bogus bogus -- this doesn't do anything! | 1405 /* #### bogus bogus -- this doesn't do anything! |
1406 Should probably call add_bufbyte_string_runes(), | 1406 Should probably call add_intbyte_string_runes(), |
1407 once that function is fixed. */ | 1407 once that function is fixed. */ |
1408 break; | 1408 break; |
1409 case PROP_MINIBUF_PROMPT: | 1409 case PROP_MINIBUF_PROMPT: |
1410 { | 1410 { |
1411 face_index old_findex = data->findex; | 1411 face_index old_findex = data->findex; |
1412 Bytind bi_old_bufpos = data->bi_bufpos; | 1412 Bytebpos bi_old_charbpos = data->bi_charbpos; |
1413 | 1413 |
1414 data->findex = DEFAULT_INDEX; | 1414 data->findex = DEFAULT_INDEX; |
1415 data->bi_bufpos = 0; | 1415 data->bi_charbpos = 0; |
1416 data->cursor_type = NO_CURSOR; | 1416 data->cursor_type = NO_CURSOR; |
1417 | 1417 |
1418 while (pb->data.p_string.len > 0) | 1418 while (pb->data.p_string.len > 0) |
1419 { | 1419 { |
1420 data->ch = charptr_emchar (pb->data.p_string.str); | 1420 data->ch = charptr_emchar (pb->data.p_string.str); |
1421 add_failed = add_emchar_rune (data); | 1421 add_failed = add_emchar_rune (data); |
1422 | 1422 |
1423 if (add_failed) | 1423 if (add_failed) |
1424 { | 1424 { |
1425 data->findex = old_findex; | 1425 data->findex = old_findex; |
1426 data->bi_bufpos = bi_old_bufpos; | 1426 data->bi_charbpos = bi_old_charbpos; |
1427 goto oops_no_more_space; | 1427 goto oops_no_more_space; |
1428 } | 1428 } |
1429 else | 1429 else |
1430 { | 1430 { |
1431 /* Complicated equivalent of ptr++, len-- */ | 1431 /* Complicated equivalent of ptr++, len-- */ |
1432 Bufbyte *oldpos = pb->data.p_string.str; | 1432 Intbyte *oldpos = pb->data.p_string.str; |
1433 INC_CHARPTR (pb->data.p_string.str); | 1433 INC_CHARPTR (pb->data.p_string.str); |
1434 pb->data.p_string.len -= pb->data.p_string.str - oldpos; | 1434 pb->data.p_string.len -= pb->data.p_string.str - oldpos; |
1435 } | 1435 } |
1436 } | 1436 } |
1437 | 1437 |
1438 data->findex = old_findex; | 1438 data->findex = old_findex; |
1439 /* ##### FIXME FIXME FIXME -- Upon successful return from | 1439 /* ##### FIXME FIXME FIXME -- Upon successful return from |
1440 this function, data->bi_bufpos is automatically incremented. | 1440 this function, data->bi_charbpos is automatically incremented. |
1441 However, we don't want that to happen if we were adding | 1441 However, we don't want that to happen if we were adding |
1442 the minibuffer prompt. */ | 1442 the minibuffer prompt. */ |
1443 { | 1443 { |
1444 struct buffer *buf = | 1444 struct buffer *buf = |
1445 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))); | 1445 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))); |
1446 /* #### Chuck fix this shit or I'm gonna scream! */ | 1446 /* #### Chuck fix this shit or I'm gonna scream! */ |
1447 if (bi_old_bufpos > BI_BUF_BEGV (buf)) | 1447 if (bi_old_charbpos > BI_BUF_BEGV (buf)) |
1448 data->bi_bufpos = prev_bytind (buf, bi_old_bufpos); | 1448 data->bi_charbpos = prev_bytebpos (buf, bi_old_charbpos); |
1449 else | 1449 else |
1450 /* #### is this correct? Does anyone know? | 1450 /* #### is this correct? Does anyone know? |
1451 Does anyone care? Is this a cheesy hack or what? */ | 1451 Does anyone care? Is this a cheesy hack or what? */ |
1452 data->bi_bufpos = BI_BUF_BEGV (buf) - 1; | 1452 data->bi_charbpos = BI_BUF_BEGV (buf) - 1; |
1453 } | 1453 } |
1454 } | 1454 } |
1455 break; | 1455 break; |
1456 case PROP_BLANK: | 1456 case PROP_BLANK: |
1457 { | 1457 { |
1461 int old_width = data->blank_width; | 1461 int old_width = data->blank_width; |
1462 face_index old_findex = data->findex; | 1462 face_index old_findex = data->findex; |
1463 | 1463 |
1464 data->findex = pb->data.p_blank.findex; | 1464 data->findex = pb->data.p_blank.findex; |
1465 data->blank_width = pb->data.p_blank.width; | 1465 data->blank_width = pb->data.p_blank.width; |
1466 data->bi_cursor_bufpos = 0; | 1466 data->bi_cursor_charbpos = 0; |
1467 data->cursor_type = IGNORE_CURSOR; | 1467 data->cursor_type = IGNORE_CURSOR; |
1468 | 1468 |
1469 if (data->pixpos + data->blank_width > data->max_pixpos) | 1469 if (data->pixpos + data->blank_width > data->max_pixpos) |
1470 data->blank_width = data->max_pixpos - data->pixpos; | 1470 data->blank_width = data->max_pixpos - data->pixpos; |
1471 | 1471 |
1494 } | 1494 } |
1495 } | 1495 } |
1496 | 1496 |
1497 oops_no_more_space: | 1497 oops_no_more_space: |
1498 | 1498 |
1499 data->bi_cursor_bufpos = bi_old_cursor_bufpos; | 1499 data->bi_cursor_charbpos = bi_old_cursor_charbpos; |
1500 data->cursor_type = old_cursor_type; | 1500 data->cursor_type = old_cursor_type; |
1501 if (elt < Dynarr_length (*prop)) | 1501 if (elt < Dynarr_length (*prop)) |
1502 { | 1502 { |
1503 Dynarr_delete_many (*prop, 0, elt); | 1503 Dynarr_delete_many (*prop, 0, elt); |
1504 return *prop; | 1504 return *prop; |
1668 ERROR_ME_NOT, 1); | 1668 ERROR_ME_NOT, 1); |
1669 if (TEXT_IMAGE_INSTANCEP (instance)) | 1669 if (TEXT_IMAGE_INSTANCEP (instance)) |
1670 { | 1670 { |
1671 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance); | 1671 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance); |
1672 face_index orig_findex = data->findex; | 1672 face_index orig_findex = data->findex; |
1673 Bytind orig_bufpos = data->bi_bufpos; | 1673 Bytebpos orig_charbpos = data->bi_charbpos; |
1674 Bytind orig_start_col_enabled = data->bi_start_col_enabled; | 1674 Bytebpos orig_start_col_enabled = data->bi_start_col_enabled; |
1675 | 1675 |
1676 data->findex = findex; | 1676 data->findex = findex; |
1677 data->bi_start_col_enabled = 0; | 1677 data->bi_start_col_enabled = 0; |
1678 if (!allow_cursor) | 1678 if (!allow_cursor) |
1679 data->bi_bufpos = 0; | 1679 data->bi_charbpos = 0; |
1680 add_bufbyte_string_runes (data, XSTRING_DATA (string), | 1680 add_intbyte_string_runes (data, XSTRING_DATA (string), |
1681 XSTRING_LENGTH (string), 0); | 1681 XSTRING_LENGTH (string), 0); |
1682 data->findex = orig_findex; | 1682 data->findex = orig_findex; |
1683 data->bi_bufpos = orig_bufpos; | 1683 data->bi_charbpos = orig_charbpos; |
1684 data->bi_start_col_enabled = orig_start_col_enabled; | 1684 data->bi_start_col_enabled = orig_start_col_enabled; |
1685 return NULL; | 1685 return NULL; |
1686 } | 1686 } |
1687 | 1687 |
1688 rb.findex = findex; | 1688 rb.findex = findex; |
1689 rb.xpos = data->pixpos; | 1689 rb.xpos = data->pixpos; |
1690 rb.width = width; | 1690 rb.width = width; |
1691 rb.bufpos = 0; /* glyphs are never "at" anywhere */ | 1691 rb.charbpos = 0; /* glyphs are never "at" anywhere */ |
1692 if (data->bi_endpos) | 1692 if (data->bi_endpos) |
1693 /* #### is this necessary at all? */ | 1693 /* #### is this necessary at all? */ |
1694 rb.endpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)), | 1694 rb.endpos = bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (w)), |
1695 data->bi_endpos); | 1695 data->bi_endpos); |
1696 else | 1696 else |
1697 rb.endpos = 0; | 1697 rb.endpos = 0; |
1698 rb.type = RUNE_DGLYPH; | 1698 rb.type = RUNE_DGLYPH; |
1699 rb.object.dglyph.glyph = gb->glyph; | 1699 rb.object.dglyph.glyph = gb->glyph; |
1700 rb.object.dglyph.extent = gb->extent; | 1700 rb.object.dglyph.extent = gb->extent; |
1701 rb.object.dglyph.xoffset = xoffset; | 1701 rb.object.dglyph.xoffset = xoffset; |
1702 | 1702 |
1703 if (allow_cursor) | 1703 if (allow_cursor) |
1704 { | 1704 { |
1705 rb.bufpos = bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (w)), | 1705 rb.charbpos = bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (w)), |
1706 data->bi_bufpos); | 1706 data->bi_charbpos); |
1707 | 1707 |
1708 if (data->cursor_type == CURSOR_ON) | 1708 if (data->cursor_type == CURSOR_ON) |
1709 { | 1709 { |
1710 if (data->bi_bufpos == data->bi_cursor_bufpos) | 1710 if (data->bi_charbpos == data->bi_cursor_charbpos) |
1711 { | 1711 { |
1712 rb.cursor_type = CURSOR_ON; | 1712 rb.cursor_type = CURSOR_ON; |
1713 data->cursor_x = Dynarr_length (data->db->runes); | 1713 data->cursor_x = Dynarr_length (data->db->runes); |
1714 } | 1714 } |
1715 else | 1715 else |
1799 | 1799 |
1800 /* Given a position for a buffer in a window, ensure that the given | 1800 /* Given a position for a buffer in a window, ensure that the given |
1801 display line DL accurately represents the text on a line starting | 1801 display line DL accurately represents the text on a line starting |
1802 at the given position. | 1802 at the given position. |
1803 | 1803 |
1804 NOTE NOTE NOTE NOTE: This function works with and returns Bytinds. | 1804 NOTE NOTE NOTE NOTE: This function works with and returns Bytebposs. |
1805 You must do appropriate conversion. */ | 1805 You must do appropriate conversion. */ |
1806 | 1806 |
1807 static Bytind | 1807 static Bytebpos |
1808 create_text_block (struct window *w, struct display_line *dl, | 1808 create_text_block (struct window *w, struct display_line *dl, |
1809 Bytind bi_start_pos, prop_block_dynarr **prop, | 1809 Bytebpos bi_start_pos, prop_block_dynarr **prop, |
1810 int type) | 1810 int type) |
1811 { | 1811 { |
1812 struct frame *f = XFRAME (w->frame); | 1812 struct frame *f = XFRAME (w->frame); |
1813 struct buffer *b = XBUFFER (w->buffer); | 1813 struct buffer *b = XBUFFER (w->buffer); |
1814 struct device *d = XDEVICE (f->device); | 1814 struct device *d = XDEVICE (f->device); |
1909 XSETWINDOW (data.window, w); | 1909 XSETWINDOW (data.window, w); |
1910 data.string = Qnil; | 1910 data.string = Qnil; |
1911 data.db = db; | 1911 data.db = db; |
1912 data.dl = dl; | 1912 data.dl = dl; |
1913 | 1913 |
1914 data.bi_bufpos = bi_start_pos; | 1914 data.bi_charbpos = bi_start_pos; |
1915 data.pixpos = dl->bounds.left_in; | 1915 data.pixpos = dl->bounds.left_in; |
1916 data.last_charset = Qunbound; | 1916 data.last_charset = Qunbound; |
1917 data.last_findex = DEFAULT_INDEX; | 1917 data.last_findex = DEFAULT_INDEX; |
1918 data.result_str = Qnil; | 1918 data.result_str = Qnil; |
1919 | 1919 |
1926 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX); | 1926 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX); |
1927 data.max_pixpos -= end_glyph_width; | 1927 data.max_pixpos -= end_glyph_width; |
1928 | 1928 |
1929 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f)) | 1929 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f)) |
1930 { | 1930 { |
1931 data.bi_cursor_bufpos = BI_BUF_ZV (b); | 1931 data.bi_cursor_charbpos = BI_BUF_ZV (b); |
1932 data.cursor_type = CURSOR_ON; | 1932 data.cursor_type = CURSOR_ON; |
1933 } | 1933 } |
1934 else if (MINI_WINDOW_P (w) && !active_minibuffer) | 1934 else if (MINI_WINDOW_P (w) && !active_minibuffer) |
1935 data.cursor_type = NO_CURSOR; | 1935 data.cursor_type = NO_CURSOR; |
1936 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) && | 1936 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) && |
1937 EQ(DEVICE_CONSOLE(d), Vselected_console) && | 1937 EQ(DEVICE_CONSOLE(d), Vselected_console) && |
1938 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&& | 1938 d == XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d))))&& |
1939 f == XFRAME(DEVICE_SELECTED_FRAME(d))) | 1939 f == XFRAME(DEVICE_SELECTED_FRAME(d))) |
1940 { | 1940 { |
1941 data.bi_cursor_bufpos = BI_BUF_PT (b); | 1941 data.bi_cursor_charbpos = BI_BUF_PT (b); |
1942 data.cursor_type = CURSOR_ON; | 1942 data.cursor_type = CURSOR_ON; |
1943 } | 1943 } |
1944 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f))) | 1944 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f))) |
1945 { | 1945 { |
1946 data.bi_cursor_bufpos = bi_marker_position (w->pointm[type]); | 1946 data.bi_cursor_charbpos = bi_marker_position (w->pointm[type]); |
1947 data.cursor_type = CURSOR_ON; | 1947 data.cursor_type = CURSOR_ON; |
1948 } | 1948 } |
1949 else | 1949 else |
1950 data.cursor_type = NO_CURSOR; | 1950 data.cursor_type = NO_CURSOR; |
1951 data.cursor_x = -1; | 1951 data.cursor_x = -1; |
1986 */ | 1986 */ |
1987 while (data.pixpos <= data.max_pixpos | 1987 while (data.pixpos <= data.max_pixpos |
1988 && (active_minibuffer || !NILP (synch_minibuffers_value))) | 1988 && (active_minibuffer || !NILP (synch_minibuffers_value))) |
1989 { | 1989 { |
1990 /* #### This check probably should not be necessary. */ | 1990 /* #### This check probably should not be necessary. */ |
1991 if (data.bi_bufpos > BI_BUF_ZV (b)) | 1991 if (data.bi_charbpos > BI_BUF_ZV (b)) |
1992 { | 1992 { |
1993 /* #### urk! More of this lossage! */ | 1993 /* #### urk! More of this lossage! */ |
1994 data.bi_bufpos--; | 1994 data.bi_charbpos--; |
1995 goto done; | 1995 goto done; |
1996 } | 1996 } |
1997 | 1997 |
1998 /* If selective display was an integer and we aren't working on | 1998 /* If selective display was an integer and we aren't working on |
1999 a continuation line then find the next line we are actually | 1999 a continuation line then find the next line we are actually |
2000 supposed to display. */ | 2000 supposed to display. */ |
2001 if (selective > 0 | 2001 if (selective > 0 |
2002 && (data.bi_bufpos == BI_BUF_BEGV (b) | 2002 && (data.bi_charbpos == BI_BUF_BEGV (b) |
2003 || BUF_FETCH_CHAR (b, prev_bytind (b, data.bi_bufpos)) == '\n')) | 2003 || BUF_FETCH_CHAR (b, prev_bytebpos (b, data.bi_charbpos)) == '\n')) |
2004 { | 2004 { |
2005 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective) | 2005 while (bi_spaces_at_point (b, data.bi_charbpos) >= selective) |
2006 { | 2006 { |
2007 data.bi_bufpos = | 2007 data.bi_charbpos = |
2008 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1); | 2008 bi_find_next_newline_no_quit (b, data.bi_charbpos, 1); |
2009 if (data.bi_bufpos >= BI_BUF_ZV (b)) | 2009 if (data.bi_charbpos >= BI_BUF_ZV (b)) |
2010 { | 2010 { |
2011 data.bi_bufpos = BI_BUF_ZV (b); | 2011 data.bi_charbpos = BI_BUF_ZV (b); |
2012 goto done; | 2012 goto done; |
2013 } | 2013 } |
2014 } | 2014 } |
2015 } | 2015 } |
2016 | 2016 |
2017 /* Check for face changes. */ | 2017 /* Check for face changes. */ |
2018 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end)) | 2018 if (initial || (!no_more_frags && data.bi_charbpos == data.ef->end)) |
2019 { | 2019 { |
2020 /* Now compute the face and begin/end-glyph information. */ | 2020 /* Now compute the face and begin/end-glyph information. */ |
2021 data.findex = | 2021 data.findex = |
2022 /* Remember that the extent-fragment routines deal in Bytind's. */ | 2022 /* Remember that the extent-fragment routines deal in Bytebpos's. */ |
2023 extent_fragment_update (w, data.ef, data.bi_bufpos); | 2023 extent_fragment_update (w, data.ef, data.bi_charbpos); |
2024 | 2024 |
2025 get_display_tables (w, data.findex, &face_dt, &window_dt); | 2025 get_display_tables (w, data.findex, &face_dt, &window_dt); |
2026 | 2026 |
2027 if (data.bi_bufpos == data.ef->end) | 2027 if (data.bi_charbpos == data.ef->end) |
2028 no_more_frags = 1; | 2028 no_more_frags = 1; |
2029 } | 2029 } |
2030 initial = 0; | 2030 initial = 0; |
2031 | 2031 |
2032 /* Determine what is next to be displayed. We first handle any | 2032 /* Determine what is next to be displayed. We first handle any |
2033 glyphs returned by glyphs_at_bufpos. If there are no glyphs to | 2033 glyphs returned by glyphs_at_charbpos. If there are no glyphs to |
2034 display then we determine what to do based on the character at the | 2034 display then we determine what to do based on the character at the |
2035 current buffer position. */ | 2035 current buffer position. */ |
2036 | 2036 |
2037 /* If the current position is covered by an invisible extent, do | 2037 /* If the current position is covered by an invisible extent, do |
2038 nothing (except maybe add some ellipses). | 2038 nothing (except maybe add some ellipses). |
2072 } | 2072 } |
2073 | 2073 |
2074 /* If point is in an invisible region we place it on the | 2074 /* If point is in an invisible region we place it on the |
2075 next visible character. */ | 2075 next visible character. */ |
2076 if (data.cursor_type == CURSOR_ON | 2076 if (data.cursor_type == CURSOR_ON |
2077 && data.bi_bufpos == data.bi_cursor_bufpos) | 2077 && data.bi_charbpos == data.bi_cursor_charbpos) |
2078 { | 2078 { |
2079 data.cursor_type = NEXT_CURSOR; | 2079 data.cursor_type = NEXT_CURSOR; |
2080 } | 2080 } |
2081 | 2081 |
2082 /* #### What if we we're dealing with a display table? */ | 2082 /* #### What if we we're dealing with a display table? */ |
2083 if (data.start_col) | 2083 if (data.start_col) |
2084 data.start_col--; | 2084 data.start_col--; |
2085 | 2085 |
2086 if (data.bi_bufpos == BI_BUF_ZV (b)) | 2086 if (data.bi_charbpos == BI_BUF_ZV (b)) |
2087 goto done; | 2087 goto done; |
2088 else | 2088 else |
2089 INC_BYTIND (b, data.bi_bufpos); | 2089 INC_BYTEBPOS (b, data.bi_charbpos); |
2090 } | 2090 } |
2091 | 2091 |
2092 /* If there is propagation data, then it represents the current | 2092 /* If there is propagation data, then it represents the current |
2093 buffer position being displayed. Add them and advance the | 2093 buffer position being displayed. Add them and advance the |
2094 position counter. This might also add the minibuffer | 2094 position counter. This might also add the minibuffer |
2098 dl->used_prop_data = 1; | 2098 dl->used_prop_data = 1; |
2099 *prop = add_propagation_runes (prop, &data); | 2099 *prop = add_propagation_runes (prop, &data); |
2100 | 2100 |
2101 if (*prop) | 2101 if (*prop) |
2102 goto done; /* gee, a really narrow window */ | 2102 goto done; /* gee, a really narrow window */ |
2103 else if (data.bi_bufpos == BI_BUF_ZV (b)) | 2103 else if (data.bi_charbpos == BI_BUF_ZV (b)) |
2104 goto done; | 2104 goto done; |
2105 else if (data.bi_bufpos < BI_BUF_BEGV (b)) | 2105 else if (data.bi_charbpos < BI_BUF_BEGV (b)) |
2106 /* #### urk urk urk! Aborts are not very fun! Fix this please! */ | 2106 /* #### urk urk urk! Aborts are not very fun! Fix this please! */ |
2107 data.bi_bufpos = BI_BUF_BEGV (b); | 2107 data.bi_charbpos = BI_BUF_BEGV (b); |
2108 else | 2108 else |
2109 INC_BYTIND (b, data.bi_bufpos); | 2109 INC_BYTEBPOS (b, data.bi_charbpos); |
2110 } | 2110 } |
2111 | 2111 |
2112 /* If there are end glyphs, add them to the line. These are | 2112 /* If there are end glyphs, add them to the line. These are |
2113 the end glyphs for the previous run of text. We add them | 2113 the end glyphs for the previous run of text. We add them |
2114 here rather than doing them at the end of handling the | 2114 here rather than doing them at the end of handling the |
2130 } | 2130 } |
2131 | 2131 |
2132 /* If at end-of-buffer, we've already processed begin and | 2132 /* If at end-of-buffer, we've already processed begin and |
2133 end-glyphs at this point and there's no text to process, | 2133 end-glyphs at this point and there's no text to process, |
2134 so we're done. */ | 2134 so we're done. */ |
2135 else if (data.bi_bufpos == BI_BUF_ZV (b)) | 2135 else if (data.bi_charbpos == BI_BUF_ZV (b)) |
2136 goto done; | 2136 goto done; |
2137 | 2137 |
2138 else | 2138 else |
2139 { | 2139 { |
2140 Lisp_Object entry = Qnil; | 2140 Lisp_Object entry = Qnil; |
2141 /* Get the character at the current buffer position. */ | 2141 /* Get the character at the current buffer position. */ |
2142 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos); | 2142 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_charbpos); |
2143 if (!NILP (face_dt) || !NILP (window_dt)) | 2143 if (!NILP (face_dt) || !NILP (window_dt)) |
2144 entry = display_table_entry (data.ch, face_dt, window_dt); | 2144 entry = display_table_entry (data.ch, face_dt, window_dt); |
2145 | 2145 |
2146 /* If there is a display table entry for it, hand it off to | 2146 /* If there is a display table entry for it, hand it off to |
2147 add_disp_table_entry_runes and let it worry about it. */ | 2147 add_disp_table_entry_runes and let it worry about it. */ |
2162 fit. */ | 2162 fit. */ |
2163 data.max_pixpos += end_glyph_width; | 2163 data.max_pixpos += end_glyph_width; |
2164 | 2164 |
2165 if (selective > 0 | 2165 if (selective > 0 |
2166 && (bi_spaces_at_point | 2166 && (bi_spaces_at_point |
2167 (b, next_bytind (b, data.bi_bufpos)) | 2167 (b, next_bytebpos (b, data.bi_charbpos)) |
2168 >= selective)) | 2168 >= selective)) |
2169 { | 2169 { |
2170 if (!NILP (b->selective_display_ellipses)) | 2170 if (!NILP (b->selective_display_ellipses)) |
2171 { | 2171 { |
2172 struct glyph_block gb; | 2172 struct glyph_block gb; |
2184 the non-printing character '\n'. */ | 2184 the non-printing character '\n'. */ |
2185 data.blank_width = DEVMETH (d, eol_cursor_width, ()); | 2185 data.blank_width = DEVMETH (d, eol_cursor_width, ()); |
2186 *prop = add_emchar_rune (&data); | 2186 *prop = add_emchar_rune (&data); |
2187 } | 2187 } |
2188 | 2188 |
2189 /* We need to set data.bi_bufpos to the start of the | 2189 /* We need to set data.bi_charbpos to the start of the |
2190 next visible region in order to make this line | 2190 next visible region in order to make this line |
2191 appear to contain all of the invisible area. | 2191 appear to contain all of the invisible area. |
2192 Otherwise, the line cache won't work | 2192 Otherwise, the line cache won't work |
2193 correctly. */ | 2193 correctly. */ |
2194 INC_BYTIND (b, data.bi_bufpos); | 2194 INC_BYTEBPOS (b, data.bi_charbpos); |
2195 while (bi_spaces_at_point (b, data.bi_bufpos) >= selective) | 2195 while (bi_spaces_at_point (b, data.bi_charbpos) >= selective) |
2196 { | 2196 { |
2197 data.bi_bufpos = | 2197 data.bi_charbpos = |
2198 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1); | 2198 bi_find_next_newline_no_quit (b, data.bi_charbpos, 1); |
2199 if (data.bi_bufpos >= BI_BUF_ZV (b)) | 2199 if (data.bi_charbpos >= BI_BUF_ZV (b)) |
2200 { | 2200 { |
2201 data.bi_bufpos = BI_BUF_ZV (b); | 2201 data.bi_charbpos = BI_BUF_ZV (b); |
2202 break; | 2202 break; |
2203 } | 2203 } |
2204 } | 2204 } |
2205 if (BI_BUF_FETCH_CHAR | 2205 if (BI_BUF_FETCH_CHAR |
2206 (b, prev_bytind (b, data.bi_bufpos)) == '\n') | 2206 (b, prev_bytebpos (b, data.bi_charbpos)) == '\n') |
2207 DEC_BYTIND (b, data.bi_bufpos); | 2207 DEC_BYTEBPOS (b, data.bi_charbpos); |
2208 } | 2208 } |
2209 else | 2209 else |
2210 { | 2210 { |
2211 data.blank_width = DEVMETH (d, eol_cursor_width, ()); | 2211 data.blank_width = DEVMETH (d, eol_cursor_width, ()); |
2212 *prop = add_emchar_rune (&data); | 2212 *prop = add_emchar_rune (&data); |
2219 enabled, then add the invisible-text-glyph if | 2219 enabled, then add the invisible-text-glyph if |
2220 selective-display-ellipses is set. In any case, this | 2220 selective-display-ellipses is set. In any case, this |
2221 line is done. */ | 2221 line is done. */ |
2222 else if (data.ch == (('M' & 037)) && selective == -1) | 2222 else if (data.ch == (('M' & 037)) && selective == -1) |
2223 { | 2223 { |
2224 Bytind bi_next_bufpos; | 2224 Bytebpos bi_next_charbpos; |
2225 | 2225 |
2226 /* Find the buffer position at the end of the line. */ | 2226 /* Find the buffer position at the end of the line. */ |
2227 bi_next_bufpos = | 2227 bi_next_charbpos = |
2228 bi_find_next_newline_no_quit (b, data.bi_bufpos, 1); | 2228 bi_find_next_newline_no_quit (b, data.bi_charbpos, 1); |
2229 if (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_next_bufpos)) | 2229 if (BI_BUF_FETCH_CHAR (b, prev_bytebpos (b, bi_next_charbpos)) |
2230 == '\n') | 2230 == '\n') |
2231 DEC_BYTIND (b, bi_next_bufpos); | 2231 DEC_BYTEBPOS (b, bi_next_charbpos); |
2232 | 2232 |
2233 /* If the cursor is somewhere in the elided text make | 2233 /* If the cursor is somewhere in the elided text make |
2234 sure that the cursor gets drawn appropriately. */ | 2234 sure that the cursor gets drawn appropriately. */ |
2235 if (data.cursor_type == CURSOR_ON | 2235 if (data.cursor_type == CURSOR_ON |
2236 && (data.bi_cursor_bufpos >= data.bi_bufpos && | 2236 && (data.bi_cursor_charbpos >= data.bi_charbpos && |
2237 data.bi_cursor_bufpos < bi_next_bufpos)) | 2237 data.bi_cursor_charbpos < bi_next_charbpos)) |
2238 { | 2238 { |
2239 data.cursor_type = NEXT_CURSOR; | 2239 data.cursor_type = NEXT_CURSOR; |
2240 } | 2240 } |
2241 | 2241 |
2242 /* We won't be adding a truncation or continuation glyph | 2242 /* We won't be adding a truncation or continuation glyph |
2258 | 2258 |
2259 /* Set the buffer position to the end of the line. We | 2259 /* Set the buffer position to the end of the line. We |
2260 need to do this before potentially adding a newline | 2260 need to do this before potentially adding a newline |
2261 so that the cursor flag will get set correctly (if | 2261 so that the cursor flag will get set correctly (if |
2262 needed). */ | 2262 needed). */ |
2263 data.bi_bufpos = bi_next_bufpos; | 2263 data.bi_charbpos = bi_next_charbpos; |
2264 | 2264 |
2265 if (NILP (b->selective_display_ellipses) | 2265 if (NILP (b->selective_display_ellipses) |
2266 || data.bi_cursor_bufpos == bi_next_bufpos) | 2266 || data.bi_cursor_charbpos == bi_next_charbpos) |
2267 { | 2267 { |
2268 /* We have to at least add a newline character so | 2268 /* We have to at least add a newline character so |
2269 that the cursor shows up properly. */ | 2269 that the cursor shows up properly. */ |
2270 data.ch = '\n'; | 2270 data.ch = '\n'; |
2271 data.blank_width = DEVMETH (d, eol_cursor_width, ()); | 2271 data.blank_width = DEVMETH (d, eol_cursor_width, ()); |
2278 } | 2278 } |
2279 | 2279 |
2280 /* This had better be a newline but doing it this way | 2280 /* This had better be a newline but doing it this way |
2281 we'll see obvious incorrect results if it isn't. No | 2281 we'll see obvious incorrect results if it isn't. No |
2282 need to abort here. */ | 2282 need to abort here. */ |
2283 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos); | 2283 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_charbpos); |
2284 | 2284 |
2285 goto done; | 2285 goto done; |
2286 } | 2286 } |
2287 | 2287 |
2288 /* If the current character is considered to be printable, then | 2288 /* If the current character is considered to be printable, then |
2347 The is_*() routines have undefined results on | 2347 The is_*() routines have undefined results on |
2348 arguments outside of the range [-1, 255]. (This | 2348 arguments outside of the range [-1, 255]. (This |
2349 often bites people who carelessly use `char' instead | 2349 often bites people who carelessly use `char' instead |
2350 of `unsigned char'.) | 2350 of `unsigned char'.) |
2351 */ | 2351 */ |
2352 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch)) | 2352 else if (data.ch < 0x100 && iscntrl ((Intbyte) data.ch)) |
2353 { | 2353 { |
2354 *prop = add_control_char_runes (&data, b); | 2354 *prop = add_control_char_runes (&data, b); |
2355 | 2355 |
2356 if (*prop) | 2356 if (*prop) |
2357 goto done; | 2357 goto done; |
2374 *prop = add_emchar_rune (&data); | 2374 *prop = add_emchar_rune (&data); |
2375 if (*prop) | 2375 if (*prop) |
2376 goto done; | 2376 goto done; |
2377 } | 2377 } |
2378 | 2378 |
2379 INC_BYTIND (b, data.bi_bufpos); | 2379 INC_BYTEBPOS (b, data.bi_charbpos); |
2380 } | 2380 } |
2381 } | 2381 } |
2382 | 2382 |
2383 done: | 2383 done: |
2384 | 2384 |
2385 /* Determine the starting point of the next line if we did not hit the | 2385 /* Determine the starting point of the next line if we did not hit the |
2386 end of the buffer. */ | 2386 end of the buffer. */ |
2387 if (data.bi_bufpos < BI_BUF_ZV (b) | 2387 if (data.bi_charbpos < BI_BUF_ZV (b) |
2388 && (active_minibuffer || !NILP (synch_minibuffers_value))) | 2388 && (active_minibuffer || !NILP (synch_minibuffers_value))) |
2389 { | 2389 { |
2390 /* #### This check is not correct. If the line terminated | 2390 /* #### This check is not correct. If the line terminated |
2391 due to a begin-glyph or end-glyph hitting window-end, then | 2391 due to a begin-glyph or end-glyph hitting window-end, then |
2392 data.ch will not point to the character at data.bi_bufpos. If | 2392 data.ch will not point to the character at data.bi_charbpos. If |
2393 you make the two changes mentioned at the top of this loop, | 2393 you make the two changes mentioned at the top of this loop, |
2394 you should be able to say '(if (*prop))'. That should also | 2394 you should be able to say '(if (*prop))'. That should also |
2395 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b) | 2395 make it possible to eliminate the data.bi_charbpos < BI_BUF_ZV (b) |
2396 check. */ | 2396 check. */ |
2397 | 2397 |
2398 /* The common case is that the line ended because we hit a newline. | 2398 /* The common case is that the line ended because we hit a newline. |
2399 In that case, the next character is just the next buffer | 2399 In that case, the next character is just the next buffer |
2400 position. */ | 2400 position. */ |
2406 line in that case unless the line is completely blank. */ | 2406 line in that case unless the line is completely blank. */ |
2407 if (data.bi_start_col_enabled) | 2407 if (data.bi_start_col_enabled) |
2408 { | 2408 { |
2409 if (data.cursor_type == CURSOR_ON) | 2409 if (data.cursor_type == CURSOR_ON) |
2410 { | 2410 { |
2411 if (data.bi_cursor_bufpos >= bi_start_pos | 2411 if (data.bi_cursor_charbpos >= bi_start_pos |
2412 && data.bi_cursor_bufpos <= data.bi_bufpos) | 2412 && data.bi_cursor_charbpos <= data.bi_charbpos) |
2413 data.bi_cursor_bufpos = data.bi_bufpos; | 2413 data.bi_cursor_charbpos = data.bi_charbpos; |
2414 } | 2414 } |
2415 data.findex = DEFAULT_INDEX; | 2415 data.findex = DEFAULT_INDEX; |
2416 data.start_col = 0; | 2416 data.start_col = 0; |
2417 data.bi_start_col_enabled = 0; | 2417 data.bi_start_col_enabled = 0; |
2418 | 2418 |
2419 if (data.bi_bufpos != bi_start_pos) | 2419 if (data.bi_charbpos != bi_start_pos) |
2420 { | 2420 { |
2421 struct glyph_block gb; | 2421 struct glyph_block gb; |
2422 | 2422 |
2423 gb.extent = Qnil; | 2423 gb.extent = Qnil; |
2424 gb.glyph = Vhscroll_glyph; | 2424 gb.glyph = Vhscroll_glyph; |
2434 | 2434 |
2435 add_emchar_rune (&data); | 2435 add_emchar_rune (&data); |
2436 } | 2436 } |
2437 } | 2437 } |
2438 | 2438 |
2439 INC_BYTIND (b, data.bi_bufpos); | 2439 INC_BYTEBPOS (b, data.bi_charbpos); |
2440 } | 2440 } |
2441 | 2441 |
2442 /* Otherwise we have a buffer line which cannot fit on one display | 2442 /* Otherwise we have a buffer line which cannot fit on one display |
2443 line. */ | 2443 line. */ |
2444 else | 2444 else |
2454 data.findex = DEFAULT_INDEX; | 2454 data.findex = DEFAULT_INDEX; |
2455 gb.extent = Qnil; | 2455 gb.extent = Qnil; |
2456 | 2456 |
2457 if (truncate_win) | 2457 if (truncate_win) |
2458 { | 2458 { |
2459 Bytind bi_pos; | 2459 Bytebpos bi_pos; |
2460 | 2460 |
2461 /* Now find the start of the next line. */ | 2461 /* Now find the start of the next line. */ |
2462 bi_pos = bi_find_next_newline_no_quit (b, data.bi_bufpos, 1); | 2462 bi_pos = bi_find_next_newline_no_quit (b, data.bi_charbpos, 1); |
2463 | 2463 |
2464 /* If the cursor is past the truncation line then we | 2464 /* If the cursor is past the truncation line then we |
2465 make it appear on the truncation glyph. If we've hit | 2465 make it appear on the truncation glyph. If we've hit |
2466 the end of the buffer then we also make the cursor | 2466 the end of the buffer then we also make the cursor |
2467 appear unless eob is immediately preceded by a | 2467 appear unless eob is immediately preceded by a |
2468 newline. In that case the cursor should actually | 2468 newline. In that case the cursor should actually |
2469 appear on the next line. */ | 2469 appear on the next line. */ |
2470 if (data.cursor_type == CURSOR_ON | 2470 if (data.cursor_type == CURSOR_ON |
2471 && data.bi_cursor_bufpos >= data.bi_bufpos | 2471 && data.bi_cursor_charbpos >= data.bi_charbpos |
2472 && (data.bi_cursor_bufpos < bi_pos || | 2472 && (data.bi_cursor_charbpos < bi_pos || |
2473 (bi_pos == BI_BUF_ZV (b) | 2473 (bi_pos == BI_BUF_ZV (b) |
2474 && (bi_pos == BI_BUF_BEGV (b) | 2474 && (bi_pos == BI_BUF_BEGV (b) |
2475 || (BI_BUF_FETCH_CHAR (b, prev_bytind (b, bi_pos)) | 2475 || (BI_BUF_FETCH_CHAR (b, prev_bytebpos (b, bi_pos)) |
2476 != '\n'))))) | 2476 != '\n'))))) |
2477 data.bi_cursor_bufpos = bi_pos; | 2477 data.bi_cursor_charbpos = bi_pos; |
2478 else | 2478 else |
2479 data.cursor_type = NO_CURSOR; | 2479 data.cursor_type = NO_CURSOR; |
2480 | 2480 |
2481 data.bi_bufpos = bi_pos; | 2481 data.bi_charbpos = bi_pos; |
2482 gb.glyph = Vtruncation_glyph; | 2482 gb.glyph = Vtruncation_glyph; |
2483 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX); | 2483 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX); |
2484 } | 2484 } |
2485 else | 2485 else |
2486 { | 2486 { |
2487 /* The cursor can never be on the continuation glyph. */ | 2487 /* The cursor can never be on the continuation glyph. */ |
2488 data.cursor_type = NO_CURSOR; | 2488 data.cursor_type = NO_CURSOR; |
2489 | 2489 |
2490 /* data.bi_bufpos is already at the start of the next line. */ | 2490 /* data.bi_charbpos is already at the start of the next line. */ |
2491 | 2491 |
2492 dl->line_continuation = 1; | 2492 dl->line_continuation = 1; |
2493 gb.glyph = Vcontinuation_glyph; | 2493 gb.glyph = Vcontinuation_glyph; |
2494 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); | 2494 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); |
2495 } | 2495 } |
2496 | 2496 |
2497 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); | 2497 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); |
2498 | 2498 |
2499 if (truncate_win && data.bi_bufpos == BI_BUF_ZV (b) | 2499 if (truncate_win && data.bi_charbpos == BI_BUF_ZV (b) |
2500 && BI_BUF_FETCH_CHAR (b, prev_bytind (b, BI_BUF_ZV (b))) != '\n') | 2500 && BI_BUF_FETCH_CHAR (b, prev_bytebpos (b, BI_BUF_ZV (b))) != '\n') |
2501 /* #### Damn this losing shit. */ | 2501 /* #### Damn this losing shit. */ |
2502 data.bi_bufpos++; | 2502 data.bi_charbpos++; |
2503 } | 2503 } |
2504 } | 2504 } |
2505 else if ((active_minibuffer || !NILP (synch_minibuffers_value)) | 2505 else if ((active_minibuffer || !NILP (synch_minibuffers_value)) |
2506 && (!echo_area_active (f) || data.bi_bufpos == BI_BUF_ZV (b))) | 2506 && (!echo_area_active (f) || data.bi_charbpos == BI_BUF_ZV (b))) |
2507 { | 2507 { |
2508 /* We need to add a marker to the end of the line since there is no | 2508 /* We need to add a marker to the end of the line since there is no |
2509 newline character in order for the cursor to get drawn. We label | 2509 newline character in order for the cursor to get drawn. We label |
2510 it as a newline so that it gets handled correctly by the | 2510 it as a newline so that it gets handled correctly by the |
2511 whitespace routines below. */ | 2511 whitespace routines below. */ |
2522 data.max_pixpos -= data.blank_width; | 2522 data.max_pixpos -= data.blank_width; |
2523 | 2523 |
2524 /* #### urk! Chuck, this shit is bad news. Going around | 2524 /* #### urk! Chuck, this shit is bad news. Going around |
2525 manipulating invalid positions is guaranteed to result in | 2525 manipulating invalid positions is guaranteed to result in |
2526 trouble sooner or later. */ | 2526 trouble sooner or later. */ |
2527 data.bi_bufpos = BI_BUF_ZV (b) + 1; | 2527 data.bi_charbpos = BI_BUF_ZV (b) + 1; |
2528 } | 2528 } |
2529 | 2529 |
2530 /* Calculate left whitespace boundary. */ | 2530 /* Calculate left whitespace boundary. */ |
2531 { | 2531 { |
2532 int elt = 0; | 2532 int elt = 0; |
2622 dl->descent = descent; | 2622 dl->descent = descent; |
2623 } | 2623 } |
2624 | 2624 |
2625 dl->cursor_elt = data.cursor_x; | 2625 dl->cursor_elt = data.cursor_x; |
2626 /* #### lossage lossage lossage! Fix this shit! */ | 2626 /* #### lossage lossage lossage! Fix this shit! */ |
2627 if (data.bi_bufpos > BI_BUF_ZV (b)) | 2627 if (data.bi_charbpos > BI_BUF_ZV (b)) |
2628 dl->end_bufpos = BUF_ZV (b); | 2628 dl->end_charbpos = BUF_ZV (b); |
2629 else | 2629 else |
2630 dl->end_bufpos = bytind_to_bufpos (b, data.bi_bufpos) - 1; | 2630 dl->end_charbpos = bytebpos_to_charbpos (b, data.bi_charbpos) - 1; |
2631 if (truncate_win) | 2631 if (truncate_win) |
2632 data.dl->num_chars = column_at_point (b, dl->end_bufpos, 0); | 2632 data.dl->num_chars = column_at_point (b, dl->end_charbpos, 0); |
2633 else | 2633 else |
2634 /* This doesn't correctly take into account tabs and control | 2634 /* This doesn't correctly take into account tabs and control |
2635 characters but if the window isn't being truncated then this | 2635 characters but if the window isn't being truncated then this |
2636 value isn't going to end up being used anyhow. */ | 2636 value isn't going to end up being used anyhow. */ |
2637 data.dl->num_chars = dl->end_bufpos - dl->bufpos; | 2637 data.dl->num_chars = dl->end_charbpos - dl->charbpos; |
2638 | 2638 |
2639 /* #### handle horizontally scrolled line with text none of which | 2639 /* #### handle horizontally scrolled line with text none of which |
2640 was actually laid out. */ | 2640 was actually laid out. */ |
2641 | 2641 |
2642 /* #### handle any remainder of overlay arrow */ | 2642 /* #### handle any remainder of overlay arrow */ |
2655 /* #### If we started at EOB, then make sure we return a value past | 2655 /* #### If we started at EOB, then make sure we return a value past |
2656 it so that regenerate_window will exit properly. This is bogus. | 2656 it so that regenerate_window will exit properly. This is bogus. |
2657 The main loop should get fixed so that it isn't necessary to call | 2657 The main loop should get fixed so that it isn't necessary to call |
2658 this function if we are already at EOB. */ | 2658 this function if we are already at EOB. */ |
2659 | 2659 |
2660 if (data.bi_bufpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b)) | 2660 if (data.bi_charbpos == BI_BUF_ZV (b) && bi_start_pos == BI_BUF_ZV (b)) |
2661 return data.bi_bufpos + 1; /* Yuck! */ | 2661 return data.bi_charbpos + 1; /* Yuck! */ |
2662 else | 2662 else |
2663 return data.bi_bufpos; | 2663 return data.bi_charbpos; |
2664 } | 2664 } |
2665 | 2665 |
2666 /* Display the overlay arrow at the beginning of the given line. */ | 2666 /* Display the overlay arrow at the beginning of the given line. */ |
2667 | 2667 |
2668 static int | 2668 static int |
2694 | 2694 |
2695 Dynarr_reset (data.db->runes); | 2695 Dynarr_reset (data.db->runes); |
2696 | 2696 |
2697 if (STRINGP (Voverlay_arrow_string)) | 2697 if (STRINGP (Voverlay_arrow_string)) |
2698 { | 2698 { |
2699 add_bufbyte_string_runes | 2699 add_intbyte_string_runes |
2700 (&data, | 2700 (&data, |
2701 XSTRING_DATA (Voverlay_arrow_string), | 2701 XSTRING_DATA (Voverlay_arrow_string), |
2702 XSTRING_LENGTH (Voverlay_arrow_string), | 2702 XSTRING_LENGTH (Voverlay_arrow_string), |
2703 1); | 2703 1); |
2704 } | 2704 } |
2828 rb.findex = (side == LEFT_GLYPHS | 2828 rb.findex = (side == LEFT_GLYPHS |
2829 ? get_builtin_face_cache_index (w, Vleft_margin_face) | 2829 ? get_builtin_face_cache_index (w, Vleft_margin_face) |
2830 : get_builtin_face_cache_index (w, Vright_margin_face)); | 2830 : get_builtin_face_cache_index (w, Vright_margin_face)); |
2831 rb.xpos = xpos; | 2831 rb.xpos = xpos; |
2832 rb.width = width; | 2832 rb.width = width; |
2833 rb.bufpos = -1; | 2833 rb.charbpos = -1; |
2834 rb.endpos = 0; | 2834 rb.endpos = 0; |
2835 rb.type = RUNE_BLANK; | 2835 rb.type = RUNE_BLANK; |
2836 rb.cursor_type = CURSOR_OFF; | 2836 rb.cursor_type = CURSOR_OFF; |
2837 | 2837 |
2838 Dynarr_add (db->runes, rb); | 2838 Dynarr_add (db->runes, rb); |
3537 /* Now create the result string and frob the extents into it. */ | 3537 /* Now create the result string and frob the extents into it. */ |
3538 if (!NILP (result_str)) | 3538 if (!NILP (result_str)) |
3539 { | 3539 { |
3540 int elt; | 3540 int elt; |
3541 Bytecount len; | 3541 Bytecount len; |
3542 Bufbyte *strdata; | 3542 Intbyte *strdata; |
3543 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); | 3543 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); |
3544 | 3544 |
3545 in_modeline_generation = 1; | 3545 in_modeline_generation = 1; |
3546 | 3546 |
3547 detach_all_extents (result_str); | 3547 detach_all_extents (result_str); |
3626 dl->ypos = WINDOW_BOTTOM (w); | 3626 dl->ypos = WINDOW_BOTTOM (w); |
3627 | 3627 |
3628 rb.findex = MODELINE_INDEX; | 3628 rb.findex = MODELINE_INDEX; |
3629 rb.xpos = dl->bounds.left_out; | 3629 rb.xpos = dl->bounds.left_out; |
3630 rb.width = dl->bounds.right_out - dl->bounds.left_out; | 3630 rb.width = dl->bounds.right_out - dl->bounds.left_out; |
3631 rb.bufpos = 0; | 3631 rb.charbpos = 0; |
3632 rb.endpos = 0; | 3632 rb.endpos = 0; |
3633 rb.type = RUNE_HLINE; | 3633 rb.type = RUNE_HLINE; |
3634 rb.object.hline.thickness = 1; | 3634 rb.object.hline.thickness = 1; |
3635 rb.object.hline.yoffset = 0; | 3635 rb.object.hline.yoffset = 0; |
3636 rb.cursor_type = NO_CURSOR; | 3636 rb.cursor_type = NO_CURSOR; |
3679 for any embedded faces. */ | 3679 for any embedded faces. */ |
3680 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; | 3680 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; |
3681 } | 3681 } |
3682 | 3682 |
3683 static Charcount | 3683 static Charcount |
3684 add_string_to_fstring_db_runes (pos_data *data, const Bufbyte *str, | 3684 add_string_to_fstring_db_runes (pos_data *data, const Intbyte *str, |
3685 Charcount pos, Charcount min_pos, Charcount max_pos) | 3685 Charcount pos, Charcount min_pos, Charcount max_pos) |
3686 { | 3686 { |
3687 /* This function has been Mule-ized. */ | 3687 /* This function has been Mule-ized. */ |
3688 Charcount end; | 3688 Charcount end; |
3689 const Bufbyte *cur_pos = str; | 3689 const Intbyte *cur_pos = str; |
3690 struct display_block *db = data->db; | 3690 struct display_block *db = data->db; |
3691 | 3691 |
3692 data->blank_width = space_width (XWINDOW (data->window)); | 3692 data->blank_width = space_width (XWINDOW (data->window)); |
3693 while (Dynarr_length (db->runes) < pos) | 3693 while (Dynarr_length (db->runes) < pos) |
3694 add_blank_rune (data, NULL, 0); | 3694 add_blank_rune (data, NULL, 0); |
3698 if (max_pos != -1) | 3698 if (max_pos != -1) |
3699 end = min (max_pos, end); | 3699 end = min (max_pos, end); |
3700 | 3700 |
3701 while (pos < end && *cur_pos) | 3701 while (pos < end && *cur_pos) |
3702 { | 3702 { |
3703 const Bufbyte *old_cur_pos = cur_pos; | 3703 const Intbyte *old_cur_pos = cur_pos; |
3704 int succeeded; | 3704 int succeeded; |
3705 | 3705 |
3706 data->ch = charptr_emchar (cur_pos); | 3706 data->ch = charptr_emchar (cur_pos); |
3707 succeeded = (add_emchar_rune (data) != ADD_FAILED); | 3707 succeeded = (add_emchar_rune (data) != ADD_FAILED); |
3708 INC_CHARPTR (cur_pos); | 3708 INC_CHARPTR (cur_pos); |
3789 if (STRINGP (elt)) | 3789 if (STRINGP (elt)) |
3790 { | 3790 { |
3791 /* A string. Add to the display line and check for %-constructs | 3791 /* A string. Add to the display line and check for %-constructs |
3792 within it. */ | 3792 within it. */ |
3793 | 3793 |
3794 Bufbyte *this = XSTRING_DATA (elt); | 3794 Intbyte *this = XSTRING_DATA (elt); |
3795 | 3795 |
3796 while ((pos < max_pos || max_pos == -1) && *this) | 3796 while ((pos < max_pos || max_pos == -1) && *this) |
3797 { | 3797 { |
3798 Bufbyte *last = this; | 3798 Intbyte *last = this; |
3799 | 3799 |
3800 while (*this && *this != '%') | 3800 while (*this && *this != '%') |
3801 this++; | 3801 this++; |
3802 | 3802 |
3803 if (this != last) | 3803 if (this != last) |
3810 *offset -= size; | 3810 *offset -= size; |
3811 else | 3811 else |
3812 { | 3812 { |
3813 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset : | 3813 Charcount tmp_max = (max_pos == -1 ? pos + size - *offset : |
3814 min (pos + size - *offset, max_pos)); | 3814 min (pos + size - *offset, max_pos)); |
3815 const Bufbyte *tmp_last = charptr_n_addr (last, *offset); | 3815 const Intbyte *tmp_last = charptr_n_addr (last, *offset); |
3816 | 3816 |
3817 pos = add_string_to_fstring_db_runes (data, tmp_last, | 3817 pos = add_string_to_fstring_db_runes (data, tmp_last, |
3818 pos, pos, tmp_max); | 3818 pos, pos, tmp_max); |
3819 *offset = 0; | 3819 *offset = 0; |
3820 } | 3820 } |
3854 num_to_add = max_pos - pos; | 3854 num_to_add = max_pos - pos; |
3855 else | 3855 else |
3856 { | 3856 { |
3857 int cur_pixsize; | 3857 int cur_pixsize; |
3858 int dash_pixsize; | 3858 int dash_pixsize; |
3859 Bufbyte ch = '-'; | 3859 Intbyte ch = '-'; |
3860 SET_CURRENT_MODE_CHARS_PIXSIZE; | 3860 SET_CURRENT_MODE_CHARS_PIXSIZE; |
3861 | 3861 |
3862 dash_pixsize = | 3862 dash_pixsize = |
3863 redisplay_text_width_string (w, findex, &ch, Qnil, 0, | 3863 redisplay_text_width_string (w, findex, &ch, Qnil, 0, |
3864 1); | 3864 1); |
3867 num_to_add++; | 3867 num_to_add++; |
3868 } | 3868 } |
3869 | 3869 |
3870 while (num_to_add--) | 3870 while (num_to_add--) |
3871 pos = add_string_to_fstring_db_runes | 3871 pos = add_string_to_fstring_db_runes |
3872 (data, (const Bufbyte *) "-", pos, pos, max_pos); | 3872 (data, (const Intbyte *) "-", pos, pos, max_pos); |
3873 } | 3873 } |
3874 else if (*this != 0) | 3874 else if (*this != 0) |
3875 { | 3875 { |
3876 Emchar ch = charptr_emchar (this); | 3876 Emchar ch = charptr_emchar (this); |
3877 Bufbyte *str; | 3877 Intbyte *str; |
3878 Charcount size; | 3878 Charcount size; |
3879 | 3879 |
3880 decode_mode_spec (w, ch, type); | 3880 decode_mode_spec (w, ch, type); |
3881 | 3881 |
3882 str = Dynarr_atp (mode_spec_bufbyte_string, 0); | 3882 str = Dynarr_atp (mode_spec_intbyte_string, 0); |
3883 size = bytecount_to_charcount | 3883 size = bytecount_to_charcount |
3884 /* Skip the null character added by `decode_mode_spec' */ | 3884 /* Skip the null character added by `decode_mode_spec' */ |
3885 (str, Dynarr_length (mode_spec_bufbyte_string)) - 1; | 3885 (str, Dynarr_length (mode_spec_intbyte_string)) - 1; |
3886 | 3886 |
3887 if (size <= *offset) | 3887 if (size <= *offset) |
3888 *offset -= size; | 3888 *offset -= size; |
3889 else | 3889 else |
3890 { | 3890 { |
3891 const Bufbyte *tmp_str = charptr_n_addr (str, *offset); | 3891 const Intbyte *tmp_str = charptr_n_addr (str, *offset); |
3892 | 3892 |
3893 /* #### NOTE: I don't understand why a tmp_max is not | 3893 /* #### NOTE: I don't understand why a tmp_max is not |
3894 computed and used here as in the plain string case | 3894 computed and used here as in the plain string case |
3895 above. -- dv */ | 3895 above. -- dv */ |
3896 pos = add_string_to_fstring_db_runes (data, tmp_str, | 3896 pos = add_string_to_fstring_db_runes (data, tmp_str, |
3925 { | 3925 { |
3926 /* If value is a string, output that string literally: | 3926 /* If value is a string, output that string literally: |
3927 don't check for % within it. */ | 3927 don't check for % within it. */ |
3928 if (STRINGP (tem)) | 3928 if (STRINGP (tem)) |
3929 { | 3929 { |
3930 Bufbyte *str = XSTRING_DATA (tem); | 3930 Intbyte *str = XSTRING_DATA (tem); |
3931 Charcount size = XSTRING_CHAR_LENGTH (tem); | 3931 Charcount size = XSTRING_CHAR_LENGTH (tem); |
3932 | 3932 |
3933 if (size <= *offset) | 3933 if (size <= *offset) |
3934 *offset -= size; | 3934 *offset -= size; |
3935 else | 3935 else |
3936 { | 3936 { |
3937 const Bufbyte *tmp_str = charptr_n_addr (str, *offset); | 3937 const Intbyte *tmp_str = charptr_n_addr (str, *offset); |
3938 | 3938 |
3939 /* #### NOTE: I don't understand why a tmp_max is not | 3939 /* #### NOTE: I don't understand why a tmp_max is not |
3940 computed and used here as in the plain string case | 3940 computed and used here as in the plain string case |
3941 above. -- dv */ | 3941 above. -- dv */ |
3942 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, | 3942 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, |
4126 | 4126 |
4127 if (size <= *offset) | 4127 if (size <= *offset) |
4128 *offset -= size; | 4128 *offset -= size; |
4129 else | 4129 else |
4130 { | 4130 { |
4131 const Bufbyte *tmp_str = | 4131 const Intbyte *tmp_str = |
4132 charptr_n_addr ((const Bufbyte *) str, *offset); | 4132 charptr_n_addr ((const Intbyte *) str, *offset); |
4133 | 4133 |
4134 /* #### NOTE: I don't understand why a tmp_max is not computed and | 4134 /* #### NOTE: I don't understand why a tmp_max is not computed and |
4135 used here as in the plain string case above. -- dv */ | 4135 used here as in the plain string case above. -- dv */ |
4136 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, | 4136 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, |
4137 min_pos, max_pos); | 4137 min_pos, max_pos); |
4140 } | 4140 } |
4141 } | 4141 } |
4142 | 4142 |
4143 if (min_pos > pos) | 4143 if (min_pos > pos) |
4144 { | 4144 { |
4145 add_string_to_fstring_db_runes (data, (const Bufbyte *) "", pos, | 4145 add_string_to_fstring_db_runes (data, (const Intbyte *) "", pos, |
4146 min_pos, -1); | 4146 min_pos, -1); |
4147 } | 4147 } |
4148 | 4148 |
4149 return pos; | 4149 return pos; |
4150 } | 4150 } |
4260 functions cover text that the user *cannot edit* so we can remove | 4260 functions cover text that the user *cannot edit* so we can remove |
4261 everything to do with cursors, minibuffers etc. Eventually the | 4261 everything to do with cursors, minibuffers etc. Eventually the |
4262 modeline routines should be modified to use this code as it copes | 4262 modeline routines should be modified to use this code as it copes |
4263 with many more types of display situation. */ | 4263 with many more types of display situation. */ |
4264 | 4264 |
4265 static Bufpos | 4265 static Charbpos |
4266 create_string_text_block (struct window *w, Lisp_Object disp_string, | 4266 create_string_text_block (struct window *w, Lisp_Object disp_string, |
4267 struct display_line *dl, | 4267 struct display_line *dl, |
4268 Bufpos start_pos, | 4268 Charbpos start_pos, |
4269 prop_block_dynarr **prop, | 4269 prop_block_dynarr **prop, |
4270 face_index default_face) | 4270 face_index default_face) |
4271 { | 4271 { |
4272 struct frame *f = XFRAME (w->frame); | 4272 struct frame *f = XFRAME (w->frame); |
4273 /* Note that a lot of the buffer controlled stuff has been left in | 4273 /* Note that a lot of the buffer controlled stuff has been left in |
4280 Lisp_String* s = XSTRING (disp_string); | 4280 Lisp_String* s = XSTRING (disp_string); |
4281 | 4281 |
4282 /* we're working with these a lot so precalculate them */ | 4282 /* we're working with these a lot so precalculate them */ |
4283 Bytecount slen = XSTRING_LENGTH (disp_string); | 4283 Bytecount slen = XSTRING_LENGTH (disp_string); |
4284 Bytecount bi_string_zv = slen; | 4284 Bytecount bi_string_zv = slen; |
4285 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos); | 4285 Bytebpos bi_start_pos = charcount_to_bytecount (string_data (s), start_pos); |
4286 | 4286 |
4287 pos_data data; | 4287 pos_data data; |
4288 | 4288 |
4289 int truncate_win = b ? window_truncation_on (w) : 0; | 4289 int truncate_win = b ? window_truncation_on (w) : 0; |
4290 int end_glyph_width = 0; | 4290 int end_glyph_width = 0; |
4383 data.d = d; | 4383 data.d = d; |
4384 XSETWINDOW (data.window, w); | 4384 XSETWINDOW (data.window, w); |
4385 data.db = db; | 4385 data.db = db; |
4386 data.dl = dl; | 4386 data.dl = dl; |
4387 | 4387 |
4388 data.bi_bufpos = bi_start_pos; | 4388 data.bi_charbpos = bi_start_pos; |
4389 data.pixpos = dl->bounds.left_in; | 4389 data.pixpos = dl->bounds.left_in; |
4390 data.last_charset = Qunbound; | 4390 data.last_charset = Qunbound; |
4391 data.last_findex = default_face; | 4391 data.last_findex = default_face; |
4392 data.result_str = Qnil; | 4392 data.result_str = Qnil; |
4393 data.string = disp_string; | 4393 data.string = disp_string; |
4445 #### See also the comment after the end of this loop, below. | 4445 #### See also the comment after the end of this loop, below. |
4446 */ | 4446 */ |
4447 while (data.pixpos <= data.max_pixpos) | 4447 while (data.pixpos <= data.max_pixpos) |
4448 { | 4448 { |
4449 /* #### This check probably should not be necessary. */ | 4449 /* #### This check probably should not be necessary. */ |
4450 if (data.bi_bufpos > bi_string_zv) | 4450 if (data.bi_charbpos > bi_string_zv) |
4451 { | 4451 { |
4452 /* #### urk! More of this lossage! */ | 4452 /* #### urk! More of this lossage! */ |
4453 data.bi_bufpos--; | 4453 data.bi_charbpos--; |
4454 goto done; | 4454 goto done; |
4455 } | 4455 } |
4456 | 4456 |
4457 /* Check for face changes. */ | 4457 /* Check for face changes. */ |
4458 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end)) | 4458 if (initial || (!no_more_frags && data.bi_charbpos == data.ef->end)) |
4459 { | 4459 { |
4460 /* Now compute the face and begin/end-glyph information. */ | 4460 /* Now compute the face and begin/end-glyph information. */ |
4461 data.findex = | 4461 data.findex = |
4462 /* Remember that the extent-fragment routines deal in Bytind's. */ | 4462 /* Remember that the extent-fragment routines deal in Bytebpos's. */ |
4463 extent_fragment_update (w, data.ef, data.bi_bufpos); | 4463 extent_fragment_update (w, data.ef, data.bi_charbpos); |
4464 /* This is somewhat cheesy but the alternative is to | 4464 /* This is somewhat cheesy but the alternative is to |
4465 propagate default_face into extent_fragment_update. */ | 4465 propagate default_face into extent_fragment_update. */ |
4466 if (data.findex == DEFAULT_INDEX) | 4466 if (data.findex == DEFAULT_INDEX) |
4467 data.findex = default_face; | 4467 data.findex = default_face; |
4468 | 4468 |
4469 get_display_tables (w, data.findex, &face_dt, &window_dt); | 4469 get_display_tables (w, data.findex, &face_dt, &window_dt); |
4470 | 4470 |
4471 if (data.bi_bufpos == data.ef->end) | 4471 if (data.bi_charbpos == data.ef->end) |
4472 no_more_frags = 1; | 4472 no_more_frags = 1; |
4473 } | 4473 } |
4474 initial = 0; | 4474 initial = 0; |
4475 | 4475 |
4476 /* Determine what is next to be displayed. We first handle any | 4476 /* Determine what is next to be displayed. We first handle any |
4477 glyphs returned by glyphs_at_bufpos. If there are no glyphs to | 4477 glyphs returned by glyphs_at_charbpos. If there are no glyphs to |
4478 display then we determine what to do based on the character at the | 4478 display then we determine what to do based on the character at the |
4479 current buffer position. */ | 4479 current buffer position. */ |
4480 | 4480 |
4481 /* If the current position is covered by an invisible extent, do | 4481 /* If the current position is covered by an invisible extent, do |
4482 nothing (except maybe add some ellipses). | 4482 nothing (except maybe add some ellipses). |
4517 | 4517 |
4518 /* #### What if we're dealing with a display table? */ | 4518 /* #### What if we're dealing with a display table? */ |
4519 if (data.start_col) | 4519 if (data.start_col) |
4520 data.start_col--; | 4520 data.start_col--; |
4521 | 4521 |
4522 if (data.bi_bufpos == bi_string_zv) | 4522 if (data.bi_charbpos == bi_string_zv) |
4523 goto done; | 4523 goto done; |
4524 else | 4524 else |
4525 INC_CHARBYTIND (string_data (s), data.bi_bufpos); | 4525 INC_CHARBYTEBPOS (string_data (s), data.bi_charbpos); |
4526 } | 4526 } |
4527 | 4527 |
4528 /* If there is propagation data, then it represents the current | 4528 /* If there is propagation data, then it represents the current |
4529 buffer position being displayed. Add them and advance the | 4529 buffer position being displayed. Add them and advance the |
4530 position counter. This might also add the minibuffer | 4530 position counter. This might also add the minibuffer |
4534 dl->used_prop_data = 1; | 4534 dl->used_prop_data = 1; |
4535 *prop = add_propagation_runes (prop, &data); | 4535 *prop = add_propagation_runes (prop, &data); |
4536 | 4536 |
4537 if (*prop) | 4537 if (*prop) |
4538 goto done; /* gee, a really narrow window */ | 4538 goto done; /* gee, a really narrow window */ |
4539 else if (data.bi_bufpos == bi_string_zv) | 4539 else if (data.bi_charbpos == bi_string_zv) |
4540 goto done; | 4540 goto done; |
4541 else if (data.bi_bufpos < 0) | 4541 else if (data.bi_charbpos < 0) |
4542 /* #### urk urk urk! Aborts are not very fun! Fix this please! */ | 4542 /* #### urk urk urk! Aborts are not very fun! Fix this please! */ |
4543 data.bi_bufpos = 0; | 4543 data.bi_charbpos = 0; |
4544 else | 4544 else |
4545 INC_CHARBYTIND (string_data (s), data.bi_bufpos); | 4545 INC_CHARBYTEBPOS (string_data (s), data.bi_charbpos); |
4546 } | 4546 } |
4547 | 4547 |
4548 /* If there are end glyphs, add them to the line. These are | 4548 /* If there are end glyphs, add them to the line. These are |
4549 the end glyphs for the previous run of text. We add them | 4549 the end glyphs for the previous run of text. We add them |
4550 here rather than doing them at the end of handling the | 4550 here rather than doing them at the end of handling the |
4566 } | 4566 } |
4567 | 4567 |
4568 /* If at end-of-buffer, we've already processed begin and | 4568 /* If at end-of-buffer, we've already processed begin and |
4569 end-glyphs at this point and there's no text to process, | 4569 end-glyphs at this point and there's no text to process, |
4570 so we're done. */ | 4570 so we're done. */ |
4571 else if (data.bi_bufpos == bi_string_zv) | 4571 else if (data.bi_charbpos == bi_string_zv) |
4572 goto done; | 4572 goto done; |
4573 | 4573 |
4574 else | 4574 else |
4575 { | 4575 { |
4576 Lisp_Object entry = Qnil; | 4576 Lisp_Object entry = Qnil; |
4577 /* Get the character at the current buffer position. */ | 4577 /* Get the character at the current buffer position. */ |
4578 data.ch = string_char (s, data.bi_bufpos); | 4578 data.ch = string_char (s, data.bi_charbpos); |
4579 if (!NILP (face_dt) || !NILP (window_dt)) | 4579 if (!NILP (face_dt) || !NILP (window_dt)) |
4580 entry = display_table_entry (data.ch, face_dt, window_dt); | 4580 entry = display_table_entry (data.ch, face_dt, window_dt); |
4581 | 4581 |
4582 /* If there is a display table entry for it, hand it off to | 4582 /* If there is a display table entry for it, hand it off to |
4583 add_disp_table_entry_runes and let it worry about it. */ | 4583 add_disp_table_entry_runes and let it worry about it. */ |
4661 The is_*() routines have undefined results on | 4661 The is_*() routines have undefined results on |
4662 arguments outside of the range [-1, 255]. (This | 4662 arguments outside of the range [-1, 255]. (This |
4663 often bites people who carelessly use `char' instead | 4663 often bites people who carelessly use `char' instead |
4664 of `unsigned char'.) | 4664 of `unsigned char'.) |
4665 */ | 4665 */ |
4666 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch)) | 4666 else if (data.ch < 0x100 && iscntrl ((Intbyte) data.ch)) |
4667 { | 4667 { |
4668 *prop = add_control_char_runes (&data, b); | 4668 *prop = add_control_char_runes (&data, b); |
4669 | 4669 |
4670 if (*prop) | 4670 if (*prop) |
4671 goto done; | 4671 goto done; |
4688 *prop = add_emchar_rune (&data); | 4688 *prop = add_emchar_rune (&data); |
4689 if (*prop) | 4689 if (*prop) |
4690 goto done; | 4690 goto done; |
4691 } | 4691 } |
4692 | 4692 |
4693 INC_CHARBYTIND (string_data (s), data.bi_bufpos); | 4693 INC_CHARBYTEBPOS (string_data (s), data.bi_charbpos); |
4694 } | 4694 } |
4695 } | 4695 } |
4696 | 4696 |
4697 done: | 4697 done: |
4698 | 4698 |
4699 /* Determine the starting point of the next line if we did not hit the | 4699 /* Determine the starting point of the next line if we did not hit the |
4700 end of the buffer. */ | 4700 end of the buffer. */ |
4701 if (data.bi_bufpos < bi_string_zv) | 4701 if (data.bi_charbpos < bi_string_zv) |
4702 { | 4702 { |
4703 /* #### This check is not correct. If the line terminated | 4703 /* #### This check is not correct. If the line terminated |
4704 due to a begin-glyph or end-glyph hitting window-end, then | 4704 due to a begin-glyph or end-glyph hitting window-end, then |
4705 data.ch will not point to the character at data.bi_bufpos. If | 4705 data.ch will not point to the character at data.bi_charbpos. If |
4706 you make the two changes mentioned at the top of this loop, | 4706 you make the two changes mentioned at the top of this loop, |
4707 you should be able to say '(if (*prop))'. That should also | 4707 you should be able to say '(if (*prop))'. That should also |
4708 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b) | 4708 make it possible to eliminate the data.bi_charbpos < BI_BUF_ZV (b) |
4709 check. */ | 4709 check. */ |
4710 | 4710 |
4711 /* The common case is that the line ended because we hit a newline. | 4711 /* The common case is that the line ended because we hit a newline. |
4712 In that case, the next character is just the next buffer | 4712 In that case, the next character is just the next buffer |
4713 position. */ | 4713 position. */ |
4714 if (data.ch == '\n') | 4714 if (data.ch == '\n') |
4715 { | 4715 { |
4716 INC_CHARBYTIND (string_data (s), data.bi_bufpos); | 4716 INC_CHARBYTEBPOS (string_data (s), data.bi_charbpos); |
4717 } | 4717 } |
4718 | 4718 |
4719 /* Otherwise we have a buffer line which cannot fit on one display | 4719 /* Otherwise we have a buffer line which cannot fit on one display |
4720 line. */ | 4720 line. */ |
4721 else | 4721 else |
4731 data.findex = default_face; | 4731 data.findex = default_face; |
4732 gb.extent = Qnil; | 4732 gb.extent = Qnil; |
4733 | 4733 |
4734 if (truncate_win) | 4734 if (truncate_win) |
4735 { | 4735 { |
4736 Bytind bi_pos; | 4736 Bytebpos bi_pos; |
4737 | 4737 |
4738 /* Now find the start of the next line. */ | 4738 /* Now find the start of the next line. */ |
4739 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1); | 4739 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_charbpos, 1); |
4740 | 4740 |
4741 data.cursor_type = NO_CURSOR; | 4741 data.cursor_type = NO_CURSOR; |
4742 data.bi_bufpos = bi_pos; | 4742 data.bi_charbpos = bi_pos; |
4743 gb.glyph = Vtruncation_glyph; | 4743 gb.glyph = Vtruncation_glyph; |
4744 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX); | 4744 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX); |
4745 } | 4745 } |
4746 else | 4746 else |
4747 { | 4747 { |
4748 /* The cursor can never be on the continuation glyph. */ | 4748 /* The cursor can never be on the continuation glyph. */ |
4749 data.cursor_type = NO_CURSOR; | 4749 data.cursor_type = NO_CURSOR; |
4750 | 4750 |
4751 /* data.bi_bufpos is already at the start of the next line. */ | 4751 /* data.bi_charbpos is already at the start of the next line. */ |
4752 | 4752 |
4753 dl->line_continuation = 1; | 4753 dl->line_continuation = 1; |
4754 gb.glyph = Vcontinuation_glyph; | 4754 gb.glyph = Vcontinuation_glyph; |
4755 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); | 4755 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); |
4756 } | 4756 } |
4757 | 4757 |
4758 if (end_glyph_width) | 4758 if (end_glyph_width) |
4759 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); | 4759 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); |
4760 | 4760 |
4761 if (truncate_win && data.bi_bufpos == bi_string_zv) | 4761 if (truncate_win && data.bi_charbpos == bi_string_zv) |
4762 { | 4762 { |
4763 const Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv); | 4763 const Intbyte* endb = charptr_n_addr (string_data (s), bi_string_zv); |
4764 DEC_CHARPTR (endb); | 4764 DEC_CHARPTR (endb); |
4765 if (charptr_emchar (endb) != '\n') | 4765 if (charptr_emchar (endb) != '\n') |
4766 { | 4766 { |
4767 /* #### Damn this losing shit. */ | 4767 /* #### Damn this losing shit. */ |
4768 data.bi_bufpos++; | 4768 data.bi_charbpos++; |
4769 } | 4769 } |
4770 } | 4770 } |
4771 } | 4771 } |
4772 } | 4772 } |
4773 else if (data.bi_bufpos == bi_string_zv) | 4773 else if (data.bi_charbpos == bi_string_zv) |
4774 { | 4774 { |
4775 /* create_text_block () adds a bogus \n marker here which screws | 4775 /* create_text_block () adds a bogus \n marker here which screws |
4776 up subwindow display. Since we never have a cursor in the | 4776 up subwindow display. Since we never have a cursor in the |
4777 gutter we can safely ignore it. */ | 4777 gutter we can safely ignore it. */ |
4778 } | 4778 } |
4871 dl->descent = descent; | 4871 dl->descent = descent; |
4872 } | 4872 } |
4873 | 4873 |
4874 dl->cursor_elt = data.cursor_x; | 4874 dl->cursor_elt = data.cursor_x; |
4875 /* #### lossage lossage lossage! Fix this shit! */ | 4875 /* #### lossage lossage lossage! Fix this shit! */ |
4876 if (data.bi_bufpos > bi_string_zv) | 4876 if (data.bi_charbpos > bi_string_zv) |
4877 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv); | 4877 dl->end_charbpos = buffer_or_string_bytebpos_to_charbpos (disp_string, bi_string_zv); |
4878 else | 4878 else |
4879 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1; | 4879 dl->end_charbpos = buffer_or_string_bytebpos_to_charbpos (disp_string, data.bi_charbpos) - 1; |
4880 if (truncate_win) | 4880 if (truncate_win) |
4881 data.dl->num_chars = | 4881 data.dl->num_chars = |
4882 string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8); | 4882 string_column_at_point (s, dl->end_charbpos, b ? XINT (b->tab_width) : 8); |
4883 else | 4883 else |
4884 /* This doesn't correctly take into account tabs and control | 4884 /* This doesn't correctly take into account tabs and control |
4885 characters but if the window isn't being truncated then this | 4885 characters but if the window isn't being truncated then this |
4886 value isn't going to end up being used anyhow. */ | 4886 value isn't going to end up being used anyhow. */ |
4887 data.dl->num_chars = dl->end_bufpos - dl->bufpos; | 4887 data.dl->num_chars = dl->end_charbpos - dl->charbpos; |
4888 | 4888 |
4889 /* #### handle horizontally scrolled line with text none of which | 4889 /* #### handle horizontally scrolled line with text none of which |
4890 was actually laid out. */ | 4890 was actually laid out. */ |
4891 | 4891 |
4892 /* #### handle any remainder of overlay arrow */ | 4892 /* #### handle any remainder of overlay arrow */ |
4905 /* #### If we started at EOB, then make sure we return a value past | 4905 /* #### If we started at EOB, then make sure we return a value past |
4906 it so that regenerate_window will exit properly. This is bogus. | 4906 it so that regenerate_window will exit properly. This is bogus. |
4907 The main loop should get fixed so that it isn't necessary to call | 4907 The main loop should get fixed so that it isn't necessary to call |
4908 this function if we are already at EOB. */ | 4908 this function if we are already at EOB. */ |
4909 | 4909 |
4910 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv) | 4910 if (data.bi_charbpos == bi_string_zv && bi_start_pos == bi_string_zv) |
4911 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */ | 4911 return bytecount_to_charcount (string_data (s), data.bi_charbpos) + 1; /* Yuck! */ |
4912 else | 4912 else |
4913 return bytecount_to_charcount (string_data (s), data.bi_bufpos); | 4913 return bytecount_to_charcount (string_data (s), data.bi_charbpos); |
4914 } | 4914 } |
4915 | 4915 |
4916 /* Given a display line and a starting position, ensure that the | 4916 /* Given a display line and a starting position, ensure that the |
4917 contents of the display line accurately represent the visual | 4917 contents of the display line accurately represent the visual |
4918 representation of the buffer contents starting from the given | 4918 representation of the buffer contents starting from the given |
4920 when the contents of the line reach the right boundary of the given | 4920 when the contents of the line reach the right boundary of the given |
4921 window. | 4921 window. |
4922 | 4922 |
4923 This is very similar to generate_display_line but with the same | 4923 This is very similar to generate_display_line but with the same |
4924 limitations as create_string_text_block. I have taken the liberty | 4924 limitations as create_string_text_block. I have taken the liberty |
4925 of fixing the bytind stuff though.*/ | 4925 of fixing the bytebpos stuff though.*/ |
4926 | 4926 |
4927 static Bufpos | 4927 static Charbpos |
4928 generate_string_display_line (struct window *w, Lisp_Object disp_string, | 4928 generate_string_display_line (struct window *w, Lisp_Object disp_string, |
4929 struct display_line *dl, | 4929 struct display_line *dl, |
4930 Bufpos start_pos, | 4930 Charbpos start_pos, |
4931 prop_block_dynarr **prop, | 4931 prop_block_dynarr **prop, |
4932 face_index default_face) | 4932 face_index default_face) |
4933 { | 4933 { |
4934 Bufpos ret_bufpos; | 4934 Charbpos ret_charbpos; |
4935 | 4935 |
4936 /* you must set bounds before calling this. */ | 4936 /* you must set bounds before calling this. */ |
4937 | 4937 |
4938 /* Reset what this line is using. */ | 4938 /* Reset what this line is using. */ |
4939 if (dl->display_blocks) | 4939 if (dl->display_blocks) |
4951 | 4951 |
4952 /* We aren't generating a modeline at the moment. */ | 4952 /* We aren't generating a modeline at the moment. */ |
4953 dl->modeline = 0; | 4953 dl->modeline = 0; |
4954 | 4954 |
4955 /* Create a display block for the text region of the line. */ | 4955 /* Create a display block for the text region of the line. */ |
4956 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos, | 4956 ret_charbpos = create_string_text_block (w, disp_string, dl, start_pos, |
4957 prop, default_face); | 4957 prop, default_face); |
4958 dl->bufpos = start_pos; | 4958 dl->charbpos = start_pos; |
4959 if (dl->end_bufpos < dl->bufpos) | 4959 if (dl->end_charbpos < dl->charbpos) |
4960 dl->end_bufpos = dl->bufpos; | 4960 dl->end_charbpos = dl->charbpos; |
4961 | 4961 |
4962 /* If there are left glyphs associated with any character in the | 4962 /* If there are left glyphs associated with any character in the |
4963 text block, then create a display block to handle them. */ | 4963 text block, then create a display block to handle them. */ |
4964 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs)) | 4964 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs)) |
4965 create_left_glyph_block (w, dl, 0); | 4965 create_left_glyph_block (w, dl, 0); |
4967 /* If there are right glyphs associated with any character in the | 4967 /* If there are right glyphs associated with any character in the |
4968 text block, then create a display block to handle them. */ | 4968 text block, then create a display block to handle them. */ |
4969 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs)) | 4969 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs)) |
4970 create_right_glyph_block (w, dl); | 4970 create_right_glyph_block (w, dl); |
4971 | 4971 |
4972 return ret_bufpos; | 4972 return ret_charbpos; |
4973 } | 4973 } |
4974 | 4974 |
4975 /* This is ripped off from regenerate_window. All we want to do is | 4975 /* This is ripped off from regenerate_window. All we want to do is |
4976 loop through elements in the string creating display lines until we | 4976 loop through elements in the string creating display lines until we |
4977 have covered the provided area. Simple really. */ | 4977 have covered the provided area. Simple really. */ |
4978 void | 4978 void |
4979 generate_displayable_area (struct window *w, Lisp_Object disp_string, | 4979 generate_displayable_area (struct window *w, Lisp_Object disp_string, |
4980 int xpos, int ypos, int width, int height, | 4980 int xpos, int ypos, int width, int height, |
4981 display_line_dynarr* dla, | 4981 display_line_dynarr* dla, |
4982 Bufpos start_pos, | 4982 Charbpos start_pos, |
4983 face_index default_face) | 4983 face_index default_face) |
4984 { | 4984 { |
4985 int yend = ypos + height; | 4985 int yend = ypos + height; |
4986 Charcount s_zv; | 4986 Charcount s_zv; |
4987 | 4987 |
5009 | 5009 |
5010 while (ypos < yend) | 5010 while (ypos < yend) |
5011 { | 5011 { |
5012 struct display_line dl; | 5012 struct display_line dl; |
5013 struct display_line *dlp; | 5013 struct display_line *dlp; |
5014 Bufpos next_pos; | 5014 Charbpos next_pos; |
5015 int local; | 5015 int local; |
5016 | 5016 |
5017 if (Dynarr_length (dla) < Dynarr_largest (dla)) | 5017 if (Dynarr_length (dla) < Dynarr_largest (dla)) |
5018 { | 5018 { |
5019 dlp = Dynarr_atp (dla, Dynarr_length (dla)); | 5019 dlp = Dynarr_atp (dla, Dynarr_length (dla)); |
5083 presentation of the window. We pass the buffer instead of getting | 5083 presentation of the window. We pass the buffer instead of getting |
5084 it from the window since redisplay_window may have temporarily | 5084 it from the window since redisplay_window may have temporarily |
5085 changed it to the echo area buffer. */ | 5085 changed it to the echo area buffer. */ |
5086 | 5086 |
5087 static void | 5087 static void |
5088 regenerate_window (struct window *w, Bufpos start_pos, Bufpos point, int type) | 5088 regenerate_window (struct window *w, Charbpos start_pos, Charbpos point, int type) |
5089 { | 5089 { |
5090 struct frame *f = XFRAME (w->frame); | 5090 struct frame *f = XFRAME (w->frame); |
5091 struct buffer *b = XBUFFER (w->buffer); | 5091 struct buffer *b = XBUFFER (w->buffer); |
5092 int ypos = WINDOW_TEXT_TOP (w); | 5092 int ypos = WINDOW_TEXT_TOP (w); |
5093 int yend; /* set farther down */ | 5093 int yend; /* set farther down */ |
5296 abort (); /* structs differ */ \ | 5296 abort (); /* structs differ */ \ |
5297 \ | 5297 \ |
5298 dla_end = Dynarr_length (cdla) - 1; \ | 5298 dla_end = Dynarr_length (cdla) - 1; \ |
5299 } \ | 5299 } \ |
5300 \ | 5300 \ |
5301 start_pos = (Dynarr_atp (cdla, dla_start)->bufpos \ | 5301 start_pos = (Dynarr_atp (cdla, dla_start)->charbpos \ |
5302 + Dynarr_atp (cdla, dla_start)->offset); \ | 5302 + Dynarr_atp (cdla, dla_start)->offset); \ |
5303 /* If this isn't true, then startp has changed and we need to do a \ | 5303 /* If this isn't true, then startp has changed and we need to do a \ |
5304 full regen. */ \ | 5304 full regen. */ \ |
5305 if (startp != start_pos) \ | 5305 if (startp != start_pos) \ |
5306 return 0; \ | 5306 return 0; \ |
5318 changes it deals with it sometimes makes different assumptions | 5318 changes it deals with it sometimes makes different assumptions |
5319 which can lead to success which are much more difficult to make | 5319 which can lead to success which are much more difficult to make |
5320 when dealing with buffer changes. */ | 5320 when dealing with buffer changes. */ |
5321 | 5321 |
5322 static int | 5322 static int |
5323 regenerate_window_extents_only_changed (struct window *w, Bufpos startp, | 5323 regenerate_window_extents_only_changed (struct window *w, Charbpos startp, |
5324 Bufpos pointm, | 5324 Charbpos pointm, |
5325 Charcount beg_unchanged, | 5325 Charcount beg_unchanged, |
5326 Charcount end_unchanged) | 5326 Charcount end_unchanged) |
5327 { | 5327 { |
5328 struct buffer *b = XBUFFER (w->buffer); | 5328 struct buffer *b = XBUFFER (w->buffer); |
5329 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); | 5329 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); |
5330 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); | 5330 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); |
5331 | 5331 |
5332 int dla_start = 0; | 5332 int dla_start = 0; |
5333 int dla_end, line; | 5333 int dla_end, line; |
5334 int first_line, last_line; | 5334 int first_line, last_line; |
5335 Bufpos start_pos; | 5335 Charbpos start_pos; |
5336 /* Don't define this in the loop where it is used because we | 5336 /* Don't define this in the loop where it is used because we |
5337 definitely want its value to survive between passes. */ | 5337 definitely want its value to survive between passes. */ |
5338 prop_block_dynarr *prop = NULL; | 5338 prop_block_dynarr *prop = NULL; |
5339 | 5339 |
5340 /* If we don't have any buffer change recorded but the modiff flag has | 5340 /* If we don't have any buffer change recorded but the modiff flag has |
5394 /* Find what display line the extent changes first affect. */ | 5394 /* Find what display line the extent changes first affect. */ |
5395 line = dla_start; | 5395 line = dla_start; |
5396 while (line <= dla_end) | 5396 while (line <= dla_end) |
5397 { | 5397 { |
5398 struct display_line *dl = Dynarr_atp (cdla, line); | 5398 struct display_line *dl = Dynarr_atp (cdla, line); |
5399 Bufpos lstart = dl->bufpos + dl->offset; | 5399 Charbpos lstart = dl->charbpos + dl->offset; |
5400 Bufpos lend = dl->end_bufpos + dl->offset; | 5400 Charbpos lend = dl->end_charbpos + dl->offset; |
5401 | 5401 |
5402 if (beg_unchanged >= lstart && beg_unchanged <= lend) | 5402 if (beg_unchanged >= lstart && beg_unchanged <= lend) |
5403 break; | 5403 break; |
5404 | 5404 |
5405 line++; | 5405 line++; |
5429 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer); | 5429 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer); |
5430 | 5430 |
5431 first_line = last_line = line; | 5431 first_line = last_line = line; |
5432 while (line <= dla_end) | 5432 while (line <= dla_end) |
5433 { | 5433 { |
5434 Bufpos old_start, old_end, new_start; | 5434 Charbpos old_start, old_end, new_start; |
5435 struct display_line *cdl = Dynarr_atp (cdla, line); | 5435 struct display_line *cdl = Dynarr_atp (cdla, line); |
5436 struct display_line *ddl = Dynarr_atp (ddla, line); | 5436 struct display_line *ddl = Dynarr_atp (ddla, line); |
5437 struct display_block *db; | 5437 struct display_block *db; |
5438 int initial_size; | 5438 int initial_size; |
5439 | 5439 |
5440 assert (cdl->bufpos == ddl->bufpos); | 5440 assert (cdl->charbpos == ddl->charbpos); |
5441 assert (cdl->end_bufpos == ddl->end_bufpos); | 5441 assert (cdl->end_charbpos == ddl->end_charbpos); |
5442 assert (cdl->offset == ddl->offset); | 5442 assert (cdl->offset == ddl->offset); |
5443 | 5443 |
5444 db = get_display_block_from_line (ddl, TEXT); | 5444 db = get_display_block_from_line (ddl, TEXT); |
5445 initial_size = Dynarr_length (db->runes); | 5445 initial_size = Dynarr_length (db->runes); |
5446 old_start = ddl->bufpos + ddl->offset; | 5446 old_start = ddl->charbpos + ddl->offset; |
5447 old_end = ddl->end_bufpos + ddl->offset; | 5447 old_end = ddl->end_charbpos + ddl->offset; |
5448 | 5448 |
5449 /* If this is the first line being updated and it used | 5449 /* If this is the first line being updated and it used |
5450 propagation data, fail. Otherwise we'll be okay because | 5450 propagation data, fail. Otherwise we'll be okay because |
5451 we'll have the necessary propagation data. */ | 5451 we'll have the necessary propagation data. */ |
5452 if (line == first_line && ddl->used_prop_data) | 5452 if (line == first_line && ddl->used_prop_data) |
5453 return 0; | 5453 return 0; |
5454 | 5454 |
5455 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, | 5455 new_start = generate_display_line (w, ddl, 0, ddl->charbpos + ddl->offset, |
5456 &prop, DESIRED_DISP); | 5456 &prop, DESIRED_DISP); |
5457 ddl->offset = 0; | 5457 ddl->offset = 0; |
5458 | 5458 |
5459 /* #### If there is propagated stuff the fail. We could | 5459 /* #### If there is propagated stuff the fail. We could |
5460 probably actually deal with this if the line had propagated | 5460 probably actually deal with this if the line had propagated |
5473 || cdl->ascent != ddl->ascent | 5473 || cdl->ascent != ddl->ascent |
5474 || cdl->descent != ddl->descent | 5474 || cdl->descent != ddl->descent |
5475 || cdl->top_clip != ddl->top_clip | 5475 || cdl->top_clip != ddl->top_clip |
5476 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) | 5476 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) |
5477 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1) | 5477 || (cdl->cursor_elt == -1 && ddl->cursor_elt != -1) |
5478 || old_start != ddl->bufpos | 5478 || old_start != ddl->charbpos |
5479 || old_end != ddl->end_bufpos | 5479 || old_end != ddl->end_charbpos |
5480 || initial_size != Dynarr_length (db->runes)) | 5480 || initial_size != Dynarr_length (db->runes)) |
5481 { | 5481 { |
5482 return 0; | 5482 return 0; |
5483 } | 5483 } |
5484 | 5484 |
5490 | 5490 |
5491 last_line = line; | 5491 last_line = line; |
5492 | 5492 |
5493 /* If the extent changes end on the line we just updated then | 5493 /* If the extent changes end on the line we just updated then |
5494 we're done. Otherwise go on to the next line. */ | 5494 we're done. Otherwise go on to the next line. */ |
5495 if (end_unchanged <= ddl->end_bufpos) | 5495 if (end_unchanged <= ddl->end_charbpos) |
5496 break; | 5496 break; |
5497 else | 5497 else |
5498 line++; | 5498 line++; |
5499 } | 5499 } |
5500 | 5500 |
5507 success or failure. If this function returns a failure then a | 5507 success or failure. If this function returns a failure then a |
5508 regenerate_window _must_ be performed next in order to maintain | 5508 regenerate_window _must_ be performed next in order to maintain |
5509 invariants located here. */ | 5509 invariants located here. */ |
5510 | 5510 |
5511 static int | 5511 static int |
5512 regenerate_window_incrementally (struct window *w, Bufpos startp, | 5512 regenerate_window_incrementally (struct window *w, Charbpos startp, |
5513 Bufpos pointm) | 5513 Charbpos pointm) |
5514 { | 5514 { |
5515 struct buffer *b = XBUFFER (w->buffer); | 5515 struct buffer *b = XBUFFER (w->buffer); |
5516 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); | 5516 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); |
5517 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); | 5517 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); |
5518 Charcount beg_unchanged, end_unchanged; | 5518 Charcount beg_unchanged, end_unchanged; |
5519 Charcount extent_beg_unchanged, extent_end_unchanged; | 5519 Charcount extent_beg_unchanged, extent_end_unchanged; |
5520 | 5520 |
5521 int dla_start = 0; | 5521 int dla_start = 0; |
5522 int dla_end, line; | 5522 int dla_end, line; |
5523 Bufpos start_pos; | 5523 Charbpos start_pos; |
5524 | 5524 |
5525 /* If this function is called, the current and desired structures | 5525 /* If this function is called, the current and desired structures |
5526 had better be identical. If they are not, then that is a bug. */ | 5526 had better be identical. If they are not, then that is a bug. */ |
5527 assert (Dynarr_length (cdla) == Dynarr_length (ddla)); | 5527 assert (Dynarr_length (cdla) == Dynarr_length (ddla)); |
5528 | 5528 |
5561 /* Find what display line the buffer changes first affect. */ | 5561 /* Find what display line the buffer changes first affect. */ |
5562 line = dla_start; | 5562 line = dla_start; |
5563 while (line <= dla_end) | 5563 while (line <= dla_end) |
5564 { | 5564 { |
5565 struct display_line *dl = Dynarr_atp (cdla, line); | 5565 struct display_line *dl = Dynarr_atp (cdla, line); |
5566 Bufpos lstart = dl->bufpos + dl->offset; | 5566 Charbpos lstart = dl->charbpos + dl->offset; |
5567 Bufpos lend = dl->end_bufpos + dl->offset; | 5567 Charbpos lend = dl->end_charbpos + dl->offset; |
5568 | 5568 |
5569 if (beg_unchanged >= lstart && beg_unchanged <= lend) | 5569 if (beg_unchanged >= lstart && beg_unchanged <= lend) |
5570 break; | 5570 break; |
5571 | 5571 |
5572 line++; | 5572 line++; |
5585 Otherwise we fail. If we fail we will have altered the desired | 5585 Otherwise we fail. If we fail we will have altered the desired |
5586 structs which could lead to an assertion failure. However, if | 5586 structs which could lead to an assertion failure. However, if |
5587 we fail the next thing that is going to happen is a full regen | 5587 we fail the next thing that is going to happen is a full regen |
5588 so we will actually end up being safe. */ | 5588 so we will actually end up being safe. */ |
5589 { | 5589 { |
5590 Bufpos new_start; | 5590 Charbpos new_start; |
5591 prop_block_dynarr *prop = NULL; | 5591 prop_block_dynarr *prop = NULL; |
5592 struct display_line *cdl = Dynarr_atp (cdla, line); | 5592 struct display_line *cdl = Dynarr_atp (cdla, line); |
5593 struct display_line *ddl = Dynarr_atp (ddla, line); | 5593 struct display_line *ddl = Dynarr_atp (ddla, line); |
5594 | 5594 |
5595 assert (cdl->bufpos == ddl->bufpos); | 5595 assert (cdl->charbpos == ddl->charbpos); |
5596 assert (cdl->end_bufpos == ddl->end_bufpos); | 5596 assert (cdl->end_charbpos == ddl->end_charbpos); |
5597 assert (cdl->offset == ddl->offset); | 5597 assert (cdl->offset == ddl->offset); |
5598 | 5598 |
5599 /* If the line continues to next display line, fail. */ | 5599 /* If the line continues to next display line, fail. */ |
5600 if (ddl->line_continuation) | 5600 if (ddl->line_continuation) |
5601 return 0; | 5601 return 0; |
5602 | 5602 |
5603 /* If the line was generated using propagation data, fail. */ | 5603 /* If the line was generated using propagation data, fail. */ |
5604 if (ddl->used_prop_data) | 5604 if (ddl->used_prop_data) |
5605 return 0; | 5605 return 0; |
5606 | 5606 |
5607 new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset, | 5607 new_start = generate_display_line (w, ddl, 0, ddl->charbpos + ddl->offset, |
5608 &prop, DESIRED_DISP); | 5608 &prop, DESIRED_DISP); |
5609 ddl->offset = 0; | 5609 ddl->offset = 0; |
5610 | 5610 |
5611 /* If there is propagated stuff then it is pretty much a | 5611 /* If there is propagated stuff then it is pretty much a |
5612 guarantee that more than just the one line is affected. */ | 5612 guarantee that more than just the one line is affected. */ |
5632 return 0; | 5632 return 0; |
5633 } | 5633 } |
5634 | 5634 |
5635 /* If the changed area also ends on this line, then we may be in | 5635 /* If the changed area also ends on this line, then we may be in |
5636 business. Update everything and return success. */ | 5636 business. Update everything and return success. */ |
5637 if (end_unchanged >= ddl->bufpos && end_unchanged <= ddl->end_bufpos) | 5637 if (end_unchanged >= ddl->charbpos && end_unchanged <= ddl->end_charbpos) |
5638 { | 5638 { |
5639 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b)); | 5639 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b)); |
5640 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b)); | 5640 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b)); |
5641 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), | 5641 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), |
5642 w->buffer); | 5642 w->buffer); |
5677 buffer changes update succeeded this probably will to. | 5677 buffer changes update succeeded this probably will to. |
5678 We already know that the extent changes start at or after | 5678 We already know that the extent changes start at or after |
5679 the line because we checked before entering the loop. */ | 5679 the line because we checked before entering the loop. */ |
5680 if (extent_beg_unchanged != -1 | 5680 if (extent_beg_unchanged != -1 |
5681 && extent_end_unchanged != -1 | 5681 && extent_end_unchanged != -1 |
5682 && ((extent_beg_unchanged < ddl->bufpos) | 5682 && ((extent_beg_unchanged < ddl->charbpos) |
5683 || (extent_end_unchanged > ddl->end_bufpos))) | 5683 || (extent_end_unchanged > ddl->end_charbpos))) |
5684 return regenerate_window_extents_only_changed (w, startp, pointm, | 5684 return regenerate_window_extents_only_changed (w, startp, pointm, |
5685 extent_beg_unchanged, | 5685 extent_beg_unchanged, |
5686 extent_end_unchanged); | 5686 extent_end_unchanged); |
5687 else | 5687 else |
5688 return 1; | 5688 return 1; |
5695 | 5695 |
5696 /* Given a window and a point, update the given display lines such | 5696 /* Given a window and a point, update the given display lines such |
5697 that point is displayed in the middle of the window. | 5697 that point is displayed in the middle of the window. |
5698 Return the window's new start position. */ | 5698 Return the window's new start position. */ |
5699 | 5699 |
5700 static Bufpos | 5700 static Charbpos |
5701 regenerate_window_point_center (struct window *w, Bufpos point, int type) | 5701 regenerate_window_point_center (struct window *w, Charbpos point, int type) |
5702 { | 5702 { |
5703 Bufpos startp; | 5703 Charbpos startp; |
5704 | 5704 |
5705 /* We need to make sure that the modeline is generated so that the | 5705 /* We need to make sure that the modeline is generated so that the |
5706 window height can be calculated correctly. */ | 5706 window height can be calculated correctly. */ |
5707 ensure_modeline_generated (w, type); | 5707 ensure_modeline_generated (w, type); |
5708 | 5708 |
5715 | 5715 |
5716 /* Given a window and a set of display lines, return a boolean | 5716 /* Given a window and a set of display lines, return a boolean |
5717 indicating whether the given point is contained within. */ | 5717 indicating whether the given point is contained within. */ |
5718 | 5718 |
5719 static int | 5719 static int |
5720 point_visible (struct window *w, Bufpos point, int type) | 5720 point_visible (struct window *w, Charbpos point, int type) |
5721 { | 5721 { |
5722 struct buffer *b = XBUFFER (w->buffer); | 5722 struct buffer *b = XBUFFER (w->buffer); |
5723 display_line_dynarr *dla = window_display_lines (w, type); | 5723 display_line_dynarr *dla = window_display_lines (w, type); |
5724 int first_line; | 5724 int first_line; |
5725 | 5725 |
5728 else | 5728 else |
5729 first_line = 0; | 5729 first_line = 0; |
5730 | 5730 |
5731 if (Dynarr_length (dla) > first_line) | 5731 if (Dynarr_length (dla) > first_line) |
5732 { | 5732 { |
5733 Bufpos start, end; | 5733 Charbpos start, end; |
5734 struct display_line *dl = Dynarr_atp (dla, first_line); | 5734 struct display_line *dl = Dynarr_atp (dla, first_line); |
5735 | 5735 |
5736 start = dl->bufpos; | 5736 start = dl->charbpos; |
5737 end = BUF_Z (b) - w->window_end_pos[type] - 1; | 5737 end = BUF_Z (b) - w->window_end_pos[type] - 1; |
5738 | 5738 |
5739 if (point >= start && point <= end) | 5739 if (point >= start && point <= end) |
5740 { | 5740 { |
5741 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines) | 5741 if (!MINI_WINDOW_P (w) && scroll_on_clipped_lines) |
5742 { | 5742 { |
5743 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1); | 5743 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1); |
5744 | 5744 |
5745 if (point >= (dl->bufpos + dl->offset) | 5745 if (point >= (dl->charbpos + dl->offset) |
5746 && point <= (dl->end_bufpos + dl->offset)) | 5746 && point <= (dl->end_charbpos + dl->offset)) |
5747 return !dl->clip; | 5747 return !dl->clip; |
5748 else | 5748 else |
5749 return 1; | 5749 return 1; |
5750 } | 5750 } |
5751 else | 5751 else |
5769 | 5769 |
5770 /* Return the display line which is currently in the middle of the | 5770 /* Return the display line which is currently in the middle of the |
5771 window W for display lines TYPE. */ | 5771 window W for display lines TYPE. */ |
5772 | 5772 |
5773 int | 5773 int |
5774 line_at_center (struct window *w, int type, Bufpos start, Bufpos point) | 5774 line_at_center (struct window *w, int type, Charbpos start, Charbpos point) |
5775 { | 5775 { |
5776 display_line_dynarr *dla; | 5776 display_line_dynarr *dla; |
5777 int half; | 5777 int half; |
5778 int elt; | 5778 int elt; |
5779 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1); | 5779 int first_elt = (MINI_WINDOW_P (w) ? 0 : 1); |
5799 } | 5799 } |
5800 | 5800 |
5801 /* Return a value for point that would place it at the beginning of | 5801 /* Return a value for point that would place it at the beginning of |
5802 the line which is in the middle of the window. */ | 5802 the line which is in the middle of the window. */ |
5803 | 5803 |
5804 Bufpos | 5804 Charbpos |
5805 point_at_center (struct window *w, int type, Bufpos start, Bufpos point) | 5805 point_at_center (struct window *w, int type, Charbpos start, Charbpos point) |
5806 { | 5806 { |
5807 /* line_at_center will regenerate the display structures, if necessary. */ | 5807 /* line_at_center will regenerate the display structures, if necessary. */ |
5808 int line = line_at_center (w, type, start, point); | 5808 int line = line_at_center (w, type, start, point); |
5809 | 5809 |
5810 if (line == -1) | 5810 if (line == -1) |
5812 else | 5812 else |
5813 { | 5813 { |
5814 display_line_dynarr *dla = window_display_lines (w, type); | 5814 display_line_dynarr *dla = window_display_lines (w, type); |
5815 struct display_line *dl = Dynarr_atp (dla, line); | 5815 struct display_line *dl = Dynarr_atp (dla, line); |
5816 | 5816 |
5817 return dl->bufpos; | 5817 return dl->charbpos; |
5818 } | 5818 } |
5819 } | 5819 } |
5820 | 5820 |
5821 /* For a given window, ensure that the current visual representation | 5821 /* For a given window, ensure that the current visual representation |
5822 is accurate. */ | 5822 is accurate. */ |
6163 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer); | 6163 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), w->buffer); |
6164 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer); | 6164 Fset_marker (w->last_point[DESIRED_DISP], make_int (pointm), w->buffer); |
6165 | 6165 |
6166 if (!skip_output) | 6166 if (!skip_output) |
6167 { | 6167 { |
6168 Bufpos start = marker_position (w->start[DESIRED_DISP]); | 6168 Charbpos start = marker_position (w->start[DESIRED_DISP]); |
6169 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1 | 6169 Charbpos end = (w->window_end_pos[DESIRED_DISP] == -1 |
6170 ? BUF_ZV (b) | 6170 ? BUF_ZV (b) |
6171 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1); | 6171 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1); |
6172 /* Don't pollute the cache if not sure if we are correct */ | 6172 /* Don't pollute the cache if not sure if we are correct */ |
6173 if (w->start_at_line_beg) | 6173 if (w->start_at_line_beg) |
6174 update_line_start_cache (w, start, end, pointm, 1); | 6174 update_line_start_cache (w, start, end, pointm, 1); |
6233 } | 6233 } |
6234 | 6234 |
6235 static int | 6235 static int |
6236 call_redisplay_end_triggers (struct window *w, void *closure) | 6236 call_redisplay_end_triggers (struct window *w, void *closure) |
6237 { | 6237 { |
6238 Bufpos lrpos = w->last_redisplay_pos; | 6238 Charbpos lrpos = w->last_redisplay_pos; |
6239 w->last_redisplay_pos = 0; | 6239 w->last_redisplay_pos = 0; |
6240 if (!NILP (w->buffer) | 6240 if (!NILP (w->buffer) |
6241 && !NILP (w->redisplay_end_trigger) | 6241 && !NILP (w->redisplay_end_trigger) |
6242 && lrpos > 0) | 6242 && lrpos > 0) |
6243 { | 6243 { |
6244 Bufpos pos; | 6244 Charbpos pos; |
6245 | 6245 |
6246 if (MARKERP (w->redisplay_end_trigger) | 6246 if (MARKERP (w->redisplay_end_trigger) |
6247 && XMARKER (w->redisplay_end_trigger)->buffer != 0) | 6247 && XMARKER (w->redisplay_end_trigger)->buffer != 0) |
6248 pos = marker_position (w->redisplay_end_trigger); | 6248 pos = marker_position (w->redisplay_end_trigger); |
6249 else if (INTP (w->redisplay_end_trigger)) | 6249 else if (INTP (w->redisplay_end_trigger)) |
6637 struct device *d = XDEVICE (XFRAME (w->frame)->device); | 6637 struct device *d = XDEVICE (XFRAME (w->frame)->device); |
6638 struct buffer *b = XBUFFER (w->buffer); | 6638 struct buffer *b = XBUFFER (w->buffer); |
6639 /* Be careful in the order of these tests. The first clause will | 6639 /* Be careful in the order of these tests. The first clause will |
6640 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be). | 6640 fail if DEVICE_SELECTED_FRAME == Qnil (since w->frame cannot be). |
6641 This can occur when the frame title is computed really early */ | 6641 This can occur when the frame title is computed really early */ |
6642 Bufpos pos = | 6642 Charbpos pos = |
6643 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) && | 6643 ((EQ(DEVICE_SELECTED_FRAME(d), w->frame) && |
6644 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) && | 6644 (w == XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame(d)))) && |
6645 EQ(DEVICE_CONSOLE(d), Vselected_console) && | 6645 EQ(DEVICE_CONSOLE(d), Vselected_console) && |
6646 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d ) | 6646 XDEVICE(CONSOLE_SELECTED_DEVICE(XCONSOLE(DEVICE_CONSOLE(d)))) == d ) |
6647 ? BUF_PT (b) | 6647 ? BUF_PT (b) |
6660 } | 6660 } |
6661 | 6661 |
6662 | 6662 |
6663 /* Given a character representing an object in a modeline | 6663 /* Given a character representing an object in a modeline |
6664 specification, return a string (stored into the global array | 6664 specification, return a string (stored into the global array |
6665 `mode_spec_bufbyte_string') with the information that object | 6665 `mode_spec_intbyte_string') with the information that object |
6666 represents. | 6666 represents. |
6667 | 6667 |
6668 This function is largely unchanged from previous versions of the | 6668 This function is largely unchanged from previous versions of the |
6669 redisplay engine. | 6669 redisplay engine. |
6670 | 6670 |
6677 { | 6677 { |
6678 Lisp_Object obj = Qnil; | 6678 Lisp_Object obj = Qnil; |
6679 const char *str = NULL; | 6679 const char *str = NULL; |
6680 struct buffer *b = XBUFFER (w->buffer); | 6680 struct buffer *b = XBUFFER (w->buffer); |
6681 | 6681 |
6682 Dynarr_reset (mode_spec_bufbyte_string); | 6682 Dynarr_reset (mode_spec_intbyte_string); |
6683 | 6683 |
6684 switch (spec) | 6684 switch (spec) |
6685 { | 6685 { |
6686 /* print buffer name */ | 6686 /* print buffer name */ |
6687 case 'b': | 6687 case 'b': |
6694 break; | 6694 break; |
6695 | 6695 |
6696 /* print the current column */ | 6696 /* print the current column */ |
6697 case 'c': | 6697 case 'c': |
6698 { | 6698 { |
6699 Bufpos pt = (w == XWINDOW (Fselected_window (Qnil))) | 6699 Charbpos pt = (w == XWINDOW (Fselected_window (Qnil))) |
6700 ? BUF_PT (b) | 6700 ? BUF_PT (b) |
6701 : marker_position (w->pointm[type]); | 6701 : marker_position (w->pointm[type]); |
6702 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one; | 6702 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one; |
6703 char buf[DECIMAL_PRINT_SIZE (long)]; | 6703 char buf[DECIMAL_PRINT_SIZE (long)]; |
6704 | 6704 |
6705 long_to_string (buf, col); | 6705 long_to_string (buf, col); |
6706 | 6706 |
6707 Dynarr_add_many (mode_spec_bufbyte_string, | 6707 Dynarr_add_many (mode_spec_intbyte_string, |
6708 (const Bufbyte *) buf, strlen (buf)); | 6708 (const Intbyte *) buf, strlen (buf)); |
6709 | 6709 |
6710 goto decode_mode_spec_done; | 6710 goto decode_mode_spec_done; |
6711 } | 6711 } |
6712 /* print the file coding system */ | 6712 /* print the file coding system */ |
6713 case 'C': | 6713 case 'C': |
6807 break; | 6807 break; |
6808 | 6808 |
6809 /* print percent of buffer above top of window, or Top, Bot or All */ | 6809 /* print percent of buffer above top of window, or Top, Bot or All */ |
6810 case 'p': | 6810 case 'p': |
6811 { | 6811 { |
6812 Bufpos pos = marker_position (w->start[type]); | 6812 Charbpos pos = marker_position (w->start[type]); |
6813 | 6813 |
6814 /* This had better be while the desired lines are being done. */ | 6814 /* This had better be while the desired lines are being done. */ |
6815 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b)) | 6815 if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b)) |
6816 { | 6816 { |
6817 if (pos <= BUF_BEGV (b)) | 6817 if (pos <= BUF_BEGV (b)) |
6838 2-digit number that is close. */ | 6838 2-digit number that is close. */ |
6839 if (percent == 100) | 6839 if (percent == 100) |
6840 percent = 99; | 6840 percent = 99; |
6841 | 6841 |
6842 sprintf (buf, "%d%%", percent); | 6842 sprintf (buf, "%d%%", percent); |
6843 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, | 6843 Dynarr_add_many (mode_spec_intbyte_string, (Intbyte *) buf, |
6844 strlen (buf)); | 6844 strlen (buf)); |
6845 | 6845 |
6846 goto decode_mode_spec_done; | 6846 goto decode_mode_spec_done; |
6847 } | 6847 } |
6848 break; | 6848 break; |
6850 | 6850 |
6851 /* print percent of buffer above bottom of window, perhaps plus | 6851 /* print percent of buffer above bottom of window, perhaps plus |
6852 Top, or print Bottom or All */ | 6852 Top, or print Bottom or All */ |
6853 case 'P': | 6853 case 'P': |
6854 { | 6854 { |
6855 Bufpos toppos = marker_position (w->start[type]); | 6855 Charbpos toppos = marker_position (w->start[type]); |
6856 Bufpos botpos = BUF_Z (b) - w->window_end_pos[type]; | 6856 Charbpos botpos = BUF_Z (b) - w->window_end_pos[type]; |
6857 | 6857 |
6858 /* botpos is only accurate as of the last redisplay, so we can | 6858 /* botpos is only accurate as of the last redisplay, so we can |
6859 only treat it as a hint. In particular, after erase-buffer, | 6859 only treat it as a hint. In particular, after erase-buffer, |
6860 botpos may be negative. */ | 6860 botpos may be negative. */ |
6861 if (botpos < toppos) | 6861 if (botpos < toppos) |
6889 if (toppos <= BUF_BEGV (b)) | 6889 if (toppos <= BUF_BEGV (b)) |
6890 sprintf (buf, "Top%d%%", percent); | 6890 sprintf (buf, "Top%d%%", percent); |
6891 else | 6891 else |
6892 sprintf (buf, "%d%%", percent); | 6892 sprintf (buf, "%d%%", percent); |
6893 | 6893 |
6894 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf, | 6894 Dynarr_add_many (mode_spec_intbyte_string, (Intbyte *) buf, |
6895 strlen (buf)); | 6895 strlen (buf)); |
6896 | 6896 |
6897 goto decode_mode_spec_done; | 6897 goto decode_mode_spec_done; |
6898 } | 6898 } |
6899 break; | 6899 break; |
6914 str = "[[[... "; | 6914 str = "[[[... "; |
6915 break; | 6915 break; |
6916 } | 6916 } |
6917 | 6917 |
6918 for (i = 0; i < command_loop_level; i++) | 6918 for (i = 0; i < command_loop_level; i++) |
6919 Dynarr_add (mode_spec_bufbyte_string, '['); | 6919 Dynarr_add (mode_spec_intbyte_string, '['); |
6920 | 6920 |
6921 goto decode_mode_spec_done; | 6921 goto decode_mode_spec_done; |
6922 } | 6922 } |
6923 | 6923 |
6924 /* print one ] for each recursive editing level. */ | 6924 /* print one ] for each recursive editing level. */ |
6931 str = "...]]]"; | 6931 str = "...]]]"; |
6932 break; | 6932 break; |
6933 } | 6933 } |
6934 | 6934 |
6935 for (i = 0; i < command_loop_level; i++) | 6935 for (i = 0; i < command_loop_level; i++) |
6936 Dynarr_add (mode_spec_bufbyte_string, ']'); | 6936 Dynarr_add (mode_spec_intbyte_string, ']'); |
6937 | 6937 |
6938 goto decode_mode_spec_done; | 6938 goto decode_mode_spec_done; |
6939 } | 6939 } |
6940 | 6940 |
6941 /* print infinitely many dashes -- handle at top level now */ | 6941 /* print infinitely many dashes -- handle at top level now */ |
6943 break; | 6943 break; |
6944 | 6944 |
6945 } | 6945 } |
6946 | 6946 |
6947 if (STRINGP (obj)) | 6947 if (STRINGP (obj)) |
6948 Dynarr_add_many (mode_spec_bufbyte_string, | 6948 Dynarr_add_many (mode_spec_intbyte_string, |
6949 XSTRING_DATA (obj), | 6949 XSTRING_DATA (obj), |
6950 XSTRING_LENGTH (obj)); | 6950 XSTRING_LENGTH (obj)); |
6951 else if (str) | 6951 else if (str) |
6952 Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) str, strlen (str)); | 6952 Dynarr_add_many (mode_spec_intbyte_string, (Intbyte *) str, strlen (str)); |
6953 | 6953 |
6954 decode_mode_spec_done: | 6954 decode_mode_spec_done: |
6955 Dynarr_add (mode_spec_bufbyte_string, '\0'); | 6955 Dynarr_add (mode_spec_intbyte_string, '\0'); |
6956 } | 6956 } |
6957 | 6957 |
6958 /* Given a display line, free all of its data structures. */ | 6958 /* Given a display line, free all of its data structures. */ |
6959 | 6959 |
6960 static void | 6960 static void |
7160 continue; | 7160 continue; |
7161 else | 7161 else |
7162 { | 7162 { |
7163 struct line_start_cache lsc; | 7163 struct line_start_cache lsc; |
7164 | 7164 |
7165 lsc.start = dl->bufpos; | 7165 lsc.start = dl->charbpos; |
7166 lsc.end = dl->end_bufpos; | 7166 lsc.end = dl->end_charbpos; |
7167 lsc.height = dl->ascent + dl->descent; | 7167 lsc.height = dl->ascent + dl->descent; |
7168 | 7168 |
7169 Dynarr_add (internal_cache, lsc); | 7169 Dynarr_add (internal_cache, lsc); |
7170 } | 7170 } |
7171 } | 7171 } |
7204 | 7204 |
7205 /* Return the very first buffer position contained in the given | 7205 /* Return the very first buffer position contained in the given |
7206 window's cache, or -1 if the cache is empty. Assumes that the | 7206 window's cache, or -1 if the cache is empty. Assumes that the |
7207 cache is valid. */ | 7207 cache is valid. */ |
7208 | 7208 |
7209 static Bufpos | 7209 static Charbpos |
7210 line_start_cache_start (struct window *w) | 7210 line_start_cache_start (struct window *w) |
7211 { | 7211 { |
7212 line_start_cache_dynarr *cache = w->line_start_cache; | 7212 line_start_cache_dynarr *cache = w->line_start_cache; |
7213 | 7213 |
7214 if (!Dynarr_length (cache)) | 7214 if (!Dynarr_length (cache)) |
7219 | 7219 |
7220 /* Return the very last buffer position contained in the given | 7220 /* Return the very last buffer position contained in the given |
7221 window's cache, or -1 if the cache is empty. Assumes that the | 7221 window's cache, or -1 if the cache is empty. Assumes that the |
7222 cache is valid. */ | 7222 cache is valid. */ |
7223 | 7223 |
7224 static Bufpos | 7224 static Charbpos |
7225 line_start_cache_end (struct window *w) | 7225 line_start_cache_end (struct window *w) |
7226 { | 7226 { |
7227 line_start_cache_dynarr *cache = w->line_start_cache; | 7227 line_start_cache_dynarr *cache = w->line_start_cache; |
7228 | 7228 |
7229 if (!Dynarr_length (cache)) | 7229 if (!Dynarr_length (cache)) |
7240 then it will be treated as 0, but the cache window will not be | 7240 then it will be treated as 0, but the cache window will not be |
7241 allowed to shift. Returns -1 if POINT cannot be found in the cache | 7241 allowed to shift. Returns -1 if POINT cannot be found in the cache |
7242 for any reason. */ | 7242 for any reason. */ |
7243 | 7243 |
7244 int | 7244 int |
7245 point_in_line_start_cache (struct window *w, Bufpos point, int min_past) | 7245 point_in_line_start_cache (struct window *w, Charbpos point, int min_past) |
7246 { | 7246 { |
7247 struct buffer *b = XBUFFER (w->buffer); | 7247 struct buffer *b = XBUFFER (w->buffer); |
7248 line_start_cache_dynarr *cache = w->line_start_cache; | 7248 line_start_cache_dynarr *cache = w->line_start_cache; |
7249 int top, bottom, pos; | 7249 int top, bottom, pos; |
7250 | 7250 |
7269 if (!win_char_height) | 7269 if (!win_char_height) |
7270 win_char_height = 1; | 7270 win_char_height = 1; |
7271 | 7271 |
7272 if (!Dynarr_length (cache)) | 7272 if (!Dynarr_length (cache)) |
7273 { | 7273 { |
7274 Bufpos from = find_next_newline_no_quit (b, point, -1); | 7274 Charbpos from = find_next_newline_no_quit (b, point, -1); |
7275 Bufpos to = find_next_newline_no_quit (b, from, win_char_height); | 7275 Charbpos to = find_next_newline_no_quit (b, from, win_char_height); |
7276 | 7276 |
7277 update_line_start_cache (w, from, to, point, 0); | 7277 update_line_start_cache (w, from, to, point, 0); |
7278 | 7278 |
7279 if (!Dynarr_length (cache)) | 7279 if (!Dynarr_length (cache)) |
7280 { | 7280 { |
7287 | 7287 |
7288 loop = 0; | 7288 loop = 0; |
7289 while (line_start_cache_start (w) > point | 7289 while (line_start_cache_start (w) > point |
7290 && (loop < cache_adjustment || min_past == -1)) | 7290 && (loop < cache_adjustment || min_past == -1)) |
7291 { | 7291 { |
7292 Bufpos from, to; | 7292 Charbpos from, to; |
7293 | 7293 |
7294 from = line_start_cache_start (w); | 7294 from = line_start_cache_start (w); |
7295 if (from <= BUF_BEGV (b)) | 7295 if (from <= BUF_BEGV (b)) |
7296 break; | 7296 break; |
7297 | 7297 |
7302 loop++; | 7302 loop++; |
7303 } | 7303 } |
7304 | 7304 |
7305 if (line_start_cache_start (w) > point) | 7305 if (line_start_cache_start (w) > point) |
7306 { | 7306 { |
7307 Bufpos from, to; | 7307 Charbpos from, to; |
7308 | 7308 |
7309 from = find_next_newline_no_quit (b, point, -1); | 7309 from = find_next_newline_no_quit (b, point, -1); |
7310 if (from >= BUF_ZV (b)) | 7310 if (from >= BUF_ZV (b)) |
7311 { | 7311 { |
7312 to = find_next_newline_no_quit (b, from, -win_char_height); | 7312 to = find_next_newline_no_quit (b, from, -win_char_height); |
7321 | 7321 |
7322 loop = 0; | 7322 loop = 0; |
7323 while (line_start_cache_end (w) < point | 7323 while (line_start_cache_end (w) < point |
7324 && (loop < cache_adjustment || min_past == -1)) | 7324 && (loop < cache_adjustment || min_past == -1)) |
7325 { | 7325 { |
7326 Bufpos from, to; | 7326 Charbpos from, to; |
7327 | 7327 |
7328 to = line_start_cache_end (w); | 7328 to = line_start_cache_end (w); |
7329 if (to >= BUF_ZV (b)) | 7329 if (to >= BUF_ZV (b)) |
7330 break; | 7330 break; |
7331 | 7331 |
7336 loop++; | 7336 loop++; |
7337 } | 7337 } |
7338 | 7338 |
7339 if (line_start_cache_end (w) < point) | 7339 if (line_start_cache_end (w) < point) |
7340 { | 7340 { |
7341 Bufpos from, to; | 7341 Charbpos from, to; |
7342 | 7342 |
7343 from = find_next_newline_no_quit (b, point, -1); | 7343 from = find_next_newline_no_quit (b, point, -1); |
7344 if (from >= BUF_ZV (b)) | 7344 if (from >= BUF_ZV (b)) |
7345 { | 7345 { |
7346 to = find_next_newline_no_quit (b, from, -win_char_height); | 7346 to = find_next_newline_no_quit (b, from, -win_char_height); |
7373 bottom = 0; | 7373 bottom = 0; |
7374 | 7374 |
7375 while (1) | 7375 while (1) |
7376 { | 7376 { |
7377 int new_pos; | 7377 int new_pos; |
7378 Bufpos start, end; | 7378 Charbpos start, end; |
7379 | 7379 |
7380 pos = (bottom + top + 1) >> 1; | 7380 pos = (bottom + top + 1) >> 1; |
7381 start = Dynarr_atp (cache, pos)->start; | 7381 start = Dynarr_atp (cache, pos)->start; |
7382 end = Dynarr_atp (cache, pos)->end; | 7382 end = Dynarr_atp (cache, pos)->end; |
7383 | 7383 |
7384 if (point >= start && point <= end) | 7384 if (point >= start && point <= end) |
7385 { | 7385 { |
7386 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b)) | 7386 if (pos < min_past && line_start_cache_start (w) > BUF_BEGV (b)) |
7387 { | 7387 { |
7388 Bufpos from = | 7388 Charbpos from = |
7389 find_next_newline_no_quit (b, line_start_cache_start (w), | 7389 find_next_newline_no_quit (b, line_start_cache_start (w), |
7390 -min_past - 1); | 7390 -min_past - 1); |
7391 Bufpos to = line_start_cache_end (w); | 7391 Charbpos to = line_start_cache_end (w); |
7392 | 7392 |
7393 update_line_start_cache (w, from, to, point, 0); | 7393 update_line_start_cache (w, from, to, point, 0); |
7394 goto find_point_loop; | 7394 goto find_point_loop; |
7395 } | 7395 } |
7396 else if ((Dynarr_length (cache) - pos - 1) < min_past | 7396 else if ((Dynarr_length (cache) - pos - 1) < min_past |
7397 && line_start_cache_end (w) < BUF_ZV (b)) | 7397 && line_start_cache_end (w) < BUF_ZV (b)) |
7398 { | 7398 { |
7399 Bufpos from = line_start_cache_end (w); | 7399 Charbpos from = line_start_cache_end (w); |
7400 Bufpos to = find_next_newline_no_quit (b, from, | 7400 Charbpos to = find_next_newline_no_quit (b, from, |
7401 (min_past | 7401 (min_past |
7402 ? min_past | 7402 ? min_past |
7403 : 1)); | 7403 : 1)); |
7404 | 7404 |
7405 update_line_start_cache (w, from, to, point, 0); | 7405 update_line_start_cache (w, from, to, point, 0); |
7429 | 7429 |
7430 /* Return a boolean indicating if POINT would be visible in window W | 7430 /* Return a boolean indicating if POINT would be visible in window W |
7431 if display of the window was to begin at STARTP. */ | 7431 if display of the window was to begin at STARTP. */ |
7432 | 7432 |
7433 int | 7433 int |
7434 point_would_be_visible (struct window *w, Bufpos startp, Bufpos point) | 7434 point_would_be_visible (struct window *w, Charbpos startp, Charbpos point) |
7435 { | 7435 { |
7436 struct buffer *b = XBUFFER (w->buffer); | 7436 struct buffer *b = XBUFFER (w->buffer); |
7437 int pixpos = -WINDOW_TEXT_TOP_CLIP(w); | 7437 int pixpos = -WINDOW_TEXT_TOP_CLIP(w); |
7438 int bottom = WINDOW_TEXT_HEIGHT (w); | 7438 int bottom = WINDOW_TEXT_HEIGHT (w); |
7439 int start_elt; | 7439 int start_elt; |
7466 int height; | 7466 int height; |
7467 | 7467 |
7468 /* Expand the cache if necessary. */ | 7468 /* Expand the cache if necessary. */ |
7469 if (start_elt == Dynarr_length (w->line_start_cache)) | 7469 if (start_elt == Dynarr_length (w->line_start_cache)) |
7470 { | 7470 { |
7471 Bufpos old_startp = | 7471 Charbpos old_startp = |
7472 Dynarr_atp (w->line_start_cache, start_elt - 1)->start; | 7472 Dynarr_atp (w->line_start_cache, start_elt - 1)->start; |
7473 | 7473 |
7474 start_elt = point_in_line_start_cache (w, old_startp, | 7474 start_elt = point_in_line_start_cache (w, old_startp, |
7475 window_char_height (w, 0)); | 7475 window_char_height (w, 0)); |
7476 | 7476 |
7520 pixel_to_glyph_translation) already can handle 0 as an error return value. | 7520 pixel_to_glyph_translation) already can handle 0 as an error return value. |
7521 | 7521 |
7522 #### With a little work this could probably be reworked as just a | 7522 #### With a little work this could probably be reworked as just a |
7523 call to start_with_line_at_pixpos. */ | 7523 call to start_with_line_at_pixpos. */ |
7524 | 7524 |
7525 static Bufpos | 7525 static Charbpos |
7526 start_end_of_last_line (struct window *w, Bufpos startp, int end, | 7526 start_end_of_last_line (struct window *w, Charbpos startp, int end, |
7527 int may_error) | 7527 int may_error) |
7528 { | 7528 { |
7529 struct buffer *b = XBUFFER (w->buffer); | 7529 struct buffer *b = XBUFFER (w->buffer); |
7530 line_start_cache_dynarr *cache = w->line_start_cache; | 7530 line_start_cache_dynarr *cache = w->line_start_cache; |
7531 int pixpos = 0; | 7531 int pixpos = 0; |
7532 int bottom = WINDOW_TEXT_HEIGHT (w); | 7532 int bottom = WINDOW_TEXT_HEIGHT (w); |
7533 Bufpos cur_start; | 7533 Charbpos cur_start; |
7534 int start_elt; | 7534 int start_elt; |
7535 | 7535 |
7536 validate_line_start_cache (w); | 7536 validate_line_start_cache (w); |
7537 w->line_cache_validation_override++; | 7537 w->line_cache_validation_override++; |
7538 | 7538 |
7578 | 7578 |
7579 pixpos += height; | 7579 pixpos += height; |
7580 start_elt++; | 7580 start_elt++; |
7581 if (start_elt == Dynarr_length (cache)) | 7581 if (start_elt == Dynarr_length (cache)) |
7582 { | 7582 { |
7583 Bufpos from = line_start_cache_end (w); | 7583 Charbpos from = line_start_cache_end (w); |
7584 int win_char_height = window_char_height (w, 0); | 7584 int win_char_height = window_char_height (w, 0); |
7585 Bufpos to = find_next_newline_no_quit (b, from, | 7585 Charbpos to = find_next_newline_no_quit (b, from, |
7586 (win_char_height | 7586 (win_char_height |
7587 ? win_char_height | 7587 ? win_char_height |
7588 : 1)); | 7588 : 1)); |
7589 | 7589 |
7590 /* We've hit the end of the bottom so that's what it is. */ | 7590 /* We've hit the end of the bottom so that's what it is. */ |
7603 } | 7603 } |
7604 | 7604 |
7605 /* For the given window W, if display starts at STARTP, what will be | 7605 /* For the given window W, if display starts at STARTP, what will be |
7606 the buffer position at the beginning of the last line displayed. */ | 7606 the buffer position at the beginning of the last line displayed. */ |
7607 | 7607 |
7608 Bufpos | 7608 Charbpos |
7609 start_of_last_line (struct window *w, Bufpos startp) | 7609 start_of_last_line (struct window *w, Charbpos startp) |
7610 { | 7610 { |
7611 return start_end_of_last_line (w, startp, 0 , 0); | 7611 return start_end_of_last_line (w, startp, 0 , 0); |
7612 } | 7612 } |
7613 | 7613 |
7614 /* For the given window W, if display starts at STARTP, what will be | 7614 /* For the given window W, if display starts at STARTP, what will be |
7615 the buffer position at the end of the last line displayed. This is | 7615 the buffer position at the end of the last line displayed. This is |
7616 also know as the window end position. */ | 7616 also know as the window end position. */ |
7617 | 7617 |
7618 Bufpos | 7618 Charbpos |
7619 end_of_last_line (struct window *w, Bufpos startp) | 7619 end_of_last_line (struct window *w, Charbpos startp) |
7620 { | 7620 { |
7621 return start_end_of_last_line (w, startp, 1, 0); | 7621 return start_end_of_last_line (w, startp, 1, 0); |
7622 } | 7622 } |
7623 | 7623 |
7624 static Bufpos | 7624 static Charbpos |
7625 end_of_last_line_may_error (struct window *w, Bufpos startp) | 7625 end_of_last_line_may_error (struct window *w, Charbpos startp) |
7626 { | 7626 { |
7627 return start_end_of_last_line (w, startp, 1, 1); | 7627 return start_end_of_last_line (w, startp, 1, 1); |
7628 } | 7628 } |
7629 | 7629 |
7630 | 7630 |
7631 /* For window W, what does the starting position have to be so that | 7631 /* For window W, what does the starting position have to be so that |
7632 the line containing POINT will cover pixel position PIXPOS. */ | 7632 the line containing POINT will cover pixel position PIXPOS. */ |
7633 | 7633 |
7634 Bufpos | 7634 Charbpos |
7635 start_with_line_at_pixpos (struct window *w, Bufpos point, int pixpos) | 7635 start_with_line_at_pixpos (struct window *w, Charbpos point, int pixpos) |
7636 { | 7636 { |
7637 struct buffer *b = XBUFFER (w->buffer); | 7637 struct buffer *b = XBUFFER (w->buffer); |
7638 int cur_elt; | 7638 int cur_elt; |
7639 Bufpos cur_pos, prev_pos = point; | 7639 Charbpos cur_pos, prev_pos = point; |
7640 int point_line_height; | 7640 int point_line_height; |
7641 int pixheight = pixpos - WINDOW_TEXT_TOP (w); | 7641 int pixheight = pixpos - WINDOW_TEXT_TOP (w); |
7642 | 7642 |
7643 validate_line_start_cache (w); | 7643 validate_line_start_cache (w); |
7644 w->line_cache_validation_override++; | 7644 w->line_cache_validation_override++; |
7673 } | 7673 } |
7674 | 7674 |
7675 cur_elt--; | 7675 cur_elt--; |
7676 while (cur_elt < 0) | 7676 while (cur_elt < 0) |
7677 { | 7677 { |
7678 Bufpos from, to; | 7678 Charbpos from, to; |
7679 int win_char_height; | 7679 int win_char_height; |
7680 | 7680 |
7681 if (cur_pos <= BUF_BEGV (b)) | 7681 if (cur_pos <= BUF_BEGV (b)) |
7682 { | 7682 { |
7683 w->line_cache_validation_override--; | 7683 w->line_cache_validation_override--; |
7717 positive it is considered to be the number of lines from the top of | 7717 positive it is considered to be the number of lines from the top of |
7718 the window (0 is the top line). If it is negative the number is | 7718 the window (0 is the top line). If it is negative the number is |
7719 considered to be the number of lines from the bottom (-1 is the | 7719 considered to be the number of lines from the bottom (-1 is the |
7720 bottom line). */ | 7720 bottom line). */ |
7721 | 7721 |
7722 Bufpos | 7722 Charbpos |
7723 start_with_point_on_display_line (struct window *w, Bufpos point, int line) | 7723 start_with_point_on_display_line (struct window *w, Charbpos point, int line) |
7724 { | 7724 { |
7725 validate_line_start_cache (w); | 7725 validate_line_start_cache (w); |
7726 w->line_cache_validation_override++; | 7726 w->line_cache_validation_override++; |
7727 | 7727 |
7728 if (line >= 0) | 7728 if (line >= 0) |
7743 or what we want when line is -1. Therefore we subtract one | 7743 or what we want when line is -1. Therefore we subtract one |
7744 because we have already handled one line. */ | 7744 because we have already handled one line. */ |
7745 int new_line = -line - 1; | 7745 int new_line = -line - 1; |
7746 int cur_elt = point_in_line_start_cache (w, point, new_line); | 7746 int cur_elt = point_in_line_start_cache (w, point, new_line); |
7747 int pixpos = WINDOW_TEXT_BOTTOM (w); | 7747 int pixpos = WINDOW_TEXT_BOTTOM (w); |
7748 Bufpos retval, search_point; | 7748 Charbpos retval, search_point; |
7749 | 7749 |
7750 /* If scroll_on_clipped_lines is false, the last "visible" line of | 7750 /* If scroll_on_clipped_lines is false, the last "visible" line of |
7751 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1. | 7751 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1. |
7752 If s_o_c_l is true, then we don't want to count a clipped | 7752 If s_o_c_l is true, then we don't want to count a clipped |
7753 line, so back up from the bottom by the height of the line | 7753 line, so back up from the bottom by the height of the line |
7800 It might help to make the cache a dynarr of caches so that we can | 7800 It might help to make the cache a dynarr of caches so that we can |
7801 cover more areas. This might, however, turn out to be a lot of | 7801 cover more areas. This might, however, turn out to be a lot of |
7802 overhead for too little gain. */ | 7802 overhead for too little gain. */ |
7803 | 7803 |
7804 static void | 7804 static void |
7805 update_line_start_cache (struct window *w, Bufpos from, Bufpos to, | 7805 update_line_start_cache (struct window *w, Charbpos from, Charbpos to, |
7806 Bufpos point, int no_regen) | 7806 Charbpos point, int no_regen) |
7807 { | 7807 { |
7808 struct buffer *b = XBUFFER (w->buffer); | 7808 struct buffer *b = XBUFFER (w->buffer); |
7809 line_start_cache_dynarr *cache = w->line_start_cache; | 7809 line_start_cache_dynarr *cache = w->line_start_cache; |
7810 Bufpos low_bound, high_bound; | 7810 Charbpos low_bound, high_bound; |
7811 | 7811 |
7812 validate_line_start_cache (w); | 7812 validate_line_start_cache (w); |
7813 w->line_cache_validation_override++; | 7813 w->line_cache_validation_override++; |
7814 | 7814 |
7815 if (from < BUF_BEGV (b)) | 7815 if (from < BUF_BEGV (b)) |
7852 | 7852 |
7853 /* This could be integrated into the next two sections, but it is easier | 7853 /* This could be integrated into the next two sections, but it is easier |
7854 to follow what's going on by having it separate. */ | 7854 to follow what's going on by having it separate. */ |
7855 if (no_regen) | 7855 if (no_regen) |
7856 { | 7856 { |
7857 Bufpos start, end; | 7857 Charbpos start, end; |
7858 | 7858 |
7859 update_internal_cache_list (w, DESIRED_DISP); | 7859 update_internal_cache_list (w, DESIRED_DISP); |
7860 if (!Dynarr_length (internal_cache)) | 7860 if (!Dynarr_length (internal_cache)) |
7861 { | 7861 { |
7862 w->line_cache_validation_override--; | 7862 w->line_cache_validation_override--; |
7953 return; | 7953 return; |
7954 } | 7954 } |
7955 | 7955 |
7956 if (!Dynarr_length (cache) || from < low_bound) | 7956 if (!Dynarr_length (cache) || from < low_bound) |
7957 { | 7957 { |
7958 Bufpos startp = find_next_newline_no_quit (b, from, -1); | 7958 Charbpos startp = find_next_newline_no_quit (b, from, -1); |
7959 int marker = 0; | 7959 int marker = 0; |
7960 int old_lb = low_bound; | 7960 int old_lb = low_bound; |
7961 | 7961 |
7962 while (startp < old_lb || low_bound == -1) | 7962 while (startp < old_lb || low_bound == -1) |
7963 { | 7963 { |
7964 int ic_elt; | 7964 int ic_elt; |
7965 Bufpos new_startp; | 7965 Charbpos new_startp; |
7966 | 7966 |
7967 regenerate_window (w, startp, point, CMOTION_DISP); | 7967 regenerate_window (w, startp, point, CMOTION_DISP); |
7968 update_internal_cache_list (w, CMOTION_DISP); | 7968 update_internal_cache_list (w, CMOTION_DISP); |
7969 | 7969 |
7970 /* If this assert is triggered then regenerate_window failed | 7970 /* If this assert is triggered then regenerate_window failed |
8029 correcting the low_bound. */ | 8029 correcting the low_bound. */ |
8030 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end; | 8030 high_bound = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end; |
8031 | 8031 |
8032 if (to > high_bound) | 8032 if (to > high_bound) |
8033 { | 8033 { |
8034 Bufpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1; | 8034 Charbpos startp = Dynarr_atp (cache, Dynarr_length (cache) - 1)->end + 1; |
8035 | 8035 |
8036 do | 8036 do |
8037 { | 8037 { |
8038 regenerate_window (w, startp, point, CMOTION_DISP); | 8038 regenerate_window (w, startp, point, CMOTION_DISP); |
8039 update_internal_cache_list (w, CMOTION_DISP); | 8039 update_internal_cache_list (w, CMOTION_DISP); |
8216 d->pixel_to_glyph_cache.col = *col; \ | 8216 d->pixel_to_glyph_cache.col = *col; \ |
8217 d->pixel_to_glyph_cache.row = *row; \ | 8217 d->pixel_to_glyph_cache.row = *row; \ |
8218 d->pixel_to_glyph_cache.obj_x = *obj_x; \ | 8218 d->pixel_to_glyph_cache.obj_x = *obj_x; \ |
8219 d->pixel_to_glyph_cache.obj_y = *obj_y; \ | 8219 d->pixel_to_glyph_cache.obj_y = *obj_y; \ |
8220 d->pixel_to_glyph_cache.w = *w; \ | 8220 d->pixel_to_glyph_cache.w = *w; \ |
8221 d->pixel_to_glyph_cache.bufpos = *bufpos; \ | 8221 d->pixel_to_glyph_cache.charbpos = *charbpos; \ |
8222 d->pixel_to_glyph_cache.closest = *closest; \ | 8222 d->pixel_to_glyph_cache.closest = *closest; \ |
8223 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \ | 8223 d->pixel_to_glyph_cache.modeline_closest = *modeline_closest; \ |
8224 d->pixel_to_glyph_cache.obj1 = *obj1; \ | 8224 d->pixel_to_glyph_cache.obj1 = *obj1; \ |
8225 d->pixel_to_glyph_cache.obj2 = *obj2; \ | 8225 d->pixel_to_glyph_cache.obj2 = *obj2; \ |
8226 d->pixel_to_glyph_cache.retval = position; \ | 8226 d->pixel_to_glyph_cache.retval = position; \ |
8260 */ | 8260 */ |
8261 | 8261 |
8262 int | 8262 int |
8263 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord, | 8263 pixel_to_glyph_translation (struct frame *f, int x_coord, int y_coord, |
8264 int *col, int *row, int *obj_x, int *obj_y, | 8264 int *col, int *row, int *obj_x, int *obj_y, |
8265 struct window **w, Bufpos *bufpos, | 8265 struct window **w, Charbpos *charbpos, |
8266 Bufpos *closest, Charcount *modeline_closest, | 8266 Charbpos *closest, Charcount *modeline_closest, |
8267 Lisp_Object *obj1, Lisp_Object *obj2) | 8267 Lisp_Object *obj1, Lisp_Object *obj2) |
8268 { | 8268 { |
8269 struct device *d; | 8269 struct device *d; |
8270 struct pixel_to_glyph_translation_cache *cache; | 8270 struct pixel_to_glyph_translation_cache *cache; |
8271 Lisp_Object window; | 8271 Lisp_Object window; |
8299 *col = cache->col; | 8299 *col = cache->col; |
8300 *row = cache->row; | 8300 *row = cache->row; |
8301 *obj_x = cache->obj_x; | 8301 *obj_x = cache->obj_x; |
8302 *obj_y = cache->obj_y; | 8302 *obj_y = cache->obj_y; |
8303 *w = cache->w; | 8303 *w = cache->w; |
8304 *bufpos = cache->bufpos; | 8304 *charbpos = cache->charbpos; |
8305 *closest = cache->closest; | 8305 *closest = cache->closest; |
8306 *modeline_closest = cache->modeline_closest; | 8306 *modeline_closest = cache->modeline_closest; |
8307 *obj1 = cache->obj1; | 8307 *obj1 = cache->obj1; |
8308 *obj2 = cache->obj2; | 8308 *obj2 = cache->obj2; |
8309 | 8309 |
8314 *col = 0; | 8314 *col = 0; |
8315 *row = 0; | 8315 *row = 0; |
8316 *obj_x = 0; | 8316 *obj_x = 0; |
8317 *obj_y = 0; | 8317 *obj_y = 0; |
8318 *w = 0; | 8318 *w = 0; |
8319 *bufpos = 0; | 8319 *charbpos = 0; |
8320 *closest = 0; | 8320 *closest = 0; |
8321 *modeline_closest = -1; | 8321 *modeline_closest = -1; |
8322 *obj1 = Qnil; | 8322 *obj1 = Qnil; |
8323 *obj2 = Qnil; | 8323 *obj2 = Qnil; |
8324 | 8324 |
8541 if (Dynarr_length (db->runes)) | 8541 if (Dynarr_length (db->runes)) |
8542 { | 8542 { |
8543 if (x_check <= left_bound) | 8543 if (x_check <= left_bound) |
8544 { | 8544 { |
8545 if (dl->modeline) | 8545 if (dl->modeline) |
8546 *modeline_closest = Dynarr_atp (db->runes, 0)->bufpos; | 8546 *modeline_closest = Dynarr_atp (db->runes, 0)->charbpos; |
8547 else | 8547 else |
8548 *closest = Dynarr_atp (db->runes, 0)->bufpos; | 8548 *closest = Dynarr_atp (db->runes, 0)->charbpos; |
8549 } | 8549 } |
8550 else | 8550 else |
8551 { | 8551 { |
8552 if (dl->modeline) | 8552 if (dl->modeline) |
8553 *modeline_closest = | 8553 *modeline_closest = |
8554 Dynarr_atp (db->runes, | 8554 Dynarr_atp (db->runes, |
8555 Dynarr_length (db->runes) - 1)->bufpos; | 8555 Dynarr_length (db->runes) - 1)->charbpos; |
8556 else | 8556 else |
8557 *closest = | 8557 *closest = |
8558 Dynarr_atp (db->runes, | 8558 Dynarr_atp (db->runes, |
8559 Dynarr_length (db->runes) - 1)->bufpos; | 8559 Dynarr_length (db->runes) - 1)->charbpos; |
8560 } | 8560 } |
8561 | 8561 |
8562 if (dl->modeline) | 8562 if (dl->modeline) |
8563 *modeline_closest += dl->offset; | 8563 *modeline_closest += dl->offset; |
8564 else | 8564 else |
8609 { | 8609 { |
8610 (*col)--; | 8610 (*col)--; |
8611 rb = Dynarr_atp (db->runes, *col); | 8611 rb = Dynarr_atp (db->runes, *col); |
8612 } | 8612 } |
8613 | 8613 |
8614 *bufpos = rb->bufpos + dl->offset; | 8614 *charbpos = rb->charbpos + dl->offset; |
8615 low_x_coord = rb->xpos; | 8615 low_x_coord = rb->xpos; |
8616 high_x_coord = rb->xpos + rb->width; | 8616 high_x_coord = rb->xpos + rb->width; |
8617 | 8617 |
8618 if (rb->type == RUNE_DGLYPH) | 8618 if (rb->type == RUNE_DGLYPH) |
8619 { | 8619 { |
8624 { | 8624 { |
8625 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH) | 8625 if (Dynarr_atp (db->runes, elt)->type != RUNE_DGLYPH) |
8626 { | 8626 { |
8627 if (dl->modeline) | 8627 if (dl->modeline) |
8628 *modeline_closest = | 8628 *modeline_closest = |
8629 (Dynarr_atp (db->runes, elt)->bufpos + | 8629 (Dynarr_atp (db->runes, elt)->charbpos + |
8630 dl->offset); | 8630 dl->offset); |
8631 else | 8631 else |
8632 *closest = | 8632 *closest = |
8633 (Dynarr_atp (db->runes, elt)->bufpos + | 8633 (Dynarr_atp (db->runes, elt)->charbpos + |
8634 dl->offset); | 8634 dl->offset); |
8635 break; | 8635 break; |
8636 } | 8636 } |
8637 | 8637 |
8638 elt++; | 8638 elt++; |
8642 character so we return the last position | 8642 character so we return the last position |
8643 displayed on the line. */ | 8643 displayed on the line. */ |
8644 if (elt == Dynarr_length (db->runes)) | 8644 if (elt == Dynarr_length (db->runes)) |
8645 { | 8645 { |
8646 if (dl->modeline) | 8646 if (dl->modeline) |
8647 *modeline_closest = dl->end_bufpos + dl->offset; | 8647 *modeline_closest = dl->end_charbpos + dl->offset; |
8648 else | 8648 else |
8649 *closest = dl->end_bufpos + dl->offset; | 8649 *closest = dl->end_charbpos + dl->offset; |
8650 really_over_nothing = 1; | 8650 really_over_nothing = 1; |
8651 } | 8651 } |
8652 } | 8652 } |
8653 else | 8653 else |
8654 { | 8654 { |
8655 if (dl->modeline) | 8655 if (dl->modeline) |
8656 *modeline_closest = rb->bufpos + dl->offset; | 8656 *modeline_closest = rb->charbpos + dl->offset; |
8657 else | 8657 else |
8658 *closest = rb->bufpos + dl->offset; | 8658 *closest = rb->charbpos + dl->offset; |
8659 } | 8659 } |
8660 | 8660 |
8661 if (dl->modeline) | 8661 if (dl->modeline) |
8662 { | 8662 { |
8663 *row = window_displayed_height (*w); | 8663 *row = window_displayed_height (*w); |
9122 if (!initialized) | 9122 if (!initialized) |
9123 #endif | 9123 #endif |
9124 { | 9124 { |
9125 if (!cmotion_display_lines) | 9125 if (!cmotion_display_lines) |
9126 cmotion_display_lines = Dynarr_new (display_line); | 9126 cmotion_display_lines = Dynarr_new (display_line); |
9127 if (!mode_spec_bufbyte_string) | 9127 if (!mode_spec_intbyte_string) |
9128 mode_spec_bufbyte_string = Dynarr_new (Bufbyte); | 9128 mode_spec_intbyte_string = Dynarr_new (Intbyte); |
9129 if (!formatted_string_extent_dynarr) | 9129 if (!formatted_string_extent_dynarr) |
9130 formatted_string_extent_dynarr = Dynarr_new (EXTENT); | 9130 formatted_string_extent_dynarr = Dynarr_new (EXTENT); |
9131 if (!formatted_string_extent_start_dynarr) | 9131 if (!formatted_string_extent_start_dynarr) |
9132 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); | 9132 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); |
9133 if (!formatted_string_extent_end_dynarr) | 9133 if (!formatted_string_extent_end_dynarr) |