diff options
| author | Miles Bader | 2005-02-18 00:41:50 +0000 |
|---|---|---|
| committer | Miles Bader | 2005-02-18 00:41:50 +0000 |
| commit | 8d46efcc0f2045a1e5a2739c55ba6a88fbf4bcfc (patch) | |
| tree | bc968a02587d51199537bb335d5494e756e35fdf /src | |
| parent | 8589dc17f80450f5773a2d449fa6d94c9bb04fe3 (diff) | |
| parent | 9b516537a9899900647d4eae5ec8778e6837ad3c (diff) | |
| download | emacs-8d46efcc0f2045a1e5a2739c55ba6a88fbf4bcfc.tar.gz emacs-8d46efcc0f2045a1e5a2739c55ba6a88fbf4bcfc.zip | |
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-15
Merge from emacs--cvs-trunk--0
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
- miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-105
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 113 | ||||
| -rw-r--r-- | src/data.c | 4 | ||||
| -rw-r--r-- | src/dispextern.h | 15 | ||||
| -rw-r--r-- | src/doc.c | 11 | ||||
| -rw-r--r-- | src/emacs.c | 3 | ||||
| -rw-r--r-- | src/keyboard.c | 2 | ||||
| -rw-r--r-- | src/keymap.c | 77 | ||||
| -rw-r--r-- | src/keymap.h | 2 | ||||
| -rw-r--r-- | src/lread.c | 4 | ||||
| -rw-r--r-- | src/s/ms-w32.h | 2 | ||||
| -rw-r--r-- | src/w32.c | 2 | ||||
| -rw-r--r-- | src/w32.h | 22 | ||||
| -rw-r--r-- | src/w32select.c | 1079 | ||||
| -rw-r--r-- | src/xdisp.c | 149 | ||||
| -rw-r--r-- | src/xfns.c | 44 | ||||
| -rw-r--r-- | src/xselect.c | 20 | ||||
| -rw-r--r-- | src/xterm.c | 111 |
17 files changed, 1243 insertions, 417 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d2afed264eb..089a3f3a694 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,116 @@ | |||
| 1 | 2005-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 | |||
| 15 | 2005-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 | |||
| 32 | 2005-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 | |||
| 79 | 2005-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 | |||
| 84 | 2005-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 | |||
| 105 | 2005-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 | |||
| 1 | 2005-02-12 Dan Nicolaescu <dann@ics.uci.edu> | 114 | 2005-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/data.c b/src/data.c index c8b540cc4cc..a78ff68c7e4 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 | ||
| 1461 | DEFUN ("setq-default", Fsetq_default, Ssetq_default, 2, UNEVALLED, 0, | 1461 | DEFUN ("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. |
| 1463 | VAR, the variable name, is literal (not evaluated); | 1463 | VAR, the variable name, is literal (not evaluated); |
| 1464 | VALUE is an expression: it is evaluated and its value returned. | 1464 | VALUE 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 | |||
| 1470 | This sets each VAR's default value to the corresponding VALUE. | 1470 | This sets each VAR's default value to the corresponding VALUE. |
| 1471 | The VALUE for the Nth VAR can refer to the new default values | 1471 | The VALUE for the Nth VAR can refer to the new default values |
| 1472 | of previous VARs. | 1472 | of previous VARs. |
| 1473 | usage: (setq-default VAR VALUE [VAR VALUE...]) */) | 1473 | usage: (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 a438b305c35..19f35a744e8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1780,6 +1780,16 @@ struct it_slice | |||
| 1780 | Lisp_Object height; | 1780 | Lisp_Object height; |
| 1781 | }; | 1781 | }; |
| 1782 | 1782 | ||
| 1783 | enum it_method { | ||
| 1784 | GET_FROM_BUFFER = 0, | ||
| 1785 | GET_FROM_DISPLAY_VECTOR, | ||
| 1786 | GET_FROM_COMPOSITION, | ||
| 1787 | GET_FROM_STRING, | ||
| 1788 | GET_FROM_C_STRING, | ||
| 1789 | GET_FROM_IMAGE, | ||
| 1790 | GET_FROM_STRETCH, | ||
| 1791 | NUM_IT_METHODS | ||
| 1792 | }; | ||
| 1783 | 1793 | ||
| 1784 | struct it | 1794 | struct it |
| 1785 | { | 1795 | { |
| @@ -1790,9 +1800,8 @@ struct it | |||
| 1790 | /* The window's frame. */ | 1800 | /* The window's frame. */ |
| 1791 | struct frame *f; | 1801 | struct frame *f; |
| 1792 | 1802 | ||
| 1793 | /* Function to call to load this structure with the next display | 1803 | /* Method to use to load this structure with the next display element. */ |
| 1794 | element. */ | 1804 | enum it_method method; |
| 1795 | int (* method) P_ ((struct it *it)); | ||
| 1796 | 1805 | ||
| 1797 | /* The next position at which to check for face changes, invisible | 1806 | /* The next position at which to check for face changes, invisible |
| 1798 | text, overlay strings, end of text etc., which see. */ | 1807 | text, overlay strings, end of text etc., which see. */ |
| @@ -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 becab72ccdd..300f8ef6858 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" |
| @@ -1660,6 +1662,7 @@ main (argc, argv | |||
| 1660 | #ifdef HAVE_NTGUI | 1662 | #ifdef HAVE_NTGUI |
| 1661 | globals_of_w32fns (); | 1663 | globals_of_w32fns (); |
| 1662 | globals_of_w32menu (); | 1664 | globals_of_w32menu (); |
| 1665 | globals_of_w32select (); | ||
| 1663 | #endif /* HAVE_NTGUI */ | 1666 | #endif /* HAVE_NTGUI */ |
| 1664 | } | 1667 | } |
| 1665 | 1668 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index e10b111d12d..32d8a34216b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1442,7 +1442,7 @@ command_loop_1 () | |||
| 1442 | resize_echo_area_exactly (); | 1442 | resize_echo_area_exactly (); |
| 1443 | 1443 | ||
| 1444 | if (!NILP (Vdeferred_action_list)) | 1444 | if (!NILP (Vdeferred_action_list)) |
| 1445 | call0 (Vdeferred_action_function); | 1445 | safe_run_hooks (Qdeferred_action_function); |
| 1446 | 1446 | ||
| 1447 | if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks)) | 1447 | if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks)) |
| 1448 | { | 1448 | { |
diff --git a/src/keymap.c b/src/keymap.c index 2977b4dec09..3aaecf1a5d7 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -121,10 +121,11 @@ static void describe_command P_ ((Lisp_Object, Lisp_Object)); | |||
| 121 | static void describe_translation P_ ((Lisp_Object, Lisp_Object)); | 121 | static void describe_translation P_ ((Lisp_Object, Lisp_Object)); |
| 122 | static void describe_map P_ ((Lisp_Object, Lisp_Object, | 122 | static 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)); |
| 125 | static void describe_vector P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 125 | static 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)); | ||
| 128 | static void silly_event_symbol_error P_ ((Lisp_Object)); | 129 | static void silly_event_symbol_error P_ ((Lisp_Object)); |
| 129 | 130 | ||
| 130 | /* Keymap object support - constructors and predicates. */ | 131 | /* Keymap object support - constructors and predicates. */ |
| @@ -2853,7 +2854,7 @@ You type Translation\n\ | |||
| 2853 | 2854 | ||
| 2854 | if (!NILP (Vkey_translation_map)) | 2855 | if (!NILP (Vkey_translation_map)) |
| 2855 | describe_map_tree (Vkey_translation_map, 0, Qnil, prefix, | 2856 | describe_map_tree (Vkey_translation_map, 0, Qnil, prefix, |
| 2856 | "Key translations", nomenu, 1, 0); | 2857 | "Key translations", nomenu, 1, 0, 0); |
| 2857 | 2858 | ||
| 2858 | 2859 | ||
| 2859 | /* Print the (major mode) local map. */ | 2860 | /* Print the (major mode) local map. */ |
| @@ -2866,7 +2867,7 @@ You type Translation\n\ | |||
| 2866 | if (!NILP (start1)) | 2867 | if (!NILP (start1)) |
| 2867 | { | 2868 | { |
| 2868 | describe_map_tree (start1, 1, shadow, prefix, | 2869 | describe_map_tree (start1, 1, shadow, prefix, |
| 2869 | "\f\nOverriding Bindings", nomenu, 0, 0); | 2870 | "\f\nOverriding Bindings", nomenu, 0, 0, 0); |
| 2870 | shadow = Fcons (start1, shadow); | 2871 | shadow = Fcons (start1, shadow); |
| 2871 | } | 2872 | } |
| 2872 | else | 2873 | else |
| @@ -2887,7 +2888,8 @@ You type Translation\n\ | |||
| 2887 | if (!NILP (start1)) | 2888 | if (!NILP (start1)) |
| 2888 | { | 2889 | { |
| 2889 | describe_map_tree (start1, 1, shadow, prefix, | 2890 | describe_map_tree (start1, 1, shadow, prefix, |
| 2890 | "\f\n`keymap' Property Bindings", nomenu, 0, 0); | 2891 | "\f\n`keymap' Property Bindings", nomenu, |
| 2892 | 0, 0, 0); | ||
| 2891 | shadow = Fcons (start1, shadow); | 2893 | shadow = Fcons (start1, shadow); |
| 2892 | } | 2894 | } |
| 2893 | 2895 | ||
| @@ -2915,7 +2917,8 @@ You type Translation\n\ | |||
| 2915 | p += sizeof (" Minor Mode Bindings") - 1; | 2917 | p += sizeof (" Minor Mode Bindings") - 1; |
| 2916 | *p = 0; | 2918 | *p = 0; |
| 2917 | 2919 | ||
| 2918 | describe_map_tree (maps[i], 1, shadow, prefix, title, nomenu, 0, 0); | 2920 | describe_map_tree (maps[i], 1, shadow, prefix, |
| 2921 | title, nomenu, 0, 0, 0); | ||
| 2919 | shadow = Fcons (maps[i], shadow); | 2922 | shadow = Fcons (maps[i], shadow); |
| 2920 | } | 2923 | } |
| 2921 | 2924 | ||
| @@ -2925,23 +2928,23 @@ You type Translation\n\ | |||
| 2925 | { | 2928 | { |
| 2926 | if (EQ (start1, XBUFFER (buffer)->keymap)) | 2929 | if (EQ (start1, XBUFFER (buffer)->keymap)) |
| 2927 | describe_map_tree (start1, 1, shadow, prefix, | 2930 | describe_map_tree (start1, 1, shadow, prefix, |
| 2928 | "\f\nMajor Mode Bindings", nomenu, 0, 0); | 2931 | "\f\nMajor Mode Bindings", nomenu, 0, 0, 0); |
| 2929 | else | 2932 | else |
| 2930 | describe_map_tree (start1, 1, shadow, prefix, | 2933 | describe_map_tree (start1, 1, shadow, prefix, |
| 2931 | "\f\n`local-map' Property Bindings", | 2934 | "\f\n`local-map' Property Bindings", |
| 2932 | nomenu, 0, 0); | 2935 | nomenu, 0, 0, 0); |
| 2933 | 2936 | ||
| 2934 | shadow = Fcons (start1, shadow); | 2937 | shadow = Fcons (start1, shadow); |
| 2935 | } | 2938 | } |
| 2936 | } | 2939 | } |
| 2937 | 2940 | ||
| 2938 | describe_map_tree (current_global_map, 1, shadow, prefix, | 2941 | describe_map_tree (current_global_map, 1, shadow, prefix, |
| 2939 | "\f\nGlobal Bindings", nomenu, 0, 1); | 2942 | "\f\nGlobal Bindings", nomenu, 0, 1, 0); |
| 2940 | 2943 | ||
| 2941 | /* Print the function-key-map translations under this prefix. */ | 2944 | /* Print the function-key-map translations under this prefix. */ |
| 2942 | if (!NILP (Vfunction_key_map)) | 2945 | if (!NILP (Vfunction_key_map)) |
| 2943 | describe_map_tree (Vfunction_key_map, 0, Qnil, prefix, | 2946 | describe_map_tree (Vfunction_key_map, 0, Qnil, prefix, |
| 2944 | "\f\nFunction key map translations", nomenu, 1, 0); | 2947 | "\f\nFunction key map translations", nomenu, 1, 0, 0); |
| 2945 | 2948 | ||
| 2946 | UNGCPRO; | 2949 | UNGCPRO; |
| 2947 | return Qnil; | 2950 | return Qnil; |
| @@ -2962,17 +2965,21 @@ You type Translation\n\ | |||
| 2962 | so print strings and vectors differently. | 2965 | so print strings and vectors differently. |
| 2963 | 2966 | ||
| 2964 | If ALWAYS_TITLE is nonzero, print the title even if there are no maps | 2967 | If ALWAYS_TITLE is nonzero, print the title even if there are no maps |
| 2965 | to look through. */ | 2968 | to look through. |
| 2969 | |||
| 2970 | If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW, | ||
| 2971 | don't omit it; instead, mention it but say it is shadowed. */ | ||
| 2966 | 2972 | ||
| 2967 | void | 2973 | void |
| 2968 | describe_map_tree (startmap, partial, shadow, prefix, title, nomenu, transl, | 2974 | describe_map_tree (startmap, partial, shadow, prefix, title, nomenu, transl, |
| 2969 | always_title) | 2975 | always_title, mention_shadow) |
| 2970 | Lisp_Object startmap, shadow, prefix; | 2976 | Lisp_Object startmap, shadow, prefix; |
| 2971 | int partial; | 2977 | int partial; |
| 2972 | char *title; | 2978 | char *title; |
| 2973 | int nomenu; | 2979 | int nomenu; |
| 2974 | int transl; | 2980 | int transl; |
| 2975 | int always_title; | 2981 | int always_title; |
| 2982 | int mention_shadow; | ||
| 2976 | { | 2983 | { |
| 2977 | Lisp_Object maps, orig_maps, seen, sub_shadows; | 2984 | Lisp_Object maps, orig_maps, seen, sub_shadows; |
| 2978 | struct gcpro gcpro1, gcpro2, gcpro3; | 2985 | struct gcpro gcpro1, gcpro2, gcpro3; |
| @@ -3074,7 +3081,7 @@ key binding\n\ | |||
| 3074 | 3081 | ||
| 3075 | describe_map (Fcdr (elt), prefix, | 3082 | describe_map (Fcdr (elt), prefix, |
| 3076 | transl ? describe_translation : describe_command, | 3083 | transl ? describe_translation : describe_command, |
| 3077 | partial, sub_shadows, &seen, nomenu); | 3084 | partial, sub_shadows, &seen, nomenu, mention_shadow); |
| 3078 | 3085 | ||
| 3079 | skip: ; | 3086 | skip: ; |
| 3080 | } | 3087 | } |
| @@ -3154,7 +3161,8 @@ describe_translation (definition, args) | |||
| 3154 | PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ | 3161 | PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ |
| 3155 | 3162 | ||
| 3156 | static void | 3163 | static void |
| 3157 | describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu) | 3164 | describe_map (map, prefix, elt_describer, partial, shadow, |
| 3165 | seen, nomenu, mention_shadow) | ||
| 3158 | register Lisp_Object map; | 3166 | register Lisp_Object map; |
| 3159 | Lisp_Object prefix; | 3167 | Lisp_Object prefix; |
| 3160 | void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); | 3168 | void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); |
| @@ -3162,6 +3170,7 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu) | |||
| 3162 | Lisp_Object shadow; | 3170 | Lisp_Object shadow; |
| 3163 | Lisp_Object *seen; | 3171 | Lisp_Object *seen; |
| 3164 | int nomenu; | 3172 | int nomenu; |
| 3173 | int mention_shadow; | ||
| 3165 | { | 3174 | { |
| 3166 | Lisp_Object tail, definition, event; | 3175 | Lisp_Object tail, definition, event; |
| 3167 | Lisp_Object tem; | 3176 | Lisp_Object tem; |
| @@ -3191,9 +3200,10 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu) | |||
| 3191 | || CHAR_TABLE_P (XCAR (tail))) | 3200 | || CHAR_TABLE_P (XCAR (tail))) |
| 3192 | describe_vector (XCAR (tail), | 3201 | describe_vector (XCAR (tail), |
| 3193 | prefix, Qnil, elt_describer, partial, shadow, map, | 3202 | prefix, Qnil, elt_describer, partial, shadow, map, |
| 3194 | (int *)0, 0, 1); | 3203 | (int *)0, 0, 1, mention_shadow); |
| 3195 | else if (CONSP (XCAR (tail))) | 3204 | else if (CONSP (XCAR (tail))) |
| 3196 | { | 3205 | { |
| 3206 | int this_shadowed = 0; | ||
| 3197 | event = XCAR (XCAR (tail)); | 3207 | event = XCAR (XCAR (tail)); |
| 3198 | 3208 | ||
| 3199 | /* Ignore bindings whose "prefix" are not really valid events. | 3209 | /* Ignore bindings whose "prefix" are not really valid events. |
| @@ -3222,7 +3232,13 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu) | |||
| 3222 | if (!NILP (shadow)) | 3232 | if (!NILP (shadow)) |
| 3223 | { | 3233 | { |
| 3224 | tem = shadow_lookup (shadow, kludge, Qt); | 3234 | tem = shadow_lookup (shadow, kludge, Qt); |
| 3225 | if (!NILP (tem)) continue; | 3235 | if (!NILP (tem)) |
| 3236 | { | ||
| 3237 | if (mention_shadow) | ||
| 3238 | this_shadowed = 1; | ||
| 3239 | else | ||
| 3240 | continue; | ||
| 3241 | } | ||
| 3226 | } | 3242 | } |
| 3227 | 3243 | ||
| 3228 | tem = Flookup_key (map, kludge, Qt); | 3244 | tem = Flookup_key (map, kludge, Qt); |
| @@ -3242,6 +3258,13 @@ describe_map (map, prefix, elt_describer, partial, shadow, seen, nomenu) | |||
| 3242 | elt_describer will take care of spacing out far enough | 3258 | elt_describer will take care of spacing out far enough |
| 3243 | for alignment purposes. */ | 3259 | for alignment purposes. */ |
| 3244 | (*elt_describer) (definition, Qnil); | 3260 | (*elt_describer) (definition, Qnil); |
| 3261 | |||
| 3262 | if (this_shadowed) | ||
| 3263 | { | ||
| 3264 | SET_PT (PT - 1); | ||
| 3265 | insert_string (" (binding currently shadowed)"); | ||
| 3266 | SET_PT (PT + 1); | ||
| 3267 | } | ||
| 3245 | } | 3268 | } |
| 3246 | else if (EQ (XCAR (tail), Qkeymap)) | 3269 | else if (EQ (XCAR (tail), Qkeymap)) |
| 3247 | { | 3270 | { |
| @@ -3280,7 +3303,7 @@ DESCRIBER is the output function used; nil means use `princ'. */) | |||
| 3280 | specbind (Qstandard_output, Fcurrent_buffer ()); | 3303 | specbind (Qstandard_output, Fcurrent_buffer ()); |
| 3281 | CHECK_VECTOR_OR_CHAR_TABLE (vector); | 3304 | CHECK_VECTOR_OR_CHAR_TABLE (vector); |
| 3282 | describe_vector (vector, Qnil, describer, describe_vector_princ, 0, | 3305 | describe_vector (vector, Qnil, describer, describe_vector_princ, 0, |
| 3283 | Qnil, Qnil, (int *)0, 0, 0); | 3306 | Qnil, Qnil, (int *)0, 0, 0, 0); |
| 3284 | 3307 | ||
| 3285 | return unbind_to (count, Qnil); | 3308 | return unbind_to (count, Qnil); |
| 3286 | } | 3309 | } |
| @@ -3323,7 +3346,8 @@ DESCRIBER is the output function used; nil means use `princ'. */) | |||
| 3323 | static void | 3346 | static void |
| 3324 | describe_vector (vector, prefix, args, elt_describer, | 3347 | describe_vector (vector, prefix, args, elt_describer, |
| 3325 | partial, shadow, entire_map, | 3348 | partial, shadow, entire_map, |
| 3326 | indices, char_table_depth, keymap_p) | 3349 | indices, char_table_depth, keymap_p, |
| 3350 | mention_shadow) | ||
| 3327 | register Lisp_Object vector; | 3351 | register Lisp_Object vector; |
| 3328 | Lisp_Object prefix, args; | 3352 | Lisp_Object prefix, args; |
| 3329 | void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); | 3353 | void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); |
| @@ -3333,6 +3357,7 @@ describe_vector (vector, prefix, args, elt_describer, | |||
| 3333 | int *indices; | 3357 | int *indices; |
| 3334 | int char_table_depth; | 3358 | int char_table_depth; |
| 3335 | int keymap_p; | 3359 | int keymap_p; |
| 3360 | int mention_shadow; | ||
| 3336 | { | 3361 | { |
| 3337 | Lisp_Object definition; | 3362 | Lisp_Object definition; |
| 3338 | Lisp_Object tem2; | 3363 | Lisp_Object tem2; |
| @@ -3377,6 +3402,7 @@ describe_vector (vector, prefix, args, elt_describer, | |||
| 3377 | 3402 | ||
| 3378 | for (i = from; i < to; i++) | 3403 | for (i = from; i < to; i++) |
| 3379 | { | 3404 | { |
| 3405 | int this_shadowed = 0; | ||
| 3380 | int range_beg, range_end; | 3406 | int range_beg, range_end; |
| 3381 | Lisp_Object val; | 3407 | Lisp_Object val; |
| 3382 | 3408 | ||
| @@ -3412,7 +3438,13 @@ describe_vector (vector, prefix, args, elt_describer, | |||
| 3412 | 3438 | ||
| 3413 | tem = shadow_lookup (shadow, kludge, Qt); | 3439 | tem = shadow_lookup (shadow, kludge, Qt); |
| 3414 | 3440 | ||
| 3415 | if (!NILP (tem)) continue; | 3441 | if (!NILP (tem)) |
| 3442 | { | ||
| 3443 | if (mention_shadow) | ||
| 3444 | this_shadowed = 1; | ||
| 3445 | else | ||
| 3446 | continue; | ||
| 3447 | } | ||
| 3416 | } | 3448 | } |
| 3417 | 3449 | ||
| 3418 | /* Ignore this definition if it is shadowed by an earlier | 3450 | /* Ignore this definition if it is shadowed by an earlier |
| @@ -3477,6 +3509,13 @@ describe_vector (vector, prefix, args, elt_describer, | |||
| 3477 | elt_describer will take care of spacing out far enough | 3509 | elt_describer will take care of spacing out far enough |
| 3478 | for alignment purposes. */ | 3510 | for alignment purposes. */ |
| 3479 | (*elt_describer) (definition, args); | 3511 | (*elt_describer) (definition, args); |
| 3512 | |||
| 3513 | if (this_shadowed) | ||
| 3514 | { | ||
| 3515 | SET_PT (PT - 1); | ||
| 3516 | insert_string (" (binding currently shadowed)"); | ||
| 3517 | SET_PT (PT + 1); | ||
| 3518 | } | ||
| 3480 | } | 3519 | } |
| 3481 | 3520 | ||
| 3482 | if (CHAR_TABLE_P (vector) && ! NILP (XCHAR_TABLE (vector)->defalt)) | 3521 | if (CHAR_TABLE_P (vector) && ! NILP (XCHAR_TABLE (vector)->defalt)) |
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)); | |||
| 37 | extern Lisp_Object get_keyelt P_ ((Lisp_Object, int)); | 37 | extern Lisp_Object get_keyelt P_ ((Lisp_Object, int)); |
| 38 | extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int)); | 38 | extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int)); |
| 39 | extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object, | 39 | extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object, |
| 40 | char *, int, int, int)); | 40 | char *, int, int, int, int)); |
| 41 | extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **)); | 41 | extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **)); |
| 42 | extern void initial_define_key P_ ((Lisp_Object, int, char *)); | 42 | extern void initial_define_key P_ ((Lisp_Object, int, char *)); |
| 43 | extern void initial_define_lispy_key P_ ((Lisp_Object, char *, char *)); | 43 | extern void initial_define_lispy_key P_ ((Lisp_Object, char *, char *)); |
diff --git a/src/lread.c b/src/lread.c index ccd8909b971..709db3bf29e 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -3998,8 +3998,8 @@ as a function. */); | |||
| 3998 | 3998 | ||
| 3999 | DEFVAR_LISP ("user-init-file", &Vuser_init_file, | 3999 | DEFVAR_LISP ("user-init-file", &Vuser_init_file, |
| 4000 | doc: /* File name, including directory, of user's initialization file. | 4000 | doc: /* File name, including directory, of user's initialization file. |
| 4001 | If the file loaded had extension `.elc' and there was a corresponding `.el' | 4001 | If the file loaded had extension `.elc', and the corresponding source file |
| 4002 | file, this variable contains the name of the .el file, suitable for use | 4002 | exists, this variable contains the name of source file, suitable for use |
| 4003 | by functions like `custom-save-all' which edit the init file. */); | 4003 | by functions like `custom-save-all' which edit the init file. */); |
| 4004 | Vuser_init_file = Qnil; | 4004 | Vuser_init_file = Qnil; |
| 4005 | 4005 | ||
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 */ |
| @@ -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 | ||
| 3889 | void | 3891 | void |
| @@ -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. */ |
| 123 | extern LPBYTE w32_get_resource (char * key, LPDWORD type); | 123 | extern LPBYTE w32_get_resource (char * key, LPDWORD type); |
| 124 | 124 | ||
| 125 | extern void init_ntproc (); | 125 | extern void init_ntproc (void); |
| 126 | extern void term_ntproc (); | 126 | extern void term_ntproc (void); |
| 127 | extern void globals_of_w32 (); | 127 | extern void globals_of_w32 (void); |
| 128 | extern void syms_of_w32term (); | 128 | extern void syms_of_w32term (void); |
| 129 | extern void syms_of_w32fns (); | 129 | extern void syms_of_w32fns (void); |
| 130 | extern void globals_of_w32fns (); | 130 | extern void globals_of_w32fns (void); |
| 131 | extern void syms_of_w32select (); | 131 | extern void syms_of_w32select (void); |
| 132 | extern void syms_of_w32menu (); | 132 | extern void globals_of_w32select (void); |
| 133 | extern void globals_of_w32menu (); | 133 | extern void term_w32select (void); |
| 134 | extern void syms_of_fontset (); | 134 | extern void syms_of_w32menu (void); |
| 135 | extern void globals_of_w32menu (void); | ||
| 136 | extern 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 af3d477f876..478774663c8 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 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -18,261 +18,744 @@ along with GNU Emacs; see the file COPYING. If not, write to | |||
| 18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 19 | Boston, MA 02111-1307, USA. */ | 19 | Boston, 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 | |||
| 87 | static HGLOBAL convert_to_handle_as_ascii (void); | ||
| 88 | static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system); | ||
| 89 | static Lisp_Object render (Lisp_Object oformat); | ||
| 90 | static Lisp_Object render_locale (void); | ||
| 91 | static Lisp_Object render_all (void); | ||
| 92 | static void run_protected (Lisp_Object (*code) (), Lisp_Object arg); | ||
| 93 | static Lisp_Object lisp_error_handler (Lisp_Object error); | ||
| 94 | static LRESULT CALLBACK owner_callback (HWND win, UINT msg, | ||
| 95 | WPARAM wp, LPARAM lp); | ||
| 96 | static HWND create_owner (void); | ||
| 97 | |||
| 98 | static void setup_config (void); | ||
| 99 | static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string); | ||
| 100 | static UINT cp_from_locale (LCID lcid, UINT format); | ||
| 101 | static 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. */ | ||
| 35 | Lisp_Object QCLIPBOARD; | 107 | Lisp_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. */ |
| 39 | static Lisp_Object Vselection_coding_system; | 111 | static 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. */ |
| 42 | static Lisp_Object Vnext_selection_coding_system; | 114 | static 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. */ |
| 46 | static DWORD last_clipboard_sequence_number; | 118 | static LCID DEFAULT_LCID; |
| 47 | extern ClipboardSequence_Proc clipboard_sequence_fn; | 119 | static UINT ANSICP, OEMCP; |
| 48 | 120 | static 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 | 123 | static 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. */ | 126 | static int modifying_clipboard = 0; |
| 55 | static unsigned char *last_clipboard_text = NULL; | 127 | |
| 56 | static size_t clipboard_storage_size = 0; | 128 | /* Configured transfer parameters, based on the last inspection of |
| 57 | 129 | selection-coding-system. */ | |
| 58 | #if 0 | 130 | static Lisp_Object cfg_coding_system; |
| 59 | DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0, | 131 | static UINT cfg_codepage; |
| 60 | doc: /* This opens the clipboard with the given frame pointer. */) | 132 | static LCID cfg_lcid; |
| 61 | (frame) | 133 | static UINT cfg_clipboard_type; |
| 62 | Lisp_Object frame; | 134 | |
| 135 | /* The current state for delayed rendering. */ | ||
| 136 | static Lisp_Object current_text; | ||
| 137 | static Lisp_Object current_coding_system; | ||
| 138 | static int current_requires_encoding, current_num_nls; | ||
| 139 | static UINT current_clipboard_type; | ||
| 140 | static 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 | |||
| 152 | static HGLOBAL | ||
| 153 | convert_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 | ||
| 78 | DEFUN ("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. */ |
| 81 | Assigns ownership of the clipboard to the window which opened it. */) | 211 | |
| 82 | () | 212 | static HGLOBAL |
| 213 | convert_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; | ||
| 273 | } | ||
| 274 | |||
| 275 | static Lisp_Object | ||
| 276 | render (Lisp_Object oformat) | ||
| 277 | { | ||
| 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; | ||
| 93 | } | 321 | } |
| 94 | 322 | ||
| 95 | DEFUN ("w32-close-clipboard", Fw32_close_clipboard, | 323 | static Lisp_Object |
| 96 | Sw32_close_clipboard, 0, 0, 0, | 324 | render_locale (void) |
| 97 | doc: /* Close the clipboard. */) | ||
| 98 | () | ||
| 99 | { | 325 | { |
| 100 | BOOL ok = FALSE; | 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 | |||
| 359 | static Lisp_Object | ||
| 360 | render_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 | |||
| 417 | static void | ||
| 418 | run_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); | 441 | static Lisp_Object |
| 442 | lisp_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; | ||
| 109 | } | 448 | } |
| 110 | 449 | ||
| 111 | #endif | ||
| 112 | 450 | ||
| 113 | DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, | 451 | static LRESULT CALLBACK |
| 114 | Sw32_set_clipboard_data, 1, 2, 0, | 452 | owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp) |
| 115 | doc: /* This sets the clipboard data to the given text. */) | ||
| 116 | (string, frame) | ||
| 117 | Lisp_Object string, frame; | ||
| 118 | { | 453 | { |
| 119 | BOOL ok = TRUE; | 454 | switch (msg) |
| 120 | HANDLE htext; | 455 | { |
| 121 | int nbytes; | 456 | case WM_RENDERFORMAT: |
| 122 | int truelen, nlines = 0; | 457 | ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n")); |
| 123 | unsigned char *src; | 458 | run_protected (render, make_number (wp)); |
| 124 | unsigned char *dst; | 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; | ||
| 125 | 478 | ||
| 126 | CHECK_STRING (string); | 479 | case WM_DESTROY: |
| 480 | if (win == clipboard_owner) | ||
| 481 | clipboard_owner = NULL; | ||
| 482 | break; | ||
| 483 | } | ||
| 127 | 484 | ||
| 128 | if (!NILP (frame)) | 485 | return DefWindowProc (win, msg, wp, lp); |
| 129 | CHECK_LIVE_FRAME (frame); | 486 | } |
| 130 | 487 | ||
| 131 | BLOCK_INPUT; | 488 | static HWND |
| 489 | create_owner (void) | ||
| 490 | { | ||
| 491 | static const char CLASSNAME[] = "Emacs Clipboard"; | ||
| 492 | WNDCLASS wc; | ||
| 132 | 493 | ||
| 133 | /* Include the terminating NULL character in the source of | 494 | memset (&wc, 0, sizeof (wc)); |
| 134 | conversion. */ | 495 | wc.lpszClassName = CLASSNAME; |
| 135 | nbytes = SBYTES (string) + 1; | 496 | wc.lpfnWndProc = owner_callback; |
| 136 | src = SDATA (string); | 497 | RegisterClass (&wc); |
| 137 | dst = src; | 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 | |||
| 505 | void | ||
| 506 | term_w32select (void) | ||
| 507 | { | ||
| 508 | /* This is needed to trigger WM_RENDERALLFORMATS. */ | ||
| 509 | if (clipboard_owner != NULL) | ||
| 510 | DestroyWindow (clipboard_owner); | ||
| 511 | } | ||
| 138 | 512 | ||
| 139 | /* We need to know how many lines there are, since we need CRLF line | 513 | static void |
| 140 | termination for compatibility with other Windows Programs. | 514 | setup_config (void) |
| 141 | avoid using strchr because it recomputes the length every time */ | 515 | { |
| 142 | while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL) | 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] == '-')) | ||
| 143 | { | 543 | { |
| 144 | nlines++; | 544 | cfg_clipboard_type = CF_UNICODETEXT; |
| 145 | dst++; | 545 | return; |
| 146 | } | 546 | } |
| 147 | 547 | ||
| 148 | { | 548 | /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */ |
| 149 | /* Since we are now handling multilingual text, we must consider | 549 | slen = strlen (coding_name); |
| 150 | encoding text for the clipboard. */ | 550 | if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p') |
| 151 | int result = string_xstring_p (string); | 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 | } | ||
| 152 | 567 | ||
| 153 | if (result == 0) | 568 | /* Is it the currently active system default? */ |
| 154 | { | 569 | if (cfg_codepage == ANSICP) |
| 155 | /* No multibyte character in OBJ. We need not encode it. */ | 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 | } | ||
| 156 | 579 | ||
| 157 | /* Need to know final size after CR chars are inserted (the | 580 | /* Else determine a suitable locale the hard way. */ |
| 158 | standard CF_TEXT clipboard format uses CRLF line endings, | 581 | EnumSystemLocales (enum_locale_callback, LCID_INSTALLED); |
| 159 | while Emacs uses just LF internally). */ | 582 | } |
| 160 | 583 | ||
| 161 | truelen = nbytes + nlines; | 584 | static BOOL WINAPI |
| 585 | enum_locale_callback (/*const*/ char* loc_string) | ||
| 586 | { | ||
| 587 | LCID lcid; | ||
| 588 | UINT codepage; | ||
| 162 | 589 | ||
| 163 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) | 590 | lcid = strtoul (loc_string, NULL, 16); |
| 164 | goto error; | ||
| 165 | 591 | ||
| 166 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) | 592 | /* Is the wanted codepage the "ANSI" codepage for this locale? */ |
| 167 | goto error; | 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 | } | ||
| 168 | 609 | ||
| 169 | /* convert to CRLF line endings expected by clipboard */ | 610 | return TRUE; /* Continue enumeration */ |
| 170 | while (1) | 611 | } |
| 171 | { | ||
| 172 | unsigned char *next; | ||
| 173 | /* copy next line or remaining bytes including '\0' */ | ||
| 174 | next = _memccpy (dst, src, '\n', nbytes); | ||
| 175 | if (next) | ||
| 176 | { | ||
| 177 | /* copied one line ending with '\n' */ | ||
| 178 | int copied = next - dst; | ||
| 179 | nbytes -= copied; | ||
| 180 | src += copied; | ||
| 181 | /* insert '\r' before '\n' */ | ||
| 182 | next[-1] = '\r'; | ||
| 183 | next[0] = '\n'; | ||
| 184 | dst = next + 1; | ||
| 185 | } | ||
| 186 | else | ||
| 187 | /* copied remaining partial line -> now finished */ | ||
| 188 | break; | ||
| 189 | } | ||
| 190 | 612 | ||
| 191 | GlobalUnlock (htext); | 613 | static UINT |
| 614 | cp_from_locale (LCID lcid, UINT format) | ||
| 615 | { | ||
| 616 | char buffer[20] = ""; | ||
| 617 | UINT variant, cp; | ||
| 192 | 618 | ||
| 193 | Vlast_coding_system_used = Qraw_text; | 619 | variant = |
| 194 | } | 620 | format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE; |
| 195 | else | ||
| 196 | { | ||
| 197 | /* We must encode contents of OBJ to the selection coding | ||
| 198 | system. */ | ||
| 199 | struct coding_system coding; | ||
| 200 | HANDLE htext2; | ||
| 201 | 621 | ||
| 202 | if (NILP (Vnext_selection_coding_system)) | 622 | GetLocaleInfo (lcid, variant, buffer, sizeof (buffer)); |
| 203 | Vnext_selection_coding_system = Vselection_coding_system; | 623 | cp = strtoul (buffer, NULL, 10); |
| 204 | setup_coding_system | ||
| 205 | (Fcheck_coding_system (Vnext_selection_coding_system), &coding); | ||
| 206 | coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); | ||
| 207 | 624 | ||
| 208 | Vnext_selection_coding_system = Qnil; | 625 | if (cp == CP_ACP) |
| 626 | return ANSICP; | ||
| 627 | else if (cp == CP_OEMCP) | ||
| 628 | return OEMCP; | ||
| 629 | else | ||
| 630 | return cp; | ||
| 631 | } | ||
| 209 | 632 | ||
| 210 | /* We suppress producing escape sequences for composition. */ | 633 | static Lisp_Object |
| 211 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | 634 | coding_from_cp (UINT codepage) |
| 212 | coding.dst_bytes = SCHARS (string) * 2; | 635 | { |
| 213 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.dst_bytes)) == NULL) | 636 | char buffer[30]; |
| 214 | goto error; | 637 | sprintf (buffer, "cp%d-dos", (int) codepage); |
| 215 | if ((coding.destination = (unsigned char *) GlobalLock (htext)) == NULL) | 638 | return intern (buffer); |
| 216 | goto error; | 639 | /* We don't need to check that this coding system exists right here, |
| 217 | encode_coding_object (&coding, string, 0, 0, | 640 | because that is done when the coding system is actually |
| 218 | SCHARS (string), SBYTES (string), Qnil); | 641 | instantiated, i.e. it is passed through Fcheck_coding_system() |
| 219 | Vlast_coding_system_used = CODING_ID_NAME (coding.id); | 642 | there. */ |
| 643 | } | ||
| 220 | 644 | ||
| 221 | /* If clipboard sequence numbers are not supported, keep a copy for | ||
| 222 | later comparison. */ | ||
| 223 | if (!clipboard_sequence_fn) | ||
| 224 | { | ||
| 225 | /* Stash away the data we are about to put into the | ||
| 226 | clipboard, so we could later check inside | ||
| 227 | Fw32_get_clipboard_data whether the clipboard still | ||
| 228 | holds our data. */ | ||
| 229 | if (clipboard_storage_size < coding.produced) | ||
| 230 | { | ||
| 231 | clipboard_storage_size = coding.produced + 100; | ||
| 232 | last_clipboard_text = (char *) xrealloc (last_clipboard_text, | ||
| 233 | clipboard_storage_size); | ||
| 234 | } | ||
| 235 | if (last_clipboard_text) | ||
| 236 | memcpy (last_clipboard_text, coding.destination, | ||
| 237 | coding.produced); | ||
| 238 | } | ||
| 239 | 645 | ||
| 240 | GlobalUnlock (htext); | 646 | DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, |
| 647 | Sw32_set_clipboard_data, 1, 2, 0, | ||
| 648 | doc: /* This sets the clipboard data to the given text. */) | ||
| 649 | (string, ignored) | ||
| 650 | Lisp_Object string, ignored; | ||
| 651 | { | ||
| 652 | BOOL ok = TRUE; | ||
| 653 | int nbytes; | ||
| 654 | unsigned char *src; | ||
| 655 | unsigned char *dst; | ||
| 656 | unsigned char *end; | ||
| 241 | 657 | ||
| 242 | /* Shrink data block to actual size. */ | 658 | /* This parameter used to be the current frame, but we don't use |
| 243 | htext2 = GlobalReAlloc (htext, coding.produced, | 659 | that any more. */ |
| 244 | GMEM_MOVEABLE | GMEM_DDESHARE); | 660 | (void) ignored; |
| 245 | if (htext2 != NULL) htext = htext2; | ||
| 246 | } | ||
| 247 | } | ||
| 248 | 661 | ||
| 249 | if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) | 662 | CHECK_STRING (string); |
| 663 | |||
| 664 | setup_config (); | ||
| 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 | |||
| 673 | BLOCK_INPUT; | ||
| 674 | |||
| 675 | /* Check for non-ASCII characters. While we are at it, count the | ||
| 676 | number of LFs, so we know how many CRs we will have to add later | ||
| 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); | ||
| 680 | src = SDATA (string); | ||
| 681 | |||
| 682 | for (dst = src, end = src+nbytes; dst < end; dst++) | ||
| 683 | { | ||
| 684 | if (*dst == '\n') | ||
| 685 | current_num_nls++; | ||
| 686 | else if (*dst >= 0x80 || *dst == 0) | ||
| 687 | { | ||
| 688 | current_requires_encoding = 1; | ||
| 689 | break; | ||
| 690 | } | ||
| 691 | } | ||
| 692 | |||
| 693 | if (!current_requires_encoding) | ||
| 694 | { | ||
| 695 | /* If all we have is ASCII we don't need to pretend we offer | ||
| 696 | anything fancy. */ | ||
| 697 | current_coding_system = Qraw_text; | ||
| 698 | current_clipboard_type = CF_TEXT; | ||
| 699 | current_lcid = LOCALE_NEUTRAL; | ||
| 700 | } | ||
| 701 | |||
| 702 | if (!OpenClipboard (clipboard_owner)) | ||
| 250 | goto error; | 703 | goto error; |
| 251 | 704 | ||
| 252 | ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext); | 705 | ++modifying_clipboard; |
| 706 | ok = EmptyClipboard (); | ||
| 707 | --modifying_clipboard; | ||
| 708 | |||
| 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()); | ||
| 713 | |||
| 714 | if (ok) | ||
| 715 | { | ||
| 716 | if (clipboard_owner == NULL) | ||
| 717 | { | ||
| 718 | /* If for some reason we don't have a clipboard_owner, we | ||
| 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 | } | ||
| 253 | 736 | ||
| 254 | CloseClipboard (); | 737 | CloseClipboard (); |
| 255 | 738 | ||
| 256 | /* Common sense says to read the sequence number inside the | 739 | /* With delayed rendering we haven't really "used" this coding |
| 257 | OpenClipboard/ CloseClipboard block to avoid race conditions | 740 | system yet, and it's even unclear if we ever will. But this is a |
| 258 | where another app puts something on the clipboard straight after | 741 | way to tell the upper level what we *would* use under ideal |
| 259 | us. But experience suggests that the sequence number from the | 742 | circumstances. |
| 260 | SetClipboardData is not allocated until we close the clipboard! | 743 | |
| 261 | Since clipboard operations are normally user-driven, the race | 744 | We don't signal the actually used coding-system later when we |
| 262 | condition is probably not going to really happen. */ | 745 | finally render, because that can happen at any time and we don't |
| 263 | if (clipboard_sequence_fn) | 746 | want to disturb the "foreground" action. */ |
| 264 | last_clipboard_sequence_number = clipboard_sequence_fn (); | 747 | if (ok) |
| 748 | Vlast_coding_system_used = current_coding_system; | ||
| 749 | |||
| 750 | Vnext_selection_coding_system = Qnil; | ||
| 265 | 751 | ||
| 266 | if (ok) goto done; | 752 | if (ok) goto done; |
| 267 | 753 | ||
| 268 | error: | 754 | error: |
| 269 | 755 | ||
| 270 | ok = FALSE; | 756 | ok = FALSE; |
| 271 | if (htext) GlobalFree (htext); | 757 | current_text = Qnil; |
| 272 | if (last_clipboard_text) | 758 | current_coding_system = Qnil; |
| 273 | *last_clipboard_text = '\0'; | ||
| 274 | |||
| 275 | last_clipboard_sequence_number = 0; | ||
| 276 | 759 | ||
| 277 | done: | 760 | done: |
| 278 | UNBLOCK_INPUT; | 761 | UNBLOCK_INPUT; |
| @@ -280,24 +763,52 @@ DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, | |||
| 280 | return (ok ? string : Qnil); | 763 | return (ok ? string : Qnil); |
| 281 | } | 764 | } |
| 282 | 765 | ||
| 766 | |||
| 283 | DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | 767 | DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, |
| 284 | Sw32_get_clipboard_data, 0, 1, 0, | 768 | Sw32_get_clipboard_data, 0, 1, 0, |
| 285 | doc: /* This gets the clipboard data in text format. */) | 769 | doc: /* This gets the clipboard data in text format. */) |
| 286 | (frame) | 770 | (ignored) |
| 287 | Lisp_Object frame; | 771 | Lisp_Object ignored; |
| 288 | { | 772 | { |
| 289 | HANDLE htext; | 773 | HGLOBAL htext; |
| 290 | 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; | ||
| 291 | 781 | ||
| 292 | if (!NILP (frame)) | 782 | /* Don't pass our own text from the clipboard (which might be |
| 293 | 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; | ||
| 294 | 789 | ||
| 295 | BLOCK_INPUT; | 790 | BLOCK_INPUT; |
| 296 | 791 | ||
| 297 | if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) | 792 | if (!OpenClipboard (clipboard_owner)) |
| 298 | goto done; | 793 | goto done; |
| 299 | 794 | ||
| 300 | 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) | ||
| 301 | goto closeclip; | 812 | goto closeclip; |
| 302 | 813 | ||
| 303 | { | 814 | { |
| @@ -310,51 +821,105 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | |||
| 310 | if ((src = (unsigned char *) GlobalLock (htext)) == NULL) | 821 | if ((src = (unsigned char *) GlobalLock (htext)) == NULL) |
| 311 | goto closeclip; | 822 | goto closeclip; |
| 312 | 823 | ||
| 313 | nbytes = strlen (src); | 824 | /* If the clipboard data contains any non-ascii code, we need to |
| 314 | 825 | decode it with a coding system. */ | |
| 315 | /* If the text in clipboard is identical to what we put there | 826 | if (actual_clipboard_type == CF_UNICODETEXT) |
| 316 | last time w32_set_clipboard_data was called, pretend there's no | 827 | { |
| 317 | data in the clipboard. This is so we don't pass our own text | 828 | nbytes = lstrlenW ((WCHAR *)src) * 2; |
| 318 | from the clipboard (which might be troublesome if the killed | 829 | require_decoding = 1; |
| 319 | text includes null characters). */ | 830 | } |
| 320 | if ((clipboard_sequence_fn | 831 | else |
| 321 | && clipboard_sequence_fn () == last_clipboard_sequence_number) | 832 | { |
| 322 | || (last_clipboard_text | 833 | int i; |
| 323 | && clipboard_storage_size >= nbytes | ||
| 324 | && memcmp(last_clipboard_text, src, nbytes) == 0)) | ||
| 325 | goto closeclip; | ||
| 326 | 834 | ||
| 327 | { | 835 | nbytes = strlen (src); |
| 328 | /* If the clipboard data contains any non-ascii code, we | ||
| 329 | need to decode it. */ | ||
| 330 | int i; | ||
| 331 | 836 | ||
| 332 | for (i = 0; i < nbytes; i++) | 837 | for (i = 0; i < nbytes; i++) |
| 333 | { | 838 | { |
| 334 | if (src[i] >= 0x80) | 839 | if (src[i] >= 0x80) |
| 335 | { | 840 | { |
| 336 | require_decoding = 1; | 841 | require_decoding = 1; |
| 337 | break; | 842 | break; |
| 338 | } | 843 | } |
| 339 | } | 844 | } |
| 340 | } | 845 | } |
| 341 | 846 | ||
| 342 | if (require_decoding) | 847 | if (require_decoding) |
| 343 | { | 848 | { |
| 344 | struct coding_system coding; | 849 | struct coding_system coding; |
| 850 | Lisp_Object coding_system = Qnil; | ||
| 851 | |||
| 852 | /* `next-selection-coding-system' should override everything, | ||
| 853 | even when the locale passed by the system disagrees. The | ||
| 854 | only exception is when `next-selection-coding-system' | ||
| 855 | requested CF_UNICODETEXT and we couldn't get that. */ | ||
| 856 | if (use_configured_coding_system | ||
| 857 | && !NILP (Vnext_selection_coding_system)) | ||
| 858 | coding_system = Vnext_selection_coding_system; | ||
| 859 | |||
| 860 | /* If we have CF_TEXT or CF_OEMTEXT, we want to check out | ||
| 861 | CF_LOCALE, too. */ | ||
| 862 | else if (actual_clipboard_type != CF_UNICODETEXT) | ||
| 863 | { | ||
| 864 | HGLOBAL hlocale; | ||
| 865 | LCID lcid = DEFAULT_LCID; | ||
| 866 | UINT cp; | ||
| 867 | |||
| 868 | /* Documentation says that the OS always generates | ||
| 869 | CF_LOCALE info automatically, so the locale handle | ||
| 870 | should always be present. Fact is that this is not | ||
| 871 | always true on 9x ;-(. */ | ||
| 872 | hlocale = GetClipboardData (CF_LOCALE); | ||
| 873 | if (hlocale != NULL) | ||
| 874 | { | ||
| 875 | const LCID * lcid_ptr; | ||
| 876 | lcid_ptr = (const LCID *) GlobalLock (hlocale); | ||
| 877 | if (lcid_ptr != NULL) | ||
| 878 | { | ||
| 879 | lcid = *lcid_ptr; | ||
| 880 | GlobalUnlock (hlocale); | ||
| 881 | } | ||
| 882 | |||
| 883 | /* 9x has garbage as the sort order (to be exact there | ||
| 884 | is another instance of the language id in the upper | ||
| 885 | word). We don't care about sort order anyway, so | ||
| 886 | we just filter out the unneeded mis-information to | ||
| 887 | avoid irritations. */ | ||
| 888 | lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT); | ||
| 889 | } | ||
| 890 | |||
| 891 | /* If we are using fallback from CF_UNICODETEXT, we can't | ||
| 892 | use the configured coding system. Also we don't want | ||
| 893 | to use it, if the system has supplied us with a locale | ||
| 894 | and it is not just the system default. */ | ||
| 895 | if (!use_configured_coding_system || lcid != DEFAULT_LCID) | ||
| 896 | { | ||
| 897 | cp = cp_from_locale (lcid, actual_clipboard_type); | ||
| 898 | /* If it's just our current standard setting anyway, | ||
| 899 | use the coding system that the user has selected. | ||
| 900 | Otherwise create a new spec to match the locale | ||
| 901 | that was specified by the other side or the | ||
| 902 | system. */ | ||
| 903 | if (!use_configured_coding_system || cp != cfg_codepage) | ||
| 904 | coding_system = coding_from_cp (cp); | ||
| 905 | } | ||
| 906 | } | ||
| 907 | |||
| 908 | if (NILP (coding_system)) | ||
| 909 | coding_system = Vselection_coding_system; | ||
| 910 | Vnext_selection_coding_system = Qnil; | ||
| 345 | 911 | ||
| 346 | if (NILP (Vnext_selection_coding_system)) | 912 | setup_coding_system (Fcheck_coding_system (coding_system), &coding); |
| 347 | Vnext_selection_coding_system = Vselection_coding_system; | ||
| 348 | setup_coding_system | ||
| 349 | (Fcheck_coding_system (Vnext_selection_coding_system), &coding); | ||
| 350 | coding.src_multibyte = 0; | 913 | coding.src_multibyte = 0; |
| 351 | coding.dst_multibyte = 1; | 914 | coding.dst_multibyte = 1; |
| 352 | Vnext_selection_coding_system = Qnil; | ||
| 353 | coding.mode |= CODING_MODE_LAST_BLOCK; | 915 | coding.mode |= CODING_MODE_LAST_BLOCK; |
| 354 | /* We explicitly disable composition handling because | 916 | /* We explicitly disable composition handling because |
| 355 | selection data should not contain any composition | 917 | selection data should not contain any composition |
| 356 | sequence. */ | 918 | sequence. */ |
| 357 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | 919 | coding.common_flags &= ~CODING_ANNOTATION_MASK; |
| 920 | /* Force DOS line-ends. */ | ||
| 921 | coding.eol_type = CODING_EOL_CRLF; | ||
| 922 | |||
| 358 | coding.dst_bytes = nbytes * 2; | 923 | coding.dst_bytes = nbytes * 2; |
| 359 | coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); | 924 | coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); |
| 360 | decode_coding_c_string (&coding, src, nbytes, Qnil); | 925 | decode_coding_c_string (&coding, src, nbytes, Qnil); |
| @@ -365,10 +930,13 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | |||
| 365 | } | 930 | } |
| 366 | else | 931 | else |
| 367 | { | 932 | { |
| 368 | /* Need to know final size after CR chars are removed because we | 933 | /* FIXME: We may want to repeat the code in this branch for |
| 369 | can't change the string size manually, and doing an extra | 934 | the Unicode case. */ |
| 370 | copy is silly. Note that we only remove CR when it appears | 935 | |
| 371 | as part of CRLF. */ | 936 | /* Need to know final size after CR chars are removed because |
| 937 | we can't change the string size manually, and doing an | ||
| 938 | extra copy is silly. We only remove CR when it appears as | ||
| 939 | part of CRLF. */ | ||
| 372 | 940 | ||
| 373 | truelen = nbytes; | 941 | truelen = nbytes; |
| 374 | dst = src; | 942 | dst = src; |
| @@ -445,9 +1013,14 @@ and t is the same as `SECONDARY'. */) | |||
| 445 | 1013 | ||
| 446 | if (OpenClipboard (NULL)) | 1014 | if (OpenClipboard (NULL)) |
| 447 | { | 1015 | { |
| 448 | int format = 0; | 1016 | UINT format = 0; |
| 449 | while (format = EnumClipboardFormats (format)) | 1017 | setup_config (); |
| 450 | if (format == CF_TEXT) | 1018 | while ((format = EnumClipboardFormats (format))) |
| 1019 | /* Check CF_TEXT in addition to cfg_clipboard_type, | ||
| 1020 | because we can fall back on that if CF_UNICODETEXT is | ||
| 1021 | not available. Actually a check for CF_TEXT only | ||
| 1022 | should be enough. */ | ||
| 1023 | if (format == cfg_clipboard_type || format == CF_TEXT) | ||
| 451 | { | 1024 | { |
| 452 | val = Qt; | 1025 | val = Qt; |
| 453 | break; | 1026 | break; |
| @@ -459,24 +1032,25 @@ and t is the same as `SECONDARY'. */) | |||
| 459 | return Qnil; | 1032 | return Qnil; |
| 460 | } | 1033 | } |
| 461 | 1034 | ||
| 1035 | /* One-time init. Called in the un-dumped Emacs, but not in the | ||
| 1036 | dumped version. */ | ||
| 1037 | |||
| 462 | void | 1038 | void |
| 463 | syms_of_w32select () | 1039 | syms_of_w32select () |
| 464 | { | 1040 | { |
| 465 | #if 0 | ||
| 466 | defsubr (&Sw32_open_clipboard); | ||
| 467 | defsubr (&Sw32_empty_clipboard); | ||
| 468 | defsubr (&Sw32_close_clipboard); | ||
| 469 | #endif | ||
| 470 | defsubr (&Sw32_set_clipboard_data); | 1041 | defsubr (&Sw32_set_clipboard_data); |
| 471 | defsubr (&Sw32_get_clipboard_data); | 1042 | defsubr (&Sw32_get_clipboard_data); |
| 472 | defsubr (&Sx_selection_exists_p); | 1043 | defsubr (&Sx_selection_exists_p); |
| 473 | 1044 | ||
| 474 | DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, | 1045 | DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, |
| 475 | doc: /* Coding system for communicating with other programs. | 1046 | doc: /* Coding system for communicating with other programs. |
| 476 | When sending or receiving text via cut_buffer, selection, and clipboard, | 1047 | When sending or receiving text via cut_buffer, selection, and |
| 477 | the text is encoded or decoded by this coding system. | 1048 | clipboard, the text is encoded or decoded by this coding system. |
| 478 | The default value is `iso-latin-1-dos'. */); | 1049 | The default value is the current system default encoding on 9x/Me and |
| 479 | Vselection_coding_system = intern ("iso-latin-1-dos"); | 1050 | `utf-16le-dos' (Unicode) on NT/W2K/XP. */); |
| 1051 | /* The actual value is set dynamically in the dumped Emacs, see | ||
| 1052 | below. */ | ||
| 1053 | Vselection_coding_system = Qnil; | ||
| 480 | 1054 | ||
| 481 | DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, | 1055 | DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, |
| 482 | doc: /* Coding system for the next communication with other programs. | 1056 | doc: /* Coding system for the next communication with other programs. |
| @@ -487,6 +1061,41 @@ set to nil. */); | |||
| 487 | Vnext_selection_coding_system = Qnil; | 1061 | Vnext_selection_coding_system = Qnil; |
| 488 | 1062 | ||
| 489 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); | 1063 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); |
| 1064 | |||
| 1065 | cfg_coding_system = Qnil; staticpro (&cfg_coding_system); | ||
| 1066 | current_text = Qnil; staticpro (¤t_text); | ||
| 1067 | current_coding_system = Qnil; staticpro (¤t_coding_system); | ||
| 1068 | |||
| 1069 | QUNICODE = intern ("utf-16le-dos"); staticpro (&QUNICODE); | ||
| 1070 | QANSICP = Qnil; staticpro (&QANSICP); | ||
| 1071 | QOEMCP = Qnil; staticpro (&QOEMCP); | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | /* One-time init. Called in the dumped Emacs, but not in the | ||
| 1075 | un-dumped version. */ | ||
| 1076 | |||
| 1077 | void | ||
| 1078 | globals_of_w32select () | ||
| 1079 | { | ||
| 1080 | DEFAULT_LCID = GetUserDefaultLCID (); | ||
| 1081 | /* Drop the sort order from the LCID, so we can compare this with | ||
| 1082 | CF_LOCALE objects that have the same fix on 9x. */ | ||
| 1083 | DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT); | ||
| 1084 | |||
| 1085 | ANSICP = GetACP (); | ||
| 1086 | OEMCP = GetOEMCP (); | ||
| 1087 | |||
| 1088 | QANSICP = coding_from_cp (ANSICP); | ||
| 1089 | QOEMCP = coding_from_cp (OEMCP); | ||
| 1090 | |||
| 1091 | if (os_subtype == OS_NT) | ||
| 1092 | Vselection_coding_system = QUNICODE; | ||
| 1093 | else if (inhibit_window_system) | ||
| 1094 | Vselection_coding_system = QOEMCP; | ||
| 1095 | else | ||
| 1096 | Vselection_coding_system = QANSICP; | ||
| 1097 | |||
| 1098 | clipboard_owner = create_owner (); | ||
| 490 | } | 1099 | } |
| 491 | 1100 | ||
| 492 | /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af | 1101 | /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af |
diff --git a/src/xdisp.c b/src/xdisp.c index a90483aae1e..9aefcf5c9a5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -830,7 +830,6 @@ static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int)); | |||
| 830 | static int invisible_text_between_p P_ ((struct it *, int, int)); | 830 | static int invisible_text_between_p P_ ((struct it *, int, int)); |
| 831 | #endif | 831 | #endif |
| 832 | 832 | ||
| 833 | static int next_element_from_ellipsis P_ ((struct it *)); | ||
| 834 | static void pint2str P_ ((char *, int, int)); | 833 | static void pint2str P_ ((char *, int, int)); |
| 835 | static void pint2hrstr P_ ((char *, int, int)); | 834 | static void pint2hrstr P_ ((char *, int, int)); |
| 836 | static struct text_pos run_window_scroll_functions P_ ((Lisp_Object, | 835 | static struct text_pos run_window_scroll_functions P_ ((Lisp_Object, |
| @@ -905,6 +904,7 @@ static void reseat_1 P_ ((struct it *, struct text_pos, int)); | |||
| 905 | static void back_to_previous_visible_line_start P_ ((struct it *)); | 904 | static void back_to_previous_visible_line_start P_ ((struct it *)); |
| 906 | void reseat_at_previous_visible_line_start P_ ((struct it *)); | 905 | void reseat_at_previous_visible_line_start P_ ((struct it *)); |
| 907 | static void reseat_at_next_visible_line_start P_ ((struct it *, int)); | 906 | static void reseat_at_next_visible_line_start P_ ((struct it *, int)); |
| 907 | static int next_element_from_ellipsis P_ ((struct it *)); | ||
| 908 | static int next_element_from_display_vector P_ ((struct it *)); | 908 | static int next_element_from_display_vector P_ ((struct it *)); |
| 909 | static int next_element_from_string P_ ((struct it *)); | 909 | static int next_element_from_string P_ ((struct it *)); |
| 910 | static int next_element_from_c_string P_ ((struct it *)); | 910 | static int next_element_from_c_string P_ ((struct it *)); |
| @@ -2046,7 +2046,7 @@ static void | |||
| 2046 | check_it (it) | 2046 | check_it (it) |
| 2047 | struct it *it; | 2047 | struct it *it; |
| 2048 | { | 2048 | { |
| 2049 | if (it->method == next_element_from_string) | 2049 | if (it->method == GET_FROM_STRING) |
| 2050 | { | 2050 | { |
| 2051 | xassert (STRINGP (it->string)); | 2051 | xassert (STRINGP (it->string)); |
| 2052 | xassert (IT_STRING_CHARPOS (*it) >= 0); | 2052 | xassert (IT_STRING_CHARPOS (*it) >= 0); |
| @@ -2054,7 +2054,7 @@ check_it (it) | |||
| 2054 | else | 2054 | else |
| 2055 | { | 2055 | { |
| 2056 | xassert (IT_STRING_CHARPOS (*it) < 0); | 2056 | xassert (IT_STRING_CHARPOS (*it) < 0); |
| 2057 | if (it->method == next_element_from_buffer) | 2057 | if (it->method == GET_FROM_BUFFER) |
| 2058 | { | 2058 | { |
| 2059 | /* Check that character and byte positions agree. */ | 2059 | /* Check that character and byte positions agree. */ |
| 2060 | xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it))); | 2060 | xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it))); |
| @@ -2564,7 +2564,7 @@ init_from_display_pos (it, w, pos) | |||
| 2564 | property for an image, the iterator will be set up for that | 2564 | property for an image, the iterator will be set up for that |
| 2565 | image, and we have to undo that setup first before we can | 2565 | image, and we have to undo that setup first before we can |
| 2566 | correct the overlay string index. */ | 2566 | correct the overlay string index. */ |
| 2567 | if (it->method == next_element_from_image) | 2567 | if (it->method == GET_FROM_IMAGE) |
| 2568 | pop_it (it); | 2568 | pop_it (it); |
| 2569 | 2569 | ||
| 2570 | /* We already have the first chunk of overlay strings in | 2570 | /* We already have the first chunk of overlay strings in |
| @@ -2587,7 +2587,7 @@ init_from_display_pos (it, w, pos) | |||
| 2587 | it->string = it->overlay_strings[relative_index]; | 2587 | it->string = it->overlay_strings[relative_index]; |
| 2588 | xassert (STRINGP (it->string)); | 2588 | xassert (STRINGP (it->string)); |
| 2589 | it->current.string_pos = pos->string_pos; | 2589 | it->current.string_pos = pos->string_pos; |
| 2590 | it->method = next_element_from_string; | 2590 | it->method = GET_FROM_STRING; |
| 2591 | } | 2591 | } |
| 2592 | 2592 | ||
| 2593 | #if 0 /* This is bogus because POS not having an overlay string | 2593 | #if 0 /* This is bogus because POS not having an overlay string |
| @@ -2603,7 +2603,7 @@ init_from_display_pos (it, w, pos) | |||
| 2603 | while (it->sp) | 2603 | while (it->sp) |
| 2604 | pop_it (it); | 2604 | pop_it (it); |
| 2605 | it->current.overlay_string_index = -1; | 2605 | it->current.overlay_string_index = -1; |
| 2606 | it->method = next_element_from_buffer; | 2606 | it->method = GET_FROM_BUFFER; |
| 2607 | if (CHARPOS (pos->pos) == ZV) | 2607 | if (CHARPOS (pos->pos) == ZV) |
| 2608 | it->overlay_strings_at_end_processed_p = 1; | 2608 | it->overlay_strings_at_end_processed_p = 1; |
| 2609 | } | 2609 | } |
| @@ -2717,7 +2717,7 @@ handle_stop (it) | |||
| 2717 | { | 2717 | { |
| 2718 | /* Don't check for overlay strings below when set to deliver | 2718 | /* Don't check for overlay strings below when set to deliver |
| 2719 | characters from a display vector. */ | 2719 | characters from a display vector. */ |
| 2720 | if (it->method == next_element_from_display_vector) | 2720 | if (it->method == GET_FROM_DISPLAY_VECTOR) |
| 2721 | handle_overlay_change_p = 0; | 2721 | handle_overlay_change_p = 0; |
| 2722 | 2722 | ||
| 2723 | /* Handle overlay changes. */ | 2723 | /* Handle overlay changes. */ |
| @@ -3375,7 +3375,7 @@ setup_for_ellipsis (it, len) | |||
| 3375 | /* Remember the current face id in case glyphs specify faces. | 3375 | /* Remember the current face id in case glyphs specify faces. |
| 3376 | IT's face is restored in set_iterator_to_next. */ | 3376 | IT's face is restored in set_iterator_to_next. */ |
| 3377 | it->saved_face_id = it->face_id; | 3377 | it->saved_face_id = it->face_id; |
| 3378 | it->method = next_element_from_display_vector; | 3378 | it->method = GET_FROM_DISPLAY_VECTOR; |
| 3379 | it->ellipsis_p = 1; | 3379 | it->ellipsis_p = 1; |
| 3380 | } | 3380 | } |
| 3381 | 3381 | ||
| @@ -3740,7 +3740,7 @@ handle_single_display_spec (it, spec, object, position, | |||
| 3740 | it->image_id = -1; /* no image */ | 3740 | it->image_id = -1; /* no image */ |
| 3741 | it->position = start_pos; | 3741 | it->position = start_pos; |
| 3742 | it->object = NILP (object) ? it->w->buffer : object; | 3742 | it->object = NILP (object) ? it->w->buffer : object; |
| 3743 | it->method = next_element_from_image; | 3743 | it->method = GET_FROM_IMAGE; |
| 3744 | it->face_id = face_id; | 3744 | it->face_id = face_id; |
| 3745 | 3745 | ||
| 3746 | /* Say that we haven't consumed the characters with | 3746 | /* Say that we haven't consumed the characters with |
| @@ -3823,7 +3823,7 @@ handle_single_display_spec (it, spec, object, position, | |||
| 3823 | it->current.overlay_string_index = -1; | 3823 | it->current.overlay_string_index = -1; |
| 3824 | IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; | 3824 | IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; |
| 3825 | it->end_charpos = it->string_nchars = SCHARS (it->string); | 3825 | it->end_charpos = it->string_nchars = SCHARS (it->string); |
| 3826 | it->method = next_element_from_string; | 3826 | it->method = GET_FROM_STRING; |
| 3827 | it->stop_charpos = 0; | 3827 | it->stop_charpos = 0; |
| 3828 | it->string_from_display_prop_p = 1; | 3828 | it->string_from_display_prop_p = 1; |
| 3829 | /* Say that we haven't consumed the characters with | 3829 | /* Say that we haven't consumed the characters with |
| @@ -3833,7 +3833,7 @@ handle_single_display_spec (it, spec, object, position, | |||
| 3833 | } | 3833 | } |
| 3834 | else if (CONSP (value) && EQ (XCAR (value), Qspace)) | 3834 | else if (CONSP (value) && EQ (XCAR (value), Qspace)) |
| 3835 | { | 3835 | { |
| 3836 | it->method = next_element_from_stretch; | 3836 | it->method = GET_FROM_STRETCH; |
| 3837 | it->object = value; | 3837 | it->object = value; |
| 3838 | it->current.pos = it->position = start_pos; | 3838 | it->current.pos = it->position = start_pos; |
| 3839 | } | 3839 | } |
| @@ -3844,7 +3844,7 @@ handle_single_display_spec (it, spec, object, position, | |||
| 3844 | it->image_id = lookup_image (it->f, value); | 3844 | it->image_id = lookup_image (it->f, value); |
| 3845 | it->position = start_pos; | 3845 | it->position = start_pos; |
| 3846 | it->object = NILP (object) ? it->w->buffer : object; | 3846 | it->object = NILP (object) ? it->w->buffer : object; |
| 3847 | it->method = next_element_from_image; | 3847 | it->method = GET_FROM_IMAGE; |
| 3848 | 3848 | ||
| 3849 | /* Say that we haven't consumed the characters with | 3849 | /* Say that we haven't consumed the characters with |
| 3850 | `display' property yet. The call to pop_it in | 3850 | `display' property yet. The call to pop_it in |
| @@ -4193,7 +4193,7 @@ handle_composition_prop (it) | |||
| 4193 | 4193 | ||
| 4194 | if (id >= 0) | 4194 | if (id >= 0) |
| 4195 | { | 4195 | { |
| 4196 | it->method = next_element_from_composition; | 4196 | it->method = GET_FROM_COMPOSITION; |
| 4197 | it->cmp_id = id; | 4197 | it->cmp_id = id; |
| 4198 | it->cmp_len = COMPOSITION_LENGTH (prop); | 4198 | it->cmp_len = COMPOSITION_LENGTH (prop); |
| 4199 | /* For a terminal, draw only the first character of the | 4199 | /* For a terminal, draw only the first character of the |
| @@ -4268,7 +4268,7 @@ next_overlay_string (it) | |||
| 4268 | it->current.overlay_string_index = -1; | 4268 | it->current.overlay_string_index = -1; |
| 4269 | SET_TEXT_POS (it->current.string_pos, -1, -1); | 4269 | SET_TEXT_POS (it->current.string_pos, -1, -1); |
| 4270 | it->n_overlay_strings = 0; | 4270 | it->n_overlay_strings = 0; |
| 4271 | it->method = next_element_from_buffer; | 4271 | it->method = GET_FROM_BUFFER; |
| 4272 | 4272 | ||
| 4273 | /* If we're at the end of the buffer, record that we have | 4273 | /* If we're at the end of the buffer, record that we have |
| 4274 | processed the overlay strings there already, so that | 4274 | processed the overlay strings there already, so that |
| @@ -4297,7 +4297,7 @@ next_overlay_string (it) | |||
| 4297 | it->string = it->overlay_strings[i]; | 4297 | it->string = it->overlay_strings[i]; |
| 4298 | it->multibyte_p = STRING_MULTIBYTE (it->string); | 4298 | it->multibyte_p = STRING_MULTIBYTE (it->string); |
| 4299 | SET_TEXT_POS (it->current.string_pos, 0, 0); | 4299 | SET_TEXT_POS (it->current.string_pos, 0, 0); |
| 4300 | it->method = next_element_from_string; | 4300 | it->method = GET_FROM_STRING; |
| 4301 | it->stop_charpos = 0; | 4301 | it->stop_charpos = 0; |
| 4302 | } | 4302 | } |
| 4303 | 4303 | ||
| @@ -4562,13 +4562,13 @@ get_overlay_strings (it, charpos) | |||
| 4562 | xassert (STRINGP (it->string)); | 4562 | xassert (STRINGP (it->string)); |
| 4563 | it->end_charpos = SCHARS (it->string); | 4563 | it->end_charpos = SCHARS (it->string); |
| 4564 | it->multibyte_p = STRING_MULTIBYTE (it->string); | 4564 | it->multibyte_p = STRING_MULTIBYTE (it->string); |
| 4565 | it->method = next_element_from_string; | 4565 | it->method = GET_FROM_STRING; |
| 4566 | } | 4566 | } |
| 4567 | else | 4567 | else |
| 4568 | { | 4568 | { |
| 4569 | it->string = Qnil; | 4569 | it->string = Qnil; |
| 4570 | it->current.overlay_string_index = -1; | 4570 | it->current.overlay_string_index = -1; |
| 4571 | it->method = next_element_from_buffer; | 4571 | it->method = GET_FROM_BUFFER; |
| 4572 | } | 4572 | } |
| 4573 | 4573 | ||
| 4574 | CHECK_IT (it); | 4574 | CHECK_IT (it); |
| @@ -4946,7 +4946,7 @@ reseat_1 (it, pos, set_stop_p) | |||
| 4946 | IT_STRING_CHARPOS (*it) = -1; | 4946 | IT_STRING_CHARPOS (*it) = -1; |
| 4947 | IT_STRING_BYTEPOS (*it) = -1; | 4947 | IT_STRING_BYTEPOS (*it) = -1; |
| 4948 | it->string = Qnil; | 4948 | it->string = Qnil; |
| 4949 | it->method = next_element_from_buffer; | 4949 | it->method = GET_FROM_BUFFER; |
| 4950 | /* RMS: I added this to fix a bug in move_it_vertically_backward | 4950 | /* RMS: I added this to fix a bug in move_it_vertically_backward |
| 4951 | where it->area continued to relate to the starting point | 4951 | where it->area continued to relate to the starting point |
| 4952 | for the backward motion. Bug report from | 4952 | for the backward motion. Bug report from |
| @@ -5012,7 +5012,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte) | |||
| 5012 | it->string = string; | 5012 | it->string = string; |
| 5013 | it->s = NULL; | 5013 | it->s = NULL; |
| 5014 | it->end_charpos = it->string_nchars = SCHARS (string); | 5014 | it->end_charpos = it->string_nchars = SCHARS (string); |
| 5015 | it->method = next_element_from_string; | 5015 | it->method = GET_FROM_STRING; |
| 5016 | it->current.string_pos = string_pos (charpos, string); | 5016 | it->current.string_pos = string_pos (charpos, string); |
| 5017 | } | 5017 | } |
| 5018 | else | 5018 | else |
| @@ -5034,7 +5034,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte) | |||
| 5034 | it->end_charpos = it->string_nchars = strlen (s); | 5034 | it->end_charpos = it->string_nchars = strlen (s); |
| 5035 | } | 5035 | } |
| 5036 | 5036 | ||
| 5037 | it->method = next_element_from_c_string; | 5037 | it->method = GET_FROM_C_STRING; |
| 5038 | } | 5038 | } |
| 5039 | 5039 | ||
| 5040 | /* PRECISION > 0 means don't return more than PRECISION characters | 5040 | /* PRECISION > 0 means don't return more than PRECISION characters |
| @@ -5065,6 +5065,20 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte) | |||
| 5065 | Iteration | 5065 | Iteration |
| 5066 | ***********************************************************************/ | 5066 | ***********************************************************************/ |
| 5067 | 5067 | ||
| 5068 | /* Map enum it_method value to corresponding next_element_from_* function. */ | ||
| 5069 | |||
| 5070 | static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) = | ||
| 5071 | { | ||
| 5072 | next_element_from_buffer, | ||
| 5073 | next_element_from_display_vector, | ||
| 5074 | next_element_from_composition, | ||
| 5075 | next_element_from_string, | ||
| 5076 | next_element_from_c_string, | ||
| 5077 | next_element_from_image, | ||
| 5078 | next_element_from_stretch | ||
| 5079 | }; | ||
| 5080 | |||
| 5081 | |||
| 5068 | /* Load IT's display element fields with information about the next | 5082 | /* Load IT's display element fields with information about the next |
| 5069 | display element from the current position of IT. Value is zero if | 5083 | display element from the current position of IT. Value is zero if |
| 5070 | end of buffer (or C string) is reached. */ | 5084 | end of buffer (or C string) is reached. */ |
| @@ -5080,7 +5094,7 @@ get_next_display_element (it) | |||
| 5080 | int success_p; | 5094 | int success_p; |
| 5081 | 5095 | ||
| 5082 | get_next: | 5096 | get_next: |
| 5083 | success_p = (*it->method) (it); | 5097 | success_p = (*get_next_element[it->method]) (it); |
| 5084 | 5098 | ||
| 5085 | if (it->what == IT_CHARACTER) | 5099 | if (it->what == IT_CHARACTER) |
| 5086 | { | 5100 | { |
| @@ -5114,7 +5128,7 @@ get_next_display_element (it) | |||
| 5114 | it->current.dpvec_index = 0; | 5128 | it->current.dpvec_index = 0; |
| 5115 | it->dpvec_face_id = -1; | 5129 | it->dpvec_face_id = -1; |
| 5116 | it->saved_face_id = it->face_id; | 5130 | it->saved_face_id = it->face_id; |
| 5117 | it->method = next_element_from_display_vector; | 5131 | it->method = GET_FROM_DISPLAY_VECTOR; |
| 5118 | it->ellipsis_p = 0; | 5132 | it->ellipsis_p = 0; |
| 5119 | } | 5133 | } |
| 5120 | else | 5134 | else |
| @@ -5139,7 +5153,7 @@ get_next_display_element (it) | |||
| 5139 | else if ((it->c < ' ' | 5153 | else if ((it->c < ' ' |
| 5140 | ? (it->area != TEXT_AREA | 5154 | ? (it->area != TEXT_AREA |
| 5141 | /* In mode line, treat \n, \t like other crl chars. */ | 5155 | /* In mode line, treat \n, \t like other crl chars. */ |
| 5142 | || (it->c != '\n' | 5156 | || (it->c != '\t' |
| 5143 | && it->glyph_row && it->glyph_row->mode_line_p) | 5157 | && it->glyph_row && it->glyph_row->mode_line_p) |
| 5144 | || (it->c != '\n' && it->c != '\t')) | 5158 | || (it->c != '\n' && it->c != '\t')) |
| 5145 | : (it->multibyte_p | 5159 | : (it->multibyte_p |
| @@ -5274,7 +5288,7 @@ get_next_display_element (it) | |||
| 5274 | it->current.dpvec_index = 0; | 5288 | it->current.dpvec_index = 0; |
| 5275 | it->dpvec_face_id = face_id; | 5289 | it->dpvec_face_id = face_id; |
| 5276 | it->saved_face_id = it->face_id; | 5290 | it->saved_face_id = it->face_id; |
| 5277 | it->method = next_element_from_display_vector; | 5291 | it->method = GET_FROM_DISPLAY_VECTOR; |
| 5278 | it->ellipsis_p = 0; | 5292 | it->ellipsis_p = 0; |
| 5279 | goto get_next; | 5293 | goto get_next; |
| 5280 | } | 5294 | } |
| @@ -5340,8 +5354,9 @@ set_iterator_to_next (it, reseat_p) | |||
| 5340 | moving the iterator to a new position might set them. */ | 5354 | moving the iterator to a new position might set them. */ |
| 5341 | it->start_of_box_run_p = it->end_of_box_run_p = 0; | 5355 | it->start_of_box_run_p = it->end_of_box_run_p = 0; |
| 5342 | 5356 | ||
| 5343 | if (it->method == next_element_from_buffer) | 5357 | switch (it->method) |
| 5344 | { | 5358 | { |
| 5359 | case GET_FROM_BUFFER: | ||
| 5345 | /* The current display element of IT is a character from | 5360 | /* The current display element of IT is a character from |
| 5346 | current_buffer. Advance in the buffer, and maybe skip over | 5361 | current_buffer. Advance in the buffer, and maybe skip over |
| 5347 | invisible lines that are so because of selective display. */ | 5362 | invisible lines that are so because of selective display. */ |
| @@ -5354,32 +5369,32 @@ set_iterator_to_next (it, reseat_p) | |||
| 5354 | IT_CHARPOS (*it) += 1; | 5369 | IT_CHARPOS (*it) += 1; |
| 5355 | xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); | 5370 | xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); |
| 5356 | } | 5371 | } |
| 5357 | } | 5372 | break; |
| 5358 | else if (it->method == next_element_from_composition) | 5373 | |
| 5359 | { | 5374 | case GET_FROM_COMPOSITION: |
| 5360 | xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions); | 5375 | xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions); |
| 5361 | if (STRINGP (it->string)) | 5376 | if (STRINGP (it->string)) |
| 5362 | { | 5377 | { |
| 5363 | IT_STRING_BYTEPOS (*it) += it->len; | 5378 | IT_STRING_BYTEPOS (*it) += it->len; |
| 5364 | IT_STRING_CHARPOS (*it) += it->cmp_len; | 5379 | IT_STRING_CHARPOS (*it) += it->cmp_len; |
| 5365 | it->method = next_element_from_string; | 5380 | it->method = GET_FROM_STRING; |
| 5366 | goto consider_string_end; | 5381 | goto consider_string_end; |
| 5367 | } | 5382 | } |
| 5368 | else | 5383 | else |
| 5369 | { | 5384 | { |
| 5370 | IT_BYTEPOS (*it) += it->len; | 5385 | IT_BYTEPOS (*it) += it->len; |
| 5371 | IT_CHARPOS (*it) += it->cmp_len; | 5386 | IT_CHARPOS (*it) += it->cmp_len; |
| 5372 | it->method = next_element_from_buffer; | 5387 | it->method = GET_FROM_BUFFER; |
| 5373 | } | 5388 | } |
| 5374 | } | 5389 | break; |
| 5375 | else if (it->method == next_element_from_c_string) | 5390 | |
| 5376 | { | 5391 | case GET_FROM_C_STRING: |
| 5377 | /* Current display element of IT is from a C string. */ | 5392 | /* Current display element of IT is from a C string. */ |
| 5378 | IT_BYTEPOS (*it) += it->len; | 5393 | IT_BYTEPOS (*it) += it->len; |
| 5379 | IT_CHARPOS (*it) += 1; | 5394 | IT_CHARPOS (*it) += 1; |
| 5380 | } | 5395 | break; |
| 5381 | else if (it->method == next_element_from_display_vector) | 5396 | |
| 5382 | { | 5397 | case GET_FROM_DISPLAY_VECTOR: |
| 5383 | /* Current display element of IT is from a display table entry. | 5398 | /* Current display element of IT is from a display table entry. |
| 5384 | Advance in the display table definition. Reset it to null if | 5399 | Advance in the display table definition. Reset it to null if |
| 5385 | end reached, and continue with characters from buffers/ | 5400 | end reached, and continue with characters from buffers/ |
| @@ -5393,11 +5408,11 @@ set_iterator_to_next (it, reseat_p) | |||
| 5393 | if (it->dpvec + it->current.dpvec_index == it->dpend) | 5408 | if (it->dpvec + it->current.dpvec_index == it->dpend) |
| 5394 | { | 5409 | { |
| 5395 | if (it->s) | 5410 | if (it->s) |
| 5396 | it->method = next_element_from_c_string; | 5411 | it->method = GET_FROM_C_STRING; |
| 5397 | else if (STRINGP (it->string)) | 5412 | else if (STRINGP (it->string)) |
| 5398 | it->method = next_element_from_string; | 5413 | it->method = GET_FROM_STRING; |
| 5399 | else | 5414 | else |
| 5400 | it->method = next_element_from_buffer; | 5415 | it->method = GET_FROM_BUFFER; |
| 5401 | 5416 | ||
| 5402 | it->dpvec = NULL; | 5417 | it->dpvec = NULL; |
| 5403 | it->current.dpvec_index = -1; | 5418 | it->current.dpvec_index = -1; |
| @@ -5414,9 +5429,9 @@ set_iterator_to_next (it, reseat_p) | |||
| 5414 | /* Recheck faces after display vector */ | 5429 | /* Recheck faces after display vector */ |
| 5415 | it->stop_charpos = IT_CHARPOS (*it); | 5430 | it->stop_charpos = IT_CHARPOS (*it); |
| 5416 | } | 5431 | } |
| 5417 | } | 5432 | break; |
| 5418 | else if (it->method == next_element_from_string) | 5433 | |
| 5419 | { | 5434 | case GET_FROM_STRING: |
| 5420 | /* Current display element is a character from a Lisp string. */ | 5435 | /* Current display element is a character from a Lisp string. */ |
| 5421 | xassert (it->s == NULL && STRINGP (it->string)); | 5436 | xassert (it->s == NULL && STRINGP (it->string)); |
| 5422 | IT_STRING_BYTEPOS (*it) += it->len; | 5437 | IT_STRING_BYTEPOS (*it) += it->len; |
| @@ -5441,34 +5456,35 @@ set_iterator_to_next (it, reseat_p) | |||
| 5441 | && it->sp > 0) | 5456 | && it->sp > 0) |
| 5442 | { | 5457 | { |
| 5443 | pop_it (it); | 5458 | pop_it (it); |
| 5444 | if (!STRINGP (it->string)) | 5459 | if (STRINGP (it->string)) |
| 5445 | it->method = next_element_from_buffer; | ||
| 5446 | else | ||
| 5447 | goto consider_string_end; | 5460 | goto consider_string_end; |
| 5461 | it->method = GET_FROM_BUFFER; | ||
| 5448 | } | 5462 | } |
| 5449 | } | 5463 | } |
| 5450 | } | 5464 | break; |
| 5451 | else if (it->method == next_element_from_image | 5465 | |
| 5452 | || it->method == next_element_from_stretch) | 5466 | case GET_FROM_IMAGE: |
| 5453 | { | 5467 | case GET_FROM_STRETCH: |
| 5454 | /* The position etc with which we have to proceed are on | 5468 | /* The position etc with which we have to proceed are on |
| 5455 | the stack. The position may be at the end of a string, | 5469 | the stack. The position may be at the end of a string, |
| 5456 | if the `display' property takes up the whole string. */ | 5470 | if the `display' property takes up the whole string. */ |
| 5471 | xassert (it->sp > 0); | ||
| 5457 | pop_it (it); | 5472 | pop_it (it); |
| 5458 | it->image_id = 0; | 5473 | it->image_id = 0; |
| 5459 | if (STRINGP (it->string)) | 5474 | if (STRINGP (it->string)) |
| 5460 | { | 5475 | { |
| 5461 | it->method = next_element_from_string; | 5476 | it->method = GET_FROM_STRING; |
| 5462 | goto consider_string_end; | 5477 | goto consider_string_end; |
| 5463 | } | 5478 | } |
| 5464 | else | 5479 | it->method = GET_FROM_BUFFER; |
| 5465 | it->method = next_element_from_buffer; | 5480 | break; |
| 5481 | |||
| 5482 | default: | ||
| 5483 | /* There are no other methods defined, so this should be a bug. */ | ||
| 5484 | abort (); | ||
| 5466 | } | 5485 | } |
| 5467 | else | ||
| 5468 | /* There are no other methods defined, so this should be a bug. */ | ||
| 5469 | abort (); | ||
| 5470 | 5486 | ||
| 5471 | xassert (it->method != next_element_from_string | 5487 | xassert (it->method != GET_FROM_STRING |
| 5472 | || (STRINGP (it->string) | 5488 | || (STRINGP (it->string) |
| 5473 | && IT_STRING_CHARPOS (*it) >= 0)); | 5489 | && IT_STRING_CHARPOS (*it) >= 0)); |
| 5474 | } | 5490 | } |
| @@ -5680,7 +5696,7 @@ next_element_from_ellipsis (it) | |||
| 5680 | was in IT->saved_face_id, and signal that it's there by | 5696 | was in IT->saved_face_id, and signal that it's there by |
| 5681 | setting face_before_selective_p. */ | 5697 | setting face_before_selective_p. */ |
| 5682 | it->saved_face_id = it->face_id; | 5698 | it->saved_face_id = it->face_id; |
| 5683 | it->method = next_element_from_buffer; | 5699 | it->method = GET_FROM_BUFFER; |
| 5684 | reseat_at_next_visible_line_start (it, 1); | 5700 | reseat_at_next_visible_line_start (it, 1); |
| 5685 | it->face_before_selective_p = 1; | 5701 | it->face_before_selective_p = 1; |
| 5686 | } | 5702 | } |
| @@ -5921,11 +5937,14 @@ move_it_in_display_line_to (it, to_charpos, to_x, op) | |||
| 5921 | saved_glyph_row = it->glyph_row; | 5937 | saved_glyph_row = it->glyph_row; |
| 5922 | it->glyph_row = NULL; | 5938 | it->glyph_row = NULL; |
| 5923 | 5939 | ||
| 5924 | #define BUFFER_POS_REACHED_P() \ | 5940 | #define BUFFER_POS_REACHED_P() \ |
| 5925 | ((op & MOVE_TO_POS) != 0 \ | 5941 | ((op & MOVE_TO_POS) != 0 \ |
| 5926 | && BUFFERP (it->object) \ | 5942 | && BUFFERP (it->object) \ |
| 5927 | && IT_CHARPOS (*it) >= to_charpos \ | 5943 | && IT_CHARPOS (*it) >= to_charpos \ |
| 5928 | && it->method == next_element_from_buffer) | 5944 | && (it->method == GET_FROM_BUFFER || \ |
| 5945 | (it->method == GET_FROM_DISPLAY_VECTOR && \ | ||
| 5946 | it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) | ||
| 5947 | |||
| 5929 | 5948 | ||
| 5930 | while (1) | 5949 | while (1) |
| 5931 | { | 5950 | { |
| @@ -6616,7 +6635,7 @@ int | |||
| 6616 | in_display_vector_p (it) | 6635 | in_display_vector_p (it) |
| 6617 | struct it *it; | 6636 | struct it *it; |
| 6618 | { | 6637 | { |
| 6619 | return (it->method == next_element_from_display_vector | 6638 | return (it->method == GET_FROM_DISPLAY_VECTOR |
| 6620 | && it->current.dpvec_index > 0 | 6639 | && it->current.dpvec_index > 0 |
| 6621 | && it->dpvec + it->current.dpvec_index != it->dpend); | 6640 | && it->dpvec + it->current.dpvec_index != it->dpend); |
| 6622 | } | 6641 | } |
| @@ -15348,7 +15367,7 @@ display_line (it) | |||
| 15348 | 15367 | ||
| 15349 | /* Record whether this row ends inside an ellipsis. */ | 15368 | /* Record whether this row ends inside an ellipsis. */ |
| 15350 | row->ends_in_ellipsis_p | 15369 | row->ends_in_ellipsis_p |
| 15351 | = (it->method == next_element_from_display_vector | 15370 | = (it->method == GET_FROM_DISPLAY_VECTOR |
| 15352 | && it->ellipsis_p); | 15371 | && it->ellipsis_p); |
| 15353 | 15372 | ||
| 15354 | /* Save fringe bitmaps in this row. */ | 15373 | /* Save fringe bitmaps in this row. */ |
diff --git a/src/xfns.c b/src/xfns.c index d1edf554feb..8267709767f 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -1860,7 +1860,8 @@ hack_wm_protocols (f, widget) | |||
| 1860 | 1860 | ||
| 1861 | BLOCK_INPUT; | 1861 | BLOCK_INPUT; |
| 1862 | { | 1862 | { |
| 1863 | Atom type, *atoms = 0; | 1863 | Atom type; |
| 1864 | unsigned char *catoms; | ||
| 1864 | int format = 0; | 1865 | int format = 0; |
| 1865 | unsigned long nitems = 0; | 1866 | unsigned long nitems = 0; |
| 1866 | unsigned long bytes_after; | 1867 | unsigned long bytes_after; |
| @@ -1869,20 +1870,27 @@ hack_wm_protocols (f, widget) | |||
| 1869 | FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, | 1870 | FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, |
| 1870 | (long)0, (long)100, False, XA_ATOM, | 1871 | (long)0, (long)100, False, XA_ATOM, |
| 1871 | &type, &format, &nitems, &bytes_after, | 1872 | &type, &format, &nitems, &bytes_after, |
| 1872 | (unsigned char **) &atoms) | 1873 | &catoms) |
| 1873 | == Success) | 1874 | == Success) |
| 1874 | && format == 32 && type == XA_ATOM) | 1875 | && format == 32 && type == XA_ATOM) |
| 1875 | while (nitems > 0) | 1876 | { |
| 1876 | { | 1877 | Atom *atoms = (Atom *) catoms; |
| 1877 | nitems--; | 1878 | while (nitems > 0) |
| 1878 | if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window) | 1879 | { |
| 1879 | need_delete = 0; | 1880 | nitems--; |
| 1880 | else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus) | 1881 | if (atoms[nitems] |
| 1881 | need_focus = 0; | 1882 | == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_delete_window) |
| 1882 | else if (atoms[nitems] == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself) | 1883 | need_delete = 0; |
| 1883 | need_save = 0; | 1884 | else if (atoms[nitems] |
| 1884 | } | 1885 | == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_take_focus) |
| 1885 | if (atoms) XFree ((char *) atoms); | 1886 | need_focus = 0; |
| 1887 | else if (atoms[nitems] | ||
| 1888 | == FRAME_X_DISPLAY_INFO (f)->Xatom_wm_save_yourself) | ||
| 1889 | need_save = 0; | ||
| 1890 | } | ||
| 1891 | } | ||
| 1892 | if (catoms) | ||
| 1893 | XFree (catoms); | ||
| 1886 | } | 1894 | } |
| 1887 | { | 1895 | { |
| 1888 | Atom props [10]; | 1896 | Atom props [10]; |
| @@ -4140,7 +4148,7 @@ no value of TYPE. */) | |||
| 4140 | Atom prop_atom; | 4148 | Atom prop_atom; |
| 4141 | int rc; | 4149 | int rc; |
| 4142 | Lisp_Object prop_value = Qnil; | 4150 | Lisp_Object prop_value = Qnil; |
| 4143 | char *tmp_data = NULL; | 4151 | unsigned char *tmp_data = NULL; |
| 4144 | Atom actual_type; | 4152 | Atom actual_type; |
| 4145 | Atom target_type = XA_STRING; | 4153 | Atom target_type = XA_STRING; |
| 4146 | int actual_format; | 4154 | int actual_format; |
| @@ -4180,7 +4188,7 @@ no value of TYPE. */) | |||
| 4180 | rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window, | 4188 | rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window, |
| 4181 | prop_atom, 0, 0, False, target_type, | 4189 | prop_atom, 0, 0, False, target_type, |
| 4182 | &actual_type, &actual_format, &actual_size, | 4190 | &actual_type, &actual_format, &actual_size, |
| 4183 | &bytes_remaining, (unsigned char **) &tmp_data); | 4191 | &bytes_remaining, &tmp_data); |
| 4184 | if (rc == Success) | 4192 | if (rc == Success) |
| 4185 | { | 4193 | { |
| 4186 | int size = bytes_remaining; | 4194 | int size = bytes_remaining; |
| @@ -4193,7 +4201,7 @@ no value of TYPE. */) | |||
| 4193 | ! NILP (delete_p), target_type, | 4201 | ! NILP (delete_p), target_type, |
| 4194 | &actual_type, &actual_format, | 4202 | &actual_type, &actual_format, |
| 4195 | &actual_size, &bytes_remaining, | 4203 | &actual_size, &bytes_remaining, |
| 4196 | (unsigned char **) &tmp_data); | 4204 | &tmp_data); |
| 4197 | if (rc == Success && tmp_data) | 4205 | if (rc == Success && tmp_data) |
| 4198 | { | 4206 | { |
| 4199 | /* The man page for XGetWindowProperty says: | 4207 | /* The man page for XGetWindowProperty says: |
| @@ -4217,14 +4225,14 @@ no value of TYPE. */) | |||
| 4217 | long *ldata = (long *) tmp_data; | 4225 | long *ldata = (long *) tmp_data; |
| 4218 | 4226 | ||
| 4219 | for (i = 0; i < actual_size; ++i) | 4227 | for (i = 0; i < actual_size; ++i) |
| 4220 | idata[i]= (int) ldata[i]; | 4228 | idata[i] = (int) ldata[i]; |
| 4221 | } | 4229 | } |
| 4222 | 4230 | ||
| 4223 | if (NILP (vector_ret_p)) | 4231 | if (NILP (vector_ret_p)) |
| 4224 | prop_value = make_string (tmp_data, size); | 4232 | prop_value = make_string (tmp_data, size); |
| 4225 | else | 4233 | else |
| 4226 | prop_value = x_property_data_to_lisp (f, | 4234 | prop_value = x_property_data_to_lisp (f, |
| 4227 | (unsigned char *) tmp_data, | 4235 | tmp_data, |
| 4228 | actual_type, | 4236 | actual_type, |
| 4229 | actual_format, | 4237 | actual_format, |
| 4230 | actual_size); | 4238 | actual_size); |
diff --git a/src/xselect.c b/src/xselect.c index bf37cde4d0b..a49b6b89ee4 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -1908,7 +1908,12 @@ lisp_data_to_selection_data (display, obj, | |||
| 1908 | } | 1908 | } |
| 1909 | else if (STRINGP (obj)) | 1909 | else if (STRINGP (obj)) |
| 1910 | { | 1910 | { |
| 1911 | xassert (! STRING_MULTIBYTE (obj)); | 1911 | if (SCHARS (obj) < SBYTES (obj)) |
| 1912 | /* OBJ is a multibyte string containing a non-ASCII char. */ | ||
| 1913 | Fsignal (Qerror, /* Qselection_error */ | ||
| 1914 | Fcons (build_string | ||
| 1915 | ("Non-ASCII string must be encoded in advance"), | ||
| 1916 | Fcons (obj, Qnil))); | ||
| 1912 | if (NILP (type)) | 1917 | if (NILP (type)) |
| 1913 | type = QSTRING; | 1918 | type = QSTRING; |
| 1914 | *format_ret = 8; | 1919 | *format_ret = 8; |
| @@ -2184,7 +2189,10 @@ Disowning it means there is no such selection. */) | |||
| 2184 | { | 2189 | { |
| 2185 | Time timestamp; | 2190 | Time timestamp; |
| 2186 | Atom selection_atom; | 2191 | Atom selection_atom; |
| 2187 | struct selection_input_event event; | 2192 | union { |
| 2193 | struct selection_input_event sie; | ||
| 2194 | struct input_event ie; | ||
| 2195 | } event; | ||
| 2188 | Display *display; | 2196 | Display *display; |
| 2189 | struct x_display_info *dpyinfo; | 2197 | struct x_display_info *dpyinfo; |
| 2190 | struct frame *sf = SELECTED_FRAME (); | 2198 | struct frame *sf = SELECTED_FRAME (); |
| @@ -2212,10 +2220,10 @@ Disowning it means there is no such selection. */) | |||
| 2212 | the selection owner to None. The NCD server does, the MIT Sun4 server | 2220 | the selection owner to None. The NCD server does, the MIT Sun4 server |
| 2213 | doesn't. So we synthesize one; this means we might get two, but | 2221 | doesn't. So we synthesize one; this means we might get two, but |
| 2214 | that's ok, because the second one won't have any effect. */ | 2222 | that's ok, because the second one won't have any effect. */ |
| 2215 | SELECTION_EVENT_DISPLAY (&event) = display; | 2223 | SELECTION_EVENT_DISPLAY (&event.sie) = display; |
| 2216 | SELECTION_EVENT_SELECTION (&event) = selection_atom; | 2224 | SELECTION_EVENT_SELECTION (&event.sie) = selection_atom; |
| 2217 | SELECTION_EVENT_TIME (&event) = timestamp; | 2225 | SELECTION_EVENT_TIME (&event.sie) = timestamp; |
| 2218 | x_handle_selection_clear ((struct input_event *) &event); | 2226 | x_handle_selection_clear (&event.ie); |
| 2219 | 2227 | ||
| 2220 | return Qt; | 2228 | return Qt; |
| 2221 | } | 2229 | } |
diff --git a/src/xterm.c b/src/xterm.c index 137e0d2ae9e..3b6d2e18ac6 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -5625,8 +5625,8 @@ static struct x_display_info *next_noop_dpyinfo; | |||
| 5625 | f->output_data.x->saved_menu_event \ | 5625 | f->output_data.x->saved_menu_event \ |
| 5626 | = (XEvent *) xmalloc (sizeof (XEvent)); \ | 5626 | = (XEvent *) xmalloc (sizeof (XEvent)); \ |
| 5627 | bcopy (&event, f->output_data.x->saved_menu_event, size); \ | 5627 | bcopy (&event, f->output_data.x->saved_menu_event, size); \ |
| 5628 | inev.kind = MENU_BAR_ACTIVATE_EVENT; \ | 5628 | inev.ie.kind = MENU_BAR_ACTIVATE_EVENT; \ |
| 5629 | XSETFRAME (inev.frame_or_window, f); \ | 5629 | XSETFRAME (inev.ie.frame_or_window, f); \ |
| 5630 | } \ | 5630 | } \ |
| 5631 | while (0) | 5631 | while (0) |
| 5632 | 5632 | ||
| @@ -5733,7 +5733,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5733 | int *finish; | 5733 | int *finish; |
| 5734 | struct input_event *hold_quit; | 5734 | struct input_event *hold_quit; |
| 5735 | { | 5735 | { |
| 5736 | struct input_event inev; | 5736 | union { |
| 5737 | struct input_event ie; | ||
| 5738 | struct selection_input_event sie; | ||
| 5739 | } inev; | ||
| 5737 | int count = 0; | 5740 | int count = 0; |
| 5738 | int do_help = 0; | 5741 | int do_help = 0; |
| 5739 | int nbytes = 0; | 5742 | int nbytes = 0; |
| @@ -5743,9 +5746,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5743 | 5746 | ||
| 5744 | *finish = X_EVENT_NORMAL; | 5747 | *finish = X_EVENT_NORMAL; |
| 5745 | 5748 | ||
| 5746 | EVENT_INIT (inev); | 5749 | EVENT_INIT (inev.ie); |
| 5747 | inev.kind = NO_EVENT; | 5750 | inev.ie.kind = NO_EVENT; |
| 5748 | inev.arg = Qnil; | 5751 | inev.ie.arg = Qnil; |
| 5749 | 5752 | ||
| 5750 | switch (event.type) | 5753 | switch (event.type) |
| 5751 | { | 5754 | { |
| @@ -5843,8 +5846,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5843 | if (!f) | 5846 | if (!f) |
| 5844 | goto OTHER; /* May be a dialog that is to be removed */ | 5847 | goto OTHER; /* May be a dialog that is to be removed */ |
| 5845 | 5848 | ||
| 5846 | inev.kind = DELETE_WINDOW_EVENT; | 5849 | inev.ie.kind = DELETE_WINDOW_EVENT; |
| 5847 | XSETFRAME (inev.frame_or_window, f); | 5850 | XSETFRAME (inev.ie.frame_or_window, f); |
| 5848 | goto done; | 5851 | goto done; |
| 5849 | } | 5852 | } |
| 5850 | 5853 | ||
| @@ -5907,7 +5910,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5907 | if (event.xclient.message_type | 5910 | if (event.xclient.message_type |
| 5908 | == dpyinfo->Xatom_Scrollbar) | 5911 | == dpyinfo->Xatom_Scrollbar) |
| 5909 | { | 5912 | { |
| 5910 | x_scroll_bar_to_input_event (&event, &inev); | 5913 | x_scroll_bar_to_input_event (&event, &inev.ie); |
| 5911 | *finish = X_EVENT_GOTO_OUT; | 5914 | *finish = X_EVENT_GOTO_OUT; |
| 5912 | goto done; | 5915 | goto done; |
| 5913 | } | 5916 | } |
| @@ -5918,7 +5921,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5918 | if (!f) | 5921 | if (!f) |
| 5919 | goto OTHER; | 5922 | goto OTHER; |
| 5920 | 5923 | ||
| 5921 | if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev)) | 5924 | if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie)) |
| 5922 | *finish = X_EVENT_DROP; | 5925 | *finish = X_EVENT_DROP; |
| 5923 | } | 5926 | } |
| 5924 | break; | 5927 | break; |
| @@ -5939,11 +5942,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5939 | { | 5942 | { |
| 5940 | XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; | 5943 | XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; |
| 5941 | 5944 | ||
| 5942 | inev.kind = SELECTION_CLEAR_EVENT; | 5945 | inev.ie.kind = SELECTION_CLEAR_EVENT; |
| 5943 | SELECTION_EVENT_DISPLAY (&inev) = eventp->display; | 5946 | SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display; |
| 5944 | SELECTION_EVENT_SELECTION (&inev) = eventp->selection; | 5947 | SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection; |
| 5945 | SELECTION_EVENT_TIME (&inev) = eventp->time; | 5948 | SELECTION_EVENT_TIME (&inev.sie) = eventp->time; |
| 5946 | inev.frame_or_window = Qnil; | 5949 | inev.ie.frame_or_window = Qnil; |
| 5947 | } | 5950 | } |
| 5948 | break; | 5951 | break; |
| 5949 | 5952 | ||
| @@ -5956,14 +5959,14 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5956 | XSelectionRequestEvent *eventp | 5959 | XSelectionRequestEvent *eventp |
| 5957 | = (XSelectionRequestEvent *) &event; | 5960 | = (XSelectionRequestEvent *) &event; |
| 5958 | 5961 | ||
| 5959 | inev.kind = SELECTION_REQUEST_EVENT; | 5962 | inev.ie.kind = SELECTION_REQUEST_EVENT; |
| 5960 | SELECTION_EVENT_DISPLAY (&inev) = eventp->display; | 5963 | SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display; |
| 5961 | SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor; | 5964 | SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor; |
| 5962 | SELECTION_EVENT_SELECTION (&inev) = eventp->selection; | 5965 | SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection; |
| 5963 | SELECTION_EVENT_TARGET (&inev) = eventp->target; | 5966 | SELECTION_EVENT_TARGET (&inev.sie) = eventp->target; |
| 5964 | SELECTION_EVENT_PROPERTY (&inev) = eventp->property; | 5967 | SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property; |
| 5965 | SELECTION_EVENT_TIME (&inev) = eventp->time; | 5968 | SELECTION_EVENT_TIME (&inev.sie) = eventp->time; |
| 5966 | inev.frame_or_window = Qnil; | 5969 | inev.ie.frame_or_window = Qnil; |
| 5967 | } | 5970 | } |
| 5968 | break; | 5971 | break; |
| 5969 | 5972 | ||
| @@ -6102,8 +6105,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6102 | { | 6105 | { |
| 6103 | f->async_iconified = 1; | 6106 | f->async_iconified = 1; |
| 6104 | 6107 | ||
| 6105 | inev.kind = ICONIFY_EVENT; | 6108 | inev.ie.kind = ICONIFY_EVENT; |
| 6106 | XSETFRAME (inev.frame_or_window, f); | 6109 | XSETFRAME (inev.ie.frame_or_window, f); |
| 6107 | } | 6110 | } |
| 6108 | } | 6111 | } |
| 6109 | goto OTHER; | 6112 | goto OTHER; |
| @@ -6135,8 +6138,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6135 | 6138 | ||
| 6136 | if (f->iconified) | 6139 | if (f->iconified) |
| 6137 | { | 6140 | { |
| 6138 | inev.kind = DEICONIFY_EVENT; | 6141 | inev.ie.kind = DEICONIFY_EVENT; |
| 6139 | XSETFRAME (inev.frame_or_window, f); | 6142 | XSETFRAME (inev.ie.frame_or_window, f); |
| 6140 | } | 6143 | } |
| 6141 | else if (! NILP (Vframe_list) | 6144 | else if (! NILP (Vframe_list) |
| 6142 | && ! NILP (XCDR (Vframe_list))) | 6145 | && ! NILP (XCDR (Vframe_list))) |
| @@ -6302,18 +6305,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6302 | orig_keysym = keysym; | 6305 | orig_keysym = keysym; |
| 6303 | 6306 | ||
| 6304 | /* Common for all keysym input events. */ | 6307 | /* Common for all keysym input events. */ |
| 6305 | XSETFRAME (inev.frame_or_window, f); | 6308 | XSETFRAME (inev.ie.frame_or_window, f); |
| 6306 | inev.modifiers | 6309 | inev.ie.modifiers |
| 6307 | = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers); | 6310 | = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers); |
| 6308 | inev.timestamp = event.xkey.time; | 6311 | inev.ie.timestamp = event.xkey.time; |
| 6309 | 6312 | ||
| 6310 | /* First deal with keysyms which have defined | 6313 | /* First deal with keysyms which have defined |
| 6311 | translations to characters. */ | 6314 | translations to characters. */ |
| 6312 | if (keysym >= 32 && keysym < 128) | 6315 | if (keysym >= 32 && keysym < 128) |
| 6313 | /* Avoid explicitly decoding each ASCII character. */ | 6316 | /* Avoid explicitly decoding each ASCII character. */ |
| 6314 | { | 6317 | { |
| 6315 | inev.kind = ASCII_KEYSTROKE_EVENT; | 6318 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; |
| 6316 | inev.code = keysym; | 6319 | inev.ie.code = keysym; |
| 6317 | goto done_keysym; | 6320 | goto done_keysym; |
| 6318 | } | 6321 | } |
| 6319 | 6322 | ||
| @@ -6323,10 +6326,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6323 | Vx_keysym_table, | 6326 | Vx_keysym_table, |
| 6324 | Qnil)))) | 6327 | Qnil)))) |
| 6325 | { | 6328 | { |
| 6326 | inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) | 6329 | inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) |
| 6327 | ? ASCII_KEYSTROKE_EVENT | 6330 | ? ASCII_KEYSTROKE_EVENT |
| 6328 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | 6331 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); |
| 6329 | inev.code = XFASTINT (c); | 6332 | inev.ie.code = XFASTINT (c); |
| 6330 | goto done_keysym; | 6333 | goto done_keysym; |
| 6331 | } | 6334 | } |
| 6332 | 6335 | ||
| @@ -6416,8 +6419,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6416 | STORE_KEYSYM_FOR_DEBUG (keysym); | 6419 | STORE_KEYSYM_FOR_DEBUG (keysym); |
| 6417 | /* make_lispy_event will convert this to a symbolic | 6420 | /* make_lispy_event will convert this to a symbolic |
| 6418 | key. */ | 6421 | key. */ |
| 6419 | inev.kind = NON_ASCII_KEYSTROKE_EVENT; | 6422 | inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT; |
| 6420 | inev.code = keysym; | 6423 | inev.ie.code = keysym; |
| 6421 | goto done_keysym; | 6424 | goto done_keysym; |
| 6422 | } | 6425 | } |
| 6423 | 6426 | ||
| @@ -6469,18 +6472,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6469 | else | 6472 | else |
| 6470 | c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, | 6473 | c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, |
| 6471 | nbytes - i, len); | 6474 | nbytes - i, len); |
| 6472 | inev.kind = (SINGLE_BYTE_CHAR_P (c) | 6475 | inev.ie.kind = (SINGLE_BYTE_CHAR_P (c) |
| 6473 | ? ASCII_KEYSTROKE_EVENT | 6476 | ? ASCII_KEYSTROKE_EVENT |
| 6474 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | 6477 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); |
| 6475 | inev.code = c; | 6478 | inev.ie.code = c; |
| 6476 | kbd_buffer_store_event_hold (&inev, hold_quit); | 6479 | kbd_buffer_store_event_hold (&inev.ie, hold_quit); |
| 6477 | } | 6480 | } |
| 6478 | 6481 | ||
| 6479 | /* Previous code updated count by nchars rather than nbytes, | 6482 | /* Previous code updated count by nchars rather than nbytes, |
| 6480 | but that seems bogus to me. ++kfs */ | 6483 | but that seems bogus to me. ++kfs */ |
| 6481 | count += nbytes; | 6484 | count += nbytes; |
| 6482 | 6485 | ||
| 6483 | inev.kind = NO_EVENT; /* Already stored above. */ | 6486 | inev.ie.kind = NO_EVENT; /* Already stored above. */ |
| 6484 | 6487 | ||
| 6485 | if (keysym == NoSymbol) | 6488 | if (keysym == NoSymbol) |
| 6486 | break; | 6489 | break; |
| @@ -6507,7 +6510,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6507 | #endif | 6510 | #endif |
| 6508 | 6511 | ||
| 6509 | case EnterNotify: | 6512 | case EnterNotify: |
| 6510 | x_detect_focus_change (dpyinfo, &event, &inev); | 6513 | x_detect_focus_change (dpyinfo, &event, &inev.ie); |
| 6511 | 6514 | ||
| 6512 | f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); | 6515 | f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); |
| 6513 | 6516 | ||
| @@ -6537,11 +6540,11 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6537 | goto OTHER; | 6540 | goto OTHER; |
| 6538 | 6541 | ||
| 6539 | case FocusIn: | 6542 | case FocusIn: |
| 6540 | x_detect_focus_change (dpyinfo, &event, &inev); | 6543 | x_detect_focus_change (dpyinfo, &event, &inev.ie); |
| 6541 | goto OTHER; | 6544 | goto OTHER; |
| 6542 | 6545 | ||
| 6543 | case LeaveNotify: | 6546 | case LeaveNotify: |
| 6544 | x_detect_focus_change (dpyinfo, &event, &inev); | 6547 | x_detect_focus_change (dpyinfo, &event, &inev.ie); |
| 6545 | 6548 | ||
| 6546 | f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); | 6549 | f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); |
| 6547 | if (f) | 6550 | if (f) |
| @@ -6564,7 +6567,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6564 | goto OTHER; | 6567 | goto OTHER; |
| 6565 | 6568 | ||
| 6566 | case FocusOut: | 6569 | case FocusOut: |
| 6567 | x_detect_focus_change (dpyinfo, &event, &inev); | 6570 | x_detect_focus_change (dpyinfo, &event, &inev.ie); |
| 6568 | goto OTHER; | 6571 | goto OTHER; |
| 6569 | 6572 | ||
| 6570 | case MotionNotify: | 6573 | case MotionNotify: |
| @@ -6604,8 +6607,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6604 | && !EQ (window, last_window) | 6607 | && !EQ (window, last_window) |
| 6605 | && !EQ (window, selected_window)) | 6608 | && !EQ (window, selected_window)) |
| 6606 | { | 6609 | { |
| 6607 | inev.kind = SELECT_WINDOW_EVENT; | 6610 | inev.ie.kind = SELECT_WINDOW_EVENT; |
| 6608 | inev.frame_or_window = window; | 6611 | inev.ie.frame_or_window = window; |
| 6609 | } | 6612 | } |
| 6610 | 6613 | ||
| 6611 | last_window=window; | 6614 | last_window=window; |
| @@ -6764,13 +6767,13 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6764 | && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0) | 6767 | && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0) |
| 6765 | { | 6768 | { |
| 6766 | ignore_next_mouse_click_timeout = 0; | 6769 | ignore_next_mouse_click_timeout = 0; |
| 6767 | construct_mouse_click (&inev, &event, f); | 6770 | construct_mouse_click (&inev.ie, &event, f); |
| 6768 | } | 6771 | } |
| 6769 | if (event.type == ButtonRelease) | 6772 | if (event.type == ButtonRelease) |
| 6770 | ignore_next_mouse_click_timeout = 0; | 6773 | ignore_next_mouse_click_timeout = 0; |
| 6771 | } | 6774 | } |
| 6772 | else | 6775 | else |
| 6773 | construct_mouse_click (&inev, &event, f); | 6776 | construct_mouse_click (&inev.ie, &event, f); |
| 6774 | } | 6777 | } |
| 6775 | } | 6778 | } |
| 6776 | } | 6779 | } |
| @@ -6785,12 +6788,12 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6785 | scroll bars. */ | 6788 | scroll bars. */ |
| 6786 | if (bar && event.xbutton.state & ControlMask) | 6789 | if (bar && event.xbutton.state & ControlMask) |
| 6787 | { | 6790 | { |
| 6788 | x_scroll_bar_handle_click (bar, &event, &inev); | 6791 | x_scroll_bar_handle_click (bar, &event, &inev.ie); |
| 6789 | *finish = X_EVENT_DROP; | 6792 | *finish = X_EVENT_DROP; |
| 6790 | } | 6793 | } |
| 6791 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | 6794 | #else /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6792 | if (bar) | 6795 | if (bar) |
| 6793 | x_scroll_bar_handle_click (bar, &event, &inev); | 6796 | x_scroll_bar_handle_click (bar, &event, &inev.ie); |
| 6794 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 6797 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 6795 | } | 6798 | } |
| 6796 | 6799 | ||
| @@ -6898,9 +6901,9 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6898 | } | 6901 | } |
| 6899 | 6902 | ||
| 6900 | done: | 6903 | done: |
| 6901 | if (inev.kind != NO_EVENT) | 6904 | if (inev.ie.kind != NO_EVENT) |
| 6902 | { | 6905 | { |
| 6903 | kbd_buffer_store_event_hold (&inev, hold_quit); | 6906 | kbd_buffer_store_event_hold (&inev.ie, hold_quit); |
| 6904 | count++; | 6907 | count++; |
| 6905 | } | 6908 | } |
| 6906 | 6909 | ||