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:
parent
39739ae746
commit
e886e07a1f
3 changed files with 138 additions and 143 deletions
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue