[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:7559] Re: [Mule-UCS] buffer magnifications of shift-jisx0213-*-stream-encoder are too small



堀口と申します.

 私も偶然最近 Meadow で同じことにはまったので調べたところです.

> この件ですが、src/ccl.c で定義されている CCL_WRITE_CHAR は、0x80-0x9f
> の値を書き出す際にバッファを 2 バイト要求するため、
> shift-jisx0213-unix-stream-encoder の buffer-magnification が 1 だと
> バッファが足りない時があるというのが原因のようです。
...
> Mule-UCS に対する添付のパッチが一番簡単な回避方法になると思いますが、
> どなたかご検討いただければと思います。

 これは Mule-UCSで対策する必要はないはずです.

 どのみち食わせる文字列しだいでは複数回エンコーダを回さなければな
らない条件があるようなので(よくわかってないけど途中で変換が止まる),
ここは encode_coding を直接使うのではなく encode_coding_string を
使うのが正しいようです.

 Meadow-4234 では mw32clpbd.c に以下のパッチをあてることで治ります.
このパッチはついでにクリップボードで Unicode text のやり取りを可能
にします(こちらが私的には本題だったのですが)

 このパッチを適用した Madow で
 (set-clipboard-coding-system 'utf-16le-dos)
 をすると 0213 な文字も含めて Unicode で扱える文字がすべてクリップ
 ボード経由でやり取りできるようになるはずです.

 私の手元ではしばらく使っていて問題ないようですが, このさいなので
試してみていただけるありがたいです.

-- 
ほりぐちきょうたろう

====
Index: mw32clpbd.c
===================================================================
--- mw32clpbd.c	(revision 4234)
+++ mw32clpbd.c	(working copy)
@@ -46,6 +46,7 @@
 
 Lisp_Object Vselection_coding_system;
 int mw32_mule_clipboard_format;
+Lisp_Object clipboard_unicode_coding_system;
 
 /* 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
@@ -78,19 +79,24 @@
   struct coding_system coding;
   int htextsize, size;
   unsigned char *lptext, *lpmulecb;
+  Lisp_Object cb_str;
 
 
   CHECK_STRING (string);
 
   if (NILP (code))
     code = Vselection_coding_system;
-  setup_coding_system (Fcheck_coding_system (code), &coding);
+
+  if (setup_coding_system (Fcheck_coding_system (code), &coding) < 0)
+    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (code)));
   if (!coding.cmp_data)
     coding_allocate_composition_data (&coding, 0);
 
   BLOCK_INPUT;
 
-  htextsize = decoding_buffer_size (&coding, SBYTES (string) + 1);
+  cb_str = encode_coding_string (string, &coding, 1);
+
+  htextsize = SBYTES (cb_str) + sizeof (wchar_t);
   if ((htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
 			    htextsize)) == NULL)
     goto error;
@@ -110,9 +116,8 @@
   if ((lptext = (unsigned char *) GlobalLock (htext)) == NULL)
     goto error;
 
-  encode_coding (&coding, SDATA (string), lptext, SBYTES (string), htextsize);
-  size = coding.produced;
-  lptext[size] = '\0';
+  memcpy (lptext, SDATA (cb_str), htextsize - sizeof (wchar_t));
+  *((wchar_t *)(lptext + htextsize - sizeof (wchar_t))) = 0;
 
   if (!get_clipboard_sequence_number_fn)
     {
@@ -138,8 +143,10 @@
   if (!OpenClipboard (NULL))
     goto error;
 
-  ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
-
+  ok = EmptyClipboard () &&
+    SetClipboardData (EQ (code, clipboard_unicode_coding_system)?
+		      CF_UNICODETEXT : CF_TEXT, htext);
+  
   if (mw32_mule_clipboard_format)
     ok = ok && SetClipboardData (mw32_mule_clipboard_format, hmuletext);
 
@@ -177,10 +184,13 @@
      Lisp_Object code;
 {
   HANDLE htext, hmuletext;
+  Lisp_Object str = Qnil;
   Lisp_Object ret = Qnil;
   struct coding_system coding;
   unsigned char *lptext, *buf;
   int nbytes, size, bufsize;
+  static unsigned int formatlist[2] = {CF_UNICODETEXT, CF_TEXT};
+  unsigned int format;
 
   BLOCK_INPUT;
 
@@ -203,13 +213,33 @@
       goto closeclip;
     }
 
-  if ((htext = GetClipboardData (CF_TEXT)) == NULL)
+  if (NILP (code))
+    code = Vselection_coding_system;
+
+  if ((format = GetPriorityClipboardFormat (formatlist, 2)) == 0
+      || ! EQ (code, clipboard_unicode_coding_system))
+    format = CF_TEXT;
+
+  if ((htext = GetClipboardData (format)) == NULL)
     goto closeclip;
 
   if ((lptext = (unsigned char *) GlobalLock (htext)) == NULL)
     goto closeclip;
 
-  nbytes = strlen (lptext);
+  if (format == CF_UNICODETEXT)
+    {
+      nbytes = wcslen((wchar_t *)lptext);
+      if ((nbytes & ~(INTMASK>>1)) != 0)
+	{
+	  Lisp_Object mes;
+	  mes = build_string("Clipboard string is too long, truncated.");
+	  Fmessage (1, &mes);
+	  nbytes &= (INTMASK>>1);
+	}
+      nbytes = nbytes * 2;
+    }
+  else
+    nbytes = strlen (lptext);
 
   /* If the text in clipboard is identical to what we put there
      last time w32_set_clipboard_data was called, pretend there's no
@@ -222,19 +252,14 @@
       && last_clipboard_text_size == nbytes)
     goto closeclip;
 
-  if (NILP (code))
-    code = Vselection_coding_system;
-  setup_coding_system (Fcheck_coding_system (code), &coding);
+  if (setup_coding_system (Fcheck_coding_system (code), &coding) < 0)
+    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (code)));
 
-  bufsize = decoding_buffer_size (&coding, nbytes);
-  buf = (unsigned char*) xmalloc (bufsize);
-  decode_coding (&coding, lptext, buf, nbytes, bufsize);
-  size = coding.produced;
-  ret = make_string (buf, size);
-  xfree (buf);
-
+  str = make_string (lptext, nbytes);
   GlobalUnlock (htext);
 
+  ret = decode_coding_string (str, &coding, 1);
+
  closeclip:
   CloseClipboard ();
 
@@ -263,6 +288,7 @@
   get_clipboard_sequence_number_fn = (GetClipboardSequenceNumber_Proc)
     GetProcAddress (user32_lib, "GetClipboardSequenceNumber");
 
+  clipboard_unicode_coding_system = intern("utf-16le-dos");
   /* Test GetClipboardSequenceNumber API. If test fails, make it
      inavailable. */
   if (get_clipboard_sequence_number_fn