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