diff options
| author | Miles Bader | 2005-02-18 00:41:50 +0000 |
|---|---|---|
| committer | Miles Bader | 2005-02-18 00:41:50 +0000 |
| commit | 8d46efcc0f2045a1e5a2739c55ba6a88fbf4bcfc (patch) | |
| tree | bc968a02587d51199537bb335d5494e756e35fdf /src/w32select.c | |
| parent | 8589dc17f80450f5773a2d449fa6d94c9bb04fe3 (diff) | |
| parent | 9b516537a9899900647d4eae5ec8778e6837ad3c (diff) | |
| download | emacs-8d46efcc0f2045a1e5a2739c55ba6a88fbf4bcfc.tar.gz emacs-8d46efcc0f2045a1e5a2739c55ba6a88fbf4bcfc.zip | |
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-15
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-95
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-96
Move Gnus images into etc/images
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-97
- miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-105
Update from CVS
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-14
Merge from emacs--cvs-trunk--0
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-15
Update from CVS: lisp/imap.el (imap-log): Doc fix.
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-16
Merge from emacs--cvs-trunk--0
Diffstat (limited to 'src/w32select.c')
| -rw-r--r-- | src/w32select.c | 1079 |
1 files changed, 844 insertions, 235 deletions
diff --git a/src/w32select.c b/src/w32select.c index af3d477f876..478774663c8 100644 --- a/src/w32select.c +++ b/src/w32select.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Selection processing for Emacs on the Microsoft W32 API. | 1 | /* Selection processing for Emacs on the Microsoft W32 API. |
| 2 | Copyright (C) 1993, 1994 Free Software Foundation. | 2 | Copyright (C) 1993, 1994, 2004 Free Software Foundation. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -18,261 +18,744 @@ along with GNU Emacs; see the file COPYING. If not, write to | |||
| 18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 19 | Boston, MA 02111-1307, USA. */ | 19 | Boston, MA 02111-1307, USA. */ |
| 20 | 20 | ||
| 21 | /* Written by Kevin Gallo */ | 21 | /* Written by Kevin Gallo, Benjamin Riefenstahl */ |
| 22 | 22 | ||
| 23 | |||
| 24 | /* | ||
| 25 | * Notes on usage of selection-coding-system and | ||
| 26 | * next-selection-coding-system on MS Windows: | ||
| 27 | * | ||
| 28 | * The selection coding system variables apply only to the version of | ||
| 29 | * the clipboard data that is closest in type, i.e. when a 16-bit | ||
| 30 | * Unicode coding system is given, they apply to he Unicode clipboard | ||
| 31 | * (CF_UNICODETEXT), when a well-known console codepage is given, they | ||
| 32 | * apply to the console version of the clipboard data (CF_OEMTEXT), | ||
| 33 | * else they apply to the normal 8-bit text clipboard (CF_TEXT). | ||
| 34 | * | ||
| 35 | * When pasting (getting data from the OS), the clipboard format that | ||
| 36 | * matches the {next-}selection-coding-system is retrieved. If | ||
| 37 | * Unicode is requested, but not available, 8-bit text (CF_TEXT) is | ||
| 38 | * used. In all other cases the OS will transparently convert | ||
| 39 | * formats, so no other fallback is needed. | ||
| 40 | * | ||
| 41 | * When copying or cutting (sending data to the OS), the data is | ||
| 42 | * announced and stored internally, but only actually rendered on | ||
| 43 | * request. The requester determines the format provided. The | ||
| 44 | * {next-}selection-coding-system is only used, when its corresponding | ||
| 45 | * clipboard type matches the type requested. | ||
| 46 | * | ||
| 47 | * Scenarios to use the facilities for customizing the selection | ||
| 48 | * coding system are: | ||
| 49 | * | ||
| 50 | * ;; Generally use KOI8-R instead of the russian MS codepage for | ||
| 51 | * ;; the 8-bit clipboard. | ||
| 52 | * (set-selection-coding-system 'koi8-r-dos) | ||
| 53 | * | ||
| 54 | * Or | ||
| 55 | * | ||
| 56 | * ;; Create a special clipboard copy function that uses codepage | ||
| 57 | * ;; 1253 (Greek) to copy Greek text to a specific non-Unicode | ||
| 58 | * ;; application. | ||
| 59 | * (defun greek-copy (beg end) | ||
| 60 | * (interactive "r") | ||
| 61 | * (set-next-selection-coding-system 'cp1253-dos) | ||
| 62 | * (copy-region-as-kill beg end)) | ||
| 63 | * (global-set-key "\C-c\C-c" 'greek-copy) | ||
| 64 | */ | ||
| 65 | |||
| 66 | /* | ||
| 67 | * Ideas for further directions: | ||
| 68 | * | ||
| 69 | * The encoding and decoding routines could be moved to Lisp code | ||
| 70 | * similar to how xselect.c does it (using well-known routine names | ||
| 71 | * for the delayed rendering). If the definition of which clipboard | ||
| 72 | * types should be supported is also moved to Lisp, functionality | ||
| 73 | * could be expanded to CF_HTML, CF_RTF and maybe other types. | ||
| 74 | */ | ||
| 75 | |||
| 23 | #include <config.h> | 76 | #include <config.h> |
| 24 | #include "lisp.h" | 77 | #include "lisp.h" |
| 25 | #include "w32term.h" /* for all of the w32 includes */ | 78 | #include "w32term.h" /* for all of the w32 includes */ |
| 26 | #include "dispextern.h" /* frame.h seems to want this */ | 79 | #include "w32heap.h" /* os_subtype */ |
| 27 | #include "keyboard.h" | ||
| 28 | #include "frame.h" /* Need this to get the X window of selected_frame */ | ||
| 29 | #include "blockinput.h" | 80 | #include "blockinput.h" |
| 30 | #include "buffer.h" | 81 | #include "keyboard.h" /* cmd_error_internal() */ |
| 31 | #include "charset.h" | 82 | #include "charset.h" |
| 32 | #include "coding.h" | 83 | #include "coding.h" |
| 33 | #include "composite.h" | 84 | #include "composite.h" |
| 34 | 85 | ||
| 86 | |||
| 87 | static HGLOBAL convert_to_handle_as_ascii (void); | ||
| 88 | static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system); | ||
| 89 | static Lisp_Object render (Lisp_Object oformat); | ||
| 90 | static Lisp_Object render_locale (void); | ||
| 91 | static Lisp_Object render_all (void); | ||
| 92 | static void run_protected (Lisp_Object (*code) (), Lisp_Object arg); | ||
| 93 | static Lisp_Object lisp_error_handler (Lisp_Object error); | ||
| 94 | static LRESULT CALLBACK owner_callback (HWND win, UINT msg, | ||
| 95 | WPARAM wp, LPARAM lp); | ||
| 96 | static HWND create_owner (void); | ||
| 97 | |||
| 98 | static void setup_config (void); | ||
| 99 | static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string); | ||
| 100 | static UINT cp_from_locale (LCID lcid, UINT format); | ||
| 101 | static Lisp_Object coding_from_cp (UINT codepage); | ||
| 102 | |||
| 103 | |||
| 104 | /* A remnant from X11: Symbol for the CLIPBORD selection type. Other | ||
| 105 | selections are not used on Windows, so we don't need symbols for | ||
| 106 | PRIMARY and SECONDARY. */ | ||
| 35 | Lisp_Object QCLIPBOARD; | 107 | Lisp_Object QCLIPBOARD; |
| 36 | 108 | ||
| 37 | /* Coding system for communicating with other Windows programs via the | 109 | /* Coding system for communicating with other programs via the |
| 38 | clipboard. */ | 110 | clipboard. */ |
| 39 | static Lisp_Object Vselection_coding_system; | 111 | static Lisp_Object Vselection_coding_system; |
| 40 | 112 | ||
| 41 | /* Coding system for the next communicating with other Windows programs. */ | 113 | /* Coding system for the next communication with other programs. */ |
| 42 | static Lisp_Object Vnext_selection_coding_system; | 114 | static Lisp_Object Vnext_selection_coding_system; |
| 43 | 115 | ||
| 44 | /* Sequence number, used where possible to detect when we are pasting | 116 | /* Internal pseudo-constants, initialized in globals_of_w32select() |
| 45 | our own text. */ | 117 | based on current system parameters. */ |
| 46 | static DWORD last_clipboard_sequence_number; | 118 | static LCID DEFAULT_LCID; |
| 47 | extern ClipboardSequence_Proc clipboard_sequence_fn; | 119 | static UINT ANSICP, OEMCP; |
| 48 | 120 | static Lisp_Object QUNICODE, QANSICP, QOEMCP; | |
| 49 | /* The last text we put into the clipboard. This is used when the OS | 121 | |
| 50 | does not support sequence numbers (NT4, 95). It is undesirable to | 122 | /* A hidden window just for the clipboard management. */ |
| 51 | use data put on the clipboard by Emacs because the clipboard data | 123 | static HWND clipboard_owner; |
| 52 | could be MULEtilated by inappropriately chosen | 124 | /* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just |
| 53 | (next-)selection-coding-system. For this reason, we must store the | 125 | checking GetClipboardOwner() doesn't work, sadly). */ |
| 54 | text *after* it was encoded/Unix-to-DOS-converted. */ | 126 | static int modifying_clipboard = 0; |
| 55 | static unsigned char *last_clipboard_text = NULL; | 127 | |
| 56 | static size_t clipboard_storage_size = 0; | 128 | /* Configured transfer parameters, based on the last inspection of |
| 57 | 129 | selection-coding-system. */ | |
| 58 | #if 0 | 130 | static Lisp_Object cfg_coding_system; |
| 59 | DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0, | 131 | static UINT cfg_codepage; |
| 60 | doc: /* This opens the clipboard with the given frame pointer. */) | 132 | static LCID cfg_lcid; |
| 61 | (frame) | 133 | static UINT cfg_clipboard_type; |
| 62 | Lisp_Object frame; | 134 | |
| 135 | /* The current state for delayed rendering. */ | ||
| 136 | static Lisp_Object current_text; | ||
| 137 | static Lisp_Object current_coding_system; | ||
| 138 | static int current_requires_encoding, current_num_nls; | ||
| 139 | static UINT current_clipboard_type; | ||
| 140 | static LCID current_lcid; | ||
| 141 | |||
| 142 | #if TRACE | ||
| 143 | #define ONTRACE(stmt) stmt | ||
| 144 | #else | ||
| 145 | #define ONTRACE(stmt) /*stmt*/ | ||
| 146 | #endif | ||
| 147 | |||
| 148 | |||
| 149 | /* This function assumes that there is no multibyte character in | ||
| 150 | current_text, so we can short-cut encoding. */ | ||
| 151 | |||
| 152 | static HGLOBAL | ||
| 153 | convert_to_handle_as_ascii (void) | ||
| 63 | { | 154 | { |
| 64 | BOOL ok = FALSE; | 155 | HGLOBAL htext = NULL; |
| 156 | int nbytes; | ||
| 157 | int truelen; | ||
| 158 | unsigned char *src; | ||
| 159 | unsigned char *dst; | ||
| 65 | 160 | ||
| 66 | if (!NILP (frame)) | 161 | ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n")); |
| 67 | CHECK_LIVE_FRAME (frame); | ||
| 68 | 162 | ||
| 69 | BLOCK_INPUT; | 163 | nbytes = SBYTES (current_text) + 1; |
| 164 | src = SDATA (current_text); | ||
| 70 | 165 | ||
| 71 | ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL); | 166 | /* We need to add to the size the number of LF chars where we have |
| 167 | to insert CR chars (the standard CF_TEXT clipboard format uses | ||
| 168 | CRLF line endings, while Emacs uses just LF internally). */ | ||
| 72 | 169 | ||
| 73 | UNBLOCK_INPUT; | 170 | truelen = nbytes + current_num_nls; |
| 171 | |||
| 172 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) | ||
| 173 | return NULL; | ||
| 74 | 174 | ||
| 75 | return (ok ? frame : Qnil); | 175 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) |
| 176 | { | ||
| 177 | GlobalFree (htext); | ||
| 178 | return NULL; | ||
| 179 | } | ||
| 180 | |||
| 181 | /* convert to CRLF line endings expected by clipboard */ | ||
| 182 | while (1) | ||
| 183 | { | ||
| 184 | unsigned char *next; | ||
| 185 | /* copy next line or remaining bytes including '\0' */ | ||
| 186 | next = _memccpy (dst, src, '\n', nbytes); | ||
| 187 | if (next) | ||
| 188 | { | ||
| 189 | /* copied one line ending with '\n' */ | ||
| 190 | int copied = next - dst; | ||
| 191 | nbytes -= copied; | ||
| 192 | src += copied; | ||
| 193 | /* insert '\r' before '\n' */ | ||
| 194 | next[-1] = '\r'; | ||
| 195 | next[0] = '\n'; | ||
| 196 | dst = next + 1; | ||
| 197 | } | ||
| 198 | else | ||
| 199 | /* copied remaining partial line -> now finished */ | ||
| 200 | break; | ||
| 201 | } | ||
| 202 | |||
| 203 | GlobalUnlock (htext); | ||
| 204 | |||
| 205 | return htext; | ||
| 76 | } | 206 | } |
| 77 | 207 | ||
| 78 | DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard, | 208 | /* This function assumes that there are multibyte or NUL characters in |
| 79 | Sw32_empty_clipboard, 0, 0, 0, | 209 | current_text, or that we need to construct Unicode. It runs the |
| 80 | doc: /* Empty the clipboard. | 210 | text through the encoding machinery. */ |
| 81 | Assigns ownership of the clipboard to the window which opened it. */) | 211 | |
| 82 | () | 212 | static HGLOBAL |
| 213 | convert_to_handle_as_coded (Lisp_Object coding_system) | ||
| 83 | { | 214 | { |
| 84 | BOOL ok = FALSE; | 215 | HGLOBAL htext = NULL, htext2; |
| 216 | int nbytes; | ||
| 217 | unsigned char *src; | ||
| 218 | unsigned char *dst = NULL; | ||
| 219 | int bufsize; | ||
| 220 | struct coding_system coding; | ||
| 221 | Lisp_Object string = Qnil; | ||
| 222 | |||
| 223 | ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n", | ||
| 224 | SDATA (SYMBOL_NAME (coding_system)))); | ||
| 225 | |||
| 226 | setup_coding_system (Fcheck_coding_system (coding_system), &coding); | ||
| 227 | coding.src_multibyte = 1; | ||
| 228 | coding.dst_multibyte = 0; | ||
| 229 | /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in | ||
| 230 | encode_coding_iso2022 trying to dereference a null pointer. */ | ||
| 231 | coding.composing = COMPOSITION_DISABLED; | ||
| 232 | if (coding.type == coding_type_iso2022) | ||
| 233 | coding.flags |= CODING_FLAG_ISO_SAFE; | ||
| 234 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 235 | /* Force DOS line-ends. */ | ||
| 236 | coding.eol_type = CODING_EOL_CRLF; | ||
| 237 | |||
| 238 | if (SYMBOLP (coding.pre_write_conversion) | ||
| 239 | && !NILP (Ffboundp (coding.pre_write_conversion))) | ||
| 240 | string = run_pre_post_conversion_on_str (current_text, &coding, 1); | ||
| 241 | else | ||
| 242 | string = current_text; | ||
| 243 | |||
| 244 | nbytes = SBYTES (string); | ||
| 245 | src = SDATA (string); | ||
| 85 | 246 | ||
| 86 | BLOCK_INPUT; | 247 | bufsize = encoding_buffer_size (&coding, nbytes) +2; |
| 248 | htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize); | ||
| 87 | 249 | ||
| 88 | ok = EmptyClipboard (); | 250 | if (htext != NULL) |
| 251 | dst = (unsigned char *) GlobalLock (htext); | ||
| 89 | 252 | ||
| 90 | UNBLOCK_INPUT; | 253 | if (dst != NULL) |
| 254 | { | ||
| 255 | encode_coding (&coding, src, dst, nbytes, bufsize-2); | ||
| 256 | /* Add the string terminator. Add two NULs in case we are | ||
| 257 | producing Unicode here. */ | ||
| 258 | dst[coding.produced] = dst[coding.produced+1] = '\0'; | ||
| 259 | } | ||
| 91 | 260 | ||
| 92 | return (ok ? Qt : Qnil); | 261 | if (dst != NULL) |
| 262 | GlobalUnlock (htext); | ||
| 263 | |||
| 264 | if (htext != NULL) | ||
| 265 | { | ||
| 266 | /* Shrink data block to actual size. */ | ||
| 267 | htext2 = GlobalReAlloc (htext, coding.produced+2, | ||
| 268 | GMEM_MOVEABLE | GMEM_DDESHARE); | ||
| 269 | if (htext2 != NULL) htext = htext2; | ||
| 270 | } | ||
| 271 | |||
| 272 | return htext; | ||
| 273 | } | ||
| 274 | |||
| 275 | static Lisp_Object | ||
| 276 | render (Lisp_Object oformat) | ||
| 277 | { | ||
| 278 | HGLOBAL htext = NULL; | ||
| 279 | UINT format = XFASTINT (oformat); | ||
| 280 | |||
| 281 | ONTRACE (fprintf (stderr, "render\n")); | ||
| 282 | |||
| 283 | if (NILP (current_text)) | ||
| 284 | return Qnil; | ||
| 285 | |||
| 286 | if (current_requires_encoding || format == CF_UNICODETEXT) | ||
| 287 | { | ||
| 288 | if (format == current_clipboard_type) | ||
| 289 | htext = convert_to_handle_as_coded (current_coding_system); | ||
| 290 | else | ||
| 291 | switch (format) | ||
| 292 | { | ||
| 293 | case CF_UNICODETEXT: | ||
| 294 | htext = convert_to_handle_as_coded (QUNICODE); | ||
| 295 | break; | ||
| 296 | case CF_TEXT: | ||
| 297 | case CF_OEMTEXT: | ||
| 298 | { | ||
| 299 | Lisp_Object cs; | ||
| 300 | cs = coding_from_cp (cp_from_locale (current_lcid, format)); | ||
| 301 | htext = convert_to_handle_as_coded (cs); | ||
| 302 | break; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | } | ||
| 306 | else | ||
| 307 | htext = convert_to_handle_as_ascii (); | ||
| 308 | |||
| 309 | ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext)); | ||
| 310 | |||
| 311 | if (htext == NULL) | ||
| 312 | return Qnil; | ||
| 313 | |||
| 314 | if (SetClipboardData (format, htext) == NULL) | ||
| 315 | { | ||
| 316 | GlobalFree(htext); | ||
| 317 | return Qnil; | ||
| 318 | } | ||
| 319 | |||
| 320 | return Qt; | ||
| 93 | } | 321 | } |
| 94 | 322 | ||
| 95 | DEFUN ("w32-close-clipboard", Fw32_close_clipboard, | 323 | static Lisp_Object |
| 96 | Sw32_close_clipboard, 0, 0, 0, | 324 | render_locale (void) |
| 97 | doc: /* Close the clipboard. */) | ||
| 98 | () | ||
| 99 | { | 325 | { |
| 100 | BOOL ok = FALSE; | 326 | HANDLE hlocale = NULL; |
| 327 | LCID * lcid_ptr; | ||
| 328 | |||
| 329 | ONTRACE (fprintf (stderr, "render_locale\n")); | ||
| 330 | |||
| 331 | if (current_lcid == LOCALE_NEUTRAL || current_lcid == DEFAULT_LCID) | ||
| 332 | return Qt; | ||
| 333 | |||
| 334 | hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, sizeof (current_lcid)); | ||
| 335 | if (hlocale == NULL) | ||
| 336 | return Qnil; | ||
| 337 | |||
| 338 | if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) == NULL) | ||
| 339 | { | ||
| 340 | GlobalFree(hlocale); | ||
| 341 | return Qnil; | ||
| 342 | } | ||
| 343 | |||
| 344 | *lcid_ptr = current_lcid; | ||
| 345 | GlobalUnlock (hlocale); | ||
| 346 | |||
| 347 | if (SetClipboardData (CF_LOCALE, hlocale) == NULL) | ||
| 348 | { | ||
| 349 | GlobalFree(hlocale); | ||
| 350 | return Qnil; | ||
| 351 | } | ||
| 352 | |||
| 353 | return Qt; | ||
| 354 | } | ||
| 355 | |||
| 356 | /* At the end of the program, we want to ensure that our clipboard | ||
| 357 | data survives us. This code will do that. */ | ||
| 358 | |||
| 359 | static Lisp_Object | ||
| 360 | render_all (void) | ||
| 361 | { | ||
| 362 | ONTRACE (fprintf (stderr, "render_all\n")); | ||
| 363 | |||
| 364 | /* According to the docs we should not call OpenClipboard() here, | ||
| 365 | but testing on W2K and working code in other projects shows that | ||
| 366 | it is actually necessary. */ | ||
| 367 | |||
| 368 | OpenClipboard (NULL); | ||
| 369 | |||
| 370 | /* There is no usefull means to report errors here, there are none | ||
| 371 | expected anyway, and even if there were errors, they wouldn't do | ||
| 372 | any harm. So we just go ahead and do what has to be done without | ||
| 373 | bothering with error handling. */ | ||
| 374 | |||
| 375 | ++modifying_clipboard; | ||
| 376 | EmptyClipboard (); | ||
| 377 | --modifying_clipboard; | ||
| 378 | |||
| 379 | /* For text formats that we don't render here, the OS can use its | ||
| 380 | own translation rules instead, so we don't really need to offer | ||
| 381 | everything. To minimize memory consumption we cover three | ||
| 382 | possible situations based on our primary format as detected from | ||
| 383 | selection-coding-system (see setup_config()): | ||
| 384 | |||
| 385 | - Post CF_TEXT only. Let the OS convert to CF_OEMTEXT and the OS | ||
| 386 | (on NT) or the application (on 9x/Me) convert to | ||
| 387 | CF_UNICODETEXT. | ||
| 388 | |||
| 389 | - Post CF_OEMTEXT only. Similar automatic conversions happen as | ||
| 390 | for CF_TEXT. | ||
| 391 | |||
| 392 | - Post CF_UNICODETEXT + CF_TEXT. 9x itself ignores | ||
| 393 | CF_UNICODETEXT, even though some applications can still handle | ||
| 394 | it. | ||
| 395 | |||
| 396 | Note 1: We render the less capable CF_TEXT *before* the more | ||
| 397 | capable CF_UNICODETEXT, to prevent clobbering through automatic | ||
| 398 | conversions, just in case. | ||
| 399 | |||
| 400 | Note 2: We could check os_subtype here and only render the | ||
| 401 | additional CF_TEXT on 9x/Me. But OTOH with | ||
| 402 | current_clipboard_type == CF_UNICODETEXT we don't involve the | ||
| 403 | automatic conversions anywhere else, so to get consistent | ||
| 404 | results, we probably don't want to rely on it here either. */ | ||
| 405 | |||
| 406 | render_locale(); | ||
| 407 | |||
| 408 | if (current_clipboard_type == CF_UNICODETEXT) | ||
| 409 | render (make_number (CF_TEXT)); | ||
| 410 | render (make_number (current_clipboard_type)); | ||
| 411 | |||
| 412 | CloseClipboard (); | ||
| 413 | |||
| 414 | return Qnil; | ||
| 415 | } | ||
| 416 | |||
| 417 | static void | ||
| 418 | run_protected (Lisp_Object (*code) (), Lisp_Object arg) | ||
| 419 | { | ||
| 420 | /* FIXME: This works but it doesn't feel right. Too much fiddling | ||
| 421 | with global variables and calling strange looking functions. Is | ||
| 422 | this really the right way to run Lisp callbacks? */ | ||
| 423 | |||
| 424 | extern int waiting_for_input; | ||
| 425 | int owfi; | ||
| 101 | 426 | ||
| 102 | BLOCK_INPUT; | 427 | BLOCK_INPUT; |
| 103 | 428 | ||
| 104 | ok = CloseClipboard (); | 429 | /* Fsignal calls abort() if it sees that waiting_for_input is |
| 430 | set. */ | ||
| 431 | owfi = waiting_for_input; | ||
| 432 | waiting_for_input = 0; | ||
| 433 | |||
| 434 | internal_condition_case_1 (code, arg, Qt, lisp_error_handler); | ||
| 435 | |||
| 436 | waiting_for_input = owfi; | ||
| 105 | 437 | ||
| 106 | UNBLOCK_INPUT; | 438 | UNBLOCK_INPUT; |
| 439 | } | ||
| 107 | 440 | ||
| 108 | return (ok ? Qt : Qnil); | 441 | static Lisp_Object |
| 442 | lisp_error_handler (Lisp_Object error) | ||
| 443 | { | ||
| 444 | Vsignaling_function = Qnil; | ||
| 445 | cmd_error_internal (error, "Error in delayed clipboard rendering: "); | ||
| 446 | Vinhibit_quit = Qt; | ||
| 447 | return Qt; | ||
| 109 | } | 448 | } |
| 110 | 449 | ||
| 111 | #endif | ||
| 112 | 450 | ||
| 113 | DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, | 451 | static LRESULT CALLBACK |
| 114 | Sw32_set_clipboard_data, 1, 2, 0, | 452 | owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp) |
| 115 | doc: /* This sets the clipboard data to the given text. */) | ||
| 116 | (string, frame) | ||
| 117 | Lisp_Object string, frame; | ||
| 118 | { | 453 | { |
| 119 | BOOL ok = TRUE; | 454 | switch (msg) |
| 120 | HANDLE htext; | 455 | { |
| 121 | int nbytes; | 456 | case WM_RENDERFORMAT: |
| 122 | int truelen, nlines = 0; | 457 | ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n")); |
| 123 | unsigned char *src; | 458 | run_protected (render, make_number (wp)); |
| 124 | unsigned char *dst; | 459 | return 0; |
| 460 | |||
| 461 | case WM_RENDERALLFORMATS: | ||
| 462 | ONTRACE (fprintf (stderr, "WM_RENDERALLFORMATS\n")); | ||
| 463 | run_protected (render_all, Qnil); | ||
| 464 | return 0; | ||
| 465 | |||
| 466 | case WM_DESTROYCLIPBOARD: | ||
| 467 | if (!modifying_clipboard) | ||
| 468 | { | ||
| 469 | ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n")); | ||
| 470 | current_text = Qnil; | ||
| 471 | current_coding_system = Qnil; | ||
| 472 | } | ||
| 473 | else | ||
| 474 | { | ||
| 475 | ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (self)\n")); | ||
| 476 | } | ||
| 477 | return 0; | ||
| 125 | 478 | ||
| 126 | CHECK_STRING (string); | 479 | case WM_DESTROY: |
| 480 | if (win == clipboard_owner) | ||
| 481 | clipboard_owner = NULL; | ||
| 482 | break; | ||
| 483 | } | ||
| 127 | 484 | ||
| 128 | if (!NILP (frame)) | 485 | return DefWindowProc (win, msg, wp, lp); |
| 129 | CHECK_LIVE_FRAME (frame); | 486 | } |
| 130 | 487 | ||
| 131 | BLOCK_INPUT; | 488 | static HWND |
| 489 | create_owner (void) | ||
| 490 | { | ||
| 491 | static const char CLASSNAME[] = "Emacs Clipboard"; | ||
| 492 | WNDCLASS wc; | ||
| 132 | 493 | ||
| 133 | /* Include the terminating NULL character in the source of | 494 | memset (&wc, 0, sizeof (wc)); |
| 134 | conversion. */ | 495 | wc.lpszClassName = CLASSNAME; |
| 135 | nbytes = SBYTES (string) + 1; | 496 | wc.lpfnWndProc = owner_callback; |
| 136 | src = SDATA (string); | 497 | RegisterClass (&wc); |
| 137 | dst = src; | 498 | |
| 499 | return CreateWindow (CLASSNAME, CLASSNAME, 0, 0, 0, 0, 0, NULL, NULL, | ||
| 500 | NULL, NULL); | ||
| 501 | } | ||
| 502 | |||
| 503 | /* Called on exit by term_ntproc() in w32.c */ | ||
| 504 | |||
| 505 | void | ||
| 506 | term_w32select (void) | ||
| 507 | { | ||
| 508 | /* This is needed to trigger WM_RENDERALLFORMATS. */ | ||
| 509 | if (clipboard_owner != NULL) | ||
| 510 | DestroyWindow (clipboard_owner); | ||
| 511 | } | ||
| 138 | 512 | ||
| 139 | /* We need to know how many lines there are, since we need CRLF line | 513 | static void |
| 140 | termination for compatibility with other Windows Programs. | 514 | setup_config (void) |
| 141 | avoid using strchr because it recomputes the length every time */ | 515 | { |
| 142 | while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL) | 516 | const char *coding_name; |
| 517 | const char *cp; | ||
| 518 | char *end; | ||
| 519 | int slen; | ||
| 520 | Lisp_Object new_coding_system; | ||
| 521 | |||
| 522 | CHECK_SYMBOL (Vselection_coding_system); | ||
| 523 | |||
| 524 | /* Check if we have it cached */ | ||
| 525 | new_coding_system = NILP (Vnext_selection_coding_system) ? | ||
| 526 | Vselection_coding_system : Vnext_selection_coding_system; | ||
| 527 | if (!NILP (cfg_coding_system) | ||
| 528 | && EQ (cfg_coding_system, new_coding_system)) | ||
| 529 | return; | ||
| 530 | cfg_coding_system = new_coding_system; | ||
| 531 | |||
| 532 | /* Set some sensible fallbacks */ | ||
| 533 | cfg_codepage = ANSICP; | ||
| 534 | cfg_lcid = LOCALE_NEUTRAL; | ||
| 535 | cfg_clipboard_type = CF_TEXT; | ||
| 536 | |||
| 537 | /* Interpret the coding system symbol name */ | ||
| 538 | coding_name = SDATA (SYMBOL_NAME (cfg_coding_system)); | ||
| 539 | |||
| 540 | /* "(.*-)?utf-16.*" -> CF_UNICODETEXT */ | ||
| 541 | cp = strstr (coding_name, "utf-16"); | ||
| 542 | if (cp != NULL && (cp == coding_name || cp[-1] == '-')) | ||
| 143 | { | 543 | { |
| 144 | nlines++; | 544 | cfg_clipboard_type = CF_UNICODETEXT; |
| 145 | dst++; | 545 | return; |
| 146 | } | 546 | } |
| 147 | 547 | ||
| 148 | { | 548 | /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */ |
| 149 | /* Since we are now handling multilingual text, we must consider | 549 | slen = strlen (coding_name); |
| 150 | encoding text for the clipboard. */ | 550 | if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p') |
| 151 | int result = string_xstring_p (string); | 551 | cp = coding_name + 2; |
| 552 | else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0) | ||
| 553 | cp = coding_name + 8; | ||
| 554 | else | ||
| 555 | return; | ||
| 556 | |||
| 557 | end = (char*)cp; | ||
| 558 | cfg_codepage = strtol (cp, &end, 10); | ||
| 559 | |||
| 560 | /* Error return from strtol() or number of digits < 2 -> Restore the | ||
| 561 | default and drop it. */ | ||
| 562 | if (cfg_codepage == 0 || (end-cp) < 2 ) | ||
| 563 | { | ||
| 564 | cfg_codepage = ANSICP; | ||
| 565 | return; | ||
| 566 | } | ||
| 152 | 567 | ||
| 153 | if (result == 0) | 568 | /* Is it the currently active system default? */ |
| 154 | { | 569 | if (cfg_codepage == ANSICP) |
| 155 | /* No multibyte character in OBJ. We need not encode it. */ | 570 | { |
| 571 | /* cfg_clipboard_type = CF_TEXT; */ | ||
| 572 | return; | ||
| 573 | } | ||
| 574 | if (cfg_codepage == OEMCP) | ||
| 575 | { | ||
| 576 | cfg_clipboard_type = CF_OEMTEXT; | ||
| 577 | return; | ||
| 578 | } | ||
| 156 | 579 | ||
| 157 | /* Need to know final size after CR chars are inserted (the | 580 | /* Else determine a suitable locale the hard way. */ |
| 158 | standard CF_TEXT clipboard format uses CRLF line endings, | 581 | EnumSystemLocales (enum_locale_callback, LCID_INSTALLED); |
| 159 | while Emacs uses just LF internally). */ | 582 | } |
| 160 | 583 | ||
| 161 | truelen = nbytes + nlines; | 584 | static BOOL WINAPI |
| 585 | enum_locale_callback (/*const*/ char* loc_string) | ||
| 586 | { | ||
| 587 | LCID lcid; | ||
| 588 | UINT codepage; | ||
| 162 | 589 | ||
| 163 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) | 590 | lcid = strtoul (loc_string, NULL, 16); |
| 164 | goto error; | ||
| 165 | 591 | ||
| 166 | if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) | 592 | /* Is the wanted codepage the "ANSI" codepage for this locale? */ |
| 167 | goto error; | 593 | codepage = cp_from_locale (lcid, CF_TEXT); |
| 594 | if (codepage == cfg_codepage) | ||
| 595 | { | ||
| 596 | cfg_lcid = lcid; | ||
| 597 | cfg_clipboard_type = CF_TEXT; | ||
| 598 | return FALSE; /* Stop enumeration */ | ||
| 599 | } | ||
| 600 | |||
| 601 | /* Is the wanted codepage the OEM codepage for this locale? */ | ||
| 602 | codepage = cp_from_locale (lcid, CF_OEMTEXT); | ||
| 603 | if (codepage == cfg_codepage) | ||
| 604 | { | ||
| 605 | cfg_lcid = lcid; | ||
| 606 | cfg_clipboard_type = CF_OEMTEXT; | ||
| 607 | return FALSE; /* Stop enumeration */ | ||
| 608 | } | ||
| 168 | 609 | ||
| 169 | /* convert to CRLF line endings expected by clipboard */ | 610 | return TRUE; /* Continue enumeration */ |
| 170 | while (1) | 611 | } |
| 171 | { | ||
| 172 | unsigned char *next; | ||
| 173 | /* copy next line or remaining bytes including '\0' */ | ||
| 174 | next = _memccpy (dst, src, '\n', nbytes); | ||
| 175 | if (next) | ||
| 176 | { | ||
| 177 | /* copied one line ending with '\n' */ | ||
| 178 | int copied = next - dst; | ||
| 179 | nbytes -= copied; | ||
| 180 | src += copied; | ||
| 181 | /* insert '\r' before '\n' */ | ||
| 182 | next[-1] = '\r'; | ||
| 183 | next[0] = '\n'; | ||
| 184 | dst = next + 1; | ||
| 185 | } | ||
| 186 | else | ||
| 187 | /* copied remaining partial line -> now finished */ | ||
| 188 | break; | ||
| 189 | } | ||
| 190 | 612 | ||
| 191 | GlobalUnlock (htext); | 613 | static UINT |
| 614 | cp_from_locale (LCID lcid, UINT format) | ||
| 615 | { | ||
| 616 | char buffer[20] = ""; | ||
| 617 | UINT variant, cp; | ||
| 192 | 618 | ||
| 193 | Vlast_coding_system_used = Qraw_text; | 619 | variant = |
| 194 | } | 620 | format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE; |
| 195 | else | ||
| 196 | { | ||
| 197 | /* We must encode contents of OBJ to the selection coding | ||
| 198 | system. */ | ||
| 199 | struct coding_system coding; | ||
| 200 | HANDLE htext2; | ||
| 201 | 621 | ||
| 202 | if (NILP (Vnext_selection_coding_system)) | 622 | GetLocaleInfo (lcid, variant, buffer, sizeof (buffer)); |
| 203 | Vnext_selection_coding_system = Vselection_coding_system; | 623 | cp = strtoul (buffer, NULL, 10); |
| 204 | setup_coding_system | ||
| 205 | (Fcheck_coding_system (Vnext_selection_coding_system), &coding); | ||
| 206 | coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); | ||
| 207 | 624 | ||
| 208 | Vnext_selection_coding_system = Qnil; | 625 | if (cp == CP_ACP) |
| 626 | return ANSICP; | ||
| 627 | else if (cp == CP_OEMCP) | ||
| 628 | return OEMCP; | ||
| 629 | else | ||
| 630 | return cp; | ||
| 631 | } | ||
| 209 | 632 | ||
| 210 | /* We suppress producing escape sequences for composition. */ | 633 | static Lisp_Object |
| 211 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | 634 | coding_from_cp (UINT codepage) |
| 212 | coding.dst_bytes = SCHARS (string) * 2; | 635 | { |
| 213 | if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.dst_bytes)) == NULL) | 636 | char buffer[30]; |
| 214 | goto error; | 637 | sprintf (buffer, "cp%d-dos", (int) codepage); |
| 215 | if ((coding.destination = (unsigned char *) GlobalLock (htext)) == NULL) | 638 | return intern (buffer); |
| 216 | goto error; | 639 | /* We don't need to check that this coding system exists right here, |
| 217 | encode_coding_object (&coding, string, 0, 0, | 640 | because that is done when the coding system is actually |
| 218 | SCHARS (string), SBYTES (string), Qnil); | 641 | instantiated, i.e. it is passed through Fcheck_coding_system() |
| 219 | Vlast_coding_system_used = CODING_ID_NAME (coding.id); | 642 | there. */ |
| 643 | } | ||
| 220 | 644 | ||
| 221 | /* If clipboard sequence numbers are not supported, keep a copy for | ||
| 222 | later comparison. */ | ||
| 223 | if (!clipboard_sequence_fn) | ||
| 224 | { | ||
| 225 | /* Stash away the data we are about to put into the | ||
| 226 | clipboard, so we could later check inside | ||
| 227 | Fw32_get_clipboard_data whether the clipboard still | ||
| 228 | holds our data. */ | ||
| 229 | if (clipboard_storage_size < coding.produced) | ||
| 230 | { | ||
| 231 | clipboard_storage_size = coding.produced + 100; | ||
| 232 | last_clipboard_text = (char *) xrealloc (last_clipboard_text, | ||
| 233 | clipboard_storage_size); | ||
| 234 | } | ||
| 235 | if (last_clipboard_text) | ||
| 236 | memcpy (last_clipboard_text, coding.destination, | ||
| 237 | coding.produced); | ||
| 238 | } | ||
| 239 | 645 | ||
| 240 | GlobalUnlock (htext); | 646 | DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, |
| 647 | Sw32_set_clipboard_data, 1, 2, 0, | ||
| 648 | doc: /* This sets the clipboard data to the given text. */) | ||
| 649 | (string, ignored) | ||
| 650 | Lisp_Object string, ignored; | ||
| 651 | { | ||
| 652 | BOOL ok = TRUE; | ||
| 653 | int nbytes; | ||
| 654 | unsigned char *src; | ||
| 655 | unsigned char *dst; | ||
| 656 | unsigned char *end; | ||
| 241 | 657 | ||
| 242 | /* Shrink data block to actual size. */ | 658 | /* This parameter used to be the current frame, but we don't use |
| 243 | htext2 = GlobalReAlloc (htext, coding.produced, | 659 | that any more. */ |
| 244 | GMEM_MOVEABLE | GMEM_DDESHARE); | 660 | (void) ignored; |
| 245 | if (htext2 != NULL) htext = htext2; | ||
| 246 | } | ||
| 247 | } | ||
| 248 | 661 | ||
| 249 | if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) | 662 | CHECK_STRING (string); |
| 663 | |||
| 664 | setup_config (); | ||
| 665 | |||
| 666 | current_text = string; | ||
| 667 | current_coding_system = cfg_coding_system; | ||
| 668 | current_clipboard_type = cfg_clipboard_type; | ||
| 669 | current_lcid = cfg_lcid; | ||
| 670 | current_num_nls = 0; | ||
| 671 | current_requires_encoding = 0; | ||
| 672 | |||
| 673 | BLOCK_INPUT; | ||
| 674 | |||
| 675 | /* Check for non-ASCII characters. While we are at it, count the | ||
| 676 | number of LFs, so we know how many CRs we will have to add later | ||
| 677 | (just in the case where we can use our internal ASCII rendering, | ||
| 678 | see code and comment in convert_to_handle_as_ascii() above). */ | ||
| 679 | nbytes = SBYTES (string); | ||
| 680 | src = SDATA (string); | ||
| 681 | |||
| 682 | for (dst = src, end = src+nbytes; dst < end; dst++) | ||
| 683 | { | ||
| 684 | if (*dst == '\n') | ||
| 685 | current_num_nls++; | ||
| 686 | else if (*dst >= 0x80 || *dst == 0) | ||
| 687 | { | ||
| 688 | current_requires_encoding = 1; | ||
| 689 | break; | ||
| 690 | } | ||
| 691 | } | ||
| 692 | |||
| 693 | if (!current_requires_encoding) | ||
| 694 | { | ||
| 695 | /* If all we have is ASCII we don't need to pretend we offer | ||
| 696 | anything fancy. */ | ||
| 697 | current_coding_system = Qraw_text; | ||
| 698 | current_clipboard_type = CF_TEXT; | ||
| 699 | current_lcid = LOCALE_NEUTRAL; | ||
| 700 | } | ||
| 701 | |||
| 702 | if (!OpenClipboard (clipboard_owner)) | ||
| 250 | goto error; | 703 | goto error; |
| 251 | 704 | ||
| 252 | ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext); | 705 | ++modifying_clipboard; |
| 706 | ok = EmptyClipboard (); | ||
| 707 | --modifying_clipboard; | ||
| 708 | |||
| 709 | /* If we have something non-ASCII we may want to set a locale. We | ||
| 710 | do that directly (non-delayed), as it's just a small bit. */ | ||
| 711 | if (ok) | ||
| 712 | ok = !NILP(render_locale()); | ||
| 713 | |||
| 714 | if (ok) | ||
| 715 | { | ||
| 716 | if (clipboard_owner == NULL) | ||
| 717 | { | ||
| 718 | /* If for some reason we don't have a clipboard_owner, we | ||
| 719 | just set the text format as chosen by the configuration | ||
| 720 | and than forget about the whole thing. */ | ||
| 721 | ok = !NILP(render (make_number (current_clipboard_type))); | ||
| 722 | current_text = Qnil; | ||
| 723 | current_coding_system = Qnil; | ||
| 724 | } | ||
| 725 | else | ||
| 726 | { | ||
| 727 | /* Advertise all supported formats so that whatever the | ||
| 728 | requester chooses, only one encoding step needs to be | ||
| 729 | made. This is intentionally different from what we do in | ||
| 730 | the handler for WM_RENDERALLFORMATS. */ | ||
| 731 | SetClipboardData (CF_UNICODETEXT, NULL); | ||
| 732 | SetClipboardData (CF_TEXT, NULL); | ||
| 733 | SetClipboardData (CF_OEMTEXT, NULL); | ||
| 734 | } | ||
| 735 | } | ||
| 253 | 736 | ||
| 254 | CloseClipboard (); | 737 | CloseClipboard (); |
| 255 | 738 | ||
| 256 | /* Common sense says to read the sequence number inside the | 739 | /* With delayed rendering we haven't really "used" this coding |
| 257 | OpenClipboard/ CloseClipboard block to avoid race conditions | 740 | system yet, and it's even unclear if we ever will. But this is a |
| 258 | where another app puts something on the clipboard straight after | 741 | way to tell the upper level what we *would* use under ideal |
| 259 | us. But experience suggests that the sequence number from the | 742 | circumstances. |
| 260 | SetClipboardData is not allocated until we close the clipboard! | 743 | |
| 261 | Since clipboard operations are normally user-driven, the race | 744 | We don't signal the actually used coding-system later when we |
| 262 | condition is probably not going to really happen. */ | 745 | finally render, because that can happen at any time and we don't |
| 263 | if (clipboard_sequence_fn) | 746 | want to disturb the "foreground" action. */ |
| 264 | last_clipboard_sequence_number = clipboard_sequence_fn (); | 747 | if (ok) |
| 748 | Vlast_coding_system_used = current_coding_system; | ||
| 749 | |||
| 750 | Vnext_selection_coding_system = Qnil; | ||
| 265 | 751 | ||
| 266 | if (ok) goto done; | 752 | if (ok) goto done; |
| 267 | 753 | ||
| 268 | error: | 754 | error: |
| 269 | 755 | ||
| 270 | ok = FALSE; | 756 | ok = FALSE; |
| 271 | if (htext) GlobalFree (htext); | 757 | current_text = Qnil; |
| 272 | if (last_clipboard_text) | 758 | current_coding_system = Qnil; |
| 273 | *last_clipboard_text = '\0'; | ||
| 274 | |||
| 275 | last_clipboard_sequence_number = 0; | ||
| 276 | 759 | ||
| 277 | done: | 760 | done: |
| 278 | UNBLOCK_INPUT; | 761 | UNBLOCK_INPUT; |
| @@ -280,24 +763,52 @@ DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, | |||
| 280 | return (ok ? string : Qnil); | 763 | return (ok ? string : Qnil); |
| 281 | } | 764 | } |
| 282 | 765 | ||
| 766 | |||
| 283 | DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | 767 | DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, |
| 284 | Sw32_get_clipboard_data, 0, 1, 0, | 768 | Sw32_get_clipboard_data, 0, 1, 0, |
| 285 | doc: /* This gets the clipboard data in text format. */) | 769 | doc: /* This gets the clipboard data in text format. */) |
| 286 | (frame) | 770 | (ignored) |
| 287 | Lisp_Object frame; | 771 | Lisp_Object ignored; |
| 288 | { | 772 | { |
| 289 | HANDLE htext; | 773 | HGLOBAL htext; |
| 290 | Lisp_Object ret = Qnil; | 774 | Lisp_Object ret = Qnil; |
| 775 | UINT actual_clipboard_type; | ||
| 776 | int use_configured_coding_system = 1; | ||
| 777 | |||
| 778 | /* This parameter used to be the current frame, but we don't use | ||
| 779 | that any more. */ | ||
| 780 | (void) ignored; | ||
| 291 | 781 | ||
| 292 | if (!NILP (frame)) | 782 | /* Don't pass our own text from the clipboard (which might be |
| 293 | CHECK_LIVE_FRAME (frame); | 783 | troublesome if the killed text includes null characters). */ |
| 784 | if (!NILP (current_text)) | ||
| 785 | return ret; | ||
| 786 | |||
| 787 | setup_config (); | ||
| 788 | actual_clipboard_type = cfg_clipboard_type; | ||
| 294 | 789 | ||
| 295 | BLOCK_INPUT; | 790 | BLOCK_INPUT; |
| 296 | 791 | ||
| 297 | if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) | 792 | if (!OpenClipboard (clipboard_owner)) |
| 298 | goto done; | 793 | goto done; |
| 299 | 794 | ||
| 300 | if ((htext = GetClipboardData (CF_TEXT)) == NULL) | 795 | if ((htext = GetClipboardData (actual_clipboard_type)) == NULL) |
| 796 | { | ||
| 797 | /* If we want CF_UNICODETEXT but can't get it, the current | ||
| 798 | coding system is useless. OTOH we can still try and decode | ||
| 799 | CF_TEXT based on the locale that the system gives us and that | ||
| 800 | we get down below. */ | ||
| 801 | if (actual_clipboard_type == CF_UNICODETEXT) | ||
| 802 | { | ||
| 803 | htext = GetClipboardData (CF_TEXT); | ||
| 804 | if (htext != NULL) | ||
| 805 | { | ||
| 806 | actual_clipboard_type = CF_TEXT; | ||
| 807 | use_configured_coding_system = 0; | ||
| 808 | } | ||
| 809 | } | ||
| 810 | } | ||
| 811 | if (htext == NULL) | ||
| 301 | goto closeclip; | 812 | goto closeclip; |
| 302 | 813 | ||
| 303 | { | 814 | { |
| @@ -310,51 +821,105 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | |||
| 310 | if ((src = (unsigned char *) GlobalLock (htext)) == NULL) | 821 | if ((src = (unsigned char *) GlobalLock (htext)) == NULL) |
| 311 | goto closeclip; | 822 | goto closeclip; |
| 312 | 823 | ||
| 313 | nbytes = strlen (src); | 824 | /* If the clipboard data contains any non-ascii code, we need to |
| 314 | 825 | decode it with a coding system. */ | |
| 315 | /* If the text in clipboard is identical to what we put there | 826 | if (actual_clipboard_type == CF_UNICODETEXT) |
| 316 | last time w32_set_clipboard_data was called, pretend there's no | 827 | { |
| 317 | data in the clipboard. This is so we don't pass our own text | 828 | nbytes = lstrlenW ((WCHAR *)src) * 2; |
| 318 | from the clipboard (which might be troublesome if the killed | 829 | require_decoding = 1; |
| 319 | text includes null characters). */ | 830 | } |
| 320 | if ((clipboard_sequence_fn | 831 | else |
| 321 | && clipboard_sequence_fn () == last_clipboard_sequence_number) | 832 | { |
| 322 | || (last_clipboard_text | 833 | int i; |
| 323 | && clipboard_storage_size >= nbytes | ||
| 324 | && memcmp(last_clipboard_text, src, nbytes) == 0)) | ||
| 325 | goto closeclip; | ||
| 326 | 834 | ||
| 327 | { | 835 | nbytes = strlen (src); |
| 328 | /* If the clipboard data contains any non-ascii code, we | ||
| 329 | need to decode it. */ | ||
| 330 | int i; | ||
| 331 | 836 | ||
| 332 | for (i = 0; i < nbytes; i++) | 837 | for (i = 0; i < nbytes; i++) |
| 333 | { | 838 | { |
| 334 | if (src[i] >= 0x80) | 839 | if (src[i] >= 0x80) |
| 335 | { | 840 | { |
| 336 | require_decoding = 1; | 841 | require_decoding = 1; |
| 337 | break; | 842 | break; |
| 338 | } | 843 | } |
| 339 | } | 844 | } |
| 340 | } | 845 | } |
| 341 | 846 | ||
| 342 | if (require_decoding) | 847 | if (require_decoding) |
| 343 | { | 848 | { |
| 344 | struct coding_system coding; | 849 | struct coding_system coding; |
| 850 | Lisp_Object coding_system = Qnil; | ||
| 851 | |||
| 852 | /* `next-selection-coding-system' should override everything, | ||
| 853 | even when the locale passed by the system disagrees. The | ||
| 854 | only exception is when `next-selection-coding-system' | ||
| 855 | requested CF_UNICODETEXT and we couldn't get that. */ | ||
| 856 | if (use_configured_coding_system | ||
| 857 | && !NILP (Vnext_selection_coding_system)) | ||
| 858 | coding_system = Vnext_selection_coding_system; | ||
| 859 | |||
| 860 | /* If we have CF_TEXT or CF_OEMTEXT, we want to check out | ||
| 861 | CF_LOCALE, too. */ | ||
| 862 | else if (actual_clipboard_type != CF_UNICODETEXT) | ||
| 863 | { | ||
| 864 | HGLOBAL hlocale; | ||
| 865 | LCID lcid = DEFAULT_LCID; | ||
| 866 | UINT cp; | ||
| 867 | |||
| 868 | /* Documentation says that the OS always generates | ||
| 869 | CF_LOCALE info automatically, so the locale handle | ||
| 870 | should always be present. Fact is that this is not | ||
| 871 | always true on 9x ;-(. */ | ||
| 872 | hlocale = GetClipboardData (CF_LOCALE); | ||
| 873 | if (hlocale != NULL) | ||
| 874 | { | ||
| 875 | const LCID * lcid_ptr; | ||
| 876 | lcid_ptr = (const LCID *) GlobalLock (hlocale); | ||
| 877 | if (lcid_ptr != NULL) | ||
| 878 | { | ||
| 879 | lcid = *lcid_ptr; | ||
| 880 | GlobalUnlock (hlocale); | ||
| 881 | } | ||
| 882 | |||
| 883 | /* 9x has garbage as the sort order (to be exact there | ||
| 884 | is another instance of the language id in the upper | ||
| 885 | word). We don't care about sort order anyway, so | ||
| 886 | we just filter out the unneeded mis-information to | ||
| 887 | avoid irritations. */ | ||
| 888 | lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT); | ||
| 889 | } | ||
| 890 | |||
| 891 | /* If we are using fallback from CF_UNICODETEXT, we can't | ||
| 892 | use the configured coding system. Also we don't want | ||
| 893 | to use it, if the system has supplied us with a locale | ||
| 894 | and it is not just the system default. */ | ||
| 895 | if (!use_configured_coding_system || lcid != DEFAULT_LCID) | ||
| 896 | { | ||
| 897 | cp = cp_from_locale (lcid, actual_clipboard_type); | ||
| 898 | /* If it's just our current standard setting anyway, | ||
| 899 | use the coding system that the user has selected. | ||
| 900 | Otherwise create a new spec to match the locale | ||
| 901 | that was specified by the other side or the | ||
| 902 | system. */ | ||
| 903 | if (!use_configured_coding_system || cp != cfg_codepage) | ||
| 904 | coding_system = coding_from_cp (cp); | ||
| 905 | } | ||
| 906 | } | ||
| 907 | |||
| 908 | if (NILP (coding_system)) | ||
| 909 | coding_system = Vselection_coding_system; | ||
| 910 | Vnext_selection_coding_system = Qnil; | ||
| 345 | 911 | ||
| 346 | if (NILP (Vnext_selection_coding_system)) | 912 | setup_coding_system (Fcheck_coding_system (coding_system), &coding); |
| 347 | Vnext_selection_coding_system = Vselection_coding_system; | ||
| 348 | setup_coding_system | ||
| 349 | (Fcheck_coding_system (Vnext_selection_coding_system), &coding); | ||
| 350 | coding.src_multibyte = 0; | 913 | coding.src_multibyte = 0; |
| 351 | coding.dst_multibyte = 1; | 914 | coding.dst_multibyte = 1; |
| 352 | Vnext_selection_coding_system = Qnil; | ||
| 353 | coding.mode |= CODING_MODE_LAST_BLOCK; | 915 | coding.mode |= CODING_MODE_LAST_BLOCK; |
| 354 | /* We explicitly disable composition handling because | 916 | /* We explicitly disable composition handling because |
| 355 | selection data should not contain any composition | 917 | selection data should not contain any composition |
| 356 | sequence. */ | 918 | sequence. */ |
| 357 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | 919 | coding.common_flags &= ~CODING_ANNOTATION_MASK; |
| 920 | /* Force DOS line-ends. */ | ||
| 921 | coding.eol_type = CODING_EOL_CRLF; | ||
| 922 | |||
| 358 | coding.dst_bytes = nbytes * 2; | 923 | coding.dst_bytes = nbytes * 2; |
| 359 | coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); | 924 | coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); |
| 360 | decode_coding_c_string (&coding, src, nbytes, Qnil); | 925 | decode_coding_c_string (&coding, src, nbytes, Qnil); |
| @@ -365,10 +930,13 @@ DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | |||
| 365 | } | 930 | } |
| 366 | else | 931 | else |
| 367 | { | 932 | { |
| 368 | /* Need to know final size after CR chars are removed because we | 933 | /* FIXME: We may want to repeat the code in this branch for |
| 369 | can't change the string size manually, and doing an extra | 934 | the Unicode case. */ |
| 370 | copy is silly. Note that we only remove CR when it appears | 935 | |
| 371 | as part of CRLF. */ | 936 | /* Need to know final size after CR chars are removed because |
| 937 | we can't change the string size manually, and doing an | ||
| 938 | extra copy is silly. We only remove CR when it appears as | ||
| 939 | part of CRLF. */ | ||
| 372 | 940 | ||
| 373 | truelen = nbytes; | 941 | truelen = nbytes; |
| 374 | dst = src; | 942 | dst = src; |
| @@ -445,9 +1013,14 @@ and t is the same as `SECONDARY'. */) | |||
| 445 | 1013 | ||
| 446 | if (OpenClipboard (NULL)) | 1014 | if (OpenClipboard (NULL)) |
| 447 | { | 1015 | { |
| 448 | int format = 0; | 1016 | UINT format = 0; |
| 449 | while (format = EnumClipboardFormats (format)) | 1017 | setup_config (); |
| 450 | if (format == CF_TEXT) | 1018 | while ((format = EnumClipboardFormats (format))) |
| 1019 | /* Check CF_TEXT in addition to cfg_clipboard_type, | ||
| 1020 | because we can fall back on that if CF_UNICODETEXT is | ||
| 1021 | not available. Actually a check for CF_TEXT only | ||
| 1022 | should be enough. */ | ||
| 1023 | if (format == cfg_clipboard_type || format == CF_TEXT) | ||
| 451 | { | 1024 | { |
| 452 | val = Qt; | 1025 | val = Qt; |
| 453 | break; | 1026 | break; |
| @@ -459,24 +1032,25 @@ and t is the same as `SECONDARY'. */) | |||
| 459 | return Qnil; | 1032 | return Qnil; |
| 460 | } | 1033 | } |
| 461 | 1034 | ||
| 1035 | /* One-time init. Called in the un-dumped Emacs, but not in the | ||
| 1036 | dumped version. */ | ||
| 1037 | |||
| 462 | void | 1038 | void |
| 463 | syms_of_w32select () | 1039 | syms_of_w32select () |
| 464 | { | 1040 | { |
| 465 | #if 0 | ||
| 466 | defsubr (&Sw32_open_clipboard); | ||
| 467 | defsubr (&Sw32_empty_clipboard); | ||
| 468 | defsubr (&Sw32_close_clipboard); | ||
| 469 | #endif | ||
| 470 | defsubr (&Sw32_set_clipboard_data); | 1041 | defsubr (&Sw32_set_clipboard_data); |
| 471 | defsubr (&Sw32_get_clipboard_data); | 1042 | defsubr (&Sw32_get_clipboard_data); |
| 472 | defsubr (&Sx_selection_exists_p); | 1043 | defsubr (&Sx_selection_exists_p); |
| 473 | 1044 | ||
| 474 | DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, | 1045 | DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, |
| 475 | doc: /* Coding system for communicating with other programs. | 1046 | doc: /* Coding system for communicating with other programs. |
| 476 | When sending or receiving text via cut_buffer, selection, and clipboard, | 1047 | When sending or receiving text via cut_buffer, selection, and |
| 477 | the text is encoded or decoded by this coding system. | 1048 | clipboard, the text is encoded or decoded by this coding system. |
| 478 | The default value is `iso-latin-1-dos'. */); | 1049 | The default value is the current system default encoding on 9x/Me and |
| 479 | Vselection_coding_system = intern ("iso-latin-1-dos"); | 1050 | `utf-16le-dos' (Unicode) on NT/W2K/XP. */); |
| 1051 | /* The actual value is set dynamically in the dumped Emacs, see | ||
| 1052 | below. */ | ||
| 1053 | Vselection_coding_system = Qnil; | ||
| 480 | 1054 | ||
| 481 | DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, | 1055 | DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, |
| 482 | doc: /* Coding system for the next communication with other programs. | 1056 | doc: /* Coding system for the next communication with other programs. |
| @@ -487,6 +1061,41 @@ set to nil. */); | |||
| 487 | Vnext_selection_coding_system = Qnil; | 1061 | Vnext_selection_coding_system = Qnil; |
| 488 | 1062 | ||
| 489 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); | 1063 | QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); |
| 1064 | |||
| 1065 | cfg_coding_system = Qnil; staticpro (&cfg_coding_system); | ||
| 1066 | current_text = Qnil; staticpro (¤t_text); | ||
| 1067 | current_coding_system = Qnil; staticpro (¤t_coding_system); | ||
| 1068 | |||
| 1069 | QUNICODE = intern ("utf-16le-dos"); staticpro (&QUNICODE); | ||
| 1070 | QANSICP = Qnil; staticpro (&QANSICP); | ||
| 1071 | QOEMCP = Qnil; staticpro (&QOEMCP); | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | /* One-time init. Called in the dumped Emacs, but not in the | ||
| 1075 | un-dumped version. */ | ||
| 1076 | |||
| 1077 | void | ||
| 1078 | globals_of_w32select () | ||
| 1079 | { | ||
| 1080 | DEFAULT_LCID = GetUserDefaultLCID (); | ||
| 1081 | /* Drop the sort order from the LCID, so we can compare this with | ||
| 1082 | CF_LOCALE objects that have the same fix on 9x. */ | ||
| 1083 | DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT); | ||
| 1084 | |||
| 1085 | ANSICP = GetACP (); | ||
| 1086 | OEMCP = GetOEMCP (); | ||
| 1087 | |||
| 1088 | QANSICP = coding_from_cp (ANSICP); | ||
| 1089 | QOEMCP = coding_from_cp (OEMCP); | ||
| 1090 | |||
| 1091 | if (os_subtype == OS_NT) | ||
| 1092 | Vselection_coding_system = QUNICODE; | ||
| 1093 | else if (inhibit_window_system) | ||
| 1094 | Vselection_coding_system = QOEMCP; | ||
| 1095 | else | ||
| 1096 | Vselection_coding_system = QANSICP; | ||
| 1097 | |||
| 1098 | clipboard_owner = create_owner (); | ||
| 490 | } | 1099 | } |
| 491 | 1100 | ||
| 492 | /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af | 1101 | /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af |