diff options
| author | Paul Eggert | 2011-09-16 10:49:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-09-16 10:49:29 -0700 |
| commit | 2e621251cad236fa94c3ea0b53d8e998bf44f72d (patch) | |
| tree | 662fbe7f0e68bca0b21a9b197bf9691226e3488d /src | |
| parent | 064f328a6ac90698c719b6eace60d6f4c90e3f08 (diff) | |
| download | emacs-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/ChangeLog | 8 | ||||
| -rw-r--r-- | src/xselect.c | 39 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-09-16 Stefan Monnier <monnier@iro.umontreal.ca> | 9 | 2011-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. */ | ||
| 1729 | static unsigned long | ||
| 1730 | cons_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 | } |