Bug 8275 - I couldn't input any Chinese character or Japanese character In Mono editor on Mac
Summary: I couldn't input any Chinese character or Japanese character In Mono editor o...
Status: RESOLVED DUPLICATE of bug 828
Alias: None
Product: Xamarin Studio
Classification: Desktop
Component: Text Editor ()
Version: unspecified
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: ---
Assignee: Mike Krüger
URL:
Depends on:
Blocks:
 
Reported: 2012-11-07 20:00 UTC by HuRui
Modified: 2012-11-09 14:57 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED DUPLICATE of bug 828

Description HuRui 2012-11-07 20:00:15 UTC
hello , can you help me to fix a input bug in unity3d(mono), I find this bug but I have no time to fix it. 

My name is Hu Rui, I'm a developer from China.

I use unity3d On MAC. I find a bug in MonoDevelop that I can't input any Chinese character or Japanese character In Mono editor(it only can input english).

I download the Mono source code and spend server hours on finding this bug.


I find that it cause by IMContext commpent in Mono. it use win32 gtk lib(libgtk-win32-2.0-0.dll
) on Mac platform. if I use un-english IM , I only can input english character to Mono Editor.

I think your team can fix this bug easily (use Mac gtk lib).

Waiting for your reply. Welcome to my web: www.J2meGame.com



Bug in this code:

using Gdk;
using GLib;
using Pango;
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Gtk
{
	public class IMContext : Object
	{
		[CDeclCallback]
		private delegate void CommitVMDelegate (IntPtr context, IntPtr str);

		[CDeclCallback]
		private delegate void PreeditChangedVMDelegate (IntPtr context);

		[CDeclCallback]
		private delegate void PreeditEndVMDelegate (IntPtr context);

		[CDeclCallback]
		private delegate void PreeditStartVMDelegate (IntPtr context);

		[CDeclCallback]
		private delegate bool RetrieveSurroundingVMDelegate (IntPtr context);

		[CDeclCallback]
		private delegate bool SurroundingDeletedVMDelegate (IntPtr context, int offset, int n_chars);

		//
		// Static Fields
		//

		private static IMContext.SurroundingDeletedVMDelegate SurroundingDeletedVMCallback;

		private static IMContext.PreeditStartVMDelegate PreeditStartVMCallback;

		private static IMContext.PreeditChangedVMDelegate PreeditChangedVMCallback;

		private static IMContext.PreeditEndVMDelegate PreeditEndVMCallback;

		private static IMContext.RetrieveSurroundingVMDelegate RetrieveSurroundingVMCallback;

		private static IMContext.CommitVMDelegate CommitVMCallback;

		//
		// Static Properties
		//

		public new static GType GType
		{
			get
			{
				IntPtr val = IMContext.gtk_im_context_get_type ();
				GType result = new GType (val);
				return result;
			}
		}

		//
		// Properties
		//

		public Window ClientWindow
		{
			set
			{
				IMContext.gtk_im_context_set_client_window (base.Handle, (value != null) ? value.Handle : IntPtr.Zero);
			}
		}

		public Rectangle CursorLocation
		{
			set
			{
				IntPtr intPtr = Marshaller.StructureToPtrAlloc (value);
				IMContext.gtk_im_context_set_cursor_location (base.Handle, intPtr);
				value = Rectangle.New (intPtr);
				Marshal.FreeHGlobal (intPtr);
			}
		}

		public bool UsePreedit
		{
			set
			{
				IMContext.gtk_im_context_set_use_preedit (base.Handle, value);
			}
		}

		//
		// Constructors
		//

		protected IMContext () : base (IntPtr.Zero)
		{
			this.CreateNativeObject (new string[0], new Value[0]);
		}

		public IMContext (IntPtr raw) : base (raw)
		{
		}

		[Obsolete]
		protected IMContext (GType gtype) : base (gtype)
		{
		}

		//
		// Static Methods
		//

		private static void commit_cb (IntPtr context, IntPtr str)
		{
			try
			{
				IMContext iMContext = Object.GetObject (context, false) as IMContext;
				iMContext.OnCommit (Marshaller.Utf8PtrToString (str));
			}
			catch (Exception e)
			{
				ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[DllImport ("libgtk-win32-2.0-0.dll")] // it cause can't input chinese or japanese
		private static extern bool gtk_im_context_delete_surrounding (IntPtr raw, int offset, int n_chars);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern bool gtk_im_context_filter_keypress (IntPtr raw, IntPtr evnt);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_focus_in (IntPtr raw);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_focus_out (IntPtr raw);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_get_preedit_string (IntPtr raw, out IntPtr str, out IntPtr attrs, out int cursor_pos);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern bool gtk_im_context_get_surrounding (IntPtr raw, out IntPtr text, out int cursor_index);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern IntPtr gtk_im_context_get_type ();

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_reset (IntPtr raw);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_set_client_window (IntPtr raw, IntPtr window);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_set_cursor_location (IntPtr raw, IntPtr value);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_set_surrounding (IntPtr raw, IntPtr text, int len, int cursor_index);

		[DllImport ("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_im_context_set_use_preedit (IntPtr raw, bool use_preedit);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_base_commit (IntPtr context, IntPtr str);

		[DllImport ("gtksharpglue-2")]
		private static extern bool gtksharp_imcontext_base_delete_surrounding (IntPtr context, int offset, int n_chars);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_base_preedit_changed (IntPtr context);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_base_preedit_end (IntPtr context);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_base_preedit_start (IntPtr context);

		[DllImport ("gtksharpglue-2")]
		private static extern bool gtksharp_imcontext_base_retrieve_surrounding (IntPtr context);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_override_commit (IntPtr gtype, IMContext.CommitVMDelegate cb);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_override_delete_surrounding (IntPtr gtype, IMContext.SurroundingDeletedVMDelegate cb);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_override_preedit_changed (IntPtr gtype, IMContext.PreeditChangedVMDelegate cb);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_override_preedit_end (IntPtr gtype, IMContext.PreeditEndVMDelegate cb);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_override_preedit_start (IntPtr gtype, IMContext.PreeditStartVMDelegate cb);

		[DllImport ("gtksharpglue-2")]
		private static extern void gtksharp_imcontext_override_retrieve_surrounding (IntPtr gtype, IMContext.RetrieveSurroundingVMDelegate cb);

		private static void OverrideCommit (GType gtype)
		{
			if (IMContext.CommitVMCallback == null)
			{
				IMContext.CommitVMCallback = new IMContext.CommitVMDelegate (IMContext.commit_cb);
			}
			IMContext.gtksharp_imcontext_override_commit (gtype.Val, IMContext.CommitVMCallback);
		}

		private static void OverridePreeditChanged (GType gtype)
		{
			if (IMContext.PreeditChangedVMCallback == null)
			{
				IMContext.PreeditChangedVMCallback = new IMContext.PreeditChangedVMDelegate (IMContext.preeditchanged_cb);
			}
			IMContext.gtksharp_imcontext_override_preedit_changed (gtype.Val, IMContext.PreeditChangedVMCallback);
		}

		private static void OverridePreeditEnd (GType gtype)
		{
			if (IMContext.PreeditEndVMCallback == null)
			{
				IMContext.PreeditEndVMCallback = new IMContext.PreeditEndVMDelegate (IMContext.preeditend_cb);
			}
			IMContext.gtksharp_imcontext_override_preedit_end (gtype.Val, IMContext.PreeditEndVMCallback);
		}

		private static void OverridePreeditStart (GType gtype)
		{
			if (IMContext.PreeditStartVMCallback == null)
			{
				IMContext.PreeditStartVMCallback = new IMContext.PreeditStartVMDelegate (IMContext.preeditstart_cb);
			}
			IMContext.gtksharp_imcontext_override_preedit_start (gtype.Val, IMContext.PreeditStartVMCallback);
		}

		private static void OverrideRetrieveSurrounding (GType gtype)
		{
			if (IMContext.RetrieveSurroundingVMCallback == null)
			{
				IMContext.RetrieveSurroundingVMCallback = new IMContext.RetrieveSurroundingVMDelegate (IMContext.retrievesurrounding_cb);
			}
			IMContext.gtksharp_imcontext_override_retrieve_surrounding (gtype.Val, IMContext.RetrieveSurroundingVMCallback);
		}

		private static void OverrideSurroundingDeleted (GType gtype)
		{
			if (IMContext.SurroundingDeletedVMCallback == null)
			{
				IMContext.SurroundingDeletedVMCallback = new IMContext.SurroundingDeletedVMDelegate (IMContext.surroundingdeleted_cb);
			}
			IMContext.gtksharp_imcontext_override_delete_surrounding (gtype.Val, IMContext.SurroundingDeletedVMCallback);
		}

		private static void preeditchanged_cb (IntPtr context)
		{
			try
			{
				IMContext iMContext = Object.GetObject (context, false) as IMContext;
				iMContext.OnPreeditChanged ();
			}
			catch (Exception e)
			{
				ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		private static void preeditend_cb (IntPtr context)
		{
			try
			{
				IMContext iMContext = Object.GetObject (context, false) as IMContext;
				iMContext.OnPreeditEnd ();
			}
			catch (Exception e)
			{
				ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		private static void preeditstart_cb (IntPtr context)
		{
			try
			{
				IMContext iMContext = Object.GetObject (context, false) as IMContext;
				iMContext.OnPreeditStart ();
			}
			catch (Exception e)
			{
				ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		private static bool retrievesurrounding_cb (IntPtr context)
		{
			bool result;
			try
			{
				IMContext iMContext = Object.GetObject (context, false) as IMContext;
				result = iMContext.OnRetrieveSurrounding ();
			}
			catch (Exception ex)
			{
				ExceptionManager.RaiseUnhandledException (ex, true);
				throw ex;
			}
			return result;
		}

		private static bool surroundingdeleted_cb (IntPtr context, int offset, int n_chars)
		{
			bool result;
			try
			{
				IMContext iMContext = Object.GetObject (context, false) as IMContext;
				result = iMContext.OnSurroundingDeleted (offset, n_chars);
			}
			catch (Exception ex)
			{
				ExceptionManager.RaiseUnhandledException (ex, true);
				throw ex;
			}
			return result;
		}

		//
		// Methods
		//

		public bool DeleteSurrounding (int offset, int n_chars)
		{
			return IMContext.gtk_im_context_delete_surrounding (base.Handle, offset, n_chars);
		}

		public bool FilterKeypress (EventKey evnt)
		{
			return IMContext.gtk_im_context_filter_keypress (base.Handle, (evnt != null) ? evnt.Handle : IntPtr.Zero);
		}

		public void FocusIn ()
		{
			IMContext.gtk_im_context_focus_in (base.Handle);
		}

		public void FocusOut ()
		{
			IMContext.gtk_im_context_focus_out (base.Handle);
		}

		public void GetPreeditString (out string str, out AttrList attrs, out int cursor_pos)
		{
			IntPtr ptr;
			IntPtr intPtr;
			IMContext.gtk_im_context_get_preedit_string (base.Handle, out ptr, out intPtr, out cursor_pos);
			str = Marshaller.PtrToStringGFree (ptr);
			attrs = ((!(intPtr == IntPtr.Zero)) ? ((AttrList)Opaque.GetOpaque (intPtr, typeof(AttrList), false)) : null);
		}

		public bool GetSurrounding (out string text, out int cursor_index)
		{
			IntPtr ptr;
			bool flag = IMContext.gtk_im_context_get_surrounding (base.Handle, out ptr, out cursor_index);
			bool result = flag;
			text = Marshaller.PtrToStringGFree (ptr);
			return result;
		}

		[DefaultSignalHandler (Type = typeof(IMContext), ConnectionMethod = "OverrideCommit")]
		protected virtual void OnCommit (string str)
		{
			IntPtr intPtr = Marshaller.StringToPtrGStrdup (str);
			IMContext.gtksharp_imcontext_base_commit (base.Handle, intPtr);
			Marshaller.Free (intPtr);
		}

		[DefaultSignalHandler (Type = typeof(IMContext), ConnectionMethod = "OverridePreeditChanged")]
		protected virtual void OnPreeditChanged ()
		{
			IMContext.gtksharp_imcontext_base_preedit_changed (base.Handle);
		}

		[DefaultSignalHandler (Type = typeof(IMContext), ConnectionMethod = "OverridePreeditEnd")]
		protected virtual void OnPreeditEnd ()
		{
			IMContext.gtksharp_imcontext_base_preedit_end (base.Handle);
		}

		[DefaultSignalHandler (Type = typeof(IMContext), ConnectionMethod = "OverridePreeditStart")]
		protected virtual void OnPreeditStart ()
		{
			IMContext.gtksharp_imcontext_base_preedit_start (base.Handle);
		}

		[DefaultSignalHandler (Type = typeof(IMContext), ConnectionMethod = "OverrideRetrieveSurrounding")]
		protected virtual bool OnRetrieveSurrounding ()
		{
			return IMContext.gtksharp_imcontext_base_retrieve_surrounding (base.Handle);
		}

		[DefaultSignalHandler (Type = typeof(IMContext), ConnectionMethod = "OverrideSurroundingDeleted")]
		protected virtual bool OnSurroundingDeleted (int offset, int n_chars)
		{
			return IMContext.gtksharp_imcontext_base_delete_surrounding (base.Handle, offset, n_chars);
		}

		public void Reset ()
		{
			IMContext.gtk_im_context_reset (base.Handle);
		}

		public void SetSurrounding (string text, int cursor_index)
		{
			IntPtr intPtr = Marshaller.StringToPtrGStrdup (text);
			IMContext.gtk_im_context_set_surrounding (base.Handle, intPtr, Encoding.get_UTF8 ().GetByteCount (text), cursor_index);
			Marshaller.Free (intPtr);
		}

		//
		// Events
		//

		[Signal ("commit")]
		public event CommitHandler Commit
		{
			add
			{
				Signal signal = Signal.Lookup (this, "commit", typeof(CommitArgs));
				signal.AddDelegate (value);
			}
			remove
			{
				Signal signal = Signal.Lookup (this, "commit", typeof(CommitArgs));
				signal.RemoveDelegate (value);
			}
		}

		[Signal ("preedit_changed")]
		public event EventHandler PreeditChanged
		{
			add
			{
				Signal signal = Signal.Lookup (this, "preedit_changed");
				signal.AddDelegate (value);
			}
			remove
			{
				Signal signal = Signal.Lookup (this, "preedit_changed");
				signal.RemoveDelegate (value);
			}
		}

		[Signal ("preedit_end")]
		public event EventHandler PreeditEnd
		{
			add
			{
				Signal signal = Signal.Lookup (this, "preedit_end");
				signal.AddDelegate (value);
			}
			remove
			{
				Signal signal = Signal.Lookup (this, "preedit_end");
				signal.RemoveDelegate (value);
			}
		}

		[Signal ("preedit_start")]
		public event EventHandler PreeditStart
		{
			add
			{
				Signal signal = Signal.Lookup (this, "preedit_start");
				signal.AddDelegate (value);
			}
			remove
			{
				Signal signal = Signal.Lookup (this, "preedit_start");
				signal.RemoveDelegate (value);
			}
		}

		[Signal ("retrieve_surrounding")]
		public event RetrieveSurroundingHandler RetrieveSurrounding
		{
			add
			{
				Signal signal = Signal.Lookup (this, "retrieve_surrounding", typeof(RetrieveSurroundingArgs));
				signal.AddDelegate (value);
			}
			remove
			{
				Signal signal = Signal.Lookup (this, "retrieve_surrounding", typeof(RetrieveSurroundingArgs));
				signal.RemoveDelegate (value);
			}
		}

		[Signal ("delete_surrounding")]
		public event SurroundingDeletedHandler SurroundingDeleted
		{
			add
			{
				Signal signal = Signal.Lookup (this, "delete_surrounding", typeof(SurroundingDeletedArgs));
				signal.AddDelegate (value);
			}
			remove
			{
				Signal signal = Signal.Lookup (this, "delete_surrounding", typeof(SurroundingDeletedArgs));
				signal.RemoveDelegate (value);
			}
		}
	}
}
Comment 1 Mikayla Hutchinson [MSFT] 2012-11-09 14:57:46 UTC
Unfortunately the GTK+ toolkit lacks an IME backend for Mac, though there is an experimental patch that we plan to investigate.

*** This bug has been marked as a duplicate of bug 828 ***