1 |
/* Selection processing for Emacs on the Microsoft W32 API. |
/* Selection processing for Emacs on the Microsoft W32 API. |
2 |
Copyright (C) 1993, 1994 Free Software Foundation. |
Copyright (C) 1993, 1994, 2004 Free Software Foundation. |
3 |
|
|
4 |
This file is part of GNU Emacs. |
This file is part of GNU Emacs. |
5 |
|
|
18 |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 |
Boston, MA 02111-1307, USA. */ |
Boston, MA 02111-1307, USA. */ |
20 |
|
|
21 |
/* Written by Kevin Gallo */ |
/* Written by Kevin Gallo, Benjamin Riefenstahl */ |
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 |
|
|
76 |
#include <config.h> |
#include <config.h> |
77 |
#include "lisp.h" |
#include "lisp.h" |
78 |
#include "w32term.h" /* for all of the w32 includes */ |
#include "w32term.h" /* for all of the w32 includes */ |
79 |
#include "dispextern.h" /* frame.h seems to want this */ |
#include "w32heap.h" /* os_subtype */ |
|
#include "keyboard.h" |
|
|
#include "frame.h" /* Need this to get the X window of selected_frame */ |
|
80 |
#include "blockinput.h" |
#include "blockinput.h" |
81 |
#include "buffer.h" |
#include "keyboard.h" /* cmd_error_internal() */ |
82 |
#include "charset.h" |
#include "charset.h" |
83 |
#include "coding.h" |
#include "coding.h" |
84 |
#include "composite.h" |
#include "composite.h" |
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. */ |
107 |
Lisp_Object QCLIPBOARD; |
Lisp_Object QCLIPBOARD; |
108 |
|
|
109 |
/* Coding system for communicating with other Windows programs via the |
/* Coding system for communicating with other programs via the |
110 |
clipboard. */ |
clipboard. */ |
111 |
static Lisp_Object Vselection_coding_system; |
static Lisp_Object Vselection_coding_system; |
112 |
|
|
113 |
/* Coding system for the next communicating with other Windows programs. */ |
/* Coding system for the next communication with other programs. */ |
114 |
static Lisp_Object Vnext_selection_coding_system; |
static Lisp_Object Vnext_selection_coding_system; |
115 |
|
|
116 |
/* Sequence number, used where possible to detect when we are pasting |
/* Internal pseudo-constants, initialized in globals_of_w32select() |
117 |
our own text. */ |
based on current system parameters. */ |
118 |
static DWORD last_clipboard_sequence_number; |
static LCID DEFAULT_LCID; |
119 |
extern ClipboardSequence_Proc clipboard_sequence_fn; |
static UINT ANSICP, OEMCP; |
120 |
|
static Lisp_Object QUNICODE, QANSICP, QOEMCP; |
121 |
/* The last text we put into the clipboard. This is used when the OS |
|
122 |
does not support sequence numbers (NT4, 95). It is undesirable to |
/* A hidden window just for the clipboard management. */ |
123 |
use data put on the clipboard by Emacs because the clipboard data |
static HWND clipboard_owner; |
124 |
could be MULEtilated by inappropriately chosen |
/* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just |
125 |
(next-)selection-coding-system. For this reason, we must store the |
checking GetClipboardOwner() doesn't work, sadly). */ |
126 |
text *after* it was encoded/Unix-to-DOS-converted. */ |
static int modifying_clipboard = 0; |
127 |
static unsigned char *last_clipboard_text = NULL; |
|
128 |
static size_t clipboard_storage_size = 0; |
/* Configured transfer parameters, based on the last inspection of |
129 |
|
selection-coding-system. */ |
130 |
#if 0 |
static Lisp_Object cfg_coding_system; |
131 |
DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0, |
static UINT cfg_codepage; |
132 |
doc: /* This opens the clipboard with the given frame pointer. */) |
static LCID cfg_lcid; |
133 |
(frame) |
static UINT cfg_clipboard_type; |
134 |
Lisp_Object frame; |
|
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) |
154 |
{ |
{ |
155 |
BOOL ok = FALSE; |
HGLOBAL htext = NULL; |
156 |
|
int nbytes; |
157 |
|
int truelen; |
158 |
|
unsigned char *src; |
159 |
|
unsigned char *dst; |
160 |
|
|
161 |
if (!NILP (frame)) |
ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n")); |
|
CHECK_LIVE_FRAME (frame); |
|
162 |
|
|
163 |
BLOCK_INPUT; |
nbytes = SBYTES (current_text) + 1; |
164 |
|
src = SDATA (current_text); |
165 |
|
|
166 |
ok = OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL); |
/* 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). */ |
169 |
|
|
170 |
UNBLOCK_INPUT; |
truelen = nbytes + current_num_nls; |
171 |
|
|
172 |
|
if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) |
173 |
|
return NULL; |
174 |
|
|
175 |
return (ok ? frame : Qnil); |
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; |
206 |
} |
} |
207 |
|
|
208 |
DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard, |
/* This function assumes that there are multibyte or NUL characters in |
209 |
Sw32_empty_clipboard, 0, 0, 0, |
current_text, or that we need to construct Unicode. It runs the |
210 |
doc: /* Empty the clipboard. |
text through the encoding machinery. */ |
211 |
Assigns ownership of the clipboard to the window which opened it. */) |
|
212 |
() |
static HGLOBAL |
213 |
|
convert_to_handle_as_coded (Lisp_Object coding_system) |
214 |
{ |
{ |
215 |
BOOL ok = FALSE; |
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 |
BLOCK_INPUT; |
nbytes = SBYTES (string); |
245 |
|
src = SDATA (string); |
246 |
|
|
247 |
ok = EmptyClipboard (); |
bufsize = encoding_buffer_size (&coding, nbytes) +2; |
248 |
|
htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize); |
249 |
|
|
250 |
UNBLOCK_INPUT; |
if (htext != NULL) |
251 |
|
dst = (unsigned char *) GlobalLock (htext); |
252 |
|
|
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 |
|
} |
260 |
|
|
261 |
return (ok ? Qt : Qnil); |
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 |
DEFUN ("w32-close-clipboard", Fw32_close_clipboard, |
static Lisp_Object |
276 |
Sw32_close_clipboard, 0, 0, 0, |
render (Lisp_Object oformat) |
|
doc: /* Close the clipboard. */) |
|
|
() |
|
277 |
{ |
{ |
278 |
BOOL ok = FALSE; |
HGLOBAL htext = NULL; |
279 |
|
UINT format = XFASTINT (oformat); |
280 |
|
|
281 |
|
ONTRACE (fprintf (stderr, "render\n")); |
282 |
|
|
283 |
|
if (NILP (current_text)) |
284 |
|
return Qnil; |
285 |
|
|
286 |
|
if (current_requires_encoding || format == CF_UNICODETEXT) |
287 |
|
{ |
288 |
|
if (format == current_clipboard_type) |
289 |
|
htext = convert_to_handle_as_coded (current_coding_system); |
290 |
|
else |
291 |
|
switch (format) |
292 |
|
{ |
293 |
|
case CF_UNICODETEXT: |
294 |
|
htext = convert_to_handle_as_coded (QUNICODE); |
295 |
|
break; |
296 |
|
case CF_TEXT: |
297 |
|
case CF_OEMTEXT: |
298 |
|
{ |
299 |
|
Lisp_Object cs; |
300 |
|
cs = coding_from_cp (cp_from_locale (current_lcid, format)); |
301 |
|
htext = convert_to_handle_as_coded (cs); |
302 |
|
break; |
303 |
|
} |
304 |
|
} |
305 |
|
} |
306 |
|
else |
307 |
|
htext = convert_to_handle_as_ascii (); |
308 |
|
|
309 |
|
ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext)); |
310 |
|
|
311 |
|
if (htext == NULL) |
312 |
|
return Qnil; |
313 |
|
|
314 |
|
if (SetClipboardData (format, htext) == NULL) |
315 |
|
{ |
316 |
|
GlobalFree(htext); |
317 |
|
return Qnil; |
318 |
|
} |
319 |
|
|
320 |
|
return Qt; |
321 |
|
} |
322 |
|
|
323 |
|
static Lisp_Object |
324 |
|
render_locale (void) |
325 |
|
{ |
326 |
|
HANDLE hlocale = NULL; |
327 |
|
LCID * lcid_ptr; |
328 |
|
|
329 |
|
ONTRACE (fprintf (stderr, "render_locale\n")); |
330 |
|
|
331 |
|
if (current_lcid == LOCALE_NEUTRAL || current_lcid == DEFAULT_LCID) |
332 |
|
return Qt; |
333 |
|
|
334 |
|
hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, sizeof (current_lcid)); |
335 |
|
if (hlocale == NULL) |
336 |
|
return Qnil; |
337 |
|
|
338 |
|
if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) == NULL) |
339 |
|
{ |
340 |
|
GlobalFree(hlocale); |
341 |
|
return Qnil; |
342 |
|
} |
343 |
|
|
344 |
|
*lcid_ptr = current_lcid; |
345 |
|
GlobalUnlock (hlocale); |
346 |
|
|
347 |
|
if (SetClipboardData (CF_LOCALE, hlocale) == NULL) |
348 |
|
{ |
349 |
|
GlobalFree(hlocale); |
350 |
|
return Qnil; |
351 |
|
} |
352 |
|
|
353 |
|
return Qt; |
354 |
|
} |
355 |
|
|
356 |
|
/* At the end of the program, we want to ensure that our clipboard |
357 |
|
data survives us. This code will do that. */ |
358 |
|
|
359 |
|
static Lisp_Object |
360 |
|
render_all (void) |
361 |
|
{ |
362 |
|
ONTRACE (fprintf (stderr, "render_all\n")); |
363 |
|
|
364 |
|
/* According to the docs we should not call OpenClipboard() here, |
365 |
|
but testing on W2K and working code in other projects shows that |
366 |
|
it is actually necessary. */ |
367 |
|
|
368 |
|
OpenClipboard (NULL); |
369 |
|
|
370 |
|
/* There is no usefull means to report errors here, there are none |
371 |
|
expected anyway, and even if there were errors, they wouldn't do |
372 |
|
any harm. So we just go ahead and do what has to be done without |
373 |
|
bothering with error handling. */ |
374 |
|
|
375 |
|
++modifying_clipboard; |
376 |
|
EmptyClipboard (); |
377 |
|
--modifying_clipboard; |
378 |
|
|
379 |
|
/* For text formats that we don't render here, the OS can use its |
380 |
|
own translation rules instead, so we don't really need to offer |
381 |
|
everything. To minimize memory consumption we cover three |
382 |
|
possible situations based on our primary format as detected from |
383 |
|
selection-coding-system (see setup_config()): |
384 |
|
|
385 |
|
- Post CF_TEXT only. Let the OS convert to CF_OEMTEXT and the OS |
386 |
|
(on NT) or the application (on 9x/Me) convert to |
387 |
|
CF_UNICODETEXT. |
388 |
|
|
389 |
|
- Post CF_OEMTEXT only. Similar automatic conversions happen as |
390 |
|
for CF_TEXT. |
391 |
|
|
392 |
|
- Post CF_UNICODETEXT + CF_TEXT. 9x itself ignores |
393 |
|
CF_UNICODETEXT, even though some applications can still handle |
394 |
|
it. |
395 |
|
|
396 |
|
Note 1: We render the less capable CF_TEXT *before* the more |
397 |
|
capable CF_UNICODETEXT, to prevent clobbering through automatic |
398 |
|
conversions, just in case. |
399 |
|
|
400 |
|
Note 2: We could check os_subtype here and only render the |
401 |
|
additional CF_TEXT on 9x/Me. But OTOH with |
402 |
|
current_clipboard_type == CF_UNICODETEXT we don't involve the |
403 |
|
automatic conversions anywhere else, so to get consistent |
404 |
|
results, we probably don't want to rely on it here either. */ |
405 |
|
|
406 |
|
render_locale(); |
407 |
|
|
408 |
|
if (current_clipboard_type == CF_UNICODETEXT) |
409 |
|
render (make_number (CF_TEXT)); |
410 |
|
render (make_number (current_clipboard_type)); |
411 |
|
|
412 |
|
CloseClipboard (); |
413 |
|
|
414 |
|
return Qnil; |
415 |
|
} |
416 |
|
|
417 |
|
static void |
418 |
|
run_protected (Lisp_Object (*code) (), Lisp_Object arg) |
419 |
|
{ |
420 |
|
/* FIXME: This works but it doesn't feel right. Too much fiddling |
421 |
|
with global variables and calling strange looking functions. Is |
422 |
|
this really the right way to run Lisp callbacks? */ |
423 |
|
|
424 |
|
extern int waiting_for_input; |
425 |
|
int owfi; |
426 |
|
|
427 |
BLOCK_INPUT; |
BLOCK_INPUT; |
428 |
|
|
429 |
ok = CloseClipboard (); |
/* 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; |
437 |
|
|
438 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
439 |
|
} |
440 |
|
|
441 |
return (ok ? Qt : Qnil); |
static Lisp_Object |
442 |
|
lisp_error_handler (Lisp_Object error) |
443 |
|
{ |
444 |
|
Vsignaling_function = Qnil; |
445 |
|
cmd_error_internal (error, "Error in delayed clipboard rendering: "); |
446 |
|
Vinhibit_quit = Qt; |
447 |
|
return Qt; |
448 |
} |
} |
449 |
|
|
|
#endif |
|
450 |
|
|
451 |
DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, |
static LRESULT CALLBACK |
452 |
Sw32_set_clipboard_data, 1, 2, 0, |
owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp) |
|
doc: /* This sets the clipboard data to the given text. */) |
|
|
(string, frame) |
|
|
Lisp_Object string, frame; |
|
453 |
{ |
{ |
454 |
BOOL ok = TRUE; |
switch (msg) |
455 |
HANDLE htext; |
{ |
456 |
int nbytes; |
case WM_RENDERFORMAT: |
457 |
int truelen, nlines = 0; |
ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n")); |
458 |
unsigned char *src; |
run_protected (render, make_number (wp)); |
459 |
unsigned char *dst; |
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 |
CHECK_STRING (string); |
case WM_DESTROYCLIPBOARD: |
467 |
|
if (!modifying_clipboard) |
468 |
|
{ |
469 |
|
ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n")); |
470 |
|
current_text = Qnil; |
471 |
|
current_coding_system = Qnil; |
472 |
|
} |
473 |
|
else |
474 |
|
{ |
475 |
|
ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (self)\n")); |
476 |
|
} |
477 |
|
return 0; |
478 |
|
|
479 |
if (!NILP (frame)) |
case WM_DESTROY: |
480 |
CHECK_LIVE_FRAME (frame); |
if (win == clipboard_owner) |
481 |
|
clipboard_owner = NULL; |
482 |
|
break; |
483 |
|
} |
484 |
|
|
485 |
BLOCK_INPUT; |
return DefWindowProc (win, msg, wp, lp); |
486 |
|
} |
487 |
|
|
488 |
/* Include the terminating NULL character in the source of |
static HWND |
489 |
conversion. */ |
create_owner (void) |
490 |
nbytes = SBYTES (string) + 1; |
{ |
491 |
src = SDATA (string); |
static const char CLASSNAME[] = "Emacs Clipboard"; |
492 |
dst = src; |
WNDCLASS wc; |
493 |
|
|
494 |
|
memset (&wc, 0, sizeof (wc)); |
495 |
|
wc.lpszClassName = CLASSNAME; |
496 |
|
wc.lpfnWndProc = owner_callback; |
497 |
|
RegisterClass (&wc); |
498 |
|
|
499 |
|
return CreateWindow (CLASSNAME, CLASSNAME, 0, 0, 0, 0, 0, NULL, NULL, |
500 |
|
NULL, NULL); |
501 |
|
} |
502 |
|
|
503 |
|
/* Called on exit by term_ntproc() in w32.c */ |
504 |
|
|
505 |
|
void |
506 |
|
term_w32select (void) |
507 |
|
{ |
508 |
|
/* This is needed to trigger WM_RENDERALLFORMATS. */ |
509 |
|
if (clipboard_owner != NULL) |
510 |
|
DestroyWindow (clipboard_owner); |
511 |
|
} |
512 |
|
|
513 |
/* We need to know how many lines there are, since we need CRLF line |
static void |
514 |
termination for compatibility with other Windows Programs. |
setup_config (void) |
515 |
avoid using strchr because it recomputes the length every time */ |
{ |
516 |
while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL) |
const char *coding_name; |
517 |
|
const char *cp; |
518 |
|
char *end; |
519 |
|
int slen; |
520 |
|
Lisp_Object new_coding_system; |
521 |
|
|
522 |
|
CHECK_SYMBOL (Vselection_coding_system); |
523 |
|
|
524 |
|
/* Check if we have it cached */ |
525 |
|
new_coding_system = NILP (Vnext_selection_coding_system) ? |
526 |
|
Vselection_coding_system : Vnext_selection_coding_system; |
527 |
|
if (!NILP (cfg_coding_system) |
528 |
|
&& EQ (cfg_coding_system, new_coding_system)) |
529 |
|
return; |
530 |
|
cfg_coding_system = new_coding_system; |
531 |
|
|
532 |
|
/* Set some sensible fallbacks */ |
533 |
|
cfg_codepage = ANSICP; |
534 |
|
cfg_lcid = LOCALE_NEUTRAL; |
535 |
|
cfg_clipboard_type = CF_TEXT; |
536 |
|
|
537 |
|
/* Interpret the coding system symbol name */ |
538 |
|
coding_name = SDATA (SYMBOL_NAME (cfg_coding_system)); |
539 |
|
|
540 |
|
/* "(.*-)?utf-16.*" -> CF_UNICODETEXT */ |
541 |
|
cp = strstr (coding_name, "utf-16"); |
542 |
|
if (cp != NULL && (cp == coding_name || cp[-1] == '-')) |
543 |
{ |
{ |
544 |
nlines++; |
cfg_clipboard_type = CF_UNICODETEXT; |
545 |
dst++; |
return; |
546 |
} |
} |
547 |
|
|
548 |
{ |
/* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */ |
549 |
/* Since we are now handling multilingual text, we must consider |
slen = strlen (coding_name); |
550 |
encoding text for the clipboard. */ |
if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p') |
551 |
int charset_info = find_charset_in_text (src, SCHARS (string), |
cp = coding_name + 2; |
552 |
nbytes, NULL, Qnil); |
else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0) |
553 |
|
cp = coding_name + 8; |
554 |
|
else |
555 |
|
return; |
556 |
|
|
557 |
|
end = (char*)cp; |
558 |
|
cfg_codepage = strtol (cp, &end, 10); |
559 |
|
|
560 |
|
/* Error return from strtol() or number of digits < 2 -> Restore the |
561 |
|
default and drop it. */ |
562 |
|
if (cfg_codepage == 0 || (end-cp) < 2 ) |
563 |
|
{ |
564 |
|
cfg_codepage = ANSICP; |
565 |
|
return; |
566 |
|
} |
567 |
|
|
568 |
if (charset_info == 0) |
/* Is it the currently active system default? */ |
569 |
{ |
if (cfg_codepage == ANSICP) |
570 |
/* No multibyte character in OBJ. We need not encode it. */ |
{ |
571 |
|
/* cfg_clipboard_type = CF_TEXT; */ |
572 |
|
return; |
573 |
|
} |
574 |
|
if (cfg_codepage == OEMCP) |
575 |
|
{ |
576 |
|
cfg_clipboard_type = CF_OEMTEXT; |
577 |
|
return; |
578 |
|
} |
579 |
|
|
580 |
|
/* Else determine a suitable locale the hard way. */ |
581 |
|
EnumSystemLocales (enum_locale_callback, LCID_INSTALLED); |
582 |
|
} |
583 |
|
|
584 |
|
static BOOL WINAPI |
585 |
|
enum_locale_callback (/*const*/ char* loc_string) |
586 |
|
{ |
587 |
|
LCID lcid; |
588 |
|
UINT codepage; |
589 |
|
|
590 |
/* Need to know final size after CR chars are inserted (the |
lcid = strtoul (loc_string, NULL, 16); |
|
standard CF_TEXT clipboard format uses CRLF line endings, |
|
|
while Emacs uses just LF internally). */ |
|
591 |
|
|
592 |
truelen = nbytes + nlines; |
/* Is the wanted codepage the "ANSI" codepage for this locale? */ |
593 |
|
codepage = cp_from_locale (lcid, CF_TEXT); |
594 |
|
if (codepage == cfg_codepage) |
595 |
|
{ |
596 |
|
cfg_lcid = lcid; |
597 |
|
cfg_clipboard_type = CF_TEXT; |
598 |
|
return FALSE; /* Stop enumeration */ |
599 |
|
} |
600 |
|
|
601 |
|
/* Is the wanted codepage the OEM codepage for this locale? */ |
602 |
|
codepage = cp_from_locale (lcid, CF_OEMTEXT); |
603 |
|
if (codepage == cfg_codepage) |
604 |
|
{ |
605 |
|
cfg_lcid = lcid; |
606 |
|
cfg_clipboard_type = CF_OEMTEXT; |
607 |
|
return FALSE; /* Stop enumeration */ |
608 |
|
} |
609 |
|
|
610 |
if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL) |
return TRUE; /* Continue enumeration */ |
611 |
goto error; |
} |
612 |
|
|
613 |
if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) |
static UINT |
614 |
goto error; |
cp_from_locale (LCID lcid, UINT format) |
615 |
|
{ |
616 |
|
char buffer[20] = ""; |
617 |
|
UINT variant, cp; |
618 |
|
|
619 |
/* convert to CRLF line endings expected by clipboard */ |
variant = |
620 |
while (1) |
format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE; |
|
{ |
|
|
unsigned char *next; |
|
|
/* copy next line or remaining bytes including '\0' */ |
|
|
next = _memccpy (dst, src, '\n', nbytes); |
|
|
if (next) |
|
|
{ |
|
|
/* copied one line ending with '\n' */ |
|
|
int copied = next - dst; |
|
|
nbytes -= copied; |
|
|
src += copied; |
|
|
/* insert '\r' before '\n' */ |
|
|
next[-1] = '\r'; |
|
|
next[0] = '\n'; |
|
|
dst = next + 1; |
|
|
} |
|
|
else |
|
|
/* copied remaining partial line -> now finished */ |
|
|
break; |
|
|
} |
|
621 |
|
|
622 |
GlobalUnlock (htext); |
GetLocaleInfo (lcid, variant, buffer, sizeof (buffer)); |
623 |
|
cp = strtoul (buffer, NULL, 10); |
624 |
|
|
625 |
Vlast_coding_system_used = Qraw_text; |
if (cp == CP_ACP) |
626 |
} |
return ANSICP; |
627 |
else |
else if (cp == CP_OEMCP) |
628 |
{ |
return OEMCP; |
629 |
/* We must encode contents of OBJ to the selection coding |
else |
630 |
system. */ |
return cp; |
631 |
int bufsize; |
} |
|
struct coding_system coding; |
|
|
HANDLE htext2; |
|
632 |
|
|
633 |
if (NILP (Vnext_selection_coding_system)) |
static Lisp_Object |
634 |
Vnext_selection_coding_system = Vselection_coding_system; |
coding_from_cp (UINT codepage) |
635 |
setup_coding_system |
{ |
636 |
(Fcheck_coding_system (Vnext_selection_coding_system), &coding); |
char buffer[30]; |
637 |
if (SYMBOLP (coding.pre_write_conversion) |
sprintf (buffer, "cp%d-dos", (int) codepage); |
638 |
&& !NILP (Ffboundp (coding.pre_write_conversion))) |
return intern (buffer); |
639 |
{ |
/* We don't need to check that this coding system exists right here, |
640 |
string = run_pre_post_conversion_on_str (string, &coding, 1); |
because that is done when the coding system is actually |
641 |
src = SDATA (string); |
instantiated, i.e. it is passed through Fcheck_coding_system() |
642 |
/* Include the terminating NULL character in the source of |
there. */ |
643 |
conversion. */ |
} |
|
nbytes = SBYTES (string) + 1; |
|
|
} |
|
|
coding.src_multibyte = 1; |
|
|
coding.dst_multibyte = 0; |
|
|
/* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in |
|
|
encode_coding_iso2022 trying to dereference a null pointer. */ |
|
|
coding.composing = COMPOSITION_DISABLED; |
|
|
if (coding.type == coding_type_iso2022) |
|
|
coding.flags |= CODING_FLAG_ISO_SAFE; |
|
|
Vnext_selection_coding_system = Qnil; |
|
|
coding.mode |= CODING_MODE_LAST_BLOCK; |
|
|
bufsize = encoding_buffer_size (&coding, nbytes); |
|
|
if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize)) == NULL) |
|
|
goto error; |
|
|
if ((dst = (unsigned char *) GlobalLock (htext)) == NULL) |
|
|
goto error; |
|
|
encode_coding (&coding, src, dst, nbytes, bufsize); |
|
|
Vlast_coding_system_used = coding.symbol; |
|
644 |
|
|
|
/* If clipboard sequence numbers are not supported, keep a copy for |
|
|
later comparison. */ |
|
|
if (!clipboard_sequence_fn) |
|
|
{ |
|
|
/* Stash away the data we are about to put into the |
|
|
clipboard, so we could later check inside |
|
|
Fw32_get_clipboard_data whether the clipboard still |
|
|
holds our data. */ |
|
|
if (clipboard_storage_size < coding.produced) |
|
|
{ |
|
|
clipboard_storage_size = coding.produced + 100; |
|
|
last_clipboard_text = (char *) xrealloc (last_clipboard_text, |
|
|
clipboard_storage_size); |
|
|
} |
|
|
if (last_clipboard_text) |
|
|
memcpy (last_clipboard_text, dst, coding.produced); |
|
|
} |
|
645 |
|
|
646 |
GlobalUnlock (htext); |
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; |
657 |
|
|
658 |
/* Shrink data block to actual size. */ |
/* This parameter used to be the current frame, but we don't use |
659 |
htext2 = GlobalReAlloc (htext, coding.produced, |
that any more. */ |
660 |
GMEM_MOVEABLE | GMEM_DDESHARE); |
(void) ignored; |
661 |
if (htext2 != NULL) htext = htext2; |
|
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 |
if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) |
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)) |
703 |
goto error; |
goto error; |
704 |
|
|
705 |
ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext); |
++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 |
|
} |
736 |
|
|
737 |
CloseClipboard (); |
CloseClipboard (); |
738 |
|
|
739 |
/* Common sense says to read the sequence number inside the |
/* With delayed rendering we haven't really "used" this coding |
740 |
OpenClipboard/ CloseClipboard block to avoid race conditions |
system yet, and it's even unclear if we ever will. But this is a |
741 |
where another app puts something on the clipboard straight after |
way to tell the upper level what we *would* use under ideal |
742 |
us. But experience suggests that the sequence number from the |
circumstances. |
743 |
SetClipboardData is not allocated until we close the clipboard! |
|
744 |
Since clipboard operations are normally user-driven, the race |
We don't signal the actually used coding-system later when we |
745 |
condition is probably not going to really happen. */ |
finally render, because that can happen at any time and we don't |
746 |
if (clipboard_sequence_fn) |
want to disturb the "foreground" action. */ |
747 |
last_clipboard_sequence_number = clipboard_sequence_fn (); |
if (ok) |
748 |
|
Vlast_coding_system_used = current_coding_system; |
749 |
|
|
750 |
|
Vnext_selection_coding_system = Qnil; |
751 |
|
|
752 |
if (ok) goto done; |
if (ok) goto done; |
753 |
|
|
754 |
error: |
error: |
755 |
|
|
756 |
ok = FALSE; |
ok = FALSE; |
757 |
if (htext) GlobalFree (htext); |
current_text = Qnil; |
758 |
if (last_clipboard_text) |
current_coding_system = Qnil; |
|
*last_clipboard_text = '\0'; |
|
|
|
|
|
last_clipboard_sequence_number = 0; |
|
759 |
|
|
760 |
done: |
done: |
761 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
763 |
return (ok ? string : Qnil); |
return (ok ? string : Qnil); |
764 |
} |
} |
765 |
|
|
766 |
|
|
767 |
DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, |
DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, |
768 |
Sw32_get_clipboard_data, 0, 1, 0, |
Sw32_get_clipboard_data, 0, 1, 0, |
769 |
doc: /* This gets the clipboard data in text format. */) |
doc: /* This gets the clipboard data in text format. */) |
770 |
(frame) |
(ignored) |
771 |
Lisp_Object frame; |
Lisp_Object ignored; |
772 |
{ |
{ |
773 |
HANDLE htext; |
HGLOBAL htext; |
774 |
Lisp_Object ret = Qnil; |
Lisp_Object ret = Qnil; |
775 |
|
UINT actual_clipboard_type; |
776 |
|
int use_configured_coding_system = 1; |
777 |
|
|
778 |
if (!NILP (frame)) |
/* This parameter used to be the current frame, but we don't use |
779 |
CHECK_LIVE_FRAME (frame); |
that any more. */ |
780 |
|
(void) ignored; |
781 |
|
|
782 |
|
/* Don't pass our own text from the clipboard (which might be |
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; |
789 |
|
|
790 |
BLOCK_INPUT; |
BLOCK_INPUT; |
791 |
|
|
792 |
if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL)) |
if (!OpenClipboard (clipboard_owner)) |
793 |
goto done; |
goto done; |
794 |
|
|
795 |
if ((htext = GetClipboardData (CF_TEXT)) == NULL) |
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) |
812 |
goto closeclip; |
goto closeclip; |
813 |
|
|
814 |
{ |
{ |
821 |
if ((src = (unsigned char *) GlobalLock (htext)) == NULL) |
if ((src = (unsigned char *) GlobalLock (htext)) == NULL) |
822 |
goto closeclip; |
goto closeclip; |
823 |
|
|
824 |
nbytes = strlen (src); |
/* If the clipboard data contains any non-ascii code, we need to |
825 |
|
decode it with a coding system. */ |
826 |
/* If the text in clipboard is identical to what we put there |
if (actual_clipboard_type == CF_UNICODETEXT) |
827 |
last time w32_set_clipboard_data was called, pretend there's no |
{ |
828 |
data in the clipboard. This is so we don't pass our own text |
nbytes = lstrlenW ((WCHAR *)src) * 2; |
829 |
from the clipboard (which might be troublesome if the killed |
require_decoding = 1; |
830 |
text includes null characters). */ |
} |
831 |
if ((clipboard_sequence_fn |
else |
832 |
&& clipboard_sequence_fn () == last_clipboard_sequence_number) |
{ |
833 |
|| (last_clipboard_text |
int i; |
|
&& clipboard_storage_size >= nbytes |
|
|
&& memcmp(last_clipboard_text, src, nbytes) == 0)) |
|
|
goto closeclip; |
|
834 |
|
|
835 |
{ |
nbytes = strlen (src); |
|
/* If the clipboard data contains any non-ascii code, we |
|
|
need to decode it. */ |
|
|
int i; |
|
836 |
|
|
837 |
for (i = 0; i < nbytes; i++) |
for (i = 0; i < nbytes; i++) |
838 |
{ |
{ |
839 |
if (src[i] >= 0x80) |
if (src[i] >= 0x80) |
840 |
{ |
{ |
841 |
require_decoding = 1; |
require_decoding = 1; |
842 |
break; |
break; |
843 |
} |
} |
844 |
} |
} |
845 |
} |
} |
846 |
|
|
847 |
if (require_decoding) |
if (require_decoding) |
848 |
{ |
{ |
849 |
int bufsize; |
int bufsize; |
850 |
unsigned char *buf; |
unsigned char *buf; |
851 |
struct coding_system coding; |
struct coding_system coding; |
852 |
|
Lisp_Object coding_system = Qnil; |
853 |
|
|
854 |
|
/* `next-selection-coding-system' should override everything, |
855 |
|
even when the locale passed by the system disagrees. The |
856 |
|
only exception is when `next-selection-coding-system' |
857 |
|
requested CF_UNICODETEXT and we couldn't get that. */ |
858 |
|
if (use_configured_coding_system |
859 |
|
&& !NILP (Vnext_selection_coding_system)) |
860 |
|
coding_system = Vnext_selection_coding_system; |
861 |
|
|
862 |
|
/* If we have CF_TEXT or CF_OEMTEXT, we want to check out |
863 |
|
CF_LOCALE, too. */ |
864 |
|
else if (actual_clipboard_type != CF_UNICODETEXT) |
865 |
|
{ |
866 |
|
HGLOBAL hlocale; |
867 |
|
LCID lcid = DEFAULT_LCID; |
868 |
|
UINT cp; |
869 |
|
|
870 |
|
/* Documentation says that the OS always generates |
871 |
|
CF_LOCALE info automatically, so the locale handle |
872 |
|
should always be present. Fact is that this is not |
873 |
|
always true on 9x ;-(. */ |
874 |
|
hlocale = GetClipboardData (CF_LOCALE); |
875 |
|
if (hlocale != NULL) |
876 |
|
{ |
877 |
|
const LCID * lcid_ptr; |
878 |
|
lcid_ptr = (const LCID *) GlobalLock (hlocale); |
879 |
|
if (lcid_ptr != NULL) |
880 |
|
{ |
881 |
|
lcid = *lcid_ptr; |
882 |
|
GlobalUnlock (hlocale); |
883 |
|
} |
884 |
|
|
885 |
|
/* 9x has garbage as the sort order (to be exact there |
886 |
|
is another instance of the language id in the upper |
887 |
|
word). We don't care about sort order anyway, so |
888 |
|
we just filter out the unneeded mis-information to |
889 |
|
avoid irritations. */ |
890 |
|
lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT); |
891 |
|
} |
892 |
|
|
893 |
|
/* If we are using fallback from CF_UNICODETEXT, we can't |
894 |
|
use the configured coding system. Also we don't want |
895 |
|
to use it, if the system has supplied us with a locale |
896 |
|
and it is not just the system default. */ |
897 |
|
if (!use_configured_coding_system || lcid != DEFAULT_LCID) |
898 |
|
{ |
899 |
|
cp = cp_from_locale (lcid, actual_clipboard_type); |
900 |
|
/* If it's just our current standard setting anyway, |
901 |
|
use the coding system that the user has selected. |
902 |
|
Otherwise create a new spec to match the locale |
903 |
|
that was specified by the other side or the |
904 |
|
system. */ |
905 |
|
if (!use_configured_coding_system || cp != cfg_codepage) |
906 |
|
coding_system = coding_from_cp (cp); |
907 |
|
} |
908 |
|
} |
909 |
|
|
910 |
|
if (NILP (coding_system)) |
911 |
|
coding_system = Vselection_coding_system; |
912 |
|
Vnext_selection_coding_system = Qnil; |
913 |
|
|
914 |
if (NILP (Vnext_selection_coding_system)) |
setup_coding_system (Fcheck_coding_system (coding_system), &coding); |
|
Vnext_selection_coding_system = Vselection_coding_system; |
|
|
setup_coding_system |
|
|
(Fcheck_coding_system (Vnext_selection_coding_system), &coding); |
|
915 |
coding.src_multibyte = 0; |
coding.src_multibyte = 0; |
916 |
coding.dst_multibyte = 1; |
coding.dst_multibyte = 1; |
|
Vnext_selection_coding_system = Qnil; |
|
917 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
coding.mode |= CODING_MODE_LAST_BLOCK; |
918 |
/* We explicitely disable composition handling because |
/* We explicitely disable composition handling because |
919 |
selection data should not contain any composition |
selection data should not contain any composition |
920 |
sequence. */ |
sequence. */ |
921 |
coding.composing = COMPOSITION_DISABLED; |
coding.composing = COMPOSITION_DISABLED; |
922 |
|
/* Force DOS line-ends. */ |
923 |
|
coding.eol_type = CODING_EOL_CRLF; |
924 |
|
|
925 |
bufsize = decoding_buffer_size (&coding, nbytes); |
bufsize = decoding_buffer_size (&coding, nbytes); |
926 |
buf = (unsigned char *) xmalloc (bufsize); |
buf = (unsigned char *) xmalloc (bufsize); |
927 |
decode_coding (&coding, src, buf, nbytes, bufsize); |
decode_coding (&coding, src, buf, nbytes, bufsize); |
935 |
} |
} |
936 |
else |
else |
937 |
{ |
{ |
938 |
/* Need to know final size after CR chars are removed because we |
/* FIXME: We may want to repeat the code in this branch for |
939 |
can't change the string size manually, and doing an extra |
the Unicode case. */ |
940 |
copy is silly. Note that we only remove CR when it appears |
|
941 |
as part of CRLF. */ |
/* Need to know final size after CR chars are removed because |
942 |
|
we can't change the string size manually, and doing an |
943 |
|
extra copy is silly. We only remove CR when it appears as |
944 |
|
part of CRLF. */ |
945 |
|
|
946 |
truelen = nbytes; |
truelen = nbytes; |
947 |
dst = src; |
dst = src; |
1018 |
|
|
1019 |
if (OpenClipboard (NULL)) |
if (OpenClipboard (NULL)) |
1020 |
{ |
{ |
1021 |
int format = 0; |
UINT format = 0; |
1022 |
while (format = EnumClipboardFormats (format)) |
setup_config (); |
1023 |
if (format == CF_TEXT) |
while ((format = EnumClipboardFormats (format))) |
1024 |
|
/* Check CF_TEXT in addition to cfg_clipboard_type, |
1025 |
|
because we can fall back on that if CF_UNICODETEXT is |
1026 |
|
not available. Actually a check for CF_TEXT only |
1027 |
|
should be enough. */ |
1028 |
|
if (format == cfg_clipboard_type || format == CF_TEXT) |
1029 |
{ |
{ |
1030 |
val = Qt; |
val = Qt; |
1031 |
break; |
break; |
1037 |
return Qnil; |
return Qnil; |
1038 |
} |
} |
1039 |
|
|
1040 |
|
/* One-time init. Called in the un-dumped Emacs, but not in the |
1041 |
|
dumped version. */ |
1042 |
|
|
1043 |
void |
void |
1044 |
syms_of_w32select () |
syms_of_w32select () |
1045 |
{ |
{ |
|
#if 0 |
|
|
defsubr (&Sw32_open_clipboard); |
|
|
defsubr (&Sw32_empty_clipboard); |
|
|
defsubr (&Sw32_close_clipboard); |
|
|
#endif |
|
1046 |
defsubr (&Sw32_set_clipboard_data); |
defsubr (&Sw32_set_clipboard_data); |
1047 |
defsubr (&Sw32_get_clipboard_data); |
defsubr (&Sw32_get_clipboard_data); |
1048 |
defsubr (&Sx_selection_exists_p); |
defsubr (&Sx_selection_exists_p); |
1049 |
|
|
1050 |
DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, |
DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system, |
1051 |
doc: /* Coding system for communicating with other programs. |
doc: /* Coding system for communicating with other programs. |
1052 |
When sending or receiving text via cut_buffer, selection, and clipboard, |
When sending or receiving text via cut_buffer, selection, and |
1053 |
the text is encoded or decoded by this coding system. |
clipboard, the text is encoded or decoded by this coding system. |
1054 |
The default value is `iso-latin-1-dos'. */); |
The default value is the current system default encoding on 9x/Me and |
1055 |
Vselection_coding_system = intern ("iso-latin-1-dos"); |
`utf-16le-dos' (Unicode) on NT/W2K/XP. */); |
1056 |
|
/* The actual value is set dynamically in the dumped Emacs, see |
1057 |
|
below. */ |
1058 |
|
Vselection_coding_system = Qnil; |
1059 |
|
|
1060 |
DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, |
DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, |
1061 |
doc: /* Coding system for the next communication with other programs. |
doc: /* Coding system for the next communication with other programs. |
1066 |
Vnext_selection_coding_system = Qnil; |
Vnext_selection_coding_system = Qnil; |
1067 |
|
|
1068 |
QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); |
QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD); |
1069 |
|
|
1070 |
|
cfg_coding_system = Qnil; staticpro (&cfg_coding_system); |
1071 |
|
current_text = Qnil; staticpro (¤t_text); |
1072 |
|
current_coding_system = Qnil; staticpro (¤t_coding_system); |
1073 |
|
|
1074 |
|
QUNICODE = intern ("utf-16le-dos"); staticpro (&QUNICODE); |
1075 |
|
QANSICP = Qnil; staticpro (&QANSICP); |
1076 |
|
QOEMCP = Qnil; staticpro (&QOEMCP); |
1077 |
|
} |
1078 |
|
|
1079 |
|
/* One-time init. Called in the dumped Emacs, but not in the |
1080 |
|
un-dumped version. */ |
1081 |
|
|
1082 |
|
void |
1083 |
|
globals_of_w32select () |
1084 |
|
{ |
1085 |
|
DEFAULT_LCID = GetUserDefaultLCID (); |
1086 |
|
/* Drop the sort order from the LCID, so we can compare this with |
1087 |
|
CF_LOCALE objects that have the same fix on 9x. */ |
1088 |
|
DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT); |
1089 |
|
|
1090 |
|
ANSICP = GetACP (); |
1091 |
|
OEMCP = GetOEMCP (); |
1092 |
|
|
1093 |
|
QANSICP = coding_from_cp (ANSICP); |
1094 |
|
QOEMCP = coding_from_cp (OEMCP); |
1095 |
|
|
1096 |
|
if (os_subtype == OS_NT) |
1097 |
|
Vselection_coding_system = QUNICODE; |
1098 |
|
else if (inhibit_window_system) |
1099 |
|
Vselection_coding_system = QOEMCP; |
1100 |
|
else |
1101 |
|
Vselection_coding_system = QANSICP; |
1102 |
|
|
1103 |
|
clipboard_owner = create_owner (); |
1104 |
} |
} |
1105 |
|
|
1106 |
/* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af |
/* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af |