aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c13
-rw-r--r--src/data.c13
-rw-r--r--src/dbusbind.c188
-rw-r--r--src/dispnew.c2
-rw-r--r--src/fileio.c2
-rw-r--r--src/fns.c4
-rw-r--r--src/frame.c2
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/lisp.h10
-rw-r--r--src/nsfns.m146
-rw-r--r--src/nsterm.m87
-rw-r--r--src/pdumper.c5
-rw-r--r--src/process.c8
-rw-r--r--src/w32fns.c142
-rw-r--r--src/w32term.c1
-rw-r--r--src/w32term.h1
-rw-r--r--src/xdisp.c6
-rw-r--r--src/xsettings.c32
18 files changed, 502 insertions, 162 deletions
diff --git a/src/buffer.c b/src/buffer.c
index c1c0441a70e..b55284a4a26 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3120,14 +3120,13 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
3120{ 3120{
3121 ptrdiff_t idx = 0; 3121 ptrdiff_t idx = 0;
3122 ptrdiff_t len = *len_ptr; 3122 ptrdiff_t len = *len_ptr;
3123 ptrdiff_t next = ZV; 3123 ptrdiff_t next = Z;
3124 Lisp_Object *vec = *vec_ptr; 3124 Lisp_Object *vec = *vec_ptr;
3125 struct itree_node *node; 3125 struct itree_node *node;
3126 3126
3127 /* Extend the search range if overlays beginning at ZV are 3127 /* Extend the search range if overlays beginning at Z are wanted. */
3128 wanted. */ 3128 ptrdiff_t search_end = Z;
3129 ptrdiff_t search_end = ZV; 3129 if (end >= Z && (empty || trailing))
3130 if (end >= ZV && (empty || trailing))
3131 ++search_end; 3130 ++search_end;
3132 3131
3133 ITREE_FOREACH (node, current_buffer->overlays, beg, search_end, 3132 ITREE_FOREACH (node, current_buffer->overlays, beg, search_end,
@@ -3141,7 +3140,7 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
3141 else if (node->begin == end) 3140 else if (node->begin == end)
3142 { 3141 {
3143 next = node->begin; 3142 next = node->begin;
3144 if ((! empty || end < ZV) && beg < end) 3143 if ((! empty || end < Z) && beg < end)
3145 break; 3144 break;
3146 if (empty && node->begin != node->end) 3145 if (empty && node->begin != node->end)
3147 continue; 3146 continue;
@@ -3168,7 +3167,7 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
3168 idx++; 3167 idx++;
3169 } 3168 }
3170 if (next_ptr) 3169 if (next_ptr)
3171 *next_ptr = next ? next : ZV; 3170 *next_ptr = next ? next : Z;
3172 3171
3173 return idx; 3172 return idx;
3174} 3173}
diff --git a/src/data.c b/src/data.c
index 4314ca0294e..6d7a882dcfd 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1789,16 +1789,9 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1789 set_blv_value (blv, newval); 1789 set_blv_value (blv, newval);
1790 1790
1791 if (blv->fwd) 1791 if (blv->fwd)
1792 { 1792 store_symval_forwarding (blv->fwd, newval, (BUFFERP (where)
1793 if (unbinding_p) 1793 ? XBUFFER (where)
1794 /* If storing void (making the symbol void), forward only through 1794 : current_buffer));
1795 buffer-local indicator, not through Lisp_Objfwd, etc. */
1796 blv->fwd = NULL;
1797 else
1798 store_symval_forwarding (blv->fwd, newval,
1799 BUFFERP (where)
1800 ? XBUFFER (where) : current_buffer);
1801 }
1802 break; 1795 break;
1803 } 1796 }
1804 case SYMBOL_FORWARDED: 1797 case SYMBOL_FORWARDED:
diff --git a/src/dbusbind.c b/src/dbusbind.c
index cb705e9e92a..60ac38b5479 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -129,6 +129,8 @@ static bool xd_in_read_queued_messages = 0;
129#endif 129#endif
130 130
131/* Check whether TYPE is a basic DBusType. */ 131/* Check whether TYPE is a basic DBusType. */
132/* TODO: Shouldn't we assume, that recent D-Bus implementations carry
133 HAVE_DBUS_TYPE_IS_VALID and DBUS_TYPE_UNIX_FD? See configure.ac. */
132#ifdef HAVE_DBUS_TYPE_IS_VALID 134#ifdef HAVE_DBUS_TYPE_IS_VALID
133#define XD_BASIC_DBUS_TYPE(type) \ 135#define XD_BASIC_DBUS_TYPE(type) \
134 (dbus_type_is_valid (type) && dbus_type_is_basic (type)) 136 (dbus_type_is_valid (type) && dbus_type_is_basic (type))
@@ -310,6 +312,8 @@ XD_OBJECT_TO_STRING (Lisp_Object object)
310 } \ 312 } \
311 } while (0) 313 } while (0)
312 314
315/* TODO: Shouldn't we assume, that recent D-Bus implementations carry
316 HAVE_DBUS_VALIDATE_*? See configure.ac. */
313#if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \ 317#if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \
314 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER) 318 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER)
315#define XD_DBUS_VALIDATE_OBJECT(object, func) \ 319#define XD_DBUS_VALIDATE_OBJECT(object, func) \
@@ -1044,6 +1048,8 @@ xd_get_connection_address (Lisp_Object bus)
1044} 1048}
1045 1049
1046/* Return the file descriptor for WATCH, -1 if not found. */ 1050/* Return the file descriptor for WATCH, -1 if not found. */
1051/* TODO: Shouldn't we assume, that recent D-Bus implementations carry
1052 HAVE_DBUS_WATCH_GET_UNIX_FD? See configure.ac. */
1047static int 1053static int
1048xd_find_watch_fd (DBusWatch *watch) 1054xd_find_watch_fd (DBusWatch *watch)
1049{ 1055{
@@ -1372,6 +1378,7 @@ usage: (dbus-message-internal &rest REST) */)
1372 dbus_uint32_t serial = 0; 1378 dbus_uint32_t serial = 0;
1373 unsigned int ui_serial; 1379 unsigned int ui_serial;
1374 int timeout = -1; 1380 int timeout = -1;
1381 dbus_bool_t keepfd = FALSE;
1375 ptrdiff_t count, count0; 1382 ptrdiff_t count, count0;
1376 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; 1383 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1377 1384
@@ -1548,6 +1555,7 @@ usage: (dbus-message-internal &rest REST) */)
1548 timeout = min (XFIXNAT (args[count+1]), INT_MAX); 1555 timeout = min (XFIXNAT (args[count+1]), INT_MAX);
1549 count = count + 2; 1556 count = count + 2;
1550 } 1557 }
1558
1551 /* Check for authorizable parameter. */ 1559 /* Check for authorizable parameter. */
1552 else if (EQ (args[count], QCauthorizable)) 1560 else if (EQ (args[count], QCauthorizable))
1553 { 1561 {
@@ -1565,6 +1573,24 @@ usage: (dbus-message-internal &rest REST) */)
1565 1573
1566 count = count + 2; 1574 count = count + 2;
1567 } 1575 }
1576
1577 /* Check for keepfd parameter. */
1578 else if (EQ (args[count], QCkeep_fd))
1579 {
1580 if (mtype != DBUS_MESSAGE_TYPE_METHOD_CALL)
1581 XD_SIGNAL1
1582 (build_string (":keep-fd is only supported on method calls"));
1583
1584 /* Ignore this keyword if unsupported. */
1585#ifdef DBUS_TYPE_UNIX_FD
1586 keepfd = TRUE;
1587#else
1588 XD_DEBUG_MESSAGE (":keep-fd not supported");
1589#endif
1590
1591 ++count;
1592 }
1593
1568 else break; 1594 else break;
1569 1595
1570 } 1596 }
@@ -1618,7 +1644,8 @@ usage: (dbus-message-internal &rest REST) */)
1618 result = list3 (QCserial, bus, INT_TO_INTEGER (serial)); 1644 result = list3 (QCserial, bus, INT_TO_INTEGER (serial));
1619 1645
1620 /* Create a hash table entry. */ 1646 /* Create a hash table entry. */
1621 Fputhash (result, handler, Vdbus_registered_objects_table); 1647 Fputhash (result, keepfd ? Fcons (handler, path) : handler,
1648 Vdbus_registered_objects_table);
1622 } 1649 }
1623 else 1650 else
1624 { 1651 {
@@ -1640,106 +1667,81 @@ usage: (dbus-message-internal &rest REST) */)
1640 return result; 1667 return result;
1641} 1668}
1642 1669
1643/* Alist of registered inhibitor locks for D-Bus. 1670/* Alist of registered file descriptors for D-Bus.
1644 An entry in this list is a list (FD WHAT WHY BLOCK). 1671 The key is an open file descriptor, retrieved via `dbus-call-method'
1645 The car of the list is a file descriptor retrieved from a 1672 or `dbus--open-fd'. The value is a string OBJECT-PATH or FILENAME,
1646 'dbus-make-inhibitor-lock` call. The cdr of the list represents the 1673 which represents the arguments the function was called with. Those
1647 three arguments 'dbus-make-inhibitor-lock` was called with. */ 1674 values are not needed for further operations; they are just shown for
1648static Lisp_Object xd_registered_inhibitor_locks; 1675 information. */
1649 1676static Lisp_Object xd_registered_fds;
1650DEFUN ("dbus-make-inhibitor-lock", Fdbus_make_inhibitor_lock, 1677
1651 Sdbus_make_inhibitor_lock, 1678DEFUN ("dbus--fd-open", Fdbus__fd_open, Sdbus__fd_open, 1, 1, 0,
1652 2, 3, 0, 1679 doc: /* Open FILENAME and return the respective read-only file descriptor. */)
1653 doc: /* Inhibit system shutdowns and sleep states. 1680 (Lisp_Object filename)
1654
1655WHAT is a colon-separated string of lock types, i.e. "shutdown",
1656"sleep", "idle", "handle-power-key", "handle-suspend-key",
1657"handle-hibernate-key", "handle-lid-switch". Example: "shutdown:idle".
1658
1659WHY is a descriptive string of why the lock is taken. Example: "Package
1660Update in Progress".
1661
1662The optional BLOCK is the mode of the inhibitor lock, either "block"
1663(BLOCK is non-nil), or "delay".
1664
1665It returns a file descriptor or nil, if the lock cannot be acquired. If
1666there is already an inhibitor lock for the triple (WHAT WHY BLOCK), this
1667lock is returned.
1668
1669For details of the arguments, see Info node `(dbus)Inhibitor Locks'. */)
1670 (Lisp_Object what, Lisp_Object why, Lisp_Object block)
1671{ 1681{
1672 CHECK_STRING (what); 1682 CHECK_STRING (filename);
1673 CHECK_STRING (why); 1683 filename = Fexpand_file_name (filename, Qnil);
1674 if (!NILP (block)) 1684 filename = ENCODE_FILE (filename);
1675 block = Qt;
1676 Lisp_Object who = build_string ("Emacs");
1677 Lisp_Object mode =
1678 (NILP (block)) ? build_string ("delay") : build_string ("block");
1679 1685
1680 /* Check, whether it is registered already. */ 1686 /* Check, whether it is registered already. */
1681 Lisp_Object triple = list3 (what, why, block); 1687 Lisp_Object registered = Frassoc (filename, xd_registered_fds);
1682 Lisp_Object registered = Frassoc (triple, xd_registered_inhibitor_locks);
1683 if (!NILP (registered)) 1688 if (!NILP (registered))
1684 return CAR_SAFE (registered); 1689 return CAR_SAFE (registered);
1685 1690
1686 /* Register lock. */ 1691 /* Open file descriptor. */
1687 Lisp_Object lock = 1692 int fd = emacs_open (SSDATA (filename), O_RDONLY, 0);
1688 calln (Qdbus_call_method, QCsystem,
1689 build_string ("org.freedesktop.login1"),
1690 build_string ("/org/freedesktop/login1"),
1691 build_string ("org.freedesktop.login1.Manager"),
1692 build_string ("Inhibit"), what, who, why, mode);
1693
1694 xd_registered_inhibitor_locks =
1695 Fcons (Fcons (lock, triple), xd_registered_inhibitor_locks);
1696 return lock;
1697}
1698 1693
1699DEFUN ("dbus-close-inhibitor-lock", Fdbus_close_inhibitor_lock, 1694 if (fd <= 0)
1700 Sdbus_close_inhibitor_lock, 1695 XD_SIGNAL2 (build_string ("Cannot open file"), filename);
1701 1, 1, 0,
1702 doc: /* Close inhibitor lock file descriptor.
1703 1696
1704LOCK, a file descriptor, must be the result of a `dbus-make-inhibitor-lock' 1697 /* Register file descriptor. */
1705call. It returns t in case of success, or nil if it isn't be possible 1698 xd_registered_fds =
1706to close the lock, or if the lock is closed already. 1699 Fcons (Fcons (INT_TO_INTEGER (fd), filename), xd_registered_fds);
1700 return INT_TO_INTEGER (fd);
1701}
1707 1702
1708For details, see Info node `(dbus)Inhibitor Locks'. */) 1703DEFUN ("dbus--fd-close", Fdbus__fd_close, Sdbus__fd_close, 1, 1, 0,
1709 (Lisp_Object lock) 1704 doc: /* Close file descriptor FD.
1705FD must be the result of a `dbus-call-method' or `dbus--fd-open' call,
1706see `dbus--registered-fds'. It returns t in case of success, or nil if
1707it isn't be possible to close the file descriptor, or if the file
1708descriptor is closed already. */)
1709 (Lisp_Object fd)
1710{ 1710{
1711 CHECK_FIXNUM (lock); 1711 CHECK_FIXNUM (fd);
1712 1712
1713 /* Check, whether it is registered. */ 1713 /* Check, whether it is registered. */
1714 Lisp_Object registered = assoc_no_quit (lock, xd_registered_inhibitor_locks); 1714 Lisp_Object registered = assoc_no_quit (fd, xd_registered_fds);
1715 if (NILP (registered)) 1715 if (NILP (registered))
1716 return Qnil; 1716 return Qnil;
1717 else 1717 else
1718 { 1718 {
1719 xd_registered_inhibitor_locks = 1719 xd_registered_fds = Fdelete (registered, xd_registered_fds);
1720 Fdelete (registered, xd_registered_inhibitor_locks); 1720 return (emacs_close (XFIXNAT (fd)) == 0) ? Qt : Qnil;
1721 return (emacs_close (XFIXNAT (lock)) == 0) ? Qt : Qnil;
1722 } 1721 }
1723} 1722}
1724 1723
1725DEFUN ("dbus-registered-inhibitor-locks", Fdbus_registered_inhibitor_locks, 1724DEFUN ("dbus--registered-fds", Fdbus__registered_fds, Sdbus__registered_fds,
1726 Sdbus_registered_inhibitor_locks,
1727 0, 0, 0, 1725 0, 0, 0,
1728 doc: /* Return registered inhibitor locks, an alist. 1726 doc: /* Return registered file descriptors, an alist.
1729This allows to check, whether other packages of the running Emacs 1727The key is an open file descriptor, retrieved via `dbus-call-method' or
1730instance have acquired an inhibitor lock as well. 1728`dbus--open-fd'. The value is a string OBJECT-PATH or FILENAME, which
1731An entry in this list is a list (FD WHAT WHY BLOCK). 1729represents the arguments the function was called with. Those values are
1732The car of the list is the file descriptor retrieved from a 1730not needed for further operations; they are just shown for information.
1733'dbus-make-inhibitor-lock` call. The cdr of the list represents the 1731
1734three arguments 'dbus-make-inhibitor-lock` was called with. */) 1732This alist allows to check, whether other packages of the running Emacs
1733instance have acquired a file descriptor as well. */)
1735 (void) 1734 (void)
1736{ 1735{
1737 /* We return a copy of xd_registered_inhibitor_locks, in order to 1736 /* We return a copy of xd_registered_fds, in order to protect it
1738 protect it against malicious manipulation. */ 1737 against malicious manipulation. */
1739 Lisp_Object registered = xd_registered_inhibitor_locks; 1738 Lisp_Object registered = xd_registered_fds;
1740 Lisp_Object result = Qnil; 1739 Lisp_Object result = Qnil;
1741 for (; !NILP (registered); registered = CDR_SAFE (registered)) 1740 for (; !NILP (registered); registered = CDR_SAFE (registered))
1742 result = Fcons (Fcopy_sequence (CAR_SAFE (registered)), result); 1741 {
1742 Lisp_Object tem = CAR_SAFE (registered);
1743 result = Fcons (Fcons (CAR_SAFE (tem), CDR_SAFE (tem)), result);
1744 }
1743 return Fnreverse (result); 1745 return Fnreverse (result);
1744} 1746}
1745 1747
@@ -1859,7 +1861,22 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1859 Fremhash (key, Vdbus_registered_objects_table); 1861 Fremhash (key, Vdbus_registered_objects_table);
1860 1862
1861 /* Store the event. */ 1863 /* Store the event. */
1862 xd_store_event (value, args, event_args); 1864 xd_store_event (CONSP (value) ? CAR_SAFE (value) : value, args, event_args);
1865
1866#ifdef DBUS_TYPE_UNIX_FD
1867 /* Check, whether there is a file descriptor to be kept.
1868 value is (handler . path)
1869 args is ((:unix-fd NN) ...) */
1870 if (CONSP (value)
1871 && CONSP (CAR_SAFE (args))
1872 && EQ (CAR_SAFE (CAR_SAFE (args)), QCunix_fd))
1873 {
1874 xd_registered_fds =
1875 Fcons (Fcons (CAR_SAFE (CDR_SAFE (CAR_SAFE (args))),
1876 CDR_SAFE (value)),
1877 xd_registered_fds);
1878 }
1879#endif
1863 } 1880 }
1864 1881
1865 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */ 1882 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
@@ -1995,7 +2012,7 @@ static void
1995syms_of_dbusbind_for_pdumper (void) 2012syms_of_dbusbind_for_pdumper (void)
1996{ 2013{
1997 xd_registered_buses = Qnil; 2014 xd_registered_buses = Qnil;
1998 xd_registered_inhibitor_locks = Qnil; 2015 xd_registered_fds = Qnil;
1999} 2016}
2000 2017
2001void 2018void
@@ -2003,9 +2020,9 @@ syms_of_dbusbind (void)
2003{ 2020{
2004 defsubr (&Sdbus__init_bus); 2021 defsubr (&Sdbus__init_bus);
2005 defsubr (&Sdbus_get_unique_name); 2022 defsubr (&Sdbus_get_unique_name);
2006 defsubr (&Sdbus_make_inhibitor_lock); 2023 defsubr (&Sdbus__fd_open);
2007 defsubr (&Sdbus_close_inhibitor_lock); 2024 defsubr (&Sdbus__fd_close);
2008 defsubr (&Sdbus_registered_inhibitor_locks); 2025 defsubr (&Sdbus__registered_fds);
2009 2026
2010 DEFSYM (Qdbus_message_internal, "dbus-message-internal"); 2027 DEFSYM (Qdbus_message_internal, "dbus-message-internal");
2011 defsubr (&Sdbus_message_internal); 2028 defsubr (&Sdbus_message_internal);
@@ -2030,6 +2047,11 @@ syms_of_dbusbind (void)
2030 /* Lisp symbol for method interactive authorization. */ 2047 /* Lisp symbol for method interactive authorization. */
2031 DEFSYM (QCauthorizable, ":authorizable"); 2048 DEFSYM (QCauthorizable, ":authorizable");
2032 2049
2050 /* Lisp symbol for file descriptor kept. */
2051#ifdef DBUS_TYPE_UNIX_FD
2052 DEFSYM (QCkeep_fd, ":keep-fd");
2053#endif
2054
2033 /* Lisp symbols of D-Bus types. */ 2055 /* Lisp symbols of D-Bus types. */
2034 DEFSYM (QCbyte, ":byte"); 2056 DEFSYM (QCbyte, ":byte");
2035 DEFSYM (QCboolean, ":boolean"); 2057 DEFSYM (QCboolean, ":boolean");
@@ -2166,7 +2188,7 @@ be called when the D-Bus reply message arrives. */);
2166 /* Initialize internal objects. */ 2188 /* Initialize internal objects. */
2167 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper); 2189 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper);
2168 staticpro (&xd_registered_buses); 2190 staticpro (&xd_registered_buses);
2169 staticpro (&xd_registered_inhibitor_locks); 2191 staticpro (&xd_registered_fds);
2170 2192
2171 Fprovide (intern_c_string ("dbusbind"), Qnil); 2193 Fprovide (intern_c_string ("dbusbind"), Qnil);
2172} 2194}
diff --git a/src/dispnew.c b/src/dispnew.c
index d976660db5c..841faef8e7f 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3677,7 +3677,7 @@ box_from_display_table (struct frame *f, enum box box, GLYPH *g)
3677static void 3677static void
3678box_default (struct frame *f, enum box box, GLYPH *g) 3678box_default (struct frame *f, enum box box, GLYPH *g)
3679{ 3679{
3680 int dflt; 3680 int dflt UNINIT;
3681 switch (box) 3681 switch (box)
3682 { 3682 {
3683 case BOX_VERTICAL: 3683 case BOX_VERTICAL:
diff --git a/src/fileio.c b/src/fileio.c
index 7a3ef3267cb..c50259239a0 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4520,7 +4520,7 @@ by calling `format-decode', which see. */)
4520 /* Find the end position, which is end_offset if given, 4520 /* Find the end position, which is end_offset if given,
4521 the file's end otherwise. */ 4521 the file's end otherwise. */
4522 4522
4523 off_t endpos; 4523 off_t endpos UNINIT;
4524 if (!giveup_match_end) 4524 if (!giveup_match_end)
4525 { 4525 {
4526 endpos = end_offset; 4526 endpos = end_offset;
diff --git a/src/fns.c b/src/fns.c
index 5dbdb21202b..7c528ff0139 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -7713,4 +7713,8 @@ For best results this should end in a space. */);
7713 DEFSYM (QCin_place, ":in-place"); 7713 DEFSYM (QCin_place, ":in-place");
7714 DEFSYM (QCreverse, ":reverse"); 7714 DEFSYM (QCreverse, ":reverse");
7715 DEFSYM (Qvaluelt, "value<"); 7715 DEFSYM (Qvaluelt, "value<");
7716
7717 /* sleep-event states. */
7718 DEFSYM (Qpre_sleep, "pre-sleep");
7719 DEFSYM (Qpost_wake, "post-wake");
7716} 7720}
diff --git a/src/frame.c b/src/frame.c
index ffac559252d..e8cdecc5f94 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2604,7 +2604,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2604 struct frame *f = decode_any_frame (frame); 2604 struct frame *f = decode_any_frame (frame);
2605 struct frame *sf; 2605 struct frame *sf;
2606 struct kboard *kb; 2606 struct kboard *kb;
2607 Lisp_Object frames, frame1; 2607 Lisp_Object frames, frame1 UNINIT;
2608 int is_tooltip_frame; 2608 int is_tooltip_frame;
2609 bool nochild = !FRAME_PARENT_FRAME (f); 2609 bool nochild = !FRAME_PARENT_FRAME (f);
2610 Lisp_Object minibuffer_child_frame = Qnil; 2610 Lisp_Object minibuffer_child_frame = Qnil;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index bf69fb2d96c..8bdc6f03dac 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1425,6 +1425,8 @@ xg_frame_set_size_and_position (struct frame *f, int width, int height)
1425 1425
1426 outer_height /= scale; 1426 outer_height /= scale;
1427 outer_width /= scale; 1427 outer_width /= scale;
1428 x /= scale;
1429 y /= scale;
1428 1430
1429 /* Full force ahead. For top-level frames the gravity will get reset 1431 /* Full force ahead. For top-level frames the gravity will get reset
1430 to NorthWestGravity anyway. */ 1432 to NorthWestGravity anyway. */
diff --git a/src/lisp.h b/src/lisp.h
index 2d25f781091..80e01492c37 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3480,15 +3480,15 @@ struct Lisp_Fwd
3480 enum Lisp_Fwd_Type type : 8; 3480 enum Lisp_Fwd_Type type : 8;
3481 union 3481 union
3482 { 3482 {
3483 intmax_t *intvar; 3483 intmax_t *intvar; /* when type == Lisp_Fwd_Int */
3484 bool *boolvar; 3484 bool *boolvar; /* when type == Lisp_Fwd_Bool */
3485 Lisp_Object *objvar; 3485 Lisp_Object *objvar; /* when type == Lisp_Fwd_Obj */
3486 struct 3486 struct
3487 { 3487 {
3488 uint16_t offset; 3488 uint16_t offset;
3489 enum Lisp_Fwd_Predicate predicate : 8; 3489 enum Lisp_Fwd_Predicate predicate : 8;
3490 } buf; 3490 } buf; /* when type == Lisp_Fwd_Buffer_Obj */
3491 int kbdoffset; 3491 int kbdoffset; /* when type == Lisp_Fwd_Kboard_Obj */
3492 } u; 3492 } u;
3493}; 3493};
3494 3494
diff --git a/src/nsfns.m b/src/nsfns.m
index 6992eaa74ce..c8de5583bf3 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2210,6 +2210,62 @@ font descriptor. If string contains `fontset' and not
2210 return build_string (ns_xlfd_to_fontname (SSDATA (name))); 2210 return build_string (ns_xlfd_to_fontname (SSDATA (name)));
2211} 2211}
2212 2212
2213static void
2214ns_init_colors (void)
2215{
2216 NSTRACE ("ns_init_colors");
2217
2218 NSColorList *cl = [NSColorList colorListNamed: @"Emacs"];
2219
2220 /* There are 752 colors defined in rgb.txt. */
2221 if ( cl == nil || [[cl allKeys] count] < 752)
2222 {
2223 Lisp_Object color_file, color_map, color, name;
2224 unsigned long c;
2225
2226 color_file = Fexpand_file_name (build_string ("rgb.txt"),
2227 Fsymbol_value (intern ("data-directory")));
2228
2229 color_map = Fx_load_color_file (color_file);
2230 if (NILP (color_map))
2231 fatal ("Could not read %s.\n", SDATA (color_file));
2232
2233 cl = [[NSColorList alloc] initWithName: @"Emacs"];
2234 for ( ; CONSP (color_map); color_map = XCDR (color_map))
2235 {
2236 color = XCAR (color_map);
2237 name = XCAR (color);
2238 c = XFIXNUM (XCDR (color));
2239 c |= 0xFF000000;
2240 [cl setColor:
2241 [NSColor colorWithUnsignedLong:c]
2242 forKey: [NSString stringWithLispString: name]];
2243 }
2244 @try
2245 {
2246#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
2247#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
2248 if ([cl respondsToSelector:@selector(writeToURL:error:)])
2249#endif
2250 if ([cl writeToURL:nil error:nil] == false)
2251 fprintf (stderr, "ns_init_colors: could not write Emacs.clr\n");
2252#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
2253 else
2254#endif
2255#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 */
2256#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100 || defined (NS_IMPL_GNUSTEP)
2257 if ([cl writeToFile: nil] == false)
2258 fprintf (stderr, "ns_init_colors: could not write Emacs.clr\n");
2259#endif
2260 }
2261 @catch (NSException *e)
2262 {
2263 NSLog(@"ns_init_colors: could not write Emacs.clr: %@", e.reason);
2264 }
2265 }
2266}
2267
2268static BOOL ns_init_colors_done = NO;
2213 2269
2214DEFUN ("ns-list-colors", Fns_list_colors, Sns_list_colors, 0, 1, 0, 2270DEFUN ("ns-list-colors", Fns_list_colors, Sns_list_colors, 0, 1, 0,
2215 doc: /* Return a list of all available colors. 2271 doc: /* Return a list of all available colors.
@@ -2221,6 +2277,12 @@ The optional argument FRAME is currently ignored. */)
2221 NSColorList *clist; 2277 NSColorList *clist;
2222 NSAutoreleasePool *pool; 2278 NSAutoreleasePool *pool;
2223 2279
2280 if (ns_init_colors_done == NO)
2281 {
2282 ns_init_colors ();
2283 ns_init_colors_done = YES;
2284 }
2285
2224 if (!NILP (frame)) 2286 if (!NILP (frame))
2225 { 2287 {
2226 CHECK_FRAME (frame); 2288 CHECK_FRAME (frame);
@@ -3806,6 +3868,88 @@ If PROGRESS is nil, remove the progress indicator. */)
3806 return Qnil; 3868 return Qnil;
3807} 3869}
3808 3870
3871/* A unique integer sleep block id and a hash map of its id to opaque
3872 NSObject sleep block activity tokens. */
3873static unsigned int sleep_block_id = 0;
3874static NSMutableDictionary *sleep_block_map = NULL;
3875
3876DEFUN ("ns-block-system-sleep",
3877 Fns_block_system_sleep,
3878 Sns_block_system_sleep,
3879 2, 2, 0,
3880 doc: /* Block system idle sleep.
3881WHY is a string reason for the block.
3882If ALLOW-DISPLAY-SLEEP is non-nil, block the screen from sleeping.
3883Return a token to unblock this block using `ns-unblock-system-sleep',
3884or nil if the block fails. */)
3885 (Lisp_Object why, Lisp_Object allow_display_sleep)
3886{
3887 block_input ();
3888
3889 NSString *reason = @"Emacs";
3890 if (!NILP (why))
3891 {
3892 CHECK_STRING (why);
3893 reason = [NSString stringWithLispString: why];
3894 }
3895
3896 unsigned long activity_options =
3897 NSActivityUserInitiated | NSActivityIdleSystemSleepDisabled;
3898 if (NILP (allow_display_sleep))
3899 activity_options |= NSActivityIdleDisplaySleepDisabled;
3900
3901 NSProcessInfo *processInfo = [NSProcessInfo processInfo];
3902 NSObject *activity_id = nil;
3903 if ([processInfo respondsToSelector:@selector(beginActivityWithOptions:reason:)])
3904 activity_id = [[NSProcessInfo processInfo]
3905 beginActivityWithOptions: activity_options
3906 reason: reason];
3907 unblock_input ();
3908
3909 if (!sleep_block_map)
3910 sleep_block_map = [[NSMutableDictionary alloc] initWithCapacity: 25];
3911
3912 if (activity_id)
3913 {
3914 [sleep_block_map setObject: activity_id
3915 forKey: [NSNumber numberWithInt: ++sleep_block_id]];
3916 return make_fixnum (sleep_block_id);
3917 }
3918 else
3919 return Qnil;
3920}
3921
3922DEFUN ("ns-unblock-system-sleep",
3923 Fns_unblock_system_sleep,
3924 Sns_unblock_system_sleep,
3925 1, 1, 0,
3926 doc: /* Unblock system idle sleep.
3927TOKEN is an object returned by `ns-block-system-sleep'.
3928Return non-nil if the TOKEN block was unblocked. */)
3929 (Lisp_Object token)
3930{
3931 block_input ();
3932 Lisp_Object res = Qnil;
3933 CHECK_FIXNAT (token);
3934 if (sleep_block_map)
3935 {
3936 NSNumber *key = [NSNumber numberWithInt: XFIXNAT (token)];
3937 NSObject *activity_id = [sleep_block_map objectForKey: key];
3938 if (activity_id)
3939 {
3940 NSProcessInfo *processInfo = [NSProcessInfo processInfo];
3941 if ([processInfo respondsToSelector:@selector(endActivity:)])
3942 {
3943 [[NSProcessInfo processInfo] endActivity: activity_id];
3944 res = Qt;
3945 }
3946 [sleep_block_map removeObjectForKey: key];
3947 }
3948 }
3949 unblock_input ();
3950 return res;
3951}
3952
3809#ifdef NS_IMPL_COCOA 3953#ifdef NS_IMPL_COCOA
3810 3954
3811DEFUN ("ns-send-items", 3955DEFUN ("ns-send-items",
@@ -4092,6 +4236,8 @@ The default value is t. */);
4092 defsubr (&Sns_badge); 4236 defsubr (&Sns_badge);
4093 defsubr (&Sns_request_user_attention); 4237 defsubr (&Sns_request_user_attention);
4094 defsubr (&Sns_progress_indicator); 4238 defsubr (&Sns_progress_indicator);
4239 defsubr (&Sns_block_system_sleep);
4240 defsubr (&Sns_unblock_system_sleep);
4095#ifdef NS_IMPL_COCOA 4241#ifdef NS_IMPL_COCOA
4096 defsubr (&Sns_send_items); 4242 defsubr (&Sns_send_items);
4097#endif 4243#endif
diff --git a/src/nsterm.m b/src/nsterm.m
index cc44c58a938..3c746f2926c 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -597,7 +597,6 @@ ns_init_locale (void)
597 setenv ("LANG", lang, 1); 597 setenv ("LANG", lang, 1);
598} 598}
599 599
600
601void 600void
602ns_release_object (void *obj) 601ns_release_object (void *obj)
603/* -------------------------------------------------------------------------- 602/* --------------------------------------------------------------------------
@@ -5901,53 +5900,6 @@ ns_term_init (Lisp_Object display_name)
5901 ns_antialias_threshold = NILP (tmp) ? 10.0 : extract_float (tmp); 5900 ns_antialias_threshold = NILP (tmp) ? 10.0 : extract_float (tmp);
5902 } 5901 }
5903 5902
5904 NSTRACE_MSG ("Colors");
5905
5906 {
5907 NSColorList *cl = [NSColorList colorListNamed: @"Emacs"];
5908
5909 /* There are 752 colors defined in rgb.txt. */
5910 if ( cl == nil || [[cl allKeys] count] < 752)
5911 {
5912 Lisp_Object color_file, color_map, color, name;
5913 unsigned long c;
5914
5915 color_file = Fexpand_file_name (build_string ("rgb.txt"),
5916 Fsymbol_value (intern ("data-directory")));
5917
5918 color_map = Fx_load_color_file (color_file);
5919 if (NILP (color_map))
5920 fatal ("Could not read %s.\n", SDATA (color_file));
5921
5922 cl = [[NSColorList alloc] initWithName: @"Emacs"];
5923 for ( ; CONSP (color_map); color_map = XCDR (color_map))
5924 {
5925 color = XCAR (color_map);
5926 name = XCAR (color);
5927 c = XFIXNUM (XCDR (color));
5928 c |= 0xFF000000;
5929 [cl setColor:
5930 [NSColor colorWithUnsignedLong:c]
5931 forKey: [NSString stringWithLispString: name]];
5932 }
5933
5934 /* FIXME: Report any errors writing the color file below. */
5935#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
5936#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
5937 if ([cl respondsToSelector:@selector(writeToURL:error:)])
5938#endif
5939 [cl writeToURL:nil error:nil];
5940#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
5941 else
5942#endif
5943#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 */
5944#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100 \
5945 || defined (NS_IMPL_GNUSTEP)
5946 [cl writeToFile: nil];
5947#endif
5948 }
5949 }
5950
5951 NSTRACE_MSG ("Versions"); 5903 NSTRACE_MSG ("Versions");
5952 5904
5953 delete_keyboard_wait_descriptor (0); 5905 delete_keyboard_wait_descriptor (0);
@@ -6382,6 +6334,20 @@ ns_term_shutdown (int sig)
6382#endif 6334#endif
6383 6335
6384#ifdef NS_IMPL_COCOA 6336#ifdef NS_IMPL_COCOA
6337 /* Sleep event notification. */
6338 [[[NSWorkspace sharedWorkspace] notificationCenter]
6339 addObserver: self
6340 selector:@selector(systemWillSleep:)
6341 name: NSWorkspaceWillSleepNotification
6342 object: nil];
6343 [[[NSWorkspace sharedWorkspace] notificationCenter]
6344 addObserver: self
6345 selector: @selector(systemDidWake:)
6346 name: NSWorkspaceDidWakeNotification
6347 object: nil];
6348#endif
6349
6350#ifdef NS_IMPL_COCOA
6385 /* Some functions/methods in CoreFoundation/Foundation increase the 6351 /* Some functions/methods in CoreFoundation/Foundation increase the
6386 maximum number of open files for the process in their first call. 6352 maximum number of open files for the process in their first call.
6387 We make dummy calls to them and then reduce the resource limit 6353 We make dummy calls to them and then reduce the resource limit
@@ -6419,6 +6385,31 @@ ns_term_shutdown (int sig)
6419#endif 6385#endif
6420} 6386}
6421 6387
6388/* Sleep event notification. */
6389
6390- (void) systemWillSleep:(NSNotification *)notification
6391{
6392#ifdef NS_IMPL_COCOA
6393 NSTRACE ("[EmacsApp systemWillSleep:]");
6394 struct input_event ie;
6395 EVENT_INIT (ie);
6396 ie.kind = SLEEP_EVENT;
6397 ie.arg = list1 (Qpre_sleep);
6398 kbd_buffer_store_event (&ie);
6399#endif
6400}
6401
6402- (void) systemDidWake:(NSNotification *)notification
6403{
6404#ifdef NS_IMPL_COCOA
6405 NSTRACE ("[EmacsApp systemDidWake:]");
6406 struct input_event ie;
6407 EVENT_INIT (ie);
6408 ie.kind = SLEEP_EVENT;
6409 ie.arg = list1 (Qpost_wake);
6410 kbd_buffer_store_event (&ie);
6411#endif
6412}
6422 6413
6423/* Termination sequences: 6414/* Termination sequences:
6424 C-x C-c: 6415 C-x C-c:
diff --git a/src/pdumper.c b/src/pdumper.c
index 41edf26b77a..89752391c84 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2466,7 +2466,10 @@ dump_blv (struct dump_context *ctx,
2466 DUMP_FIELD_COPY (&out, blv, local_if_set); 2466 DUMP_FIELD_COPY (&out, blv, local_if_set);
2467 DUMP_FIELD_COPY (&out, blv, found); 2467 DUMP_FIELD_COPY (&out, blv, found);
2468 if (blv->fwd) 2468 if (blv->fwd)
2469 dump_field_fwd (ctx, &out, blv, &blv->fwd); 2469 {
2470 eassert (XFWDTYPE (blv->fwd) != Lisp_Fwd_Buffer_Obj);
2471 dump_field_fwd (ctx, &out, blv, &blv->fwd);
2472 }
2470 dump_field_lv (ctx, &out, blv, &blv->where, WEIGHT_NORMAL); 2473 dump_field_lv (ctx, &out, blv, &blv->where, WEIGHT_NORMAL);
2471 dump_field_lv (ctx, &out, blv, &blv->defcell, WEIGHT_STRONG); 2474 dump_field_lv (ctx, &out, blv, &blv->defcell, WEIGHT_STRONG);
2472 dump_field_lv (ctx, &out, blv, &blv->valcell, WEIGHT_STRONG); 2475 dump_field_lv (ctx, &out, blv, &blv->valcell, WEIGHT_STRONG);
diff --git a/src/process.c b/src/process.c
index 375c9010ba8..b2810444137 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5138,11 +5138,15 @@ server_accept_connection (Lisp_Object server, int channel)
5138 /* If the server process is locked to this thread, lock the client 5138 /* If the server process is locked to this thread, lock the client
5139 process to the same thread, otherwise clear the thread of its I/O 5139 process to the same thread, otherwise clear the thread of its I/O
5140 descriptors. */ 5140 descriptors. */
5141 eassert (!fd_callback_info[p->infd].thread);
5142 if (NILP (ps->thread)) 5141 if (NILP (ps->thread))
5143 set_proc_thread (p, NULL); 5142 {
5143 eassert (!fd_callback_info[p->infd].thread);
5144 set_proc_thread (p, NULL);
5145 }
5144 else 5146 else
5145 { 5147 {
5148 eassert (!fd_callback_info[p->infd].thread
5149 || fd_callback_info[p->infd].thread == XTHREAD (ps->thread));
5146 eassert (XTHREAD (ps->thread) == current_thread); 5150 eassert (XTHREAD (ps->thread) == current_thread);
5147 set_proc_thread (p, XTHREAD (ps->thread)); 5151 set_proc_thread (p, XTHREAD (ps->thread));
5148 } 5152 }
diff --git a/src/w32fns.c b/src/w32fns.c
index 7fd7ce2eea8..1c780739bec 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -11337,6 +11337,135 @@ if the selected frame is not (yet) associated with a window handle */)
11337#endif /* WINDOWSNT */ 11337#endif /* WINDOWSNT */
11338 11338
11339/*********************************************************************** 11339/***********************************************************************
11340 System Sleep Support
11341 ***********************************************************************/
11342
11343typedef ULONG (WINAPI * SetThreadExecutionState_Proc) (IN ULONG);
11344static SetThreadExecutionState_Proc SetThreadExecutionState_fn = NULL;
11345
11346static unsigned int sleep_block_id = 0;
11347static unsigned int sleep_block_count = 0;
11348
11349DEFUN ("w32-block-system-sleep",
11350 Fw32_block_system_sleep,
11351 Sw32_block_system_sleep,
11352 1, 1, 0,
11353 doc: /* Block system idle sleep.
11354If ALLOW-DISPLAY-SLEEP is non-nil, block the screen from sleeping.
11355Return a token to unblock this block using `w32-unblock-system-sleep',
11356or nil if the block fails. */)
11357 (Lisp_Object allow_display_sleep)
11358{
11359 if (SetThreadExecutionState_fn == NULL)
11360 return Qnil;
11361
11362 /* ES_CONTINUOUS keeps the state until cleared. */
11363 EXECUTION_STATE new_state = ES_SYSTEM_REQUIRED | ES_CONTINUOUS;
11364 if (NILP (allow_display_sleep))
11365 new_state |= ES_DISPLAY_REQUIRED;
11366
11367 if (SetThreadExecutionState (new_state) == 0)
11368 return Qnil;
11369 else
11370 {
11371 /* One more block and next id. */
11372 ++sleep_block_count;
11373 ++sleep_block_id;
11374
11375 /* Synthesize a token. */
11376 return make_fixnum (sleep_block_id);
11377 }
11378}
11379
11380DEFUN ("w32-unblock-system-sleep",
11381 Fw32_unblock_system_sleep,
11382 Sw32_unblock_system_sleep,
11383 0, 0, 0,
11384 doc: /* Unblock system idle sleep.
11385Return non-nil if the TOKEN block was unblocked. */)
11386 (void)
11387{
11388 if (SetThreadExecutionState_fn == NULL)
11389 return Qnil;
11390
11391 /* No blocks to unblock. */
11392 if (sleep_block_count == 0)
11393 return Qnil;
11394
11395 /* One fewer block. */
11396 if (--sleep_block_count == 0
11397 && SetThreadExecutionState (ES_CONTINUOUS) == 0)
11398 return Qnil;
11399 else
11400 return Qt;
11401}
11402
11403DEFUN ("w32-system-sleep-block-count",
11404 Fw32_system_sleep_block_count,
11405 Sw32_system_sleep_block_count,
11406 0, 0, 0,
11407 doc: /* Return the w32 sleep block count. */)
11408 (void)
11409{
11410 return make_fixnum (sleep_block_count);
11411}
11412
11413typedef ULONG (CALLBACK *PMY_DEVICE_NOTIFY_CALLBACK_ROUTINE)
11414 (PVOID Context, ULONG Type, PVOID Setting);
11415
11416static ULONG CALLBACK ALIGN_STACK
11417sleep_notification_callback (PVOID _Context, ULONG Type, PVOID _Setting)
11418{
11419 struct input_event ie;
11420 EVENT_INIT (ie);
11421 ie.kind = SLEEP_EVENT;
11422
11423 switch (Type)
11424 {
11425 case PBT_APMRESUMEAUTOMATIC:
11426 /* Ignore this event. No user is present. */
11427 break;
11428 case PBT_APMSUSPEND:
11429 ie.arg = list1 (Qpre_sleep);
11430 kbd_buffer_store_event (&ie);
11431 break;
11432 case PBT_APMRESUMESUSPEND:
11433 ie.arg = list1 (Qpost_wake);
11434 kbd_buffer_store_event (&ie);
11435 break;
11436 }
11437 return 0;
11438}
11439
11440typedef HPOWERNOTIFY (WINAPI * RegisterSuspendResumeNotification_Proc)
11441 (IN HANDLE, IN DWORD);
11442static RegisterSuspendResumeNotification_Proc RegisterSuspendResumeNotification_fn = NULL;
11443
11444static HPOWERNOTIFY sleep_notification_handle = 0;
11445
11446typedef struct _MY_DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS {
11447 PMY_DEVICE_NOTIFY_CALLBACK_ROUTINE Callback;
11448 PVOID Context;
11449} MY_DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS, *PMY_DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS;
11450
11451void
11452w32_register_for_sleep_notifications (void)
11453{
11454 /* PowerRegisterSuspendResumeNotification is not a user-space call so
11455 we use RegisterSuspendResumeNotification. */
11456 if (RegisterSuspendResumeNotification_fn)
11457 {
11458 MY_DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS params;
11459 params.Callback = sleep_notification_callback;
11460 params.Context = NULL;
11461
11462 /* DEVICE_NOTIFY_CALLBACK = 2 */
11463 sleep_notification_handle =
11464 RegisterSuspendResumeNotification_fn (&params, 2);
11465 }
11466}
11467
11468/***********************************************************************
11340 Initialization 11469 Initialization
11341 ***********************************************************************/ 11470 ***********************************************************************/
11342 11471
@@ -11845,6 +11974,10 @@ keys when IME input is received. */);
11845 defsubr (&Sw32_request_user_attention); 11974 defsubr (&Sw32_request_user_attention);
11846 DEFSYM (Qinformational, "informational"); 11975 DEFSYM (Qinformational, "informational");
11847 DEFSYM (Qcritical, "critical"); 11976 DEFSYM (Qcritical, "critical");
11977 /* System sleep support. */
11978 defsubr (&Sw32_unblock_system_sleep);
11979 defsubr (&Sw32_block_system_sleep);
11980 defsubr (&Sw32_system_sleep_block_count);
11848#endif 11981#endif
11849} 11982}
11850 11983
@@ -12105,6 +12238,7 @@ void
12105globals_of_w32fns (void) 12238globals_of_w32fns (void)
12106{ 12239{
12107 HMODULE user32_lib = GetModuleHandle ("user32.dll"); 12240 HMODULE user32_lib = GetModuleHandle ("user32.dll");
12241 HMODULE kernel32_lib = GetModuleHandle ("kernel32.dll");
12108 /* 12242 /*
12109 TrackMouseEvent not available in all versions of Windows, so must load 12243 TrackMouseEvent not available in all versions of Windows, so must load
12110 it dynamically. Do it once, here, instead of every time it is used. 12244 it dynamically. Do it once, here, instead of every time it is used.
@@ -12131,6 +12265,14 @@ globals_of_w32fns (void)
12131 RegisterTouchWindow_fn 12265 RegisterTouchWindow_fn
12132 = (RegisterTouchWindow_proc) get_proc_addr (user32_lib, 12266 = (RegisterTouchWindow_proc) get_proc_addr (user32_lib,
12133 "RegisterTouchWindow"); 12267 "RegisterTouchWindow");
12268 /* For system sleep support. */
12269 SetThreadExecutionState_fn
12270 = (SetThreadExecutionState_Proc)
12271 get_proc_addr (kernel32_lib, "SetThreadExecutionState");
12272 RegisterSuspendResumeNotification_fn
12273 = (RegisterSuspendResumeNotification_Proc)
12274 get_proc_addr (user32_lib, "RegisterSuspendResumeNotification");
12275
12134 SetGestureConfig_fn 12276 SetGestureConfig_fn
12135 = (SetGestureConfig_proc) get_proc_addr (user32_lib, 12277 = (SetGestureConfig_proc) get_proc_addr (user32_lib,
12136 "SetGestureConfig"); 12278 "SetGestureConfig");
diff --git a/src/w32term.c b/src/w32term.c
index 3f451fc552d..6e5c932b2c2 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -8255,6 +8255,7 @@ w32_initialize (void)
8255 } 8255 }
8256 8256
8257 w32_get_mouse_wheel_vertical_delta (); 8257 w32_get_mouse_wheel_vertical_delta ();
8258 w32_register_for_sleep_notifications ();
8258} 8259}
8259 8260
8260void 8261void
diff --git a/src/w32term.h b/src/w32term.h
index 2d2d209016b..505569fd298 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -274,6 +274,7 @@ extern const char *w32_get_string_resource (void *v_rdb,
274extern frame_parm_handler w32_frame_parm_handlers[]; 274extern frame_parm_handler w32_frame_parm_handlers[];
275extern void w32_default_font_parameter (struct frame* f, Lisp_Object parms); 275extern void w32_default_font_parameter (struct frame* f, Lisp_Object parms);
276extern Lisp_Object w32_process_dnd_data (int format, void *pDataObj); 276extern Lisp_Object w32_process_dnd_data (int format, void *pDataObj);
277extern void w32_register_for_sleep_notifications (void);
277 278
278 279
279#define PIX_TYPE COLORREF 280#define PIX_TYPE COLORREF
diff --git a/src/xdisp.c b/src/xdisp.c
index d7db4039afa..90ed743460a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11304,6 +11304,7 @@ move_it_vertically_backward (struct it *it, int dy)
11304 int line_height; 11304 int line_height;
11305 11305
11306 RESTORE_IT (&it3, &it3, it3data); 11306 RESTORE_IT (&it3, &it3, it3data);
11307 last_height = 0;
11307 y1 = line_bottom_y (&it3); 11308 y1 = line_bottom_y (&it3);
11308 line_height = y1 - y0; 11309 line_height = y1 - y0;
11309 RESTORE_IT (it, it, it2data); 11310 RESTORE_IT (it, it, it2data);
@@ -21681,8 +21682,9 @@ try_window_reusing_current_matrix (struct window *w)
21681 return false; 21682 return false;
21682 21683
21683 /* If top-line visibility has changed, give up. */ 21684 /* If top-line visibility has changed, give up. */
21684 if (window_wants_tab_line (w) 21685 if (!w->current_matrix->header_line_p
21685 != MATRIX_TAB_LINE_ROW (w->current_matrix)->mode_line_p) 21686 && (window_wants_tab_line (w)
21687 != MATRIX_TAB_LINE_ROW (w->current_matrix)->mode_line_p))
21686 return false; 21688 return false;
21687 21689
21688 /* If top-line visibility has changed, give up. */ 21690 /* If top-line visibility has changed, give up. */
diff --git a/src/xsettings.c b/src/xsettings.c
index 25edce78841..71cd6a9ad6c 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -187,6 +187,8 @@ store_tool_bar_style_changed (const char *newstyle,
187#ifndef HAVE_PGTK 187#ifndef HAVE_PGTK
188#if defined USE_CAIRO || defined HAVE_XFT 188#if defined USE_CAIRO || defined HAVE_XFT
189#define XSETTINGS_FONT_NAME "Gtk/FontName" 189#define XSETTINGS_FONT_NAME "Gtk/FontName"
190#define XSETTINGS_GDK_DPI_NAME "Gdk/UnscaledDPI"
191#define XSETTINGS_GDK_WSCALE_NAME "Gdk/WindowScalingFactor"
190#endif 192#endif
191#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle" 193#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle"
192#endif 194#endif
@@ -626,6 +628,15 @@ parse_settings (unsigned char *prop,
626 int bytes_parsed = 0; 628 int bytes_parsed = 0;
627 int settings_seen = 0; 629 int settings_seen = 0;
628 int i = 0; 630 int i = 0;
631#if defined USE_CAIRO || defined HAVE_XFT
632 /* Some X environments, e.g. XWayland, communicate DPI changes only
633 through the GDK xsettings values and not the regular Xft one, so
634 recognize both schemes. We want to see both the GDK window scaling
635 factor and the post-scaling DPI so we can compute our desired
636 actual DPI. */
637 int gdk_unscaled_dpi = 0;
638 int gdk_window_scale = 0;
639#endif
629 640
630 /* First 4 bytes is a serial number, skip that. */ 641 /* First 4 bytes is a serial number, skip that. */
631 642
@@ -668,7 +679,9 @@ parse_settings (unsigned char *prop,
668 want_this = strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0; 679 want_this = strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0;
669#if defined USE_CAIRO || defined HAVE_XFT 680#if defined USE_CAIRO || defined HAVE_XFT
670 if ((nlen > 6 && memcmp (name, "Xft/", 4) == 0) 681 if ((nlen > 6 && memcmp (name, "Xft/", 4) == 0)
671 || strcmp (XSETTINGS_FONT_NAME, name) == 0) 682 || strcmp (XSETTINGS_FONT_NAME, name) == 0
683 || strcmp (XSETTINGS_GDK_DPI_NAME, name) == 0
684 || strcmp (XSETTINGS_GDK_WSCALE_NAME, name) == 0)
672 want_this = true; 685 want_this = true;
673#endif 686#endif
674 687
@@ -769,6 +782,10 @@ parse_settings (unsigned char *prop,
769 settings->seen |= SEEN_DPI; 782 settings->seen |= SEEN_DPI;
770 settings->dpi = ival / 1024.0; 783 settings->dpi = ival / 1024.0;
771 } 784 }
785 else if (strcmp (name, XSETTINGS_GDK_DPI_NAME) == 0)
786 gdk_unscaled_dpi = ival;
787 else if (strcmp (name, XSETTINGS_GDK_WSCALE_NAME) == 0)
788 gdk_window_scale = ival;
772 else if (strcmp (name, "Xft/lcdfilter") == 0) 789 else if (strcmp (name, "Xft/lcdfilter") == 0)
773 { 790 {
774 settings->seen |= SEEN_LCDFILTER; 791 settings->seen |= SEEN_LCDFILTER;
@@ -786,6 +803,19 @@ parse_settings (unsigned char *prop,
786 } 803 }
787 } 804 }
788 805
806#if defined USE_CAIRO || defined HAVE_XFT
807 if (gdk_unscaled_dpi > 0 && gdk_window_scale > 0)
808 {
809 /* Override any previous DPI settings. GDK ones are intended to
810 be authoritative.
811 See
812 https://mail.gnome.org/archives/commits-list/2013-June/msg06726.html
813 */
814 settings->seen |= SEEN_DPI;
815 settings->dpi = gdk_window_scale * gdk_unscaled_dpi / 1024.0;
816 }
817#endif
818
789 return settings_seen; 819 return settings_seen;
790} 820}
791#endif 821#endif