--- ./zvt/zvtterm.c.jp2	Tue Oct 24 08:12:43 2000
+++ ./zvt/zvtterm.c	Sun Oct 29 18:32:20 2000
@@ -49,12 +49,15 @@
 #include <X11/Xatom.h>
 #include <X11/Xos.h>
 
-
 /* define to 'x' to enable copious debug output */
 #define d(x)
 
 /* default font */
+#ifndef ZVT_MB
 #define DEFAULT_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1"
+#else
+#define DEFAULT_FONT "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-1"
+#endif
 
 #define PADDING 2
 
@@ -115,6 +118,12 @@
 /* load the "current" background, from file or from system */
 static void       load_background (ZvtTerm *term);
 
+#ifdef ZVT_IM_ON_THE_SPOT
+static void zvt_im_preedit_set_spot(ZvtTerm *term, int col, int row, int offx, int offy);
+static void zvt_im_preedit_set_foreground(ZvtTerm *term, GdkColor *color);
+static void zvt_im_preedit_set_background(ZvtTerm *term, GdkColor *color);
+static void zvt_im_preedit_set_font(ZvtTerm *term, GdkFont *font);
+#endif
 
 /* static data */
 
@@ -146,6 +155,13 @@
 };
 static guint term_signals[LAST_SIGNAL] = { 0 };
 
+/* values for selection info */
+enum {
+  TARGET_STRING,
+  TARGET_UTF8,
+  TARGET_TEXT,
+  TARGET_COMPOUND_TEXT
+};
 
 /* GTK parent class */
 static GtkWidgetClass *parent_class = NULL;
@@ -237,6 +253,17 @@
 zvt_term_init (ZvtTerm *term)
 {
   struct _zvtprivate *zp;
+  static const GtkTargetEntry targets[] = {
+    { "STRING", 0, TARGET_STRING },
+#ifdef ZVT_UTF
+    { "UTF-8",  0, TARGET_UTF8 }, 
+#endif
+#ifdef ZVT_MB
+    { "TEXT",   0, TARGET_TEXT }, 
+    { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }
+#endif
+  };
+  static const gint n_targets = sizeof(targets) / sizeof(targets[0]);
 
   GTK_WIDGET_SET_FLAGS (term, GTK_CAN_FOCUS);
 
@@ -329,19 +356,9 @@
       term);
 
   /* selection received */
-  gtk_selection_add_target (
-      GTK_WIDGET (term),
-      GDK_SELECTION_PRIMARY,
-      GDK_SELECTION_TYPE_STRING, 
-      0);
-#ifdef ZVT_UTF
-  gtk_selection_add_target (
-      GTK_WIDGET (term),
-      GDK_SELECTION_PRIMARY,
-      gdk_atom_intern ("UTF-8", FALSE),
-      1);
-#endif
-
+  gtk_selection_add_targets (GTK_WIDGET (term),
+			     GDK_SELECTION_PRIMARY,
+			     targets, n_targets);
 }
 
 /**
@@ -666,6 +683,11 @@
   clone_col(&zp->queue_red, 0);
   clone_col(&zp->queue_green, 0);
   clone_col(&zp->queue_blue, 0);
+#ifdef ZVT_IM_ON_THE_SPOT
+  zvt_im_preedit_set_background(term, &c);
+  c.pixel = term->colors [16];
+  zvt_im_preedit_set_foreground(term, &c);
+#endif /* ZVT_IM_ON_THE_SPOT */
 }
 
 /**
@@ -801,6 +823,9 @@
   term_force_size(term);
 
   /* input context */
+#ifdef ZVT_IM_ON_THE_SPOT
+  zvt_term_set_open_im (term, True);
+#else
   if (gdk_im_ready () && !term->ic) {
     GdkICAttr attr;
     
@@ -813,6 +838,7 @@
       g_warning("Can't create input context.");
     }
   }
+#endif
 }
 
 static void
@@ -1280,7 +1306,11 @@
   case GDK_FONT_FONTSET: {
     XFontSet fontset = (XFontSet) ((GdkFontPrivate *)font)->xfont;
     XFontSetExtents *extents = XExtentsOfFontSet(fontset);
+#ifdef ZVT_MB /* This is look bug..., isn't it? */
+    term->charwidth = gdk_string_width (font, "M");
+#else
     term->charwidth = extents->max_logical_extent.width;
+#endif
     term->charheight = extents->max_logical_extent.height;
     zp->fonttype = ZVT_FONT_FONTSET;
   }
@@ -1295,6 +1325,9 @@
   if (term->font)
     gdk_font_unref (term->font);
   term->font = font;
+#ifdef ZVT_IM_ON_THE_SPOT
+  zvt_im_preedit_set_font(term, font);
+#endif
 
   if (term->font_bold)
     gdk_font_unref (term->font_bold);
@@ -1395,16 +1428,28 @@
 
   if (rest) {
     g_string_sprintf (outname, "%s-medium-r%s", newname->str, rest);
+#ifndef ZVT_MB
     font = gdk_font_load (outname->str);
+#else
+    font = gdk_fontset_load (outname->str);
+#endif
     d( printf("loading normal font %s\n", outname->str) );
     
     g_string_sprintf (outname, "%s-bold-r%s", newname->str, rest); 
+#ifndef ZVT_MB
     font_bold = gdk_font_load (outname->str);
+#else
+    font_bold = gdk_fontset_load (outname->str);
+#endif
     d( printf("loading bold font %s\n", outname->str) );
     
     zvt_term_set_fonts_internal (term, font, font_bold);
   } else {
+#ifndef ZVT_MB
     font = gdk_font_load (name);
+#else
+    font = gdk_fontset_load (name);
+#endif
     zvt_term_set_fonts_internal (term, font, 0);
   }
 
@@ -1444,7 +1489,11 @@
 {
   GdkAtom string_atom;
 #ifdef ZVT_UTF
+#ifdef ZVT_MB
+  char *types[] = {"UTF-8", "COMPOUND_TEXT"};
+#else
   char *types[] = {"UTF-8", "STRING"};
+#endif /* ZVT_MB */
   int index;
   struct _zvtprivate *zp = _ZVT_PRIVATE(widget);
 
@@ -1464,7 +1513,11 @@
   d(printf(" %s atom = %d\n", types[index], (int)string_atom));
 #else
   /* Get the atom corresonding to the target "STRING" */
+#ifdef ZVT_MB
+  string_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
+#else
   string_atom = gdk_atom_intern ("STRING", FALSE);
+#endif /* ZVT_MB */
 #endif
 
   if (string_atom == GDK_NONE) {
@@ -1890,10 +1943,15 @@
 
   switch (type) {
   default:
-  case 0: {			/* this is ascii/isolatin1 */
+
+#ifdef ZVT_MB
+  case TARGET_COMPOUND_TEXT:
+  case TARGET_TEXT:
+#endif
+  case TARGET_STRING: {               /* this is ascii/isolatin1 */
     unsigned char *o;
     d(printf("converting selection to ISOLATIN1\n"));
-    out = g_malloc(term->vx->selection_size);
+    out = g_malloc(term->vx->selection_size+1);
     o = out;
     for(i=0;i<term->vx->selection_size;i++) {
       c = term->vx->selection_data[i];
@@ -1902,7 +1960,7 @@
     *outlen = term->vx->selection_size;
     break;
   }
-  case 1: {			/* this is utf-8, basically a local implementation of wcstombs() */
+  case TARGET_UTF8: {         /* this is utf-8, basically a local implementation of wcstombs() */
     unsigned char *o;
     unsigned int len=0;
     d(printf("converting selection to UTF-8\n"));
@@ -1991,10 +2049,34 @@
   term = ZVT_TERM (widget);
   vx = term->vx;
 
+#ifdef ZVT_MB
+  if (info == TARGET_COMPOUND_TEXT||info == TARGET_TEXT) {
+      GdkAtom encoding;
+      gint    format;
+      guchar *str, *new_str;
+      gint    new_len;
+#ifdef ZVT_UTF
+      str = zvt_term_convert_selection(term, info, &len);
+#else
+      int len = vx->selection_size;
+      str = (guchar*)vx->selection_data;
+#endif
+      str[len] = '\0';
+      gdk_string_to_compound_text (str, &encoding, &format, &new_str, &new_len);
+      gtk_selection_data_set (selection_data_ptr, encoding, format,
+                            new_str, new_len);
+      gdk_free_compound_text (new_str);
+#if ZVT_UTF
+      g_free(str);
+#endif
+      return;
+  }
+#endif /* ZVT_MB */
+
 #ifdef ZVT_UTF
   /* convert selection based on info */
   /* the selection is actually stored in 32 bit chars */
-  if (info==1)
+  if (info==TARGET_UTF8)
     atom = gdk_atom_intern ("UTF-8", FALSE);
   else
     atom = GDK_SELECTION_TYPE_STRING;
@@ -2045,6 +2127,7 @@
 
   /* Make sure we got the data in the expected form */
   if (selection_data->type != GDK_SELECTION_TYPE_STRING
+      && selection_data->type != gdk_atom_intern("COMPOUND_TEXT", FALSE)
       && selection_data->type != gdk_atom_intern("UTF-8", FALSE)) {
     g_print ("Selection \"STRING\" was not returned as strings!\n");
     return;
@@ -2055,13 +2138,40 @@
     {
       int i;
       char *ctmp = selection_data->data;
+      gint length = selection_data->length;
 
-      for(i = 0; i < selection_data->length; i++)
-	if(ctmp[i] == '\n') ctmp[i] = '\r';
-
-      if (term->scroll_on_keystroke)
-	zvt_term_scroll (term, 0);
-      zvt_term_writechild(term, selection_data->data, selection_data->length);
+      if (selection_data->type == gdk_atom_intern("COMPOUND_TEXT",FALSE)) {
+        gchar **list;
+        gint    count;
+
+        count = gdk_text_property_to_text_list (selection_data->type,
+                                                selection_data->format,
+                                                selection_data->data,
+                                                selection_data->length,
+                                                &list);
+        if (count > 0) {
+            gint n;
+            length = 0;
+            for (n=0; n<count; n++)  {
+                ctmp = list[n];
+                length = strlen (list[n]);
+                for(i = 0; i < length; i++)
+                    if(ctmp[i] == '\n') ctmp[i] = '\r';
+
+                if (term->scroll_on_keystroke)
+                    zvt_term_scroll (term, 0);
+                vt_writechild(&vx->vt, ctmp, length);
+            }
+            gdk_free_text_list (list);
+        }
+      } else  {
+        for (i = 0; i < length; i++)
+            if(ctmp[i] == '\n') ctmp[i] = '\r';
+
+        if (term->scroll_on_keystroke)
+            zvt_term_scroll (term, 0);
+        vt_writechild(&vx->vt, ctmp, length);
+      }
     }
 }  
 
@@ -2113,6 +2223,141 @@
   return length;
 }
 
+#ifdef ZVT_IM_ON_THE_SPOT
+/**
+ * zvt_term_set_open_im:
+ * @term: A &ZvtTerm widget.
+ * @state: if True, open IM, else close.
+ **/
+void
+zvt_term_set_open_im (ZvtTerm *term, int state)
+{
+  if(!state)
+    {
+      if (term->ic) 
+	{
+	  gdk_ic_destroy(term->ic);
+	  term->ic = NULL;
+	}
+      return;
+    }
+
+  if (gdk_im_ready () && !term->ic)
+    {
+      gint       width, height;
+      GdkICAttr  attr;
+      GdkColormap *colormap;
+      GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
+      GdkIMStyle style;
+      GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE |
+				   GDK_IM_PREEDIT_NOTHING |
+			           GDK_IM_PREEDIT_POSITION |
+			           GDK_IM_STATUS_NONE |
+				   GDK_IM_STATUS_NOTHING;
+      
+      if (GTK_WIDGET (term)->style &&
+	  GTK_WIDGET (term)->style->font->type != GDK_FONT_FONTSET)
+	supported_style &= ~GDK_IM_PREEDIT_POSITION;
+
+      attr.style = style = gdk_im_decide_style (supported_style);
+      attr.client_window = attr.focus_window = term->term_window;
+
+      if ((colormap = gtk_widget_get_colormap (GTK_WIDGET (term)))
+	  != gtk_widget_get_default_colormap ())
+	{
+	  attrmask |= GDK_IC_PREEDIT_COLORMAP;
+	  attr.preedit_colormap = colormap;
+	}
+
+      switch (style & GDK_IM_PREEDIT_MASK)
+	{
+	  case GDK_IM_PREEDIT_POSITION:
+	    if (term->font && term->font->type != GDK_FONT_FONTSET)
+	      {
+		g_warning ("over-the-spot style requires fontset");
+		break;
+	      }
+#if 0
+	    gdk_window_get_size (term->term_window, &width, &height);
+#else
+	    width  = term->vx->vt.width* term->charwidth;
+	    height = term->vx->vt.height* term->charheight;
+#endif
+	    attrmask |= GDK_IC_PREEDIT_POSITION_REQ|GDK_IC_PREEDIT_FONTSET;
+	    attr.spot_location.x = 0;
+	    attr.spot_location.y = 0;
+	    attr.preedit_area.x = 0;
+	    attr.preedit_area.y = 0;
+	    attr.preedit_area.width = width;
+	    attr.preedit_area.height = height;
+	    attr.preedit_fontset = term->font;
+	    break;
+	}
+
+      term->ic = gdk_ic_new(&attr, attrmask);
+
+      if (!term->ic) 
+	{
+	  g_warning("Can't create input context.");
+	}
+    }
+}
+
+
+static void
+zvt_im_preedit_set_spot(ZvtTerm *term, int col, int row, int offx, int offy)
+{
+  if (term->ic && 
+      (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION))
+    {
+      GdkICAttr          attr;
+      attr.spot_location.x = col * term->charwidth + offx;
+      attr.spot_location.y = row * term->charheight
+	  + term->font->ascent + offy;
+      gdk_ic_set_attr (term->ic, &attr, GDK_IC_SPOT_LOCATION);
+    }
+}
+
+static void
+zvt_im_preedit_set_foreground(ZvtTerm *term, GdkColor *color)
+{
+  if (term->ic && 
+      (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION))
+    {
+      GdkICAttr       attr;
+      attr.preedit_foreground = *color;
+      gdk_ic_set_attr (term->ic, &attr, GDK_IC_PREEDIT_FOREGROUND);
+    }
+}
+
+static void
+zvt_im_preedit_set_background(ZvtTerm *term, GdkColor *color)
+{
+  if (term->ic && 
+      (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION))
+    {
+      GdkICAttr       attr;
+      attr.preedit_background = *color;
+      gdk_ic_set_attr (term->ic, &attr, GDK_IC_PREEDIT_BACKGROUND);
+    }
+}
+
+
+static void
+zvt_im_preedit_set_font(ZvtTerm *term, GdkFont *font)
+{
+  if (term->ic && 
+      (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION))
+    {
+      GdkICAttr       attr;
+      if (font && font->type != GDK_FONT_FONTSET)
+	  g_warning ("over-the-spot style requires fontset");
+      attr.preedit_fontset = font;
+      gdk_ic_set_attr (term->ic, &attr, GDK_IC_PREEDIT_FONTSET);
+    }
+}
+#endif /* ZVT_IM_ON_THE_SPOT */
+
 static void
 zvt_term_writemore (gpointer data, gint fd, GdkInputCondition condition)
 {
@@ -2343,7 +2588,7 @@
 static gint
 zvt_term_key_press (GtkWidget *widget, GdkEventKey *event)
 {
-  char buffer[64];
+  char buffer[128];
   char *p=buffer;
   struct _vtx *vx;
   ZvtTerm *term;
@@ -2547,11 +2792,12 @@
     break;
   default:
       if (event->length > 0){
+        gint length = MIN(((buffer+ sizeof(buffer)) - p)/sizeof(char), event->length);
 	if (event->state & GDK_MOD1_MASK){
 	   *p++ = '\033';
         }
-	memcpy(p, event->string, event->length*sizeof(char));
-	p += event->length;
+	memcpy(p, event->string, length);
+	p += length;
       } else {
 	handled = FALSE;
       }
@@ -3161,24 +3407,24 @@
   break;
   /* this is limited to 65535 characters! */
   case ZVT_FONT_FONTSET: {
-    wchar_t *expandwc = zp->text_expand;
+    char *expand = zp->text_expand;
     XFontSet fontset = (XFontSet) font_private->xfont;
 
     for (i=0;i<len;i++) {
-      expandwc[i] = VT_ASCII(line->data[i+col]);
+      expand[i] = VT_ASCII(line->data[i+col]) & 0xff;
     }
 
     /* render wide characters, with fill if we can */
     if (dofill) {
-      XwcDrawImageString(drawable_private->xdisplay, drawable_private->xwindow,
-			 fontset, gc_private->xgc, offx + x, offy + y, expandwc, len);
+      XmbDrawImageString(drawable_private->xdisplay, drawable_private->xwindow,
+                       fontset, gc_private->xgc, offx + x, offy + y, expand, len);
     } else {
-      XwcDrawString(drawable_private->xdisplay, drawable_private->xwindow,
-		    fontset, gc_private->xgc, offx + x, offy + y, expandwc, len);
+      XmbDrawString(drawable_private->xdisplay, drawable_private->xwindow,
+                    fontset, gc_private->xgc, offx + x, offy + y, expand, len);
     }
     if (overstrike)
-      XwcDrawString(drawable_private->xdisplay, drawable_private->xwindow,
-		    fontset, gc_private->xgc, offx + x + 1, offy + y, expandwc, len);
+      XmbDrawString(drawable_private->xdisplay, drawable_private->xwindow,
+                  fontset, gc_private->xgc, offx + x + 1, offy + y, expand, len);
   }
   }
 
@@ -3199,6 +3445,10 @@
 		    x + offx + len*term->charwidth, offy + row*term->charheight,
 		    1, term->charheight);
   }
+#ifdef ZVT_IM_ON_THE_SPOT
+  if (len <= MB_CUR_MAX)
+      zvt_im_preedit_set_spot(term, col, row, offx, offy);
+#endif
 }
 
 
@@ -3833,6 +4083,7 @@
   } else {
     d(printf("background hasn't moved, leaving\n"));
   }
+
 }
 
 static gint
