[PATCH] XIM support in gtk+-1.3



Hi,

Here is a patch to add XIM support in gtk+-1.3. Only 'Root' style
is supported. This works only if XMODIFIERS environment variable
specifies a input method server. E.g., you need to set
	export XMODIFIERS="@im=kinput2"
	export XMODIFIERS="@im=Ami"
or something like.

---------------- x8 ---------------- x8 ---------------- x8 ----------------
diff -urN gtk+-1.3.1.orig/gdk/gdkim.h gtk+-1.3.1/gdk/gdkim.h
--- gtk+-1.3.1.orig/gdk/gdkim.h	Wed Mar 15 04:57:22 2000
+++ gtk+-1.3.1/gdk/gdkim.h	Wed Jul 19 00:02:49 2000
@@ -100,7 +100,7 @@
 
 void         gdk_im_begin	   (GdkIC               *ic, 
 				    GdkWindow           *window);
-void         gdk_im_end		   (void);
+void         gdk_im_end		   (GdkIC               *ic);
 GdkIMStyle   gdk_im_decide_style   (GdkIMStyle           supported_style);
 GdkIMStyle   gdk_im_set_best_style (GdkIMStyle           best_allowed_style);
 
diff -urN gtk+-1.3.1.orig/gdk/linux-fb/gdkim-fb.c gtk+-1.3.1/gdk/linux-fb/gdkim-fb.c
--- gtk+-1.3.1.orig/gdk/linux-fb/gdkim-fb.c	Thu Jun  1 06:50:38 2000
+++ gtk+-1.3.1/gdk/linux-fb/gdkim-fb.c	Wed Jul 19 00:02:49 2000
@@ -103,7 +103,7 @@
 }
 
 void 
-gdk_im_end (void)
+gdk_im_end (GdkIC *ic)
 {
 }
 
diff -urN gtk+-1.3.1.orig/gdk/win32/gdkim-win32.c gtk+-1.3.1/gdk/win32/gdkim-win32.c
--- gtk+-1.3.1.orig/gdk/win32/gdkim-win32.c	Tue May  2 07:06:49 2000
+++ gtk+-1.3.1/gdk/win32/gdkim-win32.c	Wed Jul 19 00:02:49 2000
@@ -64,7 +64,7 @@
 }
 
 void 
-gdk_im_end (void)
+gdk_im_end (GdkIC *ic)
 {
 }
 
diff -urN gtk+-1.3.1.orig/gdk/x11/gdkim-x11.c gtk+-1.3.1/gdk/x11/gdkim-x11.c
--- gtk+-1.3.1.orig/gdk/x11/gdkim-x11.c	Wed Jun 21 06:04:28 2000
+++ gtk+-1.3.1/gdk/x11/gdkim-x11.c	Wed Jul 19 00:02:49 2000
@@ -184,16 +184,12 @@
   attr.focus_window = window;
   gdk_ic_set_attr (ic, &attr, GDK_IC_FOCUS_WINDOW);
 
-  if (private != gdk_xim_ic)
+  if (private->xic)
     {
-      gdk_im_end();
-      if (private->xic)
-	{
-	  XSetICFocus (private->xic);
-	  GDK_NOTE (XIM, g_message ("im_begin icfocus : %p(%ld)\n",
-				    private->xic,
-				    GDK_WINDOW_XWINDOW(private->attr->focus_window)));
-	}
+      XSetICFocus (private->xic);
+      GDK_NOTE (XIM, g_message ("im_begin icfocus : %p(%ld)\n",
+				private->xic,
+				GDK_WINDOW_XWINDOW(private->attr->focus_window)));
     }
   gdk_xim_ic = private;
   gdk_xim_window = window;
@@ -206,6 +202,7 @@
  *   End using input method with XIM Protocol(X11R6 standard)
  *
  * Arguments:
+ *   "ic" is the "Input Context" which is created by gtk_ic_new.
  *
  * Results:
  *   The gdk's event handling routine is switched to normal routine.
@@ -217,15 +214,18 @@
  */
 
 void 
-gdk_im_end (void)
+gdk_im_end (GdkIC *ic)
 {
-  if (gdk_xim_ic && gdk_xim_ic->xic)
+  GdkICPrivate *private;
+
+  private = (GdkICPrivate *) ic;
+  XUnsetICFocus (private->xic);
+  GDK_NOTE (XIM, g_message ("im_end unfocus : %p\n", private->xic));
+  if (gdk_xim_ic == private)
     {
-      XUnsetICFocus (gdk_xim_ic->xic);
-      GDK_NOTE (XIM, g_message ("im_end unfocus : %p\n", gdk_xim_ic->xic));
+      gdk_xim_ic = NULL;
+      gdk_xim_window = NULL;
     }
-  gdk_xim_ic = NULL;
-  gdk_xim_window = NULL;
 }
 
 static GdkIMStyle 
@@ -688,7 +688,7 @@
   private = (GdkICPrivate *) ic;
   
   if (gdk_xim_ic == private)
-    gdk_im_end ();
+    gdk_im_end (ic);
   
   GDK_NOTE (XIM, g_message ("ic_destroy %p\n", private->xic));
   if (private->xic != NULL)
diff -urN gtk+-1.3.1.orig/gtk/Makefile.am gtk+-1.3.1/gtk/Makefile.am
--- gtk+-1.3.1.orig/gtk/Makefile.am	Sat Jul 15 04:35:23 2000
+++ gtk+-1.3.1/gtk/Makefile.am	Wed Jul 19 00:02:49 2000
@@ -186,8 +186,8 @@
 @STRIP_END@	
 
 # GTK+ header files that don't get installed
-gtk_private_h_sources = @STRIP_BEGIN@ \
-@STRIP_END@
+gtk_private_h_sources = 
+
 # GTK+ C sources to build the library from
 gtk_c_sources = @STRIP_BEGIN@ \
 	gtkaccelgroup.c		\
@@ -239,6 +239,8 @@
 	gtkimcontextsimple.c	\
 	gtkimcontextsimple.h	\
 	gtkimmulticontext.c	\
+	gtkimcontextxim.c	\
+	gtkimcontextxim.h	\
 	gtkinputdialog.c	\
 	gtkintl.h		\
 	gtkinvisible.c		\
diff -urN gtk+-1.3.1.orig/gtk/gtkentry.c gtk+-1.3.1/gtk/gtkentry.c
--- gtk+-1.3.1.orig/gtk/gtkentry.c	Mon Jul  3 07:30:54 2000
+++ gtk+-1.3.1/gtk/gtkentry.c	Wed Jul 19 00:02:49 2000
@@ -588,6 +588,8 @@
     gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
 
   gtk_im_context_set_client_window (entry->im_context, entry->text_area);
+  if (GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_im_context_focus_in (entry->im_context);
 }
 
 static void
diff -urN gtk+-1.3.1.orig/gtk/gtkimcontextxim.c gtk+-1.3.1/gtk/gtkimcontextxim.c
--- gtk+-1.3.1.orig/gtk/gtkimcontextxim.c	Thu Jan  1 09:00:00 1970
+++ gtk+-1.3.1/gtk/gtkimcontextxim.c	Wed Jul 19 01:32:25 2000
@@ -0,0 +1,212 @@
+/* GTK - The GIMP Toolkit
+ * gtkimcontextxim.[ch]
+ * Copyright (C) 2000 Kondara Project/Digital Factory Co., Ltd.
+ * written by Akira Higuchi <a@kondara.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkim.h>
+#include "gtksignal.h"
+#include "gtkimcontextxim.h"
+#include <stdlib.h>
+#include <string.h>
+
+static void     gtk_im_context_xim_class_init (GtkIMContextXIMClass *class);
+static void     gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim);
+
+static void     gtk_im_context_xim_set_client_window (GtkIMContext *context,
+						      GdkWindow *gdkwin);
+static gboolean gtk_im_context_xim_filter_keypress (GtkIMContext *context,
+						    GdkEventKey  *key);
+static void     gtk_im_context_xim_focus_in (GtkIMContext *context);
+static void     gtk_im_context_xim_focus_out (GtkIMContext *context);
+static void     gtk_im_context_xim_real_destroy (GtkObject *object);
+
+static GtkObjectClass *parent_class = NULL;
+
+GtkType
+gtk_im_context_xim_get_type (void)
+{
+  static GtkType im_context_xim_type = 0;
+
+  if (!im_context_xim_type)
+    {
+      static const GtkTypeInfo im_context_xim_info =
+      {
+	"GtkIMContextXIM",
+	sizeof (GtkIMContextXIM),
+	sizeof (GtkIMContextXIMClass),
+	(GtkClassInitFunc) gtk_im_context_xim_class_init,
+	(GtkObjectInitFunc) gtk_im_context_xim_init,
+	/* reserved_1 */ NULL,
+        /* reserved_2 */ NULL,
+        (GtkClassInitFunc) NULL,
+      };
+
+      im_context_xim_type = gtk_type_unique (GTK_TYPE_IM_CONTEXT,
+					     &im_context_xim_info);
+    }
+
+  return im_context_xim_type;
+}
+
+static void
+gtk_im_context_xim_class_init (GtkIMContextXIMClass *class)
+{
+  GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
+  GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
+  
+  parent_class = gtk_type_class (GTK_TYPE_IM_CONTEXT);
+  
+  im_context_class->filter_keypress = gtk_im_context_xim_filter_keypress;
+  im_context_class->set_client_window = gtk_im_context_xim_set_client_window;
+  im_context_class->focus_in = gtk_im_context_xim_focus_in;
+  im_context_class->focus_out = gtk_im_context_xim_focus_out;
+  object_class->destroy = gtk_im_context_xim_real_destroy;
+}
+
+static void
+gtk_im_context_xim_init (GtkIMContextXIM *context_xim)
+{
+  gchar *locale_codeset = NULL;
+  iconv_t cd = (iconv_t)-1;
+  
+  if (!g_get_charset (&locale_codeset))
+    {
+      /* locale codeset is not utf-8. we need to convert. */
+      cd = iconv_open ("UTF-8", locale_codeset);
+    }
+  
+  context_xim->ic = NULL;
+  context_xim->client_window = NULL;
+  context_xim->cd = cd;
+}
+
+GtkIMContext *
+gtk_im_context_xim_new (void)
+{
+  gchar *xmodifiers;
+  if ((xmodifiers = getenv("XMODIFIERS")) == NULL ||
+       strstr (xmodifiers, "@im=") == NULL)
+    return NULL;
+  return GTK_IM_CONTEXT (gtk_type_new (GTK_TYPE_IM_CONTEXT_XIM));
+}
+
+static void     gtk_im_context_xim_set_client_window (GtkIMContext *context,
+						      GdkWindow *gdkwin)
+{
+  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
+
+  context_xim->client_window = gdkwin;
+  if (context_xim->ic == NULL)
+    {
+      GdkICAttr *icattr;
+      
+      if (gdk_im_ready () && (icattr = gdk_ic_attr_new ()) != NULL)
+	{
+	  GdkICAttributesType icattrmask = GDK_IC_ALL_REQ;
+	  GdkIMStyle imstyle;
+	  /* Only 'Root' style is supported. */
+	  GdkIMStyle supported_imstyle =
+	    /*
+	    GDK_IM_PREEDIT_NONE |
+	    GDK_IM_STATUS_NONE |
+	    GDK_IM_PREEDIT_AREA |
+	    GDK_IM_STATUS_AREA |
+	    GDK_IM_PREEDIT_CALLBACKS |
+	    GDK_IM_STATUS_CALLBACKS |
+	    GDK_IM_PREEDIT_POSITION |
+	    */
+	    GDK_IM_PREEDIT_NOTHING |
+	    GDK_IM_STATUS_NOTHING;
+
+	  imstyle = gdk_im_decide_style (supported_imstyle);
+	  icattr->style = imstyle;
+	  icattr->client_window = gdkwin;
+	  context_xim->ic = gdk_ic_new (icattr, icattrmask);
+	  if (context_xim->ic)
+	    {
+	      GdkEventMask mask;
+	      mask = gdk_window_get_events (gdkwin);
+	      mask |= gdk_ic_get_events (context_xim->ic);
+	      gdk_window_set_events (gdkwin, mask);
+	    }
+	}
+    }
+}
+
+static gboolean
+gtk_im_context_xim_filter_keypress (GtkIMContext *context,
+				    GdkEventKey  *event)
+{
+  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
+  guchar str[1025];
+
+  if (context_xim->cd == (iconv_t)-1)
+    {
+      strncpy (str, event->string, 1024);
+      str[MIN (event->length, 1024)] = '\0';
+    }
+  else
+    {
+      gchar *from, *to;
+      size_t from_len, to_len;
+      from = event->string;
+      from_len = event->length;
+      to = (char *)str;
+      to_len = 1024;
+      iconv (context_xim->cd, &from, &from_len, &to, &to_len);
+      to[0] = '\0';
+    }
+  if (str[0] && (str[0] >= 0x20))
+    {
+      gtk_signal_emit_by_name (GTK_OBJECT (context), "commit", &str);
+      return TRUE;
+    }
+  return FALSE;
+}
+
+static void
+gtk_im_context_xim_focus_in (GtkIMContext *context)
+{
+  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
+
+  if (context_xim->client_window && context_xim->ic)
+    gdk_im_begin (context_xim->ic, context_xim->client_window);
+}
+
+static void
+gtk_im_context_xim_focus_out (GtkIMContext *context)
+{
+  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
+
+  if (context_xim->ic)
+    gdk_im_end (context_xim->ic);
+}
+
+static void    
+gtk_im_context_xim_real_destroy (GtkObject *object)
+{
+  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (object);
+  if (context_xim->ic)
+    gdk_ic_destroy (context_xim->ic);
+  if (context_xim->cd != (iconv_t)-1)
+    iconv_close (context_xim->cd);
+  GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
diff -urN gtk+-1.3.1.orig/gtk/gtkimcontextxim.h gtk+-1.3.1/gtk/gtkimcontextxim.h
--- gtk+-1.3.1.orig/gtk/gtkimcontextxim.h	Thu Jan  1 09:00:00 1970
+++ gtk+-1.3.1/gtk/gtkimcontextxim.h	Wed Jul 19 01:14:13 2000
@@ -0,0 +1,66 @@
+/* GTK - The GIMP Toolkit
+ * gtkimcontextxim.[ch]
+ * Copyright (C) 2000 Kondara Project/Digital Factory Co., Ltd.
+ * written by Akira Higuchi <a@kondara.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_IM_CONTEXT_XIM_H__
+#define __GTK_IM_CONTEXT_XIM_H__
+
+#include <gtk/gtkimcontext.h>
+#include <iconv.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TYPE_IM_CONTEXT_XIM              (gtk_im_context_xim_get_type ())
+#define GTK_IM_CONTEXT_XIM(obj)              (GTK_CHECK_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
+#define GTK_IM_CONTEXT_XIM_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
+#define GTK_IS_IM_CONTEXT_XIM(obj)           (GTK_CHECK_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
+#define GTK_IS_IM_CONTEXT_XIM_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_XIM))
+#define GTK_IM_CONTEXT_XIM_GET_CLASS(obj)    (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
+
+
+typedef struct _GtkIMContextXIM       GtkIMContextXIM;
+typedef struct _GtkIMContextXIMClass  GtkIMContextXIMClass;
+
+struct _GtkIMContextXIM
+{
+  GtkIMContext object;
+
+  GdkIC *ic;
+  GdkWindow *client_window;
+  iconv_t cd;
+};
+
+struct _GtkIMContextXIMClass
+{
+  GtkIMContextClass parent_class;
+};
+
+GtkType       gtk_im_context_xim_get_type (void);
+GtkIMContext *gtk_im_context_xim_new      (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_IM_CONTEXT_XIM_H__ */
diff -urN gtk+-1.3.1.orig/gtk/gtkimmulticontext.c gtk+-1.3.1/gtk/gtkimmulticontext.c
--- gtk+-1.3.1.orig/gtk/gtkimmulticontext.c	Fri Jun  2 12:13:58 2000
+++ gtk+-1.3.1/gtk/gtkimmulticontext.c	Wed Jul 19 00:02:50 2000
@@ -20,6 +20,7 @@
 #include "gtksignal.h"
 #include "gtkimmulticontext.h"
 #include "gtkimcontextsimple.h"
+#include "gtkimcontextxim.h"
 
 static void     gtk_im_multicontext_class_init         (GtkIMMulticontextClass  *class);
 static void     gtk_im_multicontext_init               (GtkIMMulticontext       *im_multicontext);
@@ -148,7 +149,13 @@
 gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext)
 {
   if (!multicontext->slave)
-    gtk_im_multicontext_set_slave (multicontext, gtk_im_context_simple_new ());
+    {
+      GtkIMContext *new_slave;
+      new_slave = gtk_im_context_xim_new ();
+      if (!new_slave)
+	new_slave = gtk_im_context_simple_new ();
+      gtk_im_multicontext_set_slave (multicontext, new_slave);
+    }
 
   return multicontext->slave;
 }
diff -urN gtk+-1.3.1.orig/gtk/gtkmain.c gtk+-1.3.1/gtk/gtkmain.c
--- gtk+-1.3.1.orig/gtk/gtkmain.c	Sat Jul 15 03:43:37 2000
+++ gtk+-1.3.1/gtk/gtkmain.c	Wed Jul 19 00:02:50 2000
@@ -425,7 +425,6 @@
   gtk_signal_init ();
   gtk_rc_init ();
   
-  
   /* Register an exit function to make sure we are able to cleanup.
    */
   g_atexit (gtk_exit_func);
@@ -463,6 +462,8 @@
 void
 gtk_init (int *argc, char ***argv)
 {
+  gtk_set_locale ();
+  
   if (!gtk_init_check (argc, argv))
     {
       g_warning ("cannot open display: %s", gdk_get_display ());
diff -urN gtk+-1.3.1.orig/gtk/gtktext.c gtk+-1.3.1/gtk/gtktext.c
--- gtk+-1.3.1.orig/gtk/gtktext.c	Wed Jun 21 06:04:38 2000
+++ gtk+-1.3.1/gtk/gtktext.c	Wed Jul 19 00:02:50 2000
@@ -2269,7 +2269,7 @@
   undraw_cursor (GTK_TEXT(widget), TRUE);
   
 #ifdef USE_XIM
-  gdk_im_end ();
+  gdk_im_end (GTK_EDITABLE (widget)->ic);
 #endif
   
   return FALSE;
diff -urN gtk+-1.3.1.orig/gtk/gtktextview.c gtk+-1.3.1/gtk/gtktextview.c
--- gtk+-1.3.1.orig/gtk/gtktextview.c	Sat Jul 15 05:25:29 2000
+++ gtk+-1.3.1/gtk/gtktextview.c	Wed Jul 19 00:02:50 2000
@@ -1298,6 +1298,8 @@
   gdk_cursor_destroy (cursor);
 
   gtk_im_context_set_client_window (text_view->im_context, widget->window);
+  if (GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_im_context_focus_in (text_view->im_context);
 }
 
 static void
---------------- x8 ---------------- x8 ---------------- x8 ----------------

--------------------------------------
Akira Higuchi
Dept. of Mathematics, Hokkaido Univ.
Sapporo, Japan
a-higuti@math.sci.hokudai.ac.jp
a@kondara.org




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]