16884
|
1 /* Selection processing for Emacs on the Microsoft W32 API.
|
75227
|
2 Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
|
79759
|
3 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
4
|
14186
|
5 This file is part of GNU Emacs.
|
|
6
|
|
7 GNU Emacs is free software; you can redistribute it and/or modify
|
|
8 it under the terms of the GNU General Public License as published by
|
78260
|
9 the Free Software Foundation; either version 3, or (at your option)
|
14186
|
10 any later version.
|
|
11
|
|
12 GNU Emacs is distributed in the hope that it will be useful,
|
|
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 GNU General Public License for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GNU Emacs; see the file COPYING. If not, write to
|
64084
|
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
20 Boston, MA 02110-1301, USA. */
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
21
|
60092
|
22 /* Written by Kevin Gallo, Benjamin Riefenstahl */
|
|
23
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
24
|
60092
|
25 /*
|
|
26 * Notes on usage of selection-coding-system and
|
|
27 * next-selection-coding-system on MS Windows:
|
|
28 *
|
|
29 * The selection coding system variables apply only to the version of
|
|
30 * the clipboard data that is closest in type, i.e. when a 16-bit
|
|
31 * Unicode coding system is given, they apply to he Unicode clipboard
|
|
32 * (CF_UNICODETEXT), when a well-known console codepage is given, they
|
|
33 * apply to the console version of the clipboard data (CF_OEMTEXT),
|
|
34 * else they apply to the normal 8-bit text clipboard (CF_TEXT).
|
|
35 *
|
|
36 * When pasting (getting data from the OS), the clipboard format that
|
|
37 * matches the {next-}selection-coding-system is retrieved. If
|
|
38 * Unicode is requested, but not available, 8-bit text (CF_TEXT) is
|
|
39 * used. In all other cases the OS will transparently convert
|
|
40 * formats, so no other fallback is needed.
|
|
41 *
|
|
42 * When copying or cutting (sending data to the OS), the data is
|
|
43 * announced and stored internally, but only actually rendered on
|
|
44 * request. The requester determines the format provided. The
|
|
45 * {next-}selection-coding-system is only used, when its corresponding
|
|
46 * clipboard type matches the type requested.
|
|
47 *
|
|
48 * Scenarios to use the facilities for customizing the selection
|
|
49 * coding system are:
|
|
50 *
|
|
51 * ;; Generally use KOI8-R instead of the russian MS codepage for
|
|
52 * ;; the 8-bit clipboard.
|
|
53 * (set-selection-coding-system 'koi8-r-dos)
|
|
54 *
|
|
55 * Or
|
|
56 *
|
|
57 * ;; Create a special clipboard copy function that uses codepage
|
|
58 * ;; 1253 (Greek) to copy Greek text to a specific non-Unicode
|
|
59 * ;; application.
|
|
60 * (defun greek-copy (beg end)
|
|
61 * (interactive "r")
|
|
62 * (set-next-selection-coding-system 'cp1253-dos)
|
|
63 * (copy-region-as-kill beg end))
|
|
64 * (global-set-key "\C-c\C-c" 'greek-copy)
|
|
65 */
|
|
66
|
|
67 /*
|
|
68 * Ideas for further directions:
|
|
69 *
|
|
70 * The encoding and decoding routines could be moved to Lisp code
|
|
71 * similar to how xselect.c does it (using well-known routine names
|
|
72 * for the delayed rendering). If the definition of which clipboard
|
|
73 * types should be supported is also moved to Lisp, functionality
|
|
74 * could be expanded to CF_HTML, CF_RTF and maybe other types.
|
|
75 */
|
|
76
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
77 #include <config.h>
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
78 #include "lisp.h"
|
16588
|
79 #include "w32term.h" /* for all of the w32 includes */
|
60092
|
80 #include "w32heap.h" /* os_subtype */
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
81 #include "blockinput.h"
|
60092
|
82 #include "keyboard.h" /* cmd_error_internal() */
|
22545
|
83 #include "charset.h"
|
|
84 #include "coding.h"
|
90930
|
85 #include "character.h"
|
45988
|
86 #include "composite.h"
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
87
|
60092
|
88
|
|
89 static HGLOBAL convert_to_handle_as_ascii (void);
|
|
90 static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system);
|
|
91 static Lisp_Object render (Lisp_Object oformat);
|
|
92 static Lisp_Object render_locale (void);
|
|
93 static Lisp_Object render_all (void);
|
|
94 static void run_protected (Lisp_Object (*code) (), Lisp_Object arg);
|
|
95 static Lisp_Object lisp_error_handler (Lisp_Object error);
|
|
96 static LRESULT CALLBACK owner_callback (HWND win, UINT msg,
|
|
97 WPARAM wp, LPARAM lp);
|
|
98 static HWND create_owner (void);
|
|
99
|
|
100 static void setup_config (void);
|
|
101 static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
|
|
102 static UINT cp_from_locale (LCID lcid, UINT format);
|
|
103 static Lisp_Object coding_from_cp (UINT codepage);
|
90157
|
104 static Lisp_Object validate_coding_system (Lisp_Object coding_system);
|
|
105 static void setup_windows_coding_system (Lisp_Object coding_system,
|
|
106 struct coding_system * coding);
|
60092
|
107
|
|
108
|
|
109 /* A remnant from X11: Symbol for the CLIPBORD selection type. Other
|
|
110 selections are not used on Windows, so we don't need symbols for
|
|
111 PRIMARY and SECONDARY. */
|
15235
|
112 Lisp_Object QCLIPBOARD;
|
|
113
|
60092
|
114 /* Coding system for communicating with other programs via the
|
22545
|
115 clipboard. */
|
22914
4d4e775cf6f7
(Vselection_coding_system): Renamed from Vclipboard_coding_system.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
116 static Lisp_Object Vselection_coding_system;
|
22545
|
117
|
60092
|
118 /* Coding system for the next communication with other programs. */
|
23562
|
119 static Lisp_Object Vnext_selection_coding_system;
|
|
120
|
60092
|
121 /* Internal pseudo-constants, initialized in globals_of_w32select()
|
|
122 based on current system parameters. */
|
|
123 static LCID DEFAULT_LCID;
|
|
124 static UINT ANSICP, OEMCP;
|
|
125 static Lisp_Object QUNICODE, QANSICP, QOEMCP;
|
|
126
|
|
127 /* A hidden window just for the clipboard management. */
|
|
128 static HWND clipboard_owner;
|
|
129 /* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just
|
|
130 checking GetClipboardOwner() doesn't work, sadly). */
|
|
131 static int modifying_clipboard = 0;
|
|
132
|
|
133 /* Configured transfer parameters, based on the last inspection of
|
|
134 selection-coding-system. */
|
|
135 static Lisp_Object cfg_coding_system;
|
|
136 static UINT cfg_codepage;
|
|
137 static LCID cfg_lcid;
|
|
138 static UINT cfg_clipboard_type;
|
|
139
|
|
140 /* The current state for delayed rendering. */
|
|
141 static Lisp_Object current_text;
|
|
142 static Lisp_Object current_coding_system;
|
|
143 static int current_requires_encoding, current_num_nls;
|
|
144 static UINT current_clipboard_type;
|
|
145 static LCID current_lcid;
|
|
146
|
|
147 #if TRACE
|
|
148 #define ONTRACE(stmt) stmt
|
|
149 #else
|
|
150 #define ONTRACE(stmt) /*stmt*/
|
|
151 #endif
|
|
152
|
|
153
|
|
154 /* This function assumes that there is no multibyte character in
|
|
155 current_text, so we can short-cut encoding. */
|
|
156
|
|
157 static HGLOBAL
|
|
158 convert_to_handle_as_ascii (void)
|
|
159 {
|
|
160 HGLOBAL htext = NULL;
|
|
161 int nbytes;
|
|
162 int truelen;
|
|
163 unsigned char *src;
|
|
164 unsigned char *dst;
|
|
165
|
|
166 ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n"));
|
|
167
|
|
168 nbytes = SBYTES (current_text) + 1;
|
|
169 src = SDATA (current_text);
|
|
170
|
|
171 /* We need to add to the size the number of LF chars where we have
|
|
172 to insert CR chars (the standard CF_TEXT clipboard format uses
|
|
173 CRLF line endings, while Emacs uses just LF internally). */
|
|
174
|
|
175 truelen = nbytes + current_num_nls;
|
|
176
|
|
177 if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
|
|
178 return NULL;
|
|
179
|
|
180 if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
|
|
181 {
|
|
182 GlobalFree (htext);
|
|
183 return NULL;
|
|
184 }
|
|
185
|
|
186 /* convert to CRLF line endings expected by clipboard */
|
|
187 while (1)
|
|
188 {
|
|
189 unsigned char *next;
|
|
190 /* copy next line or remaining bytes including '\0' */
|
|
191 next = _memccpy (dst, src, '\n', nbytes);
|
|
192 if (next)
|
|
193 {
|
|
194 /* copied one line ending with '\n' */
|
|
195 int copied = next - dst;
|
|
196 nbytes -= copied;
|
|
197 src += copied;
|
|
198 /* insert '\r' before '\n' */
|
|
199 next[-1] = '\r';
|
|
200 next[0] = '\n';
|
|
201 dst = next + 1;
|
|
202 }
|
|
203 else
|
|
204 /* copied remaining partial line -> now finished */
|
|
205 break;
|
|
206 }
|
|
207
|
|
208 GlobalUnlock (htext);
|
|
209
|
|
210 return htext;
|
|
211 }
|
|
212
|
|
213 /* This function assumes that there are multibyte or NUL characters in
|
|
214 current_text, or that we need to construct Unicode. It runs the
|
|
215 text through the encoding machinery. */
|
|
216
|
|
217 static HGLOBAL
|
|
218 convert_to_handle_as_coded (Lisp_Object coding_system)
|
|
219 {
|
90157
|
220 HGLOBAL htext;
|
60092
|
221 unsigned char *dst = NULL;
|
|
222 struct coding_system coding;
|
|
223
|
|
224 ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",
|
|
225 SDATA (SYMBOL_NAME (coding_system))));
|
|
226
|
90157
|
227 setup_windows_coding_system (coding_system, &coding);
|
|
228 coding.dst_bytes = SBYTES(current_text) * 2;
|
|
229 coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
|
|
230 encode_coding_object (&coding, current_text, 0, 0,
|
|
231 SCHARS (current_text), SBYTES (current_text), Qnil);
|
60092
|
232
|
90157
|
233 htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.produced +2);
|
60092
|
234
|
|
235 if (htext != NULL)
|
|
236 dst = (unsigned char *) GlobalLock (htext);
|
|
237
|
|
238 if (dst != NULL)
|
|
239 {
|
90157
|
240 memcpy (dst, coding.destination, coding.produced);
|
60092
|
241 /* Add the string terminator. Add two NULs in case we are
|
|
242 producing Unicode here. */
|
|
243 dst[coding.produced] = dst[coding.produced+1] = '\0';
|
90157
|
244
|
|
245 GlobalUnlock (htext);
|
60092
|
246 }
|
|
247
|
90157
|
248 xfree (coding.destination);
|
60092
|
249
|
|
250 return htext;
|
|
251 }
|
|
252
|
|
253 static Lisp_Object
|
|
254 render (Lisp_Object oformat)
|
|
255 {
|
|
256 HGLOBAL htext = NULL;
|
|
257 UINT format = XFASTINT (oformat);
|
|
258
|
|
259 ONTRACE (fprintf (stderr, "render\n"));
|
|
260
|
|
261 if (NILP (current_text))
|
|
262 return Qnil;
|
|
263
|
|
264 if (current_requires_encoding || format == CF_UNICODETEXT)
|
|
265 {
|
|
266 if (format == current_clipboard_type)
|
|
267 htext = convert_to_handle_as_coded (current_coding_system);
|
|
268 else
|
|
269 switch (format)
|
|
270 {
|
|
271 case CF_UNICODETEXT:
|
|
272 htext = convert_to_handle_as_coded (QUNICODE);
|
|
273 break;
|
|
274 case CF_TEXT:
|
|
275 case CF_OEMTEXT:
|
|
276 {
|
|
277 Lisp_Object cs;
|
|
278 cs = coding_from_cp (cp_from_locale (current_lcid, format));
|
|
279 htext = convert_to_handle_as_coded (cs);
|
|
280 break;
|
|
281 }
|
|
282 }
|
|
283 }
|
|
284 else
|
|
285 htext = convert_to_handle_as_ascii ();
|
|
286
|
|
287 ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext));
|
|
288
|
|
289 if (htext == NULL)
|
|
290 return Qnil;
|
|
291
|
|
292 if (SetClipboardData (format, htext) == NULL)
|
|
293 {
|
|
294 GlobalFree(htext);
|
|
295 return Qnil;
|
|
296 }
|
|
297
|
|
298 return Qt;
|
|
299 }
|
|
300
|
|
301 static Lisp_Object
|
|
302 render_locale (void)
|
|
303 {
|
|
304 HANDLE hlocale = NULL;
|
|
305 LCID * lcid_ptr;
|
|
306
|
|
307 ONTRACE (fprintf (stderr, "render_locale\n"));
|
|
308
|
|
309 if (current_lcid == LOCALE_NEUTRAL || current_lcid == DEFAULT_LCID)
|
|
310 return Qt;
|
|
311
|
|
312 hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, sizeof (current_lcid));
|
|
313 if (hlocale == NULL)
|
|
314 return Qnil;
|
|
315
|
|
316 if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) == NULL)
|
|
317 {
|
|
318 GlobalFree(hlocale);
|
|
319 return Qnil;
|
|
320 }
|
33697
e7765cb122c3
(Fw32_set_clipboard_data): Save a copy of what is put on the clipboard.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
321
|
60092
|
322 *lcid_ptr = current_lcid;
|
|
323 GlobalUnlock (hlocale);
|
|
324
|
|
325 if (SetClipboardData (CF_LOCALE, hlocale) == NULL)
|
|
326 {
|
|
327 GlobalFree(hlocale);
|
|
328 return Qnil;
|
|
329 }
|
|
330
|
|
331 return Qt;
|
|
332 }
|
|
333
|
|
334 /* At the end of the program, we want to ensure that our clipboard
|
|
335 data survives us. This code will do that. */
|
|
336
|
|
337 static Lisp_Object
|
|
338 render_all (void)
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
339 {
|
60092
|
340 ONTRACE (fprintf (stderr, "render_all\n"));
|
|
341
|
|
342 /* According to the docs we should not call OpenClipboard() here,
|
|
343 but testing on W2K and working code in other projects shows that
|
|
344 it is actually necessary. */
|
|
345
|
|
346 OpenClipboard (NULL);
|
|
347
|
|
348 /* There is no usefull means to report errors here, there are none
|
|
349 expected anyway, and even if there were errors, they wouldn't do
|
|
350 any harm. So we just go ahead and do what has to be done without
|
|
351 bothering with error handling. */
|
|
352
|
|
353 ++modifying_clipboard;
|
|
354 EmptyClipboard ();
|
|
355 --modifying_clipboard;
|
|
356
|
|
357 /* For text formats that we don't render here, the OS can use its
|
|
358 own translation rules instead, so we don't really need to offer
|
|
359 everything. To minimize memory consumption we cover three
|
|
360 possible situations based on our primary format as detected from
|
|
361 selection-coding-system (see setup_config()):
|
|
362
|
|
363 - Post CF_TEXT only. Let the OS convert to CF_OEMTEXT and the OS
|
|
364 (on NT) or the application (on 9x/Me) convert to
|
|
365 CF_UNICODETEXT.
|
|
366
|
|
367 - Post CF_OEMTEXT only. Similar automatic conversions happen as
|
|
368 for CF_TEXT.
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
369
|
60092
|
370 - Post CF_UNICODETEXT + CF_TEXT. 9x itself ignores
|
|
371 CF_UNICODETEXT, even though some applications can still handle
|
|
372 it.
|
|
373
|
|
374 Note 1: We render the less capable CF_TEXT *before* the more
|
|
375 capable CF_UNICODETEXT, to prevent clobbering through automatic
|
|
376 conversions, just in case.
|
|
377
|
|
378 Note 2: We could check os_subtype here and only render the
|
|
379 additional CF_TEXT on 9x/Me. But OTOH with
|
|
380 current_clipboard_type == CF_UNICODETEXT we don't involve the
|
|
381 automatic conversions anywhere else, so to get consistent
|
|
382 results, we probably don't want to rely on it here either. */
|
|
383
|
|
384 render_locale();
|
|
385
|
|
386 if (current_clipboard_type == CF_UNICODETEXT)
|
|
387 render (make_number (CF_TEXT));
|
|
388 render (make_number (current_clipboard_type));
|
|
389
|
|
390 CloseClipboard ();
|
|
391
|
|
392 return Qnil;
|
|
393 }
|
|
394
|
|
395 static void
|
|
396 run_protected (Lisp_Object (*code) (), Lisp_Object arg)
|
|
397 {
|
|
398 /* FIXME: This works but it doesn't feel right. Too much fiddling
|
|
399 with global variables and calling strange looking functions. Is
|
|
400 this really the right way to run Lisp callbacks? */
|
|
401
|
|
402 extern int waiting_for_input;
|
|
403 int owfi;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
404
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
405 BLOCK_INPUT;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
406
|
60092
|
407 /* Fsignal calls abort() if it sees that waiting_for_input is
|
|
408 set. */
|
|
409 owfi = waiting_for_input;
|
|
410 waiting_for_input = 0;
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
411
|
60092
|
412 internal_condition_case_1 (code, arg, Qt, lisp_error_handler);
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
413
|
60092
|
414 waiting_for_input = owfi;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
415
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
416 UNBLOCK_INPUT;
|
60092
|
417 }
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
418
|
60092
|
419 static Lisp_Object
|
|
420 lisp_error_handler (Lisp_Object error)
|
|
421 {
|
|
422 Vsignaling_function = Qnil;
|
|
423 cmd_error_internal (error, "Error in delayed clipboard rendering: ");
|
|
424 Vinhibit_quit = Qt;
|
|
425 return Qt;
|
|
426 }
|
|
427
|
|
428
|
|
429 static LRESULT CALLBACK
|
|
430 owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp)
|
|
431 {
|
|
432 switch (msg)
|
|
433 {
|
|
434 case WM_RENDERFORMAT:
|
|
435 ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n"));
|
|
436 run_protected (render, make_number (wp));
|
|
437 return 0;
|
|
438
|
|
439 case WM_RENDERALLFORMATS:
|
|
440 ONTRACE (fprintf (stderr, "WM_RENDERALLFORMATS\n"));
|
|
441 run_protected (render_all, Qnil);
|
|
442 return 0;
|
|
443
|
|
444 case WM_DESTROYCLIPBOARD:
|
|
445 if (!modifying_clipboard)
|
|
446 {
|
|
447 ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n"));
|
|
448 current_text = Qnil;
|
|
449 current_coding_system = Qnil;
|
|
450 }
|
|
451 else
|
|
452 {
|
|
453 ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (self)\n"));
|
|
454 }
|
|
455 return 0;
|
|
456
|
|
457 case WM_DESTROY:
|
|
458 if (win == clipboard_owner)
|
|
459 clipboard_owner = NULL;
|
|
460 break;
|
|
461 }
|
|
462
|
|
463 return DefWindowProc (win, msg, wp, lp);
|
|
464 }
|
|
465
|
|
466 static HWND
|
|
467 create_owner (void)
|
|
468 {
|
|
469 static const char CLASSNAME[] = "Emacs Clipboard";
|
|
470 WNDCLASS wc;
|
|
471
|
|
472 memset (&wc, 0, sizeof (wc));
|
|
473 wc.lpszClassName = CLASSNAME;
|
|
474 wc.lpfnWndProc = owner_callback;
|
|
475 RegisterClass (&wc);
|
|
476
|
|
477 return CreateWindow (CLASSNAME, CLASSNAME, 0, 0, 0, 0, 0, NULL, NULL,
|
|
478 NULL, NULL);
|
|
479 }
|
|
480
|
|
481 /* Called on exit by term_ntproc() in w32.c */
|
|
482
|
|
483 void
|
|
484 term_w32select (void)
|
|
485 {
|
|
486 /* This is needed to trigger WM_RENDERALLFORMATS. */
|
|
487 if (clipboard_owner != NULL)
|
|
488 DestroyWindow (clipboard_owner);
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
489 }
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
490
|
60092
|
491 static void
|
|
492 setup_config (void)
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
493 {
|
60092
|
494 const char *coding_name;
|
|
495 const char *cp;
|
|
496 char *end;
|
|
497 int slen;
|
90157
|
498 Lisp_Object coding_system;
|
|
499 Lisp_Object dos_coding_system;
|
60092
|
500
|
|
501 CHECK_SYMBOL (Vselection_coding_system);
|
|
502
|
90157
|
503 coding_system = NILP (Vnext_selection_coding_system) ?
|
|
504 Vselection_coding_system : Vnext_selection_coding_system;
|
|
505
|
|
506 dos_coding_system = validate_coding_system (coding_system);
|
|
507 if (NILP (dos_coding_system))
|
|
508 Fsignal (Qerror,
|
|
509 list2 (build_string ("Coding system is invalid or doesn't have "
|
|
510 "an eol variant for dos line ends"),
|
|
511 coding_system));
|
|
512
|
60092
|
513 /* Check if we have it cached */
|
|
514 if (!NILP (cfg_coding_system)
|
90157
|
515 && EQ (cfg_coding_system, dos_coding_system))
|
60092
|
516 return;
|
90157
|
517 cfg_coding_system = dos_coding_system;
|
60092
|
518
|
|
519 /* Set some sensible fallbacks */
|
|
520 cfg_codepage = ANSICP;
|
|
521 cfg_lcid = LOCALE_NEUTRAL;
|
|
522 cfg_clipboard_type = CF_TEXT;
|
|
523
|
|
524 /* Interpret the coding system symbol name */
|
|
525 coding_name = SDATA (SYMBOL_NAME (cfg_coding_system));
|
|
526
|
|
527 /* "(.*-)?utf-16.*" -> CF_UNICODETEXT */
|
|
528 cp = strstr (coding_name, "utf-16");
|
|
529 if (cp != NULL && (cp == coding_name || cp[-1] == '-'))
|
|
530 {
|
|
531 cfg_clipboard_type = CF_UNICODETEXT;
|
|
532 return;
|
|
533 }
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
534
|
60092
|
535 /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */
|
|
536 slen = strlen (coding_name);
|
|
537 if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p')
|
|
538 cp = coding_name + 2;
|
|
539 else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0)
|
|
540 cp = coding_name + 8;
|
|
541 else
|
|
542 return;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
543
|
60092
|
544 end = (char*)cp;
|
|
545 cfg_codepage = strtol (cp, &end, 10);
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
546
|
60092
|
547 /* Error return from strtol() or number of digits < 2 -> Restore the
|
|
548 default and drop it. */
|
|
549 if (cfg_codepage == 0 || (end-cp) < 2 )
|
|
550 {
|
|
551 cfg_codepage = ANSICP;
|
|
552 return;
|
|
553 }
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
554
|
60092
|
555 /* Is it the currently active system default? */
|
|
556 if (cfg_codepage == ANSICP)
|
|
557 {
|
|
558 /* cfg_clipboard_type = CF_TEXT; */
|
|
559 return;
|
|
560 }
|
|
561 if (cfg_codepage == OEMCP)
|
|
562 {
|
|
563 cfg_clipboard_type = CF_OEMTEXT;
|
|
564 return;
|
|
565 }
|
|
566
|
|
567 /* Else determine a suitable locale the hard way. */
|
|
568 EnumSystemLocales (enum_locale_callback, LCID_INSTALLED);
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
569 }
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
570
|
60092
|
571 static BOOL WINAPI
|
|
572 enum_locale_callback (/*const*/ char* loc_string)
|
|
573 {
|
|
574 LCID lcid;
|
|
575 UINT codepage;
|
|
576
|
|
577 lcid = strtoul (loc_string, NULL, 16);
|
|
578
|
|
579 /* Is the wanted codepage the "ANSI" codepage for this locale? */
|
|
580 codepage = cp_from_locale (lcid, CF_TEXT);
|
|
581 if (codepage == cfg_codepage)
|
|
582 {
|
|
583 cfg_lcid = lcid;
|
|
584 cfg_clipboard_type = CF_TEXT;
|
|
585 return FALSE; /* Stop enumeration */
|
|
586 }
|
|
587
|
|
588 /* Is the wanted codepage the OEM codepage for this locale? */
|
|
589 codepage = cp_from_locale (lcid, CF_OEMTEXT);
|
|
590 if (codepage == cfg_codepage)
|
|
591 {
|
|
592 cfg_lcid = lcid;
|
|
593 cfg_clipboard_type = CF_OEMTEXT;
|
|
594 return FALSE; /* Stop enumeration */
|
|
595 }
|
|
596
|
|
597 return TRUE; /* Continue enumeration */
|
|
598 }
|
|
599
|
|
600 static UINT
|
|
601 cp_from_locale (LCID lcid, UINT format)
|
|
602 {
|
|
603 char buffer[20] = "";
|
|
604 UINT variant, cp;
|
|
605
|
|
606 variant =
|
|
607 format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE;
|
|
608
|
|
609 GetLocaleInfo (lcid, variant, buffer, sizeof (buffer));
|
|
610 cp = strtoul (buffer, NULL, 10);
|
|
611
|
|
612 if (cp == CP_ACP)
|
|
613 return ANSICP;
|
|
614 else if (cp == CP_OEMCP)
|
|
615 return OEMCP;
|
|
616 else
|
|
617 return cp;
|
|
618 }
|
|
619
|
|
620 static Lisp_Object
|
|
621 coding_from_cp (UINT codepage)
|
|
622 {
|
|
623 char buffer[30];
|
|
624 sprintf (buffer, "cp%d-dos", (int) codepage);
|
|
625 return intern (buffer);
|
90157
|
626 /* We don't need to check that this coding system actually exists
|
|
627 right here, because that is done later for all coding systems
|
|
628 used, regardless of where they originate. */
|
60092
|
629 }
|
|
630
|
90157
|
631 static Lisp_Object
|
|
632 validate_coding_system (Lisp_Object coding_system)
|
|
633 {
|
|
634 Lisp_Object eol_type;
|
|
635
|
|
636 /* Make sure the input is valid. */
|
|
637 if (NILP (Fcoding_system_p (coding_system)))
|
|
638 return Qnil;
|
|
639
|
|
640 /* Make sure we use a DOS coding system as mandated by the system
|
|
641 specs. */
|
|
642 eol_type = Fcoding_system_eol_type (coding_system);
|
|
643
|
|
644 /* Already a DOS coding system? */
|
|
645 if (EQ (eol_type, make_number (1)))
|
|
646 return coding_system;
|
|
647
|
|
648 /* Get EOL_TYPE vector of the base of CODING_SYSTEM. */
|
|
649 if (!VECTORP (eol_type))
|
|
650 {
|
|
651 eol_type = Fcoding_system_eol_type (Fcoding_system_base (coding_system));
|
|
652 if (!VECTORP (eol_type))
|
|
653 return Qnil;
|
|
654 }
|
|
655
|
|
656 return AREF (eol_type, 1);
|
|
657 }
|
|
658
|
|
659 static void
|
|
660 setup_windows_coding_system (Lisp_Object coding_system,
|
|
661 struct coding_system * coding)
|
|
662 {
|
|
663 memset (coding, 0, sizeof (*coding));
|
|
664 setup_coding_system (coding_system, coding);
|
|
665
|
|
666 /* Unset CODING_ANNOTATE_COMPOSITION_MASK. Previous code had
|
|
667 comments about crashes in encode_coding_iso2022 trying to
|
|
668 dereference a null pointer when composition was on. Selection
|
|
669 data should not contain any composition sequence on Windows.
|
|
670
|
|
671 CODING_ANNOTATION_MASK also includes
|
|
672 CODING_ANNOTATE_DIRECTION_MASK and CODING_ANNOTATE_CHARSET_MASK,
|
|
673 which both apply to ISO6429 only. We don't know if these really
|
|
674 need to be unset on Windows, but it probably doesn't hurt
|
|
675 either. */
|
|
676 coding->mode &= ~CODING_ANNOTATION_MASK;
|
|
677 coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
|
|
678 }
|
|
679
|
|
680
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
681
|
40962
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
682 DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
683 Sw32_set_clipboard_data, 1, 2, 0,
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
684 doc: /* This sets the clipboard data to the given text. */)
|
60092
|
685 (string, ignored)
|
|
686 Lisp_Object string, ignored;
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
687 {
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
688 BOOL ok = TRUE;
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
689 int nbytes;
|
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
690 unsigned char *src;
|
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
691 unsigned char *dst;
|
60092
|
692 unsigned char *end;
|
|
693
|
|
694 /* This parameter used to be the current frame, but we don't use
|
|
695 that any more. */
|
|
696 (void) ignored;
|
24518
|
697
|
40656
|
698 CHECK_STRING (string);
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
699
|
60092
|
700 setup_config ();
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
701
|
60092
|
702 current_text = string;
|
|
703 current_coding_system = cfg_coding_system;
|
|
704 current_clipboard_type = cfg_clipboard_type;
|
|
705 current_lcid = cfg_lcid;
|
|
706 current_num_nls = 0;
|
|
707 current_requires_encoding = 0;
|
|
708
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
709 BLOCK_INPUT;
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
710
|
60092
|
711 /* Check for non-ASCII characters. While we are at it, count the
|
|
712 number of LFs, so we know how many CRs we will have to add later
|
|
713 (just in the case where we can use our internal ASCII rendering,
|
|
714 see code and comment in convert_to_handle_as_ascii() above). */
|
|
715 nbytes = SBYTES (string);
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
716 src = SDATA (string);
|
24518
|
717
|
60092
|
718 for (dst = src, end = src+nbytes; dst < end; dst++)
|
24518
|
719 {
|
60092
|
720 if (*dst == '\n')
|
|
721 current_num_nls++;
|
|
722 else if (*dst >= 0x80 || *dst == 0)
|
|
723 {
|
|
724 current_requires_encoding = 1;
|
|
725 break;
|
|
726 }
|
24518
|
727 }
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
728
|
60092
|
729 if (!current_requires_encoding)
|
|
730 {
|
|
731 /* If all we have is ASCII we don't need to pretend we offer
|
|
732 anything fancy. */
|
|
733 current_coding_system = Qraw_text;
|
|
734 current_clipboard_type = CF_TEXT;
|
|
735 current_lcid = LOCALE_NEUTRAL;
|
|
736 }
|
22545
|
737
|
60092
|
738 if (!OpenClipboard (clipboard_owner))
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
739 goto error;
|
33697
e7765cb122c3
(Fw32_set_clipboard_data): Save a copy of what is put on the clipboard.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
740
|
60092
|
741 ++modifying_clipboard;
|
|
742 ok = EmptyClipboard ();
|
|
743 --modifying_clipboard;
|
|
744
|
|
745 /* If we have something non-ASCII we may want to set a locale. We
|
|
746 do that directly (non-delayed), as it's just a small bit. */
|
|
747 if (ok)
|
|
748 ok = !NILP(render_locale());
|
|
749
|
|
750 if (ok)
|
|
751 {
|
|
752 if (clipboard_owner == NULL)
|
|
753 {
|
|
754 /* If for some reason we don't have a clipboard_owner, we
|
|
755 just set the text format as chosen by the configuration
|
|
756 and than forget about the whole thing. */
|
|
757 ok = !NILP(render (make_number (current_clipboard_type)));
|
|
758 current_text = Qnil;
|
|
759 current_coding_system = Qnil;
|
|
760 }
|
|
761 else
|
|
762 {
|
|
763 /* Advertise all supported formats so that whatever the
|
|
764 requester chooses, only one encoding step needs to be
|
|
765 made. This is intentionally different from what we do in
|
|
766 the handler for WM_RENDERALLFORMATS. */
|
|
767 SetClipboardData (CF_UNICODETEXT, NULL);
|
|
768 SetClipboardData (CF_TEXT, NULL);
|
|
769 SetClipboardData (CF_OEMTEXT, NULL);
|
|
770 }
|
|
771 }
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
772
|
54974
64d01f3f16e5
(Fw32_set_clipboard_data): Get sequence number after closing the clipboard.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
773 CloseClipboard ();
|
64d01f3f16e5
(Fw32_set_clipboard_data): Get sequence number after closing the clipboard.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
774
|
60092
|
775 /* With delayed rendering we haven't really "used" this coding
|
|
776 system yet, and it's even unclear if we ever will. But this is a
|
|
777 way to tell the upper level what we *would* use under ideal
|
|
778 circumstances.
|
|
779
|
|
780 We don't signal the actually used coding-system later when we
|
|
781 finally render, because that can happen at any time and we don't
|
|
782 want to disturb the "foreground" action. */
|
|
783 if (ok)
|
|
784 Vlast_coding_system_used = current_coding_system;
|
|
785
|
|
786 Vnext_selection_coding_system = Qnil;
|
51777
|
787
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
788 if (ok) goto done;
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
789
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
790 error:
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
791
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
792 ok = FALSE;
|
60092
|
793 current_text = Qnil;
|
|
794 current_coding_system = Qnil;
|
51777
|
795
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
796 done:
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
797 UNBLOCK_INPUT;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
798
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
799 return (ok ? string : Qnil);
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
800 }
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
801
|
60092
|
802
|
40962
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
803 DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
804 Sw32_get_clipboard_data, 0, 1, 0,
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
805 doc: /* This gets the clipboard data in text format. */)
|
60092
|
806 (ignored)
|
|
807 Lisp_Object ignored;
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
808 {
|
60092
|
809 HGLOBAL htext;
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
810 Lisp_Object ret = Qnil;
|
60092
|
811 UINT actual_clipboard_type;
|
|
812 int use_configured_coding_system = 1;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
813
|
60092
|
814 /* This parameter used to be the current frame, but we don't use
|
|
815 that any more. */
|
|
816 (void) ignored;
|
|
817
|
|
818 /* Don't pass our own text from the clipboard (which might be
|
|
819 troublesome if the killed text includes null characters). */
|
|
820 if (!NILP (current_text))
|
|
821 return ret;
|
|
822
|
|
823 setup_config ();
|
|
824 actual_clipboard_type = cfg_clipboard_type;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
825
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
826 BLOCK_INPUT;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
827
|
60092
|
828 if (!OpenClipboard (clipboard_owner))
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
829 goto done;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
830
|
60092
|
831 if ((htext = GetClipboardData (actual_clipboard_type)) == NULL)
|
|
832 {
|
|
833 /* If we want CF_UNICODETEXT but can't get it, the current
|
|
834 coding system is useless. OTOH we can still try and decode
|
|
835 CF_TEXT based on the locale that the system gives us and that
|
|
836 we get down below. */
|
|
837 if (actual_clipboard_type == CF_UNICODETEXT)
|
|
838 {
|
|
839 htext = GetClipboardData (CF_TEXT);
|
|
840 if (htext != NULL)
|
|
841 {
|
|
842 actual_clipboard_type = CF_TEXT;
|
|
843 use_configured_coding_system = 0;
|
|
844 }
|
|
845 }
|
|
846 }
|
|
847 if (htext == NULL)
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
848 goto closeclip;
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
849
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
850 {
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
851 unsigned char *src;
|
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
852 unsigned char *dst;
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
853 int nbytes;
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
854 int truelen;
|
23835
|
855 int require_decoding = 0;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
856
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
857 if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
858 goto closeclip;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
859
|
60092
|
860 /* If the clipboard data contains any non-ascii code, we need to
|
|
861 decode it with a coding system. */
|
|
862 if (actual_clipboard_type == CF_UNICODETEXT)
|
|
863 {
|
|
864 nbytes = lstrlenW ((WCHAR *)src) * 2;
|
|
865 require_decoding = 1;
|
|
866 }
|
|
867 else
|
|
868 {
|
|
869 int i;
|
33697
e7765cb122c3
(Fw32_set_clipboard_data): Save a copy of what is put on the clipboard.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
870
|
60092
|
871 nbytes = strlen (src);
|
23562
|
872
|
60092
|
873 for (i = 0; i < nbytes; i++)
|
|
874 {
|
|
875 if (src[i] >= 0x80)
|
|
876 {
|
|
877 require_decoding = 1;
|
|
878 break;
|
|
879 }
|
|
880 }
|
|
881 }
|
43483
|
882
|
23835
|
883 if (require_decoding)
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
884 {
|
22545
|
885 struct coding_system coding;
|
60092
|
886 Lisp_Object coding_system = Qnil;
|
90157
|
887 Lisp_Object dos_coding_system;
|
60092
|
888
|
|
889 /* `next-selection-coding-system' should override everything,
|
|
890 even when the locale passed by the system disagrees. The
|
|
891 only exception is when `next-selection-coding-system'
|
|
892 requested CF_UNICODETEXT and we couldn't get that. */
|
|
893 if (use_configured_coding_system
|
|
894 && !NILP (Vnext_selection_coding_system))
|
|
895 coding_system = Vnext_selection_coding_system;
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
896
|
60092
|
897 /* If we have CF_TEXT or CF_OEMTEXT, we want to check out
|
|
898 CF_LOCALE, too. */
|
|
899 else if (actual_clipboard_type != CF_UNICODETEXT)
|
|
900 {
|
|
901 HGLOBAL hlocale;
|
|
902 LCID lcid = DEFAULT_LCID;
|
|
903 UINT cp;
|
|
904
|
|
905 /* Documentation says that the OS always generates
|
|
906 CF_LOCALE info automatically, so the locale handle
|
|
907 should always be present. Fact is that this is not
|
|
908 always true on 9x ;-(. */
|
|
909 hlocale = GetClipboardData (CF_LOCALE);
|
|
910 if (hlocale != NULL)
|
|
911 {
|
|
912 const LCID * lcid_ptr;
|
|
913 lcid_ptr = (const LCID *) GlobalLock (hlocale);
|
|
914 if (lcid_ptr != NULL)
|
|
915 {
|
|
916 lcid = *lcid_ptr;
|
|
917 GlobalUnlock (hlocale);
|
|
918 }
|
|
919
|
|
920 /* 9x has garbage as the sort order (to be exact there
|
|
921 is another instance of the language id in the upper
|
|
922 word). We don't care about sort order anyway, so
|
|
923 we just filter out the unneeded mis-information to
|
|
924 avoid irritations. */
|
|
925 lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT);
|
|
926 }
|
|
927
|
|
928 /* If we are using fallback from CF_UNICODETEXT, we can't
|
|
929 use the configured coding system. Also we don't want
|
|
930 to use it, if the system has supplied us with a locale
|
|
931 and it is not just the system default. */
|
|
932 if (!use_configured_coding_system || lcid != DEFAULT_LCID)
|
|
933 {
|
|
934 cp = cp_from_locale (lcid, actual_clipboard_type);
|
|
935 /* If it's just our current standard setting anyway,
|
|
936 use the coding system that the user has selected.
|
|
937 Otherwise create a new spec to match the locale
|
|
938 that was specified by the other side or the
|
|
939 system. */
|
|
940 if (!use_configured_coding_system || cp != cfg_codepage)
|
|
941 coding_system = coding_from_cp (cp);
|
|
942 }
|
|
943 }
|
|
944
|
|
945 if (NILP (coding_system))
|
|
946 coding_system = Vselection_coding_system;
|
|
947 Vnext_selection_coding_system = Qnil;
|
|
948
|
90157
|
949 dos_coding_system = validate_coding_system (coding_system);
|
|
950 if (!NILP (dos_coding_system))
|
|
951 {
|
|
952 setup_windows_coding_system (dos_coding_system, &coding);
|
|
953 coding.source = src;
|
|
954 decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
|
|
955 ret = coding.dst_object;
|
60092
|
956
|
90157
|
957 Vlast_coding_system_used = CODING_ID_NAME (coding.id);
|
|
958 }
|
22545
|
959 }
|
|
960 else
|
|
961 {
|
60092
|
962 /* FIXME: We may want to repeat the code in this branch for
|
|
963 the Unicode case. */
|
|
964
|
|
965 /* Need to know final size after CR chars are removed because
|
|
966 we can't change the string size manually, and doing an
|
|
967 extra copy is silly. We only remove CR when it appears as
|
|
968 part of CRLF. */
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
969
|
22545
|
970 truelen = nbytes;
|
|
971 dst = src;
|
|
972 /* avoid using strchr because it recomputes the length everytime */
|
|
973 while ((dst = memchr (dst, '\r', nbytes - (dst - src))) != NULL)
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
974 {
|
23835
|
975 if (dst[1] == '\n') /* safe because of trailing '\0' */
|
|
976 truelen--;
|
22545
|
977 dst++;
|
|
978 }
|
|
979
|
|
980 ret = make_uninit_string (truelen);
|
|
981
|
23835
|
982 /* Convert CRLF line endings (the standard CF_TEXT clipboard
|
|
983 format) to LF endings as used internally by Emacs. */
|
22545
|
984
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
985 dst = SDATA (ret);
|
22545
|
986 while (1)
|
|
987 {
|
|
988 unsigned char *next;
|
|
989 /* copy next line or remaining bytes excluding '\0' */
|
|
990 next = _memccpy (dst, src, '\r', nbytes);
|
|
991 if (next)
|
|
992 {
|
|
993 /* copied one line ending with '\r' */
|
|
994 int copied = next - dst;
|
|
995 nbytes -= copied;
|
23835
|
996 dst += copied;
|
22545
|
997 src += copied;
|
23835
|
998 if (*src == '\n')
|
|
999 dst--; /* overwrite '\r' with '\n' */
|
|
1000 }
|
22545
|
1001 else
|
|
1002 /* copied remaining partial line -> now finished */
|
|
1003 break;
|
|
1004 }
|
22745
|
1005
|
|
1006 Vlast_coding_system_used = Qraw_text;
|
15150
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
1007 }
|
e37489592e27
(Fwin32_set_clipboard_data, Fwin32_get_clipboard_data):
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
1008
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1009 GlobalUnlock (htext);
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1010 }
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1011
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1012 closeclip:
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1013 CloseClipboard ();
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1014
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1015 done:
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1016 UNBLOCK_INPUT;
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1017
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1018 return (ret);
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1019 }
|
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1020
|
15235
|
1021 /* Support checking for a clipboard selection. */
|
|
1022
|
|
1023 DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
|
40962
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1024 0, 1, 0,
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1025 doc: /* Whether there is an owner for the given X Selection.
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1026 The arg should be the name of the selection in question, typically one of
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1027 the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1028 \(Those are literal upper-case symbol names, since that's what X expects.)
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1029 For convenience, the symbol nil is the same as `PRIMARY',
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1030 and t is the same as `SECONDARY'. */)
|
15235
|
1031 (selection)
|
|
1032 Lisp_Object selection;
|
|
1033 {
|
40656
|
1034 CHECK_SYMBOL (selection);
|
15235
|
1035
|
|
1036 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
|
|
1037 if the clipboard currently has valid text format contents. */
|
|
1038
|
|
1039 if (EQ (selection, QCLIPBOARD))
|
|
1040 {
|
|
1041 Lisp_Object val = Qnil;
|
|
1042
|
90157
|
1043 setup_config ();
|
|
1044
|
15235
|
1045 if (OpenClipboard (NULL))
|
|
1046 {
|
60092
|
1047 UINT format = 0;
|
|
1048 while ((format = EnumClipboardFormats (format)))
|
|
1049 /* Check CF_TEXT in addition to cfg_clipboard_type,
|
|
1050 because we can fall back on that if CF_UNICODETEXT is
|
|
1051 not available. Actually a check for CF_TEXT only
|
|
1052 should be enough. */
|
|
1053 if (format == cfg_clipboard_type || format == CF_TEXT)
|
15235
|
1054 {
|
|
1055 val = Qt;
|
|
1056 break;
|
|
1057 }
|
|
1058 CloseClipboard ();
|
|
1059 }
|
|
1060 return val;
|
|
1061 }
|
|
1062 return Qnil;
|
|
1063 }
|
|
1064
|
60092
|
1065 /* One-time init. Called in the un-dumped Emacs, but not in the
|
|
1066 dumped version. */
|
|
1067
|
47879
4ef507bc376e
(syms_of_win32select): Fix docstring for `selection-coding-system'.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
1068 void
|
16588
|
1069 syms_of_w32select ()
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1070 {
|
16588
|
1071 defsubr (&Sw32_set_clipboard_data);
|
|
1072 defsubr (&Sw32_get_clipboard_data);
|
15235
|
1073 defsubr (&Sx_selection_exists_p);
|
|
1074
|
22914
4d4e775cf6f7
(Vselection_coding_system): Renamed from Vclipboard_coding_system.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1075 DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
|
40962
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1076 doc: /* Coding system for communicating with other programs.
|
60092
|
1077 When sending or receiving text via cut_buffer, selection, and
|
|
1078 clipboard, the text is encoded or decoded by this coding system.
|
|
1079 The default value is the current system default encoding on 9x/Me and
|
|
1080 `utf-16le-dos' (Unicode) on NT/W2K/XP. */);
|
|
1081 /* The actual value is set dynamically in the dumped Emacs, see
|
|
1082 below. */
|
|
1083 Vselection_coding_system = Qnil;
|
22545
|
1084
|
23562
|
1085 DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
|
40962
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1086 doc: /* Coding system for the next communication with other programs.
|
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1087 Usually, `selection-coding-system' is used for communicating with
|
47280
|
1088 other programs. But, if this variable is set, it is used for the
|
|
1089 next communication only. After the communication, this variable is
|
40962
f66d09d1bb2f
Change doc-string comments to `new style'. [w/`doc:' keyword]. Doc fixes.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1090 set to nil. */);
|
23562
|
1091 Vnext_selection_coding_system = Qnil;
|
|
1092
|
90922
|
1093 DEFSYM (QCLIPBOARD, "CLIPBOARD");
|
60092
|
1094
|
|
1095 cfg_coding_system = Qnil; staticpro (&cfg_coding_system);
|
|
1096 current_text = Qnil; staticpro (¤t_text);
|
|
1097 current_coding_system = Qnil; staticpro (¤t_coding_system);
|
|
1098
|
90922
|
1099 DEFSYM (QUNICODE, "utf-16le-dos");
|
60092
|
1100 QANSICP = Qnil; staticpro (&QANSICP);
|
|
1101 QOEMCP = Qnil; staticpro (&QOEMCP);
|
|
1102 }
|
|
1103
|
|
1104 /* One-time init. Called in the dumped Emacs, but not in the
|
|
1105 un-dumped version. */
|
|
1106
|
|
1107 void
|
|
1108 globals_of_w32select ()
|
|
1109 {
|
|
1110 DEFAULT_LCID = GetUserDefaultLCID ();
|
|
1111 /* Drop the sort order from the LCID, so we can compare this with
|
|
1112 CF_LOCALE objects that have the same fix on 9x. */
|
|
1113 DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT);
|
|
1114
|
|
1115 ANSICP = GetACP ();
|
|
1116 OEMCP = GetOEMCP ();
|
|
1117
|
|
1118 QANSICP = coding_from_cp (ANSICP);
|
|
1119 QOEMCP = coding_from_cp (OEMCP);
|
|
1120
|
|
1121 if (os_subtype == OS_NT)
|
|
1122 Vselection_coding_system = QUNICODE;
|
|
1123 else if (inhibit_window_system)
|
|
1124 Vselection_coding_system = QOEMCP;
|
|
1125 else
|
|
1126 Vselection_coding_system = QANSICP;
|
|
1127
|
|
1128 clipboard_owner = create_owner ();
|
13434
Geoff Voelker <voelker@cs.washington.edu>
parents:
diff
changeset
|
1129 }
|
52401
|
1130
|
|
1131 /* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af
|
|
1132 (do not change this comment) */
|