aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32select.c
diff options
context:
space:
mode:
authorKenichi Handa2005-04-28 04:56:25 +0000
committerKenichi Handa2005-04-28 04:56:25 +0000
commit9a38f8d5f3f466bd349eac89afa69f6dbaa0fb4b (patch)
tree59cb3824c161d922f782cabbd398283a3cfc143d /src/w32select.c
parenta63920223e565cb0023cda68f5ec9a6483774587 (diff)
downloademacs-9a38f8d5f3f466bd349eac89afa69f6dbaa0fb4b.tar.gz
emacs-9a38f8d5f3f466bd349eac89afa69f6dbaa0fb4b.zip
(validate_coding_system)
(setup_windows_coding_system): New functions. (convert_to_handle_as_coded, Fw32_get_clipboard_data): Use setup_windows_coding_system. (setup_config, Fw32_get_clipboard_data): Use validate_coding_system. (Fx_selection_exists): Move call to setup_config to a place were signals are allowed.
Diffstat (limited to 'src/w32select.c')
-rw-r--r--src/w32select.c160
1 files changed, 94 insertions, 66 deletions
diff --git a/src/w32select.c b/src/w32select.c
index 478774663c8..19648a22429 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -99,6 +99,9 @@ static void setup_config (void);
99static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string); 99static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
100static UINT cp_from_locale (LCID lcid, UINT format); 100static UINT cp_from_locale (LCID lcid, UINT format);
101static Lisp_Object coding_from_cp (UINT codepage); 101static Lisp_Object coding_from_cp (UINT codepage);
102static Lisp_Object validate_coding_system (Lisp_Object coding_system);
103static void setup_windows_coding_system (Lisp_Object coding_system,
104 struct coding_system * coding);
102 105
103 106
104/* A remnant from X11: Symbol for the CLIPBORD selection type. Other 107/* A remnant from X11: Symbol for the CLIPBORD selection type. Other
@@ -212,63 +215,36 @@ convert_to_handle_as_ascii (void)
212static HGLOBAL 215static HGLOBAL
213convert_to_handle_as_coded (Lisp_Object coding_system) 216convert_to_handle_as_coded (Lisp_Object coding_system)
214{ 217{
215 HGLOBAL htext = NULL, htext2; 218 HGLOBAL htext;
216 int nbytes;
217 unsigned char *src;
218 unsigned char *dst = NULL; 219 unsigned char *dst = NULL;
219 int bufsize;
220 struct coding_system coding; 220 struct coding_system coding;
221 Lisp_Object string = Qnil;
222 221
223 ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n", 222 ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",
224 SDATA (SYMBOL_NAME (coding_system)))); 223 SDATA (SYMBOL_NAME (coding_system))));
225 224
226 setup_coding_system (Fcheck_coding_system (coding_system), &coding); 225 setup_windows_coding_system (coding_system, &coding);
227 coding.src_multibyte = 1; 226 coding.dst_bytes = SBYTES(current_text) * 2;
228 coding.dst_multibyte = 0; 227 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
229 /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in 228 encode_coding_object (&coding, current_text, 0, 0,
230 encode_coding_iso2022 trying to dereference a null pointer. */ 229 SCHARS (current_text), SBYTES (current_text), Qnil);
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);
246 230
247 bufsize = encoding_buffer_size (&coding, nbytes) +2; 231 htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.produced +2);
248 htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize);
249 232
250 if (htext != NULL) 233 if (htext != NULL)
251 dst = (unsigned char *) GlobalLock (htext); 234 dst = (unsigned char *) GlobalLock (htext);
252 235
253 if (dst != NULL) 236 if (dst != NULL)
254 { 237 {
255 encode_coding (&coding, src, dst, nbytes, bufsize-2); 238 memcpy (dst, coding.destination, coding.produced);
256 /* Add the string terminator. Add two NULs in case we are 239 /* Add the string terminator. Add two NULs in case we are
257 producing Unicode here. */ 240 producing Unicode here. */
258 dst[coding.produced] = dst[coding.produced+1] = '\0'; 241 dst[coding.produced] = dst[coding.produced+1] = '\0';
259 }
260
261 if (dst != NULL)
262 GlobalUnlock (htext);
263 242
264 if (htext != NULL) 243 GlobalUnlock (htext);
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 } 244 }
271 245
246 xfree (coding.destination);
247
272 return htext; 248 return htext;
273} 249}
274 250
@@ -517,17 +493,26 @@ setup_config (void)
517 const char *cp; 493 const char *cp;
518 char *end; 494 char *end;
519 int slen; 495 int slen;
520 Lisp_Object new_coding_system; 496 Lisp_Object coding_system;
497 Lisp_Object dos_coding_system;
521 498
522 CHECK_SYMBOL (Vselection_coding_system); 499 CHECK_SYMBOL (Vselection_coding_system);
523 500
524 /* Check if we have it cached */ 501 coding_system = NILP (Vnext_selection_coding_system) ?
525 new_coding_system = NILP (Vnext_selection_coding_system) ?
526 Vselection_coding_system : Vnext_selection_coding_system; 502 Vselection_coding_system : Vnext_selection_coding_system;
503
504 dos_coding_system = validate_coding_system (coding_system);
505 if (NILP (dos_coding_system))
506 Fsignal (Qerror,
507 list2 (build_string ("Coding system is invalid or doesn't have "
508 "an eol variant for dos line ends"),
509 coding_system));
510
511 /* Check if we have it cached */
527 if (!NILP (cfg_coding_system) 512 if (!NILP (cfg_coding_system)
528 && EQ (cfg_coding_system, new_coding_system)) 513 && EQ (cfg_coding_system, dos_coding_system))
529 return; 514 return;
530 cfg_coding_system = new_coding_system; 515 cfg_coding_system = dos_coding_system;
531 516
532 /* Set some sensible fallbacks */ 517 /* Set some sensible fallbacks */
533 cfg_codepage = ANSICP; 518 cfg_codepage = ANSICP;
@@ -636,12 +621,61 @@ coding_from_cp (UINT codepage)
636 char buffer[30]; 621 char buffer[30];
637 sprintf (buffer, "cp%d-dos", (int) codepage); 622 sprintf (buffer, "cp%d-dos", (int) codepage);
638 return intern (buffer); 623 return intern (buffer);
639 /* We don't need to check that this coding system exists right here, 624 /* We don't need to check that this coding system actually exists
640 because that is done when the coding system is actually 625 right here, because that is done later for all coding systems
641 instantiated, i.e. it is passed through Fcheck_coding_system() 626 used, regardless of where they originate. */
642 there. */
643} 627}
644 628
629static Lisp_Object
630validate_coding_system (Lisp_Object coding_system)
631{
632 Lisp_Object eol_type;
633
634 /* Make sure the input is valid. */
635 if (NILP (Fcoding_system_p (coding_system)))
636 return Qnil;
637
638 /* Make sure we use a DOS coding system as mandated by the system
639 specs. */
640 eol_type = Fcoding_system_eol_type (coding_system);
641
642 /* Already a DOS coding system? */
643 if (EQ (eol_type, make_number (1)))
644 return coding_system;
645
646 /* Get EOL_TYPE vector of the base of CODING_SYSTEM. */
647 if (!VECTORP (eol_type))
648 {
649 eol_type = Fcoding_system_eol_type (Fcoding_system_base (coding_system));
650 if (!VECTORP (eol_type))
651 return Qnil;
652 }
653
654 return AREF (eol_type, 1);
655}
656
657static void
658setup_windows_coding_system (Lisp_Object coding_system,
659 struct coding_system * coding)
660{
661 memset (coding, 0, sizeof (*coding));
662 setup_coding_system (coding_system, coding);
663
664 /* Unset CODING_ANNOTATE_COMPOSITION_MASK. Previous code had
665 comments about crashes in encode_coding_iso2022 trying to
666 dereference a null pointer when composition was on. Selection
667 data should not contain any composition sequence on Windows.
668
669 CODING_ANNOTATION_MASK also includes
670 CODING_ANNOTATE_DIRECTION_MASK and CODING_ANNOTATE_CHARSET_MASK,
671 which both apply to ISO6429 only. We don't know if these really
672 need to be unset on Windows, but it probably doesn't hurt
673 either. */
674 coding->mode &= ~CODING_ANNOTATION_MASK;
675 coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
676}
677
678
645 679
646DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, 680DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
647 Sw32_set_clipboard_data, 1, 2, 0, 681 Sw32_set_clipboard_data, 1, 2, 0,
@@ -848,6 +882,7 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
848 { 882 {
849 struct coding_system coding; 883 struct coding_system coding;
850 Lisp_Object coding_system = Qnil; 884 Lisp_Object coding_system = Qnil;
885 Lisp_Object dos_coding_system;
851 886
852 /* `next-selection-coding-system' should override everything, 887 /* `next-selection-coding-system' should override everything,
853 even when the locale passed by the system disagrees. The 888 even when the locale passed by the system disagrees. The
@@ -909,24 +944,16 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
909 coding_system = Vselection_coding_system; 944 coding_system = Vselection_coding_system;
910 Vnext_selection_coding_system = Qnil; 945 Vnext_selection_coding_system = Qnil;
911 946
912 setup_coding_system (Fcheck_coding_system (coding_system), &coding); 947 dos_coding_system = validate_coding_system (coding_system);
913 coding.src_multibyte = 0; 948 if (!NILP (dos_coding_system))
914 coding.dst_multibyte = 1; 949 {
915 coding.mode |= CODING_MODE_LAST_BLOCK; 950 setup_windows_coding_system (dos_coding_system, &coding);
916 /* We explicitly disable composition handling because 951 coding.source = src;
917 selection data should not contain any composition 952 decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
918 sequence. */ 953 ret = coding.dst_object;
919 coding.common_flags &= ~CODING_ANNOTATION_MASK; 954
920 /* Force DOS line-ends. */ 955 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
921 coding.eol_type = CODING_EOL_CRLF; 956 }
922
923 coding.dst_bytes = nbytes * 2;
924 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
925 decode_coding_c_string (&coding, src, nbytes, Qnil);
926 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
927 ret = make_string_from_bytes ((char *) coding.destination,
928 coding.produced_char, coding.produced);
929 xfree (coding.destination);
930 } 957 }
931 else 958 else
932 { 959 {
@@ -1011,10 +1038,11 @@ and t is the same as `SECONDARY'. */)
1011 { 1038 {
1012 Lisp_Object val = Qnil; 1039 Lisp_Object val = Qnil;
1013 1040
1041 setup_config ();
1042
1014 if (OpenClipboard (NULL)) 1043 if (OpenClipboard (NULL))
1015 { 1044 {
1016 UINT format = 0; 1045 UINT format = 0;
1017 setup_config ();
1018 while ((format = EnumClipboardFormats (format))) 1046 while ((format = EnumClipboardFormats (format)))
1019 /* Check CF_TEXT in addition to cfg_clipboard_type, 1047 /* Check CF_TEXT in addition to cfg_clipboard_type,
1020 because we can fall back on that if CF_UNICODETEXT is 1048 because we can fall back on that if CF_UNICODETEXT is