? im_info
Index: libzvt.h
===================================================================
RCS file: /cvs/gnome/libzvt/libzvt/libzvt.h,v
retrieving revision 1.13
diff -u -r1.13 libzvt.h
--- libzvt.h	2002/05/14 04:04:07	1.13
+++ libzvt.h	2002/05/22 18:28:13
@@ -37,6 +37,7 @@
 #include <gtk/gtkadjustment.h>
 #include <gtk/gtkwidget.h>
 #include <gtk/gtksignal.h>
+#include <gtk/gtkimcontext.h>
 #include <libzvt/vtx.h>
 #include <libzvt/background.h>
 
@@ -119,8 +120,12 @@
   /*GdkColorContext *color_ctx;*/	/* Color context in use, where we allocate our colors */
   /* gulong colors [18];*/	/* Our colors, pixel values. */
   GdkColor colors [18];		/* GdkColor for colormap support */
-  /* GdkIC depecated, needto be substituted with GtkIMContext, not yet done */
-  /* GdkIC *ic;*/		/* input context */
+
+  /* input context */
+  GtkIMContext *ic;
+  guint16 preedit_length;	/* length of preedit string, in bytes */
+  guint16 preedit_cursor;	/* offset of cursor within preedit string, in chars */
+  gboolean      need_im_reset;
 
  /* file name of a pixmap, if NULL, none is loaded
   * and normal mode is used
Index: update.c
===================================================================
RCS file: /cvs/gnome/libzvt/libzvt/update.c,v
retrieving revision 1.69
diff -u -r1.69 update.c
--- update.c	2001/12/06 22:58:55	1.69
+++ update.c	2002/05/22 18:28:19
@@ -973,17 +973,17 @@
 /* convert columns start to column end of line l, into
    chars of size 'size'.
 */
-static char *vt_expand_line(struct vt_line *l, int size, int start, int end, char *out)
+static char *vt_expand_line(struct vt_line *l, int size, int start, int end,
+			    gssize *datalen)
 {
   int i;
-  unsigned int c=0;
   int state=0;
   int dataend=0;
   int lf=0;
 
   /* scan from the end of the line to the start, looking for the
      actual end of screen data on that line */
-  for(dataend=l->width;dataend>-1;) {
+  for (dataend = l->width; dataend > 0;) {
     dataend--;
     if (l->data[dataend] & VTATTR_DATAMASK) {
       dataend++;
@@ -991,14 +991,49 @@
     }
   }
 
-  if (end>dataend) {
+  if (end > dataend) {
     lf = 1;			/* we selected past the end of the line */
     end = dataend;
   }
 
   if (start<0)
     start=0;
- 
+
+  {
+    gssize len = end - start;
+    char *buf = g_new (char, len + 2);
+    char *bufp;
+    gsize bytes_read = 0;
+    gsize convlen = 0;
+    gchar *convbuf;
+    GError *error = NULL;
+    uint32 c;
+    for (bufp = buf, i = start; i < end; i++, bufp++) {
+      c = VT_ASCII(l->data[i]);
+      *bufp = c & 0x0000000ff;
+    }
+
+    if (lf)
+      buf[len++] = '\n';
+
+    buf[len] = 0;
+
+    convbuf = g_locale_to_utf8 (buf, len, &bytes_read, &convlen, &error);
+    g_free (buf);
+
+    if (error)
+      {
+	g_warning ("Error selecection data to UTF-8: %s\n", error->message);
+	g_error_free (error);
+	*datalen = 0;
+	return 0;
+      }
+
+    convbuf[convlen] = '\0';
+    *datalen = convlen;
+    return convbuf;
+  }
+#ifdef YUCK 
   /* YUCK!  oh well, this seems easiest way to do this! */
   switch(size) {
   case 2: {
@@ -1080,6 +1115,7 @@
   break;
   }
   return out;
+#endif /* YUCK */
 }
 
 /*
@@ -1097,7 +1133,7 @@
 {
   struct vt_line *wn, *nn;
   int line;
-  char *out, *data;
+  char *data;
   int tmp;
 
   if ( ((sy == ey) && (sx > ex)) ||
@@ -1107,15 +1143,6 @@
     tmp = sy; sy=ey; ey=tmp;
   }
 
-  /* makes a rough assumption about the buffer size needed */
-  if ( (data = g_malloc(size*(ey-sy+1)*(vx->vt.width+20)+1)) == 0 ) {
-    *len = 0;
-    printf("ERROR: Cannot g_malloc selection buffer\n");
-    return 0;
-  }
-
-  out = data;
-
   line = sy;
   wn = (struct vt_line *)vt_list_index((line<0)?(&vx->vt.scrollback):(&vx->vt.lines), line);
 
@@ -1131,15 +1158,15 @@
 
   /* only a single line selected? */
   if (sy == ey) {
-    out = vt_expand_line(wn, size, sx, ex, out);
+    data = vt_expand_line(wn, size, sx, ex, len);
   } else {
     /* scan lines */
     while (nn && (line<ey)) {
       d(printf("adding selection from line %d\n", line));
       if (line == sy) {
-	out = vt_expand_line(wn, size, sx, wn->width, out); /* first line */
+	data = vt_expand_line(wn, size, sx, wn->width, len); /* first line */
       } else {
-	out = vt_expand_line(wn, size, 0, wn->width, out);
+	data = vt_expand_line(wn, size, 0, wn->width, len);
       }
       line++;
       if (line==0) {		/* wrapped into 'on screen' area? */
@@ -1153,11 +1180,8 @@
 
     /* last line (if it exists - shouldn't happen?) */
     if (nn)
-      out = vt_expand_line(wn, size, 0, ex, out);
+      data = vt_expand_line(wn, size, 0, ex, len);
   }
-
-  *len = (out-data)/size;
-  *out = 0;
 
   d(printf("selected text = \n");
     fwrite(data, out-data, 1, stdout);
Index: vt.c
===================================================================
RCS file: /cvs/gnome/libzvt/libzvt/vt.c,v
retrieving revision 1.84
diff -u -r1.84 vt.c
--- vt.c	2002/04/21 21:02:11	1.84
+++ vt.c	2002/05/22 18:28:27
@@ -1552,8 +1552,16 @@
 	continue;
       }
     } else {
-      mode = modes[c & 0x7f].modes;
-      process = modes[c & 0x7f].process;
+      if (c < 80)
+	{
+	  mode = modes[c & 0x7f].modes;
+	  process = modes[c & 0x7f].process;
+	}
+      else
+	{
+	  mode = VT_LIT;
+	  process = 0;
+	}
     }
 #else
     mode = modes[c & 0x7f].modes;
Index: zvtterm.c
===================================================================
RCS file: /cvs/gnome/libzvt/libzvt/zvtterm.c,v
retrieving revision 1.186
diff -u -r1.186 zvtterm.c
--- zvtterm.c	2002/05/14 16:55:21	1.186
+++ zvtterm.c	2002/05/22 18:28:33
@@ -347,12 +347,12 @@
 }
 
 static const GtkTargetEntry target_table[] = {
-  { "STRING" },
-  { "TEXT" },
-  { "COMPOUND_TEXT" },
 #ifdef ZVT_UTF8
-  { "UTF8_STRING" },
+  { "UTF8_STRING",   0, 0 },
 #endif
+  { "COMPOUND_TEXT", 0, 0 },
+  { "TEXT",          0, 0 },
+  { "STRING",        0, 0 }
 };
 
 static void
@@ -388,8 +388,10 @@
   /* Deprecated */
   /*
   term->color_ctx = 0;
-  term->ic = NULL;
   */
+  term->ic = NULL;
+  term->preedit_length = 0;
+  term->preedit_cursor = 0;
 
   /* grid sizing */
   term->grid_width = term->vx->vt.width;
@@ -407,10 +409,6 @@
   term->scroll_on_keystroke = 0;
   term->scroll_on_output = 0;
   term->blink_enabled = 1;
-  /* Deprecated */
-  /*
-  term->ic = NULL;
-  */
   term->in_expose = 0;
   term->transparent = 0;
   term->shaded = 0;
@@ -759,14 +757,12 @@
     term->adjustment = NULL;
   }
 
-  /* Deprecated */
-  /*
+  /* destroy input context */
   if (term->ic) {
-    gdk_ic_destroy(term->ic);
+    g_object_unref (term->ic);
     term->ic = NULL;
   }
-  */
-
+    
   /* release private data */
   if (zp) {
     if (zp->text_expand)
@@ -964,6 +960,47 @@
 }
 
 static void
+zvt_term_commit_handler (GtkIMContext  *context,
+			 const gchar   *str,
+			 ZvtTerm       *term)
+{
+  gint   length = 0;
+  gchar *locstr = g_locale_from_utf8 (str, -1, NULL, &length, NULL);
+
+  if (length > 0) {
+    vt_writechild (&term->vx->vt, locstr, length);
+    if (term->scroll_on_keystroke) zvt_term_scroll (term, 0);
+  }
+  g_free (locstr);
+}
+
+static void
+zvt_term_preedit_changed_handler (GtkIMContext *context,
+				  ZvtTerm *term)
+{
+  gchar *preedit_string;
+  gint cursor_pos;
+
+  gtk_im_context_get_preedit_string (context,
+				     &preedit_string, NULL,
+				     &cursor_pos);
+  term->preedit_length = strlen (preedit_string);
+  cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1));
+  term->preedit_cursor = cursor_pos;
+  g_free (preedit_string);
+
+}
+
+static void
+zvt_term_im_reset (ZvtTerm *term)
+{
+  if (term->ic && term->need_im_reset) {
+    term->need_im_reset = FALSE;
+    gtk_im_context_reset (term->ic);
+  }
+}
+
+static void
 zvt_term_realize (GtkWidget *widget)
 {
   ZvtTerm *term;
@@ -1066,20 +1103,16 @@
   term_force_size(term);
 
   /* input context */
-#ifdef UNDEF
-  if (gdk_im_ready () && !term->ic) {
-    GdkICAttr attr;
-    
-    /* FIXME: do we have any window yet? */
-    attr.style = GDK_IM_PREEDIT_NOTHING | GDK_IM_STATUS_NOTHING;
-    attr.client_window = attr.focus_window = widget->window;
-    term->ic = gdk_ic_new(&attr, GDK_IC_ALL_REQ);
-    
-    if (!term->ic) {
-      g_warning("Can't create input context.");
-    }
+  if (!term->ic) {
+    term->ic = gtk_im_multicontext_new ();
+    g_signal_connect (term->ic, "commit",
+		      G_CALLBACK (zvt_term_commit_handler), term);
+
+    gtk_im_context_set_client_window (term->ic, widget->window);
+    g_signal_connect (G_OBJECT(term->ic), "preedit-changed",
+		      GTK_SIGNAL_FUNC(zvt_term_preedit_changed_handler), term);
   }
-#endif /* UNDEF */
+
   /* if we have a delayed background set, set it here? */
   if (zp->background_queue) {
     zvt_term_background_load(term, zp->background_queue);
@@ -1129,6 +1162,9 @@
   g_object_unref (term->fore_gc);
   term->fore_gc = NULL;
 
+  if (term->ic)
+    gtk_im_context_set_client_window (term->ic, NULL);
+  
   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
     (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
 }
@@ -1190,12 +1226,11 @@
   if (term->blink_enabled && term->timeout_id == -1)
     term->timeout_id = gtk_timeout_add (500, zvt_term_cursor_blink, term);
 
-  /* Deprecated */
-  /*
-  if (term->ic)
-    gdk_im_begin (term->ic, widget->window);
-  */
-
+  if (term->ic) {
+    term->need_im_reset = TRUE;
+    gtk_im_context_focus_in (term->ic);
+  }
+  
   return FALSE;
 }
 
@@ -1222,12 +1257,11 @@
     term->timeout_id = -1;
   }
   
-  /* Deprecated */
-  /*
-  if (term->ic)
-    gdk_im_end ();
-  */
-
+  if (term->ic) {
+    term->need_im_reset = TRUE;
+    gtk_im_context_focus_out (term->ic);
+  }
+  
   return FALSE;
 }
 
@@ -1465,13 +1499,25 @@
       zp->fonttype = ZVT_FONT_2BYTE;
     break;
   }
-  case GDK_FONT_FONTSET: {
-    XFontSet fontset = (XFontSet) GDK_FONT_XFONT(font);
-    XFontSetExtents *extents = XExtentsOfFontSet(fontset);
-    term->charwidth = extents->max_logical_extent.width;
-    term->charheight = extents->max_logical_extent.height;
-    zp->fonttype = ZVT_FONT_FONTSET;
-  }
+  case GDK_FONT_FONTSET:
+    {
+      XFontSet fontset = (XFontSet) GDK_FONT_XFONT(font);
+      XFontStruct **font_struct_list, font_struct;
+      char **font_name_list = NULL;
+      if (XFontsOfFontSet (fontset,
+			   &font_struct_list,
+			   &font_name_list))
+	{
+	  if (font_struct_list && font_struct_list[0])
+	    {
+	      font_struct = font_struct_list[0][0];
+	      term->charwidth = font_struct.max_bounds.width;
+	      term->charheight =
+		font_struct.max_bounds.ascent + font_struct.max_bounds.descent;
+	    }
+	}
+      zp->fonttype = ZVT_FONT_FONTSET;
+    }
   }
   d(printf("fonttype = %d\n", zp->fonttype));
 
@@ -1635,9 +1681,8 @@
   if (text)
     {
       int i;
-      /* FIXME: pasting utf8 doesn't really work! */
-      char *buf = gdk_utf8_to_string_target (text);
-      int len = strlen (buf);
+      int len;
+      gchar *buf = g_locale_from_utf8 (text, -1, NULL, &len, NULL);
       char *ctmp = buf;
 
       for(i = 0; i < len; i++)
@@ -1690,6 +1735,7 @@
 
   zvt_term_show_pointer (term);
 
+  zvt_term_im_reset (term);
 
   gdk_window_get_pointer(widget->window, &x, &y, &mask);
   x /= term->charwidth;
@@ -2080,6 +2126,12 @@
   int i;
   uint32 c;
 
+  out = g_malloc (term->vx->selection_size);
+  memcpy (out, term->vx->selection_data, term->vx->selection_size);
+  *outlen = term->vx->selection_size;
+  return out;
+
+#ifdef YUCK
   switch (type) {
   default:
   case 0: {			/* this is ascii/isolatin1 */
@@ -2158,6 +2210,7 @@
   }
 
   return out;
+#endif
 }
 #endif
 
@@ -2181,8 +2234,11 @@
   vx = term->vx;
 
   converted = zvt_term_convert_selection (term, info, &len);
-  gtk_selection_data_set_text (selection_data_ptr, converted, len);
-  g_free(converted);
+  if (converted)
+    {
+      gtk_selection_data_set_text (selection_data_ptr, converted, len);
+      g_free(converted);
+    }
 }
 
 /**
@@ -2511,6 +2567,13 @@
                             event->keyval,
                             event->state)){
   
+    if (term->ic) {
+      if (gtk_im_context_filter_keypress (term->ic, event)) {
+	term->need_im_reset = TRUE;
+	return TRUE;
+      }
+    }
+    
   switch (event->keyval) {
   case GDK_BackSpace:
     if (term->backspace_binding == ZVT_ERASE_CONTROL_H ||
@@ -2711,6 +2774,7 @@
   if (handled && p>buffer) {
     vt_writechild(&vx->vt, buffer, (p-buffer));
     if (term->scroll_on_keystroke) zvt_term_scroll (term, 0);
+    zvt_term_im_reset (term);
   }
   }
 
@@ -3413,26 +3477,34 @@
   }
   break;
   /* this is limited to 65535 characters! */
-  case ZVT_FONT_FONTSET: {
-    wchar_t *expandwc = zp->text_expand;
-    XFontSet fontset = (XFontSet) GDK_FONT_XFONT(f);
+  case ZVT_FONT_FONTSET:
+    {
+      char *expandmb = zp->text_expand;
+      XFontSet fontset = (XFontSet) GDK_FONT_XFONT(f);
 
-    for (i=0;i<len;i++) {
-      expandwc[i] = VT_ASCII(line->data[i+col]);
-    }
+      for (i = 0; i < len;i++) {
+        c=VT_ASCII(line->data[i+col]);
+	expandmb[i] = c & 0x000000ff;
+      }
 
-    /* render wide characters, with fill if we can */
-    if (dofill) {
-      XwcDrawImageString(GDK_WINDOW_XDISPLAY(widget->window), GDK_WINDOW_XWINDOW(real_drawable),
-			 fontset, GDK_GC_XGC(fgc), offx + x, offy + y, expandwc, len);
-    } else {
-      XwcDrawString(GDK_WINDOW_XDISPLAY(widget->window), GDK_WINDOW_XWINDOW(real_drawable),
-		    fontset, GDK_GC_XGC(fgc), offx + x, offy + y, expandwc, len);
+      /* render wide characters, with fill if we can */
+      if (dofill)
+	XmbDrawImageString (GDK_WINDOW_XDISPLAY(widget->window),
+			    GDK_WINDOW_XWINDOW(real_drawable),
+			    fontset, GDK_GC_XGC(fgc), offx + x, offy + y,
+			    expandmb, len);
+      else
+	XmbDrawString (GDK_WINDOW_XDISPLAY(widget->window),
+		       GDK_WINDOW_XWINDOW(real_drawable),
+		       fontset, GDK_GC_XGC(fgc), offx + x, offy + y,
+		       expandmb, len);
+      if (overstrike)
+	XmbDrawString (GDK_WINDOW_XDISPLAY(widget->window),
+		       GDK_WINDOW_XWINDOW(real_drawable),
+		       fontset, GDK_GC_XGC(fgc), offx + x + 1, offy + y,
+		       expandmb, len);
     }
-    if (overstrike)
-      XwcDrawString(GDK_WINDOW_XDISPLAY(widget->window), GDK_WINDOW_XWINDOW(real_drawable),
-		    fontset, GDK_GC_XGC(fgc), offx + x + 1, offy + y, expandwc, len);
-  }
+    break;
   }
   offx+=real_offx;
   offy+=real_offy;
