Sense Hofstede wrote:
Hello,

The past few weeks I've been working on getting the Mono bindings of
libappindicator[1] to work correctly. I managed to get everything work
correctly apart from making the virtual members accessible an
overridable in C#. The thing is that libappindicator provides two
(virtual) methods that provide a fall back mechanism. You can
implement your own by overriding those functions. However, I couldn't
get this to work because virtual methods aren't supported by GAPI2
which is included in GTK# 2.12.9. If everything goes well it might be
included in the GTK# 3.0 release in September. That is too late for
Lucid, obviously and therefore the libappindicator library won't have
all functionality in C# that is available in C, Python and in the near
future in Vala as well.
If there are only two virtual methods that you're struggling with you could add custom code to make them work with gapi 2. There are basically two ways to get this done: 1.) Write some ugly glue/C code that overrides the function and call it from managed custom code. Ugly, but at least it works. Gtk# 2.12 does this to get cell renderers to work properly (see gtk-sharp-212-branch/gtk/CellRenderer.cs). 2.) Do it all in managed code. This does however not work with Microsoft's implementation of .net in Version 1.1. Maybe the attached GAPI3 generated code for Cellrenderer.cs helps you getting started (have a look at OngetSize, OnRender, ..)
September 2010 is a quite far away from November 2004, which was when
VirtualMember.cs was uploaded to SVN for the first time. The long
waiting period between the introduction seems to be typical for GTK#.
VirtualMethod.cs is already part of 2.12, it is GObjectVM.cs that does what you need. However, the initial commit for this class also dates back to April 2009.

But it's true that we have a problem with all the code that languishes unreleased in SVN. There are already numerous forks of the generator, one for GLib (Gstreamer bindings) and probably a dozen other workarounds that I'm not aware of.

There have been substantial improvements especially in GLib and the generator, and of course gio bindings are now included in trunk, too.
You could say that it was GTK# that costed Banshee the position as
default media player in Ubuntu: GTK# still won't included GIO# in the
next release -- it was a requirement back then -- but most importantly
the a11y support wasn't available with the GTK# of that time. Although
it was mostly written, it wasn't released and if I read the Banshee
./configure output correctly it only will be in GTK# 2.12.10. The
other issues on the list were fixed by the Banshee developers.
Gtk# 2.12.10 plans were buried some 6 months ago. It was planned to include GAPI from trunk along with a few extension methods for GLib 2.x needed by GAPI3.
It is a shame that so many features are available, needed, but not
shipped. F-Spot started to included GIO# in their source because it
still isn't provided by GTK#. Banshee has taken a few things away from
the GTK# library as well. This is not how shared libraries should
work, the whole idea behind a shared library is that the library is
provided separately from the application, not spread across different
applications.

It would be good for GTK# and the image of Mono applications on the
GNOME desktop if GTK# wouldn't be maintained as conservatively as it
is now. Maybe it should become a part of the GNOME project and move to
gnome.org, I don't know. What I do know that it is getting
increasingly harder for Mono applications to maintain their position
on the desktop. It could be that everything is fixed with the GTK# 3.0
release, but in time there will be a GTK# 4.0 release as well. Will
GTK# development for the 3.x tree die out then as well? I hope not,
because applications like Banshee, Gbrainy and Tomboy surely add
something to the desktop and they would be missed.
The basic problem in my opinion is that we were targetting Gtk 3.0 way too early in trunk and I seriously doubt whether there will actually be a release in September. Thus, 2.12 is in a seperate branch and cut off from development. That was fine as long as nobody seemed to care about the improvements in trunk for some time, but then there were GStreamer, F-Spot(GIO#) and numerous others who now all borrowed parts from trunk.

I think that the time has come to do something and release parts of trunk. A few possible alternatives that came to my mind: - Why not simply release Gtk# 3 from trunk as it is now with the obsolete API removed? The Gtk+ team makes it pretty clear that version 3 is a maintenance release with no old, non-deprecated API going to be removed. So we would have a Gtk# 3 that uses Gtk+ 2.20 under the hood and requires .net 2. No adjustments have to be made, though the version name might be misleading and imply that we are binding Gtk+ 3. Once the release has been made on the Gtk+ side, all we have to do is recompile our binding in order to no depend on the old version 2 binaries no longer and include the new features of Gtk+ 3.

- Release GAPI3 now, but with the glue fallback option set to avoid GLib 3 and MS .net 2 dependencies.

-  Include Gio# into Gtk# 2.12.10.

Any comments or suggestions?

- Christian
[1] https://launchpad.net/indicator-application
[2] 
https://blueprints.launchpad.net/ubuntu/+spec/desktop-karmic-default-media-player-choice
[3] https://wiki.ubuntu.com/DesktopTeam/Specs/Karmic/DefaultMediaPlayerChoice

Regards,

// This file was generated by the Gtk# code generator.
// Any changes made will be lost if regenerated.

namespace Gtk {

	using System;
	using System.Collections;
	using System.Runtime.InteropServices;

#region Autogenerated code
	public partial class CellRenderer : Gtk.Object {

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

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

		[GLib.Property ("mode")]
		public Gtk.CellRendererMode Mode {
			get {
				GLib.Value val = GetProperty ("mode");
				Gtk.CellRendererMode ret = (Gtk.CellRendererMode) (Enum) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value((Enum) value);
				SetProperty("mode", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("cell-background")]
		public string CellBackground {
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("cell-background", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("is-expanded")]
		public bool IsExpanded {
			get {
				GLib.Value val = GetProperty ("is-expanded");
				bool ret = (bool) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("is-expanded", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("xpad")]
		public uint Xpad {
			get {
				GLib.Value val = GetProperty ("xpad");
				uint ret = (uint) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("xpad", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("ypad")]
		public uint Ypad {
			get {
				GLib.Value val = GetProperty ("ypad");
				uint ret = (uint) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("ypad", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("editing")]
		public bool Editing {
			get {
				GLib.Value val = GetProperty ("editing");
				bool ret = (bool) val;
				val.Dispose ();
				return ret;
			}
		}

		[GLib.Property ("is-expander")]
		public bool IsExpander {
			get {
				GLib.Value val = GetProperty ("is-expander");
				bool ret = (bool) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("is-expander", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("yalign")]
		public float Yalign {
			get {
				GLib.Value val = GetProperty ("yalign");
				float ret = (float) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("yalign", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("cell-background-gdk")]
		public Gdk.Color CellBackgroundGdk {
			get {
				GLib.Value val = GetProperty ("cell-background-gdk");
				Gdk.Color ret = (Gdk.Color) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = (GLib.Value) value;
				SetProperty("cell-background-gdk", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("width")]
		public int Width {
			get {
				GLib.Value val = GetProperty ("width");
				int ret = (int) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("width", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("xalign")]
		public float Xalign {
			get {
				GLib.Value val = GetProperty ("xalign");
				float ret = (float) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("xalign", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("sensitive")]
		public bool Sensitive {
			get {
				GLib.Value val = GetProperty ("sensitive");
				bool ret = (bool) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("sensitive", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("visible")]
		public bool Visible {
			get {
				GLib.Value val = GetProperty ("visible");
				bool ret = (bool) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("visible", val);
				val.Dispose ();
			}
		}

		[GLib.Property ("height")]
		public int Height {
			get {
				GLib.Value val = GetProperty ("height");
				int ret = (int) val;
				val.Dispose ();
				return ret;
			}
			set {
				GLib.Value val = new GLib.Value(value);
				SetProperty("height", val);
				val.Dispose ();
			}
		}

		[GLib.Signal("editing-started")]
		public event Gtk.EditingStartedHandler EditingStarted {
			add {
				GLib.Signal sig = GLib.Signal.Lookup (this, "editing-started", typeof (Gtk.EditingStartedArgs));
				sig.AddDelegate (value);
			}
			remove {
				GLib.Signal sig = GLib.Signal.Lookup (this, "editing-started", typeof (Gtk.EditingStartedArgs));
				sig.RemoveDelegate (value);
			}
		}

		[GLib.Signal("editing-canceled")]
		public event System.EventHandler EditingCanceled {
			add {
				GLib.Signal sig = GLib.Signal.Lookup (this, "editing-canceled");
				sig.AddDelegate (value);
			}
			remove {
				GLib.Signal sig = GLib.Signal.Lookup (this, "editing-canceled");
				sig.RemoveDelegate (value);
			}
		}

		static RenderNativeDelegate Render_cb_delegate;
		static RenderNativeDelegate RenderVMCallback {
			get {
				if (Render_cb_delegate == null)
					Render_cb_delegate = new RenderNativeDelegate (Render_cb);
				return Render_cb_delegate;
			}
		}

		static void OverrideRender (GLib.GType gtype)
		{
			OverrideRender (gtype, RenderVMCallback);
		}

		static void OverrideRender (GLib.GType gtype, RenderNativeDelegate callback)
		{
			GtkCellRendererClass class_iface = GetClassStruct (gtype, false);
			class_iface.Render = callback;
			OverrideClassStruct (gtype, class_iface);
		}

		[UnmanagedFunctionPointer (GLib.Global.CallingConvention)]
		delegate void RenderNativeDelegate (IntPtr inst, IntPtr window, IntPtr widget, IntPtr background_area, IntPtr cell_area, IntPtr expose_area, int flags);

		static void Render_cb (IntPtr inst, IntPtr window, IntPtr widget, IntPtr background_area, IntPtr cell_area, IntPtr expose_area, int flags)
		{
			try {
				CellRenderer __obj = GLib.Object.GetObject (inst, false) as CellRenderer;
				__obj.OnRender (GLib.Object.GetObject(window) as Gdk.Drawable, GLib.Object.GetObject(widget) as Gtk.Widget, Gdk.Rectangle.New (background_area), Gdk.Rectangle.New (cell_area), Gdk.Rectangle.New (expose_area), (Gtk.CellRendererState) flags);
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideRender")]
		protected virtual void OnRender (Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
		{
			InternalRender (window, widget, background_area, cell_area, expose_area, flags);
		}

		private void InternalRender (Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
		{
			RenderNativeDelegate unmanaged = GetClassStruct (this.LookupGType ().GetThresholdType (), true).Render;
			if (unmanaged == null) return;

			IntPtr native_background_area = GLib.Marshaller.StructureToPtrAlloc (background_area);
			IntPtr native_cell_area = GLib.Marshaller.StructureToPtrAlloc (cell_area);
			IntPtr native_expose_area = GLib.Marshaller.StructureToPtrAlloc (expose_area);
			unmanaged (this.Handle, window == null ? IntPtr.Zero : window.Handle, widget == null ? IntPtr.Zero : widget.Handle, native_background_area, native_cell_area, native_expose_area, (int) flags);
			background_area = Gdk.Rectangle.New (native_background_area);
			Marshal.FreeHGlobal (native_background_area);
			cell_area = Gdk.Rectangle.New (native_cell_area);
			Marshal.FreeHGlobal (native_cell_area);
			expose_area = Gdk.Rectangle.New (native_expose_area);
			Marshal.FreeHGlobal (native_expose_area);
		}

		static ActivateNativeDelegate Activate_cb_delegate;
		static ActivateNativeDelegate ActivateVMCallback {
			get {
				if (Activate_cb_delegate == null)
					Activate_cb_delegate = new ActivateNativeDelegate (Activate_cb);
				return Activate_cb_delegate;
			}
		}

		static void OverrideActivate (GLib.GType gtype)
		{
			OverrideActivate (gtype, ActivateVMCallback);
		}

		static void OverrideActivate (GLib.GType gtype, ActivateNativeDelegate callback)
		{
			GtkCellRendererClass class_iface = GetClassStruct (gtype, false);
			class_iface.Activate = callback;
			OverrideClassStruct (gtype, class_iface);
		}

		[UnmanagedFunctionPointer (GLib.Global.CallingConvention)]
		delegate bool ActivateNativeDelegate (IntPtr inst, IntPtr evnt, IntPtr widget, IntPtr path, IntPtr background_area, IntPtr cell_area, int flags);

		static bool Activate_cb (IntPtr inst, IntPtr evnt, IntPtr widget, IntPtr path, IntPtr background_area, IntPtr cell_area, int flags)
		{
			try {
				CellRenderer __obj = GLib.Object.GetObject (inst, false) as CellRenderer;
				bool __result = __obj.OnActivate (Gdk.Event.GetEvent (evnt), GLib.Object.GetObject(widget) as Gtk.Widget, GLib.Marshaller.Utf8PtrToString (path), Gdk.Rectangle.New (background_area), Gdk.Rectangle.New (cell_area), (Gtk.CellRendererState) flags);
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideActivate")]
		protected virtual bool OnActivate (Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags)
		{
			return InternalActivate (evnt, widget, path, background_area, cell_area, flags);
		}

		private bool InternalActivate (Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags)
		{
			ActivateNativeDelegate unmanaged = GetClassStruct (this.LookupGType ().GetThresholdType (), true).Activate;
			if (unmanaged == null) return false;

			IntPtr native_path = GLib.Marshaller.StringToPtrGStrdup (path);
			IntPtr native_background_area = GLib.Marshaller.StructureToPtrAlloc (background_area);
			IntPtr native_cell_area = GLib.Marshaller.StructureToPtrAlloc (cell_area);
			bool __result = unmanaged (this.Handle, evnt.Handle, widget == null ? IntPtr.Zero : widget.Handle, native_path, native_background_area, native_cell_area, (int) flags);
			GLib.Marshaller.Free (native_path);
			background_area = Gdk.Rectangle.New (native_background_area);
			Marshal.FreeHGlobal (native_background_area);
			cell_area = Gdk.Rectangle.New (native_cell_area);
			Marshal.FreeHGlobal (native_cell_area);
			return __result;
		}

		static StartEditingNativeDelegate StartEditing_cb_delegate;
		static StartEditingNativeDelegate StartEditingVMCallback {
			get {
				if (StartEditing_cb_delegate == null)
					StartEditing_cb_delegate = new StartEditingNativeDelegate (StartEditing_cb);
				return StartEditing_cb_delegate;
			}
		}

		static void OverrideStartEditing (GLib.GType gtype)
		{
			OverrideStartEditing (gtype, StartEditingVMCallback);
		}

		static void OverrideStartEditing (GLib.GType gtype, StartEditingNativeDelegate callback)
		{
			GtkCellRendererClass class_iface = GetClassStruct (gtype, false);
			class_iface.StartEditing = callback;
			OverrideClassStruct (gtype, class_iface);
		}

		[UnmanagedFunctionPointer (GLib.Global.CallingConvention)]
		delegate IntPtr StartEditingNativeDelegate (IntPtr inst, IntPtr evnt, IntPtr widget, IntPtr path, IntPtr background_area, IntPtr cell_area, int flags);

		static IntPtr StartEditing_cb (IntPtr inst, IntPtr evnt, IntPtr widget, IntPtr path, IntPtr background_area, IntPtr cell_area, int flags)
		{
			try {
				CellRenderer __obj = GLib.Object.GetObject (inst, false) as CellRenderer;
				Gtk.CellEditable __result = __obj.OnStartEditing (Gdk.Event.GetEvent (evnt), GLib.Object.GetObject(widget) as Gtk.Widget, GLib.Marshaller.Utf8PtrToString (path), Gdk.Rectangle.New (background_area), Gdk.Rectangle.New (cell_area), (Gtk.CellRendererState) flags);
				return __result == null ? IntPtr.Zero : ((__result is GLib.Object) ? (__result as GLib.Object).Handle : (__result as Gtk.CellEditableAdapter).Handle);
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideStartEditing")]
		protected virtual Gtk.CellEditable OnStartEditing (Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags)
		{
			return InternalStartEditing (evnt, widget, path, background_area, cell_area, flags);
		}

		private Gtk.CellEditable InternalStartEditing (Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags)
		{
			StartEditingNativeDelegate unmanaged = GetClassStruct (this.LookupGType ().GetThresholdType (), true).StartEditing;
			if (unmanaged == null) return null;

			IntPtr native_path = GLib.Marshaller.StringToPtrGStrdup (path);
			IntPtr native_background_area = GLib.Marshaller.StructureToPtrAlloc (background_area);
			IntPtr native_cell_area = GLib.Marshaller.StructureToPtrAlloc (cell_area);
			IntPtr __result = unmanaged (this.Handle, evnt.Handle, widget == null ? IntPtr.Zero : widget.Handle, native_path, native_background_area, native_cell_area, (int) flags);
			GLib.Marshaller.Free (native_path);
			background_area = Gdk.Rectangle.New (native_background_area);
			Marshal.FreeHGlobal (native_background_area);
			cell_area = Gdk.Rectangle.New (native_cell_area);
			Marshal.FreeHGlobal (native_cell_area);
			return Gtk.CellEditableAdapter.GetObject (__result, false);
		}

		static EditingCanceledNativeDelegate EditingCanceled_cb_delegate;
		static EditingCanceledNativeDelegate EditingCanceledVMCallback {
			get {
				if (EditingCanceled_cb_delegate == null)
					EditingCanceled_cb_delegate = new EditingCanceledNativeDelegate (EditingCanceled_cb);
				return EditingCanceled_cb_delegate;
			}
		}

		static void OverrideEditingCanceled (GLib.GType gtype)
		{
			OverrideEditingCanceled (gtype, EditingCanceledVMCallback);
		}

		static void OverrideEditingCanceled (GLib.GType gtype, EditingCanceledNativeDelegate callback)
		{
			GtkCellRendererClass class_iface = GetClassStruct (gtype, false);
			class_iface.EditingCanceled = callback;
			OverrideClassStruct (gtype, class_iface);
		}

		[UnmanagedFunctionPointer (GLib.Global.CallingConvention)]
		delegate void EditingCanceledNativeDelegate (IntPtr inst);

		static void EditingCanceled_cb (IntPtr inst)
		{
			try {
				CellRenderer __obj = GLib.Object.GetObject (inst, false) as CellRenderer;
				__obj.OnEditingCanceled ();
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideEditingCanceled")]
		protected virtual void OnEditingCanceled ()
		{
			InternalEditingCanceled ();
		}

		private void InternalEditingCanceled ()
		{
			EditingCanceledNativeDelegate unmanaged = GetClassStruct (this.LookupGType ().GetThresholdType (), true).EditingCanceled;
			if (unmanaged == null) return;

			unmanaged (this.Handle);
		}

		static EditingStartedNativeDelegate EditingStarted_cb_delegate;
		static EditingStartedNativeDelegate EditingStartedVMCallback {
			get {
				if (EditingStarted_cb_delegate == null)
					EditingStarted_cb_delegate = new EditingStartedNativeDelegate (EditingStarted_cb);
				return EditingStarted_cb_delegate;
			}
		}

		static void OverrideEditingStarted (GLib.GType gtype)
		{
			OverrideEditingStarted (gtype, EditingStartedVMCallback);
		}

		static void OverrideEditingStarted (GLib.GType gtype, EditingStartedNativeDelegate callback)
		{
			GtkCellRendererClass class_iface = GetClassStruct (gtype, false);
			class_iface.EditingStarted = callback;
			OverrideClassStruct (gtype, class_iface);
		}

		[UnmanagedFunctionPointer (GLib.Global.CallingConvention)]
		delegate void EditingStartedNativeDelegate (IntPtr inst, IntPtr editable, IntPtr path);

		static void EditingStarted_cb (IntPtr inst, IntPtr editable, IntPtr path)
		{
			try {
				CellRenderer __obj = GLib.Object.GetObject (inst, false) as CellRenderer;
				__obj.OnEditingStarted (Gtk.CellEditableAdapter.GetObject (editable, false), GLib.Marshaller.Utf8PtrToString (path));
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideEditingStarted")]
		protected virtual void OnEditingStarted (Gtk.CellEditable editable, string path)
		{
			InternalEditingStarted (editable, path);
		}

		private void InternalEditingStarted (Gtk.CellEditable editable, string path)
		{
			EditingStartedNativeDelegate unmanaged = GetClassStruct (this.LookupGType ().GetThresholdType (), true).EditingStarted;
			if (unmanaged == null) return;

			IntPtr native_path = GLib.Marshaller.StringToPtrGStrdup (path);
			unmanaged (this.Handle, editable == null ? IntPtr.Zero : ((editable is GLib.Object) ? (editable as GLib.Object).Handle : (editable as Gtk.CellEditableAdapter).Handle), native_path);
			GLib.Marshaller.Free (native_path);
		}

		[StructLayout (LayoutKind.Sequential)]
		struct GtkCellRendererClass {
			IntPtr GetSize;
			public RenderNativeDelegate Render;
			public ActivateNativeDelegate Activate;
			public StartEditingNativeDelegate StartEditing;
			public EditingCanceledNativeDelegate EditingCanceled;
			public EditingStartedNativeDelegate EditingStarted;
			IntPtr GtkReserved1;
			IntPtr GtkReserved2;
		}

		static uint class_offset = ((GLib.GType) typeof (Gtk.Object)).GetClassSize ();
		static Hashtable class_structs;

		static GtkCellRendererClass GetClassStruct (GLib.GType gtype, bool use_cache)
		{
			if (class_structs == null)
				class_structs = new Hashtable ();

			if (use_cache && class_structs.Contains (gtype))
				return (GtkCellRendererClass) class_structs [gtype];
			else {
				IntPtr class_ptr = new IntPtr (gtype.GetClassPtr ().ToInt64 () + class_offset);
				GtkCellRendererClass class_struct = (GtkCellRendererClass) Marshal.PtrToStructure (class_ptr, typeof (GtkCellRendererClass));
				if (use_cache)
					class_structs.Add (gtype, class_struct);
				return class_struct;
			}
		}

		static void OverrideClassStruct (GLib.GType gtype, GtkCellRendererClass class_struct)
		{
			IntPtr class_ptr = new IntPtr (gtype.GetClassPtr ().ToInt64 () + class_offset);
			Marshal.StructureToPtr (class_struct, class_ptr, false);
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern void gtk_cell_renderer_editing_canceled(IntPtr raw);

		[Obsolete]
		public void CancelEditing() {
			gtk_cell_renderer_editing_canceled(Handle);
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern IntPtr gtk_cell_renderer_get_type();

		public static new GLib.GType GType { 
			get {
				IntPtr raw_ret = gtk_cell_renderer_get_type();
				GLib.GType ret = new GLib.GType(raw_ret);
				return ret;
			}
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern bool gtk_cell_renderer_activate(IntPtr raw, IntPtr evnt, IntPtr widget, IntPtr path, IntPtr background_area, IntPtr cell_area, int flags);

		public bool Activate(Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags) {
			IntPtr native_path = GLib.Marshaller.StringToPtrGStrdup (path);
			IntPtr native_background_area = GLib.Marshaller.StructureToPtrAlloc (background_area);
			IntPtr native_cell_area = GLib.Marshaller.StructureToPtrAlloc (cell_area);
			bool raw_ret = gtk_cell_renderer_activate(Handle, evnt.Handle, widget == null ? IntPtr.Zero : widget.Handle, native_path, native_background_area, native_cell_area, (int) flags);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_path);
			background_area = Gdk.Rectangle.New (native_background_area);
			Marshal.FreeHGlobal (native_background_area);
			cell_area = Gdk.Rectangle.New (native_cell_area);
			Marshal.FreeHGlobal (native_cell_area);
			return ret;
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern void gtk_cell_renderer_stop_editing(IntPtr raw, bool canceled);

		public void StopEditing(bool canceled) {
			gtk_cell_renderer_stop_editing(Handle, canceled);
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern void gtk_cell_renderer_render(IntPtr raw, IntPtr window, IntPtr widget, IntPtr background_area, IntPtr cell_area, IntPtr expose_area, int flags);

		public void Render(Gdk.Window window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags) {
			IntPtr native_background_area = GLib.Marshaller.StructureToPtrAlloc (background_area);
			IntPtr native_cell_area = GLib.Marshaller.StructureToPtrAlloc (cell_area);
			IntPtr native_expose_area = GLib.Marshaller.StructureToPtrAlloc (expose_area);
			gtk_cell_renderer_render(Handle, window == null ? IntPtr.Zero : window.Handle, widget == null ? IntPtr.Zero : widget.Handle, native_background_area, native_cell_area, native_expose_area, (int) flags);
			background_area = Gdk.Rectangle.New (native_background_area);
			Marshal.FreeHGlobal (native_background_area);
			cell_area = Gdk.Rectangle.New (native_cell_area);
			Marshal.FreeHGlobal (native_cell_area);
			expose_area = Gdk.Rectangle.New (native_expose_area);
			Marshal.FreeHGlobal (native_expose_area);
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern void gtk_cell_renderer_get_fixed_size(IntPtr raw, out int width, out int height);

		public void GetFixedSize(out int width, out int height) {
			gtk_cell_renderer_get_fixed_size(Handle, out width, out height);
		}

		[DllImport("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern void gtk_cell_renderer_set_fixed_size(IntPtr raw, int width, int height);

		public void SetFixedSize(int width, int height) {
			gtk_cell_renderer_set_fixed_size(Handle, width, height);
		}

#endregion
#region Customized extensions
#line 1 "CellRenderer.custom"
//
// CellRenderer.custom - Gtk CellRenderer class customizations
//
// Author: Todd Berman <[email protected]>,
//         Peter Johanson <[email protected]>
//
// Copyright (C) 2004 Todd Berman
// Copyright (C) 2007 Peter Johanson
//
// This code is inserted after the automatically generated code.
//
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the Lesser GNU General 
// Public License as published by the Free Software Foundation.
//
// This program 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.

		[DllImport ("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern IntPtr gtk_cell_renderer_start_editing (IntPtr handle, IntPtr evnt, IntPtr widget, IntPtr path, ref Gdk.Rectangle bg_area, ref Gdk.Rectangle cell_area, int flags);

		public CellEditable StartEditing (Widget widget, Gdk.Event evnt, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, CellRendererState flags)
		{
			IntPtr native = GLib.Marshaller.StringToPtrGStrdup (path);
			IntPtr raw_ret = gtk_cell_renderer_start_editing (Handle, evnt.Handle, widget.Handle, native, ref background_area, ref cell_area, (int) flags);
			GLib.Marshaller.Free (native);
			Gtk.CellEditable ret = (Gtk.CellEditable) GLib.Object.GetObject(raw_ret);
			return ret;
		}

		[DllImport ("libgtk-win32-2.0-0.dll", CallingConvention = GLib.Global.CallingConvention)]
		static extern void gtk_cell_renderer_render (IntPtr handle, IntPtr drawable, IntPtr widget, ref Gdk.Rectangle bg_area, ref Gdk.Rectangle cell_area, ref Gdk.Rectangle expose_area, int flags);
		
		public void Render (Widget widget, Gdk.Drawable window, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags)
		{
			gtk_cell_renderer_render (Handle, window == null ? IntPtr.Zero : window.Handle, widget == null ? IntPtr.Zero : widget.Handle, ref background_area, ref cell_area, ref expose_area, (int) flags);
		}

		// We have to implement this VM manually because x_offset, y_offset, width and height params may be NULL and therefore cannot be treated as "out int"
		// TODO: Implement "nullable" attribute for value type parameters in GAPI
		[UnmanagedFunctionPointer (GLib.Global.CallingConvention)]
		delegate void OnGetSizeDelegate (IntPtr item, IntPtr widget, IntPtr cell_area_ptr, IntPtr x_offset, IntPtr y_offset, IntPtr width, IntPtr height);
                
		static void OnGetSize_cb (IntPtr item, IntPtr widget, IntPtr cell_area_ptr, IntPtr x_offset, IntPtr y_offset, IntPtr width, IntPtr height)
		{
			try {
				CellRenderer obj = GLib.Object.GetObject (item, false) as CellRenderer;
				Gtk.Widget widg = GLib.Object.GetObject (widget, false) as Gtk.Widget;
				Gdk.Rectangle cell_area = Gdk.Rectangle.New (cell_area_ptr);
				int a, b, c, d;

				obj.OnGetSize (widg, ref cell_area, out a, out b, out c, out d);
				if (x_offset != IntPtr.Zero)
					Marshal.WriteInt32 (x_offset, a);
				if (y_offset != IntPtr.Zero)
					Marshal.WriteInt32 (y_offset, b);
				if (width != IntPtr.Zero)
					Marshal.WriteInt32 (width, c);
				if (height != IntPtr.Zero)
					Marshal.WriteInt32 (height, d);
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[DllImport("gtksharpglue-3")]
		static extern void gtksharp_cellrenderer_override_get_size (IntPtr gtype, OnGetSizeDelegate cb);

		static OnGetSizeDelegate OnGetSizeCallback;
		static void OverrideOnGetSize (GLib.GType gtype)
		{
			if (OnGetSizeCallback == null)
				OnGetSizeCallback = new OnGetSizeDelegate (OnGetSize_cb);
			gtksharp_cellrenderer_override_get_size (gtype.Val, OnGetSizeCallback);
		}
               
		[GLib.DefaultSignalHandler (Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideOnGetSize")] 
		protected virtual void OnGetSize (Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height) 
		{
			InternalOnGetSize (widget, ref cell_area, out x_offset, out y_offset, out width, out height);
		}

		[DllImport("gtksharpglue-3")]
		static extern void gtksharp_cellrenderer_base_get_size (IntPtr cell, IntPtr widget, IntPtr cell_area, out int x_offset, out int y_offset, out int width, out int height);

		private void InternalOnGetSize (Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height) 
		{
			IntPtr native_cell_area = GLib.Marshaller.StructureToPtrAlloc (cell_area);
			gtksharp_cellrenderer_base_get_size (Handle, widget == null ? IntPtr.Zero : widget.Handle, native_cell_area, out x_offset, out y_offset, out width, out height);
			cell_area = Gdk.Rectangle.New (native_cell_area);
			Marshal.FreeHGlobal (native_cell_area);
		}

		// Compatibility code for old GetSize(..) virtual method
		static void ObsoleteGetSize_cb (IntPtr item, IntPtr widget, IntPtr cell_area_ptr, IntPtr x_offset, IntPtr y_offset, IntPtr width, IntPtr height)
		{
			try {
				CellRenderer obj = GLib.Object.GetObject (item, false) as CellRenderer;
				Gtk.Widget widg = GLib.Object.GetObject (widget, false) as Gtk.Widget;
				Gdk.Rectangle cell_area = Gdk.Rectangle.New (cell_area_ptr);
				int a, b, c, d;

				obj.GetSize (widg, ref cell_area, out a, out b, out c, out d);
				if (x_offset != IntPtr.Zero)
					Marshal.WriteInt32 (x_offset, a);
				if (y_offset != IntPtr.Zero)
					Marshal.WriteInt32 (y_offset, b);
				if (width != IntPtr.Zero)
					Marshal.WriteInt32 (width, c);
				if (height != IntPtr.Zero)
					Marshal.WriteInt32 (height, d);
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		static void OverrideObsoleteGetSize (GLib.GType gtype)
		{
			if (OnGetSizeCallback == null)
				OnGetSizeCallback = new OnGetSizeDelegate (ObsoleteGetSize_cb);
			gtksharp_cellrenderer_override_get_size (gtype.Val, OnGetSizeCallback);
		}

		[Obsolete ("Replaced by OnGetSize for implementations and GetSize(..., out Gdk.Rectangle bounds) for callers.")]
		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideObsoleteGetSize")]
		public virtual void GetSize(Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height) 
		{
			InternalOnGetSize (widget, ref cell_area, out x_offset, out y_offset, out width, out height);
		}

		// Compatibility code for old Render(..) virtual method
		static void ObsoleteRender_cb (IntPtr cell, IntPtr window, IntPtr widget, IntPtr background_area, IntPtr cell_area, IntPtr expose_area, int flags)
		{
			try {
				Gtk.CellRenderer __obj = GLib.Object.GetObject (cell, false) as Gtk.CellRenderer;
				__obj.Render (GLib.Object.GetObject(window) as Gdk.Drawable, GLib.Object.GetObject(widget) as Gtk.Widget, Gdk.Rectangle.New (background_area), Gdk.Rectangle.New (cell_area), Gdk.Rectangle.New (expose_area), (Gtk.CellRendererState) flags);
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		static RenderNativeDelegate ObsoleteRenderVMCallback;
		static void OverrideObsoleteRender (GLib.GType gtype)
		{
			if (ObsoleteRenderVMCallback == null)
				ObsoleteRenderVMCallback = new RenderNativeDelegate (ObsoleteRender_cb);
			OverrideRender (gtype, ObsoleteRenderVMCallback); // -> autogenerated method
		}

		[Obsolete ("Replaced by OnRender for subclass overrides and Render (Widget ...) for callers.")]
		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideObsoleteRender")]
		protected virtual void Render (Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
		{
			InternalRender (window, widget, background_area, cell_area, expose_area, flags);
		}

		// Compatibility code for old StartEditing(..) virtual method
		static IntPtr ObsoleteStartEditing_cb (IntPtr cell, IntPtr evnt, IntPtr widget, IntPtr path, IntPtr background_area, IntPtr cell_area, int flags)
		{
			try {
				Gtk.CellRenderer __obj = GLib.Object.GetObject (cell, false) as Gtk.CellRenderer;
				Gtk.CellEditable __result = __obj.StartEditing (Gdk.Event.GetEvent (evnt), GLib.Object.GetObject(widget) as Gtk.Widget, GLib.Marshaller.Utf8PtrToString (path), Gdk.Rectangle.New (background_area), Gdk.Rectangle.New (cell_area), (Gtk.CellRendererState) flags);
				return __result == null ? IntPtr.Zero : __result.Handle;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		static StartEditingNativeDelegate ObsoleteStartEditingVMCallback;
		static void OverrideObsoleteStartEditing (GLib.GType gtype)
		{
			if (ObsoleteStartEditingVMCallback == null)
				ObsoleteStartEditingVMCallback = new StartEditingNativeDelegate (ObsoleteStartEditing_cb);
			OverrideStartEditing (gtype, ObsoleteStartEditingVMCallback);
		}

		[Obsolete ("Replaced by OnStartEditing for subclass overrides and StartEditing (Gtk.Widget ...) for callers.")]
		[GLib.DefaultSignalHandler(Type=typeof(Gtk.CellRenderer), ConnectionMethod="OverrideObsoleteStartEditing")]
		public virtual Gtk.CellEditable StartEditing(Gdk.Event evnt, Gtk.Widget widget, string path, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gtk.CellRendererState flags) {
			return InternalStartEditing (evnt, widget, path, background_area, cell_area, flags);
		}

#endregion
	}
}
_______________________________________________
Gtk-sharp-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list

Reply via email to