/[emacs]/emacs/src/w32select.c
ViewVC logotype

Diff of /emacs/src/w32select.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.33 by handa, Wed Jun 30 23:30:39 2004 UTC revision 1.34 by jasonr, Tue Feb 15 23:19:26 2005 UTC
# Line 1  Line 1 
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    
# Line 18  along with GNU Emacs; see the file COPYI Line 18  along with GNU Emacs; see the file COPYI
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;
# Line 292  DEFUN ("w32-set-clipboard-data", Fw32_se Line 763  DEFUN ("w32-set-clipboard-data", Fw32_se
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    {    {
# Line 322  DEFUN ("w32-get-clipboard-data", Fw32_ge Line 821  DEFUN ("w32-get-clipboard-data", Fw32_ge
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);
# Line 382  DEFUN ("w32-get-clipboard-data", Fw32_ge Line 935  DEFUN ("w32-get-clipboard-data", Fw32_ge
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;
# Line 462  and t is the same as `SECONDARY'.  */) Line 1018  and t is the same as `SECONDARY'.  */)
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;
# Line 476  and t is the same as `SECONDARY'.  */) Line 1037  and t is the same as `SECONDARY'.  */)
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.
# Line 504  set to nil.  */); Line 1066  set to nil.  */);
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 (&current_text);
1072      current_coding_system = Qnil; staticpro (&current_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

Legend:
Removed from v.1.33  
changed lines
  Added in v.1.34

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26