aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2005-02-19 00:06:48 +0000
committerKaroly Lorentey2005-02-19 00:06:48 +0000
commit60c73d2ed638e5d51643c65a0fc6dea618fc72c8 (patch)
tree3d9e0adc703f9cfd5df162c66ac15999c4106738 /src
parentc20213c90736fc9c2a6eca2ca44d6e200dbf5efe (diff)
parent8a59305430c68ee23d3cc7ab7487ab3acebdbe7f (diff)
downloademacs-60c73d2ed638e5d51643c65a0fc6dea618fc72c8.tar.gz
emacs-60c73d2ed638e5d51643c65a0fc6dea618fc72c8.zip
Merged from miles@gnu.org--gnu-2005 (patch 14-16, 95-106)
Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-95 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-96 Move Gnus images into etc/images * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-97 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-98 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-99 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-100 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-101 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-102 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-103 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-104 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-105 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-106 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-14 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-15 Update from CVS: lisp/imap.el (imap-log): Doc fix. * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-16 Merge from emacs--cvs-trunk--0 git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-295
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog113
-rw-r--r--src/coding.c43
-rw-r--r--src/data.c4
-rw-r--r--src/dispextern.h15
-rw-r--r--src/doc.c11
-rw-r--r--src/emacs.c3
-rw-r--r--src/keyboard.c2
-rw-r--r--src/keymap.c80
-rw-r--r--src/keymap.h2
-rw-r--r--src/lread.c4
-rw-r--r--src/s/ms-w32.h2
-rw-r--r--src/w32.c2
-rw-r--r--src/w32.h22
-rw-r--r--src/w32select.c1095
-rw-r--r--src/xdisp.c149
-rw-r--r--src/xfns.c44
-rw-r--r--src/xselect.c20
-rw-r--r--src/xterm.c111
18 files changed, 1275 insertions, 447 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c6ab6985ed0..400946fb4d0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,116 @@
12005-02-17 Andreas Schwab <schwab@suse.de>
2
3 * xfns.c (hack_wm_protocols): Use correct type for last parameter
4 of XGetWindowProperty to avoid aliasing issues.
5 (Fx_window_property): Likewise.
6
7 * xselect.c (Fx_disown_selection_internal): Use union of struct
8 input_event and struct selection_input_event to avoid aliasing
9 issues.
10
11 * xterm.c (handle_one_xevent): Use union of struct input_event and
12 struct selection_input_event to avoid aliasing issues.
13 (SET_SAVED_MENU_EVENT): Adapt reference to inev.
14
152005-02-17 Kim F. Storm <storm@cua.dk>
16
17 * dispextern.h (enum it_method): New enum.
18 (GET_FROM_*): Its members.
19 (struct it): Change member method from function pointer to enum.
20
21 * xdisp.c (check_it, init_from_display_pos, handle_stop)
22 (setup_for_ellipsis, handle_single_display_spec)
23 (handle_composition_prop, next_overlay_string)
24 (get_overlay_strings, reseat_1, reseat_to_string)
25 (next_element_from_ellipsis, BUFFER_POS_REACHED_P)
26 (in_display_vector_p, display_line, get_next_display_element):
27 Change it->method from function pointer to enum.
28 (get_next_element): New array to map it->method to function.
29 (get_next_display_element): Use it.
30 (set_iterator_to_next): Use switch instead of if/else chain.
31
322005-02-15 Benjamin Riefenstahl <Benjamin.Riefenstahl@epost.de>
33
34 * w32select.c: Summary: Thorough rework to implement Unicode
35 clipboard operations and delayed rendering.
36
37 Drop last_clipboard_text and related code, keep track of
38 ownership via clipboard_owner instead. Drop old #if0
39 sections.
40
41 (DEFAULT_LCID, ANSICP, OEMCP, QUNICODE, QANSICP, QOEMCP)
42 (clipboard_owner, modifying_clipboard, cfg_coding_system)
43 (cfg_codepage, cfg_lcid, cfg_clipboard_type, current_text)
44 (current_coding_system, current_requires_encoding)
45 (current_num_nls, current_clipboard_type, current_lcid): New
46 static variables.
47
48 (convert_to_handle_as_ascii, convert_to_handle_as_coded)
49 (render, render_all, run_protected, lisp_error_handler)
50 (owner_callback, create_owner, setup_config)
51 (enum_locale_callback, cp_from_locale, coding_from_cp): New
52 local functions.
53
54 (term_w32select, globals_of_w32select): New global functions.
55
56 (Fw32_set_clipboard_data): Ignore parameter FRAME, use
57 clipboard_owner instead. Use delayed rendering and provide
58 all text formats. Provide CF_LOCALE if necessary.
59
60 (Fw32_get_clipboard_data): Handle CF_UNICODETEXT and
61 CF_LOCALE. Fall back to CF_TEXT, if CF_UNICODETEXT is not
62 available. Force DOS line-ends for decoding.
63
64 (Fx_selection_exists_p): Handle CF_UNICODETEXT.
65
66 (syms_of_w32select): Init and register new variables.
67
68 * w32.h: Add prototypes for globals_of_w32select and
69 term_w32select. Make the neighboring K&R declarations into
70 prototypes, too.
71
72 * emacs.c: Include w32.h to get function prototypes.
73 (main): Call globals_of_w32select.
74
75 * w32.c (term_ntproc): Call term_w32select.
76
77 * s/ms-w32.h: Guard MSC-specific #pragmas with an #ifdef.
78
792005-02-16 Kim F. Storm <storm@cua.dk>
80
81 * xdisp.c (BUFFER_POS_REACHED_P): Return true if pos reached and
82 at end of display vector.
83
842005-02-15 Richard M. Stallman <rms@gnu.org>
85
86 * xdisp.c (get_next_display_element): Fix escape-glyph criterion
87 for mode and header lines.
88
89 * lread.c (syms_of_lread) <user-init-file>: Doc fix.
90
91 * keymap.h (describe_map_tree): Change decl.
92
93 * keyboard.c (command_loop_1): Always use safe_run_hooks
94 to run Qdeferred_action_function.
95
96 * keymap.c (describe_map_tree): New arg MENTION_SHADOW. Calls changed.
97 (describe_map, describe_vector): Likewise. When it's 1,
98 don't omit shadowed bindings, instead mark them as shadowed.
99
100 * doc.c (Fsubstitute_command_keys): Compute list of shadowing maps
101 for describe_map_tree. Pass 1 for MENTION_SHADOW.
102
103 * data.c (Fsetq_default): Allow no arg case.
104
1052005-02-14 Kenichi Handa <handa@m17n.org>
106
107 * coding.c (encode_coding_string): Always return a unibyte string.
108 If NOCOPY is nonzero and there's no need of encoding, make STR
109 unibyte directly.
110
111 * xselect.c (lisp_data_to_selection_data): If OBJ is a non-ASCII
112 multibyte string, signal an error instead of aborting.
113
12005-02-12 Dan Nicolaescu <dann@ics.uci.edu> 1142005-02-12 Dan Nicolaescu <dann@ics.uci.edu>
2 115
3 * keyboard.c: If HAVE_FCNTL_H include fcntl.h. 116 * keyboard.c: If HAVE_FCNTL_H include fcntl.h.
diff --git a/src/coding.c b/src/coding.c
index 11a7061c837..9cd493ab062 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -6357,7 +6357,12 @@ encode_coding_string (str, coding, nocopy)
6357 6357
6358 if (SYMBOLP (coding->pre_write_conversion) 6358 if (SYMBOLP (coding->pre_write_conversion)
6359 && !NILP (Ffboundp (coding->pre_write_conversion))) 6359 && !NILP (Ffboundp (coding->pre_write_conversion)))
6360 str = run_pre_post_conversion_on_str (str, coding, 1); 6360 {
6361 str = run_pre_post_conversion_on_str (str, coding, 1);
6362 /* As STR is just newly generated, we don't have to copy it
6363 anymore. */
6364 nocopy = 1;
6365 }
6361 6366
6362 from = 0; 6367 from = 0;
6363 to = SCHARS (str); 6368 to = SCHARS (str);
@@ -6365,21 +6370,10 @@ encode_coding_string (str, coding, nocopy)
6365 6370
6366 /* Encoding routines determine the multibyteness of the source text 6371 /* Encoding routines determine the multibyteness of the source text
6367 by coding->src_multibyte. */ 6372 by coding->src_multibyte. */
6368 coding->src_multibyte = STRING_MULTIBYTE (str); 6373 coding->src_multibyte = SCHARS (str) < SBYTES (str);
6369 coding->dst_multibyte = 0; 6374 coding->dst_multibyte = 0;
6370 if (! CODING_REQUIRE_ENCODING (coding)) 6375 if (! CODING_REQUIRE_ENCODING (coding))
6371 { 6376 goto no_need_of_encoding;
6372 coding->consumed = SBYTES (str);
6373 coding->consumed_char = SCHARS (str);
6374 if (STRING_MULTIBYTE (str))
6375 {
6376 str = Fstring_as_unibyte (str);
6377 nocopy = 1;
6378 }
6379 coding->produced = SBYTES (str);
6380 coding->produced_char = SCHARS (str);
6381 return (nocopy ? str : Fcopy_sequence (str));
6382 }
6383 6377
6384 if (coding->composing != COMPOSITION_DISABLED) 6378 if (coding->composing != COMPOSITION_DISABLED)
6385 coding_save_composition (coding, from, to, str); 6379 coding_save_composition (coding, from, to, str);
@@ -6395,7 +6389,7 @@ encode_coding_string (str, coding, nocopy)
6395 if (from == to_byte) 6389 if (from == to_byte)
6396 { 6390 {
6397 coding_free_composition_data (coding); 6391 coding_free_composition_data (coding);
6398 return (nocopy ? str : Fcopy_sequence (str)); 6392 goto no_need_of_encoding;
6399 } 6393 }
6400 shrinked_bytes = from + (SBYTES (str) - to_byte); 6394 shrinked_bytes = from + (SBYTES (str) - to_byte);
6401 } 6395 }
@@ -6440,6 +6434,25 @@ encode_coding_string (str, coding, nocopy)
6440 coding_free_composition_data (coding); 6434 coding_free_composition_data (coding);
6441 6435
6442 return newstr; 6436 return newstr;
6437
6438 no_need_of_encoding:
6439 coding->consumed = SBYTES (str);
6440 coding->consumed_char = SCHARS (str);
6441 if (STRING_MULTIBYTE (str))
6442 {
6443 if (nocopy)
6444 /* We are sure that STR doesn't contain a multibyte
6445 character. */
6446 STRING_SET_UNIBYTE (str);
6447 else
6448 {
6449 str = Fstring_as_unibyte (str);
6450 nocopy = 1;
6451 }
6452 }
6453 coding->produced = SBYTES (str);
6454 coding->produced_char = SCHARS (str);
6455 return (nocopy ? str : Fcopy_sequence (str));
6443} 6456}
6444 6457
6445 6458
diff --git a/src/data.c b/src/data.c
index be1e4d33bbb..25691a4678b 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1458,7 +1458,7 @@ for this variable. */)
1458 return value; 1458 return value;
1459} 1459}
1460 1460
1461DEFUN ("setq-default", Fsetq_default, Ssetq_default, 2, UNEVALLED, 0, 1461DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0,
1462 doc: /* Set the default value of variable VAR to VALUE. 1462 doc: /* Set the default value of variable VAR to VALUE.
1463VAR, the variable name, is literal (not evaluated); 1463VAR, the variable name, is literal (not evaluated);
1464VALUE is an expression: it is evaluated and its value returned. 1464VALUE is an expression: it is evaluated and its value returned.
@@ -1470,7 +1470,7 @@ More generally, you can use multiple variables and values, as in
1470This sets each VAR's default value to the corresponding VALUE. 1470This sets each VAR's default value to the corresponding VALUE.
1471The VALUE for the Nth VAR can refer to the new default values 1471The VALUE for the Nth VAR can refer to the new default values
1472of previous VARs. 1472of previous VARs.
1473usage: (setq-default VAR VALUE [VAR VALUE...]) */) 1473usage: (setq-default [VAR VALUE...]) */)
1474 (args) 1474 (args)
1475 Lisp_Object args; 1475 Lisp_Object args;
1476{ 1476{
diff --git a/src/dispextern.h b/src/dispextern.h
index 84fff3f0b09..77dba7bb09e 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1781,6 +1781,16 @@ struct it_slice
1781 Lisp_Object height; 1781 Lisp_Object height;
1782}; 1782};
1783 1783
1784enum it_method {
1785 GET_FROM_BUFFER = 0,
1786 GET_FROM_DISPLAY_VECTOR,
1787 GET_FROM_COMPOSITION,
1788 GET_FROM_STRING,
1789 GET_FROM_C_STRING,
1790 GET_FROM_IMAGE,
1791 GET_FROM_STRETCH,
1792 NUM_IT_METHODS
1793};
1784 1794
1785struct it 1795struct it
1786{ 1796{
@@ -1791,9 +1801,8 @@ struct it
1791 /* The window's frame. */ 1801 /* The window's frame. */
1792 struct frame *f; 1802 struct frame *f;
1793 1803
1794 /* Function to call to load this structure with the next display 1804 /* Method to use to load this structure with the next display element. */
1795 element. */ 1805 enum it_method method;
1796 int (* method) P_ ((struct it *it));
1797 1806
1798 /* The next position at which to check for face changes, invisible 1807 /* The next position at which to check for face changes, invisible
1799 text, overlay strings, end of text etc., which see. */ 1808 text, overlay strings, end of text etc., which see. */
diff --git a/src/doc.c b/src/doc.c
index f306caed36a..0d1ab394647 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -882,6 +882,9 @@ thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ int
882 { 882 {
883 struct buffer *oldbuf; 883 struct buffer *oldbuf;
884 int start_idx; 884 int start_idx;
885 /* This is for computing the SHADOWS arg for describe_map_tree. */
886 Lisp_Object active_maps = Fcurrent_active_maps (Qnil);
887 Lisp_Object earlier_maps;
885 888
886 changed = 1; 889 changed = 1;
887 strp += 2; /* skip \{ or \< */ 890 strp += 2; /* skip \{ or \< */
@@ -932,7 +935,13 @@ thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ int
932 else if (start[-1] == '<') 935 else if (start[-1] == '<')
933 keymap = tem; 936 keymap = tem;
934 else 937 else
935 describe_map_tree (tem, 1, Qnil, Qnil, (char *)0, 1, 0, 0); 938 {
939 /* Get the list of active keymaps that precede this one.
940 If this one's not active, get nil. */
941 earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps)));
942 describe_map_tree (tem, 1, Fnreverse (earlier_maps),
943 Qnil, (char *)0, 1, 0, 0, 1);
944 }
936 tem = Fbuffer_string (); 945 tem = Fbuffer_string ();
937 Ferase_buffer (); 946 Ferase_buffer ();
938 set_buffer_internal (oldbuf); 947 set_buffer_internal (oldbuf);
diff --git a/src/emacs.c b/src/emacs.c
index d5ae652d6ee..159a162d649 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -42,6 +42,8 @@ Boston, MA 02111-1307, USA. */
42 42
43#ifdef WINDOWSNT 43#ifdef WINDOWSNT
44#include <fcntl.h> 44#include <fcntl.h>
45#include <windows.h> /* just for w32.h */
46#include "w32.h"
45#endif 47#endif
46 48
47#include "lisp.h" 49#include "lisp.h"
@@ -1655,6 +1657,7 @@ main (argc, argv
1655#ifdef HAVE_NTGUI 1657#ifdef HAVE_NTGUI
1656 globals_of_w32fns (); 1658 globals_of_w32fns ();
1657 globals_of_w32menu (); 1659 globals_of_w32menu ();
1660 globals_of_w32select ();
1658#endif /* HAVE_NTGUI */ 1661#endif /* HAVE_NTGUI */
1659 } 1662 }
1660 1663
diff --git a/src/keyboard.c b/src/keyboard.c
index f3245a59669..42255dfbd91 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1427,7 +1427,7 @@ command_loop_1 ()
1427 resize_echo_area_exactly (); 1427 resize_echo_area_exactly ();
1428 1428
1429 if (!NILP (Vdeferred_action_list)) 1429 if (!NILP (Vdeferred_action_list))
1430 call0 (Vdeferred_action_function); 1430 safe_run_hooks (Qdeferred_action_function);
1431 1431
1432 if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks)) 1432 if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
1433 { 1433 {
diff --git a/src/keymap.c b/src/keymap.c
index f28032d0f82..a55563a4e92 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -121,10 +121,11 @@ static void describe_command P_ ((Lisp_Object, Lisp_Object));
121static void describe_translation P_ ((Lisp_Object, Lisp_Object)); 121static void describe_translation P_ ((Lisp_Object, Lisp_Object));
122static void describe_map P_ ((Lisp_Object, Lisp_Object, 122static void describe_map P_ ((Lisp_Object, Lisp_Object,
123 void (*) P_ ((Lisp_Object, Lisp_Object)), 123 void (*) P_ ((Lisp_Object, Lisp_Object)),
124 int, Lisp_Object, Lisp_Object*, int)); 124 int, Lisp_Object, Lisp_Object*, int, int));
125static void describe_vector P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 125static void describe_vector P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
126 void (*) (Lisp_Object, Lisp_Object), int, 126 void (*) (Lisp_Object, Lisp_Object), int,
127 Lisp_Object, Lisp_Object, int *, int, int)); 127 Lisp_Object, Lisp_Object, int *,
128 int, int, int));
128static void silly_event_symbol_error P_ ((Lisp_Object)); 129static void silly_event_symbol_error P_ ((Lisp_Object));
129 130
130/* Keymap object support - constructors and predicates. */ 131/* Keymap object support - constructors and predicates. */
@@ -2835,7 +2836,7 @@ You type Translation\n\
2835 2836
2836 if (!NILP (Vkey_translation_map)) 2837 if (!NILP (Vkey_translation_map))
2837 describe_map_tree (Vkey_translation_map, 0, Qnil, prefix, 2838 describe_map_tree (Vkey_translation_map, 0, Qnil, prefix,
2838 "Key translations", nomenu, 1, 0); 2839 "Key translations", nomenu, 1, 0, 0);
2839 2840
2840 2841
2841 /* Print the (major mode) local map. */ 2842 /* Print the (major mode) local map. */
@@ -2848,7 +2849,7 @@ You type Translation\n\
2848 if (!NILP (start1)) 2849 if (!NILP (start1))
2849 { 2850 {
2850 describe_map_tree (start1, 1, shadow, prefix, 2851 describe_map_tree (start1, 1, shadow, prefix,
2851 "\f\nOverriding Bindings", nomenu, 0, 0); 2852 "\f\nOverriding Bindings", nomenu, 0, 0, 0);
2852 shadow = Fcons (start1, shadow); 2853 shadow = Fcons (start1, shadow);
2853 } 2854 }
2854 else 2855 else
@@ -2869,7 +2870,8 @@ You type Translation\n\
2869 if (!NILP (start1)) 2870 if (!NILP (start1))
2870 { 2871 {
2871 describe_map_tree (start1, 1, shadow, prefix, 2872 describe_map_tree (start1, 1, shadow, prefix,
2872 "\f\n`keymap' Property Bindings", nomenu, 0, 0); 2873 "\f\n`keymap' Property Bindings", nomenu,
2874 0, 0, 0);
2873 shadow = Fcons (start1, shadow); 2875 shadow = Fcons (start1, shadow);
2874 } 2876 }
2875 2877
@@ -2897,7 +2899,8 @@ You type Translation\n\
2897 p += sizeof (" Minor Mode Bindings") - 1; 2899 p += sizeof (" Minor Mode Bindings") - 1;
2898 *p = 0; 2900 *p = 0;
2899 2901
2900 describe_map_tree (maps[i], 1, shadow, prefix, title, nomenu, 0, 0); 2902 describe_map_tree (maps[i], 1, shadow, prefix,
2903 title, nomenu, 0, 0, 0);
2901 shadow = Fcons (maps[i], shadow); 2904 shadow = Fcons (maps[i], shadow);
2902 } 2905 }
2903 2906
@@ -2907,23 +2910,23 @@ You type Translation\n\
2907 { 2910 {
2908 if (EQ (start1, XBUFFER (buffer)->keymap)) 2911 if (EQ (start1, XBUFFER (buffer)->keymap))
2909 describe_map_tree (start1, 1, shadow, prefix, 2912 describe_map_tree (start1, 1, shadow, prefix,
2910 "\f\nMajor Mode Bindings", nomenu, 0, 0); 2913 "\f\nMajor Mode Bindings", nomenu, 0, 0, 0);
2911 else 2914 else
2912 describe_map_tree (start1, 1, shadow, prefix, 2915 describe_map_tree (start1, 1, shadow, prefix,
2913 "\f\n`local-map' Property Bindings", 2916 "\f\n`local-map' Property Bindings",
2914 nomenu, 0, 0); 2917 nomenu, 0, 0, 0);
2915 2918
2916 shadow = Fcons (start1, shadow); 2919 shadow = Fcons (start1, shadow);
2917 } 2920 }
2918 } 2921 }
2919 2922
2920 describe_map_tree (current_global_map, 1, shadow, prefix, 2923 describe_map_tree (current_global_map, 1, shadow, prefix,
2921 "\f\nGlobal Bindings", nomenu, 0, 1); 2924 "\f\nGlobal Bindings", nomenu, 0, 1, 0);
2922 2925
2923 /* Print the function-key-map translations under this prefix. */ 2926 /* Print the function-key-map translations under this prefix. */
2924 if (!NILP (Vfunction_key_map)) 2927 if (!NILP (Vfunction_key_map))
2925 describe_map_tree (Vfunction_key_map, 0, Qnil, prefix, 2928 describe_map_tree (Vfunction_key_map, 0, Qnil, prefix,
2926 "\f\nFunction key map translations", nomenu, 1, 0); 2929 "\f\nFunction key map translations", nomenu, 1, 0, 0);
2927 2930
2928 UNGCPRO; 2931 UNGCPRO;
2929 return Qnil; 2932 return Qnil;
@@ -2944,17 +2947,21 @@ You type Translation\n\
2944 so print strings and vectors differently. 2947 so print strings and vectors differently.
2945 2948
2946 If ALWAYS_TITLE is nonzero, print the title even if there are no maps 2949 If ALWAYS_TITLE is nonzero, print the title even if there are no maps
2947 to look through. */ 2950 to look through.
2951
2952 If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW,
2953 don't omit it; instead, mention it but say it is shadowed. */
2948 2954
2949void 2955void
2950describe_map_tree (startmap, partial, shadow, prefix, title, nomenu, transl, 2956describe_map_tree (startmap, partial, shadow, prefix, title, nomenu, transl,
2951 always_title) 2957 always_title, mention_shadow)
2952 Lisp_Object startmap, shadow, prefix; 2958 Lisp_Object startmap, shadow, prefix;
2953 int partial; 2959 int partial;
2954 char *title; 2960 char *title;
2955 int nomenu; 2961 int nomenu;
2956 int transl; 2962 int transl;
2957 int always_title; 2963 int always_title;
2964 int mention_shadow;
2958{ 2965{
2959 Lisp_Object maps, orig_maps, seen, sub_shadows; 2966 Lisp_Object maps, orig_maps, seen, sub_shadows;
2960 struct gcpro gcpro1, gcpro2, gcpro3; 2967 struct gcpro gcpro1, gcpro2, gcpro3;
@@ -3056,7 +3063,7 @@ key binding\n\
3056 3063
3057 describe_map (Fcdr (elt), prefix, 3064 describe_map (Fcdr (elt), prefix,
3058 transl ? describe_translation : describe_command, 3065 transl ? describe_translation : describe_command,
3059 partial, sub_shadows, &seen, nomenu); 3066 partial, sub_shadows, &seen, nomenu, mention_shadow);
3060 3067
3061 skip: ; 3068 skip: ;
3062 } 3069 }
@@ -3136,7 +3143,8 @@ describe_translation (definition, args)
3136 PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ 3143 PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */
3137 3144
3138static void 3145static void
3139describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu) 3146describe_map (map, prefix, elt_describer, partial, shadow,
3147 seen, nomenu, mention_shadow)
3140 register Lisp_Object map; 3148 register Lisp_Object map;
3141 Lisp_Object prefix; 3149 Lisp_Object prefix;
3142 void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); 3150 void (*elt_describer) P_ ((Lisp_Object, Lisp_Object));
@@ -3144,6 +3152,7 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu)
3144 Lisp_Object shadow; 3152 Lisp_Object shadow;
3145 Lisp_Object *seen; 3153 Lisp_Object *seen;
3146 int nomenu; 3154 int nomenu;
3155 int mention_shadow;
3147{ 3156{
3148 Lisp_Object tail, definition, event; 3157 Lisp_Object tail, definition, event;
3149 Lisp_Object tem; 3158 Lisp_Object tem;
@@ -3173,9 +3182,10 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu)
3173 || CHAR_TABLE_P (XCAR (tail))) 3182 || CHAR_TABLE_P (XCAR (tail)))
3174 describe_vector (XCAR (tail), 3183 describe_vector (XCAR (tail),
3175 prefix, Qnil, elt_describer, partial, shadow, map, 3184 prefix, Qnil, elt_describer, partial, shadow, map,
3176 (int *)0, 0, 1); 3185 (int *)0, 0, 1, mention_shadow);
3177 else if (CONSP (XCAR (tail))) 3186 else if (CONSP (XCAR (tail)))
3178 { 3187 {
3188 int this_shadowed = 0;
3179 event = XCAR (XCAR (tail)); 3189 event = XCAR (XCAR (tail));
3180 3190
3181 /* Ignore bindings whose "prefix" are not really valid events. 3191 /* Ignore bindings whose "prefix" are not really valid events.
@@ -3204,7 +3214,13 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu)
3204 if (!NILP (shadow)) 3214 if (!NILP (shadow))
3205 { 3215 {
3206 tem = shadow_lookup (shadow, kludge, Qt); 3216 tem = shadow_lookup (shadow, kludge, Qt);
3207 if (!NILP (tem)) continue; 3217 if (!NILP (tem))
3218 {
3219 if (mention_shadow)
3220 this_shadowed = 1;
3221 else
3222 continue;
3223 }
3208 } 3224 }
3209 3225
3210 tem = Flookup_key (map, kludge, Qt); 3226 tem = Flookup_key (map, kludge, Qt);
@@ -3224,6 +3240,13 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu)
3224 elt_describer will take care of spacing out far enough 3240 elt_describer will take care of spacing out far enough
3225 for alignment purposes. */ 3241 for alignment purposes. */
3226 (*elt_describer) (definition, Qnil); 3242 (*elt_describer) (definition, Qnil);
3243
3244 if (this_shadowed)
3245 {
3246 SET_PT (PT - 1);
3247 insert_string (" (binding currently shadowed)");
3248 SET_PT (PT + 1);
3249 }
3227 } 3250 }
3228 else if (EQ (XCAR (tail), Qkeymap)) 3251 else if (EQ (XCAR (tail), Qkeymap))
3229 { 3252 {
@@ -3262,7 +3285,7 @@ DESCRIBER is the output function used; nil means use `princ'. */)
3262 specbind (Qstandard_output, Fcurrent_buffer ()); 3285 specbind (Qstandard_output, Fcurrent_buffer ());
3263 CHECK_VECTOR_OR_CHAR_TABLE (vector); 3286 CHECK_VECTOR_OR_CHAR_TABLE (vector);
3264 describe_vector (vector, Qnil, describer, describe_vector_princ, 0, 3287 describe_vector (vector, Qnil, describer, describe_vector_princ, 0,
3265 Qnil, Qnil, (int *)0, 0, 0); 3288 Qnil, Qnil, (int *)0, 0, 0, 0);
3266 3289
3267 return unbind_to (count, Qnil); 3290 return unbind_to (count, Qnil);
3268} 3291}
@@ -3304,7 +3327,8 @@ DESCRIBER is the output function used; nil means use `princ'. */)
3304static void 3327static void
3305describe_vector (vector, prefix, args, elt_describer, 3328describe_vector (vector, prefix, args, elt_describer,
3306 partial, shadow, entire_map, 3329 partial, shadow, entire_map,
3307 indices, char_table_depth, keymap_p) 3330 indices, char_table_depth, keymap_p,
3331 mention_shadow)
3308 register Lisp_Object vector; 3332 register Lisp_Object vector;
3309 Lisp_Object prefix, args; 3333 Lisp_Object prefix, args;
3310 void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); 3334 void (*elt_describer) P_ ((Lisp_Object, Lisp_Object));
@@ -3314,6 +3338,7 @@ describe_vector (vector, prefix, args, elt_describer,
3314 int *indices; 3338 int *indices;
3315 int char_table_depth; 3339 int char_table_depth;
3316 int keymap_p; 3340 int keymap_p;
3341 int mention_shadow;
3317{ 3342{
3318 Lisp_Object definition; 3343 Lisp_Object definition;
3319 Lisp_Object tem2; 3344 Lisp_Object tem2;
@@ -3397,6 +3422,7 @@ describe_vector (vector, prefix, args, elt_describer,
3397 3422
3398 for (i = from; i < to; i++) 3423 for (i = from; i < to; i++)
3399 { 3424 {
3425 int this_shadowed = 0;
3400 QUIT; 3426 QUIT;
3401 3427
3402 if (CHAR_TABLE_P (vector)) 3428 if (CHAR_TABLE_P (vector))
@@ -3456,7 +3482,13 @@ describe_vector (vector, prefix, args, elt_describer,
3456 3482
3457 tem = shadow_lookup (shadow, kludge, Qt); 3483 tem = shadow_lookup (shadow, kludge, Qt);
3458 3484
3459 if (!NILP (tem)) continue; 3485 if (!NILP (tem))
3486 {
3487 if (mention_shadow)
3488 this_shadowed = 1;
3489 else
3490 continue;
3491 }
3460 } 3492 }
3461 3493
3462 /* Ignore this definition if it is shadowed by an earlier 3494 /* Ignore this definition if it is shadowed by an earlier
@@ -3532,7 +3564,8 @@ describe_vector (vector, prefix, args, elt_describer,
3532 insert ("\n", 1); 3564 insert ("\n", 1);
3533 describe_vector (definition, prefix, args, elt_describer, 3565 describe_vector (definition, prefix, args, elt_describer,
3534 partial, shadow, entire_map, 3566 partial, shadow, entire_map,
3535 indices, char_table_depth + 1, keymap_p); 3567 indices, char_table_depth + 1, keymap_p,
3568 mention_shadow);
3536 continue; 3569 continue;
3537 } 3570 }
3538 3571
@@ -3606,6 +3639,13 @@ describe_vector (vector, prefix, args, elt_describer,
3606 elt_describer will take care of spacing out far enough 3639 elt_describer will take care of spacing out far enough
3607 for alignment purposes. */ 3640 for alignment purposes. */
3608 (*elt_describer) (definition, args); 3641 (*elt_describer) (definition, args);
3642
3643 if (this_shadowed)
3644 {
3645 SET_PT (PT - 1);
3646 insert_string (" (binding currently shadowed)");
3647 SET_PT (PT + 1);
3648 }
3609 } 3649 }
3610 3650
3611 /* For (sub) char-table, print `defalt' slot at last. */ 3651 /* For (sub) char-table, print `defalt' slot at last. */
diff --git a/src/keymap.h b/src/keymap.h
index 214ba605c76..e50a62c8aa5 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -37,7 +37,7 @@ extern Lisp_Object access_keymap P_ ((Lisp_Object, Lisp_Object, int, int, int));
37extern Lisp_Object get_keyelt P_ ((Lisp_Object, int)); 37extern Lisp_Object get_keyelt P_ ((Lisp_Object, int));
38extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int)); 38extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int));
39extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object, 39extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object,
40 char *, int, int, int)); 40 char *, int, int, int, int));
41extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **)); 41extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **));
42extern void initial_define_key P_ ((Lisp_Object, int, char *)); 42extern void initial_define_key P_ ((Lisp_Object, int, char *));
43extern void initial_define_lispy_key P_ ((Lisp_Object, char *, char *)); 43extern void initial_define_lispy_key P_ ((Lisp_Object, char *, char *));
diff --git a/src/lread.c b/src/lread.c
index 42531149286..5b5ea478a16 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3861,8 +3861,8 @@ as a function. */);
3861 3861
3862 DEFVAR_LISP ("user-init-file", &Vuser_init_file, 3862 DEFVAR_LISP ("user-init-file", &Vuser_init_file,
3863 doc: /* File name, including directory, of user's initialization file. 3863 doc: /* File name, including directory, of user's initialization file.
3864If the file loaded had extension `.elc' and there was a corresponding `.el' 3864If the file loaded had extension `.elc', and the corresponding source file
3865file, this variable contains the name of the .el file, suitable for use 3865exists, this variable contains the name of source file, suitable for use
3866by functions like `custom-save-all' which edit the init file. */); 3866by functions like `custom-save-all' which edit the init file. */);
3867 Vuser_init_file = Qnil; 3867 Vuser_init_file = Qnil;
3868 3868
diff --git a/src/s/ms-w32.h b/src/s/ms-w32.h
index 09d31ed2e04..503c8547c69 100644
--- a/src/s/ms-w32.h
+++ b/src/s/ms-w32.h
@@ -477,8 +477,10 @@ extern char *get_emacs_configuration_options (void);
477 must include config.h to pick up this pragma. */ 477 must include config.h to pick up this pragma. */
478 478
479/* Names must be < 8 bytes */ 479/* Names must be < 8 bytes */
480#ifdef _MSC_VER
480#pragma data_seg("EMDATA") 481#pragma data_seg("EMDATA")
481#pragma bss_seg("EMBSS") 482#pragma bss_seg("EMBSS")
483#endif
482 484
483/* #define FULL_DEBUG */ 485/* #define FULL_DEBUG */
484/* #define EMACSDEBUG */ 486/* #define EMACSDEBUG */
diff --git a/src/w32.c b/src/w32.c
index 7b54924d736..cdc41a8c772 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -3884,6 +3884,8 @@ term_ntproc ()
3884 /* shutdown the socket interface if necessary */ 3884 /* shutdown the socket interface if necessary */
3885 term_winsock (); 3885 term_winsock ();
3886#endif 3886#endif
3887
3888 term_w32select ();
3887} 3889}
3888 3890
3889void 3891void
diff --git a/src/w32.h b/src/w32.h
index cce1f094363..79a78a5a544 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -122,16 +122,18 @@ extern void reset_standard_handles (int in, int out,
122/* Return the string resource associated with KEY of type TYPE. */ 122/* Return the string resource associated with KEY of type TYPE. */
123extern LPBYTE w32_get_resource (char * key, LPDWORD type); 123extern LPBYTE w32_get_resource (char * key, LPDWORD type);
124 124
125extern void init_ntproc (); 125extern void init_ntproc (void);
126extern void term_ntproc (); 126extern void term_ntproc (void);
127extern void globals_of_w32 (); 127extern void globals_of_w32 (void);
128extern void syms_of_w32term (); 128extern void syms_of_w32term (void);
129extern void syms_of_w32fns (); 129extern void syms_of_w32fns (void);
130extern void globals_of_w32fns (); 130extern void globals_of_w32fns (void);
131extern void syms_of_w32select (); 131extern void syms_of_w32select (void);
132extern void syms_of_w32menu (); 132extern void globals_of_w32select (void);
133extern void globals_of_w32menu (); 133extern void term_w32select (void);
134extern void syms_of_fontset (); 134extern void syms_of_w32menu (void);
135extern void globals_of_w32menu (void);
136extern void syms_of_fontset (void);
135 137
136#endif /* EMACS_W32_H */ 138#endif /* EMACS_W32_H */
137 139
diff --git a/src/w32select.c b/src/w32select.c
index 20f7cfc457f..e562dc7efbb 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -1,5 +1,5 @@
1/* Selection processing for Emacs on the Microsoft W32 API. 1/* Selection processing for Emacs on the Microsoft W32 API.
2 Copyright (C) 1993, 1994 Free Software Foundation. 2 Copyright (C) 1993, 1994, 2004 Free Software Foundation.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -18,273 +18,744 @@ along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */ 19Boston, MA 02111-1307, USA. */
20 20
21/* Written by Kevin Gallo */ 21/* Written by Kevin Gallo, Benjamin Riefenstahl */
22 22
23
24/*
25 * Notes on usage of selection-coding-system and
26 * next-selection-coding-system on MS Windows:
27 *
28 * The selection coding system variables apply only to the version of
29 * the clipboard data that is closest in type, i.e. when a 16-bit
30 * Unicode coding system is given, they apply to he Unicode clipboard
31 * (CF_UNICODETEXT), when a well-known console codepage is given, they
32 * apply to the console version of the clipboard data (CF_OEMTEXT),
33 * else they apply to the normal 8-bit text clipboard (CF_TEXT).
34 *
35 * When pasting (getting data from the OS), the clipboard format that
36 * matches the {next-}selection-coding-system is retrieved. If
37 * Unicode is requested, but not available, 8-bit text (CF_TEXT) is
38 * used. In all other cases the OS will transparently convert
39 * formats, so no other fallback is needed.
40 *
41 * When copying or cutting (sending data to the OS), the data is
42 * announced and stored internally, but only actually rendered on
43 * request. The requester determines the format provided. The
44 * {next-}selection-coding-system is only used, when its corresponding
45 * clipboard type matches the type requested.
46 *
47 * Scenarios to use the facilities for customizing the selection
48 * coding system are:
49 *
50 * ;; Generally use KOI8-R instead of the russian MS codepage for
51 * ;; the 8-bit clipboard.
52 * (set-selection-coding-system 'koi8-r-dos)
53 *
54 * Or
55 *
56 * ;; Create a special clipboard copy function that uses codepage
57 * ;; 1253 (Greek) to copy Greek text to a specific non-Unicode
58 * ;; application.
59 * (defun greek-copy (beg end)
60 * (interactive "r")
61 * (set-next-selection-coding-system 'cp1253-dos)
62 * (copy-region-as-kill beg end))
63 * (global-set-key "\C-c\C-c" 'greek-copy)
64 */
65
66/*
67 * Ideas for further directions:
68 *
69 * The encoding and decoding routines could be moved to Lisp code
70 * similar to how xselect.c does it (using well-known routine names
71 * for the delayed rendering). If the definition of which clipboard
72 * types should be supported is also moved to Lisp, functionality
73 * could be expanded to CF_HTML, CF_RTF and maybe other types.
74 */
75
23#include <config.h> 76#include <config.h>
24#include "lisp.h" 77#include "lisp.h"
25#include "w32term.h" /* for all of the w32 includes */ 78#include "w32term.h" /* for all of the w32 includes */
26#include "dispextern.h" /* frame.h seems to want this */ 79#include "w32heap.h" /* os_subtype */
27#include "keyboard.h"
28#include "frame.h" /* Need this to get the X window of selected_frame */
29#include "blockinput.h" 80#include "blockinput.h"
30#include "buffer.h" 81#include "keyboard.h" /* cmd_error_internal() */
31#include "charset.h" 82#include "charset.h"
32#include "coding.h" 83#include "coding.h"
33#include "composite.h" 84#include "composite.h"
34 85
86
87static HGLOBAL convert_to_handle_as_ascii (void);
88static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system);
89static Lisp_Object render (Lisp_Object oformat);
90static Lisp_Object render_locale (void);
91static Lisp_Object render_all (void);
92static void run_protected (Lisp_Object (*code) (), Lisp_Object arg);
93static Lisp_Object lisp_error_handler (Lisp_Object error);
94static LRESULT CALLBACK owner_callback (HWND win, UINT msg,
95 WPARAM wp, LPARAM lp);
96static HWND create_owner (void);
97
98static void setup_config (void);
99static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
100static UINT cp_from_locale (LCID lcid, UINT format);
101static Lisp_Object coding_from_cp (UINT codepage);
102
103
104/* A remnant from X11: Symbol for the CLIPBORD selection type. Other
105 selections are not used on Windows, so we don't need symbols for
106 PRIMARY and SECONDARY. */
35Lisp_Object QCLIPBOARD; 107Lisp_Object QCLIPBOARD;
36 108
37/* Coding system for communicating with other Windows programs via the 109/* Coding system for communicating with other programs via the
38 clipboard. */ 110 clipboard. */
39static Lisp_Object Vselection_coding_system; 111static Lisp_Object Vselection_coding_system;
40 112
41/* Coding system for the next communicating with other Windows programs. */ 113/* Coding system for the next communication with other programs. */
42static Lisp_Object Vnext_selection_coding_system; 114static Lisp_Object Vnext_selection_coding_system;
43 115
44/* Sequence number, used where possible to detect when we are pasting 116/* Internal pseudo-constants, initialized in globals_of_w32select()
45 our own text. */ 117 based on current system parameters. */
46static DWORD last_clipboard_sequence_number; 118static LCID DEFAULT_LCID;
47extern ClipboardSequence_Proc clipboard_sequence_fn; 119static UINT ANSICP, OEMCP;
48 120static Lisp_Object QUNICODE, QANSICP, QOEMCP;
49/* The last text we put into the clipboard. This is used when the OS 121
50 does not support sequence numbers (NT4, 95). It is undesirable to 122/* A hidden window just for the clipboard management. */
51 use data put on the clipboard by Emacs because the clipboard data 123static HWND clipboard_owner;
52 could be MULEtilated by inappropriately chosen 124/* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just
53 (next-)selection-coding-system. For this reason, we must store the 125 checking GetClipboardOwner() doesn't work, sadly). */
54 text *after* it was encoded/Unix-to-DOS-converted. */ 126static int modifying_clipboard = 0;
55static unsigned char *last_clipboard_text = NULL; 127
56static size_t clipboard_storage_size = 0; 128/* Configured transfer parameters, based on the last inspection of
57 129 selection-coding-system. */
58#if 0 130static Lisp_Object cfg_coding_system;
59DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0, 131static UINT cfg_codepage;
60 doc: /* This opens the clipboard with the given frame pointer. */) 132static LCID cfg_lcid;
61 (frame) 133static UINT cfg_clipboard_type;
62 Lisp_Object frame; 134
135/* The current state for delayed rendering. */
136static Lisp_Object current_text;
137static Lisp_Object current_coding_system;
138static int current_requires_encoding, current_num_nls;
139static UINT current_clipboard_type;
140static LCID current_lcid;
141
142#if TRACE
143#define ONTRACE(stmt) stmt
144#else
145#define ONTRACE(stmt) /*stmt*/
146#endif
147
148
149/* This function assumes that there is no multibyte character in
150 current_text, so we can short-cut encoding. */
151
152static HGLOBAL
153convert_to_handle_as_ascii (void)
63{ 154{
64 BOOL ok = FALSE; 155 HGLOBAL htext = NULL;
156 int nbytes;
157 int truelen;
158 unsigned char *src;
159 unsigned char *dst;
65 160
66 if (!NILP (frame)) 161 ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n"));
67 CHECK_LIVE_FRAME (frame);
68 162
69 BLOCK_INPUT; 163 nbytes = SBYTES (current_text) + 1;
164 src = SDATA (current_text);
70 165
71 ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL); 166 /* We need to add to the size the number of LF chars where we have
167 to insert CR chars (the standard CF_TEXT clipboard format uses
168 CRLF line endings, while Emacs uses just LF internally). */
72 169
73 UNBLOCK_INPUT; 170 truelen = nbytes + current_num_nls;
171
172 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
173 return NULL;
74 174
75 return (ok ? frame : Qnil); 175 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
176 {
177 GlobalFree (htext);
178 return NULL;
179 }
180
181 /* convert to CRLF line endings expected by clipboard */
182 while (1)
183 {
184 unsigned char *next;
185 /* copy next line or remaining bytes including '\0' */
186 next = _memccpy (dst, src, '\n', nbytes);
187 if (next)
188 {
189 /* copied one line ending with '\n' */
190 int copied = next - dst;
191 nbytes -= copied;
192 src += copied;
193 /* insert '\r' before '\n' */
194 next[-1] = '\r';
195 next[0] = '\n';
196 dst = next + 1;
197 }
198 else
199 /* copied remaining partial line -> now finished */
200 break;
201 }
202
203 GlobalUnlock (htext);
204
205 return htext;
76} 206}
77 207
78DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard, 208/* This function assumes that there are multibyte or NUL characters in
79 Sw32_empty_clipboard, 0, 0, 0, 209 current_text, or that we need to construct Unicode. It runs the
80 doc: /* Empty the clipboard. 210 text through the encoding machinery. */
81Assigns ownership of the clipboard to the window which opened it. */) 211
82 () 212static HGLOBAL
213convert_to_handle_as_coded (Lisp_Object coding_system)
83{ 214{
84 BOOL ok = FALSE; 215 HGLOBAL htext = NULL, htext2;
216 int nbytes;
217 unsigned char *src;
218 unsigned char *dst = NULL;
219 int bufsize;
220 struct coding_system coding;
221 Lisp_Object string = Qnil;
222
223 ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",
224 SDATA (SYMBOL_NAME (coding_system))));
225
226 setup_coding_system (Fcheck_coding_system (coding_system), &coding);
227 coding.src_multibyte = 1;
228 coding.dst_multibyte = 0;
229 /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
230 encode_coding_iso2022 trying to dereference a null pointer. */
231 coding.composing = COMPOSITION_DISABLED;
232 if (coding.type == coding_type_iso2022)
233 coding.flags |= CODING_FLAG_ISO_SAFE;
234 coding.mode |= CODING_MODE_LAST_BLOCK;
235 /* Force DOS line-ends. */
236 coding.eol_type = CODING_EOL_CRLF;
237
238 if (SYMBOLP (coding.pre_write_conversion)
239 && !NILP (Ffboundp (coding.pre_write_conversion)))
240 string = run_pre_post_conversion_on_str (current_text, &coding, 1);
241 else
242 string = current_text;
243
244 nbytes = SBYTES (string);
245 src = SDATA (string);
85 246
86 BLOCK_INPUT; 247 bufsize = encoding_buffer_size (&coding, nbytes) +2;
248 htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize);
87 249
88 ok = EmptyClipboard (); 250 if (htext != NULL)
251 dst = (unsigned char *) GlobalLock (htext);
89 252
90 UNBLOCK_INPUT; 253 if (dst != NULL)
254 {
255 encode_coding (&coding, src, dst, nbytes, bufsize-2);
256 /* Add the string terminator. Add two NULs in case we are
257 producing Unicode here. */
258 dst[coding.produced] = dst[coding.produced+1] = '\0';
259 }
91 260
92 return (ok ? Qt : Qnil); 261 if (dst != NULL)
262 GlobalUnlock (htext);
263
264 if (htext != NULL)
265 {
266 /* Shrink data block to actual size. */
267 htext2 = GlobalReAlloc (htext, coding.produced+2,
268 GMEM_MOVEABLE | GMEM_DDESHARE);
269 if (htext2 != NULL) htext = htext2;
270 }
271
272 return htext;
93} 273}
94 274
95DEFUN ("w32-close-clipboard", Fw32_close_clipboard, 275static Lisp_Object
96 Sw32_close_clipboard, 0, 0, 0, 276render (Lisp_Object oformat)
97 doc: /* Close the clipboard. */)
98 ()
99{ 277{
100 BOOL ok = FALSE; 278 HGLOBAL htext = NULL;
279 UINT format = XFASTINT (oformat);
280
281 ONTRACE (fprintf (stderr, "render\n"));
282
283 if (NILP (current_text))
284 return Qnil;
285
286 if (current_requires_encoding || format == CF_UNICODETEXT)
287 {
288 if (format == current_clipboard_type)
289 htext = convert_to_handle_as_coded (current_coding_system);
290 else
291 switch (format)
292 {
293 case CF_UNICODETEXT:
294 htext = convert_to_handle_as_coded (QUNICODE);
295 break;
296 case CF_TEXT:
297 case CF_OEMTEXT:
298 {
299 Lisp_Object cs;
300 cs = coding_from_cp (cp_from_locale (current_lcid, format));
301 htext = convert_to_handle_as_coded (cs);
302 break;
303 }
304 }
305 }
306 else
307 htext = convert_to_handle_as_ascii ();
308
309 ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext));
310
311 if (htext == NULL)
312 return Qnil;
313
314 if (SetClipboardData (format, htext) == NULL)
315 {
316 GlobalFree(htext);
317 return Qnil;
318 }
319
320 return Qt;
321}
322
323static Lisp_Object
324render_locale (void)
325{
326 HANDLE hlocale = NULL;
327 LCID * lcid_ptr;
328
329 ONTRACE (fprintf (stderr, "render_locale\n"));
330
331 if (current_lcid == LOCALE_NEUTRAL || current_lcid == DEFAULT_LCID)
332 return Qt;
333
334 hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, sizeof (current_lcid));
335 if (hlocale == NULL)
336 return Qnil;
337
338 if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) == NULL)
339 {
340 GlobalFree(hlocale);
341 return Qnil;
342 }
343
344 *lcid_ptr = current_lcid;
345 GlobalUnlock (hlocale);
346
347 if (SetClipboardData (CF_LOCALE, hlocale) == NULL)
348 {
349 GlobalFree(hlocale);
350 return Qnil;
351 }
352
353 return Qt;
354}
355
356/* At the end of the program, we want to ensure that our clipboard
357 data survives us. This code will do that. */
358
359static Lisp_Object
360render_all (void)
361{
362 ONTRACE (fprintf (stderr, "render_all\n"));
363
364 /* According to the docs we should not call OpenClipboard() here,
365 but testing on W2K and working code in other projects shows that
366 it is actually necessary. */
367
368 OpenClipboard (NULL);
369
370 /* There is no usefull means to report errors here, there are none
371 expected anyway, and even if there were errors, they wouldn't do
372 any harm. So we just go ahead and do what has to be done without
373 bothering with error handling. */
374
375 ++modifying_clipboard;
376 EmptyClipboard ();
377 --modifying_clipboard;
378
379 /* For text formats that we don't render here, the OS can use its
380 own translation rules instead, so we don't really need to offer
381 everything. To minimize memory consumption we cover three
382 possible situations based on our primary format as detected from
383 selection-coding-system (see setup_config()):
384
385 - Post CF_TEXT only. Let the OS convert to CF_OEMTEXT and the OS
386 (on NT) or the application (on 9x/Me) convert to
387 CF_UNICODETEXT.
388
389 - Post CF_OEMTEXT only. Similar automatic conversions happen as
390 for CF_TEXT.
391
392 - Post CF_UNICODETEXT + CF_TEXT. 9x itself ignores
393 CF_UNICODETEXT, even though some applications can still handle
394 it.
395
396 Note 1: We render the less capable CF_TEXT *before* the more
397 capable CF_UNICODETEXT, to prevent clobbering through automatic
398 conversions, just in case.
399
400 Note 2: We could check os_subtype here and only render the
401 additional CF_TEXT on 9x/Me. But OTOH with
402 current_clipboard_type == CF_UNICODETEXT we don't involve the
403 automatic conversions anywhere else, so to get consistent
404 results, we probably don't want to rely on it here either. */
405
406 render_locale();
407
408 if (current_clipboard_type == CF_UNICODETEXT)
409 render (make_number (CF_TEXT));
410 render (make_number (current_clipboard_type));
411
412 CloseClipboard ();
413
414 return Qnil;
415}
416
417static void
418run_protected (Lisp_Object (*code) (), Lisp_Object arg)
419{
420 /* FIXME: This works but it doesn't feel right. Too much fiddling
421 with global variables and calling strange looking functions. Is
422 this really the right way to run Lisp callbacks? */
423
424 extern int waiting_for_input;
425 int owfi;
101 426
102 BLOCK_INPUT; 427 BLOCK_INPUT;
103 428
104 ok = CloseClipboard (); 429 /* Fsignal calls abort() if it sees that waiting_for_input is
430 set. */
431 owfi = waiting_for_input;
432 waiting_for_input = 0;
433
434 internal_condition_case_1 (code, arg, Qt, lisp_error_handler);
435
436 waiting_for_input = owfi;
105 437
106 UNBLOCK_INPUT; 438 UNBLOCK_INPUT;
439}
107 440
108 return (ok ? Qt : Qnil); 441static Lisp_Object
442lisp_error_handler (Lisp_Object error)
443{
444 Vsignaling_function = Qnil;
445 cmd_error_internal (error, "Error in delayed clipboard rendering: ");
446 Vinhibit_quit = Qt;
447 return Qt;
448}
449
450
451static LRESULT CALLBACK
452owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp)
453{
454 switch (msg)
455 {
456 case WM_RENDERFORMAT:
457 ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n"));
458 run_protected (render, make_number (wp));
459 return 0;
460
461 case WM_RENDERALLFORMATS:
462 ONTRACE (fprintf (stderr, "WM_RENDERALLFORMATS\n"));
463 run_protected (render_all, Qnil);
464 return 0;
465
466 case WM_DESTROYCLIPBOARD:
467 if (!modifying_clipboard)
468 {
469 ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n"));
470 current_text = Qnil;
471 current_coding_system = Qnil;
472 }
473 else
474 {
475 ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (self)\n"));
476 }
477 return 0;
478
479 case WM_DESTROY:
480 if (win == clipboard_owner)
481 clipboard_owner = NULL;
482 break;
483 }
484
485 return DefWindowProc (win, msg, wp, lp);
486}
487
488static HWND
489create_owner (void)
490{
491 static const char CLASSNAME[] = "Emacs Clipboard";
492 WNDCLASS wc;
493
494 memset (&wc, 0, sizeof (wc));
495 wc.lpszClassName = CLASSNAME;
496 wc.lpfnWndProc = owner_callback;
497 RegisterClass (&wc);
498
499 return CreateWindow (CLASSNAME, CLASSNAME, 0, 0, 0, 0, 0, NULL, NULL,
500 NULL, NULL);
501}
502
503/* Called on exit by term_ntproc() in w32.c */
504
505void
506term_w32select (void)
507{
508 /* This is needed to trigger WM_RENDERALLFORMATS. */
509 if (clipboard_owner != NULL)
510 DestroyWindow (clipboard_owner);
511}
512
513static void
514setup_config (void)
515{
516 const char *coding_name;
517 const char *cp;
518 char *end;
519 int slen;
520 Lisp_Object new_coding_system;
521
522 CHECK_SYMBOL (Vselection_coding_system);
523
524 /* Check if we have it cached */
525 new_coding_system = NILP (Vnext_selection_coding_system) ?
526 Vselection_coding_system : Vnext_selection_coding_system;
527 if (!NILP (cfg_coding_system)
528 && EQ (cfg_coding_system, new_coding_system))
529 return;
530 cfg_coding_system = new_coding_system;
531
532 /* Set some sensible fallbacks */
533 cfg_codepage = ANSICP;
534 cfg_lcid = LOCALE_NEUTRAL;
535 cfg_clipboard_type = CF_TEXT;
536
537 /* Interpret the coding system symbol name */
538 coding_name = SDATA (SYMBOL_NAME (cfg_coding_system));
539
540 /* "(.*-)?utf-16.*" -> CF_UNICODETEXT */
541 cp = strstr (coding_name, "utf-16");
542 if (cp != NULL && (cp == coding_name || cp[-1] == '-'))
543 {
544 cfg_clipboard_type = CF_UNICODETEXT;
545 return;
546 }
547
548 /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */
549 slen = strlen (coding_name);
550 if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p')
551 cp = coding_name + 2;
552 else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0)
553 cp = coding_name + 8;
554 else
555 return;
556
557 end = (char*)cp;
558 cfg_codepage = strtol (cp, &end, 10);
559
560 /* Error return from strtol() or number of digits < 2 -> Restore the
561 default and drop it. */
562 if (cfg_codepage == 0 || (end-cp) < 2 )
563 {
564 cfg_codepage = ANSICP;
565 return;
566 }
567
568 /* Is it the currently active system default? */
569 if (cfg_codepage == ANSICP)
570 {
571 /* cfg_clipboard_type = CF_TEXT; */
572 return;
573 }
574 if (cfg_codepage == OEMCP)
575 {
576 cfg_clipboard_type = CF_OEMTEXT;
577 return;
578 }
579
580 /* Else determine a suitable locale the hard way. */
581 EnumSystemLocales (enum_locale_callback, LCID_INSTALLED);
582}
583
584static BOOL WINAPI
585enum_locale_callback (/*const*/ char* loc_string)
586{
587 LCID lcid;
588 UINT codepage;
589
590 lcid = strtoul (loc_string, NULL, 16);
591
592 /* Is the wanted codepage the "ANSI" codepage for this locale? */
593 codepage = cp_from_locale (lcid, CF_TEXT);
594 if (codepage == cfg_codepage)
595 {
596 cfg_lcid = lcid;
597 cfg_clipboard_type = CF_TEXT;
598 return FALSE; /* Stop enumeration */
599 }
600
601 /* Is the wanted codepage the OEM codepage for this locale? */
602 codepage = cp_from_locale (lcid, CF_OEMTEXT);
603 if (codepage == cfg_codepage)
604 {
605 cfg_lcid = lcid;
606 cfg_clipboard_type = CF_OEMTEXT;
607 return FALSE; /* Stop enumeration */
608 }
609
610 return TRUE; /* Continue enumeration */
611}
612
613static UINT
614cp_from_locale (LCID lcid, UINT format)
615{
616 char buffer[20] = "";
617 UINT variant, cp;
618
619 variant =
620 format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE;
621
622 GetLocaleInfo (lcid, variant, buffer, sizeof (buffer));
623 cp = strtoul (buffer, NULL, 10);
624
625 if (cp == CP_ACP)
626 return ANSICP;
627 else if (cp == CP_OEMCP)
628 return OEMCP;
629 else
630 return cp;
631}
632
633static Lisp_Object
634coding_from_cp (UINT codepage)
635{
636 char buffer[30];
637 sprintf (buffer, "cp%d-dos", (int) codepage);
638 return intern (buffer);
639 /* We don't need to check that this coding system exists right here,
640 because that is done when the coding system is actually
641 instantiated, i.e. it is passed through Fcheck_coding_system()
642 there. */
109} 643}
110 644
111#endif
112 645
113DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, 646DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
114 Sw32_set_clipboard_data, 1, 2, 0, 647 Sw32_set_clipboard_data, 1, 2, 0,
115 doc: /* This sets the clipboard data to the given text. */) 648 doc: /* This sets the clipboard data to the given text. */)
116 (string, frame) 649 (string, ignored)
117 Lisp_Object string, frame; 650 Lisp_Object string, ignored;
118{ 651{
119 BOOL ok = TRUE; 652 BOOL ok = TRUE;
120 HANDLE htext;
121 int nbytes; 653 int nbytes;
122 int truelen, nlines = 0;
123 unsigned char *src; 654 unsigned char *src;
124 unsigned char *dst; 655 unsigned char *dst;
656 unsigned char *end;
657
658 /* This parameter used to be the current frame, but we don't use
659 that any more. */
660 (void) ignored;
125 661
126 CHECK_STRING (string); 662 CHECK_STRING (string);
127 663
128 if (!NILP (frame)) 664 setup_config ();
129 CHECK_LIVE_FRAME (frame);
130 665
666 current_text = string;
667 current_coding_system = cfg_coding_system;
668 current_clipboard_type = cfg_clipboard_type;
669 current_lcid = cfg_lcid;
670 current_num_nls = 0;
671 current_requires_encoding = 0;
672
131 BLOCK_INPUT; 673 BLOCK_INPUT;
132 674
133 /* Include the terminating NULL character in the source of 675 /* Check for non-ASCII characters. While we are at it, count the
134 conversion. */ 676 number of LFs, so we know how many CRs we will have to add later
135 nbytes = SBYTES (string) + 1; 677 (just in the case where we can use our internal ASCII rendering,
678 see code and comment in convert_to_handle_as_ascii() above). */
679 nbytes = SBYTES (string);
136 src = SDATA (string); 680 src = SDATA (string);
137 dst = src;
138 681
139 /* We need to know how many lines there are, since we need CRLF line 682 for (dst = src, end = src+nbytes; dst < end; dst++)
140 termination for compatibility with other Windows Programs.
141 avoid using strchr because it recomputes the length every time */
142 while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
143 { 683 {
144 nlines++; 684 if (*dst == '\n')
145 dst++; 685 current_num_nls++;
686 else if (*dst >= 0x80 || *dst == 0)
687 {
688 current_requires_encoding = 1;
689 break;
690 }
146 } 691 }
147 692
148 { 693 if (!current_requires_encoding)
149 /* Since we are now handling multilingual text, we must consider 694 {
150 encoding text for the clipboard. */ 695 /* If all we have is ASCII we don't need to pretend we offer
151 int charset_info = find_charset_in_text (src, SCHARS (string), 696 anything fancy. */
152 nbytes, NULL, Qnil); 697 current_coding_system = Qraw_text;
153 698 current_clipboard_type = CF_TEXT;
154 if (charset_info == 0) 699 current_lcid = LOCALE_NEUTRAL;
155 { 700 }
156 /* No multibyte character in OBJ. We need not encode it. */
157
158 /* Need to know final size after CR chars are inserted (the
159 standard CF_TEXT clipboard format uses CRLF line endings,
160 while Emacs uses just LF internally). */
161
162 truelen = nbytes + nlines;
163
164 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
165 goto error;
166
167 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
168 goto error;
169
170 /* convert to CRLF line endings expected by clipboard */
171 while (1)
172 {
173 unsigned char *next;
174 /* copy next line or remaining bytes including '\0' */
175 next = _memccpy (dst, src, '\n', nbytes);
176 if (next)
177 {
178 /* copied one line ending with '\n' */
179 int copied = next - dst;
180 nbytes -= copied;
181 src += copied;
182 /* insert '\r' before '\n' */
183 next[-1] = '\r';
184 next[0] = '\n';
185 dst = next + 1;
186 }
187 else
188 /* copied remaining partial line -> now finished */
189 break;
190 }
191
192 GlobalUnlock (htext);
193 701
194 Vlast_coding_system_used = Qraw_text; 702 if (!OpenClipboard (clipboard_owner))
195 } 703 goto error;
196 else
197 {
198 /* We must encode contents of OBJ to the selection coding
199 system. */
200 int bufsize;
201 struct coding_system coding;
202 HANDLE htext2;
203
204 if (NILP (Vnext_selection_coding_system))
205 Vnext_selection_coding_system = Vselection_coding_system;
206 setup_coding_system
207 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
208 if (SYMBOLP (coding.pre_write_conversion)
209 && !NILP (Ffboundp (coding.pre_write_conversion)))
210 {
211 string = run_pre_post_conversion_on_str (string, &coding, 1);
212 src = SDATA (string);
213 /* Include the terminating NULL character in the source of
214 conversion. */
215 nbytes = SBYTES (string) + 1;
216 }
217 coding.src_multibyte = 1;
218 coding.dst_multibyte = 0;
219 /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
220 encode_coding_iso2022 trying to dereference a null pointer. */
221 coding.composing = COMPOSITION_DISABLED;
222 if (coding.type == coding_type_iso2022)
223 coding.flags |= CODING_FLAG_ISO_SAFE;
224 Vnext_selection_coding_system = Qnil;
225 coding.mode |= CODING_MODE_LAST_BLOCK;
226 bufsize = encoding_buffer_size (&coding, nbytes);
227 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL)
228 goto error;
229 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
230 goto error;
231 encode_coding (&coding, src, dst, nbytes, bufsize);
232 Vlast_coding_system_used = coding.symbol;
233 704
234 /* If clipboard sequence numbers are not supported, keep a copy for 705 ++modifying_clipboard;
235 later comparison. */ 706 ok = EmptyClipboard ();
236 if (!clipboard_sequence_fn) 707 --modifying_clipboard;
237 {
238 /* Stash away the data we are about to put into the
239 clipboard, so we could later check inside
240 Fw32_get_clipboard_data whether the clipboard still
241 holds our data. */
242 if (clipboard_storage_size < coding.produced)
243 {
244 clipboard_storage_size = coding.produced + 100;
245 last_clipboard_text = (char *) xrealloc (last_clipboard_text,
246 clipboard_storage_size);
247 }
248 if (last_clipboard_text)
249 memcpy (last_clipboard_text, dst, coding.produced);
250 }
251 708
252 GlobalUnlock (htext); 709 /* If we have something non-ASCII we may want to set a locale. We
710 do that directly (non-delayed), as it's just a small bit. */
711 if (ok)
712 ok = !NILP(render_locale());
253 713
254 /* Shrink data block to actual size. */ 714 if (ok)
255 htext2 = GlobalReAlloc (htext, coding.produced, 715 {
256 GMEM_MOVEABLE | GMEM_DDESHARE); 716 if (clipboard_owner == NULL)
257 if (htext2 != NULL) htext = htext2; 717 {
258 } 718 /* If for some reason we don't have a clipboard_owner, we
259 } 719 just set the text format as chosen by the configuration
720 and than forget about the whole thing. */
721 ok = !NILP(render (make_number (current_clipboard_type)));
722 current_text = Qnil;
723 current_coding_system = Qnil;
724 }
725 else
726 {
727 /* Advertise all supported formats so that whatever the
728 requester chooses, only one encoding step needs to be
729 made. This is intentionally different from what we do in
730 the handler for WM_RENDERALLFORMATS. */
731 SetClipboardData (CF_UNICODETEXT, NULL);
732 SetClipboardData (CF_TEXT, NULL);
733 SetClipboardData (CF_OEMTEXT, NULL);
734 }
735 }
260 736
261 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) 737 CloseClipboard ();
262 goto error;
263 738
264 ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext); 739 /* With delayed rendering we haven't really "used" this coding
740 system yet, and it's even unclear if we ever will. But this is a
741 way to tell the upper level what we *would* use under ideal
742 circumstances.
265 743
266 CloseClipboard (); 744 We don't signal the actually used coding-system later when we
745 finally render, because that can happen at any time and we don't
746 want to disturb the "foreground" action. */
747 if (ok)
748 Vlast_coding_system_used = current_coding_system;
267 749
268 /* Common sense says to read the sequence number inside the 750 Vnext_selection_coding_system = Qnil;
269 OpenClipboard/ CloseClipboard block to avoid race conditions
270 where another app puts something on the clipboard straight after
271 us. But experience suggests that the sequence number from the
272 SetClipboardData is not allocated until we close the clipboard!
273 Since clipboard operations are normally user-driven, the race
274 condition is probably not going to really happen. */
275 if (clipboard_sequence_fn)
276 last_clipboard_sequence_number = clipboard_sequence_fn ();
277 751
278 if (ok) goto done; 752 if (ok) goto done;
279 753
280 error: 754 error:
281 755
282 ok = FALSE; 756 ok = FALSE;
283 if (htext) GlobalFree (htext); 757 current_text = Qnil;
284 if (last_clipboard_text) 758 current_coding_system = Qnil;
285 *last_clipboard_text = '\0';
286
287 last_clipboard_sequence_number = 0;
288 759
289 done: 760 done:
290 UNBLOCK_INPUT; 761 UNBLOCK_INPUT;
@@ -292,24 +763,52 @@ DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
292 return (ok ? string : Qnil); 763 return (ok ? string : Qnil);
293} 764}
294 765
766
295DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, 767DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
296 Sw32_get_clipboard_data, 0, 1, 0, 768 Sw32_get_clipboard_data, 0, 1, 0,
297 doc: /* This gets the clipboard data in text format. */) 769 doc: /* This gets the clipboard data in text format. */)
298 (frame) 770 (ignored)
299 Lisp_Object frame; 771 Lisp_Object ignored;
300{ 772{
301 HANDLE htext; 773 HGLOBAL htext;
302 Lisp_Object ret = Qnil; 774 Lisp_Object ret = Qnil;
775 UINT actual_clipboard_type;
776 int use_configured_coding_system = 1;
777
778 /* This parameter used to be the current frame, but we don't use
779 that any more. */
780 (void) ignored;
303 781
304 if (!NILP (frame)) 782 /* Don't pass our own text from the clipboard (which might be
305 CHECK_LIVE_FRAME (frame); 783 troublesome if the killed text includes null characters). */
784 if (!NILP (current_text))
785 return ret;
786
787 setup_config ();
788 actual_clipboard_type = cfg_clipboard_type;
306 789
307 BLOCK_INPUT; 790 BLOCK_INPUT;
308 791
309 if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) 792 if (!OpenClipboard (clipboard_owner))
310 goto done; 793 goto done;
311 794
312 if ((htext = GetClipboardData (CF_TEXT)) == NULL) 795 if ((htext = GetClipboardData (actual_clipboard_type)) == NULL)
796 {
797 /* If we want CF_UNICODETEXT but can't get it, the current
798 coding system is useless. OTOH we can still try and decode
799 CF_TEXT based on the locale that the system gives us and that
800 we get down below. */
801 if (actual_clipboard_type == CF_UNICODETEXT)
802 {
803 htext = GetClipboardData (CF_TEXT);
804 if (htext != NULL)
805 {
806 actual_clipboard_type = CF_TEXT;
807 use_configured_coding_system = 0;
808 }
809 }
810 }
811 if (htext == NULL)
313 goto closeclip; 812 goto closeclip;
314 813
315 { 814 {
@@ -322,53 +821,107 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
322 if ((src = (unsigned char *) GlobalLock (htext)) == NULL) 821 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
323 goto closeclip; 822 goto closeclip;
324 823
325 nbytes = strlen (src); 824 /* If the clipboard data contains any non-ascii code, we need to
326 825 decode it with a coding system. */
327 /* If the text in clipboard is identical to what we put there 826 if (actual_clipboard_type == CF_UNICODETEXT)
328 last time w32_set_clipboard_data was called, pretend there's no 827 {
329 data in the clipboard. This is so we don't pass our own text 828 nbytes = lstrlenW ((WCHAR *)src) * 2;
330 from the clipboard (which might be troublesome if the killed 829 require_decoding = 1;
331 text includes null characters). */ 830 }
332 if ((clipboard_sequence_fn 831 else
333 && clipboard_sequence_fn () == last_clipboard_sequence_number) 832 {
334 || (last_clipboard_text 833 int i;
335 && clipboard_storage_size >= nbytes
336 && memcmp(last_clipboard_text, src, nbytes) == 0))
337 goto closeclip;
338 834
339 { 835 nbytes = strlen (src);
340 /* If the clipboard data contains any non-ascii code, we
341 need to decode it. */
342 int i;
343 836
344 for (i = 0; i < nbytes; i++) 837 for (i = 0; i < nbytes; i++)
345 { 838 {
346 if (src[i] >= 0x80) 839 if (src[i] >= 0x80)
347 { 840 {
348 require_decoding = 1; 841 require_decoding = 1;
349 break; 842 break;
350 } 843 }
351 } 844 }
352 } 845 }
353 846
354 if (require_decoding) 847 if (require_decoding)
355 { 848 {
356 int bufsize; 849 int bufsize;
357 unsigned char *buf; 850 unsigned char *buf;
358 struct coding_system coding; 851 struct coding_system coding;
852 Lisp_Object coding_system = Qnil;
853
854 /* `next-selection-coding-system' should override everything,
855 even when the locale passed by the system disagrees. The
856 only exception is when `next-selection-coding-system'
857 requested CF_UNICODETEXT and we couldn't get that. */
858 if (use_configured_coding_system
859 && !NILP (Vnext_selection_coding_system))
860 coding_system = Vnext_selection_coding_system;
861
862 /* If we have CF_TEXT or CF_OEMTEXT, we want to check out
863 CF_LOCALE, too. */
864 else if (actual_clipboard_type != CF_UNICODETEXT)
865 {
866 HGLOBAL hlocale;
867 LCID lcid = DEFAULT_LCID;
868 UINT cp;
869
870 /* Documentation says that the OS always generates
871 CF_LOCALE info automatically, so the locale handle
872 should always be present. Fact is that this is not
873 always true on 9x ;-(. */
874 hlocale = GetClipboardData (CF_LOCALE);
875 if (hlocale != NULL)
876 {
877 const LCID * lcid_ptr;
878 lcid_ptr = (const LCID *) GlobalLock (hlocale);
879 if (lcid_ptr != NULL)
880 {
881 lcid = *lcid_ptr;
882 GlobalUnlock (hlocale);
883 }
884
885 /* 9x has garbage as the sort order (to be exact there
886 is another instance of the language id in the upper
887 word). We don't care about sort order anyway, so
888 we just filter out the unneeded mis-information to
889 avoid irritations. */
890 lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT);
891 }
892
893 /* If we are using fallback from CF_UNICODETEXT, we can't
894 use the configured coding system. Also we don't want
895 to use it, if the system has supplied us with a locale
896 and it is not just the system default. */
897 if (!use_configured_coding_system || lcid != DEFAULT_LCID)
898 {
899 cp = cp_from_locale (lcid, actual_clipboard_type);
900 /* If it's just our current standard setting anyway,
901 use the coding system that the user has selected.
902 Otherwise create a new spec to match the locale
903 that was specified by the other side or the
904 system. */
905 if (!use_configured_coding_system || cp != cfg_codepage)
906 coding_system = coding_from_cp (cp);
907 }
908 }
909
910 if (NILP (coding_system))
911 coding_system = Vselection_coding_system;
912 Vnext_selection_coding_system = Qnil;
359 913
360 if (NILP (Vnext_selection_coding_system)) 914 setup_coding_system (Fcheck_coding_system (coding_system), &coding);
361 Vnext_selection_coding_system = Vselection_coding_system;
362 setup_coding_system
363 (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
364 coding.src_multibyte = 0; 915 coding.src_multibyte = 0;
365 coding.dst_multibyte = 1; 916 coding.dst_multibyte = 1;
366 Vnext_selection_coding_system = Qnil;
367 coding.mode |= CODING_MODE_LAST_BLOCK; 917 coding.mode |= CODING_MODE_LAST_BLOCK;
368 /* We explicitely disable composition handling because 918 /* We explicitely disable composition handling because
369 selection data should not contain any composition 919 selection data should not contain any composition
370 sequence. */ 920 sequence. */
371 coding.composing = COMPOSITION_DISABLED; 921 coding.composing = COMPOSITION_DISABLED;
922 /* Force DOS line-ends. */
923 coding.eol_type = CODING_EOL_CRLF;
924
372 bufsize = decoding_buffer_size (&coding, nbytes); 925 bufsize = decoding_buffer_size (&coding, nbytes);
373 buf = (unsigned char *) xmalloc (bufsize); 926 buf = (unsigned char *) xmalloc (bufsize);
374 decode_coding (&coding, src, buf, nbytes, bufsize); 927 decode_coding (&coding, src, buf, nbytes, bufsize);
@@ -382,10 +935,13 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
382 } 935 }
383 else 936 else
384 { 937 {
385 /* Need to know final size after CR chars are removed because we 938 /* FIXME: We may want to repeat the code in this branch for
386 can't change the string size manually, and doing an extra 939 the Unicode case. */
387 copy is silly. Note that we only remove CR when it appears 940
388 as part of CRLF. */ 941 /* Need to know final size after CR chars are removed because
942 we can't change the string size manually, and doing an
943 extra copy is silly. We only remove CR when it appears as
944 part of CRLF. */
389 945
390 truelen = nbytes; 946 truelen = nbytes;
391 dst = src; 947 dst = src;
@@ -462,9 +1018,14 @@ and t is the same as `SECONDARY'. */)
462 1018
463 if (OpenClipboard (NULL)) 1019 if (OpenClipboard (NULL))
464 { 1020 {
465 int format = 0; 1021 UINT format = 0;
466 while (format = EnumClipboardFormats (format)) 1022 setup_config ();
467 if (format == CF_TEXT) 1023 while ((format = EnumClipboardFormats (format)))
1024 /* Check CF_TEXT in addition to cfg_clipboard_type,
1025 because we can fall back on that if CF_UNICODETEXT is
1026 not available. Actually a check for CF_TEXT only
1027 should be enough. */
1028 if (format == cfg_clipboard_type || format == CF_TEXT)
468 { 1029 {
469 val = Qt; 1030 val = Qt;
470 break; 1031 break;
@@ -476,24 +1037,25 @@ and t is the same as `SECONDARY'. */)
476 return Qnil; 1037 return Qnil;
477} 1038}
478 1039
1040/* One-time init. Called in the un-dumped Emacs, but not in the
1041 dumped version. */
1042
479void 1043void
480syms_of_w32select () 1044syms_of_w32select ()
481{ 1045{
482#if 0
483 defsubr (&Sw32_open_clipboard);
484 defsubr (&Sw32_empty_clipboard);
485 defsubr (&Sw32_close_clipboard);
486#endif
487 defsubr (&Sw32_set_clipboard_data); 1046 defsubr (&Sw32_set_clipboard_data);
488 defsubr (&Sw32_get_clipboard_data); 1047 defsubr (&Sw32_get_clipboard_data);
489 defsubr (&Sx_selection_exists_p); 1048 defsubr (&Sx_selection_exists_p);
490 1049
491 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, 1050 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
492 doc: /* Coding system for communicating with other programs. 1051 doc: /* Coding system for communicating with other programs.
493When sending or receiving text via cut_buffer, selection, and clipboard, 1052When sending or receiving text via cut_buffer, selection, and
494the text is encoded or decoded by this coding system. 1053clipboard, the text is encoded or decoded by this coding system.
495The default value is `iso-latin-1-dos'. */); 1054The default value is the current system default encoding on 9x/Me and
496 Vselection_coding_system = intern ("iso-latin-1-dos"); 1055`utf-16le-dos' (Unicode) on NT/W2K/XP. */);
1056 /* The actual value is set dynamically in the dumped Emacs, see
1057 below. */
1058 Vselection_coding_system = Qnil;
497 1059
498 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, 1060 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
499 doc: /* Coding system for the next communication with other programs. 1061 doc: /* Coding system for the next communication with other programs.
@@ -504,6 +1066,41 @@ set to nil. */);
504 Vnext_selection_coding_system = Qnil; 1066 Vnext_selection_coding_system = Qnil;
505 1067
506 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); 1068 QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
1069
1070 cfg_coding_system = Qnil; staticpro (&cfg_coding_system);
1071 current_text = Qnil; staticpro (&current_text);
1072 current_coding_system = Qnil; staticpro (&current_coding_system);
1073
1074 QUNICODE = intern ("utf-16le-dos"); staticpro (&QUNICODE);
1075 QANSICP = Qnil; staticpro (&QANSICP);
1076 QOEMCP = Qnil; staticpro (&QOEMCP);
1077}
1078
1079/* One-time init. Called in the dumped Emacs, but not in the
1080 un-dumped version. */
1081
1082void
1083globals_of_w32select ()
1084{
1085 DEFAULT_LCID = GetUserDefaultLCID ();
1086 /* Drop the sort order from the LCID, so we can compare this with
1087 CF_LOCALE objects that have the same fix on 9x. */
1088 DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT);
1089
1090 ANSICP = GetACP ();
1091 OEMCP = GetOEMCP ();
1092
1093 QANSICP = coding_from_cp (ANSICP);
1094 QOEMCP = coding_from_cp (OEMCP);
1095
1096 if (os_subtype == OS_NT)
1097 Vselection_coding_system = QUNICODE;
1098 else if (inhibit_window_system)
1099 Vselection_coding_system = QOEMCP;
1100 else
1101 Vselection_coding_system = QANSICP;
1102
1103 clipboard_owner = create_owner ();
507} 1104}
508 1105
509/* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af 1106/* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af
diff --git a/src/xdisp.c b/src/xdisp.c
index 992c277c898..142b1fb1398 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -823,7 +823,6 @@ static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
823static int invisible_text_between_p P_ ((struct it *, int, int)); 823static int invisible_text_between_p P_ ((struct it *, int, int));
824#endif 824#endif
825 825
826static int next_element_from_ellipsis P_ ((struct it *));
827static void pint2str P_ ((char *, int, int)); 826static void pint2str P_ ((char *, int, int));
828static void pint2hrstr P_ ((char *, int, int)); 827static void pint2hrstr P_ ((char *, int, int));
829static struct text_pos run_window_scroll_functions P_ ((Lisp_Object, 828static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
@@ -898,6 +897,7 @@ static void reseat_1 P_ ((struct it *, struct text_pos, int));
898static void back_to_previous_visible_line_start P_ ((struct it *)); 897static void back_to_previous_visible_line_start P_ ((struct it *));
899void reseat_at_previous_visible_line_start P_ ((struct it *)); 898void reseat_at_previous_visible_line_start P_ ((struct it *));
900static void reseat_at_next_visible_line_start P_ ((struct it *, int)); 899static void reseat_at_next_visible_line_start P_ ((struct it *, int));
900static int next_element_from_ellipsis P_ ((struct it *));
901static int next_element_from_display_vector P_ ((struct it *)); 901static int next_element_from_display_vector P_ ((struct it *));
902static int next_element_from_string P_ ((struct it *)); 902static int next_element_from_string P_ ((struct it *));
903static int next_element_from_c_string P_ ((struct it *)); 903static int next_element_from_c_string P_ ((struct it *));
@@ -2039,7 +2039,7 @@ static void
2039check_it (it) 2039check_it (it)
2040 struct it *it; 2040 struct it *it;
2041{ 2041{
2042 if (it->method == next_element_from_string) 2042 if (it->method == GET_FROM_STRING)
2043 { 2043 {
2044 xassert (STRINGP (it->string)); 2044 xassert (STRINGP (it->string));
2045 xassert (IT_STRING_CHARPOS (*it) >= 0); 2045 xassert (IT_STRING_CHARPOS (*it) >= 0);
@@ -2047,7 +2047,7 @@ check_it (it)
2047 else 2047 else
2048 { 2048 {
2049 xassert (IT_STRING_CHARPOS (*it) < 0); 2049 xassert (IT_STRING_CHARPOS (*it) < 0);
2050 if (it->method == next_element_from_buffer) 2050 if (it->method == GET_FROM_BUFFER)
2051 { 2051 {
2052 /* Check that character and byte positions agree. */ 2052 /* Check that character and byte positions agree. */
2053 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it))); 2053 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
@@ -2557,7 +2557,7 @@ init_from_display_pos (it, w, pos)
2557 property for an image, the iterator will be set up for that 2557 property for an image, the iterator will be set up for that
2558 image, and we have to undo that setup first before we can 2558 image, and we have to undo that setup first before we can
2559 correct the overlay string index. */ 2559 correct the overlay string index. */
2560 if (it->method == next_element_from_image) 2560 if (it->method == GET_FROM_IMAGE)
2561 pop_it (it); 2561 pop_it (it);
2562 2562
2563 /* We already have the first chunk of overlay strings in 2563 /* We already have the first chunk of overlay strings in
@@ -2580,7 +2580,7 @@ init_from_display_pos (it, w, pos)
2580 it->string = it->overlay_strings[relative_index]; 2580 it->string = it->overlay_strings[relative_index];
2581 xassert (STRINGP (it->string)); 2581 xassert (STRINGP (it->string));
2582 it->current.string_pos = pos->string_pos; 2582 it->current.string_pos = pos->string_pos;
2583 it->method = next_element_from_string; 2583 it->method = GET_FROM_STRING;
2584 } 2584 }
2585 2585
2586#if 0 /* This is bogus because POS not having an overlay string 2586#if 0 /* This is bogus because POS not having an overlay string
@@ -2596,7 +2596,7 @@ init_from_display_pos (it, w, pos)
2596 while (it->sp) 2596 while (it->sp)
2597 pop_it (it); 2597 pop_it (it);
2598 it->current.overlay_string_index = -1; 2598 it->current.overlay_string_index = -1;
2599 it->method = next_element_from_buffer; 2599 it->method = GET_FROM_BUFFER;
2600 if (CHARPOS (pos->pos) == ZV) 2600 if (CHARPOS (pos->pos) == ZV)
2601 it->overlay_strings_at_end_processed_p = 1; 2601 it->overlay_strings_at_end_processed_p = 1;
2602 } 2602 }
@@ -2710,7 +2710,7 @@ handle_stop (it)
2710 { 2710 {
2711 /* Don't check for overlay strings below when set to deliver 2711 /* Don't check for overlay strings below when set to deliver
2712 characters from a display vector. */ 2712 characters from a display vector. */
2713 if (it->method == next_element_from_display_vector) 2713 if (it->method == GET_FROM_DISPLAY_VECTOR)
2714 handle_overlay_change_p = 0; 2714 handle_overlay_change_p = 0;
2715 2715
2716 /* Handle overlay changes. */ 2716 /* Handle overlay changes. */
@@ -3368,7 +3368,7 @@ setup_for_ellipsis (it, len)
3368 /* Remember the current face id in case glyphs specify faces. 3368 /* Remember the current face id in case glyphs specify faces.
3369 IT's face is restored in set_iterator_to_next. */ 3369 IT's face is restored in set_iterator_to_next. */
3370 it->saved_face_id = it->face_id; 3370 it->saved_face_id = it->face_id;
3371 it->method = next_element_from_display_vector; 3371 it->method = GET_FROM_DISPLAY_VECTOR;
3372 it->ellipsis_p = 1; 3372 it->ellipsis_p = 1;
3373} 3373}
3374 3374
@@ -3733,7 +3733,7 @@ handle_single_display_spec (it, spec, object, position,
3733 it->image_id = -1; /* no image */ 3733 it->image_id = -1; /* no image */
3734 it->position = start_pos; 3734 it->position = start_pos;
3735 it->object = NILP (object) ? it->w->buffer : object; 3735 it->object = NILP (object) ? it->w->buffer : object;
3736 it->method = next_element_from_image; 3736 it->method = GET_FROM_IMAGE;
3737 it->face_id = face_id; 3737 it->face_id = face_id;
3738 3738
3739 /* Say that we haven't consumed the characters with 3739 /* Say that we haven't consumed the characters with
@@ -3815,7 +3815,7 @@ handle_single_display_spec (it, spec, object, position,
3815 it->current.overlay_string_index = -1; 3815 it->current.overlay_string_index = -1;
3816 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; 3816 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3817 it->end_charpos = it->string_nchars = SCHARS (it->string); 3817 it->end_charpos = it->string_nchars = SCHARS (it->string);
3818 it->method = next_element_from_string; 3818 it->method = GET_FROM_STRING;
3819 it->stop_charpos = 0; 3819 it->stop_charpos = 0;
3820 it->string_from_display_prop_p = 1; 3820 it->string_from_display_prop_p = 1;
3821 /* Say that we haven't consumed the characters with 3821 /* Say that we haven't consumed the characters with
@@ -3825,7 +3825,7 @@ handle_single_display_spec (it, spec, object, position,
3825 } 3825 }
3826 else if (CONSP (value) && EQ (XCAR (value), Qspace)) 3826 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3827 { 3827 {
3828 it->method = next_element_from_stretch; 3828 it->method = GET_FROM_STRETCH;
3829 it->object = value; 3829 it->object = value;
3830 it->current.pos = it->position = start_pos; 3830 it->current.pos = it->position = start_pos;
3831 3831
@@ -3837,7 +3837,7 @@ handle_single_display_spec (it, spec, object, position,
3837 it->image_id = lookup_image (it->f, value); 3837 it->image_id = lookup_image (it->f, value);
3838 it->position = start_pos; 3838 it->position = start_pos;
3839 it->object = NILP (object) ? it->w->buffer : object; 3839 it->object = NILP (object) ? it->w->buffer : object;
3840 it->method = next_element_from_image; 3840 it->method = GET_FROM_IMAGE;
3841 3841
3842 /* Say that we haven't consumed the characters with 3842 /* Say that we haven't consumed the characters with
3843 `display' property yet. The call to pop_it in 3843 `display' property yet. The call to pop_it in
@@ -4093,7 +4093,7 @@ handle_composition_prop (it)
4093 4093
4094 if (id >= 0) 4094 if (id >= 0)
4095 { 4095 {
4096 it->method = next_element_from_composition; 4096 it->method = GET_FROM_COMPOSITION;
4097 it->cmp_id = id; 4097 it->cmp_id = id;
4098 it->cmp_len = COMPOSITION_LENGTH (prop); 4098 it->cmp_len = COMPOSITION_LENGTH (prop);
4099 /* For a terminal, draw only the first character of the 4099 /* For a terminal, draw only the first character of the
@@ -4168,7 +4168,7 @@ next_overlay_string (it)
4168 it->current.overlay_string_index = -1; 4168 it->current.overlay_string_index = -1;
4169 SET_TEXT_POS (it->current.string_pos, -1, -1); 4169 SET_TEXT_POS (it->current.string_pos, -1, -1);
4170 it->n_overlay_strings = 0; 4170 it->n_overlay_strings = 0;
4171 it->method = next_element_from_buffer; 4171 it->method = GET_FROM_BUFFER;
4172 4172
4173 /* If we're at the end of the buffer, record that we have 4173 /* If we're at the end of the buffer, record that we have
4174 processed the overlay strings there already, so that 4174 processed the overlay strings there already, so that
@@ -4197,7 +4197,7 @@ next_overlay_string (it)
4197 it->string = it->overlay_strings[i]; 4197 it->string = it->overlay_strings[i];
4198 it->multibyte_p = STRING_MULTIBYTE (it->string); 4198 it->multibyte_p = STRING_MULTIBYTE (it->string);
4199 SET_TEXT_POS (it->current.string_pos, 0, 0); 4199 SET_TEXT_POS (it->current.string_pos, 0, 0);
4200 it->method = next_element_from_string; 4200 it->method = GET_FROM_STRING;
4201 it->stop_charpos = 0; 4201 it->stop_charpos = 0;
4202 } 4202 }
4203 4203
@@ -4462,13 +4462,13 @@ get_overlay_strings (it, charpos)
4462 xassert (STRINGP (it->string)); 4462 xassert (STRINGP (it->string));
4463 it->end_charpos = SCHARS (it->string); 4463 it->end_charpos = SCHARS (it->string);
4464 it->multibyte_p = STRING_MULTIBYTE (it->string); 4464 it->multibyte_p = STRING_MULTIBYTE (it->string);
4465 it->method = next_element_from_string; 4465 it->method = GET_FROM_STRING;
4466 } 4466 }
4467 else 4467 else
4468 { 4468 {
4469 it->string = Qnil; 4469 it->string = Qnil;
4470 it->current.overlay_string_index = -1; 4470 it->current.overlay_string_index = -1;
4471 it->method = next_element_from_buffer; 4471 it->method = GET_FROM_BUFFER;
4472 } 4472 }
4473 4473
4474 CHECK_IT (it); 4474 CHECK_IT (it);
@@ -4846,7 +4846,7 @@ reseat_1 (it, pos, set_stop_p)
4846 IT_STRING_CHARPOS (*it) = -1; 4846 IT_STRING_CHARPOS (*it) = -1;
4847 IT_STRING_BYTEPOS (*it) = -1; 4847 IT_STRING_BYTEPOS (*it) = -1;
4848 it->string = Qnil; 4848 it->string = Qnil;
4849 it->method = next_element_from_buffer; 4849 it->method = GET_FROM_BUFFER;
4850 /* RMS: I added this to fix a bug in move_it_vertically_backward 4850 /* RMS: I added this to fix a bug in move_it_vertically_backward
4851 where it->area continued to relate to the starting point 4851 where it->area continued to relate to the starting point
4852 for the backward motion. Bug report from 4852 for the backward motion. Bug report from
@@ -4912,7 +4912,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4912 it->string = string; 4912 it->string = string;
4913 it->s = NULL; 4913 it->s = NULL;
4914 it->end_charpos = it->string_nchars = SCHARS (string); 4914 it->end_charpos = it->string_nchars = SCHARS (string);
4915 it->method = next_element_from_string; 4915 it->method = GET_FROM_STRING;
4916 it->current.string_pos = string_pos (charpos, string); 4916 it->current.string_pos = string_pos (charpos, string);
4917 } 4917 }
4918 else 4918 else
@@ -4934,7 +4934,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4934 it->end_charpos = it->string_nchars = strlen (s); 4934 it->end_charpos = it->string_nchars = strlen (s);
4935 } 4935 }
4936 4936
4937 it->method = next_element_from_c_string; 4937 it->method = GET_FROM_C_STRING;
4938 } 4938 }
4939 4939
4940 /* PRECISION > 0 means don't return more than PRECISION characters 4940 /* PRECISION > 0 means don't return more than PRECISION characters
@@ -4965,6 +4965,20 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4965 Iteration 4965 Iteration
4966 ***********************************************************************/ 4966 ***********************************************************************/
4967 4967
4968/* Map enum it_method value to corresponding next_element_from_* function. */
4969
4970static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
4971{
4972 next_element_from_buffer,
4973 next_element_from_display_vector,
4974 next_element_from_composition,
4975 next_element_from_string,
4976 next_element_from_c_string,
4977 next_element_from_image,
4978 next_element_from_stretch
4979};
4980
4981
4968/* Load IT's display element fields with information about the next 4982/* Load IT's display element fields with information about the next
4969 display element from the current position of IT. Value is zero if 4983 display element from the current position of IT. Value is zero if
4970 end of buffer (or C string) is reached. */ 4984 end of buffer (or C string) is reached. */
@@ -4980,7 +4994,7 @@ get_next_display_element (it)
4980 int success_p; 4994 int success_p;
4981 4995
4982 get_next: 4996 get_next:
4983 success_p = (*it->method) (it); 4997 success_p = (*get_next_element[it->method]) (it);
4984 4998
4985 if (it->what == IT_CHARACTER) 4999 if (it->what == IT_CHARACTER)
4986 { 5000 {
@@ -5014,7 +5028,7 @@ get_next_display_element (it)
5014 it->current.dpvec_index = 0; 5028 it->current.dpvec_index = 0;
5015 it->dpvec_face_id = -1; 5029 it->dpvec_face_id = -1;
5016 it->saved_face_id = it->face_id; 5030 it->saved_face_id = it->face_id;
5017 it->method = next_element_from_display_vector; 5031 it->method = GET_FROM_DISPLAY_VECTOR;
5018 it->ellipsis_p = 0; 5032 it->ellipsis_p = 0;
5019 } 5033 }
5020 else 5034 else
@@ -5040,7 +5054,7 @@ get_next_display_element (it)
5040 else if ((it->c < ' ' 5054 else if ((it->c < ' '
5041 && (it->area != TEXT_AREA 5055 && (it->area != TEXT_AREA
5042 /* In mode line, treat \n like other crl chars. */ 5056 /* In mode line, treat \n like other crl chars. */
5043 || (it->c != '\n' 5057 || (it->c != '\t'
5044 && it->glyph_row && it->glyph_row->mode_line_p) 5058 && it->glyph_row && it->glyph_row->mode_line_p)
5045 || (it->c != '\n' && it->c != '\t'))) 5059 || (it->c != '\n' && it->c != '\t')))
5046 || (it->multibyte_p 5060 || (it->multibyte_p
@@ -5172,7 +5186,7 @@ get_next_display_element (it)
5172 it->current.dpvec_index = 0; 5186 it->current.dpvec_index = 0;
5173 it->dpvec_face_id = face_id; 5187 it->dpvec_face_id = face_id;
5174 it->saved_face_id = it->face_id; 5188 it->saved_face_id = it->face_id;
5175 it->method = next_element_from_display_vector; 5189 it->method = GET_FROM_DISPLAY_VECTOR;
5176 it->ellipsis_p = 0; 5190 it->ellipsis_p = 0;
5177 goto get_next; 5191 goto get_next;
5178 } 5192 }
@@ -5234,8 +5248,9 @@ set_iterator_to_next (it, reseat_p)
5234 moving the iterator to a new position might set them. */ 5248 moving the iterator to a new position might set them. */
5235 it->start_of_box_run_p = it->end_of_box_run_p = 0; 5249 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5236 5250
5237 if (it->method == next_element_from_buffer) 5251 switch (it->method)
5238 { 5252 {
5253 case GET_FROM_BUFFER:
5239 /* The current display element of IT is a character from 5254 /* The current display element of IT is a character from
5240 current_buffer. Advance in the buffer, and maybe skip over 5255 current_buffer. Advance in the buffer, and maybe skip over
5241 invisible lines that are so because of selective display. */ 5256 invisible lines that are so because of selective display. */
@@ -5248,32 +5263,32 @@ set_iterator_to_next (it, reseat_p)
5248 IT_CHARPOS (*it) += 1; 5263 IT_CHARPOS (*it) += 1;
5249 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); 5264 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5250 } 5265 }
5251 } 5266 break;
5252 else if (it->method == next_element_from_composition) 5267
5253 { 5268 case GET_FROM_COMPOSITION:
5254 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions); 5269 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5255 if (STRINGP (it->string)) 5270 if (STRINGP (it->string))
5256 { 5271 {
5257 IT_STRING_BYTEPOS (*it) += it->len; 5272 IT_STRING_BYTEPOS (*it) += it->len;
5258 IT_STRING_CHARPOS (*it) += it->cmp_len; 5273 IT_STRING_CHARPOS (*it) += it->cmp_len;
5259 it->method = next_element_from_string; 5274 it->method = GET_FROM_STRING;
5260 goto consider_string_end; 5275 goto consider_string_end;
5261 } 5276 }
5262 else 5277 else
5263 { 5278 {
5264 IT_BYTEPOS (*it) += it->len; 5279 IT_BYTEPOS (*it) += it->len;
5265 IT_CHARPOS (*it) += it->cmp_len; 5280 IT_CHARPOS (*it) += it->cmp_len;
5266 it->method = next_element_from_buffer; 5281 it->method = GET_FROM_BUFFER;
5267 } 5282 }
5268 } 5283 break;
5269 else if (it->method == next_element_from_c_string) 5284
5270 { 5285 case GET_FROM_C_STRING:
5271 /* Current display element of IT is from a C string. */ 5286 /* Current display element of IT is from a C string. */
5272 IT_BYTEPOS (*it) += it->len; 5287 IT_BYTEPOS (*it) += it->len;
5273 IT_CHARPOS (*it) += 1; 5288 IT_CHARPOS (*it) += 1;
5274 } 5289 break;
5275 else if (it->method == next_element_from_display_vector) 5290
5276 { 5291 case GET_FROM_DISPLAY_VECTOR:
5277 /* Current display element of IT is from a display table entry. 5292 /* Current display element of IT is from a display table entry.
5278 Advance in the display table definition. Reset it to null if 5293 Advance in the display table definition. Reset it to null if
5279 end reached, and continue with characters from buffers/ 5294 end reached, and continue with characters from buffers/
@@ -5287,11 +5302,11 @@ set_iterator_to_next (it, reseat_p)
5287 if (it->dpvec + it->current.dpvec_index == it->dpend) 5302 if (it->dpvec + it->current.dpvec_index == it->dpend)
5288 { 5303 {
5289 if (it->s) 5304 if (it->s)
5290 it->method = next_element_from_c_string; 5305 it->method = GET_FROM_C_STRING;
5291 else if (STRINGP (it->string)) 5306 else if (STRINGP (it->string))
5292 it->method = next_element_from_string; 5307 it->method = GET_FROM_STRING;
5293 else 5308 else
5294 it->method = next_element_from_buffer; 5309 it->method = GET_FROM_BUFFER;
5295 5310
5296 it->dpvec = NULL; 5311 it->dpvec = NULL;
5297 it->current.dpvec_index = -1; 5312 it->current.dpvec_index = -1;
@@ -5308,9 +5323,9 @@ set_iterator_to_next (it, reseat_p)
5308 /* Recheck faces after display vector */ 5323 /* Recheck faces after display vector */
5309 it->stop_charpos = IT_CHARPOS (*it); 5324 it->stop_charpos = IT_CHARPOS (*it);
5310 } 5325 }
5311 } 5326 break;
5312 else if (it->method == next_element_from_string) 5327
5313 { 5328 case GET_FROM_STRING:
5314 /* Current display element is a character from a Lisp string. */ 5329 /* Current display element is a character from a Lisp string. */
5315 xassert (it->s == NULL && STRINGP (it->string)); 5330 xassert (it->s == NULL && STRINGP (it->string));
5316 IT_STRING_BYTEPOS (*it) += it->len; 5331 IT_STRING_BYTEPOS (*it) += it->len;
@@ -5335,34 +5350,35 @@ set_iterator_to_next (it, reseat_p)
5335 && it->sp > 0) 5350 && it->sp > 0)
5336 { 5351 {
5337 pop_it (it); 5352 pop_it (it);
5338 if (!STRINGP (it->string)) 5353 if (STRINGP (it->string))
5339 it->method = next_element_from_buffer;
5340 else
5341 goto consider_string_end; 5354 goto consider_string_end;
5355 it->method = GET_FROM_BUFFER;
5342 } 5356 }
5343 } 5357 }
5344 } 5358 break;
5345 else if (it->method == next_element_from_image 5359
5346 || it->method == next_element_from_stretch) 5360 case GET_FROM_IMAGE:
5347 { 5361 case GET_FROM_STRETCH:
5348 /* The position etc with which we have to proceed are on 5362 /* The position etc with which we have to proceed are on
5349 the stack. The position may be at the end of a string, 5363 the stack. The position may be at the end of a string,
5350 if the `display' property takes up the whole string. */ 5364 if the `display' property takes up the whole string. */
5365 xassert (it->sp > 0);
5351 pop_it (it); 5366 pop_it (it);
5352 it->image_id = 0; 5367 it->image_id = 0;
5353 if (STRINGP (it->string)) 5368 if (STRINGP (it->string))
5354 { 5369 {
5355 it->method = next_element_from_string; 5370 it->method = GET_FROM_STRING;
5356 goto consider_string_end; 5371 goto consider_string_end;
5357 } 5372 }
5358 else 5373 it->method = GET_FROM_BUFFER;
5359 it->method = next_element_from_buffer; 5374 break;
5375
5376 default:
5377 /* There are no other methods defined, so this should be a bug. */
5378 abort ();
5360 } 5379 }
5361 else
5362 /* There are no other methods defined, so this should be a bug. */
5363 abort ();
5364 5380
5365 xassert (it->method != next_element_from_string 5381 xassert (it->method != GET_FROM_STRING
5366 || (STRINGP (it->string) 5382 || (STRINGP (it->string)
5367 && IT_STRING_CHARPOS (*it) >= 0)); 5383 && IT_STRING_CHARPOS (*it) >= 0));
5368} 5384}
@@ -5574,7 +5590,7 @@ next_element_from_ellipsis (it)
5574 was in IT->saved_face_id, and signal that it's there by 5590 was in IT->saved_face_id, and signal that it's there by
5575 setting face_before_selective_p. */ 5591 setting face_before_selective_p. */
5576 it->saved_face_id = it->face_id; 5592 it->saved_face_id = it->face_id;
5577 it->method = next_element_from_buffer; 5593 it->method = GET_FROM_BUFFER;
5578 reseat_at_next_visible_line_start (it, 1); 5594 reseat_at_next_visible_line_start (it, 1);
5579 it->face_before_selective_p = 1; 5595 it->face_before_selective_p = 1;
5580 } 5596 }
@@ -5815,11 +5831,14 @@ move_it_in_display_line_to (it, to_charpos, to_x, op)
5815 saved_glyph_row = it->glyph_row; 5831 saved_glyph_row = it->glyph_row;
5816 it->glyph_row = NULL; 5832 it->glyph_row = NULL;
5817 5833
5818#define BUFFER_POS_REACHED_P() \ 5834#define BUFFER_POS_REACHED_P() \
5819 ((op & MOVE_TO_POS) != 0 \ 5835 ((op & MOVE_TO_POS) != 0 \
5820 && BUFFERP (it->object) \ 5836 && BUFFERP (it->object) \
5821 && IT_CHARPOS (*it) >= to_charpos \ 5837 && IT_CHARPOS (*it) >= to_charpos \
5822 && it->method == next_element_from_buffer) 5838 && (it->method == GET_FROM_BUFFER || \
5839 (it->method == GET_FROM_DISPLAY_VECTOR && \
5840 it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5841
5823 5842
5824 while (1) 5843 while (1)
5825 { 5844 {
@@ -6500,7 +6519,7 @@ int
6500in_display_vector_p (it) 6519in_display_vector_p (it)
6501 struct it *it; 6520 struct it *it;
6502{ 6521{
6503 return (it->method == next_element_from_display_vector 6522 return (it->method == GET_FROM_DISPLAY_VECTOR
6504 && it->current.dpvec_index > 0 6523 && it->current.dpvec_index > 0
6505 && it->dpvec + it->current.dpvec_index != it->dpend); 6524 && it->dpvec + it->current.dpvec_index != it->dpend);
6506} 6525}
@@ -15246,7 +15265,7 @@ display_line (it)
15246 15265
15247 /* Record whether this row ends inside an ellipsis. */ 15266 /* Record whether this row ends inside an ellipsis. */
15248 row->ends_in_ellipsis_p 15267 row->ends_in_ellipsis_p
15249 = (it->method == next_element_from_display_vector 15268 = (it->method == GET_FROM_DISPLAY_VECTOR
15250 && it->ellipsis_p); 15269 && it->ellipsis_p);
15251 15270
15252 /* Save fringe bitmaps in this row. */ 15271 /* Save fringe bitmaps in this row. */
diff --git a/src/xfns.c b/src/xfns.c
index 8c5039d0cf6..db2e3f74045 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1890,7 +1890,8 @@ hack_wm_protocols (f, widget)
1890 1890
1891 BLOCK_INPUT; 1891 BLOCK_INPUT;
1892 { 1892 {
1893 Atom type, *atoms = 0; 1893 Atom type;
1894 unsigned char *catoms;
1894 int format = 0; 1895 int format = 0;
1895 unsigned long nitems = 0; 1896 unsigned long nitems = 0;
1896 unsigned long bytes_after; 1897 unsigned long bytes_after;
@@ -1899,20 +1900,27 @@ hack_wm_protocols (f, widget)
1899 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, 1900 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
1900 (long)0, (long)100, False, XA_ATOM, 1901 (long)0, (long)100, False, XA_ATOM,
1901 &type, &format, &nitems, &bytes_after, 1902 &type, &format, &nitems, &bytes_after,
1902 (unsigned char **) &atoms) 1903 &catoms)
1903 == Success) 1904 == Success)
1904 && format == 32 && type == XA_ATOM) 1905 && format == 32 && type == XA_ATOM)
1905 while (nitems > 0) 1906 {
1906 { 1907 Atom *atoms = (Atom *) catoms;
1907 nitems--; 1908 while (nitems > 0)
1908 if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window) 1909 {
1909 need_delete = 0; 1910 nitems--;
1910 else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus) 1911 if (atoms[nitems]
1911 need_focus = 0; 1912 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window)
1912 else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself) 1913 need_delete = 0;
1913 need_save = 0; 1914 else if (atoms[nitems]
1914 } 1915 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus)
1915 if (atoms) XFree ((char *) atoms); 1916 need_focus = 0;
1917 else if (atoms[nitems]
1918 == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
1919 need_save = 0;
1920 }
1921 }
1922 if (catoms)
1923 XFree (catoms);
1916 } 1924 }
1917 { 1925 {
1918 Atom props [10]; 1926 Atom props [10];
@@ -4175,7 +4183,7 @@ no value of TYPE. */)
4175 Atom prop_atom; 4183 Atom prop_atom;
4176 int rc; 4184 int rc;
4177 Lisp_Object prop_value = Qnil; 4185 Lisp_Object prop_value = Qnil;
4178 char *tmp_data = NULL; 4186 unsigned char *tmp_data = NULL;
4179 Atom actual_type; 4187 Atom actual_type;
4180 Atom target_type = XA_STRING; 4188 Atom target_type = XA_STRING;
4181 int actual_format; 4189 int actual_format;
@@ -4215,7 +4223,7 @@ no value of TYPE. */)
4215 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window, 4223 rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
4216 prop_atom, 0, 0, False, target_type, 4224 prop_atom, 0, 0, False, target_type,
4217 &actual_type, &actual_format, &actual_size, 4225 &actual_type, &actual_format, &actual_size,
4218 &bytes_remaining, (unsigned char **) &tmp_data); 4226 &bytes_remaining, &tmp_data);
4219 if (rc == Success) 4227 if (rc == Success)
4220 { 4228 {
4221 int size = bytes_remaining; 4229 int size = bytes_remaining;
@@ -4228,7 +4236,7 @@ no value of TYPE. */)
4228 ! NILP (delete_p), target_type, 4236 ! NILP (delete_p), target_type,
4229 &actual_type, &actual_format, 4237 &actual_type, &actual_format,
4230 &actual_size, &bytes_remaining, 4238 &actual_size, &bytes_remaining,
4231 (unsigned char **) &tmp_data); 4239 &tmp_data);
4232 if (rc == Success && tmp_data) 4240 if (rc == Success && tmp_data)
4233 { 4241 {
4234 /* The man page for XGetWindowProperty says: 4242 /* The man page for XGetWindowProperty says:
@@ -4252,14 +4260,14 @@ no value of TYPE. */)
4252 long *ldata = (long *) tmp_data; 4260 long *ldata = (long *) tmp_data;
4253 4261
4254 for (i = 0; i < actual_size; ++i) 4262 for (i = 0; i < actual_size; ++i)
4255 idata[i]= (int) ldata[i]; 4263 idata[i] = (int) ldata[i];
4256 } 4264 }
4257 4265
4258 if (NILP (vector_ret_p)) 4266 if (NILP (vector_ret_p))
4259 prop_value = make_string (tmp_data, size); 4267 prop_value = make_string (tmp_data, size);
4260 else 4268 else
4261 prop_value = x_property_data_to_lisp (f, 4269 prop_value = x_property_data_to_lisp (f,
4262 (unsigned char *) tmp_data, 4270 tmp_data,
4263 actual_type, 4271 actual_type,
4264 actual_format, 4272 actual_format,
4265 actual_size); 4273 actual_size);
diff --git a/src/xselect.c b/src/xselect.c
index adea1f3c2d6..5a899cfa389 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1925,7 +1925,12 @@ lisp_data_to_selection_data (display, obj,
1925 } 1925 }
1926 else if (STRINGP (obj)) 1926 else if (STRINGP (obj))
1927 { 1927 {
1928 xassert (! STRING_MULTIBYTE (obj)); 1928 if (SCHARS (obj) < SBYTES (obj))
1929 /* OBJ is a multibyte string containing a non-ASCII char. */
1930 Fsignal (Qerror, /* Qselection_error */
1931 Fcons (build_string
1932 ("Non-ASCII string must be encoded in advance"),
1933 Fcons (obj, Qnil)));
1929 if (NILP (type)) 1934 if (NILP (type))
1930 type = QSTRING; 1935 type = QSTRING;
1931 *format_ret = 8; 1936 *format_ret = 8;
@@ -2201,7 +2206,10 @@ Disowning it means there is no such selection. */)
2201{ 2206{
2202 Time timestamp; 2207 Time timestamp;
2203 Atom selection_atom; 2208 Atom selection_atom;
2204 struct selection_input_event event; 2209 union {
2210 struct selection_input_event sie;
2211 struct input_event ie;
2212 } event;
2205 Display *display; 2213 Display *display;
2206 struct x_display_info *dpyinfo; 2214 struct x_display_info *dpyinfo;
2207 struct frame *sf = SELECTED_FRAME (); 2215 struct frame *sf = SELECTED_FRAME ();
@@ -2232,10 +2240,10 @@ Disowning it means there is no such selection. */)
2232 the selection owner to None. The NCD server does, the MIT Sun4 server 2240 the selection owner to None. The NCD server does, the MIT Sun4 server
2233 doesn't. So we synthesize one; this means we might get two, but 2241 doesn't. So we synthesize one; this means we might get two, but
2234 that's ok, because the second one won't have any effect. */ 2242 that's ok, because the second one won't have any effect. */
2235 SELECTION_EVENT_DISPLAY (&event) = display; 2243 SELECTION_EVENT_DISPLAY (&event.sie) = display;
2236 SELECTION_EVENT_SELECTION (&event) = selection_atom; 2244 SELECTION_EVENT_SELECTION (&event.sie) = selection_atom;
2237 SELECTION_EVENT_TIME (&event) = timestamp; 2245 SELECTION_EVENT_TIME (&event.sie) = timestamp;
2238 x_handle_selection_clear ((struct input_event *) &event); 2246 x_handle_selection_clear (&event.ie);
2239 2247
2240 return Qt; 2248 return Qt;
2241} 2249}
diff --git a/src/xterm.c b/src/xterm.c
index 367b7741fa6..aa3f8b1a8b5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -5622,8 +5622,8 @@ static struct x_display_info *next_noop_dpyinfo;
5622 f->output_data.x->saved_menu_event \ 5622 f->output_data.x->saved_menu_event \
5623 = (XEvent *) xmalloc (sizeof (XEvent)); \ 5623 = (XEvent *) xmalloc (sizeof (XEvent)); \
5624 bcopy (&event, f->output_data.x->saved_menu_event, size); \ 5624 bcopy (&event, f->output_data.x->saved_menu_event, size); \
5625 inev.kind = MENU_BAR_ACTIVATE_EVENT; \ 5625 inev.ie.kind = MENU_BAR_ACTIVATE_EVENT; \
5626 XSETFRAME (inev.frame_or_window, f); \ 5626 XSETFRAME (inev.ie.frame_or_window, f); \
5627 } \ 5627 } \
5628 while (0) 5628 while (0)
5629 5629
@@ -5730,7 +5730,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5730 int *finish; 5730 int *finish;
5731 struct input_event *hold_quit; 5731 struct input_event *hold_quit;
5732{ 5732{
5733 struct input_event inev; 5733 union {
5734 struct input_event ie;
5735 struct selection_input_event sie;
5736 } inev;
5734 int count = 0; 5737 int count = 0;
5735 int do_help = 0; 5738 int do_help = 0;
5736 int nbytes = 0; 5739 int nbytes = 0;
@@ -5740,9 +5743,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5740 5743
5741 *finish = X_EVENT_NORMAL; 5744 *finish = X_EVENT_NORMAL;
5742 5745
5743 EVENT_INIT (inev); 5746 EVENT_INIT (inev.ie);
5744 inev.kind = NO_EVENT; 5747 inev.ie.kind = NO_EVENT;
5745 inev.arg = Qnil; 5748 inev.ie.arg = Qnil;
5746 5749
5747 switch (event.type) 5750 switch (event.type)
5748 { 5751 {
@@ -5840,8 +5843,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5840 if (!f) 5843 if (!f)
5841 goto OTHER; /* May be a dialog that is to be removed */ 5844 goto OTHER; /* May be a dialog that is to be removed */
5842 5845
5843 inev.kind = DELETE_WINDOW_EVENT; 5846 inev.ie.kind = DELETE_WINDOW_EVENT;
5844 XSETFRAME (inev.frame_or_window, f); 5847 XSETFRAME (inev.ie.frame_or_window, f);
5845 goto done; 5848 goto done;
5846 } 5849 }
5847 5850
@@ -5904,7 +5907,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5904 if (event.xclient.message_type 5907 if (event.xclient.message_type
5905 == dpyinfo->Xatom_Scrollbar) 5908 == dpyinfo->Xatom_Scrollbar)
5906 { 5909 {
5907 x_scroll_bar_to_input_event (&event, &inev); 5910 x_scroll_bar_to_input_event (&event, &inev.ie);
5908 *finish = X_EVENT_GOTO_OUT; 5911 *finish = X_EVENT_GOTO_OUT;
5909 goto done; 5912 goto done;
5910 } 5913 }
@@ -5915,7 +5918,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5915 if (!f) 5918 if (!f)
5916 goto OTHER; 5919 goto OTHER;
5917 5920
5918 if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev)) 5921 if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
5919 *finish = X_EVENT_DROP; 5922 *finish = X_EVENT_DROP;
5920 } 5923 }
5921 break; 5924 break;
@@ -5936,11 +5939,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5936 { 5939 {
5937 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; 5940 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
5938 5941
5939 inev.kind = SELECTION_CLEAR_EVENT; 5942 inev.ie.kind = SELECTION_CLEAR_EVENT;
5940 SELECTION_EVENT_DISPLAY (&inev) = eventp->display; 5943 SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
5941 SELECTION_EVENT_SELECTION (&inev) = eventp->selection; 5944 SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
5942 SELECTION_EVENT_TIME (&inev) = eventp->time; 5945 SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
5943 inev.frame_or_window = Qnil; 5946 inev.ie.frame_or_window = Qnil;
5944 } 5947 }
5945 break; 5948 break;
5946 5949
@@ -5953,14 +5956,14 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
5953 XSelectionRequestEvent *eventp 5956 XSelectionRequestEvent *eventp
5954 = (XSelectionRequestEvent *) &event; 5957 = (XSelectionRequestEvent *) &event;
5955 5958
5956 inev.kind = SELECTION_REQUEST_EVENT; 5959 inev.ie.kind = SELECTION_REQUEST_EVENT;
5957 SELECTION_EVENT_DISPLAY (&inev) = eventp->display; 5960 SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
5958 SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor; 5961 SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
5959 SELECTION_EVENT_SELECTION (&inev) = eventp->selection; 5962 SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
5960 SELECTION_EVENT_TARGET (&inev) = eventp->target; 5963 SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
5961 SELECTION_EVENT_PROPERTY (&inev) = eventp->property; 5964 SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
5962 SELECTION_EVENT_TIME (&inev) = eventp->time; 5965 SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
5963 inev.frame_or_window = Qnil; 5966 inev.ie.frame_or_window = Qnil;
5964 } 5967 }
5965 break; 5968 break;
5966 5969
@@ -6099,8 +6102,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6099 { 6102 {
6100 f->async_iconified = 1; 6103 f->async_iconified = 1;
6101 6104
6102 inev.kind = ICONIFY_EVENT; 6105 inev.ie.kind = ICONIFY_EVENT;
6103 XSETFRAME (inev.frame_or_window, f); 6106 XSETFRAME (inev.ie.frame_or_window, f);
6104 } 6107 }
6105 } 6108 }
6106 goto OTHER; 6109 goto OTHER;
@@ -6132,8 +6135,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6132 6135
6133 if (f->iconified) 6136 if (f->iconified)
6134 { 6137 {
6135 inev.kind = DEICONIFY_EVENT; 6138 inev.ie.kind = DEICONIFY_EVENT;
6136 XSETFRAME (inev.frame_or_window, f); 6139 XSETFRAME (inev.ie.frame_or_window, f);
6137 } 6140 }
6138 else if (! NILP (Vframe_list) 6141 else if (! NILP (Vframe_list)
6139 && ! NILP (XCDR (Vframe_list))) 6142 && ! NILP (XCDR (Vframe_list)))
@@ -6299,18 +6302,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6299 orig_keysym = keysym; 6302 orig_keysym = keysym;
6300 6303
6301 /* Common for all keysym input events. */ 6304 /* Common for all keysym input events. */
6302 XSETFRAME (inev.frame_or_window, f); 6305 XSETFRAME (inev.ie.frame_or_window, f);
6303 inev.modifiers 6306 inev.ie.modifiers
6304 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers); 6307 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
6305 inev.timestamp = event.xkey.time; 6308 inev.ie.timestamp = event.xkey.time;
6306 6309
6307 /* First deal with keysyms which have defined 6310 /* First deal with keysyms which have defined
6308 translations to characters. */ 6311 translations to characters. */
6309 if (keysym >= 32 && keysym < 128) 6312 if (keysym >= 32 && keysym < 128)
6310 /* Avoid explicitly decoding each ASCII character. */ 6313 /* Avoid explicitly decoding each ASCII character. */
6311 { 6314 {
6312 inev.kind = ASCII_KEYSTROKE_EVENT; 6315 inev.ie.kind = ASCII_KEYSTROKE_EVENT;
6313 inev.code = keysym; 6316 inev.ie.code = keysym;
6314 goto done_keysym; 6317 goto done_keysym;
6315 } 6318 }
6316 6319
@@ -6320,10 +6323,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6320 Vx_keysym_table, 6323 Vx_keysym_table,
6321 Qnil)))) 6324 Qnil))))
6322 { 6325 {
6323 inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) 6326 inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
6324 ? ASCII_KEYSTROKE_EVENT 6327 ? ASCII_KEYSTROKE_EVENT
6325 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); 6328 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
6326 inev.code = XFASTINT (c); 6329 inev.ie.code = XFASTINT (c);
6327 goto done_keysym; 6330 goto done_keysym;
6328 } 6331 }
6329 6332
@@ -6413,8 +6416,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6413 STORE_KEYSYM_FOR_DEBUG (keysym); 6416 STORE_KEYSYM_FOR_DEBUG (keysym);
6414 /* make_lispy_event will convert this to a symbolic 6417 /* make_lispy_event will convert this to a symbolic
6415 key. */ 6418 key. */
6416 inev.kind = NON_ASCII_KEYSTROKE_EVENT; 6419 inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
6417 inev.code = keysym; 6420 inev.ie.code = keysym;
6418 goto done_keysym; 6421 goto done_keysym;
6419 } 6422 }
6420 6423
@@ -6465,18 +6468,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6465 else 6468 else
6466 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, 6469 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
6467 nbytes - i, len); 6470 nbytes - i, len);
6468 inev.kind = (SINGLE_BYTE_CHAR_P (c) 6471 inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
6469 ? ASCII_KEYSTROKE_EVENT 6472 ? ASCII_KEYSTROKE_EVENT
6470 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); 6473 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
6471 inev.code = c; 6474 inev.ie.code = c;
6472 kbd_buffer_store_event_hold (&inev, hold_quit); 6475 kbd_buffer_store_event_hold (&inev.ie, hold_quit);
6473 } 6476 }
6474 6477
6475 /* Previous code updated count by nchars rather than nbytes, 6478 /* Previous code updated count by nchars rather than nbytes,
6476 but that seems bogus to me. ++kfs */ 6479 but that seems bogus to me. ++kfs */
6477 count += nbytes; 6480 count += nbytes;
6478 6481
6479 inev.kind = NO_EVENT; /* Already stored above. */ 6482 inev.ie.kind = NO_EVENT; /* Already stored above. */
6480 6483
6481 if (keysym == NoSymbol) 6484 if (keysym == NoSymbol)
6482 break; 6485 break;
@@ -6503,7 +6506,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6503#endif 6506#endif
6504 6507
6505 case EnterNotify: 6508 case EnterNotify:
6506 x_detect_focus_change (dpyinfo, &event, &inev); 6509 x_detect_focus_change (dpyinfo, &event, &inev.ie);
6507 6510
6508 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); 6511 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
6509 6512
@@ -6533,11 +6536,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6533 goto OTHER; 6536 goto OTHER;
6534 6537
6535 case FocusIn: 6538 case FocusIn:
6536 x_detect_focus_change (dpyinfo, &event, &inev); 6539 x_detect_focus_change (dpyinfo, &event, &inev.ie);
6537 goto OTHER; 6540 goto OTHER;
6538 6541
6539 case LeaveNotify: 6542 case LeaveNotify:
6540 x_detect_focus_change (dpyinfo, &event, &inev); 6543 x_detect_focus_change (dpyinfo, &event, &inev.ie);
6541 6544
6542 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); 6545 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
6543 if (f) 6546 if (f)
@@ -6560,7 +6563,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6560 goto OTHER; 6563 goto OTHER;
6561 6564
6562 case FocusOut: 6565 case FocusOut:
6563 x_detect_focus_change (dpyinfo, &event, &inev); 6566 x_detect_focus_change (dpyinfo, &event, &inev.ie);
6564 goto OTHER; 6567 goto OTHER;
6565 6568
6566 case MotionNotify: 6569 case MotionNotify:
@@ -6600,8 +6603,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6600 && !EQ (window, last_window) 6603 && !EQ (window, last_window)
6601 && !EQ (window, selected_window)) 6604 && !EQ (window, selected_window))
6602 { 6605 {
6603 inev.kind = SELECT_WINDOW_EVENT; 6606 inev.ie.kind = SELECT_WINDOW_EVENT;
6604 inev.frame_or_window = window; 6607 inev.ie.frame_or_window = window;
6605 } 6608 }
6606 6609
6607 last_window=window; 6610 last_window=window;
@@ -6760,13 +6763,13 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6760 && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0) 6763 && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
6761 { 6764 {
6762 ignore_next_mouse_click_timeout = 0; 6765 ignore_next_mouse_click_timeout = 0;
6763 construct_mouse_click (&inev, &event, f); 6766 construct_mouse_click (&inev.ie, &event, f);
6764 } 6767 }
6765 if (event.type == ButtonRelease) 6768 if (event.type == ButtonRelease)
6766 ignore_next_mouse_click_timeout = 0; 6769 ignore_next_mouse_click_timeout = 0;
6767 } 6770 }
6768 else 6771 else
6769 construct_mouse_click (&inev, &event, f); 6772 construct_mouse_click (&inev.ie, &event, f);
6770 } 6773 }
6771 } 6774 }
6772 } 6775 }
@@ -6781,12 +6784,12 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6781 scroll bars. */ 6784 scroll bars. */
6782 if (bar && event.xbutton.state & ControlMask) 6785 if (bar && event.xbutton.state & ControlMask)
6783 { 6786 {
6784 x_scroll_bar_handle_click (bar, &event, &inev); 6787 x_scroll_bar_handle_click (bar, &event, &inev.ie);
6785 *finish = X_EVENT_DROP; 6788 *finish = X_EVENT_DROP;
6786 } 6789 }
6787#else /* not USE_TOOLKIT_SCROLL_BARS */ 6790#else /* not USE_TOOLKIT_SCROLL_BARS */
6788 if (bar) 6791 if (bar)
6789 x_scroll_bar_handle_click (bar, &event, &inev); 6792 x_scroll_bar_handle_click (bar, &event, &inev.ie);
6790#endif /* not USE_TOOLKIT_SCROLL_BARS */ 6793#endif /* not USE_TOOLKIT_SCROLL_BARS */
6791 } 6794 }
6792 6795
@@ -6894,9 +6897,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6894 } 6897 }
6895 6898
6896 done: 6899 done:
6897 if (inev.kind != NO_EVENT) 6900 if (inev.ie.kind != NO_EVENT)
6898 { 6901 {
6899 kbd_buffer_store_event_hold (&inev, hold_quit); 6902 kbd_buffer_store_event_hold (&inev.ie, hold_quit);
6900 count++; 6903 count++;
6901 } 6904 }
6902 6905