aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-09-16 10:49:29 -0700
committerPaul Eggert2011-09-16 10:49:29 -0700
commit2e621251cad236fa94c3ea0b53d8e998bf44f72d (patch)
tree662fbe7f0e68bca0b21a9b197bf9691226e3488d /src
parent064f328a6ac90698c719b6eace60d6f4c90e3f08 (diff)
downloademacs-2e621251cad236fa94c3ea0b53d8e998bf44f72d.tar.gz
emacs-2e621251cad236fa94c3ea0b53d8e998bf44f72d.zip
* xselect.c: Relax test for outgoing X longs (Bug#9498).
(cons_to_x_long): New function. (lisp_data_to_selection_data): Use it. Correct the test for short-versus-long data; it was negated. Break out of vector loop, for efficiency, when a long datum is discovered.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/xselect.c39
2 files changed, 36 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9ce2629d442..0ea45aed1a3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12011-09-16 Paul Eggert <eggert@cs.ucla.edu>
2
3 * xselect.c: Relax test for outgoing X longs (Bug#9498).
4 (cons_to_x_long): New function.
5 (lisp_data_to_selection_data): Use it. Correct the test for
6 short-versus-long data; it was negated. Break out of vector
7 loop, for efficiency, when a long datum is discovered.
8
12011-09-16 Stefan Monnier <monnier@iro.umontreal.ca> 92011-09-16 Stefan Monnier <monnier@iro.umontreal.ca>
2 10
3 * eval.c (Fquote): Document its non-consing behavior (bug#9482). 11 * eval.c (Fquote): Document its non-consing behavior (bug#9482).
diff --git a/src/xselect.c b/src/xselect.c
index 29e8552bb9c..adee1872dba 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -116,6 +116,7 @@ static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions;
116#define X_SHRT_MIN (-1 - X_SHRT_MAX) 116#define X_SHRT_MIN (-1 - X_SHRT_MAX)
117#define X_LONG_MAX 0x7fffffff 117#define X_LONG_MAX 0x7fffffff
118#define X_LONG_MIN (-1 - X_LONG_MAX) 118#define X_LONG_MIN (-1 - X_LONG_MAX)
119#define X_ULONG_MAX 0xffffffffUL
119 120
120/* If this is a smaller number than the max-request-size of the display, 121/* If this is a smaller number than the max-request-size of the display,
121 emacs will use INCR selection transfer when the selection is larger 122 emacs will use INCR selection transfer when the selection is larger
@@ -378,7 +379,8 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
378 379
379/* Given a selection-name and desired type, look up our local copy of 380/* Given a selection-name and desired type, look up our local copy of
380 the selection value and convert it to the type. 381 the selection value and convert it to the type.
381 The value is nil or a string. 382 Return nil, a string, a vector, a symbol, an integer, or a cons
383 that CONS_TO_INTEGER could plausibly handle.
382 This function is used both for remote requests (LOCAL_REQUEST is zero) 384 This function is used both for remote requests (LOCAL_REQUEST is zero)
383 and for local x-get-selection-internal (LOCAL_REQUEST is nonzero). 385 and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
384 386
@@ -1718,6 +1720,21 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
1718 } 1720 }
1719} 1721}
1720 1722
1723/* Convert OBJ to an X long value, and return it as unsigned long.
1724 OBJ should be an integer or a cons representing an integer.
1725 Treat values in the range X_LONG_MAX + 1 .. X_ULONG_MAX as X
1726 unsigned long values: in theory these values are supposed to be
1727 signed but in practice unsigned 32-bit data are communicated via X
1728 selections and we need to support that. */
1729static unsigned long
1730cons_to_x_long (Lisp_Object obj)
1731{
1732 if (X_ULONG_MAX <= INTMAX_MAX
1733 || XINT (INTEGERP (obj) ? obj : XCAR (obj)) < 0)
1734 return cons_to_signed (obj, X_LONG_MIN, min (X_ULONG_MAX, INTMAX_MAX));
1735 else
1736 return cons_to_unsigned (obj, X_ULONG_MAX);
1737}
1721 1738
1722/* Use xfree, not XFree, to free the data obtained with this function. */ 1739/* Use xfree, not XFree, to free the data obtained with this function. */
1723 1740
@@ -1783,11 +1800,11 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
1783 || (CONSP (XCDR (obj)) 1800 || (CONSP (XCDR (obj))
1784 && INTEGERP (XCAR (XCDR (obj))))))) 1801 && INTEGERP (XCAR (XCDR (obj)))))))
1785 { 1802 {
1786 *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); 1803 *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1);
1787 *format_ret = 32; 1804 *format_ret = 32;
1788 *size_ret = 1; 1805 *size_ret = 1;
1789 (*data_ret) [sizeof (long)] = 0; 1806 (*data_ret) [sizeof (unsigned long)] = 0;
1790 (*(long **) data_ret) [0] = cons_to_signed (obj, X_LONG_MIN, X_LONG_MAX); 1807 (*(unsigned long **) data_ret) [0] = cons_to_x_long (obj);
1791 if (NILP (type)) type = QINTEGER; 1808 if (NILP (type)) type = QINTEGER;
1792 } 1809 }
1793 else if (VECTORP (obj)) 1810 else if (VECTORP (obj))
@@ -1822,15 +1839,15 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
1822 if (NILP (type)) type = QINTEGER; 1839 if (NILP (type)) type = QINTEGER;
1823 for (i = 0; i < size; i++) 1840 for (i = 0; i < size; i++)
1824 { 1841 {
1825 intmax_t v = cons_to_signed (XVECTOR (obj)->contents[i], 1842 if (! RANGED_INTEGERP (X_SHRT_MIN, XVECTOR (obj)->contents[i],
1826 X_LONG_MIN, X_LONG_MAX); 1843 X_SHRT_MAX))
1827 if (X_SHRT_MIN <= v && v <= X_SHRT_MAX)
1828 { 1844 {
1829 /* Use sizeof (long) even if it is more than 32 bits. 1845 /* Use sizeof (long) even if it is more than 32 bits.
1830 See comment in x_get_window_property and 1846 See comment in x_get_window_property and
1831 x_fill_property_data. */ 1847 x_fill_property_data. */
1832 data_size = sizeof (long); 1848 data_size = sizeof (long);
1833 format = 32; 1849 format = 32;
1850 break;
1834 } 1851 }
1835 } 1852 }
1836 *data_ret = xnmalloc (size, data_size); 1853 *data_ret = xnmalloc (size, data_size);
@@ -1838,12 +1855,12 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
1838 *size_ret = size; 1855 *size_ret = size;
1839 for (i = 0; i < size; i++) 1856 for (i = 0; i < size; i++)
1840 { 1857 {
1841 long v = cons_to_signed (XVECTOR (obj)->contents[i],
1842 X_LONG_MIN, X_LONG_MAX);
1843 if (format == 32) 1858 if (format == 32)
1844 (*((long **) data_ret)) [i] = v; 1859 (*((unsigned long **) data_ret)) [i] =
1860 cons_to_x_long (XVECTOR (obj)->contents[i]);
1845 else 1861 else
1846 (*((short **) data_ret)) [i] = v; 1862 (*((short **) data_ret)) [i] =
1863 XINT (XVECTOR (obj)->contents[i]);
1847 } 1864 }
1848 } 1865 }
1849 } 1866 }