From: Benjamin Riefenstahl <Benjamin.Riefenstahl@epost.de>
Cc: Eli Zaretskii <eliz@gnu.org>,
emacs-devel@gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>,
Kenichi Handa <handa@m17n.org>
Subject: Re: Unicode support for the MS Windows clipboard
Date: Tue, 27 Jul 2004 14:24:14 +0200 [thread overview]
Message-ID: <m3pt6hsknl.fsf@seneca.benny.turtle-trading.net> (raw)
In-Reply-To: <ubri1aod1.fsf@jasonrumney.net> (Jason Rumney's message of "Tue, 27 Jul 2004 08:41:30 +0100")
[-- Attachment #1: Type: text/plain, Size: 479 bytes --]
Hi Jason,
Jason Rumney <jasonr@gnu.org> writes:
> Make sure that rendering CF_TEXT does not clobber the CF_UNICODETEXT
> that you just put there on the NT based versions of Windows that do
> automatic conversions. It might be better to reverse the order.
It's not a problem on W2K here and thinking about it, it would be a
bug in the OS if it was, automatic conversion is supposed to be a
fallback solution. But better be safe than sorry. See attached
revised patch.
benny
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: w32select.patch --]
[-- Type: text/x-patch, Size: 40030 bytes --]
Index: lisp/international/mule-cmds.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/international/mule-cmds.el,v
retrieving revision 1.257
diff -u -p -r1.257 mule-cmds.el
--- lisp/international/mule-cmds.el 12 Jun 2004 02:21:21 -0000 1.257
+++ lisp/international/mule-cmds.el 27 Jul 2004 12:10:46 -0000
@@ -2422,13 +2422,13 @@ See also `locale-charset-language-names'
(prefer-coding-system coding-system)
(setq locale-coding-system coding-system))))
- ;; On Windows, override locale-coding-system, keyboard-coding-system,
- ;; selection-coding-system with system codepage.
+ ;; On Windows, override locale-coding-system,
+ ;; keyboard-coding-system, with system codepage. Note:
+ ;; selection-coding-system is already set in w32select.c.
(when (boundp 'w32-ansi-code-page)
(let ((code-page-coding (intern (format "cp%d" w32-ansi-code-page))))
(when (coding-system-p code-page-coding)
(setq locale-coding-system code-page-coding)
- (set-selection-coding-system code-page-coding)
(set-keyboard-coding-system code-page-coding)
(set-terminal-coding-system code-page-coding))))
Index: src/emacs.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/emacs.c,v
retrieving revision 1.342
diff -u -p -r1.342 emacs.c
--- src/emacs.c 24 Jun 2004 20:24:52 -0000 1.342
+++ src/emacs.c 27 Jul 2004 12:11:01 -0000
@@ -42,6 +42,8 @@ Boston, MA 02111-1307, USA. */
#ifdef WINDOWSNT
#include <fcntl.h>
+#include <windows.h> /* just for w32.h */
+#include "w32.h"
#endif
#include "lisp.h"
@@ -1578,6 +1580,7 @@ main (argc, argv
#ifdef HAVE_NTGUI
globals_of_w32fns ();
globals_of_w32menu ();
+ globals_of_w32select ();
#endif /* end #ifdef HAVE_NTGUI */
}
Index: src/w32.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32.h,v
retrieving revision 1.15
diff -u -p -r1.15 w32.h
--- src/w32.h 1 Sep 2003 15:45:57 -0000 1.15
+++ src/w32.h 27 Jul 2004 12:11:10 -0000
@@ -122,16 +122,17 @@ extern void reset_standard_handles (int
/* Return the string resource associated with KEY of type TYPE. */
extern LPBYTE w32_get_resource (char * key, LPDWORD type);
-extern void init_ntproc ();
-extern void term_ntproc ();
-extern void globals_of_w32 ();
-extern void syms_of_w32term ();
-extern void syms_of_w32fns ();
-extern void globals_of_w32fns ();
-extern void syms_of_w32select ();
-extern void syms_of_w32menu ();
-extern void globals_of_w32menu ();
-extern void syms_of_fontset ();
+extern void init_ntproc (void);
+extern void term_ntproc (void);
+extern void globals_of_w32 (void);
+extern void syms_of_w32term (void);
+extern void syms_of_w32fns (void);
+extern void globals_of_w32fns (void);
+extern void syms_of_w32select (void);
+extern void globals_of_w32select (void);
+extern void syms_of_w32menu (void);
+extern void globals_of_w32menu (void);
+extern void syms_of_fontset (void);
#endif /* EMACS_W32_H */
Index: src/w32select.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32select.c,v
retrieving revision 1.33
diff -u -p -r1.33 w32select.c
--- src/w32select.c 30 Jun 2004 23:30:39 -0000 1.33
+++ src/w32select.c 27 Jul 2004 12:11:10 -0000
@@ -1,5 +1,5 @@
/* Selection processing for Emacs on the Microsoft W32 API.
- Copyright (C) 1993, 1994 Free Software Foundation.
+ Copyright (C) 1993, 1994, 2004 Free Software Foundation.
This file is part of GNU Emacs.
@@ -18,273 +18,681 @@ along with GNU Emacs; see the file COPYI
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Written by Kevin Gallo */
+/* Written by Kevin Gallo, Benjamin Riefenstahl */
#include <config.h>
#include "lisp.h"
#include "w32term.h" /* for all of the w32 includes */
-#include "dispextern.h" /* frame.h seems to want this */
-#include "keyboard.h"
-#include "frame.h" /* Need this to get the X window of selected_frame */
+#include "w32heap.h" /* os_subtype */
#include "blockinput.h"
-#include "buffer.h"
+#include "keyboard.h" /* cmd_error_internal() */
#include "charset.h"
#include "coding.h"
#include "composite.h"
+
+static HGLOBAL convert_to_handle_as_ascii (void);
+static HGLOBAL convert_to_handle_as_coded (Lisp_Object coding_system);
+static Lisp_Object render (Lisp_Object oformat);
+static Lisp_Object render_all (void);
+static void run_protected (Lisp_Object (*code) (), Lisp_Object arg);
+static Lisp_Object lisp_error_handler (Lisp_Object error);
+static LRESULT CALLBACK owner_callback (HWND win, UINT msg,
+ WPARAM wp, LPARAM lp);
+static HWND create_owner (void);
+static void atexit_callback (void);
+
+static void setup_config (void);
+static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
+static UINT cp_from_locale (LCID lcid, UINT format);
+static Lisp_Object coding_from_cp (UINT codepage);
+
+
Lisp_Object QCLIPBOARD;
/* Coding system for communicating with other Windows programs via the
clipboard. */
static Lisp_Object Vselection_coding_system;
-/* Coding system for the next communicating with other Windows programs. */
+/* Coding system for the next communication with other Windows
+ programs. */
static Lisp_Object Vnext_selection_coding_system;
-/* Sequence number, used where possible to detect when we are pasting
- our own text. */
-static DWORD last_clipboard_sequence_number;
-extern ClipboardSequence_Proc clipboard_sequence_fn;
-
-/* The last text we put into the clipboard. This is used when the OS
- does not support sequence numbers (NT4, 95). It is undesirable to
- use data put on the clipboard by Emacs because the clipboard data
- could be MULEtilated by inappropriately chosen
- (next-)selection-coding-system. For this reason, we must store the
- text *after* it was encoded/Unix-to-DOS-converted. */
-static unsigned char *last_clipboard_text = NULL;
-static size_t clipboard_storage_size = 0;
-
-#if 0
-DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0,
- doc: /* This opens the clipboard with the given frame pointer. */)
- (frame)
- Lisp_Object frame;
+/* Internal pseudo-constants, initialized in globals_of_w32select()
+ based on current system parameters. */
+static LCID DEFAULT_LCID;
+static UINT ANSICP, OEMCP;
+static Lisp_Object QUNICODE, QANSICP, QOEMCP;
+
+/* A hidden window just for the clipboard management. */
+static HWND clipboard_owner;
+/* A flag to tell WM_DESTROYCLIPBOARD who is to blame this time (just
+ checking GetClipboardOwner() doesn't work, sadly). */
+static int modifying_clipboard = 0;
+
+/* Configured transfer parameters, based on the last inspection of
+ selection-coding-system. */
+static Lisp_Object cfg_coding_system;
+static UINT cfg_codepage;
+static LCID cfg_lcid;
+static UINT cfg_clipboard_type;
+
+/* The current state for delayed rendering. */
+static Lisp_Object current_text;
+static Lisp_Object current_coding_system;
+static int current_requires_encoding, current_num_nls;
+static UINT current_clipboard_type;
+static LCID current_lcid;
+
+#if TRACE
+#define ONTRACE(stmt) stmt
+#else
+#define ONTRACE(stmt) /*stmt*/
+#endif
+
+
+/* This function assumes that there is no multibyte character in
+ current_text, so we can short-cut encoding. */
+
+static HGLOBAL
+convert_to_handle_as_ascii (void)
{
- BOOL ok = FALSE;
+ HGLOBAL htext = NULL;
+ int nbytes;
+ int truelen;
+ unsigned char *src;
+ unsigned char *dst;
- if (!NILP (frame))
- CHECK_LIVE_FRAME (frame);
+ ONTRACE (fprintf (stderr, "convert_to_handle_as_ascii\n"));
- BLOCK_INPUT;
+ nbytes = SBYTES (current_text) + 1;
+ src = SDATA (current_text);
- 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
+ to insert CR chars (the standard CF_TEXT clipboard format uses
+ CRLF line endings, while Emacs uses just LF internally). */
- UNBLOCK_INPUT;
+ truelen = nbytes + current_num_nls;
+
+ if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
+ return NULL;
+
+ if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
+ {
+ GlobalFree (htext);
+ return NULL;
+ }
+
+ /* convert to CRLF line endings expected by clipboard */
+ while (1)
+ {
+ 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;
+ }
- return (ok ? frame : Qnil);
+ GlobalUnlock (htext);
+
+ return htext;
}
-DEFUN ("w32-empty-clipboard", Fw32_empty_clipboard,
- Sw32_empty_clipboard, 0, 0, 0,
- doc: /* Empty the clipboard.
-Assigns ownership of the clipboard to the window which opened it. */)
- ()
+/* This function assumes that there are multibyte or NUL characters in
+ current_text, or that we need to construct Unicode. It runs the
+ text through the encoding machinery. */
+
+static HGLOBAL
+convert_to_handle_as_coded (Lisp_Object coding_system)
{
- BOOL ok = FALSE;
+ HGLOBAL htext = NULL, htext2;
+ int nbytes;
+ unsigned char *src;
+ unsigned char *dst = NULL;
+ int bufsize;
+ struct coding_system coding;
+ Lisp_Object string = Qnil;
+ struct gcpro gcpro1;
+
+ ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",
+ SDATA (SYMBOL_NAME (coding_system))));
+
+ /* FIXME: It looks like GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS on
+ Windows (see src/lisp.h and nt/config.nt), so this is probably
+ unnecessary. If it was necessary, we'd probably have to protect
+ all the symbols, too. */
+ GCPRO1 (string);
+
+ setup_coding_system (Fcheck_coding_system (coding_system), &coding);
+ 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;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ /* Force DOS line-ends. */
+ coding.eol_type = CODING_EOL_CRLF;
+
+ if (SYMBOLP (coding.pre_write_conversion)
+ && !NILP (Ffboundp (coding.pre_write_conversion)))
+ string = run_pre_post_conversion_on_str (current_text, &coding, 1);
+ else
+ string = current_text;
- BLOCK_INPUT;
+ nbytes = SBYTES (string);
+ src = SDATA (string);
- ok = EmptyClipboard ();
+ bufsize = encoding_buffer_size (&coding, nbytes) +2;
+ htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize);
- UNBLOCK_INPUT;
+ if (htext != NULL)
+ dst = (unsigned char *) GlobalLock (htext);
+
+ if (dst != NULL)
+ {
+ encode_coding (&coding, src, dst, nbytes, bufsize-2);
+ /* Add the string terminator. Add two NULs in case we are
+ producing Unicode here. */
+ dst[coding.produced] = dst[coding.produced+1] = '\0';
+ }
+
+ if (dst != NULL)
+ GlobalUnlock (htext);
+
+ if (htext != NULL)
+ {
+ /* Shrink data block to actual size. */
+ htext2 = GlobalReAlloc (htext, coding.produced+2,
+ GMEM_MOVEABLE | GMEM_DDESHARE);
+ if (htext2 != NULL) htext = htext2;
+ }
+
+ UNGCPRO;
+
+ return htext;
+}
+
+static Lisp_Object
+render (Lisp_Object oformat)
+{
+ HGLOBAL htext = NULL;
+ UINT format = XFASTINT (oformat);
+
+ ONTRACE (fprintf (stderr, "render\n"));
+
+ if (NILP (current_text))
+ return Qnil;
+
+ if (current_requires_encoding || format == CF_UNICODETEXT)
+ {
+ if (format == current_clipboard_type)
+ htext = convert_to_handle_as_coded (current_coding_system);
+ else
+ switch (format)
+ {
+ case CF_UNICODETEXT:
+ htext = convert_to_handle_as_coded (QUNICODE);
+ break;
+ case CF_TEXT:
+ case CF_OEMTEXT:
+ {
+ Lisp_Object cs;
+ cs = coding_from_cp (cp_from_locale (current_lcid, format));
+ htext = convert_to_handle_as_coded (cs);
+ break;
+ }
+ }
+ }
+ else
+ htext = convert_to_handle_as_ascii ();
+
+ ONTRACE (fprintf (stderr, "render: htext = 0x%08X\n", (unsigned) htext));
+
+ if (htext != NULL)
+ SetClipboardData (format, htext);
+
+ return Qt;
+}
+
+/* At the end of the program, we want to ensure that our clipboard
+ data survives us. This code will do that. */
+
+static Lisp_Object
+render_all (void)
+{
+ ONTRACE (fprintf (stderr, "render_all\n"));
- return (ok ? Qt : Qnil);
+ /* According to the docs we should not call OpenClipboard() here,
+ but testing on W2K and working code in other projects shows that
+ it is actually necessary. */
+
+ OpenClipboard (NULL);
+
+ /* There is no usefull means to report errors here, there are none
+ expected anyway, and even if there were errors, they wouldn't do
+ any harm. So we just go ahead and do what has to be done without
+ bothering with error handling. */
+
+ ++modifying_clipboard;
+ EmptyClipboard ();
+ --modifying_clipboard;
+
+ /* For text formats that we don't render here, the OS can use its
+ own translation rules instead, so we don't really need to offer
+ everything. To minimize memory consumption we cover three
+ possible situations based on our primary format as detected from
+ selection-coding-system (see setup_config()):
+
+ - Post CF_TEXT only. Let Windows convert to CF_OEMTEXT and
+ Windows on NT or the application on 9x/Me convert to
+ CF_UNICODETEXT.
+
+ - Post CF_OEMTEXT only. Similar automatic conversions happen as
+ for CF_TEXT.
+
+ - Post CF_UNICODETEXT + CF_TEXT. 9x itself ignores
+ CF_UNICODETEXT, even though some applications can still handle
+ it.
+
+ Note 1: We render the less capable CF_TEXT *before* the more
+ capable CF_UNICODETEXT, to prevent clobbering through automatic
+ conversions, just in case.
+
+ Note 2: We could check os_subtype here and only render the
+ additional CF_TEXT on 9x/Me. But OTOH with
+ current_clipboard_type == CF_UNICODETEXT we don't involve the
+ automatic conversions anywhere else, so to get consistent
+ results, we probably don't want to rely on it here either. */
+
+ if (current_clipboard_type == CF_UNICODETEXT)
+ render (make_number (CF_TEXT));
+ render (make_number (current_clipboard_type));
+
+ CloseClipboard ();
+
+ return Qnil;
}
-DEFUN ("w32-close-clipboard", Fw32_close_clipboard,
- Sw32_close_clipboard, 0, 0, 0,
- doc: /* Close the clipboard. */)
- ()
+static void
+run_protected (Lisp_Object (*code) (), Lisp_Object arg)
{
- BOOL ok = FALSE;
+ extern int waiting_for_input;
+ int owfi;
BLOCK_INPUT;
- ok = CloseClipboard ();
+ /* Fsignal calls abort() if it sees that waiting_for_input set. */
+ owfi = waiting_for_input;
+ waiting_for_input = 0;
+
+ internal_condition_case_1 (code, arg, Qt, lisp_error_handler);
+
+ waiting_for_input = owfi;
UNBLOCK_INPUT;
+}
- return (ok ? Qt : Qnil);
+static Lisp_Object
+lisp_error_handler (Lisp_Object error)
+{
+ Vsignaling_function = Qnil;
+ cmd_error_internal (error, "Error in delayed clipboard rendering: ");
+ Vinhibit_quit = Qt;
+ return Qt;
}
-#endif
-DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
- Sw32_set_clipboard_data, 1, 2, 0,
- doc: /* This sets the clipboard data to the given text. */)
- (string, frame)
- Lisp_Object string, frame;
+static LRESULT CALLBACK
+owner_callback (HWND win, UINT msg, WPARAM wp, LPARAM lp)
{
- BOOL ok = TRUE;
- HANDLE htext;
- int nbytes;
- int truelen, nlines = 0;
- unsigned char *src;
- unsigned char *dst;
+ switch (msg)
+ {
+ case WM_RENDERFORMAT:
+ ONTRACE (fprintf (stderr, "WM_RENDERFORMAT\n"));
+ run_protected (render, make_number (wp));
+ return 0;
+
+ case WM_RENDERALLFORMATS:
+ ONTRACE (fprintf (stderr, "WM_RENDERALLFORMATS\n"));
+ run_protected (render_all, Qnil);
+ return 0;
- CHECK_STRING (string);
+ case WM_DESTROYCLIPBOARD:
+ if (!modifying_clipboard)
+ {
+ ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (other)\n"));
+ current_text = Qnil;
+ current_coding_system = Qnil;
+ }
+ else
+ {
+ ONTRACE (fprintf (stderr, "WM_DESTROYCLIPBOARD (self)\n"));
+ }
+ return 0;
- if (!NILP (frame))
- CHECK_LIVE_FRAME (frame);
+ case WM_DESTROY:
+ if (win == clipboard_owner)
+ clipboard_owner = NULL;
+ break;
+ }
- BLOCK_INPUT;
+ return DefWindowProc (win, msg, wp, lp);
+}
- /* Include the terminating NULL character in the source of
- conversion. */
- nbytes = SBYTES (string) + 1;
- src = SDATA (string);
- dst = src;
+static HWND
+create_owner (void)
+{
+ static const char CLASSNAME[] = "Emacs Clipboard";
+ WNDCLASS wc;
+ HWND hwnd;
+
+ memset (&wc, 0, sizeof (wc));
+ wc.lpszClassName = CLASSNAME;
+ wc.lpfnWndProc = owner_callback;
+ RegisterClass (&wc);
+
+ hwnd = CreateWindow (CLASSNAME, CLASSNAME, 0, 0, 0, 0, 0, NULL, NULL,
+ NULL, NULL);
+
+ /* FIXME: w32.c says that atexit() is broken. This works here with
+ Mingw. The note in w32.c is probably about a static build, which
+ Mingw doesn't support anyway. Anyway the alternative
+ implementation using signal(SIGABRT) as in w32.c doesn't work
+ here, so standard C is our best bet. */
+
+ if (hwnd != NULL)
+ atexit (atexit_callback);
+
+ return hwnd;
+}
- /* We need to know how many lines there are, since we need CRLF line
- termination for compatibility with other Windows Programs.
- avoid using strchr because it recomputes the length every time */
- while ((dst = memchr (dst, '\n', nbytes - (dst - src))) != NULL)
+static void
+atexit_callback (void)
+{
+ /* Make sure to trigger WM_RENDERALLFORMATS. */
+ if (clipboard_owner != NULL)
+ DestroyWindow (clipboard_owner);
+}
+
+static void
+setup_config (void)
+{
+ const char *coding_name;
+ const char *cp;
+ char *end;
+ int slen;
+ Lisp_Object active_coding_system;
+
+ CHECK_SYMBOL (Vselection_coding_system);
+
+ /* Check if we have it cached */
+ active_coding_system = NILP (Vnext_selection_coding_system) ?
+ Vselection_coding_system : Vnext_selection_coding_system;
+ if (!NILP (cfg_coding_system)
+ && EQ (cfg_coding_system, active_coding_system))
+ return;
+ cfg_coding_system = active_coding_system;
+
+ /* Set some sensible fallbacks */
+ cfg_codepage = ANSICP;
+ cfg_lcid = LOCALE_NEUTRAL;
+ cfg_clipboard_type = CF_TEXT;
+
+ /* Interpret the coding system symbol name */
+ coding_name = SDATA (SYMBOL_NAME (active_coding_system));
+
+ /* "(.*-)?utf-16.*" -> CF_UNICODETEXT */
+ cp = strstr (coding_name, "utf-16");
+ if (cp != NULL && (cp == coding_name || cp[-1] == '-'))
{
- nlines++;
- dst++;
+ cfg_clipboard_type = CF_UNICODETEXT;
+ return;
}
- {
- /* Since we are now handling multilingual text, we must consider
- encoding text for the clipboard. */
- int charset_info = find_charset_in_text (src, SCHARS (string),
- nbytes, NULL, Qnil);
+ /* "cp[0-9]+.*" or "windows-[0-9]+.*" -> CF_TEXT or CF_OEMTEXT */
+ slen = strlen (coding_name);
+ if (slen >= 4 && coding_name[0] == 'c' && coding_name[1] == 'p')
+ cp = coding_name + 2;
+ else if (slen >= 10 && memcmp (coding_name, "windows-", 8) == 0)
+ cp = coding_name + 8;
+ else
+ return;
+
+ end = (char*)cp;
+ cfg_codepage = strtol (cp, &end, 10);
+
+ /* Error return from strtol() or number of digits < 2 -> Restore the
+ default and drop it. */
+ if (cfg_codepage == 0 || (end-cp) < 2 )
+ {
+ cfg_codepage = ANSICP;
+ return;
+ }
- if (charset_info == 0)
- {
- /* No multibyte character in OBJ. We need not encode it. */
+ /* Is it the currently active system default? */
+ if (cfg_codepage == ANSICP)
+ {
+ /* cfg_clipboard_type = CF_TEXT; */
+ return;
+ }
+ if (cfg_codepage == OEMCP)
+ {
+ cfg_clipboard_type = CF_OEMTEXT;
+ return;
+ }
- /* Need to know final size after CR chars are inserted (the
- standard CF_TEXT clipboard format uses CRLF line endings,
- while Emacs uses just LF internally). */
+ /* Else determine a suitable locale the hard way. */
+ EnumSystemLocales (enum_locale_callback, LCID_INSTALLED);
+}
- truelen = nbytes + nlines;
+static BOOL WINAPI
+enum_locale_callback (/*const*/ char* loc_string)
+{
+ LCID lcid;
+ UINT codepage;
- if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, truelen)) == NULL)
- goto error;
+ lcid = strtoul (loc_string, NULL, 16);
- if ((dst = (unsigned char *) GlobalLock (htext)) == NULL)
- goto error;
+ /* Is the wanted codepage the "ANSI" codepage for this locale? */
+ codepage = cp_from_locale (lcid, CF_TEXT);
+ if (codepage == cfg_codepage)
+ {
+ cfg_lcid = lcid;
+ cfg_clipboard_type = CF_TEXT;
+ return FALSE; /* Stop enumeration */
+ }
+
+ /* Is the wanted codepage the OEM codepage for this locale? */
+ codepage = cp_from_locale (lcid, CF_OEMTEXT);
+ if (codepage == cfg_codepage)
+ {
+ cfg_lcid = lcid;
+ cfg_clipboard_type = CF_OEMTEXT;
+ return FALSE; /* Stop enumeration */
+ }
- /* convert to CRLF line endings expected by clipboard */
- while (1)
- {
- 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;
- }
+ return TRUE; /* Continue enumeration */
+}
- GlobalUnlock (htext);
+static UINT
+cp_from_locale (LCID lcid, UINT format)
+{
+ char buffer[20] = "";
+ UINT variant, cp;
- Vlast_coding_system_used = Qraw_text;
- }
- else
- {
- /* We must encode contents of OBJ to the selection coding
- system. */
- int bufsize;
- struct coding_system coding;
- HANDLE htext2;
+ variant =
+ format == CF_TEXT ? LOCALE_IDEFAULTANSICODEPAGE : LOCALE_IDEFAULTCODEPAGE;
- if (NILP (Vnext_selection_coding_system))
- Vnext_selection_coding_system = Vselection_coding_system;
- setup_coding_system
- (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
- if (SYMBOLP (coding.pre_write_conversion)
- && !NILP (Ffboundp (coding.pre_write_conversion)))
- {
- string = run_pre_post_conversion_on_str (string, &coding, 1);
- src = SDATA (string);
- /* Include the terminating NULL character in the source of
- 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;
+ GetLocaleInfo (lcid, variant, buffer, sizeof (buffer));
+ cp = strtoul (buffer, NULL, 10);
- /* 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);
- }
+ if (cp == CP_ACP)
+ return ANSICP;
+ else if (cp == CP_OEMCP)
+ return OEMCP;
+ else
+ return cp;
+}
- GlobalUnlock (htext);
+static Lisp_Object
+coding_from_cp (UINT codepage)
+{
+ char buffer[30];
+ sprintf (buffer, "cp%d-dos", (int) codepage);
+ return intern (buffer);
+ /* We don't need to check that this coding system exists right here,
+ because that is done when the coding system is actually
+ instantiated, i.e. it is passed through Fcheck_coding_system()
+ there. */
+}
- /* Shrink data block to actual size. */
- htext2 = GlobalReAlloc (htext, coding.produced,
- GMEM_MOVEABLE | GMEM_DDESHARE);
- if (htext2 != NULL) htext = htext2;
- }
- }
- if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
+DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
+ Sw32_set_clipboard_data, 1, 2, 0,
+ doc: /* This sets the clipboard data to the given text. */)
+ (string, ignored)
+ Lisp_Object string, ignored;
+{
+ BOOL ok = TRUE;
+ HGLOBAL hlocale = NULL;
+ int nbytes;
+ unsigned char *src;
+ unsigned char *dst;
+ unsigned char *end;
+
+ (void) ignored;
+
+ CHECK_STRING (string);
+
+ setup_config ();
+
+ current_text = string;
+ current_coding_system = cfg_coding_system;
+ current_clipboard_type = cfg_clipboard_type;
+ current_lcid = cfg_lcid;
+ current_num_nls = 0;
+ current_requires_encoding = 0;
+
+ BLOCK_INPUT;
+
+ /* Check for non-ASCII characters. While we are at it, count the
+ number of LFs, so we know how many CRs we will have to add later
+ (just in the case where we can use our internal ASCII rendering,
+ see code and note in convert_to_handle_as_ascii() above). */
+ nbytes = SBYTES (string);
+ src = SDATA (string);
+
+ for (dst = src, end = src+nbytes; dst < end; dst++)
+ {
+ if (*dst == '\n')
+ current_num_nls++;
+ else if (*dst >= 0x80 || *dst == 0)
+ {
+ current_requires_encoding = 1;
+ break;
+ }
+ }
+
+ if (!current_requires_encoding)
+ {
+ /* If all we have is ASCII we don't need to pretend we offer
+ anything fancy. */
+ current_coding_system = Qraw_text;
+ current_clipboard_type = CF_TEXT;
+ }
+ else
+ {
+ /* If we have something non-ASCII we may want to set a locale.
+ We always do that directly (non-delayed), as it's just a
+ small bit and it simplifies the rest of the code. */
+ if (cfg_lcid != LOCALE_NEUTRAL && cfg_lcid != DEFAULT_LCID)
+ {
+ hlocale = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
+ sizeof (cfg_lcid));
+ if (hlocale != NULL)
+ {
+ LCID * lcid_ptr;
+ if ((lcid_ptr = (LCID *) GlobalLock (hlocale)) != NULL)
+ {
+ *lcid_ptr = cfg_lcid;
+ GlobalUnlock (hlocale);
+ }
+ }
+ }
+ }
+
+ if (!OpenClipboard (clipboard_owner))
goto error;
- ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
+ ++modifying_clipboard;
+ ok = EmptyClipboard ();
+ --modifying_clipboard;
+
+ if (ok)
+ {
+ if (clipboard_owner == NULL)
+ {
+ /* If for some reason we don't have a clipboard_owner, we
+ just set the text format as chosen by the configuration
+ and than forget about the whole thing. */
+ render (make_number (current_clipboard_type));
+ current_text = Qnil;
+ current_coding_system = Qnil;
+ }
+ else
+ {
+ /* Advertise all supported formats so that whatever the
+ requester chooses, only one encoding step needs to be
+ made. This is intentionally different from what we do in
+ the WM_RENDERALLFORMATS handler. */
+ SetClipboardData (CF_UNICODETEXT, NULL);
+ SetClipboardData (CF_TEXT, NULL);
+ SetClipboardData (CF_OEMTEXT, NULL);
+ }
+
+ if (hlocale != NULL)
+ {
+ ok = SetClipboardData (CF_LOCALE, hlocale) != NULL;
+ if (!ok) EmptyClipboard ();
+ }
+ }
CloseClipboard ();
- /* Common sense says to read the sequence number inside the
- OpenClipboard/ CloseClipboard block to avoid race conditions
- where another app puts something on the clipboard straight after
- us. But experience suggests that the sequence number from the
- SetClipboardData is not allocated until we close the clipboard!
- Since clipboard operations are normally user-driven, the race
- condition is probably not going to really happen. */
- if (clipboard_sequence_fn)
- last_clipboard_sequence_number = clipboard_sequence_fn ();
+ /* We haven't really "used" this coding system yet, and it's even
+ unclear if we ever will. But this is a way to tell the upper
+ level what we *would* use under ideal circumstances.
+
+ We don't signal the actually used coding-system later when we
+ finally render, because that can happen at any time and we don't
+ want to disturb the "foreground" action. */
+ Vlast_coding_system_used = current_coding_system;
+
+ Vnext_selection_coding_system = Qnil;
if (ok) goto done;
error:
ok = FALSE;
- if (htext) GlobalFree (htext);
- if (last_clipboard_text)
- *last_clipboard_text = '\0';
+ if (hlocale) GlobalFree (hlocale);
- last_clipboard_sequence_number = 0;
+ current_text = Qnil;
+ current_coding_system = Qnil;
done:
UNBLOCK_INPUT;
@@ -292,24 +700,50 @@ DEFUN ("w32-set-clipboard-data", Fw32_se
return (ok ? string : Qnil);
}
+
DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data,
Sw32_get_clipboard_data, 0, 1, 0,
doc: /* This gets the clipboard data in text format. */)
- (frame)
- Lisp_Object frame;
+ (ignored)
+ Lisp_Object ignored;
{
- HANDLE htext;
+ HGLOBAL htext;
Lisp_Object ret = Qnil;
+ UINT actual_clipboard_type;
+ int use_configured_coding_system = 1;
+
+ (void) ignored;
- if (!NILP (frame))
- CHECK_LIVE_FRAME (frame);
+ /* Don't pass our own text from the clipboard (which might be
+ troublesome if the killed text includes null characters). */
+ if (!NILP (current_text))
+ return ret;
+
+ setup_config ();
+ actual_clipboard_type = cfg_clipboard_type;
BLOCK_INPUT;
- if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
+ if (!OpenClipboard (clipboard_owner))
goto done;
- if ((htext = GetClipboardData (CF_TEXT)) == NULL)
+ if ((htext = GetClipboardData (actual_clipboard_type)) == NULL)
+ {
+ /* If we want CF_UNICODETEXT but can't get it, the current
+ coding system is useless. OTOH we can still try and decode
+ CF_TEXT based on the locale that the system gives us and that
+ we get down below. */
+ if (actual_clipboard_type == CF_UNICODETEXT)
+ {
+ htext = GetClipboardData (CF_TEXT);
+ if (htext != NULL)
+ {
+ actual_clipboard_type = CF_TEXT;
+ use_configured_coding_system = 0;
+ }
+ }
+ }
+ if (htext == NULL)
goto closeclip;
{
@@ -322,53 +756,107 @@ DEFUN ("w32-get-clipboard-data", Fw32_ge
if ((src = (unsigned char *) GlobalLock (htext)) == NULL)
goto closeclip;
- nbytes = strlen (src);
-
- /* If the text in clipboard is identical to what we put there
- last time w32_set_clipboard_data was called, pretend there's no
- data in the clipboard. This is so we don't pass our own text
- from the clipboard (which might be troublesome if the killed
- text includes null characters). */
- if ((clipboard_sequence_fn
- && clipboard_sequence_fn () == last_clipboard_sequence_number)
- || (last_clipboard_text
- && clipboard_storage_size >= nbytes
- && memcmp(last_clipboard_text, src, nbytes) == 0))
- goto closeclip;
+ /* If the clipboard data contains any non-ascii code, we need to
+ decode it with a coding system.
+ FIXME: Repeat the code for the Unicode case. */
+ if (actual_clipboard_type == CF_UNICODETEXT)
+ {
+ nbytes = lstrlenW ((WCHAR *)src) * 2;
+ require_decoding = 1;
+ }
+ else
+ {
+ int i;
- {
- /* If the clipboard data contains any non-ascii code, we
- need to decode it. */
- int i;
+ nbytes = strlen (src);
- for (i = 0; i < nbytes; i++)
- {
- if (src[i] >= 0x80)
- {
- require_decoding = 1;
- break;
- }
- }
- }
+ for (i = 0; i < nbytes; i++)
+ {
+ if (src[i] >= 0x80)
+ {
+ require_decoding = 1;
+ break;
+ }
+ }
+ }
if (require_decoding)
{
int bufsize;
unsigned char *buf;
struct coding_system coding;
+ Lisp_Object coding_system = Qnil;
+
+ /* `next-selection-coding-system' should override everything,
+ even when the locale passed by the system disagrees. The
+ only exception is when `next-selection-coding-system'
+ requested CF_UNICODETEXT and we couldn't get that. */
+ if (use_configured_coding_system
+ && !NILP (Vnext_selection_coding_system))
+ coding_system = Vnext_selection_coding_system;
+
+ /* If we have CF_TEXT or CF_OEMTEXT, we want to check out
+ CF_LOCALE, too. */
+ else if (actual_clipboard_type != CF_UNICODETEXT)
+ {
+ HGLOBAL hlocale;
+ LCID lcid = DEFAULT_LCID;
+ UINT cp;
+
+ /* Windows is documented to always generate CF_LOCALE info
+ automatically, so the locale handle should be always
+ present, but this is not always true on 9x ;-(. */
+ hlocale = GetClipboardData (CF_LOCALE);
+ if (hlocale != NULL)
+ {
+ const LCID * lcid_ptr;
+ lcid_ptr = (const LCID *) GlobalLock (hlocale);
+ if (lcid_ptr != NULL)
+ {
+ lcid = *lcid_ptr;
+ GlobalUnlock (hlocale);
+ }
+
+ /* 9x has garbage as the sort order (to be exact there
+ is another instance of the language id in the upper
+ word). We don't care about sort order anyway, so
+ we can just filter out the unneeded mis-information
+ to avoid irritations. */
+ lcid = MAKELCID (LANGIDFROMLCID (lcid), SORT_DEFAULT);
+ }
- if (NILP (Vnext_selection_coding_system))
- Vnext_selection_coding_system = Vselection_coding_system;
- setup_coding_system
- (Fcheck_coding_system (Vnext_selection_coding_system), &coding);
+ /* If we are using fallback from CF_UNICODETEXT, we can't
+ use the configured coding system. Also we don't want
+ to use it, if the system has supplied us with a locale
+ and it is not just the system default. */
+ if (!use_configured_coding_system || lcid != DEFAULT_LCID)
+ {
+ cp = cp_from_locale (lcid, actual_clipboard_type);
+ /* If it's just our current standard setting anyway,
+ use the coding system that the user has selected.
+ Otherwise create a new spec to match the locale
+ that was specified by the other side or the
+ system. */
+ if (!use_configured_coding_system || cp != cfg_codepage)
+ coding_system = coding_from_cp (cp);
+ }
+ }
+
+ if (NILP (coding_system))
+ coding_system = Vselection_coding_system;
+ Vnext_selection_coding_system = Qnil;
+
+ setup_coding_system (Fcheck_coding_system (coding_system), &coding);
coding.src_multibyte = 0;
coding.dst_multibyte = 1;
- Vnext_selection_coding_system = Qnil;
coding.mode |= CODING_MODE_LAST_BLOCK;
/* We explicitely disable composition handling because
selection data should not contain any composition
sequence. */
coding.composing = COMPOSITION_DISABLED;
+ /* Force DOS line-ends. */
+ coding.eol_type = CODING_EOL_CRLF;
+
bufsize = decoding_buffer_size (&coding, nbytes);
buf = (unsigned char *) xmalloc (bufsize);
decode_coding (&coding, src, buf, nbytes, bufsize);
@@ -382,10 +870,10 @@ DEFUN ("w32-get-clipboard-data", Fw32_ge
}
else
{
- /* Need to know final size after CR chars are removed because we
- can't change the string size manually, and doing an extra
- copy is silly. Note that we only remove CR when it appears
- as part of CRLF. */
+ /* Need to know final size after CR chars are removed because
+ we can't change the string size manually, and doing an
+ extra copy is silly. We only remove CR when it appears as
+ part of CRLF. */
truelen = nbytes;
dst = src;
@@ -462,9 +950,14 @@ and t is the same as `SECONDARY'. */)
if (OpenClipboard (NULL))
{
- int format = 0;
- while (format = EnumClipboardFormats (format))
- if (format == CF_TEXT)
+ UINT format = 0;
+ setup_config ();
+ while ((format = EnumClipboardFormats (format)))
+ /* Check CF_TEXT in addition to cfg_clipboard_type,
+ because we can fall back on that if CF_UNICODETEXT is
+ not available. Actually a check for CF_TEXT only
+ should be enough. */
+ if (format == cfg_clipboard_type || format == CF_TEXT)
{
val = Qt;
break;
@@ -476,24 +969,25 @@ and t is the same as `SECONDARY'. */)
return Qnil;
}
+/* One-time init. Called in the un-dumped Emacs, but not in the
+ dumped version. */
+
void
syms_of_w32select ()
{
-#if 0
- defsubr (&Sw32_open_clipboard);
- defsubr (&Sw32_empty_clipboard);
- defsubr (&Sw32_close_clipboard);
-#endif
defsubr (&Sw32_set_clipboard_data);
defsubr (&Sw32_get_clipboard_data);
defsubr (&Sx_selection_exists_p);
DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
doc: /* Coding system for communicating with other programs.
-When sending or receiving text via cut_buffer, selection, and clipboard,
-the text is encoded or decoded by this coding system.
-The default value is `iso-latin-1-dos'. */);
- Vselection_coding_system = intern ("iso-latin-1-dos");
+When sending or receiving text via cut_buffer, selection, and
+clipboard, the text is encoded or decoded by this coding system.
+The default value is the current system default encoding on 9x/Me and
+`utf-16le-dos' (Unicode) on NT/W2K/XP. */);
+ /* The actual value is set dynamically in the dumped Emacs, see
+ below. */
+ Vselection_coding_system = Qnil;
DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
doc: /* Coding system for the next communication with other programs.
@@ -504,6 +998,41 @@ set to nil. */);
Vnext_selection_coding_system = Qnil;
QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
+
+ cfg_coding_system = Qnil; staticpro (&cfg_coding_system);
+ current_text = Qnil; staticpro (¤t_text);
+ current_coding_system = Qnil; staticpro (¤t_coding_system);
+
+ QUNICODE = intern ("utf-16le-dos"); staticpro (&QUNICODE);
+ QANSICP = Qnil; staticpro (&QANSICP);
+ QOEMCP = Qnil; staticpro (&QOEMCP);
+}
+
+/* One-time init. Called in the dumped Emacs, but not in the
+ un-dumped version. */
+
+void
+globals_of_w32select ()
+{
+ DEFAULT_LCID = GetUserDefaultLCID ();
+ /* Drop the sort order from the LCID, so we can compare this with
+ CF_LOCALE objects that have the same fix on 9x. */
+ DEFAULT_LCID = MAKELCID (LANGIDFROMLCID (DEFAULT_LCID), SORT_DEFAULT);
+
+ ANSICP = GetACP ();
+ OEMCP = GetOEMCP ();
+
+ QANSICP = coding_from_cp (ANSICP);
+ QOEMCP = coding_from_cp (OEMCP);
+
+ if (os_subtype == OS_NT)
+ Vselection_coding_system = QUNICODE;
+ else if (inhibit_window_system)
+ Vselection_coding_system = QOEMCP;
+ else
+ Vselection_coding_system = QANSICP;
+
+ clipboard_owner = create_owner ();
}
/* arch-tag: c96e9724-5eb1-4dad-be07-289f092fd2af
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next prev parent reply other threads:[~2004-07-27 12:24 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-05-26 18:01 [Patch] Unicode support for the MS Windows clipboard Benjamin Riefenstahl
2004-05-27 7:58 ` Jason Rumney
2004-05-27 10:12 ` Benjamin Riefenstahl
2004-05-27 15:43 ` Jason Rumney
2004-05-27 17:46 ` Stefan Monnier
2004-05-27 21:30 ` Jason Rumney
2004-05-27 8:05 ` [Patch] " Eli Zaretskii
2004-05-27 9:45 ` Benjamin Riefenstahl
2004-05-28 7:44 ` Jason Rumney
2004-05-28 9:20 ` Eli Zaretskii
2004-05-29 14:46 ` Benjamin Riefenstahl
2004-05-28 13:26 ` Benjamin Riefenstahl
2004-05-28 14:48 ` Jason Rumney
2004-05-29 0:15 ` Kenichi Handa
2004-05-29 12:21 ` Eli Zaretskii
2004-05-29 14:52 ` Benjamin Riefenstahl
2004-05-29 17:40 ` Eli Zaretskii
2004-06-03 9:17 ` Benjamin Riefenstahl
2004-06-03 13:21 ` Kenichi Handa
2004-06-04 13:01 ` Eli Zaretskii
2004-07-26 19:17 ` Benjamin Riefenstahl
2004-07-26 19:35 ` Jason Rumney
2004-07-27 22:43 ` Benjamin Riefenstahl
2004-07-28 4:45 ` Eli Zaretskii
2004-07-28 8:02 ` Jason Rumney
2004-07-28 18:57 ` Eli Zaretskii
2004-07-28 11:30 ` Benjamin Riefenstahl
2004-07-28 12:38 ` Benjamin Riefenstahl
2004-07-28 13:03 ` Jason Rumney
2004-07-28 13:44 ` Benjamin Riefenstahl
2004-07-26 19:45 ` Jason Rumney
2004-07-27 11:17 ` Benjamin Riefenstahl
2004-07-27 5:07 ` Eli Zaretskii
2004-07-27 12:20 ` Benjamin Riefenstahl
2004-07-27 7:41 ` Jason Rumney
2004-07-27 11:04 ` Benjamin Riefenstahl
2004-07-27 12:24 ` Benjamin Riefenstahl [this message]
2004-07-27 13:15 ` Jason Rumney
2004-07-28 1:12 ` Tak Ota
2004-07-28 11:20 ` Benjamin Riefenstahl
2004-07-28 11:35 ` Jason Rumney
2004-07-28 12:08 ` Benjamin Riefenstahl
2004-07-28 16:57 ` Tak Ota
2004-07-28 17:34 ` Tak Ota
2004-07-28 16:26 ` Tak Ota
2004-07-28 18:42 ` Tak Ota
2004-07-28 21:51 ` Tak Ota
2004-07-29 11:42 ` Benjamin Riefenstahl
2004-07-29 16:38 ` Tak Ota
2004-08-27 17:06 ` Tak Ota
2004-08-29 13:33 ` Benjamin Riefenstahl
2004-08-30 20:47 ` Unicode support for the MS Windows clipboard [new patch] Benjamin Riefenstahl
2004-08-31 4:05 ` Eli Zaretskii
2004-09-12 19:50 ` Benjamin Riefenstahl
2004-09-13 19:55 ` Eli Zaretskii
2004-09-08 21:11 ` Tak Ota
2004-09-10 13:47 ` Kim F. Storm
2004-09-10 15:34 ` Jason Rumney
2004-09-10 17:46 ` Benjamin Riefenstahl
2004-09-12 9:09 ` Richard Stallman
2004-09-12 14:11 ` Benjamin Riefenstahl
2004-11-08 17:24 ` Benjamin Riefenstahl
2004-11-15 21:41 ` Tak Ota
2004-11-21 19:17 ` Benjamin Riefenstahl
2005-02-08 0:49 ` Tak Ota
2005-02-08 9:04 ` Jason Rumney
2005-02-15 18:19 ` Tak Ota
2005-02-16 9:52 ` Jason Rumney
2005-02-16 17:09 ` Benjamin Riefenstahl
2004-05-28 15:18 ` Unicode support for the MS Windows clipboard Stefan Monnier
2004-05-29 12:23 ` Eli Zaretskii
2004-05-27 17:48 ` [Patch] " Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3pt6hsknl.fsf@seneca.benny.turtle-trading.net \
--to=benjamin.riefenstahl@epost.de \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=handa@m17n.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).