Hello,

I'm writing an interactive canvas for the MonoUML Case Tool. I'm using
Cairo with Gtk# and I have experimented an ascending memory
consumption when drawings are continuously performed, for example
inside a MotionNotifyEvent Handler. This memory is never released and
eventually SWAP memory is needed making all too slow.

I attach a simple example that illustrate this problem. Cairo draws a
rectangle inside a Gtk.DrawingArea every time that the mouse is moved
over the DrawingArea. Compile it, run it, move the mouse, and see how
memory consumption starts to getting higher and higher over time.

Is anything wrong with my code? or is a bug?

Thanks in advance,

Manuel.

--
· Manuel Alejandro Cerón Estrada
· [EMAIL PROTECTED]
· http://ceronman.blogspot.com
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Cairo;
using Gtk;
	
public class GtkCairo
{
	static DrawingArea a;
	
	static void Main ()
	{		
		Application.Init ();
		Gtk.Window w = new Gtk.Window ("Cairo");

		a = new CairoGraphic ();	
			
		w.Add (a);
		w.Resize (200,200);		
		w.ShowAll ();		
		
		Application.Run ();
	}


}

public class CairoGraphic : DrawingArea 
{
        
        public CairoGraphic()
        {
        	SetSizeRequest (200, 200);
		AddEvents ((int)Gdk.EventMask.AllEventsMask);
        }
   
	static void draw (Cairo.Graphics gr, int width, int height)
	{
		gr.Scale (width, height);
		gr.LineWidth = 0.04;
		gr.Rectangle (0.1,0.1, 0.8, 0.8);
		gr.Stroke ();
	}
	
	protected override bool OnMotionNotifyEvent (Gdk.EventMotion ev)
	{
		int x, y;
				
		//this is necesary for getting the event every time
		Gdk.ModifierType state;
		if (ev.IsHint) {
			ev.Window.GetPointer(out x, out y, out state);
		} 
		QueueDraw();
		return true;
	}
   

	protected override bool OnExposeEvent (Gdk.EventExpose args)
	{
		Gdk.Window win = args.Window;
		Cairo.Graphics g = Graphics.CreateDrawable (win);
		int x, y, w, h, d;
		win.GetGeometry(out x, out y, out w, out h, out d);
		draw (g, w, h);
		return true;
	}

}

public class Graphics
{		
	//Use [DllImport("libgdk-win32-2.0-0.dll")] for  Win32 
	[DllImport("libgdk-x11-2.0.so")]
	  internal static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr raw);
	
	[DllImport("libgdk-x11-2.0.so")]
	  internal static extern IntPtr gdk_x11_drawable_get_xid (IntPtr raw);
	
	[DllImport("libgdk-x11-2.0.so")]
	  internal static extern IntPtr gdk_drawable_get_visual (IntPtr raw);
	
	[DllImport("libgdk-x11-2.0.so")]
	  internal static extern IntPtr gdk_x11_visual_get_xvisual (IntPtr raw);
	
	[DllImport("libgdk-x11-2.0.so")]
	  internal static extern IntPtr gdk_cairo_create (IntPtr raw);
	
        public static Cairo.Graphics CreateDrawable (Gdk.Drawable drawable)
	{
		IntPtr x_drawable = IntPtr.Zero;
		int x_off = 0, y_off = 0;			
		
		int x, y, w, h, d;
		((Gdk.Window)drawable).GetGeometry(out x, out y, out w, out h, out d);
		
		if (drawable is Gdk.Window)
		  ((Gdk.Window) drawable).GetInternalPaintInfo(out drawable, 
							    out x_off, out y_off);
		
		x_drawable = drawable.Handle;			
		IntPtr visual = gdk_drawable_get_visual(x_drawable);
		
		IntPtr Xdisplay = gdk_x11_drawable_get_xdisplay(x_drawable);
		IntPtr Xvisual = gdk_x11_visual_get_xvisual(visual);
		IntPtr Xdrawable = gdk_x11_drawable_get_xid (x_drawable);
		
		Cairo.XlibSurface s = new Cairo.XlibSurface (Xdisplay,
							   Xdrawable,
							   Xvisual,
							   w, h);
		
		Cairo.Graphics g = new Cairo.Graphics (s);
		
		// this can be safely removed now, just keep it for a bit more
		//Cairo.Graphics g = new Cairo.Graphics (
		//                    gdk_cairo_create (x_drawable ));
		
		if (drawable is Gdk.Window)
		  g.Translate (-(double)x_off,-(double)y_off);
		return g;
	}
}

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

Reply via email to