summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit6
-rw-r--r--src/alloc.c77
-rw-r--r--src/bignum.h12
-rw-r--r--src/buffer.c27
-rw-r--r--src/buffer.h4
-rw-r--r--src/bytecode.c2
-rw-r--r--src/character.h9
-rw-r--r--src/coding.c23
-rw-r--r--src/coding.h11
-rw-r--r--src/conf_post.h6
-rw-r--r--src/data.c46
-rw-r--r--src/dbusbind.c8
-rw-r--r--src/dispextern.h94
-rw-r--r--src/dispnew.c94
-rw-r--r--src/dynlib.h2
-rw-r--r--src/emacs-module.c38
-rw-r--r--src/emacs-module.h.in2
-rw-r--r--src/emacs.c3
-rw-r--r--src/eval.c50
-rw-r--r--src/fileio.c9
-rw-r--r--src/fns.c6
-rw-r--r--src/font.h4
-rw-r--r--src/frame.h2
-rw-r--r--src/ftcrfont.c417
-rw-r--r--src/ftfont.c255
-rw-r--r--src/ftfont.h18
-rw-r--r--src/ftxfont.c8
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/image.c825
-rw-r--r--src/indent.c7
-rw-r--r--src/insdel.c13
-rw-r--r--src/intervals.c39
-rw-r--r--src/json.c59
-rw-r--r--src/keyboard.c6
-rw-r--r--src/lisp.h7
-rw-r--r--src/lread.c148
-rw-r--r--src/macfont.m19
-rw-r--r--src/marker.c4
-rw-r--r--src/mini-gmp.c559
-rw-r--r--src/mini-gmp.h2
-rw-r--r--src/minibuf.c3
-rw-r--r--src/msdos.h2
-rw-r--r--src/nsfont.m2
-rw-r--r--src/nsgui.h62
-rw-r--r--src/nsimage.m4
-rw-r--r--src/nsmenu.m7
-rw-r--r--src/nsselect.m14
-rw-r--r--src/nsterm.h60
-rw-r--r--src/nsterm.m193
-rw-r--r--src/print.c40
-rw-r--r--src/search.c7
-rw-r--r--src/termhooks.h15
-rw-r--r--src/timefns.c5
-rw-r--r--src/w32.c11
-rw-r--r--src/w32fns.c27
-rw-r--r--src/w32font.c2
-rw-r--r--src/w32font.h2
-rw-r--r--src/w32gui.h43
-rw-r--r--src/w32term.c214
-rw-r--r--src/w32term.h53
-rw-r--r--src/window.c6
-rw-r--r--src/xdisp.c346
-rw-r--r--src/xfaces.c86
-rw-r--r--src/xfns.c8
-rw-r--r--src/xfont.c122
-rw-r--r--src/xftfont.c156
-rw-r--r--src/xterm.c467
-rw-r--r--src/xterm.h20
69 files changed, 2445 insertions, 2457 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index b8b303104f5..8c9a227ee33 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -1059,8 +1059,10 @@ end
define xprintsym
xsymname $arg0
xgetptr $symname
- set $sym_name = (struct Lisp_String *) $ptr
- xprintstr $sym_name
+ if $ptr != 0
+ set $sym_name = (struct Lisp_String *) $ptr
+ xprintstr $sym_name
+ end
end
document xprintsym
Print argument as a symbol.
diff --git a/src/alloc.c b/src/alloc.c
index 948a0e8a2dc..af4adb3856e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1447,9 +1447,7 @@ mark_interval_tree (INTERVAL i)
#define LARGE_STRING_BYTES 1024
-/* The SDATA typedef is a struct or union describing string memory
- sub-allocated from an sblock. This is where the contents of Lisp
- strings are stored. */
+/* The layout of a nonnull string. */
struct sdata
{
@@ -1468,13 +1466,8 @@ struct sdata
unsigned char data[FLEXIBLE_ARRAY_MEMBER];
};
-#ifdef GC_CHECK_STRING_BYTES
-
-typedef struct sdata sdata;
-#define SDATA_NBYTES(S) (S)->nbytes
-#define SDATA_DATA(S) (S)->data
-
-#else
+/* A union describing string memory sub-allocated from an sblock.
+ This is where the contents of Lisp strings are stored. */
typedef union
{
@@ -1502,8 +1495,6 @@ typedef union
#define SDATA_NBYTES(S) (S)->n.nbytes
#define SDATA_DATA(S) ((struct sdata *) (S))->data
-#endif /* not GC_CHECK_STRING_BYTES */
-
enum { SDATA_DATA_OFFSET = offsetof (struct sdata, data) };
/* Structure describing a block of memory which is sub-allocated to
@@ -1586,31 +1577,20 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
# define GC_STRING_OVERRUN_COOKIE_SIZE 0
#endif
-/* Value is the size of an sdata structure large enough to hold NBYTES
- bytes of string data. The value returned includes a terminating
- NUL byte, the size of the sdata structure, and padding. */
-
-#ifdef GC_CHECK_STRING_BYTES
-
-#define SDATA_SIZE(NBYTES) FLEXSIZEOF (struct sdata, data, (NBYTES) + 1)
+/* Return the size of an sdata structure large enough to hold N bytes
+ of string data. This counts the sdata structure, the N bytes, a
+ terminating NUL byte, and alignment padding. */
-#else /* not GC_CHECK_STRING_BYTES */
-
-/* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is
- less than the size of that member. The 'max' is not needed when
- SDATA_DATA_OFFSET is a multiple of FLEXALIGNOF (struct sdata),
- because then the alignment code reserves enough space. */
-
-#define SDATA_SIZE(NBYTES) \
- ((SDATA_DATA_OFFSET \
- + (SDATA_DATA_OFFSET % FLEXALIGNOF (struct sdata) == 0 \
- ? NBYTES \
- : max (NBYTES, FLEXALIGNOF (struct sdata) - 1)) \
- + 1 \
- + FLEXALIGNOF (struct sdata) - 1) \
- & ~(FLEXALIGNOF (struct sdata) - 1))
-
-#endif /* not GC_CHECK_STRING_BYTES */
+static ptrdiff_t
+sdata_size (ptrdiff_t n)
+{
+ /* Reserve space for the nbytes union member even when N + 1 is less
+ than the size of that member. */
+ ptrdiff_t unaligned_size = max (SDATA_DATA_OFFSET + n + 1,
+ sizeof (sdata));
+ int sdata_align = max (FLEXALIGNOF (struct sdata), alignof (sdata));
+ return (unaligned_size + sdata_align - 1) & ~(sdata_align - 1);
+}
/* Extra bytes to allocate for each string. */
#define GC_STRING_EXTRA GC_STRING_OVERRUN_COOKIE_SIZE
@@ -1664,21 +1644,14 @@ string_bytes (struct Lisp_String *s)
static void
check_sblock (struct sblock *b)
{
- sdata *from, *end, *from_end;
-
- end = b->next_free;
+ sdata *end = b->next_free;
- for (from = b->data; from < end; from = from_end)
+ for (sdata *from = b->data; from < end; )
{
- /* Compute the next FROM here because copying below may
- overwrite data we need to compute it. */
- ptrdiff_t nbytes;
-
- /* Check that the string size recorded in the string is the
- same as the one recorded in the sdata structure. */
- nbytes = SDATA_SIZE (from->string ? string_bytes (from->string)
- : SDATA_NBYTES (from));
- from_end = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA);
+ ptrdiff_t nbytes = sdata_size (from->string
+ ? string_bytes (from->string)
+ : SDATA_NBYTES (from));
+ from = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA);
}
}
@@ -1810,14 +1783,14 @@ allocate_string_data (struct Lisp_String *s,
{
sdata *data, *old_data;
struct sblock *b;
- ptrdiff_t needed, old_nbytes;
+ ptrdiff_t old_nbytes;
if (STRING_BYTES_MAX < nbytes)
string_overflow ();
/* Determine the number of bytes needed to store NBYTES bytes
of string data. */
- needed = SDATA_SIZE (nbytes);
+ ptrdiff_t needed = sdata_size (nbytes);
if (s->u.s.data)
{
old_data = SDATA_OF_STRING (s);
@@ -2068,7 +2041,7 @@ compact_small_strings (void)
nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from);
eassert (nbytes <= LARGE_STRING_BYTES);
- ptrdiff_t size = SDATA_SIZE (nbytes);
+ ptrdiff_t size = sdata_size (nbytes);
sdata *from_end = (sdata *) ((char *) from
+ size + GC_STRING_EXTRA);
diff --git a/src/bignum.h b/src/bignum.h
index 4c670bd906f..743a18fc0f7 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -94,6 +94,18 @@ bignum_integer (mpz_t *tmp, Lisp_Object i)
return &XBIGNUM (i)->value;
}
+/* Set RESULT to the value stored in the Lisp integer I. If I is a
+ big integer, copy it to RESULT. RESULT must already be
+ initialized. */
+INLINE void
+mpz_set_integer (mpz_t result, Lisp_Object i)
+{
+ if (FIXNUMP (i))
+ mpz_set_intmax (result, XFIXNUM (i));
+ else
+ mpz_set (result, XBIGNUM (i)->value);
+}
+
INLINE_HEADER_END
#endif /* BIGNUM_H */
diff --git a/src/buffer.c b/src/buffer.c
index ab477481912..209e29f0f19 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2264,7 +2264,7 @@ validate_region (register Lisp_Object *b, register Lisp_Object *e)
/* Advance BYTE_POS up to a character boundary
and return the adjusted position. */
-static ptrdiff_t
+ptrdiff_t
advance_to_char_boundary (ptrdiff_t byte_pos)
{
int c;
@@ -2702,6 +2702,9 @@ current buffer is cleared. */)
/* Do this last, so it can calculate the new correspondences
between chars and bytes. */
+ /* FIXME: Is it worth the trouble, really? Couldn't we just throw
+ away all the text-properties instead of trying to guess how
+ to adjust them? AFAICT the result is not reliable anyway. */
set_intervals_multibyte (1);
}
@@ -5600,17 +5603,17 @@ Use the command `abbrev-mode' to change this variable. */);
doc: /* Non-nil if searches and matches should ignore case. */);
DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
- Qfixnump,
+ Qintegerp,
doc: /* Column beyond which automatic line-wrapping should happen.
Interactively, you can set the buffer local value using \\[set-fill-column]. */);
DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin),
- Qfixnump,
+ Qintegerp,
doc: /* Column for the default `indent-line-function' to indent to.
Linefeed indents to this column in Fundamental mode. */);
DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
- Qfixnump,
+ Qintegerp,
doc: /* Distance between tab stops (for display of tab characters), in columns.
NOTE: This controls the display width of a TAB character, and not
the size of an indentation step.
@@ -5781,7 +5784,7 @@ If it is nil, that means don't auto-save this buffer. */);
Backing up is done before the first time the file is saved. */);
DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length),
- Qfixnump,
+ Qintegerp,
doc: /* Length of current buffer when last read in, saved or auto-saved.
0 initially.
-1 means auto-saving turned off until next real save.
@@ -5855,7 +5858,7 @@ In addition, a char-table has six extra slots to control the display of:
See also the functions `display-table-slot' and `set-display-table-slot'. */);
DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
- Qfixnump,
+ Qintegerp,
doc: /* Width in columns of left marginal area for display of a buffer.
A value of nil means no marginal area.
@@ -5863,7 +5866,7 @@ Setting this variable does not take effect until a new buffer is displayed
in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
- Qfixnump,
+ Qintegerp,
doc: /* Width in columns of right marginal area for display of a buffer.
A value of nil means no marginal area.
@@ -5871,7 +5874,7 @@ Setting this variable does not take effect until a new buffer is displayed
in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
- Qfixnump,
+ Qintegerp,
doc: /* Width of this buffer's left fringe (in pixels).
A value of 0 means no left fringe is shown in this buffer's window.
A value of nil means to use the left fringe width from the window's frame.
@@ -5880,7 +5883,7 @@ Setting this variable does not take effect until a new buffer is displayed
in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
- Qfixnump,
+ Qintegerp,
doc: /* Width of this buffer's right fringe (in pixels).
A value of 0 means no right fringe is shown in this buffer's window.
A value of nil means to use the right fringe width from the window's frame.
@@ -5897,12 +5900,12 @@ Setting this variable does not take effect until a new buffer is displayed
in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
- Qfixnump,
+ Qintegerp,
doc: /* Width of this buffer's vertical scroll bars in pixels.
A value of nil means to use the scroll bar width from the window's frame. */);
DEFVAR_PER_BUFFER ("scroll-bar-height", &BVAR (current_buffer, scroll_bar_height),
- Qfixnump,
+ Qintegerp,
doc: /* Height of this buffer's horizontal scroll bars in pixels.
A value of nil means to use the scroll bar height from the window's frame. */);
@@ -6172,7 +6175,7 @@ Setting this variable is very fast, much faster than scanning all the text in
the buffer looking for properties to change. */);
DEFVAR_PER_BUFFER ("buffer-display-count",
- &BVAR (current_buffer, display_count), Qfixnump,
+ &BVAR (current_buffer, display_count), Qintegerp,
doc: /* A number incremented each time this buffer is displayed in a window.
The function `set-window-buffer' increments it. */);
diff --git a/src/buffer.h b/src/buffer.h
index f42c3e97b97..2080a6f40b7 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -327,6 +327,10 @@ extern void enlarge_buffer_text (struct buffer *, ptrdiff_t);
#define BYTE_TO_CHAR(bytepos) \
(buf_bytepos_to_charpos (current_buffer, bytepos))
+/* For those very rare cases where you may have a "random" pointer into
+ the middle of a multibyte char, this moves to the next boundary. */
+extern ptrdiff_t advance_to_char_boundary (ptrdiff_t byte_pos);
+
/* Convert PTR, the address of a byte in the buffer, into a byte position. */
#define PTR_BYTE_POS(ptr) \
diff --git a/src/bytecode.c b/src/bytecode.c
index 40977799bfc..6f601cf0cd5 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -562,7 +562,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
/* Inline the most common case. */
if (SYMBOLP (sym)
&& !EQ (val, Qunbound)
- && !XSYMBOL (sym)->u.s.redirect
+ && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL
&& !SYMBOL_TRAPPED_WRITE_P (sym))
SET_SYMBOL_VAL (XSYMBOL (sym), val);
else
diff --git a/src/character.h b/src/character.h
index 5dff85aed47..cc57a2a7d5c 100644
--- a/src/character.h
+++ b/src/character.h
@@ -558,12 +558,13 @@ enum
/* Return a non-outlandish value for the tab width. */
-#define SANE_TAB_WIDTH(buf) \
- sanitize_tab_width (XFIXNAT (BVAR (buf, tab_width)))
+#define SANE_TAB_WIDTH(buf) sanitize_tab_width (BVAR (buf, tab_width))
+
INLINE int
-sanitize_tab_width (EMACS_INT width)
+sanitize_tab_width (Lisp_Object width)
{
- return 0 < width && width <= 1000 ? width : 8;
+ return (FIXNUMP (width) && 0 < XFIXNUM (width) && XFIXNUM (width) <= 1000
+ ? XFIXNUM (width) : 8);
}
/* Return the width of ASCII character C. The width is measured by
diff --git a/src/coding.c b/src/coding.c
index 2c6b2c4d051..9cba6494a8d 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -6353,6 +6353,29 @@ utf8_string_p (Lisp_Object string)
return check_utf_8 (&coding) != -1;
}
+/* Like make_string, but always returns a multibyte Lisp string, and
+ avoids decoding if TEXT encoded in UTF-8. */
+
+Lisp_Object
+make_string_from_utf8 (const char *text, ptrdiff_t nbytes)
+{
+ ptrdiff_t chars, bytes;
+ parse_str_as_multibyte ((const unsigned char *) text, nbytes,
+ &chars, &bytes);
+ /* If TEXT is a valid UTF-8 string, we can convert it to a Lisp
+ string directly. Otherwise, we need to decode it. */
+ if (chars == nbytes || bytes == nbytes)
+ return make_specified_string (text, chars, nbytes, true);
+ else
+ {
+ struct coding_system coding;
+ setup_coding_system (Qutf_8_unix, &coding);
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ coding.source = (const unsigned char *) text;
+ decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
+ return coding.dst_object;
+ }
+}
/* Detect how end-of-line of a text of length SRC_BYTES pointed by
SOURCE is encoded. If CATEGORY is one of
diff --git a/src/coding.h b/src/coding.h
index 0c03d1a44ed..619ca29c8e4 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -695,6 +695,7 @@ extern Lisp_Object raw_text_coding_system (Lisp_Object);
extern bool raw_text_coding_system_p (struct coding_system *);
extern Lisp_Object coding_inherit_eol_type (Lisp_Object, Lisp_Object);
extern Lisp_Object complement_process_encoding_system (Lisp_Object);
+extern Lisp_Object make_string_from_utf8 (const char *, ptrdiff_t);
extern void decode_coding_gap (struct coding_system *,
ptrdiff_t, ptrdiff_t);
@@ -762,6 +763,16 @@ surrogates_to_codepoint (int low, int high)
return 0x10000 + (low - 0xDC00) + ((high - 0xD800) * 0x400);
}
+/* Like build_string, but always returns a multibyte string, and is
+ optimized for speed when STR is a UTF-8 encoded text string. */
+
+INLINE Lisp_Object
+build_string_from_utf8 (const char *str)
+{
+ return make_string_from_utf8 (str, strlen (str));
+}
+
+
extern Lisp_Object preferred_coding_system (void);
/* Coding system to be used to encode text for terminal display when
diff --git a/src/conf_post.h b/src/conf_post.h
index 7699d2c95bc..4af1ba9331f 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -59,7 +59,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
into the same 1-, 2-, or 4-byte allocation unit in the MinGW
builds. It was also needed to port to pre-C99 compilers, although
we don't care about that any more. */
-#if NS_IMPL_GNUSTEP || defined(__MINGW32__)
+#if NS_IMPL_GNUSTEP || defined __MINGW32__
typedef unsigned int bool_bf;
#else
typedef bool bool_bf;
@@ -225,7 +225,9 @@ extern void _DebPrint (const char *fmt, ...);
extern char *emacs_getenv_TZ (void);
extern int emacs_setenv_TZ (char const *);
-#if __has_attribute (cold)
+/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at
+ <https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>. */
+#if __has_attribute (cold) && !defined __MINGW32__
# define ATTRIBUTE_COLD __attribute__ ((cold))
#else
# define ATTRIBUTE_COLD
diff --git a/src/data.c b/src/data.c
index 7928a1dc41d..c1699aeae73 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1122,20 +1122,21 @@ store_symval_forwarding (lispfwd valcontents, Lisp_Object newval,
int offset = XBUFFER_OBJFWD (valcontents)->offset;
Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate;
- if (!NILP (newval))
+ if (!NILP (newval) && !NILP (predicate))
{
- if (SYMBOLP (predicate))
+ eassert (SYMBOLP (predicate));
+ Lisp_Object choiceprop = Fget (predicate, Qchoice);
+ if (!NILP (choiceprop))
{
- Lisp_Object prop;
-
- if ((prop = Fget (predicate, Qchoice), !NILP (prop)))
- {
- if (NILP (Fmemq (newval, prop)))
- wrong_choice (prop, newval);
- }
- else if ((prop = Fget (predicate, Qrange), !NILP (prop)))
+ if (NILP (Fmemq (newval, choiceprop)))
+ wrong_choice (choiceprop, newval);
+ }
+ else
+ {
+ Lisp_Object rangeprop = Fget (predicate, Qrange);
+ if (CONSP (rangeprop))
{
- Lisp_Object min = XCAR (prop), max = XCDR (prop);
+ Lisp_Object min = XCAR (rangeprop), max = XCDR (rangeprop);
if (! NUMBERP (newval)
|| NILP (CALLN (Fleq, min, newval, max)))
wrong_range (min, max, newval);
@@ -1301,15 +1302,13 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
enum Set_Internal_Bind bindflag)
{
bool voide = EQ (newval, Qunbound);
- struct Lisp_Symbol *sym;
- Lisp_Object tem1;
/* If restoring in a dead buffer, do nothing. */
/* if (BUFFERP (where) && NILP (XBUFFER (where)->name))
return; */
CHECK_SYMBOL (symbol);
- sym = XSYMBOL (symbol);
+ struct Lisp_Symbol *sym = XSYMBOL (symbol);
switch (sym->u.s.trapped_write)
{
case SYMBOL_NOWRITE:
@@ -1328,9 +1327,10 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
bindflag == SET_INTERNAL_UNBIND? Qunlet :
voide? Qmakunbound : Qset),
where);
- /* FALLTHROUGH! */
+ break;
+
case SYMBOL_UNTRAPPED_WRITE:
- break;
+ break;
default: emacs_abort ();
}
@@ -1363,8 +1363,9 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
/* Find the new binding. */
XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */
- tem1 = assq_no_quit (symbol,
- BVAR (XBUFFER (where), local_var_alist));
+ Lisp_Object tem1
+ = assq_no_quit (symbol,
+ BVAR (XBUFFER (where), local_var_alist));
set_blv_where (blv, where);
blv->found = true;
@@ -1649,10 +1650,8 @@ void
set_default_internal (Lisp_Object symbol, Lisp_Object value,
enum Set_Internal_Bind bindflag)
{
- struct Lisp_Symbol *sym;
-
CHECK_SYMBOL (symbol);
- sym = XSYMBOL (symbol);
+ struct Lisp_Symbol *sym = XSYMBOL (symbol);
switch (sym->u.s.trapped_write)
{
case SYMBOL_NOWRITE:
@@ -1669,9 +1668,10 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
/* Setting due to thread switching doesn't count. */
&& bindflag != SET_INTERNAL_THREAD_SWITCH)
notify_variable_watchers (symbol, value, Qset_default, Qnil);
- /* FALLTHROUGH! */
+ break;
+
case SYMBOL_UNTRAPPED_WRITE:
- break;
+ break;
default: emacs_abort ();
}
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 0afae6b05ad..850d176c08f 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -346,7 +346,6 @@ xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
int subtype;
Lisp_Object elt;
char const *subsig;
- int subsiglen;
char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
elt = object;
@@ -430,10 +429,9 @@ xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
}
- subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
- "%c%s", dtype, subsig);
- if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH))
- string_overflow ();
+ signature[0] = dtype;
+ signature[1] = '\0';
+ xd_signature_cat (signature, subsig);
break;
case DBUS_TYPE_VARIANT:
diff --git a/src/dispextern.h b/src/dispextern.h
index 4d6d0371d38..ec1c9620be4 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -34,16 +34,45 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifdef HAVE_XRENDER
# include <X11/extensions/Xrender.h>
#endif
+
+typedef XColor Emacs_Color;
+typedef Cursor Emacs_Cursor;
+#define No_Cursor (None)
+typedef Pixmap Emacs_Pixmap;
+typedef XRectangle Emacs_Rectangle;
+typedef XGCValues Emacs_GC;
#else /* !HAVE_X_WINDOWS */
-/* X-related stuff used by non-X gui code. */
+/* XColor-like struct used by non-X code. */
-typedef struct {
+typedef struct
+{
unsigned long pixel;
unsigned short red, green, blue;
- char flags;
- char pad;
-} XColor;
+} Emacs_Color;
+
+/* Accommodate X's usage of None as a null resource ID. */
+#define No_Cursor (NULL)
+
+/* XRectangle-like struct used by non-X GUI code. */
+typedef struct
+{
+ int x, y;
+ unsigned width, height;
+} Emacs_Rectangle;
+
+/* XGCValues-like struct used by non-X GUI code. */
+typedef struct
+{
+ unsigned long foreground;
+ unsigned long background;
+} Emacs_GC;
+
+/* Mask values to select foreground/background. */
+/* FIXME: The GC handling in w32 really should be redesigned as to not
+ need these. */
+#define GCForeground 0x01
+#define GCBackground 0x02
#endif /* HAVE_X_WINDOWS */
@@ -63,16 +92,16 @@ xstrcasecmp (char const *a, char const *b)
#ifdef HAVE_X_WINDOWS
#include <X11/Xresource.h> /* for XrmDatabase */
typedef struct x_display_info Display_Info;
-typedef XImage * XImagePtr;
-typedef XImagePtr XImagePtr_or_DC;
+typedef XImage *Emacs_Pix_Container;
+typedef XImage *Emacs_Pix_Context;
#define NativeRectangle XRectangle
#endif
#ifdef HAVE_NTGUI
#include "w32gui.h"
typedef struct w32_display_info Display_Info;
-typedef XImage *XImagePtr;
-typedef HDC XImagePtr_or_DC;
+typedef XImage *Emacs_Pix_Container;
+typedef HDC Emacs_Pix_Context;
#endif
#ifdef HAVE_NS
@@ -80,8 +109,8 @@ typedef HDC XImagePtr_or_DC;
#define FACE_COLOR_TO_PIXEL(face_color, frame) ns_color_index_to_rgba(face_color, frame)
/* Following typedef needed to accommodate the MSDOS port, believe it or not. */
typedef struct ns_display_info Display_Info;
-typedef Pixmap XImagePtr;
-typedef XImagePtr XImagePtr_or_DC;
+typedef Emacs_Pixmap Emacs_Pix_Container;
+typedef Emacs_Pixmap Emacs_Pix_Context;
#else
#define FACE_COLOR_TO_PIXEL(face_color, frame) face_color
#endif
@@ -92,8 +121,7 @@ typedef XImagePtr XImagePtr_or_DC;
#endif
#ifndef HAVE_WINDOW_SYSTEM
-typedef int Cursor;
-#define No_Cursor (0)
+typedef void *Emacs_Cursor;
#endif
#ifndef NativeRectangle
@@ -1040,7 +1068,7 @@ struct glyph_row
#ifdef HAVE_WINDOW_SYSTEM
/* Non-NULL means the current clipping area. This is temporarily
set while exposing a region. Coordinates are frame-relative. */
- XRectangle *clip;
+ const Emacs_Rectangle *clip;
#endif
};
@@ -1281,9 +1309,6 @@ struct glyph_string
/* The window on which the glyph string is drawn. */
struct window *w;
- /* X display and window for convenience. */
- Display *display;
-
/* The glyph row for which this string was built. It determines the
y-origin and height of the string. */
struct glyph_row *row;
@@ -1292,7 +1317,7 @@ struct glyph_string
enum glyph_row_area area;
/* Characters to be drawn, and number of characters. */
- XChar2b *char2b;
+ unsigned *char2b;
int nchars;
/* A face-override for drawing cursors, mouse face and similar. */
@@ -1353,7 +1378,7 @@ struct glyph_string
GC gc;
#endif
#if defined (HAVE_NTGUI)
- XGCValues *gc;
+ Emacs_GC *gc;
HDC hdc;
#endif
@@ -1595,8 +1620,11 @@ struct face
/* If non-zero, this is a GC that we can use without modification for
drawing the characters in this face. */
+# ifdef HAVE_X_WINDOWS
GC gc;
-
+# else
+ Emacs_GC *gc;
+# endif
/* Background stipple or bitmap used for this face. This is
an id as returned from load_pixmap. */
ptrdiff_t stipple;
@@ -2891,7 +2919,7 @@ struct redisplay_interface
void (*draw_glyph_string) (struct glyph_string *s);
/* Define cursor CURSOR on frame F. */
- void (*define_frame_cursor) (struct frame *f, Cursor cursor);
+ void (*define_frame_cursor) (struct frame *f, Emacs_Cursor cursor);
/* Clear the area at (X,Y,WIDTH,HEIGHT) of frame F. */
void (*clear_frame_area) (struct frame *f, int x, int y,
@@ -2958,7 +2986,7 @@ struct image
struct timespec timestamp;
/* Pixmaps of the image. */
- Pixmap pixmap, mask;
+ Emacs_Pixmap pixmap, mask;
#ifdef USE_CAIRO
void *cr_data;
@@ -2968,7 +2996,7 @@ struct image
Non-NULL means it and its Pixmap counterpart may be out of sync
and the latter is outdated. NULL means the X image has been
synchronized to Pixmap. */
- XImagePtr ximg, mask_img;
+ XImage *ximg, *mask_img;
# ifdef HAVE_NATIVE_SCALING
/* Picture versions of pixmap and mask for compositing. */
@@ -3039,7 +3067,7 @@ struct image
int hmargin, vmargin;
/* Reference to the type of the image. */
- struct image_type *type;
+ struct image_type const *type;
/* True means that loading the image failed. Don't try again. */
bool load_failed_p;
@@ -3314,7 +3342,9 @@ extern void handle_tool_bar_click (struct frame *,
int, int, bool, int);
extern void expose_frame (struct frame *, int, int, int, int);
-extern bool gui_intersect_rectangles (XRectangle *, XRectangle *, XRectangle *);
+extern bool gui_intersect_rectangles (const Emacs_Rectangle *,
+ const Emacs_Rectangle *,
+ Emacs_Rectangle *);
#endif /* HAVE_WINDOW_SYSTEM */
extern void note_mouse_highlight (struct frame *, int, int);
@@ -3369,7 +3399,7 @@ extern void x_create_bitmap_mask (struct frame *, ptrdiff_t);
#endif
extern Lisp_Object image_find_image_file (Lisp_Object);
-void x_kill_gs_process (Pixmap, struct frame *);
+void x_kill_gs_process (Emacs_Pixmap, struct frame *);
struct image_cache *make_image_cache (void);
void free_image_cache (struct frame *);
void clear_image_caches (Lisp_Object);
@@ -3387,9 +3417,9 @@ ptrdiff_t lookup_image (struct frame *, Lisp_Object);
#endif
RGB_PIXEL_COLOR image_background (struct image *, struct frame *,
- XImagePtr_or_DC ximg);
+ Emacs_Pix_Context img);
int image_background_transparent (struct image *, struct frame *,
- XImagePtr_or_DC mask);
+ Emacs_Pix_Context mask);
int image_ascent (struct image *, struct face *, struct glyph_slice *);
@@ -3413,8 +3443,8 @@ void x_free_colors (struct frame *, unsigned long *, int);
void update_face_from_frame_parameter (struct frame *, Lisp_Object,
Lisp_Object);
-extern bool tty_defined_color (struct frame *f, const char *, XColor *, bool,
- bool);
+extern bool tty_defined_color (struct frame *, const char *, Emacs_Color *,
+ bool, bool);
Lisp_Object tty_color_name (struct frame *, int);
void clear_face_cache (bool);
@@ -3521,6 +3551,10 @@ void clear_glyph_matrix_rows (struct glyph_matrix *, int, int);
void clear_glyph_row (struct glyph_row *);
void prepare_desired_row (struct window *, struct glyph_row *, bool);
void update_single_window (struct window *);
+#ifdef HAVE_WINDOW_SYSTEM
+extern void gui_update_window_begin (struct window *);
+extern void gui_update_window_end (struct window *, bool, bool);
+#endif
void do_pending_window_change (bool);
void change_frame_size (struct frame *, int, int, bool, bool, bool, bool);
void init_display (void);
diff --git a/src/dispnew.c b/src/dispnew.c
index 25a2d1cd38b..52a7b6d6ee0 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3390,7 +3390,9 @@ update_window (struct window *w, bool force_p)
struct glyph_matrix *desired_matrix = w->desired_matrix;
bool paused_p;
int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
+#ifdef HAVE_WINDOW_SYSTEM
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+#endif
#ifdef GLYPH_DEBUG
/* Check that W's frame doesn't have glyph matrices. */
eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
@@ -3411,7 +3413,9 @@ update_window (struct window *w, bool force_p)
bool changed_p = 0, mouse_face_overwritten_p = 0;
int n_updated = 0;
- rif->update_window_begin_hook (w);
+#ifdef HAVE_WINDOW_SYSTEM
+ gui_update_window_begin (w);
+#endif
yb = window_text_bottom_y (w);
row = MATRIX_ROW (desired_matrix, 0);
end = MATRIX_MODE_LINE_ROW (desired_matrix);
@@ -3533,13 +3537,13 @@ update_window (struct window *w, bool force_p)
#ifdef HAVE_WINDOW_SYSTEM
update_window_fringes (w, 0);
-#endif
/* End the update of window W. Don't set the cursor if we
paused updating the display because in this case,
set_window_cursor_after_update hasn't been called, and
W->output_cursor doesn't contain the cursor location. */
- rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
+ gui_update_window_end (w, !paused_p, mouse_face_overwritten_p);
+#endif
}
else
paused_p = 1;
@@ -3555,6 +3559,90 @@ update_window (struct window *w, bool force_p)
return paused_p;
}
+#ifdef HAVE_WINDOW_SYSTEM
+
+/* Start update of window W. */
+
+void
+gui_update_window_begin (struct window *w)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+ block_input ();
+
+ if (FRAME_RIF (f)->update_window_begin_hook)
+ FRAME_RIF (f)->update_window_begin_hook (w);
+
+ w->output_cursor = w->cursor;
+
+ if (f == hlinfo->mouse_face_mouse_frame)
+ {
+ /* Don't do highlighting for mouse motion during the update. */
+ hlinfo->mouse_face_defer = true;
+
+ /* If the frame needs to be redrawn, simply forget about any
+ prior mouse highlighting. */
+ if (FRAME_GARBAGED_P (f))
+ hlinfo->mouse_face_window = Qnil;
+ }
+
+ unblock_input ();
+}
+
+/* End update of window W.
+
+ Draw vertical borders between horizontally adjacent windows, and
+ display W's cursor if CURSOR_ON_P is non-zero.
+
+ MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
+ glyphs in mouse-face were overwritten. In that case we have to
+ make sure that the mouse-highlight is properly redrawn. */
+void
+gui_update_window_end (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
+ block_input ();
+
+ /* Pseudo windows don't have cursors, so don't display them here. */
+ if (!w->pseudo_window_p)
+ {
+
+ if (cursor_on_p)
+ display_and_set_cursor (w, true,
+ w->output_cursor.hpos, w->output_cursor.vpos,
+ w->output_cursor.x, w->output_cursor.y);
+
+ if (draw_window_fringes (w, true))
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ gui_draw_right_divider (w);
+ else
+ gui_draw_vertical_border (w);
+ }
+ }
+
+ /* If a row with mouse-face was overwritten, arrange for
+ frame_up_to_date_hook to redisplay the mouse highlight. */
+ if (mouse_face_overwritten_p)
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+ hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+ hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+ hlinfo->mouse_face_window = Qnil;
+ }
+
+ if (FRAME_RIF (f)->update_window_end_hook)
+ FRAME_RIF (f)->update_window_end_hook (w,
+ cursor_on_p,
+ mouse_face_overwritten_p);
+ unblock_input ();
+}
+
+#endif /* HAVE_WINDOW_SYSTEM */
/* Update the display of area AREA in window W, row number VPOS.
AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
diff --git a/src/dynlib.h b/src/dynlib.h
index 2688712a13e..43a0e045f5b 100644
--- a/src/dynlib.h
+++ b/src/dynlib.h
@@ -29,7 +29,7 @@ const char *dynlib_error (void);
ATTRIBUTE_MAY_ALIAS void *dynlib_sym (dynlib_handle_ptr h, const char *sym);
-typedef struct dynlib_function_ptr_nonce *(ATTRIBUTE_MAY_ALIAS *dynlib_function_ptr) (void);
+typedef void (ATTRIBUTE_MAY_ALIAS *dynlib_function_ptr) (void);
dynlib_function_ptr dynlib_func (dynlib_handle_ptr h, const char *sym);
/* Sets *FILE to the file name from which PTR was loaded, and *SYM to
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 80a04bafc2d..907a5d8225a 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -101,11 +101,6 @@ To add a new module function, proceed as follows:
# pragma GCC diagnostic ignored "-Wclobbered"
#endif
-/* This module is lackadaisical about function casts. */
-#if GNUC_PREREQ (8, 0, 0)
-# pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-
/* We use different strategies for allocating the user-visible objects
(struct emacs_runtime, emacs_env, emacs_value), depending on
whether the user supplied the -module-assertions flag. If
@@ -223,8 +218,6 @@ static void module_reset_handlerlist (struct handler **);
static bool value_storage_contains_p (const struct emacs_value_storage *,
emacs_value, ptrdiff_t *);
static Lisp_Object module_encode (Lisp_Object);
-static Lisp_Object module_decode (Lisp_Object);
-static Lisp_Object module_decode_copy (Lisp_Object);
static bool module_assertions = false;
@@ -532,10 +525,7 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
function->data = data;
if (documentation)
- {
- AUTO_STRING (unibyte_doc, documentation);
- function->documentation = module_decode_copy (unibyte_doc);
- }
+ function->documentation = build_string_from_utf8 (documentation);
Lisp_Object result;
XSET_MODULE_FUNCTION (result, function);
@@ -668,8 +658,8 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
MODULE_FUNCTION_BEGIN (NULL);
if (! (0 <= length && length <= STRING_BYTES_BOUND))
overflow_error ();
- Lisp_Object lstr = make_unibyte_string (str, length);
- return lisp_to_value (env, module_decode (lstr));
+ Lisp_Object lstr = make_string_from_utf8 (str, length);
+ return lisp_to_value (env, lstr);
}
static emacs_value
@@ -790,10 +780,7 @@ module_extract_big_integer (emacs_env *env, emacs_value value,
MODULE_FUNCTION_BEGIN ();
Lisp_Object o = value_to_lisp (value);
CHECK_INTEGER (o);
- if (FIXNUMP (o))
- mpz_set_intmax (result->value, XFIXNUM (o));
- else
- mpz_set (result->value, XBIGNUM (o)->value);
+ mpz_set_integer (result->value, o);
}
static emacs_value
@@ -907,6 +894,11 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist)
memory_full (sizeof *args[i]);
}
+ /* The only possibility of getting an error until here is failure to
+ allocate memory for the arguments, but then we already should
+ have signaled an error before. */
+ eassert (priv.pending_non_local_exit == emacs_funcall_exit_return);
+
emacs_value ret = func->subr (env, nargs, args, func->data);
eassert (&priv == env->private_members);
@@ -1030,18 +1022,6 @@ module_encode (Lisp_Object string)
return code_convert_string (string, Qutf_8_unix, Qt, true, true, true);
}
-static Lisp_Object
-module_decode (Lisp_Object string)
-{
- return code_convert_string (string, Qutf_8_unix, Qt, false, true, true);
-}
-
-static Lisp_Object
-module_decode_copy (Lisp_Object string)
-{
- return code_convert_string (string, Qutf_8_unix, Qt, false, false, true);
-}
-
/* Value conversion. */
diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in
index fbc62a61ef4..9955e30eb7a 100644
--- a/src/emacs-module.h.in
+++ b/src/emacs-module.h.in
@@ -32,6 +32,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <gmp.h>
#endif
+#define EMACS_MAJOR_VERSION @emacs_major_version@
+
#if defined __cplusplus && __cplusplus >= 201103L
# define EMACS_NOEXCEPT noexcept
#else
diff --git a/src/emacs.c b/src/emacs.c
index 86d2bc65ac7..fd46540ce22 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2494,9 +2494,6 @@ You must run Emacs in batch mode in order to dump it. */)
# ifdef WINDOWSNT
Vlibrary_cache = Qnil;
# endif
-# ifdef HAVE_WINDOW_SYSTEM
- reset_image_types ();
-# endif
Vpurify_flag = tem;
diff --git a/src/eval.c b/src/eval.c
index 3fd9a40a3a2..567c32e0d75 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -715,6 +715,25 @@ DEFUN ("set-default-toplevel-value", Fset_default_toplevel_value,
return Qnil;
}
+DEFUN ("internal--define-uninitialized-variable",
+ Finternal__define_uninitialized_variable,
+ Sinternal__define_uninitialized_variable, 1, 2, 0,
+ doc: /* Define SYMBOL as a variable, with DOC as its docstring.
+This is like `defvar' and `defconst' but without affecting the variable's
+value. */)
+ (Lisp_Object symbol, Lisp_Object doc)
+{
+ XSYMBOL (symbol)->u.s.declared_special = true;
+ if (!NILP (doc))
+ {
+ if (!NILP (Vpurify_flag))
+ doc = Fpurecopy (doc);
+ Fput (symbol, Qvariable_documentation, doc);
+ }
+ LOADHIST_ATTACH (symbol);
+ return Qnil;
+}
+
DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0,
doc: /* Define SYMBOL as a variable, and return SYMBOL.
You are not required to define a variable in order to use it, but
@@ -754,32 +773,25 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
{
if (!NILP (XCDR (tail)) && !NILP (XCDR (XCDR (tail))))
error ("Too many arguments");
+ Lisp_Object exp = XCAR (tail);
tem = Fdefault_boundp (sym);
+ tail = XCDR (tail);
/* Do it before evaluating the initial value, for self-references. */
- XSYMBOL (sym)->u.s.declared_special = true;
+ Finternal__define_uninitialized_variable (sym, CAR (tail));
if (NILP (tem))
- Fset_default (sym, eval_sub (XCAR (tail)));
+ Fset_default (sym, eval_sub (exp));
else
{ /* Check if there is really a global binding rather than just a let
binding that shadows the global unboundness of the var. */
union specbinding *binding = default_toplevel_binding (sym);
if (binding && EQ (specpdl_old_value (binding), Qunbound))
{
- set_specpdl_old_value (binding, eval_sub (XCAR (tail)));
+ set_specpdl_old_value (binding, eval_sub (exp));
}
}
- tail = XCDR (tail);
- tem = Fcar (tail);
- if (!NILP (tem))
- {
- if (!NILP (Vpurify_flag))
- tem = Fpurecopy (tem);
- Fput (sym, Qvariable_documentation, tem);
- }
- LOADHIST_ATTACH (sym);
}
else if (!NILP (Vinternal_interpreter_environment)
&& (SYMBOLP (sym) && !XSYMBOL (sym)->u.s.declared_special))
@@ -827,19 +839,12 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
docstring = XCAR (XCDR (XCDR (args)));
}
+ Finternal__define_uninitialized_variable (sym, docstring);
tem = eval_sub (XCAR (XCDR (args)));
if (!NILP (Vpurify_flag))
tem = Fpurecopy (tem);
- Fset_default (sym, tem);
- XSYMBOL (sym)->u.s.declared_special = true;
- if (!NILP (docstring))
- {
- if (!NILP (Vpurify_flag))
- docstring = Fpurecopy (docstring);
- Fput (sym, Qvariable_documentation, docstring);
- }
- Fput (sym, Qrisky_local_variable, Qt);
- LOADHIST_ATTACH (sym);
+ Fset_default (sym, tem); /* FIXME: set-default-toplevel-value? */
+ Fput (sym, Qrisky_local_variable, Qt); /* FIXME: Why? */
return sym;
}
@@ -4198,6 +4203,7 @@ alist of active lexical bindings. */);
defsubr (&Sdefvaralias);
DEFSYM (Qdefvaralias, "defvaralias");
defsubr (&Sdefconst);
+ defsubr (&Sinternal__define_uninitialized_variable);
defsubr (&Smake_var_non_special);
defsubr (&Slet);
defsubr (&SletX);
diff --git a/src/fileio.c b/src/fileio.c
index 4ee125d7de2..9e9779967dd 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5802,6 +5802,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
&& BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
&& BUF_AUTOSAVE_MODIFF (b) < BUF_MODIFF (b)
/* -1 means we've turned off autosaving for a while--see below. */
+ && FIXNUMP (BVAR (b, save_length))
&& XFIXNUM (BVAR (b, save_length)) >= 0
&& (do_handled_files
|| NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name),
@@ -5815,13 +5816,17 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
&& before_time.tv_sec - b->auto_save_failure_time < 1200)
continue;
+ enum { growth_factor = 4 };
+ verify (BUF_BYTES_MAX <= EMACS_INT_MAX / growth_factor);
+
set_buffer_internal (b);
if (NILP (Vauto_save_include_big_deletions)
- && (XFIXNAT (BVAR (b, save_length)) * 10
- > (BUF_Z (b) - BUF_BEG (b)) * 13)
+ && FIXNUMP (BVAR (b, save_length))
/* A short file is likely to change a large fraction;
spare the user annoying messages. */
&& XFIXNAT (BVAR (b, save_length)) > 5000
+ && (growth_factor * (BUF_Z (b) - BUF_BEG (b))
+ < (growth_factor - 1) * XFIXNAT (BVAR (b, save_length)))
/* These messages are frequent and annoying for `*mail*'. */
&& !NILP (BVAR (b, filename))
&& NILP (no_message))
diff --git a/src/fns.c b/src/fns.c
index c3202495daf..6b1f7331f55 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1131,10 +1131,8 @@ string the same way whether it is unibyte or multibyte.) */)
DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
1, 1, 0,
doc: /* Return the unibyte equivalent of STRING.
-Multibyte character codes are converted to unibyte according to
-`nonascii-translation-table' or, if that is nil, `nonascii-insert-offset'.
-If the lookup in the translation table fails, this function takes just
-the low 8 bits of each character. */)
+Multibyte character codes above 255 are converted to unibyte
+by taking just the low 8 bits of each character's code. */)
(Lisp_Object string)
{
CHECK_STRING (string);
diff --git a/src/font.h b/src/font.h
index 1f62a61f0be..a590bda3db4 100644
--- a/src/font.h
+++ b/src/font.h
@@ -651,7 +651,7 @@ struct font_driver
the font FONT and the sequence of glyph codes CODE, and store the
result in METRICS. */
void (*text_extents) (struct font *font,
- unsigned *code, int nglyphs,
+ const unsigned *code, int nglyphs,
struct font_metrics *metrics);
#ifdef HAVE_WINDOW_SYSTEM
@@ -920,7 +920,7 @@ extern Lisp_Object ftfont_shape (Lisp_Object, Lisp_Object);
extern unsigned ftfont_encode_char (struct font *, int);
extern void ftfont_close (struct font *);
extern void ftfont_filter_properties (Lisp_Object, Lisp_Object);
-extern void ftfont_text_extents (struct font *, unsigned *, int,
+extern void ftfont_text_extents (struct font *, const unsigned *, int,
struct font_metrics *);
#ifdef HAVE_HARFBUZZ
extern Lisp_Object fthbfont_combining_capability (struct font *);
diff --git a/src/frame.h b/src/frame.h
index b8aed823afb..781063340d8 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1626,7 +1626,7 @@ flush_frame (struct frame *f)
#ifdef HAVE_WINDOW_SYSTEM
struct MonitorInfo {
- XRectangle geom, work;
+ Emacs_Rectangle geom, work;
int mm_width, mm_height;
char *name;
};
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index dc59c2bcadc..79bf68141dc 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -79,7 +79,6 @@ ftcrfont_glyph_extents (struct font *font,
cairo_glyph_t cr_glyph = {.index = glyph};
cairo_text_extents_t extents;
- FT_Activate_Size (ftcrfont_info->ft_size_draw);
cairo_scaled_font_glyph_extents (ftcrfont_info->cr_scaled_font,
&cr_glyph, 1, &extents);
cache->lbearing = floor (extents.x_bearing);
@@ -110,99 +109,168 @@ ftcrfont_match (struct frame *f, Lisp_Object spec)
static Lisp_Object
ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
- Lisp_Object font_object;
-
- FT_UInt size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
+ FcResult result;
+ Lisp_Object val, filename, font_object;
+ FcPattern *pat, *match;
+ struct font_info *ftcrfont_info;
+ struct font *font;
+ double size = 0;
+ cairo_font_face_t *font_face;
+ cairo_font_extents_t extents;
+ FT_Face ft_face;
+ FcMatrix *matrix;
+
+ val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
+ if (! CONSP (val))
+ return Qnil;
+ val = XCDR (val);
+ filename = XCAR (val);
+ size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
if (size == 0)
size = pixel_size;
- font_object = font_build_object (VECSIZE (struct font_info),
- AREF (entity, FONT_TYPE_INDEX),
- entity, size);
+
block_input ();
- font_object = ftfont_open2 (f, entity, pixel_size, font_object);
- if (FONT_OBJECT_P (font_object))
+
+ pat = ftfont_entity_pattern (entity, pixel_size);
+ FcConfigSubstitute (NULL, pat, FcMatchPattern);
+ FcDefaultSubstitute (pat);
+ match = FcFontMatch (NULL, pat, &result);
+ ftfont_fix_match (pat, match);
+
+ FcPatternDestroy (pat);
+ font_face = cairo_ft_font_face_create_for_pattern (match);
+ if (!font_face)
{
- struct font *font = XFONT_OBJECT (font_object);
- struct font_info *ftcrfont_info = (struct font_info *) font;
- FT_Face ft_face = ftcrfont_info->ft_size->face;
+ unblock_input ();
+ FcPatternDestroy (match);
+ return Qnil;
+ }
+ cairo_matrix_t font_matrix, ctm;
+ cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
+ cairo_matrix_init_identity (&ctm);
+ cairo_font_options_t *options = cairo_font_options_create ();
+ cairo_scaled_font_t *scaled_font
+ = cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
+ cairo_font_face_destroy (font_face);
+ cairo_font_options_destroy (options);
+ unblock_input ();
+ font_object = font_build_object (VECSIZE (struct font_info),
+ AREF (entity, FONT_TYPE_INDEX),
+ entity, size);
+ ASET (font_object, FONT_FILE_INDEX, filename);
+ font = XFONT_OBJECT (font_object);
+ font->pixel_size = size;
#ifdef HAVE_HARFBUZZ
- if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qftcrhb))
- font->driver = &ftcrhbfont_driver;
- else
+ if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qftcrhb))
+ font->driver = &ftcrhbfont_driver;
+ else
#endif /* HAVE_HARFBUZZ */
- font->driver = &ftcrfont_driver;
- FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw);
- FT_Activate_Size (ftcrfont_info->ft_size_draw);
- if (ftcrfont_info->bitmap_strike_index < 0)
- FT_Set_Pixel_Sizes (ft_face, 0, font->pixel_size);
- else
- FT_Select_Size (ft_face, ftcrfont_info->bitmap_strike_index);
- cairo_font_face_t *font_face =
- cairo_ft_font_face_create_for_ft_face (ft_face, 0);
- cairo_matrix_t font_matrix, ctm;
- cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
- cairo_matrix_init_identity (&ctm);
- cairo_font_options_t *options = cairo_font_options_create ();
- ftcrfont_info->cr_scaled_font =
- cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
- cairo_font_face_destroy (font_face);
- cairo_font_options_destroy (options);
- ftcrfont_info->metrics = NULL;
- ftcrfont_info->metrics_nrows = 0;
- if (ftcrfont_info->bitmap_strike_index >= 0)
+ font->driver = &ftcrfont_driver;
+ font->encoding_charset = font->repertory_charset = -1;
+
+ ftcrfont_info = (struct font_info *) font;
+ ftcrfont_info->cr_scaled_font = scaled_font;
+
+ /* This means that there's no need of transformation. */
+ ftcrfont_info->matrix.xx = 0;
+ if (FcPatternGetMatrix (match, FC_MATRIX, 0, &matrix) == FcResultMatch)
+ {
+ ftcrfont_info->matrix.xx = 0x10000L * matrix->xx;
+ ftcrfont_info->matrix.yy = 0x10000L * matrix->yy;
+ ftcrfont_info->matrix.xy = 0x10000L * matrix->xy;
+ ftcrfont_info->matrix.yx = 0x10000L * matrix->yx;
+ }
+
+ ftcrfont_info->metrics = NULL;
+ ftcrfont_info->metrics_nrows = 0;
+
+ block_input ();
+ cairo_glyph_t stack_glyph;
+ int n = 0;
+ font->min_width = font->average_width = font->space_width = 0;
+ for (char c = 32; c < 127; c++)
+ {
+ cairo_glyph_t *glyphs = &stack_glyph;
+ int num_glyphs = 1;
+ cairo_status_t status =
+ cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
+ 0, 0, &c, 1, &glyphs, &num_glyphs,
+ NULL, NULL, NULL);
+
+ if (status == CAIRO_STATUS_SUCCESS)
{
- /* Several members of struct font/font_info set by
- ftfont_open2 are bogus. Recalculate them with cairo
- scaled font functions. */
- cairo_font_extents_t extents;
- cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
- font->ascent = lround (extents.ascent);
- font->descent = lround (extents.descent);
- font->height = lround (extents.height);
-
- cairo_glyph_t stack_glyph;
- int n = 0;
- font->min_width = font->average_width = font->space_width = 0;
- for (char c = 32; c < 127; c++)
+ if (glyphs != &stack_glyph)
+ cairo_glyph_free (glyphs);
+ else if (stack_glyph.index)
{
- cairo_glyph_t *glyphs = &stack_glyph;
- int num_glyphs = 1;
- cairo_status_t status =
- cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
- 0, 0, &c, 1,
- &glyphs, &num_glyphs,
- NULL, NULL, NULL);
-
- if (status == CAIRO_STATUS_SUCCESS)
- {
- if (glyphs != &stack_glyph)
- cairo_glyph_free (glyphs);
- else
- {
- int this_width =
- ftcrfont_glyph_extents (font, stack_glyph.index, NULL);
-
- if (this_width > 0
- && (! font->min_width
- || font->min_width > this_width))
- font->min_width = this_width;
- if (c == 32)
- font->space_width = this_width;
- font->average_width += this_width;
- n++;
- }
- }
+ int this_width = ftcrfont_glyph_extents (font, stack_glyph.index,
+ NULL);
+
+ if (this_width > 0
+ && (! font->min_width
+ || font->min_width > this_width))
+ font->min_width = this_width;
+ if (c == 32)
+ font->space_width = this_width;
+ font->average_width += this_width;
+ n++;
}
- if (n > 0)
- font->average_width /= n;
-
- font->underline_position = -1;
- font->underline_thickness = 0;
}
}
+ if (n > 0)
+ font->average_width /= n;
+
+ cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
+ font->ascent = lround (extents.ascent);
+ val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
+ if (!(CONSP (val) && NILP (XCDR (val))))
+ {
+ font->descent = lround (extents.descent);
+ font->height = font->ascent + font->descent;
+ }
+ else
+ {
+ font->height = lround (extents.height);
+ font->descent = font->height - font->ascent;
+ }
+
+ ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+ if (XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) == 0)
+ {
+ int upEM = ft_face->units_per_EM;
+
+ font->underline_position = -ft_face->underline_position * size / upEM;
+ font->underline_thickness = ft_face->underline_thickness * size / upEM;
+ if (font->underline_thickness > 2)
+ font->underline_position -= font->underline_thickness / 2;
+ }
+ else
+ {
+ font->underline_position = -1;
+ font->underline_thickness = 0;
+ }
+#ifdef HAVE_LIBOTF
+ ftcrfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
+ ftcrfont_info->otf = NULL;
+#endif /* HAVE_LIBOTF */
+#ifdef HAVE_HARFBUZZ
+ ftcrfont_info->hb_font = NULL;
+#endif /* HAVE_HARFBUZZ */
+ if (ft_face->units_per_EM)
+ ftcrfont_info->bitmap_position_unit = 0;
+ else
+ ftcrfont_info->bitmap_position_unit = (extents.height
+ / ft_face->size->metrics.height);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
unblock_input ();
+ font->baseline_offset = 0;
+ font->relative_compose = 0;
+ font->default_ascent = 0;
+ font->vertical_centering = false;
+
return font_object;
}
@@ -213,24 +281,70 @@ ftcrfont_close (struct font *font)
return;
struct font_info *ftcrfont_info = (struct font_info *) font;
- int i;
block_input ();
- for (i = 0; i < ftcrfont_info->metrics_nrows; i++)
+#ifdef HAVE_LIBOTF
+ if (ftcrfont_info->otf)
+ {
+ OTF_close (ftcrfont_info->otf);
+ ftcrfont_info->otf = NULL;
+ }
+#endif
+#ifdef HAVE_HARFBUZZ
+ if (ftcrfont_info->hb_font)
+ {
+ hb_font_destroy (ftcrfont_info->hb_font);
+ ftcrfont_info->hb_font = NULL;
+ }
+#endif
+ for (int i = 0; i < ftcrfont_info->metrics_nrows; i++)
if (ftcrfont_info->metrics[i])
xfree (ftcrfont_info->metrics[i]);
if (ftcrfont_info->metrics)
xfree (ftcrfont_info->metrics);
- FT_Done_Size (ftcrfont_info->ft_size_draw);
cairo_scaled_font_destroy (ftcrfont_info->cr_scaled_font);
unblock_input ();
+}
+
+static int
+ftcrfont_has_char (Lisp_Object font, int c)
+{
+ if (FONT_ENTITY_P (font))
+ return ftfont_has_char (font, c);
+
+ return -1;
+}
+
+static unsigned
+ftcrfont_encode_char (struct font *font, int c)
+{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+ unsigned code = FONT_INVALID_CODE;
+ unsigned char utf8[MAX_MULTIBYTE_LENGTH];
+ unsigned char *p = utf8;
+ cairo_glyph_t stack_glyph;
+ cairo_glyph_t *glyphs = &stack_glyph;
+ int num_glyphs = 1;
+
+ CHAR_STRING_ADVANCE (c, p);
+ if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0,
+ (char *) utf8, p - utf8,
+ &glyphs, &num_glyphs,
+ NULL, NULL, NULL)
+ == CAIRO_STATUS_SUCCESS)
+ {
+ if (glyphs != &stack_glyph)
+ cairo_glyph_free (glyphs);
+ else if (stack_glyph.index)
+ code = stack_glyph.index;
+ }
- ftfont_close (font);
+ return code;
}
static void
ftcrfont_text_extents (struct font *font,
- unsigned *code,
+ const unsigned *code,
int nglyphs,
struct font_metrics *metrics)
{
@@ -268,10 +382,18 @@ ftcrfont_get_bitmap (struct font *font, unsigned int code,
{
struct font_info *ftcrfont_info = (struct font_info *) font;
- if (ftcrfont_info->bitmap_strike_index < 0)
- return ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
+ if (ftcrfont_info->bitmap_position_unit)
+ return -1;
- return -1;
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+ FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+
+ ftcrfont_info->ft_size = ft_face->size;
+ int result = ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
+
+ return result;
}
static int
@@ -280,25 +402,75 @@ ftcrfont_anchor_point (struct font *font, unsigned int code, int idx,
{
struct font_info *ftcrfont_info = (struct font_info *) font;
- if (ftcrfont_info->bitmap_strike_index < 0)
- return ftfont_anchor_point (font, code, idx, x, y);
+ if (ftcrfont_info->bitmap_position_unit)
+ return -1;
- return -1;
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+ FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+
+ ftcrfont_info->ft_size = ft_face->size;
+ int result = ftfont_anchor_point (font, code, idx, x, y);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
+
+ return result;
}
+#ifdef HAVE_LIBOTF
static Lisp_Object
-ftcrfont_shape (Lisp_Object lgstring, Lisp_Object direction)
+ftcrfont_otf_capability (struct font *font)
{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+ FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+
+ ftcrfont_info->ft_size = ft_face->size;
+ Lisp_Object result = ftfont_otf_capability (font);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
+
+ return result;
+}
+#endif
+
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
+static Lisp_Object
+ftcrfont_shape (Lisp_Object lgstring, Lisp_Object direction)
+{
struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
struct font_info *ftcrfont_info = (struct font_info *) font;
- if (ftcrfont_info->bitmap_strike_index < 0)
- return ftfont_shape (lgstring, direction);
+ if (ftcrfont_info->bitmap_position_unit)
+ return make_fixnum (0);
+
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+ FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+
+ ftcrfont_info->ft_size = ft_face->size;
+ Lisp_Object result = ftfont_shape (lgstring, direction);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
+
+ return result;
+}
#endif
- return make_fixnum (0);
+#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
+static int
+ftcrfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
+{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+ FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
+
+ ftcrfont_info->ft_size = ft_face->size;
+ int result = ftfont_variation_glyphs (font, c, variations);
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
+
+ return result;
}
+#endif /* HAVE_OTF_GET_VARIATION_GLYPHS */
static int
ftcrfont_draw (struct glyph_string *s,
@@ -309,8 +481,6 @@ ftcrfont_draw (struct glyph_string *s,
struct font_info *ftcrfont_info = (struct font_info *) s->font;
cairo_t *cr;
cairo_glyph_t *glyphs;
- cairo_surface_t *surface;
- cairo_surface_type_t surface_type;
int len = to - from;
int i;
@@ -329,28 +499,17 @@ ftcrfont_draw (struct glyph_string *s,
glyphs = alloca (sizeof (cairo_glyph_t) * len);
for (i = 0; i < len; i++)
{
- unsigned code = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
- | XCHAR2B_BYTE2 (s->char2b + from + i));
-
- glyphs[i].index = code;
+ glyphs[i].index = s->char2b[from + i];
glyphs[i].x = x;
glyphs[i].y = y;
- x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font, code, NULL));
+ x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
+ glyphs[i].index,
+ NULL));
}
x_set_cr_source_with_gc_foreground (f, s->gc);
cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
-
- FT_Activate_Size (ftcrfont_info->ft_size_draw);
cairo_show_glyphs (cr, glyphs, len);
- surface = cairo_get_target (cr);
- /* XXX: It used to be necessary to flush when exporting. It might
- be the case that this is no longer necessary. */
- surface_type = cairo_surface_get_type (surface);
- if (surface_type != CAIRO_SURFACE_TYPE_XLIB
- && (surface_type != CAIRO_SURFACE_TYPE_IMAGE
- || cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32))
- cairo_surface_flush (surface);
x_end_cr_clip (f);
@@ -377,20 +536,27 @@ static hb_font_t *
ftcrhbfont_begin_hb_font (struct font *font, double *position_unit)
{
struct font_info *ftcrfont_info = (struct font_info *) font;
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+ FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
- FT_Activate_Size (ftcrfont_info->ft_size_draw);
+ ftcrfont_info->ft_size = ft_face->size;
hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit);
- int i = ftcrfont_info->bitmap_strike_index;
- if (i >= 0)
- {
- FT_Face ft_face = ftcrfont_info->ft_size_draw->face;
- *position_unit = ((double) font->height
- / ft_face->available_sizes[i].height) / (1 << 6);
- }
+ if (ftcrfont_info->bitmap_position_unit)
+ *position_unit = ftcrfont_info->bitmap_position_unit;
return hb_font;
}
+static void
+ftcrhbfont_end_hb_font (struct font *font, hb_font_t *hb_font)
+{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
+ cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
+
+ cairo_ft_scaled_font_unlock_face (scaled_font);
+ ftcrfont_info->ft_size = NULL;
+}
+
#endif /* HAVE_HARFBUZZ */
@@ -405,18 +571,20 @@ struct font_driver const ftcrfont_driver =
.list_family = ftfont_list_family,
.open = ftcrfont_open,
.close = ftcrfont_close,
- .has_char = ftfont_has_char,
- .encode_char = ftfont_encode_char,
+ .has_char = ftcrfont_has_char,
+ .encode_char = ftcrfont_encode_char,
.text_extents = ftcrfont_text_extents,
.draw = ftcrfont_draw,
.get_bitmap = ftcrfont_get_bitmap,
.anchor_point = ftcrfont_anchor_point,
#ifdef HAVE_LIBOTF
- .otf_capability = ftfont_otf_capability,
+ .otf_capability = ftcrfont_otf_capability,
#endif
+#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
.shape = ftcrfont_shape,
+#endif
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
- .get_variation_glyphs = ftfont_variation_glyphs,
+ .get_variation_glyphs = ftcrfont_variation_glyphs,
#endif
.filter_properties = ftfont_filter_properties,
.combining_capability = ftfont_combining_capability,
@@ -447,6 +615,7 @@ syms_of_ftcrfont_for_pdumper (void)
ftcrhbfont_driver.shape = fthbfont_shape;
ftcrhbfont_driver.combining_capability = fthbfont_combining_capability;
ftcrhbfont_driver.begin_hb_font = ftcrhbfont_begin_hb_font;
+ ftcrhbfont_driver.end_hb_font = ftcrhbfont_end_hb_font;
register_font_driver (&ftcrhbfont_driver, NULL);
#endif /* HAVE_HARFBUZZ */
}
diff --git a/src/ftfont.c b/src/ftfont.c
index 2373af8766a..5694c49aaf9 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -1103,12 +1103,159 @@ ftfont_list_family (struct frame *f)
return list;
}
+void
+ftfont_fix_match (FcPattern *pat, FcPattern *match)
+{
+ /* These values are not used for matching (except antialias), but for
+ rendering, so make sure they are carried over to the match.
+ We also put antialias here because most fonts are antialiased, so
+ the match will have antialias true. */
+
+ FcBool b = FcTrue;
+ int i;
+ double dpi;
+
+ FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
+ if (! b)
+ {
+ FcPatternDel (match, FC_ANTIALIAS);
+ FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
+ }
+ FcPatternGetBool (pat, FC_HINTING, 0, &b);
+ if (! b)
+ {
+ FcPatternDel (match, FC_HINTING);
+ FcPatternAddBool (match, FC_HINTING, FcFalse);
+ }
+#ifndef FC_HINT_STYLE
+# define FC_HINT_STYLE "hintstyle"
+#endif
+ if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
+ {
+ FcPatternDel (match, FC_HINT_STYLE);
+ FcPatternAddInteger (match, FC_HINT_STYLE, i);
+ }
+#ifndef FC_LCD_FILTER
+ /* Older fontconfig versions don't have FC_LCD_FILTER. */
+#define FC_LCD_FILTER "lcdfilter"
+#endif
+ if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
+ {
+ FcPatternDel (match, FC_LCD_FILTER);
+ FcPatternAddInteger (match, FC_LCD_FILTER, i);
+ }
+ if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
+ {
+ FcPatternDel (match, FC_RGBA);
+ FcPatternAddInteger (match, FC_RGBA, i);
+ }
+ if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
+ {
+ FcPatternDel (match, FC_DPI);
+ FcPatternAddDouble (match, FC_DPI, dpi);
+ }
+}
+
+void
+ftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
+{
+ Lisp_Object tail;
+ int ival;
+
+ for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
+ {
+ Lisp_Object key = XCAR (XCAR (tail));
+ Lisp_Object val = XCDR (XCAR (tail));
+
+ if (EQ (key, QCantialias))
+ FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
+ else if (EQ (key, QChinting))
+ FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
+ else if (EQ (key, QCautohint))
+ FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
+ else if (EQ (key, QChintstyle))
+ {
+ if (FIXNUMP (val))
+ FcPatternAddInteger (pat, FC_HINT_STYLE, XFIXNUM (val));
+ else if (SYMBOLP (val)
+ && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
+ FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
+ }
+ else if (EQ (key, QCrgba))
+ {
+ if (FIXNUMP (val))
+ FcPatternAddInteger (pat, FC_RGBA, XFIXNUM (val));
+ else if (SYMBOLP (val)
+ && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
+ FcPatternAddInteger (pat, FC_RGBA, ival);
+ }
+ else if (EQ (key, QClcdfilter))
+ {
+ if (FIXNUMP (val))
+ FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XFIXNUM (val));
+ else if (SYMBOLP (val)
+ && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
+ FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
+ }
+#ifdef FC_EMBOLDEN
+ else if (EQ (key, QCembolden))
+ FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
+#endif
+ }
+}
+
+FcPattern *
+ftfont_entity_pattern (Lisp_Object entity, int pixel_size)
+{
+ Lisp_Object val, filename, idx;
+ FcPattern *pat;
+ int i;
+
+ val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
+ eassert (CONSP (val));
+ val = XCDR (val);
+ filename = XCAR (val);
+ idx = XCDR (val);
+ pat = FcPatternCreate ();
+ FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity));
+ i = FONT_SLANT_NUMERIC (entity) - 100;
+ if (i < 0) i = 0;
+ FcPatternAddInteger (pat, FC_SLANT, i);
+ FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity));
+ FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
+ val = AREF (entity, FONT_FAMILY_INDEX);
+ if (! NILP (val))
+ FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
+ val = AREF (entity, FONT_FOUNDRY_INDEX);
+ if (! NILP (val))
+ FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
+ val = AREF (entity, FONT_SPACING_INDEX);
+ if (! NILP (val))
+ FcPatternAddInteger (pat, FC_SPACING, XFIXNUM (val));
+ val = AREF (entity, FONT_DPI_INDEX);
+ if (! NILP (val))
+ {
+ double dbl = XFIXNUM (val);
+
+ FcPatternAddDouble (pat, FC_DPI, dbl);
+ }
+ val = AREF (entity, FONT_AVGWIDTH_INDEX);
+ if (FIXNUMP (val) && XFIXNUM (val) == 0)
+ FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
+ /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
+ over 10x20-ISO8859-1.pcf.gz). */
+ FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
+
+ ftfont_add_rendering_parameters (pat, entity);
+
+ FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
+ FcPatternAddInteger (pat, FC_INDEX, XFIXNUM (idx));
+
+ return pat;
+}
Lisp_Object
-ftfont_open2 (struct frame *f,
- Lisp_Object entity,
- int pixel_size,
- Lisp_Object font_object)
+ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
struct font_info *ftfont_info;
struct font *font;
@@ -1116,12 +1263,11 @@ ftfont_open2 (struct frame *f,
FT_Face ft_face;
FT_Size ft_size;
FT_UInt size;
- Lisp_Object val, filename, idx, cache;
+ Lisp_Object val, filename, idx, cache, font_object;
bool scalable;
int spacing;
int i;
double upEM;
- FT_Int strike_index = -1;
val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
if (! CONSP (val))
@@ -1132,7 +1278,6 @@ ftfont_open2 (struct frame *f,
return Qnil;
filename = XCAR (val);
idx = XCDR (val);
- val = XCDR (cache);
cache_data = xmint_pointer (XCDR (cache));
ft_face = cache_data->ft_face;
if (cache_data->face_refcount > 0)
@@ -1151,35 +1296,17 @@ ftfont_open2 (struct frame *f,
size = pixel_size;
if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
{
- int min_distance = INT_MAX;
- bool magnify = true;
-
- for (FT_Int i = 0; i < ft_face->num_fixed_sizes; i++)
- {
- int distance = ft_face->available_sizes[i].height - (int) size;
-
- /* Prefer down-scaling to upscaling. */
- if (magnify == (distance < 0) ? abs (distance) <= min_distance
- : magnify)
- {
- magnify = distance < 0;
- min_distance = abs (distance);
- strike_index = i;
- }
- }
-
- if (strike_index < 0 || FT_Select_Size (ft_face, strike_index) != 0)
+ if (cache_data->face_refcount == 0)
{
- if (cache_data->face_refcount == 0)
- {
- FT_Done_Face (ft_face);
- cache_data->ft_face = NULL;
- }
- return Qnil;
+ FT_Done_Face (ft_face);
+ cache_data->ft_face = NULL;
}
+ return Qnil;
}
cache_data->face_refcount++;
+ font_object = font_build_object (VECSIZE (struct font_info),
+ Qfreetype, entity, size);
ASET (font_object, FONT_FILE_INDEX, filename);
font = XFONT_OBJECT (font_object);
ftfont_info = (struct font_info *) font;
@@ -1192,7 +1319,6 @@ ftfont_open2 (struct frame *f,
#ifdef HAVE_HARFBUZZ
ftfont_info->hb_font = NULL;
#endif /* HAVE_HARFBUZZ */
- ftfont_info->bitmap_strike_index = strike_index;
/* This means that there's no need of transformation. */
ftfont_info->matrix.xx = 0;
font->pixel_size = size;
@@ -1204,20 +1330,38 @@ ftfont_open2 (struct frame *f,
font->driver = &ftfont_driver;
font->encoding_charset = font->repertory_charset = -1;
+ val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
+ bool no_leading_p = !(CONSP (val) && NILP (XCDR (val)));
upEM = ft_face->units_per_EM;
scalable = (FIXNUMP (AREF (entity, FONT_AVGWIDTH_INDEX))
&& XFIXNUM (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0);
if (scalable)
{
font->ascent = ft_face->ascender * size / upEM + 0.5;
- font->descent = - ft_face->descender * size / upEM + 0.5;
- font->height = ft_face->height * size / upEM + 0.5;
+ if (no_leading_p)
+ {
+ font->descent = - ft_face->descender * size / upEM + 0.5;
+ font->height = font->ascent + font->descent;
+ }
+ else
+ {
+ font->height = ft_face->height * size / upEM + 0.5;
+ font->descent = font->height - font->ascent;
+ }
}
else
{
font->ascent = ft_face->size->metrics.ascender >> 6;
- font->descent = - ft_face->size->metrics.descender >> 6;
- font->height = ft_face->size->metrics.height >> 6;
+ if (no_leading_p)
+ {
+ font->descent = - ft_face->size->metrics.descender >> 6;
+ font->height = font->ascent + font->descent;
+ }
+ else
+ {
+ font->height = ft_face->size->metrics.height >> 6;
+ font->descent = font->height - font->ascent;
+ }
}
if (FIXNUMP (AREF (entity, FONT_SPACING_INDEX)))
spacing = XFIXNUM (AREF (entity, FONT_SPACING_INDEX));
@@ -1273,32 +1417,6 @@ ftfont_open2 (struct frame *f,
return font_object;
}
-Lisp_Object
-ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
-{
- Lisp_Object font_object;
- FT_UInt size;
- size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
- if (size == 0)
- size = pixel_size;
- font_object = font_build_object (VECSIZE (struct font_info),
- AREF (entity, FONT_TYPE_INDEX),
- entity, size);
- font_object = ftfont_open2 (f, entity, pixel_size, font_object);
- if (FONT_OBJECT_P (font_object))
- {
- struct font *font = XFONT_OBJECT (font_object);
- struct font_info *ftfont_info = (struct font_info *) font;
-
- if (ftfont_info->bitmap_strike_index >= 0)
- {
- ftfont_close (font);
- font_object = Qnil;
- }
- }
- return font_object;
-}
-
void
ftfont_close (struct font *font)
{
@@ -1391,7 +1509,7 @@ ftfont_glyph_metrics (FT_Face ft_face, int c, int *advance, int *lbearing,
}
void
-ftfont_text_extents (struct font *font, unsigned int *code,
+ftfont_text_extents (struct font *font, const unsigned int *code,
int nglyphs, struct font_metrics *metrics)
{
struct font_info *ftfont_info = (struct font_info *) font;
@@ -3131,6 +3249,17 @@ syms_of_ftfont (void)
DEFSYM (Qsans, "sans");
DEFSYM (Qsans__serif, "sans serif");
+ /* The boolean-valued font property key specifying the use of leading. */
+ DEFSYM (QCminspace, ":minspace");
+
+ /* Fontconfig's rendering parameters. */
+ DEFSYM (QChinting, ":hinting");
+ DEFSYM (QCautohint, ":autohint");
+ DEFSYM (QChintstyle, ":hintstyle");
+ DEFSYM (QCrgba, ":rgba");
+ DEFSYM (QCembolden, ":embolden");
+ DEFSYM (QClcdfilter, ":lcdfilter");
+
staticpro (&freetype_font_cache);
freetype_font_cache = list1 (Qt);
diff --git a/src/ftfont.h b/src/ftfont.h
index f877860895e..b2280e9aab9 100644
--- a/src/ftfont.h
+++ b/src/ftfont.h
@@ -42,10 +42,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#endif /* HAVE_LIBOTF */
extern FcCharSet *ftfont_get_fc_charset (Lisp_Object);
-extern Lisp_Object ftfont_open2 (struct frame *f,
- Lisp_Object entity,
- int pixel_size,
- Lisp_Object font_object);
+extern void ftfont_fix_match (FcPattern *, FcPattern *);
+extern void ftfont_add_rendering_parameters (FcPattern *, Lisp_Object);
+extern FcPattern *ftfont_entity_pattern (Lisp_Object, int);
/* This struct is shared by the XFT, Freetype, and Cairo font
backends. Members up to and including 'matrix' are common, the
@@ -59,10 +58,6 @@ struct font_info
#endif /* HAVE_LIBOTF */
FT_Size ft_size;
int index;
- /* Index of the bitmap strike used as a fallback for
- FT_Set_Pixel_Sizes failure. If the value is non-negative, then
- ft_size is not of the requested size. Otherwise it is -1. */
- FT_Int bitmap_strike_index;
FT_Matrix matrix;
#ifdef HAVE_HARFBUZZ
hb_font_t *hb_font;
@@ -70,9 +65,10 @@ struct font_info
#ifdef USE_CAIRO
cairo_scaled_font_t *cr_scaled_font;
- /* To prevent cairo from cluttering the activated FT_Size maintained
- in ftfont.c, we activate this special FT_Size before drawing. */
- FT_Size ft_size_draw;
+ /* Scale factor from the bitmap strike metrics in 1/64 pixels, used
+ as the hb_position_t value in HarfBuzz, to those in (scaled)
+ pixels. The value is 0 for scalable fonts. */
+ double bitmap_position_unit;
/* Font metrics cache. */
struct font_metrics **metrics;
short metrics_nrows;
diff --git a/src/ftxfont.c b/src/ftxfont.c
index 949ef4c503b..da3e3fbae10 100644
--- a/src/ftxfont.c
+++ b/src/ftxfont.c
@@ -244,7 +244,7 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
struct font *font = s->font;
XPoint p[0x700];
int n[7];
- unsigned *code;
+ unsigned *code = s->char2b + from;
int len = to - from;
int i;
GC *gcs;
@@ -252,14 +252,9 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0;
- USE_SAFE_ALLOCA;
- SAFE_NALLOCA (code, 1, len);
block_input ();
if (with_background)
ftxfont_draw_background (f, font, s->gc, x, y, s->width);
- for (i = 0; i < len; i++)
- code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
- | XCHAR2B_BYTE2 (s->char2b + from + i));
if (face->gc == s->gc)
{
@@ -304,7 +299,6 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
}
unblock_input ();
- SAFE_FREE ();
return len;
}
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 48233576531..43918dd3da5 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -520,7 +520,7 @@ get_utf8_string (const char *str)
bool
xg_check_special_colors (struct frame *f,
const char *color_name,
- XColor *color)
+ Emacs_Color *color)
{
bool success_p = 0;
bool get_bg = strcmp ("gtk_selection_bg_color", color_name) == 0;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index ec899781ca8..229aa08f817 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -166,7 +166,7 @@ extern void xg_free_frame_widgets (struct frame *f);
extern void xg_set_background_color (struct frame *f, unsigned long bg);
extern bool xg_check_special_colors (struct frame *f,
const char *color_name,
- XColor *color);
+ Emacs_Color *color);
extern void xg_set_frame_icon (struct frame *f,
Pixmap icon_pixmap,
diff --git a/src/image.c b/src/image.c
index bf594987eb8..57b405f6db9 100644
--- a/src/image.c
+++ b/src/image.c
@@ -132,17 +132,17 @@ static unsigned long *colors_in_color_table (int *n);
#ifdef HAVE_NS
/* Use with images created by ns_image_for_XPM. */
static unsigned long
-XGetPixel (XImagePtr ximage, int x, int y)
+XGetPixel (Emacs_Pix_Container image, int x, int y)
{
- return ns_get_pixel (ximage, x, y);
+ return ns_get_pixel (image, x, y);
}
/* Use with images created by ns_image_for_XPM; alpha set to 1;
pixel is assumed to be in RGB form. */
static void
-XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
+XPutPixel (Emacs_Pix_Container image, int x, int y, unsigned long pixel)
{
- ns_put_pixel (ximage, x, y, pixel);
+ ns_put_pixel (image, x, y, pixel);
}
#endif /* HAVE_NS */
@@ -228,7 +228,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
#ifdef HAVE_NTGUI
Lisp_Object frame UNINIT; /* The value is not used. */
- Pixmap bitmap;
+ Emacs_Pixmap bitmap;
bitmap = CreateBitmap (width, height,
FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes,
FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits,
@@ -412,17 +412,19 @@ typedef void Picture;
#endif
static bool image_create_x_image_and_pixmap_1 (struct frame *, int, int, int,
- XImagePtr *, Pixmap *, Picture *);
-static void image_destroy_x_image (XImagePtr ximg);
+ Emacs_Pix_Container *,
+ Emacs_Pixmap *, Picture *);
+static void image_destroy_x_image (Emacs_Pix_Container);
#ifdef HAVE_NTGUI
-static XImagePtr_or_DC image_get_x_image_or_dc (struct frame *, struct image *,
- bool, HGDIOBJ *);
-static void image_unget_x_image_or_dc (struct image *, bool, XImagePtr_or_DC,
- HGDIOBJ);
+static HDC image_get_x_image_or_dc (struct frame *, struct image *,
+ bool, HGDIOBJ *);
+static void image_unget_x_image_or_dc (struct image *, bool,
+ HDC, HGDIOBJ);
#else
-static XImagePtr image_get_x_image (struct frame *, struct image *, bool);
-static void image_unget_x_image (struct image *, bool, XImagePtr);
+static Emacs_Pix_Container image_get_x_image (struct frame *, struct image *,
+ bool);
+static void image_unget_x_image (struct image *, bool, Emacs_Pix_Container);
#define image_get_x_image_or_dc(f, img, mask_p, dummy) \
image_get_x_image (f, img, mask_p)
#define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \
@@ -436,7 +438,7 @@ static void image_sync_to_pixmaps (struct frame *, struct image *);
/* Useful functions defined in the section
`Image type independent image structures' below. */
-static unsigned long four_corners_best (XImagePtr ximg,
+static unsigned long four_corners_best (XImage *ximg,
int *corners,
unsigned long width,
unsigned long height);
@@ -449,7 +451,7 @@ void
x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
{
Pixmap pixmap, mask;
- XImagePtr ximg, mask_img;
+ XImage *ximg, *mask_img;
unsigned long width, height;
bool result;
unsigned long bg;
@@ -548,82 +550,29 @@ struct image_type
/* Free resources of image IMG which is used on frame F. */
void (*free) (struct frame *f, struct image *img);
+#ifdef WINDOWSNT
/* Initialization function (used for dynamic loading of image
libraries on Windows), or NULL if none. */
bool (*init) (void);
-
- /* Next in list of all supported image types. */
- struct image_type *next;
+ /* An initializer for the init field. */
+# define IMAGE_TYPE_INIT(f) f
+#else
+# define IMAGE_TYPE_INIT(f)
+#endif
};
-/* List of supported image types. Use define_image_type to add new
- types. Use lookup_image_type to find a type for a given symbol. */
-
-static struct image_type *image_types;
-
/* Forward function prototypes. */
-static struct image_type *lookup_image_type (Lisp_Object);
+static struct image_type const *lookup_image_type (Lisp_Object);
static void image_laplace (struct frame *, struct image *);
static void image_emboss (struct frame *, struct image *);
static void image_build_heuristic_mask (struct frame *, struct image *,
Lisp_Object);
-#ifdef WINDOWSNT
-#define CACHE_IMAGE_TYPE(type, status) \
- do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
-#else
-#define CACHE_IMAGE_TYPE(type, status)
-#endif
-
-#define ADD_IMAGE_TYPE(type) \
- do { Vimage_types = Fcons (type, Vimage_types); } while (0)
-
-/* Define a new image type from TYPE. This adds a copy of TYPE to
- image_types and caches the loading status of TYPE. */
-static struct image_type *
-define_image_type (struct image_type *type)
+static void
+add_image_type (Lisp_Object type)
{
- struct image_type *p = NULL;
- int new_type = type->type;
- bool type_valid = true;
-
- block_input ();
-
- for (p = image_types; p; p = p->next)
- if (p->type == new_type)
- goto done;
-
- if (type->init)
- {
-#if defined HAVE_NTGUI && defined WINDOWSNT
- /* If we failed to load the library before, don't try again. */
- Lisp_Object tested = Fassq (builtin_lisp_symbol (new_type),
- Vlibrary_cache);
- if (CONSP (tested) && NILP (XCDR (tested)))
- type_valid = false;
- else
-#endif
- {
- type_valid = type->init ();
- CACHE_IMAGE_TYPE (builtin_lisp_symbol (new_type),
- type_valid ? Qt : Qnil);
- }
- }
-
- if (type_valid)
- {
- /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
- The initialized data segment is read-only. */
- p = xmalloc (sizeof *p);
- *p = *type;
- p->next = image_types;
- image_types = p;
- }
-
- done:
- unblock_input ();
- return p;
+ Vimage_types = Fcons (type, Vimage_types);
}
@@ -637,29 +586,24 @@ define_image_type (struct image_type *type)
bool
valid_image_p (Lisp_Object object)
{
- bool valid_p = 0;
-
if (IMAGEP (object))
{
- Lisp_Object tem;
-
- for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem))
- if (EQ (XCAR (tem), QCtype))
+ Lisp_Object tail = XCDR (object);
+ FOR_EACH_TAIL_SAFE (tail)
+ if (EQ (XCAR (tail), QCtype))
{
- tem = XCDR (tem);
- if (CONSP (tem) && SYMBOLP (XCAR (tem)))
+ tail = XCDR (tail);
+ if (CONSP (tail))
{
- struct image_type *type;
- type = lookup_image_type (XCAR (tem));
+ struct image_type const *type = lookup_image_type (XCAR (tail));
if (type)
- valid_p = type->valid_p (object);
+ return type->valid_p (object);
}
-
break;
}
}
- return valid_p;
+ return false;
}
@@ -1134,10 +1078,10 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
#ifdef USE_CAIRO
static uint32_t
-xcolor_to_argb32 (XColor xc)
+emacs_color_to_argb32 (Emacs_Color *ec)
{
- return ((0xffu << 24) | ((xc.red / 256) << 16)
- | ((xc.green / 256) << 8) | (xc.blue / 256));
+ return ((0xffu << 24) | ((ec->red / 256) << 16)
+ | ((ec->green / 256) << 8) | (ec->blue / 256));
}
static uint32_t
@@ -1145,11 +1089,11 @@ get_spec_bg_or_alpha_as_argb (struct image *img,
struct frame *f)
{
uint32_t bgcolor = 0;
- XColor xbgcolor;
+ Emacs_Color xbgcolor;
Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL);
if (STRINGP (bg) && x_parse_color (f, SSDATA (bg), &xbgcolor))
- bgcolor = xcolor_to_argb32 (xbgcolor);
+ bgcolor = emacs_color_to_argb32 (&xbgcolor);
return bgcolor;
}
@@ -1179,10 +1123,10 @@ set_cairo_image_surface (struct image *img, cairo_surface_t *surface)
/* Image background colors. */
/* Find the "best" corner color of a bitmap.
- On W32, XIMG is assumed to a device context with the bitmap selected. */
+ On W32, PIMG is assumed to a device context with the bitmap selected. */
static RGB_PIXEL_COLOR
-four_corners_best (XImagePtr_or_DC ximg, int *corners,
+four_corners_best (Emacs_Pix_Context pimg, int *corners,
unsigned long width, unsigned long height)
{
RGB_PIXEL_COLOR corner_pixels[4];
@@ -1191,19 +1135,19 @@ four_corners_best (XImagePtr_or_DC ximg, int *corners,
if (corners && corners[BOT_CORNER] >= 0)
{
- /* Get the colors at the corner_pixels of ximg. */
- corner_pixels[0] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[TOP_CORNER]);
- corner_pixels[1] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
- corner_pixels[2] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
- corner_pixels[3] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
+ /* Get the colors at the corner_pixels of pimg. */
+ corner_pixels[0] = GET_PIXEL (pimg, corners[LEFT_CORNER], corners[TOP_CORNER]);
+ corner_pixels[1] = GET_PIXEL (pimg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
+ corner_pixels[2] = GET_PIXEL (pimg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
+ corner_pixels[3] = GET_PIXEL (pimg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
}
else
{
- /* Get the colors at the corner_pixels of ximg. */
- corner_pixels[0] = GET_PIXEL (ximg, 0, 0);
- corner_pixels[1] = GET_PIXEL (ximg, width - 1, 0);
- corner_pixels[2] = GET_PIXEL (ximg, width - 1, height - 1);
- corner_pixels[3] = GET_PIXEL (ximg, 0, height - 1);
+ /* Get the colors at the corner_pixels of pimg. */
+ corner_pixels[0] = GET_PIXEL (pimg, 0, 0);
+ corner_pixels[1] = GET_PIXEL (pimg, width - 1, 0);
+ corner_pixels[2] = GET_PIXEL (pimg, width - 1, height - 1);
+ corner_pixels[3] = GET_PIXEL (pimg, 0, height - 1);
}
/* Choose the most frequently found color as background. */
for (i = best_count = 0; i < 4; ++i)
@@ -1221,49 +1165,29 @@ four_corners_best (XImagePtr_or_DC ximg, int *corners,
return best;
}
-/* Portability macros */
-
-#ifdef HAVE_NTGUI
-
-#define Free_Pixmap(display, pixmap) \
- DeleteObject (pixmap)
-
-#elif defined (HAVE_NS)
-
-#define Free_Pixmap(display, pixmap) \
- ns_release_object (pixmap)
-
-#else
-
-#define Free_Pixmap(display, pixmap) \
- XFreePixmap (display, pixmap)
-
-#endif /* !HAVE_NTGUI && !HAVE_NS */
-
-
/* Return the `background' field of IMG. If IMG doesn't have one yet,
it is guessed heuristically. If non-zero, XIMG is an existing
- XImage object (or device context with the image selected on W32) to
- use for the heuristic. */
+ Emacs_Pix_Context object (device context with the image selected on
+ W32) to use for the heuristic. */
RGB_PIXEL_COLOR
-image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg)
+image_background (struct image *img, struct frame *f, Emacs_Pix_Context pimg)
{
if (! img->background_valid)
/* IMG doesn't have a background yet, try to guess a reasonable value. */
{
- bool free_ximg = !ximg;
+ bool free_pimg = !pimg;
#ifdef HAVE_NTGUI
HGDIOBJ prev;
#endif /* HAVE_NTGUI */
- if (free_ximg)
- ximg = image_get_x_image_or_dc (f, img, 0, &prev);
+ if (free_pimg)
+ pimg = image_get_x_image_or_dc (f, img, 0, &prev);
- img->background = four_corners_best (ximg, img->corners, img->width, img->height);
+ img->background = four_corners_best (pimg, img->corners, img->width, img->height);
- if (free_ximg)
- image_unget_x_image_or_dc (img, 0, ximg, prev);
+ if (free_pimg)
+ image_unget_x_image_or_dc (img, 0, pimg, prev);
img->background_valid = 1;
}
@@ -1273,10 +1197,12 @@ image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg)
/* Return the `background_transparent' field of IMG. If IMG doesn't
have one yet, it is guessed heuristically. If non-zero, MASK is an
- existing XImage object to use for the heuristic. */
+ existing Emacs_Pix_Context (XImage* on X) object to use for the
+ heuristic. */
int
-image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_DC mask)
+image_background_transparent (struct image *img, struct frame *f,
+ Emacs_Pix_Context mask)
{
if (! img->background_transparent_valid)
/* IMG doesn't have a background yet, try to guess a reasonable value. */
@@ -1328,7 +1254,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags)
{
if (img->pixmap)
{
- Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap);
+ FRAME_TERMINAL (f)->free_pixmap (f, img->pixmap);
img->pixmap = NO_PIXMAP;
/* NOTE (HAVE_NS): background color is NOT an indexed color! */
img->background_valid = 0;
@@ -1347,7 +1273,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags)
{
if (img->mask)
{
- Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
+ FRAME_TERMINAL (f)->free_pixmap (f, img->mask);
img->mask = NO_PIXMAP;
img->background_transparent_valid = 0;
}
@@ -1399,7 +1325,7 @@ static unsigned long
image_alloc_image_color (struct frame *f, struct image *img,
Lisp_Object color_name, unsigned long dflt)
{
- XColor color;
+ Emacs_Color color;
unsigned long result;
eassert (STRINGP (color_name));
@@ -2079,7 +2005,7 @@ mark_image_cache (struct image_cache *c)
WIDTH and HEIGHT must both be positive.
If XIMG is null, assume it is a bitmap. */
static bool
-image_check_image_size (XImagePtr ximg, int width, int height)
+image_check_image_size (Emacs_Pix_Container ximg, int width, int height)
{
#ifdef HAVE_X_WINDOWS
/* Respect Xlib's limits: it cannot deal with images that have more
@@ -2113,18 +2039,20 @@ image_check_image_size (XImagePtr ximg, int width, int height)
#endif
}
-/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
- frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
- Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
- via xmalloc. Print error messages via image_error if an error
- occurs. Value is true if successful.
+/* Create an Emacs_Pix_Container and a pixmap of size WIDTH x
+ HEIGHT for use on frame F. Set *PIMG and *PIXMAP to the
+ Emacs_Pix_Container and Emacs_Pixmap created. Set (*PIMG)->data
+ to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print
+ error messages via image_error if an error occurs. Value is true
+ if successful.
On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
should indicate the bit depth of the image. */
static bool
image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int depth,
- XImagePtr *ximg, Pixmap *pixmap, Picture *picture)
+ Emacs_Pix_Container *pimg,
+ Emacs_Pixmap *pixmap, Picture *picture)
{
#ifdef HAVE_X_WINDOWS
Display *display = FRAME_X_DISPLAY (f);
@@ -2135,33 +2063,33 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
if (depth <= 0)
depth = DefaultDepthOfScreen (screen);
- *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
+ *pimg = XCreateImage (display, DefaultVisualOfScreen (screen),
depth, ZPixmap, 0, NULL, width, height,
depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
- if (*ximg == NULL)
+ if (*pimg == NULL)
{
image_error ("Unable to allocate X image");
return 0;
}
- if (! image_check_image_size (*ximg, width, height))
+ if (! image_check_image_size (*pimg, width, height))
{
- image_destroy_x_image (*ximg);
- *ximg = NULL;
+ image_destroy_x_image (*pimg);
+ *pimg = NULL;
image_error ("Image too large (%dx%d)",
make_fixnum (width), make_fixnum (height));
return 0;
}
/* Allocate image raster. */
- (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
+ (*pimg)->data = xmalloc ((*pimg)->bytes_per_line * height);
/* Allocate a pixmap of the same size. */
*pixmap = XCreatePixmap (display, drawable, width, height, depth);
if (*pixmap == NO_PIXMAP)
{
- image_destroy_x_image (*ximg);
- *ximg = NULL;
+ image_destroy_x_image (*pimg);
+ *pimg = NULL;
image_error ("Unable to create X pixmap");
return 0;
}
@@ -2228,10 +2156,10 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
if (depth < 16)
palette_colors = 1 << (depth - 1);
- *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
+ *pimg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
- header = &(*ximg)->info.bmiHeader;
- memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
+ header = &(*pimg)->info.bmiHeader;
+ memset (&(*pimg)->info, 0, sizeof (BITMAPINFO));
header->biSize = sizeof (*header);
header->biWidth = width;
header->biHeight = -height; /* negative indicates a top-down bitmap. */
@@ -2243,10 +2171,10 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
/* TODO: fill in palette. */
if (depth == 1)
{
- (*ximg)->info.bmiColors[0].rgbBlue = 0;
- (*ximg)->info.bmiColors[0].rgbGreen = 0;
- (*ximg)->info.bmiColors[0].rgbRed = 0;
- (*ximg)->info.bmiColors[0].rgbReserved = 0;
+ (*pimg)->info.bmiColors[0].rgbBlue = 0;
+ (*pimg)->info.bmiColors[0].rgbGreen = 0;
+ (*pimg)->info.bmiColors[0].rgbRed = 0;
+ (*pimg)->info.bmiColors[0].rgbReserved = 0;
/* bmiColors is a variable-length array declared by w32api
headers as bmiColors[1], which triggers a warning under
-Warray-bounds; shut that up. */
@@ -2254,10 +2182,10 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
# pragma GCC push_options
# pragma GCC diagnostic ignored "-Warray-bounds"
# endif
- (*ximg)->info.bmiColors[1].rgbBlue = 255;
- (*ximg)->info.bmiColors[1].rgbGreen = 255;
- (*ximg)->info.bmiColors[1].rgbRed = 255;
- (*ximg)->info.bmiColors[1].rgbReserved = 0;
+ (*pimg)->info.bmiColors[1].rgbBlue = 255;
+ (*pimg)->info.bmiColors[1].rgbGreen = 255;
+ (*pimg)->info.bmiColors[1].rgbRed = 255;
+ (*pimg)->info.bmiColors[1].rgbReserved = 0;
# if GNUC_PREREQ (4, 4, 0)
# pragma GCC pop_options
# endif
@@ -2267,10 +2195,10 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
/* Create a DIBSection and raster array for the bitmap,
and store its handle in *pixmap. */
- *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
+ *pixmap = CreateDIBSection (hdc, &((*pimg)->info),
(depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
/* casting avoids a GCC warning */
- (void **)&((*ximg)->data), NULL, 0);
+ (void **)&((*pimg)->data), NULL, 0);
/* Realize display palette and garbage all frames. */
release_frame_dc (f, hdc);
@@ -2282,8 +2210,8 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
/* All system errors are < 10000, so the following is safe. */
XSETINT (errcode, err);
image_error ("Unable to create bitmap, error code %d", errcode);
- image_destroy_x_image (*ximg);
- *ximg = NULL;
+ image_destroy_x_image (*pimg);
+ *pimg = NULL;
return 0;
}
@@ -2295,69 +2223,70 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
*pixmap = ns_image_for_XPM (width, height, depth);
if (*pixmap == 0)
{
- *ximg = NULL;
+ *pimg = NULL;
image_error ("Unable to allocate NSImage for XPM pixmap");
return 0;
}
- *ximg = *pixmap;
+ *pimg = *pixmap;
return 1;
#endif
}
-/* Destroy XImage XIMG. Free XIMG->data. */
+/* Destroy Emacs_Pix_Container PIMG. Free data associated with PIMG. */
static void
-image_destroy_x_image (XImagePtr ximg)
+image_destroy_x_image (Emacs_Pix_Container pimg)
{
eassert (input_blocked_p ());
- if (ximg)
+ if (pimg)
{
#ifdef HAVE_X_WINDOWS
- xfree (ximg->data);
- ximg->data = NULL;
- XDestroyImage (ximg);
+ xfree (pimg->data);
+ pimg->data = NULL;
+ XDestroyImage (pimg);
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NTGUI
/* Data will be freed by DestroyObject. */
- ximg->data = NULL;
- xfree (ximg);
+ pimg->data = NULL;
+ xfree (pimg);
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
- ns_release_object (ximg);
+ ns_release_object (pimg);
#endif /* HAVE_NS */
}
}
-/* Put XImage XIMG into pixmap PIXMAP on frame F. WIDTH and HEIGHT
- are width and height of both the image and pixmap. */
+/* Put Emacs_Pix_Container PIMG into pixmap PIXMAP on frame F.
+ WIDTH and HEIGHT are width and height of both the image and
+ pixmap. */
static void
-gui_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap,
- int width, int height)
+gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
+ Emacs_Pixmap pixmap, int width, int height)
{
#ifdef HAVE_X_WINDOWS
GC gc;
eassert (input_blocked_p ());
gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
- XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0,
- ximg->width, ximg->height);
+ XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, pimg, 0, 0, 0, 0,
+ pimg->width, pimg->height);
XFreeGC (FRAME_X_DISPLAY (f), gc);
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NTGUI
#if 0 /* I don't think this is necessary looking at where it is used. */
HDC hdc = get_frame_dc (f);
- SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
+ SetDIBits (hdc, pixmap, 0, height, pimg->data, &(pimg->info), DIB_RGB_COLORS);
release_frame_dc (f, hdc);
#endif
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
- eassert (ximg == pixmap);
- ns_retain_object (ximg);
+ eassert (pimg == pixmap);
+ ns_retain_object (pimg);
#endif
}
@@ -2367,7 +2296,7 @@ gui_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap,
static bool
image_create_x_image_and_pixmap (struct frame *f, struct image *img,
int width, int height, int depth,
- XImagePtr *ximg, bool mask_p)
+ Emacs_Pix_Container *ximg, bool mask_p)
{
eassert ((!mask_p ? img->pixmap : img->mask) == NO_PIXMAP);
@@ -2380,14 +2309,14 @@ image_create_x_image_and_pixmap (struct frame *f, struct image *img,
picture);
}
-/* Put X image XIMG into image IMG on frame F, as a mask if and only
- if MASK_P. On X, this simply records XIMG on a member of IMG, so
+/* Put pixel image PIMG into image IMG on frame F, as a mask if and only
+ if MASK_P. On X, this simply records PIMG on a member of IMG, so
it can be put into the pixmap afterwards via image_sync_to_pixmaps.
- On the other platforms, it puts XIMG into the pixmap, then frees
- the X image and its buffer. */
+ On the other platforms, it puts PIMG into the pixmap, then frees
+ the pixel image and its buffer. */
static void
-image_put_x_image (struct frame *f, struct image *img, XImagePtr ximg,
+image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg,
bool mask_p)
{
#ifdef HAVE_X_WINDOWS
@@ -2435,12 +2364,12 @@ image_sync_to_pixmaps (struct frame *f, struct image *img)
currently selected GDI object into *PREV for future restoration by
image_unget_x_image_or_dc. */
-static XImagePtr_or_DC
+static HDC
image_get_x_image_or_dc (struct frame *f, struct image *img, bool mask_p,
HGDIOBJ *prev)
{
HDC frame_dc = get_frame_dc (f);
- XImagePtr_or_DC ximg = CreateCompatibleDC (frame_dc);
+ HDC ximg = CreateCompatibleDC (frame_dc);
release_frame_dc (f, frame_dc);
*prev = SelectObject (ximg, !mask_p ? img->pixmap : img->mask);
@@ -2450,7 +2379,7 @@ image_get_x_image_or_dc (struct frame *f, struct image *img, bool mask_p,
static void
image_unget_x_image_or_dc (struct image *img, bool mask_p,
- XImagePtr_or_DC ximg, HGDIOBJ prev)
+ HDC ximg, HGDIOBJ prev)
{
SelectObject (ximg, prev);
DeleteDC (ximg);
@@ -2459,11 +2388,11 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p,
/* Get the X image for IMG on frame F. The resulting X image data
should be treated as read-only at least on X. */
-static XImagePtr
+static Emacs_Pix_Container
image_get_x_image (struct frame *f, struct image *img, bool mask_p)
{
#ifdef HAVE_X_WINDOWS
- XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img;
+ XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
if (ximg_in_img)
return ximg_in_img;
@@ -2471,7 +2400,7 @@ image_get_x_image (struct frame *f, struct image *img, bool mask_p)
return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
0, 0, img->width, img->height, ~0, ZPixmap);
#elif defined (HAVE_NS)
- XImagePtr pixmap = !mask_p ? img->pixmap : img->mask;
+ Emacs_Pix_Container pixmap = !mask_p ? img->pixmap : img->mask;
ns_retain_object (pixmap);
return pixmap;
@@ -2479,10 +2408,10 @@ image_get_x_image (struct frame *f, struct image *img, bool mask_p)
}
static void
-image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg)
+image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg)
{
#ifdef HAVE_X_WINDOWS
- XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img;
+ XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
if (ximg_in_img)
eassert (ximg == ximg_in_img);
@@ -2595,8 +2524,6 @@ slurp_file (int fd, ptrdiff_t *size)
XBM images
***********************************************************************/
-static bool xbm_load (struct frame *f, struct image *img);
-static bool xbm_image_p (Lisp_Object object);
static bool xbm_file_p (Lisp_Object);
@@ -2640,18 +2567,6 @@ static const struct image_keyword xbm_format[XBM_LAST] =
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
-/* Structure describing the image type XBM. */
-
-static struct image_type xbm_type =
-{
- SYMBOL_INDEX (Qxbm),
- xbm_image_p,
- xbm_load,
- image_clear_image,
- NULL,
- NULL
-};
-
/* Tokens returned from xbm_scan. */
enum xbm_token
@@ -3377,13 +3292,6 @@ xbm_load (struct frame *f, struct image *img)
XPM images
***********************************************************************/
-#if defined (HAVE_XPM) || defined (HAVE_NS)
-
-static bool xpm_image_p (Lisp_Object object);
-static bool xpm_load (struct frame *f, struct image *img);
-
-#endif /* HAVE_XPM || HAVE_NS */
-
#ifdef HAVE_XPM
#ifdef HAVE_NTGUI
/* Indicate to xpm.h that we don't have Xlib. */
@@ -3445,24 +3353,6 @@ static const struct image_keyword xpm_format[XPM_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-#if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_xpm_functions (void);
-#else
-#define init_xpm_functions NULL
-#endif
-
-/* Structure describing the image type XPM. */
-
-static struct image_type xpm_type =
-{
- SYMBOL_INDEX (Qxpm),
- xpm_image_p,
- xpm_load,
- image_clear_image,
- init_xpm_functions,
- NULL
-};
-
#ifdef HAVE_X_WINDOWS
/* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
@@ -4318,7 +4208,7 @@ xpm_load_image (struct frame *f,
#ifndef HAVE_NS
bool have_mask = false;
#endif
- XImagePtr ximg = NULL, mask_img = NULL;
+ Emacs_Pix_Container ximg = NULL, mask_img = NULL;
#define match() \
LA1 = xpm_scan (&s, end, &beg, &len)
@@ -4403,7 +4293,7 @@ xpm_load_image (struct frame *f,
char *color, *max_color;
int key, next_key, max_key = 0;
Lisp_Object symbol_color = Qnil, color_val;
- XColor cdef;
+ Emacs_Color cdef;
expect (XPM_TK_STRING);
if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
@@ -4889,18 +4779,18 @@ static int laplace_matrix[9] = {
#define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
-/* On frame F, return an array of XColor structures describing image
- IMG->pixmap. Each XColor structure has its pixel color set. RGB_P
- means also fill the red/green/blue members of the XColor
- structures. Value is a pointer to the array of XColors structures,
+/* On frame F, return an array of Emacs_Color structures describing image
+ IMG->pixmap. Each Emacs_Color structure has its pixel color set. RGB_P
+ means also fill the red/green/blue members of the Emacs_Color
+ structures. Value is a pointer to the array of Emacs_Color structures,
allocated with xmalloc; it must be freed by the caller. */
-static XColor *
-image_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
+static Emacs_Color *
+image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
{
int x, y;
- XColor *colors, *p;
- XImagePtr_or_DC ximg;
+ Emacs_Color *colors, *p;
+ Emacs_Pix_Context ximg;
ptrdiff_t nbytes;
#ifdef HAVE_NTGUI
HGDIOBJ prev;
@@ -4915,13 +4805,13 @@ image_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
/* Get the X image or create a memory device context for IMG. */
ximg = image_get_x_image_or_dc (f, img, 0, &prev);
- /* Fill the `pixel' members of the XColor array. I wished there
+ /* Fill the `pixel' members of the Emacs_Color array. I wished there
were an easy and portable way to circumvent XGetPixel. */
p = colors;
for (y = 0; y < img->height; ++y)
{
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
- XColor *row = p;
+ Emacs_Color *row = p;
for (x = 0; x < img->width; ++x, ++p)
p->pixel = GET_PIXEL (ximg, x, y);
if (rgb_p)
@@ -4956,7 +4846,7 @@ image_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
stored in ximg->data. */
static void
-XPutPixel (XImagePtr ximg, int x, int y, COLORREF color)
+XPutPixel (XImage *ximg, int x, int y, COLORREF color)
{
int width = ximg->info.bmiHeader.biWidth;
unsigned char * pixel;
@@ -4995,16 +4885,16 @@ XPutPixel (XImagePtr ximg, int x, int y, COLORREF color)
#endif /* HAVE_NTGUI */
-/* Create IMG->pixmap from an array COLORS of XColor structures, whose
+/* Create IMG->pixmap from an array COLORS of Emacs_Color structures, whose
RGB members are set. F is the frame on which this all happens.
COLORS will be freed; an existing IMG->pixmap will be freed, too. */
static void
-image_from_xcolors (struct frame *f, struct image *img, XColor *colors)
+image_from_emacs_colors (struct frame *f, struct image *img, Emacs_Color *colors)
{
int x, y;
- XImagePtr oimg = NULL;
- XColor *p;
+ Emacs_Pix_Container oimg = NULL;
+ Emacs_Color *p;
init_color_table ();
@@ -5042,8 +4932,8 @@ static void
image_detect_edges (struct frame *f, struct image *img,
int *matrix, int color_adjust)
{
- XColor *colors = image_to_xcolors (f, img, 1);
- XColor *new, *p;
+ Emacs_Color *colors = image_to_emacs_colors (f, img, 1);
+ Emacs_Color *new, *p;
int x, y, i, sum;
ptrdiff_t nbytes;
@@ -5086,7 +4976,7 @@ image_detect_edges (struct frame *f, struct image *img,
for (xx = x - 1; xx < x + 2; ++xx, ++i)
if (matrix[i])
{
- XColor *t = COLOR (colors, xx, yy);
+ Emacs_Color *t = COLOR (colors, xx, yy);
r += matrix[i] * t->red;
g += matrix[i] * t->green;
b += matrix[i] * t->blue;
@@ -5100,7 +4990,7 @@ image_detect_edges (struct frame *f, struct image *img,
}
xfree (colors);
- image_from_xcolors (f, img, new);
+ image_from_emacs_colors (f, img, new);
#undef COLOR
}
@@ -5183,8 +5073,8 @@ image_disable_image (struct frame *f, struct image *img)
/* Color (or grayscale). Convert to gray, and equalize. Just
drawing such images with a stipple can look very odd, so
we're using this method instead. */
- XColor *colors = image_to_xcolors (f, img, 1);
- XColor *p, *end;
+ Emacs_Color *colors = image_to_emacs_colors (f, img, 1);
+ Emacs_Color *p, *end;
const int h = 15000;
const int l = 30000;
@@ -5197,7 +5087,7 @@ image_disable_image (struct frame *f, struct image *img)
p->red = p->green = p->blue = i2;
}
- image_from_xcolors (f, img, colors);
+ image_from_emacs_colors (f, img, colors);
}
/* Draw a cross over the disabled image, if we must or if we
@@ -5275,13 +5165,13 @@ static void
image_build_heuristic_mask (struct frame *f, struct image *img,
Lisp_Object how)
{
- XImagePtr_or_DC ximg;
+ Emacs_Pix_Context ximg;
#ifdef HAVE_NTGUI
HGDIOBJ prev;
char *mask_img;
int row_width;
#elif !defined HAVE_NS
- XImagePtr mask_img;
+ Emacs_Pix_Container mask_img;
#endif
int x, y;
bool use_img_background;
@@ -5384,9 +5274,6 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
PBM (mono, gray, color)
***********************************************************************/
-static bool pbm_image_p (Lisp_Object object);
-static bool pbm_load (struct frame *f, struct image *img);
-
/* Indices of image specification fields in gs_format, below. */
enum pbm_keyword_index
@@ -5423,19 +5310,6 @@ static const struct image_keyword pbm_format[PBM_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-/* Structure describing the image type `pbm'. */
-
-static struct image_type pbm_type =
-{
- SYMBOL_INDEX (Qpbm),
- pbm_image_p,
- pbm_load,
- image_clear_image,
- NULL,
- NULL
-};
-
-
/* Return true if OBJECT is a valid PBM image specification. */
static bool
@@ -5533,7 +5407,7 @@ pbm_load (struct frame *f, struct image *img)
char *contents = NULL;
char *end, *p;
#ifndef USE_CAIRO
- XImagePtr ximg;
+ Emacs_Pix_Container ximg;
#endif
specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -5655,7 +5529,7 @@ pbm_load (struct frame *f, struct image *img)
unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
#ifdef USE_CAIRO
- XColor xfg, xbg;
+ Emacs_Color xfg, xbg;
int fga32, bga32;
#endif
/* Parse the image specification. */
@@ -5675,7 +5549,7 @@ pbm_load (struct frame *f, struct image *img)
xfg.pixel = fg;
x_query_colors (f, &xfg, 1);
}
- fga32 = xcolor_to_argb32 (xfg);
+ fga32 = emacs_color_to_argb32 (&xfg);
if (! fmt[PBM_BACKGROUND].count
|| ! STRINGP (fmt[PBM_BACKGROUND].value)
@@ -5688,7 +5562,7 @@ pbm_load (struct frame *f, struct image *img)
xbg.pixel = bg;
x_query_colors (f, &xbg, 1);
}
- bga32 = xcolor_to_argb32 (xbg);
+ bga32 = emacs_color_to_argb32 (&xbg);
#else
if (fmt[PBM_FOREGROUND].count
&& STRINGP (fmt[PBM_FOREGROUND].value))
@@ -5833,7 +5707,7 @@ pbm_load (struct frame *f, struct image *img)
#else
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning. */
- IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
@@ -5854,11 +5728,6 @@ pbm_load (struct frame *f, struct image *img)
#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
-/* Function prototypes. */
-
-static bool png_image_p (Lisp_Object object);
-static bool png_load (struct frame *f, struct image *img);
-
/* Indices of image specification fields in png_format, below. */
enum png_keyword_index
@@ -5893,24 +5762,6 @@ static const struct image_keyword png_format[PNG_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-#if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_png_functions (void);
-#else
-#define init_png_functions NULL
-#endif
-
-/* Structure describing the image type `png'. */
-
-static struct image_type png_type =
-{
- SYMBOL_INDEX (Qpng),
- png_image_p,
- png_load,
- image_clear_image,
- init_png_functions,
- NULL
-};
-
/* Return true if OBJECT is a valid PNG image specification. */
static bool
@@ -5951,6 +5802,7 @@ DEF_DLL_FN (png_uint_32, png_get_valid, (png_structp, png_infop, png_uint_32));
DEF_DLL_FN (void, png_set_strip_16, (png_structp));
DEF_DLL_FN (void, png_set_expand, (png_structp));
DEF_DLL_FN (void, png_set_gray_to_rgb, (png_structp));
+DEF_DLL_FN (int, png_set_interlace_handling, (png_structp));
DEF_DLL_FN (void, png_set_background,
(png_structp, png_color_16p, int, int, double));
DEF_DLL_FN (png_uint_32, png_get_bKGD,
@@ -5989,6 +5841,7 @@ init_png_functions (void)
LOAD_DLL_FN (library, png_set_strip_16);
LOAD_DLL_FN (library, png_set_expand);
LOAD_DLL_FN (library, png_set_gray_to_rgb);
+ LOAD_DLL_FN (library, png_set_interlace_handling);
LOAD_DLL_FN (library, png_set_background);
LOAD_DLL_FN (library, png_get_bKGD);
LOAD_DLL_FN (library, png_read_update_info);
@@ -6024,6 +5877,7 @@ init_png_functions (void)
# undef png_set_background
# undef png_set_expand
# undef png_set_gray_to_rgb
+# undef png_set_interlace_handling
# undef png_set_longjmp_fn
# undef png_set_read_fn
# undef png_set_sig_bytes
@@ -6048,6 +5902,7 @@ init_png_functions (void)
# define png_set_background fn_png_set_background
# define png_set_expand fn_png_set_expand
# define png_set_gray_to_rgb fn_png_set_gray_to_rgb
+# define png_set_interlace_handling fn_png_set_interlace_handling
# define png_set_longjmp_fn fn_png_set_longjmp_fn
# define png_set_read_fn fn_png_set_read_fn
# define png_set_sig_bytes fn_png_set_sig_bytes
@@ -6178,7 +6033,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
cairo_surface_t *surface;
uint32_t *dataptr;
#else
- XImagePtr ximg, mask_img = NULL;
+ Emacs_Pix_Container ximg, mask_img = NULL;
#endif
/* Find out what file to load. */
@@ -6336,7 +6191,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
/* png_color_16 *image_bg; */
Lisp_Object specified_bg
= image_spec_value (img->spec, QCbackground, NULL);
- XColor color;
+ Emacs_Color color;
/* If the user specified a color, try to use it; if not, use the
current frame background, ignoring any default background
@@ -6362,7 +6217,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
}
}
- /* Update info structure. */
+ png_set_interlace_handling (png_ptr);
png_read_update_info (png_ptr, info_ptr);
/* Get number of channels. Valid values are 1 for grayscale images
@@ -6491,7 +6346,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
#else
/* Maybe fill in the background field while we have ximg handy.
Casting avoids a GCC warning. */
- IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
@@ -6501,7 +6356,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
{
/* Fill in the background_transparent field while we have the
mask handy. Casting avoids a GCC warning. */
- image_background_transparent (img, f, (XImagePtr_or_DC)mask_img);
+ image_background_transparent (img, f, (Emacs_Pix_Context)mask_img);
image_put_x_image (f, img, mask_img, 1);
}
@@ -6538,9 +6393,6 @@ png_load (struct frame *f, struct image *img)
#if defined (HAVE_JPEG) || defined (HAVE_NS)
-static bool jpeg_image_p (Lisp_Object object);
-static bool jpeg_load (struct frame *f, struct image *img);
-
/* Indices of image specification fields in gs_format, below. */
enum jpeg_keyword_index
@@ -6575,24 +6427,6 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-#if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_jpeg_functions (void);
-#else
-#define init_jpeg_functions NULL
-#endif
-
-/* Structure describing the image type `jpeg'. */
-
-static struct image_type jpeg_type =
-{
- SYMBOL_INDEX (Qjpeg),
- jpeg_image_p,
- jpeg_load,
- image_clear_image,
- init_jpeg_functions,
- NULL
-};
-
/* Return true if OBJECT is a valid JPEG image specification. */
static bool
@@ -6735,7 +6569,7 @@ my_error_exit (j_common_ptr cinfo)
/* Init source method for JPEG data source manager. Called by
- jpeg_read_header() before any data is actually read. See
+ jpeg_read_header before any data is actually read. See
libjpeg.doc from the JPEG lib distribution. */
static void
@@ -6745,7 +6579,7 @@ our_common_init_source (j_decompress_ptr cinfo)
/* Method to terminate data source. Called by
- jpeg_finish_decompress() after all data has been processed. */
+ jpeg_finish_decompress after all data has been processed. */
static void
our_common_term_source (j_decompress_ptr cinfo)
@@ -6942,7 +6776,7 @@ jpeg_load_body (struct frame *f, struct image *img,
int i, ir, ig, ib;
#ifndef USE_CAIRO
unsigned long *colors;
- XImagePtr ximg = NULL;
+ Emacs_Pix_Container ximg = NULL;
#endif
/* Open the JPEG file. */
@@ -7132,7 +6966,7 @@ jpeg_load_body (struct frame *f, struct image *img,
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning. */
- IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
@@ -7170,9 +7004,6 @@ jpeg_load (struct frame *f, struct image *img)
#if defined (HAVE_TIFF) || defined (HAVE_NS)
-static bool tiff_image_p (Lisp_Object object);
-static bool tiff_load (struct frame *f, struct image *img);
-
/* Indices of image specification fields in tiff_format, below. */
enum tiff_keyword_index
@@ -7209,24 +7040,6 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
{":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
};
-#if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_tiff_functions (void);
-#else
-#define init_tiff_functions NULL
-#endif
-
-/* Structure describing the image type `tiff'. */
-
-static struct image_type tiff_type =
-{
- SYMBOL_INDEX (Qtiff),
- tiff_image_p,
- tiff_load,
- image_clear_image,
- init_tiff_functions,
- NULL
-};
-
/* Return true if OBJECT is a valid TIFF image specification. */
static bool
@@ -7453,7 +7266,7 @@ tiff_load (struct frame *f, struct image *img)
int width, height, x, y, count;
uint32 *buf;
int rc;
- XImagePtr ximg;
+ Emacs_Pix_Container ximg;
tiff_memory_source memsrc;
Lisp_Object image;
@@ -7623,7 +7436,7 @@ tiff_load (struct frame *f, struct image *img)
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning on W32. */
- IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
@@ -7654,10 +7467,6 @@ tiff_load (struct frame *f, struct image *img)
#if defined (HAVE_GIF) || defined (HAVE_NS)
-static bool gif_image_p (Lisp_Object object);
-static bool gif_load (struct frame *f, struct image *img);
-static void gif_clear_image (struct frame *f, struct image *img);
-
/* Indices of image specification fields in gif_format, below. */
enum gif_keyword_index
@@ -7694,24 +7503,6 @@ static const struct image_keyword gif_format[GIF_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-#if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_gif_functions (void);
-#else
-#define init_gif_functions NULL
-#endif
-
-/* Structure describing the image type `gif'. */
-
-static struct image_type gif_type =
-{
- SYMBOL_INDEX (Qgif),
- gif_image_p,
- gif_load,
- gif_clear_image,
- init_gif_functions,
- NULL
-};
-
/* Free X resources of GIF image IMG which is used on frame F. */
static void
@@ -8033,7 +7824,7 @@ gif_load (struct frame *f, struct image *img)
uint32_t *data32 = (uint32_t *) cairo_image_surface_get_data (surface);
if (STRINGP (specified_bg))
{
- XColor color;
+ Emacs_Color color;
if (FRAME_TERMINAL (f)->defined_color_hook
(f, SSDATA (specified_bg), &color, false, false))
{
@@ -8049,7 +7840,7 @@ gif_load (struct frame *f, struct image *img)
}
#else
/* Create the X image and pixmap. */
- XImagePtr ximg;
+ Emacs_Pix_Container ximg;
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
{
gif_close (gif, NULL);
@@ -8279,7 +8070,7 @@ gif_load (struct frame *f, struct image *img)
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning. */
- IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
@@ -8309,10 +8100,6 @@ gif_load (struct frame *f, struct image *img)
ImageMagick
***********************************************************************/
-static bool imagemagick_image_p (Lisp_Object);
-static bool imagemagick_load (struct frame *, struct image *);
-static void imagemagick_clear_image (struct frame *, struct image *);
-
/* Indices of image specification fields in imagemagick_format. */
enum imagemagick_keyword_index
@@ -8361,25 +8148,6 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
{":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
-#if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_imagemagick_functions (void);
-#else
-#define init_imagemagick_functions NULL
-#endif
-
-/* Structure describing the image type for any image handled via
- ImageMagick. */
-
-static struct image_type imagemagick_type =
- {
- SYMBOL_INDEX (Qimagemagick),
- imagemagick_image_p,
- imagemagick_load,
- imagemagick_clear_image,
- init_imagemagick_functions,
- NULL
- };
-
/* Free X resources of imagemagick image IMG which is used on frame F. */
static void
@@ -8686,7 +8454,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
size_t image_width, image_height;
MagickBooleanType status;
#ifndef USE_CAIRO
- XImagePtr ximg;
+ Emacs_Pix_Container ximg;
#endif
int x, y;
MagickWand *image_wand;
@@ -8791,7 +8559,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
/* Retrieve the frame's background color, for use later. */
{
- XColor bgcolor;
+ Emacs_Color bgcolor;
Lisp_Object specified_bg;
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
@@ -9157,9 +8925,6 @@ and `imagemagick-types-inhibit'. */)
/* Function prototypes. */
-static bool svg_image_p (Lisp_Object object);
-static bool svg_load (struct frame *f, struct image *img);
-
static bool svg_load_image (struct frame *, struct image *,
char *, ptrdiff_t, char *);
@@ -9197,27 +8962,6 @@ static const struct image_keyword svg_format[SVG_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-# if defined HAVE_NTGUI && defined WINDOWSNT
-static bool init_svg_functions (void);
-# else
-#define init_svg_functions NULL
-# endif
-
-/* Structure describing the image type `svg'. Its the same type of
- structure defined for all image formats, handled by emacs image
- functions. See struct image_type in dispextern.h. */
-
-static struct image_type svg_type =
-{
- SYMBOL_INDEX (Qsvg),
- svg_image_p,
- svg_load,
- image_clear_image,
- init_svg_functions,
- NULL
-};
-
-
/* Return true if OBJECT is a valid SVG image specification. Do
this by calling parse_image_spec and supplying the keywords that
identify the SVG format. */
@@ -9248,6 +8992,11 @@ svg_image_p (Lisp_Object object)
# include <librsvg/rsvg.h>
+/* librsvg is too old for us if it doesn't define this macro. */
+# ifndef LIBRSVG_CHECK_VERSION
+# define LIBRSVG_CHECK_VERSION(v, w, x) false
+# endif
+
# ifdef WINDOWSNT
/* Restore the original definition of __MINGW_MAJOR_VERSION. */
@@ -9456,7 +9205,18 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
<https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
if (filename)
- rsvg_handle_set_base_uri(rsvg_handle, filename);
+ rsvg_handle_set_base_uri (rsvg_handle, filename);
+
+ /* Suppress GCC deprecation warnings starting in librsvg 2.45.1 for
+ rsvg_handle_write and rsvg_handle_close. FIXME: Use functions
+ like rsvg_handle_new_from_gfile_sync on newer librsvg versions,
+ and remove this hack. */
+ #if GNUC_PREREQ (4, 6, 0)
+ #pragma GCC diagnostic push
+ #endif
+ #if LIBRSVG_CHECK_VERSION (2, 45, 1) && GNUC_PREREQ (4, 2, 0)
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ #endif
/* Parse the contents argument and fill in the rsvg_handle. */
rsvg_handle_write (rsvg_handle, (unsigned char *) contents, size, &err);
@@ -9467,6 +9227,10 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
rsvg_handle_close (rsvg_handle, &err);
if (err) goto rsvg_error;
+ #if GNUC_PREREQ (4, 6, 0)
+ #pragma GCC diagnostic pop
+ #endif
+
rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
if (! check_image_size (f, dimension_data.width, dimension_data.height))
{
@@ -9521,7 +9285,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
g_object_unref (pixbuf);
#else
/* Try to create a x pixmap to hold the svg pixmap. */
- XImagePtr ximg;
+ Emacs_Pix_Container ximg;
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
{
g_object_unref (pixbuf);
@@ -9532,7 +9296,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
/* Handle alpha channel by combining the image with a background
color. */
- XColor background;
+ Emacs_Color background;
Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
if (!STRINGP (specified_bg)
|| !FRAME_TERMINAL (f)->defined_color_hook (f,
@@ -9588,7 +9352,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
/* Maybe fill in the background field while we have ximg handy.
Casting avoids a GCC warning. */
- IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
+ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
@@ -9621,10 +9385,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
#ifdef HAVE_GHOSTSCRIPT
-static bool gs_image_p (Lisp_Object object);
-static bool gs_load (struct frame *f, struct image *img);
-static void gs_clear_image (struct frame *f, struct image *img);
-
/* Indices of image specification fields in gs_format, below. */
enum gs_keyword_index
@@ -9665,28 +9425,6 @@ static const struct image_keyword gs_format[GS_LAST] =
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
-/* Structure describing the image type `ghostscript'. */
-
-static struct image_type gs_type =
-{
- SYMBOL_INDEX (Qpostscript),
- gs_image_p,
- gs_load,
- gs_clear_image,
- NULL,
- NULL
-};
-
-
-/* Free X resources of Ghostscript image IMG which is used on frame F. */
-
-static void
-gs_clear_image (struct frame *f, struct image *img)
-{
- image_clear_image (f, img);
-}
-
-
/* Return true if OBJECT is a valid Ghostscript image
specification. */
@@ -9812,7 +9550,7 @@ gs_load (struct frame *f, struct image *img)
telling Emacs that Ghostscript has finished drawing. */
void
-x_kill_gs_process (Pixmap pixmap, struct frame *f)
+x_kill_gs_process (Emacs_Pixmap pixmap, struct frame *f)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
ptrdiff_t i;
@@ -9842,7 +9580,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
img->pixmap. */
if (x_mutable_colormap (FRAME_X_VISUAL (f)))
{
- XImagePtr ximg;
+ XImage *ximg;
block_input ();
@@ -9965,87 +9703,86 @@ the library file(s) specified by `dynamic-library-alist'. */)
return lookup_image_type (type) ? Qt : Qnil;
}
-/* Look up image type TYPE, and return a pointer to its image_type
- structure. Return 0 if TYPE is not a known image type. */
-
-static struct image_type *
-lookup_image_type (Lisp_Object type)
+static bool
+initialize_image_type (struct image_type const *type)
{
- /* Types pbm and xbm are built-in and always available. */
- if (EQ (type, Qpbm))
- return define_image_type (&pbm_type);
-
- if (EQ (type, Qxbm))
- return define_image_type (&xbm_type);
+#ifdef WINDOWSNT
+ Lisp_Object typesym = builtin_lisp_symbol (type->type);
+ Lisp_Object tested = Fassq (typesym, Vlibrary_cache);
+ /* If we failed to load the library before, don't try again. */
+ if (CONSP (tested))
+ return !NILP (XCDR (tested)) ? true : false;
-#if defined (HAVE_XPM) || defined (HAVE_NS)
- if (EQ (type, Qxpm))
- return define_image_type (&xpm_type);
+ bool (*init) (void) = type->init;
+ if (init)
+ {
+ bool type_valid = init ();
+ Vlibrary_cache = Fcons (Fcons (typesym, type_valid ? Qt : Qnil),
+ Vlibrary_cache);
+ return type_valid;
+ }
#endif
+ return true;
+}
-#if defined (HAVE_JPEG) || defined (HAVE_NS)
- if (EQ (type, Qjpeg))
- return define_image_type (&jpeg_type);
-#endif
+/* Array of supported image types. */
-#if defined (HAVE_TIFF) || defined (HAVE_NS)
- if (EQ (type, Qtiff))
- return define_image_type (&tiff_type);
+static struct image_type const image_types[] =
+{
+#ifdef HAVE_GHOSTSCRIPT
+ { SYMBOL_INDEX (Qpostscript), gs_image_p, gs_load, image_clear_image },
#endif
-
-#if defined (HAVE_GIF) || defined (HAVE_NS)
- if (EQ (type, Qgif))
- return define_image_type (&gif_type);
+#ifdef HAVE_IMAGEMAGICK
+ { SYMBOL_INDEX (Qimagemagick), imagemagick_image_p, imagemagick_load,
+ imagemagick_clear_image },
#endif
-
-#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
- if (EQ (type, Qpng))
- return define_image_type (&png_type);
+#ifdef HAVE_RSVG
+ { SYMBOL_INDEX (Qsvg), svg_image_p, svg_load, image_clear_image,
+ IMAGE_TYPE_INIT (init_svg_functions) },
#endif
-
-#if defined (HAVE_RSVG)
- if (EQ (type, Qsvg))
- return define_image_type (&svg_type);
+#if defined HAVE_PNG || defined HAVE_NS || defined USE_CAIRO
+ { SYMBOL_INDEX (Qpng), png_image_p, png_load, image_clear_image,
+ IMAGE_TYPE_INIT (init_png_functions) },
#endif
-
-#if defined (HAVE_IMAGEMAGICK)
- if (EQ (type, Qimagemagick))
- return define_image_type (&imagemagick_type);
+#if defined HAVE_GIF || defined HAVE_NS
+ { SYMBOL_INDEX (Qgif), gif_image_p, gif_load, gif_clear_image,
+ IMAGE_TYPE_INIT (init_gif_functions) },
#endif
-
-#ifdef HAVE_GHOSTSCRIPT
- if (EQ (type, Qpostscript))
- return define_image_type (&gs_type);
+#if defined HAVE_TIFF || defined HAVE_NS
+ { SYMBOL_INDEX (Qtiff), tiff_image_p, tiff_load, image_clear_image,
+ IMAGE_TYPE_INIT (init_tiff_functions) },
#endif
+#if defined HAVE_JPEG || defined HAVE_NS
+ { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image,
+ IMAGE_TYPE_INIT (init_jpeg_functions) },
+#endif
+#if defined HAVE_XPM || defined HAVE_NS
+ { SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
+ IMAGE_TYPE_INIT (init_xpm_functions) },
+#endif
+ { SYMBOL_INDEX (Qxbm), xbm_image_p, xbm_load, image_clear_image },
+ { SYMBOL_INDEX (Qpbm), pbm_image_p, pbm_load, image_clear_image },
+};
- return NULL;
-}
-
-#if defined HAVE_UNEXEC && defined HAVE_WINDOW_SYSTEM
-
-/* Reset image_types before dumping.
- Called from Fdump_emacs. */
+/* Look up image type TYPE, and return a pointer to its image_type
+ structure. Return 0 if TYPE is not a known image type. */
-void
-reset_image_types (void)
+static struct image_type const *
+lookup_image_type (Lisp_Object type)
{
- while (image_types)
+ for (int i = 0; i < ARRAYELTS (image_types); i++)
{
- struct image_type *next = image_types->next;
- xfree (image_types);
- image_types = next;
+ struct image_type const *r = &image_types[i];
+ if (EQ (type, builtin_lisp_symbol (r->type)))
+ return initialize_image_type (r) ? r : NULL;
}
+ return NULL;
}
-#endif
+
void
syms_of_image (void)
{
- /* Initialize this only once; it will be reset before dumping. */
- /* The portable dumper will just leave it NULL, so no need to reset. */
- image_types = NULL;
- PDUMPER_IGNORE (image_types);
-
/* Must be defined now because we're going to update it below, while
defining the supported image types. */
DEFVAR_LISP ("image-types", Vimage_types,
@@ -10096,7 +9833,7 @@ non-numeric, there is no explicit limit on the size of images. */);
DEFSYM (QCmax_width, ":max-width");
DEFSYM (QCmax_height, ":max-height");
#ifdef HAVE_GHOSTSCRIPT
- ADD_IMAGE_TYPE (Qpostscript);
+ add_image_type (Qpostscript);
DEFSYM (QCloader, ":loader");
DEFSYM (QCpt_width, ":pt-width");
DEFSYM (QCpt_height, ":pt-height");
@@ -10136,44 +9873,44 @@ non-numeric, there is no explicit limit on the size of images. */);
#endif
DEFSYM (Qpbm, "pbm");
- ADD_IMAGE_TYPE (Qpbm);
+ add_image_type (Qpbm);
DEFSYM (Qxbm, "xbm");
- ADD_IMAGE_TYPE (Qxbm);
+ add_image_type (Qxbm);
#if defined (HAVE_XPM) || defined (HAVE_NS)
DEFSYM (Qxpm, "xpm");
- ADD_IMAGE_TYPE (Qxpm);
+ add_image_type (Qxpm);
#endif
#if defined (HAVE_JPEG) || defined (HAVE_NS)
DEFSYM (Qjpeg, "jpeg");
- ADD_IMAGE_TYPE (Qjpeg);
+ add_image_type (Qjpeg);
#endif
#if defined (HAVE_TIFF) || defined (HAVE_NS)
DEFSYM (Qtiff, "tiff");
- ADD_IMAGE_TYPE (Qtiff);
+ add_image_type (Qtiff);
#endif
#if defined (HAVE_GIF) || defined (HAVE_NS)
DEFSYM (Qgif, "gif");
- ADD_IMAGE_TYPE (Qgif);
+ add_image_type (Qgif);
#endif
#if defined (HAVE_PNG) || defined (HAVE_NS)
DEFSYM (Qpng, "png");
- ADD_IMAGE_TYPE (Qpng);
+ add_image_type (Qpng);
#endif
#if defined (HAVE_IMAGEMAGICK)
DEFSYM (Qimagemagick, "imagemagick");
- ADD_IMAGE_TYPE (Qimagemagick);
+ add_image_type (Qimagemagick);
#endif
#if defined (HAVE_RSVG)
DEFSYM (Qsvg, "svg");
- ADD_IMAGE_TYPE (Qsvg);
+ add_image_type (Qsvg);
#ifdef HAVE_NTGUI
/* Other libraries used directly by svg code. */
DEFSYM (Qgdk_pixbuf, "gdk-pixbuf");
diff --git a/src/indent.c b/src/indent.c
index a022ae9fa32..f0d709e38b3 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -983,9 +983,10 @@ If specified column is within a character, point goes after that character.
If it's past end of line, point goes to end of line.
Optional second argument FORCE non-nil means if COLUMN is in the
-middle of a tab character, change it to spaces.
-In addition, if FORCE is t, and the line is too short to reach
-COLUMN, add spaces/tabs to get there.
+middle of a tab character, either change it to spaces (when
+`indent-tabs-mode' is nil), or insert enough spaces before it to reach
+COLUMN (otherwise). In addition, if FORCE is t, and the line is too short
+to reach COLUMN, add spaces/tabs to get there.
The return value is the current column. */)
(Lisp_Object column, Lisp_Object force)
diff --git a/src/insdel.c b/src/insdel.c
index 1231bb2682b..85fffd8fd16 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -2178,6 +2178,7 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
{
ptrdiff_t count = SPECPDL_INDEX ();
struct rvoe_arg rvoe_arg;
+ Lisp_Object tmp;
if (inhibit_modification_hooks)
return;
@@ -2186,7 +2187,16 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
and there are no before-change functions,
just record the args that we were going to use. */
if (! NILP (Vcombine_after_change_calls)
- && NILP (Vbefore_change_functions)
+ /* It's OK to defer after-changes even if syntax-ppss-flush-cache
+ * is on before-change-functions, which is common enough to be worth
+ * adding a special case for it. */
+ && (NILP (Vbefore_change_functions)
+ || (CONSP (Vbefore_change_functions)
+ && EQ (Qt, XCAR (Vbefore_change_functions))
+ && NILP (Fdefault_value (Qbefore_change_functions))
+ && CONSP (tmp = XCDR (Vbefore_change_functions))
+ && NILP (XCDR (tmp))
+ && EQ (XCAR (tmp), Qsyntax_ppss_flush_cache)))
&& !buffer_has_overlays ())
{
Lisp_Object elt;
@@ -2343,6 +2353,7 @@ syms_of_insdel (void)
combine_after_change_buffer = Qnil;
DEFSYM (Qundo_auto__undoable_change, "undo-auto--undoable-change");
+ DEFSYM (Qsyntax_ppss_flush_cache, "syntax-ppss-flush-cache");
DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
doc: /* Used internally by the function `combine-after-change-calls' macro. */);
diff --git a/src/intervals.c b/src/intervals.c
index 8f39c45762f..38367460a52 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2334,23 +2334,10 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
if (multi_flag)
{
- ptrdiff_t temp;
- left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i);
+ left_end_byte
+ = advance_to_char_boundary (start_byte + LEFT_TOTAL_LENGTH (i));
left_end = BYTE_TO_CHAR (left_end_byte);
-
- temp = CHAR_TO_BYTE (left_end);
-
- /* If LEFT_END_BYTE is in the middle of a character,
- adjust it and LEFT_END to a char boundary. */
- if (left_end_byte > temp)
- {
- left_end_byte = temp;
- }
- if (left_end_byte < temp)
- {
- left_end--;
- left_end_byte = CHAR_TO_BYTE (left_end);
- }
+ eassert (CHAR_TO_BYTE (left_end) == left_end_byte);
}
else
{
@@ -2367,24 +2354,10 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
if (multi_flag)
{
- ptrdiff_t temp;
-
- right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i);
+ right_start_byte
+ = advance_to_char_boundary (end_byte - RIGHT_TOTAL_LENGTH (i));
right_start = BYTE_TO_CHAR (right_start_byte);
-
- /* If RIGHT_START_BYTE is in the middle of a character,
- adjust it and RIGHT_START to a char boundary. */
- temp = CHAR_TO_BYTE (right_start);
-
- if (right_start_byte < temp)
- {
- right_start_byte = temp;
- }
- if (right_start_byte > temp)
- {
- right_start++;
- right_start_byte = CHAR_TO_BYTE (right_start);
- }
+ eassert (CHAR_TO_BYTE (right_start) == right_start_byte);
}
else
{
diff --git a/src/json.c b/src/json.c
index 03468e9f338..e2a4424463b 100644
--- a/src/json.c
+++ b/src/json.c
@@ -215,47 +215,11 @@ json_has_suffix (const char *string, const char *suffix)
#endif
-/* Create a multibyte Lisp string from the UTF-8 string in
- [DATA, DATA + SIZE). If the range [DATA, DATA + SIZE) does not
- contain a valid UTF-8 string, the returned string will include raw
- bytes.
- Note that all callers below either pass only value UTF-8 strings or
- use this function for formatting error messages; in the latter case
- correctness isn't critical. */
-
-static Lisp_Object
-json_make_string (const char *data, ptrdiff_t size)
-{
- ptrdiff_t chars, bytes;
- parse_str_as_multibyte ((const unsigned char *) data, size, &chars, &bytes);
- /* If DATA is a valid UTF-8 string, we can convert it to a Lisp
- string directly. Otherwise, we need to decode it. */
- if (chars == size || bytes == size)
- return make_specified_string (data, chars, size, true);
- else
- {
- struct coding_system coding;
- setup_coding_system (Qutf_8_unix, &coding);
- coding.mode |= CODING_MODE_LAST_BLOCK;
- coding.source = (const unsigned char *) data;
- decode_coding_object (&coding, Qnil, 0, 0, size, size, Qt);
- return coding.dst_object;
- }
-}
-
-/* Create a multibyte Lisp string from the NUL-terminated UTF-8
- string beginning at DATA. If the string is not a valid UTF-8
- string, an unspecified string is returned. Note that all callers
- below either pass only value UTF-8 strings or use this function for
+/* Note that all callers of make_string_from_utf8 and build_string_from_utf8
+ below either pass only value UTF-8 strings or use the functionf for
formatting error messages; in the latter case correctness isn't
critical. */
-static Lisp_Object
-json_build_string (const char *data)
-{
- return json_make_string (data, strlen (data));
-}
-
/* Return a unibyte string containing the sequence of UTF-8 encoding
units of the UTF-8 representation of STRING. If STRING does not
represent a sequence of Unicode scalar values, return a string with
@@ -303,9 +267,11 @@ json_parse_error (const json_error_t *error)
symbol = Qjson_parse_error;
#endif
xsignal (symbol,
- list5 (json_build_string (error->text),
- json_build_string (error->source), INT_TO_INTEGER (error->line),
- INT_TO_INTEGER (error->column), INT_TO_INTEGER (error->position)));
+ list5 (build_string_from_utf8 (error->text),
+ build_string_from_utf8 (error->source),
+ INT_TO_INTEGER (error->line),
+ INT_TO_INTEGER (error->column),
+ INT_TO_INTEGER (error->position)));
}
static void
@@ -648,7 +614,7 @@ usage: (json-serialize OBJECT &rest ARGS) */)
json_out_of_memory ();
record_unwind_protect_ptr (json_free, string);
- return unbind_to (count, json_build_string (string));
+ return unbind_to (count, build_string_from_utf8 (string));
}
struct json_buffer_and_size
@@ -855,8 +821,8 @@ json_to_lisp (json_t *json, struct json_configuration *conf)
case JSON_REAL:
return make_float (json_real_value (json));
case JSON_STRING:
- return json_make_string (json_string_value (json),
- json_string_length (json));
+ return make_string_from_utf8 (json_string_value (json),
+ json_string_length (json));
case JSON_ARRAY:
{
if (++lisp_eval_depth > max_lisp_eval_depth)
@@ -915,7 +881,7 @@ json_to_lisp (json_t *json, struct json_configuration *conf)
json_t *value;
json_object_foreach (json, key_str, value)
{
- Lisp_Object key = json_build_string (key_str);
+ Lisp_Object key = build_string_from_utf8 (key_str);
EMACS_UINT hash;
ptrdiff_t i = hash_lookup (h, key, &hash);
/* Keys in JSON objects are unique, so the key can't
@@ -932,7 +898,8 @@ json_to_lisp (json_t *json, struct json_configuration *conf)
json_t *value;
json_object_foreach (json, key_str, value)
{
- Lisp_Object key = Fintern (json_build_string (key_str), Qnil);
+ Lisp_Object key
+ = Fintern (build_string_from_utf8 (key_str), Qnil);
result
= Fcons (Fcons (key, json_to_lisp (value, conf)),
result);
diff --git a/src/keyboard.c b/src/keyboard.c
index ea13c7f5bcd..bb4d185c914 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3909,7 +3909,7 @@ kbd_buffer_get_event (KBOARD **kbp,
case END_SESSION_EVENT:
case LANGUAGE_CHANGE_EVENT:
#endif
-#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (HAVE_NS)
+#ifdef HAVE_WINDOW_SYSTEM
case DELETE_WINDOW_EVENT:
case ICONIFY_EVENT:
case DEICONIFY_EVENT:
@@ -5283,7 +5283,7 @@ make_lispy_event (struct input_event *event)
switch (event->kind)
{
-#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (HAVE_NS)
+#ifdef HAVE_WINDOW_SYSTEM
case DELETE_WINDOW_EVENT:
/* Make an event (delete-frame (FRAME)). */
return list2 (Qdelete_frame, list1 (event->frame_or_window));
@@ -9968,7 +9968,7 @@ If CHECK-TIMERS is non-nil, timers that are ready to run will do so. */)
DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 1, 0,
doc: /* Return vector of last few events, not counting those from keyboard macros.
If INCLUDE-CMDS is non-nil, include the commands that were run,
-represented as events of the form (nil . COMMAND). */)
+represented as pseudo-events of the form (nil . COMMAND). */)
(Lisp_Object include_cmds)
{
bool cmds = !NILP (include_cmds);
diff --git a/src/lisp.h b/src/lisp.h
index ca833476c03..6db90596899 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -144,11 +144,13 @@ typedef intmax_t printmax_t;
typedef uintmax_t uprintmax_t;
# define pMd PRIdMAX
# define pMu PRIuMAX
+# define pMx PRIxMAX
#else
typedef EMACS_INT printmax_t;
typedef EMACS_UINT uprintmax_t;
# define pMd pI"d"
# define pMu pI"u"
+# define pMx pI"x"
#endif
/* Use pD to format ptrdiff_t values, which suffice for indexes into
@@ -2234,7 +2236,7 @@ INLINE int
}
/* Placeholder for make-docfile to process. The actual symbol
- definition is done by lread.c's defsym. */
+ definition is done by lread.c's define_symbol. */
#define DEFSYM(sym, name) /* empty */
@@ -2677,7 +2679,7 @@ struct Lisp_Buffer_Objfwd
{
enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Buffer_Obj */
int offset;
- /* One of Qnil, Qfixnump, Qsymbolp, Qstringp, Qfloatp or Qnumberp. */
+ /* One of Qnil, Qintegerp, Qsymbolp, Qstringp, Qfloatp or Qnumberp. */
Lisp_Object predicate;
};
@@ -3641,7 +3643,6 @@ extern void init_fringe_once (void);
/* Defined in image.c. */
extern int x_bitmap_mask (struct frame *, ptrdiff_t);
-extern void reset_image_types (void);
extern void syms_of_image (void);
#ifdef HAVE_JSON
diff --git a/src/lread.c b/src/lread.c
index 1c97805ca7a..5fa90cad3f3 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -44,6 +44,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "blockinput.h"
#include "pdumper.h"
#include <c-ctype.h>
+#include <vla.h>
#ifdef MSDOS
#include "msdos.h"
@@ -2640,90 +2641,83 @@ digit_to_number (int character, int base)
return digit < base ? digit : -1;
}
+static char const invalid_radix_integer_format[] = "integer, radix %"pI"d";
+
+/* Small, as read1 is recursive (Bug#31995). But big enough to hold
+ the invalid_radix_integer string. */
+enum { stackbufsize = max (64,
+ (sizeof invalid_radix_integer_format
+ - sizeof "%"pI"d"
+ + INT_STRLEN_BOUND (EMACS_INT) + 1)) };
+
static void
-free_contents (void *p)
+invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)])
{
- void **ptr = (void **) p;
- xfree (*ptr);
+ sprintf (stackbuf, invalid_radix_integer_format, radix);
+ invalid_syntax (stackbuf);
}
/* Read an integer in radix RADIX using READCHARFUN to read
- characters. RADIX must be in the interval [2..36]; if it isn't, a
- read error is signaled . Value is the integer read. Signals an
- error if encountering invalid read syntax or if RADIX is out of
- range. */
+ characters. RADIX must be in the interval [2..36]. Use STACKBUF
+ for temporary storage as needed. Value is the integer read.
+ Signal an error if encountering invalid read syntax. */
static Lisp_Object
-read_integer (Lisp_Object readcharfun, EMACS_INT radix)
+read_integer (Lisp_Object readcharfun, int radix,
+ char stackbuf[VLA_ELEMS (stackbufsize)])
{
- /* Room for sign, leading 0, other digits, trailing NUL byte.
- Also, room for invalid syntax diagnostic. */
- size_t len = max (1 + 1 + UINTMAX_WIDTH + 1,
- sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT));
- char *buf = NULL;
- char *p = buf;
+ char *read_buffer = stackbuf;
+ ptrdiff_t read_buffer_size = stackbufsize;
+ char *p = read_buffer;
+ char *heapbuf = NULL;
int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */
-
ptrdiff_t count = SPECPDL_INDEX ();
- if (radix < 2 || radix > 36)
- valid = 0;
- else
+ int c = READCHAR;
+ if (c == '-' || c == '+')
{
- int c, digit;
-
- buf = xmalloc (len);
- record_unwind_protect_ptr (free_contents, &buf);
- p = buf;
-
+ *p++ = c;
c = READCHAR;
- if (c == '-' || c == '+')
- {
- *p++ = c;
- c = READCHAR;
- }
+ }
- if (c == '0')
- {
- *p++ = c;
- valid = 1;
+ if (c == '0')
+ {
+ *p++ = c;
+ valid = 1;
- /* Ignore redundant leading zeros, so the buffer doesn't
- fill up with them. */
- do
- c = READCHAR;
- while (c == '0');
- }
+ /* Ignore redundant leading zeros, so the buffer doesn't
+ fill up with them. */
+ do
+ c = READCHAR;
+ while (c == '0');
+ }
- while ((digit = digit_to_number (c, radix)) >= -1)
+ for (int digit; (digit = digit_to_number (c, radix)) >= -1; )
+ {
+ if (digit == -1)
+ valid = 0;
+ if (valid < 0)
+ valid = 1;
+ /* Allow 1 extra byte for the \0. */
+ if (p + 1 == read_buffer + read_buffer_size)
{
- if (digit == -1)
- valid = 0;
- if (valid < 0)
- valid = 1;
- /* Allow 1 extra byte for the \0. */
- if (p + 1 == buf + len)
- {
- ptrdiff_t where = p - buf;
- len *= 2;
- buf = xrealloc (buf, len);
- p = buf + where;
- }
- *p++ = c;
- c = READCHAR;
+ ptrdiff_t offset = p - read_buffer;
+ read_buffer = grow_read_buffer (read_buffer, offset,
+ &heapbuf, &read_buffer_size,
+ count);
+ p = read_buffer + offset;
}
-
- UNREAD (c);
+ *p++ = c;
+ c = READCHAR;
}
+ UNREAD (c);
+
if (valid != 1)
- {
- sprintf (buf, "integer, radix %"pI"d", radix);
- invalid_syntax (buf);
- }
+ invalid_radix_integer (radix, stackbuf);
*p = '\0';
- return unbind_to (count, string_to_number (buf, radix, 0));
+ return unbind_to (count, string_to_number (read_buffer, radix, NULL));
}
@@ -2739,7 +2733,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
int c;
bool uninterned_symbol = false;
bool multibyte;
- char stackbuf[128]; /* Small, as read1 is recursive (Bug#31995). */
+ char stackbuf[stackbufsize];
current_thread->stack_top = stackbuf;
*pch = 0;
@@ -3109,30 +3103,34 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
/* ## is the empty symbol. */
if (c == '#')
return Fintern (empty_unibyte_string, Qnil);
- /* Reader forms that can reuse previously read objects. */
+
if (c >= '0' && c <= '9')
{
- EMACS_INT n = 0;
- Lisp_Object tem;
+ EMACS_INT n = c - '0';
bool overflow = false;
/* Read a non-negative integer. */
- while (c >= '0' && c <= '9')
+ while ('0' <= (c = READCHAR) && c <= '9')
{
overflow |= INT_MULTIPLY_WRAPV (n, 10, &n);
overflow |= INT_ADD_WRAPV (n, c - '0', &n);
- c = READCHAR;
}
- if (!overflow && n <= MOST_POSITIVE_FIXNUM)
+ if (!overflow)
{
if (c == 'r' || c == 'R')
- return read_integer (readcharfun, n);
+ {
+ if (! (2 <= n && n <= 36))
+ invalid_radix_integer (n, stackbuf);
+ return read_integer (readcharfun, n, stackbuf);
+ }
- if (! NILP (Vread_circle))
+ if (n <= MOST_POSITIVE_FIXNUM && ! NILP (Vread_circle))
{
+ /* Reader forms that can reuse previously read objects. */
+
/* #n=object returns object, but associates it with
- n for #n#. */
+ n for #n#. */
if (c == '=')
{
/* Make a placeholder for #n# to use temporarily. */
@@ -3161,7 +3159,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
hash_put (h, number, placeholder, hash);
/* Read the object itself. */
- tem = read0 (readcharfun);
+ Lisp_Object tem = read0 (readcharfun);
/* If it can be recursive, remember it for
future substitutions. */
@@ -3211,11 +3209,11 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
/* Fall through to error message. */
}
else if (c == 'x' || c == 'X')
- return read_integer (readcharfun, 16);
+ return read_integer (readcharfun, 16, stackbuf);
else if (c == 'o' || c == 'O')
- return read_integer (readcharfun, 8);
+ return read_integer (readcharfun, 8, stackbuf);
else if (c == 'b' || c == 'B')
- return read_integer (readcharfun, 2);
+ return read_integer (readcharfun, 2, stackbuf);
UNREAD (c);
invalid_syntax ("#");
diff --git a/src/macfont.m b/src/macfont.m
index 8fcbd50fe33..abdf0ecfe59 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -1647,7 +1647,7 @@ static Lisp_Object macfont_open (struct frame *, Lisp_Object, int);
static void macfont_close (struct font *);
static int macfont_has_char (Lisp_Object, int);
static unsigned macfont_encode_char (struct font *, int);
-static void macfont_text_extents (struct font *, unsigned int *, int,
+static void macfont_text_extents (struct font *, const unsigned int *, int,
struct font_metrics *);
static int macfont_draw (struct glyph_string *, int, int, int, int, bool);
static Lisp_Object macfont_shape (Lisp_Object, Lisp_Object);
@@ -2743,7 +2743,7 @@ macfont_encode_char (struct font *font, int c)
}
static void
-macfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
+macfont_text_extents (struct font *font, const unsigned int *code, int nglyphs,
struct font_metrics *metrics)
{
int width, i;
@@ -2826,7 +2826,18 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
}
}
- context = [[NSGraphicsContext currentContext] graphicsPort];
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+ if ([[NSGraphicsContext currentContext] respondsToSelector:@selector(CGContext)])
+#endif
+ context = [[NSGraphicsContext currentContext] CGContext];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+ else
+#endif
+#endif
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+ context = [[NSGraphicsContext currentContext] graphicsPort];
+#endif
CGContextSaveGState (context);
if (!CGRectIsNull (background_rect))
@@ -3005,7 +3016,7 @@ macfont_shape (Lisp_Object lgstring, Lisp_Object direction)
if (NILP (lglyph))
{
- lglyph = make_nil_vector (LGLYPH_SIZE);
+ lglyph = LGLYPH_NEW ();
LGSTRING_SET_GLYPH (lgstring, i, lglyph);
}
diff --git a/src/marker.c b/src/marker.c
index b58051a8c2b..0b2e1bf5c6b 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -332,6 +332,10 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos)
if (best_above == best_above_byte)
return bytepos;
+ /* Check bytepos is not in the middle of a character. */
+ eassert (bytepos >= BUF_Z_BYTE (b)
+ || CHAR_HEAD_P (BUF_FETCH_BYTE (b, bytepos)));
+
best_below = BEG;
best_below_byte = BEG_BYTE;
diff --git a/src/mini-gmp.c b/src/mini-gmp.c
index 90beb6e8327..88b71c3f9a6 100644
--- a/src/mini-gmp.c
+++ b/src/mini-gmp.c
@@ -2,7 +2,7 @@
Contributed to the GNU project by Niels Möller
-Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc.
+Copyright 1991-1997, 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -58,7 +58,7 @@ see https://www.gnu.org/licenses/. */
/* Macros */
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
-#define GMP_LIMB_MAX (~ (mp_limb_t) 0)
+#define GMP_LIMB_MAX ((mp_limb_t) ~ (mp_limb_t) 0)
#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1))
#define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2))
@@ -129,6 +129,20 @@ see https://www.gnu.org/licenses/. */
#define gmp_umul_ppmm(w1, w0, u, v) \
do { \
+ int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; \
+ if (sizeof(unsigned int) * CHAR_BIT >= 2 * GMP_LIMB_BITS) \
+ { \
+ unsigned int __ww = (unsigned int) (u) * (v); \
+ w0 = (mp_limb_t) __ww; \
+ w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \
+ } \
+ else if (GMP_ULONG_BITS >= 2 * GMP_LIMB_BITS) \
+ { \
+ unsigned long int __ww = (unsigned long int) (u) * (v); \
+ w0 = (mp_limb_t) __ww; \
+ w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \
+ } \
+ else { \
mp_limb_t __x0, __x1, __x2, __x3; \
unsigned __ul, __vl, __uh, __vh; \
mp_limb_t __u = (u), __v = (v); \
@@ -150,6 +164,7 @@ see https://www.gnu.org/licenses/. */
\
(w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \
(w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \
+ } \
} while (0)
#define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
@@ -753,6 +768,18 @@ mpn_neg (mp_ptr rp, mp_srcptr up, mp_size_t n)
mp_limb_t
mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
{
+ int GMP_LIMB_BITS_MUL_3 = GMP_LIMB_BITS * 3;
+ if (sizeof (unsigned) * CHAR_BIT > GMP_LIMB_BITS * 3)
+ {
+ return (((unsigned) 1 << GMP_LIMB_BITS_MUL_3) - 1) /
+ (((unsigned) u1 << GMP_LIMB_BITS_MUL_3 / 3) + u0);
+ }
+ else if (GMP_ULONG_BITS > GMP_LIMB_BITS * 3)
+ {
+ return (((unsigned long) 1 << GMP_LIMB_BITS_MUL_3) - 1) /
+ (((unsigned long) u1 << GMP_LIMB_BITS_MUL_3 / 3) + u0);
+ }
+ else {
mp_limb_t r, p, m, ql;
unsigned ul, uh, qh;
@@ -827,7 +854,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
r -= u1;
}
- /* Now m is the 2/1 invers of u1. If u0 > 0, adjust it to become a
+ /* Now m is the 2/1 inverse of u1. If u0 > 0, adjust it to become a
3/2 inverse. */
if (u0 > 0)
{
@@ -854,6 +881,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
}
return m;
+ }
}
struct gmp_div_inverse
@@ -964,36 +992,6 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,
return r >> inv->shift;
}
-static mp_limb_t
-mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d)
-{
- assert (d > 0);
-
- /* Special case for powers of two. */
- if ((d & (d-1)) == 0)
- {
- mp_limb_t r = np[0] & (d-1);
- if (qp)
- {
- if (d <= 1)
- mpn_copyi (qp, np, nn);
- else
- {
- unsigned shift;
- gmp_ctz (shift, d);
- mpn_rshift (qp, np, nn, shift);
- }
- }
- return r;
- }
- else
- {
- struct gmp_div_inverse inv;
- mpn_div_qr_1_invert (&inv, d);
- return mpn_div_qr_1_preinv (qp, np, nn, &inv);
- }
-}
-
static void
mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn,
const struct gmp_div_inverse *inv)
@@ -1029,7 +1027,7 @@ mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn,
if (shift > 0)
{
- assert ((r0 << (GMP_LIMB_BITS - shift)) == 0);
+ assert ((r0 & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - shift))) == 0);
r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift));
r1 >>= shift;
}
@@ -1252,7 +1250,7 @@ mpn_limb_get_str (unsigned char *sp, mp_limb_t w,
l = w << binv->shift;
gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di);
- assert ( (r << (GMP_LIMB_BITS - binv->shift)) == 0);
+ assert ((r & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - binv->shift))) == 0);
r >>= binv->shift;
sp[i] = r;
@@ -1420,7 +1418,7 @@ mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base)
void
mpz_init (mpz_t r)
{
- static const mp_limb_t dummy_limb = 0xc1a0;
+ static const mp_limb_t dummy_limb = GMP_LIMB_MAX & 0xc1a0;
r->_mp_alloc = 0;
r->_mp_size = 0;
@@ -1478,6 +1476,12 @@ mpz_set_si (mpz_t r, signed long int x)
if (x >= 0)
mpz_set_ui (r, x);
else /* (x < 0) */
+ if (GMP_LIMB_BITS < GMP_ULONG_BITS)
+ {
+ mpz_set_ui (r, GMP_NEG_CAST (unsigned long int, x));
+ mpz_neg (r, r);
+ }
+ else
{
r->_mp_size = -1;
MPZ_REALLOC (r, 1)[0] = GMP_NEG_CAST (unsigned long int, x);
@@ -1491,6 +1495,15 @@ mpz_set_ui (mpz_t r, unsigned long int x)
{
r->_mp_size = 1;
MPZ_REALLOC (r, 1)[0] = x;
+ if (GMP_LIMB_BITS < GMP_ULONG_BITS)
+ {
+ int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS;
+ while (x >>= LOCAL_GMP_LIMB_BITS)
+ {
+ ++ r->_mp_size;
+ MPZ_REALLOC (r, r->_mp_size)[r->_mp_size - 1] = x;
+ }
+ }
}
else
r->_mp_size = 0;
@@ -1537,14 +1550,20 @@ mpz_init_set (mpz_t r, const mpz_t x)
int
mpz_fits_slong_p (const mpz_t u)
{
- mp_size_t us = u->_mp_size;
+ return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) &&
+ mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0;
+}
- if (us == 1)
- return u->_mp_d[0] < GMP_LIMB_HIGHBIT;
- else if (us == -1)
- return u->_mp_d[0] <= GMP_LIMB_HIGHBIT;
- else
- return (us == 0);
+static int
+mpn_absfits_ulong_p (mp_srcptr up, mp_size_t un)
+{
+ int ulongsize = GMP_ULONG_BITS / GMP_LIMB_BITS;
+ mp_limb_t ulongrem = 0;
+
+ if (GMP_ULONG_BITS % GMP_LIMB_BITS != 0)
+ ulongrem = (mp_limb_t) (ULONG_MAX >> GMP_LIMB_BITS * ulongsize) + 1;
+
+ return un <= ulongsize || (up[ulongsize] < ulongrem && un == ulongsize + 1);
}
int
@@ -1552,22 +1571,36 @@ mpz_fits_ulong_p (const mpz_t u)
{
mp_size_t us = u->_mp_size;
- return (us == (us > 0));
+ return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us);
}
long int
mpz_get_si (const mpz_t u)
{
+ unsigned long r = mpz_get_ui (u);
+ unsigned long c = -LONG_MAX - LONG_MIN;
+
if (u->_mp_size < 0)
- /* This expression is necessary to properly handle 0x80000000 */
- return -1 - (long) ((u->_mp_d[0] - 1) & ~GMP_LIMB_HIGHBIT);
+ /* This expression is necessary to properly handle -LONG_MIN */
+ return -(long) c - (long) ((r - c) & LONG_MAX);
else
- return (long) (mpz_get_ui (u) & ~GMP_LIMB_HIGHBIT);
+ return (long) (r & LONG_MAX);
}
unsigned long int
mpz_get_ui (const mpz_t u)
{
+ if (GMP_LIMB_BITS < GMP_ULONG_BITS)
+ {
+ int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS;
+ unsigned long r = 0;
+ mp_size_t n = GMP_ABS (u->_mp_size);
+ n = GMP_MIN (n, 1 + (GMP_ULONG_BITS - 1) / GMP_LIMB_BITS);
+ while (--n >= 0)
+ r = (r << LOCAL_GMP_LIMB_BITS) + u->_mp_d[n];
+ return r;
+ }
+
return u->_mp_size == 0 ? 0 : u->_mp_d[0];
}
@@ -1665,7 +1698,7 @@ mpz_set_d (mpz_t r, double x)
r->_mp_size = 0;
return;
}
- B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+ B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1);
Bi = 1.0 / B;
for (rn = 1; x >= B; rn++)
x *= Bi;
@@ -1703,7 +1736,7 @@ mpz_get_d (const mpz_t u)
mp_limb_t l;
mp_size_t un;
double x;
- double B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+ double B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1);
un = GMP_ABS (u->_mp_size);
@@ -1748,7 +1781,7 @@ mpz_cmpabs_d (const mpz_t x, double d)
{
xn = GMP_ABS (xn);
- B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+ B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1);
Bi = 1.0 / B;
/* Scale d so it can be compared with the top limb. */
@@ -1807,14 +1840,12 @@ mpz_cmp_si (const mpz_t u, long v)
{
mp_size_t usize = u->_mp_size;
- if (usize < -1)
- return -1;
- else if (v >= 0)
+ if (v >= 0)
return mpz_cmp_ui (u, v);
else if (usize >= 0)
return 1;
- else /* usize == -1 */
- return GMP_CMP (GMP_NEG_CAST (mp_limb_t, v), u->_mp_d[0]);
+ else
+ return - mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, v));
}
int
@@ -1822,12 +1853,10 @@ mpz_cmp_ui (const mpz_t u, unsigned long v)
{
mp_size_t usize = u->_mp_size;
- if (usize > 1)
- return 1;
- else if (usize < 0)
+ if (usize < 0)
return -1;
else
- return GMP_CMP (mpz_get_ui (u), v);
+ return mpz_cmpabs_ui (u, v);
}
int
@@ -1847,10 +1876,15 @@ mpz_cmp (const mpz_t a, const mpz_t b)
int
mpz_cmpabs_ui (const mpz_t u, unsigned long v)
{
- if (GMP_ABS (u->_mp_size) > 1)
+ mp_size_t un = GMP_ABS (u->_mp_size);
+
+ if (! mpn_absfits_ulong_p (u->_mp_d, un))
return 1;
else
- return GMP_CMP (mpz_get_ui (u), v);
+ {
+ unsigned long uu = mpz_get_ui (u);
+ return GMP_CMP(uu, v);
+ }
}
int
@@ -1885,81 +1919,28 @@ mpz_swap (mpz_t u, mpz_t v)
/* MPZ addition and subtraction */
-/* Adds to the absolute value. Returns new size, but doesn't store it. */
-static mp_size_t
-mpz_abs_add_ui (mpz_t r, const mpz_t a, unsigned long b)
-{
- mp_size_t an;
- mp_ptr rp;
- mp_limb_t cy;
-
- an = GMP_ABS (a->_mp_size);
- if (an == 0)
- {
- MPZ_REALLOC (r, 1)[0] = b;
- return b > 0;
- }
-
- rp = MPZ_REALLOC (r, an + 1);
-
- cy = mpn_add_1 (rp, a->_mp_d, an, b);
- rp[an] = cy;
- an += cy;
-
- return an;
-}
-
-/* Subtract from the absolute value. Returns new size, (or -1 on underflow),
- but doesn't store it. */
-static mp_size_t
-mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
-{
- mp_size_t an = GMP_ABS (a->_mp_size);
- mp_ptr rp;
-
- if (an == 0)
- {
- MPZ_REALLOC (r, 1)[0] = b;
- return -(b > 0);
- }
- rp = MPZ_REALLOC (r, an);
- if (an == 1 && a->_mp_d[0] < b)
- {
- rp[0] = b - a->_mp_d[0];
- return -1;
- }
- else
- {
- gmp_assert_nocarry (mpn_sub_1 (rp, a->_mp_d, an, b));
- return mpn_normalized_size (rp, an);
- }
-}
void
mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b)
{
- if (a->_mp_size >= 0)
- r->_mp_size = mpz_abs_add_ui (r, a, b);
- else
- r->_mp_size = -mpz_abs_sub_ui (r, a, b);
+ mpz_t bb;
+ mpz_init_set_ui (bb, b);
+ mpz_add (r, a, bb);
+ mpz_clear (bb);
}
void
mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
{
- if (a->_mp_size < 0)
- r->_mp_size = -mpz_abs_add_ui (r, a, b);
- else
- r->_mp_size = mpz_abs_sub_ui (r, a, b);
+ mpz_ui_sub (r, b, a);
+ mpz_neg (r, r);
}
void
mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b)
{
- if (b->_mp_size < 0)
- r->_mp_size = mpz_abs_add_ui (r, b, a);
- else
- r->_mp_size = -mpz_abs_sub_ui (r, b, a);
+ mpz_neg (r, b);
+ mpz_add_ui (r, r, a);
}
static mp_size_t
@@ -2046,32 +2027,17 @@ mpz_mul_si (mpz_t r, const mpz_t u, long int v)
mpz_neg (r, r);
}
else
- mpz_mul_ui (r, u, (unsigned long int) v);
+ mpz_mul_ui (r, u, v);
}
void
mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v)
{
- mp_size_t un, us;
- mp_ptr tp;
- mp_limb_t cy;
-
- us = u->_mp_size;
-
- if (us == 0 || v == 0)
- {
- r->_mp_size = 0;
- return;
- }
-
- un = GMP_ABS (us);
-
- tp = MPZ_REALLOC (r, un + 1);
- cy = mpn_mul_1 (tp, u->_mp_d, un, v);
- tp[un] = cy;
-
- un += (cy > 0);
- r->_mp_size = (us < 0) ? - un : un;
+ mpz_t vv;
+ mpz_init_set_ui (vv, v);
+ mpz_mul (r, u, vv);
+ mpz_clear (vv);
+ return;
}
void
@@ -2150,8 +2116,8 @@ void
mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v)
{
mpz_t t;
- mpz_init (t);
- mpz_mul_ui (t, u, v);
+ mpz_init_set_ui (t, v);
+ mpz_mul (t, u, t);
mpz_add (r, r, t);
mpz_clear (t);
}
@@ -2160,8 +2126,8 @@ void
mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v)
{
mpz_t t;
- mpz_init (t);
- mpz_mul_ui (t, u, v);
+ mpz_init_set_ui (t, v);
+ mpz_mul (t, u, t);
mpz_sub (r, r, t);
mpz_clear (t);
}
@@ -2557,56 +2523,20 @@ static unsigned long
mpz_div_qr_ui (mpz_t q, mpz_t r,
const mpz_t n, unsigned long d, enum mpz_div_round_mode mode)
{
- mp_size_t ns, qn;
- mp_ptr qp;
- mp_limb_t rl;
- mp_size_t rs;
-
- ns = n->_mp_size;
- if (ns == 0)
- {
- if (q)
- q->_mp_size = 0;
- if (r)
- r->_mp_size = 0;
- return 0;
- }
-
- qn = GMP_ABS (ns);
- if (q)
- qp = MPZ_REALLOC (q, qn);
- else
- qp = NULL;
+ unsigned long ret;
+ mpz_t rr, dd;
- rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d);
- assert (rl < d);
-
- rs = rl > 0;
- rs = (ns < 0) ? -rs : rs;
-
- if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0)
- || (mode == GMP_DIV_CEIL && ns >= 0)))
- {
- if (q)
- gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1));
- rl = d - rl;
- rs = -rs;
- }
+ mpz_init (rr);
+ mpz_init_set_ui (dd, d);
+ mpz_div_qr (q, rr, n, dd, mode);
+ mpz_clear (dd);
+ ret = mpz_get_ui (rr);
if (r)
- {
- MPZ_REALLOC (r, 1)[0] = rl;
- r->_mp_size = rs;
- }
- if (q)
- {
- qn -= (qp[qn-1] == 0);
- assert (qn == 0 || qp[qn-1] > 0);
-
- q->_mp_size = (ns < 0) ? - qn : qn;
- }
+ mpz_swap (r, rr);
+ mpz_clear (rr);
- return rl;
+ return ret;
}
unsigned long
@@ -2745,22 +2675,16 @@ mpn_gcd_11 (mp_limb_t u, mp_limb_t v)
unsigned long
mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v)
{
- mp_size_t un;
+ mpz_t t;
+ mpz_init_set_ui(t, v);
+ mpz_gcd (t, u, t);
+ if (v > 0)
+ v = mpz_get_ui (t);
- if (v == 0)
- {
- if (g)
- mpz_abs (g, u);
- }
- else
- {
- un = GMP_ABS (u->_mp_size);
- if (un != 0)
- v = mpn_gcd_11 (mpn_div_qr_1 (NULL, u->_mp_d, un, v), v);
+ if (g)
+ mpz_swap (t, g);
- if (g)
- mpz_set_ui (g, v);
- }
+ mpz_clear (t);
return v;
}
@@ -2854,7 +2778,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
signed long sign = mpz_sgn (v);
mpz_abs (g, v);
if (s)
- mpz_set_ui (s, 0);
+ s->_mp_size = 0;
if (t)
mpz_set_si (t, sign);
return;
@@ -2868,7 +2792,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
if (s)
mpz_set_si (s, sign);
if (t)
- mpz_set_ui (t, 0);
+ t->_mp_size = 0;
return;
}
@@ -2993,8 +2917,9 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
mpz_sub (s0, s0, s1);
mpz_add (t0, t0, t1);
}
- mpz_divexact_ui (s0, s0, 2);
- mpz_divexact_ui (t0, t0, 2);
+ assert (mpz_even_p (t0) && mpz_even_p (s0));
+ mpz_tdiv_q_2exp (s0, s0, 1);
+ mpz_tdiv_q_2exp (t0, t0, 1);
}
/* Arrange so that |s| < |u| / 2g */
@@ -3119,7 +3044,10 @@ void
mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e)
{
mpz_t b;
- mpz_pow_ui (r, mpz_roinit_normal_n (b, &blimb, blimb != 0), e);
+
+ mpz_init_set_ui (b, blimb);
+ mpz_pow_ui (r, b, e);
+ mpz_clear (b);
}
void
@@ -3231,7 +3159,10 @@ void
mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m)
{
mpz_t e;
- mpz_powm (r, b, mpz_roinit_normal_n (e, &elimb, elimb != 0), m);
+
+ mpz_init_set_ui (e, elimb);
+ mpz_powm (r, b, e, m);
+ mpz_clear (e);
}
/* x=trunc(y^(1/z)), r=y-x^z */
@@ -3409,6 +3340,177 @@ mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k)
/* Primality testing */
+
+/* Computes Kronecker (a/b) with odd b, a!=0 and GCD(a,b) = 1 */
+/* Adapted from JACOBI_BASE_METHOD==4 in mpn/generic/jacbase.c */
+static int
+gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b)
+{
+ int c, bit = 0;
+
+ assert (b & 1);
+ assert (a != 0);
+ /* assert (mpn_gcd_11 (a, b) == 1); */
+
+ /* Below, we represent a and b shifted right so that the least
+ significant one bit is implicit. */
+ b >>= 1;
+
+ gmp_ctz(c, a);
+ a >>= 1;
+
+ do
+ {
+ a >>= c;
+ /* (2/b) = -1 if b = 3 or 5 mod 8 */
+ bit ^= c & (b ^ (b >> 1));
+ if (a < b)
+ {
+ bit ^= a & b;
+ a = b - a;
+ b -= a;
+ }
+ else
+ {
+ a -= b;
+ assert (a != 0);
+ }
+
+ gmp_ctz(c, a);
+ ++c;
+ }
+ while (b > 0);
+
+ return bit & 1 ? -1 : 1;
+}
+
+static void
+gmp_lucas_step_k_2k (mpz_t V, mpz_t Qk, const mpz_t n)
+{
+ mpz_mod (Qk, Qk, n);
+ /* V_{2k} <- V_k ^ 2 - 2Q^k */
+ mpz_mul (V, V, V);
+ mpz_submul_ui (V, Qk, 2);
+ mpz_tdiv_r (V, V, n);
+ /* Q^{2k} = (Q^k)^2 */
+ mpz_mul (Qk, Qk, Qk);
+}
+
+/* Computes V_k, Q^k (mod n) for the Lucas' sequence */
+/* with P=1, Q=Q; k = (n>>b0)|1. */
+/* Requires an odd n > 4; b0 > 0; -2*Q must not overflow a long */
+/* Returns (U_k == 0) and sets V=V_k and Qk=Q^k. */
+static int
+gmp_lucas_mod (mpz_t V, mpz_t Qk, long Q,
+ mp_bitcnt_t b0, const mpz_t n)
+{
+ mp_bitcnt_t bs;
+ mpz_t U;
+ int res;
+
+ assert (b0 > 0);
+ assert (Q <= - (LONG_MIN / 2));
+ assert (Q >= - (LONG_MAX / 2));
+ assert (mpz_cmp_ui (n, 4) > 0);
+ assert (mpz_odd_p (n));
+
+ mpz_init_set_ui (U, 1); /* U1 = 1 */
+ mpz_set_ui (V, 1); /* V1 = 1 */
+ mpz_set_si (Qk, Q);
+
+ for (bs = mpz_sizeinbase (n, 2) - 1; --bs >= b0;)
+ {
+ /* U_{2k} <- U_k * V_k */
+ mpz_mul (U, U, V);
+ /* V_{2k} <- V_k ^ 2 - 2Q^k */
+ /* Q^{2k} = (Q^k)^2 */
+ gmp_lucas_step_k_2k (V, Qk, n);
+
+ /* A step k->k+1 is performed if the bit in $n$ is 1 */
+ /* mpz_tstbit(n,bs) or the the bit is 0 in $n$ but */
+ /* should be 1 in $n+1$ (bs == b0) */
+ if (b0 == bs || mpz_tstbit (n, bs))
+ {
+ /* Q^{k+1} <- Q^k * Q */
+ mpz_mul_si (Qk, Qk, Q);
+ /* U_{k+1} <- (U_k + V_k) / 2 */
+ mpz_swap (U, V); /* Keep in V the old value of U_k */
+ mpz_add (U, U, V);
+ /* We have to compute U/2, so we need an even value, */
+ /* equivalent (mod n) */
+ if (mpz_odd_p (U))
+ mpz_add (U, U, n);
+ mpz_tdiv_q_2exp (U, U, 1);
+ /* V_{k+1} <-(D*U_k + V_k) / 2 =
+ U_{k+1} + (D-1)/2*U_k = U_{k+1} - 2Q*U_k */
+ mpz_mul_si (V, V, -2*Q);
+ mpz_add (V, U, V);
+ mpz_tdiv_r (V, V, n);
+ }
+ mpz_tdiv_r (U, U, n);
+ }
+
+ res = U->_mp_size == 0;
+ mpz_clear (U);
+ return res;
+}
+
+/* Performs strong Lucas' test on x, with parameters suggested */
+/* for the BPSW test. Qk is only passed to recycle a variable. */
+/* Requires GCD (x,6) = 1.*/
+static int
+gmp_stronglucas (const mpz_t x, mpz_t Qk)
+{
+ mp_bitcnt_t b0;
+ mpz_t V, n;
+ mp_limb_t maxD, D; /* The absolute value is stored. */
+ long Q;
+ mp_limb_t tl;
+
+ /* Test on the absolute value. */
+ mpz_roinit_normal_n (n, x->_mp_d, GMP_ABS (x->_mp_size));
+
+ assert (mpz_odd_p (n));
+ /* assert (mpz_gcd_ui (NULL, n, 6) == 1); */
+ if (mpz_root (Qk, n, 2))
+ return 0; /* A square is composite. */
+
+ /* Check Ds up to square root (in case, n is prime)
+ or avoid overflows */
+ maxD = (Qk->_mp_size == 1) ? Qk->_mp_d [0] - 1 : GMP_LIMB_MAX;
+
+ D = 3;
+ /* Search a D such that (D/n) = -1 in the sequence 5,-7,9,-11,.. */
+ /* For those Ds we have (D/n) = (n/|D|) */
+ do
+ {
+ if (D >= maxD)
+ return 1 + (D != GMP_LIMB_MAX); /* (1 + ! ~ D) */
+ D += 2;
+ tl = mpz_tdiv_ui (n, D);
+ if (tl == 0)
+ return 0;
+ }
+ while (gmp_jacobi_coprime (tl, D) == 1);
+
+ mpz_init (V);
+
+ /* n-(D/n) = n+1 = d*2^{b0}, with d = (n>>b0) | 1 */
+ b0 = mpz_scan0 (n, 0);
+
+ /* D= P^2 - 4Q; P = 1; Q = (1-D)/4 */
+ Q = (D & 2) ? (D >> 2) + 1 : -(long) (D >> 2);
+
+ if (! gmp_lucas_mod (V, Qk, Q, b0, n)) /* If Ud != 0 */
+ while (V->_mp_size != 0 && --b0 != 0) /* while Vk != 0 */
+ /* V <- V ^ 2 - 2Q^k */
+ /* Q^{2k} = (Q^k)^2 */
+ gmp_lucas_step_k_2k (V, Qk, n);
+
+ mpz_clear (V);
+ return (b0 != 0);
+}
+
static int
gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y,
const mpz_t q, mp_bitcnt_t k)
@@ -3470,21 +3572,26 @@ mpz_probab_prime_p (const mpz_t n, int reps)
if (mpz_cmpabs_ui (n, 31*31) < 0)
return 2;
- /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] =
- j^2 + j + 41 using Euler's polynomial. We potentially stop early,
- if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps >
- 30 (a[30] == 971 > 31*31 == 961). */
-
mpz_init (nm1);
mpz_init (q);
- mpz_init (y);
/* Find q and k, where q is odd and n = 1 + 2**k * q. */
- nm1->_mp_size = mpz_abs_sub_ui (nm1, n, 1);
+ mpz_abs (nm1, n);
+ nm1->_mp_d[0] -= 1;
k = mpz_scan1 (nm1, 0);
mpz_tdiv_q_2exp (q, nm1, k);
- for (j = 0, is_prime = 1; is_prime & (j < reps); j++)
+ /* BPSW test */
+ mpz_init_set_ui (y, 2);
+ is_prime = gmp_millerrabin (n, nm1, y, q, k) && gmp_stronglucas (n, y);
+ reps -= 24; /* skip the first 24 repetitions */
+
+ /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] =
+ j^2 + j + 41 using Euler's polynomial. We potentially stop early,
+ if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps >
+ 30 (a[30] == 971 > 31*31 == 961). */
+
+ for (j = 0; is_prime & (j < reps); j++)
{
mpz_set_ui (y, (unsigned long) j*j+j+41);
if (mpz_cmp (y, nm1) >= 0)
@@ -3552,7 +3659,7 @@ mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index)
{
/* d < 0. Check if any of the bits below is set: If so, our bit
must be complemented. */
- if (shift > 0 && (w << (GMP_LIMB_BITS - shift)) > 0)
+ if (shift > 0 && (mp_limb_t) (w << (GMP_LIMB_BITS - shift)) > 0)
return bit ^ 1;
while (--limb_index >= 0)
if (d->_mp_d[limb_index] > 0)
@@ -3659,8 +3766,8 @@ mpz_combit (mpz_t d, mp_bitcnt_t bit_index)
void
mpz_com (mpz_t r, const mpz_t u)
{
- mpz_neg (r, u);
- mpz_sub_ui (r, r, 1);
+ mpz_add_ui (r, u, 1);
+ mpz_neg (r, r);
}
void
@@ -4000,7 +4107,7 @@ mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit)
}
/* Mask to 0 all bits before starting_bit, thus ignoring them. */
- limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
+ limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS);
}
return mpn_common_scan (limb, i, up, un, ux);
@@ -4030,7 +4137,7 @@ mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit)
limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */
/* Mask all bits before starting_bit, thus ignoring them. */
- limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
+ limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS);
return mpn_common_scan (limb, i, up, un, ux);
}
diff --git a/src/mini-gmp.h b/src/mini-gmp.h
index 2586d32db9e..27e0c0671a2 100644
--- a/src/mini-gmp.h
+++ b/src/mini-gmp.h
@@ -1,6 +1,6 @@
/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
-Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc.
+Copyright 2011-2015, 2017 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
diff --git a/src/minibuf.c b/src/minibuf.c
index 10fd5e56ac3..2bf6bc25946 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1062,7 +1062,8 @@ Optional second arg DEF is value to return if user enters an empty line,
Optional third arg REQUIRE-MATCH has the same meaning as the
REQUIRE-MATCH argument of `completing-read'.
Optional arg PREDICATE, if non-nil, is a function limiting the buffers that
-can be considered. It will be called with each potential candidate, and
+can be considered. It will be called with each potential candidate, in
+the form of either a string or a cons cell whose `car' is a string, and
should return non-nil to accept the candidate for completion, nil otherwise.
If `read-buffer-completion-ignore-case' is non-nil, completion ignores
case while reading the buffer name.
diff --git a/src/msdos.h b/src/msdos.h
index 0d15df7a331..3614c94dd0e 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -86,7 +86,6 @@ typedef int GC;
typedef int Pixmap;
typedef int Display;
typedef int Window;
-typedef int XRectangle;
#define PIX_TYPE unsigned long
#define XDISPLAY
@@ -95,7 +94,6 @@ typedef struct tty_display_info Display_Info;
extern struct tty_display_info the_only_display_info;
extern struct tty_output the_only_tty_output;
-#define FRAME_X_DISPLAY(f) ((Display *) 0)
#define FRAME_FONT(f) ((f)->output_data.tty->font)
#define FRAME_DISPLAY_INFO(f) (&the_only_display_info)
diff --git a/src/nsfont.m b/src/nsfont.m
index 9721e489357..eca97ab86cc 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -945,7 +945,7 @@ nsfont_encode_char (struct font *font, int c)
of METRICS. The glyphs are specified by their glyph codes in
CODE (length NGLYPHS). */
static void
-nsfont_text_extents (struct font *font, unsigned int *code,
+nsfont_text_extents (struct font *font, const unsigned int *code,
int nglyphs, struct font_metrics *metrics)
{
struct nsfont_info *font_info = (struct nsfont_info *)font;
diff --git a/src/nsgui.h b/src/nsgui.h
index c147f4dec49..c21953593ad 100644
--- a/src/nsgui.h
+++ b/src/nsgui.h
@@ -58,72 +58,22 @@ typedef struct _XCharStruct
int descent;
} XCharStruct;
-/* Fake structure from Xlib.h to represent two-byte characters. */
-#ifndef __OBJC__
-typedef unsigned short unichar;
-#endif
-typedef unichar XChar2b;
-
-#define STORE_XCHAR2B(chp, b1, b2) \
- (*(chp) = ((XChar2b)((((b1) & 0x00ff) << 8) | ((b2) & 0x00ff))))
-
-#define XCHAR2B_BYTE1(chp) \
- ((*(chp) & 0xff00) >> 8)
-
-#define XCHAR2B_BYTE2(chp) \
- (*(chp) & 0x00ff)
-
/* Used in xdisp.c when comparing faces and frame colors. */
extern unsigned long ns_color_index_to_rgba(int idx, struct frame *f);
-/* XXX: xfaces requires these structures, but the question is are we
- forced to use them? */
-typedef struct _XGCValues
-{
- unsigned long foreground;
- unsigned long background;
#ifdef __OBJC__
- struct ns_font *font;
+typedef id Emacs_Pixmap;
#else
- void *font;
+typedef void *Emacs_Pixmap;
#endif
-} XGCValues;
-
-typedef XGCValues * GC;
-
-#define GCForeground 0x01
-#define GCBackground 0x02
-#define GCFont 0x03
#ifdef __OBJC__
-typedef id Pixmap;
+typedef NSCursor *Emacs_Cursor;
#else
-typedef void *Pixmap;
+typedef void *Emacs_Cursor;
#endif
-#ifdef __OBJC__
-typedef NSCursor * Cursor;
-#else
-typedef void *Cursor;
-#endif
-
-#define No_Cursor (0)
-
-#ifdef __OBJC__
-typedef NSColor * Color;
-#else
-typedef void * Color;
-#endif
typedef int Window;
-typedef int Display;
-
-
-/* Some sort of attempt to normalize rectangle handling. Seems a bit
- much for what is accomplished. */
-typedef struct {
- int x, y;
- unsigned width, height;
-} XRectangle;
#ifndef __OBJC__
#if defined (__LP64__) && __LP64__
@@ -138,13 +88,13 @@ typedef struct _NSRect { NSPoint origin; NSSize size; } NSRect;
#define NativeRectangle NSRect
-#define CONVERT_TO_XRECT(xr, nr) \
+#define CONVERT_TO_EMACS_RECT(xr, nr) \
((xr).x = (nr).origin.x, \
(xr).y = (nr).origin.y, \
(xr).width = (nr).size.width, \
(xr).height = (nr).size.height)
-#define CONVERT_FROM_XRECT(xr, nr) \
+#define CONVERT_FROM_EMACS_RECT(xr, nr) \
((nr).origin.x = (xr).x, \
(nr).origin.y = (xr).y, \
(nr).size.width = (xr).width, \
diff --git a/src/nsimage.m b/src/nsimage.m
index 33236c48d42..0249d22acae 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -313,8 +313,8 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
if (bmRep == nil || color == nil)
return self;
- if ([color colorSpaceName] != NSCalibratedRGBColorSpace)
- rgbColor = [color colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+ if ([color colorSpace] != [NSColorSpace deviceRGBColorSpace])
+ rgbColor = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
else
rgbColor = color;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index fd1323344b3..3fe06cda02a 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -668,9 +668,9 @@ ns_activate_menubar (struct frame *f)
/* Draw radio buttons and tickboxes. */
if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
wv->button_type == BUTTON_TYPE_RADIO))
- [item setState: NSOnState];
+ [item setState: NSControlStateValueOn];
else
- [item setState: NSOffState];
+ [item setState: NSControlStateValueOff];
[item setTag: (NSInteger)wv->call_data];
}
@@ -1594,7 +1594,7 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
[cell setBordered: NO];
[cell setEnabled: NO];
[cell setCellAttribute: NSCellIsInsetButton to: 8];
- [cell setBezelStyle: NSRoundedBezelStyle];
+ [cell setBezelStyle: NSBezelStyleRounded];
matrix = [[NSMatrix alloc] initWithFrame: contentRect
mode: NSHighlightModeMatrix
@@ -1607,7 +1607,6 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
[matrix autorelease];
[[self contentView] addSubview: matrix];
- [self setOneShot: YES];
[self setReleasedWhenClosed: YES];
[self setHidesOnDeactivate: YES];
return self;
diff --git a/src/nsselect.m b/src/nsselect.m
index cf36c869eb1..b044fe6f32d 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -57,7 +57,7 @@ symbol_to_nsstring (Lisp_Object sym)
if (EQ (sym, QCLIPBOARD)) return NSPasteboardNameGeneral;
if (EQ (sym, QPRIMARY)) return NXPrimaryPboard;
if (EQ (sym, QSECONDARY)) return NXSecondaryPboard;
- if (EQ (sym, QTEXT)) return NSStringPboardType;
+ if (EQ (sym, QTEXT)) return NSPasteboardTypeString;
return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (sym))];
}
@@ -76,11 +76,11 @@ ns_string_to_symbol (NSString *t)
return QPRIMARY;
if ([t isEqualToString: NXSecondaryPboard])
return QSECONDARY;
- if ([t isEqualToString: NSStringPboardType])
+ if ([t isEqualToString: NSPasteboardTypeString])
return QTEXT;
if ([t isEqualToString: NSFilenamesPboardType])
return QFILE_NAME;
- if ([t isEqualToString: NSTabularTextPboardType])
+ if ([t isEqualToString: NSPasteboardTypeTabularText])
return QTEXT;
return intern ([t UTF8String]);
}
@@ -193,7 +193,7 @@ ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype)
else
{
// Used for ns-own-selection-internal.
- eassert (gtype == NSStringPboardType);
+ eassert (gtype == NSPasteboardTypeString);
[pb setString: nsStr forType: gtype];
}
[nsStr release];
@@ -345,7 +345,7 @@ anything that the functions on `selection-converter-alist' know about. */)
}
/* We only support copy of text. */
- type = NSStringPboardType;
+ type = NSPasteboardTypeString;
target_symbol = ns_string_to_symbol (type);
if (STRINGP (value))
{
@@ -472,9 +472,9 @@ nxatoms_of_nsselect (void)
[NSNumber numberWithLong:0], NSPasteboardNameGeneral,
[NSNumber numberWithLong:0], NXPrimaryPboard,
[NSNumber numberWithLong:0], NXSecondaryPboard,
- [NSNumber numberWithLong:0], NSStringPboardType,
+ [NSNumber numberWithLong:0], NSPasteboardTypeString,
[NSNumber numberWithLong:0], NSFilenamesPboardType,
- [NSNumber numberWithLong:0], NSTabularTextPboardType,
+ [NSNumber numberWithLong:0], NSPasteboardTypeTabularText,
nil] retain];
}
diff --git a/src/nsterm.h b/src/nsterm.h
index 683f2dd9341..1e56276ca3c 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -872,10 +872,10 @@ struct ns_display_info
Lisp_Object rdb;
/* The cursor to use for vertical scroll bars. */
- Cursor vertical_scroll_bar_cursor;
+ Emacs_Cursor vertical_scroll_bar_cursor;
/* The cursor to use for horizontal scroll bars. */
- Cursor horizontal_scroll_bar_cursor;
+ Emacs_Cursor horizontal_scroll_bar_cursor;
/* Information about the range of text currently shown in
mouse-face. */
@@ -931,24 +931,24 @@ struct ns_output
#endif
/* NSCursors are initialized in initFrameFromEmacs. */
- Cursor text_cursor;
- Cursor nontext_cursor;
- Cursor modeline_cursor;
- Cursor hand_cursor;
- Cursor hourglass_cursor;
- Cursor horizontal_drag_cursor;
- Cursor vertical_drag_cursor;
- Cursor left_edge_cursor;
- Cursor top_left_corner_cursor;
- Cursor top_edge_cursor;
- Cursor top_right_corner_cursor;
- Cursor right_edge_cursor;
- Cursor bottom_right_corner_cursor;
- Cursor bottom_edge_cursor;
- Cursor bottom_left_corner_cursor;
+ Emacs_Cursor text_cursor;
+ Emacs_Cursor nontext_cursor;
+ Emacs_Cursor modeline_cursor;
+ Emacs_Cursor hand_cursor;
+ Emacs_Cursor hourglass_cursor;
+ Emacs_Cursor horizontal_drag_cursor;
+ Emacs_Cursor vertical_drag_cursor;
+ Emacs_Cursor left_edge_cursor;
+ Emacs_Cursor top_left_corner_cursor;
+ Emacs_Cursor top_edge_cursor;
+ Emacs_Cursor top_right_corner_cursor;
+ Emacs_Cursor right_edge_cursor;
+ Emacs_Cursor bottom_right_corner_cursor;
+ Emacs_Cursor bottom_edge_cursor;
+ Emacs_Cursor bottom_left_corner_cursor;
/* NS-specific */
- Cursor current_pointer;
+ Emacs_Cursor current_pointer;
/* lord knows why Emacs needs to know about our Window ids.. */
Window window_desc, parent_desc;
@@ -997,12 +997,6 @@ struct x_output
#define FRAME_NS_WINDOW(f) ((f)->output_data.ns->window_desc)
#define FRAME_NATIVE_WINDOW(f) FRAME_NS_WINDOW (f)
-/* This is the `Display *' which frame F is on. */
-#define FRAME_NS_DISPLAY(f) (0)
-#define FRAME_X_DISPLAY(f) (0)
-#define FRAME_X_SCREEN(f) (0)
-#define FRAME_X_VISUAL(f) FRAME_DISPLAY_INFO(f)->visual
-
#define FRAME_FOREGROUND_COLOR(f) ((f)->output_data.ns->foreground_color)
#define FRAME_BACKGROUND_COLOR(f) ((f)->output_data.ns->background_color)
@@ -1140,10 +1134,10 @@ extern void ns_set_doc_edited (void);
extern bool
ns_defined_color (struct frame *f,
const char *name,
- XColor *color_def, bool alloc,
+ Emacs_Color *color_def, bool alloc,
bool makeIndex);
extern void
-ns_query_color (void *col, XColor *color_def, bool setPixel);
+ns_query_color (void *col, Emacs_Color *color_def, bool setPixel);
#ifdef __OBJC__
extern int ns_lisp_to_color (Lisp_Object color, NSColor **col);
@@ -1171,10 +1165,6 @@ extern void ns_release_autorelease_pool (void *);
extern const char *ns_get_defaults_value (const char *key);
extern void ns_init_locale (void);
-#ifdef NS_IMPL_COCOA
-extern void ns_enable_screen_updates (void);
-#endif
-
/* in nsmenu */
extern void update_frame_tool_bar (struct frame *f);
extern void free_frame_tool_bar (struct frame *f);
@@ -1342,4 +1332,14 @@ enum NSWindowTabbingMode
/* Deprecated in macOS 10.13. */
#define NSPasteboardNameGeneral NSGeneralPboard
#endif
+
+#if !defined (NS_IMPL_COCOA) || !defined (MAC_OS_X_VERSION_10_14)
+/* Deprecated in macOS 10.14. */
+#define NSPasteboardTypeString NSStringPboardType
+#define NSPasteboardTypeTabularText NSTabularTextPboardType
+#define NSPasteboardTypeURL NSURLPboardType
+#define NSControlStateValueOn NSOnState
+#define NSControlStateValueOff NSOffState
+#define NSBezelStyleRounded NSRoundedBezelStyle
+#endif
#endif /* HAVE_NS */
diff --git a/src/nsterm.m b/src/nsterm.m
index cdf1916e71b..0cae5e9d448 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -160,20 +160,28 @@ char const * nstrace_fullscreen_type_name (int fs_type)
- (NSColor *)colorUsingDefaultColorSpace
{
- /* FIXMES: We're checking for colorWithSRGBRed here so this will
- only work in the same place as in the method above. It should
- really be a check whether we're on macOS 10.7 or above. */
+ /* FIXME: We're checking for colorWithSRGBRed here so this will only
+ work in the same place as in the method above. It should really
+ be a check whether we're on macOS 10.7 or above. */
#if defined (NS_IMPL_COCOA) \
&& MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
- if (ns_use_srgb_colorspace
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- && [NSColor respondsToSelector:
- @selector(colorWithSRGBRed:green:blue:alpha:)]
+ if ([NSColor respondsToSelector:
+ @selector(colorWithSRGBRed:green:blue:alpha:)])
#endif
- )
- return [self colorUsingColorSpace: [NSColorSpace sRGBColorSpace]];
+ {
+ if (ns_use_srgb_colorspace)
+ return [self colorUsingColorSpace: [NSColorSpace sRGBColorSpace]];
+ else
+ return [self colorUsingColorSpace: [NSColorSpace deviceRGBColorSpace]];
+ }
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+ else
#endif
+#endif /* NS_IMPL_COCOA && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
+#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 1070
return [self colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+#endif
}
@end
@@ -283,9 +291,6 @@ static int ns_window_num = 0;
static BOOL ns_fake_keydown = NO;
#ifdef NS_IMPL_COCOA
static BOOL ns_menu_bar_is_hidden = NO;
-
-/* The number of times NSDisableScreenUpdates has been called. */
-static int disable_screen_updates_count = 0;
#endif
/* static int debug_lock = 0; */
@@ -688,40 +693,6 @@ ns_release_autorelease_pool (void *pool)
}
-#ifdef NS_IMPL_COCOA
-/* Disabling screen updates can be used to make several actions appear
- "atomic" to the end user. It seems some actions can still update
- the display, though.
-
- When we re-enable screen updates the number of calls to
- NSEnableScreenUpdates should match the number to
- NSDisableScreenUpdates.
-
- We use these functions to prevent the user seeing a blank frame
- after it has been resized. ns_set_window_size disables updates and
- when redisplay completes unwind_redisplay enables them again
- (bug#30699). */
-
-static void
-ns_disable_screen_updates (void)
-{
- NSDisableScreenUpdates ();
- disable_screen_updates_count++;
-}
-
-void
-ns_enable_screen_updates (void)
-/* Re-enable screen updates. Called from unwind_redisplay. */
-{
- while (disable_screen_updates_count > 0)
- {
- NSEnableScreenUpdates ();
- disable_screen_updates_count--;
- }
-}
-#endif
-
-
static BOOL
ns_menu_bar_should_be_hidden (void)
/* True, if the menu bar should be hidden. */
@@ -1106,7 +1077,7 @@ static void
ns_update_begin (struct frame *f)
/* --------------------------------------------------------------------------
Prepare for a grouped sequence of drawing calls
- external (RIF) call; whole frame, called before update_window_begin
+ external (RIF) call; whole frame, called before gui_update_window_begin
-------------------------------------------------------------------------- */
{
#ifdef NS_IMPL_COCOA
@@ -1129,80 +1100,10 @@ ns_update_begin (struct frame *f)
static void
-ns_update_window_begin (struct window *w)
-/* --------------------------------------------------------------------------
- Prepare for a grouped sequence of drawing calls
- external (RIF) call; for one window, called after update_begin
- -------------------------------------------------------------------------- */
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-
- NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_window_begin");
- w->output_cursor = w->cursor;
-
- block_input ();
-
- if (f == hlinfo->mouse_face_mouse_frame)
- {
- /* Don't do highlighting for mouse motion during the update. */
- hlinfo->mouse_face_defer = 1;
-
- /* If the frame needs to be redrawn,
- simply forget about any prior mouse highlighting. */
- if (FRAME_GARBAGED_P (f))
- hlinfo->mouse_face_window = Qnil;
-
- /* (further code for mouse faces ifdef'd out in other terms elided) */
- }
-
- unblock_input ();
-}
-
-
-static void
-ns_update_window_end (struct window *w, bool cursor_on_p,
- bool mouse_face_overwritten_p)
-/* --------------------------------------------------------------------------
- Finished a grouped sequence of drawing calls
- external (RIF) call; for one window called before update_end
- -------------------------------------------------------------------------- */
-{
- NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_window_end");
-
- /* note: this fn is nearly identical in all terms */
- if (!w->pseudo_window_p)
- {
- block_input ();
-
- if (cursor_on_p)
- display_and_set_cursor (w, 1,
- w->output_cursor.hpos, w->output_cursor.vpos,
- w->output_cursor.x, w->output_cursor.y);
-
- if (draw_window_fringes (w, 1))
- {
- if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
- gui_draw_right_divider (w);
- else
- gui_draw_vertical_border (w);
- }
-
- unblock_input ();
- }
-
- /* If a row with mouse-face was overwritten, arrange for
- frame_up_to_date to redisplay the mouse highlight. */
- if (mouse_face_overwritten_p)
- reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
-}
-
-
-static void
ns_update_end (struct frame *f)
/* --------------------------------------------------------------------------
Finished a grouped sequence of drawing calls
- external (RIF) call; for whole frame, called after update_window_end
+ external (RIF) call; for whole frame, called after gui_update_window_end
-------------------------------------------------------------------------- */
{
NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
@@ -1849,15 +1750,6 @@ ns_set_window_size (struct frame *f,
block_input ();
-#ifdef NS_IMPL_COCOA
- /* To prevent showing the user a blank frame, stop updates being
- flushed to the screen until after redisplay has completed. This
- breaks live resize (resizing with a mouse), so don't do it if
- we're in a live resize loop. */
- if (![view inLiveResize])
- ns_disable_screen_updates ();
-#endif
-
if (pixelwise)
{
pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
@@ -2397,7 +2289,7 @@ ns_color_index_to_rgba(int idx, struct frame *f)
}
void
-ns_query_color(void *col, XColor *color_def, bool setPixel)
+ns_query_color(void *col, Emacs_Color *color_def, bool setPixel)
/* --------------------------------------------------------------------------
Get ARGB values out of NSColor col and put them into color_def.
If setPixel, set the pixel to a concatenated version.
@@ -2420,7 +2312,7 @@ ns_query_color(void *col, XColor *color_def, bool setPixel)
bool
ns_defined_color (struct frame *f,
const char *name,
- XColor *color_def,
+ Emacs_Color *color_def,
bool alloc,
bool makeIndex)
/* --------------------------------------------------------------------------
@@ -2448,7 +2340,7 @@ ns_defined_color (struct frame *f,
}
static void
-ns_query_frame_background_color (struct frame *f, XColor *bgcolor)
+ns_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
/* --------------------------------------------------------------------------
External (hook): Store F's background color into *BGCOLOR
-------------------------------------------------------------------------- */
@@ -2585,8 +2477,7 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
/* Clear the mouse-moved flag for every frame on this display. */
FOR_EACH_FRAME (tail, frame)
- if (FRAME_NS_P (XFRAME (frame))
- && FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp))
+ if (FRAME_NS_P (XFRAME (frame)))
XFRAME (frame)->mouse_moved = 0;
dpyinfo->last_mouse_scroll_bar = nil;
@@ -2647,7 +2538,7 @@ ns_frame_up_to_date (struct frame *f)
static void
-ns_define_frame_cursor (struct frame *f, Cursor cursor)
+ns_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
/* --------------------------------------------------------------------------
External (RIF): set frame mouse pointer type.
-------------------------------------------------------------------------- */
@@ -5038,6 +4929,18 @@ ns_judge_scroll_bars (struct frame *f)
/* ==========================================================================
+ Image Hooks
+
+ ========================================================================== */
+
+static void
+ns_free_pixmap (struct frame *_f, Emacs_Pixmap pixmap)
+{
+ ns_release_object (pixmap);
+}
+
+/* ==========================================================================
+
Initialization
========================================================================== */
@@ -5166,8 +5069,8 @@ static struct redisplay_interface ns_redisplay_interface =
gui_clear_end_of_line,
ns_scroll_run,
ns_after_update_window_line,
- ns_update_window_begin,
- ns_update_window_end,
+ NULL, /* update_window_begin */
+ NULL, /* update_window_end */
0, /* flush_display */
gui_clear_window_mouse_face,
gui_get_glyph_overhangs,
@@ -5266,6 +5169,7 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar;
terminal->judge_scroll_bars_hook = ns_judge_scroll_bars;
terminal->get_string_resource_hook = ns_get_string_resource;
+ terminal->free_pixmap = ns_free_pixmap;
terminal->delete_frame_hook = ns_destroy_window;
terminal->delete_terminal_hook = ns_delete_terminal;
/* Other hooks are NULL by default. */
@@ -5517,14 +5421,14 @@ ns_term_init (Lisp_Object display_name)
NSTRACE_MSG ("Input/output types");
- ns_send_types = [[NSArray arrayWithObjects: NSStringPboardType, nil] retain];
- ns_return_types = [[NSArray arrayWithObjects: NSStringPboardType, nil]
+ ns_send_types = [[NSArray arrayWithObjects: NSPasteboardTypeString, nil] retain];
+ ns_return_types = [[NSArray arrayWithObjects: NSPasteboardTypeString, nil]
retain];
ns_drag_types = [[NSArray arrayWithObjects:
- NSStringPboardType,
- NSTabularTextPboardType,
+ NSPasteboardTypeString,
+ NSPasteboardTypeTabularText,
NSFilenamesPboardType,
- NSURLPboardType, nil] retain];
+ NSPasteboardTypeURL, nil] retain];
/* If fullscreen is in init/default-frame-alist, focus isn't set
right for fullscreen windows, so set this. */
@@ -8334,6 +8238,9 @@ not_in_argv (NSString *arg)
{
return NO;
}
+ /* FIXME: NSFilenamesPboardType is deprecated in 10.14, but the
+ NSURL method can only handle one file at a time. Stick with the
+ existing code at the moment. */
else if ([type isEqualToString: NSFilenamesPboardType])
{
NSArray *files;
@@ -8428,8 +8335,8 @@ not_in_argv (NSString *arg)
NSTRACE ("[EmacsView writeSelectionToPasteboard:types:]");
- /* We only support NSStringPboardType. */
- if ([types containsObject:NSStringPboardType] == NO) {
+ /* We only support NSPasteboardTypeString. */
+ if ([types containsObject:NSPasteboardTypeString] == NO) {
return NO;
}
@@ -8443,7 +8350,7 @@ not_in_argv (NSString *arg)
if (! STRINGP (val))
return NO;
- typesDeclared = [NSArray arrayWithObject:NSStringPboardType];
+ typesDeclared = [NSArray arrayWithObject:NSPasteboardTypeString];
[pb declareTypes:typesDeclared owner:nil];
ns_string_to_pasteboard (pb, val);
return YES;
@@ -9105,10 +9012,12 @@ not_in_argv (NSString *arg)
last_hit_part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle; break;
case NSScrollerIncrementPage:
last_hit_part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle; break;
+#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 1070
case NSScrollerDecrementLine:
last_hit_part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow; break;
case NSScrollerIncrementLine:
last_hit_part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow; break;
+#endif
case NSScrollerKnob:
last_hit_part = horizontal ? scroll_bar_horizontal_handle : scroll_bar_handle; break;
case NSScrollerKnobSlot: /* GNUstep-only */
diff --git a/src/print.c b/src/print.c
index 68ed6781c81..406abbf4a3f 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1361,6 +1361,19 @@ print_prune_string_charset (Lisp_Object string)
return string;
}
+#ifdef HAVE_MODULES
+/* Return a data pointer equal to FUNCPTR. */
+
+static void const *
+data_from_funcptr (void (*funcptr) (void))
+{
+ /* The module code, and the POSIX API for dynamic linking, already
+ assume that function and data pointers are represented
+ interchangeably, so it's OK to assume that here too. */
+ return (void const *) funcptr;
+}
+#endif
+
static bool
print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
char *buf)
@@ -1788,23 +1801,20 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
{
print_c_string ("#<module function ", printcharfun);
module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj));
- const char *file = NULL;
- const char *symbol = NULL;
+ char const *file;
+ char const *symbol;
dynlib_addr (ptr, &file, &symbol);
if (symbol == NULL)
{
- print_c_string ("at ", printcharfun);
- enum { pointer_bufsize = sizeof ptr * 16 / CHAR_BIT + 2 + 1 };
- char buffer[pointer_bufsize];
- int needed = snprintf (buffer, sizeof buffer, "%p", ptr);
- const char p0x[] = "0x";
- eassert (needed <= sizeof buffer);
- /* ANSI C doesn't guarantee that %p produces a string that
- begins with a "0x". */
- if (c_strncasecmp (buffer, p0x, sizeof (p0x) - 1) != 0)
- print_c_string (p0x, printcharfun);
- print_c_string (buffer, printcharfun);
+ uintptr_t ui = (uintptr_t) data_from_funcptr (ptr);
+
+ /* In theory this assignment could lose info on pre-C99
+ hosts, but in practice it doesn't. */
+ uprintmax_t up = ui;
+
+ int len = sprintf (buf, "at 0x%"pMx, up);
+ strout (buf, len, len, printcharfun);
}
else
print_c_string (symbol, printcharfun);
@@ -1832,7 +1842,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
{
char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT),
max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t),
- 40))];
+ max ((sizeof "at 0x"
+ + (sizeof (uprintmax_t) * CHAR_BIT + 4 - 1) / 4),
+ 40)))];
current_thread->stack_top = buf;
maybe_quit ();
diff --git a/src/search.c b/src/search.c
index dfbae5c9628..8a0f707b723 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1324,12 +1324,7 @@ search_buffer_non_re (Lisp_Object string, ptrdiff_t pos,
}
else
{
- /* Converting multibyte to single-byte.
-
- ??? Perhaps this conversion should be done in a special way
- by subtracting nonascii-insert-offset from each non-ASCII char,
- so that only the multibyte chars which really correspond to
- the chosen single-byte character set can possibly match. */
+ /* Converting multibyte to single-byte. */
raw_pattern_size = SCHARS (string);
raw_pattern_size_byte = SCHARS (string);
raw_pattern = SAFE_ALLOCA (raw_pattern_size + 1);
diff --git a/src/termhooks.h b/src/termhooks.h
index 54f09e03033..f1827128f19 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -496,7 +496,7 @@ struct terminal
If MAKEINDEX (on NS), set COLOR_DEF pixel to ARGB. */
bool (*defined_color_hook) (struct frame *f, const char *color_name,
- XColor *color_def,
+ Emacs_Color *color_def,
bool alloc,
bool makeIndex);
@@ -515,13 +515,13 @@ struct terminal
/* This hook is called to store the frame's background color into
BGCOLOR. */
- void (*query_frame_background_color) (struct frame *f, XColor *bgcolor);
+ void (*query_frame_background_color) (struct frame *f, Emacs_Color *bgcolor);
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
/* On frame F, translate pixel colors to RGB values for the NCOLORS
colors in COLORS. Use cached information, if available. */
- void (*query_colors) (struct frame *f, XColor *colors, int ncolors);
+ void (*query_colors) (struct frame *f, Emacs_Color *colors, int ncolors);
#endif
/* Return the current position of the mouse.
@@ -741,6 +741,15 @@ struct terminal
const char *name,
const char *class);
+ /* Image hooks */
+#ifdef HAVE_WINDOW_SYSTEM
+ /* Free the pixmap PIXMAP on F. */
+ void (*free_pixmap) (struct frame *f, Emacs_Pixmap pixmap);
+
+#endif
+
+ /* Deletion hooks */
+
/* Called to delete the device-specific portions of a frame that is
on this terminal device. */
void (*delete_frame_hook) (struct frame *);
diff --git a/src/timefns.c b/src/timefns.c
index 5005c73b7fc..7b5af6a5d24 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -1488,10 +1488,11 @@ usage: (encode-time &optional TIME FORM &rest OBSOLESCENT-ARGUMENTS) */)
tm.tm_mon = check_tm_member (XCAR (a), 1); a = XCDR (a);
tm.tm_year = check_tm_member (XCAR (a), TM_YEAR_BASE); a = XCDR (a);
a = XCDR (a);
- if (SYMBOLP (XCAR (a)))
- tm.tm_isdst = !NILP (XCAR (a));
+ Lisp_Object dstflag = XCAR (a);
a = XCDR (a);
zone = XCAR (a);
+ if (SYMBOLP (dstflag) && !FIXNUMP (zone) && !CONSP (zone))
+ tm.tm_isdst = !NILP (dstflag);
}
else if (nargs < 6)
xsignal2 (Qwrong_number_of_arguments, Qencode_time, make_fixnum (nargs));
diff --git a/src/w32.c b/src/w32.c
index 082a66b7384..833ff4c7e4a 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -2003,6 +2003,13 @@ getloadavg (double loadavg[], int nelem)
loadavg[elem] = avg;
}
+ /* Always return at least one element, otherwise load-average
+ returns nil, and Lisp programs might decide we cannot measure
+ system load. For example, jit-lock-stealth-load's defcustom
+ might decide that feature is "unsupported". */
+ if (elem == 0)
+ loadavg[elem++] = 0.09; /* < display-time-load-average-threshold */
+
return elem;
}
@@ -2644,7 +2651,7 @@ unsetenv (const char *name)
/* It is safe to use 'alloca' with 32K size, since the stack is at
least 2MB, and we set it to 8MB in the link command line. */
var = alloca (name_len + 2);
- strncpy (var, name, name_len);
+ memcpy (var, name, name_len);
var[name_len++] = '=';
var[name_len] = '\0';
return _putenv (var);
@@ -6054,7 +6061,7 @@ readlink (const char *name, char *buf, size_t buf_size)
lname_size = strlen (resolved) + 1;
if (lname_size <= buf_size)
size_to_copy = lname_size;
- strncpy (buf, resolved, size_to_copy);
+ memcpy (buf, resolved, size_to_copy);
/* Success! */
retval = size_to_copy;
}
diff --git a/src/w32fns.c b/src/w32fns.c
index 525642bfaab..bb74fcc1640 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1174,7 +1174,7 @@ gamma_correct (struct frame *f, COLORREF *color)
If ALLOC is nonzero, allocate a new colormap cell. */
bool
-w32_defined_color (struct frame *f, const char *color, XColor *color_def,
+w32_defined_color (struct frame *f, const char *color, Emacs_Color *color_def,
bool alloc_p, bool _makeIndex)
{
register Lisp_Object tem;
@@ -1248,7 +1248,7 @@ w32_defined_color (struct frame *f, const char *color, XColor *color_def,
static int
w32_decode_color (struct frame *f, Lisp_Object arg, int def)
{
- XColor cdef;
+ Emacs_Color cdef;
CHECK_STRING (arg);
@@ -2247,15 +2247,15 @@ w32_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
/* Subroutines for creating a frame. */
-Cursor w32_load_cursor (LPCTSTR);
+HCURSOR w32_load_cursor (LPCTSTR);
-Cursor
+HCURSOR
w32_load_cursor (LPCTSTR name)
{
/* Try first to load cursor from application resource. */
- Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL),
- name, IMAGE_CURSOR, 0, 0,
- LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
+ HCURSOR cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL),
+ name, IMAGE_CURSOR, 0, 0,
+ LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
if (!cursor)
{
/* Then try to load a shared predefined cursor. */
@@ -5217,7 +5217,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_EMACS_SETCURSOR:
{
- Cursor cursor = (Cursor) wParam;
+ HCURSOR cursor = (HCURSOR) wParam;
f = w32_window_to_frame (dpyinfo, hwnd);
if (f && cursor)
{
@@ -5559,22 +5559,19 @@ w32_icon (struct frame *f, Lisp_Object parms)
static void
w32_make_gc (struct frame *f)
{
- XGCValues gc_values;
+ Emacs_GC gc_values;
block_input ();
/* Create the GC's of this frame.
Note that many default values are used. */
- /* Normal video */
- gc_values.font = FRAME_FONT (f);
-
/* Cursor has cursor-color background, background-color foreground. */
gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
gc_values.background = f->output_data.w32->cursor_pixel;
f->output_data.w32->cursor_gc
= XCreateGC (NULL, FRAME_W32_WINDOW (f),
- (GCFont | GCForeground | GCBackground),
+ (GCForeground | GCBackground),
&gc_values);
/* Reliefs. */
@@ -6100,7 +6097,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
doc: /* SKIP: real doc in xfns.c. */)
(Lisp_Object color, Lisp_Object frame)
{
- XColor foo;
+ Emacs_Color foo;
struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -6115,7 +6112,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
doc: /* SKIP: real doc in xfns.c. */)
(Lisp_Object color, Lisp_Object frame)
{
- XColor foo;
+ Emacs_Color foo;
struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
diff --git a/src/w32font.c b/src/w32font.c
index 848016da1ca..bd68e22cc90 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -433,7 +433,7 @@ w32font_encode_char (struct font *font, int c)
CODE (length NGLYPHS). Apparently metrics can be NULL, in this
case just return the overall width. */
void
-w32font_text_extents (struct font *font, unsigned *code,
+w32font_text_extents (struct font *font, const unsigned *code,
int nglyphs, struct font_metrics *metrics)
{
int i;
diff --git a/src/w32font.h b/src/w32font.h
index 65f42a3178d..c7bb7f30570 100644
--- a/src/w32font.h
+++ b/src/w32font.h
@@ -74,7 +74,7 @@ int w32font_open_internal (struct frame *f, Lisp_Object font_entity,
int pixel_size, Lisp_Object font_object);
void w32font_close (struct font *font);
int w32font_has_char (Lisp_Object entity, int c);
-void w32font_text_extents (struct font *font, unsigned *code, int nglyphs,
+void w32font_text_extents (struct font *font, const unsigned *code, int nglyphs,
struct font_metrics *metrics);
int w32font_draw (struct glyph_string *s, int from, int to,
int x, int y, bool with_background);
diff --git a/src/w32gui.h b/src/w32gui.h
index 5dcbbd95166..62bad33c19b 100644
--- a/src/w32gui.h
+++ b/src/w32gui.h
@@ -27,41 +27,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define local_alloc(n) (HeapAlloc (local_heap, HEAP_ZERO_MEMORY, (n)))
#define local_free(p) (HeapFree (local_heap, 0, ((LPVOID) (p))))
-/* Emulate X GC's by keeping color and font info in a structure. */
-typedef struct _XGCValues
-{
- COLORREF foreground;
- COLORREF background;
- struct font *font;
-} XGCValues;
-
-#define GCForeground 0x01
-#define GCBackground 0x02
-#define GCFont 0x03
-
-typedef HBITMAP Pixmap;
-typedef HBITMAP Bitmap;
+typedef HBITMAP Emacs_Pixmap;
-typedef XGCValues * GC;
-typedef COLORREF Color;
typedef HWND Window;
typedef HDC Display; /* HDC so it doesn't conflict with xpm lib. */
-typedef HCURSOR Cursor;
-
-#define No_Cursor (0)
-
-#define XChar2b wchar_t
-
-/* Dealing with bits of wchar_t as if they were an XChar2b. */
-#define STORE_XCHAR2B(chp, byte1, byte2) \
- ((*(chp)) = ((XChar2b)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff))))
-
-#define XCHAR2B_BYTE1(chp) \
- (((*(chp)) & 0xff00) >> 8)
-
-#define XCHAR2B_BYTE2(chp) \
- ((*(chp)) & 0x00ff)
-
+typedef HCURSOR Emacs_Cursor;
/* Windows equivalent of XImage. */
typedef struct _XImage
@@ -110,20 +80,15 @@ extern HINSTANCE hinst;
#define PBaseSize (1L << 8) /* program specified base for incrementing */
#define PWinGravity (1L << 9) /* program specified window gravity */
-typedef struct {
- int x, y;
- unsigned width, height;
-} XRectangle;
-
#define NativeRectangle RECT
-#define CONVERT_TO_XRECT(xr,nr) \
+#define CONVERT_TO_EMACS_RECT(xr,nr) \
((xr).x = (nr).left, \
(xr).y = (nr).top, \
(xr).width = ((nr).right - (nr).left), \
(xr).height = ((nr).bottom - (nr).top))
-#define CONVERT_FROM_XRECT(xr,nr) \
+#define CONVERT_FROM_EMACS_RECT(xr,nr) \
((nr).left = (xr).x, \
(nr).top = (xr).y, \
(nr).right = ((xr).x + (xr).width), \
diff --git a/src/w32term.c b/src/w32term.c
index 451dd54dd8a..5726124b0ed 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -85,7 +85,7 @@ static int any_help_event_p;
extern unsigned int msh_mousewheel;
extern int w32_codepage_for_font (char *fontname);
-extern Cursor w32_load_cursor (LPCTSTR name);
+extern HCURSOR w32_load_cursor (LPCTSTR name);
/* This is display since w32 does not support multiple ones. */
@@ -166,7 +166,7 @@ int w32_message_fd = -1;
static void w32_handle_tool_bar_click (struct frame *,
struct input_event *);
-static void w32_define_cursor (Window, Cursor);
+static void w32_define_cursor (Window, Emacs_Cursor);
static void w32_scroll_bar_clear (struct frame *);
static void w32_raise_frame (struct frame *);
@@ -237,23 +237,21 @@ record_event (char *locus, int type)
static void
-XChangeGC (void *ignore, XGCValues *gc, unsigned long mask,
- XGCValues *xgcv)
+XChangeGC (void *ignore, Emacs_GC *gc, unsigned long mask,
+ Emacs_GC *egc)
{
if (mask & GCForeground)
- gc->foreground = xgcv->foreground;
+ gc->foreground = egc->foreground;
if (mask & GCBackground)
- gc->background = xgcv->background;
- if (mask & GCFont)
- gc->font = xgcv->font;
+ gc->background = egc->background;
}
-XGCValues *
-XCreateGC (void *ignore, HWND wignore, unsigned long mask, XGCValues *xgcv)
+Emacs_GC *
+XCreateGC (void *ignore, HWND wignore, unsigned long mask, Emacs_GC *egc)
{
- XGCValues *gc = xzalloc (sizeof (XGCValues));
+ Emacs_GC *gc = xzalloc (sizeof (*gc));
- XChangeGC (ignore, gc, mask, xgcv);
+ XChangeGC (ignore, gc, mask, egc);
return gc;
}
@@ -337,7 +335,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
- XRectangle wave_clip, string_clip, final_clip;
+ Emacs_Rectangle wave_clip, string_clip, final_clip;
RECT w32_final_clip, w32_string_clip;
HPEN hp, oldhp;
@@ -356,14 +354,14 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
wave_clip.height = wave_height;
get_glyph_string_clip_rect (s, &w32_string_clip);
- CONVERT_TO_XRECT (string_clip, w32_string_clip);
+ CONVERT_TO_EMACS_RECT (string_clip, w32_string_clip);
if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
return;
hp = CreatePen (PS_SOLID, thickness, color);
oldhp = SelectObject (s->hdc, hp);
- CONVERT_FROM_XRECT (final_clip, w32_final_clip);
+ CONVERT_FROM_EMACS_RECT (final_clip, w32_final_clip);
w32_set_clip_rectangle (s->hdc, &w32_final_clip);
/* Draw the waves */
@@ -396,7 +394,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
/* Draw a hollow rectangle at the specified position. */
static void
-w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
+w32_draw_rectangle (HDC hdc, Emacs_GC *gc, int x, int y,
int width, int height)
{
HBRUSH hb, oldhb;
@@ -529,7 +527,7 @@ w32_display_pixel_width (struct w32_display_info *dpyinfo)
/* Start an update of frame F. This function is installed as a hook
for update_begin, i.e. it is called when update_begin is called.
- This function is called prior to calls to w32_update_window_begin
+ This function is called prior to calls to gui_update_window_begin
for each window being updated. */
static void
@@ -555,58 +553,12 @@ w32_update_begin (struct frame *f)
static void
w32_update_window_begin (struct window *w)
{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-
/* Hide the system caret during an update. */
if (w32_use_visible_system_caret && w32_system_caret_hwnd)
{
SendMessageTimeout (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0,
0, 6000, NULL);
}
-
- w->output_cursor = w->cursor;
-
- block_input ();
-
- if (f == hlinfo->mouse_face_mouse_frame)
- {
- /* Don't do highlighting for mouse motion during the update. */
- hlinfo->mouse_face_defer = true;
-
- /* If F needs to be redrawn, simply forget about any prior mouse
- highlighting. */
- if (FRAME_GARBAGED_P (f))
- hlinfo->mouse_face_window = Qnil;
-
-#if 0 /* Rows in a current matrix containing glyphs in mouse-face have
- their mouse_face_p flag set, which means that they are always
- unequal to rows in a desired matrix which never have that
- flag set. So, rows containing mouse-face glyphs are never
- scrolled, and we don't have to switch the mouse highlight off
- here to prevent it from being scrolled. */
-
- /* Can we tell that this update does not affect the window
- where the mouse highlight is? If so, no need to turn off.
- Likewise, don't do anything if the frame is garbaged;
- in that case, the frame's current matrix that we would use
- is all wrong, and we will redisplay that line anyway. */
- if (!NILP (hlinfo->mouse_face_window)
- && w == XWINDOW (hlinfo->mouse_face_window))
- {
- int i;
-
- for (i = 0; i < w->desired_matrix->nrows; ++i)
- if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
- break;
-
- if (i < w->desired_matrix->nrows)
- clear_mouse_face (hlinfo);
- }
-#endif /* 0 */
- }
-
- unblock_input ();
}
/* Draw a vertical window border from (x,y0) to (x,y1) */
@@ -694,39 +646,8 @@ w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
static void
w32_update_window_end (struct window *w, bool cursor_on_p,
- bool mouse_face_overwritten_p)
+ bool mouse_face_overwritten_p)
{
- if (!w->pseudo_window_p)
- {
- block_input ();
-
- if (cursor_on_p)
- display_and_set_cursor (w, true,
- w->output_cursor.hpos, w->output_cursor.vpos,
- w->output_cursor.x, w->output_cursor.y);
-
- if (draw_window_fringes (w, true))
- {
- if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
- gui_draw_right_divider (w);
- else
- gui_draw_vertical_border (w);
- }
-
- unblock_input ();
- }
-
- /* If a row with mouse-face was overwritten, arrange for
- XTframe_up_to_date to redisplay the mouse highlight. */
- if (mouse_face_overwritten_p)
- {
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
-
- hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
- hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
- hlinfo->mouse_face_window = Qnil;
- }
-
/* Unhide the caret. This won't actually show the cursor, unless it
was visible before the corresponding call to HideCaret in
w32_update_window_begin. */
@@ -983,38 +904,37 @@ w32_set_cursor_gc (struct glyph_string *s)
else
{
/* Cursor on non-default face: must merge. */
- XGCValues xgcv;
+ Emacs_GC egc;
unsigned long mask;
- xgcv.background = s->f->output_data.w32->cursor_pixel;
- xgcv.foreground = s->face->background;
+ egc.background = s->f->output_data.w32->cursor_pixel;
+ egc.foreground = s->face->background;
/* If the glyph would be invisible, try a different foreground. */
- if (xgcv.foreground == xgcv.background)
- xgcv.foreground = s->face->foreground;
- if (xgcv.foreground == xgcv.background)
- xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
- if (xgcv.foreground == xgcv.background)
- xgcv.foreground = s->face->foreground;
+ if (egc.foreground == egc.background)
+ egc.foreground = s->face->foreground;
+ if (egc.foreground == egc.background)
+ egc.foreground = s->f->output_data.w32->cursor_foreground_pixel;
+ if (egc.foreground == egc.background)
+ egc.foreground = s->face->foreground;
/* Make sure the cursor is distinct from text in this face. */
- if (xgcv.background == s->face->background
- && xgcv.foreground == s->face->foreground)
+ if (egc.background == s->face->background
+ && egc.foreground == s->face->foreground)
{
- xgcv.background = s->face->foreground;
- xgcv.foreground = s->face->background;
+ egc.background = s->face->foreground;
+ egc.foreground = s->face->background;
}
IF_DEBUG (w32_check_font (s->f, s->font));
- xgcv.font = s->font;
- mask = GCForeground | GCBackground | GCFont;
+ mask = GCForeground | GCBackground;
if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
XChangeGC (NULL, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
- mask, &xgcv);
+ mask, &egc);
else
FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
- = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &xgcv);
+ = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &egc);
s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
}
@@ -1049,21 +969,20 @@ w32_set_mouse_face_gc (struct glyph_string *s)
{
/* Otherwise construct scratch_cursor_gc with values from FACE
but font FONT. */
- XGCValues xgcv;
+ Emacs_GC egc;
unsigned long mask;
- xgcv.background = s->face->background;
- xgcv.foreground = s->face->foreground;
+ egc.background = s->face->background;
+ egc.foreground = s->face->foreground;
IF_DEBUG (w32_check_font (s->f, s->font));
- xgcv.font = s->font;
- mask = GCForeground | GCBackground | GCFont;
+ mask = GCForeground | GCBackground;
if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
XChangeGC (NULL, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
- mask, &xgcv);
+ mask, &egc);
else
FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
- = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &xgcv);
+ = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &egc);
s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
}
@@ -1178,14 +1097,10 @@ w32_compute_glyph_string_overhangs (struct glyph_string *s)
&& s->first_glyph->type == CHAR_GLYPH
&& !s->font_not_found_p)
{
- unsigned *code = alloca (sizeof (unsigned) * s->nchars);
struct font *font = s->font;
struct font_metrics metrics;
- int i;
- for (i = 0; i < s->nchars; i++)
- code[i] = s->char2b[i];
- font->driver->text_extents (font, code, s->nchars, &metrics);
+ font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
s->right_overhang = (metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0);
s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
@@ -1430,7 +1345,7 @@ static void
w32_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
{
struct glyph *glyph = s->first_glyph;
- XChar2b char2b[8];
+ unsigned char2b[8];
int x, i, j;
bool with_background;
@@ -1487,16 +1402,12 @@ w32_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
{
struct font *font = s->font;
int upper_len = (len + 1) / 2;
- unsigned code;
HFONT old_font;
old_font = SelectObject (s->hdc, FONT_HANDLE (font));
/* It is certain that all LEN characters in STR are ASCII. */
for (j = 0; j < len; j++)
- {
- code = font->driver->encode_char (font, str[j]);
- STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
- }
+ char2b[j] = font->driver->encode_char (font, str[j]) & 0xFFFF;
font->driver->draw (s, 0, upper_len,
x + glyph->slice.glyphless.upper_xoff,
s->ybase + glyph->slice.glyphless.upper_yoff,
@@ -1594,7 +1505,7 @@ w32_alloc_lighter_color (struct frame *f, COLORREF *color,
colors in COLORS. On W32, we no longer try to map colors to
a palette. */
static void
-w32_query_colors (struct frame *f, XColor *colors, int ncolors)
+w32_query_colors (struct frame *f, Emacs_Color *colors, int ncolors)
{
int i;
@@ -1611,7 +1522,7 @@ w32_query_colors (struct frame *f, XColor *colors, int ncolors)
/* Store F's background color into *BGCOLOR. */
static void
-w32_query_frame_background_color (struct frame *f, XColor *bgcolor)
+w32_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
{
bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
w32_query_colors (f, bgcolor, 1);
@@ -1628,7 +1539,7 @@ static void
w32_setup_relief_color (struct frame *f, struct relief *relief, double factor,
int delta, COLORREF default_pixel)
{
- XGCValues xgcv;
+ Emacs_GC egc;
struct w32_output *di = f->output_data.w32;
unsigned long mask = GCForeground;
COLORREF pixel;
@@ -1640,22 +1551,21 @@ w32_setup_relief_color (struct frame *f, struct relief *relief, double factor,
/* TODO: Free colors (if using palette)? */
/* Allocate new color. */
- xgcv.foreground = default_pixel;
+ egc.foreground = default_pixel;
pixel = background;
if (w32_alloc_lighter_color (f, &pixel, factor, delta))
- xgcv.foreground = relief->pixel = pixel;
+ egc.foreground = relief->pixel = pixel;
- xgcv.font = NULL; /* avoid compiler warnings */
if (relief->gc == 0)
{
#if 0 /* TODO: stipple */
- xgcv.stipple = dpyinfo->gray;
+ egc.stipple = dpyinfo->gray;
mask |= GCStipple;
#endif
- relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
+ relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &egc);
}
else
- XChangeGC (NULL, relief->gc, mask, &xgcv);
+ XChangeGC (NULL, relief->gc, mask, &egc);
}
@@ -1704,7 +1614,7 @@ w32_draw_relief_rect (struct frame *f,
RECT *clip_rect)
{
int i;
- XGCValues gc;
+ Emacs_GC gc;
HDC hdc = get_frame_dc (f);
if (raised_p)
@@ -2363,7 +2273,7 @@ w32_draw_stretch_glyph_string (struct glyph_string *s)
/* Clear rest using the GC of the original non-cursor face. */
if (width < background_width)
{
- XGCValues *gc = s->face->gc;
+ Emacs_GC *gc = s->face->gc;
int y = s->y;
int w = background_width - width, h = s->height;
RECT r;
@@ -2859,7 +2769,7 @@ w32_scroll_run (struct window *w, struct run *run)
block_input ();
- /* Cursor off. Will be switched on again in w32_update_window_end. */
+ /* Cursor off. Will be switched on again in gui_update_window_end. */
gui_clear_cursor (w);
{
@@ -3506,7 +3416,7 @@ static void w32_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Objec
Lisp_Object *, Lisp_Object *,
Time *);
static void
-w32_define_cursor (Window window, Cursor cursor)
+w32_define_cursor (Window window, Emacs_Cursor cursor)
{
PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
}
@@ -5883,7 +5793,7 @@ w32_draw_bar_cursor (struct window *w, struct glyph_row *row,
/* RIF: Define cursor CURSOR on frame F. */
static void
-w32_define_frame_cursor (struct frame *f, Cursor cursor)
+w32_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
{
w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
}
@@ -6946,6 +6856,7 @@ w32_wm_set_size_hint (struct frame *f, long flags, bool user_position)
leave_crit ();
}
+
/***********************************************************************
Fonts
***********************************************************************/
@@ -7017,6 +6928,18 @@ w32_toggle_invisible_pointer (struct frame *f, bool invisible)
unblock_input ();
}
+
+/***********************************************************************
+ Image Hooks
+ ***********************************************************************/
+
+static void
+w32_free_pixmap (struct frame *_f, Emacs_Pixmap pixmap)
+{
+ DeleteObject (pixmap);
+}
+
+
/***********************************************************************
Initialization
***********************************************************************/
@@ -7196,6 +7119,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
terminal->get_string_resource_hook = w32_get_string_resource;
+ terminal->free_pixmap = w32_free_pixmap;
terminal->delete_frame_hook = w32_destroy_window;
terminal->delete_terminal_hook = w32_delete_terminal;
/* Other hooks are NULL by default. */
@@ -7271,7 +7195,7 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
/* initialize palette with white and black */
{
- XColor color;
+ Emacs_Color color;
w32_defined_color (0, "white", &color, true, false);
w32_defined_color (0, "black", &color, true, false);
}
diff --git a/src/w32term.h b/src/w32term.h
index de372d7e5d7..729e8d0fd49 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -56,7 +56,7 @@ extern BOOL bUseDflt;
struct w32_bitmap_record
{
- Pixmap pixmap;
+ Emacs_Pixmap pixmap;
char *file;
HINSTANCE hinst; /* Used to load the file */
int refcount;
@@ -114,10 +114,10 @@ struct w32_display_info
Window root_window;
/* The cursor to use for vertical scroll bars. */
- Cursor vertical_scroll_bar_cursor;
+ HCURSOR vertical_scroll_bar_cursor;
/* The cursor to use for horizontal scroll bars. */
- Cursor horizontal_scroll_bar_cursor;
+ HCURSOR horizontal_scroll_bar_cursor;
/* Resource data base */
const char *rdb;
@@ -142,7 +142,7 @@ struct w32_display_info
int smallest_font_height;
/* Reusable Graphics Context for drawing a cursor in a non-default face. */
- XGCValues *scratch_cursor_gc;
+ Emacs_GC *scratch_cursor_gc;
/* Information about the range of text currently shown in
mouse-face. */
@@ -241,7 +241,7 @@ extern void w32_set_scroll_bar_default_height (struct frame *);
extern struct w32_display_info *w32_term_init (Lisp_Object,
char *, char *);
-extern bool w32_defined_color (struct frame *, const char *, XColor *,
+extern bool w32_defined_color (struct frame *, const char *, Emacs_Color *,
bool, bool);
extern int w32_display_pixel_height (struct w32_display_info *);
extern int w32_display_pixel_width (struct w32_display_info *);
@@ -308,7 +308,7 @@ struct w32_output
HPALETTE old_palette;
/* Here are the Graphics Contexts for the default font. */
- XGCValues *cursor_gc; /* cursor drawing */
+ Emacs_GC *cursor_gc; /* cursor drawing */
/* The window used for this frame.
May be zero while the frame object is being created
@@ -348,27 +348,27 @@ struct w32_output
COLORREF scroll_bar_background_pixel;
/* Descriptor for the cursor in use for this window. */
- Cursor text_cursor;
- Cursor nontext_cursor;
- Cursor modeline_cursor;
- Cursor hand_cursor;
- Cursor hourglass_cursor;
- Cursor horizontal_drag_cursor;
- Cursor vertical_drag_cursor;
- Cursor left_edge_cursor;
- Cursor top_left_corner_cursor;
- Cursor top_edge_cursor;
- Cursor top_right_corner_cursor;
- Cursor right_edge_cursor;
- Cursor bottom_right_corner_cursor;
- Cursor bottom_edge_cursor;
- Cursor bottom_left_corner_cursor;
+ HCURSOR text_cursor;
+ HCURSOR nontext_cursor;
+ HCURSOR modeline_cursor;
+ HCURSOR hand_cursor;
+ HCURSOR hourglass_cursor;
+ HCURSOR horizontal_drag_cursor;
+ HCURSOR vertical_drag_cursor;
+ HCURSOR left_edge_cursor;
+ HCURSOR top_left_corner_cursor;
+ HCURSOR top_edge_cursor;
+ HCURSOR top_right_corner_cursor;
+ HCURSOR right_edge_cursor;
+ HCURSOR bottom_right_corner_cursor;
+ HCURSOR bottom_edge_cursor;
+ HCURSOR bottom_left_corner_cursor;
/* Non-zero means hourglass cursor is currently displayed. */
unsigned hourglass_p : 1;
/* Non-hourglass cursor that is currently active. */
- Cursor current_cursor;
+ HCURSOR current_cursor;
DWORD dwStyle;
@@ -388,7 +388,7 @@ struct w32_output
/* Relief GCs, colors etc. */
struct relief
{
- XGCValues *gc;
+ Emacs_GC *gc;
unsigned long pixel;
}
black_relief, white_relief;
@@ -420,9 +420,6 @@ extern struct w32_output w32term_display;
/* This gives the w32_display_info structure for the display F is on. */
#define FRAME_DISPLAY_INFO(f) ((void) (f), (&one_w32_display_info))
-/* This is the `Display *' which frame F is on. */
-#define FRAME_X_DISPLAY(f) (0)
-
#define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement)
#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode)
@@ -724,7 +721,7 @@ extern void complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result);
extern BOOL parse_button (int, int, int *, int *);
extern void w32_sys_ring_bell (struct frame *f);
-extern void w32_query_color (struct frame *, XColor *);
+extern void w32_query_color (struct frame *, Emacs_Color *);
extern void w32_delete_display (struct w32_display_info *dpyinfo);
#define FILE_NOTIFICATIONS_SIZE 16384
@@ -808,7 +805,7 @@ typedef struct tagTRACKMOUSEEVENT
struct image;
struct face;
-XGCValues *XCreateGC (void *, HWND, unsigned long, XGCValues *);
+Emacs_GC *XCreateGC (void *, HWND, unsigned long, Emacs_GC *);
typedef DWORD (WINAPI * ClipboardSequence_Proc) (void);
typedef BOOL (WINAPI * AppendMenuW_Proc) (
diff --git a/src/window.c b/src/window.c
index 30ffad0e513..deeb4f63fe0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3947,8 +3947,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
b->display_error_modiff = 0;
/* Update time stamps of buffer display. */
- if (FIXNUMP (BVAR (b, display_count)))
- bset_display_count (b, make_fixnum (XFIXNUM (BVAR (b, display_count)) + 1));
+ if (INTEGERP (BVAR (b, display_count)))
+ bset_display_count (b, Fadd1 (BVAR (b, display_count)));
bset_display_time (b, Fcurrent_time ());
w->window_end_pos = 0;
@@ -4089,7 +4089,7 @@ displaying that buffer. */)
return Qt;
}
- if (WINDOWP (object))
+ if (WINDOW_LIVE_P (object))
{
struct window *w = XWINDOW (object);
mark_window_display_accurate (object, false);
diff --git a/src/xdisp.c b/src/xdisp.c
index c677831020f..a448c90d8eb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -376,7 +376,26 @@ static Lisp_Object list_of_error;
|| it->s[IT_BYTEPOS (*it)] == '\t')) \
|| (IT_BYTEPOS (*it) < ZV_BYTE \
&& (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
- || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
+ || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t'))))
+
+/* If all the conditions needed to print the fill column indicator are
+ met, return the (nonnegative) column number, else return a negative
+ value. */
+static int
+fill_column_indicator_column (struct it *it)
+{
+ if (Vdisplay_fill_column_indicator
+ && it->continuation_lines_width == 0
+ && CHARACTERP (Vdisplay_fill_column_indicator_character))
+ {
+ Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt)
+ ? BVAR (current_buffer, fill_column)
+ : Vdisplay_fill_column_indicator_column);
+ if (RANGED_FIXNUMP (0, col, INT_MAX))
+ return XFIXNUM (col);
+ }
+ return -1;
+}
/* True means print newline to stdout before next mini-buffer message. */
@@ -2070,7 +2089,7 @@ frame_to_window_pixel_xy (struct window *w, int *x, int *y)
int
get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
{
- XRectangle r;
+ Emacs_Rectangle r;
if (n <= 0)
return 0;
@@ -2132,7 +2151,7 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
take the intersection with the rectangle of the cursor. */
if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
{
- XRectangle rc, r_save = r;
+ Emacs_Rectangle rc, r_save = r;
rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
rc.y = s->w->phys_cursor.y;
@@ -2198,7 +2217,7 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
if (s->row->clip)
{
- XRectangle r_save = r;
+ Emacs_Rectangle r_save = r;
if (! gui_intersect_rectangles (&r_save, s->row->clip, &r))
r.width = 0;
@@ -2207,8 +2226,8 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
if ((s->for_overlaps & OVERLAPS_BOTH) == 0
|| ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
{
-#ifdef CONVERT_FROM_XRECT
- CONVERT_FROM_XRECT (r, *rects);
+#ifdef CONVERT_FROM_EMACS_RECT
+ CONVERT_FROM_EMACS_RECT (r, *rects);
#else
*rects = r;
#endif
@@ -2220,10 +2239,10 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
multiple clipping rectangles, we exclude the row of the glyph
string from the clipping rectangle. This is to avoid drawing
the same text on the environment with anti-aliasing. */
-#ifdef CONVERT_FROM_XRECT
- XRectangle rs[2];
+#ifdef CONVERT_FROM_EMACS_RECT
+ Emacs_Rectangle rs[2];
#else
- XRectangle *rs = rects;
+ Emacs_Rectangle *rs = rects;
#endif
int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
@@ -2256,9 +2275,9 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
}
n = i;
-#ifdef CONVERT_FROM_XRECT
+#ifdef CONVERT_FROM_EMACS_RECT
for (i = 0; i < n; i++)
- CONVERT_FROM_XRECT (rs[i], rects[i]);
+ CONVERT_FROM_EMACS_RECT (rs[i], rects[i]);
#endif
return n;
}
@@ -13977,12 +13996,6 @@ redisplay_internal (void)
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
if (popup_activated ())
{
-#ifdef NS_IMPL_COCOA
- /* On macOS we may have disabled screen updates due to window
- resizing. We should re-enable them so the popup can be
- displayed. */
- ns_enable_screen_updates ();
-#endif
return;
}
#endif
@@ -14785,12 +14798,6 @@ unwind_redisplay (void)
{
redisplaying_p = false;
unblock_buffer_flips ();
-#ifdef NS_IMPL_COCOA
- /* On macOS we may have disabled screen updates due to window
- resizing. When redisplay completes we want to re-enable
- them. */
- ns_enable_screen_updates ();
-#endif
}
@@ -18031,12 +18038,14 @@ try_window_reusing_current_matrix (struct window *w)
if (run.height > 0 && run.current_y != run.desired_y)
{
+#ifdef HAVE_WINDOW_SYSTEM
update_begin (f);
- FRAME_RIF (f)->update_window_begin_hook (w);
+ gui_update_window_begin (w);
FRAME_RIF (f)->clear_window_mouse_face (w);
FRAME_RIF (f)->scroll_run_hook (w, &run);
- FRAME_RIF (f)->update_window_end_hook (w, false, false);
+ gui_update_window_end (w, false, false);
update_end (f);
+#endif
}
/* Shift current matrix down by nrows_scrolled lines. */
@@ -18195,12 +18204,14 @@ try_window_reusing_current_matrix (struct window *w)
if (run.height)
{
+#ifdef HAVE_WINDOW_SYSTEM
update_begin (f);
- FRAME_RIF (f)->update_window_begin_hook (w);
+ gui_update_window_begin (w);
FRAME_RIF (f)->clear_window_mouse_face (w);
FRAME_RIF (f)->scroll_run_hook (w, &run);
- FRAME_RIF (f)->update_window_end_hook (w, false, false);
+ gui_update_window_end (w, false, false);
update_end (f);
+#endif
}
/* Adjust Y positions of reused rows. */
@@ -19148,10 +19159,12 @@ try_window_id (struct window *w)
if (FRAME_WINDOW_P (f))
{
- FRAME_RIF (f)->update_window_begin_hook (w);
+#ifdef HAVE_WINDOW_SYSTEM
+ gui_update_window_begin (w);
FRAME_RIF (f)->clear_window_mouse_face (w);
FRAME_RIF (f)->scroll_run_hook (w, &run);
- FRAME_RIF (f)->update_window_end_hook (w, false, false);
+ gui_update_window_end (w, false, false);
+#endif
}
else
{
@@ -20147,15 +20160,53 @@ append_space_for_newline (struct it *it, bool default_face_p)
it->what = IT_CHARACTER;
memset (&it->position, 0, sizeof it->position);
it->object = Qnil;
- it->c = it->char_to_display = ' ';
it->len = 1;
+ int local_default_face_id =
+ lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
+ struct face* default_face =
+ FACE_FROM_ID_OR_NULL (it->f, local_default_face_id);
+
+ /* Corner case for when display-fill-column-indicator-mode
+ is active and the extra character should be added in the
+ same place than the line. */
+ int indicator_column = (it->w->pseudo_window_p == 0
+ ? fill_column_indicator_column (it)
+ : -1);
+ if (0 <= indicator_column)
+ {
+ struct font *font =
+ default_face->font ?
+ default_face->font : FRAME_FONT (it->f);
+ const int char_width =
+ font->average_width ?
+ font->average_width : font->space_width;
+
+ int column_x;
+ if (!INT_MULTIPLY_WRAPV (indicator_column, char_width,
+ &column_x)
+ && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x,
+ &column_x)
+ && it->current_x == column_x)
+ {
+ it->c = it->char_to_display =
+ XFIXNAT (Vdisplay_fill_column_indicator_character);
+ it->face_id =
+ merge_faces (it->w, Qfill_column_indicator,
+ 0, saved_face_id);
+ face = FACE_FROM_ID (it->f, it->face_id);
+ goto produce_glyphs;
+ }
+ }
+
+ it->c = it->char_to_display = ' ';
/* If the default face was remapped, be sure to use the
remapped face for the appended newline. */
if (default_face_p)
- it->face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
+ it->face_id = local_default_face_id;
else if (it->face_before_selective_p)
it->face_id = it->saved_face_id;
+
face = FACE_FROM_ID (it->f, it->face_id);
it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
/* In R2L rows, we will prepend a stretch glyph that will
@@ -20169,6 +20220,7 @@ append_space_for_newline (struct it *it, bool default_face_p)
&& saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
it->end_of_box_run_p = false;
+ produce_glyphs:
PRODUCE_GLYPHS (it);
#ifdef HAVE_WINDOW_SYSTEM
@@ -20317,7 +20369,8 @@ extend_face_to_end_of_line (struct it *it)
#ifdef HAVE_WINDOW_SYSTEM
&& !face->stipple
#endif
- && !it->glyph_row->reversed_p)
+ && !it->glyph_row->reversed_p
+ && !Vdisplay_fill_column_indicator)
return;
/* Set the glyph row flag indicating that the face of the last glyph
@@ -20369,6 +20422,82 @@ extend_face_to_end_of_line (struct it *it)
default_face->id;
it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
}
+
+ /* Display fill column indicator if not in modeline or
+ toolbar and display fill column indicator mode is
+ active. */
+ int indicator_column = (it->w->pseudo_window_p == 0
+ ? fill_column_indicator_column (it)
+ : -1);
+ if (0 <= indicator_column)
+ {
+ struct font *font =
+ default_face->font ? default_face->font : FRAME_FONT (f);
+ const int char_width =
+ font->average_width ?
+ font->average_width : font->space_width;
+
+ int column_x;
+ if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x)
+ && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x)
+ && it->current_x <= column_x
+ && column_x <= it->last_visible_x)
+ {
+ const char saved_char = it->char_to_display;
+ const struct text_pos saved_pos = it->position;
+ const bool saved_avoid_cursor = it->avoid_cursor_p;
+ const int saved_face_id = it->face_id;
+ const bool saved_box_start = it->start_of_box_run_p;
+ Lisp_Object save_object = it->object;
+
+ /* The stretch width needs to considet the latter
+ added glyph. */
+ const int stretch_width =
+ column_x - it->current_x - char_width;
+
+ memset (&it->position, 0, sizeof it->position);
+ it->avoid_cursor_p = true;
+ it->object = Qnil;
+
+ /* Only generate a stretch glyph if there is distance
+ between current_x and and the indicator position. */
+ if (stretch_width > 0)
+ {
+ int stretch_ascent = (((it->ascent + it->descent)
+ * FONT_BASE (font)) / FONT_HEIGHT (font));
+ append_stretch_glyph (it, Qnil, stretch_width,
+ it->ascent + it->descent,
+ stretch_ascent);
+ }
+
+ /* Generate the glyph indicator only if
+ append_space_for_newline didn't already. */
+ if (it->current_x < column_x)
+ {
+ it->char_to_display =
+ XFIXNAT (Vdisplay_fill_column_indicator_character);
+ it->face_id =
+ merge_faces (it->w, Qfill_column_indicator,
+ 0, saved_face_id);
+ PRODUCE_GLYPHS (it);
+ }
+
+ /* Restore the face after the indicator was generated. */
+ it->face_id = saved_face_id;
+
+ /* If there is space after the indicator generate an
+ extra empty glyph to restore the face. Issue was
+ observed in X systems. */
+ it->char_to_display = ' ';
+ PRODUCE_GLYPHS (it);
+
+ it->char_to_display = saved_char;
+ it->position = saved_pos;
+ it->avoid_cursor_p = saved_avoid_cursor;
+ it->start_of_box_run_p = saved_box_start;
+ it->object = save_object;
+ }
+ }
}
#ifdef HAVE_WINDOW_SYSTEM
if (it->glyph_row->reversed_p)
@@ -20377,7 +20506,7 @@ extend_face_to_end_of_line (struct it *it)
rightmost glyph will be drawn flushed all the way to the
right margin of the window. The stretch glyph that will
occupy the empty space, if any, to the left of the
- glyphs. */
+ glyph. */
struct font *font = face->font ? face->font : FRAME_FONT (f);
struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
@@ -20490,10 +20619,35 @@ extend_face_to_end_of_line (struct it *it)
it->face_id = default_face->id;
else
it->face_id = face->id;
- PRODUCE_GLYPHS (it);
- while (it->current_x <= it->last_visible_x)
- PRODUCE_GLYPHS (it);
+ /* Display fill-column indicator if needed. */
+ int indicator_column = fill_column_indicator_column (it);
+ if (0 <= indicator_column
+ && INT_ADD_WRAPV (it->lnum_pixel_width, indicator_column,
+ &indicator_column))
+ indicator_column = -1;
+ do
+ {
+ int saved_face_id;
+ bool indicate = it->current_x == indicator_column;
+ if (indicate)
+ {
+ saved_face_id = it->face_id;
+ it->face_id =
+ merge_faces (it->w, Qfill_column_indicator, 0, saved_face_id);
+ it->c = it->char_to_display =
+ XFIXNAT (Vdisplay_fill_column_indicator_character);
+ }
+
+ PRODUCE_GLYPHS (it);
+
+ if (indicate)
+ {
+ it->face_id = saved_face_id;
+ it->c = it->char_to_display = ' ';
+ }
+ }
+ while (it->current_x <= it->last_visible_x);
if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
&& (it->glyph_row->used[RIGHT_MARGIN_AREA]
@@ -20583,7 +20737,8 @@ highlight_trailing_whitespace (struct it *it)
if (!row->reversed_p)
{
while (glyph >= start
- && glyph->type == CHAR_GLYPH
+ && (glyph->type == CHAR_GLYPH
+ || glyph->type == STRETCH_GLYPH)
&& NILP (glyph->object))
--glyph;
}
@@ -23843,7 +23998,8 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
? string_byte_to_char (elt, bytepos)
: bytepos);
spec = decode_mode_spec (it->w, c, field, &string);
- multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
+ eassert (NILP (string) || STRINGP (string));
+ multibyte = !NILP (string) && STRING_MULTIBYTE (string);
switch (mode_line_target)
{
@@ -24519,8 +24675,9 @@ percent99 (ptrdiff_t n, ptrdiff_t d)
/* Return a string for the output of a mode line %-spec for window W,
generated by character C. FIELD_WIDTH > 0 means pad the string
- returned with spaces to that value. Return a Lisp string in
- *STRING if the resulting string is taken from that Lisp string.
+ returned with spaces to that value. Set *STRING to be a Lisp
+ string if the resulting string is taken from that Lisp string;
+ otherwise, set *STRING to Qnil.
Note we operate on the current buffer for most purposes. */
@@ -25729,7 +25886,7 @@ dump_glyph_string (struct glyph_string *s)
#endif /* GLYPH_DEBUG */
/* Initialize glyph string S. CHAR2B is a suitably allocated vector
- of XChar2b structures for S; it can't be allocated in
+ of 2-byte unsigned integers for S; it can't be allocated in
init_glyph_string because it must be allocated via `alloca'. W
is the window on which S is drawn. ROW and AREA are the glyph row
and area within the row from which S is constructed. START is the
@@ -25759,7 +25916,7 @@ init_glyph_string (struct glyph_string *s,
#ifdef HAVE_NTGUI
HDC hdc,
#endif
- XChar2b *char2b, struct window *w, struct glyph_row *row,
+ unsigned *char2b, struct window *w, struct glyph_row *row,
enum glyph_row_area area, int start, enum draw_glyphs_face hl)
{
memset (s, 0, sizeof *s);
@@ -25768,7 +25925,6 @@ init_glyph_string (struct glyph_string *s,
#ifdef HAVE_NTGUI
s->hdc = hdc;
#endif
- s->display = FRAME_X_DISPLAY (s->f);
s->char2b = char2b;
s->hl = hl;
s->row = row;
@@ -25839,7 +25995,7 @@ append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
static struct face *
get_char_face_and_encoding (struct frame *f, int c, int face_id,
- XChar2b *char2b, bool display_p)
+ unsigned *char2b, bool display_p)
{
struct face *face = FACE_FROM_ID (f, face_id);
unsigned code = 0;
@@ -25851,7 +26007,8 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
if (code == FONT_INVALID_CODE)
code = 0;
}
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ /* Ensure that the code is only 2 bytes wide. */
+ *char2b = code & 0xFFFF;
/* Make sure X resources of the face are allocated. */
#ifdef HAVE_X_WINDOWS
@@ -25872,7 +26029,7 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
static struct face *
get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
- XChar2b *char2b)
+ unsigned *char2b)
{
struct face *face;
unsigned code = 0;
@@ -25894,7 +26051,8 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
code = 0;
}
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ /* Ensure that the code is only 2 bytes wide. */
+ *char2b = code & 0xFFFF;
return face;
}
@@ -25903,7 +26061,7 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
Return true iff FONT has a glyph for C. */
static bool
-get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
+get_char_glyph_code (int c, struct font *font, unsigned *char2b)
{
unsigned code;
@@ -25914,7 +26072,9 @@ get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
if (code == FONT_INVALID_CODE)
return false;
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+
+ /* Ensure that the code is only 2 bytes wide. */
+ *char2b = code & 0xFFFF;
return true;
}
@@ -26027,7 +26187,8 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id,
Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
unsigned code = LGLYPH_CODE (lglyph);
- STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
+ /* Ensure that the code is only 2 bytes wide. */
+ s->char2b[i] = code & 0xFFFF;
}
s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
return glyph - s->row->glyphs[s->area];
@@ -26206,17 +26367,16 @@ fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
}
static struct font_metrics *
-get_per_char_metric (struct font *font, XChar2b *char2b)
+get_per_char_metric (struct font *font, const unsigned *char2b)
{
static struct font_metrics metrics;
- unsigned code;
if (! font)
return NULL;
- code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
- if (code == FONT_INVALID_CODE)
+ if (*char2b == FONT_INVALID_CODE)
return NULL;
- font->driver->text_extents (font, &code, 1, &metrics);
+
+ font->driver->text_extents (font, char2b, 1, &metrics);
return &metrics;
}
@@ -26234,7 +26394,7 @@ normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
if (FONT_TOO_HIGH (font))
{
- XChar2b char2b;
+ unsigned char2b;
/* Get metrics of C, defaulting to a reasonably sized ASCII
character. */
@@ -26281,7 +26441,7 @@ gui_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *r
if (glyph->type == CHAR_GLYPH)
{
- XChar2b char2b;
+ unsigned char2b;
struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
if (face->font)
{
@@ -26595,7 +26755,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
do \
{ \
int face_id; \
- XChar2b *char2b; \
+ unsigned *char2b; \
\
face_id = (row)->glyphs[area][START].face_id; \
\
@@ -26624,7 +26784,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
struct face *base_face = FACE_FROM_ID (f, face_id); \
ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
struct composition *cmp = composition_table[cmp_id]; \
- XChar2b *char2b; \
+ unsigned *char2b; \
struct glyph_string *first_s = NULL; \
int n; \
\
@@ -26656,7 +26816,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
#define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
do { \
int face_id; \
- XChar2b *char2b; \
+ unsigned *char2b; \
Lisp_Object gstring; \
\
face_id = (row)->glyphs[area][START].face_id; \
@@ -28249,7 +28409,7 @@ gui_produce_glyphs (struct it *it)
if (it->what == IT_CHARACTER)
{
- XChar2b char2b;
+ unsigned char2b;
struct face *face = FACE_FROM_ID (it->f, it->face_id);
struct font *font = face->font;
struct font_metrics *pcm = NULL;
@@ -28648,7 +28808,7 @@ gui_produce_glyphs (struct it *it)
int lbearing, rbearing;
int i, width, ascent, descent;
int c;
- XChar2b char2b;
+ unsigned char2b;
struct font_metrics *pcm;
ptrdiff_t pos;
@@ -30969,7 +31129,7 @@ Returns the alist element for the first matching AREA in MAP. */)
/* Display frame CURSOR, optionally using shape defined by POINTER. */
static void
-define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
+define_frame_cursor1 (struct frame *f, Emacs_Cursor cursor, Lisp_Object pointer)
{
#ifdef HAVE_WINDOW_SYSTEM
if (!FRAME_WINDOW_P (f))
@@ -31021,7 +31181,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- Cursor cursor = No_Cursor;
+ Emacs_Cursor cursor = No_Cursor;
Lisp_Object pointer = Qnil;
int dx, dy, width, height;
ptrdiff_t charpos;
@@ -31334,7 +31494,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
enum window_part part = ON_NOTHING;
Lisp_Object window;
struct window *w;
- Cursor cursor = No_Cursor;
+ Emacs_Cursor cursor = No_Cursor;
Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
struct buffer *b;
@@ -31642,7 +31802,9 @@ note_mouse_highlight (struct frame *f, int x, int y)
is currently hidden to avoid Bug#30519. */
|| (!hlinfo->mouse_face_hidden
&& OVERLAYP (hlinfo->mouse_face_overlay)
- && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
+ /* It's possible the overlay was deleted (Bug#35273). */
+ && XMARKER (OVERLAY_START (hlinfo->mouse_face_overlay))->buffer
+ && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
{
/* Find the highest priority overlay with a mouse-face. */
Lisp_Object overlay = Qnil;
@@ -31951,7 +32113,7 @@ cancel_mouse_face (struct frame *f)
which intersects rectangle R. R is in window-relative coordinates. */
static void
-expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
+expose_area (struct window *w, struct glyph_row *row, const Emacs_Rectangle *r,
enum glyph_row_area area)
{
struct glyph *first = row->glyphs[area];
@@ -32009,7 +32171,7 @@ expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
true if mouse-face was overwritten. */
static bool
-expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
+expose_line (struct window *w, struct glyph_row *row, const Emacs_Rectangle *r)
{
eassert (row->enabled_p);
@@ -32044,7 +32206,7 @@ static void
expose_overlaps (struct window *w,
struct glyph_row *first_overlapping_row,
struct glyph_row *last_overlapping_row,
- XRectangle *r)
+ const Emacs_Rectangle *r)
{
struct glyph_row *row;
@@ -32070,9 +32232,9 @@ expose_overlaps (struct window *w,
/* Return true if W's cursor intersects rectangle R. */
static bool
-phys_cursor_in_rect_p (struct window *w, XRectangle *r)
+phys_cursor_in_rect_p (struct window *w, const Emacs_Rectangle *r)
{
- XRectangle cr, result;
+ Emacs_Rectangle cr, result;
struct glyph *cursor_glyph;
struct glyph_row *row;
@@ -32230,10 +32392,10 @@ gui_draw_bottom_divider (struct window *w)
mouse-face. */
static bool
-expose_window (struct window *w, XRectangle *fr)
+expose_window (struct window *w, const Emacs_Rectangle *fr)
{
struct frame *f = XFRAME (w->frame);
- XRectangle wr, r;
+ Emacs_Rectangle wr, r;
bool mouse_face_overwritten_p = false;
/* If window is not yet fully initialized, do nothing. This can
@@ -32392,7 +32554,7 @@ expose_window (struct window *w, XRectangle *fr)
true if the exposure overwrites mouse-face. */
static bool
-expose_window_tree (struct window *w, XRectangle *r)
+expose_window_tree (struct window *w, const Emacs_Rectangle *r)
{
struct frame *f = XFRAME (w->frame);
bool mouse_face_overwritten_p = false;
@@ -32420,7 +32582,7 @@ expose_window_tree (struct window *w, XRectangle *r)
void
expose_frame (struct frame *f, int x, int y, int w, int h)
{
- XRectangle r;
+ Emacs_Rectangle r;
bool mouse_face_overwritten_p = false;
TRACE ((stderr, "expose_frame "));
@@ -32507,10 +32669,11 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
empty. */
bool
-gui_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
+gui_intersect_rectangles (const Emacs_Rectangle *r1, const Emacs_Rectangle *r2,
+ Emacs_Rectangle *result)
{
- XRectangle *left, *right;
- XRectangle *upper, *lower;
+ const Emacs_Rectangle *left, *right;
+ const Emacs_Rectangle *upper, *lower;
bool intersection_p = false;
/* Rearrange so that R1 is the left-most rectangle. */
@@ -32656,6 +32819,9 @@ be let-bound around code that needs to disable messages temporarily. */);
/* Name of a text property which disables line-number display. */
DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
+ /* Name of the face used to display fill column indicator character. */
+ DEFSYM (Qfill_column_indicator, "fill-column-indicator");
+
/* Name and number of the face used to highlight escape glyphs. */
DEFSYM (Qescape_glyph, "escape-glyph");
@@ -33228,6 +33394,30 @@ either `relative' or `visual'. */);
DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
+ DEFVAR_BOOL ("display-fill-column-indicator", Vdisplay_fill_column_indicator,
+ doc: /* Non-nil means display the fill column indicator. */);
+ Vdisplay_fill_column_indicator = false;
+ DEFSYM (Qdisplay_fill_column_indicator, "display-fill-column-indicator");
+ Fmake_variable_buffer_local (Qdisplay_fill_column_indicator);
+
+ DEFVAR_LISP ("display-fill-column-indicator-column", Vdisplay_fill_column_indicator_column,
+ doc: /* Column for indicator when `display-fill-column-indicator'
+is non-nil. The default value is t which means that the indicator
+will use the `fill-column' variable. If it is set to an integer the
+indicator will be drawn in that column. */);
+ Vdisplay_fill_column_indicator_column = Qt;
+ DEFSYM (Qdisplay_fill_column_indicator_column, "display-fill-column-indicator-column");
+ Fmake_variable_buffer_local (Qdisplay_fill_column_indicator_column);
+
+ DEFVAR_LISP ("display-fill-column-indicator-character", Vdisplay_fill_column_indicator_character,
+ doc: /* Character to draw the indicator when
+`display-fill-column-indicator' is non-nil. The default is U+2502 but
+a good alternative is (ascii 124) if the font in fill-column-indicator
+face does not support Unicode characters. */);
+ Vdisplay_fill_column_indicator_character = Qnil;
+ DEFSYM (Qdisplay_fill_column_indicator_character, "display-fill-column-indicator-character");
+ Fmake_variable_buffer_local (Qdisplay_fill_column_indicator_character);
+
DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
doc: /* Non-nil means don't eval Lisp during redisplay. */);
inhibit_eval_during_redisplay = false;
diff --git a/src/xfaces.c b/src/xfaces.c
index 7e04c0e9953..d211ec8c460 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -348,7 +348,7 @@ static void free_face_cache (struct face_cache *);
static bool merge_face_ref (struct window *w,
struct frame *, Lisp_Object, Lisp_Object *,
bool, struct named_merge_point *);
-static int color_distance (XColor *x, XColor *y);
+static int color_distance (Emacs_Color *x, Emacs_Color *y);
#ifdef HAVE_WINDOW_SYSTEM
static void set_font_frame_param (Lisp_Object, Lisp_Object);
@@ -513,12 +513,12 @@ x_free_gc (struct frame *f, GC gc)
#ifdef HAVE_NTGUI
/* W32 emulation of GCs */
-static GC
-x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
+static Emacs_GC *
+x_create_gc (struct frame *f, unsigned long mask, Emacs_GC *egc)
{
- GC gc;
+ Emacs_GC *gc;
block_input ();
- gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
+ gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, egc);
unblock_input ();
IF_DEBUG (++ngcs);
return gc;
@@ -528,7 +528,7 @@ x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
/* Free GC which was used on frame F. */
static void
-x_free_gc (struct frame *f, GC gc)
+x_free_gc (struct frame *f, Emacs_GC *gc)
{
IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
xfree (gc);
@@ -539,18 +539,18 @@ x_free_gc (struct frame *f, GC gc)
#ifdef HAVE_NS
/* NS emulation of GCs */
-static GC
+static Emacs_GC *
x_create_gc (struct frame *f,
unsigned long mask,
- XGCValues *xgcv)
+ Emacs_GC *egc)
{
- GC gc = xmalloc (sizeof *gc);
- *gc = *xgcv;
+ Emacs_GC *gc = xmalloc (sizeof *gc);
+ *gc = *egc;
return gc;
}
static void
-x_free_gc (struct frame *f, GC gc)
+x_free_gc (struct frame *f, Emacs_GC *gc)
{
xfree (gc);
}
@@ -802,7 +802,7 @@ load_pixmap (struct frame *f, Lisp_Object name)
/***********************************************************************
- X Colors
+ Color Handling
***********************************************************************/
/* Parse RGB_LIST, and fill in the RGB fields of COLOR.
@@ -810,7 +810,7 @@ load_pixmap (struct frame *f, Lisp_Object name)
Return true iff RGB_LIST is OK. */
static bool
-parse_rgb_list (Lisp_Object rgb_list, XColor *color)
+parse_rgb_list (Lisp_Object rgb_list, Emacs_Color *color)
{
#define PARSE_RGB_LIST_FIELD(field) \
if (CONSP (rgb_list) && FIXNUMP (XCAR (rgb_list))) \
@@ -835,8 +835,8 @@ parse_rgb_list (Lisp_Object rgb_list, XColor *color)
returned in it. */
static bool
-tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
- XColor *std_color)
+tty_lookup_color (struct frame *f, Lisp_Object color, Emacs_Color *tty_color,
+ Emacs_Color *std_color)
{
Lisp_Object frame, color_desc;
@@ -897,7 +897,7 @@ tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
bool
tty_defined_color (struct frame *f, const char *color_name,
- XColor *color_def, bool alloc, bool _makeIndex)
+ Emacs_Color *color_def, bool alloc, bool _makeIndex)
{
bool status = true;
@@ -965,7 +965,7 @@ tty_color_name (struct frame *f, int idx)
static bool
face_color_gray_p (struct frame *f, const char *color_name)
{
- XColor color;
+ Emacs_Color color;
bool gray_p;
if (FRAME_TERMINAL (f)->defined_color_hook
@@ -994,7 +994,7 @@ face_color_supported_p (struct frame *f, const char *color_name,
bool background_p)
{
Lisp_Object frame;
- XColor not_used;
+ Emacs_Color not_used;
XSETFRAME (frame, f);
return
@@ -1043,7 +1043,7 @@ COLOR must be a valid color name. */)
static unsigned long
load_color2 (struct frame *f, struct face *face, Lisp_Object name,
- enum lface_attribute_index target_index, XColor *color)
+ enum lface_attribute_index target_index, Emacs_Color *color)
{
eassert (STRINGP (name));
eassert (target_index == LFACE_FOREGROUND_INDEX
@@ -1117,7 +1117,7 @@ unsigned long
load_color (struct frame *f, struct face *face, Lisp_Object name,
enum lface_attribute_index target_index)
{
- XColor color;
+ Emacs_Color color;
return load_color2 (f, face, name, target_index, &color);
}
@@ -1134,7 +1134,7 @@ load_face_colors (struct frame *f, struct face *face,
Lisp_Object attrs[LFACE_VECTOR_SIZE])
{
Lisp_Object fg, bg, dfg;
- XColor xfg, xbg;
+ Emacs_Color xfg, xbg;
bg = attrs[LFACE_BACKGROUND_INDEX];
fg = attrs[LFACE_FOREGROUND_INDEX];
@@ -2265,11 +2265,12 @@ filter_face_ref (Lisp_Object face_ref,
}
/* Merge face attributes from the lisp `face reference' FACE_REF on
- frame F into the face attribute vector TO. If ERR_MSGS,
- problems with FACE_REF cause an error message to be shown. Return
- true if no errors occurred (regardless of the value of ERR_MSGS).
- Use NAMED_MERGE_POINTS to detect loops in face inheritance or
- list structure; it may be 0 for most callers.
+ frame F into the face attribute vector TO as appropriate for
+ window W; W is used only for filtering face specs. If ERR_MSGS
+ is non-zero, problems with FACE_REF cause an error message to be
+ shown. Return true if no errors occurred (regardless of the value
+ of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face
+ inheritance or list structure; it may be 0 for most callers.
FACE_REF may be a single face specification or a list of such
specifications. Each face specification can be:
@@ -2286,9 +2287,10 @@ filter_face_ref (Lisp_Object face_ref,
4. Conses of the form
(:filtered (:window PARAMETER VALUE) FACE-SPECIFICATION),
- which applies FACE-SPECIFICATION only if the
- given face attributes are being evaluated in the context of a
- window with a parameter named PARAMETER being EQ VALUE.
+ which applies FACE-SPECIFICATION only if the given face attributes
+ are being evaluated in the context of a window with a parameter
+ named PARAMETER being EQ VALUE. In this case, W specifies the window
+ for which the filtered face spec is to be evaluated.
5. nil, which means to merge nothing.
@@ -4138,25 +4140,25 @@ prepare_face_for_display (struct frame *f, struct face *face)
if (face->gc == 0)
{
- XGCValues xgcv;
+ Emacs_GC egc;
unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
- xgcv.foreground = face->foreground;
- xgcv.background = face->background;
+ egc.foreground = face->foreground;
+ egc.background = face->background;
#ifdef HAVE_X_WINDOWS
- xgcv.graphics_exposures = False;
+ egc.graphics_exposures = False;
#endif
block_input ();
#ifdef HAVE_X_WINDOWS
if (face->stipple)
{
- xgcv.fill_style = FillOpaqueStippled;
- xgcv.stipple = image_bitmap_pixmap (f, face->stipple);
+ egc.fill_style = FillOpaqueStippled;
+ egc.stipple = image_bitmap_pixmap (f, face->stipple);
mask |= GCFillStyle | GCStipple;
}
#endif
- face->gc = x_create_gc (f, mask, &xgcv);
+ face->gc = x_create_gc (f, mask, &egc);
if (face->font)
font_prepare_for_face (f, face);
unblock_input ();
@@ -4168,7 +4170,7 @@ prepare_face_for_display (struct frame *f, struct face *face)
/* Returns the `distance' between the colors X and Y. */
static int
-color_distance (XColor *x, XColor *y)
+color_distance (Emacs_Color *x, Emacs_Color *y)
{
/* This formula is from a paper titled `Colour metric' by Thiadmer Riemersma.
Quoting from that paper:
@@ -4203,7 +4205,7 @@ two lists of the form (RED GREEN BLUE) aforementioned. */)
Lisp_Object metric)
{
struct frame *f = decode_live_frame (frame);
- XColor cdef1, cdef2;
+ Emacs_Color cdef1, cdef2;
if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
&& !(STRINGP (color1)
@@ -4883,8 +4885,8 @@ tty_supports_face_attributes_p (struct frame *f,
{
int weight, slant;
Lisp_Object val, fg, bg;
- XColor fg_tty_color, fg_std_color;
- XColor bg_tty_color, bg_std_color;
+ Emacs_Color fg_tty_color, fg_std_color;
+ Emacs_Color bg_tty_color, bg_std_color;
unsigned test_caps = 0;
Lisp_Object *def_attrs = def_face->lface;
@@ -4986,7 +4988,7 @@ tty_supports_face_attributes_p (struct frame *f,
else
/* Make sure the color is really different than the default. */
{
- XColor def_fg_color;
+ Emacs_Color def_fg_color;
if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
&& (color_distance (&fg_tty_color, &def_fg_color)
<= TTY_SAME_COLOR_THRESHOLD))
@@ -5010,7 +5012,7 @@ tty_supports_face_attributes_p (struct frame *f,
else
/* Make sure the color is really different than the default. */
{
- XColor def_bg_color;
+ Emacs_Color def_bg_color;
if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
&& (color_distance (&bg_tty_color, &def_bg_color)
<= TTY_SAME_COLOR_THRESHOLD))
diff --git a/src/xfns.c b/src/xfns.c
index 7ef69f1b222..460dd1316e6 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -653,7 +653,7 @@ gamma_correct (struct frame *f, XColor *color)
bool
x_defined_color (struct frame *f, const char *color_name,
- XColor *color, bool alloc_p, bool _makeIndex)
+ Emacs_Color *color, bool alloc_p, bool _makeIndex)
{
bool success_p = false;
Colormap cmap = FRAME_X_COLORMAP (f);
@@ -2784,6 +2784,9 @@ set_up_x_back_buffer (struct frame *f)
block_input ();
if (FRAME_X_WINDOW (f) && !FRAME_X_DOUBLE_BUFFERED_P (f))
{
+#ifdef USE_CAIRO
+ x_cr_destroy_frame_context (f);
+#endif
FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
if (FRAME_DISPLAY_INFO (f)->supports_xdbe)
{
@@ -2813,6 +2816,9 @@ tear_down_x_back_buffer (struct frame *f)
{
if (FRAME_X_DOUBLE_BUFFERED_P (f))
{
+#ifdef USE_CAIRO
+ x_cr_destroy_frame_context (f);
+#endif
XdbeDeallocateBackBufferName (FRAME_X_DISPLAY (f),
FRAME_X_DRAWABLE (f));
FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
diff --git a/src/xfont.c b/src/xfont.c
index 5ecbd6de33b..81808e7a62e 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -46,18 +46,20 @@ struct xfont_info
/* Prototypes of support functions. */
-static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
+static XCharStruct *xfont_get_pcm (XFontStruct *, unsigned char2b);
/* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
is not contained in the font. */
static XCharStruct *
-xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
+xfont_get_pcm (XFontStruct *xfont, unsigned char2b)
{
/* The result metric information. */
XCharStruct *pcm = NULL;
+ const unsigned char byte1 = char2b >> 8;
+ const unsigned char byte2 = char2b & 0xFF;
- eassert (xfont && char2b);
+ eassert (xfont);
if (xfont->per_char != NULL)
{
@@ -66,13 +68,13 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
/* min_char_or_byte2 specifies the linear character index
corresponding to the first element of the per_char array,
max_char_or_byte2 is the index of the last character. A
- character with non-zero CHAR2B->byte1 is not in the font.
+ character with non-zero byte1 is not in the font.
A character with byte2 less than min_char_or_byte2 or
greater max_char_or_byte2 is not in the font. */
- if (char2b->byte1 == 0
- && char2b->byte2 >= xfont->min_char_or_byte2
- && char2b->byte2 <= xfont->max_char_or_byte2)
- pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
+ if (byte1 == 0
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
}
else
{
@@ -89,14 +91,14 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
D = max_char_or_byte2 - min_char_or_byte2 + 1
/ = integer division
\ = integer modulus */
- if (char2b->byte1 >= xfont->min_byte1
- && char2b->byte1 <= xfont->max_byte1
- && char2b->byte2 >= xfont->min_char_or_byte2
- && char2b->byte2 <= xfont->max_char_or_byte2)
+ if (byte1 >= xfont->min_byte1
+ && byte1 <= xfont->max_byte1
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
pcm = (xfont->per_char
+ ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
- * (char2b->byte1 - xfont->min_byte1))
- + (char2b->byte2 - xfont->min_char_or_byte2));
+ * (byte1 - xfont->min_byte1))
+ + (byte2 - xfont->min_char_or_byte2));
}
}
else
@@ -104,8 +106,8 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
/* If the per_char pointer is null, all glyphs between the first
and last character indexes inclusive have the same
information, as given by both min_bounds and max_bounds. */
- if (char2b->byte2 >= xfont->min_char_or_byte2
- && char2b->byte2 <= xfont->max_char_or_byte2)
+ if (byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
pcm = &xfont->max_bounds;
}
@@ -193,7 +195,6 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
{
int c = XFIXNUM (XCAR (chars));
unsigned code = ENCODE_CHAR (charset, c);
- XChar2b char2b;
if (code == CHARSET_INVALID_CODE (charset))
break;
@@ -201,9 +202,7 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
continue;
if (code >= 0x10000)
break;
- char2b.byte1 = code >> 8;
- char2b.byte2 = code & 0xFF;
- if (! xfont_get_pcm (xfont, &char2b))
+ if (! xfont_get_pcm (xfont, code))
break;
}
return (NILP (chars));
@@ -216,7 +215,6 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
{
int c = XFIXNUM (AREF (chars, i));
unsigned code = ENCODE_CHAR (charset, c);
- XChar2b char2b;
if (code == CHARSET_INVALID_CODE (charset))
continue;
@@ -224,9 +222,7 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
break;
if (code >= 0x10000)
continue;
- char2b.byte1 = code >> 8;
- char2b.byte2 = code & 0xFF;
- if (xfont_get_pcm (xfont, &char2b))
+ if (xfont_get_pcm (xfont, code))
break;
}
return (i >= 0);
@@ -801,11 +797,9 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
else
{
XCharStruct *pcm;
- XChar2b char2b;
Lisp_Object val;
- char2b.byte1 = 0x00, char2b.byte2 = 0x20;
- pcm = xfont_get_pcm (xfont, &char2b);
+ pcm = xfont_get_pcm (xfont, 0x20);
if (pcm)
font->space_width = pcm->width;
else
@@ -823,8 +817,8 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
int width = font->space_width, n = pcm != NULL;
- for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
- if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
+ for (unsigned char2b = 33; char2b <= 126; ++char2b)
+ if ((pcm = xfont_get_pcm (xfont, char2b)) != NULL)
width += pcm->width, n++;
if (n > 0)
font->average_width = width / n;
@@ -934,7 +928,6 @@ xfont_encode_char (struct font *font, int c)
XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
struct charset *charset;
unsigned code;
- XChar2b char2b;
charset = CHARSET_FROM_ID (font->encoding_charset);
code = ENCODE_CHAR (charset, c);
@@ -946,13 +939,11 @@ xfont_encode_char (struct font *font, int c)
return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
? code : FONT_INVALID_CODE);
}
- char2b.byte1 = code >> 8;
- char2b.byte2 = code & 0xFF;
- return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
+ return (xfont_get_pcm (xfont, code) ? code : FONT_INVALID_CODE);
}
static void
-xfont_text_extents (struct font *font, unsigned int *code,
+xfont_text_extents (struct font *font, const unsigned int *code,
int nglyphs, struct font_metrics *metrics)
{
XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
@@ -961,13 +952,11 @@ xfont_text_extents (struct font *font, unsigned int *code,
for (i = 0, first = true; i < nglyphs; i++)
{
- XChar2b char2b;
static XCharStruct *pcm;
if (code[i] >= 0x10000)
continue;
- char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
- pcm = xfont_get_pcm (xfont, &char2b);
+ pcm = xfont_get_pcm (xfont, code[i]);
if (! pcm)
continue;
if (first)
@@ -1000,6 +989,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
bool with_background)
{
XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
+ Display *display = FRAME_X_DISPLAY (s->f);
int len = to - from;
GC gc = s->gc;
int i;
@@ -1007,7 +997,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
if (s->gc != s->face->gc)
{
block_input ();
- XSetFont (s->display, gc, xfont->fid);
+ XSetFont (display, gc, xfont->fid);
unblock_input ();
}
@@ -1016,26 +1006,26 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
USE_SAFE_ALLOCA;
char *str = SAFE_ALLOCA (len);
for (i = 0; i < len ; i++)
- str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
+ str[i] = s->char2b[from + i] & 0xFF;
block_input ();
if (with_background)
{
if (s->padding_p)
for (i = 0; i < len; i++)
- XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
+ XDrawImageString (display, FRAME_X_DRAWABLE (s->f),
gc, x + i, y, str + i, 1);
else
- XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
+ XDrawImageString (display, FRAME_X_DRAWABLE (s->f),
gc, x, y, str, len);
}
else
{
if (s->padding_p)
for (i = 0; i < len; i++)
- XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
+ XDrawString (display, FRAME_X_DRAWABLE (s->f),
gc, x + i, y, str + i, 1);
else
- XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
+ XDrawString (display, FRAME_X_DRAWABLE (s->f),
gc, x, y, str, len);
}
unblock_input ();
@@ -1048,21 +1038,51 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
{
if (s->padding_p)
for (i = 0; i < len; i++)
- XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
- gc, x + i, y, s->char2b + from + i, 1);
+ {
+ const unsigned code = s->char2b[from + i];
+ const XChar2b char2b = { .byte1 = code >> 8,
+ .byte2 = code & 0xFF };
+ XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f),
+ gc, x + i, y, &char2b, 1);
+ }
else
- XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
- gc, x, y, s->char2b + from, len);
+ {
+ USE_SAFE_ALLOCA;
+ const unsigned *code = s->char2b + from;
+ XChar2b *char2b;
+ SAFE_NALLOCA (char2b, 1, len);
+ for (int i = 0; i < len; ++i)
+ char2b[i] = (XChar2b) { .byte1 = code[i] >> 8,
+ .byte2 = code[i] & 0xFF };
+ XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f),
+ gc, x, y, char2b, len);
+ SAFE_FREE ();
+ }
}
else
{
if (s->padding_p)
for (i = 0; i < len; i++)
- XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
- gc, x + i, y, s->char2b + from + i, 1);
+ {
+ const unsigned code = s->char2b[from + i];
+ const XChar2b char2b = { .byte1 = code >> 8,
+ .byte2 = code & 0xFF };
+ XDrawString16 (display, FRAME_X_DRAWABLE (s->f),
+ gc, x + i, y, &char2b, 1);
+ }
else
- XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_DRAWABLE (s->f),
- gc, x, y, s->char2b + from, len);
+ {
+ USE_SAFE_ALLOCA;
+ const unsigned *code = s->char2b + from;
+ XChar2b *char2b;
+ SAFE_NALLOCA (char2b, 1, len);
+ for (int i = 0; i < len; ++i)
+ char2b[i] = (XChar2b) { .byte1 = code[i] >> 8,
+ .byte2 = code[i] & 0xFF };
+ XDrawString16 (display, FRAME_X_DRAWABLE (s->f),
+ gc, x, y, char2b, len);
+ SAFE_FREE ();
+ }
}
unblock_input ();
diff --git a/src/xftfont.c b/src/xftfont.c
index f7b87f96569..08e4edb535a 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -119,120 +119,18 @@ xftfont_match (struct frame *f, Lisp_Object spec)
static FcChar8 ascii_printable[95];
-static void
-xftfont_fix_match (FcPattern *pat, FcPattern *match)
-{
- /* These values are not used for matching (except antialias), but for
- rendering, so make sure they are carried over to the match.
- We also put antialias here because most fonts are antialiased, so
- the match will have antialias true. */
-
- FcBool b = FcTrue;
- int i;
- double dpi;
-
- FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
- if (! b)
- {
- FcPatternDel (match, FC_ANTIALIAS);
- FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
- }
- FcPatternGetBool (pat, FC_HINTING, 0, &b);
- if (! b)
- {
- FcPatternDel (match, FC_HINTING);
- FcPatternAddBool (match, FC_HINTING, FcFalse);
- }
-#ifndef FC_HINT_STYLE
-# define FC_HINT_STYLE "hintstyle"
-#endif
- if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
- {
- FcPatternDel (match, FC_HINT_STYLE);
- FcPatternAddInteger (match, FC_HINT_STYLE, i);
- }
-#ifndef FC_LCD_FILTER
- /* Older fontconfig versions don't have FC_LCD_FILTER. */
-#define FC_LCD_FILTER "lcdfilter"
-#endif
- if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
- {
- FcPatternDel (match, FC_LCD_FILTER);
- FcPatternAddInteger (match, FC_LCD_FILTER, i);
- }
- if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
- {
- FcPatternDel (match, FC_RGBA);
- FcPatternAddInteger (match, FC_RGBA, i);
- }
- if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
- {
- FcPatternDel (match, FC_DPI);
- FcPatternAddDouble (match, FC_DPI, dpi);
- }
-}
-
-static void
-xftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
-{
- Lisp_Object tail;
- int ival;
-
- for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
- {
- Lisp_Object key = XCAR (XCAR (tail));
- Lisp_Object val = XCDR (XCAR (tail));
-
- if (EQ (key, QCantialias))
- FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
- else if (EQ (key, QChinting))
- FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
- else if (EQ (key, QCautohint))
- FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
- else if (EQ (key, QChintstyle))
- {
- if (FIXNUMP (val))
- FcPatternAddInteger (pat, FC_HINT_STYLE, XFIXNUM (val));
- else if (SYMBOLP (val)
- && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
- FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
- }
- else if (EQ (key, QCrgba))
- {
- if (FIXNUMP (val))
- FcPatternAddInteger (pat, FC_RGBA, XFIXNUM (val));
- else if (SYMBOLP (val)
- && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
- FcPatternAddInteger (pat, FC_RGBA, ival);
- }
- else if (EQ (key, QClcdfilter))
- {
- if (FIXNUMP (val))
- FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XFIXNUM (val));
- else if (SYMBOLP (val)
- && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
- FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
- }
-#ifdef FC_EMBOLDEN
- else if (EQ (key, QCembolden))
- FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
-#endif
- }
-}
-
static Lisp_Object
xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
FcResult result;
Display *display = FRAME_X_DISPLAY (f);
- Lisp_Object val, filename, idx, font_object;
+ Lisp_Object val, filename, font_object;
FcPattern *pat = NULL, *match;
struct font_info *xftfont_info = NULL;
struct font *font;
double size = 0;
XftFont *xftfont = NULL;
int spacing;
- int i;
XGlyphInfo extents;
FT_Face ft_face;
FcMatrix *matrix;
@@ -242,52 +140,17 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
return Qnil;
val = XCDR (val);
filename = XCAR (val);
- idx = XCDR (val);
size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
if (size == 0)
size = pixel_size;
- pat = FcPatternCreate ();
- FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity));
- i = FONT_SLANT_NUMERIC (entity) - 100;
- if (i < 0) i = 0;
- FcPatternAddInteger (pat, FC_SLANT, i);
- FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity));
- FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
- val = AREF (entity, FONT_FAMILY_INDEX);
- if (! NILP (val))
- FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
- val = AREF (entity, FONT_FOUNDRY_INDEX);
- if (! NILP (val))
- FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
- val = AREF (entity, FONT_SPACING_INDEX);
- if (! NILP (val))
- FcPatternAddInteger (pat, FC_SPACING, XFIXNUM (val));
- val = AREF (entity, FONT_DPI_INDEX);
- if (! NILP (val))
- {
- double dbl = XFIXNUM (val);
-
- FcPatternAddDouble (pat, FC_DPI, dbl);
- }
- val = AREF (entity, FONT_AVGWIDTH_INDEX);
- if (FIXNUMP (val) && XFIXNUM (val) == 0)
- FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
- /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
- over 10x20-ISO8859-1.pcf.gz). */
- FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
-
- xftfont_add_rendering_parameters (pat, entity);
-
- FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
- FcPatternAddInteger (pat, FC_INDEX, XFIXNUM (idx));
-
block_input ();
+ pat = ftfont_entity_pattern (entity, pixel_size);
/* Substitute in values from X resources and XftDefaultSet. */
XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
- xftfont_fix_match (pat, match);
+ ftfont_fix_match (pat, match);
FcPatternDestroy (pat);
xftfont = XftFontOpenPattern (display, match);
@@ -544,7 +407,7 @@ xftfont_encode_char (struct font *font, int c)
}
static void
-xftfont_text_extents (struct font *font, unsigned int *code,
+xftfont_text_extents (struct font *font, const unsigned int *code,
int nglyphs, struct font_metrics *metrics)
{
struct font_info *xftfont_info = (struct font_info *) font;
@@ -629,8 +492,7 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
}
code = alloca (sizeof (FT_UInt) * len);
for (i = 0; i < len; i++)
- code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
- | XCHAR2B_BYTE2 (s->char2b + from + i));
+ code[i] = s->char2b[from + i];
if (s->padding_p)
for (i = 0; i < len; i++)
@@ -704,7 +566,7 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
bool ok = false;
int i1, i2, r1, r2;
- xftfont_add_rendering_parameters (pat, entity);
+ ftfont_add_rendering_parameters (pat, entity);
XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
r1 = FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b1);
@@ -818,12 +680,6 @@ syms_of_xftfont (void)
#ifdef HAVE_HARFBUZZ
DEFSYM (Qxfthb, "xfthb");
#endif /* HAVE_HARFBUZZ */
- DEFSYM (QChinting, ":hinting");
- DEFSYM (QCautohint, ":autohint");
- DEFSYM (QChintstyle, ":hintstyle");
- DEFSYM (QCrgba, ":rgba");
- DEFSYM (QCembolden, ":embolden");
- DEFSYM (QClcdfilter, ":lcdfilter");
DEFVAR_BOOL ("xft-font-ascent-descent-override",
xft_font_ascent_descent_override,
diff --git a/src/xterm.c b/src/xterm.c
index dd19b8bde15..559d1b48924 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -201,7 +201,6 @@ enum xembed_message
XEMBED_ACTIVATE_ACCELERATOR = 14
};
-static void x_free_cr_resources (struct frame *);
static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
static void x_raise_frame (struct frame *);
static void x_lower_frame (struct frame *);
@@ -298,7 +297,10 @@ record_event (char *locus, int type)
#ifdef USE_CAIRO
#define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
-#define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
+#define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
+ ((f)->output_data.x->cr_surface_desired_width)
+#define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
+ ((f)->output_data.x->cr_surface_desired_height)
static struct x_gc_ext_data *
x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
@@ -333,19 +335,28 @@ x_extension_initialize (struct x_display_info *dpyinfo)
dpyinfo->ext_codes = ext_codes;
}
-static void
-x_cr_destroy_surface (struct frame *f)
+void
+x_cr_destroy_frame_context (struct frame *f)
{
- if (FRAME_CR_SURFACE (f))
+ if (FRAME_CR_CONTEXT (f))
{
- cairo_t *cr = FRAME_CR_CONTEXT (f);
- cairo_surface_destroy (FRAME_CR_SURFACE (f));
- FRAME_CR_SURFACE (f) = 0;
- if (cr) cairo_destroy (cr);
+ cairo_destroy (FRAME_CR_CONTEXT (f));
FRAME_CR_CONTEXT (f) = NULL;
}
}
+static void
+x_cr_update_surface_desired_size (struct frame *f, int width, int height)
+{
+ if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
+ || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
+ {
+ x_cr_destroy_frame_context (f);
+ FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
+ FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
+ }
+}
+
cairo_t *
x_begin_cr_clip (struct frame *f, GC gc)
{
@@ -353,21 +364,19 @@ x_begin_cr_clip (struct frame *f, GC gc)
if (!cr)
{
-
- if (! FRAME_CR_SURFACE (f))
- {
- int scale = 1;
-#ifdef USE_GTK
- scale = xg_get_scale (f);
-#endif
-
- FRAME_CR_SURFACE (f) =
- cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- scale * FRAME_PIXEL_WIDTH (f),
- scale * FRAME_PIXEL_HEIGHT (f));
- }
- cr = cairo_create (FRAME_CR_SURFACE (f));
- FRAME_CR_CONTEXT (f) = cr;
+ int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
+ int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
+ cairo_surface_t *surface;
+ if (FRAME_X_DOUBLE_BUFFERED_P (f))
+ surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
+ FRAME_X_RAW_DRAWABLE (f),
+ FRAME_X_VISUAL (f),
+ width, height);
+ else
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ width, height);
+ cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
+ cairo_surface_destroy (surface);
}
cairo_save (cr);
@@ -395,6 +404,8 @@ void
x_end_cr_clip (struct frame *f)
{
cairo_restore (FRAME_CR_CONTEXT (f));
+ if (FRAME_X_DOUBLE_BUFFERED_P (f))
+ x_mark_frame_dirty (f);
}
void
@@ -532,11 +543,11 @@ x_cr_draw_frame (cairo_t *cr, struct frame *f)
width = FRAME_PIXEL_WIDTH (f);
height = FRAME_PIXEL_HEIGHT (f);
- x_free_cr_resources (f);
+ cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
FRAME_CR_CONTEXT (f) = cr;
x_clear_area (f, 0, 0, width, height);
expose_frame (f, 0, 0, width, height);
- FRAME_CR_CONTEXT (f) = NULL;
+ FRAME_CR_CONTEXT (f) = saved_cr;
}
static cairo_status_t
@@ -615,11 +626,11 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
while (1)
{
- x_free_cr_resources (f);
+ cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
FRAME_CR_CONTEXT (f) = cr;
x_clear_area (f, 0, 0, width, height);
expose_frame (f, 0, 0, width, height);
- FRAME_CR_CONTEXT (f) = NULL;
+ FRAME_CR_CONTEXT (f) = saved_cr;
if (NILP (frames))
break;
@@ -654,35 +665,6 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
#endif /* USE_CAIRO */
static void
-x_free_cr_resources (struct frame *f)
-{
-#ifdef USE_CAIRO
- if (f == NULL)
- {
- Lisp_Object rest, frame;
- FOR_EACH_FRAME (rest, frame)
- if (FRAME_X_P (XFRAME (frame)))
- x_free_cr_resources (XFRAME (frame));
- }
- else
- {
- cairo_t *cr = FRAME_CR_CONTEXT (f);
-
- if (cr)
- {
- cairo_surface_t *surface = cairo_get_target (cr);
-
- if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
- {
- cairo_destroy (cr);
- FRAME_CR_CONTEXT (f) = NULL;
- }
- }
- }
-#endif
-}
-
-static void
x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
{
XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
@@ -989,77 +971,16 @@ x_set_frame_alpha (struct frame *f)
/* Start an update of frame F. This function is installed as a hook
for update_begin, i.e. it is called when update_begin is called.
- This function is called prior to calls to x_update_window_begin for
+ This function is called prior to calls to gui_update_window_begin for
each window being updated. Currently, there is nothing to do here
because all interesting stuff is done on a window basis. */
static void
x_update_begin (struct frame *f)
{
-#ifdef USE_CAIRO
- if (FRAME_TOOLTIP_P (f) && !FRAME_VISIBLE_P (f))
- return;
-
- if (! FRAME_CR_SURFACE (f))
- {
- int width, height;
-#ifdef USE_GTK
- if (FRAME_GTK_WIDGET (f))
- {
- GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
- int scale = xg_get_scale (f);
- width = scale * gdk_window_get_width (w);
- height = scale * gdk_window_get_height (w);
- }
- else
-#endif
- {
- width = FRAME_PIXEL_WIDTH (f);
- height = FRAME_PIXEL_HEIGHT (f);
- if (! FRAME_EXTERNAL_TOOL_BAR (f))
- height += FRAME_TOOL_BAR_HEIGHT (f);
- if (! FRAME_EXTERNAL_MENU_BAR (f))
- height += FRAME_MENU_BAR_HEIGHT (f);
- }
-
- if (width > 0 && height > 0)
- {
- block_input();
- FRAME_CR_SURFACE (f) = cairo_image_surface_create
- (CAIRO_FORMAT_ARGB32, width, height);
- unblock_input();
- }
- }
-#endif /* USE_CAIRO */
-}
-
-/* Start update of window W. */
-
-static void
-x_update_window_begin (struct window *w)
-{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-
- w->output_cursor = w->cursor;
-
- block_input ();
-
- if (f == hlinfo->mouse_face_mouse_frame)
- {
- /* Don't do highlighting for mouse motion during the update. */
- hlinfo->mouse_face_defer = true;
-
- /* If F needs to be redrawn, simply forget about any prior mouse
- highlighting. */
- if (FRAME_GARBAGED_P (f))
- hlinfo->mouse_face_window = Qnil;
- }
-
- unblock_input ();
+ /* Nothing to do. */
}
-
/* Draw a vertical window border from (x,y0) to (x,y1) */
static void
@@ -1139,55 +1060,6 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
}
}
-/* End update of window W.
-
- Draw vertical borders between horizontally adjacent windows, and
- display W's cursor if CURSOR_ON_P is non-zero.
-
- MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
- glyphs in mouse-face were overwritten. In that case we have to
- make sure that the mouse-highlight is properly redrawn.
-
- W may be a menu bar pseudo-window in case we don't have X toolkit
- support. Such windows don't have a cursor, so don't display it
- here. */
-
-static void
-x_update_window_end (struct window *w, bool cursor_on_p,
- bool mouse_face_overwritten_p)
-{
- if (!w->pseudo_window_p)
- {
- block_input ();
-
- if (cursor_on_p)
- display_and_set_cursor (w, true,
- w->output_cursor.hpos, w->output_cursor.vpos,
- w->output_cursor.x, w->output_cursor.y);
-
- if (draw_window_fringes (w, true))
- {
- if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
- gui_draw_right_divider (w);
- else
- gui_draw_vertical_border (w);
- }
-
- unblock_input ();
- }
-
- /* If a row with mouse-face was overwritten, arrange for
- XTframe_up_to_date to redisplay the mouse highlight. */
- if (mouse_face_overwritten_p)
- {
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
-
- hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
- hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
- hlinfo->mouse_face_window = Qnil;
- }
-}
-
/* Show the frame back buffer. If frame is double-buffered,
atomically publish to the user's screen graphics updates made since
the last call to show_back_buffer. */
@@ -1198,6 +1070,11 @@ show_back_buffer (struct frame *f)
if (FRAME_X_DOUBLE_BUFFERED_P (f))
{
#ifdef HAVE_XDBE
+#ifdef USE_CAIRO
+ cairo_t *cr = FRAME_CR_CONTEXT (f);
+ if (cr)
+ cairo_surface_flush (cairo_get_target (cr));
+#endif
XdbeSwapInfo swap_info;
memset (&swap_info, 0, sizeof (swap_info));
swap_info.swap_window = FRAME_X_WINDOW (f);
@@ -1234,30 +1111,33 @@ x_update_end (struct frame *f)
MOUSE_HL_INFO (f)->mouse_face_defer = false;
#ifdef USE_CAIRO
- if (FRAME_CR_SURFACE (f))
+ if (!FRAME_X_DOUBLE_BUFFERED_P (f))
{
- cairo_t *cr;
- cairo_surface_t *surface;
- int width, height;
-
block_input ();
- width = FRAME_PIXEL_WIDTH (f);
- height = FRAME_PIXEL_HEIGHT (f);
- if (! FRAME_EXTERNAL_TOOL_BAR (f))
- height += FRAME_TOOL_BAR_HEIGHT (f);
- if (! FRAME_EXTERNAL_MENU_BAR (f))
- height += FRAME_MENU_BAR_HEIGHT (f);
- surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
- FRAME_X_DRAWABLE (f),
- FRAME_DISPLAY_INFO (f)->visual,
- width,
- height);
- cr = cairo_create (surface);
- cairo_surface_destroy (surface);
-
- cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
- cairo_paint (cr);
- cairo_destroy (cr);
+ cairo_surface_t *source_surface = cairo_get_target (FRAME_CR_CONTEXT (f));
+ if (source_surface)
+ {
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ int width, height;
+
+ width = FRAME_PIXEL_WIDTH (f);
+ height = FRAME_PIXEL_HEIGHT (f);
+ if (! FRAME_EXTERNAL_TOOL_BAR (f))
+ height += FRAME_TOOL_BAR_HEIGHT (f);
+ if (! FRAME_EXTERNAL_MENU_BAR (f))
+ height += FRAME_MENU_BAR_HEIGHT (f);
+ surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
+ FRAME_X_DRAWABLE (f),
+ FRAME_X_VISUAL (f),
+ width, height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_surface (cr, source_surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+ }
unblock_input ();
}
#endif
@@ -1530,6 +1410,7 @@ x_set_cursor_gc (struct glyph_string *s)
/* Cursor on non-default face: must merge. */
XGCValues xgcv;
unsigned long mask;
+ Display *display = FRAME_X_DISPLAY (s->f);
xgcv.background = s->f->output_data.x->cursor_pixel;
xgcv.foreground = s->face->background;
@@ -1555,11 +1436,11 @@ x_set_cursor_gc (struct glyph_string *s)
mask = GCForeground | GCBackground | GCGraphicsExposures;
if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
- XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
+ XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
mask, &xgcv);
else
FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
- = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
+ = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
}
@@ -1595,6 +1476,7 @@ x_set_mouse_face_gc (struct glyph_string *s)
except for FONT. */
XGCValues xgcv;
unsigned long mask;
+ Display *display = FRAME_X_DISPLAY (s->f);
xgcv.background = s->face->background;
xgcv.foreground = s->face->foreground;
@@ -1602,11 +1484,11 @@ x_set_mouse_face_gc (struct glyph_string *s)
mask = GCForeground | GCBackground | GCGraphicsExposures;
if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
- XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
+ XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
mask, &xgcv);
else
FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
- = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
+ = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
@@ -1717,13 +1599,8 @@ x_compute_glyph_string_overhangs (struct glyph_string *s)
if (s->first_glyph->type == CHAR_GLYPH)
{
- unsigned *code = alloca (sizeof (unsigned) * s->nchars);
struct font *font = s->font;
- int i;
-
- for (i = 0; i < s->nchars; i++)
- code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
- font->driver->text_extents (font, code, s->nchars, &metrics);
+ font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
}
else
{
@@ -1748,11 +1625,12 @@ x_compute_glyph_string_overhangs (struct glyph_string *s)
static void
x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
- XSetForeground (s->display, s->gc, xgcv.background);
+ XGetGCValues (display, s->gc, GCForeground | GCBackground, &xgcv);
+ XSetForeground (display, s->gc, xgcv.background);
x_fill_rectangle (s->f, s->gc, x, y, w, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
}
@@ -1773,13 +1651,15 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
if (s->stippled_p)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
+
/* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
+ XSetFillStyle (display, s->gc, FillOpaqueStippled);
x_fill_rectangle (s->f, s->gc, s->x,
s->y + box_line_width,
s->background_width,
s->height - 2 * box_line_width);
- XSetFillStyle (s->display, s->gc, FillSolid);
+ XSetFillStyle (display, s->gc, FillSolid);
s->background_filled_p = true;
}
else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
@@ -1946,7 +1826,7 @@ static void
x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
{
struct glyph *glyph = s->first_glyph;
- XChar2b char2b[8];
+ unsigned char2b[8];
int x, i, j;
/* If first glyph of S has a left box line, start drawing the text
@@ -1997,14 +1877,10 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
if (str)
{
int upper_len = (len + 1) / 2;
- unsigned code;
/* It is assured that all LEN characters in STR is ASCII. */
for (j = 0; j < len; j++)
- {
- code = s->font->driver->encode_char (s->font, str[j]);
- STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
- }
+ char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
s->font->driver->draw (s, 0, upper_len,
x + glyph->slice.glyphless.upper_xoff,
s->ybase + glyph->slice.glyphless.upper_yoff,
@@ -2667,7 +2543,7 @@ x_setup_relief_colors (struct glyph_string *s)
XGCValues xgcv;
/* Get the background color of the face. */
- XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
+ XGetGCValues (FRAME_X_DISPLAY (s->f), s->gc, GCBackground, &xgcv);
color = xgcv.background;
}
@@ -2877,10 +2753,11 @@ x_draw_box_rect (struct glyph_string *s,
int left_x, int top_y, int right_x, int bottom_y, int width,
bool left_p, bool right_p, XRectangle *clip_rect)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->box_color);
+ XGetGCValues (display, s->gc, GCForeground, &xgcv);
+ XSetForeground (display, s->gc, s->face->box_color);
x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
/* Top. */
@@ -2901,7 +2778,7 @@ x_draw_box_rect (struct glyph_string *s,
x_fill_rectangle (s->f, s->gc,
right_x - width + 1, top_y, width, bottom_y - top_y + 1);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
x_reset_clip_rectangles (s->f, s->gc);
}
@@ -2964,6 +2841,7 @@ x_composite_image (struct glyph_string *s, Pixmap dest,
int srcX, int srcY, int dstX, int dstY,
int width, int height)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
#ifdef HAVE_XRENDER
if (s->img->picture)
{
@@ -2973,27 +2851,27 @@ x_composite_image (struct glyph_string *s, Pixmap dest,
/* FIXME: Should we do this each time or would it make sense to
store destination in the frame struct? */
- default_format = XRenderFindVisualFormat (s->display,
- DefaultVisual (s->display, 0));
- destination = XRenderCreatePicture (s->display, dest,
+ default_format = XRenderFindVisualFormat (display,
+ DefaultVisual (display, 0));
+ destination = XRenderCreatePicture (display, dest,
default_format, 0, &attr);
/* FIXME: It may make sense to use PictOpSrc instead of
PictOpOver, as I don't know if we care about alpha values too
much here. */
- XRenderComposite (s->display, PictOpOver,
+ XRenderComposite (display, PictOpOver,
s->img->picture, s->img->mask_picture, destination,
srcX, srcY,
srcX, srcY,
dstX, dstY,
width, height);
- XRenderFreePicture (s->display, destination);
+ XRenderFreePicture (display, destination);
return;
}
#endif
- XCopyArea (s->display, s->img->pixmap,
+ XCopyArea (display, s->img->pixmap,
dest, s->gc,
srcX, srcY,
width, height, dstX, dstY);
@@ -3068,7 +2946,7 @@ x_draw_image_foreground (struct glyph_string *s)
xgcv.clip_x_origin = x;
xgcv.clip_y_origin = y;
xgcv.function = GXcopy;
- XChangeGC (s->display, s->gc, mask, &xgcv);
+ XChangeGC (FRAME_X_DISPLAY (s->f), s->gc, mask, &xgcv);
get_glyph_string_clip_rect (s, &clip_rect);
image_rect.x = x;
@@ -3217,6 +3095,8 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
if (s->img->pixmap)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
+
if (s->img->mask)
{
/* We can't set both a clip mask and use XSetClipRectangles
@@ -3232,16 +3112,16 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
xgcv.clip_x_origin = x - s->slice.x;
xgcv.clip_y_origin = y - s->slice.y;
xgcv.function = GXcopy;
- XChangeGC (s->display, s->gc, mask, &xgcv);
+ XChangeGC (display, s->gc, mask, &xgcv);
- XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
+ XCopyArea (display, s->img->pixmap, pixmap, s->gc,
s->slice.x, s->slice.y,
s->slice.width, s->slice.height, x, y);
- XSetClipMask (s->display, s->gc, None);
+ XSetClipMask (display, s->gc, None);
}
else
{
- XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
+ XCopyArea (display, s->img->pixmap, pixmap, s->gc,
s->slice.x, s->slice.y,
s->slice.width, s->slice.height, x, y);
@@ -3276,10 +3156,12 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
{
if (s->stippled_p)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
+
/* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
+ XSetFillStyle (display, s->gc, FillOpaqueStippled);
x_fill_rectangle (s->f, s->gc, x, y, w, h);
- XSetFillStyle (s->display, s->gc, FillSolid);
+ XSetFillStyle (display, s->gc, FillSolid);
}
else
x_clear_glyph_string_rect (s, x, y, w, h);
@@ -3307,6 +3189,7 @@ x_draw_image_glyph_string (struct glyph_string *s)
int box_line_vwidth = max (s->face->box_line_width, 0);
int height;
#ifndef USE_CAIRO
+ Display *display = FRAME_X_DISPLAY (s->f);
Pixmap pixmap = None;
#endif
@@ -3337,34 +3220,34 @@ x_draw_image_glyph_string (struct glyph_string *s)
int depth = DefaultDepthOfScreen (screen);
/* Create a pixmap as large as the glyph string. */
- pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
+ pixmap = XCreatePixmap (display, FRAME_X_DRAWABLE (s->f),
s->background_width,
s->height, depth);
/* Don't clip in the following because we're working on the
pixmap. */
- XSetClipMask (s->display, s->gc, None);
+ XSetClipMask (display, s->gc, None);
/* Fill the pixmap with the background color/stipple. */
if (s->stippled_p)
{
/* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
- XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
- XFillRectangle (s->display, pixmap, s->gc,
+ XSetFillStyle (display, s->gc, FillOpaqueStippled);
+ XSetTSOrigin (display, s->gc, - s->x, - s->y);
+ XFillRectangle (display, pixmap, s->gc,
0, 0, s->background_width, s->height);
- XSetFillStyle (s->display, s->gc, FillSolid);
- XSetTSOrigin (s->display, s->gc, 0, 0);
+ XSetFillStyle (display, s->gc, FillSolid);
+ XSetTSOrigin (display, s->gc, 0, 0);
}
else
{
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
+ XGetGCValues (display, s->gc, GCForeground | GCBackground,
&xgcv);
- XSetForeground (s->display, s->gc, xgcv.background);
- XFillRectangle (s->display, pixmap, s->gc,
+ XSetForeground (display, s->gc, xgcv.background);
+ XFillRectangle (display, pixmap, s->gc,
0, 0, s->background_width, s->height);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
}
}
else
@@ -3396,9 +3279,9 @@ x_draw_image_glyph_string (struct glyph_string *s)
{
x_draw_image_foreground_1 (s, pixmap);
x_set_glyph_string_clipping (s);
- XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
+ XCopyArea (display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
0, 0, s->background_width, s->height, s->x, s->y);
- XFreePixmap (s->display, pixmap);
+ XFreePixmap (display, pixmap);
}
else
#endif /* ! USE_CAIRO */
@@ -3459,6 +3342,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
{
int y = s->y;
int w = background_width - width, h = s->height;
+ Display *display = FRAME_X_DISPLAY (s->f);
XRectangle r;
GC gc;
@@ -3481,17 +3365,17 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
if (s->face->stipple)
{
/* Fill background with a stipple pattern. */
- XSetFillStyle (s->display, gc, FillOpaqueStippled);
+ XSetFillStyle (display, gc, FillOpaqueStippled);
x_fill_rectangle (s->f, gc, x, y, w, h);
- XSetFillStyle (s->display, gc, FillSolid);
+ XSetFillStyle (display, gc, FillSolid);
}
else
{
XGCValues xgcv;
- XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
- XSetForeground (s->display, gc, xgcv.background);
+ XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv);
+ XSetForeground (display, gc, xgcv.background);
x_fill_rectangle (s->f, gc, x, y, w, h);
- XSetForeground (s->display, gc, xgcv.foreground);
+ XSetForeground (display, gc, xgcv.foreground);
}
x_reset_clip_rectangles (s->f, gc);
@@ -3546,10 +3430,12 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
static void
x_draw_underwave (struct glyph_string *s)
{
+ Display *display = FRAME_X_DISPLAY (s->f);
+
/* Adjust for scale/HiDPI. */
int scale_x, scale_y;
- x_get_scale_factor (s->display, &scale_x, &scale_y);
+ x_get_scale_factor (display, &scale_x, &scale_y);
int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
@@ -3579,7 +3465,7 @@ x_draw_underwave (struct glyph_string *s)
if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
return;
- XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
+ XSetClipRectangles (display, s->gc, 0, 0, &final_clip, 1, Unsorted);
/* Draw the waves */
@@ -3598,16 +3484,16 @@ x_draw_underwave (struct glyph_string *s)
while (x1 <= xmax)
{
- XSetLineAttributes (s->display, s->gc, thickness, LineSolid, CapButt,
+ XSetLineAttributes (display, s->gc, thickness, LineSolid, CapButt,
JoinRound);
- XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
+ XDrawLine (display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
x1 = x2, y1 = y2;
x2 += dx, y2 = y0 + odd*dy;
odd = !odd;
}
/* Restore previous clipping rectangle(s) */
- XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
+ XSetClipRectangles (display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
#endif /* not USE_CAIRO */
}
@@ -3724,11 +3610,12 @@ x_draw_glyph_string (struct glyph_string *s)
x_draw_underwave (s);
else
{
+ Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->underline_color);
+ XGetGCValues (display, s->gc, GCForeground, &xgcv);
+ XSetForeground (display, s->gc, s->face->underline_color);
x_draw_underwave (s);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
}
}
else if (s->face->underline_type == FACE_UNDER_LINE)
@@ -3808,12 +3695,13 @@ x_draw_glyph_string (struct glyph_string *s)
s->x, y, s->width, thickness);
else
{
+ Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->underline_color);
+ XGetGCValues (display, s->gc, GCForeground, &xgcv);
+ XSetForeground (display, s->gc, s->face->underline_color);
x_fill_rectangle (s->f, s->gc,
s->x, y, s->width, thickness);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
}
}
}
@@ -3827,12 +3715,13 @@ x_draw_glyph_string (struct glyph_string *s)
s->width, h);
else
{
+ Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->overline_color);
+ XGetGCValues (display, s->gc, GCForeground, &xgcv);
+ XSetForeground (display, s->gc, s->face->overline_color);
x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
s->width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
}
}
@@ -3856,12 +3745,13 @@ x_draw_glyph_string (struct glyph_string *s)
s->width, h);
else
{
+ Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->strike_through_color);
+ XGetGCValues (display, s->gc, GCForeground, &xgcv);
+ XSetForeground (display, s->gc, s->face->strike_through_color);
x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
s->width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
+ XSetForeground (display, s->gc, xgcv.foreground);
}
}
@@ -4306,11 +4196,25 @@ x_scroll_run (struct window *w, struct run *run)
block_input ();
- /* Cursor off. Will be switched on again in x_update_window_end. */
+ /* Cursor off. Will be switched on again in gui_update_window_end. */
gui_clear_cursor (w);
#ifdef USE_CAIRO
- if (FRAME_CR_CONTEXT (f))
+ if (FRAME_X_DOUBLE_BUFFERED_P (f))
+ {
+ cairo_t *cr = FRAME_CR_CONTEXT (f);
+ if (cr)
+ cairo_surface_flush (cairo_get_target (cr));
+ XCopyArea (FRAME_X_DISPLAY (f),
+ FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
+ f->output_data.x->normal_gc,
+ x, from_y,
+ width, height,
+ x, to_y);
+ if (cr)
+ cairo_surface_mark_dirty (cairo_get_target (cr));
+ }
+ else if (FRAME_CR_CONTEXT (f))
{
cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
width, height);
@@ -8287,7 +8191,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
fit in 81 bytes. So, we must prepare sufficient
bytes for copy_buffer. 513 bytes (256 chars for
two-byte character set) seems to be a fairly good
- approximation. -- 2000.8.10 handa@etl.go.jp */
+ approximation. -- 2000.8.10 handa@gnu.org */
unsigned char copy_buffer[513];
unsigned char *copy_bufptr = copy_buffer;
int copy_bufsiz = sizeof (copy_buffer);
@@ -8768,7 +8672,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
font_drop_xrender_surfaces (f);
unblock_input ();
#ifdef USE_CAIRO
- if (f) x_cr_destroy_surface (f);
+ if (f)
+ x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
+ configureEvent.xconfigure.height);
#endif
#ifdef USE_GTK
if (!f
@@ -8782,7 +8688,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xg_frame_resized (f, configureEvent.xconfigure.width,
configureEvent.xconfigure.height);
#ifdef USE_CAIRO
- x_cr_destroy_surface (f);
+ x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
+ configureEvent.xconfigure.height);
#endif
f = 0;
}
@@ -9440,7 +9347,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
/* RIF: Define cursor CURSOR on frame F. */
static void
-x_define_frame_cursor (struct frame *f, Cursor cursor)
+x_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
{
if (!f->pointer_invisible
&& f->output_data.x->current_cursor != cursor)
@@ -11892,7 +11799,9 @@ x_free_frame_resources (struct frame *f)
free_frame_xic (f);
#endif
- x_free_cr_resources (f);
+#ifdef USE_CAIRO
+ x_cr_destroy_frame_context (f);
+#endif
#ifdef USE_X_TOOLKIT
if (f->output_data.x->widget)
{
@@ -12239,6 +12148,17 @@ x_check_font (struct frame *f, struct font *font)
/***********************************************************************
+ Image Hooks
+ ***********************************************************************/
+
+static void
+x_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
+{
+ XFreePixmap (FRAME_X_DISPLAY (f), pixmap);
+}
+
+
+/***********************************************************************
Initialization
***********************************************************************/
@@ -13145,8 +13065,8 @@ static struct redisplay_interface x_redisplay_interface =
gui_clear_end_of_line,
x_scroll_run,
x_after_update_window_line,
- x_update_window_begin,
- x_update_window_end,
+ NULL, /* update_window_begin */
+ NULL, /* update_window_end */
x_flip_and_flush,
gui_clear_window_mouse_face,
gui_get_glyph_overhangs,
@@ -13314,6 +13234,7 @@ x_create_terminal (struct x_display_info *dpyinfo)
terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
terminal->get_string_resource_hook = x_get_string_resource;
+ terminal->free_pixmap = x_free_pixmap;
terminal->delete_frame_hook = x_destroy_window;
terminal->delete_terminal_hook = x_delete_terminal;
/* Other hooks are NULL by default. */
diff --git a/src/xterm.h b/src/xterm.h
index 266a42afa08..ce1443c381c 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -725,13 +725,12 @@ struct x_output
#ifdef USE_CAIRO
/* Cairo drawing context. */
cairo_t *cr_context;
- /* Cairo surface for double buffering */
- cairo_surface_t *cr_surface;
+ /* Width and height reported by the last ConfigureNotify event.
+ They are used when creating the cairo surface next time. */
+ int cr_surface_desired_width, cr_surface_desired_height;
#endif
};
-#define No_Cursor (None)
-
enum
{
/* Values for focus_state, used as bit mask.
@@ -1107,6 +1106,7 @@ extern int x_dispatch_event (XEvent *, Display *);
#endif
extern int x_x_to_emacs_modifiers (struct x_display_info *, int);
#ifdef USE_CAIRO
+extern void x_cr_destroy_frame_context (struct frame *);
extern cairo_t *x_begin_cr_clip (struct frame *, GC);
extern void x_end_cr_clip (struct frame *);
extern void x_set_cr_source_with_gc_foreground (struct frame *, GC);
@@ -1222,7 +1222,8 @@ extern void destroy_frame_xic (struct frame *);
extern void xic_set_preeditarea (struct window *, int, int);
extern void xic_set_statusarea (struct frame *);
extern void xic_set_xfontset (struct frame *, const char *);
-extern bool x_defined_color (struct frame *, const char *, XColor *, bool, bool);
+extern bool x_defined_color (struct frame *, const char *, Emacs_Color *,
+ bool, bool);
#ifdef HAVE_X_I18N
extern void free_frame_xic (struct frame *);
# if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
@@ -1261,15 +1262,6 @@ extern void x_session_close (void);
#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)
-#define STORE_XCHAR2B(chp, b1, b2) \
- ((chp)->byte1 = (b1), (chp)->byte2 = (b2))
-
-#define XCHAR2B_BYTE1(chp) \
- ((chp)->byte1)
-
-#define XCHAR2B_BYTE2(chp) \
- ((chp)->byte2)
-
#define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \
((nr).x = (rx), \
(nr).y = (ry), \