changeset 30748:13c7c5e6cc36

Include coding.h. (XTread_socket): Work around a bug of XmbLookupString. If the input is from XIM, decode it according to the current locale. In that case, generate multibyte_char_keystroke events.
author Kenichi Handa <handa@m17n.org>
date Fri, 11 Aug 2000 00:49:39 +0000
parents 6c7afd50ec6a
children 7a0d5d24269e
files src/xterm.c
diffstat 1 files changed, 80 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Fri Aug 11 00:36:30 2000 +0000
+++ b/src/xterm.c	Fri Aug 11 00:49:39 2000 +0000
@@ -68,6 +68,7 @@
 /* #include <sys/param.h>  */
 
 #include "charset.h"
+#include "coding.h"
 #include "ccl.h"
 #include "frame.h"
 #include "dispextern.h"
@@ -9026,6 +9027,7 @@
   struct frame *f;
   int event_found = 0;
   struct x_display_info *dpyinfo;
+  struct coding_system coding;
 
   if (interrupt_input_blocked)
     {
@@ -9044,6 +9046,18 @@
 
   ++handling_signal;
   
+  /* The input should be decoded if it is from XIM.  Currently the
+     locale of XIM is the same as that of the system.  So, we can use
+     Vlocale_coding_system which is initialized properly at Emacs
+     startup time.  */
+  setup_coding_system (Vlocale_coding_system, &coding);
+  coding.src_multibyte = 0;
+  coding.dst_multibyte = 1;
+  /* The input is converted to events, thus we can't handle
+     composition.  Anyway, there's no XIM that gives us composition
+     information.  */
+  coding.composing = COMPOSITION_DISABLED;
+
   /* Find the display we are supposed to read input for.
      It's the one communicating on descriptor SD.  */
   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
@@ -9500,9 +9514,20 @@
 	      if (f != 0)
 		{
 		  KeySym keysym, orig_keysym;
-		  /* al%imercury@uunet.uu.net says that making this 81 instead of
-		     80 fixed a bug whereby meta chars made his Emacs hang.  */
-		  unsigned char copy_buffer[81];
+		  /* al%imercury@uunet.uu.net says that making this 81
+		     instead of 80 fixed a bug whereby meta chars made
+		     his Emacs hang.
+
+		     It seems that some version of XmbLookupString has
+		     a bug of not returning XBufferOverflow in
+		     status_return even if the input is too long to
+		     fit in 81 bytes.  So, we must prepare sufficient
+		     bytes for copy_buffer.  513 bytes (256 chars for
+		     two-byte character set) seems to be a faily good
+		     approximation.  -- 2000.8.10 handa@etl.go.jp  */
+		  unsigned char copy_buffer[513];
+		  unsigned char *copy_bufptr = copy_buffer;
+		  int copy_bufsiz = sizeof (copy_buffer);
 		  int modifiers;
 
 		  event.xkey.state
@@ -9531,8 +9556,6 @@
 #ifdef HAVE_X_I18N
 		  if (FRAME_XIC (f))
 		    {
-		      unsigned char *copy_bufptr = copy_buffer;
-		      int copy_bufsiz = sizeof (copy_buffer);
 		      Status status_return;
 
 		      nbytes = XmbLookupString (FRAME_XIC (f),
@@ -9561,11 +9584,13 @@
 			abort ();
 		    }
 		  else
-		    nbytes = XLookupString (&event.xkey, copy_buffer,
-					    80, &keysym, &compose_status);
+		    nbytes = XLookupString (&event.xkey, copy_bufptr,
+					    copy_bufsiz, &keysym,
+					    &compose_status);
 #else
-		  nbytes = XLookupString (&event.xkey, copy_buffer,
-					  80, &keysym, &compose_status);
+		  nbytes = XLookupString (&event.xkey, copy_bufptr,
+					  copy_bufsiz, &keysym,
+					  &compose_status);
 #endif
 
 		  orig_keysym = keysym;
@@ -9660,14 +9685,54 @@
 		      else if (numchars > nbytes)
 			{
 			  register int i;
+			  register int c;
+			  unsigned char *p, *pend;
+			  int nchars, len;
 
 			  for (i = 0; i < nbytes; i++)
 			    {
-			      if (temp_index == sizeof temp_buffer / sizeof (short))
+			      if (temp_index == (sizeof temp_buffer
+						 / sizeof (short)))
 				temp_index = 0;
-			      temp_buffer[temp_index++] = copy_buffer[i];
-			      bufp->kind = ascii_keystroke;
-			      bufp->code = copy_buffer[i];
+			      temp_buffer[temp_index++] = copy_bufptr[i];
+			    }
+
+			  if (/* If the event is not from XIM, */
+			      event.xkey.keycode != 0
+			      /* or the current locale doesn't request
+				 decoding of the intup data, ... */
+			      || coding.type == coding_type_raw_text
+			      || coding.type == coding_type_no_conversion)
+			    {
+			      /* ... we can use the input data as is.  */
+			      nchars = nbytes;
+			    }
+			  else
+			    { 
+			      /* We have to decode the input data.  */
+			      int require;
+			      unsigned char *p;
+
+			      require = decoding_buffer_size (&coding, nbytes);
+			      p = (unsigned char *) alloca (require);
+			      coding.mode |= CODING_MODE_LAST_BLOCK;
+			      decode_coding (&coding, copy_bufptr, p,
+					     nbytes, require);
+			      nbytes = coding.produced;
+			      nchars = coding.produced_char;
+			      copy_bufptr = p;
+			    }
+
+			  /* Convert the input data to a sequence of
+			     character events.  */
+			  for (i = 0; i < nbytes; i += len)
+			    {
+			      c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
+							  nbytes - i, len);
+			      bufp->kind = (SINGLE_BYTE_CHAR_P (c)
+					    ? ascii_keystroke
+					    : multibyte_char_keystroke);
+			      bufp->code = c;
 			      XSETFRAME (bufp->frame_or_window, f);
 			      bufp->arg = Qnil;
 			      bufp->modifiers
@@ -9677,8 +9742,8 @@
 			      bufp++;
 			    }
 
-			  count += nbytes;
-			  numchars -= nbytes;
+			  count += nchars;
+			  numchars -= nchars;
 
 			  if (keysym == NoSymbol)
 			    break;