diff options
| author | Kenichi Handa | 2005-04-28 04:56:25 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2005-04-28 04:56:25 +0000 |
| commit | 9a38f8d5f3f466bd349eac89afa69f6dbaa0fb4b (patch) | |
| tree | 59cb3824c161d922f782cabbd398283a3cfc143d /src/w32select.c | |
| parent | a63920223e565cb0023cda68f5ec9a6483774587 (diff) | |
| download | emacs-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.c | 160 |
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); | |||
| 99 | static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string); | 99 | static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string); |
| 100 | static UINT cp_from_locale (LCID lcid, UINT format); | 100 | static UINT cp_from_locale (LCID lcid, UINT format); |
| 101 | static Lisp_Object coding_from_cp (UINT codepage); | 101 | static Lisp_Object coding_from_cp (UINT codepage); |
| 102 | static Lisp_Object validate_coding_system (Lisp_Object coding_system); | ||
| 103 | static 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) | |||
| 212 | static HGLOBAL | 215 | static HGLOBAL |
| 213 | convert_to_handle_as_coded (Lisp_Object coding_system) | 216 | convert_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 | ||
| 629 | static Lisp_Object | ||
| 630 | validate_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 | |||
| 657 | static void | ||
| 658 | setup_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 | ||
| 646 | DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, | 680 | DEFUN ("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 |