/*
This source file is part of Scol
For the latest info, see http://www.scolring.org

Copyright (c) 2010 Stephane Bisaro, aka Iri <iri@irizone.net>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

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, or go to
http://www.gnu.org/copyleft/lesser.txt

For others informations, please contact us from http://www.scolring.org/
*/


#include "../include/scol_gtk_widget.h"

static void scol_gtk_mmachine_set_GdkModifierType (mmachine m, guint mask)
{
    switch (mask)
    {
        case (GDK_SHIFT_MASK) :
            MMpush (m, ITOM (EVENT_KEY_SHIFT));
            break;
        case (GDK_LOCK_MASK) :
            MMpush (m, ITOM (EVENT_KEY_CAPS));
            break;
        case (GDK_CONTROL_MASK) :
            MMpush (m, ITOM (EVENT_KEY_CONTROL));
            break;
        case (GDK_MOD1_MASK) :
            MMpush (m, ITOM (EVENT_KEY_ALT));
            break;
        case (GDK_SUPER_MASK) :
            MMpush (m, ITOM (EVENT_KEY_SUPER));
            break;
        case (GDK_HYPER_MASK) :
            MMpush (m, ITOM (EVENT_KEY_HYPER));
            break;
        default :
            MMpush (m, ITOM (EVENT_KEY_OTHER));
    }
    return;
}

static void scol_gtk_mmachine_set_GdkDevice (mmachine m, GdkEvent *event)
{
    #ifndef SCOL_GTK_2
    Mpushstrbloc (m, (char *) gdk_device_get_name (event->motion.device));
    switch (gdk_device_get_source (event->motion.device))
    {
        case (GDK_SOURCE_MOUSE) :
            MMpush (m, ITOM (DEVICE_MOUSE));
            break;
        case (GDK_SOURCE_PEN) :
            MMpush (m, ITOM (DEVICE_PEN));
            break;
        case (GDK_SOURCE_ERASER) :
            MMpush (m, ITOM (DEVICE_ERASER));
            break;
        case (GDK_SOURCE_CURSOR) :
            MMpush (m, ITOM (DEVICE_CURSOR));
            break;
        case (GDK_SOURCE_KEYBOARD) :
            MMpush (m, ITOM (DEVICE_KEYBOARD));
            break;
        default :
            MMpush (m, ITOM (DEVICE_UNKNOWN));
    }
    #else
    Mpushstrbloc (m, "unknown");
    MMpush (m, ITOM (DEVICE_UNKNOWN));
    #endif
    MMpush (m, ITOM (2));
    MBdeftab (m);

    return;
}

static void scol_gtk_mmachine_set_GdkWindowState (mmachine m, GdkWindowState state)
{
    switch (state)
    {
        case (GDK_WINDOW_STATE_WITHDRAWN) :
            MMpush (m, ITOM (WINDOW_NOTSHOWN));
            break;
         case (GDK_WINDOW_STATE_ICONIFIED) :
            MMpush (m, ITOM (WINDOW_ICONIFIED));
            break;
         case (GDK_WINDOW_STATE_MAXIMIZED) :
            MMpush (m, ITOM (WINDOW_MAXIMIZED));
            break;
         case (GDK_WINDOW_STATE_STICKY) :
            MMpush (m, ITOM (WINDOW_STICKY));
            break;
         case (GDK_WINDOW_STATE_FULLSCREEN) :
            MMpush (m, ITOM (WINDOW_FULLSCREEN));
            break;
         case (GDK_WINDOW_STATE_ABOVE) :
            MMpush (m, ITOM (WINDOW_ABOVE));
            break;
         case (GDK_WINDOW_STATE_BELOW) :
            MMpush (m, ITOM (WINDOW_BELOW));
            break;
        default :
            MMpush (m, ITOM (WINDOW_STATE_UNKNOWN));
    }
    return;
}







/*
    Push to the machine scol any button event values => GdkEventButton
    Push !
    1 : I : type
    2 : I : button
    3 : mask
    4 : pos (x, y)
*/
static int scol_gtk_widget_cb_push_mmachine_event_button (mmachine m, GdkEvent *event)
{
    int total_event = 0;
    int type, nbutton, mask;

    type = event->button.type;
    total_event++;
    switch (type)   /* j'aurais pu prendre les mêmes valeurs que définies dans GDK .. */
    {
        case (GDK_BUTTON_PRESS) :
            MMpush (m, ITOM (EVENT_BUTTON_PRESSED));
            break;
        case (GDK_2BUTTON_PRESS) :
            MMpush (m, ITOM (EVENT_BUTTON_PRESSED2));
            break;
        case (GDK_3BUTTON_PRESS) :
            MMpush (m, ITOM (EVENT_BUTTON_PRESSED3));
            break;
        case (GDK_BUTTON_RELEASE) :
            MMpush (m, ITOM (EVENT_BUTTON_RELEASE));
            break;
        default :
            MMpush (m, ITOM (EVENT_NOTHING));
    }

    nbutton = (int) event->button.button;
    total_event++;
    MMpush (m, ITOM (nbutton));

    mask = event->button.state;
    total_event++;
    scol_gtk_mmachine_set_GdkModifierType (m, mask);

    total_event++;
    MMpush (m, ITOM ((int) event->button.x));
    MMpush (m, ITOM ((int) event->button.y));
    MMpush (m, ITOM (2));
    MBdeftab (m);

    return total_event;
}

/*
    => GdkEventConfigure
*/
int scol_gtk_widget_cb_push_mmachine_event_configure (mmachine m, GdkEvent *event)
{
    int total_event = 0;

    total_event++;
    MMpush (m, ITOM (event->configure.x));
    MMpush (m, ITOM (event->configure.y));
    MMpush (m, ITOM (2));
    MBdeftab (m);

    total_event++;
    MMpush (m, ITOM (event->configure.width));
    MMpush (m, ITOM (event->configure.height));
    MMpush (m, ITOM (2));
    MBdeftab (m);

    return total_event;
}

/*
    => GdkEventCrossing
*/
int scol_gtk_widget_cb_push_mmachine_event_crossing (mmachine m, GdkEvent *event)
{
    int total_event = 0;
    int type = 0, mask;

    total_event++;
    if (event->crossing.type == GDK_LEAVE_NOTIFY)
        type = 1;
    MMpush (m, ITOM (type));

    mask = event->crossing.state;
    total_event++;
    scol_gtk_mmachine_set_GdkModifierType (m, mask);

    total_event++;
    MMpush (m, ITOM ((int) event->crossing.focus));

    total_event++;
    MMpush (m, ITOM ((int) event->crossing.x));
    MMpush (m, ITOM ((int) event->crossing.y));
    MMpush (m, ITOM (2));
    MBdeftab (m);

    return total_event;
}

/*
    => GdkEventFocus
*/
int scol_gtk_widget_cb_push_mmachine_event_focus (mmachine m, GdkEvent *event)
{
    int total_event = 0;

    total_event++;
    MMpush (m, ITOM ((int) event->focus_change.in));

    return total_event;
}

/*
    => GdkEventKey
*/
int scol_gtk_widget_cb_push_mmachine_event_key (mmachine m, GdkEvent *event)
{
    int total_event = 0;
    GdkEventType type;
    guint mask;

    total_event++;
    type = event->key.type;
    if (type == GDK_KEY_PRESS)
        MMpush (m, ITOM (0));
    else if (type == GDK_KEY_RELEASE)
        MMpush (m, ITOM (1));
    else
        MMpush (m, NIL);

    mask = event->crossing.state;
    total_event++;
    scol_gtk_mmachine_set_GdkModifierType (m, mask);

    total_event++;
    MMpush (m, ITOM ((int) event->key.keyval));

    total_event++;
    Mpushstrbloc (m, (char *) gdk_keyval_name (event->key.keyval));

    return total_event;
}

/*
    => GdkEventMotion
*/
int scol_gtk_widget_cb_push_mmachine_event_motion (mmachine m, GdkEvent *event)
{
    int total_event = 0;
    guint mask;
    gdouble *axes;

    mask = event->motion.state;
    total_event++;
    scol_gtk_mmachine_set_GdkModifierType (m, mask);

    total_event++;
    MMpush (m, ITOM ((int)event->motion.x));
    MMpush (m, ITOM ((int)event->motion.y));
    MMpush (m, ITOM (2));
    MBdeftab (m);

    total_event++;
    axes = event->motion.axes;
    if (axes == NULL)
        MMpush (m, NIL);
    else
    {
        MMpush (m, ITOM ((int) axes[0]));
        MMpush (m, ITOM ((int) axes[1]));
        MMpush (m, ITOM (2));
        MBdeftab (m);
    }

    total_event++;
    scol_gtk_mmachine_set_GdkDevice (m, event);

    return total_event;
}

/*
    => GdkEventScroll
*/
int scol_gtk_widget_cb_push_mmachine_event_scroll (mmachine m, GdkEvent *event)
{
    int total_event = 0;
    guint mask;

    total_event++;
    switch (event->scroll.direction)
    {
        case (GDK_SCROLL_UP) :
            MMpush (m, ITOM (EVENT_SCROLL_UP));
            break;
        case (GDK_SCROLL_DOWN) :
            MMpush (m, ITOM (EVENT_SCROLL_DOWN));
            break;
        case (GDK_SCROLL_LEFT) :
            MMpush (m, ITOM (EVENT_SCROLL_LEFT));
            break;
        case (GDK_SCROLL_RIGHT) :
            MMpush (m, ITOM (EVENT_SCROLL_RIGHT));
            break;
        default :
            MMpush (m, ITOM (EVENT_SCROLL_UNKNOWN));
    }

    mask = event->scroll.state;
    total_event++;
    scol_gtk_mmachine_set_GdkModifierType (m, mask);

    total_event++;
    MMpush (m, ITOM ((int) event->scroll.x));
    MMpush (m, ITOM ((int) event->scroll.y));
    MMpush (m, ITOM (2));
    MBdeftab (m);

    total_event++;
    scol_gtk_mmachine_set_GdkDevice (m, event);

    return total_event;
}

/*
    => GdkEventWindowState
*/
int scol_gtk_widget_cb_push_mmachine_event_window_state (mmachine m, GdkEvent *event)
{
    int total_event = 0;

    total_event++;
    scol_gtk_mmachine_set_GdkWindowState (m, event->window_state.changed_mask);

    return total_event;
}







/*
    Les callbacks de GTK+
*/
gboolean scol_gtk_widget_cb_buttonpressed (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_BUTTONPRESSED);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_buttonpressed error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_button (m, event);
    OBJcallreflex (m, args);
    return mask;
}

gboolean scol_gtk_widget_cb_buttonreleased (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_BUTTONRELEASED);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_buttonreleased error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_button (m, event);
    OBJcallreflex (m, args);
    return mask;
}

gboolean scol_gtk_widget_cb_moveresize (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_MOVERESIZE);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_moveresize error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_configure (m, event);
    OBJcallreflex (m, args);
    return mask;
}

void scol_gtk_widget_cb_destroy (GtkWidget *widget, gpointer m2m)
{
    int cb;
    mmachine m;

    m = (mmachine) m2m;

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_DESTROY);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_destroy error : no callback defined ! errcode = %d", cb);
        return;
    }
    OBJcallreflex (m, 0);
    return;
}

gboolean scol_gtk_widget_cb_enterleave (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_ENTERLEAVE);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_enterleave error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_crossing (m, event);
    OBJcallreflex (m, args);
    return mask;
}

gboolean scol_gtk_widget_cb_keybfocus (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_KEYB_FOCUS);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_keybfocus error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_focus (m, event);
    OBJcallreflex (m, args);
    return mask;
}

void scol_gtk_widget_cb_hide (GtkWidget *widget, gpointer m2m)
{
    int cb;
    mmachine m;

    m = (mmachine) m2m;

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_HIDE);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_hide error : no callback defined ! errcode = %d", cb);
        return;
    }
    OBJcallreflex (m, 0);
    return;
}

void scol_gtk_widget_cb_show (GtkWidget *widget, gpointer m2m)
{
    int cb;
    mmachine m;

    m = (mmachine) m2m;

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_SHOW);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_show error : no callback defined ! errcode = %d", cb);
        return;
    }
    OBJcallreflex (m, 0);
    return;
}

gboolean scol_gtk_widget_cb_key (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_KEY);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_key error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_key (m, event);
    OBJcallreflex (m, args);
    return mask;
}

gboolean scol_gtk_widget_cb_motion (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_MOTION);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_motion error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_motion (m, event);
    OBJcallreflex (m, args);
    return mask;
}

gboolean scol_gtk_widget_cb_scroll (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_SCROLL);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_scroll error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_scroll (m, event);
    OBJcallreflex (m, args);
    return mask;
}

void scol_gtk_widget_cb_value_changed (GtkWidget *widget, gpointer m2m)
{
    int cb;
    mmachine m;
    float f;

    m = (mmachine) m2m;

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WIDGET_CB_VALUE_CHANGED);
    if (cb)
    {
        g_message ("scol_gtk_widget_cb_value_changed error : no callback defined ! errcode = %d", cb);
        return;
    }

    FSET (f, (float) gtk_range_get_value (GTK_RANGE (widget)));
    MMpush (m, f);
    OBJcallreflex (m, 1);
    return;
}













gboolean scol_gtk_window_cb_state (GtkWidget *widget, GdkEvent *event, gpointer m2m)
{
    int cb, args;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_WINDOW_CB_STATE);
    if (cb)
    {
        g_message ("scol_gtk_window_cb_state error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    args = scol_gtk_widget_cb_push_mmachine_event_window_state (m, event);
    OBJcallreflex (m, args);
    return mask;
}




gboolean scol_gtk_button_cb_clicked (GtkWidget *widget, gpointer m2m)
{
    int cb;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (widget), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) widget, OBJ2DGTK_BUTTON_CB_CLICKED);
    if (cb)
    {
        g_message ("scol_gtk_button_cb_clicked error : no callback defined ! errcode = %d", cb);
        return mask;
    }
    OBJcallreflex (m, 0);
    return mask;
}


void scol_gtk_notebook_cb_change (GtkNotebook *notebook, GtkWidget *child, guint index, gpointer m2m)
{
    int cb;
    mmachine m;

    m = (mmachine) m2m;
    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) notebook, OBJ2DGTK_NOTEBOOK_CB_CHANGE);
    if (cb)
    {
        g_message ("scol_gtk_notebook_cb_change error : no callback defined ! errcode = %d", cb);
        return;
    }
    MMpush (m, ITOM ((int) index));
    OBJcallreflex (m, 1);
    return;
}



void scol_gtk_textbuffer_cb_changed (GtkTextBuffer *buffer, gpointer m2m)
{
    int cb;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (buffer), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) buffer, OBJ2DGTK_TEXTBUFFER_CB_CHANGED);
    if (cb)
    {
        g_message ("scol_gtk_textbuffer_cb_changed error : no callback defined ! errcode = %d", cb);
        return;
    }
    OBJcallreflex (m, 0);
    return;
}

void scol_gtk_textbuffer_cb_modified (GtkTextBuffer *buffer, gpointer m2m)
{
    int cb;
    gboolean mask;
    mmachine m;

    m = (mmachine) m2m;
    mask = (gboolean) g_object_get_data (G_OBJECT (buffer), "SCOL_MASK");

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) buffer, OBJ2DGTK_TEXTBUFFER_CB_MODIFIED);
    if (cb)
    {
        g_message ("scol_gtk_textbuffer_cb_modified error : no callback defined ! errcode = %d", cb);
        return;
    }
    OBJcallreflex (m, 0);
    return;
}





/**
 * \brief Define a callback to a widget - fun [ObjGtkWidget u0 u1 I I] ObjGtkWidget
 *
 * See http://trac.scolring.org/projects/lib2dgtk/wiki/Widget_callbacks
 */
int scol_gtkWidgetCB (mmachine m)
{
    int mwidget, mflag, mmask;
    gboolean mask = TRUE;
    GtkWidget *widget;
    char s[64];

    g_message ("scol_gtkWidgetCB : entering");

    mmask = MTOI (MMpull (m));
    mflag = MTOI (MMpull (m));
    mwidget = MMget (m, 2);

    if (mwidget == NIL)
    {
        g_warning ("scol_gtkWidgetCB error : widget is nil");
        MMpull (m); MMpull (m); MMpull (m);
        MMpush (m, NIL);
        return 0;
    }

    widget = (GtkWidget *) MMfetch (m, MTOP (mwidget), OBJ2DGTK_WIDGET_HANDLE);
    if (mmask == SIGNAL_MASK_PROPAGATE)
        mask = FALSE;

    g_object_set_data (G_OBJECT (widget), "SCOL_MASK", (gpointer) mask);

    switch (mflag)
    {
        case (WIDGET_BUTTONPRESSED) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_BUTTONPRESSED);
            gtk_widget_add_events (widget, GDK_BUTTON_PRESS_MASK);
            g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (scol_gtk_widget_cb_buttonpressed), (gpointer) m);
            break;

        case (WIDGET_BUTTONRELEASED) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_BUTTONRELEASED);
            gtk_widget_add_events (widget, GDK_BUTTON_RELEASE_MASK);
            g_signal_connect (G_OBJECT (widget), "button-release-event", G_CALLBACK (scol_gtk_widget_cb_buttonreleased), (gpointer) m);
            break;

        case (WIDGET_MOVERESIZE) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_MOVERESIZE);
            gtk_widget_add_events (widget, GDK_STRUCTURE_MASK);
            g_signal_connect (G_OBJECT (widget), "configure-event", G_CALLBACK (scol_gtk_widget_cb_moveresize), (gpointer) m);
            break;

        case (WIDGET_DESTROY) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_DESTROY);
            g_signal_connect (G_OBJECT (widget), "destroy", G_CALLBACK (scol_gtk_widget_cb_destroy), (gpointer) m);
            break;

        case (WIDGET_ENTERLEAVE) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_ENTERLEAVE);
            gtk_widget_add_events (widget, GDK_ENTER_NOTIFY_MASK);
            gtk_widget_add_events (widget, GDK_LEAVE_NOTIFY_MASK);
            g_signal_connect (G_OBJECT (widget), "enter-notify-event", G_CALLBACK (scol_gtk_widget_cb_enterleave), (gpointer) m);
            g_signal_connect (G_OBJECT (widget), "leave-notify-event", G_CALLBACK (scol_gtk_widget_cb_enterleave), (gpointer) m);
            break;

        case (WIDGET_KEYB_FOCUS) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_KEYB_FOCUS);
            gtk_widget_add_events (widget, GDK_FOCUS_CHANGE_MASK);
            g_signal_connect (G_OBJECT (widget), "focus-in-event", G_CALLBACK (scol_gtk_widget_cb_keybfocus), (gpointer) m);
            g_signal_connect (G_OBJECT (widget), "focus-out-event", G_CALLBACK (scol_gtk_widget_cb_keybfocus), (gpointer) m);
            break;

        case (WIDGET_HIDE) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_HIDE);
            g_signal_connect (G_OBJECT (widget), "hide", G_CALLBACK (scol_gtk_widget_cb_hide), (gpointer) m);
            break;

        case (WIDGET_SHOW) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_SHOW);
            g_signal_connect (G_OBJECT (widget), "show", G_CALLBACK (scol_gtk_widget_cb_show), (gpointer) m);
            break;

        case (WIDGET_KEY) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_KEY);
            gtk_widget_add_events (widget, GDK_KEY_PRESS_MASK);
            gtk_widget_add_events (widget, GDK_KEY_RELEASE_MASK);
            g_signal_connect (G_OBJECT (widget), "key-press-event", G_CALLBACK (scol_gtk_widget_cb_key), (gpointer) m);
            g_signal_connect (G_OBJECT (widget), "key-release-event", G_CALLBACK (scol_gtk_widget_cb_key), (gpointer) m);
            break;

        case (WIDGET_MOTION) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_MOTION);
            gtk_widget_add_events (widget, GDK_POINTER_MOTION_MASK);
            g_signal_connect (G_OBJECT (widget), "motion-notify-event", G_CALLBACK (scol_gtk_widget_cb_motion), (gpointer) m);
            break;

        case (WIDGET_SCROLL) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_SCROLL);
            gtk_widget_add_events (widget, GDK_BUTTON_PRESS_MASK);
            g_signal_connect (G_OBJECT (widget), "scroll-event", G_CALLBACK (scol_gtk_widget_cb_scroll), (gpointer) m);
            break;

        case (WIDGET_VALUE_CHANGED) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WIDGET_CB_VALUE_CHANGED);
            g_signal_connect (G_OBJECT (widget), "value-changed", G_CALLBACK (scol_gtk_widget_cb_value_changed), (gpointer) m);
            break;




















        case (WINDOW_STATE) :
            scol_gtk_common_object_type (widget, s, 64);
            if (strcmp (s, "GtkWindow"))
            {
                g_warning ("scol_gtkWidgetCB error : flag %d asks a GtkWindow", mflag);
                break;
            }
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WINDOW_CB_STATE);
            gtk_widget_add_events (widget, GDK_STRUCTURE_MASK);
            g_signal_connect (G_OBJECT (widget), "window-state-event", G_CALLBACK (scol_gtk_window_cb_state), (gpointer) m);
            break;







        case(BUTTON_CLICKED) :
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_BUTTON_CB_CLICKED);
            g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (scol_gtk_button_cb_clicked), (gpointer) m);
            break;



        case (NOTEBOOK_CHANGE) :
            scol_gtk_common_object_type (widget, s, 64);
            if (strcmp (s, "GtkNotebook"))
            {
                g_warning ("scol_gtkWidgetCB error : flag %d asks a GtkNotebook", mflag);
                break;
            }
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_NOTEBOOK_CB_CHANGE);
            g_signal_connect (G_OBJECT (widget), "switch-page", G_CALLBACK (scol_gtk_notebook_cb_change), (gpointer) m);
            break;


        case (TEXTBUFFER_CHANGED) :
            scol_gtk_common_object_type (widget, s, 64);
            if (strcmp (s, "GtkTextBuffer"))
            {
                g_warning ("scol_gtkWidgetCB error : flag %d asks a GtkTextBuffer", mflag);
                break;
            }
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_TEXTBUFFER_CB_CHANGED);
            g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (scol_gtk_textbuffer_cb_changed), (gpointer) m);
            break;

        case (TEXTBUFFER_MODIFIED) :
            scol_gtk_common_object_type (widget, s, 64);
            if (strcmp (s, "GtkTextBuffer"))
            {
                g_warning ("scol_gtkWidgetCB error : flag %d asks a GtkTextBuffer", mflag);
                break;
            }
            OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_TEXTBUFFER_CB_MODIFIED);
            g_signal_connect (G_OBJECT (widget), "modified-changed", G_CALLBACK (scol_gtk_textbuffer_cb_modified), (gpointer) m);
            break;




        default :
            g_warning ("scol_gtkWidgetCB : flag is not valid -> %d", mflag);
    }
    return 0;
}
