2003-03-11 Miguel de Icaza <miguel@ximian.com>

* gtk/Application.cs (CurrentEvent): Property implementing the
	suggestion from Paolo.

	* glib/Object.cs (Dispose): Destructor might be invoked in a
	thread, queue the object for destruction using the Gtk idle
	handler.   We perform the real destruction of the object in the
	same thread as the Gtk+ main thread.

svn path=/trunk/gtk-sharp/; revision=12551
This commit is contained in:
Miguel de Icaza 2003-03-15 20:49:37 +00:00
parent 94f05965a8
commit 1c5b25f9a1
3 changed files with 142 additions and 14 deletions

View File

@ -1,3 +1,13 @@
2003-03-11 Miguel de Icaza <miguel@ximian.com>
* gtk/Application.cs (CurrentEvent): Property implementing the
suggestion from Paolo.
* glib/Object.cs (Dispose): Destructor might be invoked in a
thread, queue the object for destruction using the Gtk idle
handler. We perform the real destruction of the object in the
same thread as the Gtk+ main thread.
2003-03-14 Charles Iliya Krempeaux <charles@reptile.ca>
* sources/makefile : Added a "distclean" rule, so
@ -37,6 +47,8 @@
(InitCheck): new method, wraps gtk_init_check.
Removed inline docs from here. Put them on the documen
2003-03-08 Miguel de Icaza <miguel@ximian.com>
* glib/Idle.cs: Add private constructor.

View File

@ -4,7 +4,10 @@
// Mike Kestner <mkestner@speakeasy.net>
//
// (c) 2001 Bob Smith and Mike Kestner
//
// TODO:
// Could remove `disposed' for a check if an object is on the dispose_queue_list.
//
namespace GLib {
using System;
@ -36,12 +39,40 @@ namespace GLib {
bool disposed = false;
Hashtable Data;
static Hashtable Objects = new Hashtable();
static Queue PendingDestroys = new Queue ();
static bool idle_queued;
//
// The destructor is invoked by a thread
//
~Object ()
{
Dispose ();
}
static bool PerformQueuedUnrefs ()
{
Object [] objects;
lock (PendingDestroys){
objects = new Object [PendingDestroys.Count];
PendingDestroys.CopyTo (objects, 0);
PendingDestroys.Clear ();
}
lock (typeof (Object))
idle_queued = false;
foreach (Object o in objects){
if (o._obj == IntPtr.Zero)
continue;
Objects.Remove (o._obj);
o.Unref ();
o._obj = IntPtr.Zero;
}
return false;
}
/// <summary>
/// Dispose Method
/// </summary>
@ -57,25 +88,22 @@ namespace GLib {
if (disposed)
return;
DisposeNative ();
disposed = true;
lock (PendingDestroys){
PendingDestroys.Enqueue (this);
lock (typeof (Object)){
if (!idle_queued){
Idle.Add (new IdleHandler (PerformQueuedUnrefs));
idle_queued = true;
}
}
}
GC.SuppressFinalize (this);
}
[DllImport("libgobject-2.0-0.dll")]
static extern void g_object_unref (IntPtr raw);
protected virtual void DisposeNative ()
{
if (_obj == IntPtr.Zero)
return;
Objects.Remove (Raw);
GC.SuppressFinalize (this);
g_object_unref (_obj);
_obj = IntPtr.Zero;
}
[DllImport("libgobject-2.0-0.dll")]
static extern void g_object_ref (IntPtr raw);
@ -104,6 +132,8 @@ namespace GLib {
/// Decreases the reference count on the native object.
/// This method is used by generated classes and structs,
/// and should not be used in user code.
///
/// This method should not be invoked by a thread.
/// </remarks>
public virtual void Unref ()
{

View File

@ -8,6 +8,7 @@ namespace Gtk {
using System;
using System.Runtime.InteropServices;
using Gdk;
public class Application {
@ -87,5 +88,90 @@ namespace Gtk {
[DllImport("libgtk-win32-2.0-0.dll")]
static extern IntPtr gtk_get_current_event ();
public object CurrentEvent {
get {
IntPtr handle = gtk_get_current_event ();
Gdk.EventType type;
type = (Gdk.EventType) Marshal.ReadInt32 (handle);
switch (type){
case EventType.Delete:
case EventType.Destroy:
// Fixme: do not know what this maps to.
break;
case EventType.Expose:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventExpose));
case EventType.MotionNotify:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventMotion));
case EventType.ButtonPress:
case EventType.TwoButtonPress:
case EventType.ThreeButtonPress:
case EventType.ButtonRelease:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventButton));
case EventType.KeyPress:
case EventType.KeyRelease:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventKey));
case EventType.EnterNotify:
case EventType.LeaveNotify:
// FIXME: Do not know what this maps to.
break;
case EventType.FocusChange:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventFocus));
case EventType.Configure:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventConfigure));
case EventType.Map:
case EventType.Unmap:
// FIXME: Do not know what this maps to.
break;
case EventType.PropertyNotify:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventProperty));
case EventType.SelectionClear:
case EventType.SelectionRequest:
case EventType.SelectionNotify:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventSelection));
case EventType.ProximityIn:
case EventType.ProximityOut:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventProximity));
case EventType.DragEnter:
case EventType.DragLeave:
case EventType.DragMotion:
case EventType.DragStatus:
case EventType.DropFinished:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventDND));
case EventType.ClientEvent:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventClient));
case EventType.VisibilityNotify:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventVisibility));
case EventType.NoExpose:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventNoExpose));
case EventType.Scroll:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventScroll));
case EventType.WindowState:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventWindowState));
case EventType.Setting:
return Marshal.PtrToStructure (handle, typeof (Gdk.EventSetting));
}
return null;
}
}
}
}