2009-04-27 Christian Hoff <christian_hoff@gmx.net>

* gtk/Widget.custom: Implement signal registration for the
	Activate, SettScrollAdjustments and key binding signals
 	in managed code.

svn path=/trunk/gtk-sharp/; revision=132771
This commit is contained in:
Christian Hoff 2009-04-27 17:55:30 +00:00
parent 39739ae746
commit e886e07a1f
3 changed files with 138 additions and 143 deletions

View file

@ -1,3 +1,9 @@
2009-04-27 Christian Hoff <christian_hoff@gmx.net>
* gtk/Widget.custom: Implement signal registration for the
Activate, SettScrollAdjustments and key binding signals
in managed code.
2009-04-25 Mike Kestner <mkestner@novell.com>
* generator/OpaqueGen.cs: support abstract opaque classes,

View file

@ -178,48 +178,85 @@ public bool IsDrawable {
}
}
[DllImport("gtksharpglue-2")]
static extern int gtksharp_gtk_widget_style_get_int (IntPtr raw, IntPtr name);
public int FocusLineWidth {
get {
IntPtr name = GLib.Marshaller.StringToPtrGStrdup ("focus-line-width");
int result = gtksharp_gtk_widget_style_get_int (Handle, name);
GLib.Marshaller.Free (name);
return result;
return (int) StyleGetProperty ("focus-line-width");
}
}
[DllImport("gtksharpglue-2")]
static extern int gtksharp_widget_connect_set_scroll_adjustments_signal (IntPtr gtype, SetScrollAdjustmentsDelegate cb);
struct GClosure {
long fields;
IntPtr marshaler;
IntPtr data;
IntPtr notifiers;
}
[GLib.CDeclCallback]
delegate void SetScrollAdjustmentsDelegate (IntPtr widget, IntPtr hadj, IntPtr vadj);
delegate void ClosureMarshal (IntPtr closure, IntPtr return_val, uint n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data);
static SetScrollAdjustmentsDelegate SetScrollAdjustmentsCallback;
[DllImport("libgobject-2.0-0.dll")]
static extern IntPtr g_closure_new_simple (int closure_size, IntPtr dummy);
static void SetScrollAdjustments_cb (IntPtr widget, IntPtr hadj, IntPtr vadj)
[DllImport("libgobject-2.0-0.dll")]
static extern void g_closure_set_marshal (IntPtr closure, ClosureMarshal marshaler);
static IntPtr CreateClosure (ClosureMarshal marshaler) {
IntPtr raw_closure = g_closure_new_simple (Marshal.SizeOf (typeof (GClosure)), IntPtr.Zero);
g_closure_set_marshal (raw_closure, marshaler);
return raw_closure;
}
[DllImport("libgobject-2.0-0.dll")]
static extern uint g_signal_newv (IntPtr signal_name, IntPtr gtype, GLib.Signal.Flags signal_flags, IntPtr closure, IntPtr accumulator, IntPtr accu_data, IntPtr c_marshaller, IntPtr return_type, uint n_params, [MarshalAs (UnmanagedType.LPArray)] IntPtr[] param_types);
static uint RegisterSignal (string signal_name, GLib.GType gtype, GLib.Signal.Flags signal_flags, GLib.GType return_type, GLib.GType[] param_types, ClosureMarshal marshaler)
{
IntPtr[] native_param_types = new IntPtr [param_types.Length];
for (int parm_idx = 0; parm_idx < param_types.Length; parm_idx++)
native_param_types [parm_idx] = param_types [parm_idx].Val;
IntPtr native_signal_name = GLib.Marshaller.StringToPtrGStrdup (signal_name);
try {
return g_signal_newv (native_signal_name, gtype.Val, signal_flags, CreateClosure (marshaler), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, return_type.Val, (uint) param_types.Length, native_param_types);
} finally {
GLib.Marshaller.Free (native_signal_name);
}
}
static void SetScrollAdjustmentsMarshal_cb (IntPtr closure, IntPtr return_val, uint n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data)
{
try {
Widget obj;
GLib.Value[] inst_and_params = new GLib.Value [n_param_vals];
int gvalue_size = Marshal.SizeOf (typeof (GLib.Value));
for (int idx = 0; idx < n_param_vals; idx++)
inst_and_params [idx] = (GLib.Value) Marshal.PtrToStructure (new IntPtr (param_values.ToInt64 () + idx * gvalue_size), typeof (GLib.Value));
Widget inst;
try {
obj = GLib.Object.GetObject (widget, false) as Widget;
inst = inst_and_params [0].Val as Widget;
} catch (GLib.MissingIntPtrCtorException) {
return;
}
Gtk.Adjustment h = GLib.Object.GetObject (hadj, false) as Gtk.Adjustment;
Gtk.Adjustment v = GLib.Object.GetObject (vadj, false) as Gtk.Adjustment;
obj.OnSetScrollAdjustments (h, v);
Gtk.Adjustment h = inst_and_params [1].Val as Gtk.Adjustment;
Gtk.Adjustment v = inst_and_params [2].Val as Gtk.Adjustment;
inst.OnSetScrollAdjustments (h, v);
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, false);
}
}
static ClosureMarshal SetScrollAdjustmentsMarshalCallback;
[DllImport("gtksharpglue-2")]
static extern void gtksharp_widget_class_set_set_scroll_adjustments_signal (IntPtr class_struct, uint signal_id);
static void ConnectSetScrollAdjustments (GLib.GType gtype)
{
if (SetScrollAdjustmentsCallback == null)
SetScrollAdjustmentsCallback = new SetScrollAdjustmentsDelegate (SetScrollAdjustments_cb);
gtksharp_widget_connect_set_scroll_adjustments_signal (gtype.Val, SetScrollAdjustmentsCallback);
if (SetScrollAdjustmentsMarshalCallback == null)
SetScrollAdjustmentsMarshalCallback = new ClosureMarshal (SetScrollAdjustmentsMarshal_cb);
uint signal_id = RegisterSignal ("set_scroll_adjustments", gtype, GLib.Signal.Flags.RunLast, GLib.GType.None, new GLib.GType [] {Adjustment.GType, Adjustment.GType}, SetScrollAdjustmentsMarshalCallback);
gtksharp_widget_class_set_set_scroll_adjustments_signal (gtype.ClassPtr, signal_id);
}
[GLib.DefaultSignalHandler (Type=typeof (Gtk.Widget), ConnectionMethod="ConnectSetScrollAdjustments")]
@ -227,34 +264,34 @@ protected virtual void OnSetScrollAdjustments (Gtk.Adjustment hadj, Gtk.Adjustme
{
}
[DllImport("gtksharpglue-2")]
static extern int gtksharp_widget_connect_activate_signal (IntPtr gtype, ActivateDelegate cb);
[GLib.CDeclCallback]
delegate void ActivateDelegate (IntPtr widget);
static ActivateDelegate ActivateCallback;
static void Activate_cb (IntPtr widget)
static void ActivateMarshal_cb (IntPtr raw_closure, IntPtr return_val, uint n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data)
{
try {
Widget obj;
GLib.Value inst_val = (GLib.Value) Marshal.PtrToStructure (param_values, typeof (GLib.Value));
Widget inst;
try {
obj = GLib.Object.GetObject (widget, false) as Widget;
inst = inst_val.Val as Widget;
} catch (GLib.MissingIntPtrCtorException) {
return;
}
obj.OnActivate ();
inst.OnActivate ();
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, false);
}
}
static ClosureMarshal ActivateMarshalCallback;
[DllImport("gtksharpglue-2")]
static extern void gtksharp_widget_class_set_activate_signal (IntPtr class_struct, uint signal_id);
static void ConnectActivate (GLib.GType gtype)
{
if (ActivateCallback == null)
ActivateCallback = new ActivateDelegate (Activate_cb);
gtksharp_widget_connect_activate_signal (gtype.Val, ActivateCallback);
if (ActivateMarshalCallback == null)
ActivateMarshalCallback = new ClosureMarshal (ActivateMarshal_cb);
uint signal_id = RegisterSignal ("activate_signal", gtype, GLib.Signal.Flags.RunLast, GLib.GType.None, new GLib.GType [0], ActivateMarshalCallback);
gtksharp_widget_class_set_activate_signal (gtype.ClassPtr, signal_id);
}
[GLib.DefaultSignalHandler (Type=typeof (Gtk.Widget), ConnectionMethod="ConnectActivate")]
@ -278,55 +315,88 @@ private class BindingInvoker {
}
}
[GLib.CDeclCallback]
private delegate void BindingHandler (IntPtr handle, IntPtr user_data);
/* As gtk_binding_entry_add_signall only allows passing long, double and string parameters to the specified signal, we cannot pass a pointer to the BindingInvoker directly
* to the signal. Instead, the signal takes the index of the BindingInvoker in binding_invokers.
*/
static ArrayList binding_invokers;
private static void BindingCallback (IntPtr handle, IntPtr user_data)
[DllImport("libgobject-2.0-0.dll")]
static extern int g_value_get_long (ref GLib.Value val);
static void BindingMarshal_cb (IntPtr raw_closure, IntPtr return_val, uint n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data)
{
try {
Widget w = GLib.Object.GetObject (handle, false) as Widget;
BindingInvoker invoker = ((GCHandle) user_data).Target as BindingInvoker;
GLib.Value[] inst_and_params = new GLib.Value [n_param_vals];
int gvalue_size = Marshal.SizeOf (typeof (GLib.Value));
for (int idx = 0; idx < n_param_vals; idx++)
inst_and_params [idx] = (GLib.Value) Marshal.PtrToStructure (new IntPtr (param_values.ToInt64 () + idx * gvalue_size), typeof (GLib.Value));
Widget w = inst_and_params [0].Val as Widget;
BindingInvoker invoker = binding_invokers [g_value_get_long (ref inst_and_params [1])] as BindingInvoker;
invoker.Invoke (w);
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, false);
}
}
static BindingHandler binding_delegate;
static BindingHandler BindingDelegate {
static ClosureMarshal binding_delegate;
static ClosureMarshal BindingDelegate {
get {
if (binding_delegate == null)
binding_delegate = new BindingHandler (BindingCallback);
binding_delegate = new ClosureMarshal (BindingMarshal_cb);
return binding_delegate;
}
}
[DllImport ("gtksharpglue-2")]
static extern void gtksharp_widget_add_binding_signal (IntPtr gvalue, IntPtr name, BindingHandler handler);
[DllImport("libgtk-win32-2.0-0.dll")]
static extern IntPtr gtk_binding_set_by_class (IntPtr class_ptr);
[DllImport ("gtksharpglue-2")]
static extern void gtksharp_widget_register_binding (IntPtr gvalue, IntPtr name, uint key, int mod, IntPtr data);
[DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_binding_entry_add_signall (IntPtr binding_set, uint keyval, Gdk.ModifierType modifiers, IntPtr signal_name, IntPtr binding_args);
[StructLayout(LayoutKind.Sequential)]
struct GtkBindingArg {
public IntPtr arg_type;
public GtkBindingArgData data;
}
[StructLayout(LayoutKind.Explicit)]
struct GtkBindingArgData {
#if WIN64LONGS
[FieldOffset (0)] [MarshalAs (UnmanagedType.I4)] public int long_data;
#else
[FieldOffset (0)] [MarshalAs (UnmanagedType.SysInt)] public int long_data;
#endif
[FieldOffset (0)] public double double_data;
[FieldOffset (0)] public IntPtr string_data;
}
static void ClassInit (GLib.GType gtype, Type t)
{
object[] attrs = t.GetCustomAttributes (typeof (BindingAttribute), true);
if (attrs.Length == 0) return;
if (attrs.Length == 0)
return;
string signame = t.Name.Replace (".", "_") + "_bindings";
IntPtr native_signame = GLib.Marshaller.StringToPtrGStrdup (signame);
RegisterSignal (signame, gtype, GLib.Signal.Flags.RunLast | GLib.Signal.Flags.Action, GLib.GType.None, new GLib.GType[] {GLib.GType.Long}, BindingDelegate);
IntPtr signame = GLib.Marshaller.StringToPtrGStrdup (t.Name.Replace (".", "_") + "_bindings");
gtksharp_widget_add_binding_signal (gtype.Val, signame, BindingDelegate);
if (binding_invokers == null)
binding_invokers = new ArrayList ();
foreach (BindingAttribute attr in attrs) {
System.Reflection.MethodInfo mi = t.GetMethod (attr.Handler, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
if (mi == null)
throw new Exception ("Instance method " + attr.Handler + " not found in " + t);
BindingInvoker inv = new BindingInvoker (mi, attr.Parms);
gtksharp_widget_register_binding (gtype.Val, signame, (uint) attr.Key, (int) attr.Mod, (IntPtr) GCHandle.Alloc (inv));
GtkBindingArg arg = new GtkBindingArg ();
arg.arg_type = GLib.GType.Long.Val;
arg.data.long_data = binding_invokers.Add (new BindingInvoker (mi, attr.Parms));
GLib.SList binding_args = new GLib.SList (new object[] {arg}, typeof (GtkBindingArg), false, false);
gtk_binding_entry_add_signall (gtk_binding_set_by_class (gtype.ClassPtr), (uint) attr.Key, attr.Mod, native_signame, binding_args.Handle);
binding_args.Dispose ();
}
GLib.Marshaller.Free (signame);
GLib.Marshaller.Free (native_signame);
}
public object StyleGetProperty (string property_name)

View file

@ -32,14 +32,10 @@ int gtksharp_gtk_widget_get_state (GtkWidget *widget);
int gtksharp_gtk_widget_get_flags (GtkWidget *widget);
void gtksharp_gtk_widget_set_flags (GtkWidget *widget, int flags);
int gtksharp_gtk_widget_style_get_int (GtkWidget *widget, const char *name);
void gtksharp_widget_connect_set_scroll_adjustments_signal (GType gtype, gpointer callback);
void gtksharp_widget_connect_activate_signal (GType gtype, gpointer callback);
void _gtksharp_marshal_VOID__OBJECT_OBJECT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data);
void gtksharp_widget_class_set_set_scroll_adjustments_signal (GtkWidgetClass *klass, guint signal_id);
void gtksharp_widget_class_set_activate_signal (GtkWidgetClass *klass, guint signal_id);
int gtksharp_gtk_widget_get_flags (GtkWidget *widget);
void gtksharp_gtk_widget_set_flags (GtkWidget *widget, int flags);
int gtksharp_gtk_widget_style_get_int (GtkWidget *widget, const char *name);
void gtksharp_widget_add_binding_signal (GType gtype, const char *sig_name, GCallback cb);
void gtksharp_widget_register_binding (GType gtype, const char *sig_name, guint key, int mod, gpointer data);
/* */
GdkRectangle*
@ -80,92 +76,15 @@ gtksharp_gtk_widget_set_flags (GtkWidget *widget, int flags)
GTK_OBJECT(widget)->flags = flags;
}
int
gtksharp_gtk_widget_style_get_int (GtkWidget *widget, const char *name)
void
gtksharp_widget_class_set_set_scroll_adjustments_signal (GtkWidgetClass *klass, guint signal_id)
{
int value;
gtk_widget_style_get (widget, name, &value, NULL);
return value;
}
#include <glib-object.h>
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
void
_gtksharp_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer data2);
register GMarshalFunc_VOID__OBJECT_OBJECT callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
callback (data1,
g_marshal_value_peek_object (param_values + 1),
g_marshal_value_peek_object (param_values + 2),
data2);
klass->set_scroll_adjustments_signal = signal_id;
}
void
gtksharp_widget_connect_set_scroll_adjustments_signal (GType gtype, gpointer cb)
gtksharp_widget_class_set_activate_signal (GtkWidgetClass *klass, guint signal_id)
{
GType parm_types[] = {GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT};
GtkWidgetClass *klass = g_type_class_peek (gtype);
if (!klass)
klass = g_type_class_ref (gtype);
klass->set_scroll_adjustments_signal = g_signal_newv (
"set_scroll_adjustments", gtype, G_SIGNAL_RUN_LAST,
g_cclosure_new (cb, NULL, NULL), NULL, NULL, _gtksharp_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2, parm_types);
klass->activate_signal = signal_id;
}
void
gtksharp_widget_connect_activate_signal (GType gtype, gpointer cb)
{
GtkWidgetClass *klass = g_type_class_peek (gtype);
if (!klass)
klass = g_type_class_ref (gtype);
klass->activate_signal = g_signal_newv (
"activate_signal", gtype, G_SIGNAL_RUN_LAST,
g_cclosure_new (cb, NULL, NULL), NULL, NULL, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, NULL);
}
void
gtksharp_widget_add_binding_signal (GType gtype, const gchar *sig_name, GCallback cb)
{
GType parm_types[] = {G_TYPE_LONG};
g_signal_newv (sig_name, gtype, G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, g_cclosure_new (cb, NULL, NULL), NULL, NULL, g_cclosure_marshal_VOID__LONG, G_TYPE_NONE, 1, parm_types);
}
void
gtksharp_widget_register_binding (GType gtype, const gchar *signame, guint key, int mod, gpointer data)
{
GObjectClass *klass = g_type_class_peek (gtype);
if (klass == NULL)
klass = g_type_class_ref (gtype);
GtkBindingSet *set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (set, key, mod, signame, 1, G_TYPE_LONG, data);
}